Back to index

scribus-ng  1.3.4.dfsg+svn20071115
barcodegenerator.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 
00008 #include "barcodegenerator.h"
00009 #include "barcodegenerator.moc"
00010 #include "gsutil.h"
00011 #include "util.h"
00012 #include "scribus.h"
00013 #include "scpaths.h"
00014 #include "commonstrings.h"
00015 #include "undomanager.h"
00016 #include "loadsaveplugin.h"
00017 #include "../formatidlist.h"
00018 #include <qcombobox.h>
00019 #include <qtextedit.h>
00020 #include <qlineedit.h>
00021 #include <qpushbutton.h>
00022 #include <qcheckbox.h>
00023 #include <qcolor.h>
00024 #include <qcolordialog.h>
00025 #include <qlabel.h>
00026 #include <qfile.h>
00027 #include <qdir.h>
00028 #include <qfiledialog.h>
00029 #include <qregexp.h>
00030 
00031 BarcodeType::BarcodeType(QString cmd, QString exa,
00032                                            QString comm, QString regExp,
00033                                            bool includeCheck, bool includeCheckInText)
00034 {
00035        command = cmd;
00036        example = exa;
00037        comment = comm;
00038        regularExp = regExp;
00039        this->includeCheck = includeCheck;
00040        this->includeCheckInText = includeCheckInText;
00041 }
00042 
00043 BarcodeGenerator::BarcodeGenerator(QWidget* parent, const char* name)
00044        : BarcodeGeneratorBase(parent, name, true)
00045 {
00046        map["EAN-13"] = BarcodeType("ean13", "9781860742712", tr("12 or 13 digits"),
00047                                                         "[0-9]{12,13}");
00048        map["EAN-8"] = BarcodeType("ean8", "12345678", tr("8 digits"),
00049                                                     "[0-9]{8,8}");
00050        map["UPC-A"] = BarcodeType("upca", "78858101497", tr("11 or 12 digits"),
00051                                                     "[0-9]{11,12}");
00052        map["UPC-E"] = BarcodeType("upce", "0123456", tr("7 or 8 digits"),
00053                                                     "[0-9]{7,8}");
00054        map["EAN-5"] = BarcodeType("ean5", "90200", tr("5 digits"),
00055                                                     "[0-9]{5,5}");
00056        map["EAN-2"] = BarcodeType("ean2", "42", tr("2 digits"),
00057                                                     "[0-9]{2,2}");
00058        map["ISBN"] = BarcodeType("isbn", "1-58880-149",
00059                                                    tr("12 or 13 digits with dashes. The legacy ISBN-10 format accepts 9 or 10 digits with dashes, but this standard was depreciated for public use after 1st January 2007. (Note: To convert an old ISBN-10 to a new ISBN-13, prefix 978- to the first 9 digits, e.g. 1-56592-479-7 -> 978-1-56592-479. The final check-digit will be calculated automatically.)"),
00060                                                    "[0-9]*\\-[0-9]*\\-[0-9]*");
00061 //    "Code-11"] = "code11"
00062        map["Code-39"] = BarcodeType("code39", "CODE-39",
00063                                                          tr("Variable number of characters, digits and any of the symbols -. *$/+%."),
00064                                                          "[0-9a-zA-Z\\-\\.\\ \\*\\$\\/\\+\\%]*",
00065                                                         true, true);
00066 //    "Code-93"] = "code93"
00067        map["Code-128"] = BarcodeType("code128", "^104^102Count^0991234^101!",
00068                                                           tr("Variable number of ASCII characters and special function symbols, starting with the appropriate start character for the initial character set. UCC/EAN-128s must have a mandatory FNC 1 symbol immediately following the start character."),
00069                                                           "\\^[0-9a-zA-Z\\^\\!]*",
00070                                                           true, true);
00071        map["UCC/EAN-128"] = BarcodeType("code128", "^104^102Count^0991234^101!",
00072                                                                 tr("Variable number of ASCII characters and special function symbols, starting with the appropriate start character for the initial character set. UCC/EAN-128s must have a mandatory FNC 1 symbol immediately following the start character."),
00073                                                                 "\\^[0-9a-zA-Z\\^\\!]*");
00074        map["Rationalized Codabar"] = BarcodeType("rationalizedCodabar", "0123456789",
00075                                                                                tr("Variable number of digits and any of the symbols -$:/.+ABCD."),
00076                                                                                "[0-9A-D\\-\\$\\:\\/\\.\\+]*",
00077                                                                               true, true);
00078        map["Interleaved 2 of 5"] = BarcodeType("interleaved2of5", "05012345678900",
00079                                                                              tr("Variable number of digits"),
00080                                                                              "[0-9]*",
00081                                                                          true, true);
00082        map["ITF-14"] = BarcodeType("interleaved2of5", "05012345678900",
00083                                                         tr("Variable number of digits. An ITF-14 is 14 characters and does not have a check digit"),
00084                                                         "[0-9]*",
00085                                                     true, true);
00086        map["Code 2 of 5"] = BarcodeType("code2of5", "0123456789",
00087                                                                 tr("Variable number of digits"),
00088                                                                 "[0-9]*");
00089        map["Postnet"] = BarcodeType("postnet", "01234567",
00090                                                          tr("Variable number of digits"),
00091                                                          "[0-9]*",
00092                                                         false, true);
00093        map["Royal Mail"] = BarcodeType("royalmail", "LE28HS9Z",
00094                                                                tr("Variable number of digits and capital letters"),
00095                                                                "[0-9A-Z]*",
00096                                                                false, true);
00097 //    "Auspost"] = "auspost"
00098        map["MSI"] = BarcodeType("msi", "0120823635162", tr("Variable number of digits"),
00099                                                   "[0-9]*",
00100                                                  true, true);
00101 //    "KIX"] = "kix"
00102        map["Plessey"] = BarcodeType("plessey", "012345ABCDEF",
00103                                                          tr("Variable number of hexadecimal characters"),
00104                                                          "[0-9A-F]*",
00105                                                         false, true);
00106        //    "Symbol"] = "symbol"
00107 
00108        useSamples = true;
00109        guiColor = codeEdit->paletteBackgroundColor();
00110        bcCombo->insertStringList(map.keys());
00111        okButton->setText(CommonStrings::tr_OK);
00112        cancelButton->setText(CommonStrings::tr_Cancel);
00113        resetButton->setPixmap(loadIcon("u_undo16.png"));
00114        lnColor = Qt::black;
00115        txtColor = Qt::black;
00116        bgColor = Qt::white;
00117        paintColorSample(linesLabel, lnColor);
00118        paintColorSample(txtLabel, txtColor);
00119        paintColorSample(bgLabel, bgColor);
00120 
00121        tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "bcode.png");
00122        psFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "bcode.ps");
00123 
00124        // PS engine
00125        psCommand.append("%!PS-Adobe-2.0 EPSF-2.0\n");
00126        QFile f( ScPaths::instance().shareDir() + QString("/plugins/barcode.ps") );
00127        f.open(IO_ReadOnly);
00128        QTextStream ts(&f);
00129        QString s = ts.read();
00130        int begin = s.find("% --BEGIN TEMPLATE--");
00131        int end = s.find("% --END TEMPLATE--");
00132        psCommand.append(s.mid(begin, end));
00133        f.close();
00134        psCommand.append("\n\n%command\n");
00135        bcComboChanged();
00136 }
00137 
00138 BarcodeGenerator::~BarcodeGenerator()
00139 {
00140        QFile::remove(psFile);
00141        QFile::remove(tmpFile);
00142 }
00143 
00144 void BarcodeGenerator::bcComboChanged()
00145 {
00146        QString s = bcCombo->currentText();
00147        commentEdit->setText(map[s].comment);
00148        if (useSamples)
00149        {
00150               disconnect(codeEdit, SIGNAL(textChanged(const QString&)), this, SLOT(codeEdit_textChanged(const QString&)));
00151               codeEdit->setText(map[s].example);
00152               connect(codeEdit, SIGNAL(textChanged(const QString&)), this, SLOT(codeEdit_textChanged(const QString&)));
00153        }
00154 
00155        includeCheck->setEnabled(map[s].includeCheck ? true : false);
00156        if (textCheck->isChecked())
00157               includeCheckInText->setEnabled(map[s].includeCheckInText ? true : false);
00158        else
00159               includeCheckInText->setEnabled(false);
00160 
00161        codeEdit_check(codeEdit->text());
00162        paintBarcode();
00163 }
00164 
00165 void BarcodeGenerator::textCheck_changed()
00166 {
00167        bool s = textCheck->state();
00168        txtColorButton->setEnabled(s);
00169        includeCheckInText->setEnabled(s);
00170        paintBarcode();
00171 }
00172 
00173 void BarcodeGenerator::guardCheck_changed()
00174 {
00175        paintBarcode();
00176 }
00177 
00178 void BarcodeGenerator::includeCheck_stateChanged(int)
00179 {
00180        paintBarcode();
00181 }
00182 
00183 void BarcodeGenerator::includeCheckInText_stateChanged(int)
00184 {
00185        paintBarcode();
00186 }
00187 
00188 void BarcodeGenerator::paintColorSample(QLabel *l, QColor c)
00189 {
00190        QPixmap pm(1, 1);
00191        pm.fill(c);
00192        l->setPixmap(pm);
00193 }
00194 
00195 void BarcodeGenerator::bgColorButton_pressed()
00196 {
00197        bgColor = QColorDialog::getColor(bgColor, this);
00198        if (bgColor.isValid())
00199        {
00200               paintColorSample(bgLabel, bgColor);
00201               paintBarcode();
00202        }
00203 }
00204 
00205 void BarcodeGenerator::lnColorButton_pressed()
00206 {
00207        lnColor = QColorDialog::getColor(lnColor, this);
00208        if (lnColor.isValid())
00209        {
00210               paintColorSample(linesLabel, lnColor);
00211               paintBarcode();
00212        }
00213 }
00214 
00215 void BarcodeGenerator::txtColorButton_pressed()
00216 {
00217        txtColor = QColorDialog::getColor(txtColor, this);
00218        if (txtColor.isValid())
00219        {
00220               paintColorSample(txtLabel, txtColor);
00221               paintBarcode();
00222        }
00223 }
00224 
00225 void BarcodeGenerator::okButton_pressed()
00226 {
00227        // no need to call paintBarcode(tmpFile, 300); because
00228        // it's created by previous run...
00229        hide();
00230        const FileFormat * fmt = LoadSavePlugin::getFormatById(FORMATID_PSIMPORT);
00231        if( fmt )
00232               fmt->loadFile(QString::fromUtf8(psFile), LoadSavePlugin::lfUseCurrentPage|LoadSavePlugin::lfInteractive);
00233        accept();
00234 }
00235 
00236 void BarcodeGenerator::cancelButton_pressed()
00237 {
00238        reject();
00239 }
00240 
00241 bool BarcodeGenerator::codeEdit_check(const QString& )//s)
00242 {
00243        /* probably not needed as the backend do it for us (PV)
00244        QRegExp rx(map[bcCombo->currentText()].regularExp);
00245        if (!rx.exactMatch(s))
00246        {
00247               codeEdit->setPaletteBackgroundColor(QColor(255, 0, 0));
00248               sampleLabel->setText("<qt>" + tr("Barcode incomplete") + "</qt>");
00249               okButton->setEnabled(false);
00250               return false;
00251        }
00252        else
00253        {
00254               codeEdit->setPaletteBackgroundColor(guiColor);
00255               okButton->setEnabled(true);
00256               paintBarcode();
00257               return true;
00258        } */
00259        paintBarcode();
00260        return true;
00261 }
00262 
00263 void BarcodeGenerator::codeEdit_textChanged(const QString& s)
00264 {
00265        useSamples = false;
00266        codeEdit_check(s);
00267 }
00268 
00269 bool BarcodeGenerator::paintBarcode(QString fileName, int dpi)
00270 {
00271        if (fileName == QString::null)
00272               fileName = tmpFile;
00273        QString opts("barcolor=%1 showbackground backgroundcolor=%2 textcolor=%3");
00274        opts = opts.arg(lnColor.name().replace('#', "")) \
00275                      .arg(bgColor.name().replace('#', "")) \
00276                      .arg(txtColor.name().replace('#', ""));
00277        if (textCheck->isChecked())
00278               opts += " includetext";
00279        if (guardCheck->isChecked())
00280               opts += " guardwhitespace";
00281        if (includeCheckInText->isChecked() & includeCheckInText->isEnabled())
00282               opts += " includecheckintext";
00283        if (includeCheck->isChecked() & includeCheck->isEnabled())
00284               opts += " includecheck";
00285        QString comm("15 10 moveto (%1) (%2) %3 barcode");
00286        comm = comm.arg(codeEdit->text()).arg(opts).arg(map[bcCombo->currentText()].command);
00287        comm = psCommand + comm;
00288        QFile f(psFile);
00289        if (!f.open(IO_WriteOnly))
00290        {
00291               sampleLabel->setText("<qt>" + tr("Error opening file: %1").arg(psFile) + "</qt>");
00292               return false;
00293        }
00294        QTextStream ts(&f);
00295        ts << comm;
00296        f.close();
00297 
00298        QStringList gargs;
00299        // limit the area only for preview. EPS importer bounds the box itself.
00300        if (fileName == tmpFile)
00301        {
00302               gargs.append("-dDEVICEWIDTHPOINTS=200");
00303               gargs.append("-dDEVICEHEIGHTPOINTS=150");
00304        }
00305        gargs.append( QString("-r%1").arg(dpi) );
00306        gargs.append( QString("-sOutputFile=%1").arg(fileName) );
00307        gargs.append( psFile );
00308        int gs = callGS(gargs);
00309        bool retval = true;
00310        if (gs != 0)
00311               retval = false;
00312        // setup only preview
00313        if (fileName != tmpFile)
00314               return retval;
00315     if (gs == 0)
00316        {
00317               sampleLabel->setPixmap(QPixmap(fileName));
00318               okButton->setEnabled(true);
00319        }
00320        else
00321        {
00322               sampleLabel->setText("<qt>" + tr("Barcode incomplete") + "</qt>");
00323               okButton->setEnabled(false);
00324        }
00325        return retval;
00326 }
00327 
00328 void BarcodeGenerator::resetButton_clicked()
00329 {
00330        useSamples = true;
00331        bcComboChanged();
00332 }