Subversion Repositories Scribus

Rev

Rev 4453 | Rev 4505 | 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
 
2529 craig 24
#include "util.h"
8 paul 25
#include <qbitmap.h>
26
#include <qpainter.h>
27
#include <qfile.h>
28
#include <qfileinfo.h>
29
#include <qtextstream.h>
1541 fschmid 30
#include <qdatastream.h>
2295 cbradney 31
#include <qregexp.h>
19 Franz 32
#include <qdir.h>
2632 craig 33
#include <algorithm>
8 paul 34
#include <cstdlib>
35
#include <cmath>
2702 craig 36
 
37
#include "scconfig.h"
38
 
39
#ifdef HAVE_UNISTD_H
213 Franz 40
#include <unistd.h>
2702 craig 41
#endif
42
 
2730 cbradney 43
#if defined(_WIN32)
44
#if defined(_MSC_VER)
45
#define __STDC__ 1 // hack to get md5_buffer correctly identified
46
#endif
3810 cbradney 47
#include <valarray>
2730 cbradney 48
#include <windows.h>
49
#endif
50
 
8 paul 51
#include "md5.h"
2730 cbradney 52
 
201 Franz 53
#include <setjmp.h>
3733 cbradney 54
#include "commonstrings.h"
3757 cbradney 55
#include "pagestructs.h"
2517 craig 56
#include "prefsfile.h"
57
#include "prefscontext.h"
58
#include "prefstable.h"
2834 cbradney 59
#include "prefsmanager.h"
3733 cbradney 60
#include "qprocess.h"
61
#include "scmessagebox.h"
62
#include "scpaths.h"
128 Franz 63
 
1555 fschmid 64
extern "C"
65
{
201 Franz 66
#define XMD_H           // shut JPEGlib up
67
#if defined(Q_OS_UNIXWARE)
68
#  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
69
#endif
70
#include <jpeglib.h>
71
#include <jerror.h>
72
#undef HAVE_STDLIB_H
73
#ifdef const
74
#  undef const          // remove crazy C hackery in jconfig.h
75
#endif
76
}
77
 
214 Franz 78
#include "scribus.h"
68 Franz 79
#include <ft2build.h>
80
#include FT_FREETYPE_H
81
#include FT_OUTLINE_H
82
#include FT_GLYPH_H
8 paul 83
#ifdef HAVE_LIBZ
84
        #include <zlib.h>
85
#endif
86
#ifdef HAVE_TIFF
87
        #include <tiffio.h>
88
#endif
89
#ifdef HAVE_CMS
44 Franz 90
        #include CMS_INC
1555 fschmid 91
extern cmsHPROFILE CMSoutputProf;
92
extern cmsHPROFILE CMSprinterProf;
1781 fschmid 93
extern cmsHTRANSFORM stdTransG;
94
extern cmsHTRANSFORM stdProofG;
95
extern cmsHTRANSFORM stdTransImgG;
96
extern cmsHTRANSFORM stdProofImgG;
1555 fschmid 97
extern bool BlackPoint;
98
extern bool SoftProofing;
99
extern bool Gamut;
100
extern bool CMSuse;
101
extern int IntentMonitor;
102
extern int IntentPrinter;
8 paul 103
#endif
104
 
3205 craig 105
 
690 cbradney 106
using namespace std;
107
 
3240 fschmid 108
void sDebug(QString message)
109
{
110
        qDebug("%s", message.ascii());
111
}
112
 
690 cbradney 113
QImage ProofImage(QImage *Image)
8 paul 114
{
115
#ifdef HAVE_CMS
690 cbradney 116
        QImage out = Image->copy();
8 paul 117
        if ((CMSuse) && (SoftProofing))
167 Franz 118
        {
3200 cbradney 119
                int outheight=out.height();
120
                for (int i=0; i < outheight; ++i)
8 paul 121
                {
122
                        LPBYTE ptr = out.scanLine(i);
1781 fschmid 123
                        cmsDoTransform(stdProofImgG, ptr, ptr, out.width());
8 paul 124
                }
167 Franz 125
        }
8 paul 126
        else
167 Franz 127
        {
128
                if (CMSuse)
8 paul 129
                {
3200 cbradney 130
                        int outheight=out.height();
131
                        for (int i=0; i < outheight; ++i)
8 paul 132
                        {
133
                                LPBYTE ptr = out.scanLine(i);
1781 fschmid 134
                                cmsDoTransform(stdTransImgG, ptr, ptr, out.width());
8 paul 135
                        }
136
                }
167 Franz 137
        }
8 paul 138
        return out;
139
#else
690 cbradney 140
        return Image->copy();
8 paul 141
#endif
142
}
143
 
4194 fschmid 144
int System(const QStringList & args, const QString fileStdErr, const QString fileStdOut)
204 Franz 145
{
4243 mrdocs 146
        QStringList stdErrData;
147
        QStringList stdOutData;
148
        QStringList::iterator pIterator;
149
        QStringList::iterator pEnd;
150
        QProcess proc(args);
4194 fschmid 151
        if ( !proc.start() )
204 Franz 152
                return 1;
153
        /* start was OK */
690 cbradney 154
        /* wait a little bit */
4243 mrdocs 155
        while( proc.isRunning() || proc.canReadLineStdout() || proc.canReadLineStderr() )
4194 fschmid 156
        {
2730 cbradney 157
#ifndef _WIN32
204 Franz 158
                usleep(5000);
2730 cbradney 159
#else
160
                Sleep(5);
161
#endif
4243 mrdocs 162
                // Some configurations needs stdout and stderr to be read
163
                // if needed before the created process can exit
164
                if ( proc.canReadLineStdout() )
165
                        stdOutData.append( proc.readLineStdout() );
166
                if ( proc.canReadLineStderr() )
167
                        stdErrData.append( proc.readLineStderr() );
4194 fschmid 168
        }
169
        // TODO: What about proc.normalExit() ?
170
        int ex = proc.exitStatus();
690 cbradney 171
 
4194 fschmid 172
        if ( !fileStdErr.isEmpty() )
173
        {
174
                QFile ferr(fileStdErr);
175
                if ( ferr.open(IO_WriteOnly) )
176
                {
4243 mrdocs 177
                        pEnd = stdErrData.end();
178
                        QTextStream errStream(&ferr);
179
                        for ( pIterator = stdErrData.begin(); pIterator != pEnd; pIterator++ )
180
                                errStream << *pIterator << endl;
4194 fschmid 181
                        ferr.close();
182
                }
183
        }
184
 
185
        if ( !fileStdOut.isEmpty() )
186
        {
187
                QFile fout(fileStdOut);
188
                if ( fout.open(IO_WriteOnly) )
189
                {
4243 mrdocs 190
                        pEnd = stdOutData.end();
191
                        QTextStream outStream(&fout);
192
                        for ( pIterator = stdOutData.begin(); pIterator != pEnd; pIterator++ )
193
                                outStream << *pIterator << endl;
4194 fschmid 194
                        fout.close();
195
                }
196
        }
204 Franz 197
        return ex;
198
}
199
 
4194 fschmid 200
int callGS(const QStringList& args_in, const QString device)
201
{
202
        QString cmd;
203
        QStringList args;
204
        PrefsManager* prefsManager = PrefsManager::instance();
205
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
206
        args.append( "-q" );
207
        args.append( "-dNOPAUSE" );
208
        args.append( "-dQUIET" );
209
        args.append( "-dPARANOIDSAFER" );
210
        args.append( "-dBATCH" );
211
        // Choose rendering device
212
        if (!device.isEmpty())
213
                args.append( QString("-sDEVICE=%1").arg(device) ); // user specified device
214
        else if (ScMW->HavePngAlpha != 0)
215
                args.append( "-sDEVICE=png16m" );
216
        else
217
                args.append( "-sDEVICE=pngalpha" );
218
        // and antialiasing
219
        if (prefsManager->appPrefs.gs_AntiAliasText)
220
                args.append( "-dTextAlphaBits=4" );
221
        if (prefsManager->appPrefs.gs_AntiAliasGraphics)
222
                args.append( "-dGraphicsAlphaBits=4" );
2529 craig 223
 
4194 fschmid 224
        // Add any extra font paths being used by Scribus to gs's font search path
225
        PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
226
        PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
227
        const char sep = ScPaths::envPathSeparator;
228
        if (extraFonts->getRowCount() >= 1)
229
                cmd = QString("-sFONTPATH=%1").arg(extraFonts->get(0,0));
230
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
231
                cmd += QString("%1%2").arg(sep).arg(extraFonts->get(i,0));
232
        if( !cmd.isEmpty() )
233
                args.append( cmd );
1555 fschmid 234
 
4194 fschmid 235
        args += args_in;
236
        args.append("-c");
237
        args.append("showpage");
238
        return System( args );
2529 craig 239
}
240
 
