Subversion Repositories Scribus

Rev

Rev 19200 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
8 paul 7
/***************************************************************************
8
                          util.cpp  -  description
9
                             -------------------
10
    begin                : Fri Sep 14 2001
11
    copyright            : (C) 2001 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
9 Franz 23
 
12464 cbradney 24
#include <algorithm>
12461 avox 25
#include "util.h"
26
#include <zlib.h>
17942 jghali 27
 
12461 avox 28
#include <QCryptographicHash>
10203 cbradney 29
#include <QDomElement>
17942 jghali 30
#include <QMessageBox>
10006 cbradney 31
#include <QProcess>
17942 jghali 32
 
12461 avox 33
#include "pageitem.h"
214 Franz 34
#include "scribus.h"
6125 cbradney 35
#include "scribusdoc.h"
12461 avox 36
#include "scpainter.h"
8 paul 37
 
12820 pierre 38
#include <signal.h>
12821 jghali 39
 
18163 craig 40
#if !defined(_WIN32) && !defined(Q_OS_MAC) && !defined(Q_OS_HAIKU) 
12820 pierre 41
#include <execinfo.h>
12855 pierre 42
#include <cxxabi.h>
12821 jghali 43
#endif
15706 jghali 44
#if defined(_WIN32)
45
#include <windows.h>
46
#endif
12820 pierre 47
 
10246 cbradney 48
using namespace std;
690 cbradney 49
 
10246 cbradney 50
void sDebug(QString message)
3240 fschmid 51
{
10592 fschmid 52
        qDebug("%s", message.toAscii().constData());
3240 fschmid 53
}
54
 
11777 jghali 55
int System(const QString exename, const QStringList & args, const QString fileStdErr, const QString fileStdOut, bool* cancel)
204 Franz 56
{
10592 fschmid 57
        QProcess proc;
11021 jghali 58
        if (!fileStdOut.isEmpty())
59
                proc.setStandardOutputFile(fileStdOut);
60
        if (!fileStdErr.isEmpty())
61
                proc.setStandardErrorFile(fileStdErr);
62
        proc.start(exename, args);
10592 fschmid 63
        if (proc.waitForStarted(5000))
4194 fschmid 64
        {
10592 fschmid 65
                while (!proc.waitForFinished(5000))
66
                {
67
                        qApp->processEvents();
11777 jghali 68
                        if (cancel && (*cancel == true))
69
                        {
70
                                proc.kill();
71
                                break;
72
                        }
4924 cbradney 73
                }
4194 fschmid 74
        }
11777 jghali 75
        if (cancel && (*cancel == true))
76
                return -1;
10592 fschmid 77
        int ex = proc.exitCode();
204 Franz 78
        return ex;
79
}
80
 
2885 fschmid 81
// On Windows, return short path name, else return longPath;
12071 subik 82
QString getShortPathName(const QString & longPath)
2885 fschmid 83
{
4505 cbradney 84
        QString shortPath(longPath);
2885 fschmid 85
#if defined _WIN32
86
        QFileInfo fInfo(longPath);
10304 jghali 87
        if (fInfo.exists())
2885 fschmid 88
        {
10304 jghali 89
                WCHAR shortName[MAX_PATH + 1];
2885 fschmid 90
                // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
91
                // that volume does not support 8.3 filenames, so return longPath in this case
16576 craig 92
                QString nativePath = QDir::toNativeSeparators(longPath);
10304 jghali 93
                int ret = GetShortPathNameW((LPCWSTR) nativePath.utf16(), shortName, MAX_PATH);
94
                if (ret != ERROR_INVALID_PARAMETER && ret < MAX_PATH)
95
                        shortPath = QString::fromUtf16((const ushort*) shortName);
2885 fschmid 96
        }
97
#endif
98
        return shortPath;
99
}
100
 
12192 jghali 101
// On Windows, return short path name, else return longPath;
102
QString getLongPathName(const QString & shortPath)
103
{
104
        QString longPath(shortPath);
105
#if defined _WIN32
106
        QFileInfo fInfo(longPath);
107
        if (fInfo.exists())
108
        {
109
                WCHAR longName[MAX_PATH + 1];
110
                // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
111
                // that volume does not support long filenames, so return shortPath in this case
16576 craig 112
                QString nativePath = QDir::toNativeSeparators(shortPath);
12192 jghali 113
                int ret = GetLongPathNameW((LPCWSTR) nativePath.utf16(), longName, MAX_PATH);
114
                if (ret != ERROR_INVALID_PARAMETER && ret < MAX_PATH)
115
                        longPath = QString::fromUtf16((const ushort*) longName);
116
        }
117
#endif
118
        return longPath;
119
}
204 Franz 120
 
8 paul 121
QString GetAttr(QDomElement *el, QString at, QString def)
122
{
123
        return el->attribute(at, def);
124
}
125
 
1109 fschmid 126
 
3158 craig 127
// Legacy implementation of LoadText with incorrect
128
// handling of unicode data. This should be retired.
129
// Use loadRawText instead.
130
// FIXME XXX
131
//
690 cbradney 132
bool loadText(QString filename, QString *Buffer)
8 paul 133
{
690 cbradney 134
        QFile f(filename);
8 paul 135
        QFileInfo fi(f);
136
        if (!fi.exists())
137
                return false;
167 Franz 138
        bool ret;
10592 fschmid 139
        QByteArray bb(f.size(), ' ');
8501 cbradney 140
        if (f.open(QIODevice::ReadOnly))
167 Franz 141
        {
10592 fschmid 142
                f.read(bb.data(), f.size());
8 paul 143
                f.close();
8546 cbradney 144
                for (int posi = 0; posi < bb.size(); ++posi)
3027 fschmid 145
                        *Buffer += QChar(bb[posi]);
3497 avox 146
                /*
147
                int len = bb.size();
148
                int oldLen = Buffer->length();
149
                Buffer->setLength( oldLen + len + 1);
150
                // digged into Qt 3.3 sources to find that. Might break in Qt 4 -- AV
151
                unsigned short * ucsString = const_cast<unsigned short *>(Buffer->ucs2()) + oldLen;
152
                char * data = bb.data();
153
                for (uint posi = 0; posi < len; ++posi)
10200 cbradney 154
                *ucsString++ = *data++;
3497 avox 155
                *ucsString = 0;
10200 cbradney 156
                */
