From: <sv...@va...> - 2011-07-03 05:27:44
|
Author: cerion Date: 2011-07-03 06:22:53 +0100 (Sun, 03 Jul 2011) New Revision: 546 Log: Introduced a simple filtering mechanism. This is entirely separate from suppressions, and serves only as a temporary 'screen cleanup' mechanism. Actually, I'm not sure I agree that this is 'a good thing', since Valgrind issues 'should' be fixed in order. However, it seems to be much wanted, so here you go. Added: trunk/icons/filter.png trunk/icons/filter_off.png trunk/icons/refresh.png trunk/src/toolview/logviewfilter_mc.cpp trunk/src/toolview/logviewfilter_mc.h Modified: trunk/icons.qrc trunk/src/src.pro trunk/src/toolview/memcheck_logview.cpp trunk/src/toolview/memcheck_logview.h trunk/src/toolview/memcheckview.cpp trunk/src/toolview/memcheckview.h trunk/src/toolview/vglogview.h Added: trunk/icons/filter.png =================================================================== (Binary files differ) Property changes on: trunk/icons/filter.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/icons/filter_off.png =================================================================== (Binary files differ) Property changes on: trunk/icons/filter_off.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/icons/refresh.png =================================================================== (Binary files differ) Property changes on: trunk/icons/refresh.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/icons.qrc =================================================================== --- trunk/icons.qrc 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/icons.qrc 2011-07-03 05:22:53 UTC (rev 546) @@ -32,5 +32,8 @@ <file>icons/text_more.png</file> <file>icons/arrow_down.png</file> <file>icons/arrow_up.png</file> + <file>icons/filter.png</file> + <file>icons/refresh.png</file> + <file>icons/filter_off.png</file> </qresource> </RCC> Modified: trunk/src/src.pro =================================================================== --- trunk/src/src.pro 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/src/src.pro 2011-07-03 05:22:53 UTC (rev 546) @@ -69,6 +69,7 @@ options/widgets/opt_lb_widget.cpp \ toolview/helgrindview.cpp \ toolview/helgrind_logview.cpp \ + toolview/logviewfilter_mc.cpp \ toolview/memcheckview.cpp \ toolview/memcheck_logview.cpp \ toolview/toolview.cpp \ @@ -111,6 +112,7 @@ options/widgets/opt_lb_widget.h \ toolview/helgrindview.h \ toolview/helgrind_logview.h \ + toolview/logviewfilter_mc.h \ toolview/memcheckview.h \ toolview/memcheck_logview.h \ toolview/toolview.h \ Added: trunk/src/toolview/logviewfilter_mc.cpp =================================================================== --- trunk/src/toolview/logviewfilter_mc.cpp (rev 0) +++ trunk/src/toolview/logviewfilter_mc.cpp 2011-07-03 05:22:53 UTC (rev 546) @@ -0,0 +1,444 @@ +/**************************************************************************** +** LogViewFilterMC implementation +** -------------------------------------------------------------------------- +** +** Copyright (C) 2011-2011, OpenWorks LLP. All rights reserved. +** <in...@op...> +** +** This file is part of Valkyrie, a front-end for Valgrind. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file COPYING included in the packaging of +** this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "toolview/logviewfilter_mc.h" +#include "utils/vk_utils.h" + +#include <QAction> +#include <QHBoxLayout> +#include <QLineEdit> +#include <QMap> +#include <QTimer> + + + +LogViewFilterMC::LogViewFilterMC( QWidget *parent, QTreeWidget* view ) + : QWidget(parent), m_view( view ) +{ + setObjectName( QString::fromUtf8( "LogViewFilterMC" ) ); + + // ------------------------------------------------------------ + // widgets + QIcon ico_filter( QString::fromUtf8( ":/vk_icons/icons/refresh.png" ) ); + butt_refresh = new QPushButton( ico_filter, "" ); + butt_refresh->setFixedWidth( 30 ); + connect( butt_refresh, SIGNAL(clicked()), this, SLOT(refresh()) ); + + // XML tag types + combo_xmltag = new QComboBox(); + connect( combo_xmltag, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()) ); + + // Compare functions + cmpWidgStack = new QStackedWidget(); + cmpWidgStack->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ); + QComboBox* combo_cmp[3]; // for each of [CMP_KND, CMP_STR, CMP_INT] + for ( int i=0; i<3; ++i ) { + combo_cmp[i] = new QComboBox(); + combo_cmp[i]->setSizeAdjustPolicy( QComboBox::AdjustToContents ); + connect( combo_cmp[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited()) ); + cmpWidgStack->addWidget( combo_cmp[i] ); + } + vk_assert( cmpWidgStack->indexOf( combo_cmp[CMP_KND] ) == CMP_KND ); + vk_assert( cmpWidgStack->indexOf( combo_cmp[CMP_STR] ) == CMP_STR ); + vk_assert( cmpWidgStack->indexOf( combo_cmp[CMP_INT] ) == CMP_INT ); + + // Filter values (combo/lineedits) + QComboBox* combo_filter = new QComboBox(); + connect( combo_filter, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()) ); + QLineEdit* ledit_strfilter = new QLineEdit(); + connect( ledit_strfilter, SIGNAL(textChanged(QString)), this, SLOT(edited()) ); + connect( ledit_strfilter, SIGNAL(editingFinished()), this, SLOT(refresh()) ); + QLineEdit* ledit_intfilter = new QLineEdit(); + ledit_intfilter->setValidator( new QIntValidator(this) ); // only accept integers. + connect( ledit_intfilter, SIGNAL(textChanged(QString)), this, SLOT(edited()) ); + connect( ledit_intfilter, SIGNAL(editingFinished()), this, SLOT(refresh()) ); + + filterWidgStack = new QStackedWidget(); + filterWidgStack->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ); + filterWidgStack->addWidget( combo_filter ); + filterWidgStack->addWidget( ledit_strfilter ); + filterWidgStack->addWidget( ledit_intfilter ); + vk_assert( filterWidgStack->indexOf( combo_filter ) == CMP_KND ); + vk_assert( filterWidgStack->indexOf( ledit_strfilter ) == CMP_STR ); + vk_assert( filterWidgStack->indexOf( ledit_intfilter ) == CMP_INT ); + + // ------------------------------------------------------------ + // layout + QGridLayout* gridLayout = new QGridLayout( this ); + gridLayout->setColumnStretch( 0, 0 ); + gridLayout->setColumnStretch( 1, 0 ); + gridLayout->setColumnStretch( 2, 0 ); + gridLayout->setColumnStretch( 3, 1 ); + gridLayout->setMargin(0); + gridLayout->addWidget( butt_refresh, 0, 0 ); + gridLayout->addWidget( combo_xmltag, 0, 1 ); + gridLayout->addWidget( cmpWidgStack, 0, 2 ); + gridLayout->addWidget( filterWidgStack, 0, 3 ); + + + // ------------------------------------------------------------ + // initialise xml tag combobox along with all compare types + combo_xmltag->addItem( "Function", XML_FUN ); + combo_xmltag->addItem( "Object", XML_OBJ ); + combo_xmltag->addItem( "Directory", XML_DIR ); + combo_xmltag->addItem( "File", XML_FIL ); + combo_xmltag->addItem( "Line", XML_LIN ); + combo_xmltag->addItem( "Leaked Bytes", XML_LBY ); + combo_xmltag->addItem( "Leaked Blocks", XML_LBL ); + combo_xmltag->addItem( "Kind", XML_KND ); + connect( combo_xmltag, SIGNAL(currentIndexChanged(int)), this, SLOT( setupFilter(int) ) ); + + // map xmltags to compare types + map_xmltag_cmptype.insert( XML_KND, CMP_KND ); + map_xmltag_cmptype.insert( XML_LBY, CMP_INT ); + map_xmltag_cmptype.insert( XML_LBL, CMP_INT ); + map_xmltag_cmptype.insert( XML_OBJ, CMP_STR ); + map_xmltag_cmptype.insert( XML_FUN, CMP_STR ); + map_xmltag_cmptype.insert( XML_DIR, CMP_STR ); + map_xmltag_cmptype.insert( XML_FIL, CMP_STR ); + map_xmltag_cmptype.insert( XML_LIN, CMP_INT ); + + // setup compare function comboboxes, along with their enums + combo_cmp[CMP_KND]->addItem( "==", FUN_EQL ); + combo_cmp[CMP_KND]->addItem( "!=", FUN_NEQL ); + combo_cmp[CMP_STR]->addItem( "==", FUN_EQL ); + combo_cmp[CMP_STR]->addItem( "!=", FUN_NEQL ); + combo_cmp[CMP_STR]->addItem( "contains", FUN_CONT ); + combo_cmp[CMP_STR]->addItem( "! contain", FUN_NCONT ); + combo_cmp[CMP_STR]->addItem( "starts with", FUN_STRT ); + combo_cmp[CMP_STR]->addItem( "! starts with", FUN_NSTRT ); + combo_cmp[CMP_STR]->addItem( "ends with", FUN_END ); + combo_cmp[CMP_STR]->addItem( "! ends with", FUN_NEND ); + combo_cmp[CMP_INT]->addItem( "==", FUN_EQL ); + combo_cmp[CMP_INT]->addItem( "!=", FUN_NEQL ); + combo_cmp[CMP_INT]->addItem( "<", FUN_LSTHN ); + combo_cmp[CMP_INT]->addItem( ">", FUN_GRTHN ); + + // initialise filter combobox with all 'kind' types (display & matching text) + combo_filter->addItem( "", "" ); + combo_filter->addItem( "IVF - InvalidFree", "InvalidFree" ); + combo_filter->addItem( "MMF - MismatchedFree", "MismatchedFree" ); + combo_filter->addItem( "IVR - InvalidRead", "InvalidRead" ); + combo_filter->addItem( "IVW - InvalidWrite", "InvalidWrite" ); + combo_filter->addItem( "IVJ - InvalidJump", "InvalidJump" ); + combo_filter->addItem( "OVL - Overlap", "Overlap" ); + combo_filter->addItem( "IMP - InvalidMemPool", "InvalidMemPool" ); + combo_filter->addItem( "UNC - UninitCondition", "UninitCondition" ); + combo_filter->addItem( "UNV - UninitValue", "UninitValue" ); + combo_filter->addItem( "SCP - SyscallParam", "SyscallParam" ); + combo_filter->addItem( "CCK - ClientCheck", "ClientCheck" ); + combo_filter->addItem( "LDL - Leak_DefinitelyLost", "Leak_DefinitelyLost" ); + combo_filter->addItem( "LIL - Leak_IndirectlyLost", "Leak_IndirectlyLost" ); + combo_filter->addItem( "LPL - Leak_PossiblyLost", "Leak_PossiblyLost" ); + combo_filter->addItem( "LSR - Leak_StillReachable", "Leak_StillReachable" ); + + // initialise filters + setupFilter( 0 ); + ((QComboBox*)cmpWidgStack->currentWidget())->setCurrentIndex( 2 ); + + //TODO: ContextHelp::addHelp( this, urlValkyrie::XYZ); +} + +void LogViewFilterMC::setupFilter( int idx ) +{ +// vkDebug( "LogViewFilterMC::setupFilter( %d )", idx ); + + XmlTagType xmltag = (XmlTagType)combo_xmltag->itemData( idx ).toInt(); + CmpType cmp_type = map_xmltag_cmptype[ xmltag ]; + + // compares: combobox + cmpWidgStack->setCurrentIndex( cmp_type ); + + // filter values: combobox/lineedit + filterWidgStack->setCurrentIndex( cmp_type ); +} + + +void LogViewFilterMC::edited() +{ +// vkDebug( "LogViewFilterMC::edited()" ); + + butt_refresh->setEnabled( true ); +} + +void LogViewFilterMC::refresh() +{ +// vkDebug( "LogViewFilterMC::refresh()" ); + + butt_refresh->setEnabled( false ); + + updateView(); +} + + + + +void LogViewFilterMC::updateView() +{ +// vkDebug( "LogViewFilterMC::updateView()" ); + + if ( m_view == NULL ) { + vkPrintErr( "No treeview - This shouldn't happen!" ); + return; + } + + VgOutputItem* vgItemTop = (VgOutputItem*)m_view->topLevelItem( 0 ); + if ( vgItemTop == NULL ) { +// vkDebug( "No items in treeview." ); + return; + } + + // iterate over all the first-child items + for ( int i=0; i<vgItemTop->childCount(); ++i ) { + VgOutputItem* child = (VgOutputItem*)vgItemTop->child( i ); + + if ( child->elemType() == VG_ELEM::ERROR ) { + + if ( this->isHidden() ) { // show all items if filter is inactive + child->setHidden( false ); + } + else { // filter active: go filter! + showHideItem( child ); + } + } + } +} + + +void LogViewFilterMC::showHideItem( VgOutputItem* item ) +{ +// vkDebug( "LogViewFilterMC::showHideItem: %s", qPrintable( item->text(0) ) ); + + // sanity checks + if ( !item ) { + vkPrintErr( "NULL item. This shouldn't happen!"); + return; + } + + if ( item->elemType() != VG_ELEM::ERROR ) { + vkPrintErr( "Not an ERROR item. This shouldn't happen!"); + return; + } + + // get filter from widgets + // - first get and test the filter value: if empty -> no filter. + QString str_flt; + if ( filterWidgStack->currentIndex() == CMP_KND ) { // => combobox + QComboBox* combo = (QComboBox*)filterWidgStack->currentWidget(); + str_flt = combo->itemData( combo->currentIndex() ).toString(); + } + else { // => lineedit + QLineEdit* le = (QLineEdit*)filterWidgStack->currentWidget(); + str_flt = le->text(); + } + + if ( str_flt.isEmpty() ) { +// vkDebug( "Filter value empty -> empty filter" ); + item->setHidden( false ); + } + else { + QStringList xml_list; + + // get the compare function + QComboBox* comboCmpFun = (QComboBox*)cmpWidgStack->currentWidget(); + int idx = comboCmpFun->currentIndex(); + CmpFunType cmpFun = (CmpFunType)comboCmpFun->itemData( idx ).toInt(); + + // get the type to compare + idx = combo_xmltag->currentIndex(); + XmlTagType xmltag = (XmlTagType)combo_xmltag->itemData( idx ).toInt(); + CmpType cmp_type = map_xmltag_cmptype[ xmltag ]; + + // get the appropriate xml tag, and compare it with our filter + // - a positive match means the error item remains. + // - a negative match means the error item is hidden. + bool res_cmp = false; + switch ( xmltag ) { + case XML_KND: // Kind + vk_assert( cmp_type == CMP_KND ); + res_cmp = xmlCompare( item, "kind", str_flt, cmpFun, cmp_type ); + break; + case XML_LBY: // Leaked Bytes + vk_assert( cmp_type == CMP_INT ); + res_cmp = xmlCompare( item, "leakedbytes", str_flt, cmpFun, cmp_type ); + break; + case XML_LBL: // Leaked Blocks + vk_assert( cmp_type == CMP_INT ); + res_cmp = xmlCompare( item, "leakedblocks", str_flt, cmpFun, cmp_type ); + break; + case XML_OBJ: // Object + vk_assert( cmp_type == CMP_STR ); + res_cmp = xmlCompare( item, "obj", str_flt, cmpFun, cmp_type ); + break; + case XML_FUN: // Function + vk_assert( cmp_type == CMP_STR ); + res_cmp = xmlCompare( item, "fn", str_flt, cmpFun, cmp_type ); + break; + case XML_DIR: // Directory + vk_assert( cmp_type == CMP_STR ); + res_cmp = xmlCompare( item, "dir", str_flt, cmpFun, cmp_type ); + break; + case XML_FIL: // File + vk_assert( cmp_type == CMP_STR ); + res_cmp = xmlCompare( item, "file", str_flt, cmpFun, cmp_type ); + break; + case XML_LIN: // Line + vk_assert( cmp_type == CMP_INT ); + res_cmp = xmlCompare( item, "line", str_flt, cmpFun, cmp_type ); + break; + default: + vk_assert_never_reached(); + } + + item->setHidden( !res_cmp ); + } +} + + +void LogViewFilterMC::enableFilter( bool enable ) +{ + if ( enable ) + this->show(); + else + this->hide(); + + updateView(); +} + + + + + +bool LogViewFilterMC::xmlCompare( VgOutputItem* errItem, const QString& tag, + const QString& str_flt, CmpFunType cmpFun, CmpType cmp_type ) +{ + // extract the relevant XML data + // no idea if this is good enough... sometimes maybe better to get first tag only? + QStringList list_xml; + QDomNodeList nodelist = errItem->getElement().elementsByTagName( tag ); + for (int i=0; i<nodelist.count(); ++i ) { + list_xml << nodelist.at(i).toElement().text(); + } + + // compare strings or integers? + bool res_cmp = false; + switch (cmp_type) { + case CMP_KND: + case CMP_STR: + res_cmp = compare_strings( list_xml, str_flt, cmpFun ); + break; + case CMP_INT: + res_cmp = compare_integers( list_xml, str_flt, cmpFun ); + break; + default: + vk_assert_never_reached(); + } + +// vkDebug( "LogViewFilterMC::xmlCompare: res_cmp: '%d'", res_cmp ); + + return res_cmp; +} + + + +/*! + Compare strings. + If _any_ of the strings in lst_xml match str_flt, return true (don't hide) + If no match, return false (hide) + Any problems, just return true (i.e. don't hide) +*/ +bool LogViewFilterMC::compare_strings( const QStringList& lst_xml, + const QString& str_flt, + CmpFunType cmpfuntype ) +{ + + bool res_cmp = false; + foreach ( QString str_xml, lst_xml ) { +// vkDebug( "LogViewFilterMC::compare_strings(%d): '%s'' - '%s'", cmpfuntype, qPrintable( str_xml ), qPrintable( str_flt ) ); + + switch ( cmpfuntype ) { + case FUN_EQL: res_cmp = ( str_xml == str_flt ); break; + case FUN_NEQL: res_cmp = ( str_xml != str_flt ); break; + case FUN_CONT: res_cmp = ( str_xml.contains( str_flt )); break; + case FUN_NCONT: res_cmp = (!str_xml.contains( str_flt )); break; + case FUN_STRT: res_cmp = ( str_xml.startsWith( str_flt )); break; + case FUN_NSTRT: res_cmp = (!str_xml.startsWith( str_flt )); break; + case FUN_END: res_cmp = ( str_xml.endsWith( str_flt )); break; + case FUN_NEND: res_cmp = (!str_xml.endsWith( str_flt )); break; + break; + default: + vk_assert_never_reached(); + } + + // match found - don't filter out this item! + if ( res_cmp ) + return true; + } + + // no match: filter out (hide) this item + return false; +} + + +/*! + Compare integers. + First convert from strings to integers. + If _any_ of the strings in lst_xml match str_flt, return true (don't hide) + If no match, return false (hide) + Any problems, just return true (i.e. don't hide) +*/ +bool LogViewFilterMC::compare_integers( const QStringList& lst_xml, + const QString& str_flt, + CmpFunType cmpfuntype ) +{ + bool res_cmp = false; + foreach ( QString str_xml, lst_xml ) { + + bool ok = true; + int int_flt = str_flt.toInt( &ok ); + if ( !ok ) { +// vkDebug( "Failed conversion (str_flt) to integer: '%s'", qPrintable(str_flt) ); + continue; + } + + int int_xml = str_xml.toInt( &ok ); + if ( !ok ) { +// vkDebug( "Failed conversion (str_xml) to integer: '%s'", qPrintable(str_xml) ); + continue; + } + +// vkDebug( "LogViewFilterMC::compare_integers: '%d'' - '%d'", int_xml, int_flt ); + + switch ( cmpfuntype ) { + case FUN_EQL: res_cmp = (int_xml == int_flt); break; + case FUN_NEQL: res_cmp = (int_xml != int_flt); break; + case FUN_LSTHN: res_cmp = (int_xml < int_flt); break; + case FUN_GRTHN: res_cmp = (int_xml > int_flt); break; + default: + vk_assert_never_reached(); + } + + // match found - don't filter out this item! + if ( res_cmp ) + return true; + } + + // no match: filter out (hide) this item + return false; +} Added: trunk/src/toolview/logviewfilter_mc.h =================================================================== --- trunk/src/toolview/logviewfilter_mc.h (rev 0) +++ trunk/src/toolview/logviewfilter_mc.h 2011-07-03 05:22:53 UTC (rev 546) @@ -0,0 +1,68 @@ +/**************************************************************************** +** LogViewFilterMC definition +** -------------------------------------------------------------------------- +** +** Copyright (C) 2011-2011, OpenWorks LLP. All rights reserved. +** <in...@op...> +** +** This file is part of Valkyrie, a front-end for Valgrind. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file COPYING included in the packaging of +** this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef LOGVIEWFILTER_MC_H +#define LOGVIEWFILTER_MC_H + +#include "toolview/vglogview.h" + +#include <QComboBox> +#include <QPushButton> +#include <QStackedWidget> +#include <QTreeWidget> +#include <QWidget> + + +class LogViewFilterMC : public QWidget +{ + Q_OBJECT +public: + LogViewFilterMC(QWidget *parent, QTreeWidget* view ); + +public slots: + void showHideItem( VgOutputItem* item ); + void enableFilter( bool enable ); + +private slots: + void setupFilter( int idx ); + void updateView(); + void edited(); + void refresh(); + +private: + QTreeWidget* m_view; // hold on to this to rescan entire tree. + + QPushButton* butt_refresh; // refresh the filter after editing + QComboBox* combo_xmltag; // combobox of xmltags to filter on + QStackedWidget* cmpWidgStack; // hold the different compare comboboxes + QStackedWidget* filterWidgStack; // hold the different filter value widgets + + enum XmlTagType { XML_KND, XML_LBY, XML_LBL, XML_OBJ, XML_FUN, XML_DIR, XML_FIL, XML_LIN }; + enum CmpType { CMP_KND, CMP_STR, CMP_INT }; + enum CmpFunType { FUN_EQL, FUN_NEQL, FUN_LSTHN, FUN_GRTHN, FUN_CONT, + FUN_NCONT, FUN_STRT, FUN_NSTRT, FUN_END, FUN_NEND }; + QMap<XmlTagType, CmpType> map_xmltag_cmptype; + + bool xmlCompare( VgOutputItem* errItem, const QString& tag, + const QString& str_flt, CmpFunType cmpFun, CmpType cmp_type ); + bool compare_strings( const QStringList& list_xml, const QString& str_flt, CmpFunType cmpfuntype ); + bool compare_integers( const QStringList& list_xml, const QString& str_flt, CmpFunType cmpfuntype ); +}; + +#endif // LOGVIEWFILTER_MC_H Modified: trunk/src/toolview/memcheck_logview.cpp =================================================================== --- trunk/src/toolview/memcheck_logview.cpp 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/src/toolview/memcheck_logview.cpp 2011-07-03 05:22:53 UTC (rev 546) @@ -104,7 +104,7 @@ /* HACK ALERT! VALGRIND_DO_LEAK_CHECK gives repeated leaks... taking apart error::what to get record number - - if '1' then reset counters + - if this is 'record 1' then reset counters */ QDomElement text = xwhat.firstChildElement( "text" ); if ( ! text.isNull() ) { @@ -184,6 +184,10 @@ QDomElement err = elem; lastItem = new ErrorItemMC( topStatus, lastItem, err ); +// TODO: +// flicker a problem? + emit this->errorItemAdded( lastItem ); + // update topStatus topStatus->updateToolStatus( err ); break; Modified: trunk/src/toolview/memcheck_logview.h =================================================================== --- trunk/src/toolview/memcheck_logview.h 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/src/toolview/memcheck_logview.h 2011-07-03 05:22:53 UTC (rev 546) @@ -27,10 +27,14 @@ // ============================================================ class MemcheckLogView : public VgLogView { + Q_OBJECT public: MemcheckLogView( QTreeWidget* ); ~MemcheckLogView(); - + +signals: + void errorItemAdded( VgOutputItem* item ); + private: // Template method functions: TopStatusItem* createTopStatus( QTreeWidget* view, QDomElement exe, Modified: trunk/src/toolview/memcheckview.cpp =================================================================== --- trunk/src/toolview/memcheckview.cpp 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/src/toolview/memcheckview.cpp 2011-07-03 05:22:53 UTC (rev 546) @@ -23,6 +23,7 @@ #include "options/vk_options_dialog.h" #include "options/valgrind_options_page.h" #include "options/vk_suppressions_dialog.h" +#include "toolview/logviewfilter_mc.h" // filters #include "toolview/memcheckview.h" #include "toolview/memcheck_logview.h" #include "utils/vk_config.h" @@ -120,6 +121,11 @@ } logview = new MemcheckLogView( treeView ); + + // let filter show/hide an item + connect( logview, SIGNAL(errorItemAdded(VgOutputItem*)), + logviewFilter, SLOT(showHideItem(VgOutputItem*)) ); + return logview; } @@ -142,6 +148,11 @@ treeView->header()->setResizeMode(0, QHeaderView::ResizeToContents); treeView->header()->setStretchLastSection(false); + // filter + logviewFilter = new LogViewFilterMC( this, treeView ); + + // layout + vLayout->addWidget( logviewFilter ); vLayout->addWidget( treeView ); } @@ -195,6 +206,20 @@ act_SaveLog->setIconVisibleInMenu( true ); connect( act_SaveLog, SIGNAL( triggered() ), this, SIGNAL( saveLogFile() ) ); + act_enableFilter = new QAction( this ); + act_enableFilter->setObjectName( QString::fromUtf8( "act_enableFilter" ) ); + QIcon icon_filter; + icon_filter.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/filter_off.png" ) ), + QIcon::Normal, QIcon::On ); + icon_filter.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/filter.png" ) ), + QIcon::Normal, QIcon::Off ); + act_enableFilter->setIcon( icon_filter ); + act_enableFilter->setIconVisibleInMenu( true ); + act_enableFilter->setCheckable( true ); + act_enableFilter->setChecked( true ); + connect( act_enableFilter, SIGNAL(toggled(bool)), + logviewFilter, SLOT(enableFilter(bool)) ); + // ------------------------------------------------------------ // initialise actions (enable / disable) setState( false ); @@ -212,6 +237,10 @@ act_OpenLog->setToolTip( tr( "Open Memcheck XML log" ) ); act_SaveLog->setText( tr( "Save Log" ) ); act_SaveLog->setToolTip( tr( "Save Valgrind output to an XML log" ) ); + + act_enableFilter->setText( tr( "Filters on/off" ) ); + act_enableFilter->setToolTip( tr( "Enable or disable the temporary log filters." ) ); + } @@ -230,6 +259,7 @@ toolToolBar->addAction( act_ShowSrcPaths ); toolToolBar->addAction( act_OpenLog ); toolToolBar->addAction( act_SaveLog ); + toolToolBar->addAction( act_enableFilter ); // ------------------------------------------------------------ // Memcheck menu (created in base class) @@ -241,6 +271,7 @@ toolMenu->addAction( act_ShowSrcPaths ); toolMenu->addAction( act_OpenLog ); toolMenu->addAction( act_SaveLog ); + toolMenu->addAction( act_enableFilter ); } Modified: trunk/src/toolview/memcheckview.h =================================================================== --- trunk/src/toolview/memcheckview.h 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/src/toolview/memcheckview.h 2011-07-03 05:22:53 UTC (rev 546) @@ -23,6 +23,7 @@ #include "toolview/toolview.h" #include "toolview/vglogview.h" +#include "toolview/logviewfilter_mc.h" #include <QMenu> #include <QTreeWidget> @@ -63,9 +64,12 @@ QAction* act_ShowSrcPaths; QAction* act_OpenLog; QAction* act_SaveLog; + QAction* act_enableFilter; QTreeWidget* treeView; VgLogView* logview; + + LogViewFilterMC* logviewFilter; }; #endif // __MEMCHECKVIEW_H Modified: trunk/src/toolview/vglogview.h =================================================================== --- trunk/src/toolview/vglogview.h 2011-07-03 04:10:09 UTC (rev 545) +++ trunk/src/toolview/vglogview.h 2011-07-03 05:22:53 UTC (rev 546) @@ -23,6 +23,7 @@ #include <QColorGroup> #include <QDateTime> +#include <QObject> #include <QPainter> #include <QPixmap> #include <QTreeWidget> @@ -67,8 +68,9 @@ the branch. the QDomElement refs held by item are then queried to fill the item data. */ -class VgLogView +class VgLogView : public QObject { + Q_OBJECT public: VgLogView( QTreeWidget* ); ~VgLogView(); |