vidalia.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QDir>
00018 #include <QTimer>
00019 #include <QTextStream>
00020 #include <QStyleFactory>
00021 #include <QShortcut>
00022 #include <languagesupport.h>
00023 #include <vmessagebox.h>
00024 #include <stringutil.h>
00025 #include <html.h>
00026 #include <stdlib.h>
00027
00028 #include "vidalia.h"
00029
00030
00031 #define ARG_LANGUAGE "lang"
00032 #define ARG_GUISTYLE "style"
00033 #define ARG_RESET "reset"
00034 #define ARG_HELP "help"
00035 #define ARG_DATADIR "datadir"
00036 #define ARG_PIDFILE "pidfile"
00037 #define ARG_LOGFILE "logfile"
00038 #define ARG_LOGLEVEL "loglevel"
00039
00040
00041
00042 QMap<QString, QString> Vidalia::_args;
00043 QString Vidalia::_style;
00044 QString Vidalia::_language;
00045 TorControl* Vidalia::_torControl = 0;
00046 Log Vidalia::_log;
00047
00048
00049
00050
00051 void
00052 Vidalia::qt_msg_handler(QtMsgType type, const char *s)
00053 {
00054 QString msg(s);
00055 switch (type) {
00056 case QtDebugMsg:
00057 vDebug("QtDebugMsg: %1").arg(msg);
00058 break;
00059 case QtWarningMsg:
00060 vNotice("QtWarningMsg: %1").arg(msg);
00061 break;
00062 case QtCriticalMsg:
00063 vWarn("QtCriticalMsg: %1").arg(msg);
00064 break;
00065 case QtFatalMsg:
00066 vError("QtFatalMsg: %1").arg(msg);
00067 break;
00068 }
00069 if (type == QtFatalMsg) {
00070 vError("Fatal Qt error. Aborting.");
00071 abort();
00072 }
00073 }
00074
00075
00076
00077
00078 Vidalia::Vidalia(QStringList args, int &argc, char **argv)
00079 : QApplication(argc, argv)
00080 {
00081 qInstallMsgHandler(qt_msg_handler);
00082
00083
00084 parseArguments(args);
00085
00086
00087 if (_args.contains(ARG_RESET))
00088 VidaliaSettings::reset();
00089
00090
00091 if (_args.contains(ARG_LOGFILE))
00092 _log.open(_args.value(ARG_LOGFILE));
00093 if (_args.contains(ARG_LOGLEVEL)) {
00094 _log.setLogLevel(Log::stringToLogLevel(
00095 _args.value(ARG_LOGLEVEL)));
00096 if (!_args.contains(ARG_LOGFILE))
00097 _log.open(stdout);
00098 }
00099 if (!_args.contains(ARG_LOGLEVEL) &&
00100 !_args.contains(ARG_LOGFILE))
00101 _log.setLogLevel(Log::Off);
00102
00103
00104 setLanguage(_args.value(ARG_LANGUAGE));
00105
00106 setStyle(_args.value(ARG_GUISTYLE));
00107
00108
00109 _torControl = new TorControl();
00110 }
00111
00112
00113 Vidalia::~Vidalia()
00114 {
00115 delete _torControl;
00116 }
00117
00118
00119
00120 int
00121 Vidalia::run()
00122 {
00123 QTimer::singleShot(0, vApp, SLOT(onEventLoopStarted()));
00124 return vApp->exec();
00125 }
00126
00127
00128
00129
00130 void
00131 Vidalia::onEventLoopStarted()
00132 {
00133 emit running();
00134 }
00135
00136 #if defined(Q_OS_WIN)
00137
00138
00139 bool
00140 Vidalia::winEventFilter(MSG *msg, long *result)
00141 {
00142 if (msg->message == WM_QUERYENDSESSION) {
00143 emit shutdown();
00144 }
00145 return QApplication::winEventFilter(msg, result);
00146 }
00147 #endif
00148
00149
00150 bool
00151 Vidalia::showUsage()
00152 {
00153 return _args.contains(ARG_HELP);
00154 }
00155
00156
00157 void
00158 Vidalia::showUsageMessageBox()
00159 {
00160 QString usage;
00161 QTextStream out(&usage);
00162
00163 out << "Available Options:" << endl;
00164 out << "<table>";
00165 out << trow(tcol("-"ARG_HELP) +
00166 tcol(tr("Displays this usage message and exits.")));
00167 out << trow(tcol("-"ARG_RESET) +
00168 tcol(tr("Resets ALL stored Vidalia settings.")));
00169 out << trow(tcol("-"ARG_DATADIR" <dir>") +
00170 tcol(tr("Sets the directory Vidalia uses for data files.")));
00171 out << trow(tcol("-"ARG_PIDFILE" <file>") +
00172 tcol(tr("Sets the name and location of Vidalia's pidfile.")));
00173 out << trow(tcol("-"ARG_LOGFILE" <file>") +
00174 tcol(tr("Sets the name and location of Vidalia's logfile.")));
00175 out << trow(tcol("-"ARG_LOGLEVEL" <level>") +
00176 tcol(tr("Sets the verbosity of Vidalia's logging.") +
00177 "<br>[" + Log::logLevels().join("|") +"]"));
00178 out << trow(tcol("-"ARG_GUISTYLE" <style>") +
00179 tcol(tr("Sets Vidalia's interface style.") +
00180 "<br>[" + QStyleFactory::keys().join("|") + "]"));
00181 out << trow(tcol("-"ARG_LANGUAGE" <language>") +
00182 tcol(tr("Sets Vidalia's language.") +
00183 "<br>[" + LanguageSupport::languageCodes().join("|") + "]"));
00184 out << "</table>";
00185
00186 VMessageBox::information(0,
00187 tr("Vidalia Usage Information"), usage, VMessageBox::Ok);
00188 }
00189
00190
00191 bool
00192 Vidalia::argNeedsValue(QString argName)
00193 {
00194 return (argName == ARG_GUISTYLE ||
00195 argName == ARG_LANGUAGE ||
00196 argName == ARG_DATADIR ||
00197 argName == ARG_PIDFILE ||
00198 argName == ARG_LOGFILE ||
00199 argName == ARG_LOGLEVEL);
00200 }
00201
00202
00203
00204 void
00205 Vidalia::parseArguments(QStringList args)
00206 {
00207 QString arg, value;
00208
00209
00210 for (int i = 0; i < args.size(); i++) {
00211
00212 arg = args.at(i).toLower();
00213 value = "";
00214
00215
00216 if (arg.startsWith("-")) {
00217 arg = arg.mid((arg.startsWith("--") ? 2 : 1));
00218 }
00219
00220 if (i < args.size()-1 && argNeedsValue(arg)) {
00221 value = args.at(++i);
00222 }
00223
00224 _args.insert(arg, value);
00225 }
00226 }
00227
00228
00229 bool
00230 Vidalia::validateArguments(QString &errmsg)
00231 {
00232
00233 if (_args.contains(ARG_LANGUAGE) &&
00234 !LanguageSupport::isValidLanguageCode(_args.value(ARG_LANGUAGE))) {
00235 errmsg = tr("Invalid language code specified: ") + _args.value(ARG_LANGUAGE);
00236 return false;
00237 }
00238
00239 if (_args.contains(ARG_GUISTYLE) &&
00240 !QStyleFactory::keys().contains(_args.value(ARG_GUISTYLE),
00241 Qt::CaseInsensitive)) {
00242 errmsg = tr("Invalid GUI style specified: ") + _args.value(ARG_GUISTYLE);
00243 return false;
00244 }
00245
00246 if (_args.contains(ARG_LOGLEVEL) &&
00247 !Log::logLevels().contains(_args.value(ARG_LOGLEVEL))) {
00248 errmsg = tr("Invalid log level specified: ") + _args.value(ARG_LOGLEVEL);
00249 return false;
00250 }
00251
00252 if (_args.contains(ARG_LOGFILE) && !_log.isOpen()) {
00253 errmsg = tr("Unable to open log file '%1': %2")
00254 .arg(_args.value(ARG_LOGFILE))
00255 .arg(_log.errorString());
00256 return false;
00257 }
00258 return true;
00259 }
00260
00261
00262
00263
00264
00265 bool
00266 Vidalia::setLanguage(QString languageCode)
00267 {
00268
00269 if (languageCode.isEmpty()) {
00270 VidaliaSettings settings;
00271 languageCode = settings.getLanguageCode();
00272 }
00273
00274 if (LanguageSupport::translate(languageCode)) {
00275 _language = languageCode;
00276 return true;
00277 }
00278 return false;
00279 }
00280
00281
00282
00283
00284
00285 bool
00286 Vidalia::setStyle(QString styleKey)
00287 {
00288
00289 if (styleKey.isEmpty()) {
00290 VidaliaSettings settings;
00291 styleKey = settings.getInterfaceStyle();
00292 }
00293
00294 if (QApplication::setStyle(styleKey)) {
00295 _style = styleKey;
00296 return true;
00297 }
00298 return false;
00299 }
00300
00301
00302 QString
00303 Vidalia::dataDirectory()
00304 {
00305 if (_args.contains(ARG_DATADIR)) {
00306 return _args.value(ARG_DATADIR);
00307 }
00308 return defaultDataDirectory();
00309 }
00310
00311
00312 QString
00313 Vidalia::defaultDataDirectory()
00314 {
00315 #if defined(Q_OS_WIN32)
00316 return (win32_app_data_folder() + "\\Vidalia");
00317 #else
00318 return (QDir::homePath() + "/.vidalia");
00319 #endif
00320 }
00321
00322
00323 QString
00324 Vidalia::pidFile()
00325 {
00326 if (_args.contains(ARG_PIDFILE)) {
00327 return _args.value(ARG_PIDFILE);
00328 }
00329 return QDir::convertSeparators("/var/run/tor/tor.pid");
00330 }
00331
00332
00333 Log::LogMessage
00334 Vidalia::log(Log::LogLevel level, QString msg)
00335 {
00336 return _log.log(level, msg);
00337 }
00338
00339
00340
00341 void
00342 Vidalia::createShortcut(const QKeySequence &key, QWidget *sender,
00343 QWidget *receiver, const char *slot)
00344 {
00345 QShortcut *s = new QShortcut(key, sender);
00346 connect(s, SIGNAL(activated()), receiver, slot);
00347 }
00348