00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QMessageBox>
00018 #include <QFileDialog>
00019 #include <QInputDialog>
00020 #include <QMessageBox>
00021 #include <QClipboard>
00022 #include <vidalia.h>
00023 #include <html.h>
00024 #include <vmessagebox.h>
00025
00026 #include "messagelog.h"
00027
00028
00029 #define SETTING_MSG_FILTER "MessageFilter"
00030 #define SETTING_MAX_MSG_COUNT "MaxMsgCount"
00031 #define SETTING_ENABLE_LOGFILE "EnableLogFile"
00032 #define SETTING_LOGFILE "LogFile"
00033 #define DEFAULT_MSG_FILTER \
00034 (LogEvent::Error|LogEvent::Warn|LogEvent::Notice)
00035 #define DEFAULT_MAX_MSG_COUNT 50
00036 #define DEFAULT_ENABLE_LOGFILE false
00037 #if defined(Q_OS_WIN32)
00038
00039
00040 #define DEFAULT_LOGFILE \
00041 (win32_program_files_folder()+"\\Tor\\tor-log.txt")
00042 #else
00043 #define DEFAULT_LOGFILE ("/var/log/tor/tor.log")
00044 #endif
00045
00046 #define ADD_TO_FILTER(f,v,b) (f = ((b) ? ((f) | (v)) : ((f) & ~(v))))
00047
00048
00049
00050
00051
00052
00053
00054
00055 MessageLog::MessageLog(QWidget *parent, Qt::WFlags flags)
00056 : VidaliaWindow("MessageLog", parent, flags)
00057 {
00058
00059 ui.setupUi(this);
00060
00061
00062 _torControl = Vidalia::torControl();
00063
00064
00065 createActions();
00066
00067
00068 setToolTips();
00069
00070
00071 loadSettings();
00072
00073
00074 ui.lstMessages->sortItems(LogTreeWidget::TimeColumn,
00075 Qt::AscendingOrder);
00076 }
00077
00078
00079
00080 MessageLog::~MessageLog()
00081 {
00082 _logFile.close();
00083 }
00084
00085
00086 void
00087 MessageLog::createActions()
00088 {
00089 connect(ui.actionSave_Selected, SIGNAL(triggered()),
00090 this, SLOT(saveSelected()));
00091
00092 connect(ui.actionSave_All, SIGNAL(triggered()),
00093 this, SLOT(saveAll()));
00094
00095 connect(ui.actionCopy, SIGNAL(triggered()),
00096 this, SLOT(copy()));
00097
00098 connect(ui.actionFind, SIGNAL(triggered()),
00099 this, SLOT(find()));
00100
00101 connect(ui.actionHelp, SIGNAL(triggered()),
00102 this, SLOT(help()));
00103
00104 connect(ui.btnSaveSettings, SIGNAL(clicked()),
00105 this, SLOT(saveSettings()));
00106
00107 connect(ui.btnCancelSettings, SIGNAL(clicked()),
00108 this, SLOT(cancelChanges()));
00109
00110 connect(ui.btnBrowse, SIGNAL(clicked()),
00111 this, SLOT(browse()));
00112
00113 #if defined(Q_WS_MAC)
00114 ui.actionHelp->setShortcut(QString("Ctrl+?"));
00115 #endif
00116 ui.actionClose->setShortcut(QString("Esc"));
00117 Vidalia::createShortcut("Ctrl+W", this, ui.actionClose, SLOT(trigger()));
00118 }
00119
00120
00121
00122 void
00123 MessageLog::setToolTips()
00124 {
00125 ui.chkTorErr->setToolTip(tr("Messages that appear when something has \n"
00126 "gone very wrong and Tor cannot proceed."));
00127 ui.chkTorWarn->setToolTip(tr("Messages that only appear when \n"
00128 "something has gone wrong with Tor."));
00129 ui.chkTorNote->setToolTip(tr("Messages that appear infrequently \n"
00130 "during normal Tor operation and are \n"
00131 "not considered errors, but you may \n"
00132 "care about."));
00133 ui.chkTorInfo->setToolTip(tr("Messages that appear frequently \n"
00134 "during normal Tor operation."));
00135 ui.chkTorDebug->setToolTip(tr("Hyper-verbose messages primarily of \n"
00136 "interest to Tor developers."));
00137 }
00138
00139
00140 void
00141 MessageLog::loadSettings()
00142 {
00143
00144 uint maxMsgCount = getSetting(SETTING_MAX_MSG_COUNT,
00145 DEFAULT_MAX_MSG_COUNT).toUInt();
00146 ui.spnbxMaxCount->setValue(maxMsgCount);
00147 ui.lstMessages->setMaximumMessageCount(maxMsgCount);
00148
00149
00150 _enableLogging = getSetting(SETTING_ENABLE_LOGFILE,
00151 DEFAULT_ENABLE_LOGFILE).toBool();
00152 QString logfile = getSetting(SETTING_LOGFILE,
00153 DEFAULT_LOGFILE).toString();
00154 ui.lineFile->setText(QDir::convertSeparators(logfile));
00155 rotateLogFile(logfile);
00156 ui.chkEnableLogFile->setChecked(_logFile.isOpen());
00157
00158
00159 _filter = getSetting(SETTING_MSG_FILTER, DEFAULT_MSG_FILTER).toUInt();
00160 ui.chkTorErr->setChecked(_filter & LogEvent::Error);
00161 ui.chkTorWarn->setChecked(_filter & LogEvent::Warn);
00162 ui.chkTorNote->setChecked(_filter & LogEvent::Notice);
00163 ui.chkTorInfo->setChecked(_filter & LogEvent::Info);
00164 ui.chkTorDebug->setChecked(_filter & LogEvent::Debug);
00165 registerLogEvents();
00166
00167
00168 QApplication::setOverrideCursor(Qt::WaitCursor);
00169 ui.lstMessages->filter(_filter);
00170 QApplication::restoreOverrideCursor();
00171 }
00172
00173
00174
00175 void
00176 MessageLog::registerLogEvents()
00177 {
00178 QString errmsg;
00179 _filter = getSetting(SETTING_MSG_FILTER, DEFAULT_MSG_FILTER).toUInt();
00180 if (!_torControl->setLogEvents(_filter, this, &errmsg)) {
00181 VMessageBox::warning(this, tr("Error Setting Filter"),
00182 p(tr("Vidalia was unable to register for Tor's log events.")) + p(errmsg),
00183 VMessageBox::Ok);
00184 }
00185 }
00186
00187
00188
00189
00190
00191 bool
00192 MessageLog::rotateLogFile(QString filename)
00193 {
00194 QString errmsg;
00195 if (_enableLogging) {
00196 if (!_logFile.open(filename, &errmsg)) {
00197 VMessageBox::warning(this, tr("Error Opening Log File"),
00198 p(tr("Vidalia was unable to open the specified log file."))+p(errmsg),
00199 VMessageBox::Ok);
00200 return false;
00201 }
00202 } else {
00203
00204 _logFile.close();
00205 }
00206 return true;
00207 }
00208
00209
00210
00211 void
00212 MessageLog::saveSettings()
00213 {
00214
00215 _enableLogging = ui.chkEnableLogFile->isChecked();
00216 if (_enableLogging && ui.lineFile->text().isEmpty()) {
00217
00218
00219 VMessageBox::warning(this, tr("Log Filename Required"),
00220 p(tr("You must enter a filename to be able to save log "
00221 "messages to a file.")), VMessageBox::Ok);
00222 return;
00223 }
00224 if (rotateLogFile(ui.lineFile->text())) {
00225 saveSetting(SETTING_LOGFILE, ui.lineFile->text());
00226 saveSetting(SETTING_ENABLE_LOGFILE, _logFile.isOpen());
00227 }
00228 ui.lineFile->setText(QDir::convertSeparators(ui.lineFile->text()));
00229 ui.chkEnableLogFile->setChecked(_logFile.isOpen());
00230
00231
00232 saveSetting(SETTING_MAX_MSG_COUNT, ui.spnbxMaxCount->value());
00233 ui.lstMessages->setMaximumMessageCount(ui.spnbxMaxCount->value());
00234
00235
00236 uint filter = 0;
00237 ADD_TO_FILTER(filter, LogEvent::Error, ui.chkTorErr->isChecked());
00238 ADD_TO_FILTER(filter, LogEvent::Warn, ui.chkTorWarn->isChecked());
00239 ADD_TO_FILTER(filter, LogEvent::Notice, ui.chkTorNote->isChecked());
00240 ADD_TO_FILTER(filter, LogEvent::Info, ui.chkTorInfo->isChecked());
00241 ADD_TO_FILTER(filter, LogEvent::Debug, ui.chkTorDebug->isChecked());
00242 saveSetting(SETTING_MSG_FILTER, filter);
00243 registerLogEvents();
00244
00245
00246 QApplication::setOverrideCursor(Qt::WaitCursor);
00247 ui.lstMessages->filter(_filter);
00248 QApplication::restoreOverrideCursor();
00249
00250
00251 ui.actionSettings->toggle();
00252 }
00253
00254
00255
00256 void
00257 MessageLog::cancelChanges()
00258 {
00259
00260 ui.actionSettings->toggle();
00261
00262 loadSettings();
00263 }
00264
00265
00266 void
00267 MessageLog::browse()
00268 {
00269
00270 QString filename = QDir::convertSeparators(
00271 QFileDialog::getSaveFileName(this,
00272 tr("Select Log File"), "tor-log.txt"));
00273 if (!filename.isEmpty()) {
00274 ui.lineFile->setText(filename);
00275 }
00276 }
00277
00278
00279
00280
00281 void
00282 MessageLog::save(QStringList messages)
00283 {
00284 if (!messages.size()) {
00285 return;
00286 }
00287
00288 QString fileName = QFileDialog::getSaveFileName(this,
00289 tr("Save Log Messages"),
00290 "VidaliaLog-" +
00291 QDateTime::currentDateTime().toString("MM.dd.yyyy")
00292 + ".txt", tr("Text Files (*.txt)"));
00293
00294
00295 if (!fileName.isEmpty()) {
00296 LogFile logFile;
00297 QString errmsg;
00298
00299
00300 if (!logFile.open(fileName, &errmsg)) {
00301 VMessageBox::warning(this, tr("Vidalia"),
00302 p(tr("Cannot write file %1\n\n%2."))
00303 .arg(fileName)
00304 .arg(errmsg),
00305 VMessageBox::Ok);
00306 return;
00307 }
00308
00309
00310 QApplication::setOverrideCursor(Qt::WaitCursor);
00311 foreach (QString msg, messages) {
00312 logFile << msg;
00313 }
00314 QApplication::restoreOverrideCursor();
00315 }
00316 }
00317
00318
00319 void
00320 MessageLog::saveSelected()
00321 {
00322 save(ui.lstMessages->selectedMessages());
00323 }
00324
00325
00326 void
00327 MessageLog::saveAll()
00328 {
00329 save(ui.lstMessages->allMessages());
00330 }
00331
00332
00333 void
00334 MessageLog::copy()
00335 {
00336 QString contents = ui.lstMessages->selectedMessages().join("");
00337 if (!contents.isEmpty()) {
00338
00339 QApplication::clipboard()->setText(contents);
00340 }
00341 }
00342
00343
00344
00345
00346
00347
00348 void
00349 MessageLog::find()
00350 {
00351 bool ok;
00352 QString text = QInputDialog::getText(this, tr("Find in Message Log"),
00353 tr("Find:"), QLineEdit::Normal, QString(), &ok);
00354
00355 if (ok && !text.isEmpty()) {
00356
00357 QList<LogTreeItem *> results = ui.lstMessages->find(text);
00358 if (!results.size()) {
00359 VMessageBox::information(this, tr("Not Found"),
00360 p(tr("Search found 0 matches.")),
00361 VMessageBox::Ok);
00362 } else {
00363
00364 ui.lstMessages->scrollToItem(results.at(0));
00365 }
00366 }
00367 }
00368
00369
00370
00371
00372
00373
00374 void
00375 MessageLog::log(LogEvent::Severity type, QString message)
00376 {
00377
00378 if (_filter & (uint)type) {
00379
00380 LogTreeItem *item = ui.lstMessages->log(type, message);
00381
00382
00383
00384 QString currStatusTip = ui.statusbar->currentMessage();
00385 if (!currStatusTip.isEmpty()) {
00386 currStatusTip = ui.lstMessages->statusTip();
00387 ui.statusbar->showMessage(currStatusTip);
00388 }
00389
00390
00391 if (_enableLogging) {
00392 _logFile << item->toString();
00393 }
00394 }
00395 }
00396
00397
00398
00399
00400
00401 void
00402 MessageLog::customEvent(QEvent *event)
00403 {
00404 if (event->type() == CustomEventType::LogEvent) {
00405 LogEvent *e = (LogEvent *)event;
00406 log(e->severity(), e->message());
00407 e->accept();
00408 }
00409 }
00410
00411
00412 void
00413 MessageLog::help()
00414 {
00415 emit helpRequested("log");
00416 }
00417