Subversion Repositories Scribus

Rev

Rev 22947 | Rev 23168 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
20424 jghali 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
02.01.2008: Joachim Neu - joachim_neu@web.de - http://www.joachim-neu.de
7
*/
8
#include "cmdstyle.h"
9
#include "cmdutil.h"
10
 
22969 jghali 11
#include <limits>
12
 
13
#include <QBuffer>
20424 jghali 14
#include <QList>
22969 jghali 15
#include <QPixmap>
20424 jghali 16
 
17
#include "scribuscore.h"
18
#include "styles/paragraphstyle.h"
19
#include "styles/charstyle.h"
20
#include "ui/stylemanager.h"
21
 
22
/*! 02.01.2007 - 05.01.2007 : Joachim Neu : Create a paragraph style.
23
                        Special thanks go to avox for helping me! */
24
PyObject *scribus_createparagraphstyle(PyObject* /* self */, PyObject* args, PyObject* keywords)
25
{
26
        //TODO - new paragraph properties for bullets and numbering
27
        char* keywordargs[] = {
28
                        const_cast<char*>("name"),
29
                        const_cast<char*>("linespacingmode"),
30
                        const_cast<char*>("linespacing"),
31
                        const_cast<char*>("alignment"),
32
                        const_cast<char*>("leftmargin"),
33
                        const_cast<char*>("rightmargin"),
34
                        const_cast<char*>("gapbefore"),
35
                        const_cast<char*>("gapafter"),
36
                        const_cast<char*>("firstindent"),
37
                        const_cast<char*>("hasdropcap"),
38
                        const_cast<char*>("dropcaplines"),
39
                        const_cast<char*>("dropcapoffset"),
40
                        const_cast<char*>("charstyle"),
22606 craig 41
                        nullptr};
22942 jghali 42
        char *name = const_cast<char*>(""), *charStyle = const_cast<char*>("");
43
        int lineSpacingMode = 0, alignment = 0, dropCapLines = 2, hasDropCap = 0;
44
        double lineSpacing = 15.0, leftMargin = 0.0, rightMargin = 0.0;
45
        double gapBefore = 0.0, gapAfter = 0.0, firstIndent = 0.0, peOffset = 0;
20424 jghali 46
        if (!PyArg_ParseTupleAndKeywords(args, keywords, "es|ididddddiides",
22942 jghali 47
                 keywordargs, "utf-8", &name, &lineSpacingMode, &lineSpacing, &alignment,
48
                &leftMargin, &rightMargin, &gapBefore, &gapAfter, &firstIndent,
49
                &hasDropCap, &dropCapLines, &peOffset, "utf-8", &charStyle))
22606 craig 50
                return nullptr;
22653 jghali 51
        if (!checkHaveDocument())
22606 craig 52
                return nullptr;
22942 jghali 53
        if (strlen(name) == 0)
20424 jghali 54
        {
55
                PyErr_SetString(PyExc_ValueError, QObject::tr("Cannot have an empty paragraph style name.","python error").toLocal8Bit().constData());
22606 craig 56
                return nullptr;
20424 jghali 57
        }
58
 
22942 jghali 59
        ParagraphStyle tmpParagraphStyle;
60
        tmpParagraphStyle.setName(name);
61
        tmpParagraphStyle.setLineSpacingMode((ParagraphStyle::LineSpacingMode)lineSpacingMode);
62
        tmpParagraphStyle.setLineSpacing(lineSpacing);
63
        tmpParagraphStyle.setAlignment((ParagraphStyle::AlignmentType)alignment);
64
        tmpParagraphStyle.setLeftMargin(leftMargin);
65
        tmpParagraphStyle.setFirstIndent(firstIndent);
66
        tmpParagraphStyle.setRightMargin(rightMargin);
67
        tmpParagraphStyle.setGapBefore(gapBefore);
68
        tmpParagraphStyle.setGapAfter(gapAfter);
69
        if (hasDropCap == 0)
70
                tmpParagraphStyle.setHasDropCap(false);
71
        else if (hasDropCap == 1)
72
                tmpParagraphStyle.setHasDropCap(true);
20424 jghali 73
        else
74
        {
75
                PyErr_SetString(PyExc_ValueError, QObject::tr("hasdropcap has to be 0 or 1.","python error").toLocal8Bit().constData());
22606 craig 76
                return nullptr;
20424 jghali 77
        }
22942 jghali 78
        tmpParagraphStyle.setDropCapLines(dropCapLines);
79
        tmpParagraphStyle.setParEffectOffset(peOffset);
80
        tmpParagraphStyle.charStyle().setParent(charStyle);
20424 jghali 81
 
22942 jghali 82
        StyleSet<ParagraphStyle> tmpStyleSet;
83
        tmpStyleSet.create(tmpParagraphStyle);
84
        ScCore->primaryMainWindow()->doc->redefineStyles(tmpStyleSet, false);
20424 jghali 85
        // PV - refresh the Style Manager window.
86
        // I thought that this can work but it doesn't:
87
        // ScCore->primaryMainWindow()->styleMgr()->reloadStyleView();
88
        // So the brute force setDoc is called...
89
        ScCore->primaryMainWindow()->styleMgr()->setDoc(ScCore->primaryMainWindow()->doc);
90
 
91
        Py_RETURN_NONE;
92
}
93
 
