logtreewidget.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 logtreewidget.cpp
00024  * \version $Id: logtreewidget.cpp 1563 2006-12-26 06:06:04Z edmanm $
00025  * \brief Contains a collection of log messages as LogTreeItems
00026  */
00027 
00028 #include <QScrollBar>
00029 
00030 #include "logtreewidget.h"
00031 #include "logheaderview.h"
00032 
00033 
00034 /** Default constructor. */
00035 LogTreeWidget::LogTreeWidget(QWidget *parent)
00036 : QTreeWidget(parent)
00037 {
00038   setHeader(new LogHeaderView(this));
00039   
00040   setStatusTip(tr("Messages Shown: ") + "0");
00041 
00042   /* Default to always scrolling to the most recent item added */
00043   _scrollOnNewItem = true;
00044   connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
00045           this, SLOT(onVerticalScroll(int)));
00046 }
00047 
00048 /** Called when the user moves the vertical scrollbar. If the user has the
00049  * scrollbar at within one step of its maximum, then always scroll to new
00050  * items when added. Otherwise, leave the scrollbar alone since they are
00051  * probably looking at something in their history. */
00052 void
00053 LogTreeWidget::onVerticalScroll(int value)
00054 {
00055   QScrollBar *scrollbar = verticalScrollBar();
00056   _scrollOnNewItem = (value >= (scrollbar->maximum()-scrollbar->singleStep()));
00057 }
00058 
00059 /** Cast a QList of QTreeWidgetItem pointers to a list of LogTreeWidget
00060  * pointers. There really must be a better way to do this. */
00061 QList<LogTreeItem *>
00062 LogTreeWidget::qlist_cast(QList<QTreeWidgetItem *> inlist)
00063 {
00064   QList<LogTreeItem *> outlist;
00065   foreach (QTreeWidgetItem *item, inlist) {
00066     outlist << (LogTreeItem *)item;
00067   }
00068   return outlist;
00069 }
00070 
00071 /** Sorts the list of pointers to log tree items by timestamp. */
00072 QList<LogTreeItem *>
00073 LogTreeWidget::qlist_sort(QList<LogTreeItem *> inlist)
00074 {
00075   QMap<quint32, LogTreeItem *> outlist;
00076   foreach (LogTreeItem *item, inlist) {
00077     outlist.insert(item->id(), item);
00078   }
00079   return outlist.values();
00080 }
00081 
00082 /** The first time the log tree is shown, we need to set the default column
00083  * widths. */
00084 void
00085 LogTreeWidget::showEvent(QShowEvent *event)
00086 {
00087   static bool shown = false;
00088   QTreeWidget::showEvent(event);
00089   if (!shown) {
00090     /* Set the default column widths the first time this is shown */
00091     ((LogHeaderView *)header())->resetColumnWidths();
00092     /* Adjust the message column properly */
00093     adjustMessageColumn();
00094     shown = true;
00095   }
00096 }
00097 
00098 /** Clears all items from the message log and resets the counter in the status
00099  * bar. */
00100 void
00101 LogTreeWidget::clearMessages()
00102 {
00103   /* Clear the messages */
00104   clear();
00105   /* This should always be 0, but just in case clear() doesn't really remove
00106    * all, we'll get the current count again. */
00107   setStatusTip(tr("Messages Shown: %1").arg(messageCount()));
00108 }
00109 
00110 /** Adjusts the message column width to accomodate long messages. */
00111 void
00112 LogTreeWidget::adjustMessageColumn()
00113 {
00114   /* Adjust the message column, based on the longest item. */
00115   ((LogHeaderView *)header())->resize(sizeHintForColumn(MessageColumn));
00116 }
00117 
00118 /** Adds a message log item. */
00119 void
00120 LogTreeWidget::addMessageItem(LogTreeItem *item)
00121 {
00122   /* Add the new item. */
00123   addTopLevelItem(item);
00124   /* Adjust the column headers to accomodate a long message, if necesssary */
00125   adjustMessageColumn();
00126 }
00127 
00128 /** Returns a list of all currently selected items. */
00129 QStringList
00130 LogTreeWidget::selectedMessages()
00131 {
00132   QStringList messages;
00133   
00134   /* Get all selected log items */
00135   QList<LogTreeItem *> items = 
00136     qlist_cast(selectedItems());
00137   
00138   /* Format the message items as strings and put them in a list */
00139   foreach (LogTreeItem *item, qlist_sort(items)) {
00140     messages << item->toString();
00141   }
00142   return messages;
00143 }
00144 
00145 /** Returns a list of all items in the tree. */
00146 QStringList
00147 LogTreeWidget::allMessages()
00148 {
00149   QStringList messages;
00150   
00151   /* Find all items */
00152   QList<LogTreeItem *> items = 
00153     qlist_cast(findItems("*", Qt::MatchWildcard|Qt::MatchWrap, MessageColumn));
00154   
00155   /* Format the message items as strings and put them in a list */
00156   foreach (LogTreeItem *item, qlist_sort(items)) {
00157     messages << item->toString();  
00158   }
00159   return messages;
00160 }
00161 
00162 /** Returns the number of items currently shown. */
00163 int
00164 LogTreeWidget::messageCount()
00165 {
00166   return topLevelItemCount();
00167 }
00168 
00169 /** Sets the maximum number of items in the tree. */
00170 void
00171 LogTreeWidget::setMaximumMessageCount(int max)
00172 {
00173   while (max < messageCount()) {
00174     /* If the new max is less than the currently displayed number of 
00175      * items, then we'll get rid of some. */
00176     delete takeTopLevelItem(0);
00177   }
00178   _maxItemCount = max;
00179 }
00180 
00181 /** Deselects all currently selected items. */
00182 void
00183 LogTreeWidget::deselectAll()
00184 {
00185   foreach(QTreeWidgetItem *item, selectedItems()) {
00186     setItemSelected(item, false);
00187   }
00188 }
00189 
00190 /** Adds a log item to the tree and returns a pointer to the new item. */
00191 LogTreeItem*
00192 LogTreeWidget::log(LogEvent::Severity type, QString message)
00193 {
00194   LogTreeItem *item = new LogTreeItem(type, message);
00195 
00196   /* If we need to make room, then make some room */
00197   if (messageCount() >= _maxItemCount) {
00198     delete takeTopLevelItem(0);
00199   }
00200   
00201   /* Add the new message item and scroll to it (if necessary) */
00202   addMessageItem(item);
00203   if (_scrollOnNewItem) {
00204     scrollToItem(item);
00205   }
00206 
00207   /* Update our tooltip and return the new log item */
00208   setStatusTip(tr("Messages Shown: %1").arg(messageCount()));
00209   return item;
00210 }
00211 
00212 /** Filters the message log based on the given filter. */
00213 void
00214 LogTreeWidget::filter(uint filter)
00215 {
00216   LogTreeItem *item;
00217   int index = messageCount() - 1;
00218   int itemsShown = 0;
00219 
00220   while (index > -1) {
00221     item = (LogTreeItem *)topLevelItem(index);
00222     if ((itemsShown < _maxItemCount) && (filter & item->severity())) {
00223       itemsShown++;
00224     } else {
00225       delete takeTopLevelItem(index);
00226     }
00227     index--;
00228   }
00229 
00230   setStatusTip(tr("Messages Shown: %1").arg(messageCount()));
00231 }
00232 
00233 /** Searches the log for entries that contain the given text. */
00234 QList<LogTreeItem *>
00235 LogTreeWidget::find(QString text, bool highlight)
00236 {
00237   QList<LogTreeItem *> items = 
00238     qlist_cast(findItems(text, Qt::MatchContains|Qt::MatchWrap, MessageColumn));
00239   
00240   if (highlight) {
00241     /* Deselect all items before highlighting our search results. */
00242     deselectAll();
00243     foreach (LogTreeItem *item, items) {
00244       /* Highlight a matched item */
00245       setItemSelected(item, true);
00246     }
00247   }
00248 
00249   /* Return the results, sorted by timestamp */
00250   return qlist_sort(items);
00251 }
00252 

Generated on Wed Sep 5 15:49:27 2007 for Vidalia by  doxygen 1.5.3