8 paul 157
                ret = true;
167 Franz 158
        }
8 paul 159
        else
160
                ret = false;
161
        return ret;
162
}
163
 
9535 fschmid 164
bool loadRawText(const QString & filename, QByteArray & buf)
3158 craig 165
{
166
        bool ret = false;
167
        QFile f(filename);
168
        QFileInfo fi(f);
169
        if (fi.exists())
170
        {
12188 jghali 171
                // Allocating one more bytes for null terminator is unneeded with Qt4
172
                // as QByteArray ensure null termination automatically
173
                // Triggers also QDomDocument parsing errors
174
                QByteArray tempBuf(f.size() /*+ 1*/, ' ');
8501 cbradney 175
                if (f.open(QIODevice::ReadOnly))
3158 craig 176
                {
10592 fschmid 177
                        unsigned int bytesRead = f.read(tempBuf.data(), f.size());
12188 jghali 178
                        /*tempBuf[bytesRead] = '\0';*/
3158 craig 179
                        ret = bytesRead == f.size();
180
                        if (ret)
181
                                buf = tempBuf; // sharing makes this efficient
182
                }
183
        }
184
        if (f.isOpen())
185
                f.close();
186
        return ret;
187
}
188
 
5234 fschmid 189
bool loadRawBytes(const QString & filename, QByteArray & buf)
190
{
191
        bool ret = false;
192
        QFile f(filename);
193
        QFileInfo fi(f);
194
        if (fi.exists())
195
        {
10592 fschmid 196
                QByteArray tempBuf(f.size(), ' ');
8501 cbradney 197
                if (f.open(QIODevice::ReadOnly))
5234 fschmid 198
                {
10592 fschmid 199
                        unsigned int bytesRead = f.read(tempBuf.data(), f.size());
5234 fschmid 200
                        ret = bytesRead == f.size();
201
                        if (ret)
202
                                buf = tempBuf; // sharing makes this efficient
203
                }
204
        }
205
        if (f.isOpen())
206
                f.close();
207
        return ret;
208
}
209
 
8 paul 210
 
211
QString CompressStr(QString *in)
212
{
213
        QString out = "";
10592 fschmid 214
        QByteArray bb(in->length(), ' ');
9997 jghali 215
        if (bb.size() == in->length())
3158 craig 216
        {
9997 jghali 217
                for (int ax = 0; ax < in->length(); ++ax)
218
                {
219
                        // bb.insert(ax, in->at(ax)); JG monstruously inefficient due to frequent memory reallocation
220
                        bb[ax] = in->at(ax).cell();
221
                        assert(in->at(ax).row() == 0);
222
                }
10018 fschmid 223
                uLong exlen = (uLong)(bb.size() * 0.001 + 16) + bb.size();
10592 fschmid 224
                QByteArray bc(exlen, ' ');
10018 fschmid 225
                if( bc.size() == static_cast<qint32>(exlen) )
9997 jghali 226
                {
227
                        int errcode = compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
228
                        if (errcode != Z_OK)
229
                        {
230
                                qDebug("compress2 failed with code %i", errcode);
231
                                out = *in;
232
                        }
233
                        else {
234
                                for (uint cl = 0; cl < exlen; ++cl)
235
                                        out += QChar(bc[cl]);
236
                        }
237
                }
238
                else
239
                {
240
                        qDebug("insufficient memory to allocate %i bytes", in->length());
241
                        out = *in;
242
                }
243
        }
244
        else
245
        {
246
                qDebug("insufficient memory to allocate %i bytes", in->length());
2295 cbradney 247
                out = *in;
248
        }
8 paul 249
        return out;
250
}
251
 
