Subversion Repositories Scribus

Rev

Rev 8439 | 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 <qfile.h>
27
#include <qfileinfo.h>
28
#include <qtextstream.h>
6125 cbradney 29
// #include <qdatastream.h>
30
// #include <qregexp.h>
19 Franz 31
#include <qdir.h>
6125 cbradney 32
#include <qdom.h>
5557 subik 33
#include <qcheckbox.h>
6125 cbradney 34
#include <qwidget.h>
35
 
36
// #include <algorithm>
37
// #include <cstdlib>
8 paul 38
#include <cmath>
6140 jghali 39
#include <algorithm>
2702 craig 40
#include "scconfig.h"
41
 
4506 cbradney 42
//#ifdef HAVE_UNISTD_H
43
//#include <unistd.h>
44
//#endif
2702 craig 45
 
2730 cbradney 46
#if defined(_WIN32)
47
#if defined(_MSC_VER)
48
#define __STDC__ 1 // hack to get md5_buffer correctly identified
49
#endif
3810 cbradney 50
#include <valarray>
2730 cbradney 51
#include <windows.h>
52
#endif
53
 
8 paul 54
#include "md5.h"
2730 cbradney 55
 
6125 cbradney 56
// #include <setjmp.h>
3733 cbradney 57
#include "commonstrings.h"
6125 cbradney 58
// #include "pagestructs.h"
59
// #include "prefsfile.h"
60
// #include "prefscontext.h"
61
// #include "prefstable.h"
62
// #include "prefsmanager.h"
63
// #include "qprocess.h"
3733 cbradney 64
#include "scmessagebox.h"
5351 cbradney 65
#include "scpixmapcache.h"
3733 cbradney 66
#include "scpaths.h"
6125 cbradney 67
// #include "text/nlsconfig.h"
128 Franz 68
 
1555 fschmid 69
extern "C"
70
{
201 Franz 71
#define XMD_H           // shut JPEGlib up
72
#if defined(Q_OS_UNIXWARE)
73
#  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
74
#endif
75
#include <jpeglib.h>
76
#include <jerror.h>
77
#undef HAVE_STDLIB_H
78
#ifdef const
79
#  undef const          // remove crazy C hackery in jconfig.h
80
#endif
81
}
82
 
6125 cbradney 83
#include "pageitem.h"
214 Franz 84
#include "scribus.h"
6125 cbradney 85
#include "scribusdoc.h"
86
#include "scribusview.h"
87
/*#include <ft2build.h>
68 Franz 88
#include FT_FREETYPE_H
89
#include FT_OUTLINE_H
90
#include FT_GLYPH_H
6125 cbradney 91
*/
8022 jghali 92
#include <zlib.h>
8 paul 93
 
3205 craig 94
 
690 cbradney 95
using namespace std;
96
 
3240 fschmid 97
void sDebug(QString message)
98
{
99
        qDebug("%s", message.ascii());
100
}
101
 
4194 fschmid 102
int System(const QStringList & args, const QString fileStdErr, const QString fileStdOut)
204 Franz 103
{
4243 mrdocs 104
        QStringList stdErrData;
105
        QStringList stdOutData;
106
        QProcess proc(args);
4194 fschmid 107
        if ( !proc.start() )
204 Franz 108
                return 1;
109
        /* start was OK */
690 cbradney 110
        /* wait a little bit */
4243 mrdocs 111
        while( proc.isRunning() || proc.canReadLineStdout() || proc.canReadLineStderr() )
4194 fschmid 112
        {
4924 cbradney 113
                // Otherwise Scribus will sleep a *lot* when proc has huge std output
114
                if ( !proc.canReadLineStdout() && !proc.canReadLineStderr()) {
2730 cbradney 115
#ifndef _WIN32
5184 avox 116
                        usleep(5000);
2730 cbradney 117
#else
5184 avox 118
                        Sleep(5);
2730 cbradney 119
#endif
4924 cbradney 120
                }
4243 mrdocs 121
                // Some configurations needs stdout and stderr to be read
122
                // if needed before the created process can exit
123
                if ( proc.canReadLineStdout() )
124
                        stdOutData.append( proc.readLineStdout() );
125
                if ( proc.canReadLineStderr() )
126
                        stdErrData.append( proc.readLineStderr() );
4194 fschmid 127
        }
128
        // TODO: What about proc.normalExit() ?
129
        int ex = proc.exitStatus();
4505 cbradney 130
        QStringList::iterator pIterator;
131
        QStringList::iterator pEnd;
4194 fschmid 132
        if ( !fileStdErr.isEmpty() )
133
        {
134
                QFile ferr(fileStdErr);
135
                if ( ferr.open(IO_WriteOnly) )
136
                {
4243 mrdocs 137
                        pEnd = stdErrData.end();
138
                        QTextStream errStream(&ferr);
139
                        for ( pIterator = stdErrData.begin(); pIterator != pEnd; pIterator++ )
140
                                errStream << *pIterator << endl;
4194 fschmid 141
                        ferr.close();
142
                }
143
        }
144
 
145
        if ( !fileStdOut.isEmpty() )
146
        {
147
                QFile fout(fileStdOut);
148
                if ( fout.open(IO_WriteOnly) )
149
                {
4243 mrdocs 150
                        pEnd = stdOutData.end();
151
                        QTextStream outStream(&fout);
152
                        for ( pIterator = stdOutData.begin(); pIterator != pEnd; pIterator++ )
153
                                outStream << *pIterator << endl;
4194 fschmid 154
                        fout.close();
155
                }
156
        }
204 Franz 157
        return ex;
158
}
159
 
2885 fschmid 160
// On Windows, return short path name, else return longPath;
161
QString getShortPathName(QString longPath)
162
{
4505 cbradney 163
        QString shortPath(longPath);
2885 fschmid 164
#if defined _WIN32
165
        QFileInfo fInfo(longPath);
166
        if(fInfo.exists())
167
        {
168
                char shortName[MAX_PATH + 1];
169
                // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
170
                // that volume does not support 8.3 filenames, so return longPath in this case
171
                int ret = GetShortPathName(QDir::convertSeparators(longPath).local8Bit(), shortName, sizeof(shortName));
172
                if( ret != ERROR_INVALID_PARAMETER && ret < sizeof(shortName))
173
                        shortPath = shortName;
174
        }
175
#endif
176
        return shortPath;
177
}
178
 
204 Franz 179
int copyFile(QString source, QString target)
180
{
4193 craig 181
        int bytesread;
204 Franz 182
        if ((source.isNull()) || (target.isNull()))
183
                return -1;
184
        if (source == target)
185
                return -1;
186
        QFile s(source);
187
        if (!s.exists())
188
                return -1;
6125 cbradney 189
        QFile t(target);
4193 craig 190
        QByteArray bb( 65536 );
204 Franz 191
        if (s.open(IO_ReadOnly))
192
        {
193
                if (t.open(IO_WriteOnly))
194
                {
4193 craig 195
                        bytesread = s.readBlock( bb.data(), bb.size() );
196
                        while( bytesread > 0 )
197
                        {
198
                                t.writeBlock( bb.data(), bytesread );
199
                                bytesread = s.readBlock( bb.data(), bb.size() );
200
                        }
204 Franz 201
                        t.close();
202
                }
4193 craig 203
                s.close();
204 Franz 204
        }
205
        return 0;
206
}
207
 
208
int moveFile(QString source, QString target)
209
{
210
        if ((source.isNull()) || (target.isNull()))
211
                return -1;
212
        if (source == target)
213
                return -1;
214
        copyFile(source, target);
2921 fschmid 215
        QFile::remove(source);
204 Franz 216
        return 0;
217
}
218
 
8 paul 219
QString GetAttr(QDomElement *el, QString at, QString def)
220
{
221
        return el->attribute(at, def);
222
}
223
 
