Subversion Repositories Scribus

Rev

Rev 24665 | 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
*/
792 subik 7
#include "objpdffile.h"
14491 jghali 8
#include "colormgmt/sccolormgmtengine.h"
792 subik 9
#include "cmdutil.h"
2834 cbradney 10
#include "prefsmanager.h"
2960 cbradney 11
#include "scribusdoc.h"
5243 cbradney 12
#include "scribuscore.h"
19093 craig 13
#include "scribusview.h"
14170 jghali 14
#include <structmember.h>
15
#include "ui/bookmarkpalette.h"
792 subik 16
 
10223 cbradney 17
#include <QFileInfo>
22459 jghali 18
#include <QImage>
9803 fschmid 19
#include <QList>
792 subik 20
#include <vector>
418 Franz 21
 
22
// these functions are located at utils.cpp
3819 subik 23
void SCRIBUS_API ReOrderText(ScribusDoc *doc, ScribusView *view);
418 Franz 24
// end of utils.cpp
25
//this is in file scribus.cpp
420 Franz 26
 
418 Franz 27
 
420 Franz 28
static int minmaxi(int val, int min, int max)
29
{
1745 subik 30
        if (val < min)
31
                return min;
22638 craig 32
        if (val > max)
1745 subik 33
                return max;
22638 craig 34
        return val;
420 Franz 35
}
36
 
37
static double minmaxd(double val, double min, double max)
38
{
1745 subik 39
        if (val < min)
40
                return min;
22638 craig 41
        if (val > max)
1745 subik 42
                return max;
22638 craig 43
        return val;
420 Franz 44
}
45
 
733 subik 46
typedef struct
418 Franz 47
{
1745 subik 48
        PyObject_HEAD
49
        PyObject *file; // string - file to save into
20126 jghali 50
        PyObject *fontEmbedding; // int - 0: Embed fonts, 1:Outline fonts, 2:Dont embed any font
1745 subik 51
        PyObject *fonts; // list of string - fonts to  embed
20092 jghali 52
        PyObject *subsetList; // list of string - fonts to outline
1745 subik 53
        PyObject *pages; // list of int - pages to print
54
        int thumbnails; // bool -
19704 jghali 55
        int cropMarks; // bool -
56
        int bleedMarks; // bool -
57
        int registrationMarks; // bool -
58
        int colorMarks; // bool -
59
        int docInfoMarks; // bool -
60
        double markOffset; // double -
19746 jghali 61
        double markLength; // double -
1745 subik 62
        int compress; // bool -
63
        int compressmtd; // int - 0=automatic 1=jpeg 2=zip 3=none
64
        int quality; // int - 0=Maximum 4=minimum
65
        PyObject *resolution; // int - 35 - 4000 default=300 dpi
66
        PyObject *downsample; // int - 35 - 4000 default=0 do not downsample ; other downsample to this resolution
67
        int bookmarks; // bool -
68
        int binding; // bool - 0 -left margin 1 -right margin
69
        int presentation; // bool -
70
        PyObject *effval; // list of list of 5 int - effect to apply to each page during presentation
71
        int article; // bool -
72
        int encrypt; // bool -
73
        int uselpi; // bool -
3079 fschmid 74
        int usespot;
75
        int domulti;
1745 subik 76
        PyObject *lpival; // list of elements which has structure [siii]
77
        PyObject *owner; // string - owner's password
78
        PyObject *user; // string - user's password
20092 jghali 79
        int allowPrinting; // bool -  allow printing
80
        int allowChange; // bool - allow changing
81
        int allowCopy; // bool - allow copying
82
        int allowAnnots; // bool - allow adding annotation and fields
83
        int version; // int - version of pdf (12=1.2; 13=1.3; 14=1.4; 15=1.5)
1745 subik 84
        int outdst; // int - output destination 0 - screen, 1 - printer
418 Franz 85
 
1745 subik 86
        int profiles; // bool
87
        int profilei; // bool
88
        int intents; // int - 0 - 3 QString tmp_ip[] = { tr("Perceptual"), tr("Relative Colorimetric"), tr("Saturation"), tr("Absolute Colorimetric")};
89
        int intenti; // int - 0 - 3 QString tmp_ip[] = { tr("Perceptual"), tr("Relative Colorimetric"), tr("Saturation"), tr("Absolute Colorimetric")};
90
        int noembicc; // bool - "Don't use embedded ICC profiles"
91
        PyObject *solidpr; // string
92
        PyObject *imagepr; // string
93
        PyObject *printprofc; // string
94
        PyObject *info; // string
20092 jghali 95
        double bleedt; // double - 0 to height of page
1745 subik 96
        double bleedl; // double - 0 to width of page
97
        double bleedr; // double - 0 to width of page
20092 jghali 98
        double bleedb; // double - 0 to height of page
99
        int useDocBleeds; // bool
19699 jghali 100
        int useLayers;
101
        int embedPDF;
19704 jghali 102
        int mirrorH;
103
        int mirrorV;
19699 jghali 104
        int doClip;
20092 jghali 105
        PyObject * rotateDeg; // int
19699 jghali 106
        int isGrayscale;
19704 jghali 107
        int pageLayout;
19699 jghali 108
        int displayBookmarks;
109
        int displayThumbs;
110
        int displayLayers;
111
        int displayFullscreen;
112
        int hideToolBar;
113
        int hideMenuBar;
114
        int fitWindow;
115
        PyObject *openAction;
733 subik 116
 
418 Franz 117
} PDFfile;
118
 
119
static void PDFfile_dealloc(PDFfile *self)
120
{
1745 subik 121
        Py_XDECREF(self->file);
20126 jghali 122
        Py_XDECREF(self->fontEmbedding);
1745 subik 123
        Py_XDECREF(self->fonts);
20092 jghali 124
        Py_XDECREF(self->subsetList);
1745 subik 125
        Py_XDECREF(self->pages);
126
        Py_XDECREF(self->resolution);
127
        Py_XDECREF(self->downsample);
128
        Py_XDECREF(self->effval);
129
        Py_XDECREF(self->lpival);
130
        Py_XDECREF(self->owner);
131
        Py_XDECREF(self->user);
132
        Py_XDECREF(self->solidpr);
133
        Py_XDECREF(self->imagepr);
134
        Py_XDECREF(self->printprofc);
135
        Py_XDECREF(self->info);
20092 jghali 136
        Py_XDECREF(self->rotateDeg);
19699 jghali 137
        Py_XDECREF(self->openAction);
23278 jghali 138
        Py_TYPE(self)->tp_free((PyObject *)self);
418 Franz 139
}
140
 
10778 craig 141
static PyObject * PDFfile_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
418 Franz 142
{
23926 jghali 143
        // Do not create new object if there is no opened document
144
        if (!checkHaveDocument())
22537 craig 145
                return nullptr;
733 subik 146
 
1745 subik 147
        PDFfile *self;
733 subik 148
 
1745 subik 149
        self = (PDFfile *)type->tp_alloc(type, 0);
23926 jghali 150
        if (self)
151
        {
152
                // Set file attribute
23278 jghali 153
                self->file = PyUnicode_FromString("");
23926 jghali 154
                if (!self->file)
155
                {
1745 subik 156
                        Py_DECREF(self);
22537 craig 157
                        return nullptr;
1745 subik 158
                }
23926 jghali 159
                // Set font embedding mode attribute
23278 jghali 160
                self->fontEmbedding = PyLong_FromLong(0);
23926 jghali 161
                if (!self->fontEmbedding)
162
                {
20126 jghali 163
                        Py_DECREF(self);
22537 craig 164
                        return nullptr;
20126 jghali 165
                }
23926 jghali 166
                // Set fonts attribute
1745 subik 167
                self->fonts = PyList_New(0);
23926 jghali 168
                if (!self->fonts)
169
                {
1745 subik 170
                        Py_DECREF(self);
22537 craig 171
                        return nullptr;
1745 subik 172
                }
20092 jghali 173
                self->subsetList = PyList_New(0);
23926 jghali 174
                if (!self->subsetList)
175
                {
19699 jghali 176
                        Py_DECREF(self);
22537 craig 177
                        return nullptr;
19699 jghali 178
                }
23926 jghali 179
                // Set pages attribute
1745 subik 180
                self->pages = PyList_New(0);
23926 jghali 181
                if (self->pages == nullptr)
182
                {
1745 subik 183
                        Py_DECREF(self);
22537 craig 184
                        return nullptr;
1745 subik 185
                }
23926 jghali 186
                // Set thumbnails attribute
1745 subik 187
                self->thumbnails = 0;
23926 jghali 188
                // Set cropMarks attribute
19704 jghali 189
                self->cropMarks = 0;
23926 jghali 190
                // Set bleedMarks attribute
19704 jghali 191
                self->bleedMarks = 0;
23926 jghali 192
                // Set registrationMarks attribute
19704 jghali 193
                self->registrationMarks = 0;
23926 jghali 194
                // Set colorMarks attribute
19704 jghali 195
                self->colorMarks = 0;
23926 jghali 196
                // Set docInfoMarks attribute
19704 jghali 197
                self->docInfoMarks = 0;
23926 jghali 198
                // Set mark offset attribute
19704 jghali 199
                self->markOffset = 0;
23926 jghali 200
                // Set mark length attribute
19746 jghali 201
                self->markLength = 0;
23926 jghali 202
                // Set compress attribute
1745 subik 203
                self->compress = 0;
23926 jghali 204
                // Set compressmtd attribute
1745 subik 205
                self->compressmtd = 0;
23926 jghali 206
                // Set quality attribute
1745 subik 207
                self->quality = 0;
23926 jghali 208
                // Set resolution attribute
23278 jghali 209
                self->resolution = PyLong_FromLong(300);
23926 jghali 210
                if (!self->resolution)
211
                {
1745 subik 212
                        Py_DECREF(self);
22537 craig 213
                        return nullptr;
1745 subik 214
                }
23926 jghali 215
                // Set downsample attribute
23278 jghali 216
                self->downsample = PyLong_FromLong(0);
23926 jghali 217
                if (!self->downsample)
218
                {
1745 subik 219
                        Py_DECREF(self);
22537 craig 220
                        return nullptr;
1745 subik 221
                }
23926 jghali 222
                // Set bookmarks attribute
1745 subik 223
                self->bookmarks = 0;
23926 jghali 224
                // Set binding attribute
1745 subik 225
                self->binding = 0;
23926 jghali 226
                // Set presentation attribute
1745 subik 227
                self->presentation = 0;
23926 jghali 228
                // Set effval attribute
1745 subik 229
                self->effval = PyList_New(0);
23926 jghali 230
                if (!self->effval)
231
                {
1745 subik 232
                        Py_DECREF(self);
22537 craig 233
                        return nullptr;
1745 subik 234
                }
23926 jghali 235
                // Set article attribute
1745 subik 236
                self->article = 0;
23926 jghali 237
                // Set encrypt attribute
1745 subik 238
                self->encrypt = 0;
23926 jghali 239
                // Set uselpi attribute
1745 subik 240
                self->uselpi = 0;
3079 fschmid 241
                self->usespot = 1;
242
                self->domulti = 0;
23926 jghali 243
                // Set lpival attribute
1745 subik 244
                self->lpival = PyList_New(0);
23926 jghali 245
                if (!self->lpival)
246
                {
1745 subik 247
                        Py_DECREF(self);
22537 craig 248
                        return nullptr;
1745 subik 249
                }
23926 jghali 250
                // Set owner attribute
23278 jghali 251
                self->owner = PyUnicode_FromString("");
23926 jghali 252
                if (!self->owner)
253
                {
1745 subik 254
                        Py_DECREF(self);
22537 craig 255
                        return nullptr;
1745 subik 256
                }
23926 jghali 257
                // Set user attribute
23278 jghali 258
                self->user = PyUnicode_FromString("");
23926 jghali 259
                if (!self->user)
260
                {
1745 subik 261
                        Py_DECREF(self);
22537 craig 262
                        return nullptr;
1745 subik 263
                }
23926 jghali 264
                // Set allowPrinting attribute
20092 jghali 265
                self->allowPrinting = 1;
23926 jghali 266
                // Set allowChange attribute
20092 jghali 267
                self->allowChange = 1;
23926 jghali 268
                // Set allowCopy attribute
20092 jghali 269
                self->allowCopy = 1;
23926 jghali 270
                // Set allowAnnots attribute
20092 jghali 271
                self->allowAnnots = 1;
23926 jghali 272
                // Set version attribute
1745 subik 273
                self->version = 14;
23926 jghali 274
                // Set output attribute
1745 subik 275
                self->outdst = 0;
418 Franz 276
 
1745 subik 277
                self->profiles = 0; // bool
278
                self->profilei = 0; // bool
279
                self->intents = 0; // int - 0 - ?
280
                self->intenti = 0; // int - 0 - ?
281
                self->noembicc = 0; // bool
23278 jghali 282
                self->solidpr = PyUnicode_FromString("");
23926 jghali 283
                if (!self->solidpr)
284
                {
1745 subik 285
                        Py_DECREF(self);
22537 craig 286
                        return nullptr;
1745 subik 287
                }
23278 jghali 288
                self->imagepr = PyUnicode_FromString("");
23926 jghali 289
                if (!self->imagepr)
290
                {
1745 subik 291
                        Py_DECREF(self);
22537 craig 292
                        return nullptr;
1745 subik 293
                }
23278 jghali 294
                self->printprofc = PyUnicode_FromString("");
23926 jghali 295
                if (!self->printprofc)
296
                {
1745 subik 297
                        Py_DECREF(self);
22537 craig 298
                        return nullptr;
1745 subik 299
                }
23278 jghali 300
                self->info = PyUnicode_FromString("");
23926 jghali 301
                if (!self->info)
302
                {
1745 subik 303
                        Py_DECREF(self);
22537 craig 304
                        return nullptr;
1745 subik 305
                }
306
                self->bleedt = 0; // double -
307
                self->bleedl = 0; // double -
308
                self->bleedr = 0; // double -
309
                self->bleedb = 0; // double -
20092 jghali 310
                self->useDocBleeds = 1; // bool
19699 jghali 311
                self->useLayers = 0;
312
                self->embedPDF = 0;
19704 jghali 313
                self->mirrorH = 0;
314
                self->mirrorV = 0;
19699 jghali 315
                self->doClip = 0;
23278 jghali 316
                self->rotateDeg = PyLong_FromLong(0);
23926 jghali 317
                if (!self->rotateDeg)
318
                {
19699 jghali 319
                        Py_DECREF(self);
22537 craig 320
                        return nullptr;
19699 jghali 321
                }
322
                self->isGrayscale = 0;
19704 jghali 323
                self->pageLayout = 0;
19699 jghali 324
                self->displayBookmarks = 0;
325
                self->displayThumbs = 0;
326
                self->displayLayers = 0;
327
                self->displayFullscreen = 0;
328
                self->hideToolBar = 0;
329
                self->hideMenuBar = 0;
330
                self->fitWindow = 0;
23278 jghali 331
                self->openAction = PyUnicode_FromString("");
23926 jghali 332
                if (!self->openAction)
333
                {
19699 jghali 334
                        Py_DECREF(self);
22537 craig 335
                        return nullptr;
19699 jghali 336
                }
1745 subik 337
        }
338
        return (PyObject *) self;
418 Franz 339
}
340
 
