#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
+#include <QPrinter>
#include <QPushButton>
#include <QScrollArea>
+#include <QSettings>
+#include <QSignalMapper>
#include <QToolButton>
#define ROWS 20
#define COLS 20
-MLabelDialog::MLabelDialog(QWidget*par,QPrinter* pn,int nl)
+MLabelDialog::MLabelDialog(QWidget*par,QPrinter* pn,int nl,QSizeF ls)
:QDialog(par)
{
printer=pn;
numlabels=nl;
+ labelsize=ls;
+ maxrows=ROWS;
+ maxcols=COLS;
setWindowTitle(tr("Label Printing Setup"));
+ //get settings
+ QSettings set;
+ set.beginGroup("printer/"+printer->printerName());
+ double ox=set.value("offsetx",0.0).toDouble();
+ double oy=set.value("offsety",0.0).toDouble();
+ double lsx=set.value("sizex",0.0).toDouble();
+ double lsy=set.value("sizey",0.0).toDouble();
+ QString mtrc=set.value("metric",tr("mm","defaultmetric: mm, in, cm")).toString();
+ if(lsx==0.0 || lsy==0.0){
+ //convert ticket template size
+ double dx=printer->logicalDpiX();
+ double dy=printer->logicalDpiY();
+ if(mtrc=="in"){
+ lsx=ls.width()/dx;
+ lsy=ls.height()/dy;
+ }else
+ if(mtrc=="cm"){
+ lsx=ls.width()/dx*2.54;
+ lsy=ls.height()/dy*2.54;
+ }else{//mm
+ lsx=ls.width()/dx*25.4;
+ lsy=ls.height()/dy*25.4;
+ }
+ }
+
+ //display
+
QVBoxLayout*vl;
QGridLayout*gl;
setLayout(vl=new QVBoxLayout);
vl->addLayout(gl=new QGridLayout,0);
gl->addWidget(new QLabel(tr("Label offset:")),0,0);
- gl->addWidget(offx=new QLineEdit,0,1);
+ gl->addWidget(offx=new QLineEdit(QString::number(ox)),0,1);
+ offx->setValidator(new QDoubleValidator(0.0,1000.0,2,this));
gl->addWidget(new QLabel("x"),0,2);
- gl->addWidget(offy=new QLineEdit,0,3);
+ gl->addWidget(offy=new QLineEdit(QString::number(oy)),0,3);
+ offy->setValidator(new QDoubleValidator(0.0,1000.0,2,this));
gl->addWidget(new QLabel(tr("Label size:")),1,0);
- gl->addWidget(sizex=new QLineEdit,1,1);
+ gl->addWidget(sizex=new QLineEdit(QString::number(lsx)),1,1);
+ sizex->setValidator(new QDoubleValidator(0.0,1000.0,2,this));
gl->addWidget(new QLabel("x"),1,2);
- gl->addWidget(sizey=new QLineEdit,1,3);
+ gl->addWidget(sizey=new QLineEdit(QString::number(lsy)),1,3);
+ sizey->setValidator(new QDoubleValidator(0.0,1000.0,2,this));
gl->addWidget(new QLabel(tr("Unit:")),2,0);
gl->addWidget(metric=new QComboBox,2,1,1,3);
+ metric->addItem(tr("Millimeter"),"mm");
+ metric->addItem(tr("Centimeter"),"cm");
+ metric->addItem(tr("Inch"),"in");
gl->setColumnStretch(4,10);
vl->addSpacing(10);
vl->addWidget(new QLabel(tr("Page usage:")),0);
vl->addWidget(page=new QComboBox,0);
+ for(int i=0;i<nl;i++)
+ page->addItem(tr("Page %1").arg(i+1),i);
+ oldpage=0;
QScrollArea *sa;
QWidget*w=new QWidget;
QToolButton*t;
gl->addWidget(t=new QToolButton,0,0);
t->setIcon(QIcon(":/arrowdiag.png"));
+ connect(t,SIGNAL(clicked()),this,SLOT(toggleAll()));
+ QSignalMapper *cmap=new QSignalMapper(this);
+ connect(cmap,SIGNAL(mapped(int)),this,SLOT(toggleColumn(int)));
for(int i=1;i<=COLS;i++){
gl->addWidget(t=new QToolButton,0,i);
t->setIcon(QIcon(":/arrowdown.png"));
+ connect(t,SIGNAL(clicked()),cmap,SLOT(map()));
+ cmap->setMapping(t,i-1);
}
+ QSignalMapper *rmap=new QSignalMapper(this);
+ connect(rmap,SIGNAL(mapped(int)),this,SLOT(toggleRow(int)));
for(int i=1;i<=ROWS;i++){
gl->addWidget(t=new QToolButton,i,0);
t->setIcon(QIcon(":/arrowright.png"));
+ connect(t,SIGNAL(clicked()),rmap,SLOT(map()));
+ rmap->setMapping(t,i-1);
for(int j=1;j<=COLS;j++){
QCheckBox*b;
gl->addWidget(b=new QCheckBox,i,j);
checks.append(b);
+ connect(b,SIGNAL(clicked()),this,SLOT(savePage()));
}
}
sa->setWidget(w);
+ connect(page,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePage()));
+ connect(sizex,SIGNAL(textChanged(const QString&)),this,SLOT(updatePage()));
+ connect(sizey,SIGNAL(textChanged(const QString&)),this,SLOT(updatePage()));
+ connect(metric,SIGNAL(currentIndexChanged(int)),this,SLOT(updatePage()));
vl->addSpacing(15);
QHBoxLayout*hl;
QPushButton*p;
hl->addWidget(p=new QPushButton(tr("Ok")),0);
connect(p,SIGNAL(clicked()),this,SLOT(accept()));
+ connect(p,SIGNAL(clicked()),this,SLOT(saveSettings()));
+ p->setDefault(true);
hl->addWidget(p=new QPushButton(tr("Cancel")),0);
connect(p,SIGNAL(clicked()),this,SLOT(reject()));
+
+ //initialize
+ QList<bool>tpl;
+ for(int i=0;i<(ROWS*COLS);i++)tpl.append(true);
+ for(int i=0;i<nl;i++)checked.append(tpl);
+ updatePage();
}
MLabelDialog::~MLabelDialog(){}
-QPointF MLabelDialog::labelOffset(int n){}
+
+int MLabelDialog::findLabel(int n,int&row,int&col)
+{
+ //search allowed labels
+ int ctr=-1;
+ for(int p=0;p<numlabels;p++)
+ for(int r=maxrows-1;r>=0;r--)
+ for(int c=0;c<maxcols;c++){
+ if(checked[p][r*COLS+c])ctr++;
+ if(ctr==n){
+ row=r;
+ col=c;
+ return p;
+ }
+ }
+ //fail
+ return -1;
+}
+
+QPointF MLabelDialog::labelOffset(int n)
+{
+ //find it
+ int row=0,col=0;
+ findLabel(n,row,col);
+ //get offset
+ double px=offx->text().toDouble();
+ double py=offy->text().toDouble();
+ //add rows/cols
+ px+=col*sizex->text().toDouble();
+ py+=row*sizey->text().toDouble();
+ //correct to DPI
+ QString mtrc=metric->itemData(metric->currentIndex()).toString();
+ if(mtrc=="in"){
+ px*=printer->logicalDpiX();
+ py*=printer->logicalDpiY();
+ }else
+ if(mtrc=="cm"){
+ px*=printer->logicalDpiX()/2.54;
+ py*=printer->logicalDpiY()/2.54;
+ }else{
+ px*=printer->logicalDpiX()/25.4;
+ py*=printer->logicalDpiY()/25.4;
+ }
+ //return
+ return QPointF(px,py);
+}
+
+bool MLabelDialog::labelNeedsPageTurn(int n)
+{
+ //find it
+ int pg,row=0,col=0;
+ pg=findLabel(n,row,col);
+ //page 0 needs no turn
+ if(pg<=0)return false;
+ //scan that page (all rows below label)
+ for(int r=maxrows-1;r>row;r--)
+ for(int c=0;c<maxcols;c++)
+ if(checked[pg][r*COLS+c])return false;
+ //scan that page (all cols left of label)
+ for(int c=0;c<col;c++)
+ if(checked[pg][row*COLS+c])return false;
+ //none found, this is the first one: turn page
+ return true;
+}
+
+void MLabelDialog::toggleRow(int r)
+{
+ for(int i=r*COLS;i<(r*COLS+COLS);i++){
+ checked[oldpage][i]^=true;
+ checks[i]->setChecked(checked[oldpage][i]);
+ }
+}
+
+void MLabelDialog::toggleColumn(int c)
+{
+ for(int r=0;r<ROWS;r++){
+ int i=r*COLS+c;
+ checked[oldpage][i]^=true;
+ checks[i]->setChecked(checked[oldpage][i]);
+ }
+}
+
+void MLabelDialog::toggleAll()
+{
+ for(int i=0;i<(ROWS*COLS);i++){
+ checked[oldpage][i]^=true;
+ checks[i]->setChecked(checked[oldpage][i]);
+ }
+}
+
+void MLabelDialog::savePage()
+{
+ for(int i=0;i<(ROWS*COLS);i++)
+ checked[oldpage][i]=checks[i]->isChecked();
+}
+
+void MLabelDialog::updatePage()
+{
+ //find how many rows/cols fit on the page
+ double lx=sizex->text().toDouble();
+ double ly=sizey->text().toDouble();
+ QRect pr=printer->pageRect();
+ QString mtrc=metric->itemData(metric->currentIndex()).toString();
+ if(mtrc=="in"){
+ lx*=printer->logicalDpiX();
+ ly*=printer->logicalDpiY();
+ }else
+ if(mtrc=="cm"){
+ lx*=printer->logicalDpiX()/2.54;
+ ly*=printer->logicalDpiY()/2.54;
+ }else{
+ lx*=printer->logicalDpiX()/25.4;
+ ly*=printer->logicalDpiY()/25.4;
+ }
+
+ if(ly>0.0){
+ maxrows=pr.height()/ly;
+ if(maxrows>ROWS)maxrows=ROWS;
+ }else maxrows=ROWS;
+ if(lx>0.0){
+ maxcols=pr.width()/lx;
+ if(maxcols>COLS)maxcols=COLS;
+ }else maxcols=COLS;
+ //update
+ oldpage=page->itemData(page->currentIndex()).toInt();
+ for(int r=0;r<ROWS;r++)
+ for(int c=0;c<COLS;c++){
+ int i=r*COLS+c;
+ bool b=r<maxrows && c<maxcols;
+ checks[i]->setChecked(b && checked[oldpage][i]);
+ checks[i]->setEnabled(b);
+ }
+}
+
+void MLabelDialog::saveSettings()
+{
+ QSettings set;
+ set.beginGroup("printer/"+printer->printerName());
+ set.setValue("offsetx",offx->text().toDouble());
+ set.setValue("offsety",offy->text().toDouble());
+ set.setValue("sizex",sizex->text().toDouble());
+ set.setValue("sizey",sizey->text().toDouble());
+ set.setValue("metric",metric->itemData(metric->currentIndex()).toString());
+}