finalized ticket rendering
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 5 Apr 2008 12:46:42 +0000 (12:46 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 5 Apr 2008 12:46:42 +0000 (12:46 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@153 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

src/code39.cpp
src/labeldlg.cpp
src/labeldlg.h
src/orderwin.cpp
src/ticketrender.cpp

index e292b5b..8d151a9 100644 (file)
@@ -97,7 +97,7 @@ QImage code39(QString str)
                rstr+=c39map[str[i].toAscii()];
        rstr+=c39map[code39mod(str)];
        rstr+=c39map['*'];
-       qDebug("Code-39, encoding: %s -> %c",str.toAscii().data(),code39mod(str));
+//     qDebug("Code-39, encoding: %s -> %c",str.toAscii().data(),code39mod(str));
        //define xpm
        char *xpm[4];
        QByteArray xpmsz=QString().sprintf("%i 1 2 1",rstr.size()).toAscii();
index 37fe996..41dcca0 100644 (file)
 #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;
@@ -61,20 +104,34 @@ MLabelDialog::MLabelDialog(QWidget*par,QPrinter* pn,int nl)
        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;
@@ -83,9 +140,160 @@ MLabelDialog::MLabelDialog(QWidget*par,QPrinter* pn,int nl)
        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());
+}
index 48113b5..17ea5ec 100644 (file)
@@ -28,19 +28,41 @@ class MLabelDialog:public QDialog
        Q_OBJECT
        public:
                /**creates a label dialog*/
-               MLabelDialog(QWidget*parent,QPrinter*printer,int numlabels);
+               MLabelDialog(QWidget*parent,QPrinter*printer,int numlabels,QSizeF labelsize);
                /**deletes the label dialog and stores its current settings*/
                ~MLabelDialog();
                
-               /**returns the offset of label number n; relative to the coordinate system of the given paint device*/
+               /**returns the offset of label number n; relative to the coordinate system of the given paint device; starts at the bottom left of the page*/
                QPointF labelOffset(int n);
+               /**returns whether this label is on a new page*/
+               bool labelNeedsPageTurn(int n);
+               
+       private slots:
+               /**internal: toggle Row button clicked*/
+               void toggleRow(int);
+               /**internal: toggle Column button clicked*/
+               void toggleColumn(int);
+               /**internal: toggle all button clicked*/
+               void toggleAll();
+               
+               /**internal: display correct page*/
+               void updatePage();
+               /**helper: save current/old page*/
+               void savePage();
+               /**internal: save settings for next time*/
+               void saveSettings();
+               
        private:
                QLineEdit *offx,*offy,*sizex,*sizey;
+               QSizeF labelsize;
                QComboBox *metric,*page;
                QList<QCheckBox*>checks;
                QList<QList<bool> >checked;
                QPrinter* printer;
-               int numlabels;
+               int numlabels,oldpage,maxrows,maxcols;
+               
+               /**internal helper: find coordinates of label n; returns page id; returns -1 on failure*/
+               int findLabel(int n,int&row,int&col);
 };
 
 #endif
index 1ab759b..a290dcf 100644 (file)
@@ -193,15 +193,20 @@ void MOrderWindow::printTickets(QList<MTicket> tickets)
        QPrinter printer;
        QPrintDialog pd(&printer,this);
        if(pd.exec()!=QDialog::Accepted)return;
-       //TODO: insert label arrangement
-       MLabelDialog ld(this,&printer,tickets.size());
+       //label arrangement
+       MTicketRenderer render(tf);
+       MLabelDialog ld(this,&printer,tickets.size(),render.ticketSize(printer));
        if(ld.exec()!=QDialog::Accepted)
                return;
-       //TODO: fix to use correct template
-       MTicketRenderer render(tf);
+       //print
        QPainter painter(&printer);
-       render.render(tickets[0],printer,&painter);
-       
+       for(int i=0;i<tickets.size();i++){
+               QPointF p=ld.labelOffset(i);
+               if(ld.labelNeedsPageTurn(i)){
+                       printer.newPage();
+               }
+               render.render(tickets[i],printer,&painter,p);
+       }
 }
 
 void MOrderWindow::printBill()
index 1824e80..41b8adf 100644 (file)
@@ -307,7 +307,7 @@ QSizeF MTicketRendererPrivate::tonatural(const QPaintDevice&dev,QSizeF s)
        return s;
 }
 
-void MTicketRendererPrivate::render(QDomElement&sup, const MTicket&tick, QPaintDevice&pdev, QPainter*painter, QPointF offset)
+void MTicketRendererPrivate::render(QDomElement&sup, const MTicket&tick, QPaintDevice&pdev, QPainter*painter, QPointF noff)
 {
        //initialize painter
        QPainter *paint;
@@ -315,7 +315,6 @@ void MTicketRendererPrivate::render(QDomElement&sup, const MTicket&tick, QPaintD
                paint=painter;
        else
                paint=new QPainter(&pdev);
-       QPointF noff=tonatural(pdev,offset);
        QSizeF nsize=tonatural(pdev,tsize);
        paint->setClipRect(QRectF(noff,nsize));
        //parse file