Subversion Repositories Scribus

Rev

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