~ubuntu-branches/ubuntu/maverick/scribus-ng/maverick-backports

« back to all changes in this revision

Viewing changes to scribus/util.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Oleksandr Moskalenko
  • Date: 2009-02-09 09:25:18 UTC
  • mfrom: (5.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090209092518-iqsxmh3pjspgrdyd
Tags: 1.3.5.dfsg~svn20090208-2
debian/control: Use "type-handling -n arm,armel,armeb any" to generate the
list of architectures to build on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 *                                                                         *
22
22
 ***************************************************************************/
23
23
 
 
24
#include <algorithm>
24
25
#include "util.h"
25
 
#include <qbitmap.h>
26
 
#include <qfile.h>
27
 
#include <qfileinfo.h>
28
 
#include <qtextstream.h>
29
 
// #include <qdatastream.h>
30
 
// #include <qregexp.h>
31
 
#include <qdir.h>
32
 
#include <qdom.h>
33
 
#include <qcheckbox.h>
34
 
#include <qwidget.h>
35
 
 
36
 
// #include <algorithm>
37
 
// #include <cstdlib>
38
 
#include <cmath>
39
 
#include <algorithm>
40
 
#include "scconfig.h"
41
 
 
42
 
//#ifdef HAVE_UNISTD_H
43
 
//#include <unistd.h>
44
 
//#endif
45
 
 
46
 
#if defined(_WIN32)
47
 
#if defined(_MSC_VER)
48
 
#define __STDC__ 1 // hack to get md5_buffer correctly identified
49
 
#endif
50
 
#include <valarray>
51
 
#include <windows.h>
52
 
#endif
53
 
 
54
 
#include "md5.h"
55
 
 
56
 
// #include <setjmp.h>
57
 
#include "commonstrings.h"
58
 
// #include "pagestructs.h"
59
 
// #include "prefsfile.h"
60
 
// #include "prefscontext.h"
61
 
// #include "prefstable.h"
62
 
// #include "prefsmanager.h"
63
 
// #include "qprocess.h"
 
26
#include <zlib.h>
 
27
#include <QCryptographicHash>
 
28
#include <QDomElement>
 
29
#include <QProcess>
 
30
#include "pageitem.h"
64
31
#include "scmessagebox.h"
65
 
#include "scpixmapcache.h"
66
 
#include "scpaths.h"
67
 
// #include "text/nlsconfig.h"
68
 
 
69
 
extern "C"
70
 
{
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
 
 
83
 
#include "pageitem.h"
84
32
#include "scribus.h"
85
33
#include "scribusdoc.h"
86
 
#include "scribusview.h"
87
 
/*#include <ft2build.h>
88
 
#include FT_FREETYPE_H
89
 
#include FT_OUTLINE_H
90
 
#include FT_GLYPH_H
91
 
*/
92
 
#include <zlib.h>
93
 
 
 
34
#include "scpainter.h"
 
35
 
 
36
#include <signal.h>
 
37
 
 
38
#if !defined(_WIN32) && !defined(Q_OS_MAC) 
 
39
#include <execinfo.h>
 
40
#include <cxxabi.h>
 
41
#endif
94
42
 
95
43
using namespace std;
96
44
 
97
45
void sDebug(QString message)
98
46
{
99
 
        qDebug("%s", message.ascii());
 
47
        qDebug("%s", message.toAscii().constData());
100
48
}
101
49
 
102
 
int System(const QStringList & args, const QString fileStdErr, const QString fileStdOut)
 
50
int System(const QString exename, const QStringList & args, const QString fileStdErr, const QString fileStdOut, bool* cancel)
103
51
{
104
 
        QStringList stdErrData;
105
 
        QStringList stdOutData;
106
 
        QProcess proc(args);
107
 
        if ( !proc.start() )
108
 
                return 1;
109
 
        /* start was OK */
110
 
        /* wait a little bit */
111
 
        while( proc.isRunning() || proc.canReadLineStdout() || proc.canReadLineStderr() )
112
 
        {
113
 
                // Otherwise Scribus will sleep a *lot* when proc has huge std output
114
 
                if ( !proc.canReadLineStdout() && !proc.canReadLineStderr()) {
115
 
#ifndef _WIN32
116
 
                        usleep(5000);
117
 
#else
118
 
                        Sleep(5);
119
 
#endif
120
 
                }
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() );
127
 
        }
128
 
        // TODO: What about proc.normalExit() ?
129
 
        int ex = proc.exitStatus();
130
 
        QStringList::iterator pIterator;
131
 
        QStringList::iterator pEnd;
132
 
        if ( !fileStdErr.isEmpty() )
133
 
        {
134
 
                QFile ferr(fileStdErr);
135
 
                if ( ferr.open(IO_WriteOnly) )
136
 
                {
137
 
                        pEnd = stdErrData.end();
138
 
                        QTextStream errStream(&ferr);
139
 
                        for ( pIterator = stdErrData.begin(); pIterator != pEnd; pIterator++ )
140
 
                                errStream << *pIterator << endl;
141
 
                        ferr.close();
142
 
                }
143
 
        }
144
 
 
145
 
        if ( !fileStdOut.isEmpty() )
146
 
        {
147
 
                QFile fout(fileStdOut);
148
 
                if ( fout.open(IO_WriteOnly) )
149
 
                {
150
 
                        pEnd = stdOutData.end();
151
 
                        QTextStream outStream(&fout);
152
 
                        for ( pIterator = stdOutData.begin(); pIterator != pEnd; pIterator++ )
153
 
                                outStream << *pIterator << endl;
154
 
                        fout.close();
155
 
                }
156
 
        }
 
52
        QProcess proc;
 
53
        if (!fileStdOut.isEmpty())
 
54
                proc.setStandardOutputFile(fileStdOut);
 
55
        if (!fileStdErr.isEmpty())
 
56
                proc.setStandardErrorFile(fileStdErr);
 
57
        proc.start(exename, args);
 
58
        if (proc.waitForStarted(5000))
 
59
        {
 
60
                while (!proc.waitForFinished(5000))
 
61
                {
 
62
                        qApp->processEvents();
 
63
                        if (cancel && (*cancel == true))
 
64
                        {
 
65
                                proc.kill();
 
66
                                break;
 
67
                        }
 
68
                }
 
69
        }
 
70
        if (cancel && (*cancel == true))
 
71
                return -1;
 
72
        int ex = proc.exitCode();
157
73
        return ex;
158
74
}
159
75
 
160
76
// On Windows, return short path name, else return longPath;
161
 
QString getShortPathName(QString longPath)
 
77
QString getShortPathName(const QString & longPath)
162
78
{
163
79
        QString shortPath(longPath);
164
80
#if defined _WIN32
165
81
        QFileInfo fInfo(longPath);
166
 
        if(fInfo.exists())
 
82
        if (fInfo.exists())
167
83
        {
168
 
                char shortName[MAX_PATH + 1];
 
84
                WCHAR shortName[MAX_PATH + 1];
169
85
                // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
170
86
                // 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;
 
87
                QString nativePath = QDir::convertSeparators(longPath);
 
88
                int ret = GetShortPathNameW((LPCWSTR) nativePath.utf16(), shortName, MAX_PATH);
 
89
                if (ret != ERROR_INVALID_PARAMETER && ret < MAX_PATH)
 
90
                        shortPath = QString::fromUtf16((const ushort*) shortName);
174
91
        }
175
92
#endif
176
93
        return shortPath;
177
94
}
178
95
 
179
 
int copyFile(QString source, QString target)
 
96
// On Windows, return short path name, else return longPath;
 
97
QString getLongPathName(const QString & shortPath)
180
98
{
181
 
        int bytesread;
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;
189
 
        QFile t(target);
190
 
        QByteArray bb( 65536 );
191
 
        if (s.open(IO_ReadOnly))
 
99
        QString longPath(shortPath);
 
100
#if defined _WIN32
 
101
        QFileInfo fInfo(longPath);
 
102
        if (fInfo.exists())
192
103
        {
193
 
                if (t.open(IO_WriteOnly))
194
 
                {
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
 
                        }
201
 
                        t.close();
202
 
                }
203
 
                s.close();
 
104
                WCHAR longName[MAX_PATH + 1];
 
105
                // An error should not be blocking as ERROR_INVALID_PARAMETER can simply mean
 
106
                // that volume does not support long filenames, so return shortPath in this case
 
107
                QString nativePath = QDir::convertSeparators(shortPath);
 
108
                int ret = GetLongPathNameW((LPCWSTR) nativePath.utf16(), longName, MAX_PATH);
 
109
                if (ret != ERROR_INVALID_PARAMETER && ret < MAX_PATH)
 
110
                        longPath = QString::fromUtf16((const ushort*) longName);
204
111
        }
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);
215
 
        QFile::remove(source);
