summaryrefslogtreecommitdiffstats
path: root/parts/valgrind
diff options
context:
space:
mode:
Diffstat (limited to 'parts/valgrind')
-rw-r--r--parts/valgrind/Makefile.am15
-rw-r--r--parts/valgrind/README.dox45
-rw-r--r--parts/valgrind/dialog_widget.ui360
-rw-r--r--parts/valgrind/dialog_widget.ui.h21
-rw-r--r--parts/valgrind/kdevpart_valgrind.rc9
-rw-r--r--parts/valgrind/kdevvalgrind.desktop74
-rw-r--r--parts/valgrind/valgrind_dialog.cpp206
-rw-r--r--parts/valgrind/valgrind_dialog.h62
-rw-r--r--parts/valgrind/valgrind_part.cpp366
-rw-r--r--parts/valgrind/valgrind_part.h62
-rw-r--r--parts/valgrind/valgrind_widget.cpp205
-rw-r--r--parts/valgrind/valgrind_widget.h44
-rw-r--r--parts/valgrind/valgrinditem.cpp71
-rw-r--r--parts/valgrind/valgrinditem.h50
14 files changed, 1590 insertions, 0 deletions
diff --git a/parts/valgrind/Makefile.am b/parts/valgrind/Makefile.am
new file mode 100644
index 00000000..07550df6
--- /dev/null
+++ b/parts/valgrind/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util $(all_includes)
+
+kde_module_LTLIBRARIES = libkdevvalgrind.la
+libkdevvalgrind_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
+libkdevvalgrind_la_LIBADD = $(top_builddir)/lib/libkdevelop.la
+
+libkdevvalgrind_la_SOURCES = dialog_widget.ui valgrind_part.cpp valgrind_widget.cpp valgrind_dialog.cpp valgrinditem.cpp
+
+METASOURCES = AUTO
+
+servicedir = $(kde_servicesdir)
+service_DATA = kdevvalgrind.desktop
+
+rcdir = $(kde_datadir)/kdevvalgrind
+rc_DATA = kdevpart_valgrind.rc
diff --git a/parts/valgrind/README.dox b/parts/valgrind/README.dox
new file mode 100644
index 00000000..d5e79fd4
--- /dev/null
+++ b/parts/valgrind/README.dox
@@ -0,0 +1,45 @@
+/** \class ValgrindPart
+Valgrind is a tool that helps you find memory management problems in programs. http://developer.kde.org/~sewardj/
+
+\authors <a href="mailto:$EMAIL$">$AUTHOR$</a>
+\authors <a href="mailto:2nd author AT provider.com">2nd author full name</a>
+...
+\authors <a href="mailto:nth author AT provider.com">nth author full name</a>
+
+\maintainer <a href="mailto:$EMAIL$">$AUTHOR$</a>
+\maintainer <a href="mailto:2nd maintainer AT provider.com">2nd maintainer full name</a>
+...
+\maintainer <a href="mailto:nth maintainer AT provider.com">nth maintainer full name</a>
+
+\feature Integrates Valgrind into KDevelop
+
+\bug Describe a the 1st bug that you know of, but probably hasn't been reported yet.
+..
+\bug Describe a the nth bug that you know of, but probably hasn't been reported yet.
+
+\requirement Describe a the 1st requirement of your part.
+\requirement Describe a the 2nd requirement of your part.
+...
+\requirement Describe a the nth requirement of your part.
+
+\todo Describe a the 1st TODO of your part.
+\todo Describe a the 2nd TODO of your part.
+...
+\todo Describe a the nth TODO of your part.
+
+\faq <b>First frequenly asked question about your part ?</b> Answer.
+\faq <b>Second frequenly asked question about your part ?</b> Answer.
+...
+\faq <b>Last frequenly asked question about your part ?</b> Answer.
+
+\note First note text.
+\note Second note text.
+...
+\note Last note text.
+
+\warning First warning text.
+\warning Second warning text.
+...
+\warning Last warning text.
+
+*/
diff --git a/parts/valgrind/dialog_widget.ui b/parts/valgrind/dialog_widget.ui
new file mode 100644
index 00000000..35ded9c1
--- /dev/null
+++ b/parts/valgrind/dialog_widget.ui
@@ -0,0 +1,360 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>DialogWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>DialogWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>322</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Application</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>executableEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Parameters:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>paramEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Executable:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>executableEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>paramEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidgetStack" row="1" column="0">
+ <property name="name">
+ <cstring>stack</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Valgrind</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>memleakBox</cstring>
+ </property>
+ <property name="text">
+ <string>Memory &amp;leak check</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>reachableBox</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Show still reachable blocks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>childrenBox</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Trace children</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Additional p&amp;arameters:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>valParamEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>valParamEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>valExecutableEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xecutable:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>valExecutableEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>1</number>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Valgrind</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout3_2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel5_2</cstring>
+ </property>
+ <property name="text">
+ <string>Additional p&amp;arameters:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>valParamEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>ctParamEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>ctExecutableEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xecutable:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>valExecutableEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>ctChildrenBox</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Trace children</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>KCachegrind</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>kcExecutableEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Exe&amp;cutable:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>valExecutableEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>memleakBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>DialogWidget</receiver>
+ <slot>checkBoxToggled()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>executableEdit</tabstop>
+ <tabstop>paramEdit</tabstop>
+ <tabstop>memleakBox</tabstop>
+ <tabstop>reachableBox</tabstop>
+ <tabstop>childrenBox</tabstop>
+ <tabstop>valExecutableEdit</tabstop>
+ <tabstop>valParamEdit</tabstop>
+ <tabstop>ctChildrenBox</tabstop>
+ <tabstop>ctExecutableEdit</tabstop>
+ <tabstop>ctParamEdit</tabstop>
+ <tabstop>kcExecutableEdit</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in implementation">kdialog.h</include>
+</includes>
+<slots>
+ <slot access="private" specifier="non virtual">checkBoxToggled()</slot>
+ <slot>init()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/parts/valgrind/dialog_widget.ui.h b/parts/valgrind/dialog_widget.ui.h
new file mode 100644
index 00000000..9a2570ae
--- /dev/null
+++ b/parts/valgrind/dialog_widget.ui.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+
+void DialogWidget::checkBoxToggled()
+{
+ reachableBox->setEnabled( memleakBox->isChecked() );
+}
+
+
+void DialogWidget::init()
+{
+ valParamEdit->setMinimumWidth( valParamEdit->fontMetrics().width( "0" ) * 30 );
+ checkBoxToggled();
+}
diff --git a/parts/valgrind/kdevpart_valgrind.rc b/parts/valgrind/kdevpart_valgrind.rc
new file mode 100644
index 00000000..440b62c2
--- /dev/null
+++ b/parts/valgrind/kdevpart_valgrind.rc
@@ -0,0 +1,9 @@
+<!DOCTYPE kpartgui>
+<kpartplugin name="valgrind" library="libvalgrindplugin" version="3">
+<MenuBar>
+ <Menu name="debug"><Text>&amp;Debug</Text>
+ <Action name="tools_valgrind" group="profile"/>
+ <Action name="tools_calltree" group="profile"/>
+ </Menu>
+</MenuBar>
+</kpartplugin>
diff --git a/parts/valgrind/kdevvalgrind.desktop b/parts/valgrind/kdevvalgrind.desktop
new file mode 100644
index 00000000..23b5cf4f
--- /dev/null
+++ b/parts/valgrind/kdevvalgrind.desktop
@@ -0,0 +1,74 @@
+[Desktop Entry]
+Type=Service
+Exec=blubb
+Comment=Valgrind is a tool that helps you find memory management problems in programs. http://valgrind.org/
+Comment[ca]=Valgrind és una eina que us ajuda a trobar problemes en la gestió de la memòria en els programes. http://valgrind.org/
+Comment[da]=Valgrind er et værktøj der hjælper dig med at finde hukommelseshåndteringsproblemer i programmer. http://valgrind.org/
+Comment[de]=Valgrind ist ein Werkzeug zum Auffinden von Speicherverwaltungsproblemen in Anwendungen. http://valgrind.org/
+Comment[el]=Το Valgrind είναι ένα εργαλείο που βοηθά στην εύρεση προβλημάτων διαχείρισης μνήμης στα προγράμματα. http://valgrind.org/
+Comment[es]=Valgrind es una herramienta que le ayuda a encontrar problemas de gestión de memoria en los programas. http://valgrind.org/
+Comment[et]=Valgrind aitab leida programmides mälulekkeid ja muid mäluga seotud asju. http://valgrind.org/
+Comment[fr]=Valgrind est un outil qui vous aide à trouver les problèmes de gestion de la mémoire dans les programmes. http://valgrind.org/
+Comment[hu]=A Valgrind memóriakezelési hibák keresésére alkalmas program - http://valgrind.org
+Comment[it]=Valgrind è uno strumento che ti aiuta a trovare problemi di gestione della memoria nei programmi. http://valgrind.org/
+Comment[ja]=Valgrind は、プログラム内のメモリ管理問題を発見することを手助けするツールです。http://valgrind.org/
+Comment[ms]=Valgrind adalah alatan yang membantu anda mencari masalah pengurusan memori dalam program. http://valgrind.org/
+Comment[nds]=Valgrind is en Warktüüch för't Finnen vun t Spiekerpleegproblemen in Programmen. http://valgrind.org/
+Comment[nl]=Valgrind is een hulpprogramma dat u helpt bij het opsporen van geheugenproblemen in programma's. http://valgrind.org/
+Comment[pl]=Valgrind jest narzędziem pomagającym znaleźć w programach problemy z zarządzaniem pamięcią. http://valgrind.org/
+Comment[pt]=O Valgrind é uma ferramenta que o ajuda a descobrir os problemas de gestão de memória nos programas. http://www.valgrind.org/
+Comment[pt_BR]=Valgrind é uma ferramenta ajuda você a encontrar problemas de gerenciamento de memória nos programas. http://www.valgrind.org/
+Comment[ru]=Valgrind - средство нахождения проблем управления памятью в программах. http://valgrind.org/
+Comment[sk]=Valgrind je nástroj, ktorý pomáha nájsť problémy so správou pamäte v programoch. http://valgrind.org/
+Comment[sr]=Valgrind је алат који вам помаже да нађете проблеме са употребом меморије у програмима. http://valgrind.org/
+Comment[sr@Latn]=Valgrind je alat koji vam pomaže da nađete probleme sa upotrebom memorije u programima. http://valgrind.org/
+Comment[sv]=Valgrind är ett verktyg som hjälper dig hitta minneshanteringsproblem i program. Se http://valgrind.org/.
+Comment[zh_TW]=Valgrind 能協助您找到程式中記憶體管理上的問題。http://valgrind.org/
+Name=KDevvalgrind
+Name[da]=KDevelop Valgrind
+Name[de]=Unterstützung für Valgrind (KDevelop)
+Name[hi]=के-डेववेलग्रिंड
+Name[nds]=Ünnerstütten för Valgrind (KDevelop)
+Name[sk]=KDev valgrind
+Name[sv]=KDevelop valgrind
+Name[zh_TW]=KDevelop Valgrind
+GenericName=Valgrind Frontend
+GenericName[ca]=Entorn per a Valgrind
+GenericName[da]=Valgrind-grænseflade
+GenericName[de]=Oberfläche für Valgrind
+GenericName[el]=Πρόγραμμα Valgrind
+GenericName[es]=Interfaz para Valgrind
+GenericName[et]=Valgrindi kasutajaliides
+GenericName[eu]=Valgrind interfazea
+GenericName[fa]=پایانۀ Valgrind
+GenericName[fr]=Interface de Valgrind
+GenericName[ga]=Comhéadan Valgrind
+GenericName[gl]=Frontal para Valgrind
+GenericName[hi]=वेलग्रिन्ड फ्रन्टएण्ड
+GenericName[hu]=Valgrind-kezelő
+GenericName[it]=Interfaccia a Valgrind
+GenericName[ja]=Valgrind フロントエンド
+GenericName[ms]=Frontend Valgrind
+GenericName[nds]=Valgrind-Böversiet
+GenericName[ne]=भलग्रिन्ड फ्रन्टइन्ड
+GenericName[nl]=Valgrind-frontend
+GenericName[pl]=Interfejs do Valgrinda
+GenericName[pt]=Interface para o Valgrind
+GenericName[pt_BR]=Frontend do Valgrind
+GenericName[ru]=Интерфейс к Valgrind
+GenericName[sk]=Valgrind rozhranie
+GenericName[sl]=VMesnik za Valgrind
+GenericName[sr]=Кориснички интерфејс за Valgrind
+GenericName[sr@Latn]=Korisnički interfejs za Valgrind
+GenericName[sv]=Valgrind-gränssnitt
+GenericName[ta]=Valgrind முன் பகுதி
+GenericName[tg]=Интерфейс дар Valgrind
+GenericName[tr]=Valgrind Önucu
+GenericName[zh_CN]=Valgrind 前端
+GenericName[zh_TW]=Valgrind 前端介面
+Icon=kdevelop
+ServiceTypes=KDevelop/Plugin
+X-KDevelop-Scope=Global
+X-KDE-Library=libkdevvalgrind
+X-KDevelop-Version=5
+X-KDevelop-Properties=CompiledDevelopment
diff --git a/parts/valgrind/valgrind_dialog.cpp b/parts/valgrind/valgrind_dialog.cpp
new file mode 100644
index 00000000..405d78dd
--- /dev/null
+++ b/parts/valgrind/valgrind_dialog.cpp
@@ -0,0 +1,206 @@
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qregexp.h>
+#include <qwidgetstack.h>
+
+#include <kprocess.h>
+#include <klocale.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+
+#include "dialog_widget.h"
+#include "valgrind_dialog.h"
+
+#include "valgrind_dialog.moc"
+
+
+ValgrindDialog::ValgrindDialog( Type type, QWidget* parent )
+ : KDialogBase( parent, "valgrind dialog", true, i18n("Valgrind Memory Check"), Ok|Cancel ),
+ m_type(type)
+{
+ w = new DialogWidget( this );
+ w->valExecutableEdit->setURL( "valgrind" );
+ w->executableEdit->setFocus();
+ w->stack->raiseWidget(m_type);
+ setMainWidget( w );
+ connect( w->executableEdit->lineEdit(), SIGNAL( textChanged( const QString &)), this, SLOT( valgrindTextChanged()));
+ connect( w->valExecutableEdit->lineEdit(), SIGNAL( textChanged( const QString &)), this, SLOT( valgrindTextChanged()));
+ connect( w->ctExecutableEdit->lineEdit(), SIGNAL( textChanged( const QString &)), this, SLOT( valgrindTextChanged()));
+ connect( w->kcExecutableEdit->lineEdit(), SIGNAL( textChanged( const QString &)), this, SLOT( valgrindTextChanged()));
+ enableButtonOK( false );
+}
+
+
+ValgrindDialog::~ValgrindDialog()
+{
+}
+
+void ValgrindDialog::valgrindTextChanged()
+{
+ if (m_type == Memcheck)
+ enableButtonOK( !w->valExecutableEdit->lineEdit()->text().isEmpty() && !w->executableEdit->lineEdit()->text().isEmpty() );
+ else if (m_type == Calltree)
+ enableButtonOK( !w->executableEdit->lineEdit()->text().isEmpty() && !w->ctExecutableEdit->lineEdit()->text().isEmpty() && !w->kcExecutableEdit->lineEdit()->text().isEmpty() );
+}
+
+QString ValgrindDialog::executableName() const
+{
+ return w->executableEdit->url();
+}
+
+void ValgrindDialog::setExecutable( const QString& url )
+{
+ w->executableEdit->setURL( url );
+}
+
+QString ValgrindDialog::valExecutable() const
+{
+ return w->valExecutableEdit->url();
+}
+
+QString ValgrindDialog::parameters() const
+{
+ return w->paramEdit->text();
+}
+
+void ValgrindDialog::setParameters( const QString& params )
+{
+ w->paramEdit->setText( params );
+}
+
+void ValgrindDialog::setValExecutable( const QString& ve )
+{
+ QString vUrl = ve;
+ if ( vUrl.isEmpty() ) {
+ vUrl = KStandardDirs::findExe( "valgrind" );
+ }
+ if ( vUrl.isEmpty() ) {
+ KMessageBox::sorry( this, i18n( "Could not find valgrind in your $PATH. Please make "
+ "sure it is installed properly." ),
+ i18n( "Valgrind Not Found" ) );
+ w->valExecutableEdit->setURL( "valgrind" );
+ } else {
+ w->valExecutableEdit->setURL( vUrl );
+ }
+}
+
+static const QString memCheckParam( "--tool=memcheck" );
+static const QString leakCheckParam( "--leak-check=yes" );
+static const QString reachableParam( "--show-reachable=yes" );
+static const QString childrenParam( "--trace-children=yes" );
+
+QString ValgrindDialog::valParams() const
+{
+ QString params = w->valParamEdit->text();
+ if (isNewValgrindVersion())
+ params += " " + memCheckParam;
+ if ( w->memleakBox->isChecked() )
+ params += " " + leakCheckParam;
+ if ( w->reachableBox->isChecked() )
+ params += " " + reachableParam;
+ if ( w->childrenBox->isChecked() )
+ params += " " + childrenParam;
+
+ return params;
+}
+
+void ValgrindDialog::setValParams( const QString& params )
+{
+ QString myParams = params;
+ if ( myParams.contains( leakCheckParam ) )
+ w->memleakBox->setChecked( true );
+ if ( myParams.contains( reachableParam ) )
+ w->reachableBox->setChecked( true );
+ if ( myParams.contains( childrenParam ) )
+ w->childrenBox->setChecked( true );
+ w->init();
+
+ myParams = myParams.replace( QRegExp( memCheckParam ), "" );
+ myParams = myParams.replace( QRegExp( leakCheckParam ), "" );
+ myParams = myParams.replace( QRegExp( reachableParam ), "" );
+ myParams = myParams.replace( QRegExp( childrenParam ), "" );
+ myParams = myParams.stripWhiteSpace();
+ w->valParamEdit->setText( myParams );
+}
+
+QString ValgrindDialog::ctExecutable() const
+{
+ return w->ctExecutableEdit->url();
+}
+
+void ValgrindDialog::setCtExecutable( const QString& ce )
+{
+ QString vUrl = ce;
+ if ( vUrl.isEmpty() ) {
+ vUrl = KStandardDirs::findExe( "valgrind" );
+ }
+ if ( vUrl.isEmpty() ) {
+ KMessageBox::sorry( this, i18n( "Could not find valgrind in your $PATH. Please make "
+ "sure it is installed properly." ),
+ i18n( "Valgrind Not Found" ) );
+ w->ctExecutableEdit->setURL( "valgrind" );
+ } else {
+ w->ctExecutableEdit->setURL( vUrl );
+ }
+}
+
+QString ValgrindDialog::ctParams() const
+{
+ QString params = w->ctParamEdit->text();
+ if ( w->ctChildrenBox->isChecked() )
+ params += " " + childrenParam;
+
+ return params;
+}
+
+void ValgrindDialog::setCtParams( const QString& params )
+{
+ QString myParams = params;
+ //force --tool=callgrind if no params are given
+ if (myParams.isEmpty())
+ myParams = "--tool=callgrind";
+ if ( myParams.contains( childrenParam ) )
+ w->ctChildrenBox->setChecked( true );
+ w->init();
+
+ myParams = myParams.replace( QRegExp( childrenParam ), "" );
+ myParams = myParams.stripWhiteSpace();
+ w->ctParamEdit->setText( myParams );
+}
+
+QString ValgrindDialog::kcExecutable( ) const
+{
+ return w->kcExecutableEdit->url();
+}
+
+void ValgrindDialog::setKcExecutable( const QString& ke )
+{
+ QString vUrl = ke;
+ if ( vUrl.isEmpty() ) {
+ vUrl = KStandardDirs::findExe( "kcachegrind" );
+ }
+ if ( vUrl.isEmpty() ) {
+ KMessageBox::sorry( this, i18n( "Could not find kcachegrind in your $PATH. Please make "
+ "sure it is installed properly." ),
+ i18n( "KCachegrind Not Found" ) );
+ w->kcExecutableEdit->setURL( "kcachegrind" );
+ } else {
+ w->kcExecutableEdit->setURL( vUrl );
+ }
+}
+
+bool ValgrindDialog::isNewValgrindVersion( ) const
+{
+ KProcess *proc = new KProcess;
+ proc->setUseShell(true);
+ *proc << "test \"valgrind-20\" == `valgrind --version | awk -F \\. '{print $1$2}'`";
+ proc->start(KProcess::Block);
+ if (proc->normalExit())
+ return proc->exitStatus();
+ return true;
+}
+
+// kate: space-indent on; indent-width 2; tab-width 2; show-tabs on;
+
diff --git a/parts/valgrind/valgrind_dialog.h b/parts/valgrind/valgrind_dialog.h
new file mode 100644
index 00000000..41c25afc
--- /dev/null
+++ b/parts/valgrind/valgrind_dialog.h
@@ -0,0 +1,62 @@
+
+#ifndef _VALGRIND_DIALOG_H_
+#define _VALGRIND_DIALOG_H_
+
+#include <kdialogbase.h>
+
+class KURLRequester;
+class DialogWidget;
+
+/**
+ *
+ * Harald Fernengel
+ **/
+class ValgrindDialog : public KDialogBase
+{
+ Q_OBJECT
+public:
+ enum Type { Memcheck = 0, Calltree = 1 };
+
+ ValgrindDialog( Type type, QWidget* parent = 0 );
+ ~ValgrindDialog();
+
+ // the app to check
+ QString executableName() const;
+ void setExecutable( const QString& url );
+
+ // command line parameters for the app
+ QString parameters() const;
+ void setParameters( const QString& params );
+
+ // name and/or path to the valgrind executable
+ QString valExecutable() const;
+ void setValExecutable( const QString& ve );
+
+ // command line parameters for valgrind
+ QString valParams() const;
+ void setValParams( const QString& params );
+
+ // name and/or path to the calltree executable
+ QString ctExecutable() const;
+ void setCtExecutable( const QString& ce );
+
+ // command line parameters for calltree
+ QString ctParams() const;
+ void setCtParams( const QString& params );
+
+ // name and/or path to the kcachegrind executable
+ QString kcExecutable() const;
+ void setKcExecutable( const QString& ke );
+
+protected:
+ bool isNewValgrindVersion() const;
+
+private:
+ DialogWidget *w;
+ Type m_type;
+ private slots:
+ void valgrindTextChanged();
+
+};
+
+#endif
diff --git a/parts/valgrind/valgrind_part.cpp b/parts/valgrind/valgrind_part.cpp
new file mode 100644
index 00000000..868faf28
--- /dev/null
+++ b/parts/valgrind/valgrind_part.cpp
@@ -0,0 +1,366 @@
+#include "valgrind_part.h"
+
+#include <qwhatsthis.h>
+#include <qregexp.h>
+#include <qfile.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kdevgenericfactory.h>
+#include <kaction.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <kdebug.h>
+
+#include "kdevcore.h"
+#include "kdevmainwindow.h"
+#include "kdevproject.h"
+#include "kdevplugininfo.h"
+
+#include "valgrind_widget.h"
+#include "valgrind_dialog.h"
+#include "valgrinditem.h"
+
+typedef KDevGenericFactory<ValgrindPart> ValgrindFactory;
+static const KDevPluginInfo data("kdevvalgrind");
+K_EXPORT_COMPONENT_FACTORY( libkdevvalgrind, ValgrindFactory( data ) )
+
+ValgrindPart::ValgrindPart( QObject *parent, const char *name, const QStringList& )
+ : KDevPlugin( &data, parent, name ? name : "ValgrindPart" )
+{
+ setInstance( ValgrindFactory::instance() );
+ setXMLFile( "kdevpart_valgrind.rc" );
+
+ proc = new KShellProcess();
+ connect( proc, SIGNAL(receivedStdout( KProcess*, char*, int )),
+ this, SLOT(receivedStdout( KProcess*, char*, int )) );
+ connect( proc, SIGNAL(receivedStderr( KProcess*, char*, int )),
+ this, SLOT(receivedStderr( KProcess*, char*, int )) );
+ connect( proc, SIGNAL(processExited( KProcess* )),
+ this, SLOT(processExited( KProcess* )) );
+ connect( core(), SIGNAL(stopButtonClicked(KDevPlugin*)),
+ this, SLOT(slotStopButtonClicked(KDevPlugin*)) );
+ connect( core(), SIGNAL(projectOpened()),
+ this, SLOT(projectOpened()) );
+
+ m_widget = new ValgrindWidget( this );
+ m_widget->setIcon( SmallIcon("fork") );
+ m_widget->setCaption(i18n("Valgrind Output"));
+
+ QWhatsThis::add( m_widget, i18n( "<b>Valgrind</b><p>Shows the output of the valgrind. Valgrind detects<br>"
+ "use of uninitialized memory<br>"
+ "reading/writing memory after it has been free'd<br>"
+ "reading/writing off the end of malloc'd blocks<br>"
+ "reading/writing inappropriate areas on the stack<br>"
+ "memory leaks -- where pointers to malloc'd blocks are lost forever<br>"
+ "passing of uninitialised and/or unaddressable memory to system calls<br>"
+ "mismatched use of malloc/new/new [] vs free/delete/delete []<br>"
+ "some abuses of the POSIX pthread API." ) );
+
+ KAction* action = new KAction( i18n("&Valgrind Memory Leak Check"), 0, this,
+ SLOT(slotExecValgrind()), actionCollection(), "tools_valgrind" );
+ action->setToolTip(i18n("Valgrind memory leak check"));
+ action->setWhatsThis(i18n("<b>Valgrind memory leak check</b><p>Runs Valgrind - a tool to help you find memory-management problems in your programs."));
+
+ action = new KAction( i18n("P&rofile with KCachegrind"), 0, this,
+ SLOT(slotExecCalltree()), actionCollection(), "tools_calltree" );
+ action->setToolTip(i18n("Profile with KCachegrind"));
+ action->setWhatsThis(i18n("<b>Profile with KCachegrind</b><p>Runs your program in calltree and then displays profiler information in KCachegrind."));
+
+ mainWindow()->embedOutputView( m_widget, "Valgrind", i18n("Valgrind memory leak check") );
+}
+
+
+ValgrindPart::~ValgrindPart()
+{
+ if ( m_widget )
+ mainWindow()->removeView( m_widget );
+ delete m_widget;
+ delete proc;
+}
+
+void ValgrindPart::projectOpened()
+{
+ _lastExec.truncate( 0 );
+}
+
+void ValgrindPart::loadOutput()
+{
+ QString fName = KFileDialog::getOpenFileName(QString::null, "*", 0, i18n("Open Valgrind Output"));
+ if ( fName.isEmpty() )
+ return;
+
+ QFile f( fName );
+ if ( !f.open( IO_ReadOnly ) ) {
+ KMessageBox::sorry( 0, i18n("Could not open valgrind output: %1").arg(fName) );
+ return;
+ }
+
+ clear();
+ getActiveFiles();
+
+ QTextStream stream( &f );
+ while ( !stream.atEnd() ) {
+ receivedString( stream.readLine() + "\n" );
+ }
+ f.close();
+}
+
+void ValgrindPart::getActiveFiles()
+{
+ activeFiles.clear();
+ if ( project() ) {
+ QStringList projectFiles = project()->allFiles();
+ QString projectDirectory = project()->projectDirectory();
+ KURL url;
+ for ( QStringList::Iterator it = projectFiles.begin(); it != projectFiles.end(); ++it ) {
+ KURL url( projectDirectory + "/" + (*it) );
+ url.cleanPath( true );
+ activeFiles += url.path();
+ kdDebug() << "set project file: " << url.path().latin1() << endl;
+ }
+ }
+}
+
+static void guessActiveItem( ValgrindItem& item, const QStringList activeFiles )
+{
+ if ( activeFiles.isEmpty() && item.backtrace().isEmpty() )
+ return;
+ for ( ValgrindItem::BacktraceList::Iterator it = item.backtrace().begin(); it != item.backtrace().end(); ++it ) {
+ // active: first line of backtrace that lies in project source file
+ for ( QStringList::ConstIterator it2 = activeFiles.begin(); it2 != activeFiles.end(); ++it2 ) {
+ if ( (*it).url() == (*it2) ) {
+ (*it).setHighlighted( true );
+ return;
+ }
+ }
+ }
+}
+
+void ValgrindPart::appendMessage( const QString& message )
+{
+ if ( message.isEmpty() )
+ return;
+
+ ValgrindItem item( message );
+ guessActiveItem( item, activeFiles );
+ m_widget->addMessage( item );
+}
+
+void ValgrindPart::slotExecValgrind()
+{
+ ValgrindDialog* dlg = new ValgrindDialog(ValgrindDialog::Memcheck);
+ if ( project() && _lastExec.isEmpty() ) {
+ dlg->setExecutable( project()->mainProgram() );
+ } else {
+ dlg->setExecutable( _lastExec );
+ }
+ dlg->setParameters( _lastParams );
+ dlg->setValExecutable( _lastValExec );
+ dlg->setValParams( _lastValParams );
+ kcInfo.runKc = false;
+ _lastValExec = dlg->valExecutable();
+ _lastValParams = dlg->valParams();
+ if ( dlg->exec() == QDialog::Accepted ) {
+ runValgrind( dlg->executableName(), dlg->parameters(), dlg->valExecutable(), dlg->valParams() );
+ }
+}
+
+void ValgrindPart::slotExecCalltree()
+{
+ ValgrindDialog* dlg = new ValgrindDialog(ValgrindDialog::Calltree);
+ if ( project() && _lastExec.isEmpty() ) {
+ dlg->setExecutable( project()->mainProgram() );
+ } else {
+ dlg->setExecutable( _lastExec );
+ }
+ dlg->setParameters( _lastParams );
+ dlg->setCtExecutable( _lastCtExec );
+ dlg->setKcExecutable( _lastKcExec );
+ dlg->setCtParams( _lastCtParams );
+ kcInfo.runKc = true;
+ kcInfo.kcPath = dlg->kcExecutable();
+// kcInfo.kcWorkDir = KURL(dlg->executableName()).directory();
+ if ( dlg->exec() == QDialog::Accepted ) {
+ runValgrind( dlg->executableName(), dlg->parameters(), dlg->ctExecutable(), dlg->ctParams() );
+ }
+ _lastKcExec = dlg->kcExecutable();
+ _lastCtExec = dlg->ctExecutable();
+ _lastCtParams = dlg->ctParams();
+}
+
+void ValgrindPart::slotKillValgrind()
+{
+ if ( proc )
+ proc->kill();
+}
+
+void ValgrindPart::slotStopButtonClicked( KDevPlugin* which )
+{
+ if ( which != 0 && which != this )
+ return;
+ slotKillValgrind();
+}
+
+void ValgrindPart::clear()
+{
+ m_widget->clear();
+ currentMessage = QString::null;
+ currentPid = -1;
+ lastPiece = QString::null;
+}
+
+void ValgrindPart::runValgrind( const QString& exec, const QString& params, const QString& valExec, const QString& valParams )
+{
+ if ( proc->isRunning() ) {
+ KMessageBox::sorry( 0, i18n( "There is already an instance of valgrind running." ) );
+ return;
+ /// @todo - ask for forced kill
+ }
+
+ clear();
+
+ getActiveFiles();
+
+// proc->setWorkingDirectory(KURL(exec).directory());
+ proc->clearArguments();
+
+ DomUtil::PairList run_envvars;
+ if (project())
+ run_envvars = project()->runEnvironmentVars();
+
+ QStringList envVarList;
+ DomUtil::PairList::ConstIterator it;
+ for (it = run_envvars.begin(); it != run_envvars.end(); ++it)
+ {
+ envVarList << QString("%1=\"%2\" ").arg((*it).first).arg((*it).second);
+ }
+
+ *proc << envVarList.join("") << valExec << valParams << exec << params;
+ proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+ mainWindow()->raiseView( m_widget );
+ core()->running( this, true );
+
+ _lastExec = exec;
+ _lastParams = params;
+}
+
+void ValgrindPart::receivedStdout( KProcess*, char* /* msg */, int /* len */ )
+{
+ //kdDebug() << "got StdOut: " <<QString::fromLocal8Bit( msg, len ) << endl;
+}
+
+void ValgrindPart::receivedStderr( KProcess*, char* msg, int len )
+{
+ receivedString( QString::fromLocal8Bit( msg, len ) );
+}
+
+void ValgrindPart::receivedString( const QString& str )
+{
+ QString rmsg = lastPiece + str;
+ QStringList lines = QStringList::split( "\n", rmsg );
+
+// kdDebug() << "got: " << QString::fromLocal8Bit( msg, len ) << endl;
+
+ if ( !rmsg.endsWith( "\n" ) ) {
+ // the last message is trucated, we'll receive
+ // the rest in the next call
+ lastPiece = lines.back();
+ lines.pop_back();
+ } else {
+ lastPiece = QString::null;
+ }
+ appendMessages( lines );
+}
+
+void ValgrindPart::appendMessages( const QStringList& lines )
+{
+ QRegExp valRe( "==(\\d+)== (.*)" );
+
+ for ( QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it ) {
+ if ( valRe.search( *it ) < 0 )
+ continue;
+
+ int cPid = valRe.cap( 1 ).toInt();
+
+ if ( valRe.cap( 2 ).isEmpty() ) {
+ appendMessage( currentMessage );
+ currentMessage = QString::null;
+ } else if ( cPid != currentPid ) {
+ appendMessage( currentMessage );
+ currentMessage = *it;
+ currentPid = cPid;
+ } else {
+ if ( !currentMessage.isEmpty() )
+ currentMessage += "\n";
+ currentMessage += *it;
+ }
+ }
+}
+
+void ValgrindPart::processExited( KProcess* p )
+{
+ if ( p == proc ) {
+ appendMessage( currentMessage + lastPiece );
+ currentMessage = QString::null;
+ lastPiece = QString::null;
+ core()->running( this, false );
+
+ if (kcInfo.runKc)
+ {
+ KProcess *kcProc = new KProcess;
+// kcProc->setWorkingDirectory(kcInfo.kcWorkDir);
+ *kcProc << kcInfo.kcPath;
+ *kcProc << QString("callgrind.out.%1").arg(p->pid());
+ kcProc->start(KProcess::DontCare);
+ }
+ }
+}
+
+void ValgrindPart::restorePartialProjectSession( const QDomElement* el )
+{
+ QDomElement execElem = el->namedItem( "executable" ).toElement();
+ _lastExec = execElem.attribute( "path", "" );
+ _lastParams = execElem.attribute( "params", "" );
+
+ QDomElement valElem = el->namedItem( "valgrind" ).toElement();
+ _lastValExec = valElem.attribute( "path", "" );
+ _lastValParams = valElem.attribute( "params", "" );
+
+ QDomElement ctElem = el->namedItem( "calltree" ).toElement();
+ _lastCtExec = ctElem.attribute( "path", "" );
+ _lastCtParams = ctElem.attribute( "params", "" );
+
+ QDomElement kcElem = el->namedItem( "kcachegrind" ).toElement();
+ _lastKcExec = kcElem.attribute( "path", "" );
+}
+
+void ValgrindPart::savePartialProjectSession( QDomElement* el )
+{
+ QDomDocument domDoc = el->ownerDocument();
+ if ( domDoc.isNull() )
+ return;
+
+ QDomElement execElem = domDoc.createElement( "executable" );
+ execElem.setAttribute( "path", _lastExec );
+ execElem.setAttribute( "params", _lastParams );
+
+ QDomElement valElem = domDoc.createElement( "valgrind" );
+ valElem.setAttribute( "path", _lastValExec );
+ valElem.setAttribute( "params", _lastValParams );
+
+ QDomElement ctElem = domDoc.createElement( "calltree" );
+ ctElem.setAttribute( "path", _lastCtExec );
+ ctElem.setAttribute( "params", _lastCtParams );
+
+ QDomElement kcElem = domDoc.createElement( "kcachegrind" );
+ kcElem.setAttribute( "path", _lastKcExec );
+
+ el->appendChild( execElem );
+ el->appendChild( valElem );
+ el->appendChild( ctElem );
+ el->appendChild( kcElem );
+}
+
+#include "valgrind_part.moc"
diff --git a/parts/valgrind/valgrind_part.h b/parts/valgrind/valgrind_part.h
new file mode 100644
index 00000000..097eb8f8
--- /dev/null
+++ b/parts/valgrind/valgrind_part.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2002 Harald Fernengel <harry@kdevelop.org>
+ */
+
+#ifndef __KDEVPART_VALGRIND_H__
+#define __KDEVPART_VALGRIND_H__
+
+#include <qguardedptr.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <kdevplugin.h>
+
+class ValgrindWidget;
+class KProcess;
+
+class ValgrindPart : public KDevPlugin
+{
+ Q_OBJECT
+
+public:
+ ValgrindPart( QObject *parent, const char *name, const QStringList & );
+ ~ValgrindPart();
+
+ void runValgrind( const QString& exec, const QString& parameters, const QString& valExec, const QString& valParameters );
+
+ void savePartialProjectSession( QDomElement* el );
+ void restorePartialProjectSession( const QDomElement* el );
+
+private slots:
+ void slotExecValgrind();
+ void slotExecCalltree();
+ void slotKillValgrind();
+ void slotStopButtonClicked( KDevPlugin* which );
+ void receivedStdout( KProcess*, char*, int );
+ void receivedStderr( KProcess*, char*, int );
+ void processExited( KProcess* );
+ void loadOutput();
+ void projectOpened();
+
+private:
+ void getActiveFiles();
+ void appendMessage( const QString& message );
+ void appendMessages( const QStringList& lines );
+ void receivedString( const QString& str );
+ void clear();
+ QString _lastExec, _lastParams, _lastValExec, _lastValParams,
+ _lastCtExec, _lastCtParams, _lastKcExec;
+ KProcess* proc;
+ QString currentMessage;
+ QString lastPiece;
+ QStringList activeFiles;
+ int currentPid;
+ QGuardedPtr<ValgrindWidget> m_widget;
+ struct {
+ bool runKc;
+ QString kcPath;
+// QString kcWorkDir;
+ } kcInfo;
+};
+
+
+#endif
diff --git a/parts/valgrind/valgrind_widget.cpp b/parts/valgrind/valgrind_widget.cpp
new file mode 100644
index 00000000..356d97bf
--- /dev/null
+++ b/parts/valgrind/valgrind_widget.cpp
@@ -0,0 +1,205 @@
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+
+#include <kparts/part.h>
+#include <klibloader.h>
+#include <kurl.h>
+#include <kdebug.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kstatusbar.h>
+
+#include <kdevcore.h>
+#include <kdevpartcontroller.h>
+#include <kdevmainwindow.h>
+#include <kdevproject.h>
+
+#include "valgrind_part.h"
+#include "valgrind_widget.h"
+
+#define VALLISTVIEWITEMRTTI 130977
+
+// helper class to sort the ListView by item number instead of the string representation of the item number
+class ValListViewItem: public QListViewItem
+{
+public:
+ ValListViewItem( QListView* parent, int key, int pid, const QString& message ):
+ QListViewItem( parent, QString::number( key ), QString::number( pid ), message ),
+ _key( key ), _pid ( pid ), backtrace( false ), _line( -1 ), _active( false ) {}
+
+ ValListViewItem( ValListViewItem* parent, int key, int pid, const QString& message, const QString& filename, int line, bool active ):
+ QListViewItem( parent, QString::number( key ), QString::null, message ),
+ _key( key ), _pid( pid ), backtrace( true ), _filename( filename ), _line( line ), _active( active )
+ {
+ if ( parent->_pid != _pid && _pid > 0 )
+ setText( 1, QString::number( _pid ) );
+ }
+
+ virtual ~ValListViewItem();
+
+ static int intCompare( int i1, int i2 )
+ {
+ if ( i1 > i2 )
+ return 1;
+ else if ( i1 < i2 )
+ return -1;
+ else
+ return 0;
+ }
+
+ int compare( QListViewItem* i, int col, bool ascending ) const
+ {
+ if ( !i || i->rtti() != VALLISTVIEWITEMRTTI )
+ return QListViewItem::compare( i, col, ascending );
+ switch ( col ) {
+ case 0 : return intCompare( ((ValListViewItem*)i)->_key, _key );
+ case 1 : return intCompare( ((ValListViewItem*)i)->_pid, _pid );
+ default: return QListViewItem::compare( i, col, ascending );
+ }
+ }
+
+ void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align )
+ {
+ if ( _active ) {
+ QFont fnt = p->font();
+ fnt.setBold( true );
+ p->setFont( fnt );
+ }
+ QListViewItem::paintCell( p, cg, column, width, align );
+ }
+
+ int rtti() const { return VALLISTVIEWITEMRTTI; }
+
+ QString fileName() const { return _filename; }
+ int line() const { return _line; }
+ QString message() const { return text( 2 ); }
+ bool isHighlighted() const { return _active; }
+
+private:
+ int _key;
+ int _pid;
+ bool backtrace;
+ QString _filename;
+ int _line;
+ bool _active;
+};
+
+ValListViewItem::~ValListViewItem() {}
+
+ValgrindWidget::ValgrindWidget( ValgrindPart *part )
+ : QWidget(0, "valgrind widget"), _part( part )
+{
+ QVBoxLayout* vbl = new QVBoxLayout( this );
+ lv = new KListView( this );
+ lv->addColumn( i18n( "No." ) );
+ lv->addColumn( i18n( "Thread" ) );
+ lv->addColumn( i18n( "Message" ) );
+ lv->setSorting( 0, false );
+ lv->setRootIsDecorated( true );
+ lv->setAllColumnsShowFocus( true );
+ vbl->addWidget( lv );
+
+ popup = new QPopupMenu( lv, "valPopup" );
+ popup->insertItem( i18n( "&Open Valgrind Output..." ), _part, SLOT(loadOutput()), 0, 0 );
+ popup->insertSeparator();
+ popup->insertItem( i18n( "Expand All Items" ), this, SLOT(expandAll()), 0, 2 );
+ popup->insertItem( i18n( "Collapse All Items" ), this, SLOT(collapseAll()), 0, 3 );
+
+ connect( popup, SIGNAL(aboutToShow()),
+ this, SLOT(aboutToShowPopup()) );
+ connect( lv, SIGNAL(executed(QListViewItem*)),
+ this, SLOT(executed(QListViewItem*)) );
+ connect( lv, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
+ this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)) );
+}
+
+
+ValgrindWidget::~ValgrindWidget()
+{
+}
+
+void ValgrindWidget::clear()
+{
+ lv->clear();
+ msgNumber = 1;
+}
+
+void ValgrindWidget::addMessage( const ValgrindItem& vi )
+{
+ QStringList projectFiles;
+ QString projectDirectory;
+
+ ValListViewItem* lvi = new ValListViewItem( lv, msgNumber++, vi.pid(), vi.message() );
+ lvi->setMultiLinesEnabled( true );
+ const ValgrindItem::BacktraceList backtrace = vi.backtrace();
+ if ( !backtrace.isEmpty() )
+ lvi->setExpandable( true );
+
+ int i = 0;
+ for ( ValgrindItem::BacktraceList::ConstIterator it = backtrace.begin(); it != backtrace.end(); ++it ) {
+ new ValListViewItem( lvi, ++i, (*it).pid(), (*it).message(), (*it).url(), (*it).line(), (*it).isHighlighted() );
+ }
+}
+
+void ValgrindWidget::executed( QListViewItem* lvi )
+{
+ Q_ASSERT( _part );
+ Q_ASSERT( _part->partController() );
+ Q_ASSERT( _part->mainWindow() );
+
+ if ( !lvi || lvi->rtti() != VALLISTVIEWITEMRTTI )
+ return;
+ ValListViewItem* vli = 0;
+ if ( !((ValListViewItem*)lvi)->fileName().isEmpty() ) {
+ vli = (ValListViewItem*)lvi;
+ } else if ( lvi->isExpandable() ) {
+ // find the memleak position
+ QListViewItemIterator it( lv );
+ while ( vli == 0 && it.current() ) {
+ if ( it.current()->rtti() == VALLISTVIEWITEMRTTI && ((ValListViewItem*)it.current())->isHighlighted() )
+ vli = (ValListViewItem*)it.current();
+ ++it;
+ }
+ }
+ if ( vli ) {
+ // display the file
+ _part->partController()->editDocument( KURL( vli->fileName() ), vli->line() - 1 );
+ _part->mainWindow()->statusBar()->message( vli->message(), 10000 );
+ }
+}
+
+void ValgrindWidget::expandAll()
+{
+ QListViewItem* child = lv->firstChild();
+ while ( child ) {
+ child->setOpen( true );
+ child = child->nextSibling();
+ }
+}
+
+void ValgrindWidget::collapseAll()
+{
+ QListViewItem* child = lv->firstChild();
+ while ( child ) {
+ child->setOpen( false );
+ child = child->nextSibling();
+ }
+}
+
+void ValgrindWidget::aboutToShowPopup()
+{
+ bool en = (lv->firstChild() != 0);
+ popup->setItemEnabled( 2, en );
+ popup->setItemEnabled( 3, en );
+}
+
+void ValgrindWidget::slotContextMenu( KListView* l, QListViewItem* /*i*/, const QPoint& p )
+{
+ if ( l != lv )
+ return;
+
+ popup->exec( p );
+}
+
+#include "valgrind_widget.moc"
diff --git a/parts/valgrind/valgrind_widget.h b/parts/valgrind/valgrind_widget.h
new file mode 100644
index 00000000..1777e183
--- /dev/null
+++ b/parts/valgrind/valgrind_widget.h
@@ -0,0 +1,44 @@
+#ifndef __VALGRIND_WIDGET_H__
+#define __VALGRIND_WIDGET_H__
+
+#include <qwidget.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include "valgrinditem.h"
+
+class ValgrindPart;
+class KListView;
+class QListViewItem;
+class QPopupMenu;
+
+class ValgrindWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ValgrindWidget( ValgrindPart *part );
+ ~ValgrindWidget();
+
+ void addMessage( const ValgrindItem& vi );
+ void clear();
+
+signals:
+ void jumpToFile( const QString& url, int line );
+
+private slots:
+ void executed( QListViewItem* item );
+ void slotContextMenu( KListView* l, QListViewItem* i, const QPoint& p );
+ void expandAll();
+ void collapseAll();
+ void aboutToShowPopup();
+
+private:
+ KListView* lv;
+ int msgNumber;
+ ValgrindPart* _part;
+ QPopupMenu* popup;
+};
+
+
+#endif
diff --git a/parts/valgrind/valgrinditem.cpp b/parts/valgrind/valgrinditem.cpp
new file mode 100644
index 00000000..318254d3
--- /dev/null
+++ b/parts/valgrind/valgrinditem.cpp
@@ -0,0 +1,71 @@
+#include "valgrinditem.h"
+
+#include <qregexp.h>
+#include <qstringlist.h>
+
+#include <kdebug.h>
+
+ValgrindBacktraceItem::ValgrindBacktraceItem( const QString& rawOutput ): _rawOutput( rawOutput ), _highlight( false )
+{
+ QRegExp re1( "^==(\\d+)==\\s+(by|at) (0x[\\dABCDEF]+): (.*) \\((.*):(\\d+)\\)$" );
+ QRegExp re2( "^==(\\d+)==\\s+(by|at) (0x[\\dABCDEF]+): (.*) \\(in (.*)\\)$" );
+ QRegExp valRe( "==(\\d+)== (.*)" );
+ if ( valRe.search( _rawOutput ) >= 0 )
+ _message = valRe.cap( 2 );
+ if ( re1.search( _rawOutput ) >= 0 ) {
+ _type = SourceCode;
+ _pid = re1.cap( 1 ).toInt();
+ _address = re1.cap( 3 );
+ _function = re1.cap( 4 );
+ _url = re1.cap( 5 );
+ _line = re1.cap( 6 ).toInt();
+ } else if ( re2.search( _rawOutput ) >= 0 ) {
+ _type = Library;
+ _pid = re2.cap( 1 ).toInt();
+ _address = re2.cap( 3 );
+ _function = re2.cap( 4 );
+ _url = re2.cap( 5 );
+ _line = -1;
+ } else {
+ _type = Unknown;
+ _line = -1;
+ _pid = -1;
+ }
+}
+
+ValgrindBacktraceItem::~ValgrindBacktraceItem()
+{
+}
+
+
+ValgrindItem::ValgrindItem( const QString& message ): _pid(-1)
+{
+ QRegExp valRe( "==(\\d+)== (.*)" );
+ QStringList lines = QStringList::split( "\n", message );
+ QString curMsg;
+
+ for ( QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it ) {
+ if ( valRe.search( *it ) < 0 ) {
+ kdDebug() << "ValgrindItem: got unrecognizable line '" << *it << "'" << endl;
+ continue; // not of interest
+ }
+ if ( _pid == -1 )
+ _pid = valRe.cap( 1 ).toInt();
+ curMsg = valRe.cap( 2 );
+
+ if ( curMsg.startsWith( " " ) ) {
+ _backtrace.append( ValgrindBacktraceItem( *it ) );
+ } else {
+ if ( !_message.isEmpty() )
+ _message += "\n";
+ _message += curMsg;
+ }
+ }
+// static int i = 0;
+// kdDebug() << "got: " << ++i << ": " << _message << endl << message << endl;
+}
+
+
+ValgrindItem::~ValgrindItem()
+{
+}
diff --git a/parts/valgrind/valgrinditem.h b/parts/valgrind/valgrinditem.h
new file mode 100644
index 00000000..12784c42
--- /dev/null
+++ b/parts/valgrind/valgrinditem.h
@@ -0,0 +1,50 @@
+#ifndef _VALGRINDITEM_H_
+#define _VALGRINDITEM_H_
+
+#include <qvaluelist.h>
+#include <qstring.h>
+
+class ValgrindBacktraceItem
+{
+public:
+ enum Type { Unknown, SourceCode, Library };
+ ValgrindBacktraceItem( const QString& rawOutput = QString::null );
+ ~ValgrindBacktraceItem();
+
+ QString message() const { return _message; }
+ QString address() const { return _address; }
+ QString url() const { return _url; }
+ QString function() const { return _function; }
+ int line() const { return _line; }
+ int pid() const { return _pid; }
+ Type type() const { return _type; }
+ bool isHighlighted() const { return _highlight; }
+ void setHighlighted( bool h ) { _highlight = h; }
+
+private:
+ QString _rawOutput, _address, _url, _function, _message;
+ int _line;
+ int _pid;
+ Type _type;
+ bool _highlight;
+};
+
+class ValgrindItem
+{
+public:
+ ValgrindItem( const QString& message );
+ ~ValgrindItem();
+
+ typedef QValueList<ValgrindBacktraceItem> BacktraceList;
+ BacktraceList& backtrace() { return _backtrace; }
+ const BacktraceList& backtrace() const { return _backtrace; }
+ QString message() const { return _message; }
+ int pid() const { return _pid; }
+
+private:
+ BacktraceList _backtrace;
+ QString _message;
+ int _pid;
+};
+
+#endif