241
int callGS(const QString& args_in, const QString device)
242
{
2834 cbradney 243
        PrefsManager* prefsManager=PrefsManager::instance();
2885 fschmid 244
        QString cmd1 = getShortPathName(prefsManager->ghostscriptExecutable());
3317 craig 245
        cmd1 += " -q -dNOPAUSE -dQUIET -dPARANOIDSAFER -dBATCH";
2529 craig 246
        // Choose rendering device
2877 cbradney 247
        if (!device.isEmpty())
2529 craig 248
                // user specified device
249
                cmd1 += " -sDEVICE="+device;
4026 craig 250
        else if (ScMW->HavePngAlpha != 0)
1186 fschmid 251
                cmd1 += " -sDEVICE=png16m";
214 Franz 252
        else
1186 fschmid 253
                cmd1 += " -sDEVICE=pngalpha";
2529 craig 254
        // and antialiasing
2834 cbradney 255
        if (prefsManager->appPrefs.gs_AntiAliasText)
1186 fschmid 256
                cmd1 += " -dTextAlphaBits=4";
2834 cbradney 257
        if (prefsManager->appPrefs.gs_AntiAliasGraphics)
1186 fschmid 258
                cmd1 += " -dGraphicsAlphaBits=4";
2517 craig 259
 
260
        // Add any extra font paths being used by Scribus to gs's font search path
2856 cbradney 261
        PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
2517 craig 262
        PrefsTable *extraFonts = pc->getTable("ExtraFontDirs");
2843 fschmid 263
#ifndef _WIN32
2517 craig 264
        if (extraFonts->getRowCount() >= 1)
265
                cmd1 += QString(" -sFONTPATH='%1'").arg(extraFonts->get(0,0));
266
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
267
                cmd1 += QString(":'%1'").arg(extraFonts->get(i,0));
2843 fschmid 268
#else
269
        if (extraFonts->getRowCount() >= 1)
270
                cmd1 += QString(" -sFONTPATH=\"%1\"").arg(extraFonts->get(0,0));
271
        for (int i = 1; i < extraFonts->getRowCount(); ++i)
272
                cmd1 += QString(";\"%1\"").arg(extraFonts->get(i,0));
273
#endif
2517 craig 274
 
275
        // then add any user specified args and run gs
3317 craig 276
        cmd1 += " " + args_in + " -c showpage";
2621 fschmid 277
//      qDebug("Calling gs as: %s", cmd1.ascii());
2642 craig 278
        return system(cmd1.local8Bit());
204 Franz 279
}
4194 fschmid 280
 
281
int  convertPS2PS(QString in, QString out, const QStringList& opts, int level)
3083 fschmid 282
{
283
        PrefsManager* prefsManager=PrefsManager::instance();
4194 fschmid 284
        QStringList args;
285
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
286
        args.append( "-q" );
287
        args.append( "-dQUIET" );
288
        args.append( "-dNOPAUSE" );
289
        args.append( "-dPARANOIDSAFER" );
290
        args.append( "-dBATCH" );
291
        args.append( "-sDEVICE=pswrite" );
3083 fschmid 292
        if(level <= 3)
4194 fschmid 293
                args.append( QString("-dLanguageLevel=%1").arg(level) );
294
        args += opts;
295
        args.append( QString("-sOutputFile=%1").arg(QDir::convertSeparators(out)) );
296
        args.append( QDir::convertSeparators(in) );
297
        int ret = System( args );
3083 fschmid 298
        return ret;
299
}
204 Franz 300
 
4193 craig 301
int  testGSAvailability( void )
302
{
303
        QStringList args;
304
        PrefsManager* prefsManager = PrefsManager::instance();
305
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
306
        args.append( "-h" );
307
        int ret = System( args );
308
        return ret;
309
}
310
 
311
int  testGSDeviceAvailability( QString device )
312
{
313
        QStringList args;
314
        PrefsManager* prefsManager = PrefsManager::instance();
315
        args.append( getShortPathName(prefsManager->ghostscriptExecutable()) );
316
        args.append( QString("-sDEVICE=%1").arg( device ) );
317
        args.append( "-c" );
318
        args.append( "quit" );
319
        int ret = System( args );
320
        return ret;
321
}
322
 
2840 craig 323
// Return the GhostScript version string, or QString::null if it couldn't be retrived.
324
QString getGSVersion()
325
{
2885 fschmid 326
        QString gsVer;
327
        QStringList args;
328
        QString gsExe = getShortPathName(PrefsManager::instance()->ghostscriptExecutable());
329
        args.append(gsExe.local8Bit());
330
        args.append(QString("--version").local8Bit());
4194 fschmid 331
        QProcess proc(args);
332
        proc.setCommunication(QProcess::Stdout);
333
        proc.start();
334
        while(proc.isRunning())
2885 fschmid 335
        {
336
#ifndef _WIN32
337
                usleep(5000);
338
#else
339
                Sleep(5);
340
#endif
341
                qApp->processEvents();
342
        }
4194 fschmid 343
        if(!proc.exitStatus())
344
                gsVer = proc.readLineStdout();
2885 fschmid 345
        return gsVer;
2840 craig 346
}
347
 
348
// Return the GhostScript major and minor version numbers.
349
bool getNumericGSVersion(int & major, int & minor)
350
{
351
        QString gs_ver_string(getGSVersion());
352
        // gs's version string is of the form MAJOR.MINOR, so look for the .
353
        // then convert to numbers. 7.07 will become (7,7) for example.
354
        bool success = false;
355
        major = gs_ver_string.section('.', 0, 0).toInt(&success);
356
        if (!success)
357
                return false;
358
        minor = gs_ver_string.section('.', 1, 1).toInt(&success);
359
        if (!success)
360
                return false;
361
        return true;
362
}
363
 
