Subversion Repositories Scribus

Rev

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