10778 craig 341
static int PDFfile_init(PDFfile *self, PyObject * /*args*/, PyObject * /*kwds*/)
418 Franz 342
{
3819 subik 343
        int i;
23926 jghali 344
        if (!checkHaveDocument())
1745 subik 345
                return -1;
19710 jghali 346
 
347
        ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
348
        PDFOptions& pdfOptions = currentDoc->pdfOptions();
349
 
24665 jghali 350
        // Default save into file
19710 jghali 351
        QString tf = pdfOptions.fileName;
23926 jghali 352
        if (tf.isEmpty())
353
        {
22832 craig 354
                QFileInfo fi = QFileInfo(currentDoc->documentFileName());
23278 jghali 355
                tf = fi.path() + "/" + fi.baseName() + ".pdf";
1745 subik 356
        }
23926 jghali 357
 
358
        PyObject *file = PyUnicode_FromString(tf.toUtf8());
359
        if (file)
360
        {
1745 subik 361
                Py_DECREF(self->file);
362
                self->file = file;
23926 jghali 363
        }
364
        else
365
        {
1745 subik 366
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'file' attribute");
367
                return -1;
368
        }
23926 jghali 369
 
370
        // Font embedding mode
371
        PyObject *embeddingMode = PyLong_FromLong(pdfOptions.FontEmbedding);
372
        if (embeddingMode)
373
        {
20126 jghali 374
                Py_DECREF(self->fontEmbedding);
375
                self->fontEmbedding = embeddingMode;
23926 jghali 376
        }
377
        else
378
        {
20126 jghali 379
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'fontEmbedding' attribute");
380
                return -1;
381
        }
23926 jghali 382
 
383
        // Embed all used fonts
384
        PyObject *fonts = PyList_New(0);
385
        if (fonts)
386
        {
1745 subik 387
                Py_DECREF(self->fonts);
388
                self->fonts = fonts;
23926 jghali 389
        }
390
        else
391
        {
1745 subik 392
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'fonts' attribute");
393
                return -1;
394
        }
23926 jghali 395
 
396
        // Get all used fonts
19710 jghali 397
        QMap<QString,int> ReallyUsed = currentDoc->UsedFonts;
23926 jghali 398
        // Create list of all used fonts
20126 jghali 399
        QList<QString> tmpEm = ReallyUsed.keys();
400
        for (int i = 0; i < tmpEm.count(); ++i)
401
        {
22635 craig 402
                const QString& fontName = tmpEm.at(i);
23926 jghali 403
                PyObject *tmp = PyUnicode_FromString(fontName.toUtf8());
404
                if (tmp)
405
                {
20126 jghali 406
                        PyList_Append(self->fonts, tmp);
23926 jghali 407
                        // Do i need Py_DECREF(tmp) here?
408
                        // Does PyList_Append increase reference or 'steal' one from provided argument
409
                        // If it 'steal' reference comment next line
20126 jghali 410
                        Py_DECREF(tmp);
411
                }
23926 jghali 412
                else
413
                {
20126 jghali 414
                        PyErr_SetString(PyExc_SystemError, "Can not initialize 'fonts' attribute");
415
                        return -1;
416
                }
1745 subik 417
        }
23926 jghali 418
 
419
        // Init subsetList
19699 jghali 420
        fonts = PyList_New(0);
23926 jghali 421
        if (fonts)
422
        {
20092 jghali 423
                Py_DECREF(self->subsetList);
424
                self->subsetList = fonts;
23926 jghali 425
        }
426
        else
427
        {
20092 jghali 428
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'subsetList' attribute");
19699 jghali 429
                return -1;
430
        }
23926 jghali 431
 
432
        // Copied from TabPDFOptions::restoreDefaults()
19710 jghali 433
        for (int fe = 0; fe < pdfOptions.SubsetList.count(); ++fe)
19699 jghali 434
        {
22537 craig 435
                PyObject *tmp= nullptr;
23278 jghali 436
                tmp = PyUnicode_FromString(pdfOptions.SubsetList[fe].toUtf8().data());
23926 jghali 437
                if (tmp)
438
                {
20092 jghali 439
                        PyList_Append(self->subsetList, tmp);
19699 jghali 440
                        Py_DECREF(tmp);
441
                }
23926 jghali 442
                else
443
                {
20092 jghali 444
                        PyErr_SetString(PyExc_SystemError, "Can not initialize 'subsetList' attribute");
19699 jghali 445
                        return -1;
446
                }
447
        }
448
 
23926 jghali 449
        // Set to print all pages
23820 craig 450
        int num = currentDoc->Pages->count();
23926 jghali 451
        PyObject *pages = PyList_New(num);
452
        if (!pages)
453
        {
1745 subik 454
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'pages' attribute");
455
                return -1;
456
        }
23926 jghali 457
        for (i = 0; i < num; ++i)
458
        {
459
                PyObject *tmp = PyLong_FromLong((long) i + 1L);
1745 subik 460
                if (tmp)
461
                        PyList_SetItem(pages, i, tmp);
23926 jghali 462
                else
463
                {
1745 subik 464
                        PyErr_SetString(PyExc_SystemError, "Can not initialize 'pages' attribute");
465
                        return -1;
466
                }
467
        }
468
        Py_DECREF(self->pages);
469
        self->pages = pages;
23926 jghali 470
        // Print thumbnails ?
19710 jghali 471
        self->thumbnails = pdfOptions.Thumbnails;
23926 jghali 472
        // Output crop marks ?
19710 jghali 473
        self->cropMarks = pdfOptions.cropMarks;
23926 jghali 474
        // Output bleed marks ?
19710 jghali 475
        self->bleedMarks = pdfOptions.bleedMarks;
23926 jghali 476
        // Output registration marks ?
19710 jghali 477
        self->registrationMarks = pdfOptions.registrationMarks;
23926 jghali 478
        // Output color bars ?
19710 jghali 479
        self->colorMarks = pdfOptions.colorMarks;
23926 jghali 480
        // Output doc info marks ?
19710 jghali 481
        self->docInfoMarks = pdfOptions.docInfoMarks;
23926 jghali 482
        // Cropmarks offset 
19746 jghali 483
        self->markOffset = pdfOptions.markOffset * currentDoc->unitRatio();
23926 jghali 484
        // Cropmarks length 
19746 jghali 485
        self->markLength = pdfOptions.markLength * currentDoc->unitRatio();
23926 jghali 486
        // Set automatic compression
19710 jghali 487
        self->compress = pdfOptions.Compress;
488
        self->compressmtd = pdfOptions.CompressMethod;
23926 jghali 489
        // Use maximum image quality
19710 jghali 490
        self->quality = pdfOptions.Quality;
23926 jghali 491
        // Default resolution
22537 craig 492
        PyObject *resolution = nullptr;
23278 jghali 493
        resolution = PyLong_FromLong(300);
23926 jghali 494
        if (resolution)
495
        {
1745 subik 496
                Py_DECREF(self->resolution);
497
                self->resolution = resolution;
23926 jghali 498
        }
499
        else
500
        {
20126 jghali 501
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'resolution' attribute");
1745 subik 502
                return -1;
503
        }
23926 jghali 504
        // Do not downsample images
19710 jghali 505
        int down = pdfOptions.RecalcPic ? pdfOptions.PicRes : 0;
22537 craig 506
        PyObject *downsample = nullptr;
23278 jghali 507
        downsample = PyLong_FromLong(down);
23926 jghali 508
        if (downsample)
509
        {
1745 subik 510
                Py_DECREF(self->downsample);
511
                self->downsample = downsample;
23926 jghali 512
        }
513
        else
514
        {
1745 subik 515
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'downsamle' attribute");
516
                return -1;
517
        }
23926 jghali 518
        // No bookmarks
19710 jghali 519
        self->bookmarks = pdfOptions.Bookmarks;
23926 jghali 520
        // Left margin binding
19710 jghali 521
        self->binding = pdfOptions.Binding;
23926 jghali 522
        // Do not enable presentation effects
19710 jghali 523
        self->presentation = pdfOptions.PresentMode;
23926 jghali 524
        // Set effects values for all pages
22537 craig 525
        PyObject *effval = nullptr;
19710 jghali 526
        num = currentDoc->Pages->count();
1745 subik 527
        effval = PyList_New(num);
23926 jghali 528
        if (!effval)
529
        {
1745 subik 530
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'effval' attribute");
531
                return -1;
532
        }
18394 fschmid 533
        for (i = 0; i < num; ++i)
534
        {
1745 subik 535
                PyObject *tmp;
19710 jghali 536
                PDFPresentationData t = currentDoc->Pages->at(i)->PresentVals;
1745 subik 537
                tmp = Py_BuildValue(const_cast<char*>("[iiiiii]"), t.pageEffectDuration, t.pageViewDuration, t.effectType, t.Dm, t.M, t.Di );
538
                if (tmp)
539
                        PyList_SetItem(effval, i, tmp);
23926 jghali 540
                else
541
                {
1745 subik 542
                        PyErr_SetString(PyExc_SystemError, "Can not initialize 'effval' attribute");
543
                        return -1;
544
                }
23926 jghali 545
                for (; i < num; ++i)
546
                {
547
                        PyObject *tmp = Py_BuildValue(const_cast<char*>("[iiiiii]"), 1, 1, 0, 0, 0, 0);
1745 subik 548
                        if (tmp)
549
                                PyList_SetItem(effval, i, tmp);
23926 jghali 550
                        else
551
                        {
1745 subik 552
                                PyErr_SetString(PyExc_SystemError, "Can not initialize 'effval' attribute");
553
                                return -1;
554
                        }
555
                }
556
        }
557
        Py_DECREF(self->effval);
558
        self->effval = effval;
23926 jghali 559
        // Do not save linked text frames as PDF article
19710 jghali 560
        self->article = pdfOptions.Articles;
23926 jghali 561
        // Do not encrypt file
19710 jghali 562
        self->encrypt = pdfOptions.Encrypt;
23926 jghali 563
        // Do not Use Custom Rendering Settings
19710 jghali 564
        self->uselpi = pdfOptions.UseLPI;
565
        self->usespot = pdfOptions.UseSpotColors;
566
        self->domulti = pdfOptions.doMultiFile;
23926 jghali 567
        // Get default values for lpival
19710 jghali 568
        int n = pdfOptions.LPISettings.size();
1745 subik 569
        PyObject *lpival=PyList_New(n);
23926 jghali 570
        if (!lpival)
571
        {
1745 subik 572
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'lpival' attribute");
573
                return -1;
574
        }
19710 jghali 575
        QMap<QString,LPIData>::Iterator it = pdfOptions.LPISettings.begin();
23926 jghali 576
        while (it != pdfOptions.LPISettings.end())
577
        {
1745 subik 578
                PyObject *tmp;
18194 fschmid 579
                tmp = Py_BuildValue(const_cast<char*>("[siii]"), it.key().toLatin1().constData(), it.value().Frequency, it.value().Angle, it.value().SpotFunc);
23926 jghali 580
                if (!tmp)
581
                {
1745 subik 582
                        PyErr_SetString(PyExc_SystemError, "Can not initialize 'lpival' attribute");
583
                        return -1;
584
                }
585
                PyList_SetItem(lpival, --n, tmp);
586
                ++it;
587
        }
588
        PyList_Reverse(lpival);
589
        Py_DECREF(self->lpival);
590
        self->lpival = lpival;
23926 jghali 591
        // Set owner's password
592
        PyObject *owner = PyUnicode_FromString(pdfOptions.PassOwner.toUtf8());
593
        if (owner)
594
        {
1745 subik 595
                Py_DECREF(self->owner);
596
                self->owner = owner;
23926 jghali 597
        }
598
        else
599
        {
1745 subik 600
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'owner' attribute");
601
                return -1;
602
        }
23926 jghali 603
        // Set user'a password
604
        PyObject *user = PyUnicode_FromString(pdfOptions.PassUser.toUtf8());
605
        if (user)
606
        {
1745 subik 607
                Py_DECREF(self->user);
608
                self->user = user;
23926 jghali 609
        }
610
        else
611
        {
1745 subik 612
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'user' attribute");
613
                return -1;
614
        }
23926 jghali 615
        // Allow printing document
20092 jghali 616
        self->allowPrinting = pdfOptions.Permissions & 4;
23926 jghali 617
        // Allow changing document
20092 jghali 618
        self->allowChange = pdfOptions.Permissions & 8;
23926 jghali 619
        // Allow copying document
20092 jghali 620
        self->allowCopy = pdfOptions.Permissions & 16;
23926 jghali 621
        // Allow adding annotation and fields
20092 jghali 622
        self->allowAnnots = pdfOptions.Permissions & 32;
23926 jghali 623
        // Use 1.4 pdf version *aka. Acrobat 5)
19710 jghali 624
        self->version = pdfOptions.Version;
23926 jghali 625
        // Output destination is screen
19710 jghali 626
        self->outdst = pdfOptions.UseRGB ? 0 : 1;
420 Franz 627
 
19710 jghali 628
        self->profiles = pdfOptions.UseProfiles; // bool
629
        self->profilei = pdfOptions.UseProfiles2; // bool
630
        self->noembicc = pdfOptions.EmbeddedI; // bool
631
        self->intents = pdfOptions.Intent; // int - 0 - 3
632
        self->intenti = pdfOptions.Intent2; // int - 0 - 3
633
        QString tp = pdfOptions.SolidProf;
5243 cbradney 634
        if (!ScCore->InputProfiles.contains(tp))
19710 jghali 635
                tp = currentDoc->cmsSettings().DefaultSolidColorRGBProfile;
23926 jghali 636
        PyObject *solidpr = PyUnicode_FromString(tp.toUtf8());
637
        if (solidpr)
638
        {
1745 subik 639
                Py_DECREF(self->solidpr);
640
                self->solidpr = solidpr;
23926 jghali 641
        }
642
        else
643
        {
1745 subik 644
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'solidpr' attribute");
645
                return -1;
646
        }
19710 jghali 647
        QString tp2 = pdfOptions.ImageProf;
5243 cbradney 648
        if (!ScCore->InputProfiles.contains(tp2))
19710 jghali 649
                tp2 = currentDoc->cmsSettings().DefaultSolidColorRGBProfile;
23926 jghali 650
        PyObject *imagepr = PyUnicode_FromString(tp2.toUtf8());
651
        if (imagepr)
652
        {
1745 subik 653
                Py_DECREF(self->imagepr);
654
                self->imagepr = imagepr;
23926 jghali 655
        }
656
        else
657
        {
1745 subik 658
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'imagepr' attribute");
659
                return -1;
660
        }
19710 jghali 661
        QString tp3 = pdfOptions.PrintProf;
5243 cbradney 662
        if (!ScCore->PDFXProfiles.contains(tp3))
19710 jghali 663
                tp3 = currentDoc->cmsSettings().DefaultPrinterProfile;
22537 craig 664
        PyObject *printprofc = nullptr;
23278 jghali 665
        printprofc = PyUnicode_FromString(tp3.toUtf8());
23926 jghali 666
        if (printprofc)
667
        {
1745 subik 668
                Py_DECREF(self->printprofc);
669
                self->printprofc = printprofc;
23926 jghali 670
        }
671
        else
672
        {
1745 subik 673
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'printprofc' attribute");
674
                return -1;
675
        }
19710 jghali 676
        QString tinfo = pdfOptions.Info;
23926 jghali 677
        PyObject *info = PyUnicode_FromString(tinfo.toUtf8());
678
        if (info)
679
        {
1745 subik 680
                Py_DECREF(self->info);
681
                self->info = info;
23926 jghali 682
        }
683
        else
684
        {
1745 subik 685
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'info' attribute");
686
                return -1;
687
        }
19831 craig 688
        self->bleedt = pdfOptions.bleeds.top() * currentDoc->unitRatio(); // double -
689
        self->bleedl = pdfOptions.bleeds.left() * currentDoc->unitRatio(); // double -
690
        self->bleedr = pdfOptions.bleeds.right() * currentDoc->unitRatio(); // double -
691
        self->bleedb = pdfOptions.bleeds.bottom() * currentDoc->unitRatio(); // double -
20092 jghali 692
        self->useDocBleeds = pdfOptions.useDocBleeds; // bool
19710 jghali 693
        self->useLayers = pdfOptions.useLayers; // bool
694
        self->embedPDF = pdfOptions.embedPDF; // bool
695
        self->mirrorH = pdfOptions.MirrorH; // bool
696
        self->mirrorV = pdfOptions.MirrorV; // bool
697
        self->doClip = pdfOptions.doClip; // bool
23926 jghali 698
        PyObject *rotateDeg = PyLong_FromLong(0);
699
        if (rotateDeg)
700
        {
20092 jghali 701
                Py_DECREF(self->rotateDeg);
702
                self->rotateDeg = rotateDeg;
23926 jghali 703
        }
704
        else
705
        {
20092 jghali 706
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'rotateDeg' attribute");
19699 jghali 707
                return -1;
708
        }
19710 jghali 709
        self->isGrayscale = pdfOptions.isGrayscale; // bool
710
        self->pageLayout = pdfOptions.PageLayout; // int
711
        self->displayBookmarks = pdfOptions.displayBookmarks; // bool
712
        self->displayThumbs = pdfOptions.displayThumbs; // bool
713
        self->displayLayers = pdfOptions.displayLayers; // bool
714
        self->displayFullscreen = pdfOptions.displayFullscreen; // bool
715
        self->hideToolBar = pdfOptions.hideToolBar; // bool
716
        self->hideMenuBar = pdfOptions.hideMenuBar; // bool
717
        self->fitWindow = pdfOptions.fitWindow; // bool
420 Franz 718
 
23926 jghali 719
        PyObject *openAction = PyUnicode_FromString(pdfOptions.openAction.toUtf8().data());
720
        if (openAction)
721
        {
19699 jghali 722
                Py_DECREF(self->openAction);
723
                self->openAction = openAction;
23926 jghali 724
        }
725
        else
726
        {
19699 jghali 727
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'openAction' attribute");
728
                return -1;
729
        }
730
 
1745 subik 731
        return 0;
418 Franz 732
}
733
 