216
 
        return 0;
 
112
#endif
 
113
        return longPath;
217
114
}
218
115
 
219
116
QString GetAttr(QDomElement *el, QString at, QString def)
221
118
        return el->attribute(at, def);
222
119
}
223
120
 
224
 
QPixmap loadIcon(QString nam)
225
 
{
226
 
        static ScPixmapCache<QString> pxCache;
227
 
        if (pxCache.contains(nam))
228
 
                return *pxCache[nam];
229
 
 
230
 
        QString iconFilePath(QString("%1%2").arg(ScPaths::instance().iconDir()).arg(nam));
231
 
        QPixmap *pm = new QPixmap();
232
 
        
233
 
        if (!QFile::exists(iconFilePath))
234
 
                qWarning("Unable to load icon %s: File not found", iconFilePath.ascii());
235
 
        else
236
 
        {
237
 
                pm->load(iconFilePath);
238
 
                if (pm->isNull())
239
 
                        qWarning("Unable to load icon %s: Got null pixmap", iconFilePath.ascii());
240
 
        }
241
 
        pxCache.insert(nam, pm);
242
 
        return *pm;
243
 
}
244
 
 
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
121
 
270
122
// Legacy implementation of LoadText with incorrect
271
123
// handling of unicode data. This should be retired.
279
131
        if (!fi.exists())
280
132
                return false;
281
133
        bool ret;
282
 
        QByteArray bb(f.size());
283
 
        if (f.open(IO_ReadOnly))
 
134
        QByteArray bb(f.size(), ' ');
 
135
        if (f.open(QIODevice::ReadOnly))
284
136
        {
285
 
                f.readBlock(bb.data(), f.size());
 
137
                f.read(bb.data(), f.size());
286
138
                f.close();
287
 
                for (uint posi = 0; posi < bb.size(); ++posi)
 
139
                for (int posi = 0; posi < bb.size(); ++posi)
288
140
                        *Buffer += QChar(bb[posi]);
289
141
                /*
290
142
                int len = bb.size();
294
146
                unsigned short * ucsString = const_cast<unsigned short *>(Buffer->ucs2()) + oldLen;
295
147
                char * data = bb.data();
296
148
                for (uint posi = 0; posi < len; ++posi)
297
 
                        *ucsString++ = *data++;
 
149
                *ucsString++ = *data++;
298
150
                *ucsString = 0;
299
 
                 */
 
151
                */
300
152
                ret = true;
301
153
        }
302
154
        else
304
156
        return ret;
305
157
}
306
158
 
307
 
bool loadRawText(const QString & filename, QCString & buf)
 
159
bool loadRawText(const QString & filename, QByteArray & buf)
308
160
{
309
161
        bool ret = false;
310
162
        QFile f(filename);
311
163
        QFileInfo fi(f);
312
164
        if (fi.exists())
313
165
        {
314
 
                QCString tempBuf(f.size() + 1);
315
 
                if (f.open(IO_ReadOnly))
 
166
                // Allocating one more bytes for null terminator is unneeded with Qt4
 
167
                // as QByteArray ensure null termination automatically
 
168
                // Triggers also QDomDocument parsing errors
 
169
                QByteArray tempBuf(f.size() /*+ 1*/, ' ');
 
170
                if (f.open(QIODevice::ReadOnly))
316
171
                {
317
 
                        unsigned int bytesRead = f.readBlock(tempBuf.data(), f.size());
318
 
                        tempBuf[bytesRead] = '\0';
 
172
                        unsigned int bytesRead = f.read(tempBuf.data(), f.size());
 
173
                        /*tempBuf[bytesRead] = '\0';*/
319
174
                        ret = bytesRead == f.size();
320
175
                        if (ret)
321
176
                                buf = tempBuf; // sharing makes this efficient
333
188
        QFileInfo fi(f);
334
189
        if (fi.exists())
335
190
        {
336
 
                QByteArray tempBuf(f.size());
337
 
                if (f.open(IO_ReadOnly))
 
191
                QByteArray tempBuf(f.size(), ' ');
 
192
                if (f.open(QIODevice::ReadOnly))
338
193
                {
339
 
                        unsigned int bytesRead = f.readBlock(tempBuf.data(), f.size());
 
194
                        unsigned int bytesRead = f.read(tempBuf.data(), f.size());
340
195
                        ret = bytesRead == f.size();
341
196
                        if (ret)
342
197
                                buf = tempBuf; // sharing makes this efficient
347
202
        return ret;
348
203
}
349
204
 
350
 
QPointArray RegularPolygon(double w, double h, uint c, bool star, double factor, double rota)
351
 
{
352
 
        uint cx = star ? c * 2 : c;
353
 
        double seg = 360.0 / cx;
354
 
        double sc = rota + 180.0;
355
 
        double di = factor;
356
 
        int mx = 0;
357
 
        int my = 0;
358
 
        //QPointArray pts = QPointArray();
359
 
        QPointArray pts(cx);
360
 
        for (uint x = 0; x < cx; ++x)
361
 
        {
362
 
                sc = seg * x + 180.0 + rota;
363
 
                if (star)
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
 
                }
370
 
                else
371
 
                {
372
 
                        mx = qRound(sin(sc / 180 * M_PI) * (w/2) + (w/2));
373
 
                        my = qRound(cos(sc / 180 * M_PI) * (h/2) + (h/2));
374
 
                }
375
 
                //pts.resize(x+1);
376
 
                pts.setPoint(x, mx, my);
377
 
        }
378
 
        return pts;
379
 
}
380
 
 
381
 
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota)
382
 
{
383
 
        uint cx = star ? c * 2 : c;
384
 
        double seg = 360.0 / cx;
385
 
        double sc = rota + 180.0;
386
 
        double di = factor;
387
 
        double mx = 0;
388
 
        double my = 0;
389
 
        //FPointArray pts;
390
 
        FPointArray pts(cx);
391
 
        for (uint x = 0; x < cx; ++x)
392
 
        {
393
 
                sc = seg * x + 180.0 + rota;
394
 
                if (star)
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
 
                }
401
 
                else
402
 
                {
403
 
                        mx = sin(sc / 180 * M_PI) * (w/2) + (w/2);
404
 
                        my = cos(sc / 180 * M_PI) * (h/2) + (h/2);
405
 
                }
406
 
                //pts.resize(x+1);
407
 
                pts.setPoint(x, mx, my);
408
 
        }
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)
418
 
        {
419
 
                for (uint poi=0; poi<ina.size()-3; poi += 4)
420
 
                {
421
 
                        if (ina.point(poi).x() > 900000 && cli.size() > 0)
422
 
                        {
423
 
                                outa.resize(outa.size()+1);
424
 
                                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
425
 
                                Segs.append(outa.size());
426
 
                                continue;
427
 
                        }
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);
431
 
                }
432
 
                outa.resize(outa.size()+1);
433
 
                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
434
 
        }
