1 /*
2 * Copyright (c) 2015 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19 #include "KisApplicationArguments.h"
20
21 #include <QCommandLineParser>
22 #include <QCommandLineOption>
23 #include <QApplication>
24 #include <QDir>
25 #include <QStringList>
26 #include <QString>
27 #include <QDebug>
28 #include <QDataStream>
29 #include <QBuffer>
30
31 #include <klocalizedstring.h>
32 #include <KisPart.h>
33 #include <KisDocument.h>
34
35 struct Q_DECL_HIDDEN KisApplicationArguments::Private
36 {
PrivateKisApplicationArguments::Private37 Private()
38 {
39 }
40
41 QStringList filenames;
42 int dpiX {72};
43 int dpiY {72};
44 bool doTemplate {false};
45 bool exportAs {false};
46 bool exportSequence {false};
47 QString exportFileName;
48 QString workspace;
49 QString windowLayout;
50 QString session;
51 QString fileLayer;
52 bool canvasOnly {false};
53 bool noSplash {false};
54 bool fullScreen {false};
55
56 bool newImage {false};
57 QString colorModel {"RGBA"};
58 QString colorDepth {"U8"};
59 int width {2000};
60 int height {5000};
61 };
62
63
KisApplicationArguments()64 KisApplicationArguments::KisApplicationArguments()
65 : d(new Private)
66 {
67 }
68
69
~KisApplicationArguments()70 KisApplicationArguments::~KisApplicationArguments()
71 {
72 }
73
KisApplicationArguments(const QApplication & app)74 KisApplicationArguments::KisApplicationArguments(const QApplication &app)
75 : d(new Private)
76 {
77 QCommandLineParser parser;
78 parser.addVersionOption();
79 parser.addHelpOption();
80 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("template"), i18n("Open a new document with a template")));
81 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("new-image"), i18n("Create a new image.\n"
82 "Possible colorspace values are:\n"
83 " * RGBA\n"
84 " * XYZA\n"
85 " * LABA\n"
86 " * CMYKA\n"
87 " * GRAY\n"
88 " * YCbCrA\n"
89 "Possible channel depth arguments are\n"
90 " * U8 (8 bits integer)\n"
91 " * U16 (16 bits integer)\n"
92 " * F16 (16 bits floating point)\n"
93 " * F32 (32 bits floating point)\n"),
94 QLatin1String("colorspace,depth,width,height")));
95 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("workspace"), i18n("The name of the workspace to open Krita with"), QLatin1String("workspace")));
96 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("windowlayout"), i18n("The name of the window layout to open Krita with"), QLatin1String("windowlayout")));
97 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("load-session"), i18n("The name of the session to open Krita with"), QLatin1String("load-session"))); // NB: the argument "session" is already used by QGuiApplication
98 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("canvasonly"), i18n("Start Krita in canvas-only mode")));
99 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("nosplash"), i18n("Do not show the splash screen")));
100 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("fullscreen"), i18n("Start Krita in full-screen mode")));
101 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("dpi"), i18n("Override display DPI"), QLatin1String("dpiX,dpiY")));
102 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("export"), i18n("Export to the given filename and exit")));
103 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("export-sequence"), i18n("Export animation to the given filename and exit")));
104 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("export-filename"), i18n("Filename for export"), QLatin1String("filename")));
105 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("file-layer"), i18n("File layer to be added to existing or new file"), QLatin1String("file-layer")));
106 parser.addPositionalArgument(QLatin1String("[file(s)]"), i18n("File(s) or URL(s) to open"));
107
108
109 if (parser.parse(app.arguments())) {
110 parser.process(app);
111 }
112
113 QString dpiValues = parser.value("dpi");
114 if (!dpiValues.isEmpty()) {
115 int sep = dpiValues.indexOf(QRegExp("[x, ]"));
116 bool ok = true;
117 if (sep != -1) {
118 d->dpiY = dpiValues.mid(sep + 1).toInt(&ok);
119 dpiValues.truncate(sep);
120 }
121 if (ok) {
122 d->dpiX = dpiValues.toInt(&ok);
123 if (ok) {
124 if (!d->dpiY)
125 d->dpiY = d->dpiX;
126 }
127 }
128 }
129
130 QString newImageValues = parser.value("new-image");
131 d->newImage = !newImageValues.isEmpty();
132 if (d->newImage) {
133 QStringList v = newImageValues.split(",");
134 if (v.size() != 4) {
135 d->newImage = false;
136 qWarning() << "Cannot create a new image: please specify colormodel, depth, width and height.";
137 }
138 d->colorModel = v[0].toUpper();
139 d->colorDepth = v[1].toUpper();
140 d->width = v[2].toInt();
141 d->height = v[3].toInt();
142 }
143
144 d->fileLayer = parser.value("file-layer");
145 d->exportFileName = parser.value("export-filename");
146 d->workspace = parser.value("workspace");
147 d->windowLayout = parser.value("windowlayout");
148 d->session = parser.value("load-session");
149 d->doTemplate = parser.isSet("template");
150 d->exportAs = parser.isSet("export");
151 d->exportSequence = parser.isSet("export-sequence");
152 d->canvasOnly = parser.isSet("canvasonly");
153 d->noSplash = parser.isSet("nosplash");
154 d->fullScreen = parser.isSet("fullscreen");
155
156 const QDir currentDir = QDir::current();
157 Q_FOREACH (const QString &filename, parser.positionalArguments()) {
158 d->filenames << currentDir.absoluteFilePath(filename);
159 }
160 }
161
KisApplicationArguments(const KisApplicationArguments & rhs)162 KisApplicationArguments::KisApplicationArguments(const KisApplicationArguments &rhs)
163 : d(new Private)
164 {
165 d->filenames = rhs.filenames();
166 d->dpiX = rhs.dpiX();
167 d->dpiY = rhs.dpiY();
168 d->doTemplate = rhs.doTemplate();
169 d->exportAs = rhs.exportAs();
170 d->exportFileName = rhs.exportFileName();
171 d->canvasOnly = rhs.canvasOnly();
172 d->workspace = rhs.workspace();
173 d->windowLayout = rhs.windowLayout();
174 d->session = rhs.session();
175 d->noSplash = rhs.noSplash();
176 d->fullScreen = rhs.fullScreen();
177 }
178
operator =(const KisApplicationArguments & rhs)179 void KisApplicationArguments::operator=(const KisApplicationArguments &rhs)
180 {
181 d->filenames = rhs.filenames();
182 d->dpiX = rhs.dpiX();
183 d->dpiY = rhs.dpiY();
184 d->doTemplate = rhs.doTemplate();
185 d->exportAs = rhs.exportAs();
186 d->exportFileName = rhs.exportFileName();
187 d->canvasOnly = rhs.canvasOnly();
188 d->workspace = rhs.workspace();
189 d->windowLayout = rhs.windowLayout();
190 d->session = rhs.session();
191 d->noSplash = rhs.noSplash();
192 d->fullScreen = rhs.fullScreen();
193 }
194
serialize()195 QByteArray KisApplicationArguments::serialize()
196 {
197 QByteArray ba;
198 QBuffer buf(&ba);
199 buf.open(QIODevice::WriteOnly);
200 QDataStream ds(&buf);
201 ds.setVersion(QDataStream::Qt_5_0);
202 ds << d->filenames.count();
203 Q_FOREACH (const QString &filename, d->filenames) {
204 ds << filename;
205 }
206 ds << d->dpiX;
207 ds << d->dpiY;
208 ds << d->doTemplate;
209 ds << d->exportAs;
210 ds << d->exportFileName;
211 ds << d->workspace;
212 ds << d->windowLayout;
213 ds << d->session;
214 ds << d->canvasOnly;
215 ds << d->noSplash;
216 ds << d->fullScreen;
217 ds << d->newImage;
218 ds << d->height;
219 ds << d->width;
220 ds << d->height;
221 ds << d->colorModel;
222 ds << d->colorDepth;
223 ds << d->fileLayer;
224
225 buf.close();
226
227 return ba;
228 }
229
deserialize(QByteArray & serialized)230 KisApplicationArguments KisApplicationArguments::deserialize(QByteArray &serialized)
231 {
232 KisApplicationArguments args;
233
234 QBuffer buf(&serialized);
235 buf.open(QIODevice::ReadOnly);
236 QDataStream ds(&buf);
237 ds.setVersion(QDataStream::Qt_5_0);
238 int count;
239 ds >> count;
240 for(int i = 0; i < count; ++i) {
241 QString s;
242 ds >> s;
243 args.d->filenames << s;
244 }
245 ds >> args.d->dpiX;
246 ds >> args.d->dpiY;
247 ds >> args.d->doTemplate;
248 ds >> args.d->exportAs;
249 ds >> args.d->exportFileName;
250 ds >> args.d->workspace;
251 ds >> args.d->windowLayout;
252 ds >> args.d->session;
253 ds >> args.d->canvasOnly;
254 ds >> args.d->noSplash;
255 ds >> args.d->fullScreen;
256 ds >> args.d->newImage;
257 ds >> args.d->height;
258 ds >> args.d->width;
259 ds >> args.d->height;
260 ds >> args.d->colorModel;
261 ds >> args.d->colorDepth;
262 ds >> args.d->fileLayer;
263
264 buf.close();
265
266 return args;
267 }
268
filenames() const269 QStringList KisApplicationArguments::filenames() const
270 {
271 return d->filenames;
272 }
273
dpiX() const274 int KisApplicationArguments::dpiX() const
275 {
276 return d->dpiX;
277 }
278
dpiY() const279 int KisApplicationArguments::dpiY() const
280 {
281 return d->dpiY;
282 }
283
doTemplate() const284 bool KisApplicationArguments::doTemplate() const
285 {
286 return d->doTemplate;
287 }
288
exportAs() const289 bool KisApplicationArguments::exportAs() const
290 {
291 return d->exportAs;
292 }
293
exportSequence() const294 bool KisApplicationArguments::exportSequence() const
295 {
296 return d->exportSequence;
297 }
298
exportFileName() const299 QString KisApplicationArguments::exportFileName() const
300 {
301 return d->exportFileName;
302 }
303
workspace() const304 QString KisApplicationArguments::workspace() const
305 {
306 return d->workspace;
307 }
308
windowLayout() const309 QString KisApplicationArguments::windowLayout() const
310 {
311 return d->windowLayout;
312 }
313
session() const314 QString KisApplicationArguments::session() const
315 {
316 return d->session;
317 }
318
fileLayer() const319 QString KisApplicationArguments::fileLayer() const
320 {
321 return d->fileLayer;
322 }
323
canvasOnly() const324 bool KisApplicationArguments::canvasOnly() const
325 {
326 return d->canvasOnly;
327 }
328
noSplash() const329 bool KisApplicationArguments::noSplash() const
330 {
331 return d->noSplash;
332 }
333
fullScreen() const334 bool KisApplicationArguments::fullScreen() const
335 {
336 return d->fullScreen;
337 }
338
doNewImage() const339 bool KisApplicationArguments::doNewImage() const
340 {
341 return d->newImage;
342 }
343
createDocumentFromArguments() const344 KisDocument *KisApplicationArguments::createDocumentFromArguments() const
345 {
346 KisDocument *doc = KisPart::instance()->createDocument();
347 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(d->colorModel, d->colorDepth, "");
348 if (!cs) {
349 qWarning() << "Could not create the colorspace for the new image. Check the colorspace and depth arguments.";
350 return 0;
351 }
352
353 doc->newImage(i18n("Unnamed"), d->width, d->height, cs, KoColor(QColor(Qt::white), cs), KisConfig::CANVAS_COLOR, 1, "", 100.0);
354 return doc;
355 }
356