[2] | 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>
|
---|
[84] | 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 |
|
---|
[2] | 45 | #include<stdlib.h>
|
---|
| 46 | #include<time.h>
|
---|
[84] | 47 |
|
---|
[2] | 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 | {
|
---|
[84] | 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 |
|
---|
[2] | 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 | }
|
---|