1 //**********************************************************************************
2 //EncryptPad Copyright 2021 Evgeny Pokhilko
3 //<http://www.evpo.net/encryptpad>
4 //
5 //This file is part of EncryptPad
6 //
7 //EncryptPad is free software: you can redistribute it and/or modify
8 //it under the terms of the GNU General Public License as published by
9 //the Free Software Foundation, either version 2 of the License, or
10 //(at your option) any later version.
11 //
12 //EncryptPad is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with EncryptPad.  If not, see <http://www.gnu.org/licenses/>.
19 //**********************************************************************************
20 #include <QApplication>
21 #include <QTextCodec>
22 #include <QTranslator>
23 #include <QResource>
24 #include <QDirIterator>
25 #include <QLocale>
26 #include <QQueue>
27 #include <string>
28 #include "mainwindow.h"
29 #include "application.h"
30 #include "repository.h"
31 #include "diagnostic_log.h"
32 #include "plog/Log.h"
33 
34 namespace
35 {
findLangResource(const QString & prefix,const QString & userLang)36     QString findLangResource(const QString &prefix, const QString &userLang)
37     {
38         QString empty;
39         QString lowerUserLang = userLang.toLower();
40         if(lowerUserLang.indexOf('-') != -1)
41         {
42             lowerUserLang = lowerUserLang.left(lowerUserLang.indexOf('-'));
43         }
44 
45         if(lowerUserLang.length() != 2)
46             return empty;
47 
48         QDirIterator it(":/cultures/");
49         while(it.hasNext())
50         {
51             QString fullPath = it.next();
52             QString lang = it.fileName();
53 
54             if(!lang.startsWith(prefix))
55                 continue;
56 
57             lang = lang.right(lang.length() - prefix.length());
58             if(lang.indexOf('_') == -1)
59                 continue;
60 
61             lang = lang.left(lang.indexOf('_'));
62             if(lang.length() != 2)
63                 continue;
64 
65             if(lang == lowerUserLang)
66                 return fullPath;
67         }
68 
69         return empty;
70     }
71 
72     struct CommandArguments
73     {
74         QString fileName;
75         QString language;
76         QString logFile;
77         QString logSeverity;
78     };
79 
parseArguments(const Application & app)80     CommandArguments parseArguments(const Application &app)
81     {
82         CommandArguments empty;
83         CommandArguments retVal;
84         int argCount = app.arguments().length();
85         if(argCount == 0)
86             return retVal;
87 
88         QQueue<QString> queue;
89         queue.append(app.arguments());
90         // remove the executable
91         queue.pop_front();
92         while(!queue.isEmpty())
93         {
94             QString arg = queue.front();
95             if(arg == "--lang")
96             {
97                 queue.pop_front();
98                 if(queue.isEmpty())
99                     return empty;
100 
101                 retVal.language = queue.front();
102             }
103             else if(arg == "--log-file")
104             {
105                 queue.pop_front();
106                 if(queue.isEmpty())
107                     return empty;
108 
109                 retVal.logFile = queue.front();
110 
111             }
112             else if(arg == "--log-severity")
113             {
114                 queue.pop_front();
115                 if(queue.isEmpty())
116                     return empty;
117 
118                 retVal.logSeverity = queue.front();
119             }
120             else
121             {
122                 retVal.fileName = queue.front();
123             }
124             queue.pop_front();
125         }
126 
127         return retVal;
128     }
129 }
130 
loadTranslatorResource(Application & app,QTranslator & translator,QResource & resource)131 bool loadTranslatorResource(Application &app, QTranslator &translator, QResource &resource)
132 {
133     bool result = translator.load(resource.data(), resource.size());
134     assert(result);
135     result |= app.installTranslator(&translator);
136     return result;
137 }
138 
loadTranslatorResource(Application & app,QTranslator & translator,const QString & path)139 bool loadTranslatorResource(Application &app, QTranslator &translator, const QString &path)
140 {
141     QResource resource(path);
142     return loadTranslatorResource(app, translator, resource);
143 }
144 
main(int argc,char * argv[])145 int main(int argc, char *argv[])
146 {
147     Q_INIT_RESOURCE(EncryptPad);
148 
149     Application app(argc, argv);
150     CommandArguments arguments = parseArguments(app);
151     assert(argc >= 1);
152 
153     if(!arguments.logFile.isEmpty())
154     {
155         plog::init(EncryptPad::ParsePlogSeverity(arguments.logSeverity.toStdString()),
156                 arguments.logFile.toStdString().c_str());
157         LOG_INFO << "Log instance started";
158     }
159 
160     EncryptPad::InitializeRepositoryPath(argv[0]);
161 
162     QStringList userLangs;
163     if(arguments.language.isEmpty())
164     {
165         userLangs.append(QLocale::system().uiLanguages());
166     }
167     else
168     {
169         userLangs.append(arguments.language);
170     }
171     QString resourcePath;
172     QString qtExcerptPath;
173     for(QString userLang : userLangs)
174     {
175         if(userLang == "en" || userLang.startsWith("en-"))
176             break;
177         resourcePath = findLangResource("encryptpad_", userLang);
178         if(resourcePath.isEmpty())
179             continue;
180 
181         qtExcerptPath = findLangResource("qt_excerpt_", userLang);
182         assert(!qtExcerptPath.isEmpty());
183         break;
184     }
185 
186     QTranslator translator;
187     QTranslator excerptTranslator;
188 
189     if(!resourcePath.isEmpty())
190     {
191         bool result = loadTranslatorResource(app, translator, resourcePath);
192         assert(result);
193         (void)result;
194     }
195 
196     if(!qtExcerptPath.isEmpty())
197     {
198         bool result = loadTranslatorResource(app, excerptTranslator, qtExcerptPath);
199         assert(result);
200         (void)result;
201     }
202 
203     app.setOrganizationName("Evpo"); //
204     app.setApplicationName("EncryptPad");
205 
206     MainWindow mainWin;
207     app.setMainWindow(&mainWin);
208     mainWin.show();
209 
210     if(!arguments.fileName.isEmpty())
211         mainWin.open(arguments.fileName);
212 
213     return app.exec();
214 }
215