source: psi/trunk/src/main.cpp@ 85

Last change on this file since 85 was 84, checked in by dmik, 19 years ago

Psi: Added installation of the OS/2 System Exception handler (QtOS2SysXcptHandler) on the main thread.

File size: 9.4 KB
Line 
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>
39extern // defined in common.cpp
40int 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
66using namespace XMPP;
67
68QTranslator *trans;
69QTranslator *qttrans;
70QString curLang = "en";
71QString curLangName = QT_TR_NOOP("language_name");
72
73void 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
101static 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
121PsiMain::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
216PsiMain::~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
247static 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
267void 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
315void 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
328void 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
338void PsiMain::bail()
339{
340 if(pcon) {
341 delete pcon;
342 pcon = 0;
343 }
344 quit();
345}
346
347int 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}
Note: See TracBrowser for help on using the repository browser.