Logo Search packages:      
Sourcecode: kbarcode version File versions  Download package

labelprinter.cpp

/***************************************************************************
                          labelprinter.cpp  -  description
                             -------------------
    begin                : Son Mai 5 2002
    copyright            : (C) 2002 by Dominik Seichter
    email                : domseichter@web.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "labelprinter.h"
#include "kbarcode.h"
#include "label.h"
#include "sqltables.h"
#include "printersettings.h"
#include "printlabeldlg.h"
#include "smalldialogs.h"
#include "measurements.h"
#include "batchprinter.h"

// Other includes
#include <stdlib.h>
#include <stdio.h>

// QT includes
#include <qclipboard.h>
#include <qcursor.h>
#include <qgroupbox.h>
#include <qhbox.h>
#include <qlayout.h>
#include <qpainter.h>
#include <qpaintdevicemetrics.h>
#include <qprogressdialog.h>
#include <qsqlcursor.h>
#include <qvalidator.h>

// KDE includes
#include <kapplication.h>
#include <kcombobox.h>
#include <kfiledialog.h>
#include <kiconloader.h>
#include <klistview.h>
#include <klineedit.h>
#include <klineeditdlg.h>
#include <klocale.h>
#include <kmenubar.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <knuminput.h>
#include <kprinter.h>
#include <kurlrequester.h>

#define MNU_IMPORT_ID 9999

// a small helper function
QString removeQuote( QString text, QString quote ) {
    if( quote.isEmpty() )
        return text;

    text = text.stripWhiteSpace();

    if( text.left( quote.length() ) == quote )
        text = text.mid( quote.length(), text.length() - quote.length() );

    if( text.right( quote.length() ) == quote )
        text = text.left( text.length() - quote.length() );

    return text;
}

LabelPrinter::LabelPrinter( QString filename, QWidget *parent, const char *name, WFlags f )
        : DCOPObject("BatchPrinting"),
          DSMainWindow(parent, name, f)
{
    def = 0;

    QGroupBox* w = new QGroupBox( this );
    w->setColumnLayout(0, Qt::Vertical );
    w->setInsideSpacing( 40 );

    pageLayout = new QVBoxLayout( w->layout() );
    setCentralWidget( w );

    QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding );

    list = new KListView( w );
    list->addColumn( i18n("Index") );
    list->addColumn( i18n("Number of Labels") );
    list->addColumn( i18n("Article Number") );
    list->addColumn( i18n("Group") );
    list->setAllColumnsShowFocus( true );
    connect( list, SIGNAL(doubleClicked(QListViewItem*,const QPoint &,int)),
             this, SLOT(changeItem(QListViewItem*,const QPoint &,int)));

    compGroup = new KCompletion();

    QGridLayout* infoGrid = new QGridLayout();

    info1 = new QLabel( w );
    info2 = new QLabel( w );
    info3 = new QLabel( w );
    info4 = new QLabel( w );
    info5 = new QLabel( w );

    infoGrid->addWidget( info1, 0, 0 );
    infoGrid->addWidget( info2, 0, 1 );
    infoGrid->addWidget( info3, 0, 2 );
    infoGrid->addWidget( info4, 0, 3 );
    infoGrid->addMultiCellWidget( info5, 1, 1, 0, 3 );

    buttonPrint = new KPushButton( w );
    buttonPrint->setText( i18n("&Print...") );
    buttonPrint->setIconSet( SmallIconSet("fileprint") );
    buttonPrint->setEnabled( false );

    buttonImages = new KPushButton( w );
    buttonImages->setText( i18n("&Create Images...") );
    buttonImages->setIconSet( SmallIconSet("image") );
    buttonImages->setEnabled( false );

    QGridLayout* grid = new QGridLayout( 0, 6, 6 );
    grid->addWidget( new QLabel( i18n( "Label:" ), w ), 0, 0 );

    urlrequester = new KURLRequester( w );
    urlrequester->setMode( KFile::File | KFile::ExistingOnly );
    urlrequester->setFilter( "*.kbarcode" );
    grid->addMultiCellWidget( urlrequester, 0, 0, 1, 2 );

    grid->addWidget( new QLabel( i18n( "Customer name and no.:" ), w ), 1, 0 );

    customerName = new KComboBox( false, w );
    grid->addWidget( customerName, 1, 1 );

    customerId = new KComboBox( false, w );
    grid->addWidget( customerId, 1, 2 );

    customerName->setEnabled( false );
    customerId->setEnabled( false );

    grid->addWidget( new QLabel( i18n( "Serial start:" ), w ), 2, 0 );

    serialStart = new KLineEdit( w );
    grid->addWidget( serialStart, 2, 1 );

    serialInc = new KIntNumInput( 1, w );
    serialInc->setLabel( i18n( "Serial increment:" ), KNumInput::AlignLeft | KNumInput::AlignVCenter );
    serialInc->setRange( 1, 10000, 1, false );
    grid->addWidget( serialInc, 2, 2 );

    QGroupBox* hbox = new QGroupBox( 4, QGroupBox::Horizontal, w );
    buttonAdd = new KPushButton( hbox );
    buttonAdd->setText( i18n( "&Add..." ) );

    buttonEdit = new KPushButton( hbox );
    buttonEdit->setText( i18n( "&Edit..." ) );

    buttonRemove = new KPushButton( hbox );
    buttonRemove->setText( i18n("&Remove" ) );

    buttonRemoveAll = new KPushButton( hbox );
    buttonRemoveAll->setText( i18n("R&emove All") );

    pageLayout->addLayout( grid );
    pageLayout->addWidget( hbox );
    pageLayout->addWidget( list );
    pageLayout->setStretchFactor( list, 2 );
    pageLayout->addLayout( infoGrid );

    QHBoxLayout* buttonLayout = new QHBoxLayout( 0, 6, 6 );
    buttonLayout->addItem( spacer );
    buttonLayout->addWidget( buttonPrint );
    buttonLayout->addWidget( buttonImages );

    pageLayout->addLayout( buttonLayout );
    pageLayout->addItem( spacer );

    description = "";

    DSMainWindow::setupActions();
    setupActions();

    setupSql();

    connect( buttonAdd, SIGNAL( clicked() ), this, SLOT( addItem() ) );
    connect( buttonEdit, SIGNAL( clicked() ), this, SLOT( editItem() ) );
    connect( buttonRemove, SIGNAL( clicked() ), this, SLOT( removeItem() ) );
    connect( buttonRemoveAll, SIGNAL( clicked() ), list, SLOT( clear() ) );
    connect( buttonRemoveAll, SIGNAL( clicked() ), this, SLOT( updateInfo() ) );
    connect( buttonPrint, SIGNAL( clicked() ), this, SLOT( print() ) );
    connect( buttonImages, SIGNAL( clicked() ), this, SLOT( images() ) );
    connect( customerName, SIGNAL( activated(int) ), this, SLOT( customerNameChanged(int) ) );
    connect( customerId, SIGNAL( activated(int) ), this, SLOT( customerIdChanged(int) ) );
    connect( urlrequester, SIGNAL( textChanged( const QString & ) ), this, SLOT( changeDescription() ) );
    connect( this, SIGNAL( connectedSQL() ), this, SLOT( setupSql() ) );
    connect( SqlTables::getInstance(), SIGNAL( tablesChanged() ), this, SLOT( setupSql() ) );
    connect( SqlTables::getInstance(), SIGNAL( connectedSQL() ), this, SLOT( setupSql() ) );

    if( !filename.isEmpty() )
        loadFromFile( filename );

    updateInfo();
    show();
}

LabelPrinter::~LabelPrinter()
{
    DSMainWindow::saveConfig();
    delete compGroup;
    if( def )
        delete def;
}

void LabelPrinter::setupActions() {
    mnuImport = new KPopupMenu( this );
    mnuImport->insertItem( i18n("Import from File ..."), this, SLOT( loadFromFile() ) );
    mnuImport->insertItem( i18n("Import from Clipboard ..."), this, SLOT( loadFromClipboard() ) );
    mnuImport->insertItem( i18n("Import barcode_basic"), this, SLOT( addAllItems() ) );

    menuBar()->insertItem( i18n("&Import"), mnuImport, MNU_IMPORT_ID, 1 );
    menuBar()->setItemEnabled( MNU_IMPORT_ID, false );
}

void LabelPrinter::setupSql()
{
    SqlTables* tables = SqlTables::getInstance();
    if( !tables->isConnected() )
        return;

    QSqlCursor cur( TABLE_CUSTOMER );
    cur.select();
    customerId->clear();
    customerName->clear();
    while ( cur.next() ) {
        customerId->insertItem( cur.value("customer_no" ).toString() );
        customerName->insertItem( cur.value("customer_name" ).toString() );
    }

    menuBar()->setItemEnabled( MNU_IMPORT_ID, true );
    customerName->setEnabled( true );
    customerId->setEnabled( true );
}

void LabelPrinter::setCustomerId( const QString & id ) {
    for( int i = 0; i < customerId->count(); i++ )
        if( customerId->text( i ) == id ) {
            customerId->setCurrentItem( i );
            customerIdChanged( i );
            break;
        }
}

void LabelPrinter::setLabelURL( const QString & url ) {
    urlrequester->setURL( url );
}

bool LabelPrinter::existsArticle( const QString & article ) 
{
    if( article.isEmpty() )
        return false;

    QSqlQuery query( "select uid from barcode_basic where article_no='" + article + "'" );
    while ( query.next() )
        return true;

    return false;
}

void LabelPrinter::addItem()
{
    DSSmallDialogs::AddItemsDialog aid( this, "aid" );
    aid.setGroupCompletion( compGroup );
    connect( &aid, SIGNAL( add( const QString &, const QString &, int) ),
             this, SLOT( addItem( const QString &, const QString &, int) ) );

    aid.exec();
}

bool LabelPrinter::addItem( const QString & article, const QString & group, int count, bool msg )
{
    if( !article.isEmpty() && !existsArticle( article ) ) {
        if( msg )
            KMessageBox::error( this, i18n("Please enter a valid article ID") );
        return false;
    }

    QString temp;
    temp.sprintf("%0*i", 5, list->childCount() + 1 );

    KListViewItem* item = new KListViewItem( list, temp, QString( "%1" ).arg( count ),
                          article, group );
    list->insertItem( item );

    updateInfo();

    addGroupCompletion( group );
    return true;
}

00306 void LabelPrinter::addGroupCompletion( const QString & group )
{
    if( !group.isEmpty() ) {
        bool isinside = false;
        QStringList slist = compGroup->items();
        for( unsigned int i = 0; i < slist.count(); i++ )
            if( slist[i] == group ) {
                isinside = true;
                break;
            }

        if(!isinside)
            compGroup->addItem( group );
    }
}

00322 const QStringList LabelPrinter::allItems() {
    QStringList list;
    QSqlQuery query("SELECT article_no FROM " TABLE_BASIC );
    while( query.next() )
        list.append( query.value( 0 ).toString() );

    return list;
}

void LabelPrinter::addAllItems() {
    DSSmallDialogs::AddAllDialog* dlg = new DSSmallDialogs::AddAllDialog( this, "dlg" );
    if( dlg->exec() != QDialog::Accepted )
        return;

    QString temp;
    QString group = dlg->groupName();
    int n = dlg->numberLabels();

    QSqlQuery query("SELECT article_no FROM " TABLE_BASIC );
    while( query.next() ) {
        temp.sprintf("%0*i", 5, list->childCount() + 1 );

        KListViewItem* item = new KListViewItem( list, temp, QString::number( n ),
                              query.value( 0 ).toString(), group );
        list->insertItem( item );
    }

    updateInfo();
}

void LabelPrinter::editItem()
{
    QListViewItem* item = list->selectedItem();
    if( item )
        changeItem( item, QPoint(0,0), 0 );
}

void LabelPrinter::removeItem() {
    QListViewItem* item = list->firstChild();
    while( item ) {
        if( item->isSelected() ) {
            QListViewItem* it = item->nextSibling();
            delete item;

            while( it ) {
                int a = it->text( 0 ).toInt();
                QString temp;
                temp.sprintf("%0*i", 5, a - 1 );
                it->setText( 0, temp );
                it = it->nextSibling();
            }

            break;
        } else
            item = item->nextSibling();
    }

    updateInfo();
}

void LabelPrinter::fillWithData( BatchPrinter* batch )
{
    // sort by group
    list->setSorting( 3, true );
    list->sort();

    QValueList<BatchPrinter::data>* dlist = new QValueList<BatchPrinter::data>;
    QListViewItem* item = list->firstChild();
    while( item ) {
        BatchPrinter::data m_data;
        m_data.number = item->text( 1 ).toInt();
        m_data.article_no = item->text( 2 );
        m_data.group = item->text( 3 );

        dlist->append( m_data );
        item = item->nextSibling();
    };

    batch->setData( dlist );
    batch->setLabels( labels );
}

void LabelPrinter::print( bool immediately, const QString & printer ) {
    int move = 0;
    if( !immediately ) {
        PrintLabelDlg pld( this, "pld" );
        pld.setLabelsEnabled( false );
        if( pld.exec() != QDialog::Accepted )
            return;

        move = pld.position();
        PrinterSettings::getInstance()->getData()->border = pld.border();
    }

    KPrinter* prn = PrinterSettings::getInstance()->setupPrinter( this, immediately, printer );

    if( prn ) {
        QBuffer* buffer = getBuffer();

        if( !buffer ) {
            delete prn;
            return;
        }


        BatchPrinter batch( prn, this );
        batch.setBuffer( buffer );
        batch.setMove( move );
        batch.setSerial( serialStart->text(), serialInc->value() );
        batch.setName( urlrequester->url() );
        batch.setDefinition( def );
        batch.setCustomer( customerId->currentText() );

        fillWithData( &batch );

        batch.start();

        delete buffer;
        delete prn;
        KApplication::setOverrideCursor( QCursor(Qt::ArrowCursor), true );
    }
}

00445 QBuffer* LabelPrinter::getBuffer() {
    QFile f( urlrequester->url() );
    if ( !f.open( IO_ReadOnly ) )
        return 0;

    QByteArray byte = f.readAll();
    f.close();

    QBuffer* buffer = new QBuffer( byte );
    if( !buffer->open( IO_ReadOnly ) )
        return 0;

    return buffer;
}

void LabelPrinter::customerIdChanged( int index ) {
    customerName->setCurrentItem( index );
    enableControls();
}

void LabelPrinter::customerNameChanged( int index ) {
    customerId->setCurrentItem( index );
}

void LabelPrinter::loadFromFile() {
    QString f = KFileDialog::getOpenFileName( 0, 0, this );
    if( !f.isEmpty() )
        loadFromFile( f );
}

void LabelPrinter::loadFromClipboard() {
    QClipboard *cb = KApplication::clipboard();
    QString text = cb->text();
    loadData( 0, text );
}

void LabelPrinter::loadFromFile( const QString & url ) {
    QFile file( url );

    if( !file.open( IO_ReadOnly ) ) {
        qDebug("Unable to open file: " + url );
        return;
    }

    loadData( &file );

    file.close();
}

void LabelPrinter::loadData( QFile* file, const QString & data ) {
    labelprinterdata* lpdata = PrinterSettings::getInstance()->getData();
    if( lpdata->separator.isEmpty() ) {
        KMessageBox::sorry( this, i18n("Separator is empty. Please set it to a value.") );
        return;
    }

    // new config entry!!!
    KConfig* config = kapp->config();
    config->setGroup("FileFormat");
    int pos[3] = { config->readNumEntry("Data0", 0 ),
                   config->readNumEntry("Data1", 1 ),
                   config->readNumEntry("Data2", 2 ) };

    bool custom_article_no = lpdata->useCustomNo;
    /*
     * read data here
     */
    QString s;
    QStringList dropped;
    QStringList datalist;

    if( !file ) {
        datalist = QStringList::split( "\n", data, false );
    }

    unsigned int i = 0;
    while( 1 ) {
        if( file ) {
            if( file->readLine( s, 1000 ) == -1 )
                break;
        } else {
            if( i >= datalist.count() )
                break;

            s = datalist[i];
            i++;
        }

        s = s.stripWhiteSpace();
        if(!lpdata->comment.isEmpty() && 
           s.left( lpdata->comment.length() ) == lpdata->comment   )
            /* Line is a comment */
            continue;

        if( s.isEmpty() )
            continue;

        QString data[3];
        data[0] = s.section(lpdata->separator, 0, 0 );
        data[1] = s.section(lpdata->separator, 1, 1 );
        data[2] = s.section(lpdata->separator, 2, 2 );

        QString article = "";
        QString quantity = "";
        QString group = "";

        if( pos[0] == 0 )
            quantity = data[0];
        else if( pos[0] == 1 )
            article = data[0];
        else
            group = data[0];

        if( pos[1] == 0 )
            quantity = data[1];
        else if( pos[1] == 1 )
            article = data[1];
        else
            group = data[1];

        if( pos[2] == 0 )
            quantity = data[2];
        else if( pos[2] == 1 )
            article = data[2];
        else
            group = data[2];

        // data[0] == quantity
        // data[1] == article_no
        // data[2] == group

        quantity = removeQuote( quantity, lpdata->quote );
        article = removeQuote( article, lpdata->quote );
        group = removeQuote( group, lpdata->quote );

        bool qint = false;
        (void)quantity.toInt( &qint );

        if( qint && custom_article_no ) {
            qint = false;
            QSqlQuery query("SELECT article_no FROM customer_text WHERE article_no_customer='" + article + "'" );
            while( query.next() ) {
                article = query.value( 0 ).toString();
                qint = true;
                break;
            }
        }

        if( qint ) // && existsArticle( article )
        {    
            if( !addItem( QString( article ), QString( group ), quantity.toInt(), false ) )
                dropped.append( quantity + lpdata->separator +  article + lpdata->separator + group );
        }
    }

    updateInfo();

    if( !dropped.isEmpty() )
