Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

util.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                           util.cpp  -  description
00009                              -------------------
00010     begin                : Fri Sep 14 2001
00011     copyright            : (C) 2001 by Franz Schmid
00012     email                : Franz.Schmid@altmuehlnet.de
00013  ***************************************************************************/
00014 
00015 /***************************************************************************
00016  *                                                                         *
00017  *   This program is free software; you can redistribute it and/or modify  *
00018  *   it under the terms of the GNU General Public License as published by  *
00019  *   the Free Software Foundation; either version 2 of the License, or     *
00020  *   (at your option) any later version.                                   *
00021  *                                                                         *
00022  ***************************************************************************/
00023 
00024 
00025 #include <QBitmap>
00026 #include <QByteArray>
00027 #include <QCheckBox>
00028 #include <QDomElement>
00029 #include <QFile>
00030 #include <QFileInfo>
00031 #include <QImageReader>
00032 #include <QList>
00033 #include <QPixmap>
00034 #include <QWidget>
00035 #include <QDir>
00036 #include <QCryptographicHash>
00037 
00038 #include <cmath>
00039 #include <algorithm>
00040 
00041 #include "util.h"
00042 
00043 #include "scpainter.h"
00044 #include "scconfig.h"
00045 #include "pageitem_textframe.h"
00046 
00047 #if defined(_WIN32)
00048 #if defined(_MSC_VER)
00049 #define __STDC__ 1 // hack to get md5_buffer correctly identified
00050 #endif
00051 #include <valarray>
00052 #include <windows.h>
00053 #endif
00054 
00055 // #include "md5.h"
00056 
00057 #include "commonstrings.h"
00058 #include "prefsmanager.h"
00059 #include <QProcess>
00060 #include "scmessagebox.h"
00061 #include "scpixmapcache.h"
00062 #include "scpaths.h"
00063 
00064 extern "C"
00065 {
00066 #define XMD_H           // shut JPEGlib up
00067 #if defined(Q_OS_UNIXWARE)
00068 #  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
00069 #endif
00070 #include <jpeglib.h>
00071 #include <jerror.h>
00072 #undef HAVE_STDLIB_H
00073 #ifdef const
00074 #  undef const          // remove crazy C hackery in jconfig.h
00075 #endif
00076 }
00077 
00078 #include "pageitem.h"
00079 #include "scribus.h"
00080 #include "scribusdoc.h"
00081 #include "scribusview.h"
00082 #include <zlib.h>
00083 
00084 
00085 using namespace std;
00086 
00087 void sDebug(QString message)
00088 {
00089     qDebug("%s", message.toAscii().constData());
00090 }
00091 
00092 int System(const QString exename, const QStringList & args, const QString fileStdErr, const QString fileStdOut)
00093 {
00094     QProcess proc;
00095     if (!fileStdOut.isEmpty())
00096         proc.setStandardOutputFile(fileStdOut);
00097     if (!fileStdErr.isEmpty())
00098         proc.setStandardErrorFile(fileStdErr);
00099     proc.start(exename, args);
00100     if (proc.waitForStarted(5000))
00101     {
00102         while (!proc.waitForFinished(5000))
00103         {
00104             qApp->processEvents();
00105         }
00106     }
00107     int ex = proc.exitCode();
00108     return ex;
00109 }
00110 
00111 // On Windows, return short path name, else return longPath;
00112 QString getShortPathName(QString longPath)
00113 {
00114     QString shortPath(longPath);
00115 #if defined _WIN32
00116     QFileInfo fInfo(longPath);
00117     if (fInfo.exists())
00118     {
00119         WCHAR shortName[MAX_PATH + 1];
00120         // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
00121         // that volume does not support 8.3 filenames, so return longPath in this case
00122         QString nativePath = QDir::convertSeparators(longPath);
00123         int ret = GetShortPathNameW((LPCWSTR) nativePath.utf16(), shortName, MAX_PATH);
00124         if (ret != ERROR_INVALID_PARAMETER && ret < MAX_PATH)
00125             shortPath = QString::fromUtf16((const ushort*) shortName);
00126     }
00127 #endif
00128     return shortPath;
00129 }
00130 
00131 int copyFile(QString source, QString target)
00132 {
00133     int bytesread, error = -1;
00134     if ((source.isNull()) || (target.isNull()))
00135         return -1;
00136     if (source == target)
00137         return -1;
00138     QFile s(source);
00139     if (!s.exists())
00140         return -1;
00141     QFile t(target);
00142     QByteArray bb( 65536, ' ' );
00143     if (bb.size() <= 0) // Check for memory allocation failure
00144         return -1;
00145     if (s.open(QIODevice::ReadOnly))
00146     {
00147         if (t.open(QIODevice::WriteOnly))
00148         {
00149             bytesread = s.read( bb.data(), bb.size() );
00150             while( bytesread > 0 )
00151             {
00152                 t.write( bb.data(), bytesread );
00153                 bytesread = s.read( bb.data(), bb.size() );
00154             }
00155             if (s.error() == QFile::NoError && t.error() == QFile::NoError)
00156                 error = 0;
00157             t.close();
00158         }
00159         s.close();
00160     }
00161     return error;
00162 }
00163 
00164 int moveFile(QString source, QString target)
00165 {
00166     if ((source.isNull()) || (target.isNull()))
00167         return -1;
00168     if (source == target)
00169         return -1;
00170     copyFile(source, target);
00171     QFile::remove(source);
00172     return 0;
00173 }
00174 
00175 QString GetAttr(QDomElement *el, QString at, QString def)
00176 {
00177     return el->attribute(at, def);
00178 }
00179 
00180 
00181 // Legacy implementation of LoadText with incorrect
00182 // handling of unicode data. This should be retired.
00183 // Use loadRawText instead.
00184 // FIXME XXX
00185 //
00186 bool loadText(QString filename, QString *Buffer)
00187 {
00188     QFile f(filename);
00189     QFileInfo fi(f);
00190     if (!fi.exists())
00191         return false;
00192     bool ret;
00193     QByteArray bb(f.size(), ' ');
00194     if (f.open(QIODevice::ReadOnly))
00195     {
00196         f.read(bb.data(), f.size());
00197         f.close();
00198         for (int posi = 0; posi < bb.size(); ++posi)
00199             *Buffer += QChar(bb[posi]);
00200         /*
00201         int len = bb.size();
00202         int oldLen = Buffer->length();
00203         Buffer->setLength( oldLen + len + 1);
00204         // digged into Qt 3.3 sources to find that. Might break in Qt 4 -- AV
00205         unsigned short * ucsString = const_cast<unsigned short *>(Buffer->ucs2()) + oldLen;
00206         char * data = bb.data();
00207         for (uint posi = 0; posi < len; ++posi)
00208         *ucsString++ = *data++;
00209         *ucsString = 0;
00210         */
00211         ret = true;
00212     }
00213     else
00214         ret = false;
00215     return ret;
00216 }
00217 
00218 bool loadRawText(const QString & filename, QByteArray & buf)
00219 {
00220     bool ret = false;
00221     QFile f(filename);
00222     QFileInfo fi(f);
00223     if (fi.exists())
00224     {
00225         QByteArray tempBuf(f.size() + 1, ' ');
00226         if (f.open(QIODevice::ReadOnly))
00227         {
00228             unsigned int bytesRead = f.read(tempBuf.data(), f.size());
00229             tempBuf[bytesRead] = '\0';
00230             ret = bytesRead == f.size();
00231             if (ret)
00232                 buf = tempBuf; // sharing makes this efficient
00233         }
00234     }
00235     if (f.isOpen())
00236         f.close();
00237     return ret;
00238 }
00239 
00240 bool loadRawBytes(const QString & filename, QByteArray & buf)
00241 {
00242     bool ret = false;
00243     QFile f(filename);
00244     QFileInfo fi(f);
00245     if (fi.exists())
00246     {
00247         QByteArray tempBuf(f.size(), ' ');
00248         if (f.open(QIODevice::ReadOnly))
00249         {
00250             unsigned int bytesRead = f.read(tempBuf.data(), f.size());
00251             ret = bytesRead == f.size();
00252             if (ret)
00253                 buf = tempBuf; // sharing makes this efficient
00254         }
00255     }
00256     if (f.isOpen())
00257         f.close();
00258     return ret;
00259 }
00260 
00261 
00262 QString CompressStr(QString *in)
00263 {
00264     QString out = "";
00265     QByteArray bb(in->length(), ' ');
00266     if (bb.size() == in->length())
00267     {
00268         for (int ax = 0; ax < in->length(); ++ax)
00269         {
00270             // bb.insert(ax, in->at(ax)); JG monstruously inefficient due to frequent memory reallocation
00271             bb[ax] = in->at(ax).cell();
00272             assert(in->at(ax).row() == 0);
00273         }
00274         uLong exlen = (uLong)(bb.size() * 0.001 + 16) + bb.size();
00275         QByteArray bc(exlen, ' ');
00276         if( bc.size() == static_cast<qint32>(exlen) )
00277         {
00278             int errcode = compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
00279             if (errcode != Z_OK)
00280             {
00281                 qDebug("compress2 failed with code %i", errcode);
00282                 out = *in;
00283             }
00284             else {
00285                 for (uint cl = 0; cl < exlen; ++cl)
00286                     out += QChar(bc[cl]);
00287             }
00288         }
00289         else
00290         {
00291             qDebug("insufficient memory to allocate %i bytes", in->length());
00292             out = *in;
00293         }
00294     }
00295     else
00296     {
00297         qDebug("insufficient memory to allocate %i bytes", in->length());
00298         out = *in;
00299     }
00300     return out;
00301 }
00302 
00303 QByteArray CompressArray(const QByteArray& in)
00304 {
00305     QByteArray out;
00306     uLong exlen = uint(in.size() * 0.001 + 16) + in.size();
00307     QByteArray temp(exlen, ' ');
00308     int errcode = compress2((Byte *)temp.data(), &exlen, (Byte *)in.data(), uLong(in.size()), 9);
00309     if (errcode == Z_OK)
00310     {
00311         temp.resize(exlen);
00312         out = temp;
00313     }
00314     else
00315         qDebug("compress2 failed with code %i", errcode);
00316     return out;
00317 }
00318 
00319 char *toAscii85( quint32 value, bool& allZero )
00320 {
00321     int digit, i;
00322     static char asciiVal[6];
00323     allZero = true;
00324     for (i = 0; i < 5; ++i) 
00325     {
00326         digit = value % 85;
00327         if (digit != 0)
00328             allZero = false;
00329         asciiVal[4-i] = digit + 33;
00330         value = (value - digit) / 85;
00331     }
00332     asciiVal[5] = 0;
00333     return asciiVal;
00334 }
00335 
00336 char *toHex( uchar u )
00337 {
00338     static char hexVal[3];
00339     int i = 1;
00340     while ( i >= 0 )
00341     {
00342         ushort hex = (u & 0x000f);
00343         if ( hex < 0x0a )
00344             hexVal[i] = '0'+hex;
00345         else
00346             hexVal[i] = 'A'+(hex-0x0a);
00347         u = u >> 4;
00348         i--;
00349     }
00350     hexVal[2] = '\0';
00351     return hexVal;
00352 }
00353 
00354 QString String2Hex(QString *in, bool lang)
00355 {
00356     int i = 0;
00357     QString out("");
00358     for( int xi = 0; xi < in->length(); ++xi )
00359     {
00360         // Qt4 .cell() added ???
00361         out += toHex(QChar(in->at(xi)).cell());
00362         ++i;
00363         if ((i>40) && (lang))
00364         {
00365             out += '\n';
00366             i=0;
00367         }
00368     }
00369     return out;
00370 }
00371 
00372 QByteArray ComputeMD5Sum(QByteArray *in)
00373 {
00374     return QCryptographicHash::hash(*in, QCryptographicHash::Md5);
00375 //  QByteArray MDsum(16, ' ');
00376 //  md5_buffer (in->data(), in->size(), reinterpret_cast<void*>(MDsum.data()));
00377 //  return MDsum;
00378 }
00379 
00380 QString Path2Relative(QString Path, const QString& baseDir)
00381 {
00382     QDir d(baseDir);
00383     return d.relativeFilePath(Path);
00384 }
00385 
00386 QString Relative2Path(QString File, const QString& baseDir)
00387 {
00388     QString   absPath;
00389     QFileInfo fi(File);
00390     if (File.isEmpty())
00391         absPath = File;
00392     else if (fi.isRelative())
00393     {
00394         QDir d(baseDir);
00395         absPath = d.absoluteFilePath(File);
00396         absPath = QDir::cleanPath(absPath);
00397     }
00398     else
00399         absPath = File;
00400     return absPath;
00401 }
00402 
00403 /***************************************************************************
00404     begin                : Wed Oct 29 2003
00405     copyright            : (C) 2003 The Scribus Team
00406     email                : paul@all-the-johnsons.co.uk
00407  ***************************************************************************/
00408 // check if the file exists, if it does, ask if they're sure
00409 // return true if they're sure, else return false;
00410 
00411 bool overwrite(QWidget *parent, QString filename)
00412 {
00413     bool retval = true;
00414     QFileInfo fi(filename);
00415     if (fi.exists())
00416     {
00417         QString fn = QDir::convertSeparators(filename);
00418         int t = QMessageBox::warning(parent, QObject::tr("File exists"),
00419                                      "<qt>"+ QObject::tr("A file named '%1' already exists.<br/>Do you want to replace it with the file you are saving?").arg(fn) +"</qt>",
00420                                              QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
00421         if (t == QMessageBox::Cancel)
00422             retval = false;
00423     }
00424     return retval;
00425 }
00426 
00427 void WordAndPara(PageItem* currItem, int *w, int *p, int *c, int *wN, int *pN, int *cN)
00428 {
00429     QChar Dat = QChar(32);
00430     int para = 0;
00431     int ww = 0;
00432     int cc = 0;
00433     int paraN = 0;
00434     int wwN = 0;
00435     int ccN = 0;
00436     bool first = true;
00437     PageItem *nextItem = currItem;
00438     PageItem *nbl = currItem;
00439     while (nextItem != 0)
00440     {
00441         if (nextItem->prevInChain() != 0)
00442             nextItem = nextItem->prevInChain();
00443         else
00444             break;
00445     }
00446     while (nextItem != 0)
00447     {
00448         for (int a = qMax(nextItem->firstInFrame(),0); a <= nextItem->lastInFrame() && a < nextItem->itemText.length(); ++a)
00449         {
00450             QChar b = nextItem->itemText.text(a);
00451             if (b == SpecialChars::PARSEP)
00452             {
00453                 para++;
00454             }
00455             if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
00456             {
00457                 ww++;
00458             }
00459             cc++;
00460             Dat = b;
00461             first = false;
00462         }
00463         nbl = nextItem;
00464         nextItem = nextItem->nextInChain();
00465     }
00466     if (nbl->frameOverflows()) {
00467         paraN++;
00468         for (int a = nbl->lastInFrame()+1; a < nbl->itemText.length(); ++a)
00469         {
00470             QChar b = nbl->itemText.text(a);
00471             if (b == SpecialChars::PARSEP)
00472             {
00473                 paraN++;
00474             }
00475             if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
00476             {
00477                 wwN++;
00478             }
00479             ccN++;
00480             Dat = b;
00481             first = false;
00482         }
00483     }       
00484     else {
00485         para++;
00486     }
00487     if (Dat.isLetterOrNumber())
00488     {
00489         if (nbl->frameOverflows())
00490             wwN++;
00491         else
00492             ww++;
00493     }
00494     *w = ww;
00495     *p = para;
00496     *c = cc;
00497     *wN = wwN;
00498     *pN = paraN;
00499     *cN = ccN;
00500 }
00501 
00502 void ReOrderText(ScribusDoc *currentDoc, ScribusView *view)
00503 {
00504     double savScale = view->scale();
00505     view->setScale(1.0);
00506     currentDoc->RePos = true;
00507     QImage pgPix(10, 10, QImage::Format_ARGB32);
00508     QRect rd; // = QRect(0,0,9,9);
00509     ScPainter *painter = new ScPainter(&pgPix, pgPix.width(), pgPix.height());
00510     for (int azz=0; azz<currentDoc->MasterItems.count(); ++azz)
00511     {
00512         PageItem *currItem = currentDoc->MasterItems.at(azz);
00513         if (currItem->itemType() == PageItem::PathText)
00514             currItem->DrawObj(painter, rd);
00515     }
00516     for (int azz=0; azz<currentDoc->Items->count(); ++azz)
00517     {
00518         PageItem *currItem = currentDoc->Items->at(azz);
00519         currItem->layout();
00520         if (currItem->itemType() == PageItem::PathText)
00521             currItem->DrawObj(painter, rd); //FIXME: this should be replaced by code in layout()
00522     }
00523     currentDoc->RePos = false;
00524     view->setScale(savScale);
00525     delete painter;
00526 }
00527 
00534 bool compareQStrings(QString s1, QString s2)
00535 {
00536     if (QString::localeAwareCompare(s1, s2) >= 0)
00537         return false;
00538     return true;
00539 }
00540 
00541 QStringList sortQStringList(QStringList aList)
00542 {
00543     std::vector<QString> sortList;
00544     QStringList retList;
00545     QStringList::Iterator it;
00546     for (it = aList.begin(); it != aList.end(); ++it)
00547         sortList.push_back(*it);
00548     std::sort(sortList.begin(), sortList.end(), compareQStrings);
00549     for(uint i = 0; i < sortList.size(); i++)
00550         retList.append(sortList[i]);
00551     return retList;
00552 }
00553 
00554 QString checkFileExtension(const QString &currName, const QString &extension)
00555 {
00556     QString newName(currName);
00557     //If filename ends with a period, just add the extension
00558     if (newName.right(1)==".")
00559     {
00560         newName+=extension.toLower();
00561         return newName;
00562     }
00563     //If filename doesnt end with the period+extension, add it on
00564     QString dotExt("." + extension.toLower());
00565     if (!newName.endsWith(dotExt, Qt::CaseInsensitive))
00566         newName+=dotExt;
00567     return newName;
00568 }
00569 
00570 QString getFileNameByPage(ScribusDoc* currDoc, uint pageNo, QString extension)
00571 {
00572     uint number = pageNo + currDoc->FirstPnum;
00573     QString defaultName = currDoc->DocName;
00574     if (defaultName.isNull())
00575         defaultName = "export";
00576     else
00577     {
00578         QFileInfo fi(defaultName);
00579         defaultName = fi.completeBaseName();
00580     }
00581     return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number, 3, 10, QChar('0')).arg(extension);
00582 }
00583 
00584 const QString getStringFromSequence(DocumentSectionType type, uint position)
00585 {
00586     QString retVal("");
00587     switch( type )
00588     {
00589         case Type_1_2_3:
00590             retVal=QString::number(position);
00591             break;
00592         case Type_A_B_C:
00593             retVal=numberToLetterSequence(position).toUpper();
00594             break;
00595         case Type_a_b_c:
00596             retVal=numberToLetterSequence(position);
00597             break;
00598         case Type_I_II_III:
00599             retVal=arabicToRoman(position);
00600             break;
00601         case Type_i_ii_iii:
00602             //well, for lower case people will want that, even if its "wrong"
00603             //ie, X=10, x=10000
00604             retVal=arabicToRoman(position).toLower();
00605             break;
00606         case Type_None:
00607             break;
00608         default:
00609             break;
00610     }
00611     return retVal;
00612 }
00613 
00614 const QString numberToLetterSequence(uint i)
00615 {
00616     QString retVal("");
00617     unsigned digits = 1;
00618     unsigned offset = 0;
00619     uint column=i;
00620     --column;
00621 
00622     if( column > 4058115285U ) return  QString("@");
00623 
00624     for( unsigned limit = 26; column >= limit+offset; limit *= 26, digits++ )
00625         offset += limit;
00626 
00627     for( unsigned c = column - offset; digits; --digits, c/=26 )
00628         retVal.prepend( QChar( 'a' + (c%26) ) );
00629     return retVal;
00630 }
00631 
00632 const QString arabicToRoman(uint i)
00633 {
00634     QString roman("");
00635     int arabic = i;
00636     while (arabic - 1000000 >= 0){
00637         roman += "m";
00638         arabic -= 1000000;
00639     }
00640     while (arabic - 900000 >= 0){
00641         roman += "cm";
00642         arabic -= 900000;
00643     }
00644     while (arabic - 500000 >= 0){
00645         roman += "d";
00646         arabic -= 500000;
00647     }
00648     while (arabic - 400000 >= 0){
00649         roman += "cd";
00650         arabic -= 400000;
00651     }
00652     while (arabic - 100000 >= 0){
00653         roman += "c";
00654         arabic -= 100000;
00655     }
00656     while (arabic - 90000 >= 0){
00657         roman += "xc";
00658         arabic -= 90000;
00659     }
00660     while (arabic - 50000 >= 0){
00661         roman += "l";
00662         arabic -= 50000;
00663     }
00664     while (arabic - 40000 >= 0){
00665         roman += "xl";
00666         arabic -= 40000;
00667     }
00668     while (arabic - 10000 >= 0){
00669         roman += "x";
00670         arabic -= 10000;
00671     }
00672     while (arabic - 9000 >= 0){
00673         roman += "Mx";
00674         arabic -= 9000;
00675     }
00676     while (arabic - 5000 >= 0){
00677         roman += "v";
00678         arabic -= 5000;
00679     }
00680     while (arabic - 4000 >= 0){
00681         roman += "Mv";
00682         arabic -= 4000;
00683     }
00684     while (arabic - 1000 >= 0){
00685         roman += "M";
00686         arabic -= 1000;
00687     }
00688     while (arabic - 900 >= 0){
00689         roman += "CM";
00690         arabic -= 900;
00691     }
00692     while (arabic - 500 >= 0){
00693         roman += "D";
00694         arabic -= 500;
00695     }
00696     while (arabic - 400 >= 0){
00697         roman += "CD";
00698         arabic -= 400;
00699     }
00700     while (arabic - 100 >= 0){
00701         roman += "C";
00702         arabic -= 100;
00703     }
00704     while (arabic - 90 >= 0){
00705         roman += "XC";
00706         arabic -= 90;
00707     }
00708     while (arabic - 50 >= 0){
00709         roman += "L";
00710         arabic -= 50;
00711     }
00712     while (arabic - 40 >= 0){
00713         roman += "XL";
00714         arabic -= 40;
00715     }
00716     while (arabic - 10 >= 0){
00717         roman += "X";
00718         arabic -= 10;
00719     }
00720     while (arabic - 9 >= 0){
00721         roman += "IX";
00722         arabic -= 9;
00723     }
00724     while (arabic - 5 >= 0){
00725         roman += "V";
00726         arabic -= 5;
00727     }
00728     while (arabic - 4 >= 0){
00729         roman += "IV";
00730         arabic -= 4;
00731     }
00732     while (arabic - 1 >= 0){
00733         roman += "I";
00734         arabic -= 1;
00735     }
00736     return roman;
00737 }
00738 
00739 //CB Moved from scribus.cpp
00740 void parsePagesString(QString pages, std::vector<int>* pageNs, int sourcePageCount)
00741 {
00742     QString tmp(pages);
00743     QString token;
00744     int from, to, pageNr;
00745     do
00746     {
00747         if (tmp.indexOf(",") == -1)
00748         {
00749             token = tmp;
00750             tmp = "";
00751         }
00752         else
00753         {
00754             token = tmp.left(tmp.indexOf(","));
00755             tmp = tmp.right(tmp.length() - tmp.indexOf(",") - 1);
00756         }
00757 
00758         token = token.trimmed();
00759         if (token == "*") // Import all source doc pages
00760         {
00761             for (int i = 1; i <= sourcePageCount; ++i)
00762                 pageNs->push_back(i);
00763         }
00764         else if (token.indexOf("-") != -1) // import a range of source doc pages
00765         {
00766             from = QString(token.left(token.indexOf("-"))).toInt();
00767             to = QString(token.right(token.length() - token.indexOf("-") - 1)).toInt();
00768             if ((from != 0) && (to != 0))
00769             {
00770                 if (from > sourcePageCount)
00771                     from = sourcePageCount;
00772                 if (to > sourcePageCount)
00773                     to = sourcePageCount;
00774                 if (from == to)
00775                     pageNs->push_back(to);
00776                 else if (from < to)
00777                 {
00778                     for (int i = from; i <= to; ++i)
00779                         pageNs->push_back(i);
00780                 }
00781                 else
00782                 {
00783                     for (int i = from; i >= to; --i)
00784                         pageNs->push_back(i);
00785                 }
00786             }
00787         }
00788         else // import single source doc page
00789         {
00790             pageNr = token.toInt();
00791             if ((pageNr > 0) && (pageNr <= sourcePageCount))
00792                 pageNs->push_back(pageNr);
00793         }
00794     } while (!tmp.isEmpty());
00795 }
00796 
00797 
00798 int findParagraphStyle(ScribusDoc* doc, const ParagraphStyle& parStyle)
00799 {
00800     bool named = !parStyle.name().isEmpty();
00801 //qDebug(QString("looking up %1/ %2").arg(parStyle.name()).arg(parStyle.alignment())); 
00802     if (named) {
00803         for (int i=0; i < doc->paragraphStyles().count(); ++i)
00804         {
00805 //qDebug(QString("%1 %2").arg(i).arg(doc->paragraphStyles()[i].name()));
00806             if (parStyle.name() == doc->paragraphStyles()[i].name()) {
00807                 return i;
00808             }
00809         }
00810         assert(false);
00811         return -1;
00812     }
00813     else {
00814         return -1;
00815     }
00816 }
00817 
00818 int findParagraphStyle(ScribusDoc* doc, const QString &name)
00819 {
00820     for (int i=0; i < doc->paragraphStyles().count(); ++i)
00821     {
00822         if (name == doc->paragraphStyles()[i].name()) {
00823             return i;
00824         }
00825     }
00826     assert(false);
00827     return -1;
00828 }
00829 
00830 
00831 void tDebug(QString message)
00832 {
00833     QDateTime debugTime;
00834     qDebug("%s", QString("%1\t%2").arg(debugTime.currentDateTime().toString("hh:mm:ss:zzz")).arg(message).toAscii().constData());
00835 }
00836 
00837 
00838 QString readLinefromDataStream(QDataStream &s)
00839 {
00840     QString ret = "";
00841     uchar charData;
00842     while (!s.atEnd())
00843     {
00844         s >> charData;
00845         if (charData == '\x0A')
00846             break;
00847         if (charData == '\x0D')
00848         {
00849             quint64 oldPos = s.device()->pos();
00850             s >> charData;
00851             if (charData != '\x0A')
00852                 s.device()->seek(oldPos);
00853             break;
00854         }
00855         ret += QChar(charData);
00856     }
00857     return ret.trimmed();
00858 }
00859 
00860 void setCurrentComboItem(QComboBox *box, QString text)
00861 {
00862     box->blockSignals(true);
00863     int ind = box->findText(text);
00864     if (ind > -1)
00865         box->setCurrentIndex(ind);
00866     box->blockSignals(false);
00867 }
00868 
00869 QString getDashString(int dashtype, double linewidth)
00870 {
00871     QString Dt = QString::number(qMax(1.0*linewidth, 0.1));
00872     QString Sp = QString::number(qMax(2.0*linewidth, 0.1));
00873     QString Da = QString::number(qMax(4.0*linewidth, 0.1));
00874     QString tmp = "";
00875     switch (dashtype)
00876     {
00877         case 1:
00878             break;
00879         case 2:
00880             tmp += Da+" "+Sp;
00881             break;
00882         case 3:
00883             tmp += Dt+" "+Sp;
00884             break;
00885         case 4:
00886             tmp += Da+" "+Sp+" "+Dt+" "+Sp;
00887             break;
00888         case 5:
00889             tmp += Da+" "+Sp+" "+Dt+" "+Sp+" "+Dt+" "+Sp;
00890             break;
00891 // Additional line styles taken from Inkscape
00892         case 6:
00893             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00894             break;
00895         case 7:
00896             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(3.0 * linewidth, 0.01));
00897             break;
00898         case 8:
00899             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(4.0 * linewidth, 0.01));
00900             break;
00901         case 9:
00902             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(6.0 * linewidth, 0.01));
00903             break;
00904         case 10:
00905             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(8.0 * linewidth, 0.01));
00906             break;
00907         case 11:
00908             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(12.0 * linewidth, 0.01));
00909             break;
00910         case 12:
00911             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(24.0 * linewidth, 0.01));
00912             break;
00913         case 13:
00914             tmp += QString("%1 %2").arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(48.0 * linewidth, 0.01));
00915             break;
00916         case 14:
00917             tmp += QString("%1 %2").arg(qMax(2.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00918             break;
00919         case 15:
00920             tmp += QString("%1 %2").arg(qMax(3.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00921             break;
00922         case 16:
00923             tmp += QString("%1 %2").arg(qMax(4.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00924             break;
00925         case 17:
00926             tmp += QString("%1 %2").arg(qMax(6.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00927             break;
00928         case 18:
00929             tmp += QString("%1 %2").arg(qMax(8.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00930             break;
00931         case 19:
00932             tmp += QString("%1 %2").arg(qMax(10.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00933             break;
00934         case 20:
00935             tmp += QString("%1 %2").arg(qMax(12.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00936             break;
00937         case 21:
00938             tmp += QString("%1 %2").arg(qMax(2.0 * linewidth, 0.01)).arg(qMax(2.0 * linewidth, 0.01));
00939             break;
00940         case 22:
00941             tmp += QString("%1 %2").arg(qMax(3.0 * linewidth, 0.01)).arg(qMax(3.0 * linewidth, 0.01));
00942             break;
00943         case 23:
00944             tmp += QString("%1 %2").arg(qMax(4.0 * linewidth, 0.01)).arg(qMax(4.0 * linewidth, 0.01));
00945             break;
00946         case 24:
00947             tmp += QString("%1 %2").arg(qMax(6.0 * linewidth, 0.01)).arg(qMax(6.0 * linewidth, 0.01));
00948             break;
00949         case 25:
00950             tmp += QString("%1 %2").arg(qMax(8.0 * linewidth, 0.01)).arg(qMax(8.0 * linewidth, 0.01));
00951             break;
00952         case 26:
00953             tmp += QString("%1 %2").arg(qMax(10.0 * linewidth, 0.01)).arg(qMax(10.0 * linewidth, 0.01));
00954             break;
00955         case 27:
00956             tmp += QString("%1 %2").arg(qMax(12.0 * linewidth, 0.01)).arg(qMax(12.0 * linewidth, 0.01));
00957             break;
00958         case 28:
00959             tmp += QString("%1 %2").arg(qMax(2.0 * linewidth, 0.01)).arg(qMax(4.0 * linewidth, 0.01));
00960             break;
00961         case 29:
00962             tmp += QString("%1 %2").arg(qMax(2.0 * linewidth, 0.01)).arg(qMax(6.0 * linewidth, 0.01));
00963             break;
00964         case 30:
00965             tmp += QString("%1 %2").arg(qMax(6.0 * linewidth, 0.01)).arg(qMax(2.0 * linewidth, 0.01));
00966             break;
00967         case 31:
00968             tmp += QString("%1 %2").arg(qMax(4.0 * linewidth, 0.01)).arg(qMax(8.0 * linewidth, 0.01));
00969             break;
00970         case 32:
00971             tmp += QString("%1 %2").arg(qMax(8.0 * linewidth, 0.01)).arg(qMax(4.0 * linewidth, 0.01));
00972             break;
00973         case 33:
00974             tmp += QString("%1 %2 %3 %4").arg(qMax(2.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(0.5 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01));
00975             break;
00976         case 34:
00977             tmp += QString("%1 %2 %3 %4").arg(qMax(8.0 * linewidth, 0.01)).arg(qMax(2.0 * linewidth, 0.01)).arg(qMax(1.0 * linewidth, 0.01)).arg(qMax(2.0 * linewidth, 0.01));
00978             break;
00979         case 35:
00980             tmp += QString("%1 %2").arg(qMax(0.5 * linewidth, 0.01)).arg(qMax(0.5 * linewidth, 0.01));
00981             break;
00982         case 36:
00983             tmp += QString("%1 %2").arg(qMax(0.25 * linewidth, 0.01)).arg(qMax(0.25 * linewidth, 0.01));
00984             break;
00985         case 37:
00986             tmp += QString("%1 %2").arg(qMax(0.1 * linewidth, 0.01)).arg(qMax(0.1 * linewidth, 0.01));
00987             break;
00988         default:
00989             break;
00990     }
00991     return tmp;
00992 }
00993 
00994 void getDashArray(int dashtype, double linewidth, QList<double> &m_array)
00995 {
00996     m_array.clear();
00997     if ((dashtype == 1) || (dashtype == 0))
00998         return;
00999     QString tmp = getDashString(dashtype, linewidth);
01000     QStringList dashes = tmp.split(" ");
01001     for (int a = 0; a < dashes.size(); a++)
01002     {
01003         m_array.append(dashes[a].toDouble());
01004     }
01005 }
Created with personalized Doxygen. This is documentation for GPL software Scribus - Open Source Desktop Publishing.