224
QPixmap loadIcon(QString nam)
225
{
5942 subik 226
        static ScPixmapCache<QString> pxCache;
227
        if (pxCache.contains(nam))
228
                return *pxCache[nam];
229
 
7407 cbradney 230
        QString iconFilePath(QString("%1%2").arg(ScPaths::instance().iconDir()).arg(nam));
5942 subik 231
        QPixmap *pm = new QPixmap();
232
 
1672 craig 233
        if (!QFile::exists(iconFilePath))
234
                qWarning("Unable to load icon %s: File not found", iconFilePath.ascii());
235
        else
236
        {
5942 subik 237
                pm->load(iconFilePath);
238
                if (pm->isNull())
1672 craig 239
                        qWarning("Unable to load icon %s: Got null pixmap", iconFilePath.ascii());
240
        }
5942 subik 241
        pxCache.insert(nam, pm);
242
        return *pm;
8 paul 243
}
244
 
1109 fschmid 245
uint getDouble(QString in, bool raw)
246
{
247
        QByteArray bb(4);
248
        if (raw)
249
        {
250
                bb[3] = static_cast<uchar>(QChar(in.at(0)));
251
                bb[2] = static_cast<uchar>(QChar(in.at(1)));
252
                bb[1] = static_cast<uchar>(QChar(in.at(2)));
253
                bb[0] = static_cast<uchar>(QChar(in.at(3)));
254
        }
255
        else
256
        {
257
                bb[0] = static_cast<uchar>(QChar(in.at(0)));
258
                bb[1] = static_cast<uchar>(QChar(in.at(1)));
259
                bb[2] = static_cast<uchar>(QChar(in.at(2)));
260
                bb[3] = static_cast<uchar>(QChar(in.at(3)));
261
        }
262
        uint ret;
263
        ret = bb[0] & 0xff;
264
        ret |= (bb[1] << 8) & 0xff00;
265
        ret |= (bb[2] << 16) & 0xff0000;
266
        ret |= (bb[3] << 24) & 0xff000000;
267
        return ret;
268
}
269
 
3158 craig 270
// Legacy implementation of LoadText with incorrect
271
// handling of unicode data. This should be retired.
272
// Use loadRawText instead.
273
// FIXME XXX
274
//
690 cbradney 275
bool loadText(QString filename, QString *Buffer)
8 paul 276
{
690 cbradney 277
        QFile f(filename);
8 paul 278
        QFileInfo fi(f);
279
        if (!fi.exists())
280
                return false;
167 Franz 281
        bool ret;
8 paul 282
        QByteArray bb(f.size());
283
        if (f.open(IO_ReadOnly))
167 Franz 284
        {
8 paul 285
                f.readBlock(bb.data(), f.size());
286
                f.close();
690 cbradney 287
                for (uint posi = 0; posi < bb.size(); ++posi)
3027 fschmid 288
                        *Buffer += QChar(bb[posi]);
3497 avox 289
                /*
290
                int len = bb.size();
291
                int oldLen = Buffer->length();
292
                Buffer->setLength( oldLen + len + 1);
293
                // digged into Qt 3.3 sources to find that. Might break in Qt 4 -- AV
294
                unsigned short * ucsString = const_cast<unsigned short *>(Buffer->ucs2()) + oldLen;
295
                char * data = bb.data();
296
                for (uint posi = 0; posi < len; ++posi)
297
                        *ucsString++ = *data++;
298
                *ucsString = 0;
299
                 */
8 paul 300
                ret = true;
167 Franz 301
        }
8 paul 302
        else
303
                ret = false;
304
        return ret;
305
}
306
 
3646 craig 307
bool loadRawText(const QString & filename, QCString & buf)
3158 craig 308
{
309
        bool ret = false;
310
        QFile f(filename);
311
        QFileInfo fi(f);
312
        if (fi.exists())
313
        {
3646 craig 314
                QCString tempBuf(f.size() + 1);
3158 craig 315
                if (f.open(IO_ReadOnly))
316
                {
4193 craig 317
                        unsigned int bytesRead = f.readBlock(tempBuf.data(), f.size());
3646 craig 318
                        tempBuf[bytesRead] = '\0';
3158 craig 319
                        ret = bytesRead == f.size();
320
                        if (ret)
321
                                buf = tempBuf; // sharing makes this efficient
322
                }
323
        }
324
        if (f.isOpen())
325
                f.close();
326
        return ret;
327
}
328
 
5234 fschmid 329
bool loadRawBytes(const QString & filename, QByteArray & buf)
330
{
331
        bool ret = false;
332
        QFile f(filename);
333
        QFileInfo fi(f);
334
        if (fi.exists())
335
        {
336
                QByteArray tempBuf(f.size());
337
                if (f.open(IO_ReadOnly))
338
                {
339
                        unsigned int bytesRead = f.readBlock(tempBuf.data(), f.size());
340
                        ret = bytesRead == f.size();
341
                        if (ret)
342
                                buf = tempBuf; // sharing makes this efficient
343
                }
344
        }
345
        if (f.isOpen())
346
                f.close();
347
        return ret;
348
}
349
 
80 Franz 350
QPointArray RegularPolygon(double w, double h, uint c, bool star, double factor, double rota)
8 paul 351
{
167 Franz 352
        uint cx = star ? c * 2 : c;
80 Franz 353
        double seg = 360.0 / cx;
354
        double sc = rota + 180.0;
355
        double di = factor;
8 paul 356
        int mx = 0;
357
        int my = 0;
4505 cbradney 358
        //QPointArray pts = QPointArray();
359
        QPointArray pts(cx);
8 paul 360
        for (uint x = 0; x < cx; ++x)
167 Franz 361
        {
8 paul 362
                sc = seg * x + 180.0 + rota;
363
                if (star)
167 Franz 364
                {
365
                        double wf = x % 2 == 0 ? w / 2 : w / 2 * di;
366
                        double hf = x % 2 == 0 ? h / 2 : h / 2 * di;
367
                        mx = qRound(sin(sc / 180 * M_PI) * (wf) + (w/2));
368
                        my = qRound(cos(sc / 180 * M_PI) * (hf) + (h/2));
369
                }
8 paul 370
                else
167 Franz 371
                {
8 paul 372
                        mx = qRound(sin(sc / 180 * M_PI) * (w/2) + (w/2));
373
                        my = qRound(cos(sc / 180 * M_PI) * (h/2) + (h/2));
167 Franz 374
                }
4505 cbradney 375
                //pts.resize(x+1);
8 paul 376
                pts.setPoint(x, mx, my);
167 Franz 377
        }
8 paul 378
        return pts;
379
}
380
 
80 Franz 381
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota)
8 paul 382
{
167 Franz 383
        uint cx = star ? c * 2 : c;
80 Franz 384
        double seg = 360.0 / cx;
385
        double sc = rota + 180.0;
386
        double di = factor;
387
        double mx = 0;
388
        double my = 0;
4505 cbradney 389
        //FPointArray pts;
390
        FPointArray pts(cx);
8 paul 391
        for (uint x = 0; x < cx; ++x)
167 Franz 392
        {
8 paul 393
                sc = seg * x + 180.0 + rota;
394
                if (star)
167 Franz 395
                {
396
                        double wf = x % 2 == 0 ? w / 2 : w / 2 * di;
397
                        double hf = x % 2 == 0 ? h / 2 : h / 2 * di;
398
                        mx = qRound(sin(sc / 180 * M_PI) * (wf) + (w/2));
399
                        my = qRound(cos(sc / 180 * M_PI) * (hf) + (h/2));
400
                }
8 paul 401
                else
167 Franz 402
                {
8 paul 403
                        mx = sin(sc / 180 * M_PI) * (w/2) + (w/2);
404
                        my = cos(sc / 180 * M_PI) * (h/2) + (h/2);
167 Franz 405
                }
4505 cbradney 406
                //pts.resize(x+1);
8 paul 407
                pts.setPoint(x, mx, my);
167 Franz 408
        }
8 paul 409
        return pts;
410
}
411
 