2910 fschmid 364
QString getGSDefaultExeName(void)
365
{
366
        QString gsName;
367
#if defined _WIN32
368
        // Try to locate GhostScript thanks to the registry
369
        DWORD size;
370
        HKEY hKey;
371
        LONG retValue;
372
        DWORD regType = REG_SZ;
373
        char regVersion[MAX_PATH];
374
        char regPath[MAX_PATH];
375
        char gsPath[MAX_PATH];
376
 
377
        // Set gsName to its default value
378
        gsName = "gswin32c.exe";
2954 subik 379
 
2910 fschmid 380
        // Search AFPL Ghostscript first as it has more chance to be up to date
381
        if( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\AFPL Ghostscript", &hKey) == ERROR_SUCCESS )
382
                strcpy(regPath, "SOFTWARE\\AFPL Ghostscript");
2954 subik 383
        else if( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\GPL Ghostscript", &hKey) == ERROR_SUCCESS )
2910 fschmid 384
                strcpy(regPath, "SOFTWARE\\GPL Ghostscript");
385
        else
386
                return gsName;
387
 
388
        // Search the first SubKey corresponding to the version key
389
        size = sizeof(regVersion) - 1;
390
        retValue = RegEnumKeyEx(hKey, 0, regVersion, &size, NULL, NULL, NULL, NULL);
391
        RegCloseKey(hKey);
392
        if( retValue != ERROR_SUCCESS )
393
                return gsName;
394
 
395
        strcat(regPath, "\\");
396
        strcat(regPath, regVersion);
397
 
398
        // Get the GS_DLL Value
399
        if (RegOpenKey(HKEY_LOCAL_MACHINE, regPath, &hKey) != ERROR_SUCCESS)
400
          return gsName;
401
        size = sizeof(gsPath) - 1;
402
        retValue = RegQueryValueEx(hKey, "GS_DLL", 0, &regType, (LPBYTE) gsPath, &size);
403
        RegCloseKey(hKey);
404
        if( retValue != ERROR_SUCCESS )
405
                return gsName;
2954 subik 406
 
2910 fschmid 407
        // We now have GhostScript dll path, but we want gswin32c.exe
408
        // Normally gswin32c.exe and gsdll.dll are in the same directory
409
        gsName = gsPath;
410
        size = gsName.findRev("\\");
411
        if(size <= 0)
412
                return QString("gswin32c.exe");
413
        gsName = gsName.left(size + 1);
414
        gsName += "gswin32c.exe";
415
 
416
        // Check GhostScript executable existence.
417
        QFileInfo fInfo(gsName);
418
        if( fInfo.exists() )
419
                gsName.replace("\\", "/"); // Return a qt-styled path
420
        else
421
                gsName = "gswin32c.exe";
422
 
423
#else
424
        gsName = "gs";
425
#endif
426
        return gsName;
427
}
428
 
2885 fschmid 429
// On Windows, return short path name, else return longPath;
430
QString getShortPathName(QString longPath)
431
{
432
        QString shortPath = longPath;
433
#if defined _WIN32
434
        QFileInfo fInfo(longPath);
435
        if(fInfo.exists())
436
        {
437
                char shortName[MAX_PATH + 1];
438
                // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
439
                // that volume does not support 8.3 filenames, so return longPath in this case
440
                int ret = GetShortPathName(QDir::convertSeparators(longPath).local8Bit(), shortName, sizeof(shortName));
441
                if( ret != ERROR_INVALID_PARAMETER && ret < sizeof(shortName))
442
                        shortPath = shortName;
443
        }
444
#endif
445
        return shortPath;
446
}
447
 
204 Franz 448
int copyFile(QString source, QString target)
449
{
4193 craig 450
        int bytesread;
204 Franz 451
        if ((source.isNull()) || (target.isNull()))
452
                return -1;
453
        if (source == target)
454
                return -1;
455
        QFile s(source);
456
        QFile t(target);
457
        if (!s.exists())
458
                return -1;
4193 craig 459
        QByteArray bb( 65536 );
204 Franz 460
        if (s.open(IO_ReadOnly))
461
        {
462
                if (t.open(IO_WriteOnly))
463
                {
4193 craig 464
                        bytesread = s.readBlock( bb.data(), bb.size() );
465
                        while( bytesread > 0 )
466
                        {
467
                                t.writeBlock( bb.data(), bytesread );
468
                                bytesread = s.readBlock( bb.data(), bb.size() );
469
                        }
204 Franz 470
                        t.close();
471
                }
4193 craig 472
                s.close();
204 Franz 473
        }
474
        return 0;
475
}
476
 
477
int moveFile(QString source, QString target)
478
{
479
        if ((source.isNull()) || (target.isNull()))
480
                return -1;
481
        if (source == target)
482
                return -1;
483
        copyFile(source, target);
2921 fschmid 484
        QFile::remove(source);
204 Franz 485
        return 0;
486
}
487
 
690 cbradney 488
QPixmap LoadPDF(QString fn, int Page, int Size, int *w, int *h)
19 Franz 489
{
490
        QString tmp, cmd1, cmd2;
2843 fschmid 491
        QString pdfFile = QDir::convertSeparators(fn);
282 Franz 492
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
19 Franz 493
        QPixmap pm;
494
        int ret = -1;
690 cbradney 495
        tmp.setNum(Page);
204 Franz 496
        QStringList args;
497
        args.append("-r72");
2843 fschmid 498
        args.append("-sOutputFile=\""+tmpFile+"\"");
204 Franz 499
        args.append("-dFirstPage="+tmp);
500
        args.append("-dLastPage="+tmp);
2843 fschmid 501
        args.append("\""+pdfFile+"\"");
204 Franz 502
        ret = callGS(args);
19 Franz 503
        if (ret == 0)
167 Franz 504
        {
19 Franz 505
                QImage image;
159 Franz 506
                image.load(tmpFile);
204 Franz 507
                unlink(tmpFile);
1555 fschmid 508
                QImage im2;
20 Franz 509
                *h = image.height();
510
                *w = image.width();
80 Franz 511
                double sx = image.width() / static_cast<double>(Size);
512
                double sy = image.height() / static_cast<double>(Size);
167 Franz 513
                double t = (sy < sx ? sx : sy);
514
                im2 = image.smoothScale(static_cast<int>(image.width() / t), static_cast<int>(image.height() / t));
19 Franz 515
                pm.convertFromImage(im2);
516
                QPainter p;
517
                p.begin(&pm);
518
                p.setBrush(Qt::NoBrush);
519
                p.setPen(Qt::black);
520
                p.drawRect(0, 0, pm.width(), pm.height());
521
                p.end();
522
                im2.detach();
167 Franz 523
        }
19 Franz 524
        return pm;
525
}
526
 
8 paul 527
QString GetAttr(QDomElement *el, QString at, QString def)
528
{
529
        return el->attribute(at, def);
530
}
531
 
532
QPixmap loadIcon(QString nam)
533
{
1693 craig 534
        QString iconFilePath = QString("%1/%2").arg(ScPaths::instance().iconDir()).arg(nam);
8 paul 535
        QPixmap pm;
1672 craig 536
        if (!QFile::exists(iconFilePath))
537
                qWarning("Unable to load icon %s: File not found", iconFilePath.ascii());
538
        else
539
        {
540
                pm.load(iconFilePath);
541
                if (pm.isNull())
542
                        qWarning("Unable to load icon %s: Got null pixmap", iconFilePath.ascii());
543
        }
8 paul 544
        return pm;
545
}
546
 
1109 fschmid 547
uint getDouble(QString in, bool raw)
548
{
549
        QByteArray bb(4);
550
        if (raw)
551
        {
552
                bb[3] = static_cast<uchar>(QChar(in.at(0)));
553
                bb[2] = static_cast<uchar>(QChar(in.at(1)));
554
                bb[1] = static_cast<uchar>(QChar(in.at(2)));
555
                bb[0] = static_cast<uchar>(QChar(in.at(3)));
556
        }
557
        else
558
        {
559
                bb[0] = static_cast<uchar>(QChar(in.at(0)));
560
                bb[1] = static_cast<uchar>(QChar(in.at(1)));
561
                bb[2] = static_cast<uchar>(QChar(in.at(2)));
562
                bb[3] = static_cast<uchar>(QChar(in.at(3)));
563
        }
564
        uint ret;
565
        ret = bb[0] & 0xff;
566
        ret |= (bb[1] << 8) & 0xff00;
567
        ret |= (bb[2] << 16) & 0xff0000;
568
        ret |= (bb[3] << 24) & 0xff000000;
569
        return ret;
570
}
571
 
3158 craig 572
// Legacy implementation of LoadText with incorrect
573
// handling of unicode data. This should be retired.
574
// Use loadRawText instead.
575
// FIXME XXX
576
//
690 cbradney 577
bool loadText(QString filename, QString *Buffer)
8 paul 578
{
690 cbradney 579
        QFile f(filename);
8 paul 580
        QFileInfo fi(f);
581
        if (!fi.exists())
582
                return false;
167 Franz 583
        bool ret;
8 paul 584
        QByteArray bb(f.size());
585
        if (f.open(IO_ReadOnly))
167 Franz 586
        {
8 paul 587
                f.readBlock(bb.data(), f.size());
588
                f.close();
690 cbradney 589
                for (uint posi = 0; posi < bb.size(); ++posi)
3027 fschmid 590
                        *Buffer += QChar(bb[posi]);
3497 avox 591
                /*
592
                int len = bb.size();
593
                int oldLen = Buffer->length();
594
                Buffer->setLength( oldLen + len + 1);
595
                // digged into Qt 3.3 sources to find that. Might break in Qt 4 -- AV
596
                unsigned short * ucsString = const_cast<unsigned short *>(Buffer->ucs2()) + oldLen;
597
                char * data = bb.data();
598
                for (uint posi = 0; posi < len; ++posi)
599
                        *ucsString++ = *data++;
600
                *ucsString = 0;
601
                 */
8 paul 602
                ret = true;
167 Franz 603
        }
8 paul 604
        else
605
                ret = false;
606
        return ret;
607
}
608
 
3646 craig 609
bool loadRawText(const QString & filename, QCString & buf)
3158 craig 610
{
611
        bool ret = false;
612
        QFile f(filename);
613
        QFileInfo fi(f);
614
        if (fi.exists())
615
        {
616
                bool ret;
3646 craig 617
                QCString tempBuf(f.size() + 1);
3158 craig 618
                if (f.open(IO_ReadOnly))
619
                {
4193 craig 620
                        unsigned int bytesRead = f.readBlock(tempBuf.data(), f.size());
3646 craig 621
                        tempBuf[bytesRead] = '\0';
3158 craig 622
                        ret = bytesRead == f.size();
623
                        if (ret)
624
                                buf = tempBuf; // sharing makes this efficient
625
                }
626
        }
627
        if (f.isOpen())
628
                f.close();
629
        return ret;
630
}
631
 
80 Franz 632
QPointArray RegularPolygon(double w, double h, uint c, bool star, double factor, double rota)
8 paul 633
{
167 Franz 634
        uint cx = star ? c * 2 : c;
80 Franz 635
        double seg = 360.0 / cx;
636
        double sc = rota + 180.0;
637
        double di = factor;
8 paul 638
        int mx = 0;
639
        int my = 0;
640
        QPointArray pts = QPointArray();
641
        for (uint x = 0; x < cx; ++x)
167 Franz 642
        {
8 paul 643
                sc = seg * x + 180.0 + rota;
644
                if (star)
167 Franz 645
                {
646
                        double wf = x % 2 == 0 ? w / 2 : w / 2 * di;
647
                        double hf = x % 2 == 0 ? h / 2 : h / 2 * di;
648
                        mx = qRound(sin(sc / 180 * M_PI) * (wf) + (w/2));
649
                        my = qRound(cos(sc / 180 * M_PI) * (hf) + (h/2));
650
                }
8 paul 651
                else
167 Franz 652
                {
8 paul 653
                        mx = qRound(sin(sc / 180 * M_PI) * (w/2) + (w/2));
654
                        my = qRound(cos(sc / 180 * M_PI) * (h/2) + (h/2));
167 Franz 655
                }
8 paul 656
                pts.resize(x+1);
657
                pts.setPoint(x, mx, my);
167 Franz 658
        }
8 paul 659
        return pts;
660
}
661
 
80 Franz 662
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota)
8 paul 663
{
167 Franz 664
        uint cx = star ? c * 2 : c;
80 Franz 665
        double seg = 360.0 / cx;
666
        double sc = rota + 180.0;
667
        double di = factor;
668
        double mx = 0;
669
        double my = 0;
1884 fschmid 670
        FPointArray pts;
8 paul 671
        for (uint x = 0; x < cx; ++x)
167 Franz 672
        {
8 paul 673
                sc = seg * x + 180.0 + rota;
674
                if (star)
167 Franz 675
                {
676
                        double wf = x % 2 == 0 ? w / 2 : w / 2 * di;
677
                        double hf = x % 2 == 0 ? h / 2 : h / 2 * di;
678
                        mx = qRound(sin(sc / 180 * M_PI) * (wf) + (w/2));
679
                        my = qRound(cos(sc / 180 * M_PI) * (hf) + (h/2));
680
                }
8 paul 681
                else
167 Franz 682
                {
8 paul 683
                        mx = sin(sc / 180 * M_PI) * (w/2) + (w/2);
684
                        my = cos(sc / 180 * M_PI) * (h/2) + (h/2);
167 Franz 685
                }
8 paul 686
                pts.resize(x+1);
687
                pts.setPoint(x, mx, my);
167 Franz 688
        }
8 paul 689
        return pts;
690
}
691
 
692
QPointArray FlattenPath(FPointArray ina, QValueList<uint> &Segs)
693
{
694
        QPointArray Bez(4);
695
        QPointArray outa, cli;
696
        Segs.clear();
697
        if (ina.size() > 3)
167 Franz 698
        {
699
                for (uint poi=0; poi<ina.size()-3; poi += 4)
8 paul 700
                {
167 Franz 701
                        if (ina.point(poi).x() > 900000)
8 paul 702
                        {
703
                                outa.resize(outa.size()+1);
704
                                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
80 Franz 705
                                Segs.append(outa.size());
8 paul 706
                                continue;
167 Franz 707
                        }
8 paul 708
                        BezierPoints(&Bez, ina.pointQ(poi), ina.pointQ(poi+1), ina.pointQ(poi+3), ina.pointQ(poi+2));
709
                        cli = Bez.cubicBezier();
710
                        outa.putPoints(outa.size(), cli.size()-1, cli);
167 Franz 711
                }
8 paul 712
                outa.resize(outa.size()+1);
713
                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
167 Franz 714
        }
8 paul 715
        return outa;
716
}
717
 
80 Franz 718
double xy2Deg(double x, double y)
8 paul 719
{
720
        return (atan2(y,x)*(180.0/M_PI));
721
}
722
 
723
void BezierPoints(QPointArray *ar, QPoint n1, QPoint n2, QPoint n3, QPoint n4)
724
{
725
        ar->setPoint(0, n1);
726
        ar->setPoint(1, n2);
727
        ar->setPoint(2, n3);
728
        ar->setPoint(3, n4);
729
        return;
730
}
731
 
690 cbradney 732
void Level2Layer(ScribusDoc *currentDoc, struct Layer *ll, int Level)
8 paul 733
{
2955 fschmid 734
        uint layerCount=currentDoc->layerCount();
2937 cbradney 735
        for (uint la2 = 0; la2 < layerCount; ++la2)
167 Franz 736
        {
690 cbradney 737
                if (currentDoc->Layers[la2].Level == Level)
8 paul 738
                {
1065 cbradney 739
                        ll->isViewable = currentDoc->Layers[la2].isViewable;
740
                        ll->isPrintable = currentDoc->Layers[la2].isPrintable;
690 cbradney 741
                        ll->LNr = currentDoc->Layers[la2].LNr;
1737 fschmid 742
                        ll->Name = currentDoc->Layers[la2].Name;
8 paul 743
                        break;
744
                }
167 Franz 745
        }
8 paul 746
}
747
 
2937 cbradney 748
/* CB Replaced by ScribusDoc::layerLevelFromNumber
2122 fschmid 749
int Layer2Level(ScribusDoc *currentDoc, int LayerNr)
750
{
2937 cbradney 751
        int retVal=currentDoc->layerLevelFromNumber(LayerNr);
752
        int layerCount=currentDoc->layerCount();
753
        for (uint la2 = 0; la2 < layerCount; ++la2)
2122 fschmid 754
        {
755
                if (currentDoc->Layers[la2].LNr == LayerNr)
756
                        return currentDoc->Layers[la2].Level;
757
        }
758
        return 0;
759
}
2937 cbradney 760
*/
8 paul 761
QString CompressStr(QString *in)
762
{
763
        QString out = "";
764
#ifdef HAVE_LIBZ
765
        QByteArray bb(in->length());
766
        for (uint ax = 0; ax < in->length(); ++ax)
767
                bb[ax] = uchar(QChar(in->at(ax)));
768
        uLong exlen = uint(bb.size() * 0.001 + 16) + bb.size();
769
        QByteArray bc(exlen);
2295 cbradney 770
        int errcode = compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
3158 craig 771
        if (errcode != Z_OK)
772
        {
773
                qDebug("compress2 failed with code %i", errcode);
2295 cbradney 774
                out = *in;
775
        }
776
        else {
777
                for (uint cl = 0; cl < exlen; ++cl)
2884 fschmid 778
                        out += QChar(bc[cl]);
2295 cbradney 779
        }
8 paul 780
#else
781
        out = *in;
782
#endif
783
        return out;
784
}
785
 
786
char *toHex( uchar u )
787
{
1555 fschmid 788
        static char hexVal[3];
789
        int i = 1;
790
        while ( i >= 0 )
167 Franz 791
        {
792
                ushort hex = (u & 0x000f);
793
                if ( hex < 0x0a )
1555 fschmid 794
                        hexVal[i] = '0'+hex;
167 Franz 795
                else
1555 fschmid 796
                        hexVal[i] = 'A'+(hex-0x0a);
167 Franz 797
                u = u >> 4;
1555 fschmid 798
                i--;
799
        }
800
        hexVal[2] = '\0';
801
        return hexVal;
8 paul 802
}
803
 
804
QString String2Hex(QString *in, bool lang)
805
{
806
        int i = 0;
807
        QString out = "";
808
        for( uint xi = 0; xi < in->length(); ++xi )
167 Franz 809
        {
8 paul 810
                out += toHex(uchar(QChar(in->at(xi))));
811
                ++i;
812
                if ((i>40) && (lang))
167 Franz 813
                {
8 paul 814
                        out += '\n';
815
                        i=0;
816
                }
167 Franz 817
        }
8 paul 818
        return out;
819
}
820
 
821
QByteArray ComputeMD5Sum(QByteArray *in)
822
{
823
        QByteArray MDsum(16);
49 paul 824
        md5_buffer (in->data(), in->size(), reinterpret_cast<void*>(MDsum.data()));
8 paul 825
        return MDsum;
826
}
827
 
19 Franz 828
QString Path2Relative(QString Path)
829
{
830
        QString Ndir = "";
3089 fschmid 831
        QStringList Pdir;
19 Franz 832
        QFileInfo Bfi = QFileInfo(Path);
3089 fschmid 833
        QStringList Bdir;
690 cbradney 834
        bool end = true;
19 Franz 835
        uint dcoun = 0;
836
        uint dcoun2 = 0;
3089 fschmid 837
 
838
#ifndef _WIN32
839
        Pdir = QStringList::split("/", QDir::currentDirPath());
840
        Bdir = QStringList::split("/", Bfi.dirPath(true));
841
#else
842
        // On win32, file systems are case insensitive
843
        Pdir = QStringList::split("/", QDir::currentDirPath().lower());
844
        Bdir = QStringList::split("/", Bfi.dirPath(true).lower());
845
        // We must check that both path are located on same drive
846
        if( Pdir.size() > 0 && Bdir.size() > 0 )
847
        {
848
                QString drive = Bdir.front();
849
                QString currentDrive = Pdir.front();
850
                if( drive != currentDrive )
851
                        return Path;
852
        }
853
#endif
854
 
690 cbradney 855
        while (end)
167 Franz 856
        {
19 Franz 857
                if (Pdir[dcoun] == Bdir[dcoun])
858
                        dcoun++;
859
                else
860
                        break;
861
                if (dcoun > Pdir.count())
862
                        break;
167 Franz 863
        }
19 Franz 864
        dcoun2 = dcoun;
3089 fschmid 865
 
866
#ifdef _WIN32
867
        Bdir = QStringList::split("/", Bfi.dirPath(true));
868
#endif
869
 
19 Franz 870
        for (uint ddx2 = dcoun; ddx2 < Pdir.count(); ddx2++)
871
                Ndir += "../";
872
        for (uint ddx = dcoun2; ddx < Bdir.count(); ddx++)
873
                Ndir += Bdir[ddx]+"/";
874
        Ndir += Bfi.fileName();
875
        return Ndir;
876
}
877
 
90 Franz 878
/***************************************************************************
879
    begin                : Wed Oct 29 2003
880
    copyright            : (C) 2003 The Scribus Team
881
    email                : paul@all-the-johnsons.co.uk
882
 ***************************************************************************/
883
// check if the file exists, if it does, ask if they're sure
884
// return true if they're sure, else return false;
885
 
886
bool overwrite(QWidget *parent, QString filename)
887
{
167 Franz 888
        bool retval = true;
889
        QFileInfo fi(filename);
890
        if (fi.exists())
1555 fschmid 891
        {
3733 cbradney 892
                int t = ScMessageBox::warning(parent, QObject::tr("File exists"),
893
                                                                        "<qt>"+ QObject::tr("A file named '%1' already exists.<br/>Do you want to replace it with the file you are saving?").arg(filename) +"</qt>",
894
                                                                        QObject::tr("&Replace"), CommonStrings::tr_Cancel, "", 1, 1);
895
                if (t == 1)
90 Franz 896
                        retval = false;
1555 fschmid 897
        }
898
        return retval;
90 Franz 899
}
124 Franz 900
 
1957 cbradney 901
void WordAndPara(PageItem* currItem, int *w, int *p, int *c, int *wN, int *pN, int *cN)
125 Franz 902
{
903
        QChar Dat = QChar(32);
904
        int para = 0;
905
        int ww = 0;
906
        int cc = 0;
907
        int paraN = 0;
908
        int wwN = 0;
909
        int ccN = 0;
910
        bool first = true;
1957 cbradney 911
        PageItem *nextItem = currItem;
912
        PageItem *nbl = currItem;
913
        while (nextItem != 0)
167 Franz 914
        {
1957 cbradney 915
                if (nextItem->BackBox != 0)
916
                        nextItem = nextItem->BackBox;
125 Franz 917
                else
918
                        break;
167 Franz 919
        }
1957 cbradney 920
        while (nextItem != 0)
167 Franz 921
        {
1957 cbradney 922
                for (uint a = 0; a < nextItem->itemText.count(); ++a)
1555 fschmid 923
                {
1957 cbradney 924
                        QChar b = nextItem->itemText.at(a)->ch[0];
125 Franz 925
                        if (b == QChar(13))
167 Franz 926
                        {
1957 cbradney 927
                                if (a >= nextItem->MaxChars)
125 Franz 928
                                        paraN++;
929
                                else
930
                                        para++;
167 Franz 931
                        }
125 Franz 932
                        if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
167 Franz 933
                        {
1957 cbradney 934
                                if (a >= nextItem->MaxChars)
125 Franz 935
                                        wwN++;
936
                                else
937
                                        ww++;
167 Franz 938
                        }
1957 cbradney 939
                        if (a >= nextItem->MaxChars)
125 Franz 940
                                ccN++;
941
                        else
942
                                cc++;
1555 fschmid 943
                        Dat = b;
125 Franz 944
                        first = false;
1555 fschmid 945
                }
1957 cbradney 946
                nbl = nextItem;
947
                nextItem = nextItem->NextBox;
167 Franz 948
        }
1065 cbradney 949
        if (nbl->MaxChars < nbl->itemText.count())
125 Franz 950
                paraN++;
951
        else
952
                para++;
953
        if (Dat.isLetterOrNumber())
167 Franz 954
        {
1065 cbradney 955
                if (nbl->MaxChars < nbl->itemText.count())
125 Franz 956
                        wwN++;
957
                else
958
                        ww++;
167 Franz 959
        }
125 Franz 960
        *w = ww;
961
        *p = para;
962
        *c = cc;
963
        *wN = wwN;
964
        *pN = paraN;
965
        *cN = ccN;
966
}
203 Franz 967
 
690 cbradney 968
void ReOrderText(ScribusDoc *currentDoc, ScribusView *view)
203 Franz 969
{
2380 cbradney 970
        double savScale = view->getScale();
971
        view->setScale(1.0);
690 cbradney 972
        currentDoc->RePos = true;
203 Franz 973
        QPixmap pgPix(10, 10);
974
        QRect rd = QRect(0,0,9,9);
975
        ScPainter *painter = new ScPainter(&pgPix, pgPix.width(), pgPix.height());
690 cbradney 976
        for (uint azz=0; azz<currentDoc->MasterItems.count(); ++azz)
203 Franz 977
        {
1957 cbradney 978
                PageItem *currItem = currentDoc->MasterItems.at(azz);
979
                if (currItem->itemType() == PageItem::PathText)
980
                        currItem->DrawObj(painter, rd);
203 Franz 981
        }
3727 cbradney 982
        for (uint azz=0; azz<currentDoc->Items->count(); ++azz)
203 Franz 983
        {
3727 cbradney 984
                PageItem *currItem = currentDoc->Items->at(azz);
1957 cbradney 985
                if ((currItem->itemType() == PageItem::TextFrame) || (currItem->itemType() == PageItem::PathText))
986
                        currItem->DrawObj(painter, rd);
203 Franz 987
        }
690 cbradney 988
        currentDoc->RePos = false;
2380 cbradney 989
        view->setScale(savScale);
203 Franz 990
        delete painter;
991
}
447 cbradney 992
 
4449 subik 993
/*! \brief Helper function for sorting in sortQStringList.
994
\author 10/06/2004 - pv
447 cbradney 995
\param QString s1 first string
996
\param QString s2 second string
997
\retval bool t/f related s1>s2
998
 */
999
bool compareQStrings(QString s1, QString s2)
1000
{
1001
        if (QString::localeAwareCompare(s1, s2) >= 0)
2680 cbradney 1002
                return false;
1003
        return true;
447 cbradney 1004
}
1005
 
1006
QStringList sortQStringList(QStringList aList)
1007
{
1008
        std::vector<QString> sortList;
1009
        QStringList retList;
1010
        QStringList::Iterator it;
1011
        for (it = aList.begin(); it != aList.end(); ++it)
1012
                sortList.push_back(*it);
1013
        std::sort(sortList.begin(), sortList.end(), compareQStrings);
456 fschmid 1014
        for(uint i = 0; i < sortList.size(); i++)
447 cbradney 1015
                retList.append(sortList[i]);
1016
        return retList;
1017
}
517 fschmid 1018
 
1065 cbradney 1019
void GetItemProps(bool newVersion, QDomElement *obj, struct CopyPasteBuffer *OB)
517 fschmid 1020
{
1021
        QString tmp;
1022
        int x, y;
2282 fschmid 1023
        double xf, yf, xf2;
4026 craig 1024
        OB->PType = static_cast<PageItem::ItemType>(obj->attribute("PTYPE").toInt());
1025
        OB->Width=obj->attribute("WIDTH").toDouble();
1026
        OB->Height=obj->attribute("HEIGHT").toDouble();
1027
        OB->RadRect = obj->attribute("RADRECT", "0").toDouble();
1028
        OB->ClipEdited = obj->attribute("CLIPEDIT", "0").toInt();
1029
        OB->FrameType = obj->attribute("FRTYPE", "0").toInt();
1030
        OB->Pwidth=obj->attribute("PWIDTH").toDouble();
1394 cbradney 1031
        OB->Pcolor = obj->attribute("PCOLOR");
517 fschmid 1032
        if ((!newVersion) && (OB->PType == 4))
1033
        {
1034
                OB->TxtFill = obj->attribute("PCOLOR2");
1035
                OB->Pcolor2 = "None";
1036
        }
1037
        else
1038
        {
1039
                OB->Pcolor2 = obj->attribute("PCOLOR2");
1040
                OB->TxtFill = obj->attribute("TXTFILL", "Black");
1041
        }
4026 craig 1042
        OB->Shade = obj->attribute("SHADE").toInt();
1043
        OB->Shade2 = obj->attribute("SHADE2").toInt();
517 fschmid 1044
        OB->TxtStroke=obj->attribute("TXTSTROKE", "None");
4026 craig 1045
        OB->ShTxtFill=obj->attribute("TXTFILLSH", "100").toInt();
1046
        OB->ShTxtStroke=obj->attribute("TXTSTRSH", "100").toInt();
1047
        OB->TxtScale=qRound(obj->attribute("TXTSCALE", "100").toDouble() * 10);
1048
        OB->TxtScaleV=qRound(obj->attribute("TXTSCALEV", "100").toDouble() * 10);
1049
        OB->TxTBase=qRound(obj->attribute("TXTBASE", "0").toDouble() * 10);
1050
        OB->TxTStyle=obj->attribute("TXTSTYLE", "0").toInt();
1051
        OB->TxtShadowX=qRound(obj->attribute("TXTSHX", "5").toDouble() * 10);
1052
        OB->TxtShadowY=qRound(obj->attribute("TXTSHY", "-5").toDouble() * 10);
1053
        OB->TxtOutline=qRound(obj->attribute("TXTOUT", "1").toDouble() * 10);
1054
        OB->TxtUnderPos=qRound(obj->attribute("TXTULP", "-0.1").toDouble() * 10);
1055
        OB->TxtUnderWidth=qRound(obj->attribute("TXTULW", "-0.1").toDouble() * 10);
1056
        OB->TxtStrikePos=qRound(obj->attribute("TXTSTP", "-0.1").toDouble() * 10);
1057
        OB->TxtStrikeWidth=qRound(obj->attribute("TXTSTW", "-0.1").toDouble() * 10);
1058
        OB->Cols = obj->attribute("COLUMNS", "1").toInt();
1059
        OB->ColGap = obj->attribute("COLGAP", "0.0").toDouble();
1060
        OB->GrType = obj->attribute("GRTYP", "0").toInt();
517 fschmid 1061
        OB->fill_gradient.clearStops();
1062
        if (OB->GrType != 0)
1063
        {
4026 craig 1064
                OB->GrStartX = obj->attribute("GRSTARTX", "0.0").toDouble();
1065
                OB->GrStartY = obj->attribute("GRSTARTY", "0.0").toDouble();
1066
                OB->GrEndX = obj->attribute("GRENDX", "0.0").toDouble();
1067
                OB->GrEndY = obj->attribute("GRENDY", "0.0").toDouble();
517 fschmid 1068
                OB->GrColor = obj->attribute("GRCOLOR","");
2877 cbradney 1069
                if (OB->GrColor.isEmpty())
2179 fschmid 1070
                        OB->GrColor = "Black";
1071
                OB->GrColor2 = obj->attribute("GRCOLOR2","Black");
2877 cbradney 1072
                if (OB->GrColor2.isEmpty())
2179 fschmid 1073
                        OB->GrColor2 = "Black";
4026 craig 1074
                OB->GrShade = obj->attribute("GRSHADE", "100").toInt();
1075
                OB->GrShade2 = obj->attribute("GRSHADE2", "100").toInt();
517 fschmid 1076
        }
4026 craig 1077
        OB->Rot=obj->attribute("ROT").toDouble();
1078
        OB->PLineArt=Qt::PenStyle(obj->attribute("PLINEART").toInt());
1079
        OB->PLineEnd=Qt::PenCapStyle(obj->attribute("PLINEEND", "0").toInt());
1080
        OB->PLineJoin=Qt::PenJoinStyle(obj->attribute("PLINEJOIN", "0").toInt());
1081
        OB->LineSp=obj->attribute("LINESP").toDouble();
1082
        OB->LineSpMode = obj->attribute("LINESPMode", "0").toInt();
1083
        OB->LocalScX=obj->attribute("LOCALSCX").toDouble();
1084
        OB->LocalScY=obj->attribute("LOCALSCY").toDouble();
1085
        OB->LocalX=obj->attribute("LOCALX").toDouble();
1086
        OB->LocalY=obj->attribute("LOCALY").toDouble();
1087
        OB->PicArt=obj->attribute("PICART").toInt();
1088
        OB->flippedH = obj->attribute("FLIPPEDH").toInt() % 2;
1089
        OB->flippedV = obj->attribute("FLIPPEDV").toInt() % 2;
4335 fschmid 1090
/*      OB->BBoxX=obj->attribute("BBOXX").toDouble();
1091
        OB->BBoxH=obj->attribute("BBOXH").toDouble(); */
4026 craig 1092
        OB->ScaleType = obj->attribute("SCALETYPE", "1").toInt();
1093
        OB->AspectRatio = obj->attribute("RATIO", "0").toInt();
1094
        OB->isPrintable=obj->attribute("PRINTABLE").toInt();
4084 cbradney 1095
        OB->m_isAnnotation=obj->attribute("ANNOTATION", "0").toInt();
1096
        OB->m_annotation.setType(obj->attribute("ANTYPE", "0").toInt());
1097
        OB->m_annotation.setAction(obj->attribute("ANACTION",""));
1098
        OB->m_annotation.setE_act(obj->attribute("ANEACT",""));
1099
        OB->m_annotation.setX_act(obj->attribute("ANXACT",""));
1100
        OB->m_annotation.setD_act(obj->attribute("ANDACT",""));
1101
        OB->m_annotation.setFo_act(obj->attribute("ANFOACT",""));
1102
        OB->m_annotation.setBl_act(obj->attribute("ANBLACT",""));
1103
        OB->m_annotation.setK_act(obj->attribute("ANKACT",""));
1104
        OB->m_annotation.setF_act(obj->attribute("ANFACT",""));
1105
        OB->m_annotation.setV_act(obj->attribute("ANVACT",""));
1106
        OB->m_annotation.setC_act(obj->attribute("ANCACT",""));
1107
        OB->m_annotation.setActionType(obj->attribute("ANACTYP", "0").toInt());
1108
        OB->m_annotation.setExtern(obj->attribute("ANEXTERN",""));
1109
        if ((!OB->m_annotation.Extern().isEmpty()) && (OB->m_annotation.ActionType() != 8))
517 fschmid 1110
        {
4084 cbradney 1111
                QFileInfo efp(OB->m_annotation.Extern());
1112
                OB->m_annotation.setExtern(efp.absFilePath());
517 fschmid 1113
        }
4084 cbradney 1114
        OB->m_annotation.setZiel(obj->attribute("ANZIEL", "0").toInt());
1115
        OB->AnName=obj->attribute("ANNAME","");
1116
        OB->m_annotation.setToolTip(obj->attribute("ANTOOLTIP",""));
1117
        OB->m_annotation.setRollOver(obj->attribute("ANROLL",""));
1118
        OB->m_annotation.setDown(obj->attribute("ANDOWN",""));
1119
        OB->m_annotation.setBwid(obj->attribute("ANBWID", "1").toInt());
1120
        OB->m_annotation.setBsty(obj->attribute("ANBSTY", "0").toInt());
1121
        OB->m_annotation.setFeed(obj->attribute("ANFEED", "1").toInt());
1122
        OB->m_annotation.setFlag(obj->attribute("ANFLAG", "0").toInt());
1123
        OB->m_annotation.setFont(obj->attribute("ANFONT", "4").toInt());
1124
        OB->m_annotation.setFormat(obj->attribute("ANFORMAT", "0").toInt());
1125
        OB->m_annotation.setVis(obj->attribute("ANVIS", "0").toInt());
1126
        OB->m_annotation.setIsChk(static_cast<bool>(obj->attribute("ANCHK", "0").toInt()));
1127
        OB->m_annotation.setAAact(static_cast<bool>(obj->attribute("ANAA", "0").toInt()));
1128
        OB->m_annotation.setHTML(static_cast<bool>(obj->attribute("ANHTML", "0").toInt()));
1129
        OB->m_annotation.setUseIcons(static_cast<bool>(obj->attribute("ANICON", "0").toInt()));
1130
        OB->m_annotation.setChkStil(obj->attribute("ANCHKS", "0").toInt());
1131
        OB->m_annotation.setMaxChar(obj->attribute("ANMC", "-1").toInt());
1132
        OB->m_annotation.setBorderColor(obj->attribute("ANBCOL","None"));
1133
        OB->m_annotation.setIPlace(obj->attribute("ANPLACE", "1").toInt());
1134
        OB->m_annotation.setScaleW(obj->attribute("ANSCALE", "0").toInt());
4026 craig 1135
        if (obj->attribute("TRANSPARENT", "0").toInt() == 1)
517 fschmid 1136
                OB->Pcolor = "None";
4026 craig 1137
        OB->Textflow=obj->attribute("TEXTFLOW").toInt();
1138
        OB->Textflow2 =obj->attribute("TEXTFLOW2", "0").toInt();
1139
        OB->UseContour = obj->attribute("TEXTFLOW3", "0").toInt();
1140
        OB->Extra=obj->attribute("EXTRA").toDouble();
1141
        OB->TExtra=obj->attribute("TEXTRA", "1").toDouble();
1142
        OB->BExtra=obj->attribute("BEXTRA", "1").toDouble();
1143
        OB->RExtra=obj->attribute("REXTRA", "1").toDouble();
1144
        OB->PoShow = obj->attribute("PLTSHOW", "0").toInt();
1145
        OB->BaseOffs = obj->attribute("BASEOF", "0").toDouble();
1146
        OB->ISize = qRound(obj->attribute("ISIZE", "12").toDouble() * 10);
2382 fschmid 1147
        if (obj->hasAttribute("EXTRAV"))
4026 craig 1148
                OB->ExtraV = qRound(obj->attribute("EXTRAV", "0").toDouble() / obj->attribute("ISIZE", "12").toDouble() * 1000.0);
2382 fschmid 1149
        else
4026 craig 1150
                OB->ExtraV = obj->attribute("TXTKERN").toInt();
517 fschmid 1151
        OB->Pfile=obj->attribute("PFILE");
1152
        OB->Pfile2=obj->attribute("PFILE2","");
1153
        OB->Pfile3=obj->attribute("PFILE3","");
1154
        OB->IProfile=obj->attribute("PRFILE","");
1155
        OB->EmProfile=obj->attribute("EPROF","");
4026 craig 1156
        OB->IRender = obj->attribute("IRENDER", "1").toInt();
1157
        OB->UseEmbedded = obj->attribute("EMBEDDED", "1").toInt();
1158
        OB->Locked = static_cast<bool>(obj->attribute("LOCK", "0").toInt());
1159
        OB->LockRes = static_cast<bool>(obj->attribute("LOCKR", "0").toInt());
1160
        OB->Reverse = static_cast<bool>(obj->attribute("REVERS", "0").toInt());
1161
        OB->isTableItem = static_cast<bool>(obj->attribute("isTableItem", "0").toInt());
1162
        OB->TopLine = static_cast<bool>(obj->attribute("TopLine", "0").toInt());
1163
        OB->LeftLine = static_cast<bool>(obj->attribute("LeftLine", "0").toInt());
1164
        OB->RightLine = static_cast<bool>(obj->attribute("RightLine", "0").toInt());
1165
        OB->BottomLine = static_cast<bool>(obj->attribute("BottomLine", "0").toInt());
1166
        OB->TopLinkID =  obj->attribute("TopLINK", "-1").toInt();
1167
        OB->LeftLinkID =  obj->attribute("LeftLINK", "-1").toInt();
1168
        OB->RightLinkID =  obj->attribute("RightLINK", "-1").toInt();
1169
        OB->BottomLinkID =  obj->attribute("BottomLINK", "-1").toInt();
1170
        OB->Transparency = obj->attribute("TransValue", "0.0").toDouble();
517 fschmid 1171
        if (obj->hasAttribute("TransValueS"))
4026 craig 1172
                OB->TranspStroke = obj->attribute("TransValueS", "0.0").toDouble();
517 fschmid 1173
        else
1174
                OB->TranspStroke = OB->Transparency;
1175
        tmp = "";
1176
        if (obj->hasAttribute("NUMCLIP"))
1177
        {
1178
                OB->Clip.resize(obj->attribute("NUMCLIP").toUInt());
1179
                tmp = obj->attribute("CLIPCOOR");
1180
                QTextStream fc(&tmp, IO_ReadOnly);
1181
                for (uint c=0; c<obj->attribute("NUMCLIP").toUInt(); ++c)
1182
                {
1183
                        fc >> x;
1184
                        fc >> y;
1185
                        OB->Clip.setPoint(c, x, y);
1186
                }
1187
        }
1188
        else
1189
                OB->Clip.resize(0);
1190
        tmp = "";
1191
        if (obj->hasAttribute("NUMPO"))
1192
        {
1193
                OB->PoLine.resize(obj->attribute("NUMPO").toUInt());
1194
                tmp = obj->attribute("POCOOR");
1195
                QTextStream fp(&tmp, IO_ReadOnly);
1196
                for (uint cx=0; cx<obj->attribute("NUMPO").toUInt(); ++cx)
1197
                {
1198
                        fp >> xf;
1199
                        fp >> yf;
1200
                        OB->PoLine.setPoint(cx, xf, yf);
1201
                }
1202
        }
1203
        else
1204
                OB->PoLine.resize(0);
1205
        tmp = "";
1206
        if (obj->hasAttribute("NUMCO"))
1207
        {
1208
                OB->ContourLine.resize(obj->attribute("NUMCO").toUInt());
1209
                tmp = obj->attribute("COCOOR");
1210
                QTextStream fp(&tmp, IO_ReadOnly);
1211
                for (uint cx=0; cx<obj->attribute("NUMCO").toUInt(); ++cx)
1212
                {
1213
                        fp >> xf;
1214
                        fp >> yf;
1215
                        OB->ContourLine.setPoint(cx, xf, yf);
1216
                }
1217
        }
1218
        else
1219
                OB->ContourLine.resize(0);
1220
        tmp = "";
4026 craig 1221
        if ((obj->hasAttribute("NUMTAB")) && (obj->attribute("NUMTAB", "0").toInt() != 0))
517 fschmid 1222
        {
2282 fschmid 1223
                struct PageItem::TabRecord tb;
517 fschmid 1224
                tmp = obj->attribute("TABS");
1225
                QTextStream tgv(&tmp, IO_ReadOnly);
1226
                OB->TabValues.clear();
4026 craig 1227
                for (int cxv = 0; cxv < obj->attribute("NUMTAB", "0").toInt(); cxv += 2)
517 fschmid 1228
                {
1229
                        tgv >> xf;
2282 fschmid 1230
                        tgv >> xf2;
1231
                        tb.tabPosition = xf2;
1232
                        tb.tabType = static_cast<int>(xf);
1233
                        tb.tabFillChar = QChar();
1234
                        OB->TabValues.append(tb);
517 fschmid 1235
                }
1236
                tmp = "";
1237
        }
1238
        else
1239
                OB->TabValues.clear();
4026 craig 1240
        if ((obj->hasAttribute("NUMDASH")) && (obj->attribute("NUMDASH", "0").toInt() != 0))
517 fschmid 1241
        {
1242
                tmp = obj->attribute("DASHS");
1243
                QTextStream dgv(&tmp, IO_ReadOnly);
1244
                OB->DashValues.clear();
4026 craig 1245
                for (int cxv = 0; cxv < obj->attribute("NUMDASH", "0").toInt(); ++cxv)
517 fschmid 1246
                {
1247
                        dgv >> xf;
1248
                        OB->DashValues.append(xf);
1249
                }
1250
                tmp = "";
1251
        }
1252
        else
1253
                OB->DashValues.clear();
4026 craig 1254
        OB->DashOffset = obj->attribute("DASHOFF", "0.0").toDouble();
517 fschmid 1255
}
1256
 
690 cbradney 1257
QColor SetColor(ScribusDoc *currentDoc, QString color, int shad)
517 fschmid 1258
{
1488 fschmid 1259
        return currentDoc->PageColors[color].getShadeColorProof(shad);
517 fschmid 1260
}
2529 craig 1261
 
2636 cbradney 1262
 
1263
/**
1264
 * QPixmaps are really slow with Qt/Mac 3.3.4. Really, *really*, slow.
1265
 * So we better cache them.
1266
 */
2907 subik 1267
QPixmap * getSmallPixmap(QColor rgb)
2636 cbradney 1268
{
1269
        static QMap<QRgb, QPixmap*> pxCache;
1270
 
3719 cbradney 1271
        QRgb index=rgb.rgb();
1272
        if (pxCache.contains(index))
1273
                return pxCache[index];
1274
 
1275
        QPixmap *pm = new QPixmap(15, 15);
1276
        pm->fill(rgb);
1277
        QPainter p;
1278
        p.begin(pm);
1279
        p.setBrush(Qt::NoBrush);
1280
        QPen b(Qt::black, 1);
1281
        p.setPen(b);
1282
        p.drawRect(0, 0, 15, 15);
1283
        p.end();
1284
        pxCache.insert(index, pm);
2636 cbradney 1285
        return pm;
1286
}
1287
 
2907 subik 1288
QPixmap * getWidePixmap(QColor rgb)
2636 cbradney 1289
{
1290
        static QMap<QRgb, QPixmap*> pxCache;
2907 subik 1291
 
3719 cbradney 1292
        QRgb index=rgb.rgb();
1293
        if (pxCache.contains(index))
1294
                return pxCache[index];
1295
 
1296
        QPixmap *pm = new QPixmap(30, 15);
1297
        pm->fill(rgb);
1298
        pxCache.insert(index, pm);
2636 cbradney 1299
        return pm;
1300
}
1301
 
3497 avox 1302
static Q_UINT64 code64(ScColor & col) {
1303
        int C, M, Y, K, R, G, B;
1304
        Q_UINT64 result;
1305
        col.getRGB( &R, &G, &B );
1306
        col.getCMYK( &C, &M, &Y, &K );
1307
        result |= col.getColorModel() == colorModelRGB ? 1 : 0;
1308
        result |= col.isOutOfGamut() ? 64 : 0;
1309
        result |= col.isSpotColor() ? 32 : 0;
1310
        result |= col.isRegistrationColor() ? 16 : 0;
1311
        result <<= 8;
1312
        result |= C;
1313
        result <<= 8;
1314
        result |= M;
1315
        result <<= 8;
1316
        result |= Y;
1317
        result <<= 8;
1318
        result |= K;
1319
        result <<= 8;
1320
        result |= R;
1321
        result <<= 8;
1322
        result |= G;
1323
        result <<= 8;
1324
        result |= B;
1325
        return result;
1326
}
1327
 
1328
QPixmap * getFancyPixmap(ScColor col) {
3717 cbradney 1329
        static QMap<Q_UINT64, QPixmap*> pxCache;
3497 avox 1330
 
1331
        static QPixmap alertIcon;
1332
        static QPixmap cmykIcon;
1333
        static QPixmap rgbIcon;
1334
        static QPixmap spotIcon;
1335
        static QPixmap regIcon;
1336
        static bool iconsInitialized = false;
1337
 
1338
        if ( !iconsInitialized ) {
1339
                alertIcon = loadIcon("alert.png");
1340
                cmykIcon = loadIcon("cmyk.png");
1341
                rgbIcon = loadIcon("rgb.png");
1342
                spotIcon = loadIcon("spot.png");
1343
                regIcon = loadIcon("register.png");
1344
                iconsInitialized = true;
1345
        }
1346
 
3717 cbradney 1347
        Q_UINT64 res=code64(col);
1348
        if (pxCache.contains(res))
1349
                return pxCache[res];
1350
 
1351
        QPixmap *pa=new QPixmap(60, 15);
1352
        QPixmap *pm=getSmallPixmap(col.getRawRGBColor());
1353
        pa->fill(Qt::white);
1354
        paintAlert(*pm, *pa, 0, 0);
1355
        col.checkGamut();
1356
        if (col.isOutOfGamut())
1357
                paintAlert(alertIcon, *pa, 15, 0);
1358
        if ((col.getColorModel() == colorModelCMYK) || (col.isSpotColor()))
1359
                paintAlert(cmykIcon, *pa, 30, 0);
1360
        else
1361
                paintAlert(rgbIcon, *pa, 30, 0);
1362
        if (col.isSpotColor())
1363
                paintAlert(spotIcon, *pa, 46, 2);
1364
        if (col.isRegistrationColor())
1365
                paintAlert(regIcon, *pa, 45, 0);
1366
        pxCache.insert(res, pa);
3497 avox 1367
        return pa;
1368
}
1369
 
1370
 
3046 fschmid 1371
void paintAlert(QPixmap &toPaint, QPixmap &target, int x, int y)
3041 fschmid 1372
{
4449 subik 1373
        // there is no alpha mask in the beginning
1374
        if (target.mask()==0)
1375
                target.setMask(QBitmap(target.width(), target.height(), true));
3041 fschmid 1376
        QPainter p;
4449 subik 1377
        QPainter alpha; // transparency handling
3041 fschmid 1378
        p.begin(&target);
4449 subik 1379
        alpha.begin(target.mask());
1380
        alpha.setBrush(Qt::color1);
1381
        alpha.setPen(Qt::color1);
3046 fschmid 1382
        p.drawPixmap(x, y, toPaint);
4449 subik 1383
        alpha.drawRect(x, y, 15, 15);
3041 fschmid 1384
        p.end();
4449 subik 1385
        alpha.end();
3041 fschmid 1386
}
1387
 
2529 craig 1388
FPoint getMaxClipF(FPointArray* Clip)
1389
{
1390
        FPoint np, rp;
1391
        double mx = 0;
1392
        double my = 0;
3719 cbradney 1393
        uint clipSize=Clip->size();
1394
        for (uint c = 0; c < clipSize; ++c)
2529 craig 1395
        {
1396
                np = Clip->point(c);
1397
                if (np.x() > 900000)
1398
                        continue;
1399
                if (np.x() > mx)
1400
                        mx = np.x();
1401
                if (np.y() > my)
1402
                        my = np.y();
1403
        }
1404
        rp.setXY(mx, my);
1405
        return rp;
1406
}
1407
 
1408
FPoint getMinClipF(FPointArray* Clip)
1409
{
1410
        FPoint np, rp;
1411
        double mx = 99999;
1412
        double my = 99999;
3719 cbradney 1413
        uint clipSize=Clip->size();
1414
        for (uint c = 0; c < clipSize; ++c)
2529 craig 1415
        {
1416
                np = Clip->point(c);
1417
                if (np.x() > 900000)
1418
                        continue;
1419
                if (np.x() < mx)
1420
                        mx = np.x();
1421
                if (np.y() < my)
1422
                        my = np.y();
1423
        }
1424
        rp.setXY(mx, my);
1425
        return rp;
1426
}
1427
 
2834 cbradney 1428
QString checkFileExtension(const QString &currName, const QString &extension)
1429
{
1430
        QString newName(currName);
1431
        //If filename ends with a period, just add the extension
1432
        if (newName.right(1)==".")
1433
        {
1434
                newName+=extension.lower();
1435
                return newName;
1436
        }
1437
        //If filename doesnt end with the period+extension, add it on
1438
        QString dotExt("." + extension.lower());
1439
        if (!newName.endsWith(dotExt,false))
1440
                newName+=dotExt;
1441
        return newName;
1442
}
2907 subik 1443
 
1444
QString getFileNameByPage(uint pageNo, QString extension)
1445
{
1446
        QString number;
4026 craig 1447
        number = number.setNum(pageNo + ScMW->doc->FirstPnum);
1448
        QString defaultName = ScMW->doc->DocName;
2907 subik 1449
        if (defaultName.isNull())
1450
                defaultName = "export";
1451
        else
1452
        {
1453
                QFileInfo fi(defaultName);
1454
                defaultName = fi.baseName(true);
1455
        }
2954 subik 1456
        return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number).arg(extension);
2907 subik 1457
}
3689 cbradney 1458
 
