diff options
Diffstat (limited to 'kbarcode/definition.cpp')
-rw-r--r-- | kbarcode/definition.cpp | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/kbarcode/definition.cpp b/kbarcode/definition.cpp new file mode 100644 index 0000000..675a36d --- /dev/null +++ b/kbarcode/definition.cpp @@ -0,0 +1,579 @@ +/*************************************************************************** + definition.cpp - description + ------------------- + begin : Mit Nov 20 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 "definition.h" +#include "sqltables.h" + +// Qt includes +#include <qtextstream.h> +#include <qsqlquery.h> +#include <qregexp.h> + +// KDE includes +#include <kapplication.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <qprogressdialog.h> + +// a simple helper function +// that copies a file +bool filecopy( const char* src, const char* dest ) +{ + FILE* s; + FILE* d; + int c; + + d = fopen(dest, "w"); + if( d == NULL ) + return false; + + s = fopen(src, "r"); + if( s == NULL ) { + fclose( d ); + remove( dest ); + return false; + } + + while(( c = getc( s )) != EOF ) + putc( c, d ); + + fclose( s ); + fclose( d ); + return true; +} + +class PrivateParser { + public: + PrivateParser( QString line, bool all = true ); + ~PrivateParser(); + + const QString & getId() const { return m_label_def_id; } + const QString & getProducer() const { return m_producer; } + const QString & getType() const { return m_type; } + const Measurements & getMeasurements() const { return m_measure; }; + + private: + QString removeQuote( const QString & q ); + + QString m_label_def_id; + QString m_producer; + QString m_type; + + Measurements m_measure; +}; + +PrivateParser::PrivateParser( QString line, bool all ) +{ + line = line.stripWhiteSpace(); + int pos = line.find("("); + line = line.mid( pos + 1, line.length() - pos - 1 ); + + m_label_def_id = line.section( ",", 0, 0 ).stripWhiteSpace(); + m_producer = removeQuote( line.section( ",", 1, 1 ) ); + m_type = removeQuote( line.section( ",", 2, 2 ) ); + + if( all ) { + m_measure.setGapTopMM( line.section( ",", 4, 4 ).toDouble() ); + m_measure.setGapLeftMM( line.section( ",", 5, 5 ).toDouble() ); + m_measure.setHeightMM( line.section( ",", 6, 6 ).toDouble() ); + m_measure.setWidthMM( line.section( ",", 7, 7 ).toDouble() ); + m_measure.setGapVMM( line.section( ",", 8, 8 ).toDouble() ); + m_measure.setGapHMM( line.section( ",", 9, 9 ).toDouble() ); + m_measure.setNumH( line.section( ",", 10, 10 ).toInt() ); + m_measure.setNumV( line.section( ",", 11, 11 ).toInt() ); + + // fix broken label definitions + // with numh and numv = 0 + if( !m_measure.numH() ) + m_measure.setNumH( 1 ); + + if( !m_measure.numV() ) + m_measure.setNumV( 1 ); + } +} + +PrivateParser::~PrivateParser() +{ } + +QString PrivateParser::removeQuote( const QString & q ) +{ + QString quote = q.stripWhiteSpace(); + + if( quote.startsWith("'") ) + quote = quote.mid( 1, quote.length() - 1 ); + + if( quote.endsWith("'") ) + quote = quote.left( quote.length() - 1 ); + + return quote; +} + + +/***************************************************************************/ + +Definition::Definition( QWidget* parent ) + : m_parent( parent ) +{ + id = -1; +} + +Definition::Definition( int label_def_id, QWidget* parent ) + : m_parent( parent ) +{ + init( QString("%1").arg( label_def_id ) ); +} + +Definition::Definition( const QString & label_def_id, QWidget* parent ) + : m_parent( parent ) +{ + init( label_def_id ); +} + +Definition::Definition( const QString & producer, const QString & type, QWidget* parent ) + : m_parent( parent ) +{ + if( SqlTables::isConnected() ) { + QSqlQuery query( + "select label_no from " TABLE_LABEL_DEF " WHERE manufacture='" + producer + "' AND type='" + type + "'"); + while( query.next() ) + init( query.value( 0 ).toString() ); + } else { + if(!openFile()) + return; + + initProgress(); + + QString s; + while( file->readLine( s, 1000 ) != -1 ) { + if( s.isEmpty() || s.left( 1 ) == "#" ) + continue; + + increaseProgress(); + + PrivateParser p( s ); + if( p.getProducer() ==producer && p.getType() == type ) { + init( p.getId() ); + break; + } + } + + destroyProgress(); + } + +} + +Definition::~Definition() +{ +} + +QFile* Definition::file = 0; +QByteArray* Definition::array = 0; +QStringList* Definition::listProducers = 0; +QMap<QString,QStringList> Definition::mapTypes; +QProgressDialog* Definition::m_progress = 0; + +void Definition::initProgress() +{ +/* + if(!m_progress) + m_progress = new QProgressDialog( i18n("Loading Label Definitions..."), QString::null, 0, NULL, "m_progress", true ); + + m_progress->setTotalSteps( 1000 ); + m_progress->show(); +*/ +// m_progress->reparent( m_parent, m_progress->pos(), true ); +} + +void Definition::increaseProgress() +{ +/* + if( m_progress ) + m_progress->setProgress( m_progress->progress() + 1 ); +*/ +} + +void Definition::destroyProgress() +{ +/* + if( m_progress ) + delete m_progress; + m_progress = NULL; +*/ +} + +void Definition::setId( const QString & label_def_id ) +{ + init( label_def_id ); +} + +void Definition::setId( int label_def_id ) +{ + init( QString("%1").arg( label_def_id ) ); +} + +void Definition::init( const QString & label_def_id ) +{ + if( SqlTables::isConnected() ) { + QSqlQuery* query = new QSqlQuery( + "select number_h, number_v, gap_left, gap_top, gap_v, gap_h, width, height, manufacture, type from " TABLE_LABEL_DEF + " WHERE label_no = " + label_def_id ); + + while( query->next() ) { + m_measure.setNumH( query->value( 0 ).toInt() ); + m_measure.setNumV( query->value( 1 ).toInt() ); + m_measure.setGapLeftMM( query->value( 2 ).toDouble() ); + m_measure.setGapTopMM( query->value( 3 ).toDouble() ); + m_measure.setGapVMM( query->value( 4 ).toDouble() ); + m_measure.setGapHMM( query->value( 5 ).toDouble() ); + m_measure.setWidthMM( query->value( 6 ).toDouble() ); + m_measure.setHeightMM( query->value( 7 ).toDouble() ); + producer = query->value( 8 ).toString(); + type = query->value( 9 ).toString(); + } + } else { + getFileMeasurements( label_def_id ); + } + + id = label_def_id.toInt(); + +} + +const Measurements & Definition::getMeasurements() const +{ + return m_measure; +} + +void Definition::getFileMeasurements( const QString & label_def_id ) +{ + if(!openFile()) { + m_measure = Measurements(); + return; + } + + initProgress(); + + QTextStream stream(*array, IO_ReadOnly ); + while( !stream.atEnd() ) { + QString s = stream.readLine(); + if( s.isEmpty() || s.startsWith( "#" ) ) + continue; + + increaseProgress(); + + PrivateParser p( s ); + if( p.getId() != label_def_id ) + continue; + + producer = p.getProducer(); + type = p.getType(); + m_measure = p.getMeasurements(); + break; + } + + destroyProgress(); +} + +bool Definition::openFile() +{ + if( file ) { + file->at( 0 ); + return true; + } + + QString f = locateLocal( "data", "kbarcode/labeldefinitions.sql" ); + if( !QFile::exists( f ) ) { + KConfig* config = kapp->config(); + config->setGroup( "Definitions" ); + + // copy file to new location + QString fname = config->readEntry( "defpath", locate( "data", "kbarcode/labeldefinitions.sql" ) ); + if( !QFile::exists( fname ) || fname.isEmpty() ) + return ( showFileError() ? openFile() : false ); + + if(!filecopy( (const char*)fname, (const char*)f )) + return ( showFileError() ? openFile() : false ); + } + + file = new QFile( f ); + if( !file->open( IO_ReadOnly ) ) { + delete file; + file = 0; + return ( showFileError() ? openFile() : false ); + } + + // keeping this array around + // increases speed quite a lot + // but does also cost lot's of memory + array = new QByteArray(); + *array = file->readAll(); + file->at( 0 ); + + return true; +} + +const QStringList Definition::getProducers() +{ + if( listProducers ) + return *listProducers; + + listProducers = new QStringList(); + + if( SqlTables::isConnected() ) { + QSqlQuery query("SELECT manufacture FROM " TABLE_LABEL_DEF " GROUP by manufacture;"); + while( query.next() ) + listProducers->append( query.value( 0 ).toString() ); + } else { + if(!openFile() ) + return *listProducers; + + initProgress(); + + QTextStream stream(*array, IO_ReadOnly ); + while( !stream.atEnd() ) { + QString s = stream.readLine(); + if( s.isEmpty() || s.startsWith( "#" ) ) + continue; + + increaseProgress(); + + PrivateParser p( s, false ); + if( !listProducers->contains( p.getProducer() ) ) + listProducers->append( p.getProducer() ); + } + + destroyProgress(); + } + + return *listProducers; +} + +const QStringList Definition::getTypes( QString producer ) +{ + if( mapTypes.contains( producer ) ) { + return mapTypes[producer]; + } + + QStringList list; + + if( SqlTables::isConnected() ) { + QSqlQuery query("SELECT type FROM " TABLE_LABEL_DEF " WHERE manufacture='" + producer + "'" ); + while( query.next() ) + if( !list.contains( query.value( 0 ).toString() ) ) + list.append( query.value( 0 ).toString() ); + } else { + if(!openFile()) + return list; + + initProgress(); + + QTextStream stream(*array, IO_ReadOnly ); + while( !stream.atEnd() ) { + QString s = stream.readLine(); + if( s.isEmpty() || s.startsWith( "#" ) ) + continue; + + increaseProgress(); + + PrivateParser p( s, false ); + if( p.getProducer() == producer ) + if( !list.contains( p.getType() ) ) + list.append( p.getType() ); + } + + destroyProgress(); + } + + mapTypes.insert( producer, list ); + + return list; +} + +void Definition::updateProducer() +{ + // TODO: check wether this function is + // correct! w/ SQL and without + if( listProducers ) { + delete listProducers; + listProducers = 0; + + if( array ) { + delete array; + array = 0; + } + + if( file ) { + file->close(); + delete file; + file = 0; + } + mapTypes.clear(); + } +} + +int Definition::write( const Measurements & c, QString type, QString producer ) +{ + int r = -1; + if( SqlTables::isConnected() ) + r = Definition::writeSQL( c, type, producer ); + else + r = Definition::writeFile( c, type, producer ); + + Definition::updateProducer(); + return r; +} + +int Definition::writeFile( const Measurements & c, QString type, QString producer ) +{ + if( !openFile() ) + return -1; + + QStringList data; + bool datawritten = false; + int index = 0; + QString entry = ", '" + + producer + "', '" + type + "', 'C',"+ I2S(c.gapTopMM()) + + ", " + I2S(c.gapLeftMM()) + ", " + + I2S(c.heightMM()) + ", " + I2S(c.widthMM()) + ", " + + I2S(c.gapVMM()) + ", " + I2S(c.gapHMM()) + ", " + + I2S(c.numH()) + ", " + I2S(c.numV()) + ", NULL, NULL )"; + + QString s; + while( file->readLine( s, 1000 ) != -1 ) { + if( s.isEmpty() || s.left( 1 ) == "#" ) { + data.append( s ); + continue; + } + + PrivateParser p( s ); + if( p.getId().toInt() > index ) + index = p.getId().toInt(); + + if( p.getType() == type && p.getProducer() == producer ) { + // update an item already present in the list + entry = entry.prepend( "INSERT INTO " TABLE_LABEL_DEF " VALUES (" + I2S(p.getId().toInt()) ); + data.append( entry ); + datawritten = true; + } else + data.append( s ); + } + + if( !datawritten ) { + entry = entry.prepend( "INSERT INTO " TABLE_LABEL_DEF " VALUES (" + I2S(index+1) ); + data.append( entry ); + } + + file->close(); + if( !file->open( IO_WriteOnly ) ) { + file->open( IO_ReadOnly ); + return -1; + } + + QTextStream t( file ); + for( unsigned int i = 0; i < data.count(); i++ ) + t << data[i].replace( QRegExp("\\n"), "" ) << "\n"; + + // get the file back to the normal stage + file->close(); + file->open( IO_ReadOnly ); + + return index + 1; +} + +int Definition::writeSQL( const Measurements & c, QString type, QString producer ) +{ + bool newitem = true; + QSqlQuery q( "SELECT manufacture, type FROM " TABLE_LABEL_DEF ); + // TODO: use a more inteligent query using where= + while( q.next() ) + if( q.value( 0 ) == producer && + q.value( 1 ) == type ) + newitem = false; + + if( newitem ) { + QSqlQuery query( + "INSERT INTO " TABLE_LABEL_DEF " (manufacture, type, gap_top, gap_left, " + "width, height, gap_v, gap_h, number_h, number_v) VALUES ('" + + producer + "', '" + type + "', '"+ I2S( c.gapTopMM() ) + + "', '" + I2S( c.gapLeftMM() ) + "', '" + + I2S( c.widthMM() ) + "', '" + I2S( c.heightMM() ) + "', '" + + I2S( c.gapVMM() ) + "', '" + I2S( c.gapHMM() ) + "', '" + + I2S( c.numH() ) + "', '" + I2S( c.numV() ) + "')" + ); + + if(!query.isValid()) + qDebug("Query to insert values not valid!"); + } else { + QSqlQuery query( "UPDATE " TABLE_LABEL_DEF " SET " + "gap_top = " + I2S( c.gapTopMM() ) + " ,gap_left = " + I2S( c.gapLeftMM() ) + + " ,width = " + I2S( c.widthMM() ) + " ,height = " + I2S( c.heightMM() ) + + " ,gap_v = " + I2S( c.gapVMM() ) + " ,gap_h = " + I2S( c.gapHMM() ) + + " ,number_h = " + I2S( c.numH() ) + " ,number_v = " + I2S( c.numV() ) + + " WHERE manufacture = '" + producer + "' AND" + " type = '" + type + "'" ); + + if(!query.isValid()) + qDebug("Query to update values not valid!\n%s\n", query.lastQuery().latin1() ); + } + + QSqlQuery qi("SELECT label_no FROM " TABLE_LABEL_DEF " WHERE manufacture='" + producer + "' AND type='" + type + "'" ); + while( qi.next() ) + return qi.value( 0 ).toInt(); + + return -1; +} + + +bool Definition::nodefmsg = true; +bool Definition::showFileError() +{ + if( nodefmsg ) { + KMessageBox::information( 0, + i18n("KBarcode is unable to find its label definitions." + "Please make sure that the file $KDEDIR/share/apps/kbarcode/labeldefinitions.sql " + "does exist. This file is part of the KBarcode distribution. " + "You will be prompted now to select the file containing the labeldefinitions."), + "", "NoDefinitionsFound" ); + + QString f = KFileDialog::getOpenFileName( QString::null, QString::null, 0 ); + if( !f.isEmpty() && QFile::exists( f ) ) { + KConfig* config = kapp->config(); + config->setGroup( "Definitions" ); + config->writeEntry( "defpath", f ); + config->sync(); + } + nodefmsg = false; + return openFile(); + } else + qDebug("No label definitions found. Please install them."); + + return false; +} + +int Definition::getClosest( const QString & producer, const QString & type ) +{ + QStringList t = Definition::getTypes(producer); + for( unsigned int z = 0; z < t.count(); z++ ) { + if( t[z] == type ) { + Definition d( producer, type ); + return d.getId(); + } + } + + return -1; +} |