435
 
        return outa;
436
 
}
437
 
 
438
 
double xy2Deg(double x, double y)
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
 
 
452
 
void Level2Layer(ScribusDoc *currentDoc, struct Layer *ll, int Level)
453
 
{
454
 
        uint layerCount=currentDoc->layerCount();
455
 
        for (uint la2 = 0; la2 < layerCount; ++la2)
456
 
        {
457
 
                if (currentDoc->Layers[la2].Level == Level)
458
 
                {
459
 
                        ll->isViewable = currentDoc->Layers[la2].isViewable;
460
 
                        ll->isPrintable = currentDoc->Layers[la2].isPrintable;
461
 
                        ll->LNr = currentDoc->Layers[la2].LNr;
462
 
                        ll->Name = currentDoc->Layers[la2].Name;
463
 
                        ll->flowControl = currentDoc->Layers[la2].flowControl;
464
 
                        ll->transparency = currentDoc->Layers[la2].transparency;
465
 
                        ll->blendMode = currentDoc->Layers[la2].blendMode;
466
 
                        break;
467
 
                }
468
 
        }
469
 
}
470
 
 
471
 
/* CB Replaced by ScribusDoc::layerLevelFromNumber
472
 
int Layer2Level(ScribusDoc *currentDoc, int LayerNr)
473
 
{
474
 
        int retVal=currentDoc->layerLevelFromNumber(LayerNr);
475
 
        int layerCount=currentDoc->layerCount();
476
 
        for (uint la2 = 0; la2 < layerCount; ++la2)
477
 
        {
478
 
                if (currentDoc->Layers[la2].LNr == LayerNr)
479
 
                        return currentDoc->Layers[la2].Level;
480
 
        }
481
 
        return 0;
482
 
}
483
 
*/
 
205
 
484
206
QString CompressStr(QString *in)
485
207
{
486
208
        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);
492
 
        int errcode = compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
493
 
        if (errcode != Z_OK)
494
 
        {
495
 
                qDebug("compress2 failed with code %i", errcode);
 
209
        QByteArray bb(in->length(), ' ');
 
210
        if (bb.size() == in->length())
 
211
        {
 
212
                for (int ax = 0; ax < in->length(); ++ax)
 
213
                {
 
214
                        // bb.insert(ax, in->at(ax)); JG monstruously inefficient due to frequent memory reallocation
 
215
                        bb[ax] = in->at(ax).cell();
 
216
                        assert(in->at(ax).row() == 0);
 
217
                }
 
218
                uLong exlen = (uLong)(bb.size() * 0.001 + 16) + bb.size();
 
219
                QByteArray bc(exlen, ' ');
 
220
                if( bc.size() == static_cast<qint32>(exlen) )
 
221
                {
 
222
                        int errcode = compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
 
223
                        if (errcode != Z_OK)
 
224
                        {
 
225
                                qDebug("compress2 failed with code %i", errcode);
 
226
                                out = *in;
 
227
                        }
 
228
                        else {
 
229
                                for (uint cl = 0; cl < exlen; ++cl)
 
230
                                        out += QChar(bc[cl]);
 
231
                        }
 
232
                }
 
233
                else
 
234
                {
 
235
                        qDebug("insufficient memory to allocate %i bytes", in->length());
 
236
                        out = *in;
 
237
                }
 
238
        }
 
239
        else
 
240
        {
 
241
                qDebug("insufficient memory to allocate %i bytes", in->length());
496
242
                out = *in;
497
243
        }
498
 
        else {
499
 
                for (uint cl = 0; cl < exlen; ++cl)
500
 
                        out += QChar(bc[cl]);
501
 
        }
502
244
        return out;
503
245
}
504
246
 
505
 
QByteArray CompressArray(QByteArray *in)
 
247
QByteArray CompressArray(const QByteArray& in)
506
248
{
507
249
        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)
 
250
        uLong exlen = uint(in.size() * 0.001 + 16) + in.size();
 
251
        QByteArray temp(exlen, ' ');
 
252
        int errcode = compress2((Byte *)temp.data(), &exlen, (Byte *)in.data(), uLong(in.size()), 9);
 
253
        if (errcode == Z_OK)
512
254
        {
513
 
                qDebug("compress2 failed with code %i", errcode);
514
 
                out = *in;
515
 
        }
516
 
        else {
517
255
                temp.resize(exlen);
518
256
                out = temp;
519
257
        }
 
258
        else
 
259
                qDebug("compress2 failed with code %i", errcode);
520
260
        return out;
521
261
}
522
262
 
 
263
char *toAscii85( quint32 value, bool& allZero )
 