734
static PyMemberDef PDFfile_members[] = {
1745 subik 735
        {const_cast<char*>("thumbnails"), T_INT, offsetof(PDFfile, thumbnails), 0, const_cast<char*>("Generate thumbnails. Bool value.")},
19710 jghali 736
        {const_cast<char*>("cropMarks"), T_INT, offsetof(PDFfile, cropMarks), 0, const_cast<char*>("Create crop marks in the PDF indicating where the paper should be cut or trimmed after printing.")},
19704 jghali 737
        {const_cast<char*>("bleedMarks"), T_INT, offsetof(PDFfile, bleedMarks), 0, const_cast<char*>("Create marks delimiting the bleed area.")},
738
        {const_cast<char*>("registrationMarks"), T_INT, offsetof(PDFfile, registrationMarks), 0, const_cast<char*>("Add registration marks to each separation.")},
739
        {const_cast<char*>("colorMarks"), T_INT, offsetof(PDFfile, colorMarks), 0, const_cast<char*>("Add color calibration bars.")},
740
        {const_cast<char*>("docInfoMarks"), T_INT, offsetof(PDFfile, docInfoMarks), 0, const_cast<char*>("Add document information which includes the document title and page numbers.")},
741
        {const_cast<char*>("markOffset"), T_DOUBLE, offsetof(PDFfile, markOffset), 0, const_cast<char*>("Indicate the distance offset between mark and page area.")},
19746 jghali 742
        {const_cast<char*>("markLength"), T_DOUBLE, offsetof(PDFfile, markLength), 0, const_cast<char*>("Indicate the length of crop and bleed marks.")},
1745 subik 743
        {const_cast<char*>("compress"), T_INT, offsetof(PDFfile, compress), 0, const_cast<char*>("Compression switch. Bool value.")},
744
        {const_cast<char*>("compressmtd"), T_INT, offsetof(PDFfile, compressmtd), 0, const_cast<char*>("Compression method.\n\t0 - Automatic\n\t1 - JPEG\n\t2 - zip\n\t3 - None.")},
745
        {const_cast<char*>("quality"), T_INT, offsetof(PDFfile, quality), 0, const_cast<char*>("Image quality\n\t0 - Maximum\n\t1 - High\n\t2 - Medium\n\t3 - Low\n\t4 - Minimum")},
746
        {const_cast<char*>("bookmarks"), T_INT, offsetof(PDFfile, bookmarks), 0, const_cast<char*>("Embed the bookmarks you created in your document.\nThese are useful for navigating long PDF documents.\nBool value")},
747
        {const_cast<char*>("binding"), T_INT, offsetof(PDFfile, binding), 0, const_cast<char*>("Choose binding.\n\t0 - Left binding\n\t1 - Right binding")},
748
        {const_cast<char*>("presentation"), T_INT, offsetof(PDFfile, presentation), 0, const_cast<char*>("Enable Presentation Effects.Bool value")},
749
        {const_cast<char*>("article"), T_INT, offsetof(PDFfile, article), 0, const_cast<char*>("Save Linked Text Frames as PDF Articles\n\tBool value")},
750
        {const_cast<char*>("encrypt"), T_INT, offsetof(PDFfile, encrypt), 0, const_cast<char*>("Use Encription. Bool value")},
751
        {const_cast<char*>("uselpi"), T_INT, offsetof(PDFfile, uselpi), 0, const_cast<char*>("Use Custom Rendering Settings. Bool value")},
3079 fschmid 752
        {const_cast<char*>("usespot"), T_INT, offsetof(PDFfile, usespot), 0, const_cast<char*>("Use Spot Colors. Bool value")},
753
        {const_cast<char*>("domulti"), T_INT, offsetof(PDFfile, domulti), 0, const_cast<char*>("Produce a PDF File for every Page. Bool value")},
20092 jghali 754
        {const_cast<char*>("allowPrinting"), T_INT, offsetof(PDFfile, allowPrinting), 0, const_cast<char*>("Allow Printing the Document. Bool value")},
755
        {const_cast<char*>("allowChange"), T_INT, offsetof(PDFfile, allowChange), 0, const_cast<char*>("Allow Changing the Document. Bool value")},
756
        {const_cast<char*>("allowCopy"), T_INT, offsetof(PDFfile, allowCopy), 0, const_cast<char*>("Allow Copying Text and Graphics. Bool value")},
757
        {const_cast<char*>("allowAnnots"), T_INT, offsetof(PDFfile, allowAnnots), 0, const_cast<char*>("Allow Adding Annotations and Fields. Bool value")},
19463 jghali 758
        {const_cast<char*>("version"), T_INT, offsetof(PDFfile, version), 0, const_cast<char*>("Choose PDF version to use:\n\t10 = PDF/X4\n\t11 = PDF/X1a\n\t12 = PDF/X-3\n\t13 = PDF 1.3 (Acrobat 4)\n\t14 = PDF 1.4 (Acrobat 5)\n\t15 = PDF 1.5 (Acrobat 6)")},
1745 subik 759
        {const_cast<char*>("outdst"), T_INT, offsetof(PDFfile, outdst), 0, const_cast<char*>("Output destination.\n\t0 - screen\n\t1 - printer")},
760
        {const_cast<char*>("profiles"), T_INT, offsetof(PDFfile, profiles), 0, const_cast<char*>("Embed a color profile for solid colors. Bool value.")},
761
        {const_cast<char*>("profilei"), T_INT, offsetof(PDFfile, profilei), 0, const_cast<char*>("Embed a color profile for images. Bool value.")},
762
        {const_cast<char*>("intents"), T_INT, offsetof(PDFfile, intents), 0, const_cast<char*>("Rendering intent for solid colors\n\t0 - Perceptual\n\t1 - Relative Colorimetric\n\t2 - Saturation\n\t3 - Absolute Colorimetric")},
763
        {const_cast<char*>("intenti"), T_INT, offsetof(PDFfile, intenti), 0, const_cast<char*>("Rendering intent for images\n\t0 - Perceptual\n\t1 - Relative Colorimetric\n\t2 - Saturation\n\t3 - Absolute Colorimetric")},
764
        {const_cast<char*>("noembicc"), T_INT, offsetof(PDFfile, noembicc), 0, const_cast<char*>("Don't use embedded ICC profiles. Bool value")},
765
        {const_cast<char*>("bleedt"), T_DOUBLE, offsetof(PDFfile, bleedt), 0, const_cast<char*>("Bleed Top\n""Distance for bleed from the top of the physical page")},
766
        {const_cast<char*>("bleedl"), T_DOUBLE, offsetof(PDFfile, bleedl), 0, const_cast<char*>("Bleed Left\n""Distance for bleed from the left of the physical page")},
767
        {const_cast<char*>("bleedr"), T_DOUBLE, offsetof(PDFfile, bleedr), 0, const_cast<char*>("Bleed Right\n""Distance for bleed from the right of the physical page")},
768
        {const_cast<char*>("bleedb"), T_DOUBLE, offsetof(PDFfile, bleedb), 0, const_cast<char*>("Bleed Bottom\n""Distance for bleed from the bottom of the physical page")},
20092 jghali 769
        {const_cast<char*>("useDocBleeds"), T_INT, offsetof(PDFfile, useDocBleeds), 0, const_cast<char*>("Use the existing bleed settings from the document preferences. Bool value")},
20267 craig 770
        {const_cast<char*>("useLayers"), T_INT, offsetof(PDFfile, useLayers), 0, const_cast<char*>("Layers in your document are exported to the PDF. Only available if PDF 1.5 is chosen.")},
19704 jghali 771
        {const_cast<char*>("embedPDF"), T_INT, offsetof(PDFfile, embedPDF), 0, const_cast<char*>("Export EPS and PDFs in image frames as embedded PDFs. This does *not* yet take care of colorspaces, so you should know what you are doing before setting this to 'true'.")},
772
        {const_cast<char*>("mirrorH"), T_INT, offsetof(PDFfile, mirrorH), 0, const_cast<char*>("Mirror Page(s) horizontally")},
773
        {const_cast<char*>("mirrorV"), T_INT, offsetof(PDFfile, mirrorV), 0, const_cast<char*>("Mirror Page(s) vertically")},
19699 jghali 774
        {const_cast<char*>("doClip"), T_INT, offsetof(PDFfile, doClip), 0, const_cast<char*>("Do not show objects outside the margins in the exported file")},
775
        {const_cast<char*>("isGrayscale"), T_INT, offsetof(PDFfile, isGrayscale), 0, const_cast<char*>("Export PDF in grayscale")},
19704 jghali 776
        {const_cast<char*>("pageLayout"), T_INT, offsetof(PDFfile, pageLayout), 0, const_cast<char*>("Document layout in PDF viewer:\n"
19699 jghali 777
                                                                                                     "\t0 - Show the document in single page mode\n"
778
                                                                                                     "\t1 - Show the document in single page mode with the pages displayed continuously end to end like a scroll\n"
779
                                                                                                     "\t2 - Show the document with facing pages, starting with the first page displayed on the left\n"
780
                                                                                                     "\t3 - Show the document with facing pages, starting with the first page displayed on the right"
781
                                                                                                     )},
782
        {const_cast<char*>("displayBookmarks"), T_INT, offsetof(PDFfile, displayBookmarks), 0, const_cast<char*>("Display the bookmarks upon opening")},
783
        {const_cast<char*>("displayThumbs"), T_INT, offsetof(PDFfile, displayThumbs), 0, const_cast<char*>("Display the page thumbnails upon opening")},
19704 jghali 784
        {const_cast<char*>("displayLayers"), T_INT, offsetof(PDFfile, displayLayers), 0, const_cast<char*>("Display the layer list upon opening. Useful only for PDF 1.5+.")},
785
        {const_cast<char*>("displayFullscreen"), T_INT, offsetof(PDFfile, displayFullscreen), 0, const_cast<char*>("Display the document in full screen mode upon opening.")},
19710 jghali 786
        {const_cast<char*>("hideToolBar"), T_INT, offsetof(PDFfile, hideToolBar), 0, const_cast<char*>("Hide the viewer toolbar. The toolbar has usually selection and other editing capabilities.")},
787
        {const_cast<char*>("hideMenuBar"), T_INT, offsetof(PDFfile, hideMenuBar), 0, const_cast<char*>("Hide the viewer menu bar, the PDF will display in a plain window.")},
19699 jghali 788
        {const_cast<char*>("fitWindow"), T_INT, offsetof(PDFfile, fitWindow), 0, const_cast<char*>("Fit the document page or pages to the available space in the viewer window.")},
20092 jghali 789
        /** Deprecated members */
790
        {const_cast<char*>("aprint"), T_INT, offsetof(PDFfile, allowPrinting), 0, const_cast<char*>("Deprecated. Use 'allowPrinting' instead.")},
791
        {const_cast<char*>("achange"), T_INT, offsetof(PDFfile, allowChange), 0, const_cast<char*>("Deprecated. Use 'allowChange' instead.")},
792
        {const_cast<char*>("acopy"), T_INT, offsetof(PDFfile, allowCopy), 0, const_cast<char*>("Deprecated. Use 'allowCopy' instead.")},
793
        {const_cast<char*>("aanot"), T_INT, offsetof(PDFfile, allowAnnots), 0, const_cast<char*>("Deprecated. Use 'allowAnnots' instead.")},
22537 craig 794
        {nullptr, 0, 0, 0, nullptr} // sentinel
418 Franz 795
};
796
 
