1 /*
2 CommandLine.cpp
3
4 This file is part of Charm, a task-based time tracking application.
5
6 Copyright (C) 2008-2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
7
8 Author: Mirko Boehm <mirko.boehm@kdab.com>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "CommandLine.h"
25 #include "Exceptions.h"
26
27 #include <QObject>
28 #include <QString>
29
30 extern "C" {
31 #include <getopt.h>
32 }
33
34 #include <iostream>
35
CommandLine(int argc,char ** argv)36 CommandLine::CommandLine(int argc, char **argv)
37 : m_mode(Mode_None)
38 , m_index()
39 , m_userid()
40 {
41 opterr = 0;
42 int ch;
43 while ((ch = getopt(argc, argv, "vhza:x:c:ri:u:m:")) != -1)
44 {
45 if (ch == '?') {
46 // unparsable argument
47 int option = optopt;
48 if (option == 'a') {
49 throw UsageException(QObject::tr(
50 "Option -a requires a filename argument"));
51 }
52 if (option == 'i') {
53 throw UsageException(QObject::tr(
54 "Option -i requires an index argument"));
55 }
56 if (option == 'x') {
57 throw UsageException(QObject::tr(
58 "Option -x requires a filename argument"));
59 }
60 if (option == 'm')
61 throw UsageException(QObject::tr("Option -m requires a user comment argument"));
62 if (isprint(option)) {
63 throw UsageException(
64 QObject::tr("Unknown option %1").arg(option));
65 } else {
66 int code = static_cast<int>(option);
67 throw UsageException(QObject::tr("Unknown character %1").arg(
68 code));
69 }
70 }
71
72 switch (ch) {
73 case 'a':
74 if (m_mode != Mode_None) {
75 QString msg = QObject::tr(
76 "Multiple mode selections, please use only one");
77 throw UsageException(msg);
78 }
79 // mode
80 m_filename = QString::fromLocal8Bit(optarg);
81 m_mode = Mode_AddTimesheet;
82 break;
83 case 'x':
84 if (m_mode != Mode_None) {
85 QString msg = QObject::tr(
86 "Multiple mode selections, please use only one");
87 throw UsageException(msg);
88 }
89 // mode
90 m_exportFilename = QString::fromLocal8Bit(optarg);
91 m_mode = Mode_ExportProjectcodes;
92 break;
93 case 'c':
94 if (m_mode != Mode_None) {
95 QString msg = QObject::tr(
96 "Multiple mode selections, please use only one");
97 throw UsageException(msg);
98 }
99 m_userName = QString::fromLocal8Bit(optarg);
100 m_mode = Mode_CheckOrCreateUser;
101 break;
102
103 case 'r': // remove
104 if (m_mode != Mode_None) {
105 QString msg = QObject::tr(
106 "Multiple mode selections, please use only one");
107 throw UsageException(msg);
108 }
109 m_mode = Mode_RemoveTimesheet;
110 break;
111 case 'u': // user id
112 {
113 if (m_userid != 0) {
114 QString msg = QObject::tr(
115 "Multiple user id selections, please use only one");
116 throw UsageException(msg);
117 }
118
119 QString arg = QString::fromLocal8Bit(optarg);
120 bool ok;
121 m_userid = arg.toInt(&ok);
122 if (!ok || m_userid < 1) {
123 throw UsageException(
124 QObject::tr(
125 "Argument to option -u must be an integer user id larger than zero"));
126 }
127 break;
128 }
129 case 'i':
130 {
131 // index
132 if (m_index != 0) {
133 QString msg = QObject::tr(
134 "Multiple index selections, please use only one");
135 throw UsageException(msg);
136 }
137
138 QString arg = QString::fromLocal8Bit(optarg);
139 bool ok;
140 m_index = arg.toInt(&ok);
141 if (!ok || m_index < 1) {
142 throw UsageException(
143 QObject::tr(
144 "Argument to option -i must be an integer index larger than zero"));
145 }
146 break;
147 }
148 case 'm':
149 {
150 if (!m_userComment.isEmpty()) {
151 QString msg = QObject::tr("Multiple user comments specified, please use only one");
152 throw UsageException(msg);
153 }
154 QString arg = QString::fromLocal8Bit(optarg);
155 m_userComment = arg;
156 break;
157 }
158 case 'z':
159 // initialize the database
160 m_mode = Mode_InitializeDatabase;
161 break;
162 case 'v':
163 m_mode = Mode_PrintVersion;
164 break;
165 case 'h':
166 default:
167 // help/usage
168 m_mode = Mode_DescribeUsage;
169 //return;
170 }
171 }
172
173 // check for other command line arguments and yell at the user:
174 if (optind < argc) {
175 QString msg;
176 for (int index = optind; index < argc; index++) {
177 msg += QObject::tr("Unknown extra argument \"%1\"\n").arg(
178 QString::fromLatin1(argv[index]));
179 }
180 throw UsageException(msg);
181 }
182
183 // final checks:
184 QString msg;
185 if (m_mode == Mode_None) {
186 msg += QObject::tr("No mode selected. Use one of -a filename, -r.");
187 } else if (m_mode == Mode_RemoveTimesheet) {
188 if (m_index < 1) {
189 msg += QObject::tr("No index specified. -a filename, "
190 " -r require an index specified with -i.");
191 }
192
193 if (m_userid < 1) {
194 msg += QObject::tr("No userid specified. -a filename, "
195 " -r require a user id specified with -u.");
196 }
197 } else if (m_mode == Mode_AddTimesheet) {
198 if (m_index > 0)
199 msg += QObject::tr(
200 "Specifying an index when adding a time sheet is not supported anymore.");
201 }
202
203 if (!msg.isEmpty())
204 throw UsageException(msg);
205 }
206
CommandLine(const QString file,const int userId)207 CommandLine::CommandLine(const QString file, const int userId)
208 {
209 m_filename = file;
210 m_userid = userId;
211 }
212
CommandLine(const int userId,const int index)213 CommandLine::CommandLine(const int userId, const int index)
214 {
215 m_userid = userId;
216 m_index = index;
217 }
218
mode() const219 CommandLine::Mode CommandLine::mode() const
220 {
221 return m_mode;
222 }
223
userName() const224 QString CommandLine::userName() const
225 {
226 return m_userName;
227 }
228
userComment() const229 QString CommandLine::userComment() const
230 {
231 return m_userComment;
232 }
233
filename() const234 QString CommandLine::filename() const
235 {
236 return m_filename;
237 }
238
exportFilename() const239 QString CommandLine::exportFilename() const
240 {
241 return m_exportFilename;
242 }
243
userid() const244 int CommandLine::userid() const
245 {
246 return m_userid;
247 }
248
index() const249 int CommandLine::index() const
250 {
251 return m_index;
252 }
253
usage()254 void CommandLine::usage()
255 {
256 using namespace std;
257 cout << "Timesheet Processor, (C) 2008 Mirko Boehm, KDAB" << endl
258 << "Usage: " << endl
259 << " * TimesheetProzessor -h <-- get help"
260 << endl
261 << " * TimesheetProzessor -v <-- print version"
262 << endl
263 << " * TimesheetProzessor -a filename -u userid -m comment <-- add timesheet from file"
264 << endl
265 <<
266 " * TimesheetProzessor -r -i index -u userid <-- remove timesheet at index"
267 << endl
268 <<
269 " * TimesheetProzessor -c username <-- create user if user does not exist"
270 << endl
271 <<
272 " * TimesheetProzessor -x filename <-- export project codes to XML file"
273 << endl
274 <<
275 " * TimesheetProzessor -z <-- initialize database (careful!)"
276 << endl;
277 }
278