264
{
 
265
        int digit, i;
 
266
        static char asciiVal[6];
 
267
        allZero = true;
 
268
    for (i = 0; i < 5; ++i) 
 
269
        {
 
270
                digit = value % 85;
 
271
                if (digit != 0)
 
272
                        allZero = false;
 
273
                asciiVal[4-i] = digit + 33;
 
274
                value = (value - digit) / 85;
 
275
    }
 
276
        asciiVal[5] = 0;
 
277
        return asciiVal;
 
278
}
 
279
 
523
280
char *toHex( uchar u )
524
281
{
525
282
        static char hexVal[3];
541
298
QString String2Hex(QString *in, bool lang)
542
299
{
543
300
        int i = 0;
544
 
        QString out = "";
545
 
        for( uint xi = 0; xi < in->length(); ++xi )
 
301
        QString out("");
 
302
        for( int xi = 0; xi < in->length(); ++xi )
546
303
        {
547
 
                out += toHex(uchar(QChar(in->at(xi))));
 
304
                // Qt4 .cell() added ???
 
305
                out += toHex(QChar(in->at(xi)).cell());
548
306
                ++i;
549
307
                if ((i>40) && (lang))
550
308
                {
557
315
 
558
316
QByteArray ComputeMD5Sum(QByteArray *in)
559
317
{
560
 
        QByteArray MDsum(16);
561
 
        md5_buffer (in->data(), in->size(), reinterpret_cast<void*>(MDsum.data()));
562
 
        return MDsum;
563
 
}
564
 
 
565
 
QString Path2Relative(QString Path)
566
 
{
567
 
        QString Ndir("");
568
 
        QStringList Pdir;
569
 
        QFileInfo Bfi = QFileInfo(Path);
570
 
        QStringList Bdir;
571
 
        bool end = true;
572
 
        uint dcoun = 0;
573
 
        uint dcoun2 = 0;
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();
587
 
                if( drive != currentDrive )
588
 
                        return Path;
589
 
        }
590
 
#endif
591
 
 
592
 
        while (end)
593
 
        {
594
 
                if (Pdir[dcoun] == Bdir[dcoun])
595
 
                        dcoun++;
596
 
                else
597
 
                        break;
598
 
                if (dcoun > Pdir.count())
599
 
                        break;
600
 
        }
601
 
        dcoun2 = dcoun;
602
 
 
603
 
#ifdef _WIN32
604
 
        Bdir = QStringList::split("/", Bfi.dirPath(true));
605
 
#endif
606
 
 
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;
 
318
        return QCryptographicHash::hash(*in, QCryptographicHash::Md5);
 
319
//      QByteArray MDsum(16, ' ');
 
320
//      md5_buffer (in->data(), in->size(), reinterpret_cast<void*>(MDsum.data()));
 
321
//      return MDsum;
 
322
}
 
323
 
 
324
QString Path2Relative(QString Path, const QString& baseDir)
 
325
{
 
326
        QDir d(baseDir);
 
327
        return d.relativeFilePath(Path);
 
328
}
 
329
 
 
330
QString Relative2Path(QString File, const QString& baseDir)
 
331
{
 
332
        QString   absPath;
 
333
        QFileInfo fi(File);
 
334
        if (File.isEmpty())
 
335
                absPath = File;
 
336
        else if (fi.isRelative())
 
337
        {
 
338
                QDir d(baseDir);
 
339
                absPath = d.absoluteFilePath(File);
 
340
                absPath = QDir::cleanPath(absPath);
 
341
        }
 
342
        else
 
343
                absPath = File;
 
344
        return absPath;
613
345
}
614
346
 
615
347
/***************************************************************************
627
359
        if (fi.exists())
628
360
        {
629
361
                QString fn = QDir::convertSeparators(filename);
630
 
                int t = ScMessageBox::warning(parent, QObject::tr("File exists"),
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>",
632
 
                                                                        QObject::tr("&Replace"), CommonStrings::tr_Cancel, "", 1, 1);
633
 
                if (t == 1)
 
362
                int t = QMessageBox::warning(parent, QObject::tr("File exists"),
 
363
                                                                         "<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>",
 
364
                                                                                         QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
 
365
                if (t == QMessageBox::Cancel)
634
366
                        retval = false;
635
367
        }
636
368
        return retval;
657
389
        }
658
390
        while (nextItem != 0)
659
391
        {
660
 
                for (int a = QMAX(nextItem->firstInFrame(),0); a <= nextItem->lastInFrame() && a < nextItem->itemText.length(); ++a)
 
392
                for (int a = qMax(nextItem->firstInFrame(),0); a <= nextItem->lastInFrame() && a < nextItem->itemText.length(); ++a)
661
393
                {
662
394
                        QChar b = nextItem->itemText.text(a);
663
395
                        if (b == SpecialChars::PARSEP)
716
448
        double savScale = view->scale();
717
449
        view->setScale(1.0);
718
450
        currentDoc->RePos = true;
719
 
        QPixmap pgPix(10, 10);
720
 
        QRect rd = QRect(0,0,9,9);
 
451
        QImage pgPix(10, 10, QImage::Format_ARGB32);
 
452
        QRect rd; // = QRect(0,0,9,9);
721
453
        ScPainter *painter = new ScPainter(&pgPix, pgPix.width(), pgPix.height());
722
 
        for (uint azz=0; azz<currentDoc->MasterItems.count(); ++azz)
 
454
        for (int azz=0; azz<currentDoc->MasterItems.count(); ++azz)
723
455
        {
724
456
                PageItem *currItem = currentDoc->MasterItems.at(azz);
725
457
                if (currItem->itemType() == PageItem::PathText)
726
458
                        currItem->DrawObj(painter, rd);
727
459
        }
728
 
        for (uint azz=0; azz<currentDoc->Items->count(); ++azz)
 
460
        for (int azz=0; azz<currentDoc->Items->count(); ++azz)
729
461
        {
730
462
                PageItem *currItem = currentDoc->Items->at(azz);
731
 
                if (currItem->itemType() == PageItem::TextFrame)
732
 
                        currItem->asTextFrame()->layout();
733
 
                else if (currItem->itemType() == PageItem::PathText)
734
 
                        currItem->DrawObj(painter, rd);
 
463
                currItem->layout();
 
464
                if (currItem->itemType() == PageItem::PathText)
 
465
                        currItem->DrawObj(painter, rd); //FIXME: this should be replaced by code in layout()
735
466
        }
736
467
        currentDoc->RePos = false;
737
468
        view->setScale(savScale);
764
495
        return retList;
765
496
}
766
497
 
767
 
void GetItemProps(bool newVersion, QDomElement *obj, struct CopyPasteBuffer *OB)
768
 
{
769
 
        QString tmp;
770
 
        int x, y;
771
 
        double xf, yf, xf2;
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();
779
 
        OB->Pcolor = obj->attribute("PCOLOR");
780
 
        if ((!newVersion) && (OB->PType == 4))
781
 
        {
782
 
                OB->TxtFill = obj->attribute("PCOLOR2");
783
 
                OB->Pcolor2 = CommonStrings::None;
784
 
        }
785
 
        else
786
 
        {
787
 
                OB->Pcolor2 = obj->attribute("PCOLOR2");
788
 
                OB->TxtFill = obj->attribute("TXTFILL", "Black");
789
 
        }
790
 
        OB->Shade = obj->attribute("SHADE").toInt();
791
 
        OB->Shade2 = obj->attribute("SHADE2").toInt();
792
 
        OB->FillRule = obj->attribute("fillRule", "1").toInt();
793
 
        OB->TxtStroke=obj->attribute("TXTSTROKE", CommonStrings::None);
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();
810
 
        OB->fill_gradient.clearStops();
811
 
        if (OB->GrType != 0)
812
 
        {
813
 
                if (OB->GrType == 8)
814
 
                {
815
 
                        OB->pattern = obj->attribute("pattern", "");
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
 
                }
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
 
                }
837
 
        }
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;
851
 
/*      OB->BBoxX=obj->attribute("BBOXX").toDouble();
852
 
        OB->BBoxH=obj->attribute("BBOXH").toDouble(); */
853
 
        OB->ScaleType = obj->attribute("SCALETYPE", "1").toInt();
854
 
        OB->AspectRatio = obj->attribute("RATIO", "0").toInt();
855
 
        OB->isPrintable=obj->attribute("PRINTABLE").toInt();
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))
871
 
        {
872
 
                QFileInfo efp(OB->m_annotation.Extern());
873
 
                OB->m_annotation.setExtern(efp.absFilePath());
874
 
        }
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());
893
 
        OB->m_annotation.setBorderColor(obj->attribute("ANBCOL",CommonStrings::None));
