1 /*
2  * Copyright (C) 2020 Damir Porobic <damir.porobic@gmx.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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
12  * GNU 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 program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #include "StandAloneBootstrapper.h"
21 
StandAloneBootstrapper()22 StandAloneBootstrapper::StandAloneBootstrapper() :
23 	mImageGrabber(nullptr),
24 	mCommandLine(nullptr),
25 	mMainWindow(nullptr)
26 {
27 
28 }
29 
~StandAloneBootstrapper()30 StandAloneBootstrapper::~StandAloneBootstrapper()
31 {
32 	delete mCommandLine;
33 }
34 
start(const QApplication & app)35 int StandAloneBootstrapper::start(const QApplication &app)
36 {
37 	app.setQuitOnLastWindowClosed(false);
38 
39 	createImageGrabber();
40 	createCommandLineParser(app);
41 
42 	if (isVersionRequested()) {
43 		return showVersion();
44 	}
45 
46 	if (isStartedWithoutArguments()) {
47 		return startKsnip(app);
48 	}
49 
50 	if (isEditRequested()) {
51 		return startKsnipAndEditImage(app);
52 	}
53 
54 	return startKsnipAndTakeCapture(app);
55 }
56 
isEditRequested() const57 bool StandAloneBootstrapper::isEditRequested() const
58 {
59 	return mCommandLine->isEditSet();
60 }
61 
isVersionRequested() const62 bool StandAloneBootstrapper::isVersionRequested() const
63 {
64 	return mCommandLine->isVersionSet();
65 }
66 
isStartedWithoutArguments() const67 bool StandAloneBootstrapper::isStartedWithoutArguments() const
68 {
69 	auto arguments = QCoreApplication::arguments();
70 	return arguments.count() <= 1;
71 }
72 
startKsnipAndTakeCapture(const QApplication & app)73 int StandAloneBootstrapper::startKsnipAndTakeCapture(const QApplication &app)
74 {
75 	auto captureMode = getCaptureMode();
76 	auto runMode = getRunMode();
77 	auto captureCursor = getCaptureCursor();
78 	auto delay = getDelay();
79 
80 	if(runMode != RunMode::CLI) {
81 		loadTranslations(app);
82 	}
83 
84 	createMainWindow(runMode);
85 	mMainWindow->captureScreenshot(captureMode, captureCursor, delay);
86 	return app.exec();
87 }
88 
getCaptureCursor() const89 bool StandAloneBootstrapper::getCaptureCursor() const
90 {
91 	return mCommandLine->isCursorSet();
92 }
93 
getDelay() const94 int StandAloneBootstrapper::getDelay() const
95 {
96 	auto delay = 0;
97 	if (mCommandLine->isDelaySet()) {
98 		delay = mCommandLine->delay();
99 		if (delay < 0) {
100 			qWarning("Delay flag set without value, ignoring delay.");
101 			delay = 0;
102 		}
103 	}
104 	return delay * 1000;
105 }
106 
getRunMode() const107 RunMode StandAloneBootstrapper::getRunMode() const
108 {
109 	return getSave() ? RunMode::CLI : RunMode::Edit;
110 }
111 
getSave() const112 bool StandAloneBootstrapper::getSave() const
113 {
114 	return mCommandLine->isSaveSet();
115 }
116 
getCaptureMode() const117 CaptureModes StandAloneBootstrapper::getCaptureMode() const
118 {
119 	if (mCommandLine->isCaptureModeSet()) {
120 		return mCommandLine->captureMode();
121 	} else {
122 		qWarning("No capture mode selected, using default.");
123 		return CaptureModes::RectArea;
124 	}
125 }
126 
startKsnipAndEditImage(const QApplication & app)127 int StandAloneBootstrapper::startKsnipAndEditImage(const QApplication &app)
128 {
129 	loadTranslations(app);
130 	auto pathToImage = getImagePath();
131 	auto pixmap = getPixmapFromCorrectSource(pathToImage);
132 
133 	if (pixmap.isNull()) {
134 		qWarning("Unable to open image file %s.", qPrintable(pathToImage));
135 		return 1;
136 	} else {
137 		createMainWindow(RunMode::Edit);
138 		if(PathHelper::isPipePath(pathToImage)) {
139 			mMainWindow->processImage(CaptureDto(pixmap));
140 		} else {
141 			mMainWindow->processImage(CaptureFromFileDto(pixmap, pathToImage));
142 		}
143 		return app.exec();
144 	}
145 }
146 
getPixmapFromCorrectSource(const QString & pathToImage)147 QPixmap StandAloneBootstrapper::getPixmapFromCorrectSource(const QString &pathToImage)
148 {
149 	if (PathHelper::isPipePath(pathToImage)) {
150 		qInfo("Reading image from stdin.");
151 		return getPixmapFromStdin();
152 	} else {
153 		return QPixmap(pathToImage);
154 	}
155 }
156 
getPixmapFromStdin()157 QPixmap StandAloneBootstrapper::getPixmapFromStdin()
158 {
159 	QByteArray stdinImage;
160 	while (!std::cin.eof()) {
161 		char string[1024];
162 		std::cin.read(string, sizeof(string));
163 		auto length = std::cin.gcount();
164 		stdinImage.append(string, length);
165 	}
166 	QPixmap pixmap;
167 	pixmap.loadFromData(stdinImage);
168 	return pixmap;
169 }
170 
getImagePath() const171 QString StandAloneBootstrapper::getImagePath() const
172 {
173 	return mCommandLine->imagePath();
174 }
175 
startKsnip(const QApplication & app)176 int StandAloneBootstrapper::startKsnip(const QApplication &app)
177 {
178 	loadTranslations(app);
179 	createMainWindow(RunMode::GUI);
180 	return app.exec();
181 }
182 
showVersion()183 int StandAloneBootstrapper::showVersion()
184 {
185 	QTextStream stream(stdout);
186 	stream << QLatin1String("Version: ") + qPrintable(KSNIP_VERSION) + QLatin1String("\n");
187 	stream << QLatin1String("Build: ") + qPrintable(KSNIP_BUILD_NUMBER) + QLatin1String("\n");
188 	return 0;
189 }
190 
createMainWindow(RunMode mode)191 void StandAloneBootstrapper::createMainWindow(RunMode mode)
192 {
193 	Q_ASSERT(mMainWindow == nullptr);
194 
195 	mMainWindow = new MainWindow(mImageGrabber, mode);
196 }
197 
createCommandLineParser(const QApplication & app)198 void StandAloneBootstrapper::createCommandLineParser(const QApplication &app)
199 {
200 	mCommandLine = new KsnipCommandLine (app, mImageGrabber->supportedCaptureModes());
201 }
202 
createImageGrabber()203 void StandAloneBootstrapper::createImageGrabber()
204 {
205 	mImageGrabber = ImageGrabberFactory::createImageGrabber();
206 }
207 
loadTranslations(const QApplication & app)208 void StandAloneBootstrapper::loadTranslations(const QApplication &app)
209 {
210 	TranslationLoader::load(app);
211 }
212