1 | /*
|
---|
2 | * main.cpp - initialization and profile/settings handling
|
---|
3 | * Copyright (C) 2001-2003 Justin Karneges
|
---|
4 | *
|
---|
5 | * This program is free software; you can redistribute it and/or
|
---|
6 | * modify it under the terms of the GNU General Public License
|
---|
7 | * as published by the Free Software Foundation; either version 2
|
---|
8 | * of the License, or (at your option) any later version.
|
---|
9 | *
|
---|
10 | * This program is distributed in the hope that it will be useful,
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | * GNU General Public License for more details.
|
---|
14 | *
|
---|
15 | * You should have received a copy of the GNU General Public License
|
---|
16 | * along with this library; if not, write to the Free Software
|
---|
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
18 | *
|
---|
19 | */
|
---|
20 |
|
---|
21 | #include"main.h"
|
---|
22 |
|
---|
23 | #include"psiapplication.h"
|
---|
24 | #include<qtimer.h>
|
---|
25 |
|
---|
26 | #include<qprocess.h>
|
---|
27 | #include<qimage.h>
|
---|
28 | #include<qbitmap.h>
|
---|
29 | #include<qtextcodec.h>
|
---|
30 | #include<qsettings.h>
|
---|
31 | #include<qsocketdevice.h>
|
---|
32 | #include<qcombobox.h>
|
---|
33 | #include<qcheckbox.h>
|
---|
34 | #include<qmessagebox.h>
|
---|
35 | #include<qca.h>
|
---|
36 |
|
---|
37 | #if defined(Q_OS_OS2) && !defined(QT_OS2_NO_SYSEXCEPTIONS)
|
---|
38 | #include <qt_os2.h>
|
---|
39 | extern // defined in common.cpp
|
---|
40 | int psiOS2SysXcptCallback( QtOS2SysXcptReq req, QtOS2SysXcptWriter writer,
|
---|
41 | int /* reserved */ );
|
---|
42 | #endif
|
---|
43 |
|
---|
44 |
|
---|
45 | #include<stdlib.h>
|
---|
46 | #include<time.h>
|
---|
47 |
|
---|
48 | #include"common.h"
|
---|
49 | #include"profiles.h"
|
---|
50 | #include"profiledlg.h"
|
---|
51 | #include"xmpp.h"
|
---|
52 |
|
---|
53 | // need to remove this later
|
---|
54 | #include"hash.h"
|
---|
55 |
|
---|
56 | #include"eventdlg.h"
|
---|
57 | #include"chatdlg.h"
|
---|
58 | #ifdef USE_CRASH
|
---|
59 | # include"crash.h"
|
---|
60 | #endif
|
---|
61 |
|
---|
62 | #ifdef Q_OS_WIN
|
---|
63 | # include <qt_windows.h> // for RegDeleteKey
|
---|
64 | #endif
|
---|
65 |
|
---|
66 | using namespace XMPP;
|
---|
67 |
|
---|
68 | QTranslator *trans;
|
---|
69 | QTranslator *qttrans;
|
---|
70 | QString curLang = "en";
|
---|
71 | QString curLangName = QT_TR_NOOP("language_name");
|
---|
72 |
|
---|
73 | void setLang(const QString &lang)
|
---|
74 | {
|
---|
75 | //printf("changing lang: [%s]\n", lang.latin1());
|
---|
76 | trans->clear();
|
---|
77 | qttrans->clear();
|
---|
78 | if(lang == "en") {
|
---|
79 | curLang = lang;
|
---|
80 | curLangName = "English";
|
---|
81 | return;
|
---|
82 | }
|
---|
83 |
|
---|
84 | QStringList dirs;
|
---|
85 | QString subdir = "";
|
---|
86 | dirs += "." + subdir;
|
---|
87 | dirs += g.pathHome + subdir;
|
---|
88 | dirs += g.pathBase + subdir;
|
---|
89 | for(QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it) {
|
---|
90 | if(!QFile::exists(*it))
|
---|
91 | continue;
|
---|
92 | if(trans->load("psi_" + lang, *it)) {
|
---|
93 | // try to load qt library translation
|
---|
94 | qttrans->load("qt_" + lang, *it);
|
---|
95 | curLang = lang;
|
---|
96 | return;
|
---|
97 | }
|
---|
98 | }
|
---|
99 | }
|
---|
100 |
|
---|
101 | static void folderkeyRemove(QSettings &settings, const QString &d)
|
---|
102 | {
|
---|
103 | QStringList entries;
|
---|
104 | QStringList::Iterator it;
|
---|
105 |
|
---|
106 | entries = settings.subkeyList(d);
|
---|
107 | for(it = entries.begin(); it != entries.end(); ++it) {
|
---|
108 | QString str = d + "/" + *it;
|
---|
109 | folderkeyRemove(settings, str);
|
---|
110 | }
|
---|
111 |
|
---|
112 | entries = settings.entryList(d);
|
---|
113 | for(it = entries.begin(); it != entries.end(); ++it) {
|
---|
114 | QString str = d + "/" + *it;
|
---|
115 | settings.removeEntry(str);
|
---|
116 | }
|
---|
117 | settings.removeEntry(d);
|
---|
118 | }
|
---|
119 |
|
---|
120 |
|
---|
121 | PsiMain::PsiMain(QObject *par)
|
---|
122 | :QObject(par)
|
---|
123 | {
|
---|
124 | pcon = 0;
|
---|
125 |
|
---|
126 | // detect available language packs
|
---|
127 | langs.set("en", "English");
|
---|
128 |
|
---|
129 | QStringList dirs;
|
---|
130 | QString subdir = "";
|
---|
131 | dirs += "." + subdir;
|
---|
132 | dirs += g.pathHome + subdir;
|
---|
133 | dirs += g.pathBase + subdir;
|
---|
134 |
|
---|
135 | for(QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it) {
|
---|
136 | if(!QFile::exists(*it))
|
---|
137 | continue;
|
---|
138 | QDir d(*it);
|
---|
139 | QStringList entries = d.entryList();
|
---|
140 | for(QStringList::Iterator it2 = entries.begin(); it2 != entries.end(); ++it2) {
|
---|
141 | if(*it2 == "." || *it2 == "..")
|
---|
142 | continue;
|
---|
143 |
|
---|
144 | QString str = *it2;
|
---|
145 | // verify that it is a language file
|
---|
146 | if(str.left(4) != "psi_")
|
---|
147 | continue;
|
---|
148 | int n = str.find('.', 4);
|
---|
149 | if(n == -1)
|
---|
150 | continue;
|
---|
151 | if(str.mid(n) != ".qm")
|
---|
152 | continue;
|
---|
153 | QString lang = str.mid(4, n-4);
|
---|
154 |
|
---|
155 | //printf("found [%s], lang=[%s]\n", str.latin1(), lang.latin1());
|
---|
156 |
|
---|
157 | // get the language_name
|
---|
158 | QString name = QString("[") + str + "]";
|
---|
159 | QTranslator t(0);
|
---|
160 | if(!t.load(str, *it))
|
---|
161 | continue;
|
---|
162 |
|
---|
163 | if(t.contains("@default", "language_name", 0)) {
|
---|
164 | QString s = t.findMessage("@default", "language_name", 0).translation();
|
---|
165 | if(!s.isEmpty())
|
---|
166 | name = s;
|
---|
167 | }
|
---|
168 |
|
---|
169 | langs.set(lang, name);
|
---|
170 | }
|
---|
171 | }
|
---|
172 |
|
---|
173 | // load simple registry settings
|
---|
174 | QSettings *s = new QSettings;
|
---|
175 | s->setPath("psi.affinix.com", "Psi", QSettings::User); // make Psi load all prefs from HKCU on Windows systems
|
---|
176 | s->insertSearchPath(QSettings::Windows, "/Affinix");
|
---|
177 | s->insertSearchPath(QSettings::Unix, g.pathHome);
|
---|
178 | lastProfile = s->readEntry("/psi/lastProfile");
|
---|
179 | lastLang = s->readEntry("/psi/lastLang");
|
---|
180 | autoOpen = s->readBoolEntry("/psi/autoOpen", FALSE);
|
---|
181 | delete s;
|
---|
182 |
|
---|
183 | if(lastLang.isEmpty()) {
|
---|
184 | lastLang = QTextCodec::locale();
|
---|
185 | //printf("guessing locale: [%s]\n", lastLang.latin1());
|
---|
186 | }
|
---|
187 |
|
---|
188 | setLang(lastLang);
|
---|
189 |
|
---|
190 | if(autoOpen && !lastProfile.isEmpty() && profileExists(lastProfile)) {
|
---|
191 | // Auto-open the last profile
|
---|
192 | activeProfile = lastProfile;
|
---|
193 | QTimer::singleShot(0, this, SLOT(sessionStart()));
|
---|
194 | }
|
---|
195 | else {
|
---|
196 | if (!lastProfile.isEmpty() && !getProfilesList().isEmpty()) {
|
---|
197 | // Select a profile
|
---|
198 | QTimer::singleShot(0, this, SLOT(chooseProfile()));
|
---|
199 | }
|
---|
200 | else {
|
---|
201 | // Create & open the default profile
|
---|
202 | if (!profileExists("default") && !profileNew("default")) {
|
---|
203 | QMessageBox::critical(0, tr("Error"),
|
---|
204 | tr("There was an error creating the default profile."));
|
---|
205 | QTimer::singleShot(0, this, SLOT(bail()));
|
---|
206 | }
|
---|
207 | else {
|
---|
208 | lastProfile = activeProfile = "default";
|
---|
209 | autoOpen = true;
|
---|
210 | QTimer::singleShot(0, this, SLOT(sessionStart()));
|
---|
211 | }
|
---|
212 | }
|
---|
213 | }
|
---|
214 | }
|
---|
215 |
|
---|
216 | PsiMain::~PsiMain()
|
---|
217 | {
|
---|
218 | delete pcon;
|
---|
219 |
|
---|
220 | #ifdef Q_OS_WIN
|
---|
221 | // remove Psi's settings from HKLM
|
---|
222 | QSettings *rs = new QSettings;
|
---|
223 | rs->setPath("Affinix", "psi", QSettings::Global);
|
---|
224 | rs->removeEntry("/lastProfile");
|
---|
225 | rs->removeEntry("/lastLang");
|
---|
226 | rs->removeEntry("/autoOpen");
|
---|
227 |
|
---|
228 | QString affinixKey = "Software\\Affinix";
|
---|
229 | #ifdef Q_OS_TEMP
|
---|
230 | RegDeleteKeyW(HKEY_LOCAL_MACHINE, affinixKey.ucs2());
|
---|
231 | #else
|
---|
232 | RegDeleteKeyA(HKEY_LOCAL_MACHINE, affinixKey.latin1());
|
---|
233 | #endif
|
---|
234 | delete rs;
|
---|
235 | #endif
|
---|
236 |
|
---|
237 | QSettings *s = new QSettings;
|
---|
238 | s->setPath("psi.affinix.com", "Psi", QSettings::User); // make Psi load all prefs from HKCU on Windows systems
|
---|
239 | s->insertSearchPath(QSettings::Windows, "/Affinix");
|
---|
240 | s->insertSearchPath(QSettings::Unix, g.pathHome);
|
---|
241 | s->writeEntry("/psi/lastProfile", lastProfile);
|
---|
242 | s->writeEntry("/psi/lastLang", lastLang);
|
---|
243 | s->writeEntry("/psi/autoOpen", autoOpen);
|
---|
244 | delete s;
|
---|
245 | }
|
---|
246 |
|
---|
247 | static bool loadGlobal()
|
---|
248 | {
|
---|
249 | // set the paths
|
---|
250 | g.pathBase = getResourcesDir();
|
---|
251 | char *p = getenv("PSIDATADIR");
|
---|
252 | if(p)
|
---|
253 | g.pathHome = p;
|
---|
254 | else
|
---|
255 | g.pathHome = getHomeDir();
|
---|
256 | g.pathProfiles = g.pathHome + "/profiles";
|
---|
257 |
|
---|
258 | QDir d(g.pathProfiles);
|
---|
259 | if(!d.exists()) {
|
---|
260 | QDir d(g.pathHome);
|
---|
261 | d.mkdir("profiles");
|
---|
262 | }
|
---|
263 |
|
---|
264 | return TRUE;
|
---|
265 | }
|
---|
266 |
|
---|
267 | void PsiMain::chooseProfile()
|
---|
268 | {
|
---|
269 | if(pcon) {
|
---|
270 | delete pcon;
|
---|
271 | pcon = 0;
|
---|
272 | }
|
---|
273 |
|
---|
274 | QString str = "";
|
---|
275 |
|
---|
276 | // dirty, dirty, dirty hack
|
---|
277 | is = new PsiIconset;
|
---|
278 | is->loadSystem();
|
---|
279 |
|
---|
280 | while(1) {
|
---|
281 | ProfileOpenDlg *w = new ProfileOpenDlg(lastProfile, langs, curLang);
|
---|
282 | w->ck_auto->setChecked(autoOpen);
|
---|
283 | int r = w->exec();
|
---|
284 | // lang change
|
---|
285 | if(r == 10) {
|
---|
286 | QString newLang = w->newLang;
|
---|
287 | delete w;
|
---|
288 | setLang(newLang);
|
---|
289 | lastLang = curLang;
|
---|
290 | continue;
|
---|
291 | }
|
---|
292 | else {
|
---|
293 | if(r == QDialog::Accepted)
|
---|
294 | str = w->cb_profile->currentText();
|
---|
295 | autoOpen = w->ck_auto->isChecked();
|
---|
296 | delete w;
|
---|
297 | break;
|
---|
298 | }
|
---|
299 | }
|
---|
300 |
|
---|
301 | delete is;
|
---|
302 |
|
---|
303 | if(str.isEmpty()) {
|
---|
304 | quit();
|
---|
305 | return;
|
---|
306 | }
|
---|
307 |
|
---|
308 | // only set lastProfile if the user opened it
|
---|
309 | lastProfile = str;
|
---|
310 |
|
---|
311 | activeProfile = str;
|
---|
312 | sessionStart();
|
---|
313 | }
|
---|
314 |
|
---|
315 | void PsiMain::sessionStart()
|
---|
316 | {
|
---|
317 | // get a PsiCon
|
---|
318 | pcon = new PsiCon();
|
---|
319 | if(!pcon->init()) {
|
---|
320 | delete pcon;
|
---|
321 | pcon = 0;
|
---|
322 | quit();
|
---|
323 | return;
|
---|
324 | }
|
---|
325 | connect(pcon, SIGNAL(quit(int)), SLOT(sessionQuit(int)));
|
---|
326 | }
|
---|
327 |
|
---|
328 | void PsiMain::sessionQuit(int x)
|
---|
329 | {
|
---|
330 | if(x == PsiCon::QuitProgram) {
|
---|
331 | QTimer::singleShot(0, this, SLOT(bail()));
|
---|
332 | }
|
---|
333 | else if(x == PsiCon::QuitProfile) {
|
---|
334 | QTimer::singleShot(0, this, SLOT(chooseProfile()));
|
---|
335 | }
|
---|
336 | }
|
---|
337 |
|
---|
338 | void PsiMain::bail()
|
---|
339 | {
|
---|
340 | if(pcon) {
|
---|
341 | delete pcon;
|
---|
342 | pcon = 0;
|
---|
343 | }
|
---|
344 | quit();
|
---|
345 | }
|
---|
346 |
|
---|
347 | int main(int argc, char *argv[])
|
---|
348 | {
|
---|
349 | #if defined(Q_OS_OS2) && !defined(QT_OS2_NO_SYSEXCEPTIONS)
|
---|
350 | // install the OS/2 system exception handler and callback
|
---|
351 | QtOS2SysXcptMainHandler sysXcptHandler( psiOS2SysXcptCallback );
|
---|
352 | #endif
|
---|
353 |
|
---|
354 | // add library paths before creating QApplication
|
---|
355 | if (!loadGlobal())
|
---|
356 | return 1;
|
---|
357 |
|
---|
358 | QApplication::addLibraryPath(g.pathHome);
|
---|
359 | QApplication::addLibraryPath(getResourcesDir());
|
---|
360 |
|
---|
361 | PsiApplication *app = new PsiApplication(argc, argv);
|
---|
362 |
|
---|
363 | #ifdef USE_CRASH
|
---|
364 | int useCrash = true;
|
---|
365 | int i;
|
---|
366 | for(i = 1; i < argc; ++i) {
|
---|
367 | QString str = argv[i];
|
---|
368 | if ( str == "--nocrash" )
|
---|
369 | useCrash = false;
|
---|
370 | }
|
---|
371 |
|
---|
372 | if ( useCrash )
|
---|
373 | Crash::registerSigsegvHandler(argv[0]);
|
---|
374 | #endif
|
---|
375 |
|
---|
376 | // seed the random number generator
|
---|
377 | srand(time(NULL));
|
---|
378 |
|
---|
379 | //dtcp_port = 8000;
|
---|
380 | for(int n = 1; n < argc; ++n) {
|
---|
381 | QString str = argv[n];
|
---|
382 | QString var, val;
|
---|
383 | int x = str.find('=');
|
---|
384 | if(x == -1) {
|
---|
385 | var = str;
|
---|
386 | val = "";
|
---|
387 | }
|
---|
388 | else {
|
---|
389 | var = str.mid(0,x);
|
---|
390 | val = str.mid(x+1);
|
---|
391 | }
|
---|
392 |
|
---|
393 | if(var == "--no-gpg")
|
---|
394 | use_gpg = false;
|
---|
395 | else if(var == "--no-gpg-agent")
|
---|
396 | no_gpg_agent = true;
|
---|
397 | //else if(var == "--linktest")
|
---|
398 | // link_test = true;
|
---|
399 | }
|
---|
400 |
|
---|
401 | //if(link_test)
|
---|
402 | // printf("Link test enabled\n");
|
---|
403 |
|
---|
404 | // silly winsock workaround
|
---|
405 | //QSocketDevice *d = new QSocketDevice;
|
---|
406 | //delete d;
|
---|
407 |
|
---|
408 | // japanese
|
---|
409 | trans = new QTranslator(0);
|
---|
410 | app->installTranslator(trans);
|
---|
411 |
|
---|
412 | qttrans = new QTranslator(0);
|
---|
413 | app->installTranslator(qttrans);
|
---|
414 |
|
---|
415 | // need SHA1 for Iconset sound
|
---|
416 | if(!QCA::isSupported(QCA::CAP_SHA1))
|
---|
417 | QCA::insertProvider(XMPP::createProviderHash());
|
---|
418 |
|
---|
419 | PsiMain *psi = new PsiMain;
|
---|
420 | QObject::connect(psi, SIGNAL(quit()), app, SLOT(quit()));
|
---|
421 | app->exec();
|
---|
422 | delete psi;
|
---|
423 |
|
---|
424 | app->removeTranslator(trans);
|
---|
425 | delete trans;
|
---|
426 | trans = 0;
|
---|
427 | app->removeTranslator(qttrans);
|
---|
428 | delete qttrans;
|
---|
429 | qttrans = 0;
|
---|
430 |
|
---|
431 | delete app;
|
---|
432 |
|
---|
433 | QCA::unloadAllPlugins();
|
---|
434 |
|
---|
435 | return 0;
|
---|
436 | }
|
---|