1459
inline double square(double x)
1460
{
1461
        return x*x;
1462
}
1463
 
1464
inline double distance(double x, double y)
1465
{
1466
        return sqrt(x*x+y*y);
1467
}
1468
 
3757 cbradney 1469
const QString getStringFromSequence(DocumentSectionType type, uint position)
1470
{
1471
        QString retVal("");
1472
        switch( type )
1473
        {
3778 cbradney 1474
                case Type_1_2_3:
1475
                        retVal=QString::number(position);
1476
                        break;
3757 cbradney 1477
                case Type_A_B_C:
3778 cbradney 1478
                        retVal=numberToLetterSequence(position).upper();
1479
                        break;
3757 cbradney 1480
                case Type_a_b_c:
3778 cbradney 1481
                        retVal=numberToLetterSequence(position);
3757 cbradney 1482
                        break;
1483
                case Type_I_II_III:
1484
                        retVal=arabicToRoman(position);
1485
                        break;
1486
                case Type_i_ii_iii:
1487
                        //well, for lower case people will want that, even if its "wrong"
1488
                        //ie, X=10, x=10000
1489
                        retVal=arabicToRoman(position).lower();
1490
                        break;
1491
                default:
1492
                        break;
1493
        }
1494
        return retVal;
1495
}
1496
 
