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 "cmddoc.h"
8 #include "cmdutil.h"
9 #include "units.h"
10 #include "documentinformation.h"
11 #include "scribuscore.h"
12 #include "scribusdoc.h"
13 #include "scribusview.h"
14 
15 #include <QApplication>
16 
17 /*
18 newDocument(size, margins, orientation, firstPageNumber,
19             unit, pagesType, firstPageOrder)*/
scribus_newdocument(PyObject *,PyObject * args)20 PyObject *scribus_newdocument(PyObject* /* self */, PyObject* args)
21 {
22 	double topMargin, bottomMargin, leftMargin, rightMargin;
23 	double pageWidth, pageHeight;
24 //	int orientation, firstPageNr, unit, pagesType, facingPages, firstPageOrder, numPages;
25 	int orientation, firstPageNr, unit, pagesType, firstPageOrder, numPages;
26 
27 	PyObject *p, *m;
28 
29 	if ((!PyArg_ParseTuple(args, "OOiiiiii", &p, &m, &orientation,
30 											&firstPageNr, &unit,
31 											&pagesType,
32 											&firstPageOrder,
33 											&numPages)) ||
34 						(!PyArg_ParseTuple(p, "dd", &pageWidth, &pageHeight)) ||
35 						(!PyArg_ParseTuple(m, "dddd", &leftMargin, &rightMargin,
36 												&topMargin, &bottomMargin)))
37 		return nullptr;
38 	if (numPages <= 0)
39 		numPages = 1;
40 	if (pagesType == 0)
41 	{
42 	//	facingPages = 0;
43 		firstPageOrder = 0;
44 	}
45 //	else
46 //		facingPages = 1;
47 	// checking the bounds
48 	if (pagesType < firstPageOrder)
49 	{
50 		PyErr_SetString(ScribusException, QObject::tr("firstPageOrder is bigger than allowed.","python error").toLocal8Bit().constData());
51 		return nullptr;
52 	}
53 
54 
55 	pageWidth  = value2pts(pageWidth, unit);
56 	pageHeight = value2pts(pageHeight, unit);
57 	if (orientation == 1)
58 	{
59 		double x = pageWidth;
60 		pageWidth = pageHeight;
61 		pageHeight = x;
62 	}
63 	leftMargin   = value2pts(leftMargin, unit);
64 	rightMargin  = value2pts(rightMargin, unit);
65 	topMargin    = value2pts(topMargin, unit);
66 	bottomMargin = value2pts(bottomMargin, unit);
67 
68 	bool ret = ScCore->primaryMainWindow()->doFileNew(pageWidth, pageHeight,
69 								topMargin, leftMargin, rightMargin, bottomMargin,
70 								// autoframes. It's disabled in python
71 								// columnDistance, numberCols, autoframes,
72 								0, 1, false,
73 								pagesType, unit, firstPageOrder,
74 								orientation, firstPageNr, "Custom", true, numPages);
75 	ScCore->primaryMainWindow()->doc->setPageSetFirstPage(pagesType, firstPageOrder);
76 
77 	return PyLong_FromLong(static_cast<long>(ret));
78 }
79 
scribus_newdoc(PyObject *,PyObject * args)80 PyObject *scribus_newdoc(PyObject* /* self */, PyObject* args)
81 {
82 	qDebug("WARNING: newDoc() procedure is obsolete, it will be removed in a forthcoming release. Use newDocument() instead.");
83 	double b, h, lr, tpr, btr, rr, ebr;
84 	int unit, ds, fsl, fNr, ori;
85 	PyObject *p, *m;
86 	if ((!PyArg_ParseTuple(args, "OOiiiii", &p, &m, &ori, &fNr, &unit, &ds, &fsl)) ||
87 	        (!PyArg_ParseTuple(p, "dd", &b, &h)) ||
88 	        (!PyArg_ParseTuple(m, "dddd", &lr, &rr, &tpr, &btr)))
89 		return nullptr;
90 	b = value2pts(b, unit);
91 	h = value2pts(h, unit);
92 	if (ori == 1)
93 	{
94 		ebr = b;
95 		b = h;
96 		h = ebr;
97 	}
98 	/*! \todo Obsolete! In the case of no facing pages use only firstpageleft
99 	scripter is not new-page-size ready.
100 	What is it: don't allow to use wrong FSL constant in the case of
101 	onesided document. */
102 	if (ds!=1 && fsl>0)
103 		fsl = 0;
104 	// end of hack
105 
106 	tpr = value2pts(tpr, unit);
107 	lr  = value2pts(lr, unit);
108 	rr  = value2pts(rr, unit);
109 	btr = value2pts(btr, unit);
110 	bool ret = ScCore->primaryMainWindow()->doFileNew(b, h, tpr, lr, rr, btr, 0, 1, false, ds, unit, fsl, ori, fNr, "Custom", true);
111 	//	qApp->processEvents();
112 	return PyLong_FromLong(static_cast<long>(ret));
113 }
114 
scribus_setbleeds(PyObject *,PyObject * args)115 PyObject *scribus_setbleeds(PyObject */* self */, PyObject *args)
116 {
117 	double lr, tpr, btr, rr;
118 	if (!PyArg_ParseTuple(args, "dddd", &lr, &rr, &tpr, &btr))
119 		return nullptr;
120 	if (!checkHaveDocument())
121 		return nullptr;
122 	MarginStruct bleeds(ValueToPoint(tpr), ValueToPoint(lr), ValueToPoint(btr), ValueToPoint(rr));
123 
124 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
125 	ScribusView* currentView = ScCore->primaryMainWindow()->view;
126 	currentDoc->setBleeds(bleeds);
127 	currentView->reformPages();
128 	currentDoc->setModified(true);
129 	currentView->DrawNew();
130 	Py_RETURN_NONE;
131 }
132 
scribus_setmargins(PyObject *,PyObject * args)133 PyObject *scribus_setmargins(PyObject* /* self */, PyObject* args)
134 {
135 	double lr, tpr, btr, rr;
136 	if (!PyArg_ParseTuple(args, "dddd", &lr, &rr, &tpr, &btr))
137 		return nullptr;
138 	if (!checkHaveDocument())
139 		return nullptr;
140 	MarginStruct margins(ValueToPoint(tpr), ValueToPoint(lr), ValueToPoint(btr), ValueToPoint(rr));
141 
142 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
143 	ScribusView* currentView = ScCore->primaryMainWindow()->view;
144 	currentDoc->setMargins(margins);
145 	currentView->reformPages();
146 	currentDoc->setModified(true);
147 	currentView->GotoPage(currentDoc->currentPageNumber());
148 	currentView->DrawNew();
149 
150 	Py_RETURN_NONE;
151 }
152 
scribus_setbaseline(PyObject *,PyObject * args)153 PyObject *scribus_setbaseline(PyObject* /* self */, PyObject* args)
154 {
155 	double grid, offset;
156 	if (!PyArg_ParseTuple(args, "dd", &grid, &offset))
157 		return nullptr;
158 	if (!checkHaveDocument())
159 		return nullptr;
160 
161 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
162 	ScribusView* currentView = ScCore->primaryMainWindow()->view;
163 	currentDoc->guidesPrefs().valueBaselineGrid = ValueToPoint(grid);
164 	currentDoc->guidesPrefs().offsetBaselineGrid = ValueToPoint(offset);
165 	//currentView->reformPages();
166 	currentDoc->setModified(true);
167 	//currentView->GotoPage(currentDoc->currentPageNumber());
168 	currentView->DrawNew();
169 
170 	Py_RETURN_NONE;
171 }
172 
173 
scribus_closedoc(PyObject *)174 PyObject *scribus_closedoc(PyObject* /* self */)
175 {
176 	if (!checkHaveDocument())
177 		return nullptr;
178 	ScCore->primaryMainWindow()->doc->setModified(false);
179 	bool ret = ScCore->primaryMainWindow()->slotFileClose();
180 	qApp->processEvents();
181 	return PyLong_FromLong(static_cast<long>(ret));
182 }
183 
scribus_havedoc(PyObject *)184 PyObject *scribus_havedoc(PyObject* /* self */)
185 {
186 	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->HaveDoc));
187 }
188 
scribus_opendoc(PyObject *,PyObject * args)189 PyObject *scribus_opendoc(PyObject* /* self */, PyObject* args)
190 {
191 	char *Name;
192 	if (!PyArg_ParseTuple(args, "es", "utf-8", &Name))
193 		return nullptr;
194 	bool ret = ScCore->primaryMainWindow()->loadDoc(QString::fromUtf8(Name));
195 	if (!ret)
196 	{
197 		PyErr_SetString(ScribusException, QObject::tr("Failed to open document: %1","python error").arg(Name).toLocal8Bit().constData());
198 		return nullptr;
199 	}
200 	return PyBool_FromLong(static_cast<long>(true));
201 //	Py_INCREF(Py_True); // compatibility: return true, not none, on success
202 //	return Py_True;
203 //	Py_RETURN_TRUE;
204 }
205 
scribus_savedoc(PyObject *)206 PyObject *scribus_savedoc(PyObject* /* self */)
207 {
208 	if (!checkHaveDocument())
209 		return nullptr;
210 	ScCore->primaryMainWindow()->slotFileSave();
211 	Py_RETURN_NONE;
212 }
213 
scribus_revertdoc(PyObject *)214 PyObject *scribus_revertdoc(PyObject* /* self */)
215 {
216 	if (!checkHaveDocument())
217 		return nullptr;
218 	ScCore->primaryMainWindow()->slotFileRevert();
219 	Py_RETURN_NONE;
220 }
221 
scribus_getdocname(PyObject *)222 PyObject *scribus_getdocname(PyObject* /* self */)
223 {
224 	if (!checkHaveDocument())
225 		return nullptr;
226 	if (! ScCore->primaryMainWindow()->doc->hasName)
227 	{
228 		return PyUnicode_FromString("");
229 	}
230 	return PyUnicode_FromString(ScCore->primaryMainWindow()->doc->documentFileName().toUtf8());
231 }
232 
scribus_savedocas(PyObject *,PyObject * args)233 PyObject *scribus_savedocas(PyObject* /* self */, PyObject* args)
234 {
235 	char *Name;
236 	if (!PyArg_ParseTuple(args, "es", "utf-8", &Name))
237 		return nullptr;
238 	if (!checkHaveDocument())
239 		return nullptr;
240 	bool ret = ScCore->primaryMainWindow()->DoFileSave(QString::fromUtf8(Name));
241 	if (!ret)
242 	{
243 		PyErr_SetString(ScribusException, QObject::tr("Failed to save document.","python error").toLocal8Bit().constData());
244 		return nullptr;
245 	}
246 	return PyBool_FromLong(static_cast<long>(true));
247 //	Py_INCREF(Py_True); // compatibility: return true, not none, on success
248 //	return Py_True;
249 //	Py_RETURN_TRUE;
250 }
251 
scribus_setinfo(PyObject *,PyObject * args)252 PyObject *scribus_setinfo(PyObject* /* self */, PyObject* args)
253 {
254 	char *Author;
255 	char *Title;
256 	char *Desc;
257 	// z means string, but None becomes a nullptr value. QString()
258 	// will correctly handle nullptr.
259 	if (!PyArg_ParseTuple(args, "zzz", &Author, &Title, &Desc))
260 		return nullptr;
261 	if (!checkHaveDocument())
262 		return nullptr;
263 
264 	DocumentInformation& docInfo = ScCore->primaryMainWindow()->doc->documentInfo();
265 	docInfo.setAuthor(QString::fromUtf8(Author));
266 	docInfo.setTitle(QString::fromUtf8(Title));
267 	docInfo.setComments(QString::fromUtf8(Desc));
268 	ScCore->primaryMainWindow()->slotDocCh();
269 
270 	Py_RETURN_NONE;
271 }
272 
scribus_setunit(PyObject *,PyObject * args)273 PyObject *scribus_setunit(PyObject* /* self */, PyObject* args)
274 {
275 	int e;
276 	if (!PyArg_ParseTuple(args, "i", &e))
277 		return nullptr;
278 	if (!checkHaveDocument())
279 		return nullptr;
280 	if ((e < UNITMIN) || (e > UNITMAX))
281 	{
282 		PyErr_SetString(PyExc_ValueError, QObject::tr("Unit out of range. Use one of the scribus.UNIT_* constants.","python error").toLocal8Bit().constData());
283 		return nullptr;
284 	}
285 	ScCore->primaryMainWindow()->slotChangeUnit(e);
286 
287 	Py_RETURN_NONE;
288 }
289 
scribus_getunit(PyObject *)290 PyObject *scribus_getunit(PyObject* /* self */)
291 {
292 	if (!checkHaveDocument())
293 		return nullptr;
294 	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->unitIndex()));
295 }
296 
scribus_loadstylesfromfile(PyObject *,PyObject * args)297 PyObject *scribus_loadstylesfromfile(PyObject* /* self */, PyObject *args)
298 {
299 	char *fileName;
300 	if (!PyArg_ParseTuple(args, "es", "utf-8", &fileName))
301 		return nullptr;
302 	if (!checkHaveDocument())
303 		return nullptr;
304 	ScCore->primaryMainWindow()->doc->loadStylesFromFile(QString::fromUtf8(fileName));
305 
306 	Py_RETURN_NONE;
307 }
308 
scribus_setdoctype(PyObject *,PyObject * args)309 PyObject *scribus_setdoctype(PyObject* /* self */, PyObject* args)
310 {
311 	int fp, fsl;
312 	if (!PyArg_ParseTuple(args, "ii", &fp, &fsl))
313 		return nullptr;
314 	if (!checkHaveDocument())
315 		return nullptr;
316 
317 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
318 	ScribusView* currentView = ScCore->primaryMainWindow()->view;
319 
320 	if (currentDoc->pagePositioning() == fp)
321 		currentDoc->setPageSetFirstPage(currentDoc->pagePositioning(), fsl);
322 	currentView->reformPages();
323 	currentView->GotoPage(currentDoc->currentPageNumber()); // is this needed?
324 	currentView->DrawNew();   // is this needed?
325 	//CB TODO ScCore->primaryMainWindow()->pagePalette->RebuildPage(); // is this needed?
326 	ScCore->primaryMainWindow()->slotDocCh();
327 
328 	Py_RETURN_NONE;
329 }
330 
scribus_closemasterpage(PyObject *)331 PyObject *scribus_closemasterpage(PyObject* /* self */)
332 {
333 	if (!checkHaveDocument())
334 		return nullptr;
335 	ScCore->primaryMainWindow()->view->hideMasterPage();
336 
337 	Py_RETURN_NONE;
338 }
339 
scribus_masterpagenames(PyObject *)340 PyObject *scribus_masterpagenames(PyObject* /* self */)
341 {
342 	if (!checkHaveDocument())
343 		return nullptr;
344 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
345 
346 	PyObject* names = PyList_New(currentDoc->MasterPages.count());
347 	QMap<QString,int>::const_iterator it(currentDoc->MasterNames.constBegin());
348 	QMap<QString,int>::const_iterator itEnd(currentDoc->MasterNames.constEnd());
349 	int n = 0;
350 	for ( ; it != itEnd; ++it )
351 	{
352 		PyList_SET_ITEM(names, n++, PyUnicode_FromString(it.key().toUtf8().data()) );
353 	}
354 	return names;
355 }
356 
scribus_editmasterpage(PyObject *,PyObject * args)357 PyObject *scribus_editmasterpage(PyObject* /* self */, PyObject* args)
358 {
359 	char* name = nullptr;
360 	if (!PyArg_ParseTuple(args, "es", const_cast<char*>("utf-8"), &name))
361 		return nullptr;
362 	if (!checkHaveDocument())
363 		return nullptr;
364 	const QString masterPageName(name);
365 	const QMap<QString,int>& masterNames(ScCore->primaryMainWindow()->doc->MasterNames);
366 	const QMap<QString,int>::const_iterator it(masterNames.find(masterPageName));
367 	if ( it == masterNames.constEnd() )
368 	{
369 		PyErr_SetString(PyExc_ValueError, "Master page not found");
370 		return nullptr;
371 	}
372 	ScCore->primaryMainWindow()->view->showMasterPage(*it);
373 
374 	Py_RETURN_NONE;
375 }
376 
scribus_createmasterpage(PyObject *,PyObject * args)377 PyObject* scribus_createmasterpage(PyObject* /* self */, PyObject* args)
378 {
379 	char* name = nullptr;
380 	if (!PyArg_ParseTuple(args, "es", const_cast<char*>("utf-8"), &name))
381 		return nullptr;
382 	if (!checkHaveDocument())
383 		return nullptr;
384 	const QString masterPageName(name);
385 
386 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
387 	if (currentDoc->MasterNames.contains(masterPageName))
388 	{
389 		PyErr_SetString(PyExc_ValueError, "Master page already exists");
390 		return nullptr;
391 	}
392 	currentDoc->addMasterPage(currentDoc->MasterPages.count(), masterPageName);
393 
394 	Py_RETURN_NONE;
395 }
396 
scribus_deletemasterpage(PyObject *,PyObject * args)397 PyObject* scribus_deletemasterpage(PyObject* /* self */, PyObject* args)
398 {
399 	char* name = nullptr;
400 	if (!PyArg_ParseTuple(args, "es", const_cast<char*>("utf-8"), &name))
401 		return nullptr;
402 	if (!checkHaveDocument())
403 		return nullptr;
404 	const QString masterPageName(name);
405 
406 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
407 	if (!currentDoc->MasterNames.contains(masterPageName))
408 	{
409 		PyErr_SetString(PyExc_ValueError, "Master page does not exist");
410 		return nullptr;
411 	}
412 	if (masterPageName == "Normal")
413 	{
414 		PyErr_SetString(PyExc_ValueError, "Can not delete the Normal master page");
415 		return nullptr;
416 	}
417 	bool oldMode = currentDoc->masterPageMode();
418 	currentDoc->setMasterPageMode(true);
419 	ScCore->primaryMainWindow()->deletePage2(currentDoc->MasterNames[masterPageName]);
420 	currentDoc->setMasterPageMode(oldMode);
421 
422 	Py_RETURN_NONE;
423 }
424 
scribus_getmasterpage(PyObject *,PyObject * args)425 PyObject *scribus_getmasterpage(PyObject* /* self */, PyObject* args)
426 {
427 	int e;
428 	if (!PyArg_ParseTuple(args, "i", &e))
429 		return nullptr;
430 	if (!checkHaveDocument())
431 		return nullptr;
432 	e--;
433 
434 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
435 	if ((e < 0) || (e > static_cast<int>(currentDoc->Pages->count())-1))
436 	{
437 		PyErr_SetString(PyExc_IndexError, QObject::tr("Page number out of range: '%1'.","python error").arg(e+1).toLocal8Bit().constData());
438 		return nullptr;
439 	}
440 	return PyUnicode_FromString(currentDoc->DocPages.at(e)->masterPageName().toUtf8());
441 }
442 
scribus_applymasterpage(PyObject *,PyObject * args)443 PyObject* scribus_applymasterpage(PyObject* /* self */, PyObject* args)
444 {
445 	char* name = nullptr;
446 	int page = 0;
447 	if (!PyArg_ParseTuple(args, "esi", const_cast<char*>("utf-8"), &name, &page))
448 		return nullptr;
449 	if (!checkHaveDocument())
450 		return nullptr;
451 	const QString masterPageName(name);
452 
453 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
454 	if (!currentDoc->MasterNames.contains(masterPageName))
455 	{
456 		PyErr_SetString(PyExc_ValueError, QObject::tr("Master page does not exist: '%1'","python error").arg(masterPageName).toLocal8Bit().constData());
457 		return nullptr;
458 	}
459 	if ((page < 1) || (page > static_cast<int>(currentDoc->Pages->count())))
460 	{
461 		PyErr_SetString(PyExc_IndexError, QObject::tr("Page number out of range: %1.","python error").arg(page).toLocal8Bit().constData());
462 		return nullptr;
463 	}
464 
465 	if (!currentDoc->applyMasterPage(masterPageName, page-1))
466 	{
467 		PyErr_SetString(ScribusException, QObject::tr("Failed to apply masterpage '%1' on page: %2","python error").arg(masterPageName).arg(page).toLocal8Bit().constData());
468 		return nullptr;
469 	}
470 	Py_RETURN_NONE;
471 }
472 
473 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
474 with header files structure untouched (docstrings are kept near declarations)
475 PV */
cmddocdocwarnings()476 void cmddocdocwarnings()
477 {
478 	QStringList s;
479 	s << scribus_applymasterpage__doc__
480 	  << scribus_closedoc__doc__
481 	  << scribus_closemasterpage__doc__
482 	  << scribus_createmasterpage__doc__
483 	  << scribus_deletemasterpage__doc__
484 	  << scribus_editmasterpage__doc__
485 	  << scribus_getdocname__doc__
486 	  << scribus_getmasterpage__doc__
487 	  << scribus_getunit__doc__
488 	  << scribus_havedoc__doc__
489 	  << scribus_loadstylesfromfile__doc__
490 	  << scribus_masterpagenames__doc__
491 	  << scribus_newdoc__doc__
492 	  << scribus_newdocument__doc__
493 	  << scribus_opendoc__doc__
494 	  << scribus_revertdoc__doc__
495 	  << scribus_savedoc__doc__
496 	  << scribus_savedocas__doc__
497 	  << scribus_setbaseline__doc__
498 	  << scribus_setbleeds__doc__
499 	  << scribus_setdoctype__doc__
500 	  << scribus_setinfo__doc__
501 	  << scribus_setmargins__doc__
502 	  << scribus_setunit__doc__;
503 }
504