797
 
798
/* Here begins Getter & Setter functions */
799
 
10778 craig 800
static PyObject *PDFfile_getfile(PDFfile *self, void * /*closure*/)
418 Franz 801
{
1745 subik 802
        Py_INCREF(self->file);
803
        return self->file;
418 Franz 804
}
805
 
10778 craig 806
static int PDFfile_setfile(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 807
{
23926 jghali 808
        if (value == nullptr)
809
        {
1745 subik 810
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'file' attribute.");
811
                return -1;
812
        }
23926 jghali 813
        if (!PyUnicode_Check(value))
814
        {
1745 subik 815
                PyErr_SetString(PyExc_TypeError, "The 'file' attribute value must be string.");
816
                return -1;
817
        }
818
        Py_DECREF(self->file);
819
        Py_INCREF(value);
820
        self->file = value;
821
        return 0;
418 Franz 822
}
823
 
20126 jghali 824
static PyObject *PDFfile_getFontEmbeddingMode(PDFfile *self, void * /*closure*/)
825
{
826
        Py_INCREF(self->fontEmbedding);
827
        return self->fontEmbedding;
828
}
829
 
830
static int PDFfile_setFontEmbeddingMode(PDFfile *self, PyObject *value, void * /*closure*/)
831
{
23926 jghali 832
        if (value == nullptr)
833
        {
20126 jghali 834
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'fontEmbedding' attribute.");
835
                return -1;
836
        }
23926 jghali 837
        if (!PyLong_Check(value))
838
        {
20126 jghali 839
                PyErr_SetString(PyExc_TypeError, "'fontEmbedding' attribute value must be integer.");
840
                return -1;
841
        }
23278 jghali 842
        int n = PyLong_AsLong(value);
23926 jghali 843
        if (n < 0 || n > 2)
844
        {
20126 jghali 845
                PyErr_SetString(PyExc_ValueError, "'fontEmbedding' value must be an integer between 0 and 2");
846
                return -1;
847
        }
848
        Py_DECREF(self->fontEmbedding);
849
        Py_INCREF(value);
850
        self->fontEmbedding = value;
851
        return 0;
852
}
853
 
10778 craig 854
static PyObject *PDFfile_getfonts(PDFfile *self, void * /*closure*/)
418 Franz 855
{
1745 subik 856
        Py_INCREF(self->fonts);
857
        return self->fonts;
418 Franz 858
}
859
 
10778 craig 860
static int PDFfile_setfonts(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 861
{
23926 jghali 862
        if (value == nullptr)
863
        {
1745 subik 864
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'fonts' attribute.");
865
                return -1;
866
        }
23926 jghali 867
        if (!PyList_Check(value))
868
        {
1745 subik 869
                PyErr_SetString(PyExc_TypeError, "The 'fonts' attribute value must be list of strings.");
870
                return -1;
871
        }
23926 jghali 872
        int n = PyList_Size(value);
873
        for (int i = 0; i < n; ++i)
874
        {
875
                if (!PyUnicode_Check(PyList_GetItem(value, i)))
876
                {
1745 subik 877
                        PyErr_SetString(PyExc_TypeError, "The 'fonts' list must contain only strings.");
878
                        return -1;
879
                }
23926 jghali 880
        }
881
        // Do I need to check if supplied string is really
882
        // name of available font???
883
        // this is not implemented yet
1745 subik 884
        Py_DECREF(self->fonts);
885
        Py_INCREF(value);
886
        self->fonts = value;
887
        PyList_Sort(self->fonts);
888
        return 0;
418 Franz 889
}
890
 
19699 jghali 891
static PyObject *PDFfile_getSubsetList(PDFfile *self, void * /*closure*/)
892
{
20092 jghali 893
        Py_INCREF(self->subsetList);
894
        return self->subsetList;
19699 jghali 895
}
896
 
897
static int PDFfile_setSubsetList(PDFfile *self, PyObject *value, void * /*closure*/)
898
{
23926 jghali 899
        if (value == nullptr)
900
        {
20092 jghali 901
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'subsetList' attribute.");
19699 jghali 902
                return -1;
903
        }
23926 jghali 904
        if (!PyList_Check(value))
905
        {
20092 jghali 906
                PyErr_SetString(PyExc_TypeError, "The 'subsetList' attribute value must be list of strings.");
19699 jghali 907
                return -1;
908
        }
23926 jghali 909
        int n = PyList_Size(value);
910
        for (int i = 0; i < n; ++i)
911
        {
912
                if (!PyUnicode_Check(PyList_GetItem(value, i)))
913
                {
20092 jghali 914
                        PyErr_SetString(PyExc_TypeError, "The 'subsetList' list must contain only strings.");
19699 jghali 915
                        return -1;
916
                }
23926 jghali 917
        }
20092 jghali 918
        Py_DECREF(self->subsetList);
19699 jghali 919
        Py_INCREF(value);
20092 jghali 920
        self->subsetList = value;
921
        PyList_Sort(self->subsetList);
19699 jghali 922
        return 0;
923
}
924
 
10778 craig 925
static PyObject *PDFfile_getpages(PDFfile *self, void * /*closure*/)
418 Franz 926
{
1745 subik 927
        Py_INCREF(self->pages);
928
        return self->pages;
418 Franz 929
}
930
 
10778 craig 931
static int PDFfile_setpages(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 932
{
23926 jghali 933
        if (value == nullptr)
934
        {
1745 subik 935
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'pages' attribute.");
936
                return -1;
937
        }
23926 jghali 938
        if (!PyList_Check(value))
939
        {
1745 subik 940
                PyErr_SetString(PyExc_TypeError, "'pages' attribute value must be list of integers.");
941
                return -1;
942
        }
943
        int len = PyList_Size(value);
23926 jghali 944
        for (int i = 0; i < len; i++)
945
        {
1745 subik 946
                PyObject *tmp = PyList_GetItem(value, i);
22537 craig 947
                // I did not check if tmp is nullptr
1745 subik 948
                // how can PyList_GetItem fail in this case (my guess: short of available memory?)
949
                // Also do I need Py_INCREF or Py_DECREF here?
23926 jghali 950
                if (!PyLong_Check(tmp))
951
                {
1745 subik 952
                        PyErr_SetString(PyExc_TypeError, "'pages' list must contain only integers.");
953
                        return -1;
954
                }
23926 jghali 955
                if (PyLong_AsLong(tmp) > static_cast<int>(ScCore->primaryMainWindow()->doc->Pages->count()) || PyLong_AsLong(tmp) < 1)
956
                {
1745 subik 957
                        PyErr_SetString(PyExc_ValueError, "'pages' value out of range.");
958
                        return -1;
959
                }
960
        }
961
        Py_DECREF(self->pages);
962
        Py_INCREF(value);
963
        self->pages = value;
964
        return 0;
418 Franz 965
}
966
 
967
 
10778 craig 968
static PyObject *PDFfile_getresolution(PDFfile *self, void * /*closure*/)
418 Franz 969
{
1745 subik 970
        Py_INCREF(self->resolution);
971
        return self->resolution;
418 Franz 972
}
973
 
10778 craig 974
static int PDFfile_setresolution(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 975
{
23926 jghali 976
        if (value == nullptr)
977
        {
1745 subik 978
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'resolution' attribute.");
979
                return -1;
980
        }
23926 jghali 981
        if (!PyLong_Check(value))
982
        {
1745 subik 983
                PyErr_SetString(PyExc_TypeError, "'resolution' attribute value must be integer.");
984
                return -1;
985
        }
23278 jghali 986
        int n = PyLong_AsLong(value);
23926 jghali 987
        if (n < 35 || n > 4000)
988
        {
19574 jghali 989
                PyErr_SetString(PyExc_ValueError, "'resolution' value must be in interval from 35 to 4000");
1745 subik 990
                return -1;
991
        }
992
        Py_DECREF(self->resolution);
993
        Py_INCREF(value);
994
        self->resolution = value;
995
        return 0;
418 Franz 996
}
997
 
10778 craig 998
static PyObject *PDFfile_getdownsample(PDFfile *self, void * /*closure*/)
418 Franz 999
{
1745 subik 1000
        Py_INCREF(self->downsample);
1001
        return self->downsample;
418 Franz 1002
}
1003
 
10778 craig 1004
static int PDFfile_setdownsample(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1005
{
23926 jghali 1006
        if (value == nullptr)
1007
        {
1745 subik 1008
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'downsample' attribute.");
1009
                return -1;
1010
        }
23926 jghali 1011
        if (!PyLong_Check(value))
1012
        {
1745 subik 1013
                PyErr_SetString(PyExc_TypeError, "'downsample' attribute value must be integer.");
1014
                return -1;
1015
        }
23278 jghali 1016
        int n = PyLong_AsLong(value);
23926 jghali 1017
        if (n != 0 && (n < 35 || n > PyLong_AsLong(self->resolution)))
1018
        {
20126 jghali 1019
                PyErr_SetString(PyExc_TypeError, "'downsample' value must be 0 or in interval from 35 to value of 'resolution'");
1745 subik 1020
                return -1;
1021
        }
1022
        Py_DECREF(self->downsample);
1023
        Py_INCREF(value);
1024
        self->downsample = value;
1025
        return 0;
418 Franz 1026
}
1027
 
10778 craig 1028
static PyObject *PDFfile_geteffval(PDFfile *self, void * /*closure*/)
418 Franz 1029
{
1745 subik 1030
        Py_INCREF(self->effval);
1031
        return self->effval;
418 Franz 1032
}
1033
 
10778 craig 1034
static int PDFfile_seteffval(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1035
{
23926 jghali 1036
        if (value == nullptr)
1037
        {
1745 subik 1038
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'effval' attribute.");
1039
                return -1;
1040
        }
23926 jghali 1041
        if (!PyList_Check(value))
1042
        {
1745 subik 1043
                PyErr_SetString(PyExc_TypeError, "'effval' must be list.");
1044
                return -1;
1045
        }
1046
        int n = PyList_Size(value);
23926 jghali 1047
        for (int i = 0; i < n; ++i)
1048
        {
1745 subik 1049
                PyObject *tmp = PyList_GetItem(value, i);
23926 jghali 1050
                if (!PyList_Check(tmp))
1051
                {
24665 jghali 1052
                        PyErr_SetString(PyExc_TypeError, "elements of 'effval' must be list of five integers.");
1745 subik 1053
                        return -1;
1054
                }
1055
                int j = PyList_Size(tmp);
23926 jghali 1056
                if (j != 6)
1057
                {
24665 jghali 1058
                        PyErr_SetString(PyExc_TypeError, "elements of 'effval' must have exactly six integers.");
1745 subik 1059
                        return -1;
1060
                }
23926 jghali 1061
                for (--j; j > -1; --j)
1062
                {
1063
                        if (!PyLong_Check(PyList_GetItem(tmp, j)))
1064
                        {
1745 subik 1065
                                PyErr_SetString(PyExc_TypeError, "innermost element of 'effval' must be integers.");
1066
                                return -1;
1067
                        }
1068
                }
1069
        }
1070
        Py_DECREF(self->effval);
1071
        Py_INCREF(value);
1072
        self->effval = value;
1073
        return 0;
418 Franz 1074
}
1075
 
10778 craig 1076
static PyObject *PDFfile_getlpival(PDFfile *self, void * /*closure*/)
418 Franz 1077
{
1745 subik 1078
        Py_INCREF(self->lpival);
1079
        return self->lpival;
418 Franz 1080
}
1081
 
10778 craig 1082
static int PDFfile_setlpival(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1083
{
23926 jghali 1084
        if (value == nullptr)
1085
        {
1745 subik 1086
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'lpival' attribute.");
1087
                return -1;
1088
        }
23926 jghali 1089
        if (!PyList_Check(value))
1090
        {
1745 subik 1091
                PyErr_SetString(PyExc_TypeError, "'lpival' must be list.");
1092
                return -1;
1093
        }
1094
        // Do I need Py_INCREF or Py_DECREF here?
1095
        int n = PyList_Size(value);
23926 jghali 1096
        for (int i = 0; i < n; ++i)
1097
        {
1745 subik 1098
                PyObject *tmp = PyList_GetItem(value, i);
23926 jghali 1099
                if (!PyList_Check(tmp))
1100
                {
23278 jghali 1101
                        PyErr_SetString(PyExc_TypeError, "elements of 'lpival' must be list of five integers.");
1745 subik 1102
                        return -1;
1103
                }
1104
                int j = PyList_Size(tmp);
23926 jghali 1105
                if (j != 4)
1106
                {
23278 jghali 1107
                        PyErr_SetString(PyExc_TypeError, "elements of 'lpival' must have exactly four members.");
1745 subik 1108
                        return -1;
1109
                }
23926 jghali 1110
                for (--j; j > 0; --j)
1111
                {
1112
                        if (!PyLong_Check(PyList_GetItem(tmp, j)))
1113
                        {
1745 subik 1114
                                PyErr_SetString(PyExc_TypeError, "'lpival'elements must have structure [siii]");
1115
                                return -1;
1116
                        }
1117
                }
23926 jghali 1118
                if (!PyUnicode_Check(PyList_GetItem(tmp, 0)))
1119
                {
1745 subik 1120
                        PyErr_SetString(PyExc_TypeError, "'lpival'elements must have structure [siii]");
1121
                        return -1;
1122
                }
1123
        }
1124
        Py_DECREF(self->lpival);
1125
        Py_INCREF(value);
1126
        self->lpival = value;
1127
        return 0;
418 Franz 1128
}
1129
 
10778 craig 1130
static PyObject *PDFfile_getowner(PDFfile *self, void * /*closure*/)
418 Franz 1131
{
1745 subik 1132
        Py_INCREF(self->owner);
1133
        return self->owner;
418 Franz 1134
}
1135
 
10778 craig 1136
static int PDFfile_setowner(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1137
{
23926 jghali 1138
        if (value == nullptr)
1139
        {
1745 subik 1140
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'owner' attribute.");
1141
                return -1;
1142
        }
23926 jghali 1143
        if (!PyUnicode_Check(value))
1144
        {
1745 subik 1145
                PyErr_SetString(PyExc_TypeError, "'owner' attribute value must be string.");
1146
                return -1;
1147
        }
1148
        Py_DECREF(self->owner);
1149
        Py_INCREF(value);
1150
        self->owner = value;
1151
        return 0;
418 Franz 1152
}
1153
 
10778 craig 1154
static PyObject *PDFfile_getuser(PDFfile *self, void * /*closure*/)
418 Franz 1155
{
1745 subik 1156
        Py_INCREF(self->user);
1157
        return self->user;
418 Franz 1158
}
1159
 
10778 craig 1160
static int PDFfile_setuser(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1161
{
23926 jghali 1162
        if (value == nullptr)
1163
        {
1745 subik 1164
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'user' attribute.");
1165
                return -1;
1166
        }
23926 jghali 1167
        if (!PyUnicode_Check(value))
1168
        {
1745 subik 1169
                PyErr_SetString(PyExc_TypeError, "'user' attribute value must be string.");
1170
                return -1;
1171
        }
1172
        Py_DECREF(self->user);
1173
        Py_INCREF(value);
1174
        self->user = value;
1175
        return 0;
418 Franz 1176
}
1177
 
10778 craig 1178
static PyObject *PDFfile_getsolidpr(PDFfile *self, void * /*closure*/)
418 Franz 1179
{
1745 subik 1180
        Py_INCREF(self->solidpr);
1181
        return self->solidpr;
418 Franz 1182
}
1183
 
10778 craig 1184
static int PDFfile_setsolidpr(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1185
{
23926 jghali 1186
        if (value == nullptr)
1187
        {
1745 subik 1188
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'solidpr' attribute.");
1189
                return -1;
1190
        }
23926 jghali 1191
        if (!PyUnicode_Check(value))
1192
        {
1745 subik 1193
                PyErr_SetString(PyExc_TypeError, "The 'solidpr' attribute value must be string.");
1194
                return -1;
1195
        }
1196
        Py_DECREF(self->solidpr);
1197
        Py_INCREF(value);
1198
        self->solidpr = value;
1199
        return 0;
418 Franz 1200
}
1201
 
10778 craig 1202
static PyObject *PDFfile_getimagepr(PDFfile *self, void * /*closure*/)
418 Franz 1203
{
1745 subik 1204
        Py_INCREF(self->imagepr);
1205
        return self->imagepr;
418 Franz 1206
}
1207
 
10778 craig 1208
static int PDFfile_setimagepr(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1209
{
23926 jghali 1210
        if (value == nullptr)
1211
        {
1745 subik 1212
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'imagepr' attribute.");
1213
                return -1;
1214
        }
23926 jghali 1215
        if (!PyUnicode_Check(value))
1216
        {
1745 subik 1217
                PyErr_SetString(PyExc_TypeError, "The 'imagepr' attribute value must be string.");
1218
                return -1;
1219
        }
1220
        Py_DECREF(self->imagepr);
1221
        Py_INCREF(value);
1222
        self->imagepr = value;
1223
        return 0;
418 Franz 1224
}
1225
 
10778 craig 1226
static PyObject *PDFfile_getprintprofc(PDFfile *self, void * /*closure*/)
418 Franz 1227
{
1745 subik 1228
        Py_INCREF(self->printprofc);
1229
        return self->printprofc;
418 Franz 1230
}
1231
 
10778 craig 1232
static int PDFfile_setprintprofc(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1233
{
23926 jghali 1234
        if (value == nullptr)
1235
        {
1745 subik 1236
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'printprofc' attribute.");
1237
                return -1;
1238
        }
23926 jghali 1239
        if (!PyUnicode_Check(value))
1240
        {
1745 subik 1241
                PyErr_SetString(PyExc_TypeError, "The 'printprofc' attribute value must be string.");
1242
                return -1;
1243
        }
1244
        Py_DECREF(self->printprofc);
1245
        Py_INCREF(value);
1246
        self->printprofc = value;
1247
        return 0;
418 Franz 1248
}
1249
 
10778 craig 1250
static PyObject *PDFfile_getinfo(PDFfile *self, void * /*closure*/)
418 Franz 1251
{
1745 subik 1252
        Py_INCREF(self->info);
1253
        return self->info;
418 Franz 1254
}
1255
 
10778 craig 1256
static int PDFfile_setinfo(PDFfile *self, PyObject *value, void * /*closure*/)
418 Franz 1257
{
23926 jghali 1258
        if (value == nullptr)
1259
        {
1745 subik 1260
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'info' attribute.");
1261
                return -1;
1262
        }
23926 jghali 1263
        if (!PyUnicode_Check(value))
1264
        {
1745 subik 1265
                PyErr_SetString(PyExc_TypeError, "The 'info' attribute value must be string.");
1266
                return -1;
1267
        }
1268
        Py_DECREF(self->info);
1269
        Py_INCREF(value);
1270
        self->info = value;
1271
        return 0;
418 Franz 1272
}
1273
 
19699 jghali 1274
static PyObject *PDFfile_getRotateDeg(PDFfile *self, void * /*closure*/)
1275
{
20092 jghali 1276
        Py_INCREF(self->rotateDeg);
1277
        return self->rotateDeg;
19699 jghali 1278
}
1279
 
1280
static int PDFfile_setRotateDeg(PDFfile *self, PyObject *value, void * /*closure*/)
1281
{
23926 jghali 1282
        if (value == nullptr)
1283
        {
20092 jghali 1284
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'rotateDeg' attribute.");
19699 jghali 1285
                return -1;
1286
        }
23926 jghali 1287
        if (!PyLong_Check(value))
1288
        {
20092 jghali 1289
                PyErr_SetString(PyExc_TypeError, "'rotateDeg' attribute value must be integer.");
19699 jghali 1290
                return -1;
1291
        }
23278 jghali 1292
        int n = PyLong_AsLong(value);
23926 jghali 1293
        if (n != 0 && n != 90 && n != 180 && n != 270)
1294
        {
20092 jghali 1295
                PyErr_SetString(PyExc_TypeError, "'rotateDeg' value must be 0 or 90 or 180 or 270");
19699 jghali 1296
                return -1;
1297
        }
20092 jghali 1298
        Py_DECREF(self->rotateDeg);
19699 jghali 1299
        Py_INCREF(value);
20092 jghali 1300
        self->rotateDeg = value;
19699 jghali 1301
        return 0;
1302
}
1303
 
1304
static PyObject *PDFfile_getopenAction(PDFfile *self, void * /*closure*/)
1305
{
1306
        Py_INCREF(self->openAction);
1307
        return self->openAction;
1308
}
1309
 
1310
static int PDFfile_setopenAction(PDFfile *self, PyObject *value, void * /*closure*/)
1311
{
23926 jghali 1312
        if (value == nullptr)
1313
        {
19699 jghali 1314
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'openAction' attribute.");
1315
                return -1;
1316
        }
23926 jghali 1317
        if (!PyUnicode_Check(value))
1318
        {
19699 jghali 1319
                PyErr_SetString(PyExc_TypeError, "'openAction' attribute value must be string.");
1320
                return -1;
1321
        }
1322
        Py_DECREF(self->openAction);
1323
        Py_INCREF(value);
1324
        self->openAction = value;
1325
        return 0;
1326
}
1327
 
1745 subik 1328
static char *effval_doc = const_cast<char*>(
420 Franz 1329
"List of effection values for each saved page.\n"
1330
"It is list of list of six integers. Those int has followin meaning:\n\t"
1331
"- Length of time the page is shown before the presentation\n\tstarts on the selected page. (1-3600)\n\t"
1332
"- Length of time the effect runs. (1 - 3600)\n\t\tA shorter time will speed up the effect,\n\t\ta longer one will slow it down\n\t"
1333
"- Type of the display effect\n\t\t0 - No Effect\n\t\t1 - Blinds\n\t\t2 - Box\n\t\t3 - Dissolve\n\t\t4 - Glitter\n\t\t5 - Split\n\t\t6 - Wipe\n\t"
1334
"- Direction of the effect of moving lines\n\tfor the split and blind effects.\n\t\t0 - Horizontal\n\t\t1 - Vertical\n\t"
1335
"- Starting position for the box and split effects.\n\t\t0 - Inside\n\t\t1 - Outside\n\t"
1745 subik 1336
"- Direction of the glitter or wipe effects.\n\t\t0 - Left to Right\n\t\t1 - Top to Bottom\n\t\t2 - Bottom to Top\n\t\t3 - Right to Left\n\t\t4 - Top-left to Bottom-Right");
418 Franz 1337
 
1745 subik 1338
static char *lpival_doc = const_cast<char*>(
418 Franz 1339
"Rendering Settings for individual colors.\n\n"
1340
"This is list of values for each color\n"
1341
"Color values have structure [siii] which stand for:\n\t"
420 Franz 1342
"s - Color name ('Black', 'Cyan', 'Magenta', 'Yellow')\n\t"
418 Franz 1343
"i - Frequency (10 to 1000)\n\t"
1344
"i - Angle (-180 to 180)\n\t"
420 Franz 1345
"i - Spot Function\n\t\t0 - Simple Dot\n\t\t1 - Line\n\t\t2 - Round\n\t\t3 - Ellipse\n"
22055 jghali 1346
"Be careful when supplying these values as they\nare not checked for validity.");
418 Franz 1347
 
1348
static PyGetSetDef PDFfile_getseters [] = {
22537 craig 1349
        {const_cast<char*>("file"), (getter)PDFfile_getfile, (setter)PDFfile_setfile, const_cast<char*>("Name of file to save into"), nullptr},
1350
        {const_cast<char*>("fontEmbedding"), (getter)PDFfile_getFontEmbeddingMode, (setter)PDFfile_setFontEmbeddingMode, const_cast<char*>("Font embedding mode.\n\tValue must be one of integers: 0 (Embed), 1 (Outline), 2 (No embedding)."), nullptr},
1351
        {const_cast<char*>("fonts"), (getter)PDFfile_getfonts, (setter)PDFfile_setfonts, const_cast<char*>("List of fonts to embed."), nullptr},
1352
        {const_cast<char*>("subsetList"), (getter)PDFfile_getSubsetList, (setter)PDFfile_setSubsetList, const_cast<char*>("List of fonts to subsetted."), nullptr},
1353
        {const_cast<char*>("pages"), (getter)PDFfile_getpages, (setter)PDFfile_setpages, const_cast<char*>("List of pages to print"), nullptr},
1354
        {const_cast<char*>("resolution"), (getter)PDFfile_getresolution, (setter)PDFfile_setresolution, const_cast<char*>("Resolution of output file. Values from 35 to 4000."), nullptr},
1355
        {const_cast<char*>("downsample"), (getter)PDFfile_getdownsample, (setter)PDFfile_setdownsample, const_cast<char*>("Downsample image resolusion to this value. Values from 35 to 4000\nSet 0 for not to downsample"), nullptr},
1356
        {const_cast<char*>("effval"), (getter)PDFfile_geteffval, (setter)PDFfile_seteffval, effval_doc, nullptr},
1357
        {const_cast<char*>("lpival"), (getter)PDFfile_getlpival, (setter)PDFfile_setlpival, lpival_doc, nullptr},
1358
        {const_cast<char*>("owner"), (getter)PDFfile_getowner, (setter)PDFfile_setowner, const_cast<char*>("Owner's password"), nullptr},
1359
        {const_cast<char*>("user"), (getter)PDFfile_getuser, (setter)PDFfile_setuser, const_cast<char*>("User's password"), nullptr},
1360
        {const_cast<char*>("solidpr"), (getter)PDFfile_getsolidpr, (setter)PDFfile_setsolidpr, const_cast<char*>("Color profile for solid colors"), nullptr},
1361
        {const_cast<char*>("imagepr"), (getter)PDFfile_getimagepr, (setter)PDFfile_setimagepr, const_cast<char*>("Color profile for images"), nullptr},
1362
        {const_cast<char*>("printprofc"), (getter)PDFfile_getprintprofc, (setter)PDFfile_setprintprofc, const_cast<char*>("Output profile for printing. If possible, get some guidance from your printer on profile selection."), nullptr},
1363
        {const_cast<char*>("info"), (getter)PDFfile_getinfo, (setter)PDFfile_setinfo, const_cast<char*>("Mandatory string for PDF/X or the PDF will fail\nPDF/X conformance. We recommend you use the title of the document."), nullptr},
1364
        {const_cast<char*>("rotateDeg"), (getter)PDFfile_getRotateDeg, (setter)PDFfile_setRotateDeg, const_cast<char*>("Automatically rotate the exported pages\n\tValue must be one of integers: 0, 90, 180 or 270"), nullptr},
1365
        {const_cast<char*>("openAction"), (getter)PDFfile_getopenAction, (setter)PDFfile_setopenAction, const_cast<char*>("Javascript to be executed when PDF document is opened."), nullptr},
1366
        {nullptr, nullptr, nullptr, nullptr, nullptr}  // sentinel
418 Franz 1367
};
1368
 
1369
static PyObject *PDFfile_save(PDFfile *self)
1370
{
23926 jghali 1371
        if (!checkHaveDocument())
22537 craig 1372
                return nullptr;
733 subik 1373
 
19710 jghali 1374
        ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
1375
        PDFOptions& pdfOptions = currentDoc->pdfOptions();
1376
 
23920 jghali 1377
        // Copied from file scribus.cpp
1378
        // void ScribusMainWindow::SaveAsPDF()
10428 subik 1379
        if (ScCore->primaryMainWindow()->bookmarkPalette->BView->topLevelItemCount() == 0)
19710 jghali 1380
                pdfOptions.Bookmarks = false;
733 subik 1381
 
23920 jghali 1382
        // Get PDF version
23548 jghali 1383
        self->version = minmaxi(self->version, PDFVersion::PDFVersion_Min, PDFVersion::PDFVersion_Max);
1384
        pdfOptions.Version = (PDFVersion::Version) self->version;
20126 jghali 1385
 
23920 jghali 1386
        // Update used fonts
1387
        currentDoc->reorganiseFonts();
1388
 
1389
        // Apply fonts attribute
19710 jghali 1390
        pdfOptions.EmbedList.clear();
1745 subik 1391
        int n = PyList_Size(self->fonts);
23278 jghali 1392
        for (int i = 0; i < n; ++i)
20126 jghali 1393
        {
1745 subik 1394
                QString tmpFon;
23278 jghali 1395
                tmpFon = PyUnicode_asQString(PyList_GetItem(self->fonts, i));
19710 jghali 1396
                pdfOptions.EmbedList.append(tmpFon);
1745 subik 1397
        }
23920 jghali 1398
        // Apply SubsetList attribute
19710 jghali 1399
        pdfOptions.SubsetList.clear();
20092 jghali 1400
        n = PyList_Size(self->subsetList);
20126 jghali 1401
        for (int i = 0; i < n; ++i)
1402
        {
19699 jghali 1403
                QString tmpFon;
23278 jghali 1404
                tmpFon = PyUnicode_asQString(PyList_GetItem(self->subsetList, i));
19710 jghali 1405
                pdfOptions.SubsetList.append(tmpFon);
19699 jghali 1406
        }
23920 jghali 1407
        // Apply font embedding mode
23278 jghali 1408
        pdfOptions.FontEmbedding = (PDFOptions::PDFFontEmbedding) PyLong_AsLong(self->fontEmbedding);
23548 jghali 1409
        if (pdfOptions.Version == PDFVersion::PDF_X1a ||
1410
            pdfOptions.Version == PDFVersion::PDF_X3 ||
1411
            pdfOptions.Version == PDFVersion::PDF_X4)
20126 jghali 1412
        {
1413
                pdfOptions.FontEmbedding = PDFOptions::EmbedFonts;
1414
        }
1415
        if (pdfOptions.FontEmbedding == PDFOptions::EmbedFonts)
1416
        {
1417
                QStringList docFonts = currentDoc->UsedFonts.keys();
1418
                for (int i = 0; i < docFonts.count(); ++i)
1419
                {
22635 craig 1420
                        const QString& fontName = docFonts.at(i);
20126 jghali 1421
                        if (pdfOptions.SubsetList.contains(fontName))
1422
                                continue;
1423
                        if (pdfOptions.EmbedList.contains(fontName))
1424
                                continue;
1425
                        pdfOptions.SubsetList.append(fontName);
1426
                }
1427
                pdfOptions.OutlineList = QStringList();
1428
        }
1429
        else if (pdfOptions.FontEmbedding == PDFOptions::OutlineFonts)
1430
        {
1431
                pdfOptions.EmbedList   = QStringList();
1432
                pdfOptions.SubsetList  = QStringList();
1433
                pdfOptions.OutlineList = currentDoc->UsedFonts.keys();
1434
        }
1435
        else
1436
        {
1437
                pdfOptions.EmbedList   = QStringList();
1438
                pdfOptions.SubsetList  = QStringList();
1439
                pdfOptions.OutlineList = QStringList();
1440
        }
23920 jghali 1441
        // Apply file attribute
23926 jghali 1442
        QString fn = PyUnicode_asQString(self->file);
19710 jghali 1443
        pdfOptions.fileName = fn;
23920 jghali 1444
        // Apply pages attribute
1745 subik 1445
        std::vector<int> pageNs;
23278 jghali 1446
        int nn = PyList_Size(self->pages);
1745 subik 1447
        for (int i = 0; i < nn; ++i) {
23278 jghali 1448
                pageNs.push_back((int) PyLong_AsLong(PyList_GetItem(self->pages, i)));
1745 subik 1449
        }
23920 jghali 1450
        // Apply thumbnails attribute
19710 jghali 1451
        pdfOptions.Thumbnails = self->thumbnails;
23920 jghali 1452
        // Apply cropmarks attribute
19710 jghali 1453
        pdfOptions.cropMarks = self->cropMarks;
23920 jghali 1454
        // Apply bleedmarks attribute
19710 jghali 1455
        pdfOptions.bleedMarks = self->bleedMarks;
23920 jghali 1456
        // Apply registrationmarks attribute
19710 jghali 1457
        pdfOptions.registrationMarks = self->registrationMarks;
23920 jghali 1458
        // Apply colormarks attribute
19710 jghali 1459
        pdfOptions.colorMarks = self->colorMarks;
23920 jghali 1460
        // Apply docInfoMark attribute
19710 jghali 1461
        pdfOptions.docInfoMarks = self->docInfoMarks;
23920 jghali 1462
        // Apply mark offset attribute
19746 jghali 1463
        pdfOptions.markOffset = qMax(0.0, self->markOffset / currentDoc->unitRatio());
23920 jghali 1464
        // Apply mark length attribute
19746 jghali 1465
        pdfOptions.markLength = qMax(0.0, self->markLength / currentDoc->unitRatio());
23920 jghali 1466
        // Apply compress attribute
1745 subik 1467
        self->compressmtd = minmaxi(self->compressmtd, 0, 3);
19710 jghali 1468
        pdfOptions.Compress = self->compress;
1469
        pdfOptions.CompressMethod = (PDFOptions::PDFCompression) self->compressmtd;
23920 jghali 1470
        // Apply quality attribute
1745 subik 1471
        self->quality = minmaxi(self->quality, 0, 4);
19710 jghali 1472
        pdfOptions.Quality = self->quality;
23920 jghali 1473
        // Apply resolusion attribute
23278 jghali 1474
        pdfOptions.Resolution = PyLong_AsLong(self->resolution);
23920 jghali 1475
        // Apply downsample attribute
23278 jghali 1476
        pdfOptions.RecalcPic = PyLong_AsLong(self->downsample);
19710 jghali 1477
        if (pdfOptions.RecalcPic)
23278 jghali 1478
                pdfOptions.PicRes = PyLong_AsLong(self->downsample);
1745 subik 1479
        else
19710 jghali 1480
                pdfOptions.PicRes = pdfOptions.Resolution;
23920 jghali 1481
        // Apply bookmarks attribute
19710 jghali 1482
        pdfOptions.Bookmarks = self->bookmarks;
23920 jghali 1483
        // Apply binding attribute
19710 jghali 1484
        pdfOptions.Binding = self->binding;
23920 jghali 1485
        // Apply presentation attribute
19710 jghali 1486
        pdfOptions.PresentMode = self->presentation;
733 subik 1487
 
20126 jghali 1488
        int tmpnum = PyList_Size(self->effval);
1489
        for (int i = 0; i < tmpnum; ++i)
1490
        {
1745 subik 1491
                PDFPresentationData t;
1492
                PyObject *ti = PyList_GetItem(self->effval, i);
20126 jghali 1493
                if (!ti)
1494
                        continue;
24665 jghali 1495
                // Do I Need to check if every PyLong_AsLong and PyList_GetItem function succeed???
23278 jghali 1496
                t.pageEffectDuration = PyLong_AsLong(PyList_GetItem(ti, 0));
1497
                t.pageViewDuration = PyLong_AsLong(PyList_GetItem(ti, 1));
1498
                t.effectType = PyLong_AsLong(PyList_GetItem(ti, 2));
1499
                t.Dm = PyLong_AsLong(PyList_GetItem(ti, 3));
1500
                t.M = PyLong_AsLong(PyList_GetItem(ti, 4));
1501
                t.Di = PyLong_AsLong(PyList_GetItem(ti, 5));
20126 jghali 1502
                //      PresentVals.append(t);
1745 subik 1503
        }
23926 jghali 1504
//      pdfOptions.PresentVals = PresentVals;
418 Franz 1505
 
23920 jghali 1506
        // Apply lpival
1745 subik 1507
        int n2 = PyList_Size(self->lpival);
20126 jghali 1508
        for (int i = 0; i < n2; ++i)
1509
        {
1745 subik 1510
                LPIData lpi;
1511
                PyObject *t = PyList_GetItem(self->lpival, i);
418 Franz 1512
// This code always raise exception - WHY???
1745 subik 1513
//              char *s;
20126 jghali 1514
//              if (!PyArg_ParseTuple(t, "[siii]", &s, &lpi.Frequency,
1515
//                               &lpi.Angle, &lpi.SpotFunc)) {
1516
//                      PyErr_SetString(PyExc_SystemError, "while parsing 'lpival'. WHY THIS HAPPENED????");
22537 craig 1517
//                      return nullptr;
20126 jghali 1518
//              }
1519
//              pdfOptions.LPISettings[QString(s)]=lpi;
23278 jghali 1520
                QString st = PyUnicode_asQString(PyList_GetItem(t, 0));
1521
                lpi.Frequency = PyLong_AsLong(PyList_GetItem(t, 1));
1522
                lpi.Angle = PyLong_AsLong(PyList_GetItem(t, 2));
1523
                lpi.SpotFunc = PyLong_AsLong(PyList_GetItem(t, 3));
20126 jghali 1524
                pdfOptions.LPISettings[st] = lpi;
1745 subik 1525
        }
733 subik 1526
 
19710 jghali 1527
        pdfOptions.Articles = self->article;
1528
        pdfOptions.Encrypt = self->encrypt;
1529
        pdfOptions.UseLPI = self->uselpi;
1530
        pdfOptions.UseSpotColors = self->usespot;
1531
        pdfOptions.doMultiFile = self->domulti;
20126 jghali 1532
 
1745 subik 1533
        if (self->encrypt)
1534
        {
1535
                int Perm = -64;
23548 jghali 1536
                if (pdfOptions.Version == PDFVersion::PDF_14)
1745 subik 1537
                        Perm &= ~0x00240000;
20092 jghali 1538
                if (self->allowPrinting)
1745 subik 1539
                        Perm += 4;
20092 jghali 1540
                if (self->allowChange)
1745 subik 1541
                        Perm += 8;
20092 jghali 1542
                if (self->allowCopy)
1745 subik 1543
                        Perm += 16;
20092 jghali 1544
                if (self->allowAnnots)
1745 subik 1545
                        Perm += 32;
19710 jghali 1546
                pdfOptions.Permissions = Perm;
23278 jghali 1547
                pdfOptions.PassOwner = PyUnicode_asQString(self->owner);
1548
                pdfOptions.PassUser = PyUnicode_asQString(self->user);
1745 subik 1549
        }
1550
        if (self->outdst == 0)
1551
        {
19710 jghali 1552
                pdfOptions.UseRGB = true;
1553
                pdfOptions.UseProfiles = false;
1554
                pdfOptions.UseProfiles2 = false;
1745 subik 1555
        }
1556
        else
1557
        {
19710 jghali 1558
                pdfOptions.UseRGB = false;
5880 jghali 1559
                if (ScCore->primaryMainWindow()->doc->HasCMS)
1745 subik 1560
                {
19710 jghali 1561
                        pdfOptions.UseProfiles = self->profiles;
1562
                        pdfOptions.UseProfiles2 = self->profilei;
1745 subik 1563
                        self->intents = minmaxi(self->intents, 0, 3);
19710 jghali 1564
                        pdfOptions.Intent = self->intents;
1745 subik 1565
                        self->intenti = minmaxi(self->intenti, 0, 3);
19710 jghali 1566
                        pdfOptions.Intent2 = self->intenti;
1567
                        pdfOptions.EmbeddedI = self->noembicc;
23278 jghali 1568
                        pdfOptions.SolidProf = PyUnicode_asQString(self->solidpr);
1569
                        pdfOptions.ImageProf = PyUnicode_asQString(self->imagepr);
1570
                        pdfOptions.PrintProf = PyUnicode_asQString(self->printprofc);
23548 jghali 1571
                        if (pdfOptions.Version == PDFVersion::PDF_X1a ||
1572
                                pdfOptions.Version == PDFVersion::PDF_X3 ||
1573
                                pdfOptions.Version == PDFVersion::PDF_X4)
1745 subik 1574
                        {
23278 jghali 1575
                                pdfOptions.Info = PyUnicode_asQString(self->info);
19710 jghali 1576
                                pdfOptions.Encrypt = false;
1577
                                pdfOptions.PresentMode = false;
1745 subik 1578
                        }
1579
                }
1580
                else
1581
                {
19710 jghali 1582
                        pdfOptions.UseProfiles = false;
1583
                        pdfOptions.UseProfiles2 = false;
1745 subik 1584
                }
1585
        }
22460 jghali 1586
 
22459 jghali 1587
        QMap<int, QImage> thumbs;
22460 jghali 1588
        PageToPixmapFlags pixmapFlags = Pixmap_DontReloadImages | Pixmap_DrawWhiteBackground;
1745 subik 1589
        for (uint ap = 0; ap < pageNs.size(); ++ap)
1590
        {
22459 jghali 1591
                QImage thumb(10, 10, QImage::Format_ARGB32_Premultiplied );
19710 jghali 1592
                if (pdfOptions.Thumbnails)
23926 jghali 1593
                        thumb = ScCore->primaryMainWindow()->view->PageToPixmap(pageNs[ap] - 1, 100, pixmapFlags);
22459 jghali 1594
                thumbs.insert(pageNs[ap], thumb);
1745 subik 1595
        }
22460 jghali 1596
 
5781 cbradney 1597
        ReOrderText(ScCore->primaryMainWindow()->doc, ScCore->primaryMainWindow()->view);
19693 jghali 1598
 
19710 jghali 1599
        MarginStruct optBleeds(pdfOptions.bleeds);
20092 jghali 1600
        pdfOptions.useDocBleeds = self->useDocBleeds;
1601
        if (self->useDocBleeds)
19710 jghali 1602
                pdfOptions.bleeds = ScCore->primaryMainWindow()->doc->bleedsVal();
23926 jghali 1603
        else
1604
        {
19710 jghali 1605
                self->bleedt = minmaxd(self->bleedt, 0, currentDoc->pageHeight() * currentDoc->unitRatio());
19831 craig 1606
                pdfOptions.bleeds.setTop(self->bleedt / currentDoc->unitRatio());
19710 jghali 1607
                self->bleedl = minmaxd(self->bleedl, 0, currentDoc->pageWidth() * currentDoc->unitRatio());
19831 craig 1608
                pdfOptions.bleeds.setLeft(self->bleedl / currentDoc->unitRatio());
19710 jghali 1609
                self->bleedr = minmaxd(self->bleedr, 0, currentDoc->pageWidth() * currentDoc->unitRatio());
19831 craig 1610
                pdfOptions.bleeds.setRight(self->bleedr / currentDoc->unitRatio());
19710 jghali 1611
                self->bleedb = minmaxd(self->bleedb, 0, currentDoc->pageHeight() * currentDoc->unitRatio());
19831 craig 1612
                pdfOptions.bleeds.setBottom(self->bleedb / currentDoc->unitRatio());
19693 jghali 1613
        }
19710 jghali 1614
        pdfOptions.useLayers = self->useLayers;
1615
        pdfOptions.embedPDF = self->embedPDF;
1616
        pdfOptions.MirrorH = self->mirrorH;
1617
        pdfOptions.MirrorV = self->mirrorV;
1618
        pdfOptions.doClip = self->doClip;
23278 jghali 1619
        pdfOptions.RotateDeg = PyLong_AsLong(self->rotateDeg);
19710 jghali 1620
        pdfOptions.isGrayscale = self->isGrayscale;
1621
        pdfOptions.PageLayout = minmaxi(self->pageLayout, 0, 3);
1622
        pdfOptions.displayBookmarks = self->displayBookmarks;
1623
        pdfOptions.displayThumbs = self->displayThumbs;
1624
        pdfOptions.displayLayers = self->displayLayers;
1625
        pdfOptions.displayFullscreen = self->displayFullscreen;
1626
        pdfOptions.hideToolBar = self->hideToolBar;
1627
        pdfOptions.hideMenuBar = self->hideMenuBar;
1628
        pdfOptions.fitWindow = self->fitWindow;
23278 jghali 1629
        pdfOptions.openAction = PyUnicode_asQString(self->openAction);
19710 jghali 1630
        pdfOptions.firstUse = false;
19693 jghali 1631
 
11060 jghali 1632
        QString errorMessage;
23825 jghali 1633
        bool success = ScCore->primaryMainWindow()->getPDFDriver(fn, pageNs, thumbs, errorMessage);
23926 jghali 1634
        if (!success)
1635
        {
11060 jghali 1636
                fn  = "Cannot write the File: " + fn;
1637
                if (!errorMessage.isEmpty())
1638
                        fn += QString("\n%1").arg(errorMessage);
18194 fschmid 1639
                PyErr_SetString(PyExc_SystemError, fn.toLatin1());
1745 subik 1640
        }
19693 jghali 1641
 
20092 jghali 1642
        if (self->useDocBleeds)
19710 jghali 1643
                pdfOptions.bleeds = optBleeds;
19693 jghali 1644
 
1645
        if (success)
1646
                Py_RETURN_NONE;
22537 craig 1647
        return nullptr;
418 Franz 1648
}
1649
 
1650
static PyMethodDef PDFfile_methods[] = {
23980 jghali 1651
        {const_cast<char*>("save"), (PyCFunction)PDFfile_save, METH_NOARGS, pdffile_save__doc__},
22606 craig 1652
        {nullptr, (PyCFunction)(nullptr), 0, nullptr} // sentinel
418 Franz 1653
};
1654
 
1655
PyTypeObject PDFfile_Type = {
23278 jghali 1656
        PyVarObject_HEAD_INIT(nullptr, 0) // PyObject_VAR_HEAD        //
19456 jghali 1657
        const_cast<char*>("scribus.PDFfile"), // char *tp_name; /* For printing, in format "<module>.<name>" */
1745 subik 1658
        sizeof(PDFfile),     // int tp_basicsize, /* For allocation */
1659
        0,                  // int tp_itemsize; /* For allocation */
418 Franz 1660
 
1661
        /* Methods to implement standard operations */
1662
 
1745 subik 1663
        (destructor) PDFfile_dealloc, //     destructor tp_dealloc;
23314 jghali 1664
#if PY_VERSION_HEX >= 0x03080000
1665
        0,       //     Py_ssize_t tp_vectorcall_offset
1666
#else
22606 craig 1667
        nullptr, //     printfunc tp_print;
23314 jghali 1668
#endif
22606 craig 1669
        nullptr, //     getattrfunc tp_getattr;
1670
        nullptr, //     setattrfunc tp_setattr;
23314 jghali 1671
        nullptr, //     cmpfunc tp_as_async;
22606 craig 1672
        nullptr, //     reprfunc tp_repr;
418 Franz 1673
 
1674
        /* Method suites for standard classes */
1675
 
22606 craig 1676
        nullptr, //     PyNumberMethods *tp_as_number;
1677
        nullptr, //     PySequenceMethods *tp_as_sequence;
1678
        nullptr, //     PyMappingMethods *tp_as_mapping;
418 Franz 1679
 
1680
        /* More standard operations (here for binary compatibility) */
1681
 
22606 craig 1682
        nullptr, //     hashfunc tp_hash;
1683
        nullptr, //     ternaryfunc tp_call;
1684
        nullptr, //     reprfunc tp_str;
1685
        nullptr, //     getattrofunc tp_getattro;
1686
        nullptr, //     setattrofunc tp_setattro;
418 Franz 1687
 
1688
        /* Functions to access object as input/output buffer */
22606 craig 1689
        nullptr, //     PyBufferProcs *tp_as_buffer;
418 Franz 1690
 
1691
        /* Flags to define presence of optional/expanded features */
1745 subik 1692
        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,    // long tp_flags;
418 Franz 1693
 
1745 subik 1694
        pdffile__doc__,      // char *tp_doc; /* Documentation string */
733 subik 1695
 
418 Franz 1696
        /* Assigned meaning in release 2.0 */
1697
        /* call function for all accessible objects */
22606 craig 1698
        nullptr, //     traverseproc tp_traverse;
418 Franz 1699
 
1700
        /* delete references to contained objects */
22606 craig 1701
        nullptr, //     inquiry tp_clear;
418 Franz 1702
 
1703
        /* Assigned meaning in release 2.1 */
1704
        /* rich comparisons */
22606 craig 1705
        nullptr, //     richcmpfunc tp_richcompare;
418 Franz 1706
 
1707
        /* weak reference enabler */
1745 subik 1708
        0, //     long tp_weaklistoffset;
418 Franz 1709
 
1710
        /* Added in release 2.2 */
1711
        /* Iterators */
22606 craig 1712
        nullptr, //     getiterfunc tp_iter;
1713
        nullptr, //     iternextfunc tp_iternext;
418 Franz 1714
 
1715
        /* Attribute descriptor and subclassing stuff */
1745 subik 1716
        PDFfile_methods, //     struct PyMethodDef *tp_methods;
1717
        PDFfile_members, //     struct PyMemberDef *tp_members;
1718
        PDFfile_getseters, //     struct PyGetSetDef *tp_getset;
22606 craig 1719
        nullptr, //     struct _typeobject *tp_base;
1720
        nullptr, //     PyObject *tp_dict;
1721
        nullptr, //     descrgetfunc tp_descr_get;
1722
        nullptr, //     descrsetfunc tp_descr_set;
1745 subik 1723
        0, //     long tp_dictoffset;
1724
        (initproc)PDFfile_init, //     initproc tp_init;
22606 craig 1725
        nullptr, //     allocfunc tp_alloc;
1745 subik 1726
        PDFfile_new, //     newfunc tp_new;
22606 craig 1727
        nullptr, //     freefunc tp_free; /* Low-level free-memory routine */
1728
        nullptr, //     inquiry tp_is_gc; /* For PyObject_IS_GC */
1729
        nullptr, //     PyObject *tp_bases;
1730
        nullptr, //     PyObject *tp_mro; /* method resolution order */
1731
        nullptr, //     PyObject *tp_cache;
1732
        nullptr, //     PyObject *tp_subclasses;
1733
        nullptr, //     PyObject *tp_weaklist;
1734
        nullptr, //     destructor tp_del;
23278 jghali 1735
        0, //    unsigned int tp_version_tag;
1736
        0, //    destructor tp_finalize;
23314 jghali 1737
#if PY_VERSION_HEX >= 0x03080000
1738
        nullptr, // tp_vectorcall
1739
#endif
1740
#if PY_VERSION_HEX >= 0x03080000 && PY_VERSION_HEX < 0x03090000
1741
        nullptr, //deprecated tp_print
1742
#endif
418 Franz 1743
 
1744
#ifdef COUNT_ALLOCS
1745
        /* these must be last and never explicitly initialized */
1745 subik 1746
        //    int tp_allocs;
1747
        //    int tp_frees;
1748
        //    int tp_maxalloc;
23314 jghali 1749
        //    struct _typeobject *tp_prev;
1745 subik 1750
        //    struct _typeobject *tp_next;
418 Franz 1751
#endif
1752
};
24674 jghali 1753
 
1754
/*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
1755
with header files structure untouched (docstrings are kept near declarations)
1756
PV */
1757
void objpdffilewarnings()
1758
{
1759
        QStringList s;
1760
        s << pdffile__doc__
1761
          << pdffile_save__doc__;
1762
}