412
QPointArray FlattenPath(FPointArray ina, QValueList<uint> &Segs)
413
{
414
        QPointArray Bez(4);
415
        QPointArray outa, cli;
416
        Segs.clear();
417
        if (ina.size() > 3)
167 Franz 418
        {
419
                for (uint poi=0; poi<ina.size()-3; poi += 4)
8 paul 420
                {
5234 fschmid 421
                        if (ina.point(poi).x() > 900000 && cli.size() > 0)
8 paul 422
                        {
423
                                outa.resize(outa.size()+1);
424
                                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
80 Franz 425
                                Segs.append(outa.size());
8 paul 426
                                continue;
167 Franz 427
                        }
8 paul 428
                        BezierPoints(&Bez, ina.pointQ(poi), ina.pointQ(poi+1), ina.pointQ(poi+3), ina.pointQ(poi+2));
429
                        cli = Bez.cubicBezier();
430
                        outa.putPoints(outa.size(), cli.size()-1, cli);
167 Franz 431
                }
8 paul 432
                outa.resize(outa.size()+1);
433
                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
167 Franz 434
        }
8 paul 435
        return outa;
436
}
437
 
80 Franz 438
double xy2Deg(double x, double y)
8 paul 439
{
440
        return (atan2(y,x)*(180.0/M_PI));
441
}
442
 
443
void BezierPoints(QPointArray *ar, QPoint n1, QPoint n2, QPoint n3, QPoint n4)
444
{
445
        ar->setPoint(0, n1);
446
        ar->setPoint(1, n2);
447
        ar->setPoint(2, n3);
448
        ar->setPoint(3, n4);
449
        return;
450
}
451
 
690 cbradney 452
void Level2Layer(ScribusDoc *currentDoc, struct Layer *ll, int Level)
8 paul 453
{
2955 fschmid 454
        uint layerCount=currentDoc->layerCount();
2937 cbradney 455
        for (uint la2 = 0; la2 < layerCount; ++la2)
167 Franz 456
        {
690 cbradney 457
                if (currentDoc->Layers[la2].Level == Level)
8 paul 458
                {
1065 cbradney 459
                        ll->isViewable = currentDoc->Layers[la2].isViewable;
460
                        ll->isPrintable = currentDoc->Layers[la2].isPrintable;
690 cbradney 461
                        ll->LNr = currentDoc->Layers[la2].LNr;
1737 fschmid 462
                        ll->Name = currentDoc->Layers[la2].Name;
5373 fschmid 463
                        ll->flowControl = currentDoc->Layers[la2].flowControl;
464
                        ll->transparency = currentDoc->Layers[la2].transparency;
5375 fschmid 465
                        ll->blendMode = currentDoc->Layers[la2].blendMode;
8 paul 466
                        break;
467
                }
167 Franz 468
        }
8 paul 469
}
470
 
2937 cbradney 471
/* CB Replaced by ScribusDoc::layerLevelFromNumber
2122 fschmid 472
int Layer2Level(ScribusDoc *currentDoc, int LayerNr)
473
{
2937 cbradney 474
        int retVal=currentDoc->layerLevelFromNumber(LayerNr);
475
        int layerCount=currentDoc->layerCount();
476
        for (uint la2 = 0; la2 < layerCount; ++la2)
2122 fschmid 477
        {
478
                if (currentDoc->Layers[la2].LNr == LayerNr)
479
                        return currentDoc->Layers[la2].Level;
480
        }
481
        return 0;
482
}
2937 cbradney 483
*/
8 paul 484
QString CompressStr(QString *in)
485
{
486
        QString out = "";
487
        QByteArray bb(in->length());
488
        for (uint ax = 0; ax < in->length(); ++ax)
489
                bb[ax] = uchar(QChar(in->at(ax)));
490
        uLong exlen = uint(bb.size() * 0.001 + 16) + bb.size();
491
        QByteArray bc(exlen);
2295 cbradney 492
        int errcode = compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
3158 craig 493
        if (errcode != Z_OK)
494
        {
495
                qDebug("compress2 failed with code %i", errcode);
2295 cbradney 496
                out = *in;
497
        }
498
        else {
499
                for (uint cl = 0; cl < exlen; ++cl)
2884 fschmid 500
                        out += QChar(bc[cl]);
2295 cbradney 501
        }
8 paul 502
        return out;
503
}
504
 
5234 fschmid 505
QByteArray CompressArray(QByteArray *in)
506
{
507
        QByteArray out;
508
        uLong exlen = uint(in->size() * 0.001 + 16) + in->size();
509
        QByteArray temp(exlen);
510
        int errcode = compress2((Byte *)temp.data(), &exlen, (Byte *)in->data(), uLong(in->size()), 9);
511
        if (errcode != Z_OK)
512
        {
513
                qDebug("compress2 failed with code %i", errcode);
514
                out = *in;
515
        }
516
        else {
517
                temp.resize(exlen);
518
                out = temp;
519
        }
520
        return out;
521
}
522
 
8 paul 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
{
6125 cbradney 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
        {
7152 jghali 629
                QString fn = QDir::convertSeparators(filename);
4546 subik 630
                int t = ScMessageBox::warning(parent, QObject::tr("File exists"),
7152 jghali 631
                                                                        "<qt>"+ QObject::tr("A file named '%1' already exists.<br/>Do you want to replace it with the file you are saving?").arg(fn) +"</qt>",
3733 cbradney 632
                                                                        QObject::tr("&Replace"), CommonStrings::tr_Cancel, "", 1, 1);
633
                if (t == 1)
90 Franz 634
                        retval = false;
1555 fschmid 635
        }
636
        return retval;
90 Franz 637
}
124 Franz 638
 
1957 cbradney 639
void WordAndPara(PageItem* currItem, int *w, int *p, int *c, int *wN, int *pN, int *cN)
125 Franz 640
{
641
        QChar Dat = QChar(32);
642
        int para = 0;
643
        int ww = 0;
644
        int cc = 0;
645
        int paraN = 0;
646
        int wwN = 0;
647
        int ccN = 0;
648
        bool first = true;
1957 cbradney 649
        PageItem *nextItem = currItem;
650
        PageItem *nbl = currItem;
651
        while (nextItem != 0)
167 Franz 652
        {
7994 avox 653
                if (nextItem->prevInChain() != 0)
654
                        nextItem = nextItem->prevInChain();
125 Franz 655
                else
656
                        break;
167 Franz 657
        }
1957 cbradney 658
        while (nextItem != 0)
167 Franz 659
        {
6377 avox 660
                for (int a = QMAX(nextItem->firstInFrame(),0); a <= nextItem->lastInFrame() && a < nextItem->itemText.length(); ++a)
1555 fschmid 661
                {
5184 avox 662
                        QChar b = nextItem->itemText.text(a);
5732 avox 663
                        if (b == SpecialChars::PARSEP)
167 Franz 664
                        {
5732 avox 665
                                para++;
167 Franz 666
                        }
125 Franz 667
                        if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
167 Franz 668
                        {
5732 avox 669
                                ww++;
167 Franz 670
                        }
5732 avox 671
                        cc++;
1555 fschmid 672
                        Dat = b;
125 Franz 673
                        first = false;
1555 fschmid 674
                }
1957 cbradney 675
                nbl = nextItem;
7994 avox 676
                nextItem = nextItem->nextInChain();
167 Franz 677
        }
5732 avox 678
        if (nbl->frameOverflows()) {
125 Franz 679
                paraN++;
5736 avox 680
                for (int a = nbl->lastInFrame()+1; a < nbl->itemText.length(); ++a)
5732 avox 681
                {
5736 avox 682
                        QChar b = nbl->itemText.text(a);
5732 avox 683
                        if (b == SpecialChars::PARSEP)
684
                        {
685
                                paraN++;
686
                        }
687
                        if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
688
                        {
689
                                wwN++;
690
                        }
691
                        ccN++;
692
                        Dat = b;
693
                        first = false;
694
                }
695
        }              
696
        else {
125 Franz 697
                para++;
5732 avox 698
        }
125 Franz 699
        if (Dat.isLetterOrNumber())
167 Franz 700
        {
5559 avox 701
                if (nbl->frameOverflows())
125 Franz 702
                        wwN++;
703
                else
704
                        ww++;
167 Franz 705
        }
125 Franz 706
        *w = ww;
707
        *p = para;
708
        *c = cc;
709
        *wN = wwN;
710
        *pN = paraN;
711
        *cN = ccN;
712
}
203 Franz 713
 