94
/*! 03.01.2007 - 05.01.2007 : Joachim Neu : Create a char style.
95
                        Special thanks go to avox for helping me! */
96
PyObject *scribus_createcharstyle(PyObject* /* self */, PyObject* args, PyObject* keywords)
97
{
98
        char* keywordargs[] = {
22832 craig 99
                const_cast<char*>("name"),
100
                const_cast<char*>("font"),
101
                const_cast<char*>("fontsize"),
102
                const_cast<char*>("features"),
103
                const_cast<char*>("fillcolor"),
104
                const_cast<char*>("fillshade"),
105
                const_cast<char*>("strokecolor"),
106
                const_cast<char*>("strokeshade"),
107
                const_cast<char*>("baselineoffset"),
108
                const_cast<char*>("shadowxoffset"),
109
                const_cast<char*>("shadowyoffset"),
110
                const_cast<char*>("outlinewidth"),
111
                const_cast<char*>("underlineoffset"),
112
                const_cast<char*>("underlinewidth"),
113
                const_cast<char*>("strikethruoffset"),
114
                const_cast<char*>("strikethruwidth"),
115
                const_cast<char*>("scaleh"),
116
                const_cast<char*>("scalev"),
117
                const_cast<char*>("tracking"),
118
                const_cast<char*>("language"),
22945 jghali 119
                const_cast<char*>("fontfeatures"),
22832 craig 120
                nullptr};
22940 jghali 121
 
122
        if (!checkHaveDocument())
123
                return nullptr;
124
 
22969 jghali 125
        const double dbl_min = -std::numeric_limits<double>::max();
126
 
22940 jghali 127
        ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
128
        const StyleSet<CharStyle>& charStyles = ScCore->primaryMainWindow()->doc->charStyles();
129
        const CharStyle* defaultStyle = charStyles.getDefault();
130
 
22969 jghali 131
        char *name = const_cast<char*>(""), *font = const_cast<char*>(""), *features = const_cast<char*>("inherit"), *fillColor = const_cast<char*>(""), *fontFeatures = const_cast<char*>(""), *strokeColor = const_cast<char*>("Black"), *language = const_cast<char*>("");
132
        double fontSize = -1;
133
        double fillShade = -1, strokeShade = -1;
134
        double scaleH = -1, scaleV = -1;
135
        double baselineOffset = dbl_min;
136
        double shadowXOffset  = dbl_min, shadowYOffset = dbl_min;
137
        double outlineWidth = dbl_min, underlineOffset = dbl_min, underlineWidth = dbl_min;
138
        double strikethruOffset = dbl_min, strikethruWidth = dbl_min;
139
        double tracking = dbl_min;
140
 
20424 jghali 141
        if (!PyArg_ParseTupleAndKeywords(args, keywords, "es|esdesesdesddddddddddddes", keywordargs,
22941 jghali 142
                                                                        "utf-8", &name, "utf-8", &font, &fontSize, "utf-8", &features,
143
                                                                        "utf-8", &fillColor, &fillShade, "utf-8", &strokeColor, &strokeShade, &baselineOffset, &shadowXOffset,
144
                                                                        &shadowYOffset, &outlineWidth, &underlineOffset, &underlineWidth, &strikethruOffset, &strikethruWidth,
145
                                                                        &scaleH, &scaleV, &tracking, "utf-8", &language))
22606 craig 146
                return nullptr;
22940 jghali 147
 
22941 jghali 148
        if (strlen(name) == 0)
20424 jghali 149
        {
150
                PyErr_SetString(PyExc_ValueError, QObject::tr("Cannot have an empty char style name.","python error").toLocal8Bit().constData());
22606 craig 151
                return nullptr;
20424 jghali 152
        }
153
 
22941 jghali 154
        QString realFont = QString(font);
22969 jghali 155
        if (!realFont.isEmpty())
22924 jghali 156
        {
22969 jghali 157
                if (!currentDoc->AllFonts->contains(realFont))
158
                {
159
                        PyErr_SetString(PyExc_ValueError, QObject::tr("Specified font is not available.", "python error").toLocal8Bit().constData());
160
                        return nullptr;
161
                }
22924 jghali 162
        }
163
 
22940 jghali 164
        const ColorList& docColors = currentDoc->PageColors;
22941 jghali 165
        QString qFillColor = QString(fillColor);
166
        QString qStrokeColor = QString(strokeColor);
22969 jghali 167
        if (!qFillColor.isEmpty())
22925 jghali 168
        {
22969 jghali 169
                if ((qFillColor != CommonStrings::None) && (!docColors.contains(qFillColor)))
170
                {
171
                        PyErr_SetString(PyExc_ValueError, QObject::tr("Specified fill color is not available in document.", "python error").toLocal8Bit().constData());
172
                        return nullptr;
173
                }
22925 jghali 174
        }
22969 jghali 175
        if (!qStrokeColor.isEmpty())
22925 jghali 176
        {
22969 jghali 177
                if ((qStrokeColor != CommonStrings::None) && (!docColors.contains(qStrokeColor)))
178
                {
179
                        PyErr_SetString(PyExc_ValueError, QObject::tr("Specified stroke color is not available in document.", "python error").toLocal8Bit().constData());
180
                        return nullptr;
181
                }
22925 jghali 182
        }
183
 
22969 jghali 184
        if (fillShade >= 0)
185
                fillShade = qMax(0.0, qMin(fillShade, 1.0));
186
        if (strokeShade >= 0)
187
                strokeShade = qMax(0.0, qMin(strokeShade, 1.0));
22947 jghali 188
        QStringList featuresList = QString(features).split(',', QString::SkipEmptyParts);
22969 jghali 189
        QString qLanguage = QString(language);
20424 jghali 190
 
22941 jghali 191
        CharStyle tmpCharStyle;
192
        tmpCharStyle.setName(name);
22969 jghali 193
        if (!realFont.isEmpty())
194
                tmpCharStyle.setFont((*currentDoc->AllFonts)[realFont]);
195
        if (fontSize > 0)
196
                tmpCharStyle.setFontSize(fontSize * 10);
197
        if (fontFeatures != defaultStyle->fontFeatures())
198
                tmpCharStyle.setFontFeatures(fontFeatures);
199
        if (featuresList != defaultStyle->features())
200
                tmpCharStyle.setFeatures(featuresList);
201
        if (!qFillColor.isEmpty())
202
                tmpCharStyle.setFillColor(qFillColor);
203
        if (fillShade >= 0)
204
                tmpCharStyle.setFillShade(fillShade * 100);
205
        if (!qStrokeColor.isEmpty())
206
                tmpCharStyle.setStrokeColor(qStrokeColor);
207
        if (strokeShade >= 0)
208
                tmpCharStyle.setStrokeShade(strokeShade * 100);
209
        if (baselineOffset >= 0)
210
                tmpCharStyle.setBaselineOffset(baselineOffset);
211
        if (shadowXOffset != dbl_min)
212
                tmpCharStyle.setShadowXOffset(shadowXOffset);
213
        if (shadowYOffset != dbl_min)
214
                tmpCharStyle.setShadowYOffset(shadowYOffset);
215
        if (outlineWidth >= 0)
216
                tmpCharStyle.setOutlineWidth(outlineWidth);
217
        if (underlineOffset >= 0)
218
                tmpCharStyle.setUnderlineOffset(underlineOffset);
219
        if (underlineWidth >= 0)
220
                tmpCharStyle.setUnderlineWidth(underlineWidth);
221
        if (strikethruOffset >= 0)
222
                tmpCharStyle.setStrikethruOffset(strikethruOffset);
223
        if (strikethruWidth >= 0)
224
                tmpCharStyle.setStrikethruWidth(strikethruWidth);
225
        if (scaleH > 0)
226
                tmpCharStyle.setScaleH(scaleH * 1000);
227
        if (scaleV > 0)
228
                tmpCharStyle.setScaleV(scaleV * 1000);
229
        if (tracking != dbl_min)
230
                tmpCharStyle.setTracking(tracking);
231
        if (!qLanguage.isEmpty())
232
                tmpCharStyle.setLanguage(qLanguage);
20424 jghali 233
 
22941 jghali 234
        StyleSet<CharStyle> tmpStyleSet;
235
        tmpStyleSet.create(tmpCharStyle);
236
        currentDoc->redefineCharStyles(tmpStyleSet, false);
20424 jghali 237
        // PV - refresh the Style Manager window.
238
        // I thought that this can work but it doesn't:
239
        // ScCore->primaryMainWindow()->styleMgr()->reloadStyleView();
240
        // So the brute force setDoc is called...
241
        ScCore->primaryMainWindow()->styleMgr()->setDoc(ScCore->primaryMainWindow()->doc);
242
 
243
        Py_RETURN_NONE;
244
}
245
 
