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 /***************************************************************************
8 * Riku Leino, tsoots@gmail.com *
9 ***************************************************************************/
10 #include "satemplate.h"
11 #include "satdialog.h"
12
13 #include "api/api_application.h"
14 #include "scpaths.h"
15 #include "ui/scmessagebox.h"
16 #include "scribuscore.h"
17 #include "scribusdoc.h"
18 #include "scribusview.h"
19 #include "prefsfile.h"
20 #include "prefsmanager.h"
21
saveastemplateplugin_getPluginAPIVersion()22 int saveastemplateplugin_getPluginAPIVersion()
23 {
24 return PLUGIN_API_VERSION;
25 }
26
saveastemplateplugin_getPlugin()27 ScPlugin* saveastemplateplugin_getPlugin()
28 {
29 SaveAsTemplatePlugin* plug = new SaveAsTemplatePlugin();
30 Q_CHECK_PTR(plug);
31 return plug;
32 }
33
saveastemplateplugin_freePlugin(ScPlugin * plugin)34 void saveastemplateplugin_freePlugin(ScPlugin* plugin)
35 {
36 SaveAsTemplatePlugin* plug = qobject_cast<SaveAsTemplatePlugin*>(plugin);
37 Q_ASSERT(plug);
38 delete plug;
39 }
40
SaveAsTemplatePlugin()41 SaveAsTemplatePlugin::SaveAsTemplatePlugin()
42 {
43 // Set action info in languageChange, so we only have to do
44 // it in one place.
45 languageChange();
46 }
47
~SaveAsTemplatePlugin()48 SaveAsTemplatePlugin::~SaveAsTemplatePlugin() {};
49
languageChange()50 void SaveAsTemplatePlugin::languageChange()
51 {
52 // Note that we leave the unused members unset. They'll be initialised
53 // with their default ctors during construction.
54 // Action name
55 m_actionInfo.name = "SaveAsDocumentTemplate";
56 // Action text for menu, including accel
57 m_actionInfo.text = tr("Save as &Template...");
58 // Shortcut
59 m_actionInfo.keySequence = "Ctrl+Alt+S";
60 // Menu
61 m_actionInfo.menu = "File";
62 m_actionInfo.menuAfterName = "fileSaveAs";
63 m_actionInfo.enabledOnStartup = true;
64 m_actionInfo.needsNumObjects = -1;
65 }
66
fullTrName() const67 QString SaveAsTemplatePlugin::fullTrName() const
68 {
69 return QObject::tr("Save As Template");
70 }
71
getAboutData() const72 const ScActionPlugin::AboutData* SaveAsTemplatePlugin::getAboutData() const
73 {
74 AboutData* about = new AboutData;
75 Q_CHECK_PTR(about);
76 about->authors = QString::fromUtf8("Riku Leino <riku@scribus.info>");
77 about->shortDescription = tr("Save a document as a template");
78 about->description = tr("Save a document as a template. Good way to ease the "
79 "initial work for documents with a constant look");
80 // about->version
81 // about->releaseDate
82 // about->copyright
83 about->license = "GPL";
84 return about;
85 }
86
deleteAboutData(const AboutData * about) const87 void SaveAsTemplatePlugin::deleteAboutData(const AboutData* about) const
88 {
89 Q_ASSERT(about);
90 delete about;
91 }
92
run(ScribusDoc * doc,const QString & target)93 bool SaveAsTemplatePlugin::run(ScribusDoc* doc, const QString& target)
94 /*{
95 Q_ASSERT(target.isEmpty());
96 Sat = new MenuSAT();
97 Sat->RunSATPlug();
98 delete Sat;
99 Sat = 0;
100 return true;
101 }
102 */
103 /* jghali's fix when the new file dialog is cancelled SaT is still active in the menu - PL */
104 {
105 m_Doc=doc;
106 if ( m_Doc )
107 {
108 Q_ASSERT(target.isEmpty());
109 MenuSAT* Sat = new MenuSAT();
110 Sat->RunSATPlug(m_Doc);
111 delete Sat;
112 Sat = nullptr;
113 }
114 return true;
115 }
RunSATPlug(ScribusDoc * doc)116 void MenuSAT::RunSATPlug(ScribusDoc* doc)
117 {
118 QDir templates(ScPaths::applicationDataDir());
119 if (!templates.exists("templates"))
120 {
121 templates.mkdir("templates");
122 }
123 QString currentPath(QDir::currentPath());
124 QString currentFile(doc->documentFileName());
125 bool hasName = doc->hasName;
126 bool isModified = doc->isModified();
127 QString userTemplatesDir = ScPaths::instance().userTemplateDir(true);
128 PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
129 QString oldCollect = dirs->get("collect", ".");
130 if (userTemplatesDir.isEmpty())
131 {
132 ScMessageBox::warning(doc->scMW(), QObject::tr("No User Template Location Defined"), "<qt>" +
133 QObject::tr("You have not configured where to save document templates.<br>Please go to the Paths section in the Scribus application Preferences to set a location.") + "</qt>",
134 QMessageBox::Ok, // GUI default
135 QMessageBox::Ok); // batch default
136 return;
137 }
138
139 if (userTemplatesDir.right(1) == "/")
140 userTemplatesDir.chop(1);
141
142 dirs->set("collect", userTemplatesDir);
143 if (doc->scMW()->fileCollect().isEmpty())
144 return;
145 if (oldCollect != ".")
146 dirs->set("collect", oldCollect);
147 QString docPath = doc->documentFileName();
148 QString docDir = docPath.left(docPath.lastIndexOf('/'));
149 QString docName = docPath.right(docPath.length() - docPath.lastIndexOf('/') - 1);
150 docName = docName.left(docName.lastIndexOf(".s"));
151
152 if (currentFile == doc->documentFileName())
153 return;
154 SATDialog* satdia = new SATDialog(doc->scMW(),docName,
155 static_cast<int>(doc->pageWidth() + 0.5),
156 static_cast<int>(doc->pageHeight() + 0.5));
157 if (satdia->exec())
158 {
159 sat* s = new sat(doc, satdia, docPath.right(docPath.length() - docPath.lastIndexOf('/') - 1),docDir);
160 s->createImages();
161 s->createTmplXml();
162 delete s;
163 }
164 // Restore the state that was before ScMW->Collect()
165 doc->setDocumentFileName(currentFile);
166 doc->hasName = hasName;
167 doc->setModified(isModified);
168 QString newCaption=currentFile;
169 if (isModified)
170 newCaption.append('*');
171 doc->scMW()->updateActiveWindowCaption(newCaption);
172 doc->scMW()->removeRecent(docPath);
173 QDir::setCurrent(currentPath);
174 delete satdia;
175 }
176
177 // --------------------- CLASS sat ------------------------------------------------//
178
sat(ScribusDoc * doc,SATDialog * satdia,const QString & fileName,const QString & tmplDir)179 sat::sat(ScribusDoc* doc, SATDialog* satdia, const QString& fileName, const QString& tmplDir)
180 {
181 lang = ScCore->getGuiLanguage();
182 m_Doc = doc;
183 dia = satdia;
184 dir = tmplDir;
185 if (dir.right(1) == "/")
186 dir = tmplDir.left(tmplDir.length() - 1);
187 file = fileName;
188 tmplXmlFile = findTemplateXml(dir);
189 }
190
createTmplXml()191 void sat::createTmplXml()
192 {
193 QFile tmplXml(tmplXmlFile);
194 if (tmplXml.exists())
195 {
196 appendTmplXml();
197 return; // We don't want to overwrite the template.xml file
198 }
199 QString xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
200 xml += "<templates>\n";
201 xml += getTemplateTag();
202 xml += "</templates>\n";
203 if ( tmplXml.open( QIODevice::WriteOnly ) )
204 {
205 QTextStream stream(&tmplXml);
206 stream.setCodec("UTF-8");
207 stream << xml;
208 tmplXml.close();
209 }
210 }
211
createImages()212 void sat::createImages()
213 {
214 QString tnsmallName = dia->nameEdit->text() + "tn.png";
215 QString tnlargeName = dia->nameEdit->text() + ".png";
216 double pageh = m_Doc->pageHeight();
217 double pagew = m_Doc->pageWidth();
218 int pageSizeSmall = 0;
219 int pageSizeLarge = 0;
220 if (pageh > pagew)
221 {
222 pageSizeSmall = static_cast<int>(pageh / 10);
223 pageSizeLarge = static_cast<int>(pageh / 3);
224 }
225 else
226 {
227 pageSizeSmall = static_cast<int>(pagew / 10);
228 pageSizeLarge = static_cast<int>(pagew / 3);
229 }
230 QImage tnsmall = m_Doc->view()->PageToPixmap(0,pageSizeSmall);
231 QImage tnlarge = m_Doc->view()->PageToPixmap(0,pageSizeLarge);
232 tnsmall.save(dir+"/"+tnsmallName,"PNG",70);
233 tnlarge.save(dir+"/"+tnlargeName, "PNG", 70);
234 }
235
appendTmplXml()236 void sat::appendTmplXml()
237 {
238 QFile tmplXml(tmplXmlFile);
239 if (tmplXml.open(QIODevice::ReadOnly))
240 {
241 QTextStream stream(&tmplXml);
242 QString tmp = stream.readLine();
243 QString file = "";
244 while (!tmp.isNull())
245 {
246 file += tmp + "\n";
247 tmp = stream.readLine();
248 if (tmp.indexOf("</templates>") != -1)
249 file += getTemplateTag();
250 }
251 tmplXml.close();
252 if ( tmplXml.open( QIODevice::WriteOnly ) )
253 {
254 QTextStream stream2(&tmplXml);
255 stream2.setCodec("UTF-8");
256 stream2 << file;
257 tmplXml.close();
258 }
259 }
260 }
261
getTemplateTag()262 QString sat::getTemplateTag()
263 {
264 QString category = dia->catsCombo->currentText();
265 if (category.isEmpty())
266 category = QObject::tr("Own Templates");
267 else
268 category = dia->cats.key(category, category);
269 QDate now = QDate::currentDate();
270 QString cat = QString(category);
271 replaceIllegalChars(cat);
272 QString tag = "\t<template category=\""+cat+"\">\n";
273 QString name = QString(dia->nameEdit->text());
274 replaceIllegalChars(name);
275 tag += "\t\t<name>"+name+"</name>\n";
276 tag += "\t\t<file>"+file+"</file>\n";
277 tag += "\t\t<tnail>"+name+"tn.png"+"</tnail>\n";
278 tag += "\t\t<img>"+name+".png"+"</img>\n";
279 QString psize = QString(dia->psizeEdit->text());
280 replaceIllegalChars(psize);
281 tag += "\t\t<psize>"+psize+"</psize>\n";
282 QString colors = QString(dia->colorsEdit->text());
283 replaceIllegalChars(colors);
284 tag += "\t\t<color>"+colors+"</color>\n";
285 QString descr = QString(dia->descrEdit->toPlainText());
286 replaceIllegalChars(descr);
287 tag += "\t\t<descr>"+descr+"</descr>\n";
288 QString usage = QString(dia->usageEdit->toPlainText());
289 replaceIllegalChars(usage);
290 tag += "\t\t<usage>"+usage+"</usage>\n";
291 QString scribus_version(ScribusAPI::getVersion());
292 replaceIllegalChars(scribus_version);
293 tag += "\t\t<scribus_version>" + scribus_version + "</scribus_version>\n";
294 QString date = QString(now.toString(Qt::ISODate));
295 replaceIllegalChars(date);
296 tag += "\t\t<date>" + date + "</date>\n";
297 QString author = QString(dia->authorEdit->text());
298 replaceIllegalChars(author);
299 tag += "\t\t<author>"+author+"</author>\n";
300 QString email = QString(dia->emailEdit->text());
301 replaceIllegalChars(email);
302 tag += "\t\t<email>"+email+"</email>\n";
303 tag += "\t</template>\n";
304
305 return tag;
306 }
307
replaceIllegalChars(QString & s)308 void sat::replaceIllegalChars(QString& s)
309 {
310 s.replace("&", "&");
311 s.replace("<", "<");
312 s.replace(">", ">");
313 s.replace(""", "\"");
314 s.replace("'", "\'");
315 s.replace("&", "&");
316 s.replace("<", "<");
317 s.replace(">", ">");
318 s.replace("\"", """);
319 s.replace("\'", "'");
320 }
321
findTemplateXml(const QString & dir)322 QString sat::findTemplateXml(const QString& dir)
323 {
324 QString tmp = dir + "/template." + lang + ".xml";
325 if (QFile(tmp).exists())
326 return tmp;
327
328 if (lang.length() > 2)
329 {
330 tmp = dir + "/template." + lang.left(2) + ".xml";
331 if (QFile(tmp).exists())
332 return tmp;
333 }
334 return dir + "/template.xml";
335 }
336
~sat()337 sat::~sat()
338 {
339 }
340