894
 
        OB->m_annotation.setIPlace(obj->attribute("ANPLACE", "1").toInt());
895
 
        OB->m_annotation.setScaleW(obj->attribute("ANSCALE", "0").toInt());
896
 
        if (obj->attribute("TRANSPARENT", "0").toInt() == 1)
897
 
                OB->Pcolor = CommonStrings::None;
898
 
        OB->textAlignment=obj->attribute("ALIGN", "0").toInt();
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;
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();
918
 
        OB->textPathType =  obj->attribute("textPathType", "0").toInt();
919
 
        OB->textPathFlipped = static_cast<bool>(obj->attribute("textPathFlipped", "0").toInt());
920
 
        OB->ISize = qRound(obj->attribute("ISIZE", "12").toDouble() * 10);
921
 
        if (obj->hasAttribute("EXTRAV"))
922
 
                OB->ExtraV = qRound(obj->attribute("EXTRAV", "0").toDouble() / obj->attribute("ISIZE", "12").toDouble() * 1000.0);
923
 
        else
924
 
                OB->ExtraV = obj->attribute("TXTKERN").toInt();
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","");
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();
945
 
        if (obj->hasAttribute("TransValueS"))
946
 
                OB->TranspStroke = obj->attribute("TransValueS", "0.0").toDouble();
947
 
        else
948
 
                OB->TranspStroke = OB->Transparency;
949
 
        OB->TransBlend = obj->attribute("TransBlend", "0").toInt();
950
 
        OB->TransBlendS = obj->attribute("TransBlendS", "0").toInt();
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 = "";
997
 
        if ((obj->hasAttribute("NUMTAB")) && (obj->attribute("NUMTAB", "0").toInt() != 0))
998
 
        {
999
 
                ParagraphStyle::TabRecord tb;
1000
 
                tmp = obj->attribute("TABS");
1001
 
                QTextStream tgv(&tmp, IO_ReadOnly);
1002
 
                OB->TabValues.clear();
1003
 
                for (int cxv = 0; cxv < obj->attribute("NUMTAB", "0").toInt(); cxv += 2)
1004
 
                {
1005
 
                        tgv >> xf;
1006
 
                        tgv >> xf2;
1007
 
                        tb.tabPosition = xf2;
1008
 
                        tb.tabType = static_cast<int>(xf);
1009
 
                        tb.tabFillChar = QChar();
1010
 
                        OB->TabValues.append(tb);
1011
 
                }
1012
 
                tmp = "";
1013
 
        }
1014
 
        else
1015
 
                OB->TabValues.clear();
1016
 
        if ((obj->hasAttribute("NUMDASH")) && (obj->attribute("NUMDASH", "0").toInt() != 0))
1017
 
        {
1018
 
                tmp = obj->attribute("DASHS");
1019
 
                QTextStream dgv(&tmp, IO_ReadOnly);
1020
 
                OB->DashValues.clear();
1021
 
                for (int cxv = 0; cxv < obj->attribute("NUMDASH", "0").toInt(); ++cxv)
1022
 
                {
1023
 
                        dgv >> xf;
1024
 
                        OB->DashValues.append(xf);
1025
 
                }
1026
 
                tmp = "";
1027
 
        }
1028
 
        else
1029
 
                OB->DashValues.clear();
1030
 
        OB->DashOffset = obj->attribute("DASHOFF", "0.0").toDouble();
1031
 
}
1032
 
 
1033
 
FPoint getMaxClipF(FPointArray* Clip)
1034
 
{
1035
 
        FPoint np, rp;
1036
 
        double mx = 0;
1037
 
        double my = 0;
1038
 
        uint clipSize=Clip->size();
1039
 
        for (uint c = 0; c < clipSize; ++c)
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;
1058
 
        uint clipSize=Clip->size();
1059
 
        for (uint c = 0; c < clipSize; ++c)
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
 
 
1073
498
QString checkFileExtension(const QString &currName, const QString &extension)
1074
499
{
1075
500
        QString newName(currName);
1076
501
        //If filename ends with a period, just add the extension
1077
502
        if (newName.right(1)==".")
1078
503
        {
1079
 
                newName+=extension.lower();
 
504
                newName+=extension.toLower();
1080
505
                return newName;
1081
506
        }
1082
507
        //If filename doesnt end with the period+extension, add it on
1083
 
        QString dotExt("." + extension.lower());
1084
 
        if (!newName.endsWith(dotExt,false))
 
508
        QString dotExt("." + extension.toLower());
 
509
        if (!newName.endsWith(dotExt, Qt::CaseInsensitive))
1085
510
                newName+=dotExt;
1086
511
        return newName;
1087
512
}
1088
513
 
1089
514
QString getFileNameByPage(ScribusDoc* currDoc, uint pageNo, QString extension)
1090
515
{
1091
 
        QString number;
1092
 
        number = number.setNum(pageNo + currDoc->FirstPnum);
 
516
        uint number = pageNo + currDoc->FirstPnum;
1093
517
        QString defaultName = currDoc->DocName;
1094
518
        if (defaultName.isNull())
1095
519
                defaultName = "export";
1096
520
        else
1097
521
        {
1098
522
                QFileInfo fi(defaultName);
1099
 
                defaultName = fi.baseName(true);
1100
 
        }
1101
 
        return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number).arg(extension);
1102
 
}
1103
 
 
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
 
 
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
 
 
1125
 
