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 */
7 #include "cmdsetprop.h"
8 #include "cmdutil.h"
9 #include "scribuscore.h"
10 #include "scribusdoc.h"
11 
scribus_setgradfill(PyObject *,PyObject * args)12 PyObject *scribus_setgradfill(PyObject* /* self */, PyObject* args)
13 {
14 	char *Name = const_cast<char*>("");
15 	char *Color1;
16 	char *Color2;
17 	int typ, shade1, shade2;
18 	if (!PyArg_ParseTuple(args, "iesiesi|es", &typ, "utf-8", &Color1, &shade1, "utf-8", &Color2, &shade2, "utf-8", &Name))
19 		return nullptr;
20 	if (!checkHaveDocument())
21 		return nullptr;
22 	if ((shade1 < 0) || (shade1 > 100) || (shade2 < 0) || (shade2 > 100))
23 	{
24 		PyErr_SetString(PyExc_ValueError, QObject::tr("Stop shade out of bounds, must be 0 <= shade <= 100.","python error").toLocal8Bit().constData());
25 		return nullptr;
26 	}
27 	PageItem *currItem = GetUniqueItem(QString::fromUtf8(Name));
28 	if (currItem == nullptr)
29 		return nullptr;
30 	QColor tmp;
31 	currItem->fill_gradient.clearStops();
32 	QString c1 = QString::fromUtf8(Color1);
33 	QString c2 = QString::fromUtf8(Color2);
34 	currItem->SetQColor(&tmp, c1, shade1);
35 	currItem->fill_gradient.addStop(tmp, 0.0, 0.5, 1.0, c1, shade1);
36 	currItem->SetQColor(&tmp, c2, shade2);
37 	currItem->fill_gradient.addStop(tmp, 1.0, 0.5, 1.0, c2, shade2);
38 	currItem->GrType = typ;
39 	switch (currItem->GrType)
40 	{
41 		case 0:
42 		case 1:
43 			currItem->GrStartX = 0;
44 			currItem->GrStartY = currItem->height() / 2.0;
45 			currItem->GrEndX = currItem->width();
46 			currItem->GrEndY = currItem->height() / 2.0;
47 			break;
48 		case 2:
49 			currItem->GrStartX = currItem->width() / 2.0;
50 			currItem->GrStartY = 0;
51 			currItem->GrEndX = currItem->width() / 2.0;
52 			currItem->GrEndY = currItem->height();
53 			break;
54 		case 3:
55 			currItem->GrStartX = 0;
56 			currItem->GrStartY = 0;
57 			currItem->GrEndX = currItem->width();
58 			currItem->GrEndY = currItem->height();
59 			break;
60 		case 4:
61 			currItem->GrStartX = 0;
62 			currItem->GrStartY = currItem->height();
63 			currItem->GrEndX = currItem->width();
64 			currItem->GrEndY = 0;
65 			break;
66 		case 5:
67 			currItem->GrStartX = currItem->width() / 2.0;
68 			currItem->GrStartY = currItem->height() / 2.0;
69 			if (currItem->width() >= currItem->height())
70 			{
71 				currItem->GrEndX = currItem->width();
72 				currItem->GrEndY = currItem->height() / 2.0;
73 			}
74 			else
75 			{
76 				currItem->GrEndX = currItem->width() / 2.0;
77 				currItem->GrEndY = currItem->height();
78 			}
79 			break;
80 		default:
81 			break;
82 	}
83 	//ScCore->primaryMainWindow()->view->updateGradientVectors(currItem);
84 	currItem->updateGradientVectors();
85 	currItem->update();
86 	Py_RETURN_NONE;
87 }
88 
scribus_setgradstop(PyObject *,PyObject * args)89 PyObject *scribus_setgradstop(PyObject* /* self */, PyObject* args)
90 {
91 	char *Name = const_cast<char*>("");
92 	char *Color1;
93 	int  shade1;
94 	double rampPoint, opacity;
95 	if (!PyArg_ParseTuple(args, "esidd|es", "utf-8", &Color1, &shade1, &opacity, &rampPoint, "utf-8", &Name))
96 		return nullptr;
97 	if (!checkHaveDocument())
98 		return nullptr;
99 	if ((shade1 < 0) || (shade1 > 100))
100 	{
101 		PyErr_SetString(PyExc_ValueError, QObject::tr("Stop shade out of bounds, must be 0 <= shade <= 100.","python error").toLocal8Bit().constData());
102 		return nullptr;
103 	}
104 	if ((rampPoint < 0.0) || (rampPoint > 1.0))
105 	{
106 		PyErr_SetString(PyExc_ValueError, QObject::tr("Ramp point out of bounds, must be 0 <= rampPoint <= 1.","python error").toLocal8Bit().constData());
107 		return nullptr;
108 	}
109 	if ((opacity < 0.0) || (opacity > 1.0))
110 	{
111 		PyErr_SetString(PyExc_ValueError, QObject::tr("Opacity out of bounds, must be 0 <= transparency <= 1.","python error").toLocal8Bit().constData());
112 		return nullptr;
113 	}
114 	PageItem *currItem = GetUniqueItem(QString::fromUtf8(Name));
115 	if (currItem == nullptr)
116 		return nullptr;
117 	QColor tmp;
118 	QString c1 = QString::fromUtf8(Color1);
119 	currItem->SetQColor(&tmp, c1, shade1);
120 	currItem->fill_gradient.setStop(tmp, rampPoint, 0.5, opacity, c1, shade1);
121 	currItem->updateGradientVectors();
122 	currItem->update();
123 	Py_RETURN_NONE;
124 }
125 
scribus_setfillcolor(PyObject *,PyObject * args)126 PyObject *scribus_setfillcolor(PyObject* /* self */, PyObject* args)
127 {
128 	char *Name = const_cast<char*>("");
129 	char *Color;
130 	if (!PyArg_ParseTuple(args, "es|es", "utf-8", &Color, "utf-8", &Name))
131 		return nullptr;
132 	if (!checkHaveDocument())
133 		return nullptr;
134 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
135 	if (i == nullptr)
136 		return nullptr;
137 	i->setFillColor(QString::fromUtf8(Color));
138 	Py_RETURN_NONE;
139 }
140 
scribus_setfilltrans(PyObject *,PyObject * args)141 PyObject *scribus_setfilltrans(PyObject* /* self */, PyObject* args)
142 {
143 	char *Name = const_cast<char*>("");
144 	double w;
145 	if (!PyArg_ParseTuple(args, "d|es", &w, "utf-8", &Name))
146 		return nullptr;
147 	if (!checkHaveDocument())
148 		return nullptr;
149 	if ((w < 0.0) || (w > 1.0))
150 	{
151 		PyErr_SetString(PyExc_ValueError, QObject::tr("Transparency out of bounds, must be 0 <= transparency <= 1.","python error").toLocal8Bit().constData());
152 		return nullptr;
153 	}
154 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
155 	if (i == nullptr)
156 		return nullptr;
157 	i->setFillTransparency(1.0 - w);
158 	Py_RETURN_NONE;
159 }
160 
scribus_setfillblend(PyObject *,PyObject * args)161 PyObject *scribus_setfillblend(PyObject* /* self */, PyObject* args)
162 {
163 	char *Name = const_cast<char*>("");
164 	int w;
165 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
166 		return nullptr;
167 	if (!checkHaveDocument())
168 		return nullptr;
169 	if ((w < 0) || (w > 15))
170 	{
171 		PyErr_SetString(PyExc_ValueError, QObject::tr("Blendmode out of bounds, must be 0 <= blendmode <= 15.","python error").toLocal8Bit().constData());
172 		return nullptr;
173 	}
174 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
175 	if (i == nullptr)
176 		return nullptr;
177 	i->setFillBlendmode(w);
178 	Py_RETURN_NONE;
179 }
180 
scribus_setcustomlinestyle(PyObject *,PyObject * args)181 PyObject *scribus_setcustomlinestyle(PyObject* /* self */, PyObject* args)
182 {
183 	char *Name = const_cast<char*>("");
184 	char *Style;
185 	if (!PyArg_ParseTuple(args, "es|es", "utf-8", &Style, "utf-8", &Name))
186 		return nullptr;
187 	if (!checkHaveDocument())
188 		return nullptr;
189 	PageItem *it = GetUniqueItem(QString::fromUtf8(Name));
190 	if (it == nullptr)
191 		return nullptr;
192 	QString qStyle = QString::fromUtf8(Style);
193 	if (! ScCore->primaryMainWindow()->doc->docLineStyles.contains(qStyle))
194 	{
195 		PyErr_SetString(NotFoundError, QObject::tr("Line Style not found.","python error").toLocal8Bit().constData());
196 		return nullptr;
197 
198 	}
199 	it->setCustomLineStyle(qStyle);
200 	Py_RETURN_NONE;
201 }
202 
scribus_setlinecolor(PyObject *,PyObject * args)203 PyObject *scribus_setlinecolor(PyObject* /* self */, PyObject* args)
204 {
205 	char *Name = const_cast<char*>("");
206 	char *Color;
207 	if (!PyArg_ParseTuple(args, "es|es", "utf-8", &Color, "utf-8", &Name))
208 		return nullptr;
209 	if (!checkHaveDocument())
210 		return nullptr;
211 	PageItem *it = GetUniqueItem(QString::fromUtf8(Name));
212 	if (it == nullptr)
213 		return nullptr;
214 	it->setLineColor(QString::fromUtf8(Color));
215 	Py_RETURN_NONE;
216 }
217 
scribus_setlinetrans(PyObject *,PyObject * args)218 PyObject *scribus_setlinetrans(PyObject* /* self */, PyObject* args)
219 {
220 	char *Name = const_cast<char*>("");
221 	double w;
222 	if (!PyArg_ParseTuple(args, "d|es", &w, "utf-8", &Name))
223 		return nullptr;
224 	if (!checkHaveDocument())
225 		return nullptr;
226 	if ((w < 0.0) || (w > 1.0))
227 	{
228 		PyErr_SetString(PyExc_ValueError, QObject::tr("Transparency out of bounds, must be 0 <= transparency <= 1.","python error").toLocal8Bit().constData());
229 		return nullptr;
230 	}
231 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
232 	if (i == nullptr)
233 		return nullptr;
234 	i->setLineTransparency(1.0 - w);
235 	Py_RETURN_NONE;
236 }
237 
scribus_setlineblend(PyObject *,PyObject * args)238 PyObject *scribus_setlineblend(PyObject* /* self */, PyObject* args)
239 {
240 	char *Name = const_cast<char*>("");
241 	int w;
242 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
243 		return nullptr;
244 	if (!checkHaveDocument())
245 		return nullptr;
246 	if ((w < 0) || (w > 15))
247 	{
248 		PyErr_SetString(PyExc_ValueError, QObject::tr("Blendmode out of bounds, must be 0 <= blendmode <= 15.","python error").toLocal8Bit().constData());
249 		return nullptr;
250 	}
251 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
252 	if (i == nullptr)
253 		return nullptr;
254 	i->setLineBlendmode(w);
255 	Py_RETURN_NONE;
256 }
257 
scribus_setlinewidth(PyObject *,PyObject * args)258 PyObject *scribus_setlinewidth(PyObject* /* self */, PyObject* args)
259 {
260 	char *Name = const_cast<char*>("");
261 	double w;
262 	if (!PyArg_ParseTuple(args, "d|es", &w, "utf-8", &Name))
263 		return nullptr;
264 	if (!checkHaveDocument())
265 		return nullptr;
266 	if ((w < 0.0) || (w > 300.0))
267 	{
268 		PyErr_SetString(PyExc_ValueError, QObject::tr("Line width out of bounds, must be 0 <= line_width <= 300.","python error").toLocal8Bit().constData());
269 		return nullptr;
270 	}
271 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
272 	if (i == nullptr)
273 		return nullptr;
274 	i->setLineWidth(w);
275 	Py_RETURN_NONE;
276 }
277 
scribus_setlineshade(PyObject *,PyObject * args)278 PyObject *scribus_setlineshade(PyObject* /* self */, PyObject* args)
279 {
280 	char *Name = const_cast<char*>("");
281 	int w;
282 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
283 		return nullptr;
284 	if (!checkHaveDocument())
285 		return nullptr;
286 	if ((w < 0) || (w > 100))
287 	{
288 		PyErr_SetString(PyExc_ValueError, QObject::tr("Line shade out of bounds, must be 0 <= shade <= 100.","python error").toLocal8Bit().constData());
289 		return nullptr;
290 	}
291 	PageItem *it = GetUniqueItem(QString::fromUtf8(Name));
292 	if (it == nullptr)
293 		return nullptr;
294 	it->setLineShade(w);
295 	Py_RETURN_NONE;
296 }
297 
scribus_setfillshade(PyObject *,PyObject * args)298 PyObject *scribus_setfillshade(PyObject* /* self */, PyObject* args)
299 {
300 	char *Name = const_cast<char*>("");
301 	int w;
302 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
303 		return nullptr;
304 	if (!checkHaveDocument())
305 		return nullptr;
306 	if ((w < 0) || (w > 100))
307 	{
308 		PyErr_SetString(PyExc_ValueError, QObject::tr("Fill shade out of bounds, must be 0 <= shade <= 100.","python error").toLocal8Bit().constData());
309 		return nullptr;
310 	}
311 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
312 	if (i == nullptr)
313 		return nullptr;
314 	i->setFillShade(w);
315 	Py_RETURN_NONE;
316 }
317 
scribus_setlinejoin(PyObject *,PyObject * args)318 PyObject *scribus_setlinejoin(PyObject* /* self */, PyObject* args)
319 {
320 	char *Name = const_cast<char*>("");
321 	int w;
322 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
323 		return nullptr;
324 	if (!checkHaveDocument())
325 		return nullptr;
326 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
327 	if (i == nullptr)
328 		return nullptr;
329 	i->PLineJoin = Qt::PenJoinStyle(w);
330 	Py_RETURN_NONE;
331 }
332 
scribus_setlinecap(PyObject *,PyObject * args)333 PyObject *scribus_setlinecap(PyObject* /* self */, PyObject* args)
334 {
335 	char *Name = const_cast<char*>("");
336 	int w;
337 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
338 		return nullptr;
339 	if (!checkHaveDocument())
340 		return nullptr;
341 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
342 	if (i == nullptr)
343 		return nullptr;
344 	i->PLineEnd = Qt::PenCapStyle(w);
345 	Py_RETURN_NONE;
346 }
347 
scribus_setlinestyle(PyObject *,PyObject * args)348 PyObject *scribus_setlinestyle(PyObject* /* self */, PyObject* args)
349 {
350 	char *Name = const_cast<char*>("");
351 	int w;
352 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
353 		return nullptr;
354 	if (!checkHaveDocument())
355 		return nullptr;
356 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
357 	if (i == nullptr)
358 		return nullptr;
359 	i->PLineArt = Qt::PenStyle(w);
360 	Py_RETURN_NONE;
361 }
362 
scribus_setcornerradius(PyObject *,PyObject * args)363 PyObject *scribus_setcornerradius(PyObject* /* self */, PyObject* args)
364 {
365 	char *Name = const_cast<char*>("");
366 	int w;
367 	if (!PyArg_ParseTuple(args, "i|es", &w, "utf-8", &Name))
368 		return nullptr;
369 	if (!checkHaveDocument())
370 		return nullptr;
371 	if (w < 0)
372 	{
373 		PyErr_SetString(PyExc_ValueError, QObject::tr("Corner radius must be a positive number.","python error").toLocal8Bit().constData());
374 		return nullptr;
375 	}
376 	PageItem *currItem = GetUniqueItem(QString::fromUtf8(Name));
377 	if (currItem == nullptr)
378 		return nullptr;
379 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
380 	// apply rounding
381 	currItem->setCornerRadius(w);
382 	currItem->SetFrameRound();
383 	currentDoc->setRedrawBounding(currItem);
384 	currentDoc->setFrameRounded();
385 	Py_RETURN_NONE;
386 }
387 
scribus_setmultiline(PyObject *,PyObject * args)388 PyObject *scribus_setmultiline(PyObject* /* self */, PyObject* args)
389 {
390 	char *Name = const_cast<char*>("");
391 	char *Style = nullptr;
392 	if (!PyArg_ParseTuple(args, "es|es", "utf-8", &Style, "utf-8", &Name))
393 		return nullptr;
394 	if (!checkHaveDocument())
395 		return nullptr;
396 	PageItem *currItem = GetUniqueItem(QString::fromUtf8(Name));
397 	if (currItem == nullptr)
398 		return nullptr;
399 	if (!ScCore->primaryMainWindow()->doc->docLineStyles.contains(QString::fromUtf8(Style)))
400 	{
401 		PyErr_SetString(NotFoundError, QObject::tr("Line style not found.","python error").toLocal8Bit().constData());
402 		return nullptr;
403 	}
404 	currItem->NamedLStyle = QString::fromUtf8(Style);
405 	Py_RETURN_NONE;
406 }
407 
scribus_setitemname(PyObject *,PyObject * args)408 PyObject *scribus_setitemname(PyObject* /* self */, PyObject* args)
409 {
410 	char *Name = const_cast<char*>("");
411 	char *newName = const_cast<char*>("");
412 	if (!PyArg_ParseTuple(args, "es|es", "utf-8", &newName, "utf-8", &Name))
413 		return nullptr;
414 	if (!checkHaveDocument())
415 		return nullptr;
416 
417 	PageItem *currItem = GetUniqueItem(QString::fromUtf8(Name));
418 	if (currItem == nullptr)
419 		return nullptr;
420 	currItem->setItemName(newName);
421 
422 	return PyString_FromString(currItem->itemName().toUtf8());
423 }
424 
scribus_setobjectattributes(PyObject *,PyObject * args)425 PyObject *scribus_setobjectattributes(PyObject* /* self */, PyObject* args)
426 {
427 	if (!checkHaveDocument())
428 		return nullptr;
429 	char *Name = const_cast<char*>("");
430 	PyObject *attr;
431 	if (!PyArg_ParseTuple(args, "O|es", &attr, "utf-8", &Name))
432 		return nullptr;
433 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
434 	if (item == nullptr)
435 		return nullptr;
436 
437 	if (!PyList_Check(attr))
438 	{
439 		PyErr_SetString(PyExc_TypeError, "argument must be list.");
440 		return nullptr;
441 	}
442 
443 	ObjAttrVector attributes;
444 	int n = PyList_Size(attr);
445 	for (int i = 0; i < n; ++i)
446 	{
447 		PyObject *tmp = PyList_GetItem(attr, i);
448 		if (!PyDict_Check(tmp))
449 		{
450 			PyErr_SetString(PyExc_TypeError, "elements of 'attr' must be dictionary.");
451 			return nullptr;
452 		}
453 		ObjectAttribute blank;
454 		PyObject *val;
455 		char* data;
456 
457 		val = PyDict_GetItemString(tmp, "Name");
458 		if (!val)
459 		{
460 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Name' key.");
461 			return nullptr;
462 		}
463 		data = PyString_AsString(val);
464 		if (!data)
465 			return nullptr;
466 		blank.name = QString(data);
467 
468 		val = PyDict_GetItemString(tmp, "Type");
469 		if (!val)
470 		{
471 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Type' key.");
472 			return nullptr;
473 		}
474 		data = PyString_AsString(val);
475 		if (!data)
476 			return nullptr;
477 		blank.type = QString(data);
478 
479 		val = PyDict_GetItemString(tmp, "Value");
480 		if (!val)
481 		{
482 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Value' key.");
483 			return nullptr;
484 		}
485 		data = PyString_AsString(val);
486 		if (!data)
487 			return nullptr;
488 		blank.value = QString(data);
489 
490 		val = PyDict_GetItemString(tmp, "Parameter");
491 		if (!val)
492 		{
493 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Parameter' key.");
494 			return nullptr;
495 		}
496 		data = PyString_AsString(val);
497 		if (!data)
498 			return nullptr;
499 		blank.parameter = QString(data);
500 
501 		val = PyDict_GetItemString(tmp, "Relationship");
502 		if (!val)
503 		{
504 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Relationship' key.");
505 			return nullptr;
506 		}
507 		data = PyString_AsString(val);
508 		if (!data)
509 			return nullptr;
510 		blank.relationship = QString(data);
511 
512 		val = PyDict_GetItemString(tmp, "RelationshipTo");
513 		if (!val)
514 		{
515 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'RelationshipTo' key.");
516 			return nullptr;
517 		}
518 		data = PyString_AsString(val);
519 		if (!data)
520 			return nullptr;
521 		blank.relationshipto = QString(data);
522 
523 		val = PyDict_GetItemString(tmp, "AutoAddTo");
524 		if (!val)
525 		{
526 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'AutoAddTo' key.");
527 			return nullptr;
528 		}
529 		data = PyString_AsString(val);
530 		if (!data)
531 			return nullptr;
532 		blank.autoaddto = QString(data);
533 
534 		attributes.append(blank);
535 	}
536 
537 	item->setObjectAttributes(&attributes);
538 	Py_RETURN_NONE;
539 }
540 
541 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
542 with header files structure untouched (docstrings are kept near declarations)
543 PV */
cmdsetpropdocwarnings()544 void cmdsetpropdocwarnings()
545 {
546 	QStringList s;
547 	s << scribus_setcornerradius__doc__
548 	  << scribus_setcustomlinestyle__doc__
549 	  << scribus_setfillblend__doc__
550 	  << scribus_setfillcolor__doc__
551 	  << scribus_setfillshade__doc__
552 	  << scribus_setfilltrans__doc__
553 	  << scribus_setgradfill__doc__
554 	  << scribus_setgradstop__doc__
555 	  << scribus_setitemname__doc__
556 	  << scribus_setlineblend__doc__
557 	  << scribus_setlinecap__doc__
558 	  << scribus_setlinecolor__doc__
559 	  << scribus_setlinejoin__doc__
560 	  << scribus_setlineshade__doc__
561 	  << scribus_setlinestyle__doc__
562 	  << scribus_setlinetrans__doc__
563 	  << scribus_setlinewidth__doc__
564 	  << scribus_setmultiline__doc__
565 	  << scribus_setobjectattributes__doc__;
566 }
567