You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
580 lines
16 KiB
580 lines
16 KiB
/***************************************************************************
|
|
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"
|
|
|
|
// TQt includes
|
|
#include <tqtextstream.h>
|
|
#include <tqsqlquery.h>
|
|
#include <tqregexp.h>
|
|
|
|
// KDE includes
|
|
#include <tdeapplication.h>
|
|
#include <tdefiledialog.h>
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kstandarddirs.h>
|
|
#include <tqprogressdialog.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( TQString line, bool all = true );
|
|
~PrivateParser();
|
|
|
|
const TQString & getId() const { return m_label_def_id; }
|
|
const TQString & getProducer() const { return m_producer; }
|
|
const TQString & getType() const { return m_type; }
|
|
const Measurements & getMeasurements() const { return m_measure; };
|
|
|
|
private:
|
|
TQString removeQuote( const TQString & q );
|
|
|
|
TQString m_label_def_id;
|
|
TQString m_producer;
|
|
TQString m_type;
|
|
|
|
Measurements m_measure;
|
|
};
|
|
|
|
PrivateParser::PrivateParser( TQString line, bool all )
|
|
{
|
|
line = line.stripWhiteSpace();
|
|
int pos = line.find("(");
|
|
line = line.mid( pos + 1, line.length() - pos - 1 );
|
|
|
|
m_label_def_id = TQString(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()
|
|
{ }
|
|
|
|
TQString PrivateParser::removeQuote( const TQString & q )
|
|
{
|
|
TQString 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( TQWidget* parent )
|
|
: m_parent( parent )
|
|
{
|
|
id = -1;
|
|
}
|
|
|
|
Definition::Definition( int label_def_id, TQWidget* parent )
|
|
: m_parent( parent )
|
|
{
|
|
init( TQString("%1").arg( label_def_id ) );
|
|
}
|
|
|
|
Definition::Definition( const TQString & label_def_id, TQWidget* parent )
|
|
: m_parent( parent )
|
|
{
|
|
init( label_def_id );
|
|
}
|
|
|
|
Definition::Definition( const TQString & producer, const TQString & type, TQWidget* parent )
|
|
: m_parent( parent )
|
|
{
|
|
if( SqlTables::isConnected() ) {
|
|
TQSqlQuery 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();
|
|
|
|
TQString 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()
|
|
{
|
|
}
|
|
|
|
TQFile* Definition::file = 0;
|
|
TQByteArray* Definition::array = 0;
|
|
TQStringList* Definition::listProducers = 0;
|
|
TQMap<TQString,TQStringList> Definition::mapTypes;
|
|
TQProgressDialog* Definition::m_progress = 0;
|
|
|
|
void Definition::initProgress()
|
|
{
|
|
/*
|
|
if(!m_progress)
|
|
m_progress = new TQProgressDialog( i18n("Loading Label Definitions..."), TQString(), 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 TQString & label_def_id )
|
|
{
|
|
init( label_def_id );
|
|
}
|
|
|
|
void Definition::setId( int label_def_id )
|
|
{
|
|
init( TQString("%1").arg( label_def_id ) );
|
|
}
|
|
|
|
void Definition::init( const TQString & label_def_id )
|
|
{
|
|
if( SqlTables::isConnected() ) {
|
|
TQSqlQuery* query = new TQSqlQuery(
|
|
"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 TQString & label_def_id )
|
|
{
|
|
if(!openFile()) {
|
|
m_measure = Measurements();
|
|
return;
|
|
}
|
|
|
|
initProgress();
|
|
|
|
TQTextStream stream(*array, IO_ReadOnly );
|
|
while( !stream.atEnd() ) {
|
|
TQString 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;
|
|
}
|
|
|
|
TQString f = locateLocal( "data", "kbarcode/labeldefinitions.sql" );
|
|
if( !TQFile::exists( f ) ) {
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup( "Definitions" );
|
|
|
|
// copy file to new location
|
|
TQString fname = config->readEntry( "defpath", locate( "data", "kbarcode/labeldefinitions.sql" ) );
|
|
if( !TQFile::exists( fname ) || fname.isEmpty() )
|
|
return ( showFileError() ? openFile() : false );
|
|
|
|
if(!filecopy( fname.local8Bit(), f.local8Bit() ))
|
|
return ( showFileError() ? openFile() : false );
|
|
}
|
|
|
|
file = new TQFile( 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 TQByteArray();
|
|
*array = file->readAll();
|
|
file->at( 0 );
|
|
|
|
return true;
|
|
}
|
|
|
|
const TQStringList Definition::getProducers()
|
|
{
|
|
if( listProducers )
|
|
return *listProducers;
|
|
|
|
listProducers = new TQStringList();
|
|
|
|
if( SqlTables::isConnected() ) {
|
|
TQSqlQuery 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();
|
|
|
|
TQTextStream stream(*array, IO_ReadOnly );
|
|
while( !stream.atEnd() ) {
|
|
TQString 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 TQStringList Definition::getTypes( TQString producer )
|
|
{
|
|
if( mapTypes.contains( producer ) ) {
|
|
return mapTypes[producer];
|
|
}
|
|
|
|
TQStringList list;
|
|
|
|
if( SqlTables::isConnected() ) {
|
|
TQSqlQuery 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();
|
|
|
|
TQTextStream stream(*array, IO_ReadOnly );
|
|
while( !stream.atEnd() ) {
|
|
TQString 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, TQString type, TQString 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, TQString type, TQString producer )
|
|
{
|
|
if( !openFile() )
|
|
return -1;
|
|
|
|
TQStringList data;
|
|
bool datawritten = false;
|
|
int index = 0;
|
|
TQString 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 )";
|
|
|
|
TQString 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;
|
|
}
|
|
|
|
TQTextStream t( file );
|
|
for( unsigned int i = 0; i < data.count(); i++ )
|
|
t << data[i].replace( TQRegExp("\\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, TQString type, TQString producer )
|
|
{
|
|
bool newitem = true;
|
|
TQSqlQuery 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 ) {
|
|
TQSqlQuery 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())
|
|
tqDebug("Query to insert values not valid!");
|
|
} else {
|
|
TQSqlQuery 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())
|
|
tqDebug("Query to update values not valid!\n%s\n", query.lastQuery().latin1() );
|
|
}
|
|
|
|
TQSqlQuery 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 $TDEDIR/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" );
|
|
|
|
TQString f = KFileDialog::getOpenFileName( TQString(), TQString(), 0 );
|
|
if( !f.isEmpty() && TQFile::exists( f ) ) {
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup( "Definitions" );
|
|
config->writeEntry( "defpath", f );
|
|
config->sync();
|
|
}
|
|
nodefmsg = false;
|
|
return openFile();
|
|
} else
|
|
tqDebug("No label definitions found. Please install them.");
|
|
|
|
return false;
|
|
}
|
|
|
|
int Definition::getClosest( const TQString & producer, const TQString & type )
|
|
{
|
|
TQStringList 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;
|
|
}
|