1497
const QString numberToLetterSequence(uint i)
1498
{
1499
        QString retVal("");
1500
        unsigned digits = 1;
1501
        unsigned offset = 0;
1502
        uint column=i;
1503
        --column;
1504
 
1505
        if( column > 4058115285U ) return  QString("@");
1506
 
1507
        for( unsigned limit = 26; column >= limit+offset; limit *= 26, digits++ )
1508
                offset += limit;
1509
 
1510
        for( unsigned c = column - offset; digits; --digits, c/=26 )
1511
                retVal.prepend( QChar( 'a' + (c%26) ) );
1512
        return retVal;
1513
}
1514
 
1515
const QString arabicToRoman(uint i)
1516
{
1517
        QString roman("");
1518
        int arabic = i;
1519
        while (arabic - 1000000 >= 0){
1520
        roman += "m";
1521
        arabic -= 1000000;
1522
        }
1523
        while (arabic - 900000 >= 0){
1524
        roman += "cm";
1525
        arabic -= 900000;
1526
        }
1527
        while (arabic - 500000 >= 0){
1528
        roman += "d";
1529
        arabic -= 500000;
1530
        }
1531
        while (arabic - 400000 >= 0){
1532
        roman += "cd";
1533
        arabic -= 400000;
1534
        }
1535
        while (arabic - 100000 >= 0){
1536
        roman += "c";
1537
        arabic -= 100000;
1538
        }
1539
        while (arabic - 90000 >= 0){
1540
        roman += "xc";
1541
        arabic -= 90000;
1542
        }
1543
        while (arabic - 50000 >= 0){
1544
        roman += "l";
1545
        arabic -= 50000;
1546
        }
1547
        while (arabic - 40000 >= 0){
1548
        roman += "xl";
1549
        arabic -= 40000;
1550
        }
1551
        while (arabic - 10000 >= 0){
1552
        roman += "x";
1553
        arabic -= 10000;
1554
        }
1555
        while (arabic - 9000 >= 0){
1556
        roman += "Mx";
1557
        arabic -= 9000;
1558
        }
1559
        while (arabic - 5000 >= 0){
1560
        roman += "v";
1561
        arabic -= 5000;
1562
        }
1563
        while (arabic - 4000 >= 0){
1564
        roman += "Mv";
1565
        arabic -= 4000;
1566
        }
1567
        while (arabic - 1000 >= 0){
1568
        roman += "M";
1569
        arabic -= 1000;
1570
        }
1571
        while (arabic - 900 >= 0){
1572
        roman += "CM";
1573
        arabic -= 900;
1574
        }
1575
        while (arabic - 500 >= 0){
1576
        roman += "D";
1577
        arabic -= 500;
1578
        }
1579
        while (arabic - 400 >= 0){
1580
        roman += "CD";
1581
        arabic -= 400;
1582
        }
1583
        while (arabic - 100 >= 0){
1584
        roman += "C";
1585
        arabic -= 100;
1586
        }
1587
        while (arabic - 90 >= 0){
1588
        roman += "XC";
1589
        arabic -= 90;
1590
        }
1591
        while (arabic - 50 >= 0){
1592
        roman += "L";
1593
        arabic -= 50;
1594
        }
1595
        while (arabic - 40 >= 0){
1596
        roman += "XL";
1597
        arabic -= 40;
1598
        }
1599
        while (arabic - 10 >= 0){
1600
        roman += "X";
1601
        arabic -= 10;
1602
        }
1603
        while (arabic - 9 >= 0){
1604
        roman += "IX";
1605
        arabic -= 9;
1606
        }
1607
        while (arabic - 5 >= 0){
1608
        roman += "V";
1609
        arabic -= 5;
1610
        }
1611
        while (arabic - 4 >= 0){
1612
        roman += "IV";
1613
        arabic -= 4;
1614
        }
1615
        while (arabic - 1 >= 0){
1616
        roman += "I";
1617
        arabic -= 1;
1618
        }
1619
        return roman;
3776 cbradney 1620
}
3784 cbradney 1621
 