690 cbradney 714
void ReOrderText(ScribusDoc *currentDoc, ScribusView *view)
203 Franz 715
{
4593 cbradney 716
        double savScale = view->scale();
2380 cbradney 717
        view->setScale(1.0);
690 cbradney 718
        currentDoc->RePos = true;
203 Franz 719
        QPixmap pgPix(10, 10);
720
        QRect rd = QRect(0,0,9,9);
721
        ScPainter *painter = new ScPainter(&pgPix, pgPix.width(), pgPix.height());
690 cbradney 722
        for (uint azz=0; azz<currentDoc->MasterItems.count(); ++azz)
203 Franz 723
        {
1957 cbradney 724
                PageItem *currItem = currentDoc->MasterItems.at(azz);
725
                if (currItem->itemType() == PageItem::PathText)
726
                        currItem->DrawObj(painter, rd);
203 Franz 727
        }
3727 cbradney 728
        for (uint azz=0; azz<currentDoc->Items->count(); ++azz)
203 Franz 729
        {
3727 cbradney 730
                PageItem *currItem = currentDoc->Items->at(azz);
7145 jghali 731
                if (currItem->itemType() == PageItem::TextFrame)
732
                        currItem->asTextFrame()->layout();
733
                else if (currItem->itemType() == PageItem::PathText)
1957 cbradney 734
                        currItem->DrawObj(painter, rd);
203 Franz 735
        }
690 cbradney 736
        currentDoc->RePos = false;
2380 cbradney 737
        view->setScale(savScale);
203 Franz 738
        delete painter;
739
}
447 cbradney 740
 
4449 subik 741
/*! \brief Helper function for sorting in sortQStringList.
742
\author 10/06/2004 - pv
4645 subik 743
\param s1 first string
744
\param s2 second string
447 cbradney 745
\retval bool t/f related s1>s2
746
 */
747
bool compareQStrings(QString s1, QString s2)
748
{
749
        if (QString::localeAwareCompare(s1, s2) >= 0)
2680 cbradney 750
                return false;
751
        return true;
447 cbradney 752
}
753
 
754
QStringList sortQStringList(QStringList aList)
755
{
756
        std::vector<QString> sortList;
757
        QStringList retList;
758
        QStringList::Iterator it;
759
        for (it = aList.begin(); it != aList.end(); ++it)
760
                sortList.push_back(*it);
761
        std::sort(sortList.begin(), sortList.end(), compareQStrings);
456 fschmid 762
        for(uint i = 0; i < sortList.size(); i++)
447 cbradney 763
                retList.append(sortList[i]);
764
        return retList;
765
}
517 fschmid 766
 
