|
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();
|