logtreewidget.cpp

Go to the documentation of this file.
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.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file logtreewidget.cpp
00013 ** \version $Id: logtreewidget.cpp 2922 2008-08-03 01:19:40Z edmanm $
00014 ** \brief Contains a collection of log messages as LogTreeItems
00015 */
00016 
00017 #include <QScrollBar>
00018 
00019 #include "logtreewidget.h"
00020 #include "logheaderview.h"
00021 
00022 
00023 /** Default constructor. */
00024 LogTreeWidget::LogTreeWidget(QWidget *parent)
00025 : QTreeWidget(parent)
00026 {
00027   setHeader(new LogHeaderView(this));
00028   
00029   /* Default to always scrolling to the most recent item added */
00030   _scrollOnNewItem = true;
00031   setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
00032   connect(verticalScrollBar(), SIGNAL(sliderReleased()),
00033           this, SLOT(verticalSliderReleased()));
00034 }
00035 
00036 /** Called when the user moves the vertical scrollbar. If the user has the
00037  * scrollbar at within one step of its maximum, then always scroll to new
00038  * items when added. Otherwise, leave the scrollbar alone since they are
00039  * probably looking at something in their history. */
00040 void
00041 LogTreeWidget::verticalSliderReleased()
00042 {
00043   QScrollBar *scrollBar = verticalScrollBar();
00044   if (header()->sortIndicatorOrder() == Qt::AscendingOrder)
00045     _scrollOnNewItem = (scrollBar->value() == scrollBar->maximum());
00046   else
00047     _scrollOnNewItem = (scrollBar->value() == scrollBar->minimum());
00048 }
00049 
00050 /** Cast a QList of QTreeWidgetItem pointers to a list of LogTreeWidget
00051  * pointers. There really must be a better way to do this. */
00052 QList<LogTreeItem *>
00053 LogTreeWidget::qlist_cast(QList<QTreeWidgetItem *> inlist)
00054 {
00055   QList<LogTreeItem *> outlist;
00056   foreach (QTreeWidgetItem *item, inlist) {
00057     outlist << (LogTreeItem *)item;
00058   }
00059   return outlist;
00060 }
00061 
00062 /** Sorts the list of pointers to log tree items by timestamp. */
00063 QList<LogTreeItem *>
00064 LogTreeWidget::qlist_sort(QList<LogTreeItem *> inlist)
00065 {
00066   QMap<quint32, LogTreeItem *> outlist;
00067   foreach (LogTreeItem *item, inlist) {
00068     outlist.insert(item->id(), item);
00069   }
00070   return outlist.values();
00071 }
00072 
00073 /** The first time the log tree is shown, we need to set the default column
00074  * widths. */
00075 void
00076 LogTreeWidget::showEvent(QShowEvent *event)
00077 {
00078   static bool shown = false;
00079   QTreeWidget::showEvent(event);
00080   if (!shown) {
00081     /* Set the default column widths the first time this is shown */
00082     ((LogHeaderView *)header())->resetColumnWidths();
00083     shown = true;
00084   }
00085 }
00086 
00087 /** Clears all items from the message log and resets the counter in the status
00088  * bar. */
00089 void
00090 LogTreeWidget::clearMessages()
00091 {
00092   /* Clear the messages */
00093   clear();
00094 }
00095 
00096 /** Returns a list of all currently selected items. */
00097 QStringList
00098 LogTreeWidget::selectedMessages()
00099 {
00100   QStringList messages;
00101   
00102   /* Get all selected log items */
00103   QList<LogTreeItem *> items = 
00104     qlist_cast(selectedItems());
00105   
00106   /* Format the message items as strings and put them in a list */
00107   foreach (LogTreeItem *item, qlist_sort(items)) {
00108     messages << item->toString();
00109   }
00110   return messages;
00111 }
00112 
00113 /** Returns a list of all items in the tree. */
00114 QStringList
00115 LogTreeWidget::allMessages()
00116 {
00117   QStringList messages;
00118   
00119   /* Find all items */
00120   QList<LogTreeItem *> items = 
00121     qlist_cast(findItems("*", Qt::MatchWildcard|Qt::MatchWrap, MessageColumn));
00122   
00123   /* Format the message items as strings and put them in a list */
00124   foreach (LogTreeItem *item, qlist_sort(items)) {
00125     messages << item->toString();  
00126   }
00127   return messages;
00128 }
00129 
00130 /** Returns the number of items currently shown. */
00131 int
00132 LogTreeWidget::messageCount()
00133 {
00134   return topLevelItemCount();
00135 }
00136 
00137 /** Sets the maximum number of items in the tree. */
00138 void
00139 LogTreeWidget::setMaximumMessageCount(int max)
00140 {
00141   while (max < messageCount()) {
00142     /* If the new max is less than the currently displayed number of 
00143      * items, then we'll get rid of some. */
00144     delete takeTopLevelItem(0);
00145   }
00146   _maxItemCount = max;
00147 }
00148 
00149 /** Deselects all currently selected items. */
00150 void
00151 LogTreeWidget::deselectAll()
00152 {
00153   foreach(QTreeWidgetItem *item, selectedItems()) {
00154     setItemSelected(item, false);
00155   }
00156 }
00157 
00158 /** Adds a log item to the tree and returns a pointer to the new item. */
00159 LogTreeItem*
00160 LogTreeWidget::log(LogEvent::Severity type, QString message)
00161 {
00162   LogTreeItem *item = new LogTreeItem(type, message);
00163 
00164   /* If we need to make room, then make some room */
00165   if (messageCount() >= _maxItemCount) {
00166     delete takeTopLevelItem(0);
00167   }
00168   
00169   /* Add the new message item and scroll to it (if necessary) 
00170    * NOTE: We disable sorting, add the new item, and then re-enable sorting
00171    *       to force the result to be sorted immediately. Otherwise, the new
00172    *       message is not sorted until the message log has focus again.
00173    */
00174   setSortingEnabled(false);
00175   addTopLevelItem(item);
00176   setSortingEnabled(true);
00177 
00178   if (_scrollOnNewItem) {
00179     QScrollBar *scrollBar = verticalScrollBar();
00180     if (header()->sortIndicatorOrder() == Qt::AscendingOrder)
00181       scrollBar->setValue(scrollBar->maximum());
00182     else
00183       scrollBar->setValue(scrollBar->minimum());
00184   }
00185 
00186   return item;
00187 }
00188 
00189 /** Filters the message log based on the given filter. */
00190 void
00191 LogTreeWidget::filter(uint filter)
00192 {
00193   LogTreeItem *item;
00194   int index = messageCount() - 1;
00195   int itemsShown = 0;
00196 
00197   while (index > -1) {
00198     item = (LogTreeItem *)topLevelItem(index);
00199     if ((itemsShown < _maxItemCount) && (filter & item->severity())) {
00200       itemsShown++;
00201     } else {
00202       delete takeTopLevelItem(index);
00203     }
00204     index--;
00205   }
00206 }
00207 
00208 /** Searches the log for entries that contain the given text. */
00209 QList<LogTreeItem *>
00210 LogTreeWidget::find(QString text, bool highlight)
00211 {
00212   QList<LogTreeItem *> items = 
00213     qlist_cast(findItems(text, Qt::MatchContains|Qt::MatchWrap, MessageColumn));
00214   
00215   if (highlight) {
00216     /* Deselect all items before highlighting our search results. */
00217     deselectAll();
00218     foreach (LogTreeItem *item, items) {
00219       /* Highlight a matched item */
00220       setItemSelected(item, true);
00221     }
00222   }
00223 
00224   /* Return the results, sorted by timestamp */
00225   return qlist_sort(items);
00226 }
00227 

Generated on Sat Aug 16 17:31:48 2008 for Vidalia by  doxygen 1.5.6