1 /*
2  * Copyright (C) 2011 Elvis Stansvik <elvstone@gmail.com>
3  *
4  * For general Scribus (>=1.3.2) copyright and licensing information please refer
5  * to the COPYING file provided with the program. Following this notice may exist
6  * a copyright and/or license notice that predates the release of Scribus 1.3.2
7  * for which a new license (GPL+exception) is in place.
8  */
9 
10 #include "cmdcell.h"
11 #include "cmdutil.h"
12 #include "pageitem_table.h"
13 #include "pageitem_textframe.h"
14 #include "tableborder.h"
15 
scribus_getcelltext(PyObject *,PyObject * args)16 PyObject *scribus_getcelltext(PyObject* /* self */, PyObject* args)
17 {
18 	char *Name = const_cast<char*>("");
19 	int row, column;
20 	if (!PyArg_ParseTuple(args, "ii|es", &row, &column, "utf-8", &Name))
21 		return nullptr;
22 	if (!checkHaveDocument())
23 		return nullptr;
24 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
25 	if (i == nullptr)
26 		return nullptr;
27 	PageItem_Table *table = i->asTable();
28 	if (!table)
29 	{
30 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell text on a non-table item.","python error").toLocal8Bit().constData());
31 		return nullptr;
32 	}
33 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
34 	{
35 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
36 		return nullptr;
37 	}
38 
39 	PageItem* textFrame = table->cellAt(row, column).textFrame();
40 	const StoryText& story = textFrame->itemText;
41 	QString text;
42 	text.reserve(story.hasSelection() ? story.selectionLength() : story.length());
43 	for (int i = 0; i < story.length(); i++)
44 	{
45 		if (textFrame->HasSel)
46 		{
47 			if (story.selected(i))
48 				text += story.text(i);
49 		}
50 		else
51 		{
52 			text += story.text(i);
53 		}
54 	}
55 	return PyUnicode_FromString(text.toUtf8());
56 }
57 
scribus_setcelltext(PyObject *,PyObject * args)58 PyObject *scribus_setcelltext(PyObject* /* self */, PyObject* args)
59 {
60 	char *Name = const_cast<char*>("");
61 	int row, column;
62 	char *text;
63 	if (!PyArg_ParseTuple(args, "iies|es", &row, &column, "utf-8", &text, "utf-8", &Name))
64 		return nullptr;
65 	if (!checkHaveDocument())
66 		return nullptr;
67 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
68 	if (i == nullptr)
69 		return nullptr;
70 	PageItem_Table *table = i->asTable();
71 	if (!table)
72 	{
73 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell text on a non-table item.","python error").toLocal8Bit().constData());
74 		return nullptr;
75 	}
76 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
77 	{
78 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
79 		return nullptr;
80 	}
81 	table->cellAt(row, column).setText(QString::fromUtf8(text));
82 	Py_RETURN_NONE;
83 }
84 
scribus_getcellstyle(PyObject *,PyObject * args)85 PyObject *scribus_getcellstyle(PyObject* /* self */, PyObject* args)
86 {
87 	char *Name = const_cast<char*>("");
88 	int row, column;
89 	if (!PyArg_ParseTuple(args, "ii|es", &row, &column, "utf-8", &Name))
90 		return nullptr;
91 	if (!checkHaveDocument())
92 		return nullptr;
93 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
94 	if (i == nullptr)
95 		return nullptr;
96 	PageItem_Table *table = i->asTable();
97 	if (!table)
98 	{
99 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell style on a non-table item.","python error").toLocal8Bit().constData());
100 		return nullptr;
101 	}
102 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
103 	{
104 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
105 		return nullptr;
106 	}
107 	return PyUnicode_FromString(table->cellAt(row, column).styleName().toUtf8());
108 }
109 
scribus_setcellstyle(PyObject *,PyObject * args)110 PyObject *scribus_setcellstyle(PyObject* /* self */, PyObject* args)
111 {
112 	char *Name = const_cast<char*>("");
113 	int row, column;
114 	char *style;
115 	if (!PyArg_ParseTuple(args, "iies|es", &row, &column, "utf-8", &style, "utf-8", &Name))
116 		return nullptr;
117 	if (!checkHaveDocument())
118 		return nullptr;
119 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
120 	if (i == nullptr)
121 		return nullptr;
122 	PageItem_Table *table = i->asTable();
123 	if (!table)
124 	{
125 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell style on a non-table item.","python error").toLocal8Bit().constData());
126 		return nullptr;
127 	}
128 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
129 	{
130 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
131 		return nullptr;
132 	}
133 	table->cellAt(row, column).setStyle(QString::fromUtf8(style));
134 	Py_RETURN_NONE;
135 }
136 
scribus_getcellrowspan(PyObject *,PyObject * args)137 PyObject *scribus_getcellrowspan(PyObject* /* self */, PyObject* args)
138 {
139 	char *Name = const_cast<char*>("");
140 	int row, column;
141 	if (!PyArg_ParseTuple(args, "ii|es", &row, &column, "utf-8", &Name))
142 		return nullptr;
143 	if (!checkHaveDocument())
144 		return nullptr;
145 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
146 	if (i == nullptr)
147 		return nullptr;
148 	PageItem_Table *table = i->asTable();
149 	if (!table)
150 	{
151 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell row span from non-table item.","python error").toLocal8Bit().constData());
152 		return nullptr;
153 	}
154 	return PyLong_FromLong(static_cast<long>(table->cellAt(row, column).rowSpan()));
155 }
156 
scribus_getcellcolumnspan(PyObject *,PyObject * args)157 PyObject *scribus_getcellcolumnspan(PyObject* /* self */, PyObject* args)
158 {
159 	char *Name = const_cast<char*>("");
160 	int row, column;
161 	if (!PyArg_ParseTuple(args, "ii|es", &row, &column, "utf-8", &Name))
162 		return nullptr;
163 	if (!checkHaveDocument())
164 		return nullptr;
165 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
166 	if (i == nullptr)
167 		return nullptr;
168 	PageItem_Table *table = i->asTable();
169 	if (!table)
170 	{
171 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell column span from non-table item.","python error").toLocal8Bit().constData());
172 		return nullptr;
173 	}
174 	return PyLong_FromLong(static_cast<long>(table->cellAt(row, column).columnSpan()));
175 }
176 
scribus_getcellfillcolor(PyObject *,PyObject * args)177 PyObject *scribus_getcellfillcolor(PyObject* /* self */, PyObject* args)
178 {
179 	char *Name = const_cast<char*>("");
180 	int row, column;
181 	if (!PyArg_ParseTuple(args, "ii|es", &row, &column, "utf-8", &Name))
182 		return nullptr;
183 	if (!checkHaveDocument())
184 		return nullptr;
185 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
186 	if (i == nullptr)
187 		return nullptr;
188 	PageItem_Table *table = i->asTable();
189 	if (!table)
190 	{
191 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell fill color on a non-table item.","python error").toLocal8Bit().constData());
192 		return nullptr;
193 	}
194 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
195 	{
196 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
197 		return nullptr;
198 	}
199 	return PyUnicode_FromString(table->cellAt(row, column).fillColor().toUtf8());
200 }
201 
scribus_setcellfillcolor(PyObject *,PyObject * args)202 PyObject *scribus_setcellfillcolor(PyObject* /* self */, PyObject* args)
203 {
204 	char *Name = const_cast<char*>("");
205 	int row, column;
206 	char *color;
207 	if (!PyArg_ParseTuple(args, "iies|es", &row, &column, "utf-8", &color, "utf-8", &Name))
208 		return nullptr;
209 	if (!checkHaveDocument())
210 		return nullptr;
211 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
212 	if (i == nullptr)
213 		return nullptr;
214 	PageItem_Table *table = i->asTable();
215 	if (!table)
216 	{
217 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell fill color on a non-table item.","python error").toLocal8Bit().constData());
218 		return nullptr;
219 	}
220 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
221 	{
222 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
223 		return nullptr;
224 	}
225 	table->cellAt(row, column).setFillColor(QString::fromUtf8(color));
226 	Py_RETURN_NONE;
227 }
228 
scribus_setcellleftborder(PyObject *,PyObject * args)229 PyObject *scribus_setcellleftborder(PyObject* /* self */, PyObject* args)
230 {
231 	char *Name = const_cast<char*>("");
232 	int row, column;
233 	PyObject* borderLines;
234 	if (!PyArg_ParseTuple(args, "iiO|es", &row, &column, &borderLines, "utf-8", &Name))
235 		return nullptr;
236 	if (!checkHaveDocument())
237 		return nullptr;
238 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
239 	if (i == nullptr)
240 		return nullptr;
241 	PageItem_Table *table = i->asTable();
242 	if (!table)
243 	{
244 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell left border on a non-table item.","python error").toLocal8Bit().constData());
245 		return nullptr;
246 	}
247 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
248 	{
249 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
250 		return nullptr;
251 	}
252 
253 	bool ok = false;
254 	TableBorder border = parseBorder(borderLines, &ok);
255 	if (ok)
256 		table->cellAt(row, column).setLeftBorder(border);
257 	else
258 		return nullptr;
259 
260 	Py_RETURN_NONE;
261 }
262 
scribus_setcellrightborder(PyObject *,PyObject * args)263 PyObject *scribus_setcellrightborder(PyObject* /* self */, PyObject* args)
264 {
265 	char *Name = const_cast<char*>("");
266 	int row, column;
267 	PyObject* borderLines;
268 	if (!PyArg_ParseTuple(args, "iiO|es", &row, &column, &borderLines, "utf-8", &Name))
269 		return nullptr;
270 	if (!checkHaveDocument())
271 		return nullptr;
272 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
273 	if (i == nullptr)
274 		return nullptr;
275 	PageItem_Table *table = i->asTable();
276 	if (!table)
277 	{
278 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell right border on a non-table item.","python error").toLocal8Bit().constData());
279 		return nullptr;
280 	}
281 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
282 	{
283 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
284 		return nullptr;
285 	}
286 
287 	bool ok = false;
288 	TableBorder border = parseBorder(borderLines, &ok);
289 	if (ok)
290 		table->cellAt(row, column).setRightBorder(border);
291 	else
292 		return nullptr;
293 
294 	Py_RETURN_NONE;
295 }
296 
scribus_setcelltopborder(PyObject *,PyObject * args)297 PyObject *scribus_setcelltopborder(PyObject* /* self */, PyObject* args)
298 {
299 	char *Name = const_cast<char*>("");
300 	int row, column;
301 	PyObject* borderLines;
302 	if (!PyArg_ParseTuple(args, "iiO|es", &row, &column, &borderLines, "utf-8", &Name))
303 		return nullptr;
304 	if (!checkHaveDocument())
305 		return nullptr;
306 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
307 	if (i == nullptr)
308 		return nullptr;
309 	PageItem_Table *table = i->asTable();
310 	if (!table)
311 	{
312 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell top border on a non-table item.","python error").toLocal8Bit().constData());
313 		return nullptr;
314 	}
315 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
316 	{
317 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
318 		return nullptr;
319 	}
320 
321 	bool ok = false;
322 	TableBorder border = parseBorder(borderLines, &ok);
323 	if (ok)
324 		table->cellAt(row, column).setTopBorder(border);
325 	else
326 		return nullptr;
327 
328 	Py_RETURN_NONE;
329 }
330 
scribus_setcellbottomborder(PyObject *,PyObject * args)331 PyObject *scribus_setcellbottomborder(PyObject* /* self */, PyObject* args)
332 {
333 	char *Name = const_cast<char*>("");
334 	int row, column;
335 	PyObject* borderLines;
336 	if (!PyArg_ParseTuple(args, "iiO|es", &row, &column, &borderLines, "utf-8", &Name))
337 		return nullptr;
338 	if (!checkHaveDocument())
339 		return nullptr;
340 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
341 	if (i == nullptr)
342 		return nullptr;
343 	PageItem_Table *table = i->asTable();
344 	if (!table)
345 	{
346 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell bottom border on a non-table item.","python error").toLocal8Bit().constData());
347 		return nullptr;
348 	}
349 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
350 	{
351 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
352 		return nullptr;
353 	}
354 
355 	bool ok = false;
356 	TableBorder border = parseBorder(borderLines, &ok);
357 	if (ok)
358 		table->cellAt(row, column).setBottomBorder(border);
359 	else
360 		return nullptr;
361 
362 	Py_RETURN_NONE;
363 }
364 
scribus_setcellleftpadding(PyObject *,PyObject * args)365 PyObject *scribus_setcellleftpadding(PyObject* /* self */, PyObject* args)
366 {
367 	char *Name = const_cast<char*>("");
368 	int row, column;
369 	double padding;
370 	if (!PyArg_ParseTuple(args, "iid|es", &row, &column, &padding, "utf-8", &Name))
371 		return nullptr;
372 	if (!checkHaveDocument())
373 		return nullptr;
374 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
375 	if (i == nullptr)
376 		return nullptr;
377 	PageItem_Table *table = i->asTable();
378 	if (!table)
379 	{
380 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell left padding on a non-table item.","python error").toLocal8Bit().constData());
381 		return nullptr;
382 	}
383 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
384 	{
385 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
386 		return nullptr;
387 	}
388 	if (padding < 0.0)
389 	{
390 		PyErr_SetString(PyExc_ValueError, QObject::tr("Cell padding must be >= 0.0", "python error").toLocal8Bit().constData());
391 		return nullptr;
392 	}
393 	table->cellAt(row, column).setLeftPadding(padding);
394 
395 	Py_RETURN_NONE;
396 }
397 
scribus_setcellrightpadding(PyObject *,PyObject * args)398 PyObject *scribus_setcellrightpadding(PyObject* /* self */, PyObject* args)
399 {
400 	char *Name = const_cast<char*>("");
401 	int row, column;
402 	double padding;
403 	if (!PyArg_ParseTuple(args, "iid|es", &row, &column, &padding, "utf-8", &Name))
404 		return nullptr;
405 	if (!checkHaveDocument())
406 		return nullptr;
407 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
408 	if (i == nullptr)
409 		return nullptr;
410 	PageItem_Table *table = i->asTable();
411 	if (!table)
412 	{
413 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell right padding on a non-table item.","python error").toLocal8Bit().constData());
414 		return nullptr;
415 	}
416 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
417 	{
418 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
419 		return nullptr;
420 	}
421 	if (padding < 0.0)
422 	{
423 		PyErr_SetString(PyExc_ValueError, QObject::tr("Cell padding must be >= 0.0", "python error").toLocal8Bit().constData());
424 		return nullptr;
425 	}
426 	table->cellAt(row, column).setRightPadding(padding);
427 
428 	Py_RETURN_NONE;
429 }
430 
scribus_setcelltoppadding(PyObject *,PyObject * args)431 PyObject *scribus_setcelltoppadding(PyObject* /* self */, PyObject* args)
432 {
433 	char *Name = const_cast<char*>("");
434 	int row, column;
435 	double padding;
436 	if (!PyArg_ParseTuple(args, "iid|es", &row, &column, &padding, "utf-8", &Name))
437 		return nullptr;
438 	if (!checkHaveDocument())
439 		return nullptr;
440 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
441 	if (i == nullptr)
442 		return nullptr;
443 	PageItem_Table *table = i->asTable();
444 	if (!table)
445 	{
446 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell top padding on a non-table item.","python error").toLocal8Bit().constData());
447 		return nullptr;
448 	}
449 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
450 	{
451 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
452 		return nullptr;
453 	}
454 	if (padding < 0.0)
455 	{
456 		PyErr_SetString(PyExc_ValueError, QObject::tr("Cell padding must be >= 0.0", "python error").toLocal8Bit().constData());
457 		return nullptr;
458 	}
459 	table->cellAt(row, column).setTopPadding(padding);
460 
461 	Py_RETURN_NONE;
462 }
463 
scribus_setcellbottompadding(PyObject *,PyObject * args)464 PyObject *scribus_setcellbottompadding(PyObject* /* self */, PyObject* args)
465 {
466 	char *Name = const_cast<char*>("");
467 	int row, column;
468 	double padding;
469 	if (!PyArg_ParseTuple(args, "iid|es", &row, &column, &padding, "utf-8", &Name))
470 		return nullptr;
471 	if (!checkHaveDocument())
472 		return nullptr;
473 	PageItem *i = GetUniqueItem(QString::fromUtf8(Name));
474 	if (i == nullptr)
475 		return nullptr;
476 	PageItem_Table *table = i->asTable();
477 	if (!table)
478 	{
479 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set cell bottom padding on a non-table item.","python error").toLocal8Bit().constData());
480 		return nullptr;
481 	}
482 	if (column < 0 || column >= table->columns() || row < 0 || row >= table->rows())
483 	{
484 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
485 		return nullptr;
486 	}
487 	if (padding < 0.0)
488 	{
489 		PyErr_SetString(PyExc_ValueError, QObject::tr("Cell padding must be >= 0.0", "python error").toLocal8Bit().constData());
490 		return nullptr;
491 	}
492 	table->cellAt(row, column).setBottomPadding(padding);
493 
494 	Py_RETURN_NONE;
495 }
496 
497 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
498 with header files structure untouched (docstrings are kept near declarations)
499 PV */
cmdcelldocwarnings()500 void cmdcelldocwarnings()
501 {
502 	QStringList s;
503 	s << scribus_getcellcolumnspan__doc__
504 	  << scribus_getcellfillcolor__doc__
505 	  << scribus_getcellrowspan__doc__
506 	  << scribus_getcellstyle__doc__
507 	  << scribus_getcelltext__doc__
508 	  << scribus_setcellbottomborder__doc__
509 	  << scribus_setcellbottompadding__doc__
510 	  << scribus_setcellfillcolor__doc__
511 	  << scribus_setcellleftborder__doc__
512 	  << scribus_setcellleftpadding__doc__
513 	  << scribus_setcellrightborder__doc__
514 	  << scribus_setcellrightpadding__doc__
515 	  << scribus_setcellstyle__doc__
516 	  << scribus_setcelltext__doc__
517 	  << scribus_setcelltopborder__doc__
518 	  << scribus_setcelltoppadding__doc__;
519 }
520