1065 cbradney 767
void GetItemProps(bool newVersion, QDomElement *obj, struct CopyPasteBuffer *OB)
517 fschmid 768
{
769
        QString tmp;
770
        int x, y;
2282 fschmid 771
        double xf, yf, xf2;
4026 craig 772
        OB->PType = static_cast<PageItem::ItemType>(obj->attribute("PTYPE").toInt());
773
        OB->Width=obj->attribute("WIDTH").toDouble();
774
        OB->Height=obj->attribute("HEIGHT").toDouble();
775
        OB->RadRect = obj->attribute("RADRECT", "0").toDouble();
776
        OB->ClipEdited = obj->attribute("CLIPEDIT", "0").toInt();
777
        OB->FrameType = obj->attribute("FRTYPE", "0").toInt();
778
        OB->Pwidth=obj->attribute("PWIDTH").toDouble();
1394 cbradney 779
        OB->Pcolor = obj->attribute("PCOLOR");
517 fschmid 780
        if ((!newVersion) && (OB->PType == 4))
781
        {
782
                OB->TxtFill = obj->attribute("PCOLOR2");
4546 subik 783
                OB->Pcolor2 = CommonStrings::None;
517 fschmid 784
        }
785
        else
786
        {
787
                OB->Pcolor2 = obj->attribute("PCOLOR2");
788
                OB->TxtFill = obj->attribute("TXTFILL", "Black");
789
        }
4026 craig 790
        OB->Shade = obj->attribute("SHADE").toInt();
791
        OB->Shade2 = obj->attribute("SHADE2").toInt();
6454 jghali 792
        OB->FillRule = obj->attribute("fillRule", "1").toInt();
4546 subik 793
        OB->TxtStroke=obj->attribute("TXTSTROKE", CommonStrings::None);
4026 craig 794
        OB->ShTxtFill=obj->attribute("TXTFILLSH", "100").toInt();
795
        OB->ShTxtStroke=obj->attribute("TXTSTRSH", "100").toInt();
796
        OB->TxtScale=qRound(obj->attribute("TXTSCALE", "100").toDouble() * 10);
797
        OB->TxtScaleV=qRound(obj->attribute("TXTSCALEV", "100").toDouble() * 10);
798
        OB->TxTBase=qRound(obj->attribute("TXTBASE", "0").toDouble() * 10);
799
        OB->TxTStyle=obj->attribute("TXTSTYLE", "0").toInt();
800
        OB->TxtShadowX=qRound(obj->attribute("TXTSHX", "5").toDouble() * 10);
801
        OB->TxtShadowY=qRound(obj->attribute("TXTSHY", "-5").toDouble() * 10);
802
        OB->TxtOutline=qRound(obj->attribute("TXTOUT", "1").toDouble() * 10);
803
        OB->TxtUnderPos=qRound(obj->attribute("TXTULP", "-0.1").toDouble() * 10);
804
        OB->TxtUnderWidth=qRound(obj->attribute("TXTULW", "-0.1").toDouble() * 10);
805
        OB->TxtStrikePos=qRound(obj->attribute("TXTSTP", "-0.1").toDouble() * 10);
806
        OB->TxtStrikeWidth=qRound(obj->attribute("TXTSTW", "-0.1").toDouble() * 10);
807
        OB->Cols = obj->attribute("COLUMNS", "1").toInt();
808
        OB->ColGap = obj->attribute("COLGAP", "0.0").toDouble();
809
        OB->GrType = obj->attribute("GRTYP", "0").toInt();
517 fschmid 810
        OB->fill_gradient.clearStops();
811
        if (OB->GrType != 0)
812
        {
6369 fschmid 813
                if (OB->GrType == 8)
6414 fschmid 814
                {
6369 fschmid 815
                        OB->pattern = obj->attribute("pattern", "");
6414 fschmid 816
                        OB->patternScaleX = obj->attribute("pScaleX", "100.0").toDouble();
817
                        OB->patternScaleY = obj->attribute("pScaleY", "100.0").toDouble();
818
                        OB->patternOffsetX = obj->attribute("pOffsetX", "0.0").toDouble();
819
                        OB->patternOffsetY = obj->attribute("pOffsetY", "0.0").toDouble();
820
                        OB->patternRotation = obj->attribute("pRotation", "0.0").toDouble();
821
                }
6369 fschmid 822
                else
823
                {
824
                        OB->GrStartX = obj->attribute("GRSTARTX", "0.0").toDouble();
825
                        OB->GrStartY = obj->attribute("GRSTARTY", "0.0").toDouble();
826
                        OB->GrEndX = obj->attribute("GRENDX", "0.0").toDouble();
827
                        OB->GrEndY = obj->attribute("GRENDY", "0.0").toDouble();
828
                        OB->GrColor = obj->attribute("GRCOLOR","");
829
                        if (OB->GrColor.isEmpty())
830
                                OB->GrColor = "Black";
831
                        OB->GrColor2 = obj->attribute("GRCOLOR2","Black");
832
                        if (OB->GrColor2.isEmpty())
833
                                OB->GrColor2 = "Black";
834
                        OB->GrShade = obj->attribute("GRSHADE", "100").toInt();
835
                        OB->GrShade2 = obj->attribute("GRSHADE2", "100").toInt();
836
                }
517 fschmid 837
        }
4026 craig 838
        OB->Rot=obj->attribute("ROT").toDouble();
839
        OB->PLineArt=Qt::PenStyle(obj->attribute("PLINEART").toInt());
840
        OB->PLineEnd=Qt::PenCapStyle(obj->attribute("PLINEEND", "0").toInt());
841
        OB->PLineJoin=Qt::PenJoinStyle(obj->attribute("PLINEJOIN", "0").toInt());
842
        OB->LineSp=obj->attribute("LINESP").toDouble();
843
        OB->LineSpMode = obj->attribute("LINESPMode", "0").toInt();
844
        OB->LocalScX=obj->attribute("LOCALSCX").toDouble();
845
        OB->LocalScY=obj->attribute("LOCALSCY").toDouble();
846
        OB->LocalX=obj->attribute("LOCALX").toDouble();
847
        OB->LocalY=obj->attribute("LOCALY").toDouble();
848
        OB->PicArt=obj->attribute("PICART").toInt();
849
        OB->flippedH = obj->attribute("FLIPPEDH").toInt() % 2;
850
        OB->flippedV = obj->attribute("FLIPPEDV").toInt() % 2;
4335 fschmid 851
/*      OB->BBoxX=obj->attribute("BBOXX").toDouble();
852
        OB->BBoxH=obj->attribute("BBOXH").toDouble(); */
4026 craig 853
        OB->ScaleType = obj->attribute("SCALETYPE", "1").toInt();
854
        OB->AspectRatio = obj->attribute("RATIO", "0").toInt();
855
        OB->isPrintable=obj->attribute("PRINTABLE").toInt();
4084 cbradney 856
        OB->m_isAnnotation=obj->attribute("ANNOTATION", "0").toInt();
857
        OB->m_annotation.setType(obj->attribute("ANTYPE", "0").toInt());
858
        OB->m_annotation.setAction(obj->attribute("ANACTION",""));
859
        OB->m_annotation.setE_act(obj->attribute("ANEACT",""));
860
        OB->m_annotation.setX_act(obj->attribute("ANXACT",""));
861
        OB->m_annotation.setD_act(obj->attribute("ANDACT",""));
862
        OB->m_annotation.setFo_act(obj->attribute("ANFOACT",""));
863
        OB->m_annotation.setBl_act(obj->attribute("ANBLACT",""));
864
        OB->m_annotation.setK_act(obj->attribute("ANKACT",""));
865
        OB->m_annotation.setF_act(obj->attribute("ANFACT",""));
866
        OB->m_annotation.setV_act(obj->attribute("ANVACT",""));
867
        OB->m_annotation.setC_act(obj->attribute("ANCACT",""));
868
        OB->m_annotation.setActionType(obj->attribute("ANACTYP", "0").toInt());
869
        OB->m_annotation.setExtern(obj->attribute("ANEXTERN",""));
870
        if ((!OB->m_annotation.Extern().isEmpty()) && (OB->m_annotation.ActionType() != 8))
517 fschmid 871
        {
4084 cbradney 872
                QFileInfo efp(OB->m_annotation.Extern());
873
                OB->m_annotation.setExtern(efp.absFilePath());
517 fschmid 874
        }
4084 cbradney 875
        OB->m_annotation.setZiel(obj->attribute("ANZIEL", "0").toInt());
876
        OB->AnName=obj->attribute("ANNAME","");
877
        OB->m_annotation.setToolTip(obj->attribute("ANTOOLTIP",""));
878
        OB->m_annotation.setRollOver(obj->attribute("ANROLL",""));
879
        OB->m_annotation.setDown(obj->attribute("ANDOWN",""));
880
        OB->m_annotation.setBwid(obj->attribute("ANBWID", "1").toInt());
881
        OB->m_annotation.setBsty(obj->attribute("ANBSTY", "0").toInt());
882
        OB->m_annotation.setFeed(obj->attribute("ANFEED", "1").toInt());
883
        OB->m_annotation.setFlag(obj->attribute("ANFLAG", "0").toInt());
884
        OB->m_annotation.setFont(obj->attribute("ANFONT", "4").toInt());
885
        OB->m_annotation.setFormat(obj->attribute("ANFORMAT", "0").toInt());
886
        OB->m_annotation.setVis(obj->attribute("ANVIS", "0").toInt());
887
        OB->m_annotation.setIsChk(static_cast<bool>(obj->attribute("ANCHK", "0").toInt()));
888
        OB->m_annotation.setAAact(static_cast<bool>(obj->attribute("ANAA", "0").toInt()));
889
        OB->m_annotation.setHTML(static_cast<bool>(obj->attribute("ANHTML", "0").toInt()));
890
        OB->m_annotation.setUseIcons(static_cast<bool>(obj->attribute("ANICON", "0").toInt()));
891
        OB->m_annotation.setChkStil(obj->attribute("ANCHKS", "0").toInt());
892
        OB->m_annotation.setMaxChar(obj->attribute("ANMC", "-1").toInt());
4546 subik 893
        OB->m_annotation.setBorderColor(obj->attribute("ANBCOL",CommonStrings::None));
4084 cbradney 894
        OB->m_annotation.setIPlace(obj->attribute("ANPLACE", "1").toInt());
895
        OB->m_annotation.setScaleW(obj->attribute("ANSCALE", "0").toInt());
4026 craig 896
        if (obj->attribute("TRANSPARENT", "0").toInt() == 1)
4546 subik 897
                OB->Pcolor = CommonStrings::None;
6604 jghali 898
        OB->textAlignment=obj->attribute("ALIGN", "0").toInt();
5620 jghali 899
        if ( obj->hasAttribute("TEXTFLOWMODE") )
900
                OB->TextflowMode = (PageItem::TextFlowMode) obj->attribute("TEXTFLOWMODE", "0").toInt();
901
        else if ( obj->attribute("TEXTFLOW").toInt() )
902
        {
903
                if (obj->attribute("TEXTFLOW2", "0").toInt())
904
                        OB->TextflowMode = PageItem::TextFlowUsesBoundingBox;
905
                else if (obj->attribute("TEXTFLOW3", "0").toInt())
906
                        OB->TextflowMode = PageItem::TextFlowUsesContourLine;
907
                else
908
                        OB->TextflowMode = PageItem::TextFlowUsesFrameShape;   
909
        }
910
        else
911
                OB->TextflowMode = PageItem::TextFlowDisabled;
4026 craig 912
        OB->Extra=obj->attribute("EXTRA").toDouble();
913
        OB->TExtra=obj->attribute("TEXTRA", "1").toDouble();
914
        OB->BExtra=obj->attribute("BEXTRA", "1").toDouble();
915
        OB->RExtra=obj->attribute("REXTRA", "1").toDouble();
916
        OB->PoShow = obj->attribute("PLTSHOW", "0").toInt();
917
        OB->BaseOffs = obj->attribute("BASEOF", "0").toDouble();
7926 fschmid 918
        OB->textPathType =  obj->attribute("textPathType", "0").toInt();
919
        OB->textPathFlipped = static_cast<bool>(obj->attribute("textPathFlipped", "0").toInt());
4026 craig 920
        OB->ISize = qRound(obj->attribute("ISIZE", "12").toDouble() * 10);
2382 fschmid 921
        if (obj->hasAttribute("EXTRAV"))
4026 craig 922
                OB->ExtraV = qRound(obj->attribute("EXTRAV", "0").toDouble() / obj->attribute("ISIZE", "12").toDouble() * 1000.0);
2382 fschmid 923
        else
4026 craig 924
                OB->ExtraV = obj->attribute("TXTKERN").toInt();
517 fschmid 925
        OB->Pfile=obj->attribute("PFILE");
926
        OB->Pfile2=obj->attribute("PFILE2","");
927
        OB->Pfile3=obj->attribute("PFILE3","");
928
        OB->IProfile=obj->attribute("PRFILE","");
929
        OB->EmProfile=obj->attribute("EPROF","");
4026 craig 930
        OB->IRender = obj->attribute("IRENDER", "1").toInt();
931
        OB->UseEmbedded = obj->attribute("EMBEDDED", "1").toInt();
932
        OB->Locked = static_cast<bool>(obj->attribute("LOCK", "0").toInt());
933
        OB->LockRes = static_cast<bool>(obj->attribute("LOCKR", "0").toInt());
934
        OB->Reverse = static_cast<bool>(obj->attribute("REVERS", "0").toInt());
935
        OB->isTableItem = static_cast<bool>(obj->attribute("isTableItem", "0").toInt());
936
        OB->TopLine = static_cast<bool>(obj->attribute("TopLine", "0").toInt());
937
        OB->LeftLine = static_cast<bool>(obj->attribute("LeftLine", "0").toInt());
938
        OB->RightLine = static_cast<bool>(obj->attribute("RightLine", "0").toInt());
939
        OB->BottomLine = static_cast<bool>(obj->attribute("BottomLine", "0").toInt());
940
        OB->TopLinkID =  obj->attribute("TopLINK", "-1").toInt();
941
        OB->LeftLinkID =  obj->attribute("LeftLINK", "-1").toInt();
942
        OB->RightLinkID =  obj->attribute("RightLINK", "-1").toInt();
943
        OB->BottomLinkID =  obj->attribute("BottomLINK", "-1").toInt();
944
        OB->Transparency = obj->attribute("TransValue", "0.0").toDouble();
517 fschmid 945
        if (obj->hasAttribute("TransValueS"))
4026 craig 946
                OB->TranspStroke = obj->attribute("TransValueS", "0.0").toDouble();
517 fschmid 947
        else
948
                OB->TranspStroke = OB->Transparency;
5746 fschmid 949
        OB->TransBlend = obj->attribute("TransBlend", "0").toInt();
950
        OB->TransBlendS = obj->attribute("TransBlendS", "0").toInt();
517 fschmid 951
        tmp = "";
952
        if (obj->hasAttribute("NUMCLIP"))
953
        {
954
                OB->Clip.resize(obj->attribute("NUMCLIP").toUInt());
955
                tmp = obj->attribute("CLIPCOOR");
956
                QTextStream fc(&tmp, IO_ReadOnly);
957
                for (uint c=0; c<obj->attribute("NUMCLIP").toUInt(); ++c)
958
                {
959
                        fc >> x;
960
                        fc >> y;
961
                        OB->Clip.setPoint(c, x, y);
962
                }
963
        }
964
        else
965
                OB->Clip.resize(0);
966
        tmp = "";
967
        if (obj->hasAttribute("NUMPO"))
968
        {
969
                OB->PoLine.resize(obj->attribute("NUMPO").toUInt());
970
                tmp = obj->attribute("POCOOR");
971
                QTextStream fp(&tmp, IO_ReadOnly);
972
                for (uint cx=0; cx<obj->attribute("NUMPO").toUInt(); ++cx)
973
                {
974
                        fp >> xf;
975
                        fp >> yf;
976
                        OB->PoLine.setPoint(cx, xf, yf);
977
                }
978
        }
979
        else
980
                OB->PoLine.resize(0);
981
        tmp = "";
982
        if (obj->hasAttribute("NUMCO"))
983
        {
984
                OB->ContourLine.resize(obj->attribute("NUMCO").toUInt());
985
                tmp = obj->attribute("COCOOR");
986
                QTextStream fp(&tmp, IO_ReadOnly);
987
                for (uint cx=0; cx<obj->attribute("NUMCO").toUInt(); ++cx)
988
                {
989
                        fp >> xf;
990
                        fp >> yf;
991
                        OB->ContourLine.setPoint(cx, xf, yf);
992
                }
993
        }
994
        else
995
                OB->ContourLine.resize(0);
996
        tmp = "";
4026 craig 997
        if ((obj->hasAttribute("NUMTAB")) && (obj->attribute("NUMTAB", "0").toInt() != 0))
517 fschmid 998
        {
5184 avox 999
                ParagraphStyle::TabRecord tb;
517 fschmid 1000
                tmp = obj->attribute("TABS");
1001
                QTextStream tgv(&tmp, IO_ReadOnly);
1002
                OB->TabValues.clear();
4026 craig 1003
                for (int cxv = 0; cxv < obj->attribute("NUMTAB", "0").toInt(); cxv += 2)
517 fschmid 1004
                {
1005
                        tgv >> xf;
2282 fschmid 1006
                        tgv >> xf2;
1007
                        tb.tabPosition = xf2;
1008
                        tb.tabType = static_cast<int>(xf);
1009
                        tb.tabFillChar = QChar();
1010
                        OB->TabValues.append(tb);
517 fschmid 1011
                }
1012
                tmp = "";
1013
        }
1014
        else
1015
                OB->TabValues.clear();
4026 craig 1016
        if ((obj->hasAttribute("NUMDASH")) && (obj->attribute("NUMDASH", "0").toInt() != 0))
517 fschmid 1017
        {
1018
                tmp = obj->attribute("DASHS");
1019
                QTextStream dgv(&tmp, IO_ReadOnly);
1020
                OB->DashValues.clear();
4026 craig 1021
                for (int cxv = 0; cxv < obj->attribute("NUMDASH", "0").toInt(); ++cxv)
517 fschmid 1022
                {
1023
                        dgv >> xf;
1024
                        OB->DashValues.append(xf);
1025
                }
1026
                tmp = "";
1027
        }
1028
        else
1029
                OB->DashValues.clear();
4026 craig 1030
        OB->DashOffset = obj->attribute("DASHOFF", "0.0").toDouble();
517 fschmid 1031
}
1032
 