22205 jghali 246
PyObject *scribus_createcustomlinestyle(PyObject * /* self */, PyObject* args)
247
{
248
        char *Name = const_cast<char*>("");
249
        PyObject *obj;
250
 
251
        if (!PyArg_ParseTuple(args, "esO", "utf-8", &Name, &obj))
22606 craig 252
                return nullptr;
22205 jghali 253
 
254
        if (!PyList_Check(obj)) {
255
                PyErr_SetString(PyExc_TypeError, "'style' must be list.");
22606 craig 256
                return nullptr;
22205 jghali 257
        }
258
 
22943 jghali 259
        if (!checkHaveDocument())
260
                return nullptr;
261
        ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
262
 
22205 jghali 263
        multiLine ml;
22943 jghali 264
        const ColorList& docColors = currentDoc->PageColors;
22926 jghali 265
 
266
        for (int i = 0; i < PyList_Size(obj); i++)
267
        {
22205 jghali 268
                PyObject *line = PyList_GetItem(obj, i);
22926 jghali 269
                if (!PyDict_Check(line))
270
                {
22205 jghali 271
                        PyErr_SetString(PyExc_TypeError, "elements of list must be Dictionary.");
22606 craig 272
                        return nullptr;
22205 jghali 273
                }
274
                struct SingleLine sl;
275
                PyObject *val;
22926 jghali 276
 
22205 jghali 277
                val = PyDict_GetItemString(line, "Color");
22926 jghali 278
                if (val)
22205 jghali 279
                        sl.Color = PyString_AsString(val);
22926 jghali 280
                else
22943 jghali 281
                        sl.Color = currentDoc->itemToolPrefs().lineColor;
22926 jghali 282
 
22205 jghali 283
                val = PyDict_GetItemString(line, "Dash");
22926 jghali 284
                if (val)
22205 jghali 285
                        sl.Dash = PyInt_AsLong(val);
22926 jghali 286
                else
22205 jghali 287
                        sl.Dash = Qt::SolidLine;
22926 jghali 288
 
22205 jghali 289
                val = PyDict_GetItemString(line, "LineEnd");
22926 jghali 290
                if (val)
22205 jghali 291
                        sl.LineEnd = PyInt_AsLong(val);
22926 jghali 292
                else
22205 jghali 293
                        sl.LineEnd = Qt::FlatCap;
22926 jghali 294
 
22205 jghali 295
                val = PyDict_GetItemString(line, "LineJoin");
22926 jghali 296
                if (val)
22205 jghali 297
                        sl.LineJoin = PyInt_AsLong(val);
22926 jghali 298
                else
22205 jghali 299
                        sl.LineJoin = Qt::MiterJoin;
22926 jghali 300
 
22205 jghali 301
                val = PyDict_GetItemString(line, "Shade");
22926 jghali 302
                if (val)
22205 jghali 303
                        sl.Shade = PyInt_AsLong(val);
22926 jghali 304
                else
22943 jghali 305
                        sl.Shade = currentDoc->itemToolPrefs().lineColorShade;
22926 jghali 306
 
22205 jghali 307
                val = PyDict_GetItemString(line, "Width");
22926 jghali 308
                if (val)
22205 jghali 309
                        sl.Width = PyFloat_AsDouble(val);
22926 jghali 310
                else
22943 jghali 311
                        sl.Width = currentDoc->itemToolPrefs().lineWidth;
22205 jghali 312
 
313
                val = PyDict_GetItemString(line, "Shortcut");
22926 jghali 314
                if (val)
22205 jghali 315
                        ml.shortcut = PyString_AsString(val);
22926 jghali 316
                else
22205 jghali 317
                        ml.shortcut = "";
22926 jghali 318
 
319
                if (!docColors.contains(sl.Color))
320
                {
321
                        PyErr_SetString(PyExc_ValueError, QObject::tr("Specified color is not available in document.", "python error").toLocal8Bit().constData());
322
                        return nullptr;
323
                }
22205 jghali 324
                ml.push_back(sl);
325
        }
22606 craig 326
        if (!ml.empty())
22943 jghali 327
                currentDoc->MLineStyles[Name] = ml;
22205 jghali 328
        Py_RETURN_NONE;
329
}
330
 
331
 
20424 jghali 332
/*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
333
with header files structure untouched (docstrings are kept near declarations)
334
PV */
335
void cmdstyledocwarnings()
336
{
337
        QStringList s;
338
        s << scribus_createparagraphstyle__doc__ << scribus_createcharstyle__doc__;
22205 jghali 339
        s << scribus_createcustomlinestyle__doc__;
20424 jghali 340
}