From a31484700c86701f144e20a188d2ea6809c5e860 Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Mon, 2 Oct 2017 23:15:43 -0400 Subject: [PATCH] Initial implementation of glabels-batch. Note: must currently use QGuiApplication instead of QCoreApplication to support QFont. Unfortunately, this means that glabels-batch must run within a windowing system. Ideally, it would not have this requirement. --- glabels/CMakeLists.txt | 99 ++++++++++++++++++ glabels/Db.cpp | 1 - glabels/PageRenderer.cpp | 35 ++++++- glabels/PageRenderer.h | 4 +- glabels/PrintView.cpp | 22 +--- glabels/Template.cpp | 12 --- glabels/Template.h | 8 -- glabels/TemplatePicker.cpp | 2 +- glabels/TemplatePickerItem.cpp | 6 +- glabels/TemplatePickerItem.h | 2 + glabels/XmlLabelParser.cpp | 4 +- glabels/glabels-batch_main.cpp | 181 ++++++++++++++++++++++++++++++++ translations/glabels_C.ts | 184 ++++++++++++++++++++++----------- 13 files changed, 449 insertions(+), 111 deletions(-) create mode 100644 glabels/glabels-batch_main.cpp diff --git a/glabels/CMakeLists.txt b/glabels/CMakeLists.txt index 200390e..938f359 100644 --- a/glabels/CMakeLists.txt +++ b/glabels/CMakeLists.txt @@ -44,6 +44,10 @@ configure_file (Config.h.in ${CMAKE_CURRENT_BINARY_DIR}/Config.h @ONLY) #======================================= # Sources #======================================= + +# +# glabels executable +# set (glabels_sources glabels_main.cpp AboutDialog.cpp @@ -213,6 +217,101 @@ target_link_libraries (glabels-qt ) +# +# glabels-batch executable +# +set (glabels-batch_sources + glabels-batch_main.cpp + BarcodeBackends.cpp + BarcodeStyle.cpp + Category.cpp + ColorNode.cpp + DataCache.cpp + Db.cpp + Distance.cpp + FileUtil.cpp + Frame.cpp + FrameCd.cpp + FrameEllipse.cpp + FrameRect.cpp + FrameRound.cpp + Handles.cpp + LabelModel.cpp + LabelModelObject.cpp + LabelModelBarcodeObject.cpp + LabelModelBoxObject.cpp + LabelModelEllipseObject.cpp + LabelModelImageObject.cpp + LabelModelLineObject.cpp + LabelModelShapeObject.cpp + LabelModelTextObject.cpp + Layout.cpp + Markup.cpp + Outline.cpp + PageRenderer.cpp + Paper.cpp + Point.cpp + RawText.cpp + Region.cpp + Settings.cpp + Size.cpp + StrUtil.cpp + Template.cpp + TextNode.cpp + Units.cpp + Vendor.cpp + XmlCategoryParser.cpp + XmlLabelCreator.cpp + XmlLabelParser.cpp + XmlPaperParser.cpp + XmlTemplateCreator.cpp + XmlTemplateParser.cpp + XmlUtil.cpp + XmlVendorParser.cpp +) + +set (glabels-batch_qobject_headers + BarcodeBackends.h + LabelModel.h + LabelModelObject.h + LabelModelBarcodeObject.h + LabelModelBoxObject.h + LabelModelEllipseObject.h + LabelModelImageObject.h + LabelModelLineObject.h + LabelModelShapeObject.h + LabelModelTextObject.h + PageRenderer.h + Settings.h +) + +qt5_wrap_cpp (glabels-batch_moc_sources ${glabels-batch_qobject_headers}) + +if (WIN32) + # Windows resource file + set (glabels-batch_win_rc glabels-batch.rc) +endif () + +add_executable (glabels-batch-qt WIN32 + ${glabels-batch_sources} + ${glabels-batch_moc_sources} + ${glabels-batch_win_rc} +) + +target_link_libraries (glabels-batch-qt + Barcode + Merge + glbarcode + ${Qt5PrintSupport_LIBRARIES} + ${Qt5Xml_LIBRARIES} + ${Qt5Svg_LIBRARIES} + ${ZLIB_LIBRARIES} + ${GNUBARCODE_LIBRARIES} + ${LIBQRENCODE_LIBRARIES} + ${LIBZINT_LIBRARIES} +) + + #======================================= # Where to find stuff #======================================= diff --git a/glabels/Db.cpp b/glabels/Db.cpp index f1e9680..d321ab2 100644 --- a/glabels/Db.cpp +++ b/glabels/Db.cpp @@ -430,7 +430,6 @@ namespace glabels { if ( !isTemplateKnown( tmplate->brand(), tmplate->part() ) ) { - tmplate->initPreview(); mTemplates << tmplate; } else diff --git a/glabels/PageRenderer.cpp b/glabels/PageRenderer.cpp index ee1292f..2ee1c68 100644 --- a/glabels/PageRenderer.cpp +++ b/glabels/PageRenderer.cpp @@ -44,12 +44,15 @@ namespace glabels } - PageRenderer::PageRenderer() + PageRenderer::PageRenderer( const LabelModel* model ) : mModel(nullptr), mNCopies(0), mStartLabel(0), mPrintOutlines(false), mPrintCropMarks(false), mPrintReverse(false), mIPage(0), mIsMerge(false), mNPages(0) { - // empty + if ( model ) + { + setModel( model ); + } } @@ -182,6 +185,34 @@ namespace glabels } + /// + /// Print + /// + void PageRenderer::print( QPrinter* printer ) const + { + QSizeF pageSize( mModel->tmplate()->pageWidth().pt(), mModel->tmplate()->pageHeight().pt() ); + printer->setPageSize( QPageSize(pageSize, QPageSize::Point) ); + printer->setFullPage( true ); + printer->setPageMargins( 0, 0, 0, 0, QPrinter::Point ); + + QPainter painter( printer ); + + QRectF rectPx = printer->paperRect( QPrinter::DevicePixel ); + QRectF rectPts = printer->paperRect( QPrinter::Point ); + painter.scale( rectPx.width()/rectPts.width(), rectPx.height()/rectPts.height() ); + + for ( int iPage = 0; iPage < mNPages; iPage++ ) + { + if ( iPage ) + { + printer->newPage(); + } + + printPage( &painter, iPage ); + } + } + + /// /// Print page using persistent page number /// diff --git a/glabels/PageRenderer.h b/glabels/PageRenderer.h index 1415aee..8189c67 100644 --- a/glabels/PageRenderer.h +++ b/glabels/PageRenderer.h @@ -28,6 +28,7 @@ #include "Merge/Record.h" #include +#include #include #include @@ -50,7 +51,7 @@ namespace glabels // Life Cycle ///////////////////////////////// public: - PageRenderer(); + PageRenderer( const LabelModel* model = nullptr ); ///////////////////////////////// @@ -68,6 +69,7 @@ namespace glabels int nItems() const; int nPages() const; QRectF pageRect() const; + void print( QPrinter* printer ) const; void printPage( QPainter* painter ) const; void printPage( QPainter* painter, int iPage ) const; diff --git a/glabels/PrintView.cpp b/glabels/PrintView.cpp index f6e98b0..8b1a46e 100644 --- a/glabels/PrintView.cpp +++ b/glabels/PrintView.cpp @@ -41,6 +41,7 @@ namespace glabels preview->setRenderer( &mRenderer ); mPrinter = new QPrinter( QPrinter::HighResolution ); + mPrinter->setColorMode( QPrinter::Color ); } @@ -121,11 +122,6 @@ namespace glabels /// void PrintView::onPrintButtonClicked() { - QSizeF pageSize( mModel->tmplate()->pageWidth().pt(), mModel->tmplate()->pageHeight().pt() ); - mPrinter->setPageSize( QPageSize(pageSize, QPageSize::Point) ); - mPrinter->setFullPage( true ); - mPrinter->setPageMargins( 0, 0, 0, 0, QPrinter::Point ); - QPrintDialog printDialog( mPrinter, this ); printDialog.setOption( QAbstractPrintDialog::PrintToFile, true ); @@ -137,21 +133,7 @@ namespace glabels if ( printDialog.exec() == QDialog::Accepted ) { - QPainter painter( mPrinter ); - - QRectF rectPx = mPrinter->paperRect( QPrinter::DevicePixel ); - QRectF rectPts = mPrinter->paperRect( QPrinter::Point ); - painter.scale( rectPx.width()/rectPts.width(), rectPx.height()/rectPts.height() ); - - for ( int iPage = 0; iPage < mRenderer.nPages(); iPage++ ) - { - if ( iPage ) - { - mPrinter->newPage(); - } - - mRenderer.printPage( &painter, iPage ); - } + mRenderer.print( mPrinter ); } } diff --git a/glabels/Template.cpp b/glabels/Template.cpp index 96b87c4..5b7d29e 100644 --- a/glabels/Template.cpp +++ b/glabels/Template.cpp @@ -207,12 +207,6 @@ namespace glabels } - const MiniPreviewPixmap& Template::preview() const - { - return mPreview; - } - - const QList& Template::frames() const { return mFrames; @@ -231,12 +225,6 @@ namespace glabels } - void Template::initPreview() - { - mPreview = MiniPreviewPixmap( this, TEMPLATE_PREVIEW_SIZE, TEMPLATE_PREVIEW_SIZE ); - } - - bool Template::operator==( const Template& other ) const { return (mBrand == other.mBrand) && (mPart == other.mPart); diff --git a/glabels/Template.h b/glabels/Template.h index 4874474..fbf156f 100644 --- a/glabels/Template.h +++ b/glabels/Template.h @@ -36,9 +36,6 @@ namespace glabels { - const int TEMPLATE_PREVIEW_SIZE = 80; - - class Template { Q_DECLARE_TR_FUNCTIONS(Template) @@ -87,9 +84,6 @@ namespace glabels void addCategory( const QString& categoryId ); void addFrame( Frame* frame ); - void initPreview(); - const MiniPreviewPixmap& preview() const; - const QList& frames() const; bool operator==( const Template& other ) const; @@ -116,8 +110,6 @@ namespace glabels QStringList mCategoryIds; QList mFrames; - - MiniPreviewPixmap mPreview; }; } diff --git a/glabels/TemplatePicker.cpp b/glabels/TemplatePicker.cpp index 852005e..6b065b0 100644 --- a/glabels/TemplatePicker.cpp +++ b/glabels/TemplatePicker.cpp @@ -38,7 +38,7 @@ namespace glabels setSpacing( 24 ); setWordWrap( true ); setUniformItemSizes( true ); - setIconSize( QSize(TEMPLATE_PREVIEW_SIZE, TEMPLATE_PREVIEW_SIZE) ); + setIconSize( QSize(TemplatePickerItem::SIZE, TemplatePickerItem::SIZE) ); } diff --git a/glabels/TemplatePickerItem.cpp b/glabels/TemplatePickerItem.cpp index a7f42d0..bb4526e 100644 --- a/glabels/TemplatePickerItem.cpp +++ b/glabels/TemplatePickerItem.cpp @@ -20,6 +20,8 @@ #include "TemplatePickerItem.h" +#include "MiniPreviewPixmap.h" + #include #include #include @@ -36,9 +38,9 @@ namespace glabels { mTmplate = tmplate; - setIcon( QIcon(tmplate->preview()) ); + setIcon( QIcon( MiniPreviewPixmap( tmplate, SIZE, SIZE ) ) ); setText( tmplate->name() ); - + setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); } diff --git a/glabels/TemplatePickerItem.h b/glabels/TemplatePickerItem.h index 0909b73..7434eb0 100644 --- a/glabels/TemplatePickerItem.h +++ b/glabels/TemplatePickerItem.h @@ -36,6 +36,8 @@ namespace glabels /// class TemplatePickerItem : public QListWidgetItem { + public: + static const int SIZE = 80; ///////////////////////////////// // Life Cycle diff --git a/glabels/XmlLabelParser.cpp b/glabels/XmlLabelParser.cpp index f3c2d88..c0b00f9 100644 --- a/glabels/XmlLabelParser.cpp +++ b/glabels/XmlLabelParser.cpp @@ -54,8 +54,8 @@ namespace glabels if ( !file.open( QFile::ReadOnly ) ) { - qWarning() << "Error: Cannot read file " << qPrintable(fileName) - << ": " << file.errorString(); + qWarning() << "Error: Cannot read file" << fileName + << ":" << file.errorString(); return nullptr; } diff --git a/glabels/glabels-batch_main.cpp b/glabels/glabels-batch_main.cpp new file mode 100644 index 0000000..17dab37 --- /dev/null +++ b/glabels/glabels-batch_main.cpp @@ -0,0 +1,181 @@ +/* glabels-batch_main.cpp + * + * Copyright (C) 2013-2016 Jim Evins + * + * This file is part of gLabels-qt. + * + * gLabels-qt 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 3 of the License, or + * (at your option) any later version. + * + * gLabels-qt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gLabels-qt. If not, see . + */ + +#include "BarcodeBackends.h" +#include "FileUtil.h" +#include "Db.h" +#include "LabelModel.h" +#include "PageRenderer.h" +#include "Settings.h" +#include "Version.h" +#include "XmlLabelParser.h" + +#include "Merge/Factory.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +int main( int argc, char **argv ) +{ + QGuiApplication app( argc, argv ); + + QCoreApplication::setOrganizationName( "glabels.org" ); + QCoreApplication::setOrganizationDomain( "glabels.org" ); + QCoreApplication::setApplicationName( "glabels-batch-qt" ); + QCoreApplication::setApplicationVersion( glabels::Version::STRING ); + + // + // Setup translators + // + QLocale locale = QLocale::system(); + QString qtTranslationsDir = QLibraryInfo::location( QLibraryInfo::TranslationsPath ); + QString myTranslationsDir = glabels::FileUtil::translationsDir().canonicalPath(); + + QTranslator qtTranslator; + if ( qtTranslator.load( locale, "qt", "_", qtTranslationsDir ) ) + { + app.installTranslator(&qtTranslator); + } + + QTranslator glabelsTranslator; + if ( glabelsTranslator.load( locale, "glabels", "_", myTranslationsDir ) ) + { + app.installTranslator(&glabelsTranslator); + } + + QTranslator templatesTranslator; + if ( templatesTranslator.load( locale, "templates", "_", myTranslationsDir ) ) + { + app.installTranslator(&templatesTranslator); + } + + + // + // Parse command line + // + const QList options = { + {{"p","printer"}, + QString( QCoreApplication::translate( "main", "Send output to . (Default=\"%1\")") ).arg( QPrinterInfo::defaultPrinterName() ), + QCoreApplication::translate( "main", "printer" ), + QPrinterInfo::defaultPrinterName() }, + + {{"o","output"}, + QCoreApplication::translate( "main", "Set output filename to . (Default=\"output.pdf\")" ), + QCoreApplication::translate( "main", "filename" ), + "output.pdf" }, + + {{"s","sheets"}, + QCoreApplication::translate( "main", "Set number of sheets to . (Default=1)" ), + "n", "1" }, + + {{"c","copies"}, + QCoreApplication::translate( "main", "Set number of copies to . (Default=1)" ), + "n", "1" }, + + {{"f","first"}, + QCoreApplication::translate( "main", "Set starting label on 1st page to . (Default=1)" ), + "n", "1" }, + + {{"l","outlines"}, + QCoreApplication::translate( "main", "Print label outlines." ) }, + + {{"m","crop-marks"}, + QCoreApplication::translate( "main", "Print crop marks." ) }, + + {{"r","reverse"}, + QCoreApplication::translate( "main", "Print in reverse (mirror image)." ) } + }; + + + QCommandLineParser parser; + parser.setApplicationDescription( QCoreApplication::translate( "main", "gLabels Label Designer (Batch Front-end)" ) ); + parser.addOptions( options ); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument( "file", + QCoreApplication::translate( "main", "gLabels project file to print." ), + "file" ); + parser.process( app ); + + + // + // Initialize subsystems + // + glabels::Settings::init(); + glabels::Db::init(); + glabels::merge::Factory::init(); + glabels::BarcodeBackends::init(); + + + if ( parser.positionalArguments().size() == 1 ) + { + QString filename = parser.positionalArguments().first(); + + glabels::LabelModel *label = glabels::XmlLabelParser::readFile( filename ); + if ( label ) + { + QPrinter printer( QPrinter::HighResolution ); + printer.setColorMode( QPrinter::Color ); + if ( parser.isSet("printer") ) + { + qDebug() << "Batch mode. printer =" << parser.value("printer"); + printer.setPrinterName( parser.value("printer") ); + } + else if ( parser.isSet("output") ) + { + qDebug() << "Batch mode. output =" << parser.value("output"); + printer.setOutputFileName( parser.value("output") ); + } + else + { + qDebug() << "Batch mode. printer =" << QPrinterInfo::defaultPrinterName(); + } + + glabels::PageRenderer renderer( label ); + renderer.setNCopies( 1 ); + renderer.setStartLabel( parser.value( "first" ).toInt() - 1 ); + renderer.setPrintOutlines( parser.isSet( "outlines" ) ); + renderer.setPrintCropMarks( parser.isSet( "crop-marks" ) ); + renderer.setPrintReverse( parser.isSet( "reverse" ) ); + renderer.print( &printer ); + } + } + else + { + if ( parser.positionalArguments().size() == 0 ) + { + qWarning() << "Error: missing glabels project file."; + } + else + { + qWarning() << "Error: batch mode supports only one glabels project file."; + } + return -1; + } + + return 0; +} diff --git a/translations/glabels_C.ts b/translations/glabels_C.ts index 3f7f4bd..bd5822d 100644 --- a/translations/glabels_C.ts +++ b/translations/glabels_C.ts @@ -825,7 +825,7 @@ - + UPC-E @@ -841,7 +841,7 @@ - + ISBN @@ -852,7 +852,7 @@ - + Code 128 @@ -868,13 +868,13 @@ - + Interleaved 2 of 5 - + Codabar @@ -890,7 +890,7 @@ - + Code 93 @@ -920,282 +920,282 @@ - + Aztec Code - + Aztec Rune - + Code One - + Code 11 - + Code 16K - + Code 2 of 5 Matrix - + Code 2 of 5 IATA - + Code 2 of 5 Data Logic - + Code 32 (Italian Pharmacode) - + Code 49 - + Code 128 (Mode C supression) - + DAFT Code - + Data Matrix - + Deutsche Post Leitcode - + Deutsche Post Identcode - + Dutch Post KIX Code - + EAN - + Grid Matrix - + GS1-128 - + GS1 DataBar-14 - + GS1 DataBar-14 Stacked - + GS1 DataBar-14 Stacked Omni. - + GS1 DataBar Extended Stacked - + HIBC Code 128 - + HIBC Code 39 - + HIBC Data Matrix - + HIBC QR Code - + HIBC PDF417 - + HIBC Micro PDF417 - + HIBC Aztec Code - + ITF-14 - + Japanese Postal - + Korean Postal - + LOGMARS - + Maxicode - + Micro PDF417 - + Micro QR Code - + MSI Plessey - + NVE-18 - + PDF417 - + PDF417 Truncated - + PLANET - + PostNet - + Pharmacode - + Pharmacode 2-track - + Pharmazentral Nummer (PZN) - + QR Code - + Royal Mail 4-State - + Telepen - + Telepen Numeric - + USPS One Code - + UK Plessey - + Code 39 - + Code 39 Extended - + UPC-A @@ -2340,7 +2340,7 @@ - + (Will print a total of %1 items on %2 pages.) @@ -2378,6 +2378,66 @@ gLabels Label Designer + + + Send output to <printer>. (Default="%1") + + + + + printer + + + + + Set output filename to <filename>. (Default="output.pdf") + + + + + filename + + + + + Set number of sheets to <n>. (Default=1) + + + + + Set number of copies to <n>. (Default=1) + + + + + Set starting label on 1st page to <n>. (Default=1) + + + + + Print label outlines. + + + + + Print crop marks. + + + + + Print in reverse (mirror image). + + + + + gLabels Label Designer (Batch Front-end) + + + + + gLabels project file to print. + + gLabels project files to open, optionally.