2529 craig 1033
FPoint getMaxClipF(FPointArray* Clip)
1034
{
1035
        FPoint np, rp;
1036
        double mx = 0;
1037
        double my = 0;
3719 cbradney 1038
        uint clipSize=Clip->size();
1039
        for (uint c = 0; c < clipSize; ++c)
2529 craig 1040
        {
1041
                np = Clip->point(c);
1042
                if (np.x() > 900000)
1043
                        continue;
1044
                if (np.x() > mx)
1045
                        mx = np.x();
1046
                if (np.y() > my)
1047
                        my = np.y();
1048
        }
1049
        rp.setXY(mx, my);
1050
        return rp;
1051
}
1052
 
1053
FPoint getMinClipF(FPointArray* Clip)
1054
{
1055
        FPoint np, rp;
1056
        double mx = 99999;
1057
        double my = 99999;
3719 cbradney 1058
        uint clipSize=Clip->size();
1059
        for (uint c = 0; c < clipSize; ++c)
2529 craig 1060
        {
1061
                np = Clip->point(c);
1062
                if (np.x() > 900000)
1063
                        continue;
1064
                if (np.x() < mx)
1065
                        mx = np.x();
1066
                if (np.y() < my)
1067
                        my = np.y();
1068
        }
1069
        rp.setXY(mx, my);
1070
        return rp;
1071
}
1072
 
2834 cbradney 1073
QString checkFileExtension(const QString &currName, const QString &extension)
1074
{
1075
        QString newName(currName);
1076
        //If filename ends with a period, just add the extension
1077
        if (newName.right(1)==".")
1078
        {
1079
                newName+=extension.lower();
1080
                return newName;
1081
        }
1082
        //If filename doesnt end with the period+extension, add it on
1083
        QString dotExt("." + extension.lower());
1084
        if (!newName.endsWith(dotExt,false))
1085
                newName+=dotExt;
1086
        return newName;
1087
}
2907 subik 1088
 
5781 cbradney 1089
QString getFileNameByPage(ScribusDoc* currDoc, uint pageNo, QString extension)
2907 subik 1090
{
1091
        QString number;
5781 cbradney 1092
        number = number.setNum(pageNo + currDoc->FirstPnum);
1093
        QString defaultName = currDoc->DocName;
2907 subik 1094
        if (defaultName.isNull())
1095
                defaultName = "export";
1096
        else
1097
        {
1098
                QFileInfo fi(defaultName);
1099
                defaultName = fi.baseName(true);
1100
        }
2954 subik 1101
        return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number).arg(extension);