11317 jghali 252
QByteArray CompressArray(const QByteArray& in)
5234 fschmid 253
{
254
        QByteArray out;
11317 jghali 255
        uLong exlen = uint(in.size() * 0.001 + 16) + in.size();
10592 fschmid 256
        QByteArray temp(exlen, ' ');
11317 jghali 257
        int errcode = compress2((Byte *)temp.data(), &exlen, (Byte *)in.data(), uLong(in.size()), 9);
258
        if (errcode == Z_OK)
5234 fschmid 259
        {
260
                temp.resize(exlen);
261
                out = temp;
262
        }
11317 jghali 263
        else
264
                qDebug("compress2 failed with code %i", errcode);
5234 fschmid 265
        return out;
266
}
267
 
11107 jghali 268
char *toAscii85( quint32 value, bool& allZero )
269
{
270
        int digit, i;
271
        static char asciiVal[6];
272
        allZero = true;
273
    for (i = 0; i < 5; ++i)
274
        {
275
                digit = value % 85;
276
                if (digit != 0)
277
                        allZero = false;
278
                asciiVal[4-i] = digit + 33;
279
                value = (value - digit) / 85;
280
    }
281
        asciiVal[5] = 0;
282
        return asciiVal;
283
}
284
 
8 paul 285
char *toHex( uchar u )
286
{
1555 fschmid 287
        static char hexVal[3];
288
        int i = 1;
289
        while ( i >= 0 )
167 Franz 290
        {
291
                ushort hex = (u & 0x000f);
292
                if ( hex < 0x0a )
1555 fschmid 293
                        hexVal[i] = '0'+hex;
167 Franz 294
                else
1555 fschmid 295
                        hexVal[i] = 'A'+(hex-0x0a);
167 Franz 296
                u = u >> 4;
1555 fschmid 297
                i--;
298
        }
299
        hexVal[2] = '\0';
300
        return hexVal;
8 paul 301
}
302
 
303
QString String2Hex(QString *in, bool lang)
304
{
305
        int i = 0;
8546 cbradney 306
        QString out("");
307
        for( int xi = 0; xi < in->length(); ++xi )
167 Franz 308
        {
8663 subik 309
                // Qt4 .cell() added ???
8799 jghali 310
                out += toHex(QChar(in->at(xi)).cell());
8 paul 311
                ++i;
312
                if ((i>40) && (lang))
167 Franz 313
                {
8 paul 314
                        out += '\n';
315
                        i=0;
316
                }
167 Franz 317
        }
8 paul 318
        return out;
319
}
320
 
321
QByteArray ComputeMD5Sum(QByteArray *in)
322
{
10692 fschmid 323
        return QCryptographicHash::hash(*in, QCryptographicHash::Md5);
324
//      QByteArray MDsum(16, ' ');
325
//      md5_buffer (in->data(), in->size(), reinterpret_cast<void*>(MDsum.data()));
326
//      return MDsum;
8 paul 327
}
328
 
10259 jghali 329
QString Path2Relative(QString Path, const QString& baseDir)
19 Franz 330
{
10259 jghali 331
        QDir d(baseDir);
9717 fschmid 332
        return d.relativeFilePath(Path);
10200 cbradney 333
}
3089 fschmid 334
 
10259 jghali 335
QString Relative2Path(QString File, const QString& baseDir)
336
{
337
        QString   absPath;
338
        QFileInfo fi(File);
339
        if (File.isEmpty())
340
                absPath = File;
341
        else if (fi.isRelative())
167 Franz 342
        {
10259 jghali 343
                QDir d(baseDir);
344
                absPath = d.absoluteFilePath(File);
345
                absPath = QDir::cleanPath(absPath);
346
        }
10200 cbradney 347
        else
10259 jghali 348
                absPath = File;
349
        return absPath;
10200 cbradney 350
}
3089 fschmid 351
 
90 Franz 352
/***************************************************************************
353
    begin                : Wed Oct 29 2003
354
    copyright            : (C) 2003 The Scribus Team
355
    email                : paul@all-the-johnsons.co.uk
356
 ***************************************************************************/
357
// check if the file exists, if it does, ask if they're sure
358
// return true if they're sure, else return false;
359
 