double constrainAngle(double angle, double constrain)
1126
 
{
1127
 
        double newAngle=angle;
1128
 
        double constrainTo=constrain;
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
 
 
1137
 
double getRotationFromMatrix(QWMatrix& matrix, double def)
1138
 
{
1139
 
        double value = def;
1140
 
        double norm = sqrt(fabs(matrix.det()));
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;
1147
 
                if (fabs(m11) <= 1.0 && fabs(m12) <= 1.0 && fabs(m21) <= 1.0 && fabs(m22) <= 1.0)
1148
 
                {
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
 
                        }
1155
 
                }
1156
 
        }
1157
 
        return value;
 
523
                defaultName = fi.completeBaseName();
 
524
        }
 
525
        return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number, 3, 10, QChar('0')).arg(extension);
1158
526
}
1159
527
 
1160
528
const QString getStringFromSequence(DocumentSectionType type, uint position)
1166
534
                        retVal=QString::number(position);
1167
535
                        break;
1168
536
                case Type_A_B_C:
1169
 
                        retVal=numberToLetterSequence(position).upper();
 
537
                        retVal=numberToLetterSequence(position).toUpper();
1170
538
                        break;
1171
539
                case Type_a_b_c:
1172
540
                        retVal=numberToLetterSequence(position);
1177
545
                case Type_i_ii_iii:
1178
546
                        //well, for lower case people will want that, even if its "wrong"
1179
547
                        //ie, X=10, x=10000
1180
 
                        retVal=arabicToRoman(position).lower();
 
548
                        retVal=arabicToRoman(position).toLower();
1181
549
                        break;
1182
550
                case Type_None:
1183
551
                        break;
1210
578
        QString roman("");
1211
579
        int arabic = i;
1212
580
        while (arabic - 1000000 >= 0){
1213
 
        roman += "m";
1214
 
        arabic -= 1000000;
 
581
                roman += "m";
 
582
                arabic -= 1000000;
1215
583
        }
1216
584
        while (arabic - 900000 >= 0){
1217
 
        roman += "cm";
1218
 
        arabic -= 900000;
 
585
                roman += "cm";
 
586
                arabic -= 900000;
1219
587
        }
1220
588
        while (arabic - 500000 >= 0){
1221
 
        roman += "d";
1222
 
        arabic -= 500000;
 
589
                roman += "d";
 
590
                arabic -= 500000;
1223
591
        }
1224
592
        while (arabic - 400000 >= 0){
1225
 
        roman += "cd";
1226
 
        arabic -= 400000;
 
593
                roman += "cd";
 
594
                arabic -= 400000;
1227
595
        }
1228
596
        while (arabic - 100000 >= 0){
1229
 
        roman += "c";
1230
 
        arabic -= 100000;
 
597
                roman += "c";
 
598
                arabic -= 100000;
1231
599
        }
1232
600
        while (arabic - 90000 >= 0){
1233
 
        roman += "xc";
1234
 
        arabic -= 90000;
 
601
                roman += "xc";
 
602
                arabic -= 90000;
1235
603
        }
1236
604
        while (arabic - 50000 >= 0){
1237
 
        roman += "l";
1238
 
        arabic -= 50000;
 
605
                roman += "l";
 
606
                arabic -= 50000;
1239
607
        }
1240
608
        while (arabic - 40000 >= 0){
1241
 
        roman += "xl";
1242
 
        arabic -= 40000;
 
609
                roman += "xl";
 
610
                arabic -= 40000;
1243
611
        }
1244
612
        while (arabic - 10000 >= 0){
1245
 
        roman += "x";
1246
 
        arabic -= 10000;
 
613
                roman += "x";
 
614
                arabic -= 10000;
1247
615
        }
1248
616
        while (arabic - 9000 >= 0){
1249
 
        roman += "Mx";
1250
 
        arabic -= 9000;
 
617
                roman += "Mx";
 
618
                arabic -= 9000;
1251
619
        }
1252
620
        while (arabic - 5000 >= 0){
1253
 
        roman += "v";
1254
 
        arabic -= 5000;
 
621
                roman += "v";
 
622
                arabic -= 5000;
1255
623
        }
1256
624
        while (arabic - 4000 >= 0){
1257
 
        roman += "Mv";
1258
 
        arabic -= 4000;
 
625
                roman += "Mv";
 
626
                arabic -= 4000;
1259
627
        }
1260
628
        while (arabic - 1000 >= 0){
1261
 
        roman += "M";
1262
 
        arabic -= 1000;
 
629
                roman += "M";
 
630
                arabic -= 1000;
1263
631
        }
1264
632
        while (arabic - 900 >= 0){
1265
 
        roman += "CM";
1266
 
        arabic -= 900;
 
633
                roman += "CM";
 
634
                arabic -= 900;
1267
635
        }
1268
636
        while (arabic - 500 >= 0){
1269
 
        roman += "D";
1270
 
        arabic -= 500;
 
637
                roman += "D";
 
638
                arabic -= 500;
1271
639
        }
1272
640
        while (arabic - 400 >= 0){
1273
 
        roman += "CD";
1274
 
        arabic -= 400;
 
641
                roman += "CD";
 
642
                arabic -= 400;
1275
643
        }
1276
644
        while (arabic - 100 >= 0){
1277
 
        roman += "C";
1278
 
        arabic -= 100;
 
645
                roman += "C";
 
646
                arabic -= 100;
1279
647
        }
1280
648
        while (arabic - 90 >= 0){
1281
 
        roman += "XC";
1282
 
        arabic -= 90;
 
649
                roman += "XC";
 
650
                arabic -= 90;
1283
651
        }
1284
652
        while (arabic - 50 >= 0){
1285
 
        roman += "L";
1286
 
        arabic -= 50;
 
653
                roman += "L";
 
654
                arabic -= 50;
1287
655
        }
1288
656
        while (arabic - 40 >= 0){
1289
 
        roman += "XL";
1290
 
        arabic -= 40;
 
657
                roman += "XL";
 
658
                arabic -= 40;
1291
659
        }
1292
660
        while (arabic - 10 >= 0){
1293
 
        roman += "X";
1294
 
        arabic -= 10;
 
661
                roman += "X";
 
662
                arabic -= 10;
1295
663
        }
1296
664
        while (arabic - 9 >= 0){
1297
 
        roman += "IX";
1298
 
        arabic -= 9;
 
665
                roman += "IX";
 
666
                arabic -= 9;
1299
667
        }