2907 subik 1102
}
3689 cbradney 1103
 
9390 jghali 1104
bool compareDouble(double a, double b)
1105
{
1106
        if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
1107
        {
1108
                long al = static_cast<long>(10000 * a);
1109
                long bl = static_cast<long>(10000 * b);
1110
                return al == bl;
1111
        }
1112
        return a == b;
1113
}
1114
 
3689 cbradney 1115
inline double square(double x)
1116
{
1117
        return x*x;
1118
}
1119
 
1120
inline double distance(double x, double y)
1121
{
1122
        return sqrt(x*x+y*y);
1123
}
1124
 
6618 fschmid 1125
double constrainAngle(double angle, double constrain)
4754 cbradney 1126
{
1127
        double newAngle=angle;
6618 fschmid 1128
        double constrainTo=constrain;
4754 cbradney 1129
        if (newAngle<0.0)
1130
                newAngle+=360.0;
1131
        newAngle=qRound(angle/constrainTo)*constrainTo;
1132
        if (newAngle==360.0)
1133
                newAngle=0.0;
1134
        return newAngle;
1135
}
1136
 
6604 jghali 1137
double getRotationFromMatrix(QWMatrix& matrix, double def)
1138
{
1139
        double value = def;
6624 jghali 1140
        double norm = sqrt(fabs(matrix.det()));
6604 jghali 1141
        if (norm > 0.0000001)
1142
        {
1143
                double m11 = matrix.m11() / norm;
1144
                double m12 = matrix.m12() / norm;
1145
                double m21 = matrix.m21() / norm;
1146
                double m22 = matrix.m22() / norm;
6624 jghali 1147
                if (fabs(m11) <= 1.0 && fabs(m12) <= 1.0 && fabs(m21) <= 1.0 && fabs(m22) <= 1.0)
6604 jghali 1148
                {
6624 jghali 1149
                        QWMatrix mat(m11, m12, m21, m22, 0, 0);
1150
                        if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
1151
                        {
1152
                                double ac = acos(mat.m11());
1153
                                value = (mat.m21() >= 0.0) ? ac : (-ac);
1154
                        }
6604 jghali 1155
                }
1156
        }
1157
        return value;
1158
}
1159
 
3757 cbradney 1160
const QString getStringFromSequence(DocumentSectionType type, uint position)
1161
{
1162
        QString retVal("");
1163
        switch( type )
1164
        {
3778 cbradney 1165
                case Type_1_2_3:
1166
                        retVal=QString::number(position);
1167
                        break;
3757 cbradney 1168
                case Type_A_B_C:
3778 cbradney 1169
                        retVal=numberToLetterSequence(position).upper();
1170
                        break;
3757 cbradney 1171
                case Type_a_b_c:
3778 cbradney 1172
                        retVal=numberToLetterSequence(position);
3757 cbradney 1173
                        break;
1174
                case Type_I_II_III:
1175
                        retVal=arabicToRoman(position);
1176
                        break;
1177
                case Type_i_ii_iii:
1178
                        //well, for lower case people will want that, even if its "wrong"
1179
                        //ie, X=10, x=10000
1180
                        retVal=arabicToRoman(position).lower();
1181
                        break;
8439 cbradney 1182
                case Type_None:
1183
                        break;
3757 cbradney 1184
                default:
1185
                        break;
1186
        }
1187
        return retVal;
1188
}
1189
 
1190
const QString numberToLetterSequence(uint i)
1191
{
1192
        QString retVal("");
1193
        unsigned digits = 1;
1194
        unsigned offset = 0;
1195
        uint column=i;
1196
        --column;
1197
 
1198
        if( column > 4058115285U ) return  QString("@");
1199
 
1200
        for( unsigned limit = 26; column >= limit+offset; limit *= 26, digits++ )
1201
                offset += limit;
1202
 
1203
        for( unsigned c = column - offset; digits; --digits, c/=26 )
1204
                retVal.prepend( QChar( 'a' + (c%26) ) );
1205
        return retVal;
1206
}
1207
 
1208
const QString arabicToRoman(uint i)
1209
{
1210
        QString roman("");
1211
        int arabic = i;
1212
        while (arabic - 1000000 >= 0){
1213
        roman += "m";
1214
        arabic -= 1000000;
1215
        }
1216
        while (arabic - 900000 >= 0){
1217
        roman += "cm";
1218
        arabic -= 900000;
1219
        }
1220
        while (arabic - 500000 >= 0){
1221
        roman += "d";
1222
        arabic -= 500000;
1223
        }
1224
        while (arabic - 400000 >= 0){
1225
        roman += "cd";
1226
        arabic -= 400000;
1227
        }
1228
        while (arabic - 100000 >= 0){
1229
        roman += "c";
1230
        arabic -= 100000;
1231
        }
1232
        while (arabic - 90000 >= 0){
1233
        roman += "xc";
1234
        arabic -= 90000;
1235
        }
1236
        while (arabic - 50000 >= 0){
1237
        roman += "l";
1238
        arabic -= 50000;
1239
        }
1240
        while (arabic - 40000 >= 0){
1241
        roman += "xl";
1242
        arabic -= 40000;
1243
        }
1244
        while (arabic - 10000 >= 0){
1245
        roman += "x";
1246
        arabic -= 10000;
1247
        }
1248
        while (arabic - 9000 >= 0){
1249
        roman += "Mx";
1250
        arabic -= 9000;
1251
        }
1252
        while (arabic - 5000 >= 0){
1253
        roman += "v";
1254
        arabic -= 5000;
1255
        }
1256
        while (arabic - 4000 >= 0){
1257
        roman += "Mv";
1258
        arabic -= 4000;
1259
        }
1260
        while (arabic - 1000 >= 0){
1261
        roman += "M";
1262
        arabic -= 1000;
1263
        }
1264
        while (arabic - 900 >= 0){
1265
        roman += "CM";
1266
        arabic -= 900;
1267
        }
1268
        while (arabic - 500 >= 0){
1269
        roman += "D";
1270
        arabic -= 500;
1271
        }
1272
        while (arabic - 400 >= 0){
1273
        roman += "CD";
1274
        arabic -= 400;
1275
        }
1276
        while (arabic - 100 >= 0){
1277
        roman += "C";
1278
        arabic -= 100;
1279
        }
1280
        while (arabic - 90 >= 0){
1281
        roman += "XC";
1282
        arabic -= 90;
1283
        }
1284
        while (arabic - 50 >= 0){
1285
        roman += "L";
1286
        arabic -= 50;
1287
        }
1288
        while (arabic - 40 >= 0){
1289
        roman += "XL";
1290
        arabic -= 40;
1291
        }
1292
        while (arabic - 10 >= 0){
1293
        roman += "X";
1294
        arabic -= 10;
1295
        }
1296
        while (arabic - 9 >= 0){
1297
        roman += "IX";
1298
        arabic -= 9;
1299
        }
1300
        while (arabic - 5 >= 0){
1301
        roman += "V";
1302
        arabic -= 5;
1303
        }
1304
        while (arabic - 4 >= 0){
1305
        roman += "IV";
1306
        arabic -= 4;
1307
        }
1308
        while (arabic - 1 >= 0){
1309
        roman += "I";
1310
        arabic -= 1;
1311
        }
1312
        return roman;
3776 cbradney 1313
}
3784 cbradney 1314
 
