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 <QString>
8 #include <QDir>
9 #include <QMessageBox>
10 #include <QInputDialog>
11 #include <QtDebug>
12 #include <QApplication>
13
14 #include "scripterimpl.h"
15 #include "ui/scmessagebox.h"
16
17
ScripterImpl()18 ScripterImpl::ScripterImpl() : QObject(QApplication::instance())
19 {
20 setObjectName("Scripter");
21 _instance = this;
22 qDebug() << "ScripterImpl object created";
23 }
24
25
26
~ScripterImpl()27 ScripterImpl::~ScripterImpl()
28 {
29 qDebug() << "destructor";
30 Q_ASSERT(python);
31 delete python;
32 //Q_ASSERT(collected);
33 //delete collected;
34 _instance = nullptr;
35 qDebug() << "Scripter deleted";
36 };
37
38
39
instance()40 ScripterImpl *ScripterImpl::instance()
41 {
42 //return QApplication::instance()->findChild<ScripterImpl *>("Scripter");
43 return _instance;
44 }
45
46
init()47 bool ScripterImpl::init()
48 {
49 collected = new QObject(this);
50 collected->setObjectName(QString("internal_garbage_collector"));
51 new PreferencesAPI();
52 new DialogsAPI();
53 python = new Pythonize();
54 Q_CHECK_PTR(python);
55 path = ScPaths::instance().libDir() + "plugins/scripter/";
56 //qRegisterMetaType< QList<QVariant*> >("QList<QVariant*>");
57 QString init_py = path + "init_scripter.py";
58 bool ok = runScript(init_py);
59 return ok;
60 }
61
62
63
runScript(const QString & filename)64 bool ScripterImpl::runScript(const QString & filename)
65 {
66 qDebug() << "Running" << filename;
67 if (!python->runScript(filename.toLocal8Bit().data()))
68 {
69 qDebug() << "Running" << filename << "failed";
70 return false;
71 }
72 return true;
73 }
74
75
cleanup()76 bool ScripterImpl::cleanup()
77 {
78 QString clean_py = path + "cleanup_scripter.py";
79 return runScript(clean_py);
80 }
81
82
83 /**
84 * Scripter.fromVariant(variant)
85 * variant is a QVariant
86 * returns instance of QObject-subclass
87 *
88 * This is a helper method for PyQt
89 * Because PyQt cannot cast a variant to a QObject or QWidget
90 * I hope that will change some time.
91 */
fromVariant(const QVariant & v)92 QObject *ScripterImpl::fromVariant(const QVariant& v)
93 {
94
95 if (v.canConvert< QWidget* >())
96 {
97 QObject* obj = qvariant_cast< QWidget* >(v);
98 return obj;
99 }
100 else if (v.canConvert< QObject* >())
101 {
102 QObject* obj = qvariant_cast< QObject* >(v);
103 return obj;
104 }
105 else
106 return 0;
107 }
108
109
110 /**
111 * Scripter.openDocument(filename)
112 * filename is a string
113 * returns opened active Document object
114 */
openDocument(const QString & filename)115 QObject *ScripterImpl::openDocument(const QString & filename)
116 {
117 bool ret = ScCore->primaryMainWindow()->loadDoc(filename);
118 if (!ret)
119 {
120 RAISE("Failed to open " + filename);
121 return nullptr;
122 }
123 return activeDocument();
124 }
125
126
127
128 /**
129 * Scripter.activeDocument
130 * Property
131 * returns a Document object if a document is open
132 */
activeDocument()133 QObject *ScripterImpl::activeDocument()
134 {
135 if (ScCore->primaryMainWindow()->HaveDoc)
136 return new DocumentAPI();
137 else
138 return nullptr;
139 }
140
141
142 /**
143 * Scripter.activeWindow
144 * Property
145 * returns a Window object if a window is open
146 */
activeWindow()147 QObject *ScripterImpl::activeWindow()
148 {
149 if (ScCore->primaryMainWindow()->HaveDoc)
150 return new WindowAPI();
151 else
152 return nullptr;
153 }
154
155 /**
156 * Scripter.colors
157 * Property
158 * returns a color object
159 */
colors()160 QList<QVariant> ScripterImpl::colors()
161 {
162 QList<QVariant> l;
163
164 ColorList names = PrefsManager::instance()->colorSet();
165 ColorList::Iterator it;
166 for (it = names.begin(); it != names.end(); ++it)
167 {
168 ScColor *value = &(names[it.key()]);
169 ColorAPI *color = new ColorAPI(value, it.key());
170 l.append(qVariantFromValue((QObject *)(color)));
171 }
172 return l;
173 }
174
fontInfo()175 QList< QVariant > ScripterImpl::fontInfo()
176 {
177 int cc2 = 0;
178 SCFontsIterator it2(PrefsManager::instance()->appPrefs.fontPrefs.AvailFonts);
179 for ( ; it2.hasNext() ; it2.next())
180 {
181 if (it2.current().usable())
182 cc2++;
183 }
184 QList<QVariant> l;
185 SCFontsIterator it(PrefsManager::instance()->appPrefs.fontPrefs.AvailFonts);
186 int cc = 0;
187 for ( ; it.hasNext() ; it.next())
188 {
189 if (it.current().usable())
190 {
191 l.append(it.currentKey());
192 cc++;
193 }
194 }
195 return l;
196 }
197
xFontInfo()198 QList<QVariant> ScripterImpl::xFontInfo()
199 {
200 QList<QVariant> l;
201 SCFontsIterator it(PrefsManager::instance()->appPrefs.fontPrefs.AvailFonts);
202 int cc = 0;
203 QList<QVariant> row;
204 for ( ; it.hasNext() ; it.next())
205 {
206 row.append(it.currentKey());
207 row.append(it.current().family());
208 row.append(it.current().psName());
209 row.append(it.current().subset());
210 row.append(it.current().embedPs());
211 row.append(it.current().fontFilePath());
212 l.append(row);
213 cc++;
214 }
215 return l;
216 }
217
218 /**
219 * Scripter.newDocument(topMargin, bottomMargin, leftMargin, rightMargin, pageWIdth, pageHeight, orientation, firstPageNr, pagesTypes, facingPages, firstPageOrger, numPages)
220 * topMargin is double
221 * bottomMargin is double
222 * leftMargin is double
223 * rightMargin is double
224 * pageWidth is double
225 * pageHeight is double
226 * orientation is int
227 * firstPageNr is int
228 * unit is int
229 * pagesType is int
230 * facingPages is int
231 * firstPageOrder is int
232 * numPages is int
233 * returns new a new active Document object
234 */
newDocument(double topMargin,double bottomMargin,double leftMargin,double rightMargin,double pageWidth,double pageHeight,int orientation,int firstPageNr,int unit,int pagesType,int facingPages,int firstPageOrder,int numPages)235 QObject *ScripterImpl::newDocument(
236 double topMargin, double bottomMargin,
237 double leftMargin, double rightMargin,
238 double pageWidth, double pageHeight,
239 int orientation, int firstPageNr, int unit, int pagesType,
240 int facingPages, int firstPageOrder, int numPages)
241 {
242 if (numPages <= 0)
243 numPages = 1;
244 if (pagesType == 0)
245 {
246 facingPages = 0;
247 firstPageOrder = 0;
248 }
249 else
250 facingPages = 1;
251 // checking the bounds
252 if (pagesType < firstPageOrder)
253 {
254 RAISE("firstPageOrder is bigger than allowed.");
255 return nullptr;
256 }
257 if (orientation == 1)
258 {
259 double x = pageWidth;
260 pageWidth = pageHeight;
261 pageHeight = x;
262 }
263 bool ret = ScCore->primaryMainWindow()->doFileNew(
264 pageWidth, pageHeight, topMargin, leftMargin,
265 rightMargin, bottomMargin,
266 // XXX: add later?
267 // autoframes. It's disabled in python
268 // columnDistance, numberCols, autoframes,
269 0, 1, false,
270 pagesType, unit, firstPageOrder,
271 orientation, firstPageNr, "Custom", true, numPages);
272 if (!ret)
273 {
274 RAISE("Page creation failed");
275 return nullptr;
276 }
277 ScCore->primaryMainWindow()->doc->setPageSetFirstPage(pagesType, firstPageOrder);
278 return activeDocument();
279 }
280
281
282
283
284 /*
285 * slot which emits a signal for PyQt
286 * init_scripter.py waits for it to create the menu
287 */
addToMainWindowMenu(ScribusMainWindow * mainwin)288 void ScripterImpl::addToMainWindowMenu(ScribusMainWindow *mainwin)
289 {
290 emit createMenu(mainwin);
291 }
292
language()293 QString ScripterImpl::language()
294 {
295 return ScCore->getGuiLanguage();
296 }
297
298
299 /*
300 * A simple test method: input some code and evaluate it
301 * It was used before there was a script editor and console
302 * I will keep it for now but will remove it later.
303 */
test()304 bool ScripterImpl::test()
305 {
306 bool ok;
307 QString code = QInputDialog::getText(
308 0, tr("Scripter"), tr("Please enter a Python command:"), QLineEdit::Normal,
309 "import scripterconsole; scripterconsole.show_console()", &ok);
310 if (ok && !code.isEmpty())
311 {
312 bool success = python->runString(code.toUtf8().data());
313 if (!success)
314 qDebug() << "python->runString(..) failed";
315 }
316 return true;
317 }
318
319
320
321 /**
322 * Scripter.aboutScripter()
323 *
324 * Like qApp.aboutQt()
325 * The quickest way to see if calling Scripter works.
326 */
aboutScripter()327 void ScripterImpl::aboutScripter()
328 {
329 ScMessageBox::information(
330 0, //(QWidget*)doc->scMW(),
331 tr("Scribus - Scripter Plugin"),
332 tr("If you see this box, Scripter probably works :)"),
333 QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape,
334 QMessageBox::NoButton);
335 }
336
337
338 ScripterImpl *ScripterImpl::_instance;
339
340
341