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.
kbarcode/kbarcode/xmlutils.cpp

490 lines
18 KiB

/***************************************************************************
xmlutils.cpp - description
-------------------
begin : Mit Mai 7 2003
copyright : (C) 2003 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 "xmlutils.h"
#include "definition.h"
#include "mycanvasview.h"
#include "mycanvasitem.h"
#include "labelutils.h"
#include "measurements.h"
#include "barcodeitem.h"
#include "rectitem.h"
#include "imageitem.h"
#include "lineitem.h"
#include "textitem.h"
#include "textlineitem.h"
// TQt includes
#include <tqdom.h>
// KDE includes
#include <tdeapplication.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
XMLUtils::XMLUtils()
{
// read barcodes saved by kbarcode < 1.3.0
if( !legacy.count() )
{
legacy.insert( "0", "any" );
legacy.insert( "1", "ean" );
legacy.insert( "2", "upc" );
legacy.insert( "3", "isbn" );
legacy.insert( "4", "code39" );
legacy.insert( "5", "code128" );
legacy.insert( "6", "code128c" );
legacy.insert( "7", "code128b" );
legacy.insert( "8", "i25" );
legacy.insert( "9", "i28raw" );
legacy.insert( "10", "cbr" );
legacy.insert( "11", "msi" );
legacy.insert( "12", "pls" );
legacy.insert( "13", "code93" );
legacy.insert( "14", "msi" );
legacy.insert( "15", "code39 -c" );
legacy.insert( "16", "i25 -c" );
}
}
XMLUtils::~XMLUtils()
{
}
TQMap<TQString,TQString> XMLUtils::legacy;
void XMLUtils::readXMLHeader( TQDomDocument* doc, TQString & description, bool & kbarcode18, Definition** def )
{
TQDomNode n = doc->documentElement().firstChild();
// this should not be neccessary,
// but <label><id> needs to be processed first
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() )
// label has to be the first xml element!
if( e.tagName() == "label" ) {
kbarcode18 = (e.attribute( "fileformat-version", "1" ).toInt() == 1);
TQDomNode n = e.firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() )
if( e.tagName() == "description" )
description = e.text();
else if( e.tagName() == "id" ) {
if( *def )
delete *def;
*def = readDefinition( &e );
}
n = n.nextSibling();
}
}
n = n.nextSibling();
}
}
void XMLUtils::writeXMLHeader( TQDomNode* root, const TQString & description, Definition* def )
{
TQDomElement data = root->ownerDocument().createElement( "label" );
/** kbarcode <= 1.8.x = fileformat-version = 1 */
/** kbarcode >= 1.9.0 = fileformat-version = 2 */
data.setAttribute( "fileformat-version", "2" );
if( !description.isEmpty() ) {
TQDomElement labeldescription = root->ownerDocument().createElement( "description" );
labeldescription.appendChild( root->ownerDocument().createTextNode( description ) );
data.appendChild( labeldescription );
}
TQDomElement labelid = root->ownerDocument().createElement( "id" );
writeDefinition( &labelid, def );
labelid.appendChild( root->ownerDocument().createTextNode( TQString( "%1" ).arg(def->getId()) ) );
data.appendChild( labelid );
root->appendChild( data );
}
void XMLUtils::readDocumentItems( DocumentItemList* list, TQDomDocument* doc, TokenProvider* token, bool kbarcode18 )
{
TQDomNode n = doc->documentElement().firstChild();
list->setAutoDelete( false );
if( kbarcode18 )
{
// legacy loading
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() )
if( e.tagName() == "barcode" ) {
BarcodeItem* bcode = new BarcodeItem();
((DocumentItem*)bcode)->setTokenProvider( token );
readBarcode( &e, bcode );
bcode->updateBarcode();
bcode->setZ( e.attribute( "z", "0" ).toInt() );
list->append( bcode );
} else if( e.tagName() == "textfield" ) {
TextItem* t = new TextItem();
t->setTokenProvider( token );
TQRect r = readXMLRect( &e );
t->setBoundingRect( r );
t->setZ( e.attribute( "z", "0" ).toInt() );
TQDomNode n = e.firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() )
if( e.tagName() == "text" )
{
t->setText( e.text() );
break;
}
n = n.nextSibling();
}
list->append( t );
} else if( e.tagName() == "picture" ) {
ImageItem* r = new ImageItem();
TQRect rect = readXMLRect( &e );
r->setBoundingRect( rect );
TQPixmap pix;
pix.loadFromData( e.text().utf8(), "XPM" );
r->setPixmap( pix );
r->setRotation( e.attribute("rotation", "0.0" ).toDouble() );
r->setZ( e.attribute( "z", "0" ).toInt() );
list->append( r );
} else if( e.tagName() == "rect" ) {
RectItem* r = new RectItem();
TQRect rect = readXMLRect( &e );
r->setBoundingRect( rect );
r->setZ( e.attribute( "z", "0" ).toInt() );
r->setCircle( e.attribute( "circle", "0" ).toInt() );
r->setPen( TQPen(readXMLColor( &e, "bordercolor", TQt::black ),e.attribute( "borderwidth", "1" ).toInt(),(TQt::PenStyle)e.attribute( "borderstyle", "1" ).toInt() ));
r->setColor( readXMLColor( &e, "color", TQt::black ) );
list->append( r );
} else if( e.tagName() == "line" ) {
#warning "TODO: test legacy loading of lines"
LineItem* cl = new LineItem();
int x = e.attribute( "x1", "0" ).toInt();
int y = e.attribute( "y1", "0" ).toInt();
cl->setBoundingRect( TQRect( x, y, e.attribute( "x2", "0" ).toInt(), e.attribute( "y2", "0" ).toInt() ) );
cl->setZ( e.attribute( "z", "0" ).toInt() );
cl->setPen( TQPen( readXMLColor( &e, "color", TQt::black ),
e.attribute( "width", "0" ).toInt(), (TQPen::PenStyle)e.attribute( "style", "0" ).toInt() ) );
list->append( cl );
}
n = n.nextSibling();
}
}
else
{
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() )
{
DocumentItem* item = NULL;
if( readXMLDocumentItem( &e, &item, token ) )
list->append( item );
}
n = n.nextSibling();
}
}
}
void XMLUtils::writeXMLDocumentItem( TQDomElement* root, DocumentItem** item )
{
if( !item )
return;
TQDomElement tag;
if( (*item)->rtti() == eRtti_Barcode )
tag = root->ownerDocument().createElement( "barcode" );
else if( (*item)->rtti() == eRtti_Image )
tag = root->ownerDocument().createElement( "picture" );
else if( (*item)->rtti() == eRtti_Text )
tag = root->ownerDocument().createElement( "textfield" );
else if( (*item)->rtti() == eRtti_Rect )
tag = root->ownerDocument().createElement( "rect" );
else if( (*item)->rtti() == eRtti_Line )
tag = root->ownerDocument().createElement( "line" );
//NY32
else if( (*item)->rtti() == eRtti_TextLine )
tag = root->ownerDocument().createElement( "textlinefield" );
//NY32
if( !tag.isNull() )
{
(*item)->saveXML( &tag );
root->appendChild( tag );
}
}
bool XMLUtils::readXMLDocumentItem( TQDomElement* tag, DocumentItem** item, TokenProvider* token )
{
if( !item )
return false;
if( tag->tagName() == "barcode" )
*item = new BarcodeItem();
else if( tag->tagName() == "textfield" )
*item = new TextItem();
else if( tag->tagName() == "picture" )
*item = new ImageItem();
else if( tag->tagName() == "rect" )
*item = new RectItem();
else if( tag->tagName() == "line" )
*item = new LineItem();
else if( tag->tagName() == "textlinefield" )
*item = new TextLineItem();
else
return false;
(*item)->setTokenProvider( token );
(*item)->loadXML( tag );
return true;
}
void XMLUtils::writeXMLColor( TQDomElement* tag, const TQString & prefix, TQColor c ) const
{
tag->setAttribute( prefix + "r", c.red() );
tag->setAttribute( prefix + "g", c.green() );
tag->setAttribute( prefix + "b", c.blue() );
}
TQColor XMLUtils::readXMLColor( TQDomElement* tag, const TQString & prefix, TQColor c )
{
int r = c.red();
int g = c.green();
int b = c.blue();
r = tag->attribute( prefix + "r", TQString("%1").arg( r ) ).toInt();
g = tag->attribute( prefix + "g", TQString("%1").arg( g ) ).toInt();
b = tag->attribute( prefix + "b", TQString("%1").arg( b ) ).toInt();
return TQColor( r, g, b);
}
/*
void XMLUtils::writeXMLRect( TQDomElement* tag, TQRect r, TQPoint ptOrigin ) const
{
r.moveBy( -ptOrigin.x(), -ptOrigin.y() );
tag->setAttribute( "x", r.x() );
tag->setAttribute( "y", r.y() );
tag->setAttribute( "width", r.width() );
tag->setAttribute( "height", r.height() );
LabelUtils l;
tag->setAttribute( "x_mm", l.pixelToMm( r.x(), TDEApplication::desktop(), LabelUtils::DpiX ) );
tag->setAttribute( "y_mm", l.pixelToMm( r.y(), TDEApplication::desktop(), LabelUtils::DpiY ) );
tag->setAttribute( "width_mm", l.pixelToMm( r.width(), TDEApplication::desktop(), LabelUtils::DpiX ) );
tag->setAttribute( "height_mm", l.pixelToMm( r.height(), TDEApplication::desktop(), LabelUtils::DpiY ) );
}*/
TQRect XMLUtils::readXMLRect( TQDomElement* tag )
{
TQRect r;
int x = tag->attribute( "x", "0" ).toInt();
int y = tag->attribute( "y", "0" ).toInt();
r.setX( x );
r.setY( y );
r.setWidth( tag->attribute( "width", "-1" ).toInt() );
r.setHeight( tag->attribute( "height", "-1" ).toInt() );
return r;
}
void XMLUtils::writeDefinition( TQDomElement* tag, Definition* d ) const
{
tag->setAttribute("producer", d->getProducer());
tag->setAttribute("type", d->getType());
tag->setAttribute("width", d->getMeasurements().widthMM());
tag->setAttribute("height", d->getMeasurements().heightMM());
tag->setAttribute("gap_left", d->getMeasurements().gapLeftMM());
tag->setAttribute("gap_top", d->getMeasurements().gapTopMM());
tag->setAttribute("gap_v", d->getMeasurements().gapVMM());
tag->setAttribute("gap_h", d->getMeasurements().gapHMM());
tag->setAttribute("num_v", d->getMeasurements().numV());
tag->setAttribute("num_h", d->getMeasurements().numH());
}
Definition* XMLUtils::readDefinition( TQDomElement* tag )
{
int label_def_id = tag->text().toInt();
TQString producer = tag->attribute("producer", "" );
TQString type = tag->attribute("type", "" );
// The label was written by KBarcode <= 1.2.0
Definition* d = new Definition( label_def_id );
if( type.isEmpty() && producer.isEmpty() ) {
KMessageBox::information( NULL,
i18n("<qt>This appears file appears to be created by an older version of KBarcode.<br>"
"Please check if the used label definition is correct:<br>"
"<b>") + d->getProducer() + " " + d->getType() + "</b><br>"
"You can change the label definition at <i>Edit->Change Label...</i></qt>");
return d;
}
if( d->getType() == type && d->getProducer() == producer && !type.isEmpty() && !producer.isEmpty() )
return d;
// The id does not match the correct type and producer,
// try to find the correct one
if( (d->getType() != type || d->getProducer() != producer) &&
!(type.isEmpty() && producer.isEmpty() ) ) {
int id = label_def_id;
TQStringList p = Definition::getProducers();
if( !p.contains( producer ) ) {
for( unsigned int i = 0; i < p.count(); i++ ) {
id = Definition::getClosest( p[i], type );
if( id >= 0 )
break;
}
} else
id = Definition::getClosest( producer, type );
if( id != label_def_id && id >= 0 ) {
d->setId( id );
return d;
}
}
// Everything failed
// Read the measurements from the file
Measurements m;
m.setWidthMM( tag->attribute("width", I2S( m.widthMM() ) ).toDouble() );
m.setHeightMM( tag->attribute("height", I2S( m.heightMM() )).toDouble() );
m.setGapLeftMM( tag->attribute("gap_left", I2S( m.gapLeftMM() )).toDouble() );
m.setGapTopMM( tag->attribute("gap_top", I2S( m.gapTopMM() )).toDouble() );
m.setGapVMM( tag->attribute("gap_v", I2S( m.gapVMM() )).toDouble() );
m.setGapHMM( tag->attribute("gap_h", I2S( m.gapHMM() )).toDouble() );
m.setNumV( tag->attribute("num_v", I2S( m.numH() )).toInt() );
m.setNumH( tag->attribute("num_h", I2S( m.numV() )).toInt() );
tqDebug("Definition not found: writing to file!");
d->setId( Definition::write( m, type, producer ) );
return d;
}
void XMLUtils::writeBarcode( TQDomElement* tag, const Barkode* data, bool cache ) const
{
if( !cache ) {
/*
* This values are not needed for the barcode cache.
*/
tag->setAttribute( "margin", data->quietZone() );
tag->setAttribute( "rotation", data->rotation() );
tag->setAttribute( "cut", data->cut() );
tag->setAttribute( "caption", data->databaseMode() );
/*
* This values are only needed for !cache and for sequences
*/
tag->setAttribute( "sequenceenabled", data->sequenceEnabled() );
/*
if( data->sequenceEnabled() ) {
tag->setAttribute( "sequencemode", data->sequence.mode );
tag->setAttribute( "sequencestep", data->sequence.step );
tag->setAttribute( "sequencestart", data->sequence.start );
}
*/
}
tag->setAttribute( "type", data->type() );
tag->setAttribute( "text", data->textVisible() );
tag->setAttribute( "scale", data->scaling()*1000 );
/*
if( BarCode::hasFeature( data->type, PDF417BARCODE ) ) {
tag->setAttribute( "pdf417.row", data->pdf417.row );
tag->setAttribute( "pdf417.col", data->pdf417.col );
tag->setAttribute( "pdf417.err", data->pdf417.err );
}
if( BarCode::hasFeature( data->type, DATAMATRIX ) )
tag->setAttribute( "datamatrix.size", data->datamatrix.size );
if( BarCode::hasFeature( data->type, TBARCODE ) ) {
tag->setAttribute( "tbarcode.modulewidth", data->tbarcode.modulewidth );
tag->setAttribute( "tbarcode.escape", data->tbarcode.escape );
tag->setAttribute( "tbarcode.above", data->tbarcode.above );
tag->setAttribute( "tbarcode.autocorrect", data->tbarcode.autocorrect );
tag->setAttribute( "tbarcode.checksum", data->tbarcode.checksum );
}
*/
TQDomElement texttag = tag->ownerDocument().createElement( "value" );
texttag.appendChild( tag->ownerDocument().createTextNode( data->value() ) );
tag->appendChild( texttag );
}
void XMLUtils::readBarcode( TQDomElement* tag, Barkode* bcode )
{
if( tag->tagName() == "barcode" ) {
bcode->setQuietZone( tag->attribute("margin", "10" ).toInt() );
bcode->setRotation( tag->attribute("rotation", "0" ).toInt() );
bcode->setScaling( tag->attribute("scale", "1000" ).toDouble() / 1000 );
bcode->setCut( tag->attribute("cut", "1.0" ).toDouble() );
bcode->setType( tag->attribute("type", "code39" ) );
/*
* check for encoding types saved by kbarcode <= 1.2.0
*/
if( legacy.contains( bcode->type() ) )
bcode->setType( legacy[bcode->type()] );
bcode->setTextVisible( tag->attribute("text", "0" ).toInt() );
bcode->setDatabaseMode( tag->attribute("caption", "static" ) );
if( bcode->engine()->options() )
bcode->engine()->options()->load( tag );
bcode->setDatamatrixSize( tag->attribute( "datamatrix.size", "0" ).toInt() );
bcode->setSequenceEnabled( tag->attribute( "sequenceenabled", "0" ).toInt() );
if( bcode->sequenceEnabled() )
{
bcode->setSequenceMode( (ESequence)tag->attribute( "sequencemode", "0" ).toInt() );
bcode->setSequenceStep( tag->attribute( "sequencestep", "1" ).toInt() );
bcode->setSequenceStart( tag->attribute( "sequencestart", "0" ).toInt() );
}
TQDomNode n = tag->firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() )
if( e.tagName() == "value" )
bcode->setValue( e.text() );
n = n.nextSibling();
}
}
}