1315
//CB Moved from scribus.cpp
1316
void parsePagesString(QString pages, std::vector<int>* pageNs, int sourcePageCount)
1317
{
1318
        QString tmp(pages);
1319
        QString token;
1320
        int from, to, pageNr;
1321
        do
1322
        {
1323
                if (tmp.find(",") == -1)
1324
                {
1325
                        token = tmp;
1326
                        tmp = "";
1327
                }
1328
                else
1329
                {
1330
                        token = tmp.left(tmp.find(","));
1331
                        tmp = tmp.right(tmp.length() - tmp.find(",") - 1);
1332
                }
1333
 
1334
                token = token.stripWhiteSpace();
1335
                if (token == "*") // Import all source doc pages
1336
                {
1337
                        for (int i = 1; i <= sourcePageCount; ++i)
1338
                                pageNs->push_back(i);
1339
                }
1340
                else if (token.find("-") != -1) // import a range of source doc pages
1341
                {
1342
                        from = QString(token.left(token.find("-"))).toInt();
1343
                        to = QString(token.right(token.length() - token.find("-") - 1)).toInt();
1344
                        if ((from != 0) && (to != 0))
1345
                        {
1346
                                if (from > sourcePageCount)
1347
                                        from = sourcePageCount;
1348
                                if (to > sourcePageCount)
1349
                                        to = sourcePageCount;
1350
                                if (from == to)
1351
                                        pageNs->push_back(to);
1352
                                else if (from < to)
1353
                                {
1354
                                        for (int i = from; i <= to; ++i)
1355
                                                pageNs->push_back(i);
1356
                                }
1357
                                else
1358
                                {
1359
                                        for (int i = from; i >= to; --i)
1360
                                                pageNs->push_back(i);
1361
                                }
1362
                        }
1363
                }
1364
                else // import single source doc page
1365
                {
1366
                        pageNr = token.toInt();
1367
                        if ((pageNr > 0) && (pageNr <= sourcePageCount))
1368
                                pageNs->push_back(pageNr);
1369
                }
1370
        } while (!tmp.isEmpty());
3793 cbradney 1371
}
5184 avox 1372
 
1373
 
1374
int findParagraphStyle(ScribusDoc* doc, const ParagraphStyle& parStyle)
1375
{
1376
        bool named = !parStyle.name().isEmpty();
1377
//qDebug(QString("looking up %1/ %2").arg(parStyle.name()).arg(parStyle.alignment())); 
1378
        if (named) {
7442 avox 1379
                for (uint i=0; i < doc->paragraphStyles().count(); ++i)
5184 avox 1380
                {
7442 avox 1381
//qDebug(QString("%1 %2").arg(i).arg(doc->paragraphStyles()[i].name()));
1382
                        if (parStyle.name() == doc->paragraphStyles()[i].name()) {
5184 avox 1383
                                return i;
1384
                        }
1385
                }
1386
                assert(false);
1387
                return -1;
1388
        }
1389
        else {
6866 avox 1390
                return -1;
5184 avox 1391
        }
1392
}
5557 subik 1393
 
6044 tsoots 1394
int findParagraphStyle(ScribusDoc* doc, const QString &name)
1395
{
7442 avox 1396
        for (uint i=0; i < doc->paragraphStyles().count(); ++i)
6044 tsoots 1397
        {
7442 avox 1398
                if (name == doc->paragraphStyles()[i].name()) {
6044 tsoots 1399
                        return i;
1400
                }
1401
        }
1402
        assert(false);
1403
        return -1;
1404
}
1405
 
1406
 
5557 subik 1407
QPixmap getQCheckBoxPixmap(const bool checked, const QColor background)
1408
{
1409
        QCheckBox *tmpItem = new QCheckBox("", 0, "tmpItem");
1410
        tmpItem->setMaximumSize(QSize(30, 30));
1411
        tmpItem->setMinimumSize(QSize(30, 30));
1412
        tmpItem->setPaletteBackgroundColor(background);
1413
        tmpItem->setChecked(checked);
1414
        QPixmap pm = QPixmap::grabWidget(tmpItem);
1415
        pm.setMask(pm.createHeuristicMask());
1416
        delete tmpItem;
1417
        return pm;
1418
}
5712 fschmid 1419
 
1420
 
5890 subik 1421
void tDebug(QString message)
1422
{
1423
        QDateTime debugTime;
8305 cbradney 1424
        qDebug("%s", QString("%1\t%2").arg(debugTime.currentDateTime().toString("hh:mm:ss:zzz")).arg(message).ascii());
5890 subik 1425
}
6116 fschmid 1426
 
6124 cbradney 1427
QString setupImageFormats()
1428
{
1429
        QString formats = "";
1430
        QString formatD = QObject::tr("All Supported Formats")+" (";
1431
        QString form1 = "";
1432
        QString form2 = "";
1433
        for ( uint i = 0; i < QImageIO::inputFormats().count(); ++i )
1434
        {
1435
                form1 = QString(QImageIO::inputFormats().at(i)).lower();
1436
                form2 = QString(QImageIO::inputFormats().at(i)).upper();
1437
                if (form1 == "jpeg")
1438
                {
1439
                        form1 = "jpg";
1440
                        form2 = "JPG";
1441
                }
1442
                if ((form1 == "png") || (form1 == "xpm") || (form1 == "gif"))
1443
                {
1444
                        formats += form2 + " (*."+form1+" *."+form2+");;";
1445
                        formatD += "*."+form1+" *."+form2+" ";
1446
                }
1447
                else if (form1 == "jpg")
1448
                {
1449
                        // JPEG is a special case because both .jpg and .jpeg
1450
                        // are acceptable extensions.
1451
                        formats += "JPEG (*.jpg *.jpeg *.JPG *.JPEG);;";
1452
                        formatD += "*.jpg *.jpeg *.JPG *.JPEG ";
1453
                }
1454
        }
1455
        formats += "TIFF (*.tif *.tiff *.TIF *.TIFF);;";
1456
        formatD += "*.tif *.tiff *.TIF *.TIFF";
1457
        formats += "PSD (*.psd *.PSD);;";
1458
        formatD += " *.psd *.PSD";
7420 fschmid 1459
        formats += "EPS (*.eps *.EPS);;EPSI (*.epsi *.EPSI);;PDF (*.pdf *.PDF);;" + QObject::tr("All Files (*)");
1460
        formatD += " *.epsi *.EPSI *.eps *.EPS *.pdf *.PDF";
6124 cbradney 1461
        formatD += ");;"+formats;
1462
        return formatD;
1463
}
1464
 
6808 fschmid 1465
QString getImageType(QString filename)
1466
{
1467
        QString ret = "";
1468
        QFile f(filename);
1469
        QFileInfo fi(f);
1470
        if (fi.exists())
1471
        {
1472
                QByteArray buf(20);
1473
                if (f.open(IO_ReadOnly))
1474
                {
1475
                        f.readBlock(buf.data(), 20);
1476
                        if ((buf[0] == '%') && (buf[1] == '!') && (buf[2] == 'P') && (buf[3] == 'S') && (buf[4] == '-') && (buf[5] == 'A'))
1477
                                ret = "eps";
1478
                        else if ((buf[0] == '\xC5') && (buf[1] == '\xD0') && (buf[2] == '\xD3') && (buf[3] == '\xC6'))
1479
                                ret = "eps";
1480
                        else if ((buf[0] == 'G') && (buf[1] == 'I') && (buf[2] == 'F') && (buf[3] == '8'))
1481
                                ret = "gif";
1482
                        else if ((buf[0] == '\xFF') && (buf[1] == '\xD8') && (buf[2] == '\xFF'))
1483
                                ret = "jpg";
1484
                        else if ((buf[0] == '%') && (buf[1] == 'P') && (buf[2] == 'D') && (buf[3] == 'F'))
1485
                                ret = "pdf";
1486
                        else if ((buf[0] == '\x89') && (buf[1] == 'P') && (buf[2] == 'N') && (buf[3] == 'G'))
1487
                                ret = "png";
1488
                        else if ((buf[0] == '8') && (buf[1] == 'B') && (buf[2] == 'P') && (buf[3] == 'S'))
1489
                                ret = "psd";
1490
                        else if (((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == '\x2A')) || ((buf[0] == 'M') && (buf[1] == 'M') && (buf[3] == '\x2A')))
1491
                                ret = "tif";
1492
                        else if ((buf[0] == '/') && (buf[1] == '*') && (buf[2] == ' ') && (buf[3] == 'X') && (buf[4] == 'P') && (buf[5] == 'M'))
1493
                                ret = "xpm";
1494
                }
1495
        }
1496
        if (f.isOpen())
1497
                f.close();
1498
        return ret;
1499
 
1500
}