1300
668
        while (arabic - 5 >= 0){
1301
 
        roman += "V";
1302
 
        arabic -= 5;
 
669
                roman += "V";
 
670
                arabic -= 5;
1303
671
        }
1304
672
        while (arabic - 4 >= 0){
1305
 
        roman += "IV";
1306
 
        arabic -= 4;
 
673
                roman += "IV";
 
674
                arabic -= 4;
1307
675
        }
1308
676
        while (arabic - 1 >= 0){
1309
 
        roman += "I";
1310
 
        arabic -= 1;
 
677
                roman += "I";
 
678
                arabic -= 1;
1311
679
        }
1312
680
        return roman;
1313
681
}
1320
688
        int from, to, pageNr;
1321
689
        do
1322
690
        {
1323
 
                if (tmp.find(",") == -1)
 
691
                if (tmp.indexOf(",") == -1)
1324
692
                {
1325
693
                        token = tmp;
1326
694
                        tmp = "";
1327
695
                }
1328
696
                else
1329
697
                {
1330
 
                        token = tmp.left(tmp.find(","));
1331
 
                        tmp = tmp.right(tmp.length() - tmp.find(",") - 1);
 
698
                        token = tmp.left(tmp.indexOf(","));
 
699
                        tmp = tmp.right(tmp.length() - tmp.indexOf(",") - 1);
1332
700
                }
1333
701
 
1334
 
                token = token.stripWhiteSpace();
 
702
                token = token.trimmed();
1335
703
                if (token == "*") // Import all source doc pages
1336
704
                {
1337
705
                        for (int i = 1; i <= sourcePageCount; ++i)
1338
706
                                pageNs->push_back(i);
1339
707
                }
1340
 
                else if (token.find("-") != -1) // import a range of source doc pages
 
708
                else if (token.indexOf("-") != -1) // import a range of source doc pages
1341
709
                {
1342
 
                        from = QString(token.left(token.find("-"))).toInt();
1343
 
                        to = QString(token.right(token.length() - token.find("-") - 1)).toInt();
 
710
                        from = QString(token.left(token.indexOf("-"))).toInt();
 
711
                        to = QString(token.right(token.length() - token.indexOf("-") - 1)).toInt();
1344
712
                        if ((from != 0) && (to != 0))
1345
713
                        {
1346
714
                                if (from > sourcePageCount)
1370
738
        } while (!tmp.isEmpty());
1371
739
}
1372
740
 
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) {
1379
 
                for (uint i=0; i < doc->paragraphStyles().count(); ++i)
1380
 
                {
1381
 
//qDebug(QString("%1 %2").arg(i).arg(doc->paragraphStyles()[i].name()));
1382
 
                        if (parStyle.name() == doc->paragraphStyles()[i].name()) {
1383
 
                                return i;
1384
 
                        }
1385
 
                }
1386
 
                assert(false);
1387
 
                return -1;
1388
 
        }
1389
 
        else {
1390
 
                return -1;
1391
 
        }
1392
 
}
1393
 
 
1394
 
int findParagraphStyle(ScribusDoc* doc, const QString &name)
1395
 
{
1396
 
        for (uint i=0; i < doc->paragraphStyles().count(); ++i)
1397
 
        {
1398
 
                if (name == doc->paragraphStyles()[i].name()) {
1399
 
                        return i;
1400
 
                }
1401
 
        }
1402
 
        assert(false);
1403
 
        return -1;
1404
 
}
1405
 
 
1406
 
 
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
 
}
1419
 
 
1420
 
 
1421
741
void tDebug(QString message)
1422
742
{
1423
743
        QDateTime debugTime;
1424
 
        qDebug("%s", QString("%1\t%2").arg(debugTime.currentDateTime().toString("hh:mm:ss:zzz")).arg(message).ascii());
1425
 
}
1426
 
 
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";
1459
 
        formats += "EPS (*.eps *.EPS);;EPSI (*.epsi *.EPSI);;PDF (*.pdf *.PDF);;" + QObject::tr("All Files (*)");
1460
 
        formatD += " *.epsi *.EPSI *.eps *.EPS *.pdf *.PDF";
1461
 
        formatD += ");;"+formats;
1462
 
        return formatD;
1463
 
}
1464
 
 
1465
 
QString getImageType(QString filename)
 
744
        qDebug("%s", QString("%1\t%2").arg(debugTime.currentDateTime().toString("hh:mm:ss:zzz")).arg(message).toAscii().constData());
 
745
}
 
746
 
 
747
 
 
748
QString readLinefromDataStream(QDataStream &s)
1466
749
{
1467
750
        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
 
}
 
751
        uchar charData;
 
752
        while (!s.atEnd())
 
753
        {
 
754
                s >> charData;
 
755
                if (charData == '\x0A')
 
756
                        break;
 
757
                if (charData == '\x0D')
 
758
                {
 
759
                        quint64 oldPos = s.device()->pos();
 
760
                        s >> charData;
 
761
                        if (charData != '\x0A')
 
762
                                s.device()->seek(oldPos);
 
763
                        break;
 
764
                }
 
765
                ret += QChar(charData);
 
766
        }
 
767
        return ret.trimmed();
 
768
}
 
769
 
 
770
void setCurrentComboItem(QComboBox *box, QString text)
 
771
{
 
772
        box->blockSignals(true);
 
773
        int ind = box->findText(text);
 
774
        if (ind > -1)
 
775
                box->setCurrentIndex(ind);
 
776
        box->blockSignals(false);
 
777
}
 
778
 
 
779
QString getDashString(int dashtype, double linewidth)
 
780
{
 
781
        QString dashString;
 
782
        QVector<double> dashArray;
 
783
        getDashArray(dashtype, linewidth, dashArray);
 
784
        for (int a = 0; a < dashArray.size(); ++a)
 
785
        {
 
786
                dashString += QString::number(dashArray.at(a));
 
787
                if (a < (dashArray.size() - 1))
 
788
                        dashString += " ";
 
789
        }
 
790
        return dashString;
 
791
}
 
792
 
 
793
void getDashArray(int dashtype, double linewidth, QVector<float> &m_array) {
 
794
   QVector<double> tmp;
 
795
   getDashArray(dashtype, linewidth, tmp);
 
796
   m_array.clear();
 
797
   for (int i = 0; i < tmp.count(); ++i) {
 
798
   m_array << static_cast<float>(tmp[i]);
 
799
  }
 
800
}
 
801
 
 
802
void getDashArray(int dashtype, double linewidth, QVector<double> &m_array)
 
