1 /*
2 SPDX-License-Identifier: GPL-2.0-or-later
3 SPDX-FileCopyrightText: 2002-2021 Umbrello UML Modeller Authors <umbrello-devel@kde.org>
4 */
5
6 // app includes
7 #include "debug_utils.h"
8 #include "uml.h"
9 #include "version.h"
10 #include "umldoc.h"
11 #include "cmdlineexportallviewsevent.h"
12 #include "umlviewimageexportermodel.h"
13 #include "umbrellosettings.h"
14
15 // kde includes
16 #if QT_VERSION > 0x050000
17 // prevent including of <kaboutdata.h>
18 #define KABOUTDATA_H
19 #include <k4aboutdata.h>
20 #define KAboutData K4AboutData
21 #include <KCrash>
22 #else
23 #include <kaboutdata.h>
24 #endif
25
26 #include <kapplication.h>
27 #include <kcmdlineargs.h>
28 #include <kconfig.h>
29 #include <KLocalizedString>
30 #include <ktip.h>
31 #include <KUrl>
32
33 // KF5 uses i18n
34 #define i18n ki18n
35
36 #include <stdio.h>
37
38 void getFiles(QStringList& files, const QString& path, QStringList& filters);
39
40 /**
41 * Determines if the application GUI should be shown based on command line arguments.
42 * @todo Add options to use the documentation generators from command line.
43 *
44 * @param args The command line arguments given.
45 * @return True if the GUI should be shown, false otherwise.
46 */
showGUI(KCmdLineArgs * args)47 bool showGUI(KCmdLineArgs *args)
48 {
49 if (args->getOptionList("export").size() > 0 || args->isSet("export-formats")) {
50 return false;
51 }
52 return true;
53 }
54
55 /**
56 * Initializes the document used by the application.
57 * If a file was specified in command line arguments, opens that file. Else, it
58 * opens the last opened file, or a new file if there isn't any "last file used"
59 * in the configuration.
60 *
61 * @param args The command line arguments given.
62 */
initDocument(KCmdLineArgs * args,Uml::ProgrammingLanguage::Enum progLang)63 void initDocument(KCmdLineArgs *args, Uml::ProgrammingLanguage::Enum progLang)
64 {
65 if (args->count()) {
66 UMLApp::app()->openDocumentFile(args->url(0));
67 } else {
68 bool last = UmbrelloSettings::loadlast();
69 QString file = UmbrelloSettings::lastFile();
70 if(last && !file.isEmpty()) {
71 UMLApp::app()->openDocumentFile(KUrl(file));
72 } else {
73 UMLApp::app()->newDocument();
74 if (progLang != Uml::ProgrammingLanguage::Reserved)
75 UMLApp::app()->setActiveLanguage(progLang);
76 }
77 }
78 }
79
80 /**
81 * Export all the views in the document using the command line args set by the user.
82 * Errors that occurred while exporting, if any, are shown using uError().
83 *
84 * @param args The command line arguments given.
85 * @param exportOpt A list containing all the "export" arguments given.
86 */
87
exportAllViews(KCmdLineArgs * args,const QStringList & exportOpt)88 void exportAllViews(KCmdLineArgs *args, const QStringList &exportOpt)
89 {
90 QString extension(exportOpt.last());
91 uDebug() << "extension: " << extension;
92
93 // export to the specified directory, or the directory where the file is saved
94 // if no directory was specified
95 QUrl directory;
96 QStringList directoryOpt = args->getOptionList("directory");
97 if (directoryOpt.size() > 0) {
98 directory = KCmdLineArgs::makeURL(directoryOpt.last().toLocal8Bit());
99 } else {
100 QFileInfo fi(UMLApp::app()->document()->url().toLocalFile());
101 directory = QUrl::fromLocalFile(fi.absolutePath());
102 }
103
104 bool useFolders = args->isSet("use-folders");
105
106 uDebug() << "directory: " << directory;
107
108 // the event is posted so when the Qt loop begins it's processed. UMLApp process this event executing
109 // the method it provides for exporting the views. Once all the views were exported, a quit event
110 // is sent and the app finishes without user interaction
111 kapp->postEvent(UMLApp::app(), new CmdLineExportAllViewsEvent(extension, directory, useFolders));
112 }
113
main(int argc,char * argv[])114 int main(int argc, char *argv[])
115 {
116 KAboutData aboutData("umbrello",
117 0,
118 i18n("Umbrello UML Modeller"),
119 umbrelloVersion(),
120 i18n("Umbrello – Visual development environment for software, "
121 "based on the industry standard Unified Modelling Language (UML).<br/>"
122 "See also <a href=\"http://www.omg.org/spec/\">http://www.omg.org/spec/</a>."),
123 KAboutData::License_GPL,
124 i18n("Copyright © 2001 Paul Hensgen,\nCopyright © 2002-2021 Umbrello UML Modeller Authors"),
125 KLocalizedString(),
126 "http://umbrello.kde.org/");
127 aboutData.addAuthor(i18n("Paul Hensgen"), i18n("Author of initial version."), "phensgen@users.sourceforge.net");
128 aboutData.addAuthor(i18n("Umbrello UML Modeller Authors"), KLocalizedString(), "umbrello-devel@kde.org");
129
130 // authors with more than 200 commits: git shortlog -seu | sort -g
131 aboutData.addCredit(i18n("Oliver Kellogg"),
132 i18n("Bug fixing, porting work, code cleanup, new features."),
133 "okellogg@users.sourceforge.net");
134 aboutData.addCredit(i18n("Ralf Habacker"),
135 i18n("Bug fixing, porting work, code cleanup, new features."),
136 "ralf.habacker@freenet.de");
137 aboutData.addCredit(i18n("Andi Fischer"),
138 i18n("Porting work, code cleanup, new features."),
139 "andi.fischer@hispeed.ch");
140 aboutData.addCredit(i18n("Jonathan Riddell"),
141 i18n("Current maintainer."),
142 "jr@jriddell.org");
143 aboutData.addCredit(i18n("Brian Thomas"),
144 i18n("A lot of work for C++ and Java code generation. Codeeditor."),
145 "thomas@mail630.gsfc.nasa.gov");
146
147 KCmdLineArgs::init(argc, argv, &aboutData);
148 KCmdLineOptions options;
149 options.add("+[File]", i18n("File to open"));
150 options.add("export <extension>", i18n("export diagrams to extension and exit"));
151 options.add("export-formats", i18n("list available export extensions"));
152 options.add("directory <url>", i18n("the local directory to save the exported diagrams in"), I18N_NOOP("the directory of the file"));
153 options.add("import-files", i18n("import files"));
154 options.add("languages", i18n("list supported languages"));
155 options.add("use-folders", i18n("keep the tree structure used to store the views in the document in the target directory"));
156 options.add("import-directory <dir>", i18n("import files from directory <dir>"));
157 for (int i = Uml::ProgrammingLanguage::ActionScript; i <= Uml::ProgrammingLanguage::Reserved; i++) {
158 Uml::ProgrammingLanguage::Enum pl = Uml::ProgrammingLanguage::fromInt(i);
159 QByteArray optionString = "set-language-" + Uml::ProgrammingLanguage::toString(pl).toLower().toLocal8Bit();
160 options.add(optionString, i18n("set active language"));
161 }
162 KCmdLineArgs::addCmdLineOptions(options); // Add our own options.
163 KApplication app;
164 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
165 #if QT_VERSION > 0x050000
166 KCrash::initialize();
167 KLocalizedString::setApplicationDomain("umbrello");
168 Q_INIT_RESOURCE(ui);
169 #endif
170
171 Q_INIT_RESOURCE(icons);
172 app.setLayoutDirection(UmbrelloSettings::rightToLeftUI() ? Qt::RightToLeft : Qt::LeftToRight);
173 QPointer<UMLApp> uml;
174 if (app.isSessionRestored()) {
175 kRestoreMainWindows< UMLApp >();
176 } else {
177 if (args->isSet("export-formats")) {
178 foreach(const QString& type, UMLViewImageExporterModel::supportedImageTypes())
179 fprintf(stdout, "%s\n", qPrintable(type));
180 return 0;
181 } else if (args->isSet("languages")) {
182 for (int i = Uml::ProgrammingLanguage::ActionScript; i <= Uml::ProgrammingLanguage::Reserved; i++) {
183 Uml::ProgrammingLanguage::Enum pl = Uml::ProgrammingLanguage::fromInt(i);
184 fprintf(stdout, "%s\n", qPrintable(Uml::ProgrammingLanguage::toString(pl)));
185 }
186 return 0;
187 }
188
189 uml = new UMLApp();
190 app.processEvents();
191
192 if (showGUI(args)) {
193 uml->show();
194 }
195
196 Uml::ProgrammingLanguage::Enum lang = Uml::ProgrammingLanguage::Reserved;
197 for(int i = Uml::ProgrammingLanguage::ActionScript; i < Uml::ProgrammingLanguage::Reserved; i++) {
198 Uml::ProgrammingLanguage::Enum pl = Uml::ProgrammingLanguage::fromInt(i);
199 QByteArray langString = "set-language-";
200 langString += Uml::ProgrammingLanguage::toString(pl).toLower().toLocal8Bit();
201 if (args->isSet(langString)) {
202 lang = Uml::ProgrammingLanguage::fromInt(i);
203 }
204 }
205
206 if (args->isSet("import-files") && args->count() > 0) {
207 QStringList importList;
208 for (int i = 0; i < args->count(); i++)
209 importList.append(args->url(i).toLocalFile());
210 uml->newDocument();
211 if (lang != Uml::ProgrammingLanguage::Reserved)
212 uml->setActiveLanguage(lang);
213 uml->importFiles(importList);
214 }
215 else if (args->isSet("import-directory")) {
216 uml->newDocument();
217 if (lang != Uml::ProgrammingLanguage::Reserved)
218 uml->setActiveLanguage(lang);
219 QStringList filter = Uml::ProgrammingLanguage::toExtensions(uml->activeLanguage());
220 QString dir = args->getOption("import-directory");
221 QStringList listFile;
222 getFiles(listFile, dir, filter);
223 uml->importFiles(listFile, dir);
224 }
225 else {
226 initDocument(args, lang);
227 }
228
229 // export option
230 QStringList exportOpt = args->getOptionList("export");
231 if (exportOpt.size() > 0) {
232 exportAllViews(args, exportOpt);
233 }
234 }
235 int result = app.exec();
236 delete uml;
237 return result;
238 }
239