vidalia.cpp

Go to the documentation of this file.
00001 /****************************************************************
00002  *  Vidalia is distributed under the following license:
00003  *
00004  *  Copyright (C) 2006,  Matt Edman, Justin Hipple
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  *  Boston, MA  02110-1301, USA.
00020  ****************************************************************/
00021 
00022 /**
00023  * \file vidalia.cpp
00024  * \version $Id: vidalia.cpp 1238 2006-09-25 17:50:57Z edmanm $
00025  * \brief Main Vidalia QApplication object
00026  */
00027 
00028 #include <QDir>
00029 #include <QTextStream>
00030 #include <QStyleFactory>
00031 #include <util/string.h>
00032 #include <lang/languagesupport.h>
00033 
00034 #include "vidalia.h"
00035 
00036 /* Available command-line arguments. */
00037 #define ARG_LANGUAGE   "lang"    /**< Argument specifying language.    */
00038 #define ARG_GUISTYLE   "style"   /**< Argument specfying GUI style.    */
00039 #define ARG_RESET      "reset"   /**< Reset Vidalia's saved settings.  */
00040 #define ARG_HELP       "help"    /**< Display usage informatino.       */
00041 #define ARG_DATADIR    "datadir" /**< Directory to use for data files. */
00042 #define ARG_PIDFILE    "/var/run/tor/tor.pid" /**< Location and name of our pidfile.*/
00043 
00044 /* Static member variables */
00045 QMap<QString, QString> Vidalia::_args; /**< List of command-line arguments.  */
00046 QString Vidalia::_style;               /**< The current GUI style.           */
00047 QString Vidalia::_language;            /**< The current language.            */
00048 VidaliaSettings Vidalia::_settings;    /**< Vidalia's configurable settings. */
00049 HelpBrowser*  Vidalia::_help = 0;      /**< Vidalia's help system.           */
00050 TorControl* Vidalia::_torControl = 0;  /**< Main TorControl object.          */
00051 
00052 
00053 /** Constructor. Parses the command-line arguments, resets Vidalia's
00054  * configuration (if requested), and sets up the GUI style and language
00055  * translation. */
00056 Vidalia::Vidalia(QStringList args, int &argc, char **argv)
00057 : QApplication(argc, argv)
00058 {
00059   /* Read in all our command-line arguments. */
00060   parseArguments(args);
00061 
00062   /* Check if we're supposed to reset our config before proceeding. */
00063   if (_args.contains(ARG_RESET)) {
00064     _settings.reset();
00065   }
00066 
00067   /** Translate the GUI to the appropriate language. */
00068   setLanguage(_args.value(ARG_LANGUAGE));
00069 
00070   /** Set the GUI style appropriately. */
00071   setStyle(_args.value(ARG_GUISTYLE));
00072 
00073   /** Creates a TorControl object, used to talk to Tor. */
00074   _torControl = new TorControl();
00075   /** Create a help browser object, used to dispaly various help topics. */
00076   _help = new HelpBrowser();
00077 }
00078 
00079 /** Destructor */
00080 Vidalia::~Vidalia()
00081 {
00082   delete _help;
00083   delete _torControl;
00084 }
00085 
00086 #if defined(Q_OS_WIN)
00087 /** On Windows, we need to catch the WM_QUERYENDSESSION message
00088  * so we know that it is time to shutdown. */
00089 bool
00090 Vidalia::winEventFilter(MSG *msg, long *result)
00091 {
00092   if (msg->message == WM_QUERYENDSESSION) {
00093     emit shutdown();
00094   }
00095   return QApplication::winEventFilter(msg, result);
00096 }
00097 #endif
00098 
00099 /** Display usage information regarding command-line arguments. */
00100 void
00101 Vidalia::printUsage(QString errmsg)
00102 {
00103   QTextStream out(stdout);
00104 
00105   /* If there was an error message, print it out. */
00106   if (!errmsg.isEmpty()) {
00107     out << "** " << errmsg << " **" << endl << endl;
00108   }
00109 
00110   /* Now print the application usage */
00111   out << "Usage: " << endl;
00112   out << "\t" << qApp->arguments().at(0) << " [options]"    << endl;
00113 
00114   /* And available options */
00115   out << endl << "Available Options:"                                   << endl;
00116   out << "\t-"ARG_HELP"\t\tDisplays this usage message and exits."      << endl;
00117   out << "\t-"ARG_RESET"\t\tResets ALL stored Vidalia settings."        << endl;
00118   out << "\t-"ARG_DATADIR"\tSets the directory Vidalia uses for data files"<< endl;
00119   out << "\t-"ARG_PIDFILE"\tSets the name and location of Vidalia's pidfile"<< endl;
00120   out << "\t-"ARG_GUISTYLE"\t\tSets Vidalia's interface style."         << endl;
00121   out << "\t\t\t[" << QStyleFactory::keys().join("|") << "]"            << endl;
00122   out << "\t-"ARG_LANGUAGE"\t\tSets Vidalia's language."                << endl;
00123   out << "\t\t\t[" << LanguageSupport::languageCodes().join("|") << "]" << endl;
00124 }
00125 
00126 /** Returns true if the specified argument expects a value. */
00127 bool
00128 Vidalia::argNeedsValue(QString argName)
00129 {
00130   return (argName == ARG_GUISTYLE ||
00131           argName == ARG_LANGUAGE ||
00132           argName == ARG_DATADIR  ||
00133           argName == ARG_PIDFILE);
00134 }
00135 
00136 /** Parses the list of command-line arguments for their argument names and
00137  * values. */
00138 void
00139 Vidalia::parseArguments(QStringList args)
00140 {
00141   QString arg, value;
00142 
00143   /* Loop through all command-line args/values and put them in a map */
00144   for (int i = 0; i < args.size(); i++) {
00145     /* Get the argument name and set a blank value */
00146     arg   = args.at(i).toLower();
00147     value = "";
00148 
00149     /* Check if it starts with a - or -- */
00150     if (arg.startsWith("-")) {
00151       arg = arg.mid((arg.startsWith("--") ? 2 : 1));
00152     }
00153     /* Check if it takes a value and there is one on the command-line */
00154     if (i < args.size()-1 && argNeedsValue(arg)) {
00155       value = args.at(++i);
00156     }
00157     /* Place this arg/value in the map */
00158     _args.insert(arg, value);
00159   }
00160 }
00161 
00162 /** Verifies that all specified arguments were valid. */
00163 bool
00164 Vidalia::validateArguments(QString &errmsg)
00165 {
00166   /* If they want help, just return false now */
00167   if (_args.contains(ARG_HELP)) {
00168     return false;
00169   }
00170   /* Check for a language that Vidalia recognizes. */
00171   if (_args.contains(ARG_LANGUAGE) &&
00172       !LanguageSupport::isValidLanguageCode(_args.value(ARG_LANGUAGE))) {
00173     errmsg = tr("Invalid language code specified: ") + _args.value(ARG_LANGUAGE);
00174     return false;
00175   }
00176   /* Check for a valid GUI style */
00177   if (_args.contains(ARG_GUISTYLE) &&
00178       !QStyleFactory::keys().contains(_args.value(ARG_GUISTYLE),
00179                                       Qt::CaseInsensitive)) {
00180     errmsg = tr("Invalid GUI style specified: ") + _args.value(ARG_GUISTYLE);
00181     return false;
00182   }
00183   return true;
00184 }
00185 
00186 /** Sets the translation Vidalia will use. If one was specified on the
00187  * command-line, we will use that. Otherwise, we'll check to see if one was
00188  * saved previously. If not, we'll default to one appropriate for the system
00189  * locale. */
00190 bool
00191 Vidalia::setLanguage(QString languageCode)
00192 {
00193   /* If the language code is empty, use the previously-saved setting */
00194   if (languageCode.isEmpty()) {
00195     languageCode = _settings.getLanguageCode();
00196   }
00197   /* Translate into the desired langauge */
00198   if (LanguageSupport::translate(languageCode)) {
00199     _language = languageCode;
00200     return true;
00201   }
00202   return false;
00203 }
00204 
00205 /** Sets the GUI style Vidalia will use. If one was specified on the
00206  * command-line, we will use that. Otherwise, we'll check to see if one was
00207  * saved previously. If not, we'll default to one appropriate for the
00208  * operating system. */
00209 bool
00210 Vidalia::setStyle(QString styleKey)
00211 {
00212   /* If no style was specified, use the previously-saved setting */
00213   if (styleKey.isEmpty()) {
00214     styleKey = _settings.getInterfaceStyle();
00215   }
00216   /* Apply the specified GUI style */
00217   if (QApplication::setStyle(styleKey)) {
00218     _style = styleKey;
00219     return true;
00220   }
00221   return false;
00222 }
00223 
00224 /** Displays the help page associated with the specified topic. If no topic is
00225  * specified, then the default help page will be displayed. */
00226 void
00227 Vidalia::help(QString topic)
00228 {
00229   _help->show(topic);
00230 }
00231 
00232 /** Returns the directory Vidalia uses for its data files. */
00233 QString
00234 Vidalia::dataDirectory()
00235 {
00236   if (_args.contains(ARG_DATADIR)) {
00237     return _args.value(ARG_DATADIR);
00238   }
00239   return defaultDataDirectory();
00240 }
00241 
00242 /** Returns the default location of Vidalia's data directory. */
00243 QString
00244 Vidalia::defaultDataDirectory()
00245 {
00246 #if defined(Q_OS_WIN32)
00247   return (win32_app_data_folder() + "\\Vidalia");
00248 #else
00249   return (QDir::homePath() + "/.vidalia");
00250 #endif
00251 }
00252 
00253 /** Returns the location of Vidalia's pid file. */
00254 QString
00255 Vidalia::pidFile()
00256 {
00257   if (_args.contains(ARG_PIDFILE)) {
00258     return _args.value(ARG_PIDFILE);
00259   }
00260   return QDir::convertSeparators(dataDirectory() + "/vidalia.pid");
00261 }
00262 

Generated on Mon Oct 23 20:08:16 2006 for Vidalia by  doxygen 1.5.0