803
{
 
804
        m_array.clear();
 
805
        if ((dashtype == 1) || (dashtype == 0))
 
806
                return;
 
807
        double Dt = qMax(1.0*linewidth, 0.1);
 
808
        double Sp = qMax(2.0*linewidth, 0.1);
 
809
        double Da = qMax(4.0*linewidth, 0.1);
 
810
        switch (dashtype)
 
811
        {
 
812
                case 1:
 
813
                        break;
 
814
                case 2:
 
815
                        m_array << Da << Sp;
 
816
                        break;
 
817
                case 3:
 
818
                        m_array << Dt << Sp;
 
819
                        break;
 
820
                case 4:
 
821
                        m_array << Da << Sp << Dt << Sp;
 
822
                        break;
 
823
                case 5:
 
824
                        m_array << Da << Sp << Dt << Sp << Dt << Sp;
 
825
                        break;
 
826
// Additional line styles taken from Inkscape
 
827
                case 6:
 
828
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
829
                        break;
 
830
                case 7:
 
831
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(3.0 * linewidth, 0.01);
 
832
                        break;
 
833
                case 8:
 
834
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
 
835
                        break;
 
836
                case 9:
 
837
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(6.0 * linewidth, 0.01);
 
838
                        break;
 
839
                case 10:
 
840
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(8.0 * linewidth, 0.01);
 
841
                        break;
 
842
                case 11:
 
843
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(12.0 * linewidth, 0.01);
 
844
                        break;
 
845
                case 12:
 
846
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(24.0 * linewidth, 0.01);
 
847
                        break;
 
848
                case 13:
 
849
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(48.0 * linewidth, 0.01);
 
850
                        break;
 
851
                case 14:
 
852
                        m_array << qMax(2.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
853
                        break;
 
854
                case 15:
 
855
                        m_array << qMax(3.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
856
                        break;
 
857
                case 16:
 
858
                        m_array << qMax(4.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
859
                        break;
 
860
                case 17:
 
861
                        m_array << qMax(6.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
862
                        break;
 
863
                case 18:
 
864
                        m_array << qMax(8.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
865
                        break;
 
866
                case 19:
 
867
                        m_array << qMax(10.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
868
                        break;
 
869
                case 20:
 
870
                        m_array << qMax(12.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
871
                        break;
 
872
                case 21:
 
873
                        m_array << qMax(2.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
 
874
                        break;
 
875
                case 22:
 
876
                        m_array << qMax(3.0 * linewidth, 0.01) << qMax(3.0 * linewidth, 0.01);
 
877
                        break;
 
878
                case 23:
 
879
                        m_array << qMax(4.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
 
880
                        break;
 
881
                case 24:
 
882
                        m_array << qMax(6.0 * linewidth, 0.01) << qMax(6.0 * linewidth, 0.01);
 
883
                        break;
 
884
                case 25:
 
885
                        m_array << qMax(8.0 * linewidth, 0.01) << qMax(8.0 * linewidth, 0.01);
 
886
                        break;
 
887
                case 26:
 
888
                        m_array << qMax(10.0 * linewidth, 0.01) << qMax(10.0 * linewidth, 0.01);
 
889
                        break;
 
890
                case 27:
 
891
                        m_array << qMax(12.0 * linewidth, 0.01) << qMax(12.0 * linewidth, 0.01);
 
892
                        break;
 
893
                case 28:
 
894
                        m_array << qMax(2.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
 
895
                        break;
 
896
                case 29:
 
897
                        m_array << qMax(2.0 * linewidth, 0.01) << qMax(6.0 * linewidth, 0.01);
 
898
                        break;
 
899
                case 30:
 
900
                        m_array << qMax(6.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
 
901
                        break;
 
902
                case 31:
 
903
                        m_array << qMax(4.0 * linewidth, 0.01) << qMax(8.0 * linewidth, 0.01);
 
904
                        break;
 
905
                case 32:
 
906
                        m_array << qMax(8.0 * linewidth, 0.01) << qMax(4.0 * linewidth, 0.01);
 
907
                        break;
 
908
                case 33:
 
909
                        m_array << qMax(2.0 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
910
                        m_array << qMax(0.5 * linewidth, 0.01) << qMax(1.0 * linewidth, 0.01);
 
911
                        break;
 
912
                case 34:
 
913
                        m_array << qMax(8.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
 
914
                        m_array << qMax(1.0 * linewidth, 0.01) << qMax(2.0 * linewidth, 0.01);
 
915
                        break;
 
916
                case 35:
 
917
                        m_array << qMax(0.5 * linewidth, 0.01) << qMax(0.5 * linewidth, 0.01);
 
918
                        break;
 
919
                case 36:
 
920
                        m_array << qMax(0.25 * linewidth, 0.01) << qMax(0.25 * linewidth, 0.01);
 
921
                        break;
 
922
                case 37:
 
923
                        m_array << qMax(0.1 * linewidth, 0.01) << qMax(0.1 * linewidth, 0.01);
 
924
                        break;
 
925
                default:
 
926
                        break;
 
927
        }
 
928
}
 
929
 
 
930
#if !defined(_WIN32) && !defined(Q_OS_MAC)
 
931
/**
 
932
 * Print a backtrace
 
933
 * Please never commit code that uses it.
 
934
 * @param nFrames specify how much frames you want to be printed
 
935
 */
 
936
void printBacktrace ( int nFrames )
 
937
{
 
938
        void ** trace = new void*[nFrames + 1];
 
939
        char **messages = ( char ** ) NULL;
 
940
        int i, trace_size = 0;
 
941
 
 
942
        trace_size = backtrace ( trace, nFrames + 1 );
 
943
        messages = backtrace_symbols ( trace, trace_size );
 
944
        if ( messages )
 
945
        {
 
946
                for ( i=1; i < trace_size; ++i )
 
947
                {
 
948
                        QString msg ( messages[i] );
 
949
                        int sep1 ( msg.indexOf ( "(" ) );
 
950
                        int sep2 ( msg.indexOf ( "+" ) );
 
951
                        QString mName ( msg.mid ( sep1 + 1,sep2-sep1 -1) );
 
952
                        
 
953
                        QString name;
 
954
                        if(mName.startsWith("_Z"))
 
955
                        {
 
956
                                char* outbuf = 0; 
 
957
                                size_t length = 0;
 
958
                                int status = 0; 
 
959
                                outbuf = abi::__cxa_demangle(mName.trimmed().toAscii().data(), outbuf, &length, &status);
 
960
                                name = QString::fromAscii( outbuf,length );
 
961
                                if(!status)
 
962
                                        free(outbuf);
 
963
                        }
 
964
                        else
 
965
                                name = mName;
 
966
                        QString bts ( "[ScBT] %1. %2" );
 
967
                        qDebug ("%s", bts.arg( i ).arg( name ).toUtf8().data() );
 
968
                }
 
969
                free ( messages );
 
970
        }
 
971
        delete[] trace;
 
972
}
 
973
#endif
 
974