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/batchprinter.cpp

543 lines
15 KiB

/***************************************************************************
batchprinter.cpp - description
-------------------
begin : Sat Jan 10 2004
copyright : (C) 2004 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 "batchprinter.h"
#include "definition.h"
#include "kbarcode.h"
#include "label.h"
#include "printersettings.h"
#include "zplutils.h"
#include "tec.h"
// TQt includes
#include <tqfile.h>
#include <tqpainter.h>
#include <tqpaintdevicemetrics.h>
#include <tqprogressdialog.h>
// KDE includes
#include <kabc/addressee.h>
#include <kabc/addresseelist.h>
#include <kapplication.h>
#include <tdeconfig.h>
#include <kimageio.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kprinter.h>
// Other includes
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <krun.h>
#define MAXDATASIZE 32550
BatchPrinter::BatchPrinter( KPrinter* p, TQWidget* _parent )
: printer( p ), parent( _parent )
{
m_events = true;
m_data = NULL;
m_vardata = NULL;
m_addrdata = NULL;
m_cur_data_count = 0;
m_paintDevice = p;
}
BatchPrinter::BatchPrinter( const TQString & path, TQWidget* p )
: m_path( path ), parent( p )
{
m_data = NULL;
m_vardata = NULL;
m_addrdata = NULL;
m_move = 0;
m_image_filename = E_BARCODE;
m_cur_data_count = 0;
m_paintDevice = TQT_TQPAINTDEVICE(p);
}
BatchPrinter::BatchPrinter( const TQString & path, int format, TQWidget* _parent )
: m_path( path ), m_bcp_format( format ), parent( _parent )
{
m_data = NULL;
m_vardata = NULL;
m_addrdata = NULL;
m_move = 0;
m_image_filename = E_BARCODE;
m_cur_data_count = 0;
m_paintDevice = TQT_TQPAINTDEVICE(_parent);
}
BatchPrinter::~BatchPrinter()
{
delete m_data;
delete m_vardata;
delete m_addrdata;
}
void BatchPrinter::start()
{
painter = new TQPainter( printer );
m_cur_data_count = 0;
TQPaintDeviceMetrics pdm( painter->device() );
pageh = pdm.height(); // in pixel
curw = 0;
curh = 0;
c_h = 0;
c_w = 0;
TQProgressDialog* progress = createProgressDialog( i18n("Printing...") );
m_measure = def->getMeasurements();
moveLabels();
if( m_data )
startPrintData( progress );
else if( m_vardata || m_addrdata )
startPrintVarData( progress );
painter->end();
delete progress;
delete painter;
}
void BatchPrinter::startPrintData( TQProgressDialog* progress )
{
labelprinterdata* lpdata = PrinterSettings::getInstance()->getData();
unsigned int index = 0; // counter gets increased for every label, but not for
// labels like article_no etc. (those who are created
// by events.
for( unsigned int i = 0; i < m_data->count(); i++ )
{
Label l( def, TQT_TQIODEVICE(buffer), m_name, printer, m_customer,
(*m_data)[i].article_no, (*m_data)[i].group );
l.setSerial( m_serial, m_increment );
bool newgroup = false;
if( i == 0 )
newgroup = true;
else {
if( (*m_data)[i].group != (*m_data)[i-1].group )
newgroup = true;
}
if( !curw )
curw = m_measure.gapLeft( printer );
if( !curh )
curh = m_measure.gapTop( printer );
if( m_events ) {
if( newgroup ) {
proccessEvents( lpdata->groupEvent1, i18n("Group : ") + (*m_data)[i].group, &l );
proccessEvents( lpdata->groupEvent2, i18n("Group : ") + (*m_data)[i].group, &l );
proccessEvents( lpdata->groupEvent3, i18n("Group : ") + (*m_data)[i].group, &l );
proccessEvents( lpdata->groupEvent4, i18n("Group : ") + (*m_data)[i].group, &l );
}
proccessEvents( lpdata->articleEvent1, i18n("Article No. : ") + (*m_data)[i].article_no, &l );
proccessEvents( lpdata->articleEvent2, i18n("Article No. : ") + (*m_data)[i].article_no, &l );
proccessEvents( lpdata->articleEvent3, i18n("Article No. : ") + (*m_data)[i].article_no, &l );
proccessEvents( lpdata->articleEvent4, i18n("Article No. : ") + (*m_data)[i].article_no, &l );
}
for( int z = 0; z < (*m_data)[i].number; z++ ) {
changeLine();
checkForNewPage( &l );
painter->setClipRect((int)curw, (int)curh, (int)m_measure.width( printer ), (int)m_measure.height( printer ));
l.setIndex( index );
l.setRow( c_w );
l.setCol( c_h );
painter->save();
l.draw( painter, (int)curw, (int)curh );
painter->restore();
//painter->drawPicture( (int)curw, (int)curh, *l.picture() );
index++;
painter->setClipping( false );
drawBorders();
curw += m_measure.gapH( printer );
c_h++;
if( !checkProgressDialog( progress) ) {
printer->abort();
painter->end();
return;
}
}
}
}
void BatchPrinter::startPrintVarData( TQProgressDialog* progress )
{
Label* l;
while( ( l = initLabel() ) != NULL )
{
if( !curw )
curw = m_measure.gapLeft( printer );
if( !curh )
curh = m_measure.gapTop( printer );
changeLine();
checkForNewPage( l );
painter->setClipRect((int)curw, (int)curh, (int)m_measure.width( printer ), (int)m_measure.height( printer ));
painter->save();
l->draw( painter, (int)curw, (int)curh );
delete l;
painter->restore();
painter->setClipping( false );
drawBorders();
curw += m_measure.gapH( printer );
c_h++;
if( !checkProgressDialog( progress) )
{
printer->abort();
painter->end();
return;
}
}
}
Label* BatchPrinter::initLabel( int* number )
{
Label* l = NULL;
if( (m_vardata && m_cur_data_count >= m_vardata->count() ) ||
(m_data && m_cur_data_count >= m_data->count() ) ||
(m_addrdata && m_cur_data_count >= m_addrdata->count() ) )
return NULL;
if( number )
*number = 1;
if( m_vardata )
{
l = new Label( def, TQT_TQIODEVICE(buffer), m_name, m_paintDevice );
l->setUserVars( (*m_vardata)[m_cur_data_count] );
}
else if( m_data )
{
l = new Label( def, TQT_TQIODEVICE(buffer), m_name, m_paintDevice, m_customer,
(*m_data)[m_cur_data_count].article_no, (*m_data)[m_cur_data_count].group );
if( number )
*number = (*m_data)[m_cur_data_count].number;
}
else if( m_addrdata )
{
l = new Label( def, TQT_TQIODEVICE(buffer), m_name, m_paintDevice );
l->setAddressee( &((*m_addrdata)[m_cur_data_count]) );
}
l->setSerial( m_serial, m_increment );
l->setIndex( m_cur_data_count );
m_cur_data_count++;
return l;
}
void BatchPrinter::startImages()
{
TQProgressDialog* progress = createProgressDialog( i18n("Creating Images...") );
int number = 0;
m_cur_data_count = 0;
Measurements measure = def->getMeasurements();
Label* l = NULL;
painter = new TQPainter();
TQPixmap pixmap( (int)measure.width( TQT_TQPAINTDEVICE(parent) ), (int)measure.height( TQT_TQPAINTDEVICE(parent) ) );
while( (l = initLabel( &number ) ) != NULL )
{
for( int i = 0; i < number; i++ )
{
pixmap.fill( TQt::white );
painter->begin( &pixmap );
l->setIndex( i );
l->setRow( 0 );
l->setCol( 0 );
l->draw( painter, 0, 0 );
painter->end();
TQString name = m_path + "/";
if( m_image_filename == E_ARTICLE )
name += m_data ? (*m_data)[m_cur_data_count].article_no : TQString::number( m_cur_data_count );
else if( m_image_filename == E_BARCODE )
name += l->barcodeNo();
else
name += m_image_custom_filename;
TQString filename = name + TQString("_%1.").arg( i ) + KImageIO::suffix( m_image_format );
unsigned int c = 0;
while( TQFile::exists( filename ) ) {
filename += "." + TQString::number( c );
c++;
}
pixmap.save( filename, m_image_format );
if( !checkProgressDialog( progress ) )
{
delete l;
delete progress;
delete painter;
return;
}
}
delete l;
}
delete progress;
delete painter;
new KRun( m_path );
}
void BatchPrinter::startBCP()
{
int number = 0;
TQFile file( m_path );
if( !file.open( IO_WriteOnly ) ) // | IO_Raw ) )
{
KMessageBox::error( parent, TQString( i18n("<qt>Can't open the file or device <b>%1</b></qt>.") ).arg( m_path ) );
return;
}
TQProgressDialog* progress = createProgressDialog( i18n("Printing...") );
if( m_bcp_format == PrinterSettings::ZEBRA )
// Zebra printers are printed at 304dpi, this should
// be user defined, though
m_paintDevice = new BarcodePrinterDevice( 304.0, 304.0 );
else if( m_bcp_format == PrinterSettings::INTERMEC )
m_paintDevice = new BarcodePrinterDevice( 300.0, 300.0 );
else if( m_bcp_format == PrinterSettings::TEC )
// don't know which resolution is used for tec printers
// so we use a factor to convert everything to mm
// this is not accurate as TQPaintDevice supports only integers
m_paintDevice = new BarcodePrinterDevice( 25.4000508001016, 25.4000508001016 );
else if( m_bcp_format == PrinterSettings::EPCL )
m_paintDevice = new BarcodePrinterDevice( 304.0, 304.0 );
TQTextStream stream( &file );
Label* l;
while( ( l = initLabel( &number ) ) != NULL )
{
for( int i = 0; i < number; i++ )
{
switch( m_bcp_format )
{
case PrinterSettings::TEC:
// TODO: normally you should not care about the number or counter
// KBarcode will ensure that the label is printed often enough
if( m_data )
stream << tec452(m_name, (*m_data)[m_cur_data_count].number, (*m_data)[m_cur_data_count].article_no, (*m_data)[m_cur_data_count].group, m_customer);
else
/* TODO */;
#warning "TEC requires Old KBarcode SQL tables for printing"
tqDebug( "TEC requires Old KBarcode SQL tables for printing" );
break;
case PrinterSettings::ZEBRA:
l->zpl( &stream );
break;
case PrinterSettings::INTERMEC:
l->ipl( &stream );
break;
case PrinterSettings::EPCL:
l->epcl( &stream );
break;
default:
break;
}
if( !checkProgressDialog( progress ) )
{
delete l;
delete progress;
delete m_paintDevice;
m_paintDevice = NULL;
file.close();
return;
}
}
delete l;
}
delete progress;
delete m_paintDevice;
m_paintDevice = NULL;
file.close();
}
void BatchPrinter::checkForNewPage( Label* label )
{
if( curh + m_measure.height( printer ) > pageh || c_w == m_measure.numV() ) {
printer->newPage();
label->setPage( label->page() + 1 );
curh = m_measure.gapTop( printer );
curw = m_measure.gapLeft( printer );
c_w = 0;
}
}
void BatchPrinter::drawBorders()
{
if( PrinterSettings::getInstance()->getData()->border ) {
painter->setPen( TQPen( TQt::black, 1 ) );
painter->drawRect( (int)curw, (int)curh,
(int)m_measure.width( TQT_TQPAINTDEVICE(painter->device()) ),
(int)m_measure.height( TQT_TQPAINTDEVICE(painter->device()) ) );
}
}
void BatchPrinter::changeLine()
{
if( c_h >= m_measure.numH() ) {
c_h = 0;
curw = m_measure.gapLeft( printer );
curh += m_measure.gapV( printer );
c_w++;
}
}
void BatchPrinter::proccessEvents( int lb, TQString value, Label* label )
{
if( lb == NEW_PAGE ) {
if( curh > m_measure.gapTop( printer ) || curw > m_measure.gapLeft( printer ) ) {
printer->newPage();
label->setPage( label->page() + 1 );
curh = m_measure.gapTop( printer );
curw = m_measure.gapLeft( printer );
c_h = 0;
c_w = 0;
}
}
if( lb == LINE_BREAK )
changeLine();
if( lb == ARTICLE_GROUP_NO )
printXLabel( lb, label, value );
if( lb == LABEL_X )
printXLabel( lb, label, TQString() );
}
void BatchPrinter::printXLabel( int lb, Label* label, const TQString & value )
{
changeLine();
checkForNewPage( label );
Label::getXLabel( curw, curh, m_measure.width( printer ), m_measure.height( printer ), painter, lb, value );
drawBorders();
curw += + m_measure.gapH( printer );
c_h++;
}
void BatchPrinter::moveLabels()
{
for( unsigned int i = 0; i < m_move; i++ )
{
if( !curw )
curw = m_measure.gapLeft( printer );
if( !curh )
curh = m_measure.gapTop( printer );
changeLine();
if( curh + m_measure.height( printer ) > pageh || c_w == m_measure.numV() )
{
c_w = 0;
curh = m_measure.gapTop( printer );
curw = m_measure.gapLeft( printer );
}
curw += m_measure.gapH( printer );
c_h++;
}
}
TQProgressDialog* BatchPrinter::createProgressDialog( const TQString & caption )
{
TQProgressDialog* progress = new TQProgressDialog( caption, i18n("&Cancel"), m_labels+1, parent );
progress->setProgress( 0 );
progress->show();
return progress;
}
bool BatchPrinter::checkProgressDialog( TQProgressDialog* progress )
{
kapp->processEvents( 0 );
progress->setProgress( progress->progress() + 1 );
if( progress->wasCancelled() ) {
delete progress;
return false;
}
return true;
}
void BatchPrinter::setData( TQValueList<data>* list )
{
if( m_data )
delete m_data;
m_data = list;
}
void BatchPrinter::setData( TVariableList* list )
{
if( m_vardata )
delete m_vardata;
m_vardata = list;
}
void BatchPrinter::setData( KABC::AddresseeList* list )
{
if( m_addrdata )
delete m_addrdata;
m_addrdata = list;
}