#if QT_VERSION >= 0x030100
        KMessageBox::informationList( this, i18n("<qt>The following items can not be added:" )+ "</qt>", dropped );
#else
        KMessageBox::questionYesNoList( this, i18n("<qt>The following items can not be added:" )+ "</qt>", dropped );
#endif
}

void LabelPrinter::updateInfo() {
    labels = 0;
    int articles = 0;
    int groups = 0;
    int pages = 0;

    QStringList slist;
    QStringList glist;

    QListViewItem* item = list->firstChild();
    while( item ) {
        labels += item->text( 1 ).toInt();
        if( !glist.contains( item->text( 3 ) ) ) {
            glist.append( item->text( 3 ) );
            groups++;
        }

        if( !slist.contains( item->text( 2 ) ) ) {
            articles++;
            slist.append( item->text( 2 ) );
        }

        item = item->nextSibling();
    }

    // Calculate numer of pages
    // algorithm by Stonki!
    int num_h = 0;
    int num_v = 0;

    if( def ) {
        Measurements* m = def->getMeasurements();
        num_h = m->numH();
        num_v = m->numV();
    }

    int number_page = num_h * num_v;
    int fake = 0;

    if( number_page ) {
        pages = int((fake + labels) / number_page);
        if( (fake + labels) % number_page > 0 && labels)
            pages++;
    }

    info1->setText( QString(i18n("Labels to print: %1")).arg( labels ) );
    info2->setText( QString(i18n("Different articles: %1")).arg( articles ) );
    info3->setText( QString(i18n("Different groups: %1")).arg( groups ) );
    info4->setText( QString(i18n("Pages: %1")).arg( pages ) );
    if( !description.isEmpty() )
        info5->setText( i18n("Label description: ") + description );
    else
        info5->setText( "" );

    enableControls();
}