360
bool overwrite(QWidget *parent, QString filename)
361
{
167 Franz 362
        bool retval = true;
363
        QFileInfo fi(filename);
364
        if (fi.exists())
1555 fschmid 365
        {
16576 craig 366
                QString fn = QDir::toNativeSeparators(filename);
9706 cbradney 367
                int t = QMessageBox::warning(parent, QObject::tr("File exists"),
10200 cbradney 368
                                                                         "<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>",
369
                                                                                         QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
9422 fschmid 370
                if (t == QMessageBox::Cancel)
90 Franz 371
                        retval = false;
1555 fschmid 372
        }
373
        return retval;
90 Franz 374
}
124 Franz 375
 
1957 cbradney 376
void WordAndPara(PageItem* currItem, int *w, int *p, int *c, int *wN, int *pN, int *cN)
125 Franz 377
{
378
        QChar Dat = QChar(32);
379
        int para = 0;
380
        int ww = 0;
381
        int cc = 0;
382
        int paraN = 0;
383
        int wwN = 0;
384
        int ccN = 0;
385
        bool first = true;
1957 cbradney 386
        PageItem *nextItem = currItem;
387
        PageItem *nbl = currItem;
388
        while (nextItem != 0)
167 Franz 389
        {
7994 avox 390
                if (nextItem->prevInChain() != 0)
391
                        nextItem = nextItem->prevInChain();
125 Franz 392
                else
393
                        break;
167 Franz 394
        }
1957 cbradney 395
        while (nextItem != 0)
167 Franz 396
        {
8562 jghali 397
                for (int a = qMax(nextItem->firstInFrame(),0); a <= nextItem->lastInFrame() && a < nextItem->itemText.length(); ++a)
1555 fschmid 398
                {
5184 avox 399
                        QChar b = nextItem->itemText.text(a);
5732 avox 400
                        if (b == SpecialChars::PARSEP)
167 Franz 401
                        {
5732 avox 402
                                para++;
167 Franz 403
                        }
125 Franz 404
                        if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
167 Franz 405
                        {
5732 avox 406
                                ww++;
167 Franz 407
                        }
5732 avox 408
                        cc++;
1555 fschmid 409
                        Dat = b;
125 Franz 410
                        first = false;
1555 fschmid 411
                }
1957 cbradney 412
                nbl = nextItem;
7994 avox 413
                nextItem = nextItem->nextInChain();
167 Franz 414
        }
5732 avox 415
        if (nbl->frameOverflows()) {
125 Franz 416
                paraN++;
5736 avox 417
                for (int a = nbl->lastInFrame()+1; a < nbl->itemText.length(); ++a)
5732 avox 418
                {
5736 avox 419
                        QChar b = nbl->itemText.text(a);
5732 avox 420
                        if (b == SpecialChars::PARSEP)
421
                        {
422
                                paraN++;
423
                        }
424
                        if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
425
                        {
426
                                wwN++;
427
                        }
428
                        ccN++;
429
                        Dat = b;
430
                        first = false;
431
                }
432
        }              
433
        else {
125 Franz 434
                para++;
5732 avox 435
        }
125 Franz 436
        if (Dat.isLetterOrNumber())
167 Franz 437
        {
5559 avox 438
                if (nbl->frameOverflows())
125 Franz 439
                        wwN++;
440
                else
441
                        ww++;
167 Franz 442
        }
125 Franz 443
        *w = ww;
444
        *p = para;
445
        *c = cc;
446
        *wN = wwN;
447
        *pN = paraN;
448
        *cN = ccN;
449
}
203 Franz 450
 
690 cbradney 451
void ReOrderText(ScribusDoc *currentDoc, ScribusView *view)
203 Franz 452
{
4593 cbradney 453
        double savScale = view->scale();
2380 cbradney 454
        view->setScale(1.0);
690 cbradney 455
        currentDoc->RePos = true;
9319 fschmid 456
        QImage pgPix(10, 10, QImage::Format_ARGB32);
10840 avox 457
        QRect rd; // = QRect(0,0,9,9);
203 Franz 458
        ScPainter *painter = new ScPainter(&pgPix, pgPix.width(), pgPix.height());
9903 fschmid 459
        for (int azz=0; azz<currentDoc->MasterItems.count(); ++azz)
203 Franz 460
        {
1957 cbradney 461
                PageItem *currItem = currentDoc->MasterItems.at(azz);
462
                if (currItem->itemType() == PageItem::PathText)
463
                        currItem->DrawObj(painter, rd);
203 Franz 464
        }
9903 fschmid 465
        for (int azz=0; azz<currentDoc->Items->count(); ++azz)
203 Franz 466
        {
3727 cbradney 467
                PageItem *currItem = currentDoc->Items->at(azz);
11388 avox 468
                currItem->layout();
469
                if (currItem->itemType() == PageItem::PathText)
470
                        currItem->DrawObj(painter, rd); //FIXME: this should be replaced by code in layout()
203 Franz 471
        }
690 cbradney 472
        currentDoc->RePos = false;
2380 cbradney 473
        view->setScale(savScale);
203 Franz 474
        delete painter;
475
}
447 cbradney 476
 
4449 subik 477
/*! \brief Helper function for sorting in sortQStringList.
478
\author 10/06/2004 - pv
4645 subik 479
\param s1 first string
480
\param s2 second string
447 cbradney 481
\retval bool t/f related s1>s2
482
 */
483
bool compareQStrings(QString s1, QString s2)
484
{
485
        if (QString::localeAwareCompare(s1, s2) >= 0)
2680 cbradney 486
                return false;
487
        return true;
447 cbradney 488
}
489
 
490
QStringList sortQStringList(QStringList aList)
491
{
492
        std::vector<QString> sortList;
493
        QStringList retList;
494
        QStringList::Iterator it;
495
        for (it = aList.begin(); it != aList.end(); ++it)
496
                sortList.push_back(*it);
497
        std::sort(sortList.begin(), sortList.end(), compareQStrings);
456 fschmid 498
        for(uint i = 0; i < sortList.size(); i++)
447 cbradney 499
                retList.append(sortList[i]);
500
        return retList;
501
}
517 fschmid 502
 
16603 craig 503
bool sortingQPairOfStrings( QPair<QString, QString> aP, QPair<QString, QString> bP)
504
{
505
        if (aP.first == bP.first)
506
                return (aP.second < bP.second);
507
        return (aP.first < bP.first);
508
}
509
 
2834 cbradney 510
QString checkFileExtension(const QString &currName, const QString &extension)
511
{
512
        QString newName(currName);
513
        //If filename ends with a period, just add the extension
514
        if (newName.right(1)==".")
515
        {
10398 cbradney 516
                newName+=extension.toLower();
2834 cbradney 517
                return newName;
518
        }
519
        //If filename doesnt end with the period+extension, add it on
10398 cbradney 520
        QString dotExt("." + extension.toLower());
10592 fschmid 521
        if (!newName.endsWith(dotExt, Qt::CaseInsensitive))
2834 cbradney 522
                newName+=dotExt;
523
        return newName;
524
}
2907 subik 525
 
5781 cbradney 526
QString getFileNameByPage(ScribusDoc* currDoc, uint pageNo, QString extension)
2907 subik 527
{
9791 jghali 528
        uint number = pageNo + currDoc->FirstPnum;
5781 cbradney 529
        QString defaultName = currDoc->DocName;
2907 subik 530
        if (defaultName.isNull())
531
                defaultName = "export";
532
        else
533
        {
534
                QFileInfo fi(defaultName);
10469 cbradney 535
                defaultName = fi.completeBaseName();
2907 subik 536
        }
9791 jghali 537
        return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number, 3, 10, QChar('0')).arg(extension);
2907 subik 538
}
3689 cbradney 539
 
3757 cbradney 540
const QString getStringFromSequence(DocumentSectionType type, uint position)
541
{
542
        QString retVal("");
543
        switch( type )
544
        {
3778 cbradney 545
                case Type_1_2_3:
546
                        retVal=QString::number(position);
547
                        break;
3757 cbradney 548
                case Type_A_B_C:
10398 cbradney 549
                        retVal=numberToLetterSequence(position).toUpper();
3778 cbradney 550
                        break;
3757 cbradney 551
                case Type_a_b_c:
3778 cbradney 552
                        retVal=numberToLetterSequence(position);
3757 cbradney 553
                        break;
554
                case Type_I_II_III:
555
                        retVal=arabicToRoman(position);
556
                        break;
557
                case Type_i_ii_iii:
558
                        //well, for lower case people will want that, even if its "wrong"
559
                        //ie, X=10, x=10000
10398 cbradney 560
                        retVal=arabicToRoman(position).toLower();
3757 cbradney 561
                        break;
8439 cbradney 562
                case Type_None:
563
                        break;
3757 cbradney 564
                default:
565
                        break;
566
        }
567
        return retVal;
568
}
569
 
570
const QString numberToLetterSequence(uint i)
571
{
572
        QString retVal("");
573
        unsigned digits = 1;
574
        unsigned offset = 0;
575
        uint column=i;
576
        --column;
577
 
578
        if( column > 4058115285U ) return  QString("@");
579
 
580
        for( unsigned limit = 26; column >= limit+offset; limit *= 26, digits++ )
581
                offset += limit;
582
 
583
        for( unsigned c = column - offset; digits; --digits, c/=26 )
584
                retVal.prepend( QChar( 'a' + (c%26) ) );
585
        return retVal;
586
}
587
 
588
const QString arabicToRoman(uint i)
589
{
590
        QString roman("");
591
        int arabic = i;
592
        while (arabic - 1000000 >= 0){
10200 cbradney 593
                roman += "m";
594
                arabic -= 1000000;
3757 cbradney 595
        }
596
        while (arabic - 900000 >= 0){
10200 cbradney 597
                roman += "cm";
598
                arabic -= 900000;
3757 cbradney 599
        }
600
        while (arabic - 500000 >= 0){
10200 cbradney 601
                roman += "d";
602
                arabic -= 500000;
3757 cbradney 603
        }
604
        while (arabic - 400000 >= 0){
10200 cbradney 605
                roman += "cd";
606
                arabic -= 400000;
3757 cbradney 607
        }
608
        while (arabic - 100000 >= 0){
10200 cbradney 609
                roman += "c";
610
                arabic -= 100000;
3757 cbradney 611
        }
612
        while (arabic - 90000 >= 0){
10200 cbradney 613
                roman += "xc";
614
                arabic -= 90000;
3757 cbradney 615
        }
616
        while (arabic - 50000 >= 0){
10200 cbradney 617
                roman += "l";
618
                arabic -= 50000;
3757 cbradney 619
        }
620
        while (arabic - 40000 >= 0){
10200 cbradney 621
                roman += "xl";
622
                arabic -= 40000;
3757 cbradney 623
        }
624
        while (arabic - 10000 >= 0){
10200 cbradney 625
                roman += "x";
626
                arabic -= 10000;
3757 cbradney 627
        }
628
        while (arabic - 9000 >= 0){
10200 cbradney 629
                roman += "Mx";
630
                arabic -= 9000;
3757 cbradney 631
        }
632
        while (arabic - 5000 >= 0){
10200 cbradney 633
                roman += "v";
634
                arabic -= 5000;
3757 cbradney 635
        }
636
        while (arabic - 4000 >= 0){
10200 cbradney 637
                roman += "Mv";
638
                arabic -= 4000;
3757 cbradney 639
        }
640
        while (arabic - 1000 >= 0){
10200 cbradney 641
                roman += "M";
642
                arabic -= 1000;
3757 cbradney 643
        }
644
        while (arabic - 900 >= 0){
10200 cbradney 645
                roman += "CM";
646
                arabic -= 900;
3757 cbradney 647
        }
648
        while (arabic - 500 >= 0){
10200 cbradney 649
                roman += "D";
650
                arabic -= 500;
3757 cbradney 651
        }
652
        while (arabic - 400 >= 0){
10200 cbradney 653
                roman += "CD";
654
                arabic -= 400;
3757 cbradney 655
        }
656
        while (arabic - 100 >= 0){
10200 cbradney 657
                roman += "C";
658
                arabic -= 100;
3757 cbradney 659
        }
660
        while (arabic - 90 >= 0){
10200 cbradney 661
                roman += "XC";
662
                arabic -= 90;
3757 cbradney 663
        }
664
        while (arabic - 50 >= 0){
10200 cbradney 665
                roman += "L";
666
                arabic -= 50;
3757 cbradney 667
        }
668
        while (arabic - 40 >= 0){
10200 cbradney 669
                roman += "XL";
670
                arabic -= 40;
3757 cbradney 671
        }
672
        while (arabic - 10 >= 0){
10200 cbradney 673
                roman += "X";
674
                arabic -= 10;
3757 cbradney 675
        }
676
        while (arabic - 9 >= 0){
10200 cbradney 677
                roman += "IX";
678
                arabic -= 9;
3757 cbradney 679
        }
680
        while (arabic - 5 >= 0){
10200 cbradney 681
                roman += "V";
682
                arabic -= 5;
3757 cbradney 683
        }
684
        while (arabic - 4 >= 0){
10200 cbradney 685
                roman += "IV";
686
                arabic -= 4;
3757 cbradney 687
        }
688
        while (arabic - 1 >= 0){
10200 cbradney 689
                roman += "I";
690
                arabic -= 1;
3757 cbradney 691
        }
692
        return roman;
3776 cbradney 693
}
3784 cbradney 694
 
695
//CB Moved from scribus.cpp
696
void parsePagesString(QString pages, std::vector<int>* pageNs, int sourcePageCount)
697
{
698
        QString tmp(pages);
699
        QString token;
700
        int from, to, pageNr;
701
        do
702
        {
10517 cbradney 703
                if (tmp.indexOf(",") == -1)
3784 cbradney 704
                {
705
                        token = tmp;
706
                        tmp = "";
707
                }
708
                else
709
                {
10517 cbradney 710
                        token = tmp.left(tmp.indexOf(","));
711
                        tmp = tmp.right(tmp.length() - tmp.indexOf(",") - 1);
3784 cbradney 712
                }
713
 
10394 cbradney 714
                token = token.trimmed();
3784 cbradney 715
                if (token == "*") // Import all source doc pages
716
                {
717
                        for (int i = 1; i <= sourcePageCount; ++i)
718
                                pageNs->push_back(i);
719
                }
10517 cbradney 720
                else if (token.indexOf("-") != -1) // import a range of source doc pages
3784 cbradney 721
                {
10517 cbradney 722
                        from = QString(token.left(token.indexOf("-"))).toInt();
723
                        to = QString(token.right(token.length() - token.indexOf("-") - 1)).toInt();
3784 cbradney 724
                        if ((from != 0) && (to != 0))
725
                        {
726
                                if (from > sourcePageCount)
727
                                        from = sourcePageCount;
728
                                if (to > sourcePageCount)
729
                                        to = sourcePageCount;
730
                                if (from == to)
731
                                        pageNs->push_back(to);
732
                                else if (from < to)
733
                                {
734
                                        for (int i = from; i <= to; ++i)
735
                                                pageNs->push_back(i);
736
                                }
737
                                else
738
                                {
739
                                        for (int i = from; i >= to; --i)
740
                                                pageNs->push_back(i);
741
                                }
742
                        }
743
                }
744
                else // import single source doc page
745
                {
746
                        pageNr = token.toInt();
747
                        if ((pageNr > 0) && (pageNr <= sourcePageCount))
748
                                pageNs->push_back(pageNr);
749
                }
750
        } while (!tmp.isEmpty());
3793 cbradney 751
}
5184 avox 752
 
5890 subik 753
void tDebug(QString message)
754
{
755
        QDateTime debugTime;
10592 fschmid 756
        qDebug("%s", QString("%1\t%2").arg(debugTime.currentDateTime().toString("hh:mm:ss:zzz")).arg(message).toAscii().constData());
5890 subik 757
}
6116 fschmid 758
 
9970 fschmid 759
 
9991 fschmid 760
QString readLinefromDataStream(QDataStream &s)
9970 fschmid 761
{
762
        QString ret = "";
9991 fschmid 763
        uchar charData;
9970 fschmid 764
        while (!s.atEnd())
765
        {
9991 fschmid 766
                s >> charData;
767
                if (charData == '\x0A')
768
                        break;
769
                if (charData == '\x0D')
9970 fschmid 770
                {
9991 fschmid 771
                        quint64 oldPos = s.device()->pos();
772
                        s >> charData;
773
                        if (charData != '\x0A')
774
                                s.device()->seek(oldPos);
9970 fschmid 775
                        break;
776
                }
9991 fschmid 777
                ret += QChar(charData);
9970 fschmid 778
        }
779
        return ret.trimmed();
780
}
10648 fschmid 781
 
782
void setCurrentComboItem(QComboBox *box, QString text)
783
{
19295 jghali 784
        bool sigBlocked = box->blockSignals(true);
10648 fschmid 785
        int ind = box->findText(text);
786
        if (ind > -1)
787
                box->setCurrentIndex(ind);
19295 jghali 788
        box->blockSignals(sigBlocked);
10648 fschmid 789
}
10988 fschmid 790
 
791
QString getDashString(int dashtype, double linewidth)
792
{
12055 jghali 793
        QString dashString;
794
        QVector<double> dashArray;
795
        getDashArray(dashtype, linewidth, dashArray);
796
        for (int a = 0; a < dashArray.size(); ++a)
797
        {
798
                dashString += QString::number(dashArray.at(a));
799
                if (a < (dashArray.size() - 1))
800
                        dashString += " ";
801
        }
802
        return dashString;
803
}
804
 
19200 jghali 805
void getDashArray(int dashtype, double linewidth, QVector<float> &dashArray)
806
{
807
        QVector<double> tmp;
808
        getDashArray(dashtype, linewidth, tmp);
809
        dashArray.clear();
810
        for (int i = 0; i < tmp.count(); ++i) {
811
                dashArray << static_cast<float>(tmp[i]);
812
        }
13099 malex 813
}
814
 
19200 jghali 815
void getDashArray(int dashtype, double linewidth, QVector<double> &dashArray)
12055 jghali 816
{
19200 jghali 817
        dashArray.clear();
12055 jghali 818
        if ((dashtype == 1) || (dashtype == 0))
819
                return;
820
        double Dt = qMax(1.0*linewidth, 0.1);
821
        double Sp = qMax(2.0*linewidth, 0.1);
822
        double Da = qMax(4.0*linewidth, 0.1);
10988 fschmid 823
        switch (dashtype)
824
        {
825
                case 1:
826
                        break;
827
                case 2:
19200 jghali 828
                        dashArray << Da << Sp;
10988 fschmid 829
                        break;
830
                case 3:
19200 jghali 831
                        dashArray << Dt << Sp;
10988 fschmid 832
                        break;
833
                case 4:
19200 jghali 834
                        dashArray << Da << Sp << Dt << Sp;
10988 fschmid 835
                        break;
836
                case 5:
19200 jghali 837
                        dashArray << Da << Sp << Dt << Sp << Dt << Sp;
10988 fschmid 838
                        break;
839
// Additional line styles taken from Inkscape
11177 fschmid 840
                case 6:
19200 jghali 841
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 842
                        break;
843
                case 7:
19200 jghali 844
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(3.0 * linewidth, 0.01);
10988 fschmid 845
                        break;
846
                case 8:
19200 jghali 847
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
10988 fschmid 848
                        break;
849
                case 9:
19200 jghali 850
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(6.0 * linewidth, 0.01);
10988 fschmid 851
                        break;
852
                case 10:
19200 jghali 853
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(8.0 * linewidth, 0.01);
10988 fschmid 854
                        break;
855
                case 11:
19200 jghali 856
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(12.0 * linewidth, 0.01);
10988 fschmid 857
                        break;
858
                case 12:
19200 jghali 859
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(24.0 * linewidth, 0.01);
10988 fschmid 860
                        break;
861
                case 13:
19200 jghali 862
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(48.0 * linewidth, 0.01);
10988 fschmid 863
                        break;
864
                case 14:
19200 jghali 865
                        dashArray << qMax(2.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 866
                        break;
867
                case 15:
19200 jghali 868
                        dashArray << qMax(3.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 869
                        break;
870
                case 16:
19200 jghali 871
                        dashArray << qMax(4.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 872
                        break;
873
                case 17:
19200 jghali 874
                        dashArray << qMax(6.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 875
                        break;
876
                case 18:
19200 jghali 877
                        dashArray << qMax(8.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 878
                        break;
879
                case 19:
19200 jghali 880
                        dashArray << qMax(10.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 881
                        break;
882
                case 20:
19200 jghali 883
                        dashArray << qMax(12.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 884
                        break;
885
                case 21:
19200 jghali 886
                        dashArray << qMax(2.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
10988 fschmid 887
                        break;
888
                case 22:
19200 jghali 889
                        dashArray << qMax(3.0 * linewidth, 0.01) << qMax(3.0 * linewidth, 0.01);
10988 fschmid 890
                        break;
891
                case 23:
19200 jghali 892
                        dashArray << qMax(4.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
10988 fschmid 893
                        break;
894
                case 24:
19200 jghali 895
                        dashArray << qMax(6.0 * linewidth, 0.01) << qMax(6.0 * linewidth, 0.01);
10988 fschmid 896
                        break;
897
                case 25:
19200 jghali 898
                        dashArray << qMax(8.0 * linewidth, 0.01) << qMax(8.0 * linewidth, 0.01);
10988 fschmid 899
                        break;
900
                case 26:
19200 jghali 901
                        dashArray << qMax(10.0 * linewidth, 0.01) << qMax(10.0 * linewidth, 0.01);
10988 fschmid 902
                        break;
903
                case 27:
19200 jghali 904
                        dashArray << qMax(12.0 * linewidth, 0.01) << qMax(12.0 * linewidth, 0.01);
10988 fschmid 905
                        break;
906
                case 28:
19200 jghali 907
                        dashArray << qMax(2.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
10988 fschmid 908
                        break;
909
                case 29:
19200 jghali 910
                        dashArray << qMax(2.0 * linewidth, 0.01) << qMax(6.0 * linewidth, 0.01);
10988 fschmid 911
                        break;
912
                case 30:
19200 jghali 913
                        dashArray << qMax(6.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
10988 fschmid 914
                        break;
915
                case 31:
19200 jghali 916
                        dashArray << qMax(4.0 * linewidth, 0.01) << qMax(8.0 * linewidth, 0.01);
10988 fschmid 917
                        break;
918
                case 32:
19200 jghali 919
                        dashArray << qMax(8.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
10988 fschmid 920
                        break;
921
                case 33:
19200 jghali 922
                        dashArray << qMax(2.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
923
                        dashArray << qMax(0.5 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
10988 fschmid 924
                        break;
925
                case 34:
19200 jghali 926
                        dashArray << qMax(8.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
927
                        dashArray << qMax(1.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
10988 fschmid 928
                        break;
929
                case 35:
19200 jghali 930
                        dashArray << qMax(0.5 * linewidth, 0.01) << qMax(0.5 * linewidth, 0.01);
10988 fschmid 931
                        break;
932
                case 36:
19200 jghali 933
                        dashArray << qMax(0.25 * linewidth, 0.01) << qMax(0.25 * linewidth, 0.01);
10988 fschmid 934
                        break;
935
                case 37:
19200 jghali 936
                        dashArray << qMax(0.1 * linewidth, 0.01) << qMax(0.1 * linewidth, 0.01);
11177 fschmid 937
                        break;
10988 fschmid 938
                default:
939
                        break;
940
        }
941
}
12820 pierre 942
 
943
/**
944
 * Print a backtrace
12830 jghali 945
 * Please never commit code that uses it.
12820 pierre 946
 * @param nFrames specify how much frames you want to be printed
947
 */
12855 pierre 948
void printBacktrace ( int nFrames )
12820 pierre 949
{
18163 craig 950
#if !defined(_WIN32) && !defined(Q_OS_MAC) && !defined(Q_OS_OPENBSD)  && !defined(Q_OS_FREEBSD) && !defined(Q_OS_HAIKU)
12830 jghali 951
        void ** trace = new void*[nFrames + 1];
952
        char **messages = ( char ** ) NULL;
953
        int i, trace_size = 0;
12820 pierre 954
 
12855 pierre 955
        trace_size = backtrace ( trace, nFrames + 1 );
12830 jghali 956
        messages = backtrace_symbols ( trace, trace_size );
12855 pierre 957
        if ( messages )
12830 jghali 958
        {
959
                for ( i=1; i < trace_size; ++i )
960
                {
12855 pierre 961
                        QString msg ( messages[i] );
962
                        int sep1 ( msg.indexOf ( "(" ) );
963
                        int sep2 ( msg.indexOf ( "+" ) );
964
                        QString mName ( msg.mid ( sep1 + 1,sep2-sep1 -1) );
965
 
966
                        QString name;
967
                        if(mName.startsWith("_Z"))
968
                        {
969
                                char* outbuf = 0;
970
                                size_t length = 0;
971
                                int status = 0;
972
                                outbuf = abi::__cxa_demangle(mName.trimmed().toAscii().data(), outbuf, &length, &status);
973
                                name = QString::fromAscii( outbuf,length );
974
                                if(!status)
975
                                        free(outbuf);
976
                        }
977
                        else
978
                                name = mName;
979
                        QString bts ( "[ScBT] %1. %2" );
13085 jghali 980
                        qDebug ("%s", bts.arg( i ).arg( name ).toUtf8().data() );
12830 jghali 981
                }
12855 pierre 982
                free ( messages );
12830 jghali 983
        }
984
        delete[] trace;
15398 craig 985
#endif
12820 pierre 986
}
12821 jghali 987