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