void LabelPrinter::changeDescription() {
    QFile f( urlrequester->url() );
    if ( !f.open( IO_ReadOnly ) )
        return;

    QDomDocument* doc = new QDomDocument( "KBarcodeLabel" );
    if ( !doc->setContent( &f ) ) {
        f.close();
        delete doc;
        return;
    }

    f.close();
    QDomNode n = doc->documentElement().firstChild();
    while( !n.isNull() ) {
        QDomElement e = n.toElement(); // try to convert the node to an element.
        if( !e.isNull() )
            if( e.tagName() == "label" ) {
                QDomNode node = e.firstChild();
                while( !node.isNull() ) {
                    QDomElement e = node.toElement(); // try to convert the node to an element.
                    if( !e.isNull() )
                        if( e.tagName() == "description" )
                            description = e.text();
                        else if( e.tagName() == "id" )
                            def = readDefinition( &e, this );

                    node = node.nextSibling();
                }
                n = n.nextSibling();
            }

        n = n.nextSibling();
    }

    delete doc;

    updateInfo();
}

void LabelPrinter::changeItem( QListViewItem* item, const QPoint &, int )
{
    if(!item)
        return;

    DSSmallDialogs::AddItemsDialog aid( item->text( 2 ), item->text( 3 ),
                                        item->text( 1 ).toInt(), this, "aid" );
    aid.setGroupCompletion( compGroup );

    if( aid.exec() == QDialog::Accepted ) {
        item->setText( 1, QString::number( aid.count() ) );
        item->setText( 2, aid.articleNo() );
        item->setText( 3, aid.groupName() );
        addGroupCompletion( aid.groupName() );
        updateInfo();
    }
}

void LabelPrinter::enableControls()
{
    bool e = (!urlrequester->url().isEmpty() && def && list->childCount() && def->getId() > -1 );

    buttonPrint->setEnabled( e );
    buttonImages->setEnabled( e );

    buttonRemove->setEnabled( list->childCount() );
    buttonRemoveAll->setEnabled(list->childCount() );
    buttonEdit->setEnabled( list->childCount() );
}

void LabelPrinter::images() {
    QString dirname = KFileDialog::getExistingDirectory ( QString::null, this, i18n("Select output directory") );
    if( dirname.isEmpty() )
        return;

    QBuffer* buffer = getBuffer();
    if( !buffer )
        return;

    BatchPrinter batch( dirname, this );
    batch.setBuffer( buffer );
    batch.setMove( 0 );
    batch.setSerial( serialStart->text(), serialInc->value() );
    batch.setName( urlrequester->url() );
    batch.setDefinition( def );
    batch.setCustomer( customerId->currentText() );

    fillWithData( &batch );

    batch.startImages();
    delete buffer;
    KMessageBox::information( this, i18n("Images creation finished.") );
}

Generated by  Doxygen 1.6.0   Back to index