1622
//CB Moved from scribus.cpp
1623
void parsePagesString(QString pages, std::vector<int>* pageNs, int sourcePageCount)
1624
{
1625
        QString tmp(pages);
1626
        QString token;
1627
        int from, to, pageNr;
1628
        do
1629
        {
1630
                if (tmp.find(",") == -1)
1631
                {
1632
                        token = tmp;
1633
                        tmp = "";
1634
                }
1635
                else
1636
                {
1637
                        token = tmp.left(tmp.find(","));
1638
                        tmp = tmp.right(tmp.length() - tmp.find(",") - 1);
1639
                }
1640
 
1641
                token = token.stripWhiteSpace();
1642
                if (token == "*") // Import all source doc pages
1643
                {
1644
                        for (int i = 1; i <= sourcePageCount; ++i)
1645
                                pageNs->push_back(i);
1646
                }
1647
                else if (token.find("-") != -1) // import a range of source doc pages
1648
                {
1649
                        from = QString(token.left(token.find("-"))).toInt();
1650
                        to = QString(token.right(token.length() - token.find("-") - 1)).toInt();
1651
                        if ((from != 0) && (to != 0))
1652
                        {
1653
                                if (from > sourcePageCount)
1654
                                        from = sourcePageCount;
1655
                                if (to > sourcePageCount)
1656
                                        to = sourcePageCount;
1657
                                if (from == to)
1658
                                        pageNs->push_back(to);
1659
                                else if (from < to)
1660
                                {
1661
                                        for (int i = from; i <= to; ++i)
1662
                                                pageNs->push_back(i);
1663
                                }
1664
                                else
1665
                                {
1666
                                        for (int i = from; i >= to; --i)
1667
                                                pageNs->push_back(i);
1668
                                }
1669
                        }
1670
                }
1671
                else // import single source doc page
1672
                {
1673
                        pageNr = token.toInt();
1674
                        if ((pageNr > 0) && (pageNr <= sourcePageCount))
1675
                                pageNs->push_back(pageNr);
1676
                }
1677
        } while (!tmp.isEmpty());
3793 cbradney 1678
}