Vidalia 0.2.15
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If you 00004 ** did not receive the LICENSE file with this file, you may obtain it from the 00005 ** Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file TorrcDialog.cpp 00013 ** \brief Torrc Dialog, contains the dialog for displaying and editing the torrc 00014 ** 00015 ** Implements the dialog for editing the torrc file inside Vidalia 00016 */ 00017 00018 #include "TorrcDialog.h" 00019 #include "Vidalia.h" 00020 00021 #include <QMessageBox> 00022 00023 void 00024 TorHighlighter::highlightBlock(const QString &text) 00025 { 00026 bool firstFormatted = false; 00027 00028 for (int i = 0; i < text.length(); ++i) { 00029 if(text.mid(i, 1) == " " and !firstFormatted) { 00030 setFormat(0, i, QColor(2,71,105)); 00031 setFormat(i, text.length() - 1, Qt::gray); 00032 firstFormatted = true; 00033 } else if (text.mid(i, 1) == "#") { 00034 setFormat(i, text.length() - i, QColor(112,144,128)); 00035 break; 00036 } 00037 } 00038 } 00039 00040 /** Constructor */ 00041 TorrcDialog::TorrcDialog(QWidget *parent) 00042 : QDialog(parent) 00043 { 00044 /* Invoke the Qt Designer generated object setup routine */ 00045 ui.setupUi(this); 00046 TorHighlighter *highlighter = new TorHighlighter(ui.teditTorrc); 00047 00048 /* Retrieve the global TorControl instance */ 00049 tc = Vidalia::torControl(); 00050 /* Load the torrc file to the TextEdit */ 00051 loadTorrc(); 00052 00053 /* Connect the accepted event from the dialog with the parsing and saving 00054 * routine */ 00055 connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(saveTorrc())); 00056 } 00057 00058 /** Destructor */ 00059 TorrcDialog::~TorrcDialog() 00060 { 00061 00062 } 00063 00064 /** Gives a shallow parse phase to the settings to catch most errors 00065 * and passes on the error messages from Tor if the setting's value isn't 00066 * valid. It returns false if something went wrong. 00067 * If there's a problem in the setting stage, changes to that point will 00068 * remaind but won't be saved. */ 00069 bool 00070 TorrcDialog::parseAndSet(QString *errmsg) 00071 { 00072 if(!errmsg) errmsg = new QString(""); 00073 if(!tc || !tc->isConnected()) { 00074 *errmsg = tr("Error connecting to Tor"); 00075 return false; 00076 } 00077 00078 QString key, val; 00079 QStringList parts, lines; 00080 00081 if(ui.rdoAll->isChecked()) 00082 lines = ui.teditTorrc->toPlainText().split('\n', QString::SkipEmptyParts); 00083 else { 00084 QString tmp = ui.teditTorrc->toPlainText(); 00085 QTextCursor tcursor = ui.teditTorrc->textCursor(); 00086 int start = tcursor.selectionStart(); 00087 int end = tcursor.selectionEnd(); 00088 tmp = tmp.mid(start, end - start).trimmed(); 00089 if(tmp.isEmpty()) { 00090 *errmsg = tr("Selection is empty. Please select some text, or check \"Apply all\""); 00091 return false; 00092 } 00093 00094 lines = tmp.split('\n', QString::SkipEmptyParts); 00095 } 00096 /* First pass: parsing */ 00097 int i = 0; 00098 foreach(QString line, lines) { 00099 i++; 00100 line = line.trimmed(); 00101 if(line.startsWith("#")) continue; // Skip commentaries 00102 parts = line.split(" ", QString::SkipEmptyParts); 00103 if(parts.count() < 2) { 00104 *errmsg = tr("Error at line %1: \"%2\"").arg(i).arg(line); 00105 return false; 00106 } 00107 } 00108 /* Second pass: setting */ 00109 QHash<QString,QString> settings; 00110 foreach(QString line, lines) { 00111 line = line.trimmed(); 00112 parts = line.split(" ", QString::SkipEmptyParts); 00113 key = parts[0]; 00114 parts.removeFirst(); 00115 val = parts.join(" "); 00116 settings.insert(key, val); 00117 } 00118 00119 if(!tc->setConf(settings, errmsg)) return false; 00120 00121 return true; 00122 } 00123 00124 /** Loads the saved torrc file that Tor's using to the TextEdit widget for 00125 * editing */ 00126 void 00127 TorrcDialog::loadTorrc() 00128 { 00129 if(tc && tc->isConnected()) { 00130 QString text = ""; 00131 QFile file(tc->getInfo("config-file").toString()); 00132 if(file.open(QFile::ReadOnly)) { 00133 QTextStream in(&file); 00134 QString line = ""; 00135 do { 00136 line = in.readLine(); 00137 text += line + "\n"; 00138 } while(!line.isNull()); 00139 ui.teditTorrc->setText(text); 00140 } else { 00141 QMessageBox::critical(this, tr("Error"), tr("An error ocurred while opening torrc file")); 00142 } 00143 } 00144 } 00145 00146 /** Calls the parsing and setting routine, and if everything went right 00147 * it saves the configuration to the torrc file through the SAVECONF control */ 00148 void 00149 TorrcDialog::saveTorrc() 00150 { 00151 QString errmsg = ""; 00152 if(tc && tc->isConnected()) { 00153 if(!parseAndSet(&errmsg)) { 00154 QMessageBox::critical(this, tr("Error"), errmsg); 00155 return; 00156 } 00157 if(ui.chkSave->isChecked()) { 00158 if(!tc->saveConf(&errmsg)) { 00159 QMessageBox::critical(this, tr("Error"), errmsg); 00160 return; 00161 } 00162 } 00163 } 00164 accept(); 00165 }