1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Assistant of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 #include "tracer.h"
29 
30 #include <QtCore/QFileInfo>
31 #include <QtCore/QStringBuilder>
32 #include <QtWidgets/QMessageBox>
33 
34 #include "cmdlineparser.h"
35 
36 QT_BEGIN_NAMESPACE
37 
38 static const char helpMessage[] = QT_TRANSLATE_NOOP("CmdLineParser",
39         "Usage: assistant [Options]\n\n"
40         "-collectionFile file       Uses the specified collection\n"
41         "                           file instead of the default one\n"
42         "-showUrl url               Shows the document with the\n"
43         "                           url.\n"
44         "-enableRemoteControl       Enables Assistant to be\n"
45         "                           remotely controlled.\n"
46         "-show widget               Shows the specified dockwidget\n"
47         "                           which can be \"contents\", \"index\",\n"
48         "                           \"bookmarks\" or \"search\".\n"
49         "-activate widget           Activates the specified dockwidget\n"
50         "                           which can be \"contents\", \"index\",\n"
51         "                           \"bookmarks\" or \"search\".\n"
52         "-hide widget               Hides the specified dockwidget\n"
53         "                           which can be \"contents\", \"index\"\n"
54         "                           \"bookmarks\" or \"search\".\n"
55         "-register helpFile         Registers the specified help file\n"
56         "                           (.qch) in the given collection\n"
57         "                           file.\n"
58         "-unregister helpFile       Unregisters the specified help file\n"
59         "                           (.qch) from the give collection\n"
60         "                           file.\n"
61         "-setCurrentFilter filter   Set the filter as the active filter.\n"
62         "-remove-search-index       Removes the full text search index.\n"
63         "-rebuild-search-index      Obsolete. Use -remove-search-index instead.\n"
64         "                           Removes the full text search index.\n"
65         "                           It will be rebuilt on next Assistant run.\n"
66         "-quiet                     Does not display any error or\n"
67         "                           status message.\n"
68         "-help                      Displays this help.\n"
69         );
70 
71 
CmdLineParser(const QStringList & arguments)72 CmdLineParser::CmdLineParser(const QStringList &arguments)
73     : m_pos(0),
74     m_enableRemoteControl(false),
75     m_contents(Untouched),
76     m_index(Untouched),
77     m_bookmarks(Untouched),
78     m_search(Untouched),
79     m_register(None),
80     m_removeSearchIndex(false),
81     m_quiet(false)
82 {
83     TRACE_OBJ
84     for (int i = 1; i < arguments.count(); ++i) {
85         const QString &arg = arguments.at(i);
86         if (arg.toLower() == "-quiet")
87             m_quiet = true;
88         else
89             m_arguments.append(arg);
90     }
91 }
92 
parse()93 CmdLineParser::Result CmdLineParser::parse()
94 {
95     TRACE_OBJ
96     bool showHelp = false;
97 
98     while (m_error.isEmpty() && hasMoreArgs()) {
99         const QString &arg = nextArg().toLower();
100         if (arg == QLatin1String("-collectionfile"))
101             handleCollectionFileOption();
102         else if (arg == QLatin1String("-showurl"))
103             handleShowUrlOption();
104         else if (arg == QLatin1String("-enableremotecontrol"))
105             m_enableRemoteControl = true;
106         else if (arg == QLatin1String("-show"))
107             handleShowOption();
108         else if (arg == QLatin1String("-hide"))
109             handleHideOption();
110         else if (arg == QLatin1String("-activate"))
111             handleActivateOption();
112         else if (arg == QLatin1String("-register"))
113             handleRegisterOption();
114         else if (arg == QLatin1String("-unregister"))
115             handleUnregisterOption();
116         else if (arg == QLatin1String("-setcurrentfilter"))
117             handleSetCurrentFilterOption();
118         else if (arg == QLatin1String("-remove-search-index"))
119             m_removeSearchIndex = true;
120         else if (arg == QLatin1String("-rebuild-search-index"))
121             m_removeSearchIndex = true;
122         else if (arg == QLatin1String("-help"))
123             showHelp = true;
124         else
125             m_error = tr("Unknown option: %1").arg(arg);
126     }
127 
128     if (!m_error.isEmpty()) {
129         showMessage(m_error + QLatin1String("\n\n\n") + tr(helpMessage), true);
130         return Error;
131     } else if (showHelp) {
132         showMessage(tr(helpMessage), false);
133         return Help;
134     }
135     return Ok;
136 }
137 
hasMoreArgs() const138 bool CmdLineParser::hasMoreArgs() const
139 {
140     TRACE_OBJ
141     return m_pos < m_arguments.count();
142 }
143 
nextArg()144 const QString &CmdLineParser::nextArg()
145 {
146     TRACE_OBJ
147     Q_ASSERT(hasMoreArgs());
148     return m_arguments.at(m_pos++);
149 }
150 
handleCollectionFileOption()151 void CmdLineParser::handleCollectionFileOption()
152 {
153     TRACE_OBJ
154     if (hasMoreArgs()) {
155         const QString &fileName = nextArg();
156         m_collectionFile = getFileName(fileName);
157         if (m_collectionFile.isEmpty())
158             m_error = tr("The collection file '%1' does not exist.").
159                           arg(fileName);
160     } else {
161         m_error = tr("Missing collection file.");
162     }
163 }
164 
handleShowUrlOption()165 void CmdLineParser::handleShowUrlOption()
166 {
167     TRACE_OBJ
168     if (hasMoreArgs()) {
169         const QString &urlString = nextArg();
170         QUrl url(urlString);
171         if (url.isValid()) {
172             m_url = url;
173         } else
174             m_error = tr("Invalid URL '%1'.").arg(urlString);
175     } else {
176         m_error = tr("Missing URL.");
177     }
178 }
179 
handleShowOption()180 void CmdLineParser::handleShowOption()
181 {
182     TRACE_OBJ
183     handleShowOrHideOrActivateOption(Show);
184 }
185 
handleHideOption()186 void CmdLineParser::handleHideOption()
187 {
188     TRACE_OBJ
189     handleShowOrHideOrActivateOption(Hide);
190 }
191 
handleActivateOption()192 void CmdLineParser::handleActivateOption()
193 {
194     TRACE_OBJ
195     handleShowOrHideOrActivateOption(Activate);
196 }
197 
handleShowOrHideOrActivateOption(ShowState state)198 void CmdLineParser::handleShowOrHideOrActivateOption(ShowState state)
199 {
200     TRACE_OBJ
201     if (hasMoreArgs()) {
202         const QString &widget = nextArg().toLower();
203         if (widget == QLatin1String("contents"))
204             m_contents = state;
205         else if (widget == QLatin1String("index"))
206             m_index = state;
207         else if (widget == QLatin1String("bookmarks"))
208             m_bookmarks = state;
209         else if (widget == QLatin1String("search"))
210             m_search = state;
211         else
212             m_error = tr("Unknown widget: %1").arg(widget);
213     } else {
214         m_error = tr("Missing widget.");
215     }
216 }
217 
handleRegisterOption()218 void CmdLineParser::handleRegisterOption()
219 {
220     TRACE_OBJ
221     handleRegisterOrUnregisterOption(Register);
222 }
223 
handleUnregisterOption()224 void CmdLineParser::handleUnregisterOption()
225 {
226     TRACE_OBJ
227     handleRegisterOrUnregisterOption(Unregister);
228 }
229 
handleRegisterOrUnregisterOption(RegisterState state)230 void CmdLineParser::handleRegisterOrUnregisterOption(RegisterState state)
231 {
232     TRACE_OBJ
233     if (hasMoreArgs()) {
234         const QString &fileName = nextArg();
235         m_helpFile = getFileName(fileName);
236         if (m_helpFile.isEmpty())
237             m_error = tr("The Qt help file '%1' does not exist.").arg(fileName);
238         else
239             m_register = state;
240     } else {
241         m_error = tr("Missing help file.");
242     }
243 }
244 
handleSetCurrentFilterOption()245 void CmdLineParser::handleSetCurrentFilterOption()
246 {
247     TRACE_OBJ
248     if (hasMoreArgs())
249         m_currentFilter = nextArg();
250     else
251         m_error = tr("Missing filter argument.");
252 }
253 
getFileName(const QString & fileName)254 QString CmdLineParser::getFileName(const QString &fileName)
255 {
256     TRACE_OBJ
257     QFileInfo fi(fileName);
258     if (!fi.exists())
259         return QString();
260     return fi.absoluteFilePath();
261 }
262 
showMessage(const QString & msg,bool error)263 void CmdLineParser::showMessage(const QString &msg, bool error)
264 {
265     TRACE_OBJ
266     if (m_quiet)
267         return;
268 #ifdef Q_OS_WIN
269     QString message = QLatin1String("<pre>") % msg % QLatin1String("</pre>");
270     if (error)
271         QMessageBox::critical(0, tr("Error"), message);
272     else
273         QMessageBox::information(0, tr("Notice"), message);
274 #else
275     fprintf(error ? stderr : stdout, "%s\n", qPrintable(msg));
276 #endif
277 }
278 
setCollectionFile(const QString & file)279 void CmdLineParser::setCollectionFile(const QString &file)
280 {
281     TRACE_OBJ
282     m_collectionFile = file;
283 }
284 
collectionFile() const285 QString CmdLineParser::collectionFile() const
286 {
287     TRACE_OBJ
288     return m_collectionFile;
289 }
290 
collectionFileGiven() const291 bool CmdLineParser::collectionFileGiven() const
292 {
293     TRACE_OBJ
294     return m_arguments.contains(QLatin1String("-collectionfile"),
295         Qt::CaseInsensitive);
296 }
297 
url() const298 QUrl CmdLineParser::url() const
299 {
300     TRACE_OBJ
301     return m_url;
302 }
303 
enableRemoteControl() const304 bool CmdLineParser::enableRemoteControl() const
305 {
306     TRACE_OBJ
307     return m_enableRemoteControl;
308 }
309 
contents() const310 CmdLineParser::ShowState CmdLineParser::contents() const
311 {
312     TRACE_OBJ
313     return m_contents;
314 }
315 
index() const316 CmdLineParser::ShowState CmdLineParser::index() const
317 {
318     TRACE_OBJ
319     return m_index;
320 }
321 
bookmarks() const322 CmdLineParser::ShowState CmdLineParser::bookmarks() const
323 {
324     TRACE_OBJ
325     return m_bookmarks;
326 }
327 
search() const328 CmdLineParser::ShowState CmdLineParser::search() const
329 {
330     TRACE_OBJ
331     return m_search;
332 }
333 
currentFilter() const334 QString CmdLineParser::currentFilter() const
335 {
336     TRACE_OBJ
337     return m_currentFilter;
338 }
339 
removeSearchIndex() const340 bool CmdLineParser::removeSearchIndex() const
341 {
342     TRACE_OBJ
343     return m_removeSearchIndex;
344 }
345 
registerRequest() const346 CmdLineParser::RegisterState CmdLineParser::registerRequest() const
347 {
348     TRACE_OBJ
349     return m_register;
350 }
351 
helpFile() const352 QString CmdLineParser::helpFile() const
353 {
354     TRACE_OBJ
355     return m_helpFile;
356 }
357 
358 QT_END_NAMESPACE
359