From f95872aa737eab5e93f03ae89acf2d92f56304c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Andriot?= Date: Mon, 10 Nov 2014 19:00:44 +0100 Subject: RPM packaging: update tdesdk --- redhat/main/tdesdk/kdesdk-3.5.12.spec | 245 - .../kdesdk-3.5.13-add_forgotten_cmake_files.patch | 1921 - redhat/main/tdesdk/kdesdk-3.5.13-cmake_port.patch | 100 - .../kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch | 32 - redhat/main/tdesdk/kdesdk-3.5.13-misc_ftbfs.patch | 10 - .../tdesdk/kdesdk-3.5.13.1-add_missing_files.patch | 309 - .../tdesdk/kdesdk-3.5.13.1-fix_cmake_macros.patch | 17 - .../kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch | 39683 ------------------- ...desdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch.gz | Bin 500738 -> 0 bytes .../kdesdk-3.5.13.1-fix_various_cmake_issues.patch | 159 - ...dk-3.5.13.1-fix_xkcachegrind_installation.patch | 13 - .../kdesdk-3.5.13.1-use_flex_instead_of_lex.patch | 11 - redhat/main/tdesdk/kdesdk-3.5.13.1.spec | 1161 - redhat/main/tdesdk/kdesdk-3.5.13.spec | 1130 - redhat/main/tdesdk/kdesdk-3.5.7-subversion.patch | 21 - redhat/main/tdesdk/tdesdk-14.0.0.spec | 64 +- 16 files changed, 46 insertions(+), 44830 deletions(-) delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.12.spec delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13-add_forgotten_cmake_files.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13-cmake_port.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13-misc_ftbfs.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-add_missing_files.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-fix_cmake_macros.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch.gz delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-fix_xkcachegrind_installation.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1-use_flex_instead_of_lex.patch delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.1.spec delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.13.spec delete mode 100644 redhat/main/tdesdk/kdesdk-3.5.7-subversion.patch (limited to 'redhat/main/tdesdk') diff --git a/redhat/main/tdesdk/kdesdk-3.5.12.spec b/redhat/main/tdesdk/kdesdk-3.5.12.spec deleted file mode 100644 index ded3104de..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.12.spec +++ /dev/null @@ -1,245 +0,0 @@ -# Default version for this component -%if "%{?version}" == "" -%define version 3.5.12 -%endif -%define release 3 - -# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt". -%if "%{?_prefix}" != "/usr" -%define _variant .opt -%define _docdir %{_prefix}/share/doc -%endif - -# TDE 3.5.12 specific building variables -BuildRequires: autoconf automake libtool m4 -%define tde_docdir %{_docdir} -%define tde_libdir %{_libdir}/kde3 - - -%define _with_subversion --with-subversion -%if 0%{?fedora} > 6 || 0%{?rhel} > 4 -%define _with_apr_config --with-apr-config=apr-1-config -%define _with_apu_config --with-apu-config=apu-1-config -%endif - - -Name: trinity-kdesdk -Summary: The KDE Software Development Kit (SDK) -Version: %{?version} -Release: %{?release}%{?dist}%{?_variant} - -License: GPLv2 -Group: User Interface/Desktops -URL: http://www.trinitydesktop.org/ -Vendor: Trinity Project -Packager: Francois Andriot - -Prefix: %{_prefix} -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -Source: kdesdk-%{version}.tar.gz - -# RedHat Legacy patches -Patch1: kdesdk-3.5.7-subversion.patch - -# Official patches from SVN -# Import of revision 66 from svn.trinitydesktop.org -Patch2: r1225998.diff - -Provides: kdesdk3 = %{version}-%{release} - -Requires: %{name}-libs = %{version}-%{release} - -BuildRequires: libtool -BuildRequires: tqtinterface-devel -BuildRequires: pcre-devel -BuildRequires: trinity-kdelibs-devel -# for kbugbuster/libkcal -BuildRequires: trinity-kdepim-devel -BuildRequires: db4-devel -BuildRequires: desktop-file-utils -# kbabel, F-7+: flex >= 2.5.33-9 -BuildRequires: flex -# umbrello -BuildRequires: libxslt-devel libxml2-devel -%if 0%{?fedora} > 5 || 0%{?rhel} > 4 -BuildRequires: binutils-devel -%endif -BuildRequires: perl -BuildRequires: subversion-devel neon-devel - -# Obsoletes/Provides -%define cervisia_ver 2.4.7 -Provides: cervisia = %{cervisia_ver}-%{release} - -%define umbrello_ver 1.5.7 -Obsoletes: umbrello < %{umbrello_ver}-%{release} -Provides: umbrello = %{umbrello_ver}-%{release} - - -%description -A collection of applications and tools used by developers, including: -* cervisia: a CVS frontend -* kbabel: PO file management -* kbugbuster: a tool to manage the KDE bug report system -* kcachegrind: a browser for data produced by profiling tools (e.g. cachegrind) -* kompare: diff tool -* kuiviewer: displays designer's UI files -* umbrello: UML modeller and UML diagram tool - -%package devel -Summary: Development files for %{name} -Group: Development/Libraries -Provides: trinity-kdesdk-devel = %{version}-%{release} -Requires: %{name}-libs = %{version}-%{release} -Requires: trinity-kdelibs-devel -%description devel -%{summary}. - -%package libs -Summary: %{name} runtime libraries -Group: System Environment/Libraries -Requires: trinity-kdelibs -# helps multilib upgrades -Obsoletes: %{name} < %{version}-%{release} -# include to be paranoid, installing libs-only is still mostly untested -- Rex -Requires: %{name} = %{version}-%{release} -%description libs -%{summary}. - - -%prep -%setup -q -n kdesdk -%patch1 -p1 -b .subversion -%patch2 -p1 - -%__cp "/usr/share/aclocal/libtool.m4" "admin/libtool.m4.in" -%__cp "/usr/share/libtool/config/ltmain.sh" "admin/ltmain.sh" -%__make -f admin/Makefile.common - - -%build -unset QTDIR || :; . /etc/profile.d/qt.sh -export PATH="%{_bindir}:${PATH}" -export LDFLAGS="-L%{_libdir} -I%{_includedir}" - -%configure \ - --includedir=%{_includedir}/kde \ - --disable-rpath \ - --enable-new-ldflags \ - --disable-debug --disable-warnings \ - --disable-dependancy-tracking --enable-final \ - %{?_with_subversion} %{?_with_apr_config} %{?_with_apu_config} \ - --with-extra-includes=%{_includedir}/tqt \ - --without-svn \ - --enable-closure - -# Do not use %{?_smp_mflags} ! -%__make - - -%install -export PATH="%{_bindir}:${PATH}" -%__rm -rf %{buildroot} - -%__make install DESTDIR=%{?buildroot} - -desktop-file-install --vendor "" \ - --dir %{buildroot}%{_datadir}/applications/kde \ - %{buildroot}%{_datadir}/applications/kde/*.desktop \ - -# make symlinks relative -if [ -d %{buildroot}%{tde_docdir}/HTML/en ]; then - pushd %{buildroot}%{tde_docdir}/HTML/en - for i in *; do - if [ -d $i -a -L $i/common ]; then - rm -f $i/common - ln -nfs ../common $i - fi - done - popd -fi - -%__rm -f %{buildroot}/%{_datadir}/apps/kapptemplate/admin/Makefile \ - %{buildroot}/%{_datadir}/apps/kapptemplate/admin/Makefile.in - - -%clean -%__rm -rf %{buildroot} - - -# trick to replace a dir by a symlink -- Rex -%pre -if [ $1 -gt 0 -a ! -L %{_docdir}/HTML/en/cervisia/common ]; then - rm -rf %{tde_docdir}/HTML/en/cervisia/common ||: -fi - -%post -for f in crystalsvg hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -for f in crystalsvg hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%post libs -/sbin/ldconfig - -%postun libs -/sbin/ldconfig - - -%files -%defattr(-,root,root,-) -%{_bindir}/* -%{tde_docdir}/HTML/en/* -%{_datadir}/apps/* -%{_datadir}/mimelnk/application/* -%{_datadir}/services/* -%{_datadir}/servicetypes/* -%{_datadir}/icons/crystalsvg/*/*/* -%{_datadir}/icons/hicolor/*/*/* -%{_datadir}/icons/locolor/*/*/* -%{_datadir}/applications/kde/* -%{_datadir}/config.kcfg/* -%{tde_libdir}/* -%{_libdir}/libkdeinit_*.so -%{_mandir}/man1/* - -# Removes conflict with package 'rpmdevtool' on RHEL 6 -%if "%{_prefix}" == "/usr" -%exclude %{_bindir}/licensecheck -%endif - -%files libs -%defattr(-,root,root,-) -%{_libdir}/lib*.so.* -%{_libdir}/lib*.la - -%files devel -%defattr(-,root,root,-) -%{_includedir}/kde/* -%{_libdir}/lib*.so -%exclude %{_libdir}/libkdeinit_*.so -%{_libdir}/kmtrace/* - - -%changelog -* Mon Sep 19 2011 Francois Andriot - 3.5.12-3 -- Add support for RHEL5 - -* Mon Sep 05 2011 Francois Andriot - 3.5.12-2 -- Import to GIT - -* Mon Aug 22 2011 Francois Andriot - 3.5.12-1 -- Correct macro to install under "/opt", if desired - -* Tue Jun 21 2011 Francois Andriot - 3.5.12-0 -- Initial version for RHEL 6 -- Specfile based on Fedora 8 'kdesdk 3.5.10-1' diff --git a/redhat/main/tdesdk/kdesdk-3.5.13-add_forgotten_cmake_files.patch b/redhat/main/tdesdk/kdesdk-3.5.13-add_forgotten_cmake_files.patch deleted file mode 100644 index 7571e552c..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13-add_forgotten_cmake_files.patch +++ /dev/null @@ -1,1921 +0,0 @@ -commit adee843c4d5c8fbce75abd3a768d643392e4ea90 -Author: Serghei Amelian -Date: 1329245722 +0200 - - [tdesdk/cmake] added forgotten files - -diff --git a/kdeaccounts-plugin/CMakeLists.txt b/kdeaccounts-plugin/CMakeLists.txt -new file mode 100644 -index 0000000..2a14486 ---- /dev/null -+++ b/kdeaccounts-plugin/CMakeLists.txt -@@ -0,0 +1,34 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES kdeaccountsplugin.desktop -+ DESTINATION ${DATA_INSTALL_DIR}/kabc/formats ) -+ -+ -+##### kabcformat_kdeaccounts (module) ########### -+ -+tde_add_kpart( kabcformat_kdeaccounts -+ SOURCES kdeaccountsformat.cpp -+ LINK kabc-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kfile-plugins/CMakeLists.txt b/kfile-plugins/CMakeLists.txt -new file mode 100644 -index 0000000..6b769e5 ---- /dev/null -+++ b/kfile-plugins/CMakeLists.txt -@@ -0,0 +1,14 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( diff ) -+add_subdirectory( c++ ) -+add_subdirectory( ts ) -diff --git a/kfile-plugins/c++/CMakeLists.txt b/kfile-plugins/c++/CMakeLists.txt -new file mode 100644 -index 0000000..9b56e9d ---- /dev/null -+++ b/kfile-plugins/c++/CMakeLists.txt -@@ -0,0 +1,35 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES kfile_cpp.desktop kfile_h.desktop -+ DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+ -+##### kfile_cpp (module) ######################## -+ -+tde_add_kpart( kfile_cpp AUTOMOC -+ SOURCES kfile_cpp.cpp -+ LINK kio-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kfile-plugins/diff/CMakeLists.txt b/kfile-plugins/diff/CMakeLists.txt -new file mode 100644 -index 0000000..292372c ---- /dev/null -+++ b/kfile-plugins/diff/CMakeLists.txt -@@ -0,0 +1,34 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES kfile_diff.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+ -+##### kfile_diff (module) ####################### -+ -+tde_add_kpart( kfile_diff AUTOMOC -+ SOURCES kfile_diff.cpp -+ LINK kio-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kfile-plugins/ts/CMakeLists.txt b/kfile-plugins/ts/CMakeLists.txt -new file mode 100644 -index 0000000..4e68beb ---- /dev/null -+++ b/kfile-plugins/ts/CMakeLists.txt -@@ -0,0 +1,35 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES kfile_ts.desktop -+ DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+ -+##### kfile_ts (module) ######################### -+ -+tde_add_kpart( kfile_ts AUTOMOC -+ SOURCES kfile_ts.cpp -+ LINK kio-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kioslave/CMakeLists.txt b/kioslave/CMakeLists.txt -new file mode 100644 -index 0000000..a23a176 ---- /dev/null -+++ b/kioslave/CMakeLists.txt -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( svn ) -diff --git a/kioslave/svn/CMakeLists.txt b/kioslave/svn/CMakeLists.txt -new file mode 100644 -index 0000000..9d3c496 ---- /dev/null -+++ b/kioslave/svn/CMakeLists.txt -@@ -0,0 +1,46 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include( ConfigureChecks.cmake ) -+ -+add_subdirectory( ksvnd ) -+add_subdirectory( svnhelper ) -+add_subdirectory( icons ) -+ -+include_directories( -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+ ${APR_INCLUDE_DIRS} -+ ${SVN_INCLUDE_DIR} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+ ${APR_LIBRARY_DIRS} -+ ${SVN_LIBRARY_DIR} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES -+ svn+http.protocol svn+https.protocol svn+file.protocol -+ svn+ssh.protocol svn.protocol -+ DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+ -+##### kio_svn (module) ########################## -+ -+tde_add_kpart( kio_svn -+ SOURCES svn.cpp -+ LINK kio-shared ${APR_LIBRARIES} ${SVN_LIBRARIES} -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kioslave/svn/ConfigureChecks.cmake b/kioslave/svn/ConfigureChecks.cmake -new file mode 100644 -index 0000000..81358c6 ---- /dev/null -+++ b/kioslave/svn/ConfigureChecks.cmake -@@ -0,0 +1,50 @@ -+################################################# -+# -+# (C) 2010-2011 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+pkg_search_module( APR apr-1 ) -+if( APR_FOUND ) -+ set( HAVE_APR 1 ) -+else( ) -+ tde_message_fatal( "apr-1 is required, but was not found on your system" ) -+endif( ) -+ -+ -+# check for subversion library -+ -+check_library_exists( "svn_client-1" "svn_pool_create_ex" "${SVN_LIBRARY_DIR}" HAVE_SVN_POOL_CREATE_EX ) -+ -+if( HAVE_SVN_POOL_CREATE_EX ) -+ set( SVN_LIBRARIES "svn_client-1;svn_subr-1;svn_ra-1" ) -+else( ) -+ tde_message_fatal( "svn_client-1 library was not found on your system.\n Subversion is installed?\n Try to set SVN_LIBRARY_DIR to subversion library directory." ) -+endif( ) -+ -+ -+# check for subversion headers -+ -+set( CMAKE_REQUIRED_FLAGS "-I${APR_INCLUDE_DIRS}" ) -+set( CMAKE_REQUIRED_DEFINITIONS "${APR_CFLAGS}" ) -+ -+if( SVN_INCLUDE_DIR ) -+ set( CMAKE_REQUIRED_INCLUDES "${SVN_INCLUDE_DIR}" ) -+ check_include_file( "svn_types.h" HAVE_SVN_TYPES_H ) -+ tde_restore( CMAKE_REQUIRED_INCLUDES ) -+else( ) -+ # FIXME must be improved -+ check_include_file( "/usr/include/subversion-1/svn_types.h" HAVE_SVN_TYPES_H ) -+ set( SVN_INCLUDE_DIR "/usr/include/subversion-1" ) -+endif( ) -+ -+tde_restore( CMAKE_REQUIRED_FLAGS CMAKE_REQUIRED_DEFINITIONS ) -+ -+if( NOT HAVE_SVN_TYPES_H ) -+ tde_message_fatal( "svn_types.h file was not found on your system.\n Subversion devel files are installed?\n Try to set SVN_INCLUDE_DIR to subversion include directory." ) -+endif( ) -diff --git a/kioslave/svn/icons/CMakeLists.txt b/kioslave/svn/icons/CMakeLists.txt -new file mode 100644 -index 0000000..96bca44 ---- /dev/null -+++ b/kioslave/svn/icons/CMakeLists.txt -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+tde_install_icons( ) -diff --git a/kioslave/svn/ksvnd/CMakeLists.txt b/kioslave/svn/ksvnd/CMakeLists.txt -new file mode 100644 -index 0000000..d377ee7 ---- /dev/null -+++ b/kioslave/svn/ksvnd/CMakeLists.txt -@@ -0,0 +1,36 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES ksvnd.desktop -+ DESTINATION ${SERVICES_INSTALL_DIR}/kded ) -+ -+ -+##### kded_ksvnd (module) ####################### -+ -+tde_add_kpart( kded_ksvnd AUTOMOC -+ SOURCES commitdlg.ui ksvnd.cpp ksvnd.skel -+ LINK kio-shared kdeinit_kded-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kioslave/svn/svnhelper/CMakeLists.txt b/kioslave/svn/svnhelper/CMakeLists.txt -new file mode 100644 -index 0000000..ad82d38 ---- /dev/null -+++ b/kioslave/svn/svnhelper/CMakeLists.txt -@@ -0,0 +1,38 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES -+ subversion.desktop subversion_toplevel.desktop -+ DESTINATION ${DATA_INSTALL_DIR}/konqueror/servicemenus ) -+ -+ -+##### kio_svn_helper (executable) ############### -+ -+tde_add_executable( kio_svn_helper AUTOMOC -+ SOURCES -+ kio_svn_helper.cpp subversioncheckout.ui subversionswitch.ui -+ subversionlog.ui subversiondiff.ui -+ LINK kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/kmtrace/CMakeLists.txt b/kmtrace/CMakeLists.txt -new file mode 100644 -index 0000000..600391b ---- /dev/null -+++ b/kmtrace/CMakeLists.txt -@@ -0,0 +1,76 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+set( LD_FLAGS "-Wl,-Bstatic -liberty -Wl,-Bdynamic" ) -+ -+ -+##### other data ################################ -+ -+configure_file( kminspector.cmake kminspector @ONLY ) -+ -+install( FILES kde.excludes -+ DESTINATION ${DATA_INSTALL_DIR}/kmtrace ) -+ -+install( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kminspector -+ DESTINATION ${BIN_INSTALL_DIR} ) -+ -+ -+##### ktrace_s (static) ######################### -+ -+tde_add_library( ktrace_s STATIC -+ SOURCES ktrace.c -+ DESTINATION ${LIB_INSTALL_DIR} -+) -+ -+ -+##### ktrace (shared) ########################### -+ -+tde_add_library( ktrace SHARED -+ SOURCES ksotrace.cpp ktrace.c -+ LINK dl -+ DESTINATION ${LIB_INSTALL_DIR}/kmtrace -+) -+ -+ -+##### kmtrace (executable) ###################### -+ -+tde_add_executable( kmtrace -+ SOURCES kmtrace.cpp -+ LINK ${LD_FLAGS} kdecore-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### demangle (executable) ##################### -+ -+tde_add_executable( demangle -+ SOURCES demangle.cpp -+ LINK ${LD_FLAGS} ${TQT_LIBRARIES} -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### kmmatch (executable) ###################### -+ -+tde_add_executable( kmmatch -+ SOURCES match.cpp -+ LINK ${TQT_LIBRARIES} -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/kmtrace/kminspector.cmake b/kmtrace/kminspector.cmake -new file mode 100644 -index 0000000..c572ba7 ---- /dev/null -+++ b/kmtrace/kminspector.cmake -@@ -0,0 +1,9 @@ -+#! /bin/sh -+ -+export MALLOC_TREE=kminspector.tree -+export MALLOC_THRESHOLD=2000 -+export LD_PRELOAD=@LIB_INSTALL_DIR@/kmtrace/libktrace.so -+ -+$* -+ -+cat kminspector.tree | less -diff --git a/kompare/CMakeLists.txt b/kompare/CMakeLists.txt -new file mode 100644 -index 0000000..42d5d45 ---- /dev/null -+++ b/kompare/CMakeLists.txt -@@ -0,0 +1,55 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( interfaces ) -+add_subdirectory( libdiff2 ) -+add_subdirectory( libdialogpages ) -+add_subdirectory( komparenavtreepart ) -+add_subdirectory( komparepart ) -+add_subdirectory( pics ) -+ -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR}/libdiff2 -+ ${CMAKE_CURRENT_SOURCE_DIR}/libdialogpages -+ ${CMAKE_CURRENT_SOURCE_DIR}/komparenavtreepart -+ ${CMAKE_CURRENT_SOURCE_DIR}/komparepart -+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES kompare.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) -+install( FILES kompareui.rc DESTINATION ${DATA_INSTALL_DIR}/kompare ) -+ -+install( FILES -+ komparenavigationpart.desktop kompareviewpart.desktop -+ DESTINATION ${SERVICETYPES_INSTALL_DIR} ) -+ -+ -+##### kompare (executable) ###################### -+ -+tde_add_executable( kompare AUTOMOC -+ SOURCES -+ main.cpp kompare_shell.cpp kompareurldialog.cpp -+ LINK -+ dialogpages-static kompareinterface-shared kio-shared -+ kparts-shared ktexteditor-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/kompare/interfaces/CMakeLists.txt b/kompare/interfaces/CMakeLists.txt -new file mode 100644 -index 0000000..bd6583e ---- /dev/null -+++ b/kompare/interfaces/CMakeLists.txt -@@ -0,0 +1,28 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### kompareinterface (shared) ################# -+ -+tde_add_library( kompareinterface SHARED -+ SOURCES kompareinterface.cpp -+ LINK ${TQT_LIBRARIES} -+ DESTINATION ${LIB_INSTALL_DIR} -+) -diff --git a/kompare/komparenavtreepart/CMakeLists.txt b/kompare/komparenavtreepart/CMakeLists.txt -new file mode 100644 -index 0000000..32af473 ---- /dev/null -+++ b/kompare/komparenavtreepart/CMakeLists.txt -@@ -0,0 +1,36 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR}/../libdiff2 -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES komparenavtreepart.desktop -+ DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+ -+##### libkomparenavtreepart (module) ############ -+ -+tde_add_kpart( libkomparenavtreepart AUTOMOC -+ SOURCES komparenavtreepart.cpp -+ LINK diff2-static kparts-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kompare/komparepart/CMakeLists.txt b/kompare/komparepart/CMakeLists.txt -new file mode 100644 -index 0000000..00fe0e0 ---- /dev/null -+++ b/kompare/komparepart/CMakeLists.txt -@@ -0,0 +1,46 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR}/../libdiff2 -+ ${CMAKE_CURRENT_SOURCE_DIR}/../libdialogpages -+ ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES komparepart.desktop -+ DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+install( FILES komparepartui.rc -+ DESTINATION ${DATA_INSTALL_DIR}/kompare ) -+ -+ -+##### libkomparepart (module) ################### -+ -+tde_add_kpart( libkomparepart AUTOMOC -+ SOURCES -+ kompare_part.cpp kompareconnectwidget.cpp komparesplitter.cpp -+ komparelistview.cpp kompareprefdlg.cpp komparesaveoptionsbase.ui -+ komparesaveoptionswidget.cpp -+ LINK -+ dialogpages-static diff2-static kompareinterface-shared -+ kparts-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/kompare/libdialogpages/CMakeLists.txt b/kompare/libdialogpages/CMakeLists.txt -new file mode 100644 -index 0000000..40f61bd ---- /dev/null -+++ b/kompare/libdialogpages/CMakeLists.txt -@@ -0,0 +1,26 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR}/../libdiff2 -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### dialogpages (static) ###################### -+ -+tde_add_library( dialogpages STATIC_PIC AUTOMOC -+ SOURCES -+ settingsbase.cpp diffsettings.cpp filessettings.cpp viewsettings.cpp -+ pagebase.cpp diffpage.cpp filespage.cpp viewpage.cpp -+) -diff --git a/kompare/libdiff2/CMakeLists.txt b/kompare/libdiff2/CMakeLists.txt -new file mode 100644 -index 0000000..65dd77e ---- /dev/null -+++ b/kompare/libdiff2/CMakeLists.txt -@@ -0,0 +1,31 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR}/../libdialogpages -+ ${CMAKE_CURRENT_SOURCE_DIR}/../komparepart -+ ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### diff2 (static) ############################ -+ -+tde_add_library( diff2 STATIC_PIC AUTOMOC -+ SOURCES -+ kompareprocess.cpp komparemodellist.cpp diffmodellist.cpp -+ diffmodel.cpp difference.cpp diffhunk.cpp levenshteintable.cpp -+ parser.cpp parserbase.cpp cvsdiffparser.cpp diffparser.cpp -+ perforceparser.cpp -+) -diff --git a/kompare/pics/CMakeLists.txt b/kompare/pics/CMakeLists.txt -new file mode 100644 -index 0000000..96bca44 ---- /dev/null -+++ b/kompare/pics/CMakeLists.txt -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+tde_install_icons( ) -diff --git a/kprofilemethod/CMakeLists.txt b/kprofilemethod/CMakeLists.txt -new file mode 100644 -index 0000000..85ad07e ---- /dev/null -+++ b/kprofilemethod/CMakeLists.txt -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+install( FILES kprofilemethod.h DESTINATION ${INCLUDE_INSTALL_DIR} ) -diff --git a/kspy/CMakeLists.txt b/kspy/CMakeLists.txt -new file mode 100644 -index 0000000..2dee53a ---- /dev/null -+++ b/kspy/CMakeLists.txt -@@ -0,0 +1,40 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### headers ################################### -+ -+install( FILES -+ kspy.h -+ DESTINATION ${INCLUDE_INSTALL_DIR} ) -+ -+ -+##### kspy (shared) ############################# -+ -+tde_add_library( kspy SHARED AUTOMOC -+ SOURCES -+ navviewitem.cpp propsview.cpp navview.cpp spy.cpp sigslotview.cpp -+ receiversview.cpp classinfoview.cpp -+ VERSION 1.2.0 -+ LINK kdeui-shared -+ DESTINATION ${LIB_INSTALL_DIR} -+) -diff --git a/kstartperf/CMakeLists.txt b/kstartperf/CMakeLists.txt -new file mode 100644 -index 0000000..5d377e7 ---- /dev/null -+++ b/kstartperf/CMakeLists.txt -@@ -0,0 +1,38 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### kstartperf (shared) ####################### -+ -+tde_add_library( kstartperf SHARED AUTOMOC -+ SOURCES libkstartperf.c -+ VERSION 1.0.0 -+ LINK ltdl -+ DESTINATION ${LIB_INSTALL_DIR} -+) -+ -+ -+##### kstartperf (executable) ################### -+ -+tde_add_executable( kstartperf -+ SOURCES kstartperf.cpp -+ LINK kdecore-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/kuiviewer/CMakeLists.txt b/kuiviewer/CMakeLists.txt -new file mode 100644 -index 0000000..0376ea1 ---- /dev/null -+++ b/kuiviewer/CMakeLists.txt -@@ -0,0 +1,69 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+tde_install_icons( kuiviewer ) -+ -+install( FILES -+ kuiviewerui.rc -+ DESTINATION ${DATA_INSTALL_DIR}/kuiviewer ) -+ -+install( FILES -+ kuiviewer.desktop -+ DESTINATION ${XDG_APPS_INSTALL_DIR} ) -+ -+install( FILES -+ kuiviewer_part.desktop designerthumbnail.desktop -+ DESTINATION ${SERVICES_INSTALL_DIR} ) -+ -+install( FILES -+ kuiviewer_part.rc -+ DESTINATION ${DATA_INSTALL_DIR}/kuiviewerpart ) -+ -+ -+##### libkuiviewerpart (module) ################# -+ -+tde_add_kpart( libkuiviewerpart AUTOMOC -+ SOURCES kuiviewer_part.cpp -+ LINK ktexteditor-shared qui -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -+ -+ -+##### quithumbnail (module) ##################### -+ -+tde_add_kpart( quithumbnail -+ SOURCES quicreator.cpp -+ LINK ${TQT_LIBRARIES} qui -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -+ -+ -+##### kuiviewer (executable) #################### -+ -+tde_add_executable( kuiviewer AUTOMOC -+ SOURCES main.cpp kuiviewer.cpp -+ LINK ktexteditor-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/kunittest/CMakeLists.txt b/kunittest/CMakeLists.txt -new file mode 100644 -index 0000000..6b3aefd ---- /dev/null -+++ b/kunittest/CMakeLists.txt -@@ -0,0 +1,49 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### headers ################################### -+ -+install( FILES -+ runnergui.h -+ DESTINATION ${INCLUDE_INSTALL_DIR}/kunittest ) -+ -+install( PROGRAMS -+ kunittest kunittestmod kunittest_debughelper -+ DESTINATION ${BIN_INSTALL_DIR} ) -+ -+ -+##### kunittestgui (shared) ##################### -+ -+tde_add_library( kunittestgui SHARED AUTOMOC -+ SOURCES testerwidget.ui runnergui.cpp dcopinterface.skel -+ LINK kunittest-shared -+ DESTINATION ${LIB_INSTALL_DIR} -+) -+ -+ -+##### kunittestguimodrunner (executable) ######## -+ -+tde_add_executable( kunittestguimodrunner -+ SOURCES guimodrunner.cpp -+ LINK kunittestgui-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/poxml/CMakeLists.txt b/poxml/CMakeLists.txt -new file mode 100644 -index 0000000..ed6c1ae ---- /dev/null -+++ b/poxml/CMakeLists.txt -@@ -0,0 +1,70 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_definitions( -fexceptions ) -+ -+add_subdirectory( antlr ) -+ -+ -+include_directories( -+ ${CMAKE_CURRENT_SOURCE_DIR}/antlr -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### split2po (executable) ##################### -+ -+tde_add_executable( split2po -+ SOURCES split.cpp parser.cpp -+ LINK kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### xml2pot (executable) ###################### -+ -+tde_add_executable( xml2pot -+ SOURCES xml2pot.cpp parser.cpp -+ LINK kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### po2xml (executable) ####################### -+ -+tde_add_executable( po2xml -+ SOURCES GettextLexer.cpp GettextParser.cpp po2xml.cpp parser.cpp -+ LINK antlr-static kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### swappo (executable) ####################### -+ -+tde_add_executable( swappo -+ SOURCES GettextLexer.cpp GettextParser.cpp swappo.cpp parser.cpp -+ LINK antlr-static kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### transxx (executable) ###################### -+ -+tde_add_executable( transxx -+ SOURCES GettextLexer.cpp GettextParser.cpp transxx.cpp parser.cpp -+ LINK antlr-static kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/poxml/antlr/CMakeLists.txt b/poxml/antlr/CMakeLists.txt -new file mode 100644 -index 0000000..636d2f7 ---- /dev/null -+++ b/poxml/antlr/CMakeLists.txt -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( src ) -diff --git a/poxml/antlr/src/CMakeLists.txt b/poxml/antlr/src/CMakeLists.txt -new file mode 100644 -index 0000000..cc54d00 ---- /dev/null -+++ b/poxml/antlr/src/CMakeLists.txt -@@ -0,0 +1,33 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+string( REPLACE ${TQT_CXX_FLAGS} "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ) -+ -+include_directories( -+ ${CMAKE_CURRENT_SOURCE_DIR}/.. -+) -+ -+ -+##### antlr (static) ############################ -+ -+tde_add_library( antlr STATIC_PIC -+ SOURCES -+ ANTLRException.cpp ASTFactory.cpp ASTRefCount.cpp BaseAST.cpp -+ BitSet.cpp CharBuffer.cpp CharScanner.cpp CommonAST.cpp -+ CommonASTWithHiddenTokens.cpp CommonHiddenStreamToken.cpp -+ CommonToken.cpp InputBuffer.cpp LLkParser.cpp -+ LexerSharedInputState.cpp MismatchedCharException.cpp -+ MismatchedTokenException.cpp NoViableAltException.cpp -+ NoViableAltForCharException.cpp Parser.cpp ParserSharedInputState.cpp -+ RecognitionException.cpp String.cpp Token.cpp TokenBuffer.cpp -+ TokenStreamBasicFilter.cpp TokenStreamHiddenTokenFilter.cpp -+ TokenStreamSelector.cpp TreeParser.cpp TreeParserSharedInputState.cpp -+) -diff --git a/scheck/CMakeLists.txt b/scheck/CMakeLists.txt -new file mode 100644 -index 0000000..bef3a46 ---- /dev/null -+++ b/scheck/CMakeLists.txt -@@ -0,0 +1,34 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES scheck.themerc DESTINATION ${DATA_INSTALL_DIR}/kstyle/themes ) -+ -+ -+##### scheck (module) ############################ -+ -+tde_add_kpart( scheck AUTOMOC -+ SOURCES scheck.cpp -+ LINK kdeui-shared -+ DESTINATION ${PLUGIN_INSTALL_DIR} -+) -diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt -new file mode 100644 -index 0000000..6ed8ca8 ---- /dev/null -+++ b/scripts/CMakeLists.txt -@@ -0,0 +1,43 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+install( PROGRAMS -+ create_makefile create_makefiles adddebug cheatmake makeobj kde-build -+ build-progress.sh pruneemptydirs cvsbackport cvsversion cvscheck -+ cvslastchange cvslastlog cvsrevertlast noncvslist cvs-clean cvs2dist -+ cvsblame cvsforwardport create_cvsignore colorsvn create_svnignore -+ nonsvnlist svn2dist svnaddcurrentdir svnbackport svnforwardport -+ svn-clean svngettags svnlastchange svnlastlog svnrevertlast -+ svnversions svnchangesince findmissingcrystal kdesvn-build -+ kdedoc qtdoc extractrc extractattr zonetab2pot.py licensecheck -+ fixkdeincludes fixuifiles includemocs cxxmetric extend_dmalloc -+ kdekillall kdelnk2desktop.py package_crystalsvg png2mng.pl -+ kdemangen.pl -+ DESTINATION ${BIN_INSTALL_DIR} ) -+ -+ -+install( FILES -+ kdesvn-buildrc.xml -+ DESTINATION ${DATA_INSTALL_DIR}/katepart/syntax ) -+ -+ -+macro( _pod2man ) -+ foreach( _pod ${ARGN} ) -+ add_custom_command( -+ OUTPUT ${_pod}.1 -+ COMMAND pod2man ${CMAKE_CURRENT_SOURCE_DIR}/${_pod} > ${_pod}.1 -+ DEPENDS ${_pod} ) -+ add_custom_target( "${_pod}-man" ALL DEPENDS ${_pod}.1 ) -+ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR} ) -+ endforeach( ) -+endmacro() -+ -+_pod2man( kde-build kdesvn-build cvsversion cvscheck noncvslist cvsblame includemocs ) -diff --git a/kcachegrind/CMakeLists.txt b/kcachegrind/CMakeLists.txt -new file mode 100644 -index 0000000..8c2da80 ---- /dev/null -+++ b/kcachegrind/CMakeLists.txt -@@ -0,0 +1,21 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include( ConfigureChecks.cmake ) -+ -+set( KCACHEGRIND_VERSION "0.4.6kde" ) -+configure_file( version.h.in version.h @ONLY ) -+configure_file( kcachegrind.spec.in kcachegrind.spec @ONLY ) -+configure_file( kcachegrind.lsm.in kcachegrind.lsm @ONLY ) -+ -+add_subdirectory( kcachegrind ) -+add_subdirectory( pics ) -+add_subdirectory( converters ) -diff --git a/kcachegrind/ConfigureChecks.cmake b/kcachegrind/ConfigureChecks.cmake -new file mode 100644 -index 0000000..e9b5cc2 ---- /dev/null -+++ b/kcachegrind/ConfigureChecks.cmake -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+check_function_exists( mmap HAVE_MMAP ) -diff --git a/kcachegrind/converters/CMakeLists.txt b/kcachegrind/converters/CMakeLists.txt -new file mode 100644 -index 0000000..03e86bc ---- /dev/null -+++ b/kcachegrind/converters/CMakeLists.txt -@@ -0,0 +1,15 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+install( PROGRAMS -+ hotshot2calltree op2calltree pprof2calltree -+ dprof2calltree memprof2calltree -+ DESTINATION ${BIN_INSTALL_DIR} ) -diff --git a/kcachegrind/pics/CMakeLists.txt b/kcachegrind/pics/CMakeLists.txt -new file mode 100644 -index 0000000..ee29446 ---- /dev/null -+++ b/kcachegrind/pics/CMakeLists.txt -@@ -0,0 +1,14 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( hicolor ) -+ -+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kcachegrind/icons ) -diff --git a/kcachegrind/pics/hicolor/CMakeLists.txt b/kcachegrind/pics/hicolor/CMakeLists.txt -new file mode 100644 -index 0000000..1c162a1 ---- /dev/null -+++ b/kcachegrind/pics/hicolor/CMakeLists.txt -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kcachegrind/icons ) -diff --git a/kcachegrind/kcachegrind/CMakeLists.txt b/kcachegrind/kcachegrind/CMakeLists.txt -new file mode 100644 -index 0000000..cd284c3 ---- /dev/null -+++ b/kcachegrind/kcachegrind/CMakeLists.txt -@@ -0,0 +1,50 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+tde_install_icons( ) -+install( FILES kcachegrind.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) -+install( FILES kcachegrindui.rc tips DESTINATION ${DATA_INSTALL_DIR}/kcachegrind ) -+install( FILES x-kcachegrind.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) -+ -+ -+##### kcachegrind (executable) ################## -+ -+tde_add_executable( kcachegrind AUTOMOC -+ SOURCES -+ functionselectionbase.ui stackselectionbase.ui partselectionbase.ui -+ configdlgbase.ui loader.cpp cachegrindloader.cpp treemap.cpp pool.cpp -+ main.cpp configuration.cpp functionselection.cpp coverage.cpp -+ partgraph.cpp toplevel.cpp stackselection.cpp stackbrowser.cpp -+ subcost.cpp tracedata.cpp partselection.cpp configdlg.cpp -+ utils.cpp fixcost.cpp traceitemview.cpp instrview.cpp tabview.cpp -+ sourceview.cpp callmapview.cpp callview.cpp coverageview.cpp -+ costtypeview.cpp partview.cpp listutils.cpp costtypeitem.cpp -+ multiview.cpp callitem.cpp coverageitem.cpp sourceitem.cpp -+ costlistitem.cpp partlistitem.cpp functionitem.cpp instritem.cpp -+ stackitem.cpp callgraphview.cpp -+ LINK kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/umbrello/CMakeLists.txt b/umbrello/CMakeLists.txt -new file mode 100644 -index 0000000..5429f5a ---- /dev/null -+++ b/umbrello/CMakeLists.txt -@@ -0,0 +1,19 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include( ConfigureChecks.cmake ) -+ -+# generate version.h -+file( READ VERSION text ) -+string( REGEX REPLACE "\n" "" text "${text}" ) -+file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/version.h "#define UMBRELLO_VERSION \"${text}\"\n" ) -+ -+add_subdirectory( umbrello ) -diff --git a/umbrello/ConfigureChecks.cmake b/umbrello/ConfigureChecks.cmake -new file mode 100644 -index 0000000..2167ab9 ---- /dev/null -+++ b/umbrello/ConfigureChecks.cmake -@@ -0,0 +1,20 @@ -+################################################# -+# -+# (C) 2010-2011 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+pkg_search_module( XML2 libxml-2.0 ) -+if( NOT XML2_FOUND ) -+ tde_message_fatal( "libxml-2.0 is required, but was not found on your system" ) -+endif( ) -+ -+pkg_search_module( XSLT libxslt ) -+if( NOT XSLT_FOUND ) -+ tde_message_fatal( "libxslt is required, but was not found on your system" ) -+endif( ) -diff --git a/umbrello/umbrello/CMakeLists.txt b/umbrello/umbrello/CMakeLists.txt -new file mode 100644 -index 0000000..f7c299b ---- /dev/null -+++ b/umbrello/umbrello/CMakeLists.txt -@@ -0,0 +1,86 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( codeimport ) -+add_subdirectory( dialogs ) -+add_subdirectory( docgenerators ) -+add_subdirectory( clipboard ) -+add_subdirectory( pics ) -+add_subdirectory( codegenerators ) -+add_subdirectory( headings ) -+add_subdirectory( refactoring ) -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_BINARY_DIR}/.. # for version.h -+ ${CMAKE_CURRENT_BINARY_DIR}/dialogs -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+tde_install_icons( ) -+install( FILES x-umbrello.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) -+install( FILES tips umbrelloui.rc DESTINATION ${DATA_INSTALL_DIR}/umbrello ) -+install( FILES umbrello.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) -+ -+ -+##### umbrello (executable) ##################### -+ -+tde_add_executable( umbrello AUTOMOC -+ SOURCES -+ activitywidget.cpp actor.cpp actorwidget.cpp aligntoolbar.cpp -+ artifact.cpp artifactwidget.cpp association.cpp associationwidget.cpp -+ assocrules.cpp attribute.cpp boxwidget.cpp classifier.cpp -+ classifiercodedocument.cpp classifierlistitem.cpp -+ classifierwidget.cpp cmdlineexportallviewsevent.cpp -+ codeaccessormethod.cpp codeblock.cpp codeblockwithcomments.cpp -+ codeclassfield.cpp codeclassfielddeclarationblock.cpp -+ codecomment.cpp codedocument.cpp codegenerationpolicy.cpp -+ codegenerator.cpp codegenobjectwithtextblocks.cpp codemethodblock.cpp -+ codeoperation.cpp codeparameter.cpp component.cpp componentwidget.cpp -+ configurable.cpp datatypewidget.cpp dialog_utils.cpp -+ docwindow.cpp entity.cpp entityattribute.cpp entitywidget.cpp -+ enum.cpp enumliteral.cpp enumwidget.cpp floatingtextwidget.cpp -+ floatingtextwidgetcontroller.cpp folder.cpp forkjoinwidget.cpp -+ kplayerslideraction.cpp hierarchicalcodeblock.cpp import_rose.cpp -+ kstartuplogo.cpp linepath.cpp linkwidget.cpp listpopupmenu.cpp -+ main.cpp messagewidget.cpp messagewidgetcontroller.cpp -+ model_utils.cpp node.cpp nodewidget.cpp notewidget.cpp -+ notewidgetcontroller.cpp objectwidget.cpp objectwidgetcontroller.cpp -+ object_factory.cpp operation.cpp optionstate.cpp ownedcodeblock.cpp -+ ownedhierarchicalcodeblock.cpp package.cpp packagewidget.cpp -+ petalnode.cpp petaltree2uml.cpp plugin.cpp pluginloader.cpp -+ seqlinewidget.cpp statewidget.cpp stereotype.cpp template.cpp -+ textblock.cpp toolbarstate.cpp toolbarstatearrow.cpp -+ toolbarstateassociation.cpp toolbarstatefactory.cpp -+ toolbarstatemessages.cpp toolbarstateother.cpp toolbarstatepool.cpp -+ uml.cpp umlattributelist.cpp umlentityattributelist.cpp -+ umlcanvasobject.cpp umlclassifierlistitemlist.cpp umldoc.cpp -+ umllistview.cpp umllistviewitem.cpp umlnamespace.cpp umlobject.cpp -+ umlobjectlist.cpp umlrole.cpp umlview.cpp umlviewcanvas.cpp -+ umlviewimageexporter.cpp umlviewimageexporterall.cpp -+ umlviewimageexportermodel.cpp umlwidget.cpp umlwidgetcontroller.cpp -+ uniqueid.cpp usecase.cpp usecasewidget.cpp widgetbase.cpp -+ widget_factory.cpp widget_utils.cpp worktoolbar.cpp -+ LINK -+ refactoring-static codeimport-static kdevcppparser-static clipboard-static -+ codegenerator-static docgenerators-static dialogs-static -+ kdeprint-shared kio-shared ${XML2_LIBRARIES} ${XSLT_LIBRARIES} -+ DESTINATION ${BIN_INSTALL_DIR} -+) -diff --git a/umbrello/umbrello/clipboard/CMakeLists.txt b/umbrello/umbrello/clipboard/CMakeLists.txt -new file mode 100644 -index 0000000..a2e6113 ---- /dev/null -+++ b/umbrello/umbrello/clipboard/CMakeLists.txt -@@ -0,0 +1,25 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### clipboard (static) ######################## -+ -+tde_add_library( clipboard STATIC AUTOMOC -+ SOURCES -+ umldrag.cpp umlclipboard.cpp idchangelog.cpp -+) -diff --git a/umbrello/umbrello/codegenerators/CMakeLists.txt b/umbrello/umbrello/codegenerators/CMakeLists.txt -new file mode 100644 -index 0000000..7d68333 ---- /dev/null -+++ b/umbrello/umbrello/codegenerators/CMakeLists.txt -@@ -0,0 +1,54 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_BINARY_DIR}/../dialogs -+ ${CMAKE_CURRENT_SOURCE_DIR}/../dialogs -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### codegenerator (static) #################### -+ -+tde_add_library( codegenerator STATIC AUTOMOC -+ SOURCES -+ codegenfactory.cpp classifierinfo.cpp javacodegenerator.cpp -+ javaantcodedocument.cpp javacodeclassfield.cpp -+ javaclassifiercodedocument.cpp javacodecomment.cpp -+ javacodedocumentation.cpp javacodeoperation.cpp -+ javacodeaccessormethod.cpp javaclassdeclarationblock.cpp -+ javacodeclassfielddeclarationblock.cpp javacodegenerationpolicy.cpp -+ javacodegenerationpolicypage.cpp javacodegenerationformbase.ui -+ cppcodegenerator.cpp cppcodedocumentation.cpp cppcodeclassfield.cpp -+ cppcodecomment.cpp cppmakecodedocument.cpp cppsourcecodedocument.cpp -+ cppsourcecodeoperation.cpp cppsourcecodeaccessormethod.cpp -+ cppsourcecodeclassfielddeclarationblock.cpp -+ cppheadercodedocument.cpp cppheaderclassdeclarationblock.cpp -+ cppheadercodeoperation.cpp cppheadercodeaccessormethod.cpp -+ cppheadercodeclassfielddeclarationblock.cpp -+ cppcodegenerationpolicy.cpp cppcodegenerationpolicypage.cpp -+ cppcodegenerationformbase.ui cppcodegenerationform.cpp -+ rubycodegenerator.cpp rubycodeclassfield.cpp -+ rubyclassifiercodedocument.cpp rubycodecomment.cpp -+ rubycodedocumentation.cpp rubycodeoperation.cpp -+ rubycodeaccessormethod.cpp rubyclassdeclarationblock.cpp -+ rubycodeclassfielddeclarationblock.cpp rubycodegenerationpolicy.cpp -+ rubycodegenerationpolicypage.cpp rubycodegenerationformbase.ui -+ simplecodegenerator.cpp adawriter.cpp aswriter.cpp cppwriter.cpp -+ csharpwriter.cpp dwriter.cpp javawriter.cpp jswriter.cpp -+ idlwriter.cpp pascalwriter.cpp perlwriter.cpp php5writer.cpp -+ phpwriter.cpp pythonwriter.cpp rubywriter.cpp sqlwriter.cpp -+ tclwriter.cpp xmlschemawriter.cpp xmlelementcodeblock.cpp -+ xmlcodecomment.cpp codegen_utils.cpp -+) -diff --git a/umbrello/umbrello/codeimport/CMakeLists.txt b/umbrello/umbrello/codeimport/CMakeLists.txt -new file mode 100644 -index 0000000..d616ca6 ---- /dev/null -+++ b/umbrello/umbrello/codeimport/CMakeLists.txt -@@ -0,0 +1,29 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( kdevcppparser ) -+ -+ -+include_directories( -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### codeimport (static) ######################## -+ -+tde_add_library( codeimport STATIC -+ SOURCES -+ adaimport.cpp classimport.cpp cppimport.cpp idlimport.cpp -+ import_utils.cpp javaimport.cpp nativeimportbase.cpp pascalimport.cpp -+ pythonimport.cpp -+) -diff --git a/umbrello/umbrello/codeimport/kdevcppparser/CMakeLists.txt b/umbrello/umbrello/codeimport/kdevcppparser/CMakeLists.txt -new file mode 100644 -index 0000000..6c16fe3 ---- /dev/null -+++ b/umbrello/umbrello/codeimport/kdevcppparser/CMakeLists.txt -@@ -0,0 +1,24 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### kdevcppparser (static) #################### -+ -+tde_add_library( kdevcppparser STATIC -+ SOURCES -+ ast.cpp driver.cpp errors.cpp lexer.cpp lookup.cpp parser.cpp -+ tree_parser.cpp urlutil.cpp ast_utils.cpp cpptree2uml.cpp -+) -diff --git a/umbrello/umbrello/dialogs/CMakeLists.txt b/umbrello/umbrello/dialogs/CMakeLists.txt -new file mode 100644 -index 0000000..fbe04fa ---- /dev/null -+++ b/umbrello/umbrello/dialogs/CMakeLists.txt -@@ -0,0 +1,40 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### dialogs (static) ########################## -+ -+tde_add_library( dialogs STATIC AUTOMOC -+ SOURCES -+ codegenerationoptionsbase.ui codegenerationpolicybase.ui -+ codegenerationwizardbase.ui codeviewerdialogbase.ui -+ codevieweroptionsbase.ui diagrampropertiespage.ui -+ exportallviewsdialogbase.ui umlrolepropertiesbase.ui -+ activitydialog.cpp activitypage.cpp assocgenpage.cpp -+ assocpage.cpp assocpropdlg.cpp assocrolepage.cpp classgenpage.cpp -+ classifierlistpage.cpp classoptionspage.cpp classpropdlg.cpp -+ classwizard.cpp codeeditor.cpp codegenerationoptionspage.cpp -+ codegenerationpolicypage.cpp codegenerationwizard.cpp -+ codeviewerdialog.cpp codevieweroptionspage.cpp -+ defaultcodegenpolicypage.cpp diagramprintpage.cpp -+ exportallviewsdialog.cpp notedialog.cpp overwritedialogue.cpp -+ pkgcontentspage.cpp parmpropdlg.cpp selectopdlg.cpp settingsdlg.cpp -+ statedialog.cpp umlattributedialog.cpp umlentityattributedialog.cpp -+ umloperationdialog.cpp umltemplatedialog.cpp umlroledialog.cpp -+ umlroleproperties.cpp umlviewdialog.cpp umlwidgetcolorpage.cpp -+) -diff --git a/umbrello/umbrello/docgenerators/CMakeLists.txt b/umbrello/umbrello/docgenerators/CMakeLists.txt -new file mode 100644 -index 0000000..7ab19cf ---- /dev/null -+++ b/umbrello/umbrello/docgenerators/CMakeLists.txt -@@ -0,0 +1,48 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_BINARY_DIR}/../.. # for version.h -+ ${CMAKE_CURRENT_SOURCE_DIR}/.. -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+ ${XML2_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+install( FILES -+ xmi2docbook.xsl docbook2xhtml.xsl xmi.css common.ent -+ DESTINATION ${DATA_INSTALL_DIR}/umbrello ) -+ -+ -+##### umbodoc (executable) ###################### -+ -+tde_add_executable( umbodoc -+ SOURCES main.cpp -+ LINK kdecore-shared ${XML2_LIBRARIES} ${XSLT_LIBRARIES} -+ DESTINATION ${BIN_INSTALL_DIR} -+) -+ -+ -+##### docgenerators (static) #################### -+ -+tde_add_library( docgenerators STATIC AUTOMOC -+ SOURCES -+ docbookgenerator.h docbookgenerator.cpp xhtmlgenerator.cpp -+) -diff --git a/umbrello/umbrello/headings/CMakeLists.txt b/umbrello/umbrello/headings/CMakeLists.txt -new file mode 100644 -index 0000000..aeac637 ---- /dev/null -+++ b/umbrello/umbrello/headings/CMakeLists.txt -@@ -0,0 +1,16 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+install( FILES -+ heading.adb heading.ads heading.as heading.cpp heading.cs heading.d -+ heading.h heading.idl heading.java heading.js heading.php heading.pm -+ heading.py heading.rb heading.sql heading.xsd -+ DESTINATION ${DATA_INSTALL_DIR}/umbrello/headings ) -diff --git a/umbrello/umbrello/pics/CMakeLists.txt b/umbrello/umbrello/pics/CMakeLists.txt -new file mode 100644 -index 0000000..2d350aa ---- /dev/null -+++ b/umbrello/umbrello/pics/CMakeLists.txt -@@ -0,0 +1,53 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+tde_install_icons( -+ umbrello_diagram_activity umbrello_diagram_class -+ umbrello_diagram_collaboration umbrello_diagram_component -+ umbrello_diagram_deployment umbrello_diagram_sequence -+ umbrello_diagram_state umbrello_diagram_usecase -+ umbrello_diagram_entityrelationship ) -+ -+ -+install( FILES -+ actor.png aggregation.png align_left.png align_right.png -+ align_top.png align_bottom.png align_vert_middle.png -+ align_hori_middle.png align_vert_distribute.png -+ align_hori_distribute.png anchor.png andline.png arrow.png -+ association.png choice-rhomb.png choice-round.png component.png -+ composition.png containment.png CVglobal_meth.png CVglobal_var.png -+ CVimplementation_meth.png CVimplementation_signal.png -+ CVimplementation_slot.png CVimplementation_var.png CVnamespace.png -+ CVprivate_meth.png CVprivate_signal.png CVprivate_slot.png -+ CVprivate_var.png CVprotected_meth.png CVprotected_signal.png -+ CVprotected_slot.png CVprotected_var.png CVpublic_meth.png -+ CVpublic_signal.png CVpublic_slot.png CVpublic_var.png CVstruct.png -+ deep-history.png shallow-history.png dependency.png end_state.png -+ generalisation.png initial_state.png interface.png join.png -+ junction.png datatype.png enum.png message-synchronous.png -+ message-asynchronous.png note.png object.png startlogo.png -+ template.png text.png class.png uniassociation.png usecase.png -+ branch.png fork.png state-fork.png package.png subsystem.png -+ artifact.png box.png node.png entity.png relationship.png -+ cursor-actor.png cursor-andline.png cursor-choice-rhomb.png -+ cursor-choice-round.png cursor-deep-history.png cursor-join.png -+ cursor-junction.png cursor-shallow-history.png cursor-state-fork.png -+ cursor-usecase.png cursor-initial_state.png cursor-package.png -+ cursor-aggregation.png cursor-component.png cursor-containment.png -+ cursor-interface.png cursor-datatype.png cursor-enum.png -+ cursor-text.png cursor-anchor.png cursor-composition.png -+ cursor-message-asynchronous.png cursor-class.png cursor-artifact.png -+ cursor-dependency.png cursor-message-synchronous.png -+ cursor-uniassociation.png cursor-association.png cursor-end_state.png -+ cursor-node.png cursor-box.png cursor-fork.png cursor-note.png -+ cursor-branch.png cursor-generalisation.png cursor-object.png -+ cursor-entity.png cursor-relationship.png -+ DESTINATION ${DATA_INSTALL_DIR}/umbrello/pics ) -diff --git a/umbrello/umbrello/refactoring/CMakeLists.txt b/umbrello/umbrello/refactoring/CMakeLists.txt -new file mode 100644 -index 0000000..fd20459 ---- /dev/null -+++ b/umbrello/umbrello/refactoring/CMakeLists.txt -@@ -0,0 +1,24 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+ -+##### refactoring (static) ###################### -+ -+tde_add_library( refactoring STATIC AUTOMOC -+ SOURCES refactoringassistant.cpp -+) diff --git a/redhat/main/tdesdk/kdesdk-3.5.13-cmake_port.patch b/redhat/main/tdesdk/kdesdk-3.5.13-cmake_port.patch deleted file mode 100644 index 48d239534..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13-cmake_port.patch +++ /dev/null @@ -1,100 +0,0 @@ -commit bfb0bc00e959ed3cac6cf4e517a24de50446be50 -Author: Serghei Amelian -Date: 1329176749 +0200 - - [tdesdk] cmake port - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 806890a..c6f7d3d 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -26,6 +26,7 @@ include( CheckIncludeFile ) - include( CheckTypeSize ) - include( CheckCSourceCompiles ) - include( CheckCXXSourceCompiles ) -+include( CheckFunctionExists ) - include( CheckLibraryExists ) - - -@@ -55,6 +56,21 @@ option( BUILD_DOC "Build documentation" ${BUILD_ALL} ) - option( BUILD_KAPPTEMPLATE "Build kapptemplate" ${BUILD_ALL} ) - option( BUILD_KBABEL "Build kbabel" ${BUILD_ALL} ) - option( BUILD_KBUGBUSTER "Build kbugbuster" ${BUILD_ALL} ) -+option( BUILD_KDEACCOUNTS_PLUGIN "Build kdeaccounts-plugin" ${BUILD_ALL} ) -+option( BUILD_KFILE_PLUGINS "Build kfile-plugins" ${BUILD_ALL} ) -+option( BUILD_KIOSLAVE "Build kioslave" ${BUILD_ALL} ) -+option( BUILD_KMTRACE "Build kmtrace" ${BUILD_ALL} ) -+option( BUILD_KOMPARE "Build kompare" ${BUILD_ALL} ) -+option( BUILD_KPROFILEMETHOD "Build kprofilemethod" ${BUILD_ALL} ) -+option( BUILD_KSPY "Build kspy" ${BUILD_ALL} ) -+option( BUILD_KSTARTPERF "Build kstartperf" ${BUILD_ALL} ) -+option( BUILD_KUIVIEWER "Build kuiviewer" ${BUILD_ALL} ) -+option( BUILD_KUNITTEST "Build kunittest" ${BUILD_ALL} ) -+option( BUILD_POXML "Build poxml" ${BUILD_ALL} ) -+option( BUILD_SCHECK "Build scheck" ${BUILD_ALL} ) -+option( BUILD_SCRIPTS "Build scripts" ${BUILD_ALL} ) -+option( BUILD_TDECACHEGRIND "Build tdecachegrind" ${BUILD_ALL} ) -+option( BUILD_UMBRELLO "Build umbrello" ${BUILD_ALL} ) - - - ##### configure checks ########################## -@@ -83,6 +96,21 @@ tde_conditional_add_subdirectory( BUILD_DOC doc ) - tde_conditional_add_subdirectory( BUILD_KAPPTEMPLATE kapptemplate ) - tde_conditional_add_subdirectory( BUILD_KBABEL kbabel ) - tde_conditional_add_subdirectory( BUILD_KBUGBUSTER kbugbuster ) -+tde_conditional_add_subdirectory( BUILD_KDEACCOUNTS_PLUGIN kdeaccounts-plugin ) -+tde_conditional_add_subdirectory( BUILD_KFILE_PLUGINS kfile-plugins ) -+tde_conditional_add_subdirectory( BUILD_KIOSLAVE kioslave ) -+tde_conditional_add_subdirectory( BUILD_KMTRACE kmtrace ) -+tde_conditional_add_subdirectory( BUILD_KOMPARE kompare ) -+tde_conditional_add_subdirectory( BUILD_KPROFILEMETHOD kprofilemethod ) -+tde_conditional_add_subdirectory( BUILD_KSPY kspy ) -+tde_conditional_add_subdirectory( BUILD_KSTARTPERF kstartperf ) -+tde_conditional_add_subdirectory( BUILD_KUIVIEWER kuiviewer ) -+tde_conditional_add_subdirectory( BUILD_KUNITTEST kunittest ) -+tde_conditional_add_subdirectory( BUILD_POXML poxml ) -+tde_conditional_add_subdirectory( BUILD_SCHECK scheck ) -+tde_conditional_add_subdirectory( BUILD_SCRIPTS scripts ) -+tde_conditional_add_subdirectory( BUILD_TDECACHEGRIND kcachegrind ) -+tde_conditional_add_subdirectory( BUILD_UMBRELLO umbrello ) - - - ##### write configure files ##################### -diff --git a/config.h.cmake b/config.h.cmake -index 139f3c7..7ab8b07 100644 ---- a/config.h.cmake -+++ b/config.h.cmake -@@ -1 +1,4 @@ - #cmakedefine VERSION "@version@" -+ -+// kcachegrind -+#cmakedefine HAVE_MMAP 1 -diff --git a/kbabel/kbabel/CMakeLists.txt b/kbabel/kbabel/CMakeLists.txt -index b5164b4..6b263b5 100644 ---- a/kbabel/kbabel/CMakeLists.txt -+++ b/kbabel/kbabel/CMakeLists.txt -@@ -62,4 +62,5 @@ tde_add_library( kbabel STATIC AUTOMOC - fontpreferences.ui editordiffpreferences.ui editorpreferences.ui - searchpreferences.ui colorpreferences.ui kbcataloglistview.cpp - kbcataloglistviewitem.cpp errorlistview.cpp -+ DEPENDENCIES kbabelcommon-shared - ) -diff --git a/kmtrace/ktrace.c b/kmtrace/ktrace.c -index 21fca37..8b9eb2f 100644 ---- a/kmtrace/ktrace.c -+++ b/kmtrace/ktrace.c -@@ -778,12 +778,12 @@ kuntrace() - "Mallocs: %8ld Frees: %8ld Leaks: %8ld\n" - "Logged Mallocs: %8ld Logged Frees: %8ld Logged Leaks: %8ld\n" - "Avg. Free lookups: %ld Malloc collisions: %ld Max offset: %ld\n", -- tr_max_mallocs, TR_CACHE_SIZE, tr_flashes, -+ tr_max_mallocs, (long int)TR_CACHE_SIZE, tr_flashes, - tr_mallocs, tr_frees, tr_current_mallocs, - tr_logged_mallocs, tr_logged_frees, - tr_logged_mallocs - tr_logged_frees, - tr_frees > 0 ? ( tr_failed_free_lookups / tr_frees ) : 0, -- tr_malloc_collisions, tr_max_offset); -+ tr_malloc_collisions, (long int)tr_max_offset); - #endif - fclose (mallstream); - mallstream = NULL; diff --git a/redhat/main/tdesdk/kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch b/redhat/main/tdesdk/kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch deleted file mode 100644 index 38db4c083..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch +++ /dev/null @@ -1,32 +0,0 @@ -commit 572169a2e18705e526990c52924a268b218ff52b -Author: Timothy Pearson -Date: 1340737965 -0500 - - Fix FTBFS on newer subversion libraries - This closes Bug 872 - -diff --git a/kioslave/svn/ConfigureChecks.cmake b/kioslave/svn/ConfigureChecks.cmake -index 81358c6..3d46c74 100644 ---- a/kioslave/svn/ConfigureChecks.cmake -+++ b/kioslave/svn/ConfigureChecks.cmake -@@ -19,12 +19,16 @@ endif( ) - - # check for subversion library - --check_library_exists( "svn_client-1" "svn_pool_create_ex" "${SVN_LIBRARY_DIR}" HAVE_SVN_POOL_CREATE_EX ) -- --if( HAVE_SVN_POOL_CREATE_EX ) -+check_library_exists( "svn_client-1" "svn_pool_create_ex" "${SVN_LIBRARY_DIR}" HAVE_SVN_POOL_CREATE_EX_SVN_CLIENT ) -+if( HAVE_SVN_POOL_CREATE_EX_SVN_CLIENT ) - set( SVN_LIBRARIES "svn_client-1;svn_subr-1;svn_ra-1" ) - else( ) -- tde_message_fatal( "svn_client-1 library was not found on your system.\n Subversion is installed?\n Try to set SVN_LIBRARY_DIR to subversion library directory." ) -+ check_library_exists( "svn_subr-1" "svn_pool_create_ex" "${SVN_LIBRARY_DIR}" HAVE_SVN_POOL_CREATE_EX_SUBR ) -+ if( HAVE_SVN_POOL_CREATE_EX_SUBR ) -+ set( SVN_LIBRARIES "svn_client-1;svn_subr-1;svn_ra-1" ) -+ else( ) -+ tde_message_fatal( "svn_client-1 or svn_subr-1 library was not found on your system.\n Subversion is installed?\n Try to set SVN_LIBRARY_DIR to subversion library directory." ) -+ endif( ) - endif( ) - - diff --git a/redhat/main/tdesdk/kdesdk-3.5.13-misc_ftbfs.patch b/redhat/main/tdesdk/kdesdk-3.5.13-misc_ftbfs.patch deleted file mode 100644 index a40248909..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13-misc_ftbfs.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- kdesdk/kbugbuster/kresources/CMakeLists.txt.ORI 2012-07-30 18:00:21.039575551 +0200 -+++ kdesdk/kbugbuster/kresources/CMakeLists.txt 2012-07-30 18:00:25.414486000 +0200 -@@ -17,6 +17,7 @@ - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../backend - ${TDE_INCLUDE_DIR} -+ ${TDE_INCLUDE_DIR}/kde - ${TQT_INCLUDE_DIRS} - ) - diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-add_missing_files.patch b/redhat/main/tdesdk/kdesdk-3.5.13.1-add_missing_files.patch deleted file mode 100644 index 48dc16c0c..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1-add_missing_files.patch +++ /dev/null @@ -1,309 +0,0 @@ -diff -Nuar kdesdk-3.5.13.1/CMakeLists.txt kdesdk-3.5.13.1.patched/CMakeLists.txt ---- kdesdk-3.5.13.1/CMakeLists.txt 2012-09-08 12:06:50.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/CMakeLists.txt 2012-10-01 19:24:39.244352538 +0200 -@@ -109,7 +109,7 @@ - tde_conditional_add_subdirectory( BUILD_POXML poxml ) - tde_conditional_add_subdirectory( BUILD_SCHECK scheck ) - tde_conditional_add_subdirectory( BUILD_SCRIPTS scripts ) --tde_conditional_add_subdirectory( BUILD_KDECACHEGRIND kdecachegrind ) -+tde_conditional_add_subdirectory( BUILD_KDECACHEGRIND kcachegrind ) - tde_conditional_add_subdirectory( BUILD_UMBRELLO umbrello ) - - -diff -Nuar kdesdk-3.5.13.1/kcachegrind/CMakeLists.txt kdesdk-3.5.13.1.patched/kcachegrind/CMakeLists.txt ---- kdesdk-3.5.13.1/kcachegrind/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -+++ kdesdk-3.5.13.1.patched/kcachegrind/CMakeLists.txt 2012-10-01 19:35:12.689266467 +0200 -@@ -0,0 +1,21 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include( ConfigureChecks.cmake ) -+ -+set( KCACHEGRIND_VERSION "0.4.6kde" ) -+configure_file( version.h.in version.h @ONLY ) -+configure_file( kcachegrind.spec.in kcachegrind.spec @ONLY ) -+configure_file( kcachegrind.lsm.in kcachegrind.lsm @ONLY ) -+ -+add_subdirectory( kcachegrind ) -+add_subdirectory( pics ) -+add_subdirectory( converters ) -diff -Nuar kdesdk-3.5.13.1/kcachegrind/ConfigureChecks.cmake kdesdk-3.5.13.1.patched/kcachegrind/ConfigureChecks.cmake ---- kdesdk-3.5.13.1/kcachegrind/ConfigureChecks.cmake 1970-01-01 01:00:00.000000000 +0100 -+++ kdesdk-3.5.13.1.patched/kcachegrind/ConfigureChecks.cmake 2012-10-01 19:35:15.546204776 +0200 -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+check_function_exists( mmap HAVE_MMAP ) -diff -Nuar kdesdk-3.5.13.1/kcachegrind/converters/CMakeLists.txt kdesdk-3.5.13.1.patched/kcachegrind/converters/CMakeLists.txt ---- kdesdk-3.5.13.1/kcachegrind/converters/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -+++ kdesdk-3.5.13.1.patched/kcachegrind/converters/CMakeLists.txt 2012-10-01 19:33:48.381089049 +0200 -@@ -0,0 +1,15 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+install( PROGRAMS -+ hotshot2calltree op2calltree pprof2calltree -+ dprof2calltree memprof2calltree -+ DESTINATION ${BIN_INSTALL_DIR} ) -diff -Nuar kdesdk-3.5.13.1/kcachegrind/kcachegrind/CMakeLists.txt kdesdk-3.5.13.1.patched/kcachegrind/kcachegrind/CMakeLists.txt ---- kdesdk-3.5.13.1/kcachegrind/kcachegrind/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -+++ kdesdk-3.5.13.1.patched/kcachegrind/kcachegrind/CMakeLists.txt 2012-10-01 19:35:46.872528600 +0200 -@@ -0,0 +1,50 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+include_directories( -+ ${CMAKE_CURRENT_BINARY_DIR} -+ ${CMAKE_CURRENT_SOURCE_DIR} -+ ${CMAKE_BINARY_DIR} -+ ${TDE_INCLUDE_DIR} -+ ${TQT_INCLUDE_DIRS} -+) -+ -+link_directories( -+ ${TQT_LIBRARY_DIRS} -+) -+ -+ -+##### other data ################################ -+ -+tde_install_icons( ) -+install( FILES kcachegrind.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) -+install( FILES kcachegrindui.rc tips DESTINATION ${DATA_INSTALL_DIR}/kcachegrind ) -+install( FILES x-kcachegrind.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) -+ -+ -+##### kcachegrind (executable) ################## -+ -+tde_add_executable( kcachegrind AUTOMOC -+ SOURCES -+ functionselectionbase.ui stackselectionbase.ui partselectionbase.ui -+ configdlgbase.ui loader.cpp cachegrindloader.cpp treemap.cpp pool.cpp -+ main.cpp configuration.cpp functionselection.cpp coverage.cpp -+ partgraph.cpp toplevel.cpp stackselection.cpp stackbrowser.cpp -+ subcost.cpp tracedata.cpp partselection.cpp configdlg.cpp -+ utils.cpp fixcost.cpp traceitemview.cpp instrview.cpp tabview.cpp -+ sourceview.cpp callmapview.cpp callview.cpp coverageview.cpp -+ costtypeview.cpp partview.cpp listutils.cpp costtypeitem.cpp -+ multiview.cpp callitem.cpp coverageitem.cpp sourceitem.cpp -+ costlistitem.cpp partlistitem.cpp functionitem.cpp instritem.cpp -+ stackitem.cpp callgraphview.cpp -+ LINK kio-shared -+ DESTINATION ${BIN_INSTALL_DIR} -+) -\ Pas de fin de ligne à la fin du fichier -diff -Nuar kdesdk-3.5.13.1/kcachegrind/pics/CMakeLists.txt kdesdk-3.5.13.1.patched/kcachegrind/pics/CMakeLists.txt ---- kdesdk-3.5.13.1/kcachegrind/pics/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -+++ kdesdk-3.5.13.1.patched/kcachegrind/pics/CMakeLists.txt 2012-10-01 19:35:59.697251930 +0200 -@@ -0,0 +1,14 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+add_subdirectory( hicolor ) -+ -+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kcachegrind/icons ) -diff -Nuar kdesdk-3.5.13.1/kcachegrind/pics/hicolor/CMakeLists.txt kdesdk-3.5.13.1.patched/kcachegrind/pics/hicolor/CMakeLists.txt ---- kdesdk-3.5.13.1/kcachegrind/pics/hicolor/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -+++ kdesdk-3.5.13.1.patched/kcachegrind/pics/hicolor/CMakeLists.txt 2012-10-01 19:36:11.193004007 +0200 -@@ -0,0 +1,12 @@ -+################################################# -+# -+# (C) 2012 Serghei Amelian -+# serghei (DOT) amelian (AT) gmail.com -+# -+# Improvements and feedback are welcome -+# -+# This file is released under GPL >= 2 -+# -+################################################# -+ -+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kcachegrind/icons ) -diff -Nuar kdesdk-3.5.13.1/kdecachegrind/CMakeLists.txt kdesdk-3.5.13.1.patched/kdecachegrind/CMakeLists.txt ---- kdesdk-3.5.13.1/kdecachegrind/CMakeLists.txt 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/kdecachegrind/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -@@ -1,21 +0,0 @@ --################################################# --# --# (C) 2012 Serghei Amelian --# serghei (DOT) amelian (AT) gmail.com --# --# Improvements and feedback are welcome --# --# This file is released under GPL >= 2 --# --################################################# -- --include( ConfigureChecks.cmake ) -- --set( KCACHEGRIND_VERSION "0.4.6kde" ) --configure_file( version.h.in version.h @ONLY ) --configure_file( kdecachegrind.spec.in kcachegrind.spec @ONLY ) --configure_file( kdecachegrind.lsm.in kcachegrind.lsm @ONLY ) -- --add_subdirectory( kdecachegrind ) --add_subdirectory( pics ) --add_subdirectory( converters ) -diff -Nuar kdesdk-3.5.13.1/kdecachegrind/ConfigureChecks.cmake kdesdk-3.5.13.1.patched/kdecachegrind/ConfigureChecks.cmake ---- kdesdk-3.5.13.1/kdecachegrind/ConfigureChecks.cmake 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/kdecachegrind/ConfigureChecks.cmake 1970-01-01 01:00:00.000000000 +0100 -@@ -1,12 +0,0 @@ --################################################# --# --# (C) 2012 Serghei Amelian --# serghei (DOT) amelian (AT) gmail.com --# --# Improvements and feedback are welcome --# --# This file is released under GPL >= 2 --# --################################################# -- --check_function_exists( mmap HAVE_MMAP ) -diff -Nuar kdesdk-3.5.13.1/kdecachegrind/converters/CMakeLists.txt kdesdk-3.5.13.1.patched/kdecachegrind/converters/CMakeLists.txt ---- kdesdk-3.5.13.1/kdecachegrind/converters/CMakeLists.txt 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/kdecachegrind/converters/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -@@ -1,15 +0,0 @@ --################################################# --# --# (C) 2012 Serghei Amelian --# serghei (DOT) amelian (AT) gmail.com --# --# Improvements and feedback are welcome --# --# This file is released under GPL >= 2 --# --################################################# -- --install( PROGRAMS -- hotshot2calltree op2calltree pprof2calltree -- dprof2calltree memprof2calltree -- DESTINATION ${BIN_INSTALL_DIR} ) -diff -Nuar kdesdk-3.5.13.1/kdecachegrind/kdecachegrind/CMakeLists.txt kdesdk-3.5.13.1.patched/kdecachegrind/kdecachegrind/CMakeLists.txt ---- kdesdk-3.5.13.1/kdecachegrind/kdecachegrind/CMakeLists.txt 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/kdecachegrind/kdecachegrind/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -@@ -1,50 +0,0 @@ --################################################# --# --# (C) 2012 Serghei Amelian --# serghei (DOT) amelian (AT) gmail.com --# --# Improvements and feedback are welcome --# --# This file is released under GPL >= 2 --# --################################################# -- --include_directories( -- ${CMAKE_CURRENT_BINARY_DIR} -- ${CMAKE_CURRENT_SOURCE_DIR} -- ${CMAKE_BINARY_DIR} -- ${TDE_INCLUDE_DIR} -- ${TQT_INCLUDE_DIRS} --) -- --link_directories( -- ${TQT_LIBRARY_DIRS} --) -- -- --##### other data ################################ -- --tde_install_icons( ) --install( FILES kdecachegrind.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) --install( FILES kdecachegrindui.rc tips DESTINATION ${DATA_INSTALL_DIR}/kcachegrind ) --install( FILES x-kdecachegrind.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) -- -- --##### kdecachegrind (executable) ################## -- --tde_add_executable( kdecachegrind AUTOMOC -- SOURCES -- functionselectionbase.ui stackselectionbase.ui partselectionbase.ui -- configdlgbase.ui loader.cpp cachegrindloader.cpp treemap.cpp pool.cpp -- main.cpp configuration.cpp functionselection.cpp coverage.cpp -- partgraph.cpp toplevel.cpp stackselection.cpp stackbrowser.cpp -- subcost.cpp tracedata.cpp partselection.cpp configdlg.cpp -- utils.cpp fixcost.cpp traceitemview.cpp instrview.cpp tabview.cpp -- sourceview.cpp callmapview.cpp callview.cpp coverageview.cpp -- costtypeview.cpp partview.cpp listutils.cpp costtypeitem.cpp -- multiview.cpp callitem.cpp coverageitem.cpp sourceitem.cpp -- costlistitem.cpp partlistitem.cpp functionitem.cpp instritem.cpp -- stackitem.cpp callgraphview.cpp -- LINK kio-shared -- DESTINATION ${BIN_INSTALL_DIR} --) -diff -Nuar kdesdk-3.5.13.1/kdecachegrind/pics/CMakeLists.txt kdesdk-3.5.13.1.patched/kdecachegrind/pics/CMakeLists.txt ---- kdesdk-3.5.13.1/kdecachegrind/pics/CMakeLists.txt 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/kdecachegrind/pics/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -@@ -1,14 +0,0 @@ --################################################# --# --# (C) 2012 Serghei Amelian --# serghei (DOT) amelian (AT) gmail.com --# --# Improvements and feedback are welcome --# --# This file is released under GPL >= 2 --# --################################################# -- --add_subdirectory( hicolor ) -- --tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kdecachegrind/icons ) -diff -Nuar kdesdk-3.5.13.1/kdecachegrind/pics/hicolor/CMakeLists.txt kdesdk-3.5.13.1.patched/kdecachegrind/pics/hicolor/CMakeLists.txt ---- kdesdk-3.5.13.1/kdecachegrind/pics/hicolor/CMakeLists.txt 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1.patched/kdecachegrind/pics/hicolor/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 -@@ -1,12 +0,0 @@ --################################################# --# --# (C) 2012 Serghei Amelian --# serghei (DOT) amelian (AT) gmail.com --# --# Improvements and feedback are welcome --# --# This file is released under GPL >= 2 --# --################################################# -- --tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kdecachegrind/icons ) diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_cmake_macros.patch b/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_cmake_macros.patch deleted file mode 100644 index adfe47f52..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_cmake_macros.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- kdesdk-3.5.13.1/kioslave/svn/ConfigureChecks.cmake 2012-09-30 20:05:52.627163660 +0200 -+++ kdesdk/kioslave/svn/ConfigureChecks.cmake 2012-09-30 20:02:29.267164082 +0200 -@@ -34,11 +34,11 @@ - - # check for subversion headers - --tde_save_and_set( CMAKE_REQUIRED_FLAGS "-I${APR_INCLUDE_DIRS}" ) --tde_save_and_set( CMAKE_REQUIRED_DEFINITIONS "${APR_CFLAGS}" ) -+set( CMAKE_REQUIRED_FLAGS "-I${APR_INCLUDE_DIRS}" ) -+set( CMAKE_REQUIRED_DEFINITIONS "${APR_CFLAGS}" ) - - if( SVN_INCLUDE_DIR ) -- set_and_save( CMAKE_REQUIRED_INCLUDES "${SVN_INCLUDE_DIR}" ) -+ set( CMAKE_REQUIRED_INCLUDES "${SVN_INCLUDE_DIR}" ) - check_include_file( "svn_types.h" HAVE_SVN_TYPES_H ) - tde_restore( CMAKE_REQUIRED_INCLUDES ) - else( ) diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch b/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch deleted file mode 100644 index 80ca10ff8..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch +++ /dev/null @@ -1,39683 +0,0 @@ -commit cfccedd9c8db3af36d7c5635ca212fa170bb6ff5 -Author: Timothy Pearson -Date: 1327976424 -0600 - - Part 2 of prior commit - -diff --git a/kdecachegrind/AUTHORS b/kdecachegrind/AUTHORS -new file mode 100644 -index 0000000..ded6005 ---- /dev/null -+++ b/kdecachegrind/AUTHORS -@@ -0,0 +1 @@ -+Josef Weidendorfer -diff --git a/kdecachegrind/COPYING b/kdecachegrind/COPYING -new file mode 100644 -index 0000000..c13faf0 ---- /dev/null -+++ b/kdecachegrind/COPYING -@@ -0,0 +1,340 @@ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Library General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) year name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ , 1 April 1989 -+ Ty Coon, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Library General -+Public License instead of this License. -diff --git a/kdecachegrind/ChangeLog b/kdecachegrind/ChangeLog -new file mode 100644 -index 0000000..05f3081 ---- /dev/null -+++ b/kdecachegrind/ChangeLog -@@ -0,0 +1,89 @@ -+2004/06/30 -+ * Leak fixes -+ * Crash fixes on reload (make setData() synchroneous) -+ * Some update fixes in the data model (tracedata.cpp) -+ * Fix update problems in Function Profile -+ * Reselect active function on refresh in function profile -+ with grouping on -+ -+2004/04/28 -+ * toplevel.h/cpp, kdecachegrindui.rc -+ - Switching Layouts -+ * multiview.cpp: Removed some qDebug's -+ * Same term fixes -+ -+2004/04/26 -+ * cachegrindloader.cpp, fixcost.cpp: -+ - Allow Ranges in Subposition Spec, currently not used -+ - Correctly parse "Desc: Trigger:" -+ - Allow Event Spec (Long Name, Formula) with "event:" -+ * listutils.cpp: -+ - make level meters for costs only 1 bar -+ (2 with upper from 0..50%, lower 50%..100% is really confusing) -+ - Besides from Call graph and Tree maps, truncate bars to -+ only use needed size (removes lots of empty rectangles) -+ * CallGraphView: -+ - some fixes when no data is loaded -+ * functionselection.cpp (Function Profile) -+ - activation on mouse release to allow for context menu -+ * tracedata.cpp -+ - more robust parsing of events lists -+ - Introduction of Ranges (not currently used) -+ * utils.cpp: -+ - more robust parsing functions -+ -+2004/04/05 -+ * CallGraphView: -+ - Add Context menu item "Export as Image" -+ - Hide Birdseye-View if call-graph fits into widget -+ - Error messages in Canvas when something goes wrong -+ * Some Fixes, qDebug->kdDebug -+ -+2004/04/02 -+ * In most views columns for 2nd Event Type added -+ * Context menus modified to allow quick change of 2nd Event Type -+ * Toolbar simplified (only most used actions) -+ * Terminology fixes ("cost type"->"event type", -+ "trace data"->"profile data", long names of Ir,Dr,...) -+ * Sorting costs in lists is always descending now -+ * New File menu item: "Add..." other profile data to current window -+ * Detect Cachegrind format by "events:" content, not file name -+ Allows for arbitrary names of profile data files. -+ -+2004/03/25 -+ * New Class Addr as wrapper for memory addresses. Use 64bit -+ to allow loading of data produced on 64bit architectures -+ -+2004/03/17 -+ -+ * costtypeview.cpp, tracedata.h/cpp: -+ Fixed deletion of custom types -+ * cachegrindloader.cpp, tracedata.h/cpp: -+ Moved String compression handling in Cachegrind files -+ to CachegrindLoader -+ * Do not show inclusive cost column in FunctionSelection -+ side bar if not available -+ * Remove "isPartOfTrace" from Loader interface -+ (we allow parts from multiple experiments for comp.) -+ * partview.cpp, partlistitem.h/cpp: -+ Remove Column Callees, add Trigger -+ -+2003/05/10 -+ -+ * Status progress on loading and cycle calculation -+ * Corrected order of trace parts (PID/PartNo/ThreadID) -+ * Allow adding traces (BUGGY...) -+ -+2003/02/06 -+ -+ * Version 0.3a -+ * Bugfixes: -+ - Compiles with KDE 3.0.x -+ - Always select a first cost type -+ - Loading from another directory -+ -+ -+2002/11/28 -+ -+ * Version 0.3 -+ -diff --git a/kdecachegrind/INSTALL b/kdecachegrind/INSTALL -new file mode 100644 -index 0000000..02a4a07 ---- /dev/null -+++ b/kdecachegrind/INSTALL -@@ -0,0 +1,167 @@ -+Basic Installation -+================== -+ -+ These are generic installation instructions. -+ -+ The `configure' shell script attempts to guess correct values for -+various system-dependent variables used during compilation. It uses -+those values to create a `Makefile' in each directory of the package. -+It may also create one or more `.h' files containing system-dependent -+definitions. Finally, it creates a shell script `config.status' that -+you can run in the future to recreate the current configuration, a file -+`config.cache' that saves the results of its tests to speed up -+reconfiguring, and a file `config.log' containing compiler output -+(useful mainly for debugging `configure'). -+ -+ If you need to do unusual things to compile the package, please try -+to figure out how `configure' could check whether to do them, and mail -+diffs or instructions to the address given in the `README' so they can -+be considered for the next release. If at some point `config.cache' -+contains results you don't want to keep, you may remove or edit it. -+ -+ The file `configure.in' is used to create `configure' by a program -+called `autoconf'. You only need `configure.in' if you want to change -+it or regenerate `configure' using a newer version of `autoconf'. -+ -+The simplest way to compile this package is: -+ -+ 1. `cd' to the directory containing the package's source code and type -+ `./configure' to configure the package for your system. If you're -+ using `csh' on an old version of System V, you might need to type -+ `sh ./configure' instead to prevent `csh' from trying to execute -+ `configure' itself. -+ -+ Running `configure' takes a while. While running, it prints some -+ messages telling which features it is checking for. -+ -+ 2. Type `make' to compile the package. -+ -+ 3. Type `make install' to install the programs and any data files and -+ documentation. -+ -+ 4. You can remove the program binaries and object files from the -+ source code directory by typing `make clean'. -+ -+Compilers and Options -+===================== -+ -+ Some systems require unusual options for compilation or linking that -+the `configure' script does not know about. You can give `configure' -+initial values for variables by setting them in the environment. Using -+a Bourne-compatible shell, you can do that on the command line like -+this: -+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure -+ -+Or on systems that have the `env' program, you can do it like this: -+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure -+ -+Compiling For Multiple Architectures -+==================================== -+ -+ You can compile the package for more than one kind of computer at the -+same time, by placing the object files for each architecture in their -+own directory. To do this, you must use a version of `make' that -+supports the `VPATH' variable, such as GNU `make'. `cd' to the -+directory where you want the object files and executables to go and run -+the `configure' script. `configure' automatically checks for the -+source code in the directory that `configure' is in and in `..'. -+ -+ If you have to use a `make' that does not supports the `VPATH' -+variable, you have to compile the package for one architecture at a time -+in the source code directory. After you have installed the package for -+one architecture, use `make distclean' before reconfiguring for another -+architecture. -+ -+Installation Names -+================== -+ -+ By default, `make install' will install the package's files in -+`/usr/local/bin', `/usr/local/man', etc. You can specify an -+installation prefix other than `/usr/local' by giving `configure' the -+option `--prefix=PATH'. -+ -+ You can specify separate installation prefixes for -+architecture-specific files and architecture-independent files. If you -+give `configure' the option `--exec-prefix=PATH', the package will use -+PATH as the prefix for installing programs and libraries. -+Documentation and other data files will still use the regular prefix. -+ -+ If the package supports it, you can cause programs to be installed -+with an extra prefix or suffix on their names by giving `configure' the -+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. -+ -+Optional Features -+================= -+ -+ Some packages pay attention to `--enable-FEATURE' options to -+`configure', where FEATURE indicates an optional part of the package. -+They may also pay attention to `--with-PACKAGE' options, where PACKAGE -+is something like `gnu-as' or `x' (for the X Window System). The -+`README' should mention any `--enable-' and `--with-' options that the -+package recognizes. -+ -+ For packages that use the X Window System, `configure' can usually -+find the X include and library files automatically, but if it doesn't, -+you can use the `configure' options `--x-includes=DIR' and -+`--x-libraries=DIR' to specify their locations. -+ -+Specifying the System Type -+========================== -+ -+ There may be some features `configure' can not figure out -+automatically, but needs to determine by the type of host the package -+will run on. Usually `configure' can figure that out, but if it prints -+a message saying it can not guess the host type, give it the -+`--host=TYPE' option. TYPE can either be a short name for the system -+type, such as `sun4', or a canonical name with three fields: -+ CPU-COMPANY-SYSTEM -+ -+See the file `config.sub' for the possible values of each field. If -+`config.sub' isn't included in this package, then this package doesn't -+need to know the host type. -+ -+ If you are building compiler tools for cross-compiling, you can also -+use the `--target=TYPE' option to select the type of system they will -+produce code for and the `--build=TYPE' option to select the type of -+system on which you are compiling the package. -+ -+Sharing Defaults -+================ -+ -+ If you want to set default values for `configure' scripts to share, -+you can create a site shell script called `config.site' that gives -+default values for variables like `CC', `cache_file', and `prefix'. -+`configure' looks for `PREFIX/share/config.site' if it exists, then -+`PREFIX/etc/config.site' if it exists. Or, you can set the -+`CONFIG_SITE' environment variable to the location of the site script. -+A warning: not all `configure' scripts look for a site script. -+ -+Operation Controls -+================== -+ -+ `configure' recognizes the following options to control how it -+operates. -+ -+`--cache-file=FILE' -+ Use and save the results of the tests in FILE instead of -+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for -+ debugging `configure'. -+ -+`--help' -+ Print a summary of the options to `configure', and exit. -+ -+`--quiet' -+`--silent' -+`-q' -+ Do not print messages saying which checks are being made. -+ -+`--srcdir=DIR' -+ Look for the package's source code in directory DIR. Usually -+ `configure' can determine that directory automatically. -+ -+`--version' -+ Print the version of Autoconf used to generate the `configure' -+ script, and exit. -+ -+`configure' also accepts some other, not widely useful, options. -+ -diff --git a/kdecachegrind/Makefile.am b/kdecachegrind/Makefile.am -new file mode 100644 -index 0000000..e93f6af ---- /dev/null -+++ b/kdecachegrind/Makefile.am -@@ -0,0 +1,6 @@ -+SUBDIRS = kdecachegrind pics converters -+ -+EXTRA_DIST = \ -+ AUTHORS COPYING NEWS ChangeLog INSTALL README TODO \ -+ kdecachegrind.lsm kdecachegrind.spec version.h -+ -diff --git a/kdecachegrind/NEWS b/kdecachegrind/NEWS -new file mode 100644 -index 0000000..e69de29 -diff --git a/kdecachegrind/README b/kdecachegrind/README -new file mode 100644 -index 0000000..0866eb8 ---- /dev/null -+++ b/kdecachegrind/README -@@ -0,0 +1,62 @@ -+KCachegrind -+=========== -+ -+ -+What is all this about ? -+------------------------- -+ -+Profiling, i.e. determinating most time consuming execution parts, -+is an important last step when developing applications. -+KCachegrind visualizes traces, generated by profiling, in various ways; -+most notable is the TreeMap visualization of the calls happening -+and a condensed version of it, the Coverage analysis. -+KCachegrind is designed to allow fast browsing and to provide a quick -+overview of very large programs, such as KDE applications (but not -+limited to!). -+ -+At the moment, it uses Cachegrind as profiling backend, which is using -+the excellent CPU simulator in Valgrind. Thus, profiling does not -+need any preparation, can cope with shared libraries and plugin -+architectures, and allows for profile runs to not influence the measuring -+by the profile itself (all in contrast to e.g. GProf). Disadvantage is -+slower profile runs, unfortunately. -+ -+For Cachegrind to provide call tree information, a patch is provided. -+This enables the most interesting visualization features of KCachegrind. -+ -+ -+Requirements -+------------ -+ -+A call-tree version of Cachegrind: -+ - X86 Linux -+ - Valgrind 1.0.x with call-tree patch from KCachegrind Website -+ - Valgrind 2.0.x with call-tree skin installed -+ -+Cachegrind runs on x86 platforms, KCachegrind on all KDE enabled -+platforms (KDE 3.0.x). -+ -+ -+Compilation and Installation -+---------------------------- -+ -+Simple do the command sequence -+ -+ ./configure --prefix= -+ make -+ make install -+ -+ -+ -+KCachegrind features -+-------------------- -+ -+Most important: TreeMap calltree visualisation. -+For the rest, see the detailed "What's this?" help for -+each part of KCachegrind and the quick starter on the -+WWW page ( http://kcachegrind.sourceforge.net/cgi-bin/show.cgi ) -+ -+ -+ -+Happy Profiling, -+ Josef Weidendorfer -diff --git a/kdecachegrind/TODO b/kdecachegrind/TODO -new file mode 100644 -index 0000000..1eca67e ---- /dev/null -+++ b/kdecachegrind/TODO -@@ -0,0 +1,100 @@ -+TODO/Wishlist Items -+=================== -+ -+ -+KCachegrind -+----------- -+ -+All cost Lists: -+* Show up to a number of items, not down to a threadshold. -+ If more, add a "..." with number of items not shown, and context option -+ to show more -+* "Copy from Top" converts lists into ASCII, puts into clipboard -+ -+ -+Configuration: -+ Source dirs per ELF object -+ -+Layout: -+* 1/2/3/4 vertical/horizontal FunctionInfos -+ with Shift/Wraparound selection mode -+* Inside each FunctionInfo different Layouts -+ - tabbed layout -+ - top: info, bottom left: calls/coverage, bottom right: graph/source -+* Long/short info tab -+ -+General: -+* Selected Item can be a object/file/class/function/line -+* Configuration Dlg -+ - Local config (?) -+ - Cost Types -+ - function colors -+ - Try to reload source after config. -+* Session Management -+ -+ -+ -+Annotation Views: -+ -+ BUGS: -+ * Draw problem with multiple srcs to one target -+ * REP case... -+ -+ TODO: -+ * Selectable Jumps (Arrows) -+ * Tooltip for Jumps (Kind, from/to, jump count) -+ * Show direction (arrows) on jump lines -+ -+ Source view TODO: -+ * Implicit jumps (green) [needs support from the tool?] -+ -+ -+ -+Callgraph: -+* Fix Arrows for back-arcs -+* Less "Jumps" for minimap -+* Correct Keyboard navigation (how?) -+ -+Types: -+* Ratios -+* Automatic subtypes -+ -+WISHS: -+* Support for Data tracing -+ Which variables are touched how often from which function? -+ - Some graphical visualisation... -+ -+* GCC -pg (gmon.out) as Profiling Backend -+* Demangler (use c++filt) -+* Calculation of call weights (if not given) -+* OProfile, DynaProf -+ -+Support for KCachegrind in Calltree -+----------------------------------- -+ -+WISHS: -+- store more details of calltree -+ - for every function call: executed from shared lib -+ (Not needed, if function names are unique in whole app) -+ - adaptive call chain context (Really needed ? MUCH Data!) -+- dump at -+ - breakpoints -+ - watchpoints (with data tracing!) -+ - every xxx BBs (DONE) -+- dump around -+ - function invocation -+ - KAction event -+ - DCOP event -+ -+- data accesses from (instr address/count) -+ stack: -> (function, stackframe-offset) -+ dynamic: -> (mem region start, [type], offset) -+ type can be get when a constructor is called for region -+ static: -> (mem region start, type, offset) -+ -+* Generate full instr/data access trace for offline analysis. -+ -+* Appending mode -+ -+ -+ -diff --git a/kdecachegrind/configure.in.in b/kdecachegrind/configure.in.in -new file mode 100644 -index 0000000..dfc8508 ---- /dev/null -+++ b/kdecachegrind/configure.in.in -@@ -0,0 +1,8 @@ -+KCACHEGRIND_VERSION=0.4.6kde -+AC_SUBST(KCACHEGRIND_VERSION) -+ -+AC_FUNC_MMAP -+ -+dnl AC_OUTPUT( kdecachegrind/version.h ) -+dnl AC_OUTPUT( kdecachegrind/kdecachegrind.spec ) -+dnl AC_OUTPUT( kdecachegrind/kdecachegrind.lsm ) -diff --git a/kdecachegrind/converters/Makefile.am b/kdecachegrind/converters/Makefile.am -new file mode 100644 -index 0000000..08b3696 ---- /dev/null -+++ b/kdecachegrind/converters/Makefile.am -@@ -0,0 +1,2 @@ -+bin_SCRIPTS = hotshot2calltree op2calltree pprof2calltree dprof2calltree \ -+ memprof2calltree -diff --git a/kdecachegrind/converters/README b/kdecachegrind/converters/README -new file mode 100644 -index 0000000..c27d3c6 ---- /dev/null -+++ b/kdecachegrind/converters/README -@@ -0,0 +1,24 @@ -+This directory contains some scripts to convert output of different -+profiling tools into the format which can be loaded by KCachegrind. -+See the comment at start of every script for details. -+ -+In the long run, these should be replaced by import filters in -+KCachegrind directly, but I can't promise anything. Partly, this -+is because some scripts are provided as contribution from others. -+ -+hotshot2calltree Converter from Python Hotshot Profiler. -+op2calltree Converter from OProfile sampling data. -+dprof2calltree Converter from PERL::DProf Profiler. -+pprof2calltree Converter from APD PHP Profiler. -+ -+Thanks go to -+* George Schlossnagle for -+ dprof2calltree and pprof2calltree, -+* Jörg Beyer for -+ hotshot2calltree -+ -+If you want to write a converter, have a look at the calltree format -+description on the web site (kdecachegrind.sf.net). -+ -+Josef -+ -diff --git a/kdecachegrind/converters/dprof2calltree b/kdecachegrind/converters/dprof2calltree -new file mode 100644 -index 0000000..f276e18 ---- /dev/null -+++ b/kdecachegrind/converters/dprof2calltree -@@ -0,0 +1,199 @@ -+#!/usr/bin/perl -+# -+# Redistribution and use in source and binary forms, with or without -+# modification, are permitted provided that the following conditions are met: -+# -+# - Redistributions of source code must retain the above copyright notice, -+# this list of conditions and the following disclaimer. -+# -+# - Redistributions in binary form must reproduce the above copyright -+# notice, this list of conditions and the following disclaimer in the -+# documentation and/or other materials provided with the distribution. -+# -+# - All advertising materials mentioning features or use of this software -+# must display the following acknowledgement: This product includes software -+# developed by OmniTI Computer Consulting. -+# -+# - Neither name of the company nor the names of its contributors may be -+# used to endorse or promote products derived from this software without -+# specific prior written permission. -+# -+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND ANY -+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+# -+# Copyright (c) 2004 OmniTI Computer Consulting -+# All rights reserved -+# The following code was written by George Schlossnagle -+# and is provided completely free and without any warranty. -+# -+ -+# -+# This script is designed to convert the tmon.out output emitted -+# from Perl's Devel::DProf profiling package. To use this: -+# -+# 1) Run your perl script as -+# > perl -d:DProf yoursript.pl -+# This will create a file called tmon.out. If you want to -+# inspect it on the command line, look at the man page -+# for dprofp for details. -+# -+# 2) Run -+# > dprof2calltree -f tmon.out -+# or -+# > dprof2calltree -f tmon.out -o cachegrind.out.foo -+# -+# This creates a cachegrind-style file called cachgrind.out.tmon.out or -+# cachegrind.out.foo, respecitvely. -+# -+# 3) Run kdecachegrind cachegrind.out.foo -+# -+# 4) Enjoy! -+ -+use strict; -+use Config; -+use Getopt::Std; -+use IO::File; -+ -+my @callstack; -+my %function_info; -+my $tree = {}; -+my $total_cost = 0; -+my %opts; -+ -+getopt('f:o:', \%opts); -+ -+my $infd; -+usage() unless ($opts{'f'} && ($infd = IO::File->new($opts{'f'}, "r"))); -+ -+my $outfd; -+my $outfile = $opts{'o'}; -+unless($outfile) { -+ $opts{'f'} =~ m!([^/]+)$!; -+ $outfile = "cachegrind.out.$1"; -+} -+$outfd = new IO::File $outfile, "w"; -+usage() unless defined $outfd; -+ -+while(<$infd>) { -+ last if /^PART2/; -+} -+while(<$infd>) { -+ chomp; -+ my @args = split; -+ if($args[0] eq '@') { -+ # record timing event -+ my $call_element = pop @callstack; -+ if($call_element) { -+ $call_element->{'cost'} += $args[3]; -+ $call_element->{'cumm_cost'} += $args[3]; -+ $total_cost += $args[3]; -+ push @callstack, $call_element; -+ } -+ } -+ elsif($args[0] eq '&') { -+ # declare function -+ $function_info{$args[1]}->{'package'} = $args[2]; -+ if($args[2] ne 'main') { -+ $function_info{$args[1]}->{'name'} = $args[2]."::".$args[3]; -+ } else { -+ $function_info{$args[1]}->{'name'} = $args[3]; -+ } -+ } -+ elsif($args[0] eq '+') { -+ # push myself onto the stack -+ my $call_element = { 'specifier' => $args[1], 'cost' => 0 }; -+ push @callstack, $call_element; -+ } -+ elsif($args[0] eq '-') { -+ my $called = pop @callstack; -+ my $called_id = $called->{'specifier'}; -+ my $caller = pop @callstack; -+ if (exists $tree->{$called_id}) { -+ $tree->{$called_id}->{'cost'} += $called->{'cost'}; -+ } -+ else { -+ $tree->{$called_id} = $called; -+ } -+ if($caller) { -+ $caller->{'child_calls'}++; -+ my $caller_id = $caller->{'specifier'}; -+ if(! exists $tree->{$caller_id} ) { -+ $tree->{$caller_id} = { 'specifier' => $caller_id, 'cost' => 0 }; -+# $tree->{$caller_id} = $caller; -+ } -+ $caller->{'cumm_cost'} += $called->{'cumm_cost'}; -+ $tree->{$caller_id}->{'called_funcs'}->[$tree->{$caller_id}->{'call_counter'}++]->{$called_id} += $called->{'cumm_cost'}; -+ push @callstack, $caller; -+ } -+ } -+ elsif($args[0] eq '*') { -+ # goto &func -+ # replace last caller with self -+ my $call_element = pop @callstack; -+ $call_element->{'specifier'} = $args[1]; -+ push @callstack, $call_element; -+ } -+ else {print STDERR "Unexpected line: $_\n";} -+} -+ -+# -+# Generate output -+# -+my $output = ''; -+$output .= "events: Tick\n"; -+$output .= "summary: $total_cost\n"; -+$output .= "cmd: your script\n\n"; -+foreach my $specifier ( keys %$tree ) { -+ my $caller_package = $function_info{$specifier}->{'package'} || '???'; -+ my $caller_name = $function_info{$specifier}->{'name'} || '???'; -+ my $include = find_include($caller_package); -+ $output .= "ob=\n"; -+ $output .= sprintf "fl=%s\n", find_include($caller_package); -+ $output .= sprintf "fn=%s\n", $caller_name; -+ $output .= sprintf "1 %d\n", $tree->{$specifier}->{'cost'}; -+ if(exists $tree->{$specifier}->{'called_funcs'}) { -+ foreach my $items (@{$tree->{$specifier}->{'called_funcs'}}) { -+ while(my ($child_specifier, $costs) = each %$items) { -+ $output .= sprintf "cfn=%s\n", $function_info{$child_specifier}->{'name'}; -+ $output .= sprintf "cfi=%s\n", find_include($function_info{$child_specifier}->{'package'}); -+ $output .= "calls=1\n"; -+ $output .= sprintf "1 %d\n", $costs; -+ } -+ } -+ } -+ $output .= "\n"; -+} -+print STDERR "Writing kdecachegrind output to $outfile\n"; -+$outfd->print($output); -+ -+ -+ -+sub find_include { -+ my $module = shift; -+ $module =~ s!::!/!g; -+ for (@INC) { -+ if ( -f "$_/$module.pm" ) { -+ return "$_/$module.pm"; -+ } -+ if ( -f "$_/$module.so" ) { -+ return "$_/$module.so"; -+ } -+ } -+ return "???"; -+} -+ -+sub usage() { -+ print STDERR "dprof2calltree -f [-o outfile]\n"; -+ exit -1; -+} -+ -+ -+# vim: set sts=2 ts=2 bs ai expandtab : -diff --git a/kdecachegrind/converters/hotshot2calltree b/kdecachegrind/converters/hotshot2calltree -new file mode 100644 -index 0000000..f62a46e ---- /dev/null -+++ b/kdecachegrind/converters/hotshot2calltree -@@ -0,0 +1,394 @@ -+#!/usr/bin/env python -+# _*_ coding: latin1 _*_ -+ -+# -+# Copyright (c) 2003 by WEB.DE, Karlsruhe -+# Autor: Jörg Beyer -+# -+# hotshot2cachegrind is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public -+# License as published by the Free Software Foundation, version 2. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program; see the file COPYING. If not, write to -+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+# Boston, MA 02110-1301, USA. -+# -+# -+# This script transforms the pstat output of the hotshot -+# python profiler into the input of kdecachegrind. -+# -+# example usage: -+# modify you python script to run this code: -+# -+# import hotshot -+# filename = "pythongrind.prof" -+# prof = hotshot.Profile(filename, lineevents=1) -+# prof.runcall(run) # assuming that "run" should be called. -+# prof.close() -+# -+# it will run the "run"-method under profiling and write -+# the results in a file, called "pythongrind.prof". -+# -+# then call this script: -+# hotshot2cachegrind -o -+# or here: -+# hotshot2cachegrind cachegrind.out.0 pythongrind.prof -+# -+# then call kdecachegrind: -+# kdecachegrind cachegrind.out.0 -+# -+# TODO: -+# * es gibt Probleme mit rekursiven (direkt und indirekt) Aufrufen - dann -+# stimmen die Kosten nicht. -+# -+# * einige Funktionen werden mit "?" als Name angezeigt. Evtl sind -+# das nur die C/C++ extensions. -+# -+# * es fehlt noch ein Funktionsnamen Mangling, dass die Filenamen berücksichtigt, -+# zZ sind alle __init__'s und alle run's schwer unterscheidbar :-( -+# -+version = "$Revision$" -+progname = "hotshot2cachegrind" -+ -+import os, sys -+from hotshot import stats,log -+import os.path -+ -+file_limit=0 -+ -+what2text = { -+ log.WHAT_ADD_INFO : "ADD_INFO", -+ log.WHAT_DEFINE_FUNC : "DEFINE_FUNC", -+ log.WHAT_DEFINE_FILE : "DEFINE_FILE", -+ log.WHAT_LINENO : "LINENO", -+ log.WHAT_EXIT : "EXIT", -+ log.WHAT_ENTER : "ENTER"} -+ -+# a pseudo caller on the caller stack. This represents -+# the Python interpreter that executes the given python -+# code. -+root_caller = ("PythonInterpreter",0,"execute") -+ -+class CallStack: -+ """A tiny Stack implementation, based on python lists""" -+ def __init__(self): -+ self.stack = [] -+ self.recursion_counter = {} -+ def push(self, elem): -+ """put something on the stack""" -+ self.stack.append(elem) -+ rc = self.recursion_counter.get(elem, 0) -+ self.recursion_counter[elem] = rc + 1 -+ -+ def pop(self): -+ """get the head element of the stack and remove it from teh stack""" -+ elem = self.stack[-1:][0] -+ rc = self.recursion_counter.get(elem) - 1 -+ if rc>0: -+ self.recursion_counter[elem] = rc -+ else: -+ del self.recursion_counter[elem] -+ return self.stack.pop() -+ -+ def top(self): -+ """get the head element of the stack, stack is unchanged.""" -+ return self.stack[-1:][0] -+ def handleLineCost(self, tdelta): -+ p, c = self.stack.pop() -+ self.stack.append( (p,c + tdelta) ) -+ def size(self): -+ """ return how many elements the stack has""" -+ return len(self.stack) -+ -+ def __str__(self): -+ return "[stack: %s]" % self.stack -+ -+ def recursion(self, pos): -+ return self.recursion_counter.get(pos, 0) -+ #return self.recursion_dict.has_key((entry[0][0], entry[0][2])) -+ -+def return_from_call(caller_stack, call_dict, cost_now): -+ """return from a function call -+ remove the function from the caller stack, -+ add the costs to the calling function. -+ """ -+ called, cost_at_enter = caller_stack.pop() -+ caller, caller_cost = caller_stack.top() -+ -+ #print "return_from_call: %s ruft %s" % (caller, called,) -+ -+ per_file_dict = call_dict.get(called[0], {}) -+ per_caller_dict = per_file_dict.get(called[2], {}) -+ cost_so_far, call_counter = per_caller_dict.get(caller, (0, 0)) -+ -+ if caller_stack.recursion(called): -+ per_caller_dict[caller] = (cost_so_far, call_counter + 1) -+ else: -+ per_caller_dict[caller] = (cost_so_far + cost_now - cost_at_enter, call_counter + 1) -+ -+ per_file_dict[called[2]] = per_caller_dict -+ call_dict[called[0]] = per_file_dict -+ -+ -+def updateStatus(filecount): -+ sys.stdout.write("reading File #%d \r" % filecount) -+ sys.stdout.flush() -+def convertProfFiles(output, inputfilenames): -+ """convert all the given input files into one kdecachegrind -+ input file. -+ """ -+ call_dict = {} -+ cost_per_pos = {} -+ cost_per_function = {} -+ caller_stack = CallStack() -+ caller_stack.push((root_caller, 0)) -+ -+ total_cost = 0 -+ filecount = 1 -+ number_of_files = len(inputfilenames) -+ for inputfilename in inputfilenames: -+ updateStatus(filecount) -+ cost, filecount = convertHandleFilename(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount) -+ total_cost += cost -+ if (file_limit > 0) and (filecount > file_limit): -+ break -+ -+ print -+ print "total_cost: % d Ticks",total_cost -+ dumpResults(output, call_dict, total_cost, cost_per_pos, cost_per_function) -+ -+def convertHandleFilename(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount): -+ updateStatus(filecount) -+ if not ((file_limit > 0) and (filecount > file_limit)): -+ if os.path.isdir(inputfilename): -+ cost, filecount = convertProfDir(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount) -+ elif os.path.isfile(inputfilename): -+ cost = convertProfFile(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function) -+ filecount += 1 -+ else: -+ sys.stderr.write("warn: ignoring '%s', is no file and no directory\n" % inputfilename) -+ cost = 0 -+ return (cost, filecount) -+ -+def convertProfDir(start, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount): -+ cost = 0 -+ filenames = os.listdir(start) -+ for f in filenames: -+ if (file_limit > 0) and (filecount > file_limit): -+ break -+ full = os.path.join(start, f) -+ c, filecount = convertHandleFilename(full, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount) -+ cost += c; -+ return (cost, filecount) -+ -+def handleCostPerPos(cost_per_pos, pos, current_cost): -+ """ -+ the cost per source position are managed in a dict in a dict. -+ -+ the cost are handled per file and there per function. -+ so, the per-file-dict contains some per-function-dicts -+ which sum up the cost per line (in this function and in -+ this file). -+ """ -+ filename = pos[0] -+ lineno = pos[1] -+ funcname = pos[2] -+ file_dict = cost_per_pos.get(filename, {}) -+ func_dict = file_dict.get(funcname, {}) -+ func_dict.setdefault(lineno, 0) -+ func_dict[lineno] += current_cost -+ file_dict[funcname] = func_dict -+ cost_per_pos[filename] = file_dict -+ -+def convertProfFile(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function): -+ """convert a single input file into one kdecachegrind -+ data. -+ -+ this is the most expensive function in this python source :-) -+ """ -+ -+ total_cost = 0 -+ try: -+ logreader = log.LogReader(inputfilename) -+ current_cost = 0 -+ hc = handleCostPerPos # shortcut -+ for item in logreader: -+ what, pos ,tdelta = item -+ (file, lineno, func) = pos -+ #line = "%s %s %d %s %d" % (what2text[what], file, lineno, func, tdelta) -+ #print line -+ # most common cases first -+ if what == log.WHAT_LINENO: -+ # add the current cost to the current function -+ hc(cost_per_pos, pos, tdelta) -+ total_cost += tdelta -+ elif what == log.WHAT_ENTER: -+ caller_stack.push((pos, total_cost)) -+ hc(cost_per_pos, pos, tdelta) -+ total_cost += tdelta -+ elif what == log.WHAT_EXIT: -+ hc(cost_per_pos, pos, tdelta) -+ total_cost += tdelta -+ return_from_call(caller_stack, call_dict, total_cost) -+ else: -+ assert 0, "duh: %d" % what -+ -+ -+ # I have no idea, why sometimes the stack is not empty - we -+ # have to rewind the stack to get 100% for the root_caller -+ while caller_stack.size() > 1: -+ return_from_call(caller_stack, call_dict, total_cost) -+ -+ except IOError: -+ print "could not open inputfile '%s', ignore this." % inputfilename -+ except EOFError, m: -+ print "EOF: %s" % (m,) -+ return total_cost -+ -+def pretty_name(file, function): -+ #pfile = os.path.splitext(os.path.basename(file)) [0] -+ #return "%s_[%s]" % (function, file) -+ return "%s" % function -+ #return "%s::%s" % (file, function) -+ #return "%s_%s" % (pfile, function) -+ -+class TagWriter: -+ def __init__(self, output): -+ self.output = output -+ self.last_values = {} -+ -+ def clearTag(self, tag): -+ if self.last_values.has_key(tag): -+ del self.last_values[ tag ] -+ def clear(self): -+ self.last_values = {} -+ -+ def write(self, tag, value): -+ self.output.write("%s=%s\n" % (tag, value)) -+ #if (not self.last_values.has_key(tag)) or self.last_values[tag] != value: -+ # self.last_values[ tag ] = value -+ # self.output.write("%s=%s\n" % (tag, value)) -+ -+def dumpResults(output, call_dict, total_cost, cost_per_pos, cost_per_function): -+ """write the collected results in the format kdecachegrind -+ could read. -+ """ -+ # the intro -+ output.write("events: Tick\n") -+ output.write("summary: %d\n" % total_cost) -+ output.write("cmd: your python script\n") -+ output.write("\n") -+ tagwriter = TagWriter(output) -+ -+ # now the costs per line -+ for file in cost_per_pos.keys(): -+ func_dict = cost_per_pos[file] -+ for func in func_dict.keys(): -+ line_dict = func_dict[func] -+ tagwriter.write("ob", file) -+ tagwriter.write("fn", func)# pretty_name(file, func)) ; output.write("# ^--- 2\n") -+ tagwriter.write("fl", file) -+ for line in line_dict: -+ output.write("%d %d\n" %( line, line_dict[line] )) -+ -+ output.write("\n\n") -+ # now the function calls. For each caller all the called -+ # functions and their costs are written. -+ for file in call_dict.keys(): -+ per_file_dict = call_dict[file] -+ #print "file %s -> %s" % (file, per_file_dict) -+ for called_x in per_file_dict.keys(): -+ #print "called_x:",called_x -+ per_caller_dict = per_file_dict[called_x] -+ #print "called_x %s wird gerufen von: %s" % (called_x, per_caller_dict) -+ for caller_x in per_caller_dict.keys(): -+ tagwriter.write("ob", caller_x[0]) -+ tagwriter.write("fn", caller_x[2])# pretty_name(caller_x[2], caller_x[0])) ; output.write("# ^--- 1\n") -+ tagwriter.write("fl", caller_x[0]) -+ tagwriter.write("cob", file) -+ tagwriter.write("cfn", called_x) #pretty_name(file, called_x)) -+ tagwriter.write("cfl", file) -+ cost, count = per_caller_dict[caller_x] -+ #print "called_x:",called_x -+ output.write("calls=%d\n%d %d\n" % (count, caller_x[1], cost)) -+ tagwriter.clear() -+ #tagwriter.clearTag("cob") -+ # is it a bug in kdecachegrind, that the "cob=xxx" line has -+ # to be rewritten after a calls entry with costline ? -+ #assert cost <= total_cost, "caller_x: %s, per_caller_dict: %s " % (caller_x, per_caller_dict, ) -+ #output.write("calls=%d\n%d %d\n" % (count, caller_x[1], cost)) -+ output.write("\n") -+ -+def run_without_optparse(): -+ """parse the options without optparse, use sys.argv""" -+ if len(sys.argv) < 4 or sys.argv[1] != "-o" : -+ print "usage: hotshot2cachegrind -o outputfile in1 [in2 [in3 [...]]]" -+ return -+ outputfilename = sys.argv[2] -+ try: -+ output = file(outputfilename, "w") -+ args = sys.argv[3:] -+ convertProfFiles(output, args) -+ output.close() -+ except IOError: -+ print "could not open '%s' for writing." % outputfilename -+ -+def run_with_optparse(): -+ """parse the options with optparse""" -+ -+ global file_limit -+ -+ versiontext = "%s version: %s" % ( progname, version.split()[1], ) -+ parser = OptionParser(version=versiontext) -+ parser.add_option("-o", "--output", -+ action="store", type="string", dest="outputfilename", -+ help="write output into FILE") -+ parser.add_option("--file-limit", -+ action="store", dest="file_limit", default=0, -+ help="stop after given number of input files") -+ output = sys.stdout -+ close_output = 0 -+ (options, args) = parser.parse_args() -+ file_limit = int(options.file_limit) -+ try: -+ if options.outputfilename and options.outputfilename != "-": -+ output = file(options.outputfilename, "w") -+ close_output = 1 -+ except IOError: -+ print "could not open '%s' for writing." % options.outputfilename -+ if output: -+ convertProfFiles(output, args) -+ if close_output: -+ output.close() -+ -+ -+def profile_myself(): -+ import hotshot -+ filename = "self.prof" -+ if not os.path.exists(filename): -+ prof = hotshot.Profile(filename, lineevents=1) -+ prof.runcall(run) -+ prof.close() -+ else: -+ print "not profiling myself, since '%s' exists, running normal" % filename -+ run() -+ -+# check if optparse is available. -+try: -+ from optparse import OptionParser -+ run = run_with_optparse -+except ImportError: -+ run = run_without_optparse -+ -+if __name__ == "__main__": -+ try: -+ run() -+ #profile_myself() -+ except KeyboardInterrupt: -+ sys.exit(1) -diff --git a/kdecachegrind/converters/memprof2calltree b/kdecachegrind/converters/memprof2calltree -new file mode 100755 -index 0000000..e82d6e8 ---- /dev/null -+++ b/kdecachegrind/converters/memprof2calltree -@@ -0,0 +1,38 @@ -+#!/usr/bin/perl -+# -+# Convert the memory profiles of memprof to calltree format, -+# loadable with KCachegrind -+# -+# (C) 2004, Josef Weidendorfer -+ -+print "events: Allocated\n"; -+ -+while(<>) { -+ if (/^(\S.*)$/) { -+ $next = 0; -+ print "\nfn=$1\n"; -+ next; -+ } -+ if (/^ children:/) { -+ $next = 1; #children -+ next; -+ } -+ if (/^ inherited:/) { -+ $next = 2; #inherited -+ next; -+ } -+ if (/^ total:/) { -+ # ignore, is calculated -+ next; -+ } -+ if (/^ self:\s*(\d+)/) { -+ if ($1 ne "0") { -+ print "0 $1\n"; -+ } -+ next; -+ } -+ if (/^\s+(\S.*?):\s*(\d+)$/) { -+ if ($next < 2) { next; } -+ print "cfn=$1\ncalls=0 0\n0 $2\n"; -+ } -+} -diff --git a/kdecachegrind/converters/op2calltree b/kdecachegrind/converters/op2calltree -new file mode 100755 -index 0000000..ca121a2 ---- /dev/null -+++ b/kdecachegrind/converters/op2calltree -@@ -0,0 +1,238 @@ -+#!/usr/bin/perl -+# -+# Copyright (c) 2004 -+# Author: Josef Weidendorfer -+# -+# op2calltree is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public -+# License as published by the Free Software Foundation, version 2. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program; see the file COPYING. If not, write to -+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+# Boston, MA 02110-1301, USA. -+# -+# -+# Converter from OProfile's output of "opreport -gdf" (v 0.8) -+# into callgrind format. -+# -+# Generate a OProfile report with opreport and flags -gdf -+# and pipe this as standard input into this script. -+# This will generate separate cachegrind files for every application. -+# -+ -+ -+# parse symbol line. example (with 1 event type, $has_image==0): -+# 308 0.1491 /path/source.c:6 /path/app main -+sub parseSymSpec { -+ $e = 0; -+ while($e < $eventCount) { -+ ($line) = ($line =~ /\d+\s+\S+\s+(.*)/); -+ $e++; -+ } -+ if ($line =~ s/^\(no location information\)\s+//) { -+ $file = "???"; -+ $linenr = 0; -+ } -+ else { -+ ($file,$linenr) = ($line =~ s/(\S+?):(\d+)\s+//); -+ } -+ if ($has_image) { -+ if ($line =~ s/^(\S+)\s+//) { $img = $1; } -+ } -+ if ($has_app) { -+ if ($line =~ s/^(\S+)\s+//) { $app = $1; } -+ if (!$has_image) { $img = $app; } -+ } -+ $sym = $line; -+ -+ $app =~ s/^.*\///; -+ if ($sym eq "(no symbols)") { $sym = "???"; } -+ $file{$sym} = $file; -+ $linenr{$sym} = $linenr; -+ $app{$sym} = $app; -+ $img{$app,$sym} = $img; -+ $syms{$app}++; -+ -+ if ($app ne $oldApp) { -+ $oldApp = $app; -+ print "\n\nApp $app\n"; -+ } -+ print " Symbol $sym (Image $img)\n"; -+} -+ -+ -+ -+$eventCount = 0; -+$descCount = 0; -+$lnr = 0; -+$has_image = 0; -+$has_app = 0; -+$app = "unnamed"; -+$img = "???"; -+ -+# first loop till first symbol specification -+while(<>) { -+ $lnr++; -+ chomp; -+ if (/^CPU:/) { -+ $desc[$descCount++] = $_; -+ next; -+ } -+ if (/^Counted\s*(\S+)/) { -+ $desc[$descCount++] = $_; -+ $eventCount++; -+ $events[$eventCount] = $1; -+ next; -+ } -+ if (/^(Profiling through timer.*)/) { -+ $desc[$descCount++] = $_; -+ $eventCount++; -+ $events[$eventCount] = "Timer"; -+ next; -+ } -+ if (/^vma/) { -+ # title row: adapt to separation options of OProfile -+ if (/image/) { $has_image = 1; } -+ if (/app/) { $has_app = 1; } -+ next; -+ } -+ if (/^([0-9a-fA-F]+)\s*(.*)$/) { -+ $vmaSym = $1; -+ $line = $2; -+ last; -+ } -+} -+ -+if ($eventCount == 0) { -+ die "No Events found"; -+} -+ -+print "Description:\n"; -+foreach $d (@desc) { print " $d\n"; } -+print "\n"; -+ -+print "Events:"; -+foreach $e (@events) { print " $e"; } -+print "\n"; -+ -+parseSymSpec; -+ -+while(<>) { -+ $lnr++; -+ if (/^([0-9a-fA-F]+)\s*(.*)$/) { -+ $vmaSym = $1; -+ $line = $2; -+ -+ parseSymSpec; -+ next; -+ } -+ if (/^\s+([0-9a-fA-F]+)\s*(.*)$/) { -+ -+ $sampleCount{$app,$sym}++; -+ $sc = $sampleCount{$app,$sym}; -+ -+ $vma{$app,$sym,$sc} = $1; -+ $line = $2; -+ -+ $e = 1; -+ while($e <= $eventCount) { -+ ($cost, $line) = ($line =~ /(\d+)\s+\S+\s+(.*)/); -+ $summary{$app,$e} += $cost; -+ $cost{"$app,$sym,$sc,$e"} = $cost; -+ $e++; -+ } -+ if ($line =~ /\(no location information\)/) { -+ $file = "???"; -+ $linenr = 0; -+ } -+ else { -+ ($file,$linenr) = ($line =~ /(\S+?):(\d+)/); -+ } -+ $sFile{$app,$sym,$sc} = $file; -+ $linenr{$app,$sym,$sc} = $linenr; -+ -+ $file =~ s/^.*\///; -+ print " Sample $sc: $vma{$app,$sym,$sc} ($file:$linenr):"; -+ foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; print " $c"; } -+ print "\n"; -+ next; -+ } -+ die "ERROR: Reading line $lnr '$_'\n"; -+} -+ -+foreach $app (keys %syms) { -+ if ($app eq "") { next; } -+ print "Generating dump for App '$app'...\n"; -+ -+ $out = "# Generated by op2cg, using OProfile with opreport -gdf\n"; -+ $out .= "positions: instr line\n"; -+ -+ $out .= "events:"; -+ foreach $e (@events) { $out .= " $e"; } -+ $out .= "\n"; -+ -+ $out .= "summary:"; -+ foreach $e (1 .. $eventCount) { $out .= " $summary{$app,$e}"; } -+ $out .= "\n\n"; -+ -+ %fileNum = (); -+ $fileNum = 1; -+ $sf = ""; -+ -+ $img = ""; -+ -+ foreach $sym (keys %file) { -+ if ($sampleCount{$app,$sym} eq "") { next; } -+ -+ if ($img{$app,$sym} ne $img) { -+ $img = $img{$app,$sym}; -+ $out .= "ob=$img\n"; -+ } -+ -+ $file = $file{$sym}; -+ if ($sf ne $file) { -+ if ($fileNum{$file} eq "") { -+ $fileNum{$file} = $fileNum; -+ $out .= "fl=($fileNum) $file\n"; -+ $fileNum++; -+ } -+ else { -+ $out .= "fl=($fileNum{$file})\n"; -+ } -+ $sf = $file; -+ } -+ -+ $out .= "fn=$sym\n"; -+ foreach $sc (1 .. $sampleCount{$app,$sym}) { -+ if ($sf ne $sFile{$app,$sym,$sc}) { -+ $sf = $sFile{$app,$sym,$sc}; -+ if ($sf eq $file) { -+ $out .= "fe=($fileNum{$file})\n"; -+ } -+ else { -+ if ($fileNum{$sf} eq "") { -+ $fileNum{$sf} = $fileNum; -+ $out .= "fi=($fileNum) $sf\n"; -+ $fileNum++; -+ } -+ else { -+ $out .= "fi=($fileNum{$sf})\n"; -+ } -+ } -+ } -+ $out .= "0x$vma{$app,$sym,$sc} $linenr{$app,$sym,$sc}"; -+ foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; $out .= " $c"; } -+ $out .= "\n"; -+ } -+ } -+ -+ open OUT, ">oprof.out.$app"; -+ print OUT $out; -+ close OUT; -+} -diff --git a/kdecachegrind/converters/pprof2calltree b/kdecachegrind/converters/pprof2calltree -new file mode 100644 -index 0000000..0e70e1c ---- /dev/null -+++ b/kdecachegrind/converters/pprof2calltree -@@ -0,0 +1,218 @@ -+#!/usr/bin/env php -+# Redistribution and use in source and binary forms, with or without -+# modification, are permitted provided that the following conditions are met: -+# -+# - Redistributions of source code must retain the above copyright notice, -+# this list of conditions and the following disclaimer. -+# -+# - Redistributions in binary form must reproduce the above copyright -+# notice, this list of conditions and the following disclaimer in the -+# documentation and/or other materials provided with the distribution. -+# -+# - All advertising materials mentioning features or use of this software -+# must display the following acknowledgement: This product includes software -+# developed by OmniTI Computer Consulting. -+# -+# - Neither name of the company nor the names of its contributors may be -+# used to endorse or promote products derived from this software without -+# specific prior written permission. -+# -+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND ANY -+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+# -+# Copyright (c) 2004 OmniTI Computer Consulting -+# All rights reserved -+# The following code was written by George Schlossnagle -+# and is provided completely free and without any warranty. -+# -+# This script is designed to convert the pprof output from -+# APD (http://pecl.php.net/apd/) to one readable by kdecachegrind. To use -+# this script: -+# -+# 1) Install APD. -+# 2) Profile your script with APD accordingto the directions in it's -+# README file. -+# 3) Take the pprof trace file for your script (pprof.XXXXX.Y) and run it -+# through this script as follows: -+# > pprof2calltree -f pprof.12345.1 -+# This creates a new file cachegrind.out.12345.1 -+# 4) View your trace with pprof2calltree cachegrind.out.12345.1 -+ -+readPHPArgv(); -+array_shift($args); -+$shortoptions = 'f:'; -+$retval = $con->getopt( $args, $shortoptions); -+if(is_object($retval)) { -+ usage(); -+} -+foreach ($retval[0] as $kv_array) { -+ $opt[$kv_array[0]] = $kv_array[1]; -+} -+if(!$opt['f']) { -+ usage(); -+} -+if(!file_exists($opt['f'])) { -+ print "Trace file ${opt['f']} does not exist\n"; -+ exit; -+} -+$IN = fopen($opt['f'], "r"); -+if(!$IN) { -+ print "Trace file ${opt['f']} could not be opened\n"; -+ exit; -+} -+ -+$path_parts = pathinfo($opt['f']); -+$outfile = "cachegrind.out.".$path_parts['basename']; -+$OUT = fopen($outfile, "w"); -+if(!$OUT) { -+ print "Destination file $outfile could not be opened.\n"; -+ exit; -+} -+ -+while(($line = fgets($IN)) !== false) { -+ $line = rtrim($line); -+ if($line == "END_HEADER") { -+ break; -+ } -+} -+$tree = array(); -+$callstack = array(); -+while(($line = fgets($IN)) !== false) { -+ $line = rtrim($line); -+ $args = explode(" ", $line); -+ if($args[0] == '!') { -+ $file_lookup[$args[1]] = $args[2]; -+ } -+ else if($args[0] == '&') { -+ $function_lookup[$args[1]] = $args[2]; -+ $function_type[$args[1]] = ($args[3] == 2)?"USER":"INTERNAL"; -+ } -+ else if($args[0] == '+') { -+ $val = array(function_id => $args[1], -+ file_id => $args[2], -+ line => $args[3], -+ cost => 0); -+ array_push($callstack, $val); -+ } -+ else if($args[0] == '-') { -+ // retrieve $called to discard -+ $called = array_pop($callstack); -+ // retrieve $caller for reference -+ $caller = array_pop($callstack); -+ $called_id = $called['function_id']; -+ -+ // Set meta data if not already set' -+ if(!array_key_exists($called_id, $tree)) { -+ $tree[$called_id] = $called; -+ // initialize these to 0 -+ $tree[$called_id]['cost_per_line'] = array(); -+ } -+ if($caller !== null) { -+ $caller['child_calls']++; -+ $caller_id = $caller['function_id']; -+ if(!array_key_exists($caller_id, $tree)) { -+ $tree[$caller_id] = $caller; -+ } -+ $caller['cost'] += $called['cost']; -+ $tree[$caller_id]['called_funcs'][$tree[$caller_id]['call_counter']++][$called_id][$called['file_id']][$called['line']] += $called['cost']; -+ array_push($callstack, $caller); -+ } -+ if(is_array($called['cost_per_line'])) { -+ foreach($called[cost_per_line] as $file => $lines) { -+ foreach($lines as $line => $cost) { -+ $tree[$called_id]['cost_per_line'][$file][$line] += $cost; -+ } -+ } -+ } -+ } -+ else if($args[0] == '@') { -+ $called = array_pop($callstack); -+ switch(count($args)) { -+ // support new and old-style pprof data -+ case 6: -+ $file = $args[1]; -+ $line = $args[2]; -+ $real_tm = $args[5]; -+ break; -+ case 4: -+ $file = $called['file_id']; -+ $line = $called['line']; -+ $real_tm = $args[3]; -+ break; -+ -+ } -+ $called['cost_per_line'][$file][$line] += $real_tm; -+ $called['cost'] += $real_tm; -+ $total_cost += $real_tm; -+ array_push($callstack, $called); -+ } -+} -+ -+ob_start(); -+print "events: Tick\n"; -+print "summary: $total_cost\n"; -+printf("cmd: %s\n", $file_lookup[1]); -+print "\n"; -+ -+foreach($tree as $caller => $data) { -+ $filename = $file_lookup[$data['file_id']]?$file_lookup[$data['file_id']]:"???"; -+ printf("ob=%s\n", $function_type[$caller]); -+ printf("fl=%s\n", $filename); -+ printf("fn=%s\n", $function_lookup[$caller]); -+ if(is_array($data['cost_per_line'])) { -+ foreach($data['cost_per_line'] as $file => $lines) { -+ foreach($lines as $line => $cost) { -+ print "$line $cost\n"; -+ } -+ } -+ } -+ else if ($data['cost']) { -+ printf("COST %s %s\n", $items['line'], $items['cost']); -+ } -+ else { -+ print_r($items); -+ } -+ if(is_array($data['called_funcs'])) { -+ foreach($data['called_funcs'] as $counter => $items) { -+ foreach($items as $called_id => $costs) { -+ if(is_array($costs)) { -+ printf("cfn=%s\n", $function_lookup[$called_id]); -+ foreach($costs as $file => $lines) { -+ printf("cfi=%s\ncalls=1\n", $file_lookup[$file]); -+ foreach($lines as $line => $cost) { -+ print "$line $cost\n"; -+ } -+ } -+ } -+ } -+ } -+ } -+ print "\n"; -+} -+print "\ntotals=$total_cost\n"; -+$buffer = ob_get_clean(); -+print "Writing kdecachegrind compatible output to $outfile\n"; -+fwrite($OUT, $buffer); -+ -+function usage() -+{ -+ print << -+ -+EOD; -+ exit(1); -+} -+?> -diff --git a/kdecachegrind/pics/Makefile.am b/kdecachegrind/pics/Makefile.am -new file mode 100644 -index 0000000..f4a3186 ---- /dev/null -+++ b/kdecachegrind/pics/Makefile.am -@@ -0,0 +1,3 @@ -+kdecachegrindicondir = $(kde_datadir)/kdecachegrind/icons -+kdecachegrindicon_ICON = AUTO -+SUBDIRS = hicolor -diff --git a/kdecachegrind/pics/hicolor/Makefile.am b/kdecachegrind/pics/hicolor/Makefile.am -new file mode 100644 -index 0000000..068e319 ---- /dev/null -+++ b/kdecachegrind/pics/hicolor/Makefile.am -@@ -0,0 +1,2 @@ -+kdecachegrindicondir = $(kde_datadir)/kdecachegrind/icons -+kdecachegrindicon_ICON = AUTO -diff --git a/kdecachegrind/pics/hicolor/hi16-action-fromrec.png b/kdecachegrind/pics/hicolor/hi16-action-fromrec.png -new file mode 100644 -index 0000000..a5cb430 -Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-fromrec.png differ -diff --git a/kdecachegrind/pics/hicolor/hi16-action-percent.png b/kdecachegrind/pics/hicolor/hi16-action-percent.png -new file mode 100644 -index 0000000..7a4ba47 -Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-percent.png differ -diff --git a/kdecachegrind/pics/hicolor/hi16-action-recrec.png b/kdecachegrind/pics/hicolor/hi16-action-recrec.png -new file mode 100644 -index 0000000..ec11bfa -Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-recrec.png differ -diff --git a/kdecachegrind/pics/hicolor/hi16-action-torec.png b/kdecachegrind/pics/hicolor/hi16-action-torec.png -new file mode 100644 -index 0000000..c092c01 -Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-torec.png differ -diff --git a/kdecachegrind/pics/hicolor/hi22-action-percent.png b/kdecachegrind/pics/hicolor/hi22-action-percent.png -new file mode 100644 -index 0000000..c64a378 -Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi22-action-percent.png differ -diff --git a/kdecachegrind/pics/hicolor/hi32-action-percent.png b/kdecachegrind/pics/hicolor/hi32-action-percent.png -new file mode 100644 -index 0000000..e876c30 -Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi32-action-percent.png differ -diff --git a/kdecachegrind/kdecachegrind.lsm.in b/kdecachegrind/kdecachegrind.lsm.in -new file mode 100644 -index 0000000..fab7ced ---- /dev/null -+++ b/kdecachegrind/kdecachegrind.lsm.in -@@ -0,0 +1,11 @@ -+Begin3 -+Title: kdecachegrind -+Version: @KCACHEGRIND_VERSION@ -+Description: KDE Profiling Visualisation Tool -+Keywords: Profiling, Performance Analysis, Visualisation, Development -+Author: Josef Weidendorfer -+Maintained-by: Josef Weidendorfer -+Home-page: http://kcachegrind.sourceforge.net -+Platforms: Linux and other Unices -+Copying-policy: GNU Public License -+End -diff --git a/kdecachegrind/kdecachegrind.spec.in b/kdecachegrind/kdecachegrind.spec.in -new file mode 100644 -index 0000000..42b3e24 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind.spec.in -@@ -0,0 +1,55 @@ -+Summary: KDE Profiling Visualisation Tool -+Name: kdecachegrind -+Version: @KCACHEGRIND_VERSION@ -+Release: 1 -+Copyright: GPL -+Group: Development/Tools -+Vendor: (none) -+URL: http://kcachegrind.sourceforge.net -+Packager: Josef Weidendorfer -+Source: kdecachegrind-@KCACHEGRIND_VERSION@.tar.gz -+BuildRoot: /var/tmp/build -+ -+%description -+KCachegrind is a GPL'd tool for quick browsing in and visualisation -+of performance data of an application run. This data is produced by -+profiling tools and typically includes distribution of cost events -+to source code ranges (instructions, source lines, functions, C++ classes) -+and call relationship of functions. -+KCachegrind has a list of functions sorted according to different cost -+types, and can provide various performance views for a function like -+direct/indirect callers/callees, TreeMap visualisation of cost distribution -+among callees, call graph sectors centered around the function and -+annotated source/assembler. -+Currently, KCachegrind depends on data delivered by the profiling tool -+calltree, powered by the Valgrind runtime instrumentation framework. -+ -+%prep -+%setup -+CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure \ -+ \ -+ $LOCALFLAGS -+%build -+# Setup for parallel builds -+numprocs=`egrep -c ^cpu[0-9]+ /proc/stat || :` -+if [ "$numprocs" = "0" ]; then -+ numprocs=1 -+fi -+ -+make -j$numprocs -+ -+%install -+make install-strip DESTDIR=$RPM_BUILD_ROOT -+ -+cd $RPM_BUILD_ROOT -+find . -type d | sed '1,2d;s,^\.,\%attr(-\,root\,root) \%dir ,' > $RPM_BUILD_DIR/file.list.kdecachegrind -+find . -type f | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.kdecachegrind -+find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.kdecachegrind -+ -+%clean -+rm -rf $RPM_BUILD_ROOT/* -+rm -rf $RPM_BUILD_DIR/kdecachegrind -+rm -rf ../file.list.kdecachegrind -+ -+ -+%files -f ../file.list.kdecachegrind -diff --git a/kdecachegrind/kdecachegrind/Doxyfile b/kdecachegrind/kdecachegrind/Doxyfile -new file mode 100644 -index 0000000..9d5d050 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/Doxyfile -@@ -0,0 +1,157 @@ -+# Doxygen configuration generated by Doxywizard version 0.1 -+#--------------------------------------------------------------------------- -+# General configuration options -+#--------------------------------------------------------------------------- -+PROJECT_NAME = kdecachegrind -+PROJECT_NUMBER = -+OUTPUT_DIRECTORY = -+OUTPUT_LANGUAGE = English -+EXTRACT_ALL = YES -+EXTRACT_PRIVATE = YES -+EXTRACT_STATIC = YES -+HIDE_UNDOC_MEMBERS = -+HIDE_UNDOC_CLASSES = -+BRIEF_MEMBER_DESC = -+REPEAT_BRIEF = -+ALWAYS_DETAILED_SEC = -+FULL_PATH_NAMES = -+STRIP_FROM_PATH = -+INTERNAL_DOCS = -+CLASS_DIAGRAMS = -+SOURCE_BROWSER = -+INLINE_SOURCES = -+STRIP_CODE_COMMENTS = -+CASE_SENSE_NAMES = -+SHORT_NAMES = -+HIDE_SCOPE_NAMES = -+VERBATIM_HEADERS = -+SHOW_INCLUDE_FILES = -+JAVADOC_AUTOBRIEF = -+INHERIT_DOCS = -+INLINE_INFO = -+SORT_MEMBER_DOCS = -+DISTRIBUTE_GROUP_DOC = -+TAB_SIZE = -+ENABLED_SECTIONS = -+GENERATE_TODOLIST = -+GENERATE_TESTLIST = -+GENERATE_BUGLIST = -+ALIASES = -+MAX_INITIALIZER_LINES = -+OPTIMIZE_OUTPUT_FOR_C = -+SHOW_USED_FILES = -+#--------------------------------------------------------------------------- -+# configuration options related to warning and progress messages -+#--------------------------------------------------------------------------- -+QUIET = -+WARNINGS = -+WARN_IF_UNDOCUMENTED = -+WARN_FORMAT = "$file:$line: $text" -+WARN_LOGFILE = -+#--------------------------------------------------------------------------- -+# configuration options related to the input files -+#--------------------------------------------------------------------------- -+INPUT = . -+FILE_PATTERNS = *.cpp \ -+ *.h -+RECURSIVE = no -+EXCLUDE = -+EXCLUDE_PATTERNS = -+EXAMPLE_PATH = -+EXAMPLE_PATTERNS = -+IMAGE_PATH = -+INPUT_FILTER = -+FILTER_SOURCE_FILES = -+#--------------------------------------------------------------------------- -+# configuration options related to the alphabetical class index -+#--------------------------------------------------------------------------- -+ALPHABETICAL_INDEX = -+COLS_IN_ALPHA_INDEX = -+IGNORE_PREFIX = -+#--------------------------------------------------------------------------- -+# configuration options related to the HTML output -+#--------------------------------------------------------------------------- -+GENERATE_HTML = -+HTML_OUTPUT = html -+HTML_HEADER = -+HTML_FOOTER = -+HTML_STYLESHEET = -+HTML_ALIGN_MEMBERS = -+GENERATE_HTMLHELP = -+GENERATE_CHI = -+BINARY_TOC = -+TOC_EXPAND = -+DISABLE_INDEX = -+ENUM_VALUES_PER_LINE = -+GENERATE_TREEVIEW = -+TREEVIEW_WIDTH = -+#--------------------------------------------------------------------------- -+# configuration options related to the LaTeX output -+#--------------------------------------------------------------------------- -+GENERATE_LATEX = NO -+LATEX_OUTPUT = latex -+COMPACT_LATEX = -+PAPER_TYPE = a4wide -+EXTRA_PACKAGES = -+LATEX_HEADER = -+PDF_HYPERLINKS = -+USE_PDFLATEX = -+LATEX_BATCHMODE = -+#--------------------------------------------------------------------------- -+# configuration options related to the RTF output -+#--------------------------------------------------------------------------- -+GENERATE_RTF = NO -+RTF_OUTPUT = rtf -+COMPACT_RTF = -+RTF_HYPERLINKS = -+RTF_STYLESHEET_FILE = -+RTF_EXTENSIONS_FILE = -+#--------------------------------------------------------------------------- -+# configuration options related to the man page output -+#--------------------------------------------------------------------------- -+GENERATE_MAN = NO -+MAN_OUTPUT = man -+MAN_EXTENSION = .3 -+MAN_LINKS = -+#--------------------------------------------------------------------------- -+# Configuration options related to the preprocessor -+#--------------------------------------------------------------------------- -+ENABLE_PREPROCESSING = -+MACRO_EXPANSION = -+EXPAND_ONLY_PREDEF = -+SEARCH_INCLUDES = -+INCLUDE_PATH = -+INCLUDE_FILE_PATTERNS = -+PREDEFINED = -+EXPAND_AS_DEFINED = -+#--------------------------------------------------------------------------- -+# Configuration::addtions related to external references -+#--------------------------------------------------------------------------- -+TAGFILES = -+GENERATE_TAGFILE = -+ALLEXTERNALS = -+PERL_PATH = /usr/bin/perl -+#--------------------------------------------------------------------------- -+# Configuration options related to the dot tool -+#--------------------------------------------------------------------------- -+HAVE_DOT = -+CLASS_GRAPH = -+COLLABORATION_GRAPH = -+INCLUDE_GRAPH = -+INCLUDED_BY_GRAPH = -+GRAPHICAL_HIERARCHY = -+DOT_PATH = -+MAX_DOT_GRAPH_WIDTH = -+MAX_DOT_GRAPH_HEIGHT = -+GENERATE_LEGEND = -+DOT_CLEANUP = -+#--------------------------------------------------------------------------- -+# Configuration::addtions related to the search engine -+#--------------------------------------------------------------------------- -+SEARCHENGINE = -+CGI_NAME = search.cgi -+CGI_URL = -+DOC_URL = -+DOC_ABSPATH = -+BIN_ABSPATH = /usr/local/bin/ -+EXT_DOC_PATHS = -diff --git a/kdecachegrind/kdecachegrind/Makefile.am b/kdecachegrind/kdecachegrind/Makefile.am -new file mode 100644 -index 0000000..53cd35d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/Makefile.am -@@ -0,0 +1,62 @@ -+bin_PROGRAMS = kdecachegrind -+ -+kdecachegrind_SOURCES = \ -+ functionselectionbase.ui \ -+ stackselectionbase.ui \ -+ partselectionbase.ui \ -+ configdlgbase.ui \ -+ loader.cpp cachegrindloader.cpp treemap.cpp pool.cpp \ -+ main.cpp configuration.cpp \ -+ functionselection.cpp coverage.cpp partgraph.cpp \ -+ toplevel.cpp stackselection.cpp stackbrowser.cpp \ -+ subcost.cpp tracedata.cpp partselection.cpp configdlg.cpp \ -+ utils.cpp fixcost.cpp \ -+ traceitemview.cpp instrview.cpp tabview.cpp \ -+ sourceview.cpp callmapview.cpp callview.cpp \ -+ coverageview.cpp costtypeview.cpp partview.cpp \ -+ listutils.cpp costtypeitem.cpp multiview.cpp \ -+ callitem.cpp coverageitem.cpp sourceitem.cpp \ -+ costlistitem.cpp partlistitem.cpp functionitem.cpp \ -+ instritem.cpp stackitem.cpp callgraphview.cpp -+ -+kdecachegrind_COMPILE_FIRST = ../version.h -+ -+kdecachegrind_LDADD = $(LIB_KIO) -+ -+KDE_ICON = AUTO -+ -+xdg_apps_DATA = kdecachegrind.desktop -+ -+mimeapplicationdir = $(kde_mimedir)/application -+mimeapplication_DATA = x-kcachegrind.desktop -+ -+EXTRA_DIST = \ -+ kdecachegrind.desktop \ -+ x-kcachegrind.desktop \ -+ hi32-app-kcachegrind.png \ -+ hi48-app-kcachegrind.png \ -+ Doxyfile \ -+ kdecachegrindui.rc -+ -+# set the include path for X, qt and KDE -+INCLUDES= $(all_includes) -+ -+METASOURCES = AUTO -+ -+# the library search path. -+kdecachegrind_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_KDECORE) $(LIB_KDEUI) -lkdefx $(LIB_KIO) -lktexteditor -+ -+rcdir = $(kde_datadir)/kdecachegrind -+rc_DATA = kdecachegrindui.rc -+ -+tipdir = $(kde_datadir)/kdecachegrind -+tip_DATA = tips -+ -+messages: rc.cpp -+ $(PREPARETIPS) > tips.txt -+ LIST=`find . -name \*.h -o -name \*.cpp -o -name \*.txt`; \ -+ if test -n "$$LIST"; then \ -+ $(XGETTEXT) $$LIST -o $(podir)/kdecachegrind.pot; \ -+ fi -+ rm -f tips.txt -+ -diff --git a/kdecachegrind/kdecachegrind/cachegrindloader.cpp b/kdecachegrind/kdecachegrind/cachegrindloader.cpp -new file mode 100644 -index 0000000..4fe57d3 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/cachegrindloader.cpp -@@ -0,0 +1,1323 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "loader.h" -+#include "tracedata.h" -+#include "utils.h" -+#include "fixcost.h" -+ -+ -+#define TRACE_LOADER 0 -+ -+/* -+ * Loader for Callgrind Profile data (format based on Cachegrind format). -+ * See Callgrind documentation for the file format. -+ */ -+ -+class CachegrindLoader: public Loader -+{ -+public: -+ CachegrindLoader(); -+ -+ bool canLoadTrace(TQFile* file); -+ bool loadTrace(TracePart*); -+ bool isPartOfTrace(TQString file, TraceData*); -+ -+private: -+ bool loadTraceInternal(TracePart*); -+ -+ enum lineType { SelfCost, CallCost, BoringJump, CondJump }; -+ -+ bool parsePosition(FixString& s, PositionSpec& newPos); -+ -+ // position setters -+ void clearPosition(); -+ void ensureObject(); -+ void ensureFile(); -+ void ensureFunction(); -+ void setObject(const TQString&); -+ void setCalledObject(const TQString&); -+ void setFile(const TQString&); -+ void setCalledFile(const TQString&); -+ void setFunction(const TQString&); -+ void setCalledFunction(const TQString&); -+ -+ TQString _emptyString; -+ -+ // current line in file to read in -+ TQString _filename; -+ int _lineNo; -+ -+ TraceSubMapping* subMapping; -+ TraceData* _data; -+ TracePart* _part; -+ -+ // current position -+ lineType nextLineType; -+ bool hasLineInfo, hasAddrInfo; -+ PositionSpec currentPos; -+ -+ // current function/line -+ TraceObject* currentObject; -+ TracePartObject* currentPartObject; -+ TraceFile* currentFile; -+ TracePartFile* currentPartFile; -+ TraceFunction* currentFunction; -+ TracePartFunction* currentPartFunction; -+ TraceFunctionSource* currentFunctionSource; -+ TraceInstr* currentInstr; -+ TracePartInstr* currentPartInstr; -+ TraceLine* currentLine; -+ TracePartLine* currentPartLine; -+ -+ // current call -+ TraceObject* currentCalledObject; -+ TracePartObject* currentCalledPartObject; -+ TraceFile* currentCalledFile; -+ TracePartFile* currentCalledPartFile; -+ TraceFunction* currentCalledFunction; -+ TracePartFunction* currentCalledPartFunction; -+ SubCost currentCallCount; -+ -+ // current jump -+ TraceFile* currentJumpToFile; -+ TraceFunction* currentJumpToFunction; -+ PositionSpec targetPos; -+ SubCost jumpsFollowed, jumpsExecuted; -+ -+ /** Support for compressed string format -+ * This uses the following string compression model -+ * for objects, files, functions: -+ * If the name matches -+ * "() Name": this is a compression specification, -+ * mapping the integer number to Name and using Name. -+ * "()" : this is a compression reference. -+ * Assumes previous compression specification of the -+ * integer number to a name, uses this name. -+ * "Name" : Regular name -+ */ -+ void clearCompression(); -+ const TQString& checkUnknown(const TQString& n); -+ TraceObject* compressedObject(const TQString& name); -+ TraceFile* compressedFile(const TQString& name); -+ TraceFunction* compressedFunction(const TQString& name, -+ TraceFile*, TraceObject*); -+ -+ TQPtrVector _objectVector, _fileVector, _functionVector; -+}; -+ -+ -+ -+/********************************************************** -+ * Loader -+ */ -+ -+ -+CachegrindLoader::CachegrindLoader() -+ : Loader("Callgrind", -+ i18n( "Import filter for Cachegrind/Callgrind generated profile data files") ) -+{ -+ _emptyString = TQString(""); -+} -+ -+bool CachegrindLoader::canLoadTrace(TQFile* file) -+{ -+ if (!file) return false; -+ -+ if (!file->isOpen()) { -+ if (!file->open( IO_ReadOnly ) ) { -+ kdDebug() << TQFile::encodeName(_filename).data() << ": " -+ << strerror( errno ) << endl; -+ return false; -+ } -+ } -+ -+ /* -+ * We recognize this as cachegrind/callgrind format if in the first -+ * 2047 bytes we see the string "\nevents:" -+ */ -+ char buf[2048]; -+ int read = file->readBlock(buf,2047); -+ if (read < 0) -+ return false; -+ buf[read] = 0; -+ -+ TQCString s; -+ s.setRawData(buf, read+1); -+ int pos = s.find("events:"); -+ if (pos>0 && buf[pos-1] != '\n') pos = -1; -+ s.resetRawData(buf, read+1); -+ return (pos>=0); -+} -+ -+bool CachegrindLoader::loadTrace(TracePart* p) -+{ -+ /* do the loading in a new object so parallel load -+ * operations do not interfere each other. -+ */ -+ CachegrindLoader l; -+ -+ /* emit progress signals via the singleton loader */ -+ connect(&l, TQT_SIGNAL(updateStatus(TQString, int)), -+ this, TQT_SIGNAL(updateStatus(TQString, int))); -+ -+ return l.loadTraceInternal(p); -+} -+ -+Loader* createCachegrindLoader() -+{ -+ return new CachegrindLoader(); -+} -+ -+ -+ -+/** -+ * Return false if this is no position specification -+ */ -+bool CachegrindLoader::parsePosition(FixString& line, -+ PositionSpec& newPos) -+{ -+ char c; -+ uint diff; -+ -+ if (hasAddrInfo) { -+ -+ if (!line.first(c)) return false; -+ -+ if (c == '*') { -+ // nothing changed -+ line.stripFirst(c); -+ newPos.fromAddr = currentPos.fromAddr; -+ newPos.toAddr = currentPos.toAddr; -+ } -+ else if (c == '+') { -+ line.stripFirst(c); -+ line.stripUInt(diff, false); -+ newPos.fromAddr = currentPos.fromAddr + diff; -+ newPos.toAddr = newPos.fromAddr; -+ } -+ else if (c == '-') { -+ line.stripFirst(c); -+ line.stripUInt(diff, false); -+ newPos.fromAddr = currentPos.fromAddr - diff; -+ newPos.toAddr = newPos.fromAddr; -+ } -+ else if (c >= '0') { -+ uint64 v; -+ line.stripUInt64(v, false); -+ newPos.fromAddr = Addr(v); -+ newPos.toAddr = newPos.fromAddr; -+ } -+ else return false; -+ -+ // Range specification -+ if (line.first(c)) { -+ if (c == '+') { -+ line.stripFirst(c); -+ line.stripUInt(diff); -+ newPos.toAddr = newPos.fromAddr + diff; -+ } -+ else if ((c == '-') || (c == ':')) { -+ line.stripFirst(c); -+ uint64 v; -+ line.stripUInt64(v); -+ newPos.toAddr = Addr(v); -+ } -+ } -+ line.stripSpaces(); -+ -+#if TRACE_LOADER -+ if (newPos.fromAddr == newPos.toAddr) -+ kdDebug() << " Got Addr " << newPos.fromAddr.toString() << endl; -+ else -+ kdDebug() << " Got AddrRange " << newPos.fromAddr.toString() -+ << ":" << newPos.toAddr.toString() << endl; -+#endif -+ -+ } -+ -+ if (hasLineInfo) { -+ -+ if (!line.first(c)) return false; -+ -+ if (c > '9') return false; -+ else if (c == '*') { -+ // nothing changed -+ line.stripFirst(c); -+ newPos.fromLine = currentPos.fromLine; -+ newPos.toLine = currentPos.toLine; -+ } -+ else if (c == '+') { -+ line.stripFirst(c); -+ line.stripUInt(diff, false); -+ newPos.fromLine = currentPos.fromLine + diff; -+ newPos.toLine = newPos.fromLine; -+ } -+ else if (c == '-') { -+ line.stripFirst(c); -+ line.stripUInt(diff, false); -+ if (currentPos.fromLine < diff) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Negative line number " -+ << (int)currentPos.fromLine - (int)diff << endl; -+ diff = currentPos.fromLine; -+ } -+ newPos.fromLine = currentPos.fromLine - diff; -+ newPos.toLine = newPos.fromLine; -+ } -+ else if (c >= '0') { -+ line.stripUInt(newPos.fromLine, false); -+ newPos.toLine = newPos.fromLine; -+ } -+ else return false; -+ -+ // Range specification -+ if (line.first(c)) { -+ if (c == '+') { -+ line.stripFirst(c); -+ line.stripUInt(diff); -+ newPos.toLine = newPos.fromLine + diff; -+ } -+ else if ((c == '-') || (c == ':')) { -+ line.stripFirst(c); -+ line.stripUInt(newPos.toLine); -+ } -+ } -+ line.stripSpaces(); -+ -+#if TRACE_LOADER -+ if (newPos.fromLine == newPos.toLine) -+ kdDebug() << " Got Line " << newPos.fromLine << endl; -+ else -+ kdDebug() << " Got LineRange " << newPos.fromLine -+ << ":" << newPos.toLine << endl; -+#endif -+ -+ } -+ -+ return true; -+} -+ -+// Support for compressed strings -+void CachegrindLoader::clearCompression() -+{ -+ // this doesn't delete previous contained objects -+ _objectVector.clear(); -+ _fileVector.clear(); -+ _functionVector.clear(); -+ -+ // reset to reasonable init size. We double lengths if needed. -+ _objectVector.resize(100); -+ _fileVector.resize(1000); -+ _functionVector.resize(10000); -+} -+ -+const TQString& CachegrindLoader::checkUnknown(const TQString& n) -+{ -+ if (n == "???") return _emptyString; -+ return n; -+} -+ -+TraceObject* CachegrindLoader::compressedObject(const TQString& name) -+{ -+ if ((name[0] != '(') || !name[1].isDigit()) return _data->object(checkUnknown(name)); -+ -+ // compressed format using _objectVector -+ int p = name.find(')'); -+ if (p<2) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid compressed ELF object ('" -+ << name << "')" << endl; -+ return 0; -+ } -+ unsigned index = name.mid(1, p-1).toInt(); -+ TraceObject* o = 0; -+ p++; -+ if ((int)name.length()>p) { -+ while(name.at(p).isSpace()) p++; -+ -+ if (_objectVector.size() <= index) { -+ int newSize = index * 2; -+#if TRACE_LOADER -+ kdDebug() << " CachegrindLoader: objectVector enlarged to " -+ << newSize << endl; -+#endif -+ _objectVector.resize(newSize); -+ } -+ -+ TQString realName = checkUnknown(name.mid(p)); -+ o = (TraceObject*) _objectVector.at(index); -+ if (o && (o->name() != realName)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Redefinition of compressed ELF object index " << index -+ << " (was '" << o->name() -+ << "') to '" << realName << "'" << endl; -+ } -+ -+ o = _data->object(realName); -+ _objectVector.insert(index, o); -+ } -+ else { -+ if ((_objectVector.size() <= index) || -+ ( (o=(TraceObject*)_objectVector.at(index)) == 0)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Undefined compressed ELF object index " << index << endl; -+ return 0; -+ } -+ } -+ -+ return o; -+} -+ -+ -+// Note: Callgrind sometimes gives different IDs for same file -+// (when references to same source file come from different ELF objects) -+TraceFile* CachegrindLoader::compressedFile(const TQString& name) -+{ -+ if ((name[0] != '(') || !name[1].isDigit()) return _data->file(checkUnknown(name)); -+ -+ // compressed format using _fileVector -+ int p = name.find(')'); -+ if (p<2) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid compressed file ('" -+ << name << "')" << endl; -+ return 0; -+ } -+ unsigned int index = name.mid(1, p-1).toUInt(); -+ TraceFile* f = 0; -+ p++; -+ if ((int)name.length()>p) { -+ while(name.at(p).isSpace()) p++; -+ -+ if (_fileVector.size() <= index) { -+ int newSize = index * 2; -+#if TRACE_LOADER -+ kdDebug() << " CachegrindLoader::fileVector enlarged to " -+ << newSize << endl; -+#endif -+ _fileVector.resize(newSize); -+ } -+ -+ TQString realName = checkUnknown(name.mid(p)); -+ f = (TraceFile*) _fileVector.at(index); -+ if (f && (f->name() != realName)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Redefinition of compressed file index " << index -+ << " (was '" << f->name() -+ << "') to '" << realName << "'" << endl; -+ } -+ -+ f = _data->file(realName); -+ _fileVector.insert(index, f); -+ } -+ else { -+ if ((_fileVector.size() <= index) || -+ ( (f=(TraceFile*)_fileVector.at(index)) == 0)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Undefined compressed file index " << index << endl; -+ return 0; -+ } -+ } -+ -+ return f; -+} -+ -+// Note: Callgrind gives different IDs even for same function -+// when parts of the function are from different source files. -+// Thus, it is no error when multiple indexes map to same function. -+TraceFunction* CachegrindLoader::compressedFunction(const TQString& name, -+ TraceFile* file, -+ TraceObject* object) -+{ -+ if ((name[0] != '(') || !name[1].isDigit()) -+ return _data->function(checkUnknown(name), file, object); -+ -+ // compressed format using _functionVector -+ int p = name.find(')'); -+ if (p<2) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid compressed function ('" -+ << name << "')" << endl; -+ return 0; -+ } -+ -+ -+ unsigned int index = name.mid(1, p-1).toUInt(); -+ TraceFunction* f = 0; -+ p++; -+ if ((int)name.length()>p) { -+ while(name.at(p).isSpace()) p++; -+ -+ if (_functionVector.size() <= index) { -+ int newSize = index * 2; -+#if TRACE_LOADER -+ kdDebug() << " CachegrindLoader::functionVector enlarged to " -+ << newSize << endl; -+#endif -+ _functionVector.resize(newSize); -+ } -+ -+ TQString realName = checkUnknown(name.mid(p)); -+ f = (TraceFunction*) _functionVector.at(index); -+ if (f && (f->name() != realName)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Redefinition of compressed function index " << index -+ << " (was '" << f->name() -+ << "') to '" << realName << "'" << endl; -+ } -+ -+ f = _data->function(realName, file, object); -+ _functionVector.insert(index, f); -+ -+#if TRACE_LOADER -+ kdDebug() << "compressedFunction: Inserted at Index " << index -+ << "\n " << f->fullName() -+ << "\n in " << f->cls()->fullName() -+ << "\n in " << f->file()->fullName() -+ << "\n in " << f->object()->fullName() << endl; -+#endif -+ } -+ else { -+ if ((_functionVector.size() <= index) || -+ ( (f=(TraceFunction*)_functionVector.at(index)) == 0)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Undefined compressed function index " -+ << index << endl; -+ return 0; -+ } -+ -+ // there was a check if the used function (returned from KCachegrinds -+ // model) has the same object and file as here given to us, but that was wrong: -+ // that holds only if we make this assumption on the model... -+ } -+ -+ return f; -+} -+ -+ -+// make sure that a valid object is set, at least dummy with empty name -+void CachegrindLoader::ensureObject() -+{ -+ if (currentObject) return; -+ -+ currentObject = _data->object(_emptyString); -+ currentPartObject = currentObject->partObject(_part); -+} -+ -+void CachegrindLoader::setObject(const TQString& name) -+{ -+ currentObject = compressedObject(name); -+ if (!currentObject) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid object specification, setting to unknown" << endl; -+ -+ currentObject = _data->object(_emptyString); -+ } -+ -+ currentPartObject = currentObject->partObject(_part); -+ currentFunction = 0; -+ currentPartFunction = 0; -+} -+ -+void CachegrindLoader::setCalledObject(const TQString& name) -+{ -+ currentCalledObject = compressedObject(name); -+ -+ if (!currentCalledObject) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid called specification, setting to unknown" << endl; -+ -+ currentCalledObject = _data->object(_emptyString); -+ } -+ -+ currentCalledPartObject = currentCalledObject->partObject(_part); -+} -+ -+ -+// make sure that a valid file is set, at least dummy with empty name -+void CachegrindLoader::ensureFile() -+{ -+ if (currentFile) return; -+ -+ currentFile = _data->file(_emptyString); -+ currentPartFile = currentFile->partFile(_part); -+} -+ -+void CachegrindLoader::setFile(const TQString& name) -+{ -+ currentFile = compressedFile(name); -+ -+ if (!currentFile) { -+ kdWarning() << _filename << ":" << _lineNo -+ << " - Invalid file specification, setting to unknown" << endl; -+ -+ currentFile = _data->file(_emptyString); -+ } -+ -+ currentPartFile = currentFile->partFile(_part); -+ currentLine = 0; -+ currentPartLine = 0; -+} -+ -+void CachegrindLoader::setCalledFile(const TQString& name) -+{ -+ currentCalledFile = compressedFile(name); -+ -+ if (!currentCalledFile) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid called file specification, setting to unknown" << endl; -+ -+ currentCalledFile = _data->file(_emptyString); -+ } -+ -+ currentCalledPartFile = currentCalledFile->partFile(_part); -+} -+ -+// make sure that a valid function is set, at least dummy with empty name -+void CachegrindLoader::ensureFunction() -+{ -+ if (currentFunction) return; -+ -+ kdWarning() << _filename << ":" << _lineNo -+ << " - Function name not set" << endl; -+ -+ ensureFile(); -+ ensureObject(); -+ -+ currentFunction = _data->function(_emptyString, -+ currentFile, -+ currentObject); -+ currentPartFunction = currentFunction->partFunction(_part, -+ currentPartFile, -+ currentPartObject); -+} -+ -+void CachegrindLoader::setFunction(const TQString& name) -+{ -+ ensureFile(); -+ ensureObject(); -+ -+ currentFunction = compressedFunction( name, -+ currentFile, -+ currentObject); -+ -+ if (!currentFunction) { -+ kdWarning() << _filename << ":" << _lineNo -+ << " - Invalid function, setting to unknown" << endl; -+ -+ currentFunction = _data->function(_emptyString, -+ currentFile, -+ currentObject); -+ } -+ -+ currentPartFunction = currentFunction->partFunction(_part, -+ currentPartFile, -+ currentPartObject); -+ -+ currentFunctionSource = 0; -+ currentLine = 0; -+ currentPartLine = 0; -+} -+ -+void CachegrindLoader::setCalledFunction(const TQString& name) -+{ -+ // if called object/file not set, use current object/file -+ if (!currentCalledObject) { -+ currentCalledObject = currentObject; -+ currentCalledPartObject = currentPartObject; -+ } -+ -+ if (!currentCalledFile) { -+ // !=0 as functions needs file -+ currentCalledFile = currentFile; -+ currentCalledPartFile = currentPartFile; -+ } -+ -+ currentCalledFunction = compressedFunction(name, -+ currentCalledFile, -+ currentCalledObject); -+ if (!currentCalledFunction) { -+ kdWarning() << _filename << ":" << _lineNo -+ << " - Invalid called function, setting to unknown" << endl; -+ -+ currentCalledFunction = _data->function(_emptyString, -+ currentCalledFile, -+ currentCalledObject); -+ } -+ -+ currentCalledPartFunction = -+ currentCalledFunction->partFunction(_part, -+ currentCalledPartFile, -+ currentCalledPartObject); -+} -+ -+ -+void CachegrindLoader::clearPosition() -+{ -+ currentPos = PositionSpec(); -+ -+ // current function/line -+ currentFunction = 0; -+ currentPartFunction = 0; -+ currentFunctionSource = 0; -+ currentFile = 0; -+ currentPartFile = 0; -+ currentObject = 0; -+ currentPartObject = 0; -+ currentLine = 0; -+ currentPartLine = 0; -+ currentInstr = 0; -+ currentPartInstr = 0; -+ -+ // current call -+ currentCalledObject = 0; -+ currentCalledPartObject = 0; -+ currentCalledFile = 0; -+ currentCalledPartFile = 0; -+ currentCalledFunction = 0; -+ currentCalledPartFunction = 0; -+ currentCallCount = 0; -+ -+ // current jump -+ currentJumpToFile = 0; -+ currentJumpToFunction = 0; -+ targetPos = PositionSpec(); -+ jumpsFollowed = 0; -+ jumpsExecuted = 0; -+ -+ subMapping = 0; -+} -+ -+ -+/** -+ * The main import function... -+ */ -+bool CachegrindLoader::loadTraceInternal(TracePart* part) -+{ -+ clearCompression(); -+ clearPosition(); -+ -+ _part = part; -+ _data = part->data(); -+ TQFile* pFile = part->file(); -+ -+ if (!pFile) return false; -+ -+ _filename = pFile->name(); -+ -+ FixFile file(pFile); -+ if (!file.exists()) { -+ kdError() << "File doesn't exist\n" << endl; -+ return false; -+ } -+ kdDebug() << "Loading " << _filename << " ..." << endl; -+ TQString statusMsg = i18n("Loading %1").arg(_filename); -+ int statusProgress = 0; -+ emit updateStatus(statusMsg,statusProgress); -+ -+ -+#if USE_FIXCOST -+ // FixCost Memory Pool -+ FixPool* pool = _data->fixPool(); -+#endif -+ -+ _lineNo = 0; -+ FixString line; -+ char c; -+ bool totalsSet = false; -+ -+ // current position -+ nextLineType = SelfCost; -+ // default if there's no "positions:" line -+ hasLineInfo = true; -+ hasAddrInfo = false; -+ -+ while (file.nextLine(line)) { -+ -+ _lineNo++; -+ -+#if TRACE_LOADER -+ kdDebug() << "[CachegrindLoader] " << _filename << ":" << _lineNo -+ << " - '" << TQString(line) << "'" << endl; -+#endif -+ -+ // if we cannot strip a character, this was an empty line -+ if (!line.first(c)) continue; -+ -+ if (c <= '9') { -+ -+ if (c == '#') continue; -+ -+ // parse position(s) -+ if (!parsePosition(line, currentPos)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid position specification ('" -+ << TQString(line) << "')" << endl; -+ continue; -+ } -+ -+ // go through after big switch -+ } -+ else { // if (c > '9') -+ -+ line.stripFirst(c); -+ -+ /* in order of probability */ -+ switch(c) { -+ -+ case 'f': -+ -+ // fl=, fi=, fe= -+ if (line.stripPrefix("l=") || -+ line.stripPrefix("i=") || -+ line.stripPrefix("e=")) { -+ -+ setFile(line); -+ continue; -+ } -+ -+ // fn= -+ if (line.stripPrefix("n=")) { -+ -+ setFunction(line); -+ -+ // on a new function, update status -+ int progress = (int)(100.0 * file.current() / file.len() +.5); -+ if (progress != statusProgress) { -+ statusProgress = progress; -+ -+ /* When this signal is connected, it most probably -+ * should lead to GUI update. Thus, when multiple -+ * "long operations" (like file loading) are in progress, -+ * this can temporarly switch to another operation. -+ */ -+ emit updateStatus(statusMsg,statusProgress); -+ } -+ -+ continue; -+ } -+ -+ break; -+ -+ case 'c': -+ // cob= -+ if (line.stripPrefix("ob=")) { -+ setCalledObject(line); -+ continue; -+ } -+ -+ // cfi= / cfl= -+ if (line.stripPrefix("fl=") || -+ line.stripPrefix("fi=")) { -+ setCalledFile(line); -+ continue; -+ } -+ -+ // cfn= -+ if (line.stripPrefix("fn=")) { -+ -+ setCalledFunction(line); -+ continue; -+ } -+ -+ // calls= -+ if (line.stripPrefix("alls=")) { -+ // ignore long lines... -+ line.stripUInt64(currentCallCount); -+ nextLineType = CallCost; -+ continue; -+ } -+ -+ // cmd: -+ if (line.stripPrefix("md:")) { -+ TQString command = TQString(line).stripWhiteSpace(); -+ if (!_data->command().isEmpty() && -+ _data->command() != command) { -+ -+ kdWarning() << _filename << ":" << _lineNo -+ << " - Redefined command, was '" -+ << _data->command() -+ << "'" << endl; -+ } -+ _data->setCommand(command); -+ continue; -+ } -+ -+ // creator: -+ if (line.stripPrefix("reator:")) { -+ // ignore ... -+ continue; -+ } -+ -+ break; -+ -+ case 'j': -+ -+ // jcnd= -+ if (line.stripPrefix("cnd=")) { -+ bool valid; -+ -+ valid = line.stripUInt64(jumpsFollowed) && -+ line.stripPrefix("/") && -+ line.stripUInt64(jumpsExecuted) && -+ parsePosition(line, targetPos); -+ -+ if (!valid) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid jcnd line" << endl; -+ } -+ else -+ nextLineType = CondJump; -+ continue; -+ } -+ -+ if (line.stripPrefix("ump=")) { -+ bool valid; -+ -+ valid = line.stripUInt64(jumpsExecuted) && -+ parsePosition(line, targetPos); -+ -+ if (!valid) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid jump line" << endl; -+ } -+ else -+ nextLineType = BoringJump; -+ continue; -+ } -+ -+ // jfi= -+ if (line.stripPrefix("fi=")) { -+ currentJumpToFile = compressedFile(line); -+ continue; -+ } -+ -+ // jfn= -+ if (line.stripPrefix("fn=")) { -+ -+ if (!currentJumpToFile) { -+ // !=0 as functions needs file -+ currentJumpToFile = currentFile; -+ } -+ -+ currentJumpToFunction = -+ compressedFunction(line, -+ currentJumpToFile, -+ currentObject); -+ continue; -+ } -+ -+ break; -+ -+ case 'o': -+ -+ // ob= -+ if (line.stripPrefix("b=")) { -+ setObject(line); -+ continue; -+ } -+ -+ break; -+ -+ case '#': -+ continue; -+ -+ case 't': -+ -+ // totals: -+ if (line.stripPrefix("otals:")) continue; -+ -+ // thread: -+ if (line.stripPrefix("hread:")) { -+ part->setThreadID(TQString(line).toInt()); -+ continue; -+ } -+ -+ // timeframe (BB): -+ if (line.stripPrefix("imeframe (BB):")) { -+ part->setTimeframe(line); -+ continue; -+ } -+ -+ break; -+ -+ case 'd': -+ -+ // desc: -+ if (line.stripPrefix("esc:")) { -+ -+ line.stripSurroundingSpaces(); -+ -+ // desc: Trigger: -+ if (line.stripPrefix("Trigger:")) { -+ part->setTrigger(line); -+ } -+ -+ continue; -+ } -+ break; -+ -+ case 'e': -+ -+ // events: -+ if (line.stripPrefix("vents:")) { -+ subMapping = _data->mapping()->subMapping(line); -+ part->setFixSubMapping(subMapping); -+ continue; -+ } -+ -+ // event:[=][:] -+ if (line.stripPrefix("vent:")) { -+ line.stripSurroundingSpaces(); -+ -+ FixString e, f, l; -+ if (!line.stripName(e)) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid event" << endl; -+ continue; -+ } -+ line.stripSpaces(); -+ if (!line.stripFirst(c)) continue; -+ -+ if (c=='=') f = line.stripUntil(':'); -+ line.stripSpaces(); -+ -+ // add to known cost types -+ if (line.isEmpty()) line = e; -+ TraceCostType::add(new TraceCostType(e,line,f)); -+ continue; -+ } -+ break; -+ -+ case 'p': -+ -+ // part: -+ if (line.stripPrefix("art:")) { -+ part->setPartNumber(TQString(line).toInt()); -+ continue; -+ } -+ -+ // pid: -+ if (line.stripPrefix("id:")) { -+ part->setProcessID(TQString(line).toInt()); -+ continue; -+ } -+ -+ // positions: -+ if (line.stripPrefix("ositions:")) { -+ TQString positions(line); -+ hasLineInfo = (positions.find("line")>=0); -+ hasAddrInfo = (positions.find("instr")>=0); -+ continue; -+ } -+ break; -+ -+ case 'v': -+ -+ // version: -+ if (line.stripPrefix("ersion:")) { -+ part->setVersion(line); -+ continue; -+ } -+ break; -+ -+ case 's': -+ -+ // summary: -+ if (line.stripPrefix("ummary:")) { -+ if (!subMapping) { -+ kdError() << "No event line found. Skipping '" << _filename << endl; -+ return false; -+ } -+ -+ part->totals()->set(subMapping, line); -+ continue; -+ } -+ -+ case 'r': -+ -+ // rcalls= (deprecated) -+ if (line.stripPrefix("calls=")) { -+ // handle like normal calls: we need the sum of call count -+ // recursive cost is discarded in cycle detection -+ line.stripUInt64(currentCallCount); -+ nextLineType = CallCost; -+ -+ kdDebug() << "WARNING: This trace dump was generated by an old " -+ "version\n of the call-tree skin. Use a new one!" << endl; -+ -+ continue; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid line '" << c << TQString(line) << "'" << endl; -+ continue; -+ } -+ -+ if (!subMapping) { -+ kdError() << "No event line found. Skipping '" << _filename << "'" << endl; -+ return false; -+ } -+ -+ // for a cost line, we always need a current function -+ ensureFunction(); -+ -+ -+#if USE_FIXCOST -+ if (!currentFunctionSource || -+ (currentFunctionSource->file() != currentFile)) -+ currentFunctionSource = currentFunction->sourceFile(currentFile, -+ true); -+#else -+ if (hasAddrInfo) { -+ if (!currentInstr || -+ (currentInstr->addr() != currentPos.fromAddr)) { -+ currentInstr = currentFunction->instr(currentPos.fromAddr, -+ true); -+ -+ if (!currentInstr) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Invalid address " -+ << currentPos.fromAddr.toString() << endl; -+ -+ continue; -+ } -+ -+ currentPartInstr = currentInstr->partInstr(part, -+ currentPartFunction); -+ } -+ } -+ -+ if (hasLineInfo) { -+ if (!currentLine || -+ (currentLine->lineno() != currentPos.fromLine)) { -+ -+ currentLine = currentFunction->line(currentFile, -+ currentPos.fromLine, -+ true); -+ currentPartLine = currentLine->partLine(part, -+ currentPartFunction); -+ } -+ if (hasAddrInfo && currentInstr) -+ currentInstr->setLine(currentLine); -+ } -+#endif -+ -+#if TRACE_LOADER -+ kdDebug() << _filename << ":" << _lineNo -+ << endl << " currentInstr " -+ << (currentInstr ? currentInstr->toString().ascii() : ".") -+ << endl << " currentLine " -+ << (currentLine ? currentLine->toString().ascii() : ".") -+ << "( file " << currentFile->name() << ")" -+ << endl << " currentFunction " -+ << currentFunction->prettyName().ascii() -+ << endl << " currentCalled " -+ << (currentCalledFunction ? currentCalledFunction->prettyName().ascii() : ".") -+ << endl; -+#endif -+ -+ // create cost item -+ -+ if (nextLineType == SelfCost) { -+ -+#if USE_FIXCOST -+ new (pool) FixCost(part, pool, -+ currentFunctionSource, -+ currentPos, -+ currentPartFunction, -+ line); -+#else -+ if (hasAddrInfo) { -+ TracePartInstr* partInstr; -+ partInstr = currentInstr->partInstr(part, currentPartFunction); -+ -+ if (hasLineInfo) { -+ // we need to set back after reading for the line -+ int l = line.len(); -+ const char* s = line.ascii(); -+ -+ partInstr->addCost(subMapping, line); -+ line.set(s,l); -+ } -+ else -+ partInstr->addCost(subMapping, line); -+ } -+ -+ if (hasLineInfo) { -+ TracePartLine* partLine; -+ partLine = currentLine->partLine(part, currentPartFunction); -+ partLine->addCost(subMapping, line); -+ } -+#endif -+ -+ if (!line.isEmpty()) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Garbage at end of cost line ('" -+ << TQString(line) << "')" << endl; -+ } -+ } -+ else if (nextLineType == CallCost) { -+ nextLineType = SelfCost; -+ -+ TraceCall* calling = currentFunction->calling(currentCalledFunction); -+ TracePartCall* partCalling = -+ calling->partCall(part, currentPartFunction, -+ currentCalledPartFunction); -+ -+#if USE_FIXCOST -+ FixCallCost* fcc; -+ fcc = new (pool) FixCallCost(part, pool, -+ currentFunctionSource, -+ hasLineInfo ? currentPos.fromLine : 0, -+ hasAddrInfo ? currentPos.fromAddr : Addr(0), -+ partCalling, -+ currentCallCount, line); -+ fcc->setMax(_data->callMax()); -+#else -+ if (hasAddrInfo) { -+ TraceInstrCall* instrCall; -+ TracePartInstrCall* partInstrCall; -+ -+ instrCall = calling->instrCall(currentInstr); -+ partInstrCall = instrCall->partInstrCall(part, partCalling); -+ partInstrCall->addCallCount(currentCallCount); -+ -+ if (hasLineInfo) { -+ // we need to set back after reading for the line -+ int l = line.len(); -+ const char* s = line.ascii(); -+ -+ partInstrCall->addCost(subMapping, line); -+ line.set(s,l); -+ } -+ else -+ partInstrCall->addCost(subMapping, line); -+ -+ // update maximum of call cost -+ _data->callMax()->maxCost(partInstrCall); -+ } -+ -+ if (hasLineInfo) { -+ TraceLineCall* lineCall; -+ TracePartLineCall* partLineCall; -+ -+ lineCall = calling->lineCall(currentLine); -+ partLineCall = lineCall->partLineCall(part, partCalling); -+ -+ partLineCall->addCallCount(currentCallCount); -+ partLineCall->addCost(subMapping, line); -+ -+ // update maximum of call cost -+ _data->callMax()->maxCost(partLineCall); -+ } -+#endif -+ currentCalledFile = 0; -+ currentCalledPartFile = 0; -+ currentCalledObject = 0; -+ currentCalledPartObject = 0; -+ currentCallCount = 0; -+ -+ if (!line.isEmpty()) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Garbage at end of call cost line ('" -+ << TQString(line) << "')" << endl; -+ } -+ } -+ else { // (nextLineType == BoringJump || nextLineType == CondJump) -+ -+ TraceFunctionSource* targetSource; -+ -+ if (!currentJumpToFunction) -+ currentJumpToFunction = currentFunction; -+ -+ targetSource = (currentJumpToFile) ? -+ currentJumpToFunction->sourceFile(currentJumpToFile, true) : -+ currentFunctionSource; -+ -+#if USE_FIXCOST -+ new (pool) FixJump(part, pool, -+ /* source */ -+ hasLineInfo ? currentPos.fromLine : 0, -+ hasAddrInfo ? currentPos.fromAddr : 0, -+ currentPartFunction, -+ currentFunctionSource, -+ /* target */ -+ hasLineInfo ? targetPos.fromLine : 0, -+ hasAddrInfo ? targetPos.fromAddr : Addr(0), -+ currentJumpToFunction, -+ targetSource, -+ (nextLineType == CondJump), -+ jumpsExecuted, jumpsFollowed); -+#endif -+ -+ if (0) { -+ kdDebug() << _filename << ":" << _lineNo -+ << " - jump from 0x" << currentPos.fromAddr.toString() -+ << " (line " << currentPos.fromLine -+ << ") to 0x" << targetPos.fromAddr.toString() -+ << " (line " << targetPos.fromLine << ")" << endl; -+ -+ if (nextLineType == BoringJump) -+ kdDebug() << " Boring Jump, count " << jumpsExecuted.pretty() << endl; -+ else -+ kdDebug() << " Cond. Jump, followed " << jumpsFollowed.pretty() -+ << ", executed " << jumpsExecuted.pretty() << endl; -+ } -+ -+ nextLineType = SelfCost; -+ currentJumpToFunction = 0; -+ currentJumpToFile = 0; -+ -+ if (!line.isEmpty()) { -+ kdError() << _filename << ":" << _lineNo -+ << " - Garbage at end of jump cost line ('" -+ << TQString(line) << "')" << endl; -+ } -+ -+ } -+ } -+ -+ -+ emit updateStatus(statusMsg,100); -+ -+ _part->invalidate(); -+ if (!totalsSet) { -+ _part->totals()->clear(); -+ _part->totals()->addCost(_part); -+ } -+ -+ pFile->close(); -+ -+ return true; -+} -+ -diff --git a/kdecachegrind/kdecachegrind/callgraphview.cpp b/kdecachegrind/kdecachegrind/callgraphview.cpp -new file mode 100644 -index 0000000..bc01da8 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callgraphview.cpp -@@ -0,0 +1,2734 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Callgraph View -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "callgraphview.h" -+#include "toplevel.h" -+#include "listutils.h" -+ -+ -+/* -+ * TODO: -+ * - Zooming option for work canvas? (e.g. 1:1 - 1:3) -+ */ -+ -+#define DEBUG_GRAPH 0 -+ -+// CallGraphView defaults -+ -+#define DEFAULT_FUNCLIMIT .05 -+#define DEFAULT_CALLLIMIT .05 -+#define DEFAULT_MAXCALLER 2 -+#define DEFAULT_MAXCALLING -1 -+#define DEFAULT_SHOWSKIPPED false -+#define DEFAULT_EXPANDCYCLES false -+#define DEFAULT_CLUSTERGROUPS false -+#define DEFAULT_DETAILLEVEL 1 -+#define DEFAULT_LAYOUT GraphOptions::TopDown -+#define DEFAULT_ZOOMPOS Auto -+ -+ -+// -+// GraphEdgeList -+// -+ -+GraphEdgeList::GraphEdgeList() -+ : _sortCallerPos(true) -+{} -+ -+int GraphEdgeList::compareItems(Item item1, Item item2) -+{ -+ CanvasEdge* e1 = ((GraphEdge*)item1)->canvasEdge(); -+ CanvasEdge* e2 = ((GraphEdge*)item2)->canvasEdge(); -+ -+ // edges without arrow visualisations are sorted as low -+ if (!e1) return -1; -+ if (!e2) return 1; -+ -+ int dx1, dy1, dx2, dy2; -+ int x, y; -+ if (_sortCallerPos) { -+ e1->controlPoints().point(0,&x,&y); -+ e2->controlPoints().point(0,&dx1,&dy1); -+ dx1 -= x; dy1 -= y; -+ } -+ else { -+ TQPointArray a1 = e1->controlPoints(); -+ TQPointArray a2 = e2->controlPoints(); -+ a1.point(a1.count()-2,&x,&y); -+ a2.point(a2.count()-1,&dx2,&dy2); -+ dx2 -= x; dy2 -= y; -+ } -+ double at1 = atan2(double(dx1), double(dy1)); -+ double at2 = atan2(double(dx2), double(dy2)); -+ -+ return (at1 < at2) ? 1:-1; -+} -+ -+ -+ -+ -+// -+// GraphNode -+// -+ -+GraphNode::GraphNode() -+{ -+ _f=0; -+ self = incl = 0; -+ _cn = 0; -+ -+ _visible = false; -+ _lastCallerIndex = _lastCallingIndex = -1; -+ -+ callers.setSortCallerPos(false); -+ callings.setSortCallerPos(true); -+ _lastFromCaller = true; -+} -+ -+TraceCall* GraphNode::visibleCaller() -+{ -+ if (0) qDebug("GraphNode::visibleCaller %s: last %d, count %d", -+ _f->prettyName().ascii(), _lastCallerIndex, callers.count()); -+ -+ GraphEdge* e = callers.at(_lastCallerIndex); -+ if (e && !e->isVisible()) e = 0; -+ if (!e) { -+ double maxCost = 0.0; -+ GraphEdge* maxEdge = 0; -+ int idx = 0; -+ for(e = callers.first();e; e=callers.next(),idx++) -+ if (e->isVisible() && (e->cost > maxCost)) { -+ maxCost = e->cost; -+ maxEdge = e; -+ _lastCallerIndex = idx; -+ } -+ e = maxEdge; -+ } -+ return e ? e->call() : 0; -+} -+ -+TraceCall* GraphNode::visibleCalling() -+{ -+ if (0) qDebug("GraphNode::visibleCalling %s: last %d, count %d", -+ _f->prettyName().ascii(), _lastCallingIndex, callings.count()); -+ -+ GraphEdge* e = callings.at(_lastCallingIndex); -+ if (e && !e->isVisible()) e = 0; -+ if (!e) { -+ double maxCost = 0.0; -+ GraphEdge* maxEdge = 0; -+ int idx = 0; -+ for(e = callings.first();e; e=callings.next(),idx++) -+ if (e->isVisible() && (e->cost > maxCost)) { -+ maxCost = e->cost; -+ maxEdge = e; -+ _lastCallingIndex = idx; -+ } -+ e = maxEdge; -+ } -+ return e ? e->call() : 0; -+} -+ -+void GraphNode::setCalling(GraphEdge* e) -+{ -+ _lastCallingIndex = callings.findRef(e); -+ _lastFromCaller = false; -+} -+ -+void GraphNode::setCaller(GraphEdge* e) -+{ -+ _lastCallerIndex = callers.findRef(e); -+ _lastFromCaller = true; -+} -+ -+TraceFunction* GraphNode::nextVisible() -+{ -+ TraceCall* c; -+ if (_lastFromCaller) { -+ c = nextVisibleCaller(callers.at(_lastCallerIndex)); -+ if (c) return c->called(true); -+ c = nextVisibleCalling(callings.at(_lastCallingIndex)); -+ if (c) return c->caller(true); -+ } -+ else { -+ c = nextVisibleCalling(callings.at(_lastCallingIndex)); -+ if (c) return c->caller(true); -+ c = nextVisibleCaller(callers.at(_lastCallerIndex)); -+ if (c) return c->called(true); -+ } -+ return 0; -+} -+ -+TraceFunction* GraphNode::priorVisible() -+{ -+ TraceCall* c; -+ if (_lastFromCaller) { -+ c = priorVisibleCaller(callers.at(_lastCallerIndex)); -+ if (c) return c->called(true); -+ c = priorVisibleCalling(callings.at(_lastCallingIndex)); -+ if (c) return c->caller(true); -+ } -+ else { -+ c = priorVisibleCalling(callings.at(_lastCallingIndex)); -+ if (c) return c->caller(true); -+ c = priorVisibleCaller(callers.at(_lastCallerIndex)); -+ if (c) return c->called(true); -+ } -+ return 0; -+} -+ -+TraceCall* GraphNode::nextVisibleCaller(GraphEdge* last) -+{ -+ GraphEdge* e; -+ bool found = false; -+ int idx = 0; -+ for(e = callers.first();e; e=callers.next(),idx++) { -+ if (found && e->isVisible()) { -+ _lastCallerIndex = idx; -+ return e->call(); -+ } -+ if (e == last) found = true; -+ } -+ return 0; -+} -+ -+TraceCall* GraphNode::nextVisibleCalling(GraphEdge* last) -+{ -+ GraphEdge* e; -+ bool found = false; -+ int idx = 0; -+ for(e = callings.first();e; e=callings.next(),idx++) { -+ if (found && e->isVisible()) { -+ _lastCallingIndex = idx; -+ return e->call(); -+ } -+ if (e == last) found = true; -+ } -+ return 0; -+} -+ -+TraceCall* GraphNode::priorVisibleCaller(GraphEdge* last) -+{ -+ GraphEdge *e, *prev = 0; -+ int prevIdx = -1, idx = 0; -+ for(e = callers.first(); e; e=callers.next(),idx++) { -+ if (e == last) { -+ _lastCallerIndex = prevIdx; -+ return prev ? prev->call() : 0; -+ } -+ if (e->isVisible()) { -+ prev = e; -+ prevIdx = idx; -+ } -+ } -+ return 0; -+} -+ -+TraceCall* GraphNode::priorVisibleCalling(GraphEdge* last) -+{ -+ GraphEdge *e, *prev = 0; -+ int prevIdx = -1, idx = 0; -+ for(e = callings.first(); e; e=callings.next(),idx++) { -+ if (e == last) { -+ _lastCallingIndex = prevIdx; -+ return prev ? prev->call() : 0; -+ } -+ if (e->isVisible()) { -+ prev = e; -+ prevIdx = idx; -+ } -+ } -+ return 0; -+} -+ -+// -+// GraphEdge -+// -+ -+GraphEdge::GraphEdge() -+{ -+ _c=0; -+ _from = _to = 0; -+ _fromNode = _toNode = 0; -+ cost = count = 0; -+ _ce = 0; -+ -+ _visible = false; -+ _lastFromCaller = true; -+} -+ -+TQString GraphEdge::prettyName() -+{ -+ if (_c) return _c->prettyName(); -+ if (_from) return i18n("Call(s) from %1").arg(_from->prettyName()); -+ if (_to) return i18n("Call(s) to %1").arg(_to->prettyName()); -+ return i18n("(unknown call)"); -+} -+ -+ -+TraceFunction* GraphEdge::visibleCaller() -+{ -+ if (_from) { -+ _lastFromCaller = true; -+ if (_fromNode) _fromNode->setCalling(this); -+ return _from; -+ } -+ return 0; -+} -+ -+TraceFunction* GraphEdge::visibleCalling() -+{ -+ if (_to) { -+ _lastFromCaller = false; -+ if (_toNode) _toNode->setCaller(this); -+ return _to; -+ } -+ return 0; -+} -+ -+TraceCall* GraphEdge::nextVisible() -+{ -+ TraceCall* res = 0; -+ -+ if (_lastFromCaller && _fromNode) { -+ res = _fromNode->nextVisibleCalling(this); -+ if (!res && _toNode) -+ res = _toNode->nextVisibleCaller(this); -+ } -+ else if (_toNode) { -+ res = _toNode->nextVisibleCaller(this); -+ if (!res && _fromNode) -+ res = _fromNode->nextVisibleCalling(this); -+ } -+ return res; -+} -+ -+TraceCall* GraphEdge::priorVisible() -+{ -+ TraceCall* res = 0; -+ -+ if (_lastFromCaller && _fromNode) { -+ res = _fromNode->priorVisibleCalling(this); -+ if (!res && _toNode) -+ res = _toNode->priorVisibleCaller(this); -+ } -+ else if (_toNode) { -+ res = _toNode->priorVisibleCaller(this); -+ if (!res && _fromNode) -+ res = _fromNode->priorVisibleCalling(this); -+ } -+ return res; -+} -+ -+ -+ -+// -+// GraphOptions -+// -+ -+TQString GraphOptions::layoutString(Layout l) -+{ -+ if (l == Circular) return TQString("Circular"); -+ if (l == LeftRight) return TQString("LeftRight"); -+ return TQString("TopDown"); -+} -+ -+GraphOptions::Layout GraphOptions::layout(TQString s) -+{ -+ if (s == TQString("Circular")) return Circular; -+ if (s == TQString("LeftRight")) return LeftRight; -+ return TopDown; -+} -+ -+ -+// -+// StorableGraphOptions -+// -+ -+StorableGraphOptions::StorableGraphOptions() -+{ -+ // default options -+ _funcLimit = DEFAULT_FUNCLIMIT; -+ _callLimit = DEFAULT_CALLLIMIT; -+ _maxCallerDepth = DEFAULT_MAXCALLER; -+ _maxCallingDepth = DEFAULT_MAXCALLING; -+ _showSkipped = DEFAULT_SHOWSKIPPED; -+ _expandCycles = DEFAULT_EXPANDCYCLES; -+ _detailLevel = DEFAULT_DETAILLEVEL; -+ _layout = DEFAULT_LAYOUT; -+} -+ -+ -+ -+ -+// -+// GraphExporter -+// -+ -+GraphExporter::GraphExporter() -+{ -+ _go = this; -+ _tmpFile = 0; -+ _item = 0; -+ reset(0, 0, 0, TraceItem::NoCostType, TQString()); -+} -+ -+ -+GraphExporter::GraphExporter(TraceData* d, TraceFunction* f, TraceCostType* ct, -+ TraceItem::CostType gt, TQString filename) -+{ -+ _go = this; -+ _tmpFile = 0; -+ _item = 0; -+ reset(d, f, ct, gt, filename); -+} -+ -+ -+GraphExporter::~GraphExporter() -+{ -+ if (_item && _tmpFile) { -+#if DEBUG_GRAPH -+ _tmpFile->unlink(); -+#endif -+ delete _tmpFile; -+ } -+} -+ -+ -+void GraphExporter::reset(TraceData*, TraceItem* i, TraceCostType* ct, -+ TraceItem::CostType gt, TQString filename) -+{ -+ _graphCreated = false; -+ _nodeMap.clear(); -+ _edgeMap.clear(); -+ -+ if (_item && _tmpFile) { -+ _tmpFile->unlink(); -+ delete _tmpFile; -+ } -+ -+ if (i) { -+ switch(i->type()) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ case TraceItem::Call: -+ break; -+ default: -+ i = 0; -+ } -+ } -+ -+ _item = i; -+ _costType = ct; -+ _groupType = gt; -+ if (!i) return; -+ -+ if (filename.isEmpty()) { -+ _tmpFile = new KTempFile(TQString(), ".dot"); -+ _dotName = _tmpFile->name(); -+ _useBox = true; -+ } -+ else { -+ _tmpFile = 0; -+ _dotName = filename; -+ _useBox = false; -+ } -+} -+ -+ -+ -+void GraphExporter::setGraphOptions(GraphOptions* go) -+{ -+ if (go == 0) go = this; -+ _go = go; -+} -+ -+void GraphExporter::createGraph() -+{ -+ if (!_item) return; -+ if (_graphCreated) return; -+ _graphCreated = true; -+ -+ if ((_item->type() == TraceItem::Function) || -+ (_item->type() == TraceItem::FunctionCycle)) { -+ TraceFunction* f = (TraceFunction*) _item; -+ -+ double incl = f->inclusive()->subCost(_costType); -+ _realFuncLimit = incl * _go->funcLimit(); -+ _realCallLimit = incl * _go->callLimit(); -+ -+ buildGraph(f, 0, true, 1.0); // down to callings -+ -+ // set costs of function back to 0, as it will be added again -+ GraphNode& n = _nodeMap[f]; -+ n.self = n.incl = 0.0; -+ -+ buildGraph(f, 0, false, 1.0); // up to callers -+ } -+ else { -+ TraceCall* c = (TraceCall*) _item; -+ -+ double incl = c->subCost(_costType); -+ _realFuncLimit = incl * _go->funcLimit(); -+ _realCallLimit = incl * _go->callLimit(); -+ -+ // create edge -+ TraceFunction *caller, *called; -+ caller = c->caller(false); -+ called = c->called(false); -+ TQPair p(caller, called); -+ GraphEdge& e = _edgeMap[p]; -+ e.setCall(c); -+ e.setCaller(p.first); -+ e.setCalling(p.second); -+ e.cost = c->subCost(_costType); -+ e.count = c->callCount(); -+ -+ SubCost s = called->inclusive()->subCost(_costType); -+ buildGraph(called, 0, true, e.cost / s); // down to callings -+ s = caller->inclusive()->subCost(_costType); -+ buildGraph(caller, 0, false, e.cost / s); // up to callers -+ } -+} -+ -+void GraphExporter::writeDot() -+{ -+ if (!_item) return; -+ -+ TQFile* file = 0; -+ TQTextStream* stream = 0; -+ -+ if (_tmpFile) -+ stream = _tmpFile->textStream(); -+ else { -+ file = new TQFile(_dotName); -+ if ( !file->open( IO_WriteOnly ) ) { -+ kdError() << "Can't write dot file '" << _dotName << "'" << endl; -+ return; -+ } -+ stream = new TQTextStream(file); -+ } -+ -+ if (!_graphCreated) createGraph(); -+ -+ /* Generate dot format... -+ * When used for the CallGraphView (in contrast to "Export Callgraph..."), -+ * the labels are only dummy placeholders to reserve space for our own -+ * drawings. -+ */ -+ -+ *stream << "digraph \"callgraph\" {\n"; -+ -+ if (_go->layout() == LeftRight) { -+ *stream << TQString(" rankdir=LR;\n"); -+ } -+ else if (_go->layout() == Circular) { -+ TraceFunction *f = 0; -+ switch(_item->type()) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ f = (TraceFunction*) _item; -+ break; -+ case TraceItem::Call: -+ f = ((TraceCall*)_item)->caller(true); -+ break; -+ default: -+ break; -+ } -+ if (f) -+ *stream << TQString(" center=F%1;\n").arg((long)f, 0, 16); -+ *stream << TQString(" overlap=false;\n splines=true;\n"); -+ } -+ -+ // for clustering -+ TQMap > nLists; -+ -+ GraphNodeMap::Iterator nit; -+ for ( nit = _nodeMap.begin(); -+ nit != _nodeMap.end(); ++nit ) { -+ GraphNode& n = *nit; -+ -+ if (n.incl <= _realFuncLimit) continue; -+ -+ // for clustering: get cost item group of function -+ TraceCostItem* g; -+ TraceFunction* f = n.function(); -+ switch(_groupType) { -+ case TraceItem::Object: g = f->object(); break; -+ case TraceItem::Class: g = f->cls(); break; -+ case TraceItem::File: g = f->file(); break; -+ case TraceItem::FunctionCycle: g = f->cycle(); break; -+ default: g = 0; break; -+ } -+ nLists[g].append(&n); -+ } -+ -+ TQMap >::Iterator lit; -+ int cluster = 0; -+ for ( lit = nLists.begin(); -+ lit != nLists.end(); ++lit, cluster++ ) { -+ TQPtrList& l = lit.data(); -+ TraceCostItem* i = lit.key(); -+ -+ if (_go->clusterGroups() && i) { -+ TQString iabr = i->prettyName(); -+ if ((int)iabr.length() > Configuration::maxSymbolLength()) -+ iabr = iabr.left(Configuration::maxSymbolLength()) + "..."; -+ -+ *stream << TQString("subgraph \"cluster%1\" { label=\"%2\";\n") -+ .arg(cluster).arg(iabr); -+ } -+ -+ GraphNode* np; -+ for(np = l.first(); np; np = l.next() ) { -+ TraceFunction* f = np->function(); -+ -+ TQString abr = f->prettyName(); -+ if ((int)abr.length() > Configuration::maxSymbolLength()) -+ abr = abr.left(Configuration::maxSymbolLength()) + "..."; -+ -+ *stream << TQString(" F%1 [").arg((long)f, 0, 16); -+ if (_useBox) { -+ // make label 3 lines for CallGraphView -+ *stream << TQString("shape=box,label=\"** %1 **\\n**\\n%2\"];\n") -+ .arg(abr) -+ .arg(SubCost(np->incl).pretty()); -+ } -+ else -+ *stream << TQString("label=\"%1\\n%2\"];\n") -+ .arg(abr) -+ .arg(SubCost(np->incl).pretty()); -+ } -+ -+ if (_go->clusterGroups() && i) -+ *stream << TQString("}\n"); -+ } -+ -+ GraphEdgeMap::Iterator eit; -+ for ( eit = _edgeMap.begin(); -+ eit != _edgeMap.end(); ++eit ) { -+ GraphEdge& e = *eit; -+ -+ if (e.cost < _realCallLimit) continue; -+ if (!_go->expandCycles()) { -+ // don't show inner cycle calls -+ if (e.call()->inCycle()>0) continue; -+ } -+ -+ -+ GraphNode& from = _nodeMap[e.from()]; -+ GraphNode& to = _nodeMap[e.to()]; -+ -+ e.setCallerNode(&from); -+ e.setCallingNode(&to); -+ -+ if ((from.incl <= _realFuncLimit) || -+ (to.incl <= _realFuncLimit)) continue; -+ -+ // remove dumped edges from n.callers/n.callings -+ from.callings.removeRef(&e); -+ to.callers.removeRef(&e); -+ from.callingSet.remove(&e); -+ to.callerSet.remove(&e); -+ -+ *stream << TQString(" F%1 -> F%2 [weight=%3") -+ .arg((long)e.from(), 0, 16) -+ .arg((long)e.to(), 0, 16) -+ .arg((long)log(log(e.cost))); -+ -+ if (_go->detailLevel() ==1) -+ *stream << TQString(",label=\"%1\"") -+ .arg(SubCost(e.cost).pretty()); -+ else if (_go->detailLevel() ==2) -+ *stream << TQString(",label=\"%3\\n%4 x\"") -+ .arg(SubCost(e.cost).pretty()) -+ .arg(SubCost(e.count).pretty()); -+ -+ *stream << TQString("];\n"); -+ } -+ -+ if (_go->showSkipped()) { -+ -+ // Create sum-edges for skipped edges -+ GraphEdge* e; -+ double costSum, countSum; -+ for ( nit = _nodeMap.begin(); -+ nit != _nodeMap.end(); ++nit ) { -+ GraphNode& n = *nit; -+ if (n.incl <= _realFuncLimit) continue; -+ -+ costSum = countSum = 0.0; -+ for (e=n.callers.first();e;e=n.callers.next()) { -+ costSum += e->cost; -+ countSum += e->count; -+ } -+ if (costSum > _realCallLimit) { -+ -+ TQPair p(0, n.function()); -+ e = &(_edgeMap[p]); -+ e->setCalling(p.second); -+ e->cost = costSum; -+ e->count = countSum; -+ -+ *stream << TQString(" R%1 [shape=point,label=\"\"];\n") -+ .arg((long)n.function(), 0, 16); -+ *stream << TQString(" R%1 -> F%2 [label=\"%3\\n%4 x\",weight=%5];\n") -+ .arg((long)n.function(), 0, 16) -+ .arg((long)n.function(), 0, 16) -+ .arg(SubCost(costSum).pretty()) -+ .arg(SubCost(countSum).pretty()) -+ .arg((int)log(costSum)); -+ } -+ -+ costSum = countSum = 0.0; -+ for (e=n.callings.first();e;e=n.callings.next()) { -+ costSum += e->cost; -+ countSum += e->count; -+ } -+ if (costSum > _realCallLimit) { -+ -+ TQPair p(n.function(), 0); -+ e = &(_edgeMap[p]); -+ e->setCaller(p.first); -+ e->cost = costSum; -+ e->count = countSum; -+ -+ *stream << TQString(" S%1 [shape=point,label=\"\"];\n") -+ .arg((long)n.function(), 0, 16); -+ *stream << TQString(" F%1 -> S%2 [label=\"%3\\n%4 x\",weight=%5];\n") -+ .arg((long)n.function(), 0, 16) -+ .arg((long)n.function(), 0, 16) -+ .arg(SubCost(costSum).pretty()) -+ .arg(SubCost(countSum).pretty()) -+ .arg((int)log(costSum)); -+ } -+ } -+ } -+ -+ // clear edges here completely. -+ // Visible edges are inserted again on parsing in CallGraphView::refresh -+ for ( nit = _nodeMap.begin(); -+ nit != _nodeMap.end(); ++nit ) { -+ GraphNode& n = *nit; -+ n.callers.clear(); -+ n.callings.clear(); -+ n.callerSet.clear(); -+ n.callingSet.clear(); -+ } -+ -+ *stream << "}\n"; -+ -+ if (_tmpFile) { -+ _tmpFile->close(); -+ } -+ else { -+ file->close(); -+ delete file; -+ delete stream; -+ } -+} -+ -+void GraphExporter::sortEdges() -+{ -+ GraphNodeMap::Iterator nit; -+ for ( nit = _nodeMap.begin(); -+ nit != _nodeMap.end(); ++nit ) { -+ GraphNode& n = *nit; -+ -+ n.callers.sort(); -+ n.callings.sort(); -+ } -+} -+ -+TraceFunction* GraphExporter::toFunc(TQString s) -+{ -+ if (s[0] != 'F') return 0; -+ bool ok; -+ TraceFunction* f = (TraceFunction*) s.mid(1).toULong(&ok, 16); -+ if (!ok) return 0; -+ -+ return f; -+} -+ -+GraphNode* GraphExporter::node(TraceFunction* f) -+{ -+ if (!f) return 0; -+ -+ GraphNodeMap::Iterator it = _nodeMap.find(f); -+ if (it == _nodeMap.end()) return 0; -+ -+ return &(*it); -+} -+ -+GraphEdge* GraphExporter::edge(TraceFunction* f1, TraceFunction* f2) -+{ -+ GraphEdgeMap::Iterator it = _edgeMap.find(tqMakePair(f1, f2)); -+ if (it == _edgeMap.end()) return 0; -+ -+ return &(*it); -+} -+ -+ -+/** -+ * We do a DFS and don't stop on already visited nodes/edges, -+ * but add up costs. We only stop if limits/max depth is reached. -+ * -+ * For a node/edge, it can happen that the first time visited the -+ * cost will below the limit, so the search is stopped. -+ * If on a further visit of the node/edge the limit is reached, -+ * we use the whole node/edge cost and continue search. -+ */ -+void GraphExporter::buildGraph(TraceFunction* f, int d, -+ bool toCallings, double factor) -+{ -+#if DEBUG_GRAPH -+ kdDebug() << "buildGraph(" << f->prettyName() << "," << d << "," << factor -+ << ") [to " << (toCallings ? "Callings":"Callers") << "]" << endl; -+#endif -+ -+ double oldIncl = 0.0; -+ GraphNode& n = _nodeMap[f]; -+ if (n.function() == 0) { -+ n.setFunction(f); -+ } -+ else -+ oldIncl = n.incl; -+ -+ double incl = f->inclusive()->subCost(_costType) * factor; -+ n.incl += incl; -+ n.self += f->subCost(_costType) * factor; -+ if (0) qDebug(" Added Incl. %f, now %f", incl, n.incl); -+ -+ // A negative depth limit means "unlimited" -+ int maxDepth = toCallings ? _go->maxCallingDepth() : _go->maxCallerDepth(); -+ if ((maxDepth>=0) && (d >= maxDepth)) { -+ if (0) qDebug(" Cutoff, max depth reached"); -+ return; -+ } -+ -+ // if we just reached the limit by summing, do a DFS -+ // from here with full incl. cost because of previous cutoffs -+ if ((n.incl >= _realFuncLimit) && (oldIncl < _realFuncLimit)) incl = n.incl; -+ -+ if (f->cycle()) { -+ // for cycles members, we never stop on first visit, but always on 2nd -+ // note: a 2nd visit never should happen, as we don't follow inner-cycle -+ // calls -+ if (oldIncl > 0.0) { -+ if (0) qDebug(" Cutoff, 2nd visit to Cycle Member"); -+ // and takeback cost addition, as it's added twice -+ n.incl = oldIncl; -+ n.self -= f->subCost(_costType) * factor; -+ return; -+ } -+ } -+ else if (incl <= _realFuncLimit) { -+ if (0) qDebug(" Cutoff, below limit"); -+ return; -+ } -+ -+ TraceCall* call; -+ TraceFunction* f2; -+ -+ -+ // on entering a cycle, only go the FunctionCycle -+ TraceCallList l = toCallings ? -+ f->callings(false) : f->callers(false); -+ -+ for (call=l.first();call;call=l.next()) { -+ -+ f2 = toCallings ? call->called(false) : call->caller(false); -+ -+ double count = call->callCount() * factor; -+ double cost = call->subCost(_costType) * factor; -+ -+ // ignore function calls with absolute cost < 3 per call -+ // No: This would skip a lot of functions e.g. with L2 cache misses -+ // if (count>0.0 && (cost/count < 3)) continue; -+ -+ double oldCost = 0.0; -+ TQPair p(toCallings ? f:f2, -+ toCallings ? f2:f); -+ GraphEdge& e = _edgeMap[p]; -+ if (e.call() == 0) { -+ e.setCall(call); -+ e.setCaller(p.first); -+ e.setCalling(p.second); -+ } -+ else -+ oldCost = e.cost; -+ -+ e.cost += cost; -+ e.count += count; -+ if (0) qDebug(" Edge to %s, added cost %f, now %f", -+ f2->prettyName().ascii(), cost, e.cost); -+ -+ // if this call goes into a FunctionCycle, we also show the real call -+ if (f2->cycle() == f2) { -+ TraceFunction* realF; -+ realF = toCallings ? call->called(true) : call->caller(true); -+ TQPair realP(toCallings ? f:realF, -+ toCallings ? realF:f); -+ GraphEdge& e = _edgeMap[realP]; -+ if (e.call() == 0) { -+ e.setCall(call); -+ e.setCaller(realP.first); -+ e.setCalling(realP.second); -+ } -+ e.cost += cost; -+ e.count += count; -+ } -+ -+ // - don't do a DFS on calls in recursion/cycle -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ if (toCallings) { -+ GraphEdgeSet::Iterator it = n.callingSet.find(&e); -+ if (it == n.callingSet.end()) { -+ n.callings.append(&e); -+ n.callingSet.insert(&e, 1 ); -+ } -+ } -+ else { -+ GraphEdgeSet::Iterator it = n.callerSet.find(&e); -+ if (it == n.callerSet.end()) { -+ n.callers.append(&e); -+ n.callerSet.insert(&e, 1 ); -+ } -+ } -+ -+ // if we just reached the call limit (=func limit by summing, do a DFS -+ // from here with full incl. cost because of previous cutoffs -+ if ((e.cost >= _realCallLimit) && (oldCost < _realCallLimit)) cost = e.cost; -+ if (cost < _realCallLimit) { -+ if (0) qDebug(" Edge Cutoff, limit not reached"); -+ continue; -+ } -+ -+ SubCost s; -+ if (call->inCycle()) -+ s = f2->cycle()->inclusive()->subCost(_costType); -+ else -+ s = f2->inclusive()->subCost(_costType); -+ SubCost v = call->subCost(_costType); -+ buildGraph(f2, d+1, toCallings, factor * v / s); -+ } -+} -+ -+ -+// -+// PannerView -+// -+PannerView::PannerView(TQWidget * parent, const char * name) -+ : TQCanvasView(parent, name, WNoAutoErase | WStaticContents) -+{ -+ _movingZoomRect = false; -+ -+ // why doesn't this avoid flicker ? -+ viewport()->setBackgroundMode(TQt::NoBackground); -+ setBackgroundMode(TQt::NoBackground); -+} -+ -+void PannerView::setZoomRect(TQRect r) -+{ -+ TQRect oldRect = _zoomRect; -+ _zoomRect = r; -+ updateContents(oldRect); -+ updateContents(_zoomRect); -+} -+ -+void PannerView::drawContents(TQPainter * p, int clipx, int clipy, int clipw, int cliph) -+{ -+ // save/restore around TQCanvasView::drawContents seems to be needed -+ // for QT 3.0 to get the red rectangle drawn correct -+ p->save(); -+ TQCanvasView::drawContents(p,clipx,clipy,clipw,cliph); -+ p->restore(); -+ if (_zoomRect.isValid()) { -+ p->setPen(red.dark()); -+ p->drawRect(_zoomRect); -+ p->setPen(red); -+ p->drawRect(TQRect(_zoomRect.x()+1, _zoomRect.y()+1, -+ _zoomRect.width()-2, _zoomRect.height()-2)); -+ } -+} -+ -+void PannerView::contentsMousePressEvent(TQMouseEvent* e) -+{ -+ if (_zoomRect.isValid()) { -+ if (!_zoomRect.contains(e->pos())) -+ emit zoomRectMoved(e->pos().x() - _zoomRect.center().x(), -+ e->pos().y() - _zoomRect.center().y()); -+ -+ _movingZoomRect = true; -+ _lastPos = e->pos(); -+ } -+} -+ -+void PannerView::contentsMouseMoveEvent(TQMouseEvent* e) -+{ -+ if (_movingZoomRect) { -+ emit zoomRectMoved(e->pos().x() - _lastPos.x(), e->pos().y() - _lastPos.y()); -+ _lastPos = e->pos(); -+ } -+} -+ -+void PannerView::contentsMouseReleaseEvent(TQMouseEvent*) -+{ -+ _movingZoomRect = false; -+ emit zoomRectMoveFinished(); -+} -+ -+ -+ -+ -+ -+// -+// CanvasNode -+// -+ -+CanvasNode::CanvasNode(CallGraphView* v, GraphNode* n, -+ int x, int y, int w, int h, TQCanvas* c) -+ : TQCanvasRectangle(x, y, w, h, c), _node(n), _view(v) -+{ -+ setPosition(0, DrawParams::TopCenter); -+ setPosition(1, DrawParams::BottomCenter); -+ -+ updateGroup(); -+ -+ if (!_node || !_view) return; -+ -+ if (_node->function()) -+ setText(0, _node->function()->prettyName()); -+ -+ TraceCost* totalCost; -+ if (_view->topLevel()->showExpanded()) { -+ if (_view->activeFunction()) { -+ if (_view->activeFunction()->cycle()) -+ totalCost = _view->activeFunction()->cycle()->inclusive(); -+ else -+ totalCost = _view->activeFunction()->inclusive(); -+ } -+ else -+ totalCost = (TraceCost*) _view->activeItem(); -+ } -+ else -+ totalCost = _view->TraceItemView::data(); -+ double total = totalCost->subCost(_view->costType()); -+ double inclP = 100.0 * n->incl / total; -+ if (_view->topLevel()->showPercentage()) -+ setText(1, TQString("%1 %") -+ .arg(inclP, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(1, SubCost(n->incl).pretty()); -+ setPixmap(1, percentagePixmap(25,10,(int)(inclP+.5), TQt::blue, true)); -+} -+ -+void CanvasNode::setSelected(bool s) -+{ -+ StoredDrawParams::setSelected(s); -+ update(); -+} -+ -+void CanvasNode::updateGroup() -+{ -+ if (!_view || !_node) return; -+ -+ TQColor c = Configuration::functionColor(_view->groupType(), -+ _node->function()); -+ setBackColor(c); -+ update(); -+} -+ -+void CanvasNode::drawShape(TQPainter& p) -+{ -+ TQRect r = rect(), origRect = r; -+ -+ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); -+ -+ RectDrawing d(r); -+ d.drawBack(&p, this); -+ r.setRect(r.x()+2, r.y()+2, r.width()-4, r.height()-4); -+ -+ if (StoredDrawParams::selected() && _view->hasFocus()) { -+ _view->style().tqdrawPrimitive( TQStyle::PE_FocusRect, &p, r, -+ _view->colorGroup()); -+ } -+ -+ // draw afterwards to always get a frame even when zoomed -+ p.setPen(StoredDrawParams::selected() ? red : black); -+ p.drawRect(origRect); -+ -+ d.setRect(r); -+ d.drawField(&p, 0, this); -+ d.drawField(&p, 1, this); -+} -+ -+ -+// -+// CanvasEdgeLabel -+// -+ -+CanvasEdgeLabel::CanvasEdgeLabel(CallGraphView* v, CanvasEdge* ce, -+ int x, int y, int w, int h, TQCanvas* c) -+ : TQCanvasRectangle(x, y, w, h, c), _ce(ce), _view(v) -+{ -+ GraphEdge* e = ce->edge(); -+ if (!e) return; -+ -+ setPosition(1, DrawParams::TopCenter); -+ setText(1, TQString("%1 x").arg(SubCost(e->count).pretty())); -+ -+ setPosition(0, DrawParams::BottomCenter); -+ -+ TraceCost* totalCost; -+ if (_view->topLevel()->showExpanded()) { -+ if (_view->activeFunction()) { -+ if (_view->activeFunction()->cycle()) -+ totalCost = _view->activeFunction()->cycle()->inclusive(); -+ else -+ totalCost = _view->activeFunction()->inclusive(); -+ } -+ else -+ totalCost = (TraceCost*) _view->activeItem(); -+ } -+ else -+ totalCost = _view->TraceItemView::data(); -+ double total = totalCost->subCost(_view->costType()); -+ double inclP = 100.0 * e->cost / total; -+ if (_view->topLevel()->showPercentage()) -+ setText(0, TQString("%1 %") -+ .arg(inclP, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(0, SubCost(e->cost).pretty()); -+ setPixmap(0, percentagePixmap(25,10,(int)(inclP+.5), TQt::blue, true)); -+ -+ if (e->call() && (e->call()->isRecursion() || e->call()->inCycle())) { -+ TQString icon = "undo"; -+ KIconLoader* loader = KApplication::kApplication()->iconLoader(); -+ TQPixmap p= loader->loadIcon(icon, KIcon::Small, 0, -+ KIcon::DefaultState, 0, true); -+ setPixmap(0, p); -+ } -+} -+ -+void CanvasEdgeLabel::drawShape(TQPainter& p) -+{ -+ TQRect r = rect(); -+ //p.setPen(blue); -+ //p.drawRect(r); -+ RectDrawing d(r); -+ d.drawField(&p, 0, this); -+ d.drawField(&p, 1, this); -+} -+ -+// -+// CanvasEdgeArrow -+ -+CanvasEdgeArrow::CanvasEdgeArrow(CanvasEdge* ce, TQCanvas* c) -+ : TQCanvasPolygon(c), _ce(ce) -+{} -+ -+void CanvasEdgeArrow::drawShape(TQPainter& p) -+{ -+ if (_ce->isSelected()) p.setBrush(TQt::red); -+ -+ TQCanvasPolygon::drawShape(p); -+} -+ -+// -+// CanvasEdge -+// -+ -+CanvasEdge::CanvasEdge(GraphEdge* e, TQCanvas* c) -+ : TQCanvasSpline(c), _edge(e) -+{ -+ _label = 0; -+ _arrow = 0; -+} -+ -+void CanvasEdge::setSelected(bool s) -+{ -+ TQCanvasItem::setSelected(s); -+ update(); -+ if (_arrow) _arrow->setSelected(s); -+} -+ -+TQPointArray CanvasEdge::areaPoints() const -+{ -+ int minX = poly[0].x(), minY = poly[0].y(); -+ int maxX = minX, maxY = minY; -+ int i; -+ -+ if (0) qDebug("CanvasEdge::areaPoints\n P 0: %d/%d", minX, minY); -+ int len = poly.count(); -+ for (i=1;i maxX) maxX = poly[i].x(); -+ if (poly[i].y() > maxY) maxY = poly[i].y(); -+ if (0) qDebug(" P %d: %d/%d", i, poly[i].x(), poly[i].y()); -+ } -+ TQPointArray a = poly.copy(), b = poly.copy(); -+ if (minX == maxX) { -+ a.translate(-2, 0); -+ b.translate(2, 0); -+ } -+ else { -+ a.translate(0, -2); -+ b.translate(0, 2); -+ } -+ a.resize(2*len); -+ for (i=0;iv2) { -+ r.setRect(r.x()-d, r.y()-d, r.width()+2*d, r.height()+2*d); -+ v /= f; -+ } -+ -+ _p = new TQPixmap(r.size()); -+ _p->fill(TQt::white); -+ TQPainter p(_p); -+ p.setPen(TQt::NoPen); -+ -+ r.moveBy(-r.x(), -r.y()); -+ -+ while (vwidth(), _p->height()); -+ move(n->rect().center().x()-_p->width()/2, -+ n->rect().center().y()-_p->height()/2); -+} -+ -+ -+void CanvasFrame::drawShape(TQPainter& p) -+{ -+ p.drawPixmap( int(x()), int(y()), *_p ); -+} -+ -+ -+ -+ -+// -+// Tooltips for CallGraphView -+// -+ -+class CallGraphTip: public TQToolTip -+{ -+public: -+ CallGraphTip( TQWidget* p ):TQToolTip(p) {} -+ -+protected: -+ void maybeTip( const TQPoint & ); -+}; -+ -+void CallGraphTip::maybeTip( const TQPoint& pos ) -+{ -+ if (!parentWidget()->inherits( "CallGraphView" )) return; -+ CallGraphView* cgv = (CallGraphView*)parentWidget(); -+ -+ TQPoint cPos = cgv->viewportToContents(pos); -+ -+ if (0) qDebug("CallGraphTip for (%d/%d) -> (%d/%d) ?", -+ pos.x(), pos.y(), cPos.x(), cPos.y()); -+ -+ TQCanvasItemList l = cgv->canvas()->collisions(cPos); -+ if (l.count() == 0) return; -+ TQCanvasItem* i = l.first(); -+ -+ if (i->rtti() == CANVAS_NODE) { -+ CanvasNode* cn = (CanvasNode*)i; -+ GraphNode* n = cn->node(); -+ if (0) qDebug("CallGraphTip: Mouse on Node '%s'", -+ n->function()->prettyName().ascii()); -+ -+ TQString tipStr = TQString("%1 (%2)").arg(cn->text(0)).arg(cn->text(1)); -+ TQPoint vPosTL = cgv->contentsToViewport(i->boundingRect().topLeft()); -+ TQPoint vPosBR = cgv->contentsToViewport(i->boundingRect().bottomRight()); -+ tip(TQRect(vPosTL, vPosBR), tipStr); -+ -+ return; -+ } -+ -+ // redirect from label / arrow to edge -+ if (i->rtti() == CANVAS_EDGELABEL) -+ i = ((CanvasEdgeLabel*)i)->canvasEdge(); -+ if (i->rtti() == CANVAS_EDGEARROW) -+ i = ((CanvasEdgeArrow*)i)->canvasEdge(); -+ -+ if (i->rtti() == CANVAS_EDGE) { -+ CanvasEdge* ce = (CanvasEdge*)i; -+ GraphEdge* e = ce->edge(); -+ if (0) qDebug("CallGraphTip: Mouse on Edge '%s'", -+ e->prettyName().ascii()); -+ -+ TQString tipStr; -+ if (!ce->label()) -+ tipStr = e->prettyName(); -+ else -+ tipStr = TQString("%1 (%2)") -+ .arg(ce->label()->text(0)).arg(ce->label()->text(1)); -+ tip(TQRect(pos.x()-5,pos.y()-5,pos.x()+5,pos.y()+5), tipStr); -+ } -+} -+ -+ -+ -+ -+// -+// CallGraphView -+// -+CallGraphView::CallGraphView(TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQCanvasView(parent, name), TraceItemView(parentView) -+{ -+ _zoomPosition = DEFAULT_ZOOMPOS; -+ _lastAutoPosition = TopLeft; -+ -+ _canvas = 0; -+ _xMargin = _yMargin = 0; -+ _completeView = new PannerView(this); -+ _cvZoom = 1; -+ _selectedNode = 0; -+ _selectedEdge = 0; -+ -+ _exporter.setGraphOptions(this); -+ -+ _completeView->setVScrollBarMode(TQScrollView::AlwaysOff); -+ _completeView->setHScrollBarMode(TQScrollView::AlwaysOff); -+ _completeView->raise(); -+ _completeView->hide(); -+ -+ setFocusPolicy(TQ_StrongFocus); -+ setBackgroundMode(TQt::NoBackground); -+ -+ connect(this, TQT_SIGNAL(contentsMoving(int,int)), -+ this, TQT_SLOT(contentsMovingSlot(int,int))); -+ connect(_completeView, TQT_SIGNAL(zoomRectMoved(int,int)), -+ this, TQT_SLOT(zoomRectMoved(int,int))); -+ connect(_completeView, TQT_SIGNAL(zoomRectMoveFinished()), -+ this, TQT_SLOT(zoomRectMoveFinished())); -+ -+ TQWhatsThis::add( this, whatsThis() ); -+ -+ // tooltips... -+ _tip = new CallGraphTip(this); -+ -+ _renderProcess = 0; -+ _prevSelectedNode = 0; -+ connect(&_renderTimer, TQT_SIGNAL(timeout()), -+ this, TQT_SLOT(showRenderWarning())); -+} -+ -+CallGraphView::~CallGraphView() -+{ -+ delete _completeView; -+ delete _tip; -+ -+ if (_canvas) { -+ setCanvas(0); -+ delete _canvas; -+ } -+} -+ -+TQString CallGraphView::whatsThis() const -+{ -+ return i18n( "Call Graph around active Function" -+ "

Depending on configuration, this view shows " -+ "the call graph environment of the active function. " -+ "Note: the shown cost is only the cost which is " -+ "spent while the active function was actually running; " -+ "i.e. the cost shown for main() - if it's visible - should " -+ "be the same as the cost of the active function, as that's " -+ "the part of inclusive cost of main() spent while the active " -+ "function was running.

" -+ "

For cycles, blue call arrows indicate that this is an " -+ "artificial call added for correct drawing which " -+ "actually never happened.

" -+ "

If the graph is larger than the widget area, an overview " -+ "panner is shown in one edge. " -+ "There are similar visualization options to the " -+ "Call Treemap; the selected function is highlighted.

"); -+} -+ -+void CallGraphView::updateSizes(TQSize s) -+{ -+ if (!_canvas) return; -+ -+ if (s == TQSize(0,0)) s = size(); -+ -+ // the part of the canvas that should be visible -+ int cWidth = _canvas->width() - 2*_xMargin + 100; -+ int cHeight = _canvas->height() - 2*_yMargin + 100; -+ -+ // hide birds eye view if no overview needed -+ if (!_data || !_activeItem || -+ ((cWidth < s.width()) && cHeight < s.height())) { -+ _completeView->hide(); -+ return; -+ } -+ _completeView->show(); -+ -+ // first, assume use of 1/3 of width/height (possible larger) -+ double zoom = .33 * s.width() / cWidth; -+ if (zoom * cHeight < .33 * s.height()) zoom = .33 * s.height() / cHeight; -+ -+ // fit to widget size -+ if (cWidth * zoom > s.width()) zoom = s.width() / (double)cWidth; -+ if (cHeight * zoom > s.height()) zoom = s.height() / (double)cHeight; -+ -+ // scale to never use full height/width -+ zoom = zoom * 3/4; -+ -+ // at most a zoom of 1/3 -+ if (zoom > .33) zoom = .33; -+ -+ if (zoom != _cvZoom) { -+ _cvZoom = zoom; -+ if (0) qDebug("Canvas Size: %dx%d, Visible: %dx%d, Zoom: %f", -+ _canvas->width(), _canvas->height(), -+ cWidth, cHeight, zoom); -+ -+ TQWMatrix wm; -+ wm.scale( zoom, zoom ); -+ _completeView->setWorldMatrix(wm); -+ -+ // make it a little bigger to compensate for widget frame -+ _completeView->resize(int(cWidth * zoom) + 4, -+ int(cHeight * zoom) + 4); -+ -+ // update ZoomRect in completeView -+ contentsMovingSlot(contentsX(), contentsY()); -+ } -+ -+ _completeView->setContentsPos(int(zoom*(_xMargin-50)), -+ int(zoom*(_yMargin-50))); -+ -+ int cvW = _completeView->width(); -+ int cvH = _completeView->height(); -+ int x = width()- cvW - verticalScrollBar()->width() -2; -+ int y = height()-cvH - horizontalScrollBar()->height() -2; -+ TQPoint oldZoomPos = _completeView->pos(); -+ TQPoint newZoomPos = TQPoint(0,0); -+ ZoomPosition zp = _zoomPosition; -+ if (zp == Auto) { -+ TQPoint tl1Pos = viewportToContents(TQPoint(0,0)); -+ TQPoint tl2Pos = viewportToContents(TQPoint(cvW,cvH)); -+ TQPoint tr1Pos = viewportToContents(TQPoint(x,0)); -+ TQPoint tr2Pos = viewportToContents(TQPoint(x+cvW,cvH)); -+ TQPoint bl1Pos = viewportToContents(TQPoint(0,y)); -+ TQPoint bl2Pos = viewportToContents(TQPoint(cvW,y+cvH)); -+ TQPoint br1Pos = viewportToContents(TQPoint(x,y)); -+ TQPoint br2Pos = viewportToContents(TQPoint(x+cvW,y+cvH)); -+ int tlCols = _canvas->collisions(TQRect(tl1Pos,tl2Pos)).count(); -+ int trCols = _canvas->collisions(TQRect(tr1Pos,tr2Pos)).count(); -+ int blCols = _canvas->collisions(TQRect(bl1Pos,bl2Pos)).count(); -+ int brCols = _canvas->collisions(TQRect(br1Pos,br2Pos)).count(); -+ int minCols = tlCols; -+ zp = _lastAutoPosition; -+ switch(zp) { -+ case TopRight: minCols = trCols; break; -+ case BottomLeft: minCols = blCols; break; -+ case BottomRight: minCols = brCols; break; -+ default: -+ case TopLeft: minCols = tlCols; break; -+ } -+ if (minCols > tlCols) { minCols = tlCols; zp = TopLeft; } -+ if (minCols > trCols) { minCols = trCols; zp = TopRight; } -+ if (minCols > blCols) { minCols = blCols; zp = BottomLeft; } -+ if (minCols > brCols) { minCols = brCols; zp = BottomRight; } -+ -+ _lastAutoPosition = zp; -+ } -+ -+ switch(zp) { -+ case TopRight: -+ newZoomPos = TQPoint(x,0); -+ break; -+ case BottomLeft: -+ newZoomPos = TQPoint(0,y); -+ break; -+ case BottomRight: -+ newZoomPos = TQPoint(x,y); -+ break; -+ default: -+ break; -+ } -+ if (newZoomPos != oldZoomPos) _completeView->move(newZoomPos); -+} -+ -+void CallGraphView::focusInEvent(TQFocusEvent*) -+{ -+ if (!_canvas) return; -+ -+ if (_selectedNode && _selectedNode->canvasNode()) { -+ _selectedNode->canvasNode()->setSelected(true); // requests item update -+ _canvas->update(); -+ } -+} -+ -+void CallGraphView::focusOutEvent(TQFocusEvent* e) -+{ -+ // trigger updates as in focusInEvent -+ focusInEvent(e); -+} -+ -+void CallGraphView::keyPressEvent(TQKeyEvent* e) -+{ -+ if (!_canvas) { -+ e->ignore(); -+ return; -+ } -+ -+ if ((e->key() == Key_Return) || -+ (e->key() == Key_Space)) { -+ if (_selectedNode) -+ activated(_selectedNode->function()); -+ else if (_selectedEdge && _selectedEdge->call()) -+ activated(_selectedEdge->call()); -+ return; -+ } -+ -+ // move selected node/edge -+ if (!(e->state() & (ShiftButton | ControlButton)) && -+ (_selectedNode || _selectedEdge) && -+ ((e->key() == Key_Up) || -+ (e->key() == Key_Down) || -+ (e->key() == Key_Left) || -+ (e->key() == Key_Right))) { -+ -+ TraceFunction* f = 0; -+ TraceCall* c = 0; -+ -+ // rotate arrow key meaning for LeftRight layout -+ int key = e->key(); -+ if (_layout == LeftRight) { -+ switch(key) { -+ case Key_Up: key = Key_Left; break; -+ case Key_Down: key = Key_Right; break; -+ case Key_Left: key = Key_Up; break; -+ case Key_Right: key = Key_Down; break; -+ default: break; -+ } -+ } -+ -+ if (_selectedNode) { -+ if (key == Key_Up) c = _selectedNode->visibleCaller(); -+ if (key == Key_Down) c = _selectedNode->visibleCalling(); -+ if (key == Key_Right) f = _selectedNode->nextVisible(); -+ if (key == Key_Left) f = _selectedNode->priorVisible(); -+ } -+ else if (_selectedEdge) { -+ if (key == Key_Up) f = _selectedEdge->visibleCaller(); -+ if (key == Key_Down) f = _selectedEdge->visibleCalling(); -+ if (key == Key_Right) c = _selectedEdge->nextVisible(); -+ if (key == Key_Left) c = _selectedEdge->priorVisible(); -+ } -+ -+ if (c) selected(c); -+ if (f) selected(f); -+ return; -+ } -+ -+ // move canvas... -+ if (e->key() == Key_Home) -+ scrollBy(-_canvas->width(),0); -+ else if (e->key() == Key_End) -+ scrollBy(_canvas->width(),0); -+ else if (e->key() == Key_Prior) -+ scrollBy(0,-visibleHeight()/2); -+ else if (e->key() == Key_Next) -+ scrollBy(0,visibleHeight()/2); -+ else if (e->key() == Key_Left) -+ scrollBy(-visibleWidth()/10,0); -+ else if (e->key() == Key_Right) -+ scrollBy(visibleWidth()/10,0); -+ else if (e->key() == Key_Down) -+ scrollBy(0,visibleHeight()/10); -+ else if (e->key() == Key_Up) -+ scrollBy(0,-visibleHeight()/10); -+ else e->ignore(); -+} -+ -+void CallGraphView::resizeEvent(TQResizeEvent* e) -+{ -+ TQCanvasView::resizeEvent(e); -+ if (_canvas) updateSizes(e->size()); -+} -+ -+TraceItem* CallGraphView::canShow(TraceItem* i) -+{ -+ if (i) { -+ switch(i->type()) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ case TraceItem::Call: -+ return i; -+ default: -+ break; -+ } -+ } -+ return 0; -+} -+ -+void CallGraphView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == costType2Changed) return; -+ -+ if (changeType == selectedItemChanged) { -+ if (!_canvas) return; -+ -+ if (!_selectedItem) return; -+ -+ GraphNode* n = 0; -+ GraphEdge* e = 0; -+ if ((_selectedItem->type() == TraceItem::Function) || -+ (_selectedItem->type() == TraceItem::FunctionCycle)) { -+ n = _exporter.node((TraceFunction*)_selectedItem); -+ if (n == _selectedNode) return; -+ } -+ else if (_selectedItem->type() == TraceItem::Call) { -+ TraceCall* c = (TraceCall*)_selectedItem; -+ e = _exporter.edge(c->caller(false), c->called(false)); -+ if (e == _selectedEdge) return; -+ } -+ -+ // unselected any selected item -+ if (_selectedNode && _selectedNode->canvasNode()) { -+ _selectedNode->canvasNode()->setSelected(false); -+ } -+ _selectedNode = 0; -+ if (_selectedEdge && _selectedEdge->canvasEdge()) { -+ _selectedEdge->canvasEdge()->setSelected(false); -+ } -+ _selectedEdge = 0; -+ -+ // select -+ CanvasNode* sNode = 0; -+ if (n && n->canvasNode()) { -+ _selectedNode = n; -+ _selectedNode->canvasNode()->setSelected(true); -+ -+ if (!_isMoving) sNode = _selectedNode->canvasNode(); -+ } -+ if (e && e->canvasEdge()) { -+ _selectedEdge = e; -+ _selectedEdge->canvasEdge()->setSelected(true); -+ -+#if 0 // don't change position when selecting edge -+ if (!_isMoving) { -+ if (_selectedEdge->fromNode()) -+ sNode = _selectedEdge->fromNode()->canvasNode(); -+ if (!sNode && _selectedEdge->toNode()) -+ sNode = _selectedEdge->toNode()->canvasNode(); -+ } -+#endif -+ } -+ if (sNode) { -+ double x = sNode->x() + sNode->width()/2; -+ double y = sNode->y() + sNode->height()/2; -+ -+ ensureVisible(int(x),int(y), -+ sNode->width()/2+50, sNode->height()/2+50); -+ } -+ -+ _canvas->update(); -+ return; -+ } -+ -+ if (changeType == groupTypeChanged) { -+ if (!_canvas) return; -+ -+ if (_clusterGroups) { -+ refresh(); -+ return; -+ } -+ -+ TQCanvasItemList l = _canvas->allItems(); -+ TQCanvasItemList::iterator it; -+ for (it = l.begin();it != l.end(); ++it) -+ if ((*it)->rtti() == CANVAS_NODE) -+ ((CanvasNode*) (*it))->updateGroup(); -+ -+ _canvas->update(); -+ return; -+ } -+ -+ if (changeType & dataChanged) { -+ // invalidate old selection and graph part -+ _exporter.reset(_data, _activeItem, _costType, _groupType); -+ _selectedNode = 0; -+ _selectedEdge = 0; -+ } -+ -+ refresh(); -+} -+ -+void CallGraphView::clear() -+{ -+ if (!_canvas) return; -+ -+ delete _canvas; -+ _canvas = 0; -+ _completeView->setCanvas(0); -+ setCanvas(0); -+} -+ -+void CallGraphView::showText(TQString s) -+{ -+ clear(); -+ _renderTimer.stop(); -+ -+ _canvas = new TQCanvas(TQApplication::desktop()->width(), -+ TQApplication::desktop()->height()); -+ -+ TQCanvasText* t = new TQCanvasText(s, _canvas); -+ t->move(5, 5); -+ t->show(); -+ center(0,0); -+ setCanvas(_canvas); -+ _canvas->update(); -+ _completeView->hide(); -+} -+ -+void CallGraphView::showRenderWarning() -+{ -+ TQString s; -+ -+ if (_renderProcess) -+ s =i18n("Warning: a long lasting graph layouting is in progress.\n" -+ "Reduce node/edge limits for speedup.\n"); -+ else -+ s = i18n("Layouting stopped.\n"); -+ -+ s.append(i18n("The call graph has %1 nodes and %2 edges.\n") -+ .arg(_exporter.nodeCount()) -+ .arg(_exporter.edgeCount())); -+ -+ showText(s); -+} -+ -+void CallGraphView::stopRendering() -+{ -+ if (!_renderProcess) return; -+ -+ _renderProcess->kill(); -+ delete _renderProcess; -+ _renderProcess = 0; -+ _unparsedOutput = TQString(); -+ -+ _renderTimer.start(200, true); -+} -+ -+void CallGraphView::refresh() -+{ -+ // trigger start of background rendering -+ if (_renderProcess) stopRendering(); -+ -+ // we want to keep a selected node item at the same global position -+ _prevSelectedNode = _selectedNode; -+ _prevSelectedPos = TQPoint(-1,-1); -+ if (_selectedNode) { -+ TQPoint center = _selectedNode->canvasNode()->boundingRect().center(); -+ _prevSelectedPos = contentsToViewport(center); -+ } -+ -+ if (!_data || !_activeItem) { -+ showText(i18n("No item activated for which to draw the call graph.")); -+ return; -+ } -+ -+ TraceItem::CostType t = _activeItem->type(); -+ switch(t) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ case TraceItem::Call: -+ break; -+ default: -+ showText(i18n("No call graph can be drawn for the active item.")); -+ return; -+ } -+ -+ if (1) kdDebug() << "CallGraphView::refresh" << endl; -+ -+ _selectedNode = 0; -+ _selectedEdge = 0; -+ _exporter.reset(_data, _activeItem, _costType, _groupType); -+ _exporter.writeDot(); -+ -+ _renderProcess = new TQProcess(TQT_TQOBJECT(this)); -+ if (_layout == GraphOptions::Circular) -+ _renderProcess->addArgument( "twopi" ); -+ else -+ _renderProcess->addArgument( "dot" ); -+ _renderProcess->addArgument(_exporter.filename()); -+ _renderProcess->addArgument( "-Tplain" ); -+ -+ connect( _renderProcess, TQT_SIGNAL(readyReadStdout()), -+ this, TQT_SLOT(readDotOutput()) ); -+ connect( _renderProcess, TQT_SIGNAL(processExited()), -+ this, TQT_SLOT(dotExited()) ); -+ -+ if (1) kdDebug() << "Running '" -+ << _renderProcess->arguments().join(" ") -+ << "'..." << endl; -+ -+ if ( !_renderProcess->start() ) { -+ TQString e = i18n("No call graph is available because the following\n" -+ "command cannot be run:\n'%1'\n") -+ .arg(_renderProcess->arguments().join(" ")); -+ e += i18n("Please check that 'dot' is installed (package GraphViz)."); -+ showText(e); -+ -+ delete _renderProcess; -+ _renderProcess = 0; -+ -+ return; -+ } -+ -+ _unparsedOutput = TQString(); -+ -+ // layouting of more than seconds is dubious -+ _renderTimer.start(1000, true); -+} -+ -+void CallGraphView::readDotOutput() -+{ -+ _unparsedOutput.append( _renderProcess->readStdout() ); -+} -+ -+void CallGraphView::dotExited() -+{ -+ TQString line, cmd; -+ CanvasNode *rItem; -+ TQCanvasEllipse* eItem; -+ CanvasEdge* sItem; -+ CanvasEdgeLabel* lItem; -+ TQTextStream* dotStream; -+ double scale = 1.0, scaleX = 1.0, scaleY = 1.0; -+ double dotWidth, dotHeight; -+ GraphNode* activeNode = 0; -+ GraphEdge* activeEdge = 0; -+ -+ _renderTimer.stop(); -+ viewport()->setUpdatesEnabled(false); -+ clear(); -+ dotStream = new TQTextStream(_unparsedOutput, IO_ReadOnly); -+ -+ int lineno = 0; -+ while (1) { -+ line = dotStream->readLine(); -+ if (line.isNull()) break; -+ lineno++; -+ if (line.isEmpty()) continue; -+ -+ TQTextStream lineStream(line, IO_ReadOnly); -+ lineStream >> cmd; -+ -+ if (0) qDebug("%s:%d - line '%s', cmd '%s'", -+ _exporter.filename().ascii(), lineno, -+ line.ascii(), cmd.ascii()); -+ -+ if (cmd == "stop") break; -+ -+ if (cmd == "graph") { -+ TQString dotWidthString, dotHeightString; -+ lineStream >> scale >> dotWidthString >> dotHeightString; -+ dotWidth = dotWidthString.toDouble(); -+ dotHeight = dotHeightString.toDouble(); -+ -+ if (_detailLevel == 0) { scaleX = scale * 70; scaleY = scale * 40; } -+ else if (_detailLevel == 1) { scaleX = scale * 80; scaleY = scale * 70; } -+ else { scaleX = scale * 60; scaleY = scale * 100; } -+ -+ if (!_canvas) { -+ int w = (int)(scaleX * dotWidth); -+ int h = (int)(scaleY * dotHeight); -+ -+ // We use as minimum canvas size the desktop size. -+ // Otherwise, the canvas would have to be resized on widget resize. -+ _xMargin = 50; -+ if (w < TQApplication::desktop()->width()) -+ _xMargin += (TQApplication::desktop()->width()-w)/2; -+ -+ _yMargin = 50; -+ if (h < TQApplication::desktop()->height()) -+ _yMargin += (TQApplication::desktop()->height()-h)/2; -+ -+ _canvas = new TQCanvas(int(w+2*_xMargin), int(h+2*_yMargin)); -+ -+#if DEBUG_GRAPH -+ kdDebug() << _exporter.filename().ascii() << ":" << lineno -+ << " - graph (" << dotWidth << " x " << dotHeight -+ << ") => (" << w << " x " << h << ")" << endl; -+#endif -+ } -+ else -+ kdWarning() << "Ignoring 2nd 'graph' from dot (" -+ << _exporter.filename() << ":" << lineno << ")" << endl; -+ continue; -+ } -+ -+ if ((cmd != "node") && (cmd != "edge")) { -+ kdWarning() << "Ignoring unknown command '" << cmd << "' from dot (" -+ << _exporter.filename() << ":" << lineno << ")" << endl; -+ continue; -+ } -+ -+ if (_canvas == 0) { -+ kdWarning() << "Ignoring '" << cmd << "' without 'graph' from dot (" -+ << _exporter.filename() << ":" << lineno << ")" << endl; -+ continue; -+ } -+ -+ if (cmd == "node") { -+ // x, y are centered in node -+ TQString nodeName, label, nodeX, nodeY, nodeWidth, nodeHeight; -+ double x, y, width, height; -+ lineStream >> nodeName >> nodeX >> nodeY >> nodeWidth >> nodeHeight; -+ x = nodeX.toDouble(); -+ y = nodeY.toDouble(); -+ width = nodeWidth.toDouble(); -+ height = nodeHeight.toDouble(); -+ -+ GraphNode* n = _exporter.node(_exporter.toFunc(nodeName)); -+ -+ int xx = (int)(scaleX * x + _xMargin); -+ int yy = (int)(scaleY * (dotHeight - y) + _yMargin); -+ int w = (int)(scaleX * width); -+ int h = (int)(scaleY * height); -+ -+#if DEBUG_GRAPH -+ kdDebug() << _exporter.filename() << ":" << lineno -+ << " - node '" << nodeName << "' ( " -+ << x << "/" << y << " - " -+ << width << "x" << height << " ) => (" -+ << xx-w/2 << "/" << yy-h/2 << " - " -+ << w << "x" << h << ")" << endl; -+#endif -+ -+ -+ // Unnamed nodes with collapsed edges (with 'R' and 'S') -+ if (nodeName[0] == 'R' || nodeName[0] == 'S') { -+ w = 10, h = 10; -+ eItem = new TQCanvasEllipse(w, h, _canvas); -+ eItem->move(xx, yy); -+ eItem->setBrush(TQt::gray); -+ eItem->setZ(1.0); -+ eItem->show(); -+ continue; -+ } -+ -+ if (!n) { -+ qDebug("Warning: Unknown function '%s' ?!", nodeName.ascii()); -+ continue; -+ } -+ n->setVisible(true); -+ -+ rItem = new CanvasNode(this, n, xx-w/2, yy-h/2, w, h, _canvas); -+ n->setCanvasNode(rItem); -+ -+ if (n) { -+ if (n->function() == activeItem()) activeNode = n; -+ if (n->function() == selectedItem()) _selectedNode = n; -+ rItem->setSelected(n == _selectedNode); -+ } -+ -+ rItem->setZ(1.0); -+ rItem->show(); -+ -+ continue; -+ } -+ -+ // edge -+ -+ TQString node1Name, node2Name, label, edgeX, edgeY; -+ double x, y; -+ TQPointArray pa; -+ int points, i; -+ lineStream >> node1Name >> node2Name >> points; -+ -+ GraphEdge* e = _exporter.edge(_exporter.toFunc(node1Name), -+ _exporter.toFunc(node2Name)); -+ if (!e) { -+ kdWarning() << "Unknown edge '" << node1Name << "'-'" -+ << node2Name << "' from dot (" -+ << _exporter.filename() << ":" << lineno << ")" << endl; -+ continue; -+ } -+ e->setVisible(true); -+ if (e->fromNode()) e->fromNode()->callings.append(e); -+ if (e->toNode()) e->toNode()->callers.append(e); -+ -+ if (0) qDebug(" Edge with %d points:", points); -+ -+ pa.resize(points); -+ for (i=0;i> edgeX >> edgeY; -+ x = edgeX.toDouble(); -+ y = edgeY.toDouble(); -+ -+ int xx = (int)(scaleX * x + _xMargin); -+ int yy = (int)(scaleY * (dotHeight - y) + _yMargin); -+ -+ if (0) qDebug(" P %d: ( %f / %f ) => ( %d / %d)", -+ i, x, y, xx, yy); -+ -+ pa.setPoint(i, xx, yy); -+ } -+ if (i < points) { -+ qDebug("CallGraphView: Can't read %d spline points (%s:%d)", -+ points, _exporter.filename().ascii(), lineno); -+ continue; -+ } -+ -+ // calls into/out of cycles are special: make them blue -+ TQColor arrowColor = TQt::black; -+ TraceFunction* caller = e->fromNode() ? e->fromNode()->function() : 0; -+ TraceFunction* called = e->toNode() ? e->toNode()->function() : 0; -+ if ( (caller && (caller->cycle() == caller)) || -+ (called && (called->cycle() == called)) ) arrowColor = TQt::blue; -+ -+ sItem = new CanvasEdge(e, _canvas); -+ e->setCanvasEdge(sItem); -+ sItem->setControlPoints(pa, false); -+ sItem->setPen(TQPen(arrowColor, 1 /*(int)log(log(e->cost))*/ )); -+ sItem->setZ(0.5); -+ sItem->show(); -+ -+ if (e->call() == selectedItem()) _selectedEdge = e; -+ if (e->call() == activeItem()) activeEdge = e; -+ sItem->setSelected(e == _selectedEdge); -+ -+ // Arrow head -+ TQPoint arrowDir; -+ int indexHead = -1; -+ -+ // check if head is at start of spline... -+ // this is needed because dot always gives points from top to bottom -+ CanvasNode* fromNode = e->fromNode() ? e->fromNode()->canvasNode() : 0; -+ if (fromNode) { -+ TQPoint toCenter = fromNode->rect().center(); -+ int dx0 = pa.point(0).x() - toCenter.x(); -+ int dy0 = pa.point(0).y() - toCenter.y(); -+ int dx1 = pa.point(points-1).x() - toCenter.x(); -+ int dy1 = pa.point(points-1).y() - toCenter.y(); -+ if (dx0*dx0+dy0*dy0 > dx1*dx1+dy1*dy1) { -+ // start of spline is nearer to call target node -+ indexHead=-1; -+ while(arrowDir.isNull() && (indexHead1)) { -+ indexHead--; -+ arrowDir = pa.point(indexHead) - pa.point(indexHead-1); -+ } -+ } -+ -+ if (!arrowDir.isNull()) { -+ // arrow around pa.point(indexHead) with direction arrowDir -+ arrowDir *= 10.0/sqrt(double(arrowDir.x()*arrowDir.x() + -+ arrowDir.y()*arrowDir.y())); -+ TQPointArray a(3); -+ a.setPoint(0, pa.point(indexHead) + arrowDir); -+ a.setPoint(1, pa.point(indexHead) + TQPoint(arrowDir.y()/2, -+ -arrowDir.x()/2)); -+ a.setPoint(2, pa.point(indexHead) + TQPoint(-arrowDir.y()/2, -+ arrowDir.x()/2)); -+ -+ if (0) qDebug(" Arrow: ( %d/%d, %d/%d, %d/%d)", -+ a.point(0).x(), a.point(0).y(), -+ a.point(1).x(), a.point(1).y(), -+ a.point(2).x(), a.point(2).y()); -+ -+ CanvasEdgeArrow* aItem = new CanvasEdgeArrow(sItem,_canvas); -+ aItem->setPoints(a); -+ aItem->setBrush(arrowColor); -+ aItem->setZ(1.5); -+ aItem->show(); -+ -+ sItem->setArrow(aItem); -+ } -+ -+ if (lineStream.atEnd()) continue; -+ -+ // parse quoted label -+ TQChar c; -+ lineStream >> c; -+ while (c.isSpace()) lineStream >> c; -+ if (c != '\"') { -+ lineStream >> label; -+ label = c + label; -+ } -+ else { -+ lineStream >> c; -+ while(!c.isNull() && (c != '\"')) { -+ //if (c == '\\') lineStream >> c; -+ -+ label += c; -+ lineStream >> c; -+ } -+ } -+ lineStream >> edgeX >> edgeY; -+ x = edgeX.toDouble(); -+ y = edgeY.toDouble(); -+ -+ int xx = (int)(scaleX * x + _xMargin); -+ int yy = (int)(scaleY * (dotHeight - y) + _yMargin); -+ -+ if (0) qDebug(" Label '%s': ( %f / %f ) => ( %d / %d)", -+ label.ascii(), x, y, xx, yy); -+ -+ // Fixed Dimensions for Label: 100 x 40 -+ int w = 100; -+ int h = _detailLevel * 20; -+ lItem = new CanvasEdgeLabel(this, sItem, xx-w/2, yy-h/2, w, h, _canvas); -+ // edge labels above nodes -+ lItem->setZ(1.5); -+ sItem->setLabel(lItem); -+ if (h>0) lItem->show(); -+ -+ } -+ delete dotStream; -+ -+ // for keyboard navigation -+ // TODO: Edge sorting. Better keep left-to-right edge order from dot now -+ // _exporter.sortEdges(); -+ -+ if (!_canvas) { -+ _canvas = new TQCanvas(size().width(),size().height()); -+ TQString s = i18n("Error running the graph layouting tool.\n"); -+ s += i18n("Please check that 'dot' is installed (package GraphViz)."); -+ TQCanvasText* t = new TQCanvasText(s, _canvas); -+ t->move(5, 5); -+ t->show(); -+ center(0,0); -+ } -+ else if (!activeNode && !activeEdge) { -+ TQString s = i18n("There is no call graph available for function\n" -+ "\t'%1'\n" -+ "because it has no cost of the selected event type."); -+ TQCanvasText* t = new TQCanvasText(s.arg(_activeItem->name()), _canvas); -+ // t->setTextFlags(TQt::AlignHCenter | TQt::AlignVCenter); -+ t->move(5,5); -+ t->show(); -+ center(0,0); -+ } -+ -+ _completeView->setCanvas(_canvas); -+ setCanvas(_canvas); -+ -+ // if we don't have a selection, or the old selection is not -+ // in visible graph, make active function selected for this view -+ if ((!_selectedNode || !_selectedNode->canvasNode()) && -+ (!_selectedEdge || !_selectedEdge->canvasEdge())) { -+ if (activeNode) { -+ _selectedNode = activeNode; -+ _selectedNode->canvasNode()->setSelected(true); -+ } -+ else if (activeEdge) { -+ _selectedEdge = activeEdge; -+ _selectedEdge->canvasEdge()->setSelected(true); -+ } -+ } -+ -+ CanvasNode* sNode = 0; -+ if (_selectedNode) -+ sNode = _selectedNode->canvasNode(); -+ else if (_selectedEdge) { -+ if (_selectedEdge->fromNode()) -+ sNode = _selectedEdge->fromNode()->canvasNode(); -+ if (!sNode && _selectedEdge->toNode()) -+ sNode = _selectedEdge->toNode()->canvasNode(); -+ } -+ if (sNode) { -+ int x = int(sNode->x() + sNode->width()/2); -+ int y = int(sNode->y() + sNode->height()/2); -+ -+ if (_prevSelectedNode) { -+ if (rect().contains(_prevSelectedPos)) -+ setContentsPos(x-_prevSelectedPos.x(), -+ y-_prevSelectedPos.y()); -+ else -+ ensureVisible(x,y, -+ sNode->width()/2+50, sNode->height()/2+50); -+ } -+ else center(x,y); -+ } -+ -+ if (activeNode) { -+ CanvasNode* cn = activeNode->canvasNode(); -+ CanvasFrame* f = new CanvasFrame(cn, _canvas); -+ f->setZ(-1); -+ f->show(); -+ } -+ -+ _cvZoom = 0; -+ updateSizes(); -+ -+ _canvas->update(); -+ viewport()->setUpdatesEnabled(true); -+ -+ delete _renderProcess; -+ _renderProcess = 0; -+} -+ -+void CallGraphView::contentsMovingSlot(int x, int y) -+{ -+ TQRect z(int(x * _cvZoom), int(y * _cvZoom), -+ int(visibleWidth() * _cvZoom)-1, int(visibleHeight() * _cvZoom)-1); -+ if (0) qDebug("moving: (%d,%d) => (%d/%d - %dx%d)", -+ x, y, z.x(), z.y(), z.width(), z.height()); -+ _completeView->setZoomRect(z); -+} -+ -+void CallGraphView::zoomRectMoved(int dx, int dy) -+{ -+ if (leftMargin()>0) dx = 0; -+ if (topMargin()>0) dy = 0; -+ scrollBy(int(dx/_cvZoom),int(dy/_cvZoom)); -+} -+ -+void CallGraphView::zoomRectMoveFinished() -+{ -+ if (_zoomPosition == Auto) updateSizes(); -+} -+ -+void CallGraphView::contentsMousePressEvent(TQMouseEvent* e) -+{ -+ // clicking on the viewport sets focus -+ setFocus(); -+ -+ _isMoving = true; -+ -+ TQCanvasItemList l = canvas()->collisions(e->pos()); -+ if (l.count()>0) { -+ TQCanvasItem* i = l.first(); -+ -+ if (i->rtti() == CANVAS_NODE) { -+ GraphNode* n = ((CanvasNode*)i)->node(); -+ if (0) qDebug("CallGraphView: Got Node '%s'", -+ n->function()->prettyName().ascii()); -+ -+ selected(n->function()); -+ } -+ -+ // redirect from label / arrow to edge -+ if (i->rtti() == CANVAS_EDGELABEL) -+ i = ((CanvasEdgeLabel*)i)->canvasEdge(); -+ if (i->rtti() == CANVAS_EDGEARROW) -+ i = ((CanvasEdgeArrow*)i)->canvasEdge(); -+ -+ if (i->rtti() == CANVAS_EDGE) { -+ GraphEdge* e = ((CanvasEdge*)i)->edge(); -+ if (0) qDebug("CallGraphView: Got Edge '%s'", -+ e->prettyName().ascii()); -+ -+ if (e->call()) selected(e->call()); -+ } -+ } -+ _lastPos = e->globalPos(); -+} -+ -+void CallGraphView::contentsMouseMoveEvent(TQMouseEvent* e) -+{ -+ if (_isMoving) { -+ int dx = e->globalPos().x() - _lastPos.x(); -+ int dy = e->globalPos().y() - _lastPos.y(); -+ scrollBy(-dx, -dy); -+ _lastPos = e->globalPos(); -+ } -+} -+ -+void CallGraphView::contentsMouseReleaseEvent(TQMouseEvent*) -+{ -+ _isMoving = false; -+ if (_zoomPosition == Auto) updateSizes(); -+} -+ -+void CallGraphView::contentsMouseDoubleClickEvent(TQMouseEvent* e) -+{ -+ TQCanvasItemList l = canvas()->collisions(e->pos()); -+ if (l.count() == 0) return; -+ TQCanvasItem* i = l.first(); -+ -+ if (i->rtti() == CANVAS_NODE) { -+ GraphNode* n = ((CanvasNode*)i)->node(); -+ if (0) qDebug("CallGraphView: Double Clicked on Node '%s'", -+ n->function()->prettyName().ascii()); -+ -+ activated(n->function()); -+ } -+ -+ // redirect from label / arrow to edge -+ if (i->rtti() == CANVAS_EDGELABEL) -+ i = ((CanvasEdgeLabel*)i)->canvasEdge(); -+ if (i->rtti() == CANVAS_EDGEARROW) -+ i = ((CanvasEdgeArrow*)i)->canvasEdge(); -+ -+ if (i->rtti() == CANVAS_EDGE) { -+ GraphEdge* e = ((CanvasEdge*)i)->edge(); -+ if (e->call()) { -+ if (0) qDebug("CallGraphView: Double Clicked On Edge '%s'", -+ e->call()->prettyName().ascii()); -+ -+ activated(e->call()); -+ } -+ } -+} -+ -+void CallGraphView::contentsContextMenuEvent(TQContextMenuEvent* e) -+{ -+ TQCanvasItemList l = canvas()->collisions(e->pos()); -+ TQCanvasItem* i = (l.count() == 0) ? 0 : l.first(); -+ -+ TQPopupMenu popup; -+ TraceFunction *f = 0, *cycle = 0; -+ TraceCall* c = 0; -+ -+ if (i) { -+ if (i->rtti() == CANVAS_NODE) { -+ GraphNode* n = ((CanvasNode*)i)->node(); -+ if (0) qDebug("CallGraphView: Menu on Node '%s'", -+ n->function()->prettyName().ascii()); -+ f = n->function(); -+ cycle = f->cycle(); -+ -+ TQString name = f->prettyName(); -+ popup.insertItem(i18n("Go to '%1'") -+ .arg(Configuration::shortenSymbol(name)), 93); -+ if (cycle && (cycle != f)) { -+ name = Configuration::shortenSymbol(cycle->prettyName()); -+ popup.insertItem(i18n("Go to '%1'").arg(name), 94); -+ } -+ popup.insertSeparator(); -+ } -+ -+ // redirect from label / arrow to edge -+ if (i->rtti() == CANVAS_EDGELABEL) -+ i = ((CanvasEdgeLabel*)i)->canvasEdge(); -+ if (i->rtti() == CANVAS_EDGEARROW) -+ i = ((CanvasEdgeArrow*)i)->canvasEdge(); -+ -+ if (i->rtti() == CANVAS_EDGE) { -+ GraphEdge* e = ((CanvasEdge*)i)->edge(); -+ if (0) qDebug("CallGraphView: Menu on Edge '%s'", -+ e->prettyName().ascii()); -+ c = e->call(); -+ if (c) { -+ TQString name = c->prettyName(); -+ popup.insertItem(i18n("Go to '%1'") -+ .arg(Configuration::shortenSymbol(name)), 95); -+ -+ popup.insertSeparator(); -+ } -+ } -+ } -+ -+ if (_renderProcess) { -+ popup.insertItem(i18n("Stop Layouting"), 999); -+ popup.insertSeparator(); -+ } -+ -+ addGoMenu(&popup); -+ popup.insertSeparator(); -+ -+ TQPopupMenu epopup; -+ epopup.insertItem(i18n("As PostScript"), 201); -+ epopup.insertItem(i18n("As Image ..."), 202); -+ -+ popup.insertItem(i18n("Export Graph"), &epopup, 200); -+ popup.insertSeparator(); -+ -+ TQPopupMenu gpopup1; -+ gpopup1.setCheckable(true); -+ gpopup1.insertItem(i18n("Unlimited"), 100); -+ gpopup1.setItemEnabled(100, (_funcLimit>0.005)); -+ gpopup1.insertSeparator(); -+ gpopup1.insertItem(i18n("None"), 101); -+ gpopup1.insertItem(i18n("max. 2"), 102); -+ gpopup1.insertItem(i18n("max. 5"), 103); -+ gpopup1.insertItem(i18n("max. 10"), 104); -+ gpopup1.insertItem(i18n("max. 15"), 105); -+ if (_maxCallerDepth<-1) _maxCallerDepth=-1; -+ switch(_maxCallerDepth) { -+ case -1: gpopup1.setItemChecked(100,true); break; -+ case 0: gpopup1.setItemChecked(101,true); break; -+ case 2: gpopup1.setItemChecked(102,true); break; -+ case 5: gpopup1.setItemChecked(103,true); break; -+ case 10: gpopup1.setItemChecked(104,true); break; -+ case 15: gpopup1.setItemChecked(105,true); break; -+ default: -+ gpopup1.insertItem(i18n("< %1").arg(_maxCallerDepth), 106); -+ gpopup1.setItemChecked(106,true); break; -+ } -+ -+ TQPopupMenu gpopup2; -+ gpopup2.setCheckable(true); -+ gpopup2.insertItem(i18n("Unlimited"), 110); -+ gpopup2.setItemEnabled(110, (_funcLimit>0.005)); -+ gpopup2.insertSeparator(); -+ gpopup2.insertItem(i18n("None"), 111); -+ gpopup2.insertItem(i18n("max. 2"), 112); -+ gpopup2.insertItem(i18n("max. 5"), 113); -+ gpopup2.insertItem(i18n("max. 10"), 114); -+ gpopup2.insertItem(i18n("max. 15"), 115); -+ if (_maxCallingDepth<-1) _maxCallingDepth=-1; -+ switch(_maxCallingDepth) { -+ case -1: gpopup2.setItemChecked(110,true); break; -+ case 0: gpopup2.setItemChecked(111,true); break; -+ case 2: gpopup2.setItemChecked(112,true); break; -+ case 5: gpopup2.setItemChecked(113,true); break; -+ case 10: gpopup2.setItemChecked(114,true); break; -+ case 15: gpopup2.setItemChecked(115,true); break; -+ default: -+ gpopup2.insertItem(i18n("< %1").arg(_maxCallingDepth), 116); -+ gpopup2.setItemChecked(116,true); break; -+ } -+ -+ TQPopupMenu gpopup3; -+ gpopup3.setCheckable(true); -+ gpopup3.insertItem(i18n("No Minimum"), 120); -+ gpopup3.setItemEnabled(120, -+ (_maxCallerDepth>=0) && (_maxCallingDepth>=0)); -+ gpopup3.insertSeparator(); -+ gpopup3.insertItem(i18n("50 %"), 121); -+ gpopup3.insertItem(i18n("20 %"), 122); -+ gpopup3.insertItem(i18n("10 %"), 123); -+ gpopup3.insertItem(i18n("5 %"), 124); -+ gpopup3.insertItem(i18n("3 %"), 125); -+ gpopup3.insertItem(i18n("2 %"), 126); -+ gpopup3.insertItem(i18n("1.5 %"), 127); -+ gpopup3.insertItem(i18n("1 %"), 128); -+ if (_funcLimit<0) _funcLimit = DEFAULT_FUNCLIMIT; -+ if (_funcLimit>.5) _funcLimit = .5; -+ if (_funcLimit == 0.0) gpopup3.setItemChecked(120,true); -+ else if (_funcLimit >= 0.5) gpopup3.setItemChecked(121,true); -+ else if (_funcLimit >= 0.2) gpopup3.setItemChecked(122,true); -+ else if (_funcLimit >= 0.1) gpopup3.setItemChecked(123,true); -+ else if (_funcLimit >= 0.05) gpopup3.setItemChecked(124,true); -+ else if (_funcLimit >= 0.03) gpopup3.setItemChecked(125,true); -+ else if (_funcLimit >= 0.02) gpopup3.setItemChecked(126,true); -+ else if (_funcLimit >= 0.015) gpopup3.setItemChecked(127,true); -+ else gpopup3.setItemChecked(128,true); -+ double oldFuncLimit = _funcLimit; -+ -+ TQPopupMenu gpopup4; -+ gpopup4.setCheckable(true); -+ gpopup4.insertItem(i18n("Same as Node"), 160); -+ gpopup4.insertItem(i18n("50 % of Node"), 161); -+ gpopup4.insertItem(i18n("20 % of Node"), 162); -+ gpopup4.insertItem(i18n("10 % of Node"), 163); -+ if (_callLimit<0) _callLimit = DEFAULT_CALLLIMIT; -+ if (_callLimit >= _funcLimit) _callLimit = _funcLimit; -+ if (_callLimit == _funcLimit) gpopup4.setItemChecked(160,true); -+ else if (_callLimit >= 0.5 * _funcLimit) gpopup4.setItemChecked(161,true); -+ else if (_callLimit >= 0.2 * _funcLimit) gpopup4.setItemChecked(162,true); -+ else gpopup4.setItemChecked(163,true); -+ -+ TQPopupMenu gpopup; -+ gpopup.setCheckable(true); -+ gpopup.insertItem(i18n("Caller Depth"), &gpopup1, 80); -+ gpopup.insertItem(i18n("Callee Depth"), &gpopup2, 81); -+ gpopup.insertItem(i18n("Min. Node Cost"), &gpopup3, 82); -+ gpopup.insertItem(i18n("Min. Call Cost"), &gpopup4, 83); -+ gpopup.insertSeparator(); -+ gpopup.insertItem(i18n("Arrows for Skipped Calls"), 130); -+ gpopup.setItemChecked(130,_showSkipped); -+ gpopup.insertItem(i18n("Inner-cycle Calls"), 131); -+ gpopup.setItemChecked(131,_expandCycles); -+ gpopup.insertItem(i18n("Cluster Groups"), 132); -+ gpopup.setItemChecked(132,_clusterGroups); -+ -+ TQPopupMenu vpopup; -+ vpopup.setCheckable(true); -+ vpopup.insertItem(i18n("Compact"), 140); -+ vpopup.insertItem(i18n("Normal"), 141); -+ vpopup.insertItem(i18n("Tall"), 142); -+ vpopup.setItemChecked(140,_detailLevel == 0); -+ vpopup.setItemChecked(141,_detailLevel == 1); -+ vpopup.setItemChecked(142,_detailLevel == 2); -+ vpopup.insertSeparator(); -+ vpopup.insertItem(i18n("Top to Down"), 150); -+ vpopup.insertItem(i18n("Left to Right"), 151); -+ vpopup.insertItem(i18n("Circular"), 152); -+ vpopup.setItemChecked(150,_layout == TopDown); -+ vpopup.setItemChecked(151,_layout == LeftRight); -+ vpopup.setItemChecked(152,_layout == Circular); -+ -+ TQPopupMenu opopup; -+ opopup.insertItem(i18n("TopLeft"), 170); -+ opopup.insertItem(i18n("TopRight"), 171); -+ opopup.insertItem(i18n("BottomLeft"), 172); -+ opopup.insertItem(i18n("BottomRight"), 173); -+ opopup.insertItem(i18n("Automatic"), 174); -+ opopup.setItemChecked(170,_zoomPosition == TopLeft); -+ opopup.setItemChecked(171,_zoomPosition == TopRight); -+ opopup.setItemChecked(172,_zoomPosition == BottomLeft); -+ opopup.setItemChecked(173,_zoomPosition == BottomRight); -+ opopup.setItemChecked(174,_zoomPosition == Auto); -+ -+ popup.insertItem(i18n("Graph"), &gpopup, 70); -+ popup.insertItem(i18n("Visualization"), &vpopup, 71); -+ popup.insertItem(i18n("Birds-eye View"), &opopup, 72); -+ -+ int r = popup.exec(e->globalPos()); -+ -+ switch(r) { -+ case 93: activated(f); break; -+ case 94: activated(cycle); break; -+ case 95: activated(c); break; -+ -+ case 999: stopRendering(); break; -+ -+ case 201: -+ { -+ TraceFunction* f = activeFunction(); -+ if (!f) break; -+ -+ GraphExporter ge(TraceItemView::data(), f, costType(), groupType(), -+ TQString("callgraph.dot")); -+ ge.setGraphOptions(this); -+ ge.writeDot(); -+ -+ system("(dot callgraph.dot -Tps > callgraph.ps; kghostview callgraph.ps)&"); -+ } -+ break; -+ -+ case 202: -+ // write current content of canvas as image to file -+ { -+ if (!_canvas) return; -+ -+ TQString fn = KFileDialog::getSaveFileName(":","*.png"); -+ -+ if (!fn.isEmpty()) { -+ TQPixmap pix(_canvas->size()); -+ TQPainter p(&pix); -+ _canvas->drawArea( _canvas->rect(), &p ); -+ pix.save(fn,"PNG"); -+ } -+ } -+ break; -+ -+ case 100: _maxCallerDepth = -1; break; -+ case 101: _maxCallerDepth = 0; break; -+ case 102: _maxCallerDepth = 2; break; -+ case 103: _maxCallerDepth = 5; break; -+ case 104: _maxCallerDepth = 10; break; -+ case 105: _maxCallerDepth = 15; break; -+ -+ case 110: _maxCallingDepth = -1; break; -+ case 111: _maxCallingDepth = 0; break; -+ case 112: _maxCallingDepth = 2; break; -+ case 113: _maxCallingDepth = 5; break; -+ case 114: _maxCallingDepth = 10; break; -+ case 115: _maxCallingDepth = 15; break; -+ -+ case 120: _funcLimit = 0; break; -+ case 121: _funcLimit = 0.5; break; -+ case 122: _funcLimit = 0.2; break; -+ case 123: _funcLimit = 0.1; break; -+ case 124: _funcLimit = 0.05; break; -+ case 125: _funcLimit = 0.03; break; -+ case 126: _funcLimit = 0.02; break; -+ case 127: _funcLimit = 0.015; break; -+ case 128: _funcLimit = 0.01; break; -+ -+ case 130: _showSkipped = !_showSkipped; break; -+ case 131: _expandCycles = !_expandCycles; break; -+ case 132: _clusterGroups = !_clusterGroups; break; -+ -+ case 140: _detailLevel = 0; break; -+ case 141: _detailLevel = 1; break; -+ case 142: _detailLevel = 2; break; -+ -+ case 150: _layout = TopDown; break; -+ case 151: _layout = LeftRight; break; -+ case 152: _layout = Circular; break; -+ -+ case 160: _callLimit = _funcLimit; break; -+ case 161: _callLimit = .5 * _funcLimit; break; -+ case 162: _callLimit = .2 * _funcLimit; break; -+ case 163: _callLimit = .1 * _funcLimit; break; -+ -+ case 170: _zoomPosition = TopLeft; break; -+ case 171: _zoomPosition = TopRight; break; -+ case 172: _zoomPosition = BottomLeft; break; -+ case 173: _zoomPosition = BottomRight; break; -+ case 174: _zoomPosition = Auto; break; -+ -+ default: break; -+ } -+ if (r>=120 && r<130) _callLimit *= _funcLimit / oldFuncLimit; -+ -+ if (r>99 && r<170) refresh(); -+ if (r>169 && r<180) updateSizes(); -+} -+ -+CallGraphView::ZoomPosition CallGraphView::zoomPos(TQString s) -+{ -+ if (s == TQString("TopLeft")) return TopLeft; -+ if (s == TQString("TopRight")) return TopRight; -+ if (s == TQString("BottomLeft")) return BottomLeft; -+ if (s == TQString("BottomRight")) return BottomRight; -+ if (s == TQString("Automatic")) return Auto; -+ -+ return DEFAULT_ZOOMPOS; -+} -+ -+TQString CallGraphView::zoomPosString(ZoomPosition p) -+{ -+ if (p == TopRight) return TQString("TopRight"); -+ if (p == BottomLeft) return TQString("BottomLeft"); -+ if (p == BottomRight) return TQString("BottomRight"); -+ if (p == Auto) return TQString("Automatic"); -+ -+ return TQString("TopLeft"); -+} -+ -+void CallGraphView::readViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ KConfigGroup* g = configGroup(c, prefix, postfix); -+ -+ if (0) qDebug("CallGraphView::readViewConfig"); -+ -+ _maxCallerDepth = g->readNumEntry("MaxCaller", DEFAULT_MAXCALLER); -+ _maxCallingDepth = g->readNumEntry("MaxCalling", DEFAULT_MAXCALLING); -+ _funcLimit = g->readDoubleNumEntry("FuncLimit", DEFAULT_FUNCLIMIT); -+ _callLimit = g->readDoubleNumEntry("CallLimit", DEFAULT_CALLLIMIT); -+ _showSkipped = g->readBoolEntry("ShowSkipped", DEFAULT_SHOWSKIPPED); -+ _expandCycles = g->readBoolEntry("ExpandCycles", DEFAULT_EXPANDCYCLES); -+ _clusterGroups = g->readBoolEntry("ClusterGroups", -+ DEFAULT_CLUSTERGROUPS); -+ _detailLevel = g->readNumEntry("DetailLevel", DEFAULT_DETAILLEVEL); -+ _layout = GraphOptions::layout(g->readEntry("Layout", -+ layoutString(DEFAULT_LAYOUT))); -+ _zoomPosition = zoomPos(g->readEntry("ZoomPosition", -+ zoomPosString(DEFAULT_ZOOMPOS))); -+ -+ delete g; -+} -+ -+void CallGraphView::saveViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ KConfigGroup g(c, (prefix+postfix).ascii()); -+ -+ writeConfigEntry(&g, "MaxCaller", _maxCallerDepth, DEFAULT_MAXCALLER); -+ writeConfigEntry(&g, "MaxCalling", _maxCallingDepth, DEFAULT_MAXCALLING); -+ writeConfigEntry(&g, "FuncLimit", _funcLimit, DEFAULT_FUNCLIMIT); -+ writeConfigEntry(&g, "CallLimit", _callLimit, DEFAULT_CALLLIMIT); -+ writeConfigEntry(&g, "ShowSkipped", _showSkipped, DEFAULT_SHOWSKIPPED); -+ writeConfigEntry(&g, "ExpandCycles", _expandCycles, DEFAULT_EXPANDCYCLES); -+ writeConfigEntry(&g, "ClusterGroups", _clusterGroups, -+ DEFAULT_CLUSTERGROUPS); -+ writeConfigEntry(&g, "DetailLevel", _detailLevel, DEFAULT_DETAILLEVEL); -+ writeConfigEntry(&g, "Layout", -+ layoutString(_layout), layoutString(DEFAULT_LAYOUT).utf8().data()); -+ writeConfigEntry(&g, "ZoomPosition", -+ zoomPosString(_zoomPosition), -+ zoomPosString(DEFAULT_ZOOMPOS).utf8().data()); -+} -+ -+#include "callgraphview.moc" -+ -diff --git a/kdecachegrind/kdecachegrind/callgraphview.h b/kdecachegrind/kdecachegrind/callgraphview.h -new file mode 100644 -index 0000000..4db619d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callgraphview.h -@@ -0,0 +1,501 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Callgraph View -+ */ -+ -+#ifndef CALLGRAPHVIEW_H -+#define CALLGRAPHVIEW_H -+ -+#include -+#include -+#include -+#include -+ -+#include "treemap.h" // for DrawParams -+#include "tracedata.h" -+#include "traceitemview.h" -+ -+class TQProcess; -+ -+class KTempFile; -+class CanvasNode; -+class CanvasEdge; -+class GraphEdge; -+class CallGraphView; -+ -+// sorts according start/end position of a call arc -+// this depends on attached CanvasEdge's ! -+class GraphEdgeList: public TQPtrList -+{ -+ public: -+ GraphEdgeList(); -+ void setSortCallerPos(bool b) { _sortCallerPos = b; } -+ -+ protected: -+ int compareItems ( Item item1, Item item2 ); -+ -+ private: -+ bool _sortCallerPos; -+}; -+ -+ -+typedef TQMap GraphEdgeSet; -+ -+// temporary parts of call graph to be shown -+class GraphNode -+{ -+public: -+ GraphNode(); -+ -+ TraceFunction* function() { return _f; } -+ void setFunction(TraceFunction* f) { _f = f; } -+ -+ CanvasNode* canvasNode() { return _cn; } -+ void setCanvasNode(CanvasNode* cn) { _cn = cn; } -+ -+ bool isVisible() { return _visible; } -+ void setVisible(bool v) { _visible = v; } -+ -+ // keyboard navigation -+ TraceCall* visibleCaller(); -+ TraceCall* visibleCalling(); -+ void setCalling(GraphEdge*); -+ void setCaller(GraphEdge*); -+ TraceFunction* nextVisible(); -+ TraceFunction* priorVisible(); -+ TraceCall* nextVisibleCaller(GraphEdge*); -+ TraceCall* nextVisibleCalling(GraphEdge*); -+ TraceCall* priorVisibleCaller(GraphEdge*); -+ TraceCall* priorVisibleCalling(GraphEdge*); -+ -+ double self, incl; -+ GraphEdgeList callers, callings; -+ // for fast unique insertion of GraphEdges in above lists -+ GraphEdgeSet callerSet, callingSet; -+ -+ private: -+ TraceFunction* _f; -+ CanvasNode* _cn; -+ bool _visible; -+ -+ // for keyboard navigation -+ int _lastCallerIndex, _lastCallingIndex; -+ bool _lastFromCaller; -+}; -+ -+class GraphEdge -+{ -+public: -+ GraphEdge(); -+ -+ CanvasEdge* canvasEdge() { return _ce; } -+ void setCanvasEdge(CanvasEdge* ce) { _ce = ce; } -+ -+ TraceCall* call() { return _c; } -+ void setCall(TraceCall* c) { _c = c; } -+ -+ bool isVisible() { return _visible; } -+ void setVisible(bool v) { _visible = v; } -+ -+ GraphNode* fromNode() { return _fromNode; } -+ GraphNode* toNode() { return _toNode; } -+ TraceFunction* from() { return _from; } -+ TraceFunction* to() { return _to; } -+ -+ // has special cases for collapsed edges -+ TQString prettyName(); -+ -+ void setCaller(TraceFunction* f) { _from = f; } -+ void setCalling(TraceFunction* f) { _to = f; } -+ void setCallerNode(GraphNode* n) { _fromNode = n; } -+ void setCallingNode(GraphNode* n) { _toNode = n; } -+ -+ // keyboard navigation -+ TraceFunction* visibleCaller(); -+ TraceFunction* visibleCalling(); -+ TraceCall* nextVisible(); -+ TraceCall* priorVisible(); -+ -+ double cost, count; -+ -+ private: -+ // we have a _c *and* _from/_to because for collapsed edges, -+ // only _to or _from will be unequal NULL -+ TraceCall* _c; -+ TraceFunction * _from, * _to; -+ GraphNode *_fromNode, *_toNode; -+ CanvasEdge* _ce; -+ bool _visible; -+ // for keyboard navigation: have we last reached this edge via a caller? -+ bool _lastFromCaller; -+ -+}; -+ -+ -+typedef TQMap GraphNodeMap; -+typedef TQMap, GraphEdge> GraphEdgeMap; -+ -+ -+/* Abstract Interface for graph options */ -+class GraphOptions -+{ -+ public: -+ enum Layout { TopDown, LeftRight, Circular}; -+ -+ virtual double funcLimit() = 0; -+ virtual double callLimit() = 0; -+ virtual int maxCallerDepth() = 0; -+ virtual int maxCallingDepth() = 0; -+ virtual bool showSkipped() = 0; -+ virtual bool expandCycles() = 0; -+ virtual bool clusterGroups() = 0; -+ virtual int detailLevel() = 0; -+ virtual Layout layout() = 0; -+ -+ static TQString layoutString(Layout); -+ static Layout layout(TQString); -+}; -+ -+/* Graph Options Storage */ -+class StorableGraphOptions: public GraphOptions -+{ -+ public: -+ StorableGraphOptions(); -+ -+ // implementation of getters -+ virtual double funcLimit() { return _funcLimit; } -+ virtual double callLimit() { return _callLimit; } -+ virtual int maxCallerDepth() { return _maxCallerDepth; } -+ virtual int maxCallingDepth() { return _maxCallingDepth; } -+ virtual bool showSkipped() { return _showSkipped; } -+ virtual bool expandCycles() { return _expandCycles; } -+ virtual bool clusterGroups() { return _clusterGroups; } -+ virtual int detailLevel() { return _detailLevel; } -+ virtual Layout layout() { return _layout; } -+ -+ // setters -+ void setMaxCallerDepth(int d) { _maxCallerDepth = d; } -+ void setMaxCallingDepth(int d) { _maxCallingDepth = d; } -+ void setFuncLimit(double l) { _funcLimit = l; } -+ void setCallLimit(double l) { _callLimit = l; } -+ void setShowSkipped(bool b) { _showSkipped = b; } -+ void setExpandCycles(bool b) { _expandCycles = b; } -+ void setClusterGroups(bool b) { _clusterGroups = b; } -+ void setDetailLevel(int l) { _detailLevel = l; } -+ void setLayout(Layout l) { _layout = l; } -+ -+ protected: -+ double _funcLimit, _callLimit; -+ int _maxCallerDepth, _maxCallingDepth; -+ bool _showSkipped, _expandCycles, _clusterGroups; -+ int _detailLevel; -+ Layout _layout; -+}; -+ -+/** -+ * GraphExporter -+ * -+ * Generates a graph file for "dot" -+ * Create an instance and -+ */ -+class GraphExporter: public StorableGraphOptions -+{ -+public: -+ GraphExporter(); -+ GraphExporter(TraceData*, TraceFunction*, TraceCostType*, -+ TraceItem::CostType, TQString filename = TQString()); -+ virtual ~GraphExporter(); -+ -+ void reset(TraceData*, TraceItem*, TraceCostType*, -+ TraceItem::CostType, TQString filename = TQString()); -+ -+ TQString filename() { return _dotName; } -+ int edgeCount() { return _edgeMap.count(); } -+ int nodeCount() { return _nodeMap.count(); } -+ -+ // Set the object from which to get graph options for creation. -+ // Default is this object itself (supply 0 for default) -+ void setGraphOptions(GraphOptions* go = 0); -+ -+ // Create a subgraph with given limits/maxDepths -+ void createGraph(); -+ -+ // calls createGraph before dumping of not already created -+ void writeDot(); -+ -+ // to map back to structures when parsing a layouted graph -+ -+ /* is a helper for node() and edge(). -+ * Don't use the returned pointer directly, but only with -+ * node() or edge(), because it could be a dangling pointer. -+ */ -+ TraceFunction* toFunc(TQString); -+ GraphNode* node(TraceFunction*); -+ GraphEdge* edge(TraceFunction*, TraceFunction*); -+ -+ /* After CanvasEdges are attached to GraphEdges, we can -+ * sort the incoming and outgoing edges of all nodes -+ * regarding start/end points for keyboard navigation -+ */ -+ void sortEdges(); -+ -+private: -+ void buildGraph(TraceFunction*, int, bool, double); -+ -+ TQString _dotName; -+ TraceItem* _item; -+ TraceCostType* _costType; -+ TraceItem::CostType _groupType; -+ KTempFile* _tmpFile; -+ double _realFuncLimit, _realCallLimit; -+ int _maxDepth; -+ bool _graphCreated; -+ -+ GraphOptions* _go; -+ -+ // optional graph attributes -+ bool _useBox; -+ -+ // graph parts written to file -+ GraphNodeMap _nodeMap; -+ GraphEdgeMap _edgeMap; -+}; -+ -+/** -+ * A panner layed over a TQCanvas -+ */ -+class PannerView: public TQCanvasView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ PannerView(TQWidget * parent = 0, const char * name = 0); -+ -+ void setZoomRect(TQRect r); -+ -+signals: -+ void zoomRectMoved(int dx, int dy); -+ void zoomRectMoveFinished(); -+ -+protected: -+ void contentsMousePressEvent(TQMouseEvent*); -+ void contentsMouseMoveEvent(TQMouseEvent*); -+ void contentsMouseReleaseEvent(TQMouseEvent*); -+ void drawContents(TQPainter * p, int clipx, int clipy, int clipw, int cliph); -+ -+ TQRect _zoomRect; -+ bool _movingZoomRect; -+ TQPoint _lastPos; -+}; -+ -+ -+/* -+ * Canvas Items: -+ * - CanvasNode (Rectangular Area) -+ * - CanvasEdge (Spline curve) -+ * - CanvasEdgeLabel (Label for edges) -+ * - CanvasEdgeArrow (Arrows at the end of the edge spline) -+ * - CanvasFrame (Grey background blending to show active node) -+ */ -+ -+enum { -+ CANVAS_NODE = 1122, -+ CANVAS_EDGE, CANVAS_EDGELABEL, CANVAS_EDGEARROW, -+ CANVAS_FRAME -+}; -+ -+class CanvasNode: public TQCanvasRectangle, public StoredDrawParams -+{ -+public: -+ CanvasNode(CallGraphView*,GraphNode*, int, int, int, int, TQCanvas*); -+ -+ void updateGroup(); -+ void setSelected(bool); -+ void drawShape(TQPainter&); -+ -+ GraphNode* node() { return _node; } -+ int rtti() const { return CANVAS_NODE; } -+ -+private: -+ GraphNode* _node; -+ CallGraphView* _view; -+}; -+ -+class CanvasEdgeLabel: public TQCanvasRectangle, public StoredDrawParams -+{ -+public: -+ CanvasEdgeLabel(CallGraphView*, CanvasEdge*, int, int, int, int, TQCanvas*); -+ -+ void drawShape(TQPainter&); -+ -+ CanvasEdge* canvasEdge() { return _ce; } -+ int rtti() const { return CANVAS_EDGELABEL; } -+ -+private: -+ CanvasEdge* _ce; -+ CallGraphView* _view; -+}; -+ -+class CanvasEdgeArrow: public TQCanvasPolygon -+{ -+public: -+ CanvasEdgeArrow(CanvasEdge*, TQCanvas*); -+ -+ void drawShape(TQPainter&); -+ -+ CanvasEdge* canvasEdge() { return _ce; } -+ int rtti() const { return CANVAS_EDGEARROW; } -+ -+private: -+ CanvasEdge* _ce; -+}; -+ -+ -+class CanvasEdge: public TQCanvasSpline -+{ -+public: -+ CanvasEdge(GraphEdge*, TQCanvas*); -+ -+ void setSelected(bool); -+ void drawShape(TQPainter&); -+ TQPointArray areaPoints() const; -+ -+ CanvasEdgeLabel* label() { return _label; } -+ void setLabel(CanvasEdgeLabel* l) { _label = l; } -+ CanvasEdgeArrow* arrow() { return _arrow; } -+ void setArrow(CanvasEdgeArrow* a) { _arrow = a; } -+ -+ GraphEdge* edge() { return _edge; } -+ int rtti() const { return CANVAS_EDGE; } -+ -+private: -+ GraphEdge* _edge; -+ CanvasEdgeLabel* _label; -+ CanvasEdgeArrow* _arrow; -+}; -+ -+ -+class CanvasFrame: public TQCanvasRectangle -+{ -+public: -+ CanvasFrame( CanvasNode*, TQCanvas *canvas ); -+ int rtti () const { return CANVAS_FRAME; } -+ bool hit( const TQPoint&) const { return false; } -+protected: -+ void drawShape( TQPainter & ); -+private: -+ static TQPixmap* _p; -+}; -+ -+ -+class CallGraphTip; -+ -+/** -+ * A CanvasView showing a part of the call graph -+ * and another zoomed out CanvasView in a border acting as -+ * a panner to select to visible part (only if needed) -+ */ -+class CallGraphView: public TQCanvasView, public TraceItemView, -+ public StorableGraphOptions -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ enum ZoomPosition { TopLeft, TopRight, BottomLeft, BottomRight, Auto }; -+ -+ CallGraphView(TraceItemView* parentView, -+ TQWidget* parent=0, const char* name=0); -+ ~CallGraphView(); -+ -+ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ -+ TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ -+ ZoomPosition zoomPos() const { return _zoomPosition; } -+ static ZoomPosition zoomPos(TQString); -+ static TQString zoomPosString(ZoomPosition); -+ -+public slots: -+ void contentsMovingSlot(int,int); -+ void zoomRectMoved(int,int); -+ void zoomRectMoveFinished(); -+ -+ void showRenderWarning(); -+ void stopRendering(); -+ void readDotOutput(); -+ void dotExited(); -+ -+protected: -+ void resizeEvent(TQResizeEvent*); -+ void contentsMousePressEvent(TQMouseEvent*); -+ void contentsMouseMoveEvent(TQMouseEvent*); -+ void contentsMouseReleaseEvent(TQMouseEvent*); -+ void contentsMouseDoubleClickEvent(TQMouseEvent*); -+ void contentsContextMenuEvent(TQContextMenuEvent*); -+ void keyPressEvent(TQKeyEvent*); -+ void focusInEvent(TQFocusEvent*); -+ void focusOutEvent(TQFocusEvent*); -+ -+private: -+ void updateSizes(TQSize s = TQSize(0,0)); -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ void refresh(); -+ void makeFrame(CanvasNode*, bool active); -+ void clear(); -+ void showText(TQString); -+ -+ TQCanvas *_canvas; -+ int _xMargin, _yMargin; -+ PannerView *_completeView; -+ double _cvZoom; -+ -+ CallGraphTip* _tip; -+ -+ bool _isMoving; -+ TQPoint _lastPos; -+ -+ GraphExporter _exporter; -+ -+ GraphNode* _selectedNode; -+ GraphEdge* _selectedEdge; -+ -+ // widget options -+ ZoomPosition _zoomPosition, _lastAutoPosition; -+ -+ // background rendering -+ TQProcess* _renderProcess; -+ TQTimer _renderTimer; -+ GraphNode* _prevSelectedNode; -+ TQPoint _prevSelectedPos; -+ TQString _unparsedOutput; -+}; -+ -+ -+ -+ -+#endif -+ -+ -+ -diff --git a/kdecachegrind/kdecachegrind/callitem.cpp b/kdecachegrind/kdecachegrind/callitem.cpp -new file mode 100644 -index 0000000..ebca490 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callitem.cpp -@@ -0,0 +1,185 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items for caller/callee view. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "listutils.h" -+#include "callitem.h" -+#include "callview.h" -+#include "toplevel.h" -+ -+// CallItem -+ -+ -+CallItem::CallItem(CallView* view, TQListView* parent, TraceCall* c) -+ : TQListViewItem(parent) -+{ -+ _call = c; -+ _view = view; -+ -+ _active = _view->activeFunction(); -+ bool baseIsCycle = (_active && (_active == _active->cycle())); -+ -+ TQString fName; -+ if (_view->showCallers()) { -+ _shown = _call->caller(true); -+ fName = c->callerName(!baseIsCycle); -+ } -+ else { -+ _shown = _call->called(true); -+ fName = c->calledName(!baseIsCycle); -+ } -+ -+ _shown->addPrettyLocation(fName); -+ -+ setText(3, fName); -+ updateGroup(); -+ updateCost(); -+} -+ -+void CallItem::updateGroup() -+{ -+ TQColor c = Configuration::functionColor(_view->groupType(), _shown); -+ setPixmap(3, colorPixmap(10, 10, c)); -+} -+ -+void CallItem::updateCost() -+{ -+ bool sameCycle = _shown->cycle() && (_active->cycle() == _shown->cycle()); -+ bool shownIsCycle = (_shown == _shown->cycle()); -+ bool selectedIsCycle = (_active == _active->cycle()); -+ if (_call->isRecursion()) sameCycle=true; -+ -+ TQString cStr; -+ if ((selectedIsCycle || shownIsCycle) && sameCycle) -+ cStr = "-"; -+ else { -+ _cc = _call->callCount(); -+ if (_cc == 0) -+ cStr = i18n("(active)"); -+ else -+ cStr = _call->prettyCallCount(); -+ } -+ setText(2, cStr); -+ -+ TraceCost* totalCost; -+ if (_view->topLevel()->showExpanded()) { -+ if (_active->cycle()) -+ totalCost = _active->cycle()->inclusive(); -+ else -+ totalCost = _active->inclusive(); -+ } -+ else -+ totalCost = _active->data(); -+ -+ TraceCostType* ct = _view->costType(); -+ _sum = _call->subCost(ct); -+ double total = totalCost->subCost(ct); -+ -+ if (total == 0.0) { -+ TQString str = "-"; -+ -+ setText(0, str); -+ setPixmap(0, TQPixmap()); -+ } -+ else { -+ double sum = 100.0 * _sum / total; -+ -+ if (_view->topLevel()->showPercentage()) -+ setText(0, TQString("%1") -+ .arg(sum, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(0, _call->prettySubCost(ct)); -+ -+ setPixmap(0, costPixmap(ct, _call, total, false)); -+ } -+ -+ // Cost Type 2 -+ TraceCostType* ct2 = _view->costType2(); -+ if (ct2) { -+ _sum2 = _call->subCost(ct2); -+ double total = totalCost->subCost(ct2); -+ -+ if (total == 0.0) { -+ TQString str = "-"; -+ -+ setText(1, str); -+ setPixmap(1, TQPixmap()); -+ } -+ else { -+ double sum = 100.0 * _sum2 / total; -+ -+ if (_view->topLevel()->showPercentage()) -+ setText(1, TQString("%1") -+ .arg(sum, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(1, _call->prettySubCost(ct2)); -+ -+ setPixmap(1, costPixmap(ct2, _call, total, false)); -+ } -+ } -+ -+ TQPixmap p; -+ if (sameCycle && !selectedIsCycle && !shownIsCycle) { -+ -+ TQString icon = "undo"; -+ KIconLoader* loader = KApplication::kApplication()->iconLoader(); -+ p= loader->loadIcon(icon, KIcon::Small, 0, -+ KIcon::DefaultState, 0, true); -+ } -+ setPixmap(2, p); -+} -+ -+ -+int CallItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ const CallItem* ci1 = this; -+ const CallItem* ci2 = (CallItem*) i; -+ -+ // we always want descending order -+ if (ascending) { -+ ci1 = ci2; -+ ci2 = this; -+ } -+ -+ if (col==0) { -+ if (ci1->_sum < ci2->_sum) return -1; -+ if (ci1->_sum > ci2->_sum) return 1; -+ return 0; -+ } -+ if (col==1) { -+ if (ci1->_sum2 < ci2->_sum2) return -1; -+ if (ci1->_sum2 > ci2->_sum2) return 1; -+ return 0; -+ } -+ if (col==2) { -+ if (ci1->_cc < ci2->_cc) return -1; -+ if (ci1->_cc > ci2->_cc) return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -diff --git a/kdecachegrind/kdecachegrind/callitem.h b/kdecachegrind/kdecachegrind/callitem.h -new file mode 100644 -index 0000000..94191b8 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callitem.h -@@ -0,0 +1,50 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of call view. -+ */ -+ -+#ifndef CALLITEM_H -+#define CALLITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class CallView; -+ -+class CallItem: public TQListViewItem -+{ -+public: -+ CallItem(CallView*, TQListView*, TraceCall* c); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ TraceCall* call() { return _call; } -+ CallView* view() { return _view; } -+ void updateCost(); -+ void updateGroup(); -+ -+private: -+ SubCost _sum, _sum2; -+ SubCost _cc; -+ TraceCall* _call; -+ CallView* _view; -+ TraceFunction *_active, *_shown; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/callmapview.cpp b/kdecachegrind/kdecachegrind/callmapview.cpp -new file mode 100644 -index 0000000..0e4d5e3 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callmapview.cpp -@@ -0,0 +1,999 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Call Map View -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "callmapview.h" -+#include "configuration.h" -+#include "listutils.h" -+#include "toplevel.h" -+ -+// -+// CallMapView -+// -+ -+ -+// defaults -+#define DEFAULT_SPLITMODE "Rows" -+#define DEFAULT_DRAWNAME true -+#define DEFAULT_DRAWCOST true -+#define DEFAULT_DRAWLOCATION false -+#define DEFAULT_DRAWCALLS false -+#define DEFAULT_FORCESTRINGS false -+#define DEFAULT_ROTATION true -+#define DEFAULT_SHADING true -+#define DEFAULT_MAXAREA 100 -+ -+ -+CallMapView::CallMapView(bool showCallers, TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TreeMapWidget(new CallMapBaseItem(), parent, name), TraceItemView(parentView) -+{ -+ _showCallers = showCallers; -+ -+ setFieldType(0, i18n( "Name" )); -+ setFieldType(1, i18n( "Cost" )); -+ setFieldType(2, i18n( "Location" )); -+ setFieldPosition(2, TreeMapItem::TopLeft); -+ setFieldType(3, i18n( "Calls" )); -+ setFieldPosition(3, TreeMapItem::TopRight); -+ -+ setSplitMode(DEFAULT_SPLITMODE); -+ setFieldVisible(0, DEFAULT_DRAWNAME); -+ setFieldVisible(1, DEFAULT_DRAWCOST); -+ setFieldVisible(2, DEFAULT_DRAWLOCATION); -+ setFieldVisible(3, DEFAULT_DRAWCALLS); -+ setFieldForced(0, DEFAULT_FORCESTRINGS); -+ setFieldForced(1, DEFAULT_FORCESTRINGS); -+ setFieldForced(2, DEFAULT_FORCESTRINGS); -+ setFieldForced(3, DEFAULT_FORCESTRINGS); -+ setAllowRotation(DEFAULT_ROTATION); -+ setShadingEnabled(DEFAULT_SHADING); -+ setMinimalArea(DEFAULT_MAXAREA); -+ -+ connect(this, -+ TQT_SIGNAL(doubleClicked(TreeMapItem*)), -+ TQT_SLOT(activatedSlot(TreeMapItem*))); -+ connect(this, -+ TQT_SIGNAL(returnPressed(TreeMapItem*)), -+ TQT_SLOT(activatedSlot(TreeMapItem*))); -+ connect(this, -+ TQT_SIGNAL(currentChanged(TreeMapItem*, bool)), -+ TQT_SLOT(selectedSlot(TreeMapItem*, bool))); -+ connect(this, -+ TQT_SIGNAL(contextMenuRequested(TreeMapItem*,const TQPoint &)), -+ TQT_SLOT(context(TreeMapItem*,const TQPoint &))); -+ -+ TQWhatsThis::add( this, whatsThis()); -+} -+ -+TQString CallMapView::whatsThis() const -+{ -+ TQString s = _showCallers ? -+ i18n( "Caller Map" -+ "

This graph shows the nested hierarchy of " -+ "all callers of the current activated function. " -+ "Each colored rectangle represents a function; " -+ "its size tries to be proportional to the cost spent " -+ "therein while the active function is running " -+ "(however, there are drawing constrains).

") : -+ i18n("Call Map" -+ "

This graph shows the nested hierarchy of " -+ "all callees of the current activated function. " -+ "Each colored rectangle represents a function; " -+ "its size tries to be proportional to the cost spent " -+ "therein while the active function is running " -+ "(however, there are drawing constrains).

"); -+ -+ s += i18n( "

Appearance options can be found in the " -+ "in the context menu. To get exact size proportions, " -+ "choose 'Hide incorrect borders'. As this mode can be " -+ "very time consuming, you may want to limit " -+ "the maximum drawn nesting level before. " -+ "'Best' determinates the split direction for children " -+ "from the aspect ratio of the parent. " -+ "'Always Best' decides on remaining space for each " -+ "sibling. " -+ "'Ignore Proportions' takes space for function name " -+ "drawing before drawing children. Note that " -+ "size proportions can get heavily wrong.

" -+ -+ "

This is a TreeMap widget. " -+ "Keyboard navigation is available with the left/right arrow " -+ "keys for traversing siblings, and up/down arrow keys " -+ "to go a nesting level up/down. " -+ "Return activates the current item.

"); -+ -+ return s; -+} -+ -+void CallMapView::setData(TraceData* d) -+{ -+ TraceItemView::setData(d); -+ -+ ((CallMapBaseItem*)base())->setFunction(0); -+} -+ -+void CallMapView::context(TreeMapItem* i,const TQPoint & p) -+{ -+ if (!i) return; -+ -+ TQPopupMenu popup; -+ TQPopupMenu fpopup; // select function subpopup -+ TQPopupMenu vpopup; // visualisation subpopup -+ TQPopupMenu dpopup; // split direction -+ TQPopupMenu bpopup; // border subpopup -+ TQPopupMenu l1popup; // depth limit subpopup -+ TQPopupMenu l2popup; // function limit subpopup -+ TQPopupMenu l3popup; // area limit subpopup -+ -+ TreeMapItem* item = i; -+ int count; -+ -+ TQString shortCurrentName; -+ if (i) { -+ shortCurrentName = i->text(0); -+ if ((int)shortCurrentName.length() > Configuration::maxSymbolLength()) -+ shortCurrentName = -+ shortCurrentName.left(Configuration::maxSymbolLength()) + "..."; -+ } -+ -+ if (item) { -+ popup.insertItem(i18n("Go To"), &fpopup, 100); -+ count = 0; -+ while (counttext(0); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ fpopup.insertItem(name, 101+count); -+ item = item->parent(); -+ count++; -+ } -+ popup.insertSeparator(); -+ } -+ -+ addGoMenu(&popup); -+ popup.insertSeparator(); -+ -+ l1popup.setCheckable(true); -+ popup.insertItem(i18n("Stop at Depth"), &l1popup, 12); -+ -+ int maxDepth = maxDrawingDepth(); -+ l1popup.insertItem(i18n("No Depth Limit"), 50); -+ l1popup.setItemChecked(50, maxDepth==-1); -+ l1popup.insertSeparator(); -+ l1popup.insertItem(i18n("Depth 10"), 51); -+ l1popup.setItemChecked(51, maxDepth==10); -+ l1popup.insertItem(i18n("Depth 15"), 52); -+ l1popup.setItemChecked(52, maxDepth==15); -+ l1popup.insertItem(i18n("Depth 20"), 53); -+ l1popup.setItemChecked(53, maxDepth==20); -+ if (i) { -+ l1popup.insertSeparator(); -+ l1popup.insertItem(i18n("Depth of '%1' (%2)") -+ .arg(shortCurrentName).arg(i->depth()), 55); -+ l1popup.setItemChecked(55, maxDepth == i->depth()); -+ } -+ if (maxDepth>0) { -+ l1popup.insertSeparator(); -+ l1popup.insertItem(i18n("Decrement Depth (to %1)").arg(maxDepth-1), 56); -+ l1popup.insertItem(i18n("Increment Depth (to %1)").arg(maxDepth+1), 57); -+ } -+ -+ l2popup.setCheckable(true); -+ popup.insertItem(i18n("Stop at Function"), &l2popup, 13); -+ l2popup.insertItem(i18n("No Function Limit"), 200); -+ l2popup.setItemChecked(200, fieldStop(0).isEmpty()); -+ bool foundStopName = false; -+ item = i; -+ if (i) { -+ l2popup.insertSeparator(); -+ count = 0; -+ while (counttext(0); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ l2popup.insertItem(name, 201+count); -+ if (item->text(0) == fieldStop(0)) { -+ l2popup.setItemChecked(201+count, true); -+ foundStopName = true; -+ } -+ item = item->parent(); -+ count++; -+ } -+ } -+ if (!foundStopName && !fieldStop(0).isEmpty()) { -+ l2popup.insertSeparator(); -+ TQString name = fieldStop(0); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ l2popup.insertItem(name, 199); -+ l2popup.setItemChecked(199, true); -+ } -+ -+ l3popup.setCheckable(true); -+ popup.insertItem(i18n("Stop at Area"), &l3popup, 14); -+ -+ int mArea = minimalArea(); -+ l3popup.insertItem(i18n("No Area Limit"), 60); -+ l3popup.setItemChecked(60, mArea ==-1); -+ l3popup.insertSeparator(); -+ l3popup.insertItem(i18n("50 Pixels"), 63); -+ l3popup.setItemChecked(63, mArea==50); -+ l3popup.insertItem(i18n("100 Pixels"), 64); -+ l3popup.setItemChecked(64, mArea==100); -+ l3popup.insertItem(i18n("200 Pixels"), 65); -+ l3popup.setItemChecked(65, mArea==200); -+ l3popup.insertItem(i18n("500 Pixels"), 66); -+ l3popup.setItemChecked(66, mArea==500); -+ int currentArea = 0; -+ if (i) { -+ currentArea = i->width() * i->height(); -+ l3popup.insertSeparator(); -+ l3popup.insertItem(i18n("Area of '%1' (%2)") -+ .arg(shortCurrentName).arg(currentArea), 67); -+ l3popup.setItemChecked(67, mArea == currentArea); -+ } -+ if (mArea>0) { -+ l3popup.insertSeparator(); -+ l3popup.insertItem(i18n("Double Area Limit (to %1)") -+ .arg(mArea*2), 68); -+ l3popup.insertItem(i18n("Half Area Limit (to %1)") -+ .arg(mArea/2), 69); -+ } -+ -+ popup.insertSeparator(); -+ -+ vpopup.setCheckable(true); -+ popup.insertItem(i18n("Visualisation"), &vpopup, 10); -+ -+ TQPopupMenu splitpopup; -+ addSplitDirectionItems(&splitpopup, 1001); -+ vpopup.insertItem(i18n("Split Direction"), &splitpopup, 1000); -+ -+ vpopup.insertItem(i18n("Skip Incorrect Borders"), 40); -+ vpopup.setItemEnabled(40, !_showCallers); -+ vpopup.setItemChecked(40, skipIncorrectBorder()); -+ -+ bpopup.setCheckable(true); -+ vpopup.insertItem(i18n("Border Width"), &bpopup, 41); -+ bpopup.insertItem(i18n("Border 0"), 42); -+ bpopup.setItemEnabled(42, !_showCallers); -+ bpopup.setItemChecked(42, borderWidth()==0); -+ bpopup.insertItem(i18n("Border 1"), 43); -+ bpopup.setItemChecked(43, borderWidth()==1); -+ bpopup.insertItem(i18n("Border 2"), 44); -+ bpopup.setItemChecked(44, borderWidth()==2); -+ bpopup.insertItem(i18n("Border 3"), 45); -+ bpopup.setItemChecked(45, borderWidth()==3); -+ -+ vpopup.insertSeparator(); -+ -+ vpopup.insertItem(i18n("Draw Symbol Names"), 20); -+ vpopup.insertItem(i18n("Draw Cost"), 21); -+ vpopup.insertItem(i18n("Draw Location"), 22); -+ vpopup.insertItem(i18n("Draw Calls"), 23); -+ vpopup.insertSeparator(); -+ -+ vpopup.insertItem(i18n("Ignore Proportions"), 24); -+ vpopup.insertItem(i18n("Allow Rotation"), 25); -+ if (!fieldVisible(0) && -+ !fieldVisible(1) && -+ !fieldVisible(2) && -+ !fieldVisible(3)) { -+ vpopup.setItemEnabled(24, false); -+ vpopup.setItemEnabled(25, false); -+ } -+ else { -+ vpopup.setItemChecked(20,fieldVisible(0)); -+ vpopup.setItemChecked(21,fieldVisible(1)); -+ vpopup.setItemChecked(22,fieldVisible(2)); -+ vpopup.setItemChecked(23,fieldVisible(3)); -+ vpopup.setItemChecked(24,fieldForced(0)); -+ vpopup.setItemChecked(25,allowRotation()); -+ } -+ -+ vpopup.insertItem(i18n("Shading"), 26); -+ vpopup.setItemChecked(26,isShadingEnabled()); -+ -+ int r = popup.exec(mapToGlobal(p)); -+ -+ if (r>100 && r<150) { -+ r -= 100; -+ while (i && (r>1)) { -+ i=i->parent(); -+ r--; -+ } -+ activatedSlot(i); -+ return; -+ } -+ -+ if (r>200 && r<250) { -+ r -= 200; -+ while (i && (r>1)) { -+ i=i->parent(); -+ r--; -+ } -+ if (i) -+ setFieldStop(0, i->text(0)); -+ -+ return; -+ } -+ -+ switch(r) { -+ case 20: -+ setFieldVisible(0, !vpopup.isItemChecked(20)); -+ break; -+ -+ case 21: -+ setFieldVisible(1, !vpopup.isItemChecked(21)); -+ break; -+ -+ case 22: -+ setFieldVisible(2, !vpopup.isItemChecked(22)); -+ break; -+ -+ case 23: -+ setFieldVisible(3, !vpopup.isItemChecked(23)); -+ break; -+ -+ case 24: -+ setFieldForced(0, !vpopup.isItemChecked(24)); -+ setFieldForced(1, !vpopup.isItemChecked(24)); -+ setFieldForced(2, !vpopup.isItemChecked(24)); -+ setFieldForced(3, !vpopup.isItemChecked(24)); -+ break; -+ -+ case 25: setAllowRotation(!vpopup.isItemChecked(25)); break; -+ case 26: setShadingEnabled(!vpopup.isItemChecked(26)); break; -+ -+ case 40: -+ setSkipIncorrectBorder(!vpopup.isItemChecked(40)); -+ break; -+ -+ case 42: setBorderWidth(0); break; -+ case 43: setBorderWidth(1); break; -+ case 44: setBorderWidth(2); break; -+ case 45: setBorderWidth(3); break; -+ -+ case 50: setMaxDrawingDepth(-1); break; -+ case 51: setMaxDrawingDepth(10); break; -+ case 52: setMaxDrawingDepth(15); break; -+ case 53: setMaxDrawingDepth(20); break; -+ case 55: setMaxDrawingDepth(i->depth()); break; -+ case 56: setMaxDrawingDepth(maxDepth-1); break; -+ case 57: setMaxDrawingDepth(maxDepth+1); break; -+ -+ case 200: setFieldStop(0, TQString()); break; -+ -+ case 60: setMinimalArea(-1); break; -+ case 61: setMinimalArea(10); break; -+ case 62: setMinimalArea(20); break; -+ case 63: setMinimalArea(50); break; -+ case 64: setMinimalArea(100); break; -+ case 65: setMinimalArea(200); break; -+ case 66: setMinimalArea(500); break; -+ case 67: setMinimalArea(currentArea); break; -+ case 68: setMinimalArea(mArea*2); break; -+ case 69: setMinimalArea(mArea/2); break; -+ } -+} -+ -+void CallMapView::activatedSlot(TreeMapItem* item) -+{ -+ if (!item) return; -+ -+ if (item->rtti() == 1) { -+ CallMapBaseItem* bi = (CallMapBaseItem*)item; -+ activated(bi->function()); -+ } -+ else if (item->rtti() == 2) { -+ CallMapCallingItem* ci = (CallMapCallingItem*)item; -+ activated(ci->function()); -+ } -+ else if (item->rtti() == 3) { -+ CallMapCallerItem* ci = (CallMapCallerItem*)item; -+ activated(ci->function()); -+ } -+} -+ -+void CallMapView::selectedSlot(TreeMapItem* item, bool kbd) -+{ -+ if (!item) return; -+ if (item->text(0).isEmpty()) return; -+ -+ if (kbd) { -+ TQString msg = i18n("Call Map: Current is '%1'").arg(item->text(0)); -+ if (_topLevel) -+ _topLevel->showMessage(msg, 5000); -+ } -+ -+ TraceFunction* f = 0; -+ -+ if (item->rtti() == 1) { -+ CallMapBaseItem* bi = (CallMapBaseItem*)item; -+ f = bi->function(); -+ } -+ else if (item->rtti() == 2) { -+ CallMapCallingItem* ci = (CallMapCallingItem*)item; -+ f = ci->function(); -+ } -+ else if (item->rtti() == 3) { -+ CallMapCallerItem* ci = (CallMapCallerItem*)item; -+ f = ci->function(); -+ } -+ if (f) { -+ // this avoids marking -+ _selectedItem = f; -+ selected(f); -+ } -+} -+ -+TraceItem* CallMapView::canShow(TraceItem* i) -+{ -+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType; -+ -+ switch(t) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ return i; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+void CallMapView::doUpdate(int changeType) -+{ -+ if (changeType == costType2Changed) return; -+ -+ // if there is a selected item, always draw marking... -+ if (changeType & selectedItemChanged) { -+ TraceFunction* f = 0; -+ -+ if (_selectedItem) { -+ switch(_selectedItem->type()) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ f = (TraceFunction*)_selectedItem; -+ break; -+ default: -+ break; -+ } -+ } -+ // if this is the only change... -+ if (changeType == selectedItemChanged) { -+ setMarked(f ? 1:0, true); -+ return; -+ } -+ setMarked(f ? 1:0, false); -+ } -+ -+ -+ if (changeType & activeItemChanged) { -+ TraceFunction* f = 0; -+ -+ if (_activeItem) { -+ switch(_activeItem->type()) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ f = (TraceFunction*)_activeItem; -+ break; -+ default: -+ break; -+ } -+ } -+ ((CallMapBaseItem*)base())->setFunction(f); -+ } -+ else if ( ((changeType & partsChanged) && Configuration::showCycles()) || -+ (changeType & dataChanged) || -+ (changeType & configChanged)) { -+ /* regenerates the treemap because traceitems were added/removed */ -+ base()->refresh(); -+ } -+ else if ((changeType & partsChanged) || -+ (changeType & costTypeChanged)) { -+ /* we need to do the draw order sorting again as the values change */ -+ resort(); -+ redraw(); -+ } -+ else -+ redraw(); -+} -+ -+ -+ -+TQColor CallMapView::groupColor(TraceFunction* f) const -+{ -+ if (!f) -+ return colorGroup().button(); -+ -+ return Configuration::functionColor(_groupType, f); -+} -+ -+ -+TQString CallMapView::tipString(TreeMapItem* i) const -+{ -+ TQString tip, itemTip; -+ int count = 0; -+ -+ //qDebug("CallMapView::tipString for '%s'", i->text(0).ascii()); -+ -+ // first, SubPartItem's -+ while (i && counttext(0); -+ if ((int)itemTip.length()>Configuration::maxSymbolLength()) -+ itemTip = itemTip.left(Configuration::maxSymbolLength()) + "..."; -+ -+ if (!i->text(1).isEmpty()) -+ itemTip += " (" + i->text(1) + ")"; -+ -+ if (!tip.isEmpty()) tip += "\n"; -+ -+ tip += itemTip; -+ i = i->parent(); -+ count++; -+ } -+ if (count == Configuration::maxSymbolCount()) tip += "\n..."; -+ -+ return tip; -+} -+ -+ -+TraceCost* CallMapView::totalCost() -+{ -+ TraceFunction* f = ((CallMapBaseItem*)base())->function(); -+ if (!f) return 0; -+ -+ return Configuration::showExpanded() ? f->inclusive() : f->data(); -+} -+ -+ -+ -+ -+// CallMapBaseItem -+ -+CallMapBaseItem::CallMapBaseItem() -+{ -+ _f = 0; -+} -+ -+void CallMapBaseItem::setFunction(TraceFunction* f) -+{ -+ if (f == _f) return; -+ -+ _f = f; -+ refresh(); -+} -+ -+ -+TQString CallMapBaseItem::text(int textNo) const -+{ -+ if (textNo == 0) { -+ if (!_f) -+ return i18n("(no function)"); -+ -+ return _f->prettyName(); -+ } -+ -+ if (!_f) return TQString(); -+ -+ if (textNo == 2) return _f->prettyLocation(); -+ if (textNo == 3) return _f->calledCount().pretty(); -+ if (textNo != 1) return TQString(); -+ -+ TraceCostType* ct = ((CallMapView*)widget())->costType(); -+ TraceCost* t = ((CallMapView*)widget())->totalCost(); -+ -+ if (Configuration::showPercentage()) { -+ double sum, total = t->subCost(ct); -+ if (total == 0.0) -+ sum = 100.0; -+ else -+ sum = 100.0 * _f->inclusive()->subCost(ct) / total; -+ -+ return TQString("%1 %") -+ .arg(sum, 0, 'f', Configuration::percentPrecision()); -+ } -+ return _f->inclusive()->prettySubCost(ct); -+} -+ -+TQPixmap CallMapBaseItem::pixmap(int i) const -+{ -+ if ((i != 1) || !_f) return TQPixmap(); -+ -+ TraceCostType* ct = ((CallMapView*)widget())->costType(); -+ TraceCost* t = ((CallMapView*)widget())->totalCost(); -+ -+ // colored level meter with frame -+ return costPixmap( ct, _f->inclusive(), (double) (t->subCost(ct)), true); -+} -+ -+ -+double CallMapBaseItem::value() const -+{ -+ if (!_f) return 0.0; -+ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ return (double) _f->inclusive()->subCost(ct); -+} -+ -+ -+double CallMapBaseItem::sum() const -+{ -+ if (!_f) return 0.0; -+ -+ CallMapView* w = (CallMapView*)widget(); -+ -+ if (w->showCallers()) -+ return 0.0; -+ else -+ return (double) _f->inclusive()->subCost(w->costType()); -+} -+ -+ -+bool CallMapBaseItem::isMarked(int) const -+{ -+ return ((CallMapView*)widget())->selectedItem() == _f; -+} -+ -+TreeMapItemList* CallMapBaseItem::children() -+{ -+ if (_f && !initialized()) { -+ CallMapView* w = (CallMapView*)widget(); -+ -+ if (0) qDebug("Create Function %s (%s)", -+ w->showCallers() ? "Callers":"Callees", -+ text(0).ascii()); -+ -+ TraceCall* call; -+ -+ setSorting(-1); -+ if (w->showCallers()) { -+ TraceCallList l = _f->callers(); -+ for (call=l.first();call;call=l.next()) { -+ -+ // don't show calls inside of a cycle -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ addItem(new CallMapCallerItem(1.0, call)); -+ } -+ -+ setSum(0); -+ } -+ else { -+ TraceCallList l = _f->callings(); -+ for (call=l.first();call;call=l.next()) { -+ -+ // don't show calls inside of a cycle -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ CallMapCallingItem* i = new CallMapCallingItem(1.0, call); -+ i->init(); -+ addItem(i); -+ } -+ -+ setSum(_f->inclusive()->subCost(w->costType())); -+ } -+ setSorting(-2, false); -+ } -+ -+ return _children; -+} -+ -+TQColor CallMapBaseItem::backColor() const -+{ -+ return ((CallMapView*)widget())->groupColor(_f); -+} -+ -+ -+ -+// CallMapCallingItems -+ -+CallMapCallingItem::CallMapCallingItem(double factor, TraceCall* c) -+{ -+ _factor = factor; -+ _c = c; -+} -+ -+void CallMapCallingItem::init() -+{ -+#if 0 -+ // create assoziation: if not possible, i.e. an ass. already exists -+ // for the function, we need to draw the recursive version -+ _recursive = !setFunction(_c->called()); -+ _valid = true; -+#endif -+} -+ -+TQString CallMapCallingItem::text(int textNo) const -+{ -+ if (textNo == 0) { -+ if (!_c) -+ return i18n("(no call)"); -+ -+ return _c->calledName(); -+ } -+ -+ if (textNo == 2) return _c->called()->prettyLocation(); -+ if (textNo == 3) return SubCost(_factor * _c->callCount()).pretty(); -+ if (textNo != 1) return TQString(); -+ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ -+ SubCost val = SubCost(_factor * _c->subCost(ct)); -+ if (Configuration::showPercentage()) { -+ // percentage relative to function cost -+ TraceCost* t = ((CallMapView*)widget())->totalCost(); -+ double p = 100.0 * _factor * _c->subCost(ct) / t->subCost(ct); -+ return TQString("%1 %") -+ .arg(p, 0, 'f', Configuration::percentPrecision()); -+ } -+ return val.pretty(); -+} -+ -+TQPixmap CallMapCallingItem::pixmap(int i) const -+{ -+ if (i != 1) return TQPixmap(); -+ -+ // Cost pixmap -+ TraceCostType* ct = ((CallMapView*)widget())->costType(); -+ TraceCost* t = ((CallMapView*)widget())->totalCost(); -+ -+ // colored level meter with frame -+ return costPixmap( ct, _c, t->subCost(ct) / _factor, true); -+} -+ -+ -+double CallMapCallingItem::value() const -+{ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ return _factor * _c->subCost(ct); -+} -+ -+double CallMapCallingItem::sum() const -+{ -+ return value(); -+} -+ -+bool CallMapCallingItem::isMarked(int) const -+{ -+ return ((CallMapView*)widget())->selectedItem() == _c->called(); -+} -+ -+ -+TreeMapItemList* CallMapCallingItem::children() -+{ -+ if (!initialized()) { -+ if (0) qDebug("Create Calling subitems (%s)", path(0).join("/").ascii()); -+ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ -+ // same as sum() -+ SubCost s = _c->called()->inclusive()->subCost(ct); -+ SubCost v = _c->subCost(ct); -+ if (v>s) { -+ qDebug("Warning: CallingItem subVal %u > Sum %u (%s)", -+ (unsigned)v, (unsigned)s, _c->called()->prettyName().ascii()); -+ v = s; -+ } -+ double newFactor = _factor * v / s; -+ -+#if 0 -+ qDebug("CallingItem: Subitems of %s => %s, factor %f * %d/%d => %f", -+ _c->caller()->prettyName().ascii(), -+ _c->called()->prettyName().ascii(), -+ _factor, v, s, newFactor); -+#endif -+ setSorting(-1); -+ TraceCall* call; -+ TraceCallList l = _c->called()->callings(); -+ for (call=l.first();call;call=l.next()) { -+ -+ // don't show calls inside of a cycle -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ CallMapCallingItem* i = new CallMapCallingItem(newFactor, call); -+ i->init(); -+ addItem(i); -+ } -+ setSorting(-2, false); -+ } -+ -+ return _children; -+} -+ -+ -+TQColor CallMapCallingItem::backColor() const -+{ -+ CallMapView* w = (CallMapView*)widget(); -+ return w->groupColor(_c->called()); -+} -+ -+ -+// CallMapCallerItem -+ -+CallMapCallerItem::CallMapCallerItem(double factor, TraceCall* c) -+{ -+ _factor = factor; -+ _c = c; -+} -+ -+TQString CallMapCallerItem::text(int textNo) const -+{ -+ if (textNo == 0) { -+ if (!_c) -+ return i18n("(no call)"); -+ -+ return _c->callerName(); -+ } -+ -+ if (textNo == 2) return _c->caller()->prettyLocation(); -+ if (textNo == 3) return SubCost(_factor * _c->callCount()).pretty(); -+ if (textNo != 1) return TQString(); -+ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ -+ SubCost val = SubCost(_factor * _c->subCost(ct)); -+ if (Configuration::showPercentage()) { -+ TraceCost* t = ((CallMapView*)widget())->totalCost(); -+ double p = 100.0 * _factor * _c->subCost(ct) / t->subCost(ct); -+ return TQString("%1 %") -+ .arg(p, 0, 'f', Configuration::percentPrecision()); -+ } -+ return val.pretty(); -+} -+ -+ -+TQPixmap CallMapCallerItem::pixmap(int i) const -+{ -+ if (i != 1) return TQPixmap(); -+ -+ // Cost pixmap -+ TraceCostType* ct = ((CallMapView*)widget())->costType(); -+ TraceCost* t = ((CallMapView*)widget())->totalCost(); -+ -+ // colored level meter with frame -+ return costPixmap( ct, _c, t->subCost(ct) / _factor, true ); -+} -+ -+ -+double CallMapCallerItem::value() const -+{ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ return (double) _c->subCost(ct); -+} -+ -+bool CallMapCallerItem::isMarked(int) const -+{ -+ return ((CallMapView*)widget())->selectedItem() == _c->caller(); -+} -+ -+ -+TreeMapItemList* CallMapCallerItem::children() -+{ -+ if (!initialized()) { -+ //qDebug("Create Caller subitems (%s)", name().ascii()); -+ -+ TraceCostType* ct; -+ ct = ((CallMapView*)widget())->costType(); -+ -+ SubCost s = _c->caller()->inclusive()->subCost(ct); -+ SubCost v = _c->subCost(ct); -+ double newFactor = _factor * v / s; -+ -+ -+#if 0 -+ qDebug("CallerItem: Subitems of %s => %s, factor %f * %d/%d => %f", -+ _c->caller()->prettyName().ascii(), -+ _c->called()->prettyName().ascii(), -+ _factor, v, s, newFactor); -+#endif -+ setSorting(-1); -+ -+ TraceCall* call; -+ TraceCallList l = _c->caller()->callers(); -+ for (call=l.first();call;call=l.next()) { -+ -+ // don't show calls inside of a cycle -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ TreeMapItem* i = new CallMapCallerItem(newFactor, call); -+ addItem(i); -+ } -+ setSorting(-2, false); -+ } -+ -+ return _children; -+} -+ -+TQColor CallMapCallerItem::backColor() const -+{ -+ CallMapView* w = (CallMapView*)widget(); -+ return w->groupColor(_c->caller()); -+} -+ -+void CallMapView::readViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ KConfigGroup* g = configGroup(c, prefix, postfix); -+ -+ setSplitMode(g->readEntry("SplitMode", DEFAULT_SPLITMODE)); -+ -+ setFieldVisible(0, g->readBoolEntry("DrawName", DEFAULT_DRAWNAME)); -+ setFieldVisible(1, g->readBoolEntry("DrawCost", DEFAULT_DRAWCOST)); -+ setFieldVisible(2, g->readBoolEntry("DrawLocation", DEFAULT_DRAWLOCATION)); -+ setFieldVisible(3, g->readBoolEntry("DrawCalls", DEFAULT_DRAWCALLS)); -+ -+ bool enable = g->readBoolEntry("ForceStrings", DEFAULT_FORCESTRINGS); -+ setFieldForced(0, enable); -+ setFieldForced(1, enable); -+ setFieldForced(2, enable); -+ setFieldForced(3, enable); -+ -+ setAllowRotation(g->readBoolEntry("AllowRotation", DEFAULT_ROTATION)); -+ setShadingEnabled(g->readBoolEntry("Shading", DEFAULT_SHADING)); -+ setFieldStop(0, g->readEntry("StopName")); -+ setMaxDrawingDepth(g->readNumEntry("MaxDepth", -1)); -+ setMinimalArea(g->readNumEntry("MaxArea", DEFAULT_MAXAREA)); -+ -+ delete g; -+} -+ -+void CallMapView::saveViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ KConfigGroup g(c, (prefix+postfix).ascii()); -+ -+ writeConfigEntry(&g, "SplitMode", splitModeString(), DEFAULT_SPLITMODE); -+ writeConfigEntry(&g, "DrawName", fieldVisible(0), DEFAULT_DRAWNAME); -+ writeConfigEntry(&g, "DrawCost", fieldVisible(1), DEFAULT_DRAWCOST); -+ writeConfigEntry(&g, "DrawLocation", fieldVisible(2), DEFAULT_DRAWLOCATION); -+ writeConfigEntry(&g, "DrawCalls", fieldVisible(3), DEFAULT_DRAWCALLS); -+ // when option for all text (0-3) -+ writeConfigEntry(&g, "ForceStrings", fieldForced(0), DEFAULT_FORCESTRINGS); -+ -+ writeConfigEntry(&g, "AllowRotation", allowRotation(), DEFAULT_ROTATION); -+ writeConfigEntry(&g, "Shading", isShadingEnabled(), DEFAULT_SHADING); -+ -+ writeConfigEntry(&g, "StopName", fieldStop(0), ""); -+ writeConfigEntry(&g, "MaxDepth", maxDrawingDepth(), -1); -+ writeConfigEntry(&g, "MaxArea", minimalArea(), DEFAULT_MAXAREA); -+} -+ -+#include "callmapview.moc" -diff --git a/kdecachegrind/kdecachegrind/callmapview.h b/kdecachegrind/kdecachegrind/callmapview.h -new file mode 100644 -index 0000000..860743f ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callmapview.h -@@ -0,0 +1,130 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Call Map View -+ */ -+ -+#ifndef CALLMAPVIEW_H -+#define CALLMAPVIEW_H -+ -+#include "treemap.h" -+#include "tracedata.h" -+#include "traceitemview.h" -+ -+class CallMapView: public TreeMapWidget, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ -+ CallMapView(bool showCallers, TraceItemView* parentView, -+ TQWidget* parent=0, const char* name=0); -+ -+ TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ void setData(TraceData*); -+ -+ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ -+ bool showCallers() const { return _showCallers; } -+ TraceCost* totalCost(); -+ TQString tipString(TreeMapItem*) const; -+ TQColor groupColor(TraceFunction*) const; -+ -+private slots: -+ void context(TreeMapItem*,const TQPoint &); -+ void selectedSlot(TreeMapItem*, bool); -+ void activatedSlot(TreeMapItem*); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ -+ bool _showCallers; -+}; -+ -+ -+ -+// Subitems of CallMap -+ -+class CallMapBaseItem: public TreeMapItem -+{ -+public: -+ CallMapBaseItem(); -+ -+ void setFunction(TraceFunction* f); -+ TraceFunction* function() { return _f; } -+ int rtti() const { return 1; } -+ double sum() const; -+ double value() const ; -+ bool isMarked(int) const; -+ TQString text(int) const; -+ TQPixmap pixmap(int) const; -+ TreeMapItemList* children(); -+ TQColor backColor() const; -+ -+private: -+ TraceFunction* _f; -+}; -+ -+ -+class CallMapCallingItem: public TreeMapItem -+{ -+public: -+ CallMapCallingItem(double factor, TraceCall* c); -+ void init(); -+ int rtti() const { return 2; } -+ int borderWidth() const { return widget()->borderWidth(); } -+ TraceFunction* function() { return _c->called(); } -+ double value() const; -+ double sum() const; -+ bool isMarked(int) const; -+ TQString text(int) const; -+ TQPixmap pixmap(int) const; -+ TreeMapItemList* children(); -+ TQColor backColor() const; -+ -+private: -+ TraceCall* _c; -+ double _factor; -+}; -+ -+class CallMapCallerItem: public TreeMapItem -+{ -+public: -+ CallMapCallerItem(double factor, TraceCall* c); -+ int rtti() const { return 3; } -+ int borderWidth() const { return widget()->borderWidth(); } -+ TraceFunction* function() { return _c->caller(); } -+ double value() const; -+ bool isMarked(int) const; -+ TQString text(int) const; -+ TQPixmap pixmap(int) const; -+ TreeMapItemList* children(); -+ TQColor backColor() const; -+ -+private: -+ TraceCall* _c; -+ double _factor; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/callview.cpp b/kdecachegrind/kdecachegrind/callview.cpp -new file mode 100644 -index 0000000..317d137 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callview.cpp -@@ -0,0 +1,256 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Call Views -+ */ -+ -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "callitem.h" -+#include "callview.h" -+ -+ -+ -+// -+// CallView -+// -+ -+ -+CallView::CallView(bool showCallers, TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQListView(parent, name), TraceItemView(parentView) -+{ -+ _showCallers = showCallers; -+ -+ addColumn( i18n( "Cost" ) ); -+ addColumn( i18n( "Cost 2" ) ); -+ if (_showCallers) { -+ addColumn( i18n( "Count" ) ); -+ addColumn( i18n( "Caller" ) ); -+ } -+ else { -+ addColumn( i18n( "Count" ) ); -+ addColumn( i18n( "Callee" ) ); -+ } -+ -+ setSorting(0,false); -+ setColumnAlignment(0, TQt::AlignRight); -+ setColumnAlignment(1, TQt::AlignRight); -+ setColumnAlignment(2, TQt::AlignRight); -+ setAllColumnsShowFocus(true); -+ setResizeMode(TQListView::LastColumn); -+ setMinimumHeight(50); -+ -+ connect( this, -+ TQT_SIGNAL( selectionChanged(TQListViewItem*) ), -+ TQT_SLOT( selectedSlot(TQListViewItem*) ) ); -+ -+ connect( this, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int))); -+ -+ connect(this, -+ TQT_SIGNAL(doubleClicked(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ TQWhatsThis::add( this, whatsThis() ); -+} -+ -+TQString CallView::whatsThis() const -+{ -+ return _showCallers ? -+ i18n( "List of direct Callers" -+ "

This list shows all functions calling the " -+ "current selected one directly, together with " -+ "a call count and the cost spent in the current " -+ "selected function while being called from the " -+ "function from the list.

" -+ "

An icon instead of an inclusive cost specifies " -+ "that this is a call inside of a recursive cycle. " -+ "An inclusive cost makes no sense here.

" -+ "

Selecting a function makes it the current selected " -+ "one of this information panel. " -+ "If there are two panels (Split mode), the " -+ "function of the other panel is changed instead.

") : -+ i18n( "List of direct Callees" -+ "

This list shows all functions called by the " -+ "current selected one directly, together with " -+ "a call count and the cost spent in this function " -+ "while being called from the selected function.

" -+ "

Selecting a function makes it the current selected " -+ "one of this information panel. " -+ "If there are two panels (Split mode), the " -+ "function of the other panel is changed instead.

"); -+} -+ -+ -+void CallView::context(TQListViewItem* i, const TQPoint & p, int col) -+{ -+ TQPopupMenu popup; -+ -+ // Menu entry: -+ TraceCall* c = i ? ((CallItem*) i)->call() : 0; -+ TraceFunction *f = 0, *cycle = 0; -+ -+ if (c) { -+ TQString name = _showCallers ? c->callerName(true) : c->calledName(true); -+ f = _showCallers ? c->caller(true) : c->called(true); -+ cycle = f->cycle(); -+ -+ popup.insertItem(i18n("Go to '%1'") -+ .arg(Configuration::shortenSymbol(name)), 93); -+ -+ if (cycle) { -+ name = Configuration::shortenSymbol(cycle->prettyName()); -+ popup.insertItem(i18n("Go to '%1'").arg(name), 94); -+ } -+ -+ popup.insertSeparator(); -+ } -+ -+ if ((col == 0) || (col == 1)) { -+ addCostMenu(&popup); -+ popup.insertSeparator(); -+ } -+ addGoMenu(&popup); -+ -+ int r = popup.exec(p); -+ if (r == 93) activated(f); -+ else if (r == 94) activated(cycle); -+} -+ -+void CallView::selectedSlot(TQListViewItem * i) -+{ -+ if (!i) return; -+ TraceCall* c = ((CallItem*) i)->call(); -+ // Should we skip cycles here? -+ TraceItem* f = _showCallers ? c->caller(false) : c->called(false); -+ -+ _selectedItem = f; -+ selected(f); -+} -+ -+void CallView::activatedSlot(TQListViewItem * i) -+{ -+ if (!i) return; -+ TraceCall* c = ((CallItem*) i)->call(); -+ // skip cycles: use the context menu to get to the cycle... -+ TraceItem* f = _showCallers ? c->caller(true) : c->called(true); -+ -+ activated(f); -+} -+ -+TraceItem* CallView::canShow(TraceItem* i) -+{ -+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType; -+ -+ switch(t) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ return i; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+void CallView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == selectedItemChanged) { -+ -+ if (!_selectedItem) { -+ clearSelection(); -+ return; -+ } -+ -+ CallItem* ci = (CallItem*) TQListView::selectedItem(); -+ TraceCall* c; -+ TraceItem* ti; -+ if (ci) { -+ c = ci->call(); -+ ti = _showCallers ? c->caller() : c->called(); -+ if (ti == _selectedItem) return; -+ } -+ -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) { -+ c = ((CallItem*) item)->call(); -+ ti = _showCallers ? c->caller() : c->called(); -+ if (ti == _selectedItem) { -+ ensureItemVisible(item); -+ setSelected(item, true); -+ break; -+ } -+ } -+ if (!item && ci) clearSelection(); -+ return; -+ } -+ -+ if (changeType == groupTypeChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) -+ ((CallItem*)item)->updateGroup(); -+ return; -+ } -+ -+ refresh(); -+} -+ -+void CallView::refresh() -+{ -+ clear(); -+ setColumnWidth(0, 50); -+ setColumnWidth(1, _costType2 ? 50:0); -+ setColumnWidth(2, 50); -+ if (_costType) -+ setColumnText(0, _costType->name()); -+ if (_costType2) -+ setColumnText(1, _costType2->name()); -+ -+ if (!_data || !_activeItem) return; -+ -+ TraceFunction* f = activeFunction(); -+ if (!f) return; -+ -+ TraceCall* call; -+ // In the call lists, we skip cycles to show the real call relations -+ TraceCallList l = _showCallers ? f->callers(true) : f->callings(true); -+ -+ // Allow resizing of column 1 -+ setColumnWidthMode(1, TQListView::Maximum); -+ -+ for (call=l.first();call;call=l.next()) -+ if (call->subCost(_costType)>0) -+ new CallItem(this, this, call); -+ -+ if (!_costType2) { -+ setColumnWidthMode(1, TQListView::Manual); -+ setColumnWidth(1, 0); -+ } -+} -+ -+#include "callview.moc" -diff --git a/kdecachegrind/kdecachegrind/callview.h b/kdecachegrind/kdecachegrind/callview.h -new file mode 100644 -index 0000000..be644f9 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/callview.h -@@ -0,0 +1,56 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Call Views -+ */ -+ -+#ifndef CALLVIEW_H -+#define CALLVIEW_H -+ -+#include -+#include "tracedata.h" -+#include "traceitemview.h" -+ -+class CallView: public TQListView, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ CallView(bool showCallers, TraceItemView* parentView, -+ TQWidget* parent=0, const char* name=0); -+ -+ virtual TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ bool showCallers() const { return _showCallers; } -+ -+private slots: -+ void context(TQListViewItem*,const TQPoint &, int); -+ void selectedSlot(TQListViewItem*); -+ void activatedSlot(TQListViewItem*); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ void refresh(); -+ -+ bool _showCallers; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/configdlg.cpp b/kdecachegrind/kdecachegrind/configdlg.cpp -new file mode 100644 -index 0000000..e0b4547 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/configdlg.cpp -@@ -0,0 +1,398 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Configuration Dialog for KCachegrind -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "configdlg.h" -+#include "tracedata.h" -+#include "configuration.h" -+ -+ -+ConfigDlg::ConfigDlg(Configuration* c, TraceData* data, -+ TQWidget* parent, const char* name) -+ :ConfigDlgBase(parent, name) -+{ -+ _config = c; -+ _data = data; -+ _objectCS = 0; -+ _classCS = 0; -+ _fileCS = 0; -+ KIntValidator * numValidator = new KIntValidator( this ); -+ maxListEdit->setValidator(numValidator ); -+ symbolCount->setValidator(numValidator ); -+ symbolLength->setValidator(numValidator ); -+ precisionEdit->setValidator(numValidator ); -+ contextEdit->setValidator(numValidator ); -+ -+#if 0 -+ TQListViewItem *oItem, *fItem, *cItem, *fnItem; -+ oItem = new(colorList, i18n("ELF Objects")); -+ -+ fItem = new(colorList, i18n("Source Files")); -+ cItem = new(colorList, i18n("C++ Classes")); -+ fnItem = new(colorList, i18n("Function (no Grouping)")); -+#endif -+ -+ connect(objectCombo, TQT_SIGNAL(activated(const TQString &)), -+ this, TQT_SLOT(objectActivated(const TQString &))); -+ connect(objectCombo, TQT_SIGNAL(textChanged(const TQString &)), -+ this, TQT_SLOT(objectActivated(const TQString &))); -+ connect(objectCheck, TQT_SIGNAL(toggled(bool)), -+ this, TQT_SLOT(objectCheckChanged(bool))); -+ connect(objectColor, TQT_SIGNAL(changed(const TQColor &)), -+ this, TQT_SLOT(objectColorChanged(const TQColor &))); -+ -+ connect(classCombo, TQT_SIGNAL(activated(const TQString &)), -+ this, TQT_SLOT(classActivated(const TQString &))); -+ connect(classCombo, TQT_SIGNAL(textChanged(const TQString &)), -+ this, TQT_SLOT(classActivated(const TQString &))); -+ connect(classCheck, TQT_SIGNAL(toggled(bool)), -+ this, TQT_SLOT(classCheckChanged(bool))); -+ connect(classColor, TQT_SIGNAL(changed(const TQColor &)), -+ this, TQT_SLOT(classColorChanged(const TQColor &))); -+ -+ connect(fileCombo, TQT_SIGNAL(activated(const TQString &)), -+ this, TQT_SLOT(fileActivated(const TQString &))); -+ connect(fileCombo, TQT_SIGNAL(textChanged(const TQString &)), -+ this, TQT_SLOT(fileActivated(const TQString &))); -+ connect(fileCheck, TQT_SIGNAL(toggled(bool)), -+ this, TQT_SLOT(fileCheckChanged(bool))); -+ connect(fileColor, TQT_SIGNAL(changed(const TQColor &)), -+ this, TQT_SLOT(fileColorChanged(const TQColor &))); -+ -+ TQString objectPrefix = TraceCost::typeName(TraceCost::Object); -+ TQString classPrefix = TraceCost::typeName(TraceCost::Class); -+ TQString filePrefix = TraceCost::typeName(TraceCost::File); -+ -+ objectCombo->setDuplicatesEnabled(false); -+ classCombo->setDuplicatesEnabled(false); -+ fileCombo->setDuplicatesEnabled(false); -+ objectCombo->setAutoCompletion(true); -+ classCombo->setAutoCompletion(true); -+ fileCombo->setAutoCompletion(true); -+ -+ // first unspecified cost items from data -+ TraceObjectMap::Iterator oit; -+ TQStringList oList; -+ for ( oit = data->objectMap().begin(); -+ oit != data->objectMap().end(); ++oit ) -+ oList.append((*oit).prettyName()); -+ -+ TraceClassMap::Iterator cit; -+ TQStringList cList; -+ for ( cit = data->classMap().begin(); -+ cit != data->classMap().end(); ++cit ) -+ cList.append((*cit).prettyName()); -+ -+ TraceFileMap::Iterator fit; -+ TQStringList fList; -+ for ( fit = data->fileMap().begin(); -+ fit != data->fileMap().end(); ++fit ) -+ fList.append((*fit).prettyName()); -+ -+ // then already defined colors (have to check for duplicates!) -+ TQDictIterator it( c->_colors ); -+ for( ; it.current(); ++it ) { -+ if ((*it)->automatic) continue; -+ -+ TQString n = it.currentKey(); -+ if (n.startsWith(objectPrefix)) { -+ n = n.remove(0, objectPrefix.length()+1); -+ if (oList.findIndex(n) == -1) oList.append(n); -+ } -+ else if (n.startsWith(classPrefix)) { -+ n = n.remove(0, classPrefix.length()+1); -+ if (cList.findIndex(n) == -1) cList.append(n); -+ } -+ else if (n.startsWith(filePrefix)) { -+ n = n.remove(0, filePrefix.length()+1); -+ if (fList.findIndex(n) == -1) fList.append(n); -+ } -+ } -+ -+ oList.sort(); -+ cList.sort(); -+ fList.sort(); -+ objectCombo->insertStringList(oList); -+ classCombo->insertStringList(cList); -+ fileCombo->insertStringList(fList); -+ -+ objectActivated(objectCombo->currentText()); -+ classActivated(classCombo->currentText()); -+ fileActivated(fileCombo->currentText()); -+ -+ maxListEdit->setText(TQString::number(c->_maxListCount)); -+ -+ _dirItem = 0; -+ -+ TQListViewItem* i = new TQListViewItem(dirList, i18n("(always)")); -+ i->setOpen(true); -+ TQStringList::Iterator sit = c->_generalSourceDirs.begin(); -+ for(; sit != c->_generalSourceDirs.end(); ++sit ) { -+ TQString d = (*sit); -+ if (d.isEmpty()) d = "/"; -+ new TQListViewItem(i, d); -+ } -+ for ( oit = data->objectMap().begin(); -+ oit != data->objectMap().end(); ++oit ) { -+ TQString n = (*oit).name(); -+ i = new TQListViewItem(dirList, n); -+ i->setOpen(true); -+ TQStringList* dirs = c->_objectSourceDirs[n]; -+ if (!dirs) continue; -+ -+ sit = dirs->begin(); -+ for(; sit != dirs->end(); ++sit ) { -+ TQString d = (*sit); -+ if (d.isEmpty()) d = "/"; -+ new TQListViewItem(i, d); -+ } -+ } -+ -+ connect(dirList, TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ this, TQT_SLOT(dirsItemChanged(TQListViewItem*))); -+ connect(addDirButton, TQT_SIGNAL(clicked()), -+ this, TQT_SLOT(dirsAddPressed())); -+ connect(deleteDirButton, TQT_SIGNAL(clicked()), -+ this, TQT_SLOT(dirsDeletePressed())); -+ dirList->setSelected(dirList->firstChild(), true); -+ -+ symbolCount->setText(TQString::number(c->_maxSymbolCount)); -+ symbolLength->setText(TQString::number(c->_maxSymbolLength)); -+ precisionEdit->setText(TQString::number(c->_percentPrecision)); -+ contextEdit->setText(TQString::number(c->_context)); -+} -+ -+ConfigDlg::~ConfigDlg() -+{ -+} -+ -+bool ConfigDlg::configure(Configuration* c, TraceData* d, TQWidget* p) -+{ -+ ConfigDlg dlg(c, d, p); -+ -+ if (dlg.exec()) { -+ -+ bool ok; -+ int newValue = dlg.maxListEdit->text().toUInt(&ok); -+ if (ok && newValue < 500) -+ c->_maxListCount = newValue; -+ else -+ TQMessageBox::warning(p, i18n("KCachegrind Configuration"), -+ i18n("The Maximum Number of List Items should be below 500." -+ "The previous set value (%1) will still be used.") -+ .arg(TQString::number(c->_maxListCount)), -+ TQMessageBox::Ok, 0); -+ -+ c->_maxSymbolCount = dlg.symbolCount->text().toInt(); -+ c->_maxSymbolLength = dlg.symbolLength->text().toInt(); -+ c->_percentPrecision = dlg.precisionEdit->text().toInt(); -+ c->_context = dlg.contextEdit->text().toInt(); -+ return true; -+ } -+ return false; -+} -+ -+void ConfigDlg::objectActivated(const TQString & s) -+{ -+// qDebug("objectActivated: %s", s.ascii()); -+ -+ if (s.isEmpty()) { _objectCS=0; return; } -+ -+ TQString n = TraceCost::typeName(TraceCost::Object) + "-" + s; -+ -+ Configuration* c = Configuration::config(); -+ Configuration::ColorSetting* cs = c->_colors[n]; -+ if (!cs) -+ cs = Configuration::color(n); -+// else -+// qDebug("found color %s", n.ascii()); -+ -+ _objectCS = cs; -+ -+ objectCheck->setChecked(cs->automatic); -+ objectColor->setColor(cs->color); -+ -+ /* -+ qDebug("Found Color %s, automatic to %s", -+ _objectCS->name.ascii(), -+ _objectCS->automatic ? "true":"false"); -+ */ -+} -+ -+ -+void ConfigDlg::objectCheckChanged(bool b) -+{ -+ if (_objectCS) { -+ _objectCS->automatic = b; -+ /* -+ qDebug("Set Color %s automatic to %s", -+ _objectCS->name.ascii(), -+ _objectCS->automatic ? "true":"false"); -+ */ -+ } -+} -+ -+void ConfigDlg::objectColorChanged(const TQColor & c) -+{ -+ if (_objectCS) _objectCS->color = c; -+} -+ -+void ConfigDlg::classActivated(const TQString & s) -+{ -+// qDebug("classActivated: %s", s.ascii()); -+ -+ if (s.isEmpty()) { _classCS=0; return; } -+ -+ TQString n = TraceCost::typeName(TraceCost::Class) + "-" + s; -+ -+ Configuration* c = Configuration::config(); -+ Configuration::ColorSetting* cs = c->_colors[n]; -+ if (!cs) -+ cs = Configuration::color(n); -+ -+ _classCS = cs; -+ -+ classCheck->setChecked(cs->automatic); -+ classColor->setColor(cs->color); -+ -+} -+ -+ -+void ConfigDlg::classCheckChanged(bool b) -+{ -+ if (_classCS) _classCS->automatic = b; -+} -+ -+void ConfigDlg::classColorChanged(const TQColor & c) -+{ -+ if (_classCS) _classCS->color = c; -+} -+ -+ -+void ConfigDlg::fileActivated(const TQString & s) -+{ -+// qDebug("fileActivated: %s", s.ascii()); -+ -+ if (s.isEmpty()) { _fileCS=0; return; } -+ -+ TQString n = TraceCost::typeName(TraceCost::File) + "-" + s; -+ -+ Configuration* c = Configuration::config(); -+ Configuration::ColorSetting* cs = c->_colors[n]; -+ if (!cs) -+ cs = Configuration::color(n); -+ -+ _fileCS = cs; -+ -+ fileCheck->setChecked(cs->automatic); -+ fileColor->setColor(cs->color); -+} -+ -+ -+void ConfigDlg::fileCheckChanged(bool b) -+{ -+ if (_fileCS) _fileCS->automatic = b; -+} -+ -+void ConfigDlg::fileColorChanged(const TQColor & c) -+{ -+ if (_fileCS) _fileCS->color = c; -+} -+ -+ -+void ConfigDlg::dirsItemChanged(TQListViewItem* i) -+{ -+ _dirItem = i; -+ deleteDirButton->setEnabled(i->depth() == 1); -+ addDirButton->setEnabled(i->depth() == 0); -+} -+ -+void ConfigDlg::dirsDeletePressed() -+{ -+ if (!_dirItem || (_dirItem->depth() == 0)) return; -+ TQListViewItem* p = _dirItem->parent(); -+ if (!p) return; -+ -+ Configuration* c = Configuration::config(); -+ TQString objName = p->text(0); -+ -+ TQStringList* dirs; -+ if (objName == i18n("(always)")) -+ dirs = &(c->_generalSourceDirs); -+ else -+ dirs = c->_objectSourceDirs[objName]; -+ if (!dirs) return; -+ -+ dirs->remove(_dirItem->text(0)); -+ delete _dirItem; -+ _dirItem = 0; -+ -+ deleteDirButton->setEnabled(false); -+} -+ -+void ConfigDlg::dirsAddPressed() -+{ -+ if (!_dirItem || (_dirItem->depth() >0)) return; -+ -+ Configuration* c = Configuration::config(); -+ TQString objName = _dirItem->text(0); -+ -+ TQStringList* dirs; -+ if (objName == i18n("(always)")) -+ dirs = &(c->_generalSourceDirs); -+ else { -+ dirs = c->_objectSourceDirs[objName]; -+ if (!dirs) { -+ dirs = new TQStringList; -+ c->_objectSourceDirs.insert(objName, dirs); -+ } -+ } -+ -+ TQString newDir; -+ newDir = KFileDialog::getExistingDirectory(TQString(), -+ this, -+ i18n("Choose Source Folder")); -+ if (newDir.isEmpty()) return; -+ -+ // even for "/", we strip the tailing slash -+ if (newDir.endsWith("/")) -+ newDir = newDir.left(newDir.length()-1); -+ -+ if (dirs->findIndex(newDir)>=0) return; -+ -+ dirs->append(newDir); -+ if (newDir.isEmpty()) newDir = TQString("/"); -+ new TQListViewItem(_dirItem, newDir); -+} -+ -+#include "configdlg.moc" -diff --git a/kdecachegrind/kdecachegrind/configdlg.h b/kdecachegrind/kdecachegrind/configdlg.h -new file mode 100644 -index 0000000..5ef6bab ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/configdlg.h -@@ -0,0 +1,65 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Configuration Dialog for KCachegrind -+ */ -+ -+#ifndef CONFIGDLG_H -+#define CONFIGDLG_H -+ -+#include "configdlgbase.h" -+#include "configuration.h" -+ -+class TraceData; -+ -+class ConfigDlg : public ConfigDlgBase -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ ConfigDlg(Configuration*, TraceData*, -+ TQWidget* parent = 0, const char* name = 0); -+ ~ConfigDlg(); -+ -+ static bool configure(Configuration*, TraceData*, TQWidget*); -+ -+protected slots: -+ void objectActivated(const TQString &); -+ void objectCheckChanged(bool); -+ void objectColorChanged(const TQColor &); -+ void classActivated(const TQString &); -+ void classCheckChanged(bool); -+ void classColorChanged(const TQColor &); -+ void fileActivated(const TQString &); -+ void fileCheckChanged(bool); -+ void fileColorChanged(const TQColor &); -+ void dirsItemChanged(TQListViewItem*); -+ void dirsDeletePressed(); -+ void dirsAddPressed(); -+ -+private: -+ Configuration* _config; -+ TraceData* _data; -+ -+ Configuration::ColorSetting *_objectCS, *_classCS, *_fileCS; -+ TQListViewItem* _dirItem; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/configdlgbase.ui b/kdecachegrind/kdecachegrind/configdlgbase.ui -new file mode 100644 -index 0000000..dc0ee9e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/configdlgbase.ui -@@ -0,0 +1,653 @@ -+ -+ConfigDlgBase -+ -+ -+ configDlgBase -+ -+ -+ -+ 0 -+ 0 -+ 447 -+ 378 -+ -+ -+ -+ Configuration -+ -+ -+ -+ unnamed -+ -+ -+ 11 -+ -+ -+ 6 -+ -+ -+ -+ tabWidget2 -+ -+ -+ -+ tab -+ -+ -+ General -+ -+ -+ -+ unnamed -+ -+ -+ -+ layout10 -+ -+ -+ -+ unnamed -+ -+ -+ -+ precisionEdit -+ -+ -+ -+ 7 -+ 0 -+ 2 -+ 0 -+ -+ -+ -+ -+ -+ TextLabel2 -+ -+ -+ Truncated when more/longer than: -+ -+ -+ -+ -+ TextLabel4_3 -+ -+ -+ Precision of percentage values: -+ -+ -+ -+ -+ TextLabel3 -+ -+ -+ Symbols in tooltips and context menus -+ -+ -+ -+ -+ symbolLength -+ -+ -+ -+ 4 -+ 0 -+ 0 -+ 0 -+ -+ -+ -+ -+ -+ Spacer6_2_2_2 -+ -+ -+ Horizontal -+ -+ -+ Fixed -+ -+ -+ -+ 16 -+ 20 -+ -+ -+ -+ -+ -+ maxListEdit -+ -+ -+ -+ -+ symbolCount -+ -+ -+ -+ 4 -+ 0 -+ 0 -+ 0 -+ -+ -+ -+ -+ -+ TextLabel5 -+ -+ -+ Maximum number of items in lists: -+ -+ -+ -+ -+ -+ -+ TextLabel1 -+ -+ -+ -+ 1 -+ -+ -+ -+ NoFrame -+ -+ -+ Plain -+ -+ -+ Cost Item Colors -+ -+ -+ -+ -+ Layout9 -+ -+ -+ -+ unnamed -+ -+ -+ 0 -+ -+ -+ 6 -+ -+ -+ -+ Spacer9 -+ -+ -+ Vertical -+ -+ -+ Fixed -+ -+ -+ -+ 20 -+ 16 -+ -+ -+ -+ -+ -+ Spacer6 -+ -+ -+ Horizontal -+ -+ -+ Fixed -+ -+ -+ -+ 16 -+ 20 -+ -+ -+ -+ -+ -+ Layout9 -+ -+ -+ -+ unnamed -+ -+ -+ 0 -+ -+ -+ 6 -+ -+ -+ -+ classCombo -+ -+ -+ -+ 300 -+ 32767 -+ -+ -+ -+ true -+ -+ -+ -+ -+ fileCheck -+ -+ -+ Automatic -+ -+ -+ -+ -+ TextLabel4 -+ -+ -+ Object: -+ -+ -+ -+ -+ TextLabel4_2_2 -+ -+ -+ Class: -+ -+ -+ -+ -+ fileColor -+ -+ -+ -+ 0 -+ 0 -+ 0 -+ 0 -+ -+ -+ -+ -+ -+ -+ -+ -+ classCheck -+ -+ -+ Automatic -+ -+ -+ -+ -+ objectColor -+ -+ -+ -+ -+ -+ -+ -+ objectCheck -+ -+ -+ Automatic -+ -+ -+ -+ -+ TextLabel4_2 -+ -+ -+ File: -+ -+ -+ -+ -+ classColor -+ -+ -+ -+ 0 -+ 0 -+ 0 -+ 0 -+ -+ -+ -+ -+ -+ -+ -+ -+ fileCombo -+ -+ -+ -+ 300 -+ 32767 -+ -+ -+ -+ true -+ -+ -+ -+ -+ objectCombo -+ -+ -+ -+ 3 -+ 0 -+ 0 -+ 0 -+ -+ -+ -+ -+ 300 -+ 32767 -+ -+ -+ -+ true -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ tab -+ -+ -+ Annotations -+ -+ -+ -+ unnamed -+ -+ -+ -+ layout8 -+ -+ -+ -+ unnamed -+ -+ -+ -+ TextLabel4_3_2 -+ -+ -+ Context lines in annotations: -+ -+ -+ -+ -+ contextEdit -+ -+ -+ -+ 7 -+ 0 -+ 2 -+ 0 -+ -+ -+ -+ -+ -+ -+ -+ TextLabel1_2 -+ -+ -+ -+ 1 -+ -+ -+ -+ Source Folders -+ -+ -+ -+ -+ layout11 -+ -+ -+ -+ unnamed -+ -+ -+ -+ Spacer6_2 -+ -+ -+ Horizontal -+ -+ -+ Fixed -+ -+ -+ -+ 16 -+ 20 -+ -+ -+ -+ -+ -+ -+ Object / Related Source Base -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ dirList -+ -+ -+ true -+ -+ -+ -+ -+ layout10 -+ -+ -+ -+ unnamed -+ -+ -+ -+ addDirButton -+ -+ -+ Add... -+ -+ -+ -+ -+ Spacer5 -+ -+ -+ Vertical -+ -+ -+ Expanding -+ -+ -+ -+ 16 -+ 49 -+ -+ -+ -+ -+ -+ deleteDirButton -+ -+ -+ Delete -+ -+ -+ -+ -+ -+ -+ Spacer9_2 -+ -+ -+ Vertical -+ -+ -+ Fixed -+ -+ -+ -+ 20 -+ 16 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Line1 -+ -+ -+ HLine -+ -+ -+ Sunken -+ -+ -+ Horizontal -+ -+ -+ -+ -+ Layout4 -+ -+ -+ -+ unnamed -+ -+ -+ 0 -+ -+ -+ 6 -+ -+ -+ -+ Spacer2 -+ -+ -+ Horizontal -+ -+ -+ Expanding -+ -+ -+ -+ 210 -+ 0 -+ -+ -+ -+ -+ -+ PushButton2 -+ -+ -+ &OK -+ -+ -+ true -+ -+ -+ -+ -+ PushButton1 -+ -+ -+ &Cancel -+ -+ -+ -+ -+ -+ -+ -+ -+ PushButton2 -+ clicked() -+ configDlgBase -+ accept() -+ -+ -+ PushButton1 -+ clicked() -+ configDlgBase -+ reject() -+ -+ -+ classCheck -+ toggled(bool) -+ classColor -+ setDisabled(bool) -+ -+ -+ fileCheck -+ toggled(bool) -+ fileColor -+ setDisabled(bool) -+ -+ -+ objectCheck -+ toggled(bool) -+ objectColor -+ setDisabled(bool) -+ -+ -+ -+ objectCombo -+ objectCheck -+ classCombo -+ classCheck -+ classColor -+ fileCombo -+ fileCheck -+ fileColor -+ maxListEdit -+ PushButton1 -+ PushButton2 -+ -+ -+ kcolorbutton.h -+ -+ -+ -+ -diff --git a/kdecachegrind/kdecachegrind/configuration.cpp b/kdecachegrind/kdecachegrind/configuration.cpp -new file mode 100644 -index 0000000..02d5c09 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/configuration.cpp -@@ -0,0 +1,490 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Configuration for KCachegrind -+ */ -+ -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "tracedata.h" -+#include "configdlgbase.h" -+ -+#include "traceitemview.h" -+ -+// -+// Some predefined cost types... -+// -+ -+static TQStringList knownTypes() -+{ -+ TQStringList l; -+ -+ l << "Ir" << "Dr" << "Dw" -+ << "I1mr" << "D1mr" << "D1mw" -+ << "I2mr" << "D2mr" << "D2mw" -+ -+ << "Smp" << "Sys" << "User" -+ << "L1m" << "L2m" << "CEst"; -+ -+ return l; -+} -+ -+ -+static TQString knownFormula(TQString name) -+{ -+ if (name =="L1m") return TQString("I1mr + D1mr + D1mw"); -+ if (name =="L2m") return TQString("I2mr + D2mr + D2mw"); -+ if (name =="CEst") return TQString("Ir + 10 L1m + 100 L2m"); -+ -+ return TQString(); -+} -+ -+static TQString knownLongName(TQString name) -+{ -+ if (name == "Ir") return i18n("Instruction Fetch"); -+ if (name =="Dr") return i18n("Data Read Access"); -+ if (name =="Dw") return i18n("Data Write Access"); -+ if (name =="I1mr") return i18n("L1 Instr. Fetch Miss"); -+ if (name =="D1mr") return i18n("L1 Data Read Miss"); -+ if (name =="D1mw") return i18n("L1 Data Write Miss"); -+ if (name =="I2mr") return i18n("L2 Instr. Fetch Miss"); -+ if (name =="D2mr") return i18n("L2 Data Read Miss"); -+ if (name =="D2mw") return i18n("L2 Data Write Miss"); -+ if (name =="Smp") return i18n("Samples"); -+ if (name =="Sys") return i18n("System Time"); -+ if (name =="User") return i18n("User Time"); -+ if (name =="L1m") return i18n("L1 Miss Sum"); -+ if (name =="L2m") return i18n("L2 Miss Sum"); -+ if (name =="CEst") return i18n("Cycle Estimation"); -+ -+ return TQString(); -+} -+ -+ -+ -+ -+// -+// Configuration -+// -+ -+Configuration* Configuration::_config = 0; -+ -+Configuration::Configuration() -+ :_colors(517) -+{ -+ _config = 0; -+ -+ _colors.setAutoDelete(true); -+ _objectSourceDirs.setAutoDelete(true); -+ -+ // defaults -+ _showPercentage = true; -+ _showExpanded = false; -+ _showCycles = true; -+ _cycleCut = 0.0; -+ _percentPrecision = 2; -+ -+ // max symbol count/length in tooltip/popup -+ _maxSymbolLength = 30; -+ _maxSymbolCount = 10; -+ _maxListCount = 100; -+ -+ // annotation behaviour -+ _context = 3; -+ _noCostInside = 20; -+} -+ -+Configuration* Configuration::config() -+{ -+ if (!_config) -+ _config = new Configuration(); -+ -+ return _config; -+} -+ -+ -+void Configuration::saveOptions(KConfig* kconfig) -+{ -+ Configuration* c = config(); -+ -+ // color options -+ KConfigGroup colorConfig(kconfig, TQCString("CostColors")); -+ TQDictIterator it( c->_colors ); -+ int count = 1; -+ for( ; it.current(); ++it ) { -+ if ( !(*it)->automatic ) { -+ colorConfig.writeEntry( TQString("Name%1").arg(count), -+ it.currentKey()); -+ colorConfig.writeEntry( TQString("Color%1").arg(count), -+ (*it)->color); -+ //qDebug("Written Color %s (%d)", it.currentKey().ascii(), count); -+ -+ count++; -+ } -+ } -+ colorConfig.writeEntry( "Count", count-1); -+ -+ // source options -+ KConfigGroup sourceConfig(kconfig, TQCString("Source")); -+ sourceConfig.writeEntry("Dirs", c->_generalSourceDirs, ':'); -+ TQDictIterator it2( c->_objectSourceDirs ); -+ count = 1; -+ for( ; it2.current(); ++it2 ) { -+ sourceConfig.writeEntry( TQString("Object%1").arg(count), -+ it2.currentKey()); -+ sourceConfig.writeEntry( TQString("Dirs%1").arg(count), -+ *(*it2), ':'); -+ count++; -+ } -+ sourceConfig.writeEntry( "Count", count-1); -+ -+ // general options -+ KConfigGroup generalConfig(kconfig, TQCString("General")); -+ generalConfig.writeEntry("ShowPercentage", c->_showPercentage); -+ generalConfig.writeEntry("ShowExpanded", c->_showExpanded); -+ generalConfig.writeEntry("ShowCycles", c->_showCycles); -+ generalConfig.writeEntry("CycleCut", c->_cycleCut); -+ generalConfig.writeEntry("MaxSymbolCount", c->_maxSymbolCount); -+ generalConfig.writeEntry("MaxListCount", c->_maxListCount); -+ generalConfig.writeEntry("MaxSymbolLength", c->_maxSymbolLength); -+ generalConfig.writeEntry("PercentPrecision", c->_percentPrecision); -+ -+ generalConfig.writeEntry("Context", c->_context); -+ generalConfig.writeEntry("NoCostInside", c->_noCostInside); -+ -+ KConfigGroup ctConfig(kconfig, TQCString("CostTypes")); -+ int ctCount = TraceCostType::knownTypeCount(); -+ ctConfig.writeEntry( "Count", ctCount); -+ for (int i=0; iname()); -+ -+ // Use localized key -+ TraceItemView::writeConfigEntry(&ctConfig, -+ TQString("Longname%1").arg(i+1).ascii(), -+ t->longName(), -+ knownLongName(t->name()).utf8().data() /*, true */ ); -+ TraceItemView::writeConfigEntry(&ctConfig, -+ TQString("Formula%1").arg(i+1).ascii(), -+ t->formula(), knownFormula(t->name()).utf8().data()); -+ } -+} -+ -+ -+ -+ -+void Configuration::readOptions(KConfig* kconfig) -+{ -+ int i, count; -+ Configuration* c = config(); -+ -+ // color options -+ c->_colors.clear(); -+ -+ // colors for default cost types: -+ // red for L2 misses, green for L1 misses, blue for normal accesses -+ c->color("CostType-I2mr")->color = TQColor(240, 0, 0); -+ c->color("CostType-D2mr")->color = TQColor(180,40,40); -+ c->color("CostType-D2mw")->color = TQColor(120,80,80); -+ -+ c->color("CostType-I1mr")->color = TQColor(0, 240, 0); -+ c->color("CostType-D1mr")->color = TQColor(40,180,40); -+ c->color("CostType-D1mw")->color = TQColor(80,120,80); -+ -+ c->color("CostType-Ir")->color = TQColor(0, 0, 240); -+ c->color("CostType-Dr")->color = TQColor(40,40,180); -+ c->color("CostType-Dw")->color = TQColor(80,80,120); -+ -+ KConfigGroup colorConfig(kconfig, TQCString("CostColors")); -+ count = colorConfig.readNumEntry("Count", 0); -+ for (i=1;i<=count;i++) { -+ TQString n = colorConfig.readEntry(TQString("Name%1").arg(i)); -+ TQColor color = colorConfig.readColorEntry(TQString("Color%1").arg(i)); -+ -+ if (n.isEmpty()) continue; -+ -+ ColorSetting* cs = new ColorSetting; -+ cs->name = n; -+ cs->automatic = false; -+ cs->color = color; -+ -+ c->_colors.insert(n, cs); -+ -+ //qDebug("Read Color %s", n.ascii()); -+ } -+ -+ // source options -+ KConfigGroup sourceConfig(kconfig, TQCString("Source")); -+ TQStringList dirs; -+ dirs = sourceConfig.readListEntry("Dirs", ':'); -+ if (dirs.count()>0) c->_generalSourceDirs = dirs; -+ count = sourceConfig.readNumEntry("Count", 0); -+ c->_objectSourceDirs.clear(); -+ if (count>17) c->_objectSourceDirs.resize(count); -+ for (i=1;i<=count;i++) { -+ TQString n = sourceConfig.readEntry(TQString("Object%1").arg(i)); -+ dirs = sourceConfig.readListEntry(TQString("Dirs%1").arg(i), ':'); -+ -+ if (n.isEmpty() || (dirs.count()==0)) continue; -+ -+ c->_objectSourceDirs.insert(n, new TQStringList(dirs)); -+ } -+ -+ -+ // general options -+ KConfigGroup generalConfig(kconfig, TQCString("General")); -+ c->_showPercentage = generalConfig.readBoolEntry("ShowPercentage", true); -+ c->_showExpanded = generalConfig.readBoolEntry("ShowExpanded", false); -+ c->_showCycles = generalConfig.readBoolEntry("ShowCycles", true); -+ c->_cycleCut = generalConfig.readDoubleNumEntry("CycleCut", 0.0); -+ c->_maxSymbolCount = generalConfig.readNumEntry("MaxSymbolCount", 10); -+ c->_maxListCount = generalConfig.readNumEntry("MaxListCount", 100); -+ c->_maxSymbolLength = generalConfig.readNumEntry("MaxSymbolLength", 30); -+ c->_percentPrecision = generalConfig.readNumEntry("PercentPrecision", 2); -+ -+ c->_context = generalConfig.readNumEntry("Context", 3); -+ c->_noCostInside = generalConfig.readNumEntry("NoCostInside", 20); -+ -+ // known cost types -+ if (TraceCostType::knownTypeCount()==0) { -+ -+ KConfigGroup ctConfig(kconfig, TQCString("CostTypes")); -+ int ctCount = ctConfig.readNumEntry("Count", 0); -+ if (ctCount>0) { -+ for (int i=1;i<=ctCount;i++) { -+ TQString n = ctConfig.readEntry(TQString("Name%1").arg(i)); -+ TQString l = ctConfig.readEntry(TQString("Longname%1").arg(i)); -+ if (l.isEmpty()) l = knownLongName(n); -+ TQString f = ctConfig.readEntry(TQString("Formula%1").arg(i)); -+ if (f.isEmpty()) f = knownFormula(n); -+ -+ TraceCostType::add(new TraceCostType(n, l, f)); -+ } -+ } -+ else { -+ // add default types -+ -+ TQString longName, formula; -+ TraceCostType* ct; -+ TQStringList l = knownTypes(); -+ for ( TQStringList::Iterator it = l.begin(); -+ it != l.end(); ++it ) { -+ longName = knownLongName(*it); -+ formula = knownFormula(*it); -+ ct = new TraceCostType(*it, longName, formula); -+ TraceCostType::add(ct); -+ } -+ } -+ } -+} -+ -+TQColor Configuration::groupColor(TraceItem* cost) -+{ -+ TQString n; -+ -+ if (!cost) -+ n = TQString("default"); -+ else -+ n = TraceCost::typeName(cost->type()) + "-" + cost->prettyName(); -+ -+ return color(n)->color; -+} -+ -+TQColor Configuration::costTypeColor(TraceCostType* t) -+{ -+ TQString n; -+ -+ if (!t) -+ n = TQString("CostType-default"); -+ else -+ n = TQString("CostType-%1").arg(t->name()); -+ -+ return color(n)->color; -+} -+ -+TQColor Configuration::functionColor(TraceCost::CostType gt, -+ TraceFunction* f) -+{ -+ TraceCost* group = f; -+ TQString n; -+ -+ switch(gt) { -+ case TraceCost::Object: group = f->object(); break; -+ case TraceCost::Class: group = f->cls(); break; -+ case TraceCost::File: group = f->file(); break; -+ default: -+ break; -+ } -+ -+ if (group != f) { -+ // first look for manual color of a function in a group -+ n = TraceCost::typeName(group->type()) + -+ "-" + group->prettyName() + -+ "-" + f->prettyName(); -+ -+ ColorSetting* cs = color(n, false); -+ if (cs) return cs->color; -+ } -+ return groupColor(group); -+} -+ -+Configuration::ColorSetting* Configuration::color(TQString n, bool createNew) -+{ -+// qDebug("Color for %s", n.latin1()); -+ -+ // predefined ? -+ Configuration* c = config(); -+ ColorSetting* cs = c->_colors[n]; -+ if (cs || !createNew) return cs; -+ -+ // automatic colors... -+ int h = 0, s = 100; -+ const char* str = n.ascii(); -+ while (*str) { -+ h = (h * 37 + s* (unsigned)*str) % 256; -+ s = (s * 17 + h* (unsigned)*str) % 192; -+ str++; -+ } -+ -+ //qDebug("New color for %s: H %d, S %d", n.ascii(), h, 64+s); -+ TQColor color = TQColor(h, 64+s, 192, TQColor::Hsv); -+ -+ cs = new ColorSetting; -+ cs->name = n; -+ cs->automatic = true; -+ cs->color = color; -+ c->_colors.insert(n, cs); -+ -+ //qDebug("new Color %s", n.ascii()); -+ -+ return cs; -+} -+ -+/* Gives back a list of all Source Base Directories of Objects in -+ * current trace. If a special object is given in 2nd argument, -+ * put its Source Base in front. -+ */ -+TQStringList Configuration::sourceDirs(TraceData* data, TraceObject* o) -+{ -+ TQStringList l = config()->_generalSourceDirs, *ol, *ol2 = 0; -+ TraceObjectMap::Iterator oit; -+ for ( oit = data->objectMap().begin(); -+ oit != data->objectMap().end(); ++oit ) { -+ ol = config()->_objectSourceDirs[(*oit).name()]; -+ if (&(*oit) == o) { -+ ol2 = ol; -+ continue; -+ } -+ if (!ol) continue; -+ -+ for(unsigned int i=0;icount();i++) -+ l.prepend( (*ol)[i] ); -+ } -+ if (ol2) { -+ for(unsigned int i=0;icount();i++) -+ l.prepend( (*ol2)[i] ); -+ } -+ if (0) kdDebug() << "Configuration::sourceDirs: " << l.join(":") << endl; -+ -+ return l; -+} -+ -+bool Configuration::showPercentage() -+{ -+ return config()->_showPercentage; -+} -+ -+bool Configuration::showExpanded() -+{ -+ return config()->_showExpanded; -+} -+ -+bool Configuration::showCycles() -+{ -+ return config()->_showCycles; -+} -+ -+void Configuration::setShowPercentage(bool s) -+{ -+ Configuration* c = config(); -+ if (c->_showPercentage == s) return; -+ -+ c->_showPercentage = s; -+} -+ -+void Configuration::setShowExpanded(bool s) -+{ -+ Configuration* c = config(); -+ if (c->_showExpanded == s) return; -+ -+ c->_showExpanded = s; -+} -+ -+void Configuration::setShowCycles(bool s) -+{ -+ Configuration* c = config(); -+ if (c->_showCycles == s) return; -+ -+ c->_showCycles = s; -+} -+ -+double Configuration::cycleCut() -+{ -+ return config()->_cycleCut; -+} -+ -+int Configuration::percentPrecision() -+{ -+ return config()->_percentPrecision; -+} -+ -+int Configuration::maxSymbolLength() -+{ -+ return config()->_maxSymbolLength; -+} -+ -+TQString Configuration::shortenSymbol(TQString s) -+{ -+ if ((int)s.length() > maxSymbolLength()) -+ s = s.left(maxSymbolLength()) + "..."; -+ return s; -+} -+ -+int Configuration::maxListCount() -+{ -+ return config()->_maxListCount; -+} -+ -+int Configuration::maxSymbolCount() -+{ -+ return config()->_maxSymbolCount; -+} -+ -+int Configuration::context() -+{ -+ return config()->_context; -+} -+ -+int Configuration::noCostInside() -+{ -+ return config()->_noCostInside; -+} -diff --git a/kdecachegrind/kdecachegrind/configuration.h b/kdecachegrind/kdecachegrind/configuration.h -new file mode 100644 -index 0000000..478f617 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/configuration.h -@@ -0,0 +1,101 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Configuration for KCachegrind -+ */ -+ -+#ifndef CONFIGURATION_H -+#define CONFIGURATION_H -+ -+#include -+#include -+#include -+ -+#include "tracedata.h" -+ -+class KConfig; -+ -+class Configuration -+{ -+ friend class ConfigDlg; -+ -+public: -+ Configuration(); -+ -+ static Configuration* config(); -+ -+ static void saveOptions(KConfig*); -+ static void readOptions(KConfig*); -+ -+ // color for visualisation of an object -+ static TQColor functionColor(TraceItem::CostType gt, TraceFunction*); -+ static TQColor groupColor(TraceItem*); -+ static TQColor costTypeColor(TraceCostType*); -+ static TQStringList sourceDirs(TraceData*, TraceObject* o = 0); -+ static bool showPercentage(); -+ static bool showExpanded(); -+ static bool showCycles(); -+ -+ // lower percentage limit of cost items filled into lists -+ static int percentPrecision(); -+ // max symbol lengths/count in tooltip/popup -+ static int maxSymbolLength(); -+ // strip a symbol name according to -+ static TQString shortenSymbol(TQString); -+ static int maxSymbolCount(); -+ // max. number of items in lists -+ static int maxListCount(); -+ -+ // how many lines of context to show before/after annotated source/assembler -+ static int context(); -+ // how many lines without cost are still regarded as inside a function -+ static int noCostInside(); -+ -+ static void setShowPercentage(bool); -+ static void setShowExpanded(bool); -+ -+ static void setShowCycles(bool); -+ // upper limit for cutting of a call in cycle detection -+ static double cycleCut(); -+ -+private: -+ struct ColorSetting { -+ TQString name; -+ TQColor color; -+ bool automatic; -+ }; -+ -+ static ColorSetting* color(TQString, bool createNew = true); -+ -+ TQDict _colors; -+ -+ TQStringList _generalSourceDirs; -+ TQDict _objectSourceDirs; -+ -+ bool _showPercentage, _showExpanded, _showCycles; -+ double _cycleCut; -+ int _percentPrecision; -+ int _maxSymbolLength, _maxSymbolCount, _maxListCount; -+ int _context, _noCostInside; -+ -+ static Configuration* _config; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/costlistitem.cpp b/kdecachegrind/kdecachegrind/costlistitem.cpp -new file mode 100644 -index 0000000..1e777b0 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/costlistitem.cpp -@@ -0,0 +1,136 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "listutils.h" -+#include "costlistitem.h" -+#include "coverage.h" -+#include "configuration.h" -+ -+// CostListItem -+ -+ -+CostListItem::CostListItem(TQListView* parent, TraceCostItem* costItem, -+ TraceCostType* ct, int size) -+ :TQListViewItem(parent) -+{ -+ _groupSize = size; -+ _skipped = 0; -+ _costItem = costItem; -+ setCostType(ct); -+ -+ if (costItem) { -+ updateName(); -+ setPixmap(1, colorPixmap(10, 10, -+ Configuration::groupColor(_costItem))); -+ } -+} -+ -+CostListItem::CostListItem(TQListView* parent, int skipped, -+ TraceCostItem* costItem, TraceCostType* ct) -+ :TQListViewItem(parent) -+{ -+ _skipped = skipped; -+ _costItem = costItem; -+ setCostType(ct); -+ -+ setText(1, i18n("(%n item skipped)", "(%n items skipped)", _skipped)); -+} -+ -+void CostListItem::setCostType(TraceCostType* ct) -+{ -+ _costType = ct; -+ update(); -+} -+ -+void CostListItem::updateName() -+{ -+ if (!_costItem) return; -+ -+ TQString n = _costItem->prettyName(); -+ if (_groupSize>=0) n += TQString(" (%1)").arg(_groupSize); -+ -+ setText(1, n); -+} -+ -+void CostListItem::setSize(int s) -+{ -+ _groupSize = s; -+ updateName(); -+} -+ -+void CostListItem::update() -+{ -+ if (!_costItem) return; -+ TraceData* d = _costItem->data(); -+ -+ double total = d->subCost(_costType); -+ if (total == 0.0) { -+ setText(0, TQString("---")); -+ setPixmap(0, TQPixmap()); -+ return; -+ } -+ -+ _pure = _costItem->subCost(_costType); -+ double pure = 100.0 * _pure / total; -+ TQString str; -+ if (Configuration::showPercentage()) -+ str = TQString("%1").arg(pure, 0, 'f', Configuration::percentPrecision()); -+ else -+ str = _costItem->prettySubCost(_costType); -+ -+ if (_skipped) { -+ // special handling for skip entries... -+ setText(0, TQString("< %1").arg(str)); -+ return; -+ } -+ -+ setText(0, str); -+ setPixmap(0, costPixmap(_costType, _costItem, total, false)); -+} -+ -+int CostListItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ const CostListItem* fi1 = this; -+ const CostListItem* fi2 = (CostListItem*) i; -+ -+ // we always want descending order -+ if (ascending) { -+ fi1 = fi2; -+ fi2 = this; -+ } -+ -+ // a skip entry is always sorted last -+ if (fi1->_skipped) return -1; -+ if (fi2->_skipped) return 1; -+ -+ if (col==0) { -+ if (fi1->_pure < fi2->_pure) return -1; -+ if (fi1->_pure > fi2->_pure) return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -diff --git a/kdecachegrind/kdecachegrind/costlistitem.h b/kdecachegrind/kdecachegrind/costlistitem.h -new file mode 100644 -index 0000000..99f654e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/costlistitem.h -@@ -0,0 +1,52 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#ifndef COSTLISTITEM_H -+#define COSTLISTITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class CostListItem: public TQListViewItem -+{ -+public: -+ CostListItem(TQListView* parent, TraceCostItem* cost, -+ TraceCostType* ct, int size = -1); -+ // entry with multiple skipped items -+ CostListItem(TQListView* parent, int skipped, TraceCostItem* cost, -+ TraceCostType* ct); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ TraceCostItem* costItem() { return (_skipped) ? 0 : _costItem; } -+ void setCostType(TraceCostType* ct); -+ void update(); -+ void setSize(int s); -+ -+private: -+ void updateName(); -+ -+ SubCost _pure; -+ TraceCostType* _costType; -+ TraceCostItem* _costItem; -+ // >0 only for last item in list, if items are skipped -+ int _skipped; -+ // number of items in group, is put in parenthesis after name -+ int _groupSize; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/costtypeitem.cpp b/kdecachegrind/kdecachegrind/costtypeitem.cpp -new file mode 100644 -index 0000000..dc35cb2 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/costtypeitem.cpp -@@ -0,0 +1,149 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of cost type view. -+ */ -+ -+#include -+#include -+ -+#include "configuration.h" -+#include "listutils.h" -+#include "costtypeitem.h" -+ -+ -+// CostTypeItem -+ -+ -+CostTypeItem::CostTypeItem(TQListView* parent, TraceCostItem* costItem, -+ TraceCostType* ct, TraceCost::CostType gt) -+ :TQListViewItem(parent) -+{ -+ _costItem = costItem; -+ _costType = ct; -+ _groupType = gt; -+ -+ if (ct) { -+ setText(0, ct->longName()); -+ setText(3, ct->name()); -+ TQString formula = ct->formula(); -+ setText(5, formula); -+ if (!formula.isEmpty()) { -+ setText(4, "="); -+ // we have a virtual type: allow editing -+ setRenameEnabled(0, true); -+ setRenameEnabled(3, true); -+ setRenameEnabled(5, true); -+ } -+ } -+ else { -+ setText(0, i18n("Unknown Type")); -+ } -+ update(); -+} -+ -+void CostTypeItem::setGroupType(TraceCost::CostType gt) -+{ -+ if (_groupType == gt) return; -+ -+ _groupType = gt; -+ update(); -+} -+ -+void CostTypeItem::update() -+{ -+ TraceData* d = _costItem ? _costItem->data() : 0; -+ double total = d ? ((double)d->subCost(_costType)) : 0.0; -+ -+ if (total == 0.0) { -+ setText(1, "-"); -+ setPixmap(1, TQPixmap()); -+ setText(2, "-"); -+ setPixmap(2, TQPixmap()); -+ return; -+ } -+ -+ TraceFunction* f = (_costItem->type()==TraceCost::Function) ? -+ (TraceFunction*)_costItem : 0; -+ -+ TraceCost* selfTotalCost = f ? f->data() : d; -+ if (f && Configuration::showExpanded()) { -+ switch(_groupType) { -+ case TraceCost::Object: selfTotalCost = f->object(); break; -+ case TraceCost::Class: selfTotalCost = f->cls(); break; -+ case TraceCost::File: selfTotalCost = f->file(); break; -+ case TraceCost::FunctionCycle: selfTotalCost = f->cycle(); break; -+ default: break; -+ } -+ } -+ if (_costItem->type()==TraceCost::FunctionCycle) { -+ f = (TraceFunction*)_costItem; -+ selfTotalCost = f->data(); -+ } -+ -+ double selfTotal = selfTotalCost->subCost(_costType); -+ -+ // for all cost items there's a self cost -+ _pure = _costItem ? _costItem->subCost(_costType) : SubCost(0); -+ double pure = 100.0 * _pure / selfTotal; -+ if (Configuration::showPercentage()) { -+ setText(2, TQString("%1") -+ .arg(pure, 0, 'f', Configuration::percentPrecision())); -+ } -+ else -+ setText(2, _costItem->prettySubCost(_costType)); -+ -+ setPixmap(2, costPixmap(_costType, _costItem, selfTotal, false)); -+ -+ if (!f) { -+ setText(1, "-"); -+ setPixmap(1, TQPixmap()); -+ return; -+ } -+ -+ _sum = f->inclusive()->subCost(_costType); -+ double sum = 100.0 * _sum / total; -+ if (Configuration::showPercentage()) { -+ setText(1, TQString("%1") -+ .arg(sum, 0, 'f', Configuration::percentPrecision())); -+ } -+ else -+ setText(1, _sum.pretty()); -+ -+ setPixmap(1, costPixmap(_costType, f->inclusive(), total, false)); -+} -+ -+ -+int CostTypeItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ CostTypeItem* fi = (CostTypeItem*) i; -+ if (col==0) { -+ if (_sum < fi->_sum) return -1; -+ if (_sum > fi->_sum) return 1; -+ return 0; -+ } -+ if (col==1) { -+ if (_pure < fi->_pure) return -1; -+ if (_pure > fi->_pure) return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -+ -diff --git a/kdecachegrind/kdecachegrind/costtypeitem.h b/kdecachegrind/kdecachegrind/costtypeitem.h -new file mode 100644 -index 0000000..d34973d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/costtypeitem.h -@@ -0,0 +1,50 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of cost type view. -+ */ -+ -+#ifndef COSTTYEPITEM_H -+#define COSTTYEPITEM_H -+ -+#include -+#include "tracedata.h" -+ -+ -+class CostTypeItem: public TQListViewItem -+{ -+public: -+ CostTypeItem(TQListView* parent, TraceCostItem* costItem, -+ TraceCostType* ct, TraceCost::CostType gt); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ void setGroupType(TraceCost::CostType); -+ TraceCostItem* costItem() { return _costItem; } -+ TraceCostType* costType() { return _costType; } -+ void update(); -+ -+private: -+ SubCost _sum, _pure; -+ TraceCostType* _costType; -+ TraceCostItem* _costItem; -+ TraceCost::CostType _groupType; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/costtypeview.cpp b/kdecachegrind/kdecachegrind/costtypeview.cpp -new file mode 100644 -index 0000000..3f5417e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/costtypeview.cpp -@@ -0,0 +1,310 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Cost Type View -+ */ -+ -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "costtypeitem.h" -+#include "costtypeview.h" -+#include "toplevel.h" -+ -+ -+// -+// CostTypeView -+// -+ -+ -+CostTypeView::CostTypeView(TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQListView(parent, name), TraceItemView(parentView) -+{ -+ addColumn( i18n( "Event Type" ) ); -+ addColumn( i18n( "Incl." ) ); -+ addColumn( i18n( "Self" ) ); -+ addColumn( i18n( "Short" ) ); -+ addColumn( TQString() ); -+ addColumn( i18n( "Formula" ) ); -+ -+ setSorting(-1); -+ setAllColumnsShowFocus(true); -+ setColumnAlignment(1, TQt::AlignRight); -+ setColumnAlignment(2, TQt::AlignRight); -+ setColumnAlignment(3, TQt::AlignRight); -+ setMinimumHeight(50); -+ -+ connect( this, -+ TQT_SIGNAL( selectionChanged(TQListViewItem*) ), -+ TQT_SLOT( selectedSlot(TQListViewItem*) ) ); -+ -+ connect( this, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int))); -+ -+ connect(this, -+ TQT_SIGNAL(doubleClicked(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(itemRenamed(TQListViewItem*,int,const TQString&)), -+ TQT_SLOT(renamedSlot(TQListViewItem*,int,const TQString&))); -+ -+ TQWhatsThis::add( this, whatsThis() ); -+} -+ -+TQString CostTypeView::whatsThis() const -+{ -+ return i18n( "Cost Types List" -+ "

This list shows all cost types available " -+ "and what the self/inclusive cost of the " -+ "current selected function is for that cost type.

" -+ "

By choosing a cost type from the list, " -+ "you change the cost type of costs shown " -+ "all over KCachegrind to be the selected one.

"); -+} -+ -+ -+void CostTypeView::context(TQListViewItem* i, const TQPoint & p, int) -+{ -+ TQPopupMenu popup; -+ -+ TraceCostType* ct = i ? ((CostTypeItem*) i)->costType() : 0; -+ -+ if (ct) -+ popup.insertItem(i18n("Set Secondary Event Type"), 99); -+ if (_costType2) -+ popup.insertItem(i18n("Remove Secondary Event Type"), 98); -+ if (popup.count()>0) -+ popup.insertSeparator(); -+ -+ if (ct && !ct->isReal()) { -+ popup.insertItem(i18n("Edit Long Name"), 93); -+ popup.insertItem(i18n("Edit Short Name"), 94); -+ popup.insertItem(i18n("Edit Formula"), 95); -+ popup.insertItem(i18n("Remove"), 96); -+ popup.insertSeparator(); -+ } -+ -+ addGoMenu(&popup); -+ -+ popup.insertSeparator(); -+ popup.insertItem(i18n("New Cost Type ..."), 97); -+ -+ int r = popup.exec(p); -+ if (r == 98) selectedCostType2(0); -+ else if (r == 99) selectedCostType2(ct); -+ else if (r == 93) i->startRename(0); -+ else if (r == 94) i->startRename(3); -+ else if (r == 95) i->startRename(5); -+ else if (r == 96) { -+ -+ // search for a previous type -+ TraceCostType* prev = 0, *ct = 0; -+ TraceCostMapping* m = _data->mapping(); -+ for (int i=0;irealCount();i++) { -+ ct = m->realType(i); -+ if (ct) prev = ct; -+ } -+ for (int i=0;ivirtualCount();i++) { -+ ct = m->virtualType(i); -+ if (ct == _costType) break; -+ if (ct) prev = ct; -+ } -+ -+ if (_data->mapping()->remove(ct)) { -+ // select previous cost type -+ selectedCostType(prev); -+ if (_costType2 == ct) -+ selectedCostType2(prev); -+ refresh(); -+ } -+ } -+ else if (r == 97) { -+ int i = 1; -+ while(1) { -+ if (!TraceCostType::knownVirtualType(i18n("New%1").arg(i))) -+ break; -+ i++; -+ } -+ // add same new cost type to this mapping and to known types -+ TQString shortName = i18n("New%1").arg(i); -+ TQString longName = i18n("New Cost Type %1").arg(i); -+ TraceCostType::add(new TraceCostType(shortName, longName, "0")); -+ _data->mapping()->add(new TraceCostType(shortName, longName, "0")); -+ refresh(); -+ } -+} -+ -+void CostTypeView::selectedSlot(TQListViewItem * i) -+{ -+ TraceCostType* ct = i ? ((CostTypeItem*) i)->costType() : 0; -+ if (ct) -+ selectedCostType(ct); -+} -+ -+void CostTypeView::activatedSlot(TQListViewItem * i) -+{ -+ TraceCostType* ct = i ? ((CostTypeItem*) i)->costType() : 0; -+ if (ct) -+ selectedCostType2(ct); -+} -+ -+TraceItem* CostTypeView::canShow(TraceItem* i) -+{ -+ if (!i) return 0; -+ -+ switch(i->type()) { -+ case TraceCost::Object: -+ case TraceCost::Class: -+ case TraceCost::File: -+ case TraceCost::Call: -+ case TraceCost::FunctionCycle: -+ case TraceCost::Function: -+ break; -+ default: -+ return 0; -+ } -+ return i; -+} -+ -+void CostTypeView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == selectedItemChanged) return; -+ -+ if (changeType == costType2Changed) return; -+ -+ if (changeType == groupTypeChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) -+ ((CostTypeItem*)item)->setGroupType(_groupType); -+ -+ return; -+ } -+ -+ if (changeType == costTypeChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) -+ if ( ((CostTypeItem*)item)->costType() == _costType) { -+ setSelected(item, true); -+ ensureItemVisible(item); -+ break; -+ } -+ -+ return; -+ } -+ -+ if (changeType == partsChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) -+ ((CostTypeItem*)item)->update(); -+ -+ return; -+ } -+ -+ -+ refresh(); -+} -+ -+void CostTypeView::refresh() -+{ -+ clear(); -+ setColumnWidth(1, 50); -+ setColumnWidth(2, 50); -+ -+ if (!_data || !_activeItem) return; -+ switch(_activeItem->type()) { -+ case TraceCost::Object: -+ case TraceCost::Class: -+ case TraceCost::File: -+ case TraceCost::FunctionCycle: -+ case TraceCost::Function: -+ break; -+ default: -+ return; -+ } -+ TraceCostItem* c = (TraceCostItem*) _activeItem; -+ -+ TraceCostType* ct =0 ; -+ TQListViewItem* item = 0; -+ TQString sumStr, pureStr; -+ TQListViewItem* costItem=0; -+ -+ TraceCostMapping* m = _data->mapping(); -+ for (int i=m->virtualCount()-1;i>=0;i--) { -+ ct = m->virtualType(i); -+ if (!ct) continue; -+ item = new CostTypeItem(this, c, ct, _groupType); -+ if (ct == _costType) costItem = item; -+ } -+ for (int i=m->realCount()-1;i>=0;i--) { -+ ct = m->realType(i); -+ item = new CostTypeItem(this, c, ct, _groupType); -+ if (ct == _costType) costItem = item; -+ } -+ -+ if (costItem) { -+ setSelected(costItem, true); -+ ensureItemVisible(costItem); -+ } -+ -+ if (item) setMinimumHeight(3*item->height()); -+} -+ -+ -+void CostTypeView::renamedSlot(TQListViewItem* item,int c,const TQString& t) -+{ -+ TraceCostType* ct = item ? ((CostTypeItem*) item)->costType() : 0; -+ if (!ct || ct->isReal()) return; -+ -+ // search for matching known Type -+ int knownCount = TraceCostType::knownTypeCount(); -+ TraceCostType* known = 0; -+ for (int i=0; iname() == ct->name()) break; -+ } -+ -+ if (c == 0) { -+ ct->setLongName(t); -+ if (known) known->setLongName(t); -+ } -+ else if (c == 3) { -+ ct->setName(t); -+ if (known) known->setName(t); -+ } -+ else if (c == 5) { -+ ct->setFormula(t); -+ if (known) known->setFormula(t); -+ } -+ else return; -+ -+ if (_topLevel) _topLevel->configChanged(); -+ refresh(); -+} -+ -+#include "costtypeview.moc" -diff --git a/kdecachegrind/kdecachegrind/costtypeview.h b/kdecachegrind/kdecachegrind/costtypeview.h -new file mode 100644 -index 0000000..ee9963e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/costtypeview.h -@@ -0,0 +1,54 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Cost Type View -+ */ -+ -+#ifndef COSTTYPEVIEW_H -+#define COSTTYPEVIEW_H -+ -+#include -+#include "tracedata.h" -+#include "traceitemview.h" -+ -+class CostTypeView: public TQListView, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ CostTypeView(TraceItemView* parentView, -+ TQWidget* parent=0, const char* name=0); -+ -+ virtual TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ -+private slots: -+ void context(TQListViewItem*,const TQPoint &, int); -+ void selectedSlot(TQListViewItem*); -+ void activatedSlot(TQListViewItem*); -+ void renamedSlot(TQListViewItem*,int,const TQString&); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ void refresh(); -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/coverage.cpp b/kdecachegrind/kdecachegrind/coverage.cpp -new file mode 100644 -index 0000000..86e6f7f ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/coverage.cpp -@@ -0,0 +1,329 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Function Coverage Analysis -+ */ -+ -+#include "coverage.h" -+ -+//#define DEBUG_COVERAGE 1 -+ -+TraceCostType* Coverage::_costType; -+ -+const int Coverage::maxHistogramDepth = maxHistogramDepthValue; -+const int Coverage::Rtti = 1; -+ -+Coverage::Coverage() -+{ -+} -+ -+void Coverage::init() -+{ -+ _self = 0.0; -+ _incl = 0.0; -+ _callCount = 0.0; -+ // should always be overwritten before usage -+ _firstPercentage = 1.0; -+ _minDistance = 9999; -+ _maxDistance = 0; -+ _active = false; -+ _inRecursion = false; -+ for (int i = 0;imaxP) { -+ maxP = _inclHisto[i]; -+ medD = i; -+ } -+ -+ return medD; -+} -+ -+int Coverage::selfMedian() -+{ -+ double maxP = _selfHisto[0]; -+ int medD = 0; -+ for (int i = 1;imaxP) { -+ maxP = _selfHisto[i]; -+ medD = i; -+ } -+ -+ return medD; -+} -+ -+TraceFunctionList Coverage::coverage(TraceFunction* f, CoverageMode m, -+ TraceCostType* ct) -+{ -+ invalidate(f->data(), Coverage::Rtti); -+ -+ _costType = ct; -+ -+ // function f takes ownership over c! -+ Coverage* c = new Coverage(); -+ c->setFunction(f); -+ c->init(); -+ -+ TraceFunctionList l; -+ -+ if (m == Caller) -+ c->addCallerCoverage(l, 1.0, 0); -+ else -+ c->addCallingCoverage(l, 1.0, 1.0, 0); -+ -+ return l; -+} -+ -+void Coverage::addCallerCoverage(TraceFunctionList& fList, -+ double pBack, int d) -+{ -+ TraceCallList cList; -+ TraceCall* call; -+ Coverage* c; -+ -+ if (_inRecursion) return; -+ -+ double incl; -+ incl = (double) (_function->inclusive()->subCost(_costType)); -+ -+ if (_active) { -+#ifdef DEBUG_COVERAGE -+ qDebug("CallerCov: D %d, %s (was active, incl %f, self %f): newP %f", d, -+ _function->prettyName().ascii(), _incl, _self, pBack); -+#endif -+ _inRecursion = true; -+ } -+ else { -+ _active = true; -+ -+ // only add cost if this is no recursion -+ -+ _incl += pBack; -+ _firstPercentage = pBack; -+ -+ if (_minDistance > d) _minDistance = d; -+ if (_maxDistance < d) _maxDistance = d; -+ if (dprettyName().ascii(), _incl, pBack); -+#endif -+ } -+ -+ double callVal, pBackNew; -+ -+ cList = _function->callers(); -+ for (call=cList.first();call;call=cList.next()) { -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ if (call->subCost(_costType)>0) { -+ TraceFunction* caller = call->caller(); -+ -+ c = (Coverage*) caller->assoziation(rtti()); -+ if (!c) { -+ c = new Coverage(); -+ c->setFunction(caller); -+ } -+ if (!c->isValid()) { -+ c->init(); -+ fList.append(caller); -+ } -+ -+ if (c->isActive()) continue; -+ if (c->inRecursion()) continue; -+ -+ callVal = (double) call->subCost(_costType); -+ pBackNew = pBack * (callVal / incl); -+ -+ // FIXME ?!? -+ -+ if (!c->isActive()) { -+ if (d>=0) -+ c->callCount() += (double)call->callCount(); -+ else -+ c->callCount() += _callCount; -+ } -+ else { -+ // adjust pNew by sum of geometric series of recursion factor. -+ // Thus we can avoid endless recursion here -+ pBackNew *= 1.0 / (1.0 - pBackNew / c->firstPercentage()); -+ } -+ -+ // Limit depth -+ if (pBackNew > 0.0001) -+ c->addCallerCoverage(fList, pBackNew, d+1); -+ } -+ } -+ -+ if (_inRecursion) -+ _inRecursion = false; -+ else if (_active) -+ _active = false; -+} -+ -+/** -+ * pForward is time on percent used, -+ * pBack is given to allow for calculation of call counts -+ */ -+void Coverage::addCallingCoverage(TraceFunctionList& fList, -+ double pForward, double pBack, int d) -+{ -+ TraceCallList cList; -+ TraceCall* call; -+ Coverage* c; -+ -+ if (_inRecursion) return; -+ -+#ifdef DEBUG_COVERAGE -+ static const char* spaces = " "; -+#endif -+ -+ double self, incl; -+ incl = (double) (_function->inclusive()->subCost(_costType)); -+ -+#ifdef DEBUG_COVERAGE -+ qDebug("CngCov:%s - %s (incl %f, self %f): forward %f, back %f", -+ spaces+strlen(spaces)-d, -+ _function->prettyName().ascii(), _incl, _self, pForward, pBack); -+#endif -+ -+ -+ if (_active) { -+ _inRecursion = true; -+ -+#ifdef DEBUG_COVERAGE -+ qDebug("CngCov:%s < %s: STOP (is active)", -+ spaces+strlen(spaces)-d, -+ _function->prettyName().ascii()); -+#endif -+ -+ } -+ else { -+ _active = true; -+ -+ // only add cost if this is no recursion -+ self = pForward * (_function->subCost(_costType)) / incl; -+ _incl += pForward; -+ _self += self; -+ _firstPercentage = pForward; -+ -+ if (_minDistance > d) _minDistance = d; -+ if (_maxDistance < d) _maxDistance = d; -+ if (dprettyName().ascii(), _incl, _self); -+#endif -+ } -+ -+ double callVal, pForwardNew, pBackNew; -+ -+ cList = _function->callings(); -+ for (call=cList.first();call;call=cList.next()) { -+ if (call->inCycle()>0) continue; -+ if (call->isRecursion()) continue; -+ -+ if (call->subCost(_costType)>0) { -+ TraceFunction* calling = call->called(); -+ -+ c = (Coverage*) calling->assoziation(rtti()); -+ if (!c) { -+ c = new Coverage(); -+ c->setFunction(calling); -+ } -+ if (!c->isValid()) { -+ c->init(); -+ fList.append(calling); -+ } -+ -+ if (c->isActive()) continue; -+ if (c->inRecursion()) continue; -+ -+ callVal = (double) call->subCost(_costType); -+ pForwardNew = pForward * (callVal / incl); -+ pBackNew = pBack * (callVal / -+ calling->inclusive()->subCost(_costType)); -+ -+ if (!c->isActive()) { -+ c->callCount() += pBack * call->callCount(); -+ -+#ifdef DEBUG_COVERAGE -+ qDebug("CngCov:%s > %s: forward %f, back %f, calls %f -> %f, now %f", -+ spaces+strlen(spaces)-d, -+ calling->prettyName().ascii(), -+ pForwardNew, pBackNew, -+ (double)call->callCount(), -+ pBack * call->callCount(), -+ c->callCount()); -+#endif -+ } -+ else { -+ // adjust pNew by sum of geometric series of recursion factor. -+ // Thus we can avoid endless recursion here -+ double fFactor = 1.0 / (1.0 - pForwardNew / c->firstPercentage()); -+ double bFactor = 1.0 / (1.0 - pBackNew); -+#ifdef DEBUG_COVERAGE -+ qDebug("CngCov:%s Recursion - origP %f, actP %f => factor %f, newP %f", -+ spaces+strlen(spaces)-d, -+ c->firstPercentage(), pForwardNew, -+ fFactor, pForwardNew * fFactor); -+#endif -+ pForwardNew *= fFactor; -+ pBackNew *= bFactor; -+ -+ } -+ -+ // Limit depth -+ if (pForwardNew > 0.0001) -+ c->addCallingCoverage(fList, pForwardNew, pBackNew, d+1); -+ } -+ } -+ -+ if (_inRecursion) -+ _inRecursion = false; -+ else if (_active) -+ _active = false; -+} -+ -diff --git a/kdecachegrind/kdecachegrind/coverage.h b/kdecachegrind/kdecachegrind/coverage.h -new file mode 100644 -index 0000000..50c5936 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/coverage.h -@@ -0,0 +1,102 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Function Coverage Analysis -+ */ -+ -+#ifndef COVERAGE_H -+#define COVERAGE_H -+ -+#include "tracedata.h" -+ -+/** -+ * Coverage of a function. -+ * When analysis is done, every function involved will have a -+ * pointer to an object of this class. -+ * -+ * This function also holds the main routine for coverage analysis, -+ * Coverage::coverage(), as static method. -+ */ -+class Coverage : public TraceAssoziation -+{ -+public: -+ /* Direction of coverage analysis */ -+ enum CoverageMode { Caller, Called }; -+ -+ // max depth for distance histogram -+#define maxHistogramDepthValue 40 -+ static const int maxHistogramDepth; -+ -+ static const int Rtti; -+ -+ Coverage(); -+ -+ virtual int rtti() { return Rtti; } -+ void init(); -+ -+ TraceFunction* function() { return _function; } -+ double self() { return _self; } -+ double inclusive() { return _incl; } -+ double firstPercentage() { return _firstPercentage; } -+ double& callCount() { return _callCount; } -+ int minDistance() { return _minDistance; } -+ int maxDistance() { return _maxDistance; } -+ int inclusiveMedian(); -+ int selfMedian(); -+ double* selfHistogram() { return _selfHisto; } -+ double* inclusiveHistogram() { return _inclHisto; } -+ bool isActive() { return _active; } -+ bool inRecursion() { return _inRecursion; } -+ -+ void setSelf(float p) { _self = p; } -+ void setInclusive(float p) { _incl = p; } -+ void setCallCount(float cc) { _callCount = cc; } -+ void setActive(bool a) { _active = a; } -+ void setInRecursion(bool r) { _inRecursion = r; } -+ -+ /** -+ * Calculate coverage of all functions based on function f. -+ * If mode is Called, the coverage of functions called by -+ * f is calculated, otherwise that of functions calling f. -+ * SubCost type ct is used for the analysis. -+ * Self values are undefined for Caller mode. -+ * -+ * Returns list of functions covered. -+ * Coverage degree of returned functions can be get -+ * with function->coverage()->percentage() -+ */ -+ static TraceFunctionList coverage(TraceFunction* f, CoverageMode m, -+ TraceCostType* ct); -+ -+private: -+ void addCallerCoverage(TraceFunctionList& l, double, int d); -+ void addCallingCoverage(TraceFunctionList& l, double, double, int d); -+ -+ double _self, _incl, _firstPercentage, _callCount; -+ int _minDistance, _maxDistance; -+ bool _active, _inRecursion; -+ double _selfHisto[maxHistogramDepthValue]; -+ double _inclHisto[maxHistogramDepthValue]; -+ -+ // temporary set for one coverage analysis -+ static TraceCostType* _costType; -+}; -+ -+#endif -+ -diff --git a/kdecachegrind/kdecachegrind/coverageitem.cpp b/kdecachegrind/kdecachegrind/coverageitem.cpp -new file mode 100644 -index 0000000..26e5b36 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/coverageitem.cpp -@@ -0,0 +1,343 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of coverage view. -+ */ -+ -+#include -+#include -+ -+#include "configuration.h" -+#include "listutils.h" -+#include "coverage.h" -+#include "coverageitem.h" -+ -+ -+// CallerCoverageItem -+ -+ -+CallerCoverageItem::CallerCoverageItem(TQListView* parent, Coverage* c, -+ TraceFunction* base, -+ TraceCostType* ct, -+ TraceCost::CostType gt) -+ : TQListViewItem(parent) -+{ -+ _skipped = 0; -+ _coverage = c; -+ _function = c ? c->function() : 0; -+ _base = base; -+ _groupType = TraceCost::NoCostType; -+ -+ setText(3, _function->prettyNameWithLocation()); -+ -+ setCostType(ct); -+ setGroupType(gt); -+} -+ -+CallerCoverageItem::CallerCoverageItem(TQListView* parent, int skipped, Coverage* c, -+ TraceFunction* base, -+ TraceCostType* ct, -+ TraceCost::CostType gt) -+ : TQListViewItem(parent) -+{ -+ _skipped = skipped; -+ _coverage = c; -+ _function = c ? c->function() : 0; -+ _base = base; -+ _groupType = TraceCost::NoCostType; -+ -+ setText(3, i18n("(%n function skipped)", "(%n functions skipped)", _skipped)); -+ -+ setCostType(ct); -+ setGroupType(gt); -+} -+ -+void CallerCoverageItem::setGroupType(TraceCost::CostType gt) -+{ -+ if (_skipped) return; -+ if (_groupType == gt) return; -+ _groupType = gt; -+ -+ TQColor c = Configuration::functionColor(_groupType, _function); -+ setPixmap(3, colorPixmap(10, 10, c)); -+} -+ -+void CallerCoverageItem::setCostType(TraceCostType* ct) -+{ -+ _costType = ct; -+ update(); -+} -+ -+void CallerCoverageItem::update() -+{ -+ if (!_coverage) { -+ setText(0, TQString()); -+ setText(1, TQString()); -+ return; -+ } -+ -+ _pSum = 100.0 * _coverage->inclusive(); -+ SubCost realSum = _base->inclusive()->subCost(_costType); -+ _sum = SubCost(realSum * _coverage->inclusive()); -+ TQString str; -+ if (Configuration::showPercentage()) -+ str = TQString("%1").arg(_pSum, 0, 'f', Configuration::percentPrecision()); -+ else -+ str = _sum.pretty(); -+ -+ if (_skipped) { -+ setText(0, TQString("< %1").arg(str)); -+ return; -+ } -+ -+ setText(0, str); -+ setPixmap(0, partitionPixmap(25, 10, _coverage->inclusiveHistogram(), 0, -+ Coverage::maxHistogramDepth, false)); -+ -+ // call count -+ _cc = SubCost(_coverage->callCount()); -+ setText(2, _cc ? _cc.pretty() : TQString("(0)")); -+ -+ // distance (min/max/median) -+ _distance = _coverage->inclusiveMedian(); -+ TQString distString; -+ if (_coverage->minDistance() == _coverage->maxDistance()) -+ distString = TQString::number(_distance); -+ else -+ distString = TQString("%1-%2 (%3)") -+ .arg(_coverage->minDistance()) -+ .arg(_coverage->maxDistance()) -+ .arg(_distance); -+ setText(1, distString); -+} -+ -+ -+int CallerCoverageItem::compare(TQListViewItem * i, -+ int col, bool ascending ) const -+{ -+ const CallerCoverageItem* ci1 = this; -+ const CallerCoverageItem* ci2 = (CallerCoverageItem*) i; -+ -+ // we always want descending order -+ if (ascending) { -+ ci1 = ci2; -+ ci2 = this; -+ } -+ -+ // a skip entry is always sorted last -+ if (ci1->_skipped) return -1; -+ if (ci2->_skipped) return 1; -+ -+ if (col==0) { -+ if (ci1->_pSum < ci2->_pSum) return -1; -+ if (ci1->_pSum > ci2->_pSum) return 1; -+ -+ // for same percentage (e.g. all 100%), use distance info -+ if (ci1->_distance < ci2->_distance) return -1; -+ if (ci1->_distance > ci2->_distance) return 1; -+ return 0; -+ } -+ -+ if (col==1) { -+ if (ci1->_distance < ci2->_distance) return -1; -+ if (ci1->_distance > ci2->_distance) return 1; -+ return 0; -+ } -+ -+ if (col==2) { -+ if (ci1->_cc < ci2->_cc) return -1; -+ if (ci1->_cc > ci2->_cc) return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -+ -+// CalleeCoverageItem -+ -+ -+CalleeCoverageItem::CalleeCoverageItem(TQListView* parent, Coverage* c, -+ TraceFunction* base, -+ TraceCostType* ct, -+ TraceCost::CostType gt) -+ : TQListViewItem(parent) -+{ -+ _skipped = 0; -+ _coverage = c; -+ _function = c ? c->function() : 0; -+ _base = base; -+ _groupType = TraceCost::NoCostType; -+ -+ setText(4, _function->prettyNameWithLocation()); -+ -+ setCostType(ct); -+ setGroupType(gt); -+} -+ -+CalleeCoverageItem::CalleeCoverageItem(TQListView* parent, int skipped, Coverage* c, -+ TraceFunction* base, -+ TraceCostType* ct, -+ TraceCost::CostType gt) -+ : TQListViewItem(parent) -+{ -+ _skipped = skipped; -+ _coverage = c; -+ _function = c ? c->function() : 0; -+ _base = base; -+ _groupType = TraceCost::NoCostType; -+ -+ setText(4, i18n("(%n function skipped)", "(%n functions skipped)", _skipped)); -+ -+ setCostType(ct); -+ setGroupType(gt); -+} -+ -+void CalleeCoverageItem::setGroupType(TraceCost::CostType gt) -+{ -+ if (_skipped) return; -+ if (_groupType == gt) return; -+ _groupType = gt; -+ -+ TQColor c = Configuration::functionColor(_groupType, _function); -+ setPixmap(4, colorPixmap(10, 10, c)); -+} -+ -+void CalleeCoverageItem::setCostType(TraceCostType* ct) -+{ -+ _costType = ct; -+ update(); -+} -+ -+void CalleeCoverageItem::update() -+{ -+ if (!_coverage) { -+ setText(0, TQString()); -+ setText(1, TQString()); -+ setText(2, TQString()); -+ return; -+ } -+ -+ _pSum = 100.0 * _coverage->inclusive(); -+ -+ // pSum/pSelf are percentages of inclusive cost of base -+ SubCost realSum = _base->inclusive()->subCost(_costType); -+ _sum = SubCost(realSum * _coverage->inclusive()); -+ -+ -+ TQString str; -+ if (Configuration::showPercentage()) -+ str = TQString("%1").arg(_pSum, 0, 'f', Configuration::percentPrecision()); -+ else -+ str = _sum.pretty(); -+ -+ if (_skipped) { -+ str = TQString("< %1").arg(str); -+ setText(0, str); -+ setText(1, str); -+ return; -+ } -+ setText(0, str); -+ -+ _pSelf = 100.0 * _coverage->self(); -+ _self = SubCost(realSum * _coverage->self()); -+ -+ if (Configuration::showPercentage()) { -+ setText(1, TQString("%1") -+ .arg(_pSelf, 0, 'f', Configuration::percentPrecision())); -+ } -+ else { -+ setText(1, _self.pretty()); -+ } -+ -+ setPixmap(0, partitionPixmap(25, 10, _coverage->inclusiveHistogram(), 0, -+ Coverage::maxHistogramDepth, false)); -+ setPixmap(1, partitionPixmap(25, 10, _coverage->selfHistogram(), 0, -+ Coverage::maxHistogramDepth, false)); -+ -+ -+ _cc = SubCost(_coverage->callCount()); -+ setText(3, _cc ? _cc.pretty() : TQString("(0)")); -+ -+ // for comparations -+ _distance = _coverage->inclusiveMedian(); -+ TQString distString; -+ if (_coverage->minDistance() == _coverage->maxDistance()) -+ distString = TQString::number(_distance); -+ else { -+ int sMed = _coverage->selfMedian(); -+ TQString med; -+ if (_distance == sMed) -+ med = TQString::number(_distance); -+ else -+ med = TQString("%1/%2").arg(_distance).arg(sMed); -+ -+ distString = TQString("%1-%2 (%3)") -+ .arg(_coverage->minDistance()) -+ .arg(_coverage->maxDistance()) -+ .arg(med); -+ } -+ setText(2, distString); -+} -+ -+ -+int CalleeCoverageItem::compare(TQListViewItem * i, -+ int col, bool ascending ) const -+{ -+ CalleeCoverageItem* ci = (CalleeCoverageItem*) i; -+ -+ // a skip entry is always sorted last -+ if (_skipped) return -1; -+ if (ci->_skipped) return 1; -+ -+ if (col==0) { -+ if (_pSum < ci->_pSum) return -1; -+ if (_pSum > ci->_pSum) return 1; -+ -+ // for same percentage (e.g. all 100%), use distance info -+ if (_distance < ci->_distance) return -1; -+ if (_distance > ci->_distance) return 1; -+ return 0; -+ } -+ -+ if (col==1) { -+ if (_pSelf < ci->_pSelf) return -1; -+ if (_pSelf > ci->_pSelf) return 1; -+ -+ // for same percentage (e.g. all 100%), use distance info -+ if (_distance < ci->_distance) return -1; -+ if (_distance > ci->_distance) return 1; -+ return 0; -+ } -+ -+ if (col==2) { -+ // we want to sort the distance in contra direction to costs -+ if (_distance < ci->_distance) return 1; -+ if (_distance > ci->_distance) return -1; -+ return 0; -+ } -+ -+ if (col==3) { -+ if (_cc < ci->_cc) return -1; -+ if (_cc > ci->_cc) return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -+ -diff --git a/kdecachegrind/kdecachegrind/coverageitem.h b/kdecachegrind/kdecachegrind/coverageitem.h -new file mode 100644 -index 0000000..ba442aa ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/coverageitem.h -@@ -0,0 +1,82 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of coverage view. -+ */ -+ -+#ifndef COVERAGEITEM_H -+#define COVERAGEITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class Coverage; -+ -+class CallerCoverageItem: public TQListViewItem -+{ -+public: -+ CallerCoverageItem(TQListView* parent, Coverage* c, TraceFunction* base, -+ TraceCostType* ct, TraceCost::CostType gt); -+ CallerCoverageItem(TQListView* parent, int skipped, Coverage* c, TraceFunction* base, -+ TraceCostType* ct, TraceCost::CostType gt); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ TraceFunction* function() { return (_skipped) ? 0 : _function; } -+ void setCostType(TraceCostType* ct); -+ void setGroupType(TraceCost::CostType); -+ void update(); -+ -+private: -+ float _pSum; -+ SubCost _sum; -+ TraceCostType* _costType; -+ TraceCost::CostType _groupType; -+ SubCost _cc; -+ int _distance, _skipped; -+ TraceFunction *_function, *_base; -+ Coverage* _coverage; -+}; -+ -+ -+class CalleeCoverageItem: public TQListViewItem -+{ -+public: -+ CalleeCoverageItem(TQListView* parent, Coverage* c, TraceFunction* base, -+ TraceCostType* ct, TraceCost::CostType gt); -+ CalleeCoverageItem(TQListView* parent, int skipped, Coverage* c, TraceFunction* base, -+ TraceCostType* ct, TraceCost::CostType gt); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ TraceFunction* function() { return (_skipped) ? 0 : _function; } -+ void setCostType(TraceCostType* ct); -+ void setGroupType(TraceCost::CostType); -+ void update(); -+ -+private: -+ float _pSum, _pSelf; -+ SubCost _sum, _self; -+ TraceCostType* _costType; -+ TraceCost::CostType _groupType; -+ SubCost _cc; -+ int _distance, _skipped; -+ TraceFunction *_function, *_base; -+ Coverage* _coverage; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/coverageview.cpp b/kdecachegrind/kdecachegrind/coverageview.cpp -new file mode 100644 -index 0000000..6657e92 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/coverageview.cpp -@@ -0,0 +1,321 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Coverage Views -+ */ -+ -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "coverageitem.h" -+#include "coverage.h" -+#include "coverageview.h" -+ -+ -+ -+// -+// CoverageView -+// -+ -+ -+CoverageView::CoverageView(bool showCallers, TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQListView(parent, name), TraceItemView(parentView) -+{ -+ _showCallers = showCallers; -+ -+ -+ addColumn( i18n( "Incl." ) ); -+ if (_showCallers) { -+ addColumn( i18n( "Distance" ) ); -+ addColumn( i18n( "Called" ) ); -+ addColumn( i18n( "Caller" ) ); -+ } -+ else { -+ addColumn( i18n( "Self" ) ); -+ addColumn( i18n( "Distance" ) ); -+ addColumn( i18n( "Calling" ) ); -+ addColumn( i18n( "Callee" ) ); -+ setColumnAlignment(3, TQt::AlignRight); -+ } -+ -+ setSorting(0,false); -+ setColumnAlignment(0, TQt::AlignRight); -+ setColumnAlignment(1, TQt::AlignRight); -+ setColumnAlignment(2, TQt::AlignRight); -+ setAllColumnsShowFocus(true); -+ setResizeMode(TQListView::LastColumn); -+ setMinimumHeight(50); -+ -+ connect( this, -+ TQT_SIGNAL( selectionChanged(TQListViewItem*) ), -+ TQT_SLOT( selectedSlot(TQListViewItem*) ) ); -+ -+ connect( this, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int))); -+ -+ connect(this, -+ TQT_SIGNAL(doubleClicked(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ TQWhatsThis::add( this, whatsThis() ); -+} -+ -+TQString CoverageView::whatsThis() const -+{ -+ return _showCallers ? -+ i18n( "List of all Callers" -+ "

This list shows all functions calling the " -+ "current selected one, either directly or with " -+ "several functions in-between on the stack; the " -+ "number of functions in-between plus one " -+ "is called the Distance (e.g. " -+ "for function A,B,C there exists a call from " -+ "A to C when A calls B and B calls C, i.e. " -+ "A => B => C. The distance here is 2).

" -+ -+ "

Absolute cost shown is the cost spent in the " -+ "selected function while a listed function is active; " -+ "relative cost is the percentage of all cost spent in " -+ "the selected function while the listed one is " -+ "active. The cost graphic shows logarithmic " -+ "percentage with a different color for each " -+ "distance.

" -+ -+ "

As there can be many calls from the same function, " -+ "the distance column sometimes shows " -+ "the range of distances for all " -+ "calls happening; then, in parentheses, there is the " -+ "medium distance, i.e. the distance where most of the " -+ "call costs happened.

" -+ -+ "

Selecting a function makes it the current selected " -+ "one of this information panel. " -+ "If there are two panels (Split mode), the " -+ "function of the other panel is changed instead.

") : -+ -+ i18n( "List of all Callees" -+ "

This list shows all functions called by the " -+ "current selected one, either directly or with " -+ "several function in-between on the stack; the " -+ "number of function in-between plus one " -+ "is called the Distance (e.g. " -+ "for function A,B,C there exists a call from " -+ "A to C when A calls B and B calls C, i.e. " -+ "A => B => C. The distance here is 2).

" -+ -+ "

Absolute cost shown is the cost spent in the " -+ "listed function while the selected is active; " -+ "relative cost is the percentage of all cost spent in " -+ "the listed function while the selected one is active. " -+ "The cost graphic always shows logarithmic " -+ "percentage with a different color for each " -+ "distance.

" -+ -+ "

As there can be many calls to the same function, " -+ "the distance column sometimes shows " -+ "the range of distances for all " -+ "calls happening; then, in parentheses, there is the " -+ "medium distance, i.e. the distance where most of the " -+ "call costs happened.

" -+ -+ "

Selecting a function makes it the current selected " -+ "one of this information panel. " -+ "If there are two panels (Split mode), the " -+ "function of the other panel is changed instead.

"); -+} -+ -+void CoverageView::context(TQListViewItem* i, const TQPoint & p, int c) -+{ -+ TQPopupMenu popup; -+ -+ TraceFunction* f = 0; -+ if (i) { -+ f = _showCallers ? -+ ((CallerCoverageItem*)i)->function() : -+ ((CalleeCoverageItem*)i)->function(); -+ } -+ -+ if (f) { -+ TQString name = f->name(); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ popup.insertItem(i18n("Go to '%1'").arg(name), 93); -+ popup.insertSeparator(); -+ } -+ -+ if ((c == 0) || (!_showCallers && c == 1)) { -+ addCostMenu(&popup, false); -+ popup.insertSeparator(); -+ } -+ addGoMenu(&popup); -+ -+ int r = popup.exec(p); -+ if (r == 93) activated(f); -+} -+ -+void CoverageView::selectedSlot(TQListViewItem * i) -+{ -+ TraceFunction* f = 0; -+ if (i) { -+ f = _showCallers ? -+ ((CallerCoverageItem*)i)->function() : -+ ((CalleeCoverageItem*)i)->function(); -+ } -+ -+ if (f) { -+ _selectedItem = f; -+ selected(f); -+ } -+} -+ -+void CoverageView::activatedSlot(TQListViewItem * i) -+{ -+ TraceFunction* f = 0; -+ if (i) { -+ f = _showCallers ? -+ ((CallerCoverageItem*)i)->function() : -+ ((CalleeCoverageItem*)i)->function(); -+ } -+ -+ if (f) activated(f); -+} -+ -+TraceItem* CoverageView::canShow(TraceItem* i) -+{ -+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType; -+ -+ switch(t) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ return i; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+void CoverageView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == selectedItemChanged) { -+ -+ if (!_selectedItem) { -+ clearSelection(); -+ return; -+ } -+ -+ TraceFunction* f = 0; -+ TQListViewItem* i = TQListView::selectedItem(); -+ if (i) { -+ f = _showCallers ? -+ ((CallerCoverageItem*)i)->function() : -+ ((CalleeCoverageItem*)i)->function(); -+ } -+ if (f == _selectedItem) return; -+ -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) { -+ f = _showCallers ? -+ ((CallerCoverageItem*)item)->function() : -+ ((CalleeCoverageItem*)item)->function(); -+ if (f == _selectedItem) { -+ ensureItemVisible(item); -+ setCurrentItem(item); -+ break; -+ } -+ } -+ return; -+ } -+ -+ if (changeType == groupTypeChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) { -+ if (_showCallers) -+ ((CallerCoverageItem*)item)->setGroupType(_groupType); -+ else -+ ((CalleeCoverageItem*)item)->setGroupType(_groupType); -+ } -+ return; -+ } -+ -+ refresh(); -+} -+ -+void CoverageView::refresh() -+{ -+ clear(); -+ setColumnWidth(0, 50); -+ if (!_showCallers) -+ setColumnWidth(1, 50); -+ -+ if (!_data || !_activeItem) return; -+ -+ TraceItem::CostType t = _activeItem->type(); -+ TraceFunction* f = 0; -+ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem; -+ if (t == TraceItem::FunctionCycle) f = (TraceFunction*) _activeItem; -+ if (!f) return; -+ -+ TraceFunction* ff; -+ TraceFunctionList l; -+ -+ _hc.clear(Configuration::maxListCount()); -+ SubCost realSum = f->inclusive()->subCost(_costType); -+ -+ if (_showCallers) -+ l = Coverage::coverage(f, Coverage::Caller, _costType); -+ else -+ l = Coverage::coverage(f, Coverage::Called, _costType); -+ -+ for (ff=l.first();ff;ff=l.next()) { -+ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti); -+ if (c && (c->inclusive()>0.0)) -+ _hc.addCost(ff, SubCost(realSum * c->inclusive())); -+ } -+ -+ for(int i=0;i<_hc.realCount();i++) { -+ ff = (TraceFunction*) _hc[i]; -+ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti); -+ if (_showCallers) -+ new CallerCoverageItem(this, c, f, _costType, _groupType); -+ else -+ new CalleeCoverageItem(this, c, f, _costType, _groupType); -+ } -+ if (_hc.hasMore()) { -+ // a placeholder for all the functions skipped ... -+ ff = (TraceFunction*) _hc[_hc.maxSize()-1]; -+ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti); -+ if (_showCallers) -+ new CallerCoverageItem(this, _hc.count() - _hc.maxSize(), -+ c, f, _costType, _groupType); -+ else -+ new CalleeCoverageItem(this, _hc.count() - _hc.maxSize(), -+ c, f, _costType, _groupType); -+ } -+} -+ -+#include "coverageview.moc" -diff --git a/kdecachegrind/kdecachegrind/coverageview.h b/kdecachegrind/kdecachegrind/coverageview.h -new file mode 100644 -index 0000000..09c5de0 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/coverageview.h -@@ -0,0 +1,57 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Coverage Views -+ */ -+ -+#ifndef COVERAGEVIEW_H -+#define COVERAGEVIEW_H -+ -+#include -+#include "tracedata.h" -+#include "traceitemview.h" -+#include "listutils.h" -+ -+class CoverageView: public TQListView, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ CoverageView(bool showCallers, TraceItemView* parentView, -+ TQWidget* parent=0, const char* name=0); -+ -+ virtual TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ -+private slots: -+ void context(TQListViewItem*,const TQPoint &, int); -+ void selectedSlot(TQListViewItem*); -+ void activatedSlot(TQListViewItem*); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ void refresh(); -+ -+ HighestCostList _hc; -+ bool _showCallers; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/dumpmanager.cpp b/kdecachegrind/kdecachegrind/dumpmanager.cpp -new file mode 100644 -index 0000000..2f0891a ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/dumpmanager.cpp -@@ -0,0 +1,50 @@ -+/** -+ * DumpManager -+ * Part of KCachegrind -+ * 2003, Josef Weidendorfer (GPL V2) -+ */ -+ -+#include "dumpmanager.h" -+ -+ -+// -+// Dump -+// -+ -+Dump::Dump(TQString file) -+{ -+ _filename = file; -+} -+ -+ -+// -+// DumpManager -+// -+ -+DumpManager* DumpManager::_self = 0; -+ -+ -+DumpManager::DumpManager() -+{ -+} -+ -+DumpManager* DumpManager::self() -+{ -+ if (!_self) -+ _self = new DumpManager(); -+ -+ return _self; -+} -+ -+ -+DumpList DumpManager::loadableDumps() -+{ -+ DumpList res; -+ -+ return res; -+} -+ -+TraceData* DumpManager::load(Dump*) -+{ -+ return 0; -+} -diff --git a/kdecachegrind/kdecachegrind/dumpmanager.h b/kdecachegrind/kdecachegrind/dumpmanager.h -new file mode 100644 -index 0000000..4925819 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/dumpmanager.h -@@ -0,0 +1,59 @@ -+/** -+ * DumpManager -+ * Part of KCachegrind -+ * 2003, Josef Weidendorfer (GPL V2) -+ * -+ * DumpManager is a Singleton. -+ * - Has List of current loaded dumps / loadable dumps -+ * - Does "communication" with current running profiles -+ * for dump selection dockable -+ */ -+ -+#ifndef DUMPMANAGER_H -+#define DUMPMANAGER_H -+ -+#include -+#include -+ -+class Dump; -+class TraceData; -+ -+typedef TQPtrList DumpList; -+ -+ -+/** -+ * A loadable profile Dump -+ */ -+class Dump -+{ -+public: -+ Dump(TQString); -+ -+ TQString filename() { return _filename; } -+ -+private: -+ TQString _filename; -+}; -+ -+ -+/* -+ * TODO: -+ * - Everything -+ * -+ */ -+ -+class DumpManager -+{ -+public: -+ DumpManager(); -+ -+ DumpManager* self(); -+ -+ DumpList loadableDumps(); -+ TraceData* load(Dump*); -+ -+private: -+ static DumpManager* _self; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/dumpselection.cpp b/kdecachegrind/kdecachegrind/dumpselection.cpp -new file mode 100644 -index 0000000..4d812ef ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/dumpselection.cpp -@@ -0,0 +1,33 @@ -+/** -+ * DumpSelection Dockable -+ * Part of KCachegrind -+ * 2003, Josef Weidendorfer (GPL V2) -+ * -+ * - Fast Selection of dumps to load/activate/use for comparing -+ * - Start a profile run from GUI (current supported: Callgrind) -+ * - View state of running profile runs. -+ * -+ */ -+ -+#include "dumpselection.h" -+ -+/* -+ * TODO: -+ * - Everything !! -+ * - Request State info on current function.. -+ * -+ */ -+ -+ -+DumpSelection::DumpSelection( TopLevel* top, -+ TQWidget* parent, const char* name) -+ : DumpSelectionBase(parent, name), TraceItemView(0, top) -+{ -+} -+ -+DumpSelection::~DumpSelection() -+{} -+ -+ -+#include "dumpselection.moc" -+ -diff --git a/kdecachegrind/kdecachegrind/dumpselection.h b/kdecachegrind/kdecachegrind/dumpselection.h -new file mode 100644 -index 0000000..49ca532 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/dumpselection.h -@@ -0,0 +1,30 @@ -+/** -+ * DumpSelection Dockable -+ * Part of KCachegrind -+ * 2003, Josef Weidendorfer (GPL V2) -+ * -+ * - Fast Selection of dumps to load/activate/use for comparing -+ * - Start a profile run from GUI (current supported: Callgrind) -+ * - View state of running profile runs. -+ * -+ */ -+ -+#ifndef DUMPSELECTION_H -+#define DUMPSELECTION_H -+ -+#include "dumpselectionbase.h" -+#include "traceitemview.h" -+ -+class DumpSelection : public DumpSelectionBase, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ DumpSelection( TopLevel*, TQWidget* parent = 0, const char* name = 0); -+ virtual ~DumpSelection(); -+ -+ TQWidget* widget() { return this; } -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/dumpselectionbase.ui b/kdecachegrind/kdecachegrind/dumpselectionbase.ui -new file mode 100644 -index 0000000..b8ad1b0 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/dumpselectionbase.ui -@@ -0,0 +1,1082 @@ -+ -+DumpSelectionBase -+ -+ -+ DumpSelectionBase -+ -+ -+ -+ 0 -+ 0 -+ 349 -+ 832 -+ -+ -+ -+ Profile Dumps -+ -+ -+ -+ unnamed -+ -+ -+ -+ splitter1 -+ -+ -+ Vertical -+ -+ -+ -+ -+ Target -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Time -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Path -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ listView1 -+ -+ -+ -+ -+ tabWidget2 -+ -+ -+ -+ tab -+ -+ -+ Options -+ -+ -+ -+ unnamed -+ -+ -+ -+ textLabel1 -+ -+ -+ -+ 5 -+ 5 -+ 1 -+ 0 -+ -+ -+ -+ Target command: -+ -+ -+ -+ -+ lineEdit1 -+ -+ -+ -+ -+ textLabel2 -+ -+ -+ Profiler options: -+ -+ -+ -+ -+ -+ Option -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Value -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Trace -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Jumps -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Instructions -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Events -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Full Cache -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Custom -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Collect -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ At Startup -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ While In -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Skip -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ PLT -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Function -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Dump Profile -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Every BBs -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ On Entering -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ On Leaving -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Zero Events -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ On Entering -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Separate -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Threads -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Recursions -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Call Chain -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ listView3 -+ -+ -+ -+ -+ textLabel1_2 -+ -+ -+ -+ 5 -+ 5 -+ 1 -+ 0 -+ -+ -+ -+ Custom profiler options: -+ -+ -+ -+ -+ lineEdit1_2 -+ -+ -+ -+ -+ layout3 -+ -+ -+ -+ unnamed -+ -+ -+ -+ spacer1 -+ -+ -+ Horizontal -+ -+ -+ Expanding -+ -+ -+ -+ 21 -+ 20 -+ -+ -+ -+ -+ -+ pushButton2 -+ -+ -+ Run New Profile -+ -+ -+ -+ -+ -+ -+ -+ -+ tab -+ -+ -+ Info -+ -+ -+ -+ unnamed -+ -+ -+ -+ textLabel8 -+ -+ -+ Dump reason: -+ -+ -+ -+ -+ lineEdit3 -+ -+ -+ -+ -+ textLabel6 -+ -+ -+ Event summary: -+ -+ -+ -+ -+ -+ Name -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Sum -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ listView4 -+ -+ -+ -+ -+ textLabel7 -+ -+ -+ Miscellaneous: -+ -+ -+ -+ -+ textEdit2 -+ -+ -+ -+ -+ layout7 -+ -+ -+ -+ unnamed -+ -+ -+ -+ spacer3 -+ -+ -+ Horizontal -+ -+ -+ Expanding -+ -+ -+ -+ 50 -+ 20 -+ -+ -+ -+ -+ -+ pushButton6 -+ -+ -+ Show -+ -+ -+ -+ -+ pushButton5 -+ -+ -+ Compare -+ -+ -+ -+ -+ -+ -+ -+ -+ tab -+ -+ -+ State -+ -+ -+ -+ unnamed -+ -+ -+ -+ layout2 -+ -+ -+ -+ unnamed -+ -+ -+ -+ pushButton1 -+ -+ -+ Update -+ -+ -+ -+ -+ checkBox1 -+ -+ -+ Every [s]: -+ -+ -+ -+ -+ lineEdit3_2 -+ -+ -+ -+ -+ -+ -+ -+ Counter -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Value -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Dumps Done -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Is Collecting -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Executed -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Basic Blocks -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Calls -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Jumps -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Events -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Ir -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Distinct -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ ELF Objects -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Functions -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Contexts -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ listView4_3 -+ -+ -+ -+ -+ layout4 -+ -+ -+ -+ unnamed -+ -+ -+ -+ textLabel4 -+ -+ -+ -+ 5 -+ 5 -+ 1 -+ 0 -+ -+ -+ -+ Stack trace: -+ -+ -+ -+ -+ checkBox2 -+ -+ -+ Sync. -+ -+ -+ -+ -+ -+ -+ -+ # -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Incl. -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Called -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Function -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Location -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ listView7 -+ -+ -+ -+ -+ layout6 -+ -+ -+ -+ unnamed -+ -+ -+ -+ pushButton7 -+ -+ -+ Start -+ -+ -+ -+ -+ spacer2 -+ -+ -+ Horizontal -+ -+ -+ Expanding -+ -+ -+ -+ 20 -+ 20 -+ -+ -+ -+ -+ -+ pushButton6_2 -+ -+ -+ Zero -+ -+ -+ -+ -+ pushButton4 -+ -+ -+ Dump -+ -+ -+ -+ -+ -+ -+ -+ -+ tab -+ -+ -+ Messages -+ -+ -+ -+ unnamed -+ -+ -+ -+ textEdit2_2 -+ -+ -+ -+ -+ layout6 -+ -+ -+ -+ unnamed -+ -+ -+ -+ pushButton9 -+ -+ -+ Kill Run -+ -+ -+ -+ -+ spacer4 -+ -+ -+ Horizontal -+ -+ -+ Expanding -+ -+ -+ -+ 21 -+ 20 -+ -+ -+ -+ -+ -+ pushButton8 -+ -+ -+ Clear -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/kdecachegrind/kdecachegrind/fixcost.cpp b/kdecachegrind/kdecachegrind/fixcost.cpp -new file mode 100644 -index 0000000..4102926 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/fixcost.cpp -@@ -0,0 +1,174 @@ -+/* -+ * Part of KCacheGrind -+ * -+ * 2003, Josef Weidendorfer -+ */ -+ -+#include "fixcost.h" -+#include "utils.h" -+ -+ -+// FixCost -+ -+FixCost::FixCost(TracePart* part, FixPool* pool, -+ TraceFunctionSource* functionSource, -+ PositionSpec& pos, -+ TracePartFunction* partFunction, -+ FixString& s) -+{ -+ int maxCount = part->fixSubMapping()->count(); -+ -+ _part = part; -+ _functionSource = functionSource; -+ _pos = pos; -+ -+ _cost = (SubCost*) pool->reserve(sizeof(SubCost) * maxCount); -+ s.stripSpaces(); -+ int i = 0; -+ while(iallocateReserved(sizeof(SubCost) * _count)) -+ _count = 0; -+ -+ _nextCostOfPartFunction = partFunction ? -+ partFunction->setFirstFixCost(this) : 0; -+} -+ -+void* FixCost::operator new(size_t size, FixPool* pool) -+{ -+ return pool->allocate(size); -+} -+ -+void FixCost::addTo(TraceCost* c) -+{ -+ TraceSubMapping* sm = _part->fixSubMapping(); -+ -+ int i, realIndex; -+ -+ for(i=0; i<_count; i++) { -+ realIndex = sm->realIndex(i); -+ c->addCost(realIndex, _cost[i]); -+ } -+} -+ -+ -+ -+// FixCallCost -+ -+FixCallCost::FixCallCost(TracePart* part, FixPool* pool, -+ TraceFunctionSource* functionSource, -+ unsigned int line, Addr addr, -+ TracePartCall* partCall, -+ SubCost callCount, FixString& s) -+{ -+ if (0) qDebug("Got FixCallCost (addr 0x%s, line %d): calls %s", -+ addr.toString().ascii(), line, -+ callCount.pretty().ascii()); -+ -+ int maxCount = part->fixSubMapping()->count(); -+ -+ _part = part; -+ _functionSource = functionSource; -+ _line = line; -+ _addr = addr; -+ -+ _cost = (SubCost*) pool->reserve(sizeof(SubCost) * (maxCount+1)); -+ s.stripSpaces(); -+ int i = 0; -+ while(iallocateReserved(sizeof(SubCost) * (_count+1) )) -+ _count = 0; -+ else -+ _cost[_count] = callCount; -+ -+ _nextCostOfPartCall = partCall ? partCall->setFirstFixCallCost(this) : 0; -+} -+ -+void* FixCallCost::operator new(size_t size, FixPool* pool) -+{ -+ return pool->allocate(size); -+} -+ -+void FixCallCost::addTo(TraceCallCost* c) -+{ -+ TraceSubMapping* sm = _part->fixSubMapping(); -+ -+ int i, realIndex; -+ -+ for(i=0; i<_count; i++) { -+ realIndex = sm->realIndex(i); -+ c->addCost(realIndex, _cost[i]); -+ } -+ c->addCallCount(_cost[_count]); -+ -+ if (0) qDebug("Adding from (addr 0x%s, ln %d): calls %s", -+ _addr.toString().ascii(), _line, -+ _cost[_count].pretty().ascii()); -+} -+ -+void FixCallCost::setMax(TraceCost* c) -+{ -+ TraceSubMapping* sm = _part->fixSubMapping(); -+ -+ int i, realIndex; -+ -+ for(i=0; i<_count; i++) { -+ realIndex = sm->realIndex(i); -+ c->maxCost(realIndex, _cost[i]); -+ } -+} -+ -+ -+// FixJump -+ -+FixJump::FixJump(TracePart* part, FixPool* pool, -+ unsigned int line, Addr addr, -+ TracePartFunction* partFunction, -+ TraceFunctionSource* source, -+ unsigned int targetLine, Addr targetAddr, -+ TraceFunction* targetFunction, -+ TraceFunctionSource* targetSource, -+ bool isCondJump, -+ SubCost executed, SubCost followed) -+{ -+ _part = part; -+ _source = source; -+ _line = line; -+ _addr = addr; -+ -+ _targetFunction = targetFunction; -+ _targetSource = targetSource; -+ _targetLine = targetLine; -+ _targetAddr = targetAddr; -+ -+ _isCondJump = isCondJump; -+ -+ int size = (isCondJump ? 2 : 1) * sizeof(SubCost); -+ _cost = (SubCost*) pool->allocate(size); -+ _cost[0] = executed; -+ if (isCondJump) _cost[1] = followed; -+ -+ _nextJumpOfPartFunction = partFunction ? -+ partFunction->setFirstFixJump(this) : 0; -+} -+ -+void* FixJump::operator new(size_t size, FixPool* pool) -+{ -+ return pool->allocate(size); -+} -+ -+void FixJump::addTo(TraceJumpCost* jc) -+{ -+ jc->addExecutedCount(_cost[0]); -+ if (_isCondJump) -+ jc->addFollowedCount(_cost[1]); -+} -diff --git a/kdecachegrind/kdecachegrind/fixcost.h b/kdecachegrind/kdecachegrind/fixcost.h -new file mode 100644 -index 0000000..7e90fb4 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/fixcost.h -@@ -0,0 +1,171 @@ -+/* -+ * Part of KCacheGrind -+ * -+ * 2003, Josef Weidendorfer -+ */ -+ -+#ifndef FIXCOST_H -+#define FIXCOST_H -+ -+/** -+ * Setting USE_FIXCOST to 1 enables a memory space hack: -+ * For some data, build up internal data model lazy by using -+ * the Fix*Cost classes, which are simple copies from input data. -+ */ -+#define USE_FIXCOST 1 -+ -+#include "tracedata.h" -+#include "pool.h" -+ -+class PositionSpec -+{ -+ public: -+ PositionSpec() -+ { fromLine = 0, toLine = 0, fromAddr = 0, toAddr = 0; } -+ PositionSpec(uint l1, uint l2, Addr a1, Addr a2) -+ { fromLine = l1, toLine = l2, fromAddr = a1, toAddr = a2; } -+ -+ bool isLineRegion() const { return (fromLine != toLine); } -+ bool isAddrRegion() const { return (fromAddr != toAddr); } -+ -+ uint fromLine, toLine; -+ Addr fromAddr, toAddr; -+}; -+ -+/** -+ * A class holding an unchangable cost item of an input file. -+ * -+ * As there can be a lot of such cost items, we use our own -+ * allocator which uses FixPool -+ */ -+class FixCost -+{ -+ -+ public: -+ FixCost(TracePart*, FixPool*, -+ TraceFunctionSource*, -+ PositionSpec&, -+ TracePartFunction*, -+ FixString&); -+ -+ void *operator new(size_t size, FixPool*); -+ -+ void addTo(TraceCost*); -+ -+ TracePart* part() const { return _part; } -+ bool isLineRegion() const { return _pos.isLineRegion(); } -+ bool isAddrRegion() const { return _pos.isAddrRegion(); } -+ uint fromLine() const { return _pos.fromLine; } -+ uint line() const { return _pos.fromLine; } -+ uint toLine() const { return _pos.toLine; } -+ Addr fromAddr() const { return _pos.fromAddr; } -+ Addr addr() const { return _pos.fromAddr; } -+ Addr toAddr() const { return _pos.toAddr; } -+ TraceFunctionSource* functionSource() const { return _functionSource; } -+ -+ FixCost* nextCostOfPartFunction() const -+ { return _nextCostOfPartFunction; } -+ -+ private: -+ int _count; -+ SubCost* _cost; -+ PositionSpec _pos; -+ -+ TracePart* _part; -+ TraceFunctionSource* _functionSource; -+ FixCost *_nextCostOfPartFunction; -+}; -+ -+/** -+ * A FixCallCost will be inserted into a -+ * - TracePartCall to keep source/target function info -+ * - TraceFunctionSourceFile to keep file info of call source -+ */ -+class FixCallCost -+{ -+ -+ public: -+ FixCallCost(TracePart*, FixPool*, -+ TraceFunctionSource*, -+ unsigned int line, -+ Addr addr, -+ TracePartCall*, -+ SubCost, FixString&); -+ -+ void *operator new(size_t size, FixPool*); -+ -+ void addTo(TraceCallCost*); -+ void setMax(TraceCost*); -+ -+ TracePart* part() const { return _part; } -+ unsigned int line() const { return _line; } -+ Addr addr() const { return _addr; } -+ SubCost callCount() const { return _cost[_count]; } -+ TraceFunctionSource* functionSource() const { return _functionSource; } -+ FixCallCost* nextCostOfPartCall() const -+ { return _nextCostOfPartCall; } -+ -+ private: -+ // we use 1 SubCost more than _count: _cost[_count] is the call count -+ int _count; -+ SubCost* _cost; -+ unsigned int _line; -+ Addr _addr; -+ -+ TracePart* _part; -+ TraceFunctionSource* _functionSource; -+ FixCallCost* _nextCostOfPartCall; -+}; -+ -+/** -+ * A class holding a jump (mostly) inside of a function -+ */ -+class FixJump -+{ -+ -+ public: -+ FixJump(TracePart*, FixPool*, -+ /* source position */ -+ unsigned int line, Addr addr, -+ TracePartFunction*, TraceFunctionSource*, -+ /* target position */ -+ unsigned int targetLine, Addr targetAddr, -+ TraceFunction*, TraceFunctionSource*, -+ bool isCondJump, -+ SubCost, SubCost); -+ -+ void *operator new(size_t size, FixPool*); -+ -+ void addTo(TraceJumpCost*); -+ -+ TracePart* part() const { return _part; } -+ unsigned int line() const { return _line; } -+ Addr addr() const { return _addr; } -+ TraceFunctionSource* source() const { return _source; } -+ TraceFunction* targetFunction() const { return _targetFunction; } -+ unsigned int targetLine() const { return _targetLine; } -+ Addr targetAddr() const { return _targetAddr; } -+ TraceFunctionSource* targetSource() const { return _targetSource; } -+ bool isCondJump() { return _isCondJump; } -+ SubCost executedCount() const { return _cost[0]; } -+ SubCost followedCount() const -+ { return _isCondJump ? _cost[1] : SubCost(0); } -+ -+ FixJump* nextJumpOfPartFunction() const -+ { return _nextJumpOfPartFunction; } -+ -+ private: -+ bool _isCondJump; -+ SubCost* _cost; -+ unsigned int _line, _targetLine; -+ Addr _addr, _targetAddr; -+ -+ TracePart* _part; -+ TraceFunctionSource *_source, *_targetSource; -+ TraceFunction* _targetFunction; -+ FixJump *_nextJumpOfPartFunction; -+}; -+ -+#endif -+ -+ -diff --git a/kdecachegrind/kdecachegrind/functionitem.cpp b/kdecachegrind/kdecachegrind/functionitem.cpp -new file mode 100644 -index 0000000..3b694dd ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/functionitem.cpp -@@ -0,0 +1,236 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * List Item for the FunctionSelection list -+ */ -+ -+ -+//#include -+ -+//#include -+//#include -+ -+#include -+#include -+#include -+ -+#include "listutils.h" -+#include "functionitem.h" -+#include "configuration.h" -+ -+ -+// FunctionItem -+ -+FunctionItem::FunctionItem(TQListView* parent, TraceFunction* f, -+ TraceCostType* ct, TraceCost::CostType gt) -+ :TQListViewItem(parent) -+{ -+#if 0 -+ _costPixValid = false; -+ _groupPixValid = false; -+#endif -+ -+ _function = f; -+ _skipped = 0; -+ _groupType = TraceCost::NoCostType; -+ setGroupType(gt); -+ setCostType(ct); -+ -+ setText(3, f->prettyName()); -+ setText(4, f->prettyLocation()); -+} -+ -+FunctionItem::FunctionItem(TQListView* parent, int skipped, -+ TraceFunction* f, TraceCostType* ct) -+ :TQListViewItem(parent) -+{ -+#if 0 -+ _costPixValid = false; -+ _groupPixValid = false; -+#endif -+ _skipped = skipped; -+ _function = f; -+ _groupType = TraceCost::NoCostType; -+ setCostType(ct); -+ -+ setText(3, i18n("(%n function skipped)", "(%n functions skipped)", skipped)); -+} -+ -+#if 0 -+const TQPixmap* FunctionItem::pixmap(int column) const -+{ -+ if (column == 3) { -+ if (!_groupPixValid) { -+ TQColor c = Configuration::functionColor(_groupType, _function); -+ _groupPix = colorPixmap(10, 10, c); -+ _groupPixValid = true; -+ } -+ return &_groupPix; -+ } -+ if (column == 1) { -+ if (!_costPixValid) { -+ _costPix = colorPixmap(10, 10, c); -+ _costPixValid = true; -+ } -+ return &_costPix; -+ } -+ return 0; -+} -+#endif -+ -+void FunctionItem::setGroupType(TraceCost::CostType gt) -+{ -+ if (_skipped) return; -+ if (_groupType == gt) return; -+ _groupType = gt; -+ -+ -+#if 0 -+ _groupPixValid = false; -+ viewList()->repaint(); -+#else -+ TQColor c = Configuration::functionColor(_groupType, _function); -+ setPixmap(3, colorPixmap(10, 10, c)); -+#endif -+} -+ -+void FunctionItem::setCostType(TraceCostType* c) -+{ -+ _costType = c; -+ update(); -+} -+ -+void FunctionItem::update() -+{ -+ double inclTotal = _function->data()->subCost(_costType); -+ TQString str; -+ -+ TraceCost* selfCost = _function->data(); -+ if (Configuration::showExpanded()) { -+ switch(_groupType) { -+ case TraceCost::Object: selfCost = _function->object(); break; -+ case TraceCost::Class: selfCost = _function->cls(); break; -+ case TraceCost::File: selfCost = _function->file(); break; -+ default: break; -+ } -+ } -+ double selfTotal = selfCost->subCost(_costType); -+ -+ if (_skipped) { -+ // special handling for skip entries... -+ -+ // only text updates of incl./self -+ -+ // for all skipped functions, cost is below the given function -+ _sum = _function->inclusive()->subCost(_costType); -+ double incl = 100.0 * _sum / inclTotal; -+ if (Configuration::showPercentage()) -+ str = TQString("%1").arg(incl, 0, 'f', Configuration::percentPrecision()); -+ else -+ str = _function->inclusive()->prettySubCost(_costType); -+ str = "< " + str; -+ setText(0, str); -+ setText(1, str); -+ return; -+ } -+ -+ // Call count... -+ if (_function->calledCount() >0) -+ str = _function->prettyCalledCount(); -+ else { -+ if (_function == _function->cycle()) -+ str = TQString("-"); -+ else -+ str = TQString("(0)"); -+ } -+ setText(2, str); -+ -+ // Incl. cost -+ _sum = _function->inclusive()->subCost(_costType); -+ if (inclTotal == 0.0) { -+ setPixmap(0, TQPixmap()); -+ setText(0, "-"); -+ } -+ else { -+ double incl = 100.0 * _sum / inclTotal; -+ if (Configuration::showPercentage()) -+ setText(0, TQString("%1") -+ .arg(incl, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(0, _function->inclusive()->prettySubCost(_costType)); -+ -+ setPixmap(0, costPixmap(_costType, _function->inclusive(), inclTotal, false)); -+ } -+ -+ // self -+ _pure = _function->subCost(_costType); -+ if (selfTotal == 0.0) { -+ setPixmap(1, TQPixmap()); -+ setText(1, "-"); -+ } -+ else { -+ double self = 100.0 * _pure / selfTotal; -+ -+ if (Configuration::showPercentage()) -+ setText(1, TQString("%1") -+ .arg(self, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(1, _function->prettySubCost(_costType)); -+ -+ setPixmap(1, costPixmap(_costType, _function, selfTotal, false)); -+ } -+} -+ -+ -+int FunctionItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ const FunctionItem* fi1 = this; -+ const FunctionItem* fi2 = (FunctionItem*) i; -+ -+ // we always want descending order -+ if (ascending) { -+ fi1 = fi2; -+ fi2 = this; -+ } -+ -+ // a skip entry is always sorted last -+ if (fi1->_skipped) return -1; -+ if (fi2->_skipped) return 1; -+ -+ if (col==0) { -+ if (fi1->_sum < fi2->_sum) return -1; -+ if (fi1->_sum > fi2->_sum) return 1; -+ return 0; -+ } -+ if (col==1) { -+ if (fi1->_pure < fi2->_pure) return -1; -+ if (fi1->_pure > fi2->_pure) return 1; -+ return 0; -+ } -+ if (col==2) { -+ if (fi1->_function->calledCount() < -+ fi2->_function->calledCount()) return -1; -+ if (fi1->_function->calledCount() > -+ fi2->_function->calledCount()) return 1; -+ return 0; -+ } -+ -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -diff --git a/kdecachegrind/kdecachegrind/functionitem.h b/kdecachegrind/kdecachegrind/functionitem.h -new file mode 100644 -index 0000000..d8f98f4 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/functionitem.h -@@ -0,0 +1,58 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * List Item for the FunctionSelection list -+ */ -+ -+#ifndef FUNCTIONITEM_H -+#define FUNCTIONITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class FunctionItem: public TQListViewItem -+{ -+public: -+ FunctionItem(TQListView* parent, TraceFunction* function, -+ TraceCostType* ct, TraceCost::CostType gt); -+ // constructor for a "Skipped ... " entry -+ FunctionItem(TQListView* parent, int skipped, -+ TraceFunction* function, TraceCostType* ct); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ TraceFunction* function() { return (_skipped) ? 0 : _function; } -+ void setCostType(TraceCostType* ct); -+ void setGroupType(TraceCost::CostType); -+ void update(); -+ -+#if 0 -+ const TQPixmap* pixmap (int column) const; -+ bool _costPixValid, _groupPixValid; -+ TQPixMap _costPix, _groupPix; -+#endif -+ -+private: -+ SubCost _sum, _pure; -+ TraceCostType* _costType; -+ TraceCost::CostType _groupType; -+ TraceFunction* _function; -+ int _skipped; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/functionselection.cpp b/kdecachegrind/kdecachegrind/functionselection.cpp -new file mode 100644 -index 0000000..c5646dd ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/functionselection.cpp -@@ -0,0 +1,871 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * For function selection, to be put into a TQDockWindow -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "traceitemview.h" -+#include "stackbrowser.h" -+#include "functionselection.h" -+#include "partgraph.h" -+#include "functionitem.h" -+#include "costlistitem.h" -+#include "configuration.h" -+#include "toplevel.h" -+ -+FunctionSelection::FunctionSelection( TopLevel* top, -+ TQWidget* parent, const char* name) -+ : FunctionSelectionBase(parent, name), TraceItemView(0, top) -+{ -+ _group = 0; -+ _inSetGroup = false; -+ _inSetFunction = false; -+ -+ TQStringList args; -+ args << i18n("(No Grouping)") -+ << TraceCost::i18nTypeName(TraceItem::Object) -+ << TraceCost::i18nTypeName(TraceItem::File) -+ << TraceCost::i18nTypeName(TraceItem::Class) -+ << TraceCost::i18nTypeName(TraceItem::FunctionCycle); -+ -+ groupBox->insertStringList(args); -+ // this needs same order of grouptype actionlist! -+ connect(groupBox, TQT_SIGNAL(activated(int)), -+ top, TQT_SLOT(groupTypeSelected(int))); -+ -+ // search while typing... -+ connect(searchEdit, TQT_SIGNAL(textChanged(const TQString&)), -+ this, TQT_SLOT(searchChanged(const TQString&))); -+ connect(&_searchTimer, TQT_SIGNAL(timeout()), -+ this, TQT_SLOT(queryDelayed())); -+ // select first matching group/function on return -+ connect(searchEdit, TQT_SIGNAL(returnPressed()), -+ this, TQT_SLOT(searchReturnPressed())); -+ searchEdit->setMinimumWidth(50); -+ -+ // we start with desending cost sorting -+ functionList->setSorting(0,false); -+ functionList->setColumnAlignment(0, TQt::AlignRight); -+ functionList->setColumnAlignment(1, TQt::AlignRight); -+ functionList->setColumnAlignment(2, TQt::AlignRight); -+ functionList->setAllColumnsShowFocus(true); -+ // functionList->setShowSortIndicator(true); -+ // we can have very long function and location names -+ functionList->setColumnWidthMode(3, TQListView::Manual); -+ functionList->setColumnWidth(3, 200); -+ functionList->setColumnWidthMode(4, TQListView::Manual); -+ functionList->setColumnWidth(4, 200); -+ -+ groupList->setSorting(0,false); -+ groupList->setColumnAlignment(0, TQt::AlignRight); -+ groupList->setAllColumnsShowFocus(true); -+ // groupList->setShowSortIndicator(true); -+ groupList->setResizeMode(TQListView::LastColumn); -+ -+#if 0 -+ // single click press activation -+ connect(functionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ this, TQT_SLOT(functionActivated(TQListViewItem*))); -+ connect(functionList, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ this, TQT_SLOT(functionContext(TQListViewItem*, const TQPoint &, int))); -+#else -+ // single click release activation -+ connect(functionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ this, TQT_SLOT(functionSelected(TQListViewItem*))); -+ connect(functionList, TQT_SIGNAL(clicked(TQListViewItem*)), -+ this, TQT_SLOT(functionActivated(TQListViewItem*))); -+ connect(functionList, TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ this, TQT_SLOT(functionActivated(TQListViewItem*))); -+ connect(functionList, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ this, TQT_SLOT(functionContext(TQListViewItem*, const TQPoint &, int))); -+#endif -+ -+ connect(groupList, TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ this, TQT_SLOT(groupSelected(TQListViewItem*))); -+ connect(groupList, TQT_SIGNAL(doubleClicked(TQListViewItem*)), -+ this, TQT_SLOT(groupDoubleClicked(TQListViewItem*))); -+ connect(groupList, TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ this, TQT_SLOT(groupDoubleClicked(TQListViewItem*))); -+ connect(groupList, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ this, TQT_SLOT(groupContext(TQListViewItem*, const TQPoint &, int))); -+ -+ // start hidden -+ groupList->hide(); -+} -+ -+FunctionSelection::~FunctionSelection() -+{ -+} -+ -+void FunctionSelection::searchReturnPressed() -+{ -+ query(searchEdit->text()); -+ -+ TQListViewItem* item; -+ if (_groupType != TraceItem::Function) { -+ // if current group not matching, select first matching group -+ item = groupList->currentItem(); -+ if (!item || !item->isVisible()) { -+ item = groupList->firstChild(); -+ for (;item;item = item->nextSibling()) -+ if (item->isVisible()) break; -+ if (!item) return; -+ -+ setGroup(((CostListItem*)item)->costItem()); -+ return; -+ } -+ } -+ -+ functionActivated(functionList->firstChild()); -+} -+ -+// trigger the query after some delay, dependent on length -+void FunctionSelection::searchChanged(const TQString& q) -+{ -+ _searchDelayed = q; -+ int ms = 100; -+ if (q.length()<5) ms = 200; -+ if (q.length()<2) ms = 300; -+ _searchTimer.start(ms,true); -+} -+ -+void FunctionSelection::queryDelayed() -+{ -+ query(_searchDelayed); -+} -+ -+void FunctionSelection::functionContext(TQListViewItem* i, -+ const TQPoint & p, int c) -+{ -+ TQPopupMenu popup; -+ TraceFunction* f = 0; -+ -+ if (i) { -+ f = ((FunctionItem*) i)->function(); -+ if (f) { -+ popup.insertItem(i18n("Go to %1").arg(f->prettyName()), 93); -+ popup.insertSeparator(); -+ } -+ } -+ -+ if ((c == 0) || (c == 1)) { -+ addCostMenu(&popup,false); -+ popup.insertSeparator(); -+ } -+ addGroupMenu(&popup); -+ popup.insertSeparator(); -+ addGoMenu(&popup); -+ -+ int r = popup.exec(p); -+ if (r == 93) activated(f); -+} -+ -+void FunctionSelection::groupContext(TQListViewItem* /*i*/, -+ const TQPoint & p, int c) -+{ -+ TQPopupMenu popup; -+ -+#if 0 -+ TraceCostItem* g = 0; -+ if (i) { -+ g = ((CostListItem*) i)->costItem(); -+ if (!g) { -+ popup.insertItem(i18n("Show All Items"), 93); -+ popup.insertSeparator(); -+ } -+ } -+#endif -+ if (c == 0) { -+ addCostMenu(&popup,false); -+ popup.insertSeparator(); -+ } -+ addGroupMenu(&popup); -+ popup.insertSeparator(); -+ addGoMenu(&popup); -+ -+ popup.exec(p); -+} -+ -+ -+void FunctionSelection::addGroupMenu(TQPopupMenu* popup) -+{ -+ TQPopupMenu *popup1 = new TQPopupMenu(popup); -+ popup1->setCheckable(true); -+ -+ if (_groupType != TraceItem::Function) { -+ popup1->insertItem(i18n("No Grouping"),0); -+ popup1->insertSeparator(); -+ } -+ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::Object),1); -+ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::File),2); -+ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::Class),3); -+ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::FunctionCycle),4); -+ switch(_groupType) { -+ case TraceItem::Object: popup1->setItemChecked(1, true); break; -+ case TraceItem::File: popup1->setItemChecked(2, true); break; -+ case TraceItem::Class: popup1->setItemChecked(3, true); break; -+ case TraceItem::FunctionCycle: popup1->setItemChecked(4, true); break; -+ default: break; -+ } -+ connect(popup1,TQT_SIGNAL(activated(int)), -+ _topLevel,TQT_SLOT(groupTypeSelected(int))); -+ -+ popup->insertItem(i18n("Grouping"), popup1); -+} -+ -+ -+TraceItem* FunctionSelection::canShow(TraceItem* i) -+{ -+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType; -+ -+ switch(t) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ case TraceItem::Object: -+ case TraceItem::File: -+ case TraceItem::Class: -+ break; -+ -+ case TraceItem::Instr: -+ i = ((TraceInstr*)i)->function(); -+ break; -+ -+ case TraceItem::Line: -+ i = ((TraceLine*)i)->functionSource()->function(); -+ break; -+ -+ default: -+ i = 0; -+ break; -+ } -+ return i; -+} -+ -+ -+void FunctionSelection::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == selectedItemChanged) return; -+ -+ // we don't show cost 2 at all... -+ if (changeType == costType2Changed) return; -+ -+ if (changeType == activeItemChanged) { -+ if (_activeItem ==0) { -+ functionList->clearSelection(); -+ return; -+ } -+ switch(_activeItem->type()) { -+ case TraceItem::Object: -+ case TraceItem::File: -+ case TraceItem::Class: -+ setGroup((TraceCostItem*)_activeItem); -+ return; -+ default: break; -+ } -+ -+ // active item is a function -+ TraceFunction* f = (TraceFunction*) _activeItem; -+ -+ // if already current, nothing to do -+ TQListViewItem* i = functionList->currentItem(); -+ if (i && (((FunctionItem*)i)->function() == f)) { -+ functionList->setSelected(i,true); -+ return; -+ } -+ -+ // reset searchEdit (as not activated from this view) -+ _searchString = TQString(); -+ query(TQString()); -+ -+ // select cost item group of function -+ switch(_groupType) { -+ case TraceItem::Object: setGroup(f->object()); break; -+ case TraceItem::Class: setGroup(f->cls()); break; -+ case TraceItem::File: setGroup(f->file()); break; -+ case TraceItem::FunctionCycle: setGroup(f->cycle()); break; -+ default: -+ break; -+ } -+ -+ TQListViewItem* item = functionList->firstChild(); -+ for (;item;item = item->nextSibling()) -+ if (((FunctionItem*)item)->function() == f) -+ break; -+ -+ if (!item) -+ item = new FunctionItem(functionList, f, _costType, _groupType); -+ -+ functionList->ensureItemVisible(item); -+ // prohibit signalling of a function selection -+ _inSetFunction = true; -+ functionList->setSelected(item, true); -+ _inSetFunction = false; -+ -+ return; -+ } -+ -+ if (changeType & groupTypeChanged) { -+ if (_activeItem && (_activeItem->type() == TraceItem::Function)) { -+ TraceFunction* f = (TraceFunction*) _activeItem; -+ -+ // select cost item group of function -+ switch(_groupType) { -+ case TraceItem::Object: _group = f->object(); break; -+ case TraceItem::Class: _group = f->cls(); break; -+ case TraceItem::File: _group = f->file(); break; -+ case TraceItem::FunctionCycle: _group = f->cycle(); break; -+ default: -+ _group = 0; -+ break; -+ } -+ } -+ -+ int id; -+ switch(_groupType) { -+ case TraceItem::Object: id = 1; break; -+ case TraceItem::File: id = 2; break; -+ case TraceItem::Class: id = 3; break; -+ case TraceItem::FunctionCycle: id = 4; break; -+ default: id = 0; break; -+ } -+ groupBox->setCurrentItem(id); -+ -+ if (_groupType == TraceItem::Function) -+ groupList->hide(); -+ else -+ groupList->show(); -+ } -+ -+ // reset searchEdit -+ _searchString = TQString(); -+ query(TQString()); -+ -+ refresh(); -+} -+ -+ -+/* -+ * This set/selects a group of the set available within the -+ * current group type -+ */ -+void FunctionSelection::setGroup(TraceCostItem* g) -+{ -+ if (!g) return; -+ if (g->type() != _groupType) return; -+ if (g == _group) return; -+ _group = g; -+ -+ TQListViewItem* item = groupList->firstChild(); -+ for (;item;item = item->nextSibling()) -+ if (((CostListItem*)item)->costItem() == g) -+ break; -+ -+ if (item) { -+ groupList->ensureItemVisible(item); -+ // prohibit signalling of a group selection -+ _inSetGroup = true; -+ groupList->setSelected(item, true); -+ _inSetGroup = false; -+ } -+ else -+ groupList->clearSelection(); -+} -+ -+ -+void FunctionSelection::refresh() -+{ -+ groupList->setUpdatesEnabled(false); -+ groupList->clear(); -+ -+ // make cost columns as small as possible: -+ // the new functions make them as wide as needed -+ groupList->setColumnWidth(0, 50); -+ -+ groupList->setColumnText(1, TraceItem::i18nTypeName(_groupType)); -+ -+ if (!_data || _data->parts().count()==0) { -+ functionList->clear(); -+ groupList->setUpdatesEnabled(true); -+ groupList->repaint(); -+ -+ // this clears all other lists -+ functionList->setSelected(functionList->firstChild(), true); -+ return; -+ } -+ -+ /* -+ qDebug("FunctionSelection::fillLists (%s)", -+ _data->command().ascii()); -+ */ -+ -+ TraceObjectMap::Iterator oit; -+ TraceClassMap::Iterator cit; -+ TraceFileMap::Iterator fit; -+ TQListViewItem *i = 0, *item = 0, *fitem = 0; -+ -+ // Fill up group list. -+ // Always show group of current function, even if cost below low limit. -+ // -+ -+ _hc.clear(Configuration::maxListCount()); -+ -+ TraceCostItem *group; -+ -+ // update group from _activeItem if possible -+ if (_activeItem && (_activeItem->type() == _groupType)) -+ _group = (TraceCostItem*) _activeItem; -+ -+ switch(_groupType) { -+ case TraceItem::Object: -+ -+ for ( oit = _data->objectMap().begin(); -+ oit != _data->objectMap().end(); ++oit ) -+ _hc.addCost(&(*oit), (*oit).subCost(_costType)); -+ break; -+ -+ case TraceItem::Class: -+ -+ for ( cit = _data->classMap().begin(); -+ cit != _data->classMap().end(); ++cit ) -+ _hc.addCost(&(*cit), (*cit).subCost(_costType)); -+ break; -+ -+ case TraceItem::File: -+ -+ for ( fit = _data->fileMap().begin(); -+ fit != _data->fileMap().end(); ++fit ) -+ _hc.addCost(&(*fit), (*fit).subCost(_costType)); -+ break; -+ -+ case TraceItem::FunctionCycle: -+ { -+ // add all cycles -+ TraceFunctionCycleList l = _data->functionCycles(); -+ for (group=l.first();group;group=l.next()) -+ _hc.addCost(group, group->subCost(_costType)); -+ } -+ -+ break; -+ -+ default: -+ { -+ TQListViewItem* oldItem = functionList->selectedItem(); -+ TraceFunction* oldFunction = 0; -+ int oldPos = 0; -+ if (oldItem) { -+ oldFunction = ((FunctionItem*)oldItem)->function(); -+ oldPos = oldItem->itemPos(); -+ oldPos -= functionList->contentsY(); -+ if (oldPos < 0 || oldPos > functionList->height()) -+ oldFunction = 0; -+ } -+ -+ // switching off TQListView updates is buggy with some QT versions... -+ //functionList->setUpdatesEnabled(false); -+ functionList->clear(); -+ setCostColumnWidths(); -+ -+ if (0) qDebug("Function %s at %d, Item %p", -+ oldFunction ? oldFunction->name().ascii() : "-", -+ oldPos, (void*)oldItem); -+ -+ TraceFunctionMap::Iterator it; -+ TraceFunction *f; -+ i = 0; -+ fitem = 0; -+ for ( it = _data->functionMap().begin(); -+ it != _data->functionMap().end(); ++it ) -+ _hc.addCost(&(*it), (*it).inclusive()->subCost(_costType)); -+ -+ TraceFunctionCycleList l = _data->functionCycles(); -+ for (f=l.first();f;f=l.next()) -+ _hc.addCost(f, f->inclusive()->subCost(_costType)); -+ -+ if (_activeItem && -+ ((_activeItem->type() == TraceItem::Function) || -+ (_activeItem->type() == TraceItem::FunctionCycle))) -+ fitem = new FunctionItem(functionList, (TraceFunction*)_activeItem, -+ _costType, _groupType); -+ -+ for(int i=0;i<_hc.realCount();i++) { -+ f = (TraceFunction*)_hc[i]; -+ if (f == _activeItem) continue; -+ new FunctionItem(functionList, f, _costType, _groupType); -+ } -+ if (_hc.hasMore()) { -+ // a placeholder for all the cost items skipped ... -+ new FunctionItem(functionList, _hc.count() - _hc.maxSize(), -+ (TraceFunction*)_hc[_hc.maxSize()-1], _costType); -+ } -+ functionList->sort(); -+ -+ if (fitem && oldFunction) { -+ _inSetFunction = true; -+ functionList->setSelected(fitem, true); -+ _inSetFunction = false; -+ int newPos = functionList->itemPos(fitem) - functionList->contentsY(); -+ functionList->scrollBy(0, newPos-oldPos); -+ } -+ else if (fitem) { -+ functionList->ensureItemVisible(fitem); -+ _inSetFunction = true; -+ functionList->setSelected(fitem, true); -+ _inSetFunction = false; -+ } -+ else -+ functionList->clearSelection(); -+ -+ //functionList->setUpdatesEnabled(true); -+ //functionList->repaint(); -+ groupList->setUpdatesEnabled(true); -+ groupList->repaint(); -+ return; -+ } -+ } -+ -+ // we always put group of active item in list, even if -+ // it would be skipped because of small costs -+ if (_group) -+ item = new CostListItem(groupList, _group, _costType); -+ -+ for(int i=0;i<_hc.realCount();i++) { -+ group = (TraceCostItem*)_hc[i]; -+ // don't put group of active item twice into list -+ if (group == _group) continue; -+ new CostListItem(groupList, group, _costType); -+ } -+ if (_hc.hasMore()) { -+ // a placeholder for all the cost items skipped ... -+ new CostListItem(groupList, _hc.count() - _hc.maxSize(), -+ (TraceCostItem*)_hc[_hc.maxSize()-1], _costType); -+ } -+ groupList->sort(); -+ if (item) { -+ groupList->ensureItemVisible(item); -+ _inSetGroup = true; -+ groupList->setSelected(item, true); -+ _inSetGroup = false; -+ } -+ else -+ groupList->clearSelection(); -+ -+ groupList->setUpdatesEnabled(true); -+ groupList->repaint(); -+} -+ -+ -+void FunctionSelection::groupSelected(TQListViewItem* i) -+{ -+ if (!i) return; -+ if (!_data) return; -+ -+ TraceCostItem* g = ((CostListItem*) i)->costItem(); -+ if (!g) return; -+ -+ _group = g; -+ -+ TraceFunctionList list; -+ -+ switch(g->type()) { -+ case TraceItem::Object: -+ list = ((TraceObject*)g)->functions(); -+ break; -+ case TraceItem::Class: -+ list = ((TraceClass*)g)->functions(); -+ break; -+ case TraceItem::File: -+ list = ((TraceFile*)g)->functions(); -+ break; -+ case TraceItem::FunctionCycle: -+ list = ((TraceFunctionCycle*)g)->members(); -+ break; -+ default: -+ return; -+ } -+ -+ // switching off TQListView updates is buggy with some QT versions... -+ //functionList->setUpdatesEnabled(false); -+ -+ functionList->clear(); -+ setCostColumnWidths(); -+ -+ double total; -+ if (Configuration::showExpanded()) -+ total = (double) g->subCost(_costType); -+ else -+ total = (double) _data->subCost(_costType); -+#if 0 -+ if (total == 0.0) { -+ functionList->setUpdatesEnabled(true); -+ functionList->repaint(); -+ return; -+ } -+#endif -+ -+ TQRegExp re(_searchString, false, true); -+ -+ FunctionItem* fitem = 0; -+ TraceFunction *f; -+ _hc.clear(Configuration::maxListCount()); -+ for (f=list.first();f;f=list.next()) { -+ if (re.search(f->prettyName())<0) continue; -+ -+ _hc.addCost(f, f->inclusive()->subCost(_costType)); -+ if (_activeItem == f) -+ fitem = new FunctionItem(functionList, (TraceFunction*)_activeItem, -+ _costType, _groupType); -+ } -+ -+ for(int i=0;i<_hc.realCount();i++) { -+ if (_activeItem == (TraceFunction*)_hc[i]) continue; -+ new FunctionItem(functionList, (TraceFunction*)_hc[i], -+ _costType, _groupType); -+ } -+ -+ if (_hc.hasMore()) { -+ // a placeholder for all the functions skipped ... -+ new FunctionItem(functionList, _hc.count() - _hc.maxSize(), -+ (TraceFunction*)_hc[_hc.maxSize()-1], _costType); -+ } -+ functionList->sort(); -+ -+ if (fitem) { -+ functionList->ensureItemVisible(fitem); -+ _inSetFunction = true; -+ functionList->setSelected(fitem, true); -+ _inSetFunction = false; -+ } -+ -+ //functionList->setUpdatesEnabled(true); -+ //functionList->repaint(); -+ -+ // Don't emit signal if cost item was changed programatically -+ if (!_inSetGroup) { -+ _selectedItem = g; -+ selected(g); -+ } -+} -+ -+void FunctionSelection::groupDoubleClicked(TQListViewItem* i) -+{ -+ if (!i) return; -+ if (!_data) return; -+ TraceCostItem* g = ((CostListItem*) i)->costItem(); -+ -+ if (!g) return; -+ // group must be selected first -+ if (g != _group) return; -+ -+ activated(g); -+} -+ -+ -+TraceCostItem* FunctionSelection::group(TQString s) -+{ -+ TQListViewItem *item; -+ item = groupList->firstChild(); -+ for(;item;item = item->nextSibling()) -+ if (((CostListItem*)item)->costItem()->name() == s) -+ return ((CostListItem*)item)->costItem(); -+ -+ return 0; -+} -+ -+ -+ -+void FunctionSelection::functionSelected(TQListViewItem* i) -+{ -+ if (!i) return; -+ if (!_data) return; -+ -+ TraceFunction* f = ((FunctionItem*) i)->function(); -+ if (!f) return; -+ -+ //qDebug("FunctionSelection::functionSelected %s", f->name().ascii()); -+ -+ // Don't emit signal if function was changed programatically -+ if (!_inSetFunction) { -+ _selectedItem = f; -+ selected(f); -+ } -+} -+ -+void FunctionSelection::functionActivated(TQListViewItem* i) -+{ -+ if (!i) return; -+ if (!_data) return; -+ TraceFunction* f = ((FunctionItem*) i)->function(); -+ -+ if (!f) return; -+ -+ if (!_inSetFunction) -+ activated(f); -+} -+ -+void FunctionSelection::updateGroupSizes(bool hideEmpty) -+{ -+ TQListViewItem* item = groupList->firstChild(); -+ for (;item;item = item->nextSibling()) { -+ CostListItem* i = (CostListItem*)item; -+ int size = (_groupSize.contains(i->costItem())) ? -+ _groupSize[i->costItem()] : -1; -+ i->setSize(size); -+ i->setVisible(!hideEmpty || (size>0)); -+ } -+} -+ -+void FunctionSelection::query(TQString query) -+{ -+ if (searchEdit->text() != query) -+ searchEdit->setText(query); -+ if (_searchString == query) { -+ // when resetting query, get rid of group sizes -+ if (query.isEmpty()) { -+ _groupSize.clear(); -+ updateGroupSizes(false); -+ } -+ return; -+ } -+ _searchString = query; -+ -+ TQRegExp re(query, false, true); -+ _groupSize.clear(); -+ -+ TraceFunction* f = 0; -+ TraceFunctionList list2; -+ -+ _hc.clear(Configuration::maxListCount()); -+ -+ TraceFunctionMap::Iterator it; -+ for ( it = _data->functionMap().begin(); -+ it != _data->functionMap().end(); ++it ) { -+ f = &(*it); -+ if (re.search(f->prettyName())>=0) { -+ if (_group) { -+ if (_groupType==TraceItem::Object) { -+ if (_groupSize.contains(f->object())) -+ _groupSize[f->object()]++; -+ else -+ _groupSize[f->object()] = 1; -+ if (f->object() != _group) continue; -+ } -+ else if (_groupType==TraceItem::Class) { -+ if (_groupSize.contains(f->cls())) -+ _groupSize[f->cls()]++; -+ else -+ _groupSize[f->cls()] = 1; -+ if (f->cls() != _group) continue; -+ } -+ else if (_groupType==TraceItem::File) { -+ if (_groupSize.contains(f->file())) -+ _groupSize[f->file()]++; -+ else -+ _groupSize[f->file()] = 1; -+ if (f->file() != _group) continue; -+ } -+ else if (_groupType==TraceItem::FunctionCycle) { -+ if (_groupSize.contains(f->cycle())) -+ _groupSize[f->cycle()]++; -+ else -+ _groupSize[f->cycle()] = 1; -+ if (f->cycle() != _group) continue; -+ } -+ } -+ _hc.addCost(f, f->inclusive()->subCost(_costType)); -+ } -+ } -+ -+ updateGroupSizes(true); -+ -+ FunctionItem *fi, *item = 0; -+ -+ functionList->clear(); -+ setCostColumnWidths(); -+ -+ for(int i=0;i<_hc.realCount();i++) { -+ fi = new FunctionItem(functionList, (TraceFunction*)_hc[i], -+ _costType, _groupType); -+ if (_activeItem == f) item = fi; -+ } -+ if (_hc.hasMore()) { -+ // a placeholder for all the functions skipped ... -+ new FunctionItem(functionList, _hc.count() - _hc.maxSize(), -+ (TraceFunction*)_hc[_hc.maxSize()-1], _costType); -+ } -+ -+ functionList->sort(); -+ -+ -+ if (item) { -+ functionList->ensureItemVisible(item); -+ _inSetFunction = true; -+ functionList->setSelected(item, true); -+ _inSetFunction = false; -+ } -+ else { -+ // this emits a function selection -+ functionList->setSelected(functionList->firstChild(), true); -+ } -+} -+ -+bool FunctionSelection::setTopFunction() -+{ -+ TQListViewItem* i = functionList->firstChild(); -+ // this emits a function selection -+ functionList->setSelected(i, true); -+ functionActivated(i); -+ return i!=0; -+} -+ -+void FunctionSelection::setCostColumnWidths() -+{ -+ if (_costType && (_costType->subCost(_data->callMax())>0) ) { -+ functionList->setColumnWidthMode(0, TQListView::Maximum); -+ functionList->setColumnWidth(0,50); -+ functionList->setColumnWidthMode(2, TQListView::Maximum); -+ functionList->setColumnWidth(2,50); -+ } -+ else { -+ functionList->setColumnWidthMode(0, TQListView::Manual); -+ functionList->setColumnWidth(0,0); -+ functionList->setColumnWidthMode(2, TQListView::Manual); -+ functionList->setColumnWidth(2,0); -+ } -+ -+ functionList->setColumnWidth(1, 50); -+} -+ -+ -+ -+#include "functionselection.moc" -diff --git a/kdecachegrind/kdecachegrind/functionselection.h b/kdecachegrind/kdecachegrind/functionselection.h -new file mode 100644 -index 0000000..c5f7810 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/functionselection.h -@@ -0,0 +1,86 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * For function selection, to be put into a TQDockWindow -+ */ -+ -+#ifndef FUNCTIONSELECTION_H -+#define FUNCTIONSELECTION_H -+ -+#include "functionselectionbase.h" -+#include "traceitemview.h" -+#include "tracedata.h" -+#include "listutils.h" -+ -+class TQPopupMenu; -+ -+class TraceFunction; -+class TraceData; -+class StackBrowser; -+class NestedAreaItem; -+ -+class FunctionSelection : public FunctionSelectionBase, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ FunctionSelection( TopLevel*, TQWidget* parent = 0, const char* name = 0); -+ ~FunctionSelection(); -+ -+ TraceCostItem* group(TQString); -+ void setGroup(TraceCostItem*); -+ void query(TQString); -+ bool setTopFunction(); -+ -+ TQWidget* widget() { return this; } -+ -+ void addGroupMenu(TQPopupMenu*); -+ -+public slots: -+ void searchReturnPressed(); -+ void searchChanged(const TQString&); -+ void queryDelayed(); -+ void groupDoubleClicked( TQListViewItem* ); -+ void functionActivated( TQListViewItem* ); -+ void groupSelected( TQListViewItem* ); -+ void functionSelected( TQListViewItem* ); -+ void functionContext(TQListViewItem*, const TQPoint &, int); -+ void groupContext(TQListViewItem*, const TQPoint &, int); -+ -+private: -+ TraceItem* canShow(TraceItem* i); -+ void doUpdate(int); -+ void selectFunction(); -+ void refresh(); -+ void setCostColumnWidths(); -+ void updateGroupSizes(bool hideEmpty); -+ -+ TraceCostItem* _group; -+ -+ TQString _searchString, _searchDelayed; -+ TQTimer _searchTimer; -+ TQMap _groupSize; -+ -+ HighestCostList _hc; -+ // when setting a -+ bool _inSetGroup, _inSetFunction; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/functionselectionbase.ui b/kdecachegrind/kdecachegrind/functionselectionbase.ui -new file mode 100644 -index 0000000..eec019d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/functionselectionbase.ui -@@ -0,0 +1,163 @@ -+ -+FunctionSelectionBase -+ -+ -+ FunctionSelectionBase -+ -+ -+ -+ 0 -+ 0 -+ 223 -+ 485 -+ -+ -+ -+ Function Profile -+ -+ -+ -+ unnamed -+ -+ -+ 3 -+ -+ -+ 6 -+ -+ -+ -+ layout1 -+ -+ -+ -+ unnamed -+ -+ -+ -+ searchLabel -+ -+ -+ &Search: -+ -+ -+ searchEdit -+ -+ -+ -+ -+ searchEdit -+ -+ -+ -+ -+ groupBox -+ -+ -+ -+ -+ -+ -+ -+ Self -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Group -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ groupList -+ -+ -+ -+ 7 -+ 5 -+ 0 -+ 0 -+ -+ -+ -+ -+ 32767 -+ 150 -+ -+ -+ -+ -+ -+ -+ Incl. -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Self -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Called -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Function -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Location -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ functionList -+ -+ -+ -+ -+ -+ -diff --git a/kdecachegrind/kdecachegrind/hi32-app-kcachegrind.png b/kdecachegrind/kdecachegrind/hi32-app-kcachegrind.png -new file mode 100644 -index 0000000..bd41dae -Binary files /dev/null and b/kdecachegrind/kdecachegrind/hi32-app-kcachegrind.png differ -diff --git a/kdecachegrind/kdecachegrind/hi48-app-kcachegrind.png b/kdecachegrind/kdecachegrind/hi48-app-kcachegrind.png -new file mode 100644 -index 0000000..58c2efd -Binary files /dev/null and b/kdecachegrind/kdecachegrind/hi48-app-kcachegrind.png differ -diff --git a/kdecachegrind/kdecachegrind/instritem.cpp b/kdecachegrind/kdecachegrind/instritem.cpp -new file mode 100644 -index 0000000..ce5e81b ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/instritem.cpp -@@ -0,0 +1,469 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of instruction view. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "listutils.h" -+#include "instritem.h" -+#include "instrview.h" -+ -+ -+// InstrItem -+ -+// for messages -+InstrItem::InstrItem(InstrView* iv, TQListView* parent, -+ Addr addr, const TQString& msg) -+ : TQListViewItem(parent) -+{ -+ _view = iv; -+ _addr = addr; -+ _instr = 0; -+ _instrCall = 0; -+ _instrJump = 0; -+ _inside = false; -+ -+ setText(0, addr.pretty()); -+ setText(6, msg); -+ -+ updateGroup(); -+ updateCost(); -+} -+ -+// for code lines -+InstrItem::InstrItem(InstrView* iv, TQListView* parent, -+ Addr addr, bool inside, -+ const TQString& code, const TQString& cmd, -+ const TQString& args, TraceInstr* instr) -+ : TQListViewItem(parent) -+{ -+ _view = iv; -+ _addr = addr; -+ _instr = instr; -+ _instrCall = 0; -+ _instrJump = 0; -+ _inside = inside; -+ -+ if (args == "...") -+ setText(0, args); -+ else -+ setText(0, addr.pretty()); -+ setText(4, code); -+ setText(5, cmd); -+ setText(6, args); -+ -+ TraceLine* l; -+ if (instr && (l = instr->line())) -+ setText(7, l->name()); -+ -+ updateGroup(); -+ updateCost(); -+} -+ -+// for call lines -+InstrItem::InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr, -+ TraceInstr* instr, TraceInstrCall* instrCall) -+ : TQListViewItem(parent) -+{ -+ _view = iv; -+ _addr = addr; -+ _instr = instr; -+ _instrCall = instrCall; -+ _instrJump = 0; -+ _inside = true; -+ -+ //qDebug("InstrItem: (file %d, line %d) Linecall to %s", -+ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii()); -+ -+ SubCost cc = _instrCall->callCount(); -+ TQString templ = " "; -+ if (cc==0) -+ templ += i18n("Active call to '%1'"); -+ else -+ templ += i18n("%n call to '%1'", "%n calls to '%1'", cc); -+ -+ TQString callStr = templ.arg(_instrCall->call()->calledName()); -+ TraceFunction* calledF = _instrCall->call()->called(); -+ calledF->addPrettyLocation(callStr); -+ -+ setText(6, callStr); -+ -+ updateGroup(); -+ updateCost(); -+} -+ -+// for jump lines -+InstrItem::InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr, -+ TraceInstr* instr, TraceInstrJump* instrJump) -+ : TQListViewItem(parent) -+{ -+ _view = iv; -+ _addr = addr; -+ _inside = true; -+ _instr = instr; -+ _instrCall = 0; -+ _instrJump = instrJump; -+ -+ //qDebug("SourceItem: (file %d, line %d) Linecall to %s", -+ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii()); -+ -+ TQString jStr; -+ if (_instrJump->isCondJump()) -+ jStr = i18n("Jump %1 of %2 times to 0x%3") -+ .arg(_instrJump->followedCount().pretty()) -+ .arg(_instrJump->executedCount().pretty()) -+ .arg(_instrJump->instrTo()->addr().toString()); -+ else -+ jStr = i18n("Jump %1 times to 0x%2") -+ .arg(_instrJump->executedCount().pretty()) -+ .arg(_instrJump->instrTo()->addr().toString()); -+ -+ setText(6, jStr); -+ -+ updateGroup(); -+ updateCost(); -+} -+ -+ -+void InstrItem::updateGroup() -+{ -+ if (!_instrCall) return; -+ -+ TraceFunction* f = _instrCall->call()->called(); -+ TQColor c = Configuration::functionColor(_view->groupType(), f); -+ setPixmap(6, colorPixmap(10, 10, c)); -+} -+ -+void InstrItem::updateCost() -+{ -+ _pure = SubCost(0); -+ _pure2 = SubCost(0); -+ -+ if (!_instr) return; -+ if (_instrJump) return; -+ -+ TraceCost* instrCost = _instrCall ? -+ (TraceCost*)_instrCall : (TraceCost*)_instr; -+ -+ // don't show any cost inside of cycles -+ if (_instrCall && -+ ((_instrCall->call()->inCycle()>0) || -+ (_instrCall->call()->isRecursion()>0))) { -+ TQString str; -+ TQPixmap p; -+ -+ TQString icon = "undo"; -+ KIconLoader* loader = KApplication::kApplication()->iconLoader(); -+ p= loader->loadIcon(icon, KIcon::Small, 0, -+ KIcon::DefaultState, 0, true); -+ if (p.isNull()) -+ str = i18n("(cycle)"); -+ -+ setText(1, str); -+ setPixmap(1, p); -+ setText(2, str); -+ setPixmap(2, p); -+ return; -+ } -+ -+ TraceCost* totalCost; -+ if (Configuration::showExpanded()) -+ totalCost = _instr->function()->inclusive(); -+ else -+ totalCost = _instr->function()->data(); -+ -+ TraceCostType *ct = _view->costType(); -+ _pure = ct ? instrCost->subCost(ct) : SubCost(0); -+ if (_pure == 0) { -+ setText(1, TQString()); -+ setPixmap(1, TQPixmap()); -+ } -+ else { -+ double total = totalCost->subCost(ct); -+ double pure = 100.0 * _pure / total; -+ -+ if (Configuration::showPercentage()) -+ setText(1, TQString("%1") -+ .arg(pure, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(1, _pure.pretty()); -+ -+ setPixmap(1, costPixmap(ct, instrCost, total, false)); -+ } -+ -+ TraceCostType *ct2 = _view->costType2(); -+ _pure2 = ct2 ? instrCost->subCost(ct2) : SubCost(0); -+ if (_pure2 == 0) { -+ setText(2, TQString()); -+ setPixmap(2, TQPixmap()); -+ } -+ else { -+ double total = totalCost->subCost(ct2); -+ double pure = 100.0 * _pure2 / total; -+ -+ if (Configuration::showPercentage()) -+ setText(2, TQString("%1") -+ .arg(pure, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(2, _pure2.pretty()); -+ -+ setPixmap(2, costPixmap(ct2, instrCost, total, false)); -+ } -+} -+ -+ -+int InstrItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ const InstrItem* ii1 = this; -+ const InstrItem* ii2 = (InstrItem*) i; -+ -+ // we always want descending order -+ if (((col>0) && ascending) || -+ ((col==0) && !ascending) ) { -+ ii1 = ii2; -+ ii2 = this; -+ } -+ -+ if (col==1) { -+ if (ii1->_pure < ii2->_pure) return -1; -+ if (ii1->_pure > ii2->_pure) return 1; -+ return 0; -+ } -+ if (col==2) { -+ if (ii1->_pure2 < ii2->_pure2) return -1; -+ if (ii1->_pure2 > ii2->_pure2) return 1; -+ return 0; -+ } -+ if (col==0) { -+ if (ii1->_addr < ii2->_addr) return -1; -+ if (ii1->_addr > ii2->_addr) return 1; -+ -+ // Same address: code gets above calls/jumps -+ if (!ii1->_instrCall && !ii1->_instrJump) return -1; -+ if (!ii2->_instrCall && !ii2->_instrJump) return 1; -+ -+ // calls above jumps -+ if (ii1->_instrCall && !ii2->_instrCall) return -1; -+ if (ii2->_instrCall && !ii1->_instrCall) return 1; -+ -+ if (ii1->_instrCall && ii2->_instrCall) { -+ // Two calls: desending sort according costs -+ if (ii1->_pure < ii2->_pure) return 1; -+ if (ii1->_pure > ii2->_pure) return -1; -+ -+ // Two calls: sort according function names -+ TraceFunction* f1 = ii1->_instrCall->call()->called(); -+ TraceFunction* f2 = ii2->_instrCall->call()->called(); -+ if (f1->prettyName() > f2->prettyName()) return 1; -+ return -1; -+ } -+ -+ // Two jumps: descending sort according target address -+ if (ii1->_instrJump->instrTo()->addr() < -+ ii2->_instrJump->instrTo()->addr()) -+ return -1; -+ if (ii1->_instrJump->instrTo()->addr() > -+ ii2->_instrJump->instrTo()->addr()) -+ return 1; -+ return 0; -+ -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -+void InstrItem::paintCell( TQPainter *p, const TQColorGroup &cg, -+ int column, int width, int alignment ) -+{ -+ TQColorGroup _cg( cg ); -+ -+ if ( !_inside || ((column==1) || column==2)) -+ _cg.setColor( TQColorGroup::Base, cg.button() ); -+ else if ((_instrCall || _instrJump) && column>2) -+ _cg.setColor( TQColorGroup::Base, cg.midlight() ); -+ -+ if (column == 3) -+ paintArrows(p, _cg, width); -+ else -+ TQListViewItem::paintCell( p, _cg, column, width, alignment ); -+} -+ -+void InstrItem::setJumpArray(const TQMemArray& a) -+{ -+ _jump.duplicate(a); -+} -+ -+void InstrItem::paintArrows(TQPainter *p, const TQColorGroup &cg, int width) -+{ -+ TQListView *lv = listView(); -+ if ( !lv ) return; -+ InstrView* iv = (InstrView*) lv; -+ -+ const BackgroundMode bgmode = lv->viewport()->backgroundMode(); -+ const TQColorGroup::ColorRole crole -+ = TQPalette::backgroundRoleFromMode( bgmode ); -+ if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) ) -+ p->fillRect( 0, 0, width, height(), cg.brush( crole ) ); -+ else -+ iv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) ); -+ -+ if ( isSelected() && lv->allColumnsShowFocus() ) -+ p->fillRect( 0, 0, width, height(), cg.brush( TQColorGroup::Highlight ) ); -+ -+ int marg = lv->itemMargin(); -+ int yy = height()/2, y1, y2; -+ TQColor c; -+ -+ int start = -1, end = -1; -+ -+ // draw line borders, detect start/stop of a line -+ for(int i=0;i< (int)_jump.size();i++) { -+ if (_jump[i] == 0) continue; -+ -+ y1 = 0; -+ y2 = height(); -+ if ((_instrJump == _jump[i]) && -+ (_jump[i]->instrFrom()->addr() == _addr)) { -+ -+ //kdDebug() << "InstrItem " << _addr.toString() << ": start " << i << endl; -+ if (start<0) start = i; -+ if (_jump[i]->instrTo()->addr() <= _addr) -+ y2 = yy; -+ else -+ y1 = yy; -+ } -+ else if (!_instrJump && !_instrCall && -+ (_jump[i]->instrTo()->addr() == _addr)) { -+ -+ //kdDebug() << "InstrItem " << _addr.toString() << ": end " << i << endl; -+ if (end<0) end = i; -+ if (_jump[i]->instrFrom()->addr() < _addr) -+ y2 = yy; -+ else -+ y1 = yy; -+ } -+ -+ c = _jump[i]->isCondJump() ? red : blue; -+#if 0 -+ if (_jump[i] == ((TraceItemView*)_view)->selectedItem()) { -+ p->fillRect( marg + 6*i-2, (y1==0) ? y1: y1-2, -+ 8, (y2-y1==height())? y2:y2+2, -+ cg.brush( TQColorGroup::Highlight ) ); -+ c = lv->colorGroup().highlightedText(); -+ } -+#endif -+ p->fillRect( marg + 6*i, y1, 4, y2, c); -+ p->setPen(c.light()); -+ p->drawLine( marg + 6*i, y1, marg + 6*i, y2); -+ p->setPen(c.dark()); -+ p->drawLine( marg + 6*i +3, y1, marg + 6*i +3, y2); -+ } -+ -+ // draw start/stop horizontal line -+ int x, y = yy-2, w, h = 4; -+ if (start >= 0) { -+#if 0 -+ if (_jump[start] == ((TraceItemView*)_view)->selectedItem()) { -+ c = lv->colorGroup().highlightedText(); -+ } -+#endif -+ c = _jump[start]->isCondJump() ? red : blue; -+ x = marg + 6*start; -+ w = 6*(iv->arrowLevels() - start) + 10; -+ p->fillRect( x, y, w, h, c); -+ p->setPen(c.light()); -+ p->drawLine(x, y, x+w-1, y); -+ p->drawLine(x, y, x, y+h-1); -+ p->setPen(c.dark()); -+ p->drawLine(x+w-1, y, x+w-1, y+h-1); -+ p->drawLine(x+1, y+h-1, x+w-1, y+h-1); -+ } -+ if (end >= 0) { -+ c = _jump[end]->isCondJump() ? red : blue; -+ x = marg + 6*end; -+ w = 6*(iv->arrowLevels() - end) + 10; -+ -+ TQPointArray a; -+ a.putPoints(0, 7, x, y+h, -+ x,y, x+w-8, y, x+w-8, y-2, -+ x+w, yy, -+ x+w-8, y+h+2, x+w-8, y+h); -+ p->setBrush(c); -+ p->drawConvexPolygon(a); -+ -+ p->setPen(c.light()); -+ p->drawPolyline(a, 0, 5); -+ p->setPen(c.dark()); -+ p->drawPolyline(a, 4, 2); -+ p->setPen(c.light()); -+ p->drawPolyline(a, 5, 2); -+ p->setPen(c.dark()); -+ p->drawPolyline(a, 6, 2); -+ } -+ -+ // draw inner vertical line for start/stop -+ // this overwrites borders of horizontal line -+ for(int i=0;i< (int)_jump.size();i++) { -+ if (_jump[i] == 0) continue; -+ -+ c = _jump[i]->isCondJump() ? red : blue; -+ -+ if (_jump[i]->instrFrom()->addr() == _addr) { -+ bool drawUp = true; -+ if (_jump[i]->instrTo()->addr() == _addr) -+ if (start<0) drawUp=false; -+ if (_jump[i]->instrTo()->addr() > _addr) drawUp=false; -+ if (drawUp) -+ p->fillRect( marg + 6*i +1, 0, 2, yy, c); -+ else -+ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c); -+ } -+ else if (_jump[i]->instrTo()->addr() == _addr) { -+ if (end<0) end = i; -+ if (_jump[i]->instrFrom()->addr() < _addr) -+ p->fillRect( marg + 6*i +1, 0, 2, yy, c); -+ else -+ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c); -+ } -+ } -+ -+} -+ -+int InstrItem::width( const TQFontMetrics& fm, -+ const TQListView* lv, int c ) const -+{ -+ if (c != 3) return TQListViewItem::width(fm, lv, c); -+ -+ InstrView* iv = (InstrView*) lv; -+ int levels = iv->arrowLevels(); -+ -+ if (levels == 0) return 0; -+ -+ // 10 pixels for the arrow -+ return 10 + 6*levels + lv->itemMargin() * 2; -+} -+ -diff --git a/kdecachegrind/kdecachegrind/instritem.h b/kdecachegrind/kdecachegrind/instritem.h -new file mode 100644 -index 0000000..2bbce71 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/instritem.h -@@ -0,0 +1,86 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of instruction view. -+ */ -+ -+#ifndef INSTRITEM_H -+#define INSTRITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class InstrView; -+ -+class InstrItem: public TQListViewItem -+{ -+ -+public: -+ // for messages -+ InstrItem(InstrView* iv, TQListView* parent, -+ Addr addr, const TQString&); -+ -+ // for instruction lines -+ InstrItem(InstrView* iv, TQListView* parent, -+ Addr addr, bool inside, -+ const TQString&, const TQString&, const TQString&, -+ TraceInstr* instr); -+ -+ // for call instr -+ InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr, -+ TraceInstr* instr, TraceInstrCall* instrCall); -+ -+ // for jump lines -+ InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr, -+ TraceInstr* instr, TraceInstrJump* instrJump); -+ -+ Addr addr() const { return _addr; } -+ TraceInstr* instr() const { return _instr; } -+ TraceInstrCall* instrCall() const { return _instrCall; } -+ TraceInstrJump* instrJump() const { return _instrJump; } -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ -+ void paintCell(TQPainter *p, const TQColorGroup &cg, -+ int column, int width, int alignment ); -+ int width( const TQFontMetrics& fm, -+ const TQListView* lv, int c ) const; -+ -+ void updateGroup(); -+ void updateCost(); -+ -+ // arrow lines -+ void setJumpArray(const TQMemArray& a); -+ -+protected: -+ void paintArrows(TQPainter *p, const TQColorGroup &cg, int width); -+ TQMemArray _jump; -+ -+private: -+ InstrView* _view; -+ SubCost _pure, _pure2; -+ Addr _addr; -+ TraceInstr* _instr; -+ TraceInstrJump* _instrJump; -+ TraceInstrCall* _instrCall; -+ bool _inside; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/instrview.cpp b/kdecachegrind/kdecachegrind/instrview.cpp -new file mode 100644 -index 0000000..3df1679 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/instrview.cpp -@@ -0,0 +1,949 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Instruction View -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "instritem.h" -+#include "instrview.h" -+ -+// InstrView defaults -+ -+#define DEFAULT_SHOWHEXCODE true -+ -+ -+// Helpers for parsing output of 'objdump' -+ -+static Addr parseAddr(char* buf) -+{ -+ Addr addr; -+ uint pos = 0; -+ -+ // check for instruction line: * ":" * -+ while(buf[pos]==' ' || buf[pos]=='\t') pos++; -+ -+ int digits = addr.set(buf + pos); -+ if ((digits==0) || (buf[pos+digits] != ':')) return Addr(0); -+ -+ return addr; -+} -+ -+ -+static bool parseLine(char* buf, Addr& addr, -+ uint& pos1, uint& pos2, uint& pos3) -+{ -+ // check for instruction line: * ":" * -+ -+ pos1 = 0; -+ while(buf[pos1]==' ' || buf[pos1]=='\t') pos1++; -+ -+ int digits = addr.set(buf + pos1); -+ pos1 += digits; -+ if ((digits==0) || (buf[pos1] != ':')) return false; -+ -+ // further parsing of objdump output... -+ pos1++; -+ while(buf[pos1]==' ' || buf[pos1]=='\t') pos1++; -+ -+ // skip code, pattern "xx "* -+ pos2 = pos1; -+ while(1) { -+ if (! ((buf[pos2]>='0' && buf[pos2]<='9') || -+ (buf[pos2]>='a' && buf[pos2]<='f')) ) break; -+ if (! ((buf[pos2+1]>='0' && buf[pos2+1]<='9') || -+ (buf[pos2+1]>='a' && buf[pos2+1]<='f')) ) break; -+ if (buf[pos2+2] != ' ') break; -+ pos2 += 3; -+ } -+ buf[pos2-1]=0; -+ while(buf[pos2]==' '|| buf[pos2]=='\t') pos2++; -+ -+ // skip mnemonic -+ pos3 = pos2; -+ while(buf[pos3] && buf[pos3]!=' ' && buf[pos3]!='\t') pos3++; -+ if (buf[pos3] != 0) { -+ buf[pos3] = 0; -+ pos3++; -+ while(buf[pos3]==' '|| buf[pos3]=='\t') pos3++; -+ } -+ -+ // maximal 50 chars -+ if (strlen(buf+pos2) > 50) -+ strcpy(buf+pos2+47, "..."); -+ -+ if (0) qDebug("For 0x%s: Code '%s', Mnc '%s', Args '%s'", -+ addr.toString().ascii(), buf+pos1, buf+pos2, buf+pos3); -+ -+ return true; -+} -+ -+ -+ -+ -+// -+// InstrView -+// -+ -+ -+InstrView::InstrView(TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQListView(parent, name), TraceItemView(parentView) -+{ -+ _showHexCode = DEFAULT_SHOWHEXCODE; -+ _lastHexCodeWidth = 50; -+ -+ _inSelectionUpdate = false; -+ _arrowLevels = 0; -+ _lowList.setSortLow(true); -+ _highList.setSortLow(false); -+ -+ addColumn( i18n( "#" ) ); -+ addColumn( i18n( "Cost" ) ); -+ addColumn( i18n( "Cost 2" ) ); -+ addColumn( "" ); -+ addColumn( i18n( "Hex" ) ); -+ addColumn( "" ); // Instruction -+ addColumn( i18n( "Assembler" ) ); -+ addColumn( i18n( "Source Position" ) ); -+ -+ setAllColumnsShowFocus(true); -+ setColumnAlignment(1, TQt::AlignRight); -+ setColumnAlignment(2, TQt::AlignRight); -+ -+ connect(this, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int))); -+ -+ connect(this, TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ TQT_SLOT(selectedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(doubleClicked(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ TQWhatsThis::add( this, whatsThis()); -+} -+ -+void InstrView::paintEmptyArea( TQPainter * p, const TQRect & r) -+{ -+ TQListView::paintEmptyArea(p, r); -+} -+ -+TQString InstrView::whatsThis() const -+{ -+ return i18n( "Annotated Assembler" -+ "

The annotated assembler list shows the " -+ "machine code instructions of the current selected " -+ "function together with (self) cost spent while " -+ "executing an instruction. If this is a call " -+ "instruction, lines with details on the " -+ "call happening are inserted into the source: " -+ "the cost spent inside of the call, the " -+ "number of calls happening, and the call destination.

" -+ "

The disassembler output shown is generated with " -+ "the 'objdump' utility from the 'binutils' package.

" -+ "

Select a line with call information to " -+ "make the destination function of this call current.

"); -+} -+ -+void InstrView::context(TQListViewItem* i, const TQPoint & p, int c) -+{ -+ TQPopupMenu popup; -+ -+ TraceInstrCall* ic = i ? ((InstrItem*) i)->instrCall() : 0; -+ TraceInstrJump* ij = i ? ((InstrItem*) i)->instrJump() : 0; -+ TraceFunction* f = ic ? ic->call()->called() : 0; -+ TraceInstr* instr = ij ? ij->instrTo() : 0; -+ -+ if (f) { -+ TQString name = f->name(); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ popup.insertItem(i18n("Go to '%1'").arg(name), 93); -+ popup.insertSeparator(); -+ } -+ else if (instr) { -+ popup.insertItem(i18n("Go to Address %1").arg(instr->name()), 93); -+ popup.insertSeparator(); -+ } -+ -+ if ((c == 1) || (c == 2)) { -+ addCostMenu(&popup); -+ popup.insertSeparator(); -+ } -+ addGoMenu(&popup); -+ -+ popup.insertSeparator(); -+ popup.setCheckable(true); -+ popup.insertItem(i18n("Hex Code"), 94); -+ if (_showHexCode) popup.setItemChecked(94,true); -+ -+ int r = popup.exec(p); -+ if (r == 93) { -+ if (f) activated(f); -+ if (instr) activated(instr); -+ } -+ else if (r == 94) { -+ _showHexCode = !_showHexCode; -+ // remember width when hiding -+ if (!_showHexCode) -+ _lastHexCodeWidth = columnWidth(4); -+ setColumnWidths(); -+ } -+} -+ -+ -+void InstrView::selectedSlot(TQListViewItem * i) -+{ -+ if (!i) return; -+ // programatically selected items are not signalled -+ if (_inSelectionUpdate) return; -+ -+ TraceInstrCall* ic = ((InstrItem*) i)->instrCall(); -+ TraceInstrJump* ij = ((InstrItem*) i)->instrJump(); -+ -+ if (!ic && !ij) { -+ TraceInstr* instr = ((InstrItem*) i)->instr(); -+ if (instr) { -+ _selectedItem = instr; -+ selected(instr); -+ } -+ return; -+ } -+ -+ if (ic) { -+ _selectedItem = ic; -+ selected(ic); -+ } -+ else if (ij) { -+ _selectedItem = ij; -+ selected(ij); -+ } -+} -+ -+void InstrView::activatedSlot(TQListViewItem * i) -+{ -+ if (!i) return; -+ TraceInstrCall* ic = ((InstrItem*) i)->instrCall(); -+ TraceInstrJump* ij = ((InstrItem*) i)->instrJump(); -+ -+ if (!ic && !ij) { -+ TraceInstr* instr = ((InstrItem*) i)->instr(); -+ if (instr) activated(instr); -+ return; -+ } -+ -+ if (ic) { -+ TraceFunction* f = ic->call()->called(); -+ if (f) activated(f); -+ } -+ else if (ij) { -+ TraceInstr* instr = ij->instrTo(); -+ if (instr) activated(instr); -+ } -+} -+ -+ -+TraceItem* InstrView::canShow(TraceItem* i) -+{ -+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType; -+ TraceFunction* f = 0; -+ -+ switch(t) { -+ case TraceItem::Function: -+ f = (TraceFunction*) i; -+ break; -+ -+ case TraceItem::Instr: -+ f = ((TraceInstr*)i)->function(); -+ select(i); -+ break; -+ -+ case TraceItem::Line: -+ f = ((TraceLine*)i)->functionSource()->function(); -+ select(i); -+ break; -+ -+ default: -+ break; -+ } -+ -+ return f; -+} -+ -+ -+void InstrView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == selectedItemChanged) { -+ -+ if (!_selectedItem) { -+ clearSelection(); -+ return; -+ } -+ -+ InstrItem *ii = (InstrItem*)TQListView::selectedItem(); -+ if (ii) { -+ if ((ii->instr() == _selectedItem) || -+ (ii->instr() && (ii->instr()->line() == _selectedItem))) return; -+ } -+ -+ TQListViewItem *item, *item2; -+ for (item = firstChild();item;item = item->nextSibling()) { -+ ii = (InstrItem*)item; -+ if ((ii->instr() == _selectedItem) || -+ (ii->instr() && (ii->instr()->line() == _selectedItem))) { -+ ensureItemVisible(item); -+ _inSelectionUpdate = true; -+ setCurrentItem(item); -+ _inSelectionUpdate = false; -+ break; -+ } -+ item2 = item->firstChild(); -+ for (;item2;item2 = item2->nextSibling()) { -+ ii = (InstrItem*)item2; -+ if (!ii->instrCall()) continue; -+ if (ii->instrCall()->call()->called() == _selectedItem) { -+ ensureItemVisible(item2); -+ _inSelectionUpdate = true; -+ setCurrentItem(item2); -+ _inSelectionUpdate = false; -+ break; -+ } -+ } -+ if (item2) break; -+ } -+ return; -+ } -+ -+ if (changeType == groupTypeChanged) { -+ TQListViewItem *item, *item2; -+ for (item = firstChild();item;item = item->nextSibling()) -+ for (item2 = item->firstChild();item2;item2 = item2->nextSibling()) -+ ((InstrItem*)item2)->updateGroup(); -+ return; -+ } -+ -+ refresh(); -+} -+ -+void InstrView::setColumnWidths() -+{ -+ if (_showHexCode) { -+ setColumnWidthMode(4, TQListView::Maximum); -+ setColumnWidth(4, _lastHexCodeWidth); -+ } -+ else { -+ setColumnWidthMode(4, TQListView::Manual); -+ setColumnWidth(4, 0); -+ } -+} -+ -+void InstrView::refresh() -+{ -+ _arrowLevels = 0; -+ -+ // reset to automatic sizing to get column width -+ setColumnWidthMode(4, TQListView::Maximum); -+ -+ clear(); -+ setColumnWidth(0, 20); -+ setColumnWidth(1, 50); -+ setColumnWidth(2, _costType2 ? 50:0); -+ setColumnWidth(3, 0); // arrows, defaults to invisible -+ setColumnWidth(4, 0); // hex code column -+ setColumnWidth(5, 20); // command column -+ setColumnWidth(6, 200); // arg column -+ setSorting(0); // always reset to address number sort -+ if (_costType) -+ setColumnText(1, _costType->name()); -+ if (_costType2) -+ setColumnText(2, _costType2->name()); -+ -+ if (!_data || !_activeItem) return; -+ -+ TraceItem::CostType t = _activeItem->type(); -+ TraceFunction* f = 0; -+ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem; -+ if (t == TraceItem::Instr) { -+ f = ((TraceInstr*)_activeItem)->function(); -+ if (!_selectedItem) _selectedItem = _activeItem; -+ } -+ if (t == TraceItem::Line) { -+ f = ((TraceLine*)_activeItem)->functionSource()->function(); -+ if (!_selectedItem) _selectedItem = _activeItem; -+ } -+ -+ if (!f) return; -+ -+ // Allow resizing of column 2 -+ setColumnWidthMode(2, TQListView::Maximum); -+ -+ // check for instruction map -+ TraceInstrMap::Iterator itStart, it, tmpIt, itEnd; -+ TraceInstrMap* instrMap = f->instrMap(); -+ if (instrMap) { -+ it = instrMap->begin(); -+ itEnd = instrMap->end(); -+ // get first instruction with cost of selected type -+ while(it != itEnd) { -+ if ((*it).hasCost(_costType)) break; -+ if (_costType2 && (*it).hasCost(_costType2)) break; -+ ++it; -+ } -+ } -+ if (!instrMap || (it == itEnd)) { -+ new InstrItem(this, this, 1, -+ i18n("There is no instruction info in the profile data file.")); -+ new InstrItem(this, this, 2, -+ i18n("For the Valgrind Calltree Skin, rerun with option")); -+ new InstrItem(this, this, 3, i18n(" --dump-instr=yes")); -+ new InstrItem(this, this, 4, i18n("To see (conditional) jumps, additionally specify")); -+ new InstrItem(this, this, 5, i18n(" --trace-jump=yes")); -+ return; -+ } -+ -+ // initialisation for arrow drawing -+ // create sorted list of jumps (for jump arrows) -+ _lowList.clear(); -+ _highList.clear(); -+ itStart = it; -+ while(1) { -+ TraceInstrJumpList jlist = (*it).instrJumps(); -+ TraceInstrJump* ij; -+ for (ij=jlist.first();ij;ij=jlist.next()) { -+ if (ij->executedCount()==0) continue; -+ _lowList.append(ij); -+ _highList.append(ij); -+ } -+ ++it; -+ while(it != itEnd) { -+ if ((*it).hasCost(_costType)) break; -+ if (_costType2 && (*it).hasCost(_costType2)) break; -+ ++it; -+ } -+ if (it == itEnd) break; -+ } -+ _lowList.sort(); -+ _highList.sort(); -+ _lowList.first(); // iterators to list start -+ _highList.first(); -+ _arrowLevels = 0; -+ _jump.resize(0); -+ -+ -+ // do multiple calls to 'objdump' if there are large gaps in addresses -+ it = itStart; -+ while(1) { -+ itStart = it; -+ while(1) { -+ tmpIt = it; -+ ++it; -+ while(it != itEnd) { -+ if ((*it).hasCost(_costType)) break; -+ if (_costType2 && (*it).hasCost(_costType2)) break; -+ ++it; -+ } -+ if (it == itEnd) break; -+ if (!(*it).addr().isInRange( (*tmpIt).addr(),10000) ) break; -+ } -+ -+ // tmpIt is always last instruction with cost -+ if (!fillInstrRange(f, itStart, ++tmpIt)) break; -+ if (it == itEnd) break; -+ } -+ -+ _lastHexCodeWidth = columnWidth(4); -+ setColumnWidths(); -+ -+ if (!_costType2) { -+ setColumnWidthMode(2, TQListView::Manual); -+ setColumnWidth(2, 0); -+ } -+} -+ -+/* This is called after adding instrItems, for each of them in -+ * address order. _jump is the global array of valid jumps -+ * for a line while we iterate downwards. -+ * The existing jumps, sorted in lowList according lower address, -+ * is iterated in the same way. -+ */ -+void InstrView::updateJumpArray(Addr addr, InstrItem* ii, -+ bool ignoreFrom, bool ignoreTo) -+{ -+ TraceInstrJump* ij; -+ Addr lowAddr, highAddr; -+ int iEnd = -1, iStart = -1; -+ -+ if (0) qDebug("updateJumpArray(addr 0x%s, jump to %s)", -+ addr.toString().ascii(), -+ ii->instrJump() -+ ? ii->instrJump()->instrTo()->name().ascii() : "?" ); -+ -+ // check for new arrows starting from here downwards -+ ij=_lowList.current(); -+ while(ij) { -+ lowAddr = ij->instrFrom()->addr(); -+ if (ij->instrTo()->addr() < lowAddr) -+ lowAddr = ij->instrTo()->addr(); -+ -+ if (lowAddr > addr) break; -+ -+ // if target is downwards but we draw no source, break -+ if (ignoreFrom && (lowAddr < ij->instrTo()->addr())) break; -+ // if source is downward but we draw no target, break -+ if (ignoreTo && (lowAddr < ij->instrFrom()->addr())) break; -+ // if this is another jump start, break -+ if (ii->instrJump() && (ij != ii->instrJump())) break; -+ -+#if 0 -+ for(iStart=0;iStart<_arrowLevels;iStart++) -+ if (_jump[iStart] && -+ (_jump[iStart]->instrTo() == ij->instrTo())) break; -+#else -+ iStart = _arrowLevels; -+#endif -+ -+ if (iStart==_arrowLevels) { -+ for(iStart=0;iStart<_arrowLevels;iStart++) -+ if (_jump[iStart] == 0) break; -+ if (iStart==_arrowLevels) { -+ _arrowLevels++; -+ _jump.resize(_arrowLevels); -+ } -+ if (0) qDebug(" new start at %d for %s", iStart, ij->name().ascii()); -+ _jump[iStart] = ij; -+ } -+ ij=_lowList.next(); -+ } -+ -+ ii->setJumpArray(_jump); -+ -+ // check for active arrows ending here -+ ij=_highList.current(); -+ while(ij) { -+ highAddr = ij->instrFrom()->addr(); -+ if (ij->instrTo()->addr() > highAddr) { -+ highAddr = ij->instrTo()->addr(); -+ if (ignoreTo) break; -+ } -+ else if (ignoreFrom) break; -+ -+ if (highAddr > addr) break; -+ -+ for(iEnd=0;iEnd<_arrowLevels;iEnd++) -+ if (_jump[iEnd] == ij) break; -+ if (iEnd==_arrowLevels) { -+ kdDebug() << "InstrView: no jump start for end at 0x" -+ << highAddr.toString() << " ?" << endl; -+ iEnd = -1; -+ } -+ -+ if (0 && (iEnd>=0)) -+ qDebug(" end %d (%s to %s)", -+ iEnd, -+ _jump[iEnd]->instrFrom()->name().ascii(), -+ _jump[iEnd]->instrTo()->name().ascii()); -+ -+ if (0 && ij) qDebug("next end: %s to %s", -+ ij->instrFrom()->name().ascii(), -+ ij->instrTo()->name().ascii()); -+ -+ ij=_highList.next(); -+ if (highAddr > addr) -+ break; -+ else { -+ if (iEnd>=0) _jump[iEnd] = 0; -+ iEnd = -1; -+ } -+ } -+ if (iEnd>=0) _jump[iEnd] = 0; -+} -+ -+ -+ -+/** -+ * Fill up with instructions from cost range [it;itEnd[ -+ */ -+bool InstrView::fillInstrRange(TraceFunction* function, -+ TraceInstrMap::Iterator it, -+ TraceInstrMap::Iterator itEnd) -+{ -+ Addr costAddr, nextCostAddr, objAddr, addr; -+ Addr dumpStartAddr, dumpEndAddr; -+ TraceInstrMap::Iterator costIt; -+ -+ // shouldn't happen -+ if (it == itEnd) return false; -+ -+ // calculate address range for call to objdump -+ TraceInstrMap::Iterator tmpIt = itEnd; -+ --tmpIt; -+ nextCostAddr = (*it).addr(); -+ dumpStartAddr = (nextCostAddr<20) ? Addr(0) : nextCostAddr -20; -+ dumpEndAddr = (*tmpIt).addr() +20; -+ -+ // generate command -+ TQString popencmd, objfile; -+ objfile = function->object()->name(); -+ objfile = objfile.replace(TQRegExp("[\"']"), ""); // security... -+ popencmd = TQString("objdump -C -d " -+ "--start-address=0x%1 --stop-address=0x%2 \"%3\"") -+ .arg(dumpStartAddr.toString()).arg(dumpEndAddr.toString()) -+ .arg(objfile); -+ if (1) qDebug("Running '%s'...", popencmd.ascii()); -+ -+ // and run... -+ FILE* iFILE = popen(TQFile::encodeName( popencmd ), "r"); -+ if (iFILE == 0) { -+ new InstrItem(this, this, 1, -+ i18n("There is an error trying to execute the command")); -+ new InstrItem(this, this, 2, ""); -+ new InstrItem(this, this, 3, popencmd); -+ new InstrItem(this, this, 4, ""); -+ new InstrItem(this, this, 5, -+ i18n("Check that you have installed 'objdump'.")); -+ new InstrItem(this, this, 6, -+ i18n("This utility can be found in the 'binutils' package.")); -+ return false; -+ } -+ TQFile file; -+ file.open(IO_ReadOnly, iFILE); -+ -+#define BUF_SIZE 256 -+ -+ char buf[BUF_SIZE]; -+ bool inside = false, skipLineWritten = true; -+ int readBytes = -1; -+ int objdumpLineno = 0, dumpedLines = 0, noAssLines = 0; -+ SubCost most = 0; -+ TraceInstr* currInstr; -+ InstrItem *ii, *ii2, *item = 0, *first = 0, *selected = 0; -+ TQString code, cmd, args; -+ bool needObjAddr = true, needCostAddr = true; -+ -+ costAddr = 0; -+ objAddr = 0; -+ -+ while (1) { -+ -+ if (needObjAddr) { -+ needObjAddr = false; -+ -+ // read next objdump line -+ while (1) { -+ readBytes=file.readLine(buf, BUF_SIZE); -+ if (readBytes<=0) { -+ objAddr = 0; -+ break; -+ } -+ -+ objdumpLineno++; -+ if (readBytes == BUF_SIZE) { -+ qDebug("ERROR: Line %d of '%s' too long\n", -+ objdumpLineno, popencmd.ascii()); -+ } -+ else if ((readBytes>0) && (buf[readBytes-1] == '\n')) -+ buf[readBytes-1] = 0; -+ -+ objAddr = parseAddr(buf); -+ if ((objAddrdumpEndAddr)) -+ objAddr = 0; -+ if (objAddr != 0) break; -+ } -+ -+ if (0) kdDebug() << "Got ObjAddr: 0x" << objAddr.toString() << endl; -+ } -+ -+ // try to keep objAddr in [costAddr;nextCostAddr] -+ if (needCostAddr && -+ (nextCostAddr > 0) && -+ ((objAddr == Addr(0)) || (objAddr >= nextCostAddr)) ) { -+ needCostAddr = false; -+ -+ costIt = it; -+ ++it; -+ while(it != itEnd) { -+ if ((*it).hasCost(_costType)) break; -+ if (_costType2 && (*it).hasCost(_costType2)) break; -+ ++it; -+ } -+ costAddr = nextCostAddr; -+ nextCostAddr = (it == itEnd) ? Addr(0) : (*it).addr(); -+ -+ if (0) kdDebug() << "Got nextCostAddr: 0x" << nextCostAddr.toString() -+ << ", costAddr 0x" << costAddr.toString() << endl; -+ } -+ -+ // if we have no more address from objdump, stop -+ if (objAddr == 0) break; -+ -+ if ((nextCostAddr==0) || (costAddr == 0) || -+ (objAddr < nextCostAddr)) { -+ // next line is objAddr -+ -+ uint pos1, pos2, pos3; -+ -+ // this sets addr -+ parseLine(buf, addr, pos1, pos2, pos3); -+ code = TQString(buf + pos1); -+ cmd = TQString(buf + pos2); -+ args = TQString(buf + pos3); -+ -+ if (costAddr == objAddr) { -+ currInstr = &(*costIt); -+ needCostAddr = true; -+ } -+ else -+ currInstr = 0; -+ -+ needObjAddr = true; -+ -+ if (0) kdDebug() << "Dump Obj Addr: 0x" << addr.toString() -+ << " [" << cmd << " " << args << "], cost (0x" -+ << costAddr.toString() << ", next 0x" -+ << nextCostAddr.toString() << ")" << endl; -+ } -+ else { -+ addr = costAddr; -+ code = cmd = TQString(); -+ args = i18n("(No Assembler)"); -+ -+ currInstr = &(*costIt); -+ needCostAddr = true; -+ -+ noAssLines++; -+ if (0) kdDebug() << "Dump Cost Addr: 0x" << addr.toString() -+ << " (no ass), objAddr 0x" << objAddr.toString() << endl; -+ } -+ -+ // update inside -+ if (!inside) { -+ if (currInstr) inside = true; -+ } -+ else { -+ if (0) kdDebug() << "Check if 0x" << addr.toString() << " is in ]0x" -+ << costAddr.toString() << ",0x" -+ << (nextCostAddr - 3*Configuration::noCostInside()).toString() -+ << "[" << endl; -+ -+ // Suppose a average instruction len of 3 bytes -+ if ( (addr > costAddr) && -+ ((nextCostAddr==0) || -+ (addr < nextCostAddr - 3*Configuration::noCostInside()) )) -+ inside = false; -+ } -+ -+ int context = Configuration::context(); -+ -+ if ( ((costAddr==0) || (addr > costAddr + 3*context)) && -+ ((nextCostAddr==0) || (addr < nextCostAddr - 3*context)) ) { -+ -+ // the very last skipLine can be ommitted -+ if ((it == itEnd) && -+ (itEnd == function->instrMap()->end())) skipLineWritten=true; -+ -+ if (!skipLineWritten) { -+ skipLineWritten = true; -+ // a "skipping" line: print "..." instead of a line number -+ code = cmd = TQString(); -+ args = TQString("..."); -+ } -+ else -+ continue; -+ } -+ else -+ skipLineWritten = false; -+ -+ -+ ii = new InstrItem(this, this, addr, inside, -+ code, cmd, args, currInstr); -+ dumpedLines++; -+ if (0) kdDebug() << "Dumped 0x" << addr.toString() << " " -+ << (inside ? "Inside " : "Outside") -+ << (currInstr ? "Cost" : "") << endl; -+ -+ // no calls/jumps if we have no cost for this line -+ if (!currInstr) continue; -+ -+ if (!selected && -+ (currInstr == _selectedItem) || -+ (currInstr->line() == _selectedItem)) selected = ii; -+ -+ if (!first) first = ii; -+ -+ if (currInstr->subCost(_costType) > most) { -+ item = ii; -+ most = currInstr->subCost(_costType); -+ } -+ -+ ii->setOpen(true); -+ TraceInstrCallList list = currInstr->instrCalls(); -+ TraceInstrCall* ic; -+ for (ic=list.first();ic;ic=list.next()) { -+ if ((ic->subCost(_costType)==0) && -+ (ic->subCost(_costType2)==0)) continue; -+ -+ if (ic->subCost(_costType) > most) { -+ item = ii; -+ most = ic->subCost(_costType); -+ } -+ -+ ii2 = new InstrItem(this, ii, addr, currInstr, ic); -+ -+ if (!selected && (ic->call()->called() == _selectedItem)) -+ selected = ii2; -+ } -+ -+ TraceInstrJumpList jlist = currInstr->instrJumps(); -+ TraceInstrJump* ij; -+ for (ij=jlist.first();ij;ij=jlist.next()) { -+ if (ij->executedCount()==0) continue; -+ -+ new InstrItem(this, ii, addr, currInstr, ij); -+ } -+ } -+ -+ if (selected) item = selected; -+ if (item) first = item; -+ if (first) { -+ ensureItemVisible(first); -+ _inSelectionUpdate = true; -+ setCurrentItem(first); -+ _inSelectionUpdate = false; -+ } -+ -+ file.close(); -+ pclose(iFILE); -+ -+ // for arrows: go down the list according to list sorting -+ sort(); -+ TQListViewItem *item1, *item2; -+ for (item1=firstChild();item1;item1 = item1->nextSibling()) { -+ ii = (InstrItem*)item1; -+ updateJumpArray(ii->addr(), ii, true, false); -+ -+ for (item2=item1->firstChild();item2;item2 = item2->nextSibling()) { -+ ii2 = (InstrItem*)item2; -+ if (ii2->instrJump()) -+ updateJumpArray(ii->addr(), ii2, false, true); -+ else -+ ii2->setJumpArray(_jump); -+ } -+ } -+ -+ if (arrowLevels()) -+ setColumnWidth(3, 10 + 6*arrowLevels() + itemMargin() * 2); -+ else -+ setColumnWidth(3, 0); -+ -+ -+ if (noAssLines > 1) { -+ // trace cost not machting code -+ -+ new InstrItem(this, this, 1, -+ i18n("There is %n cost line without assembler code.", -+ "There are %n cost lines without assembler code.", noAssLines)); -+ new InstrItem(this, this, 2, -+ i18n("This happens because the code of")); -+ new InstrItem(this, this, 3, TQString(" %1").arg(objfile)); -+ new InstrItem(this, this, 4, -+ i18n("does not seem to match the profile data file.")); -+ new InstrItem(this, this, 5, ""); -+ new InstrItem(this, this, 6, -+ i18n("Are you using an old profile data file or is the above mentioned")); -+ new InstrItem(this, this, 7, -+ i18n("ELF object from an updated installation/another machine?")); -+ new InstrItem(this, this, 8, ""); -+ return false; -+ } -+ -+ if (dumpedLines == 0) { -+ // no matching line read from popen -+ new InstrItem(this, this, 1, -+ i18n("There seems to be an error trying to execute the command")); -+ new InstrItem(this, this, 2, ""); -+ new InstrItem(this, this, 3, popencmd); -+ new InstrItem(this, this, 4, ""); -+ new InstrItem(this, this, 5, -+ i18n("Check that the ELF object used in the command exists.")); -+ new InstrItem(this, this, 6, -+ i18n("Check that you have installed 'objdump'.")); -+ new InstrItem(this, this, 7, -+ i18n("This utility can be found in the 'binutils' package.")); -+ return false; -+ } -+ -+ return true; -+} -+ -+ -+void InstrView::updateInstrItems() -+{ -+ InstrItem* ii; -+ TQListViewItem* item = firstChild(); -+ for (;item;item = item->nextSibling()) { -+ ii = (InstrItem*)item; -+ TraceInstr* instr = ii->instr(); -+ if (!instr) continue; -+ -+ ii->updateCost(); -+ -+ TQListViewItem *next, *i = ii->firstChild(); -+ for (;i;i = next) { -+ next = i->nextSibling(); -+ ((InstrItem*)i)->updateCost(); -+ } -+ } -+} -+ -+void InstrView::readViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ KConfigGroup* g = configGroup(c, prefix, postfix); -+ -+ if (0) qDebug("InstrView::readViewConfig"); -+ -+ _showHexCode = g->readBoolEntry("ShowHexCode", DEFAULT_SHOWHEXCODE); -+ -+ delete g; -+} -+ -+void InstrView::saveViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ KConfigGroup g(c, (prefix+postfix).ascii()); -+ -+ writeConfigEntry(&g, "ShowHexCode", _showHexCode, DEFAULT_SHOWHEXCODE); -+} -+ -+#include "instrview.moc" -diff --git a/kdecachegrind/kdecachegrind/instrview.h b/kdecachegrind/kdecachegrind/instrview.h -new file mode 100644 -index 0000000..79d3d76 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/instrview.h -@@ -0,0 +1,83 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Instruction View -+ */ -+ -+#ifndef INSTRVIEW_H -+#define INSTRVIEW_H -+ -+#include -+#include "traceitemview.h" -+ -+class InstrItem; -+ -+class InstrView : public TQListView, public TraceItemView -+{ -+ friend class InstrItem; -+ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ InstrView(TraceItemView* parentView, -+ TQWidget* parent = 0, const char* name = 0); -+ -+ virtual TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ -+ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ -+protected: -+ int arrowLevels() { return _arrowLevels; } -+ void paintEmptyArea( TQPainter *, const TQRect & ); -+ -+private slots: -+ void context(TQListViewItem*, const TQPoint &, int); -+ void selectedSlot(TQListViewItem *); -+ void activatedSlot(TQListViewItem *); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ void refresh(); -+ void setColumnWidths(); -+ void fillInstr(); -+ void updateJumpArray(Addr,InstrItem*,bool,bool); -+ bool fillInstrRange(TraceFunction*, -+ TraceInstrMap::Iterator,TraceInstrMap::Iterator); -+ void updateInstrItems(); -+ -+ bool _inSelectionUpdate; -+ -+ // arrows -+ int _arrowLevels; -+ // temporary needed on creation... -+ TQMemArray _jump; -+ TraceInstrJumpList _lowList, _highList; -+ -+ // remember width of hex code column if hidden -+ int _lastHexCodeWidth; -+ -+ // widget options -+ bool _showHexCode; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/listutils.cpp b/kdecachegrind/kdecachegrind/listutils.cpp -new file mode 100644 -index 0000000..0053646 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/listutils.cpp -@@ -0,0 +1,266 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Some helper functions for TQListViewItem derivates -+ */ -+ -+#include -+#include "listutils.h" -+ -+#define COSTPIX_WIDTH 25 -+ -+TQPixmap colorPixmap(int w, int h, TQColor c) -+{ -+ static TQPixmap* pixs[37]; -+ static TQColor cols[37]; -+ static bool inited = false; -+ -+ if (!inited) { -+ for (int i=0;i<37;i++) pixs[i]=0; -+ inited = true; -+ } -+ int hash = (w+h+c.red()+c.green()+c.blue()) % 37; -+ if (pixs[hash]) { -+ if ((pixs[hash]->width() == w) && -+ (pixs[hash]->height() == h) && -+ (cols[hash] == c)) -+ return *pixs[hash]; -+ -+ delete pixs[hash]; -+ } -+ -+ -+ TQPixmap* pix = new TQPixmap(w, h); -+ pix->fill(c); -+ TQPainter p(pix); -+ p.setPen(c.light()); -+ p.drawLine(0, 0, w-1, 0); -+ p.drawLine(0, 0, 0, h-1); -+ p.setPen(c.dark()); -+ p.drawLine(w-1, 0, w-1, h-1); -+ p.drawLine(0, h-1, w-1, h-1); -+ -+ pixs[hash] = pix; -+ cols[hash] = c; -+ return *pix; -+} -+ -+/** -+ * Create a percentage pixmap with a filling rate of p percent (0-100). -+ * When withFrame==false, the pixmap is truncated to only the filled portion. -+ */ -+TQPixmap percentagePixmap(int w, int h, int percent, TQColor c, bool framed) -+{ -+ int iw, ix1, ix2, ih, iy1, iy2; -+ -+ // inner rectangle to fill with bar -+ if (framed) { -+ iw = w-2, ix1 = 1, ix2 = w-2; -+ ih = h-2, iy1 = 1, iy2 = h-2; -+ } -+ else { -+ iw = w; ix1 = 0; ix2 = w-1; -+ ih = h; iy1 = 0; iy2 = h-1; -+ } -+ -+ /* Limit bar to 100% */ -+ int filled = (percent>100) ? iw+1 : iw*percent/100+1; -+ if (!framed) w=filled-1; -+ if (w<3) return TQPixmap(); -+ -+ TQPixmap pix(w, h); -+ pix.fill(TQt::white); -+ TQPainter p(&pix); -+ p.setPen(TQt::black); -+ if (framed) -+ p.drawRect(0, 0, w, h); -+ -+ // inside -+ p.setPen(TQt::NoPen); -+ p.setBrush(c); -+ p.drawRect(ix1, iy1, filled-1,ih); -+ -+ // frame -+ ix2 = ix1+filled-2; -+ p.setPen(c.light()); -+ p.drawLine(ix1, iy1, ix2, iy1); -+ p.drawLine(ix1, iy1, ix1, iy2); -+ p.setPen(c.dark()); -+ p.drawLine(ix1+1, iy2, ix2, iy2); -+ p.drawLine(ix2, iy1, ix2, iy2); -+ -+ return pix; -+} -+ -+inline TQColor partitionColor(int d, int max) -+{ -+ return TQColor( (720*d/max) % 360, -+ 255-(128*d/max), 192, TQColor::Hsv); -+} -+ -+ -+TQPixmap partitionPixmap(int w, int h, -+ double* hist, TQColor* cArray, int maxIndex, bool framed) -+{ -+ int lastPos = 0, nextPos; -+ double val=0.0, sum=0.0; -+ int d, dmin=maxIndex, dmax=0; -+ for (d = 0;d0.0) { -+ sum += hist[d]; -+ if (dmin>d) dmin = d; -+ if (dmax=iw) x2=iw-1; -+ -+ // inside -+ p.setPen(TQt::NoPen); -+ p.setBrush(c); -+ p.drawRect(x1, iy1, x2-x1+1, ih); -+ -+ // lighter top border -+ p.setPen(c.light()); -+ p.drawLine(x1, iy1, x2-1, iy1); -+ -+ // when width for last and current distance >2, draw full 3D effect... -+ if (!leftDrawn) { -+ p.drawLine(x1, iy1+1, x1, iy2); -+ leftDrawn = true; -+ } -+ -+ // darker bottom border -+ p.setPen(c.dark()); -+ p.drawLine(x1, iy2, x2-1, iy2); -+ -+ lastPos = nextPos; -+ lastDiff = diff; -+ cLast = c; -+ d++; -+ } -+ -+ // right border (in last color) -+ if (x2>0) -+ p.drawLine(x2, iy1, x2, iy2); -+ -+ return pix; -+} -+ -+ -+TQPixmap costPixmap(TraceCostType* ct, TraceCost* cost, double total, bool framed) -+{ -+ if (ct->isReal()) { -+ TQColor color = ct->color(); -+ double p = 100.0 * cost->subCost(ct) / total; -+ return percentagePixmap(COSTPIX_WIDTH, 10, (int)(p+.5), color, framed); -+ } -+ -+ int maxIndex; -+ double h[MaxRealIndexValue]; -+ TQColor* cs = ct->mapping()->realColors(); -+ maxIndex = ct->histCost(cost, total, h); -+ -+ if (maxIndex ==0) return TQPixmap(); -+ return partitionPixmap(COSTPIX_WIDTH, 10, h, cs, maxIndex, framed); -+} -+ -+ -+ -+// HighestCostList -+ -+HighestCostList::HighestCostList() -+{ -+ _maxSize = 0; -+ _count = 0; -+ _costType = 0; -+} -+ -+void HighestCostList::clear(int maxSize) -+{ -+ _maxSize = maxSize; -+ _count = 0; -+ _item.resize(maxSize); -+ _cost.resize(maxSize); -+} -+ -+void HighestCostList::addCost(TraceCost* c, SubCost cost) -+{ -+ int i; -+ -+ _count++; -+ if (_count > _maxSize) { -+ if (_cost[_maxSize-1] >= cost) return; -+ i = _maxSize-1; -+ } -+ else i = _count-1; -+ -+ for(; i>0; i--) { -+ if (_cost[i-1] >= cost) break; -+ else { -+ _cost[i] = _cost[i-1]; -+ _item[i] = _item[i-1]; -+ } -+ } -+ _cost[i] = cost; -+ _item[i] = c; -+} -+ -+ -diff --git a/kdecachegrind/kdecachegrind/listutils.h b/kdecachegrind/kdecachegrind/listutils.h -new file mode 100644 -index 0000000..e3e13fb ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/listutils.h -@@ -0,0 +1,65 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Some helper functions for TQListViewItem derivates -+ */ -+ -+#ifndef LISTUTILS_H -+#define LISTUTILS_H -+ -+#include -+#include -+#include -+#include "tracedata.h" -+ -+TQString bigNum(SubCost); -+TQPixmap colorPixmap(int w, int h, TQColor c); -+TQPixmap percentagePixmap(int w, int h, int percent, TQColor c, bool framed); -+TQPixmap partitionPixmap(int w, int h, double* hist, TQColor*, -+ int maxIndex, bool framed); -+TQPixmap costPixmap(TraceCostType* ct, TraceCost* cost, double total, bool framed); -+ -+/** -+ * A class to calculate the TraceCost items -+ * with highest cost. -+ */ -+ -+class HighestCostList -+{ -+ public: -+ HighestCostList(); -+ -+ void clear(int maxSize); -+ void addCost(TraceCost*, SubCost); -+ int count() { return _count; } -+ int realCount() { return (_count > _maxSize) ? _maxSize:_count; } -+ int maxSize() { return _maxSize; } -+ bool hasMore() { return _count > _maxSize; } -+ TraceCost* operator[] (int i) -+ { return (i>=0 && i<_count && i<_maxSize) ? _item[i] : 0; } -+ -+ private: -+ TraceCostList _list; -+ int _maxSize, _count; -+ TraceCostType* _costType; -+ TQMemArray _item; -+ TQMemArray _cost; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/lo16-app-kcachegrind.png b/kdecachegrind/kdecachegrind/lo16-app-kcachegrind.png -new file mode 100644 -index 0000000..0985586 -Binary files /dev/null and b/kdecachegrind/kdecachegrind/lo16-app-kcachegrind.png differ -diff --git a/kdecachegrind/kdecachegrind/lo32-app-kcachegrind.png b/kdecachegrind/kdecachegrind/lo32-app-kcachegrind.png -new file mode 100644 -index 0000000..12542c8 -Binary files /dev/null and b/kdecachegrind/kdecachegrind/lo32-app-kcachegrind.png differ -diff --git a/kdecachegrind/kdecachegrind/loader.cpp b/kdecachegrind/kdecachegrind/loader.cpp -new file mode 100644 -index 0000000..a4aecf5 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/loader.cpp -@@ -0,0 +1,85 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Base class for loaders of profiling data. -+ */ -+ -+#include "loader.h" -+ -+ -+/// Loader -+ -+LoaderList Loader::_loaderList; -+ -+Loader::Loader(TQString name, TQString desc) -+{ -+ _name = name; -+ _description = desc; -+} -+ -+Loader::~Loader() -+{} -+ -+bool Loader::canLoadTrace(TQFile*) -+{ -+ return false; -+} -+ -+bool Loader::loadTrace(TracePart*) -+{ -+ return false; -+} -+ -+Loader* Loader::matchingLoader(TQFile* file) -+{ -+ Loader* l; -+ for (l=_loaderList.first(); l; l = _loaderList.next()) -+ if (l->canLoadTrace(file)) -+ return l; -+ -+ return 0; -+} -+ -+Loader* Loader::loader(TQString name) -+{ -+ Loader* l; -+ for (l=_loaderList.first(); l; l = _loaderList.next()) -+ if (l->name() == name) -+ return l; -+ -+ return 0; -+} -+ -+// factories of available loaders -+Loader* createCachegrindLoader(); -+ -+void Loader::initLoaders() -+{ -+ _loaderList.append(createCachegrindLoader()); -+ //_loaderList.append(GProfLoader::createLoader()); -+} -+ -+void Loader::deleteLoaders() -+{ -+ _loaderList.setAutoDelete(true); -+ _loaderList.clear(); -+} -+ -+ -+#include "loader.moc" -diff --git a/kdecachegrind/kdecachegrind/loader.h b/kdecachegrind/kdecachegrind/loader.h -new file mode 100644 -index 0000000..f79f13d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/loader.h -@@ -0,0 +1,80 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Base class for loaders of profiling data. -+ */ -+ -+#ifndef LOADER_H -+#define LOADER_H -+ -+#include -+#include -+#include -+ -+class TQFile; -+class TraceData; -+class TracePart; -+class Loader; -+ -+ -+typedef TQPtrList LoaderList; -+ -+/** -+ * To implement a new loader, inherit from the Loader class -+ * and implement canLoadTrace(), loadTrace() and if a trace in -+ * this format can consist out of multiple parts, implement -+ * isPartOfTrace(), too. -+ * For registration, put into the static initLoaders() function -+ * of this base class a _loaderList.append(new MyLoader()). -+ * -+ * KCachegrind will use the first matching loader. -+ */ -+ -+class Loader: public TQObject -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ Loader(TQString name, TQString desc); -+ virtual ~Loader(); -+ -+ virtual bool canLoadTrace(TQFile* file); -+ virtual bool loadTrace(TracePart*); -+ -+ static Loader* matchingLoader(TQFile* file); -+ static Loader* loader(TQString name); -+ static void initLoaders(); -+ static void deleteLoaders(); -+ -+ TQString name() const { return _name; } -+ TQString description() const { return _description; } -+ -+signals: -+ void updateStatus(TQString, int); -+ -+private: -+ TQString _name, _description; -+ -+ static LoaderList _loaderList; -+}; -+ -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/main.cpp b/kdecachegrind/kdecachegrind/main.cpp -new file mode 100644 -index 0000000..fd9df1b ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/main.cpp -@@ -0,0 +1,95 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * KCachegrind startup -+ */ -+ -+// for KCACHEGRIND_VERSION -+#include "../version.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "toplevel.h" -+#include "tracedata.h" -+#include "loader.h" -+ -+static KCmdLineOptions options[] = -+{ -+ { "r ", I18N_NOOP("Run under cachegrind"), 0 }, -+ { "+[trace]", I18N_NOOP("Show information of this trace"), 0 }, -+ KCmdLineLastOption // End of options. -+}; -+ -+int main( int argc, char ** argv ) -+{ -+ KAboutData aboutData("kdecachegrind", -+ I18N_NOOP("KCachegrind"), -+ KCACHEGRIND_VERSION, -+ I18N_NOOP("KDE Frontend for Cachegrind"), -+ KAboutData::License_GPL, -+ I18N_NOOP("(C) 2002, 2003, 2004"), 0, -+ "http://kdecachegrind.sf.net"); -+ aboutData.addAuthor("Josef Weidendorfer", -+ I18N_NOOP("Author/Maintainer"), -+ "Josef.Weidendorfer@gmx.de"); -+ -+ KCmdLineArgs::init(argc, argv, &aboutData); -+ KCmdLineArgs::addCmdLineOptions( options ); -+ -+ KApplication a; -+ TopLevel* t; -+ Loader::initLoaders(); -+ -+ if (a.isRestored()){ -+ int n = 1; -+ while (KMainWindow::canBeRestored(n)){ -+ (new TopLevel())->restore(n); -+ n++; -+ } -+ } -+ else { -+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); -+ if (args->count()>0) { -+ for(int i = 0; i < args->count(); i++) { -+ t = new TopLevel(); -+ t->show(); -+ t->loadDelayed(TQFile::decodeName(args->arg(i))); -+ } -+ } -+ else { -+ // load trace in current dir -+ t = new TopLevel(); -+ t->show(); -+ t->loadDelayed("."); -+ } -+ } -+ -+ a.connect( &a, TQT_SIGNAL( lastWindowClosed() ), &a, TQT_SLOT( quit() ) ); -+ int res = a.exec(); -+ -+ // to make leak checking in valgrind happy... -+ Loader::deleteLoaders(); -+ TraceItem::cleanup(); -+ -+ return res; -+} -diff --git a/kdecachegrind/kdecachegrind/multiview.cpp b/kdecachegrind/kdecachegrind/multiview.cpp -new file mode 100644 -index 0000000..4288e2d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/multiview.cpp -@@ -0,0 +1,224 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * MultiView, enclosing multiple TabView's with a user choosable -+ * active view (i.e. focus), separated by a splitter. -+ * Selection of the active view is shown in the next to the right view -+ * (with wrap around). -+ */ -+ -+#include -+#include -+#include -+ -+#include "multiview.h" -+#include "tabview.h" -+ -+// -+// MultiView -+// -+ -+MultiView::MultiView(TopLevel* top, TQWidget* parent, const char* name) -+ : TQSplitter(parent, name), TraceItemView(0, top) -+{ -+ // default -+ setOrientation(Qt::Horizontal); -+ -+ appendView(); -+ _active = _views.first(); -+ _active->setActive(true); -+} -+ -+void MultiView::setData(TraceData* d) -+{ -+ TraceItemView::setData(d); -+ -+ TabView* tv; -+ for(tv=_views.first(); tv; tv=_views.next()) -+ tv->setData(d); -+} -+ -+void MultiView::setChildCount(int n) -+{ -+ while(n< (int)_views.count()) removeView(); -+ while(n> (int)_views.count()) appendView(); -+} -+ -+void MultiView::appendView() -+{ -+ int n = _views.count()+1; -+ -+ TabView* tv = new TabView(this, this, -+ TQString("TabView-%1").arg(n).ascii()); -+ connect(tv, TQT_SIGNAL(activated(TabView*)), -+ this, TQT_SLOT(tabActivated(TabView*)) ); -+ _views.append(tv); -+ tv->show(); -+ -+ // set same attributes as in active view -+ tv->set(0, _data, _costType, _costType2, -+ _groupType, _partList, _activeItem, 0); -+ tv->updateView(); -+ -+ if (0) kdDebug() << "MultiView::appendView, now " -+ << _views.count() << endl; -+} -+ -+void MultiView::removeView() -+{ -+ if (_views.count()<=1) return; -+ -+ TabView* last = _views.last(); -+ -+ // if last tab is active, make first active -+ if (last == _active) { -+ TabView* newActive = _views.first(); -+ newActive->setActive(true); -+ tabActivated(newActive); -+ } -+ -+ _views.removeRef(last); -+ delete last; -+ -+ if (0) kdDebug() << "MultiView::removeView, now " -+ << _views.count() << endl; -+} -+ -+ -+void MultiView::tabActivated(TabView* newActiveTab) -+{ -+ if (_active == newActiveTab) return; -+ -+ if (0) kdDebug() << "MultiView::tabActivated " -+ << newActiveTab->name() << endl; -+ -+ TraceItem* oldActiveItem = 0; -+ if (_active) { -+ oldActiveItem = _active->activeItem(); -+ _active->setActive(false); -+ } -+ _active = newActiveTab; -+ -+ // make the active item of the new TabView active -+ if (_active && (oldActiveItem != _active->activeItem())) -+ TraceItemView::activated(_active->activeItem()); -+} -+ -+void MultiView::selected(TraceItemView* sender, TraceItem* i) -+{ -+ if (0) kdDebug() << "MultiView::selected " << i->name() -+ << ", sender " << sender->widget()->name() << endl; -+ -+ // we react only on selection changes of the active TabView -+ if (sender != (TraceItemView*)_active) return; -+ -+ _views.findRef(_active); -+ TabView* next = _views.next(); -+ if (!next) next = _views.first(); -+ -+ // don't change item of active tab -+ if (next == _active) return; -+ -+ next->activate(i); -+ next->updateView(); -+} -+ -+void MultiView::activated(TraceItemView* sender, TraceItem* i) -+{ -+ if (0) kdDebug() << "MultiView::activated " << i->name() -+ << ", sender " << sender->widget()->name() << endl; -+ -+ // we react only on selection changes of the active TabView -+ if (sender != (TraceItemView*)_active) return; -+ -+ TraceItemView::activated(sender,i); -+} -+ -+void MultiView::doUpdate(int changeType) -+{ -+ TabView* tv; -+ for(tv=_views.first(); tv; tv=_views.next()) { -+ tv->set(changeType, _data, _costType, _costType2, -+ _groupType, _partList, -+ (tv == _active) ? _activeItem : tv->activeItem(), -+ tv->selectedItem()); -+ tv->notifyChange(changeType); -+ if (tv->isViewVisible()) -+ tv->updateView(); -+ } -+} -+ -+ -+void MultiView::readViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, -+ bool withOptions) -+{ -+ if (0) qDebug("%s::readConfig(%s%s)", name(), -+ prefix.ascii(), postfix.ascii()); -+ -+ TQString active; -+ KConfigGroup* g = configGroup(c, prefix, postfix); -+ int n = g->readNumEntry("Panels", 1); -+ setChildCount(n); -+ setOrientation( (g->readEntry("Orientation") == TQString("Horizontal")) ? -+ Qt::Horizontal : Qt::Vertical ); -+ -+ setSizes(g->readIntListEntry("PanelSizes")); -+ -+ active = g->readEntry("ActivePanel", ""); -+ delete g; -+ -+ TabView* tv, *activeTV = 0; -+ for(tv=_views.first();tv;tv=_views.next()) { -+ if (tv->name() == active) activeTV=tv; -+ tv->readViewConfig(c, TQString("%1-%2").arg(prefix).arg(tv->name()), -+ postfix, withOptions); -+ } -+ -+ // activate panel after restoring -+ if (!activeTV) activeTV = _views.first(); -+ -+ if (_active == activeTV) -+ TraceItemView::activated(_active->activeItem()); -+ else -+ activeTV->setActive(true); -+} -+ -+void MultiView::saveViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, -+ bool withOptions) -+{ -+ KConfigGroup g(c, (prefix+postfix).ascii()); -+ -+ g.writeEntry("Panels", childCount()); -+ g.writeEntry("Orientation", -+ (orientation() == Qt::Horizontal) ? -+ "Horizontal" : "Vertical"); -+ -+ g.writeEntry("PanelSizes", sizes()); -+ g.writeEntry("ActivePanel", _active ? _active->name() : "none"); -+ -+ TabView* tv; -+ for(tv=_views.first();tv;tv=_views.next()) -+ tv->saveViewConfig(c, TQString("%1-%2").arg(prefix).arg(tv->name()), -+ postfix, withOptions); -+} -+ -+ -+#include "multiview.moc" -diff --git a/kdecachegrind/kdecachegrind/multiview.h b/kdecachegrind/kdecachegrind/multiview.h -new file mode 100644 -index 0000000..9d77101 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/multiview.h -@@ -0,0 +1,67 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * MultiView, enclosing multiple (default: 2) TabView's with a user -+ * choosable active view (i.e. focus). This is a splitter itself. -+ * Selection of the active view is shown in the next to the right view -+ * (with wrap around). -+ */ -+ -+#ifndef MULTIVIEW_H -+#define MULTIVIEW_H -+ -+#include -+#include -+#include "traceitemview.h" -+#include "tabview.h" // because of TQPtrList -+ -+class MultiView : public TQSplitter, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ MultiView(TopLevel* top, TQWidget* parent = 0, const char* name = 0); -+ -+ TQWidget* widget() { return this; } -+ TabView* activeTabView() const { return _active; } -+ void setData(TraceData*); -+ -+ void appendView(); -+ void removeView(); -+ void setChildCount(int); -+ int childCount() { return _views.count(); } -+ -+ void selected(TraceItemView*, TraceItem*); -+ void activated(TraceItemView*, TraceItem*); -+ -+ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ -+public slots: -+ void tabActivated(TabView*); -+ -+ private: -+ void doUpdate(int); -+ -+ TabView* _active; -+ TQPtrList _views; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/partgraph.cpp b/kdecachegrind/kdecachegrind/partgraph.cpp -new file mode 100644 -index 0000000..a20f53d ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partgraph.cpp -@@ -0,0 +1,534 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * TracePart as Nested Area -+ */ -+ -+#include -+ -+#include "partgraph.h" -+#include "configuration.h" -+#include "listutils.h" -+ -+ -+// PartAreaWidget -+ -+PartAreaWidget::PartAreaWidget(TQWidget* parent, const char* name) -+ : TreeMapWidget(new BasePartItem(), parent, name) -+{ -+ _data = 0; -+ _function = 0; -+ -+ _costType = 0; -+ _groupType = TraceCost::NoCostType; -+ _visualisation = NoVisualisation; -+ _zoomFunction = false; -+ _callLevels = 1; -+} -+ -+void PartAreaWidget::setData(TraceData* data) -+{ -+ if (data == _data) return; -+ -+ _data = data; -+ _function = 0; -+ _hiddenParts.clear(); -+ -+ ((BasePartItem*)base())->setData(data); -+} -+ -+void PartAreaWidget::changeHidden(const TracePartList& list) -+{ -+ _hiddenParts = list; -+ base()->refresh(); -+} -+ -+ -+void PartAreaWidget::setCostType(TraceCostType* ct) -+{ -+ _costType = ct; -+ -+ // this resizes items -+ base()->redraw(); -+} -+ -+void PartAreaWidget::setVisualisation(VisualisationMode m) -+{ -+ _visualisation = m; -+ refreshParts(); -+} -+ -+void PartAreaWidget::setZoomFunction(bool zoomFunction) -+{ -+ _zoomFunction = zoomFunction; -+ refreshParts(); -+} -+ -+void PartAreaWidget::setCallLevels(int callLevels) -+{ -+ _callLevels = callLevels; -+ refreshParts(); -+} -+ -+void PartAreaWidget::refreshParts() -+{ -+ // rebuild only subparts to keep part selection state -+ TreeMapItem* i; -+ TreeMapItemList* l = base()->children(); -+ if (l) -+ for (i=l->first();i;i=l->next()) -+ i->refresh(); -+ -+ // but resize part areas -+ base()->redraw(); -+} -+ -+ -+void PartAreaWidget::setFunction(TraceFunction* f) -+{ -+ _function = f; -+ -+ if (_visualisation == PartAreaWidget::Inclusive) -+ refreshParts(); -+} -+ -+void PartAreaWidget::setGroupType(TraceCost::CostType gt) -+{ -+ _groupType = gt; -+ -+ // rebuild hierarchy below parts. -+ // thus, selected parts stay selected -+ TreeMapItem* i; -+ TreeMapItemList* l = base()->children(); -+ if (l) -+ for (i=l->first();i;i=l->next()) -+ i->refresh(); -+ -+ base()->redraw(); -+} -+ -+bool PartAreaWidget::isHidden(TracePart* part) const -+{ -+ return (_hiddenParts.containsRef(part)>0); -+} -+ -+TQColor PartAreaWidget::groupColor(TraceFunction* f) const -+{ -+ if (!f) -+ return colorGroup().button(); -+ -+ return Configuration::functionColor(_groupType, f); -+} -+ -+TQString PartAreaWidget::tipString(TreeMapItem* i) const -+{ -+ TQString tip, itemTip; -+ int count = 0; -+ -+ //qDebug("PartAreaWidget::tipString for '%s'", i->name().ascii()); -+ -+ // first, SubPartItem's -+ while (i && countrtti() == 3) { -+ itemTip = i->text(0); -+ if ((int)itemTip.length()>Configuration::maxSymbolLength()) -+ itemTip = itemTip.left(Configuration::maxSymbolLength()) + "..."; -+ -+ if (!i->text(1).isEmpty()) -+ itemTip += " (" + i->text(1) + ")"; -+ -+ if (!tip.isEmpty()) -+ itemTip += "\n"; -+ -+ tip = itemTip + tip; -+ i = i->parent(); -+ count++; -+ } -+ -+ // skip to part -+ while (i && i->rtti()==3) i = i->parent(); -+ -+ if (i && i->rtti()==2) { -+ itemTip = i18n("Profile Part %1").arg(i->text(0)); -+ if (!i->text(1).isEmpty()) -+ itemTip += " (" + i->text(1) + ")"; -+ -+ if (!tip.isEmpty()) -+ itemTip += "\n"; -+ -+ tip = itemTip + tip; -+ } -+ -+// qDebug("PartAreaWidget:: tip %s, itemTip %s", -+// tip.ascii(), itemTip.ascii()); -+ -+ return tip; -+} -+ -+ -+ -+ -+ -+// BasePartItem -+ -+BasePartItem::BasePartItem() -+ : TreeMapItem() -+{ -+ _data = 0; -+ setSorting(-1); -+} -+ -+void BasePartItem::setData(TraceData* data) -+{ -+ if (data == _data) return; -+ -+ _data = data; -+ refresh(); -+} -+ -+TreeMapItemList* BasePartItem::children() -+{ -+ if (!_data) return _children; -+ -+ if (!initialized()) { -+// qDebug("Create Parts (%s)", name().ascii()); -+ -+ PartAreaWidget* w = (PartAreaWidget*) widget(); -+ TracePart* part; -+ TracePartList l = _data->parts(); -+ for (part=l.first();part;part=l.next()) -+ if (!w->isHidden(part)) -+ addItem(new PartItem(part)); -+ } -+ -+ return _children; -+} -+ -+TQString BasePartItem::text(int textNo) const -+{ -+ if (textNo == 0) { -+ if (!_data) -+ return i18n("(no trace)"); -+ -+ if (_data->parts().count() == 0) -+ return i18n("(no part)"); -+ } -+ return TQString(); -+} -+ -+ -+TQColor BasePartItem::backColor() const -+{ -+ return widget()->colorGroup().base(); -+} -+ -+double BasePartItem::value() const -+{ -+ if (!_data) return 0; -+ -+ PartAreaWidget* w = (PartAreaWidget*) widget(); -+ return (double)_data->subCost(w->costType()); -+} -+ -+ -+ -+ -+ -+// PartItem -+ -+PartItem::PartItem(TracePart* p) -+{ -+ _p = p; -+ _factor=1; -+} -+ -+TQString PartItem::text(int textNo) const -+{ -+ if (textNo == 0) -+ return _p->prettyName(); -+ -+ if (textNo != 1) -+ return TQString(); -+ -+ TraceCostType* ct; -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ SubCost v; -+ -+ ct = w->costType(); -+ v = _p->subCost(ct); -+ -+ if (Configuration::showPercentage()) { -+ TraceCost* t = _p->data()->totals(); -+ double p = 100.0 * v / t->subCost(ct); -+ return TQString("%1 %") -+ .arg(p, 0, 'f', Configuration::percentPrecision()); -+ } -+ return v.pretty(); -+} -+ -+ -+TQPixmap PartItem::pixmap(int i) const -+{ -+ if (i != 1) return TQPixmap(); -+ -+ // Cost pixmap -+ -+ TraceCostType* ct = ((PartAreaWidget*)widget())->costType(); -+ return costPixmap( ct, _p, (double) (_p->data()->totals()->subCost(ct)), false ); -+} -+ -+ -+double PartItem::value() const -+{ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ TraceCostType* ct = w->costType(); -+ if ((w->visualisation() == PartAreaWidget::Inclusive) && -+ w->zoomFunction()) { -+ -+ // use value of zoomed function -+ TraceFunction* f = w->function(); -+ if (f) { -+ TracePartFunction* pf = (TracePartFunction*) f->findDepFromPart(_p); -+ if (pf) -+ return (double) pf->inclusive()->subCost(ct); -+ // when function is not available in part, hide part -+ return 0.0; -+ } -+ } -+ return (double) _p->subCost(ct); -+} -+ -+double PartItem::sum() const -+{ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ if (w->visualisation() == PartAreaWidget::Inclusive) { -+ double s = value(); -+ //qDebug("PartItem::sum [part %s]: %d", _p->name().ascii(), s); -+ return s; -+ } -+ return 0.0; -+} -+ -+TreeMapItemList* PartItem::children() -+{ -+ if (initialized()) return _children; -+ -+ TraceCost* c; -+// qDebug("Create Part subitems (%s)", name().ascii()); -+ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ if (w->visualisation() == PartAreaWidget::Inclusive) { -+ TraceFunction* f = w->function(); -+ if (f) { -+ c = f->findDepFromPart(_p); -+ if (c) addItem(new SubPartItem(c)); -+ } -+ -+ return _children; -+ } -+ -+ -+ switch( ((PartAreaWidget*)widget())->groupType() ) { -+ -+ case TraceCost::Object: -+ { -+ TraceObjectMap::Iterator it; -+ for ( it = _p->data()->objectMap().begin(); -+ it != _p->data()->objectMap().end(); ++it ) { -+ c = (*it).findDepFromPart(_p); -+ if (c) -+ addItem(new SubPartItem(c)); -+ } -+ } -+ break; -+ -+ case TraceCost::Class: -+ { -+ TraceClassMap::Iterator it; -+ for ( it = _p->data()->classMap().begin(); -+ it != _p->data()->classMap().end(); ++it ) { -+ c = (*it).findDepFromPart(_p); -+ if (c) -+ addItem(new SubPartItem(c)); -+ } -+ } -+ break; -+ -+ case TraceCost::File: -+ { -+ TraceFileMap::Iterator it; -+ for ( it = _p->data()->fileMap().begin(); -+ it != _p->data()->fileMap().end(); ++it ) { -+ c = (*it).findDepFromPart(_p); -+ if (c) -+ addItem(new SubPartItem(c)); -+ } -+ } -+ break; -+ -+ case TraceCost::Function: -+ { -+ TraceFunctionMap::Iterator it; -+ for ( it = _p->data()->functionMap().begin(); -+ it != _p->data()->functionMap().end(); ++it ) { -+ c = (*it).findDepFromPart(_p); -+ if (c) -+ addItem(new SubPartItem(c)); -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return _children; -+} -+ -+ -+TQColor PartItem::backColor() const -+{ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ return w->groupColor(0); -+} -+ -+ -+// SubPartItem -+ -+SubPartItem::SubPartItem(TraceCost* c) -+{ -+ _partCostItem = c; -+ _factor=1; -+} -+ -+TQString SubPartItem::text(int textNo) const -+{ -+ if (textNo == 0) { -+ if (!_partCostItem) -+ return i18n("(unknown)"); -+ -+ return _partCostItem->dependant()->prettyName(); -+ } -+ -+ if (textNo != 1) -+ return TQString(); -+ -+ TraceCostType* ct; -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ SubCost v; -+ -+ ct = w->costType(); -+ if (w->visualisation() == PartAreaWidget::Inclusive) -+ v = ((TracePartFunction*)_partCostItem)->inclusive()->subCost(ct); -+ else -+ v = _partCostItem->subCost(ct); -+ -+ if (Configuration::showPercentage()) { -+ TraceCost* t = Configuration::showExpanded() ? -+ _partCostItem->part() : _partCostItem->part()->data()->totals(); -+ double p = 100.0 * v / t->subCost(ct); -+ return TQString("%1 %") -+ .arg(p, 0, 'f', Configuration::percentPrecision()); -+ } -+ return v.pretty(); -+} -+ -+TQPixmap SubPartItem::pixmap(int i) const -+{ -+ if (i != 1) return TQPixmap(); -+ -+ // Cost pixmap -+ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ TraceCostType* ct = w->costType(); -+ TraceCost* t = Configuration::showExpanded() ? -+ _partCostItem->part() : _partCostItem->part()->data()->totals(); -+ TraceCost* c; -+ if (w->visualisation() == PartAreaWidget::Inclusive) -+ c = ((TracePartFunction*)_partCostItem)->inclusive(); -+ else -+ c = _partCostItem; -+ -+ return costPixmap( ct, c, (double) (t->subCost(ct)), false ); -+} -+ -+double SubPartItem::value() const -+{ -+ TraceCostType* ct; -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ -+ ct = w->costType(); -+ if (w->visualisation() == PartAreaWidget::Inclusive) -+ return (double) -+ ((TracePartFunction*)_partCostItem)->inclusive()->subCost(ct); -+ -+ return (double) _partCostItem->subCost(ct); -+} -+ -+double SubPartItem::sum() const -+{ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ if (w->visualisation() == PartAreaWidget::Inclusive) { -+ double s = value(); -+ //qDebug("SubPartItem::sum [Cost %s]: %d", _cost->name().ascii(), s); -+ return s; -+ } -+ return 0.0; -+} -+ -+TreeMapItemList* SubPartItem::children() -+{ -+ if (!initialized()) { -+// qDebug("Create Part sub-subitems (%s)", name().ascii()); -+ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ -+ if (depth()-2 > w->callLevels()) -+ return _children; -+ -+ if (w->visualisation() == PartAreaWidget::Inclusive) { -+ TracePartCall* call; -+ TracePartCallList l; -+ -+ setSum(value()); -+ -+ l = ((TracePartFunction*)_partCostItem)->partCallings(); -+ for (call=l.first();call;call=l.next()) { -+ TraceFunction* called = call->call()->called(); -+ TraceCost* partCalled = called->findDepFromPart(call->part()); -+ if (partCalled) -+ addItem(new SubPartItem(partCalled)); -+ } -+ } -+ } -+ -+ return _children; -+} -+ -+ -+TQColor SubPartItem::backColor() const -+{ -+ PartAreaWidget* w = (PartAreaWidget*)widget(); -+ if (w->visualisation() == PartAreaWidget::Inclusive) -+ return w->groupColor((TraceFunction*)(_partCostItem->dependant())); -+ -+ return Configuration::groupColor(_partCostItem->dependant()); -+} -+ -+ -+#include "partgraph.moc" -diff --git a/kdecachegrind/kdecachegrind/partgraph.h b/kdecachegrind/kdecachegrind/partgraph.h -new file mode 100644 -index 0000000..f28f12e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partgraph.h -@@ -0,0 +1,132 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * TracePart Graph -+ */ -+ -+#ifndef PARTGRAPH_H -+#define PARTGRAPH_H -+ -+#include "treemap.h" -+#include "tracedata.h" -+ -+class PartAreaWidget: public TreeMapWidget -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ // Visualisation inside of trace parts -+ enum VisualisationMode { NoVisualisation, Partitioning, Inclusive }; -+ -+ PartAreaWidget(TQWidget* parent=0, const char* name=0); -+ -+ void setData(TraceData* d); -+ void setCostType(TraceCostType* ct); -+ void setGroupType(TraceCost::CostType gt); -+ void setVisualisation(VisualisationMode); -+ void setZoomFunction(bool zoomFunction); -+ void setCallLevels(int callLevels); -+ void setFunction(TraceFunction* f); -+ -+ TraceCostType* costType() const { return _costType; } -+ TraceCost::CostType groupType() const { return _groupType; } -+ TraceFunction* function() const { return _function; } -+ VisualisationMode visualisation() const { return _visualisation; } -+ bool zoomFunction() const { return _zoomFunction; } -+ int callLevels() const { return _callLevels; } -+ -+ TQColor groupColor(TraceFunction*) const; -+ TQString tipString(TreeMapItem*) const; -+ -+ void changeHidden(const TracePartList& list); -+ bool isHidden(TracePart*) const; -+ -+private: -+ void refreshParts(); -+ -+ TraceData* _data; -+ TraceCostType* _costType; -+ TraceCost::CostType _groupType; -+ TraceFunction* _function; -+ VisualisationMode _visualisation; -+ bool _zoomFunction; -+ int _callLevels; -+ -+ TracePartList _hiddenParts; -+}; -+ -+class BasePartItem: public TreeMapItem -+{ -+public: -+ BasePartItem(); -+ -+ void setData(TraceData* d); -+ -+ int rtti() const { return 1; } -+ double value() const; -+ TQString text(int) const; -+ int borderWidth() const { return 0; } -+ TreeMapItemList* children(); -+ TQColor backColor() const; -+ -+private: -+ TraceData* _data; -+}; -+ -+class PartItem: public TreeMapItem -+{ -+public: -+ PartItem(TracePart* p); -+ int rtti() const { return 2; } -+ TracePart* part() { return _p; } -+ double value() const; -+ double sum() const; -+ int borderWidth() const { return 0; } -+ TQString text(int) const; -+ TQPixmap pixmap(int) const; -+ TreeMapItemList* children(); -+ TQColor backColor() const; -+ -+private: -+ TracePart* _p; -+ unsigned int _factor; -+}; -+ -+class SubPartItem: public TreeMapItem -+{ -+public: -+ SubPartItem(TraceCost*); -+ int rtti() const { return 3; } -+ TraceCost* partCostItem() { return _partCostItem; } -+ double value() const; -+ double sum() const; -+ SplitMode splitMode() const { return Vertical; } -+ TQString text(int) const; -+ TQPixmap pixmap(int) const; -+ TreeMapItemList* children(); -+ TQColor backColor() const; -+ -+private: -+ TraceCost* _partCostItem; -+ unsigned int _factor; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/partlistitem.cpp b/kdecachegrind/kdecachegrind/partlistitem.cpp -new file mode 100644 -index 0000000..40c2db3 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partlistitem.cpp -@@ -0,0 +1,189 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "listutils.h" -+#include "partlistitem.h" -+#include "coverage.h" -+#include "configuration.h" -+ -+ -+// PartListItem -+ -+PartListItem::PartListItem(TQListView* parent, TraceCostItem* costItem, -+ TraceCostType* ct, TraceCost::CostType gt, -+ TracePart* part) -+ :TQListViewItem(parent) -+{ -+ _partCostItem = costItem->findDepFromPart(part); -+ _part = part; -+ _groupType = gt; -+ _costType = ct; -+ -+#if 0 -+ TQString partName = TQString::number(part->partNumber()); -+ if (part->data()->maxThreadID() >1) -+ partName += i18n(" (Thread %1)").arg(part->threadID()); -+ setText(0, partName); -+#else -+ setText(0, _part->prettyName()); -+#endif -+ -+ if (_part->trigger().isEmpty()) -+ setText(4,i18n("(none)")); -+ else -+ setText(4, _part->trigger()); -+ -+ update(); -+} -+ -+void PartListItem::setCostType(TraceCostType* ct) -+{ -+ if (_costType == ct) return; -+ -+ _costType = ct; -+ update(); -+} -+ -+void PartListItem::setGroupType(TraceCost::CostType gt) -+{ -+ if (_groupType == gt) return; -+ -+ _groupType = gt; -+ update(); -+} -+ -+void PartListItem::update() -+{ -+ TracePartFunction* pf; -+ pf = !_partCostItem ? 0 : -+ (_partCostItem->type()==TraceCost::PartFunction) ? -+ ((TracePartFunction*)_partCostItem) : 0; -+ -+ double total = _part->subCost(_costType); -+ -+ TraceCost* selfTotalCost = _part; -+ if (pf && Configuration::showExpanded()) { -+ switch(_groupType) { -+ case TraceCost::Object: selfTotalCost = pf->partObject(); break; -+ case TraceCost::Class: selfTotalCost = pf->partClass(); break; -+ case TraceCost::File: selfTotalCost = pf->partFile(); break; -+ default: break; -+ } -+ } -+ double selfTotal = selfTotalCost->subCost(_costType); -+ -+ _pure = _partCostItem ? _partCostItem->subCost(_costType) : SubCost(0); -+ _sum = pf ? pf->inclusive()->subCost(_costType) : SubCost(0); -+ -+ if (selfTotal == 0 || !_partCostItem) { -+ setText(2, TQString("-")); -+ setPixmap(2, TQPixmap()); -+ } -+ else { -+ double pure = 100.0 * _pure / selfTotal; -+ if (Configuration::showPercentage()) { -+ setText(2, TQString("%1") -+ .arg(pure, 0, 'f', Configuration::percentPrecision())); -+ } -+ else -+ setText(2, _partCostItem->prettySubCost(_costType)); -+ -+ setPixmap(2, costPixmap(_costType, _partCostItem, selfTotal, false)); -+ } -+ -+ if (total == 0 || !pf) { -+ setText(1, TQString("-")); -+ setPixmap(1, TQPixmap()); -+ } -+ else { -+ double sum = 100.0 * _sum / total; -+ if (Configuration::showPercentage()) { -+ setText(1, TQString("%1") -+ .arg(sum, 0, 'f', Configuration::percentPrecision())); -+ } -+ else -+ setText(1, _sum.pretty()); -+ -+ setPixmap(1, costPixmap(_costType, pf->inclusive(), total, false)); -+ } -+ -+ if (!pf) { -+ setText(3, TQString("-")); -+ _callers = 0; -+ return; -+ } -+ -+ TracePartCall* pc; -+ TracePartCallList pl; -+ SubCost callers, callees; -+ TQString str; -+ -+ callers = 0; -+ pl = pf->partCallers(); -+ for (pc=pl.first();pc;pc=pl.next()) { -+ callers += pc->callCount(); -+ } -+ -+ if ((callers == 0) && (pf->calledContexts()>0)) -+ str = i18n("(active)"); -+ else -+ str = callers.pretty(); -+ -+ _callers = callers; -+ setText(3, str); -+} -+ -+ -+int PartListItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ PartListItem* fi = (PartListItem*) i; -+ if (col==0) { -+ int mTID = _part->data()->maxThreadID()+1; -+ int mNum = _part->data()->maxPartNumber()+1; -+ -+ return -+ (_part->processID() - fi->_part->processID()) * mTID * mNum + -+ (_part->partNumber() - fi->_part->partNumber()) * mTID + -+ (_part->threadID() - fi->_part->threadID()); -+ } -+ if (col==1) { -+ if (_sum < fi->_sum) return -1; -+ if (_sum > fi->_sum) return 1; -+ return 0; -+ } -+ if (col==2) { -+ if (_pure < fi->_pure) return -1; -+ if (_pure > fi->_pure) return 1; -+ return 0; -+ } -+ if (col==3) { -+ if (_callers < fi->_callers) return -1; -+ if (_callers > fi->_callers) return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -diff --git a/kdecachegrind/kdecachegrind/partlistitem.h b/kdecachegrind/kdecachegrind/partlistitem.h -new file mode 100644 -index 0000000..0ab99a9 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partlistitem.h -@@ -0,0 +1,54 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#ifndef PARTLISTITEM_H -+#define PARTLISTITEM_H -+ -+#include -+#include "tracedata.h" -+ -+/** -+ * For info tab, trace part list. -+ * Needs update on -+ * - cost type change -+ * -+ * Note: on a cost item / percentage change, the list is rebuild -+ */ -+class PartListItem: public TQListViewItem -+{ -+public: -+ PartListItem(TQListView* parent, TraceCostItem* costItem, -+ TraceCostType* ct, TraceCost::CostType gt, TracePart* part); -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ TraceCost* partCostItem() { return _partCostItem; } -+ void setCostType(TraceCostType* ct); -+ void setGroupType(TraceCost::CostType); -+ TracePart* part() { return _part; } -+ void update(); -+ -+private: -+ SubCost _sum, _pure; -+ SubCost _callers; -+ TraceCostType* _costType; -+ TraceCost* _partCostItem; -+ TracePart* _part; -+ TraceCost::CostType _groupType; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/partselection.cpp b/kdecachegrind/kdecachegrind/partselection.cpp -new file mode 100644 -index 0000000..703dd75 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partselection.cpp -@@ -0,0 +1,567 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * For part file selection, to be put into a TQDockWindow -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "partselection.h" -+#include "partgraph.h" -+ -+PartSelection::PartSelection( TQWidget* parent, const char* name) -+ : PartSelectionBase(parent, name) -+{ -+ _data = 0; -+ _costType = 0; -+ _costType2 = 0; -+ _groupType = TraceItem::NoCostType; -+ _group = 0; -+ _function = 0; -+ _inSelectionUpdate = false; -+ -+ _diagramMode = false; -+ _drawFrames = true; -+ -+ partAreaWidget->setAllowRotation(false); -+ partAreaWidget->setMaxSelectDepth(2); -+ partAreaWidget->setSelectionMode(TreeMapWidget::Extended); -+ partAreaWidget->setSplitMode(TreeMapItem::HAlternate); -+ partAreaWidget->setVisibleWidth(2, true); -+ partAreaWidget->setFieldType(0, i18n( "Name" )); -+ partAreaWidget->setFieldType(1, i18n( "Cost" )); -+ -+ connect(partAreaWidget, TQT_SIGNAL(selectionChanged()), -+ this, TQT_SLOT(selectionChanged())); -+ connect(partAreaWidget, TQT_SIGNAL(currentChanged(TreeMapItem*, bool)), -+ this, TQT_SLOT(currentChangedSlot(TreeMapItem*, bool))); -+ connect(partAreaWidget, TQT_SIGNAL(doubleClicked(TreeMapItem*)), -+ this, TQT_SLOT(doubleClicked(TreeMapItem*))); -+ connect(partAreaWidget, -+ TQT_SIGNAL(contextMenuRequested(TreeMapItem*,const TQPoint &)), -+ this, -+ TQT_SLOT(contextMenuRequested(TreeMapItem*,const TQPoint &))); -+ -+ _showInfo = true; -+ showInfo(false); -+} -+ -+PartSelection::~PartSelection() -+{ -+} -+ -+void PartSelection::setData(TraceData* data) -+{ -+ if (_data == data) return; -+ -+ _data = data; -+ partAreaWidget->setData(data); -+ fillInfo(); -+} -+ -+ -+void PartSelection::refresh() -+{ -+ partAreaWidget->redraw(); -+ fillInfo(); -+} -+ -+void PartSelection::setCostType(TraceCostType* ct) -+{ -+ if (ct == _costType) return; -+ _costType = ct; -+ -+ partAreaWidget->setCostType(ct); -+} -+ -+void PartSelection::setCostType2(TraceCostType* ct) -+{ -+ if (ct == _costType2) return; -+ _costType2 = ct; -+ if (!_diagramMode) return; -+ -+ //TODO: get max cost(type1)/cost(type2) of shown parts -+ //partAreaWidget->setCostType(ct); -+} -+ -+void PartSelection::setGroupType(TraceItem::CostType gt) -+{ -+ if (gt == _groupType) return; -+ _groupType = gt; -+ -+ partAreaWidget->setGroupType(gt); -+} -+ -+void PartSelection::setGroup(TraceCostItem*) -+{ -+} -+ -+void PartSelection::setFunction(TraceFunction* f) -+{ -+ if (_function == f) return; -+ _function = f; -+ -+ //kdDebug() << "PartSelection::setFunction " << f->name() << endl; -+ -+ // FIXME: The TreeMap shouldn't produce spurious selectionChanged events -+ _inSelectionUpdate = true; -+ partAreaWidget->setFunction(_function); -+ _inSelectionUpdate = false; -+} -+ -+void PartSelection::setPart(TracePart*) -+{} -+ -+void PartSelection::currentChangedSlot(TreeMapItem* i, bool kbd) -+{ -+ if (!i) return; -+ if (!kbd) return; -+ if (i->text(0).isEmpty()) return; -+ -+ TQString str = i->text(0); -+ if (!i->text(1).isEmpty()) -+ str += " (" + i->text(1) + ")"; -+ TQString msg = i18n("Profile Part Overview: Current is '%1'").arg(str); -+ emit showMessage(msg, 5000); -+ -+ if (_showInfo) fillInfo(); -+} -+ -+ -+void PartSelection::doubleClicked(TreeMapItem* i) -+{ -+ if (!i || i->rtti() != 3) return; -+ -+ TraceCost* c = ((SubPartItem*) i)->partCostItem(); -+ TraceCostItem* ci = 0; -+ -+ switch(c->type()) { -+ case TraceItem::PartFunction: -+ { -+ TraceFunction* f = ((TracePartFunction*)c)->function(); -+ if (f) -+ emit functionChanged(f); -+ } -+ return; -+ -+ case TraceItem::PartObject: -+ ci = ((TracePartObject*)c)->object(); -+ break; -+ case TraceItem::PartClass: -+ ci = ((TracePartClass*)c)->cls(); -+ break; -+ case TraceItem::PartFile: -+ ci = ((TracePartFile*)c)->file(); -+ break; -+ default: -+ break; -+ } -+ -+ if (ci) -+ emit groupChanged(ci); -+} -+ -+ -+void PartSelection::selectionChanged() -+{ -+ if (_inSelectionUpdate) return; -+ -+ kdDebug() << "PartSelection::selectionChanged" << endl; -+ -+ bool something_changed = false; -+ bool nothingSelected = true; -+ -+ TracePartList pList; -+ TreeMapItem* i; -+ TracePart* part; -+ -+ // if nothing is selected, activate all parts -+ TreeMapItemList* list = partAreaWidget->base()->children(); -+ if (!list) return; -+ -+ for (i=list->first();i;i=list->next()) -+ if (partAreaWidget->isSelected(i)) { -+ nothingSelected = false; -+ break; -+ } -+ -+ for (i=list->first();i;i=list->next()) { -+ part = ((PartItem*)i)->part(); -+ bool active = nothingSelected || partAreaWidget->isSelected(i); -+ if (active) { -+ pList.append(part); -+ something_changed = true; -+ } -+ } -+ -+ if (something_changed) { -+ //qDebug("PartSelection: Something changed."); -+ emit activePartsChanged(pList); -+ } -+} -+ -+/* this makes the graph selection the same to the parts in the list */ -+void PartSelection::activePartsChangedSlot(const TracePartList& list) -+{ -+ _inSelectionUpdate = true; -+ -+ kdDebug() << "Entering PartSelection::activePartsChangedSlot" << endl; -+ -+ TreeMapItem* i; -+ TreeMapItemList l = *partAreaWidget->base()->children(); -+ // first deselect inactive, then select active (makes current active) -+ for (i=l.first();i;i=l.next()) { -+ TracePart* part = ((PartItem*)i)->part(); -+ bool active = (list.containsRef(part)>0); -+ if (!active && partAreaWidget->isSelected(i)) { -+#if 0 -+ qDebug("PartSelection::partsChangedSlot: Part %s changed to unselected.", -+ ((PartItem*)i)->part()->shortName().ascii()); -+#endif -+ -+ partAreaWidget->setSelected(i, false); -+ } -+ } -+ for (i=l.first();i;i=l.next()) { -+ TracePart* part = ((PartItem*)i)->part(); -+ bool active = (list.containsRef(part)>0); -+ if (active && !partAreaWidget->isSelected(i)) { -+#if 0 -+ qDebug("PartSelection::partsChangedSlot: Part %s changed to selected.", -+ ((PartItem*)i)->part()->shortName().ascii()); -+#endif -+ partAreaWidget->setSelected(i, true); -+ } -+ } -+ -+ _inSelectionUpdate = false; -+ -+ kdDebug() << "Leaving PartSelection::activePartsChangedSlot" << endl; -+ -+ fillInfo(); -+} -+ -+void PartSelection::contextMenuRequested(TreeMapItem* i, -+ const TQPoint & p) -+{ -+ if (!i) return; -+ -+ TQPopupMenu popup; -+ TQPopupMenu ppopup; -+ TQPopupMenu vpopup; -+ -+ TQString str; -+ TreeMapItem* s = 0; -+ -+ if (_data && (_data->parts().count()>1)) { -+ s = partAreaWidget->possibleSelection(i); -+ if (!s->text(0).isEmpty()) { -+ str = (partAreaWidget->isSelected(s)) ? -+ i18n("Deselect") : i18n("Select"); -+ str += " '" + s->text(0) + "'"; -+ popup.insertItem(str, 1); -+ } -+ -+ popup.insertItem(i18n("Select All Parts"), 2); -+ -+ popup.insertItem(i18n("Visible Parts"), &ppopup, 10); -+ -+ ppopup.insertItem(i18n("Hide Selected Parts"), 3); -+ ppopup.insertItem(i18n("Unhide Hidden Parts"), 4); -+ -+ popup.insertSeparator(); -+ } -+ -+ popup.insertItem(i18n("Go Back"), 99); -+ if (i->rtti() == 3) { -+ TreeMapItem* ni = i; -+ int id = 100; -+ while (ni && ni->rtti() == 3) { -+ TraceCost* c = ((SubPartItem*)ni)->partCostItem(); -+ if (c->type() == TraceItem::PartFunction) -+ if ( ((TracePartFunction*)c)->function() == _function) break; -+ -+ str = i18n("Select") + " '" + ni->text(0) + "'"; -+ popup.insertItem(str, id); -+ ni = ni->parent(); -+ id++; -+ } -+ } -+ popup.insertSeparator(); -+ -+ vpopup.setCheckable(true); -+ popup.insertItem(i18n("Visualization"), &vpopup, 10); -+ -+ vpopup.insertItem(i18n("Partitioning Mode"), 30); -+ vpopup.insertItem(i18n("Diagram Mode"), 34); -+ vpopup.insertItem(i18n("Zoom Function"), 31); -+ vpopup.insertItem(i18n("Show Direct Calls"), 32); -+ vpopup.insertItem(i18n("Increment Shown Call Levels"), 33); -+ if (partAreaWidget->visualisation() == PartAreaWidget::Partitioning) { -+ vpopup.setItemChecked(30, true); -+ vpopup.setItemEnabled(31, false); -+ vpopup.setItemEnabled(32, false); -+ vpopup.setItemEnabled(33, false); -+ } -+ else { -+ vpopup.setItemChecked(31, partAreaWidget->zoomFunction()); -+ } -+ vpopup.setItemChecked(34, _diagramMode); -+ -+ vpopup.insertSeparator(); -+ -+ vpopup.insertItem(i18n("Draw Names"), 20); -+ vpopup.insertItem(i18n("Draw Costs"), 21); -+ vpopup.insertItem(i18n("Ignore Proportions"), 22); -+ vpopup.insertItem(i18n("Draw Frames"), 24); -+ vpopup.insertItem(i18n("Allow Rotation"), 23); -+ if (!partAreaWidget->fieldVisible(0) && -+ !partAreaWidget->fieldVisible(1)) { -+ vpopup.setItemEnabled(22, false); -+ vpopup.setItemEnabled(23, false); -+ } -+ else { -+ vpopup.setItemChecked(20,partAreaWidget->fieldVisible(0)); -+ vpopup.setItemChecked(21,partAreaWidget->fieldVisible(1)); -+ vpopup.setItemChecked(22,partAreaWidget->fieldForced(0)); -+ vpopup.setItemChecked(23,partAreaWidget->allowRotation()); -+ vpopup.setItemChecked(24,_drawFrames); -+ } -+ -+ if (_showInfo) -+ popup.insertItem(i18n("Hide Info"), 40); -+ else -+ popup.insertItem(i18n("Show Info"), 41); -+ -+ int r = popup.exec(partAreaWidget->mapToGlobal(p)); -+ -+ if (r>=100) { -+ TreeMapItem* ci = i; -+ while (ci && r>100) { -+ ci = ci->parent(); -+ r--; -+ } -+ doubleClicked(ci); -+ return; -+ } -+ -+ switch(r) { -+ case 1: -+ // select/deselect part under mouse -+ partAreaWidget->setSelected(s, !partAreaWidget->isSelected(s)); -+ break; -+ -+ case 2: -+ // select all parts -+ { -+ TreeMapItemList list = *partAreaWidget->base()->children(); -+ partAreaWidget->setRangeSelection(list.first(), list.last(), true); -+ } -+ break; -+ -+ case 3: -+ emit partsHideSelected(); -+ break; -+ -+ case 4: -+ emit partsUnhideAll(); -+ break; -+ -+ case 99: -+ // last selected function -+ emit goBack(); -+ break; -+ -+ case 20: -+ partAreaWidget->setFieldVisible(0, !vpopup.isItemChecked(20)); -+ break; -+ -+ case 21: -+ partAreaWidget->setFieldVisible(1, !vpopup.isItemChecked(21)); -+ break; -+ -+ case 22: -+ partAreaWidget->setFieldForced(0, !vpopup.isItemChecked(22)); -+ partAreaWidget->setFieldForced(1, !vpopup.isItemChecked(22)); -+ break; -+ -+ case 23: partAreaWidget->setAllowRotation(!vpopup.isItemChecked(23)); break; -+ -+ case 24: -+ _drawFrames = !_drawFrames; -+ partAreaWidget->drawFrame(2,_drawFrames); -+ partAreaWidget->drawFrame(3,_drawFrames); -+ break; -+ -+ case 30: -+ partAreaWidget->setVisualisation(!vpopup.isItemChecked(30) ? -+ PartAreaWidget::Partitioning : -+ PartAreaWidget::Inclusive); -+ break; -+ -+ case 31: -+ // zoom/unzoom function -+ partAreaWidget->setZoomFunction(!vpopup.isItemChecked(31)); -+ break; -+ -+ case 32: -+ case 33: -+ // change call Levels -+ { -+ int l = (r==32) ? 1 : partAreaWidget->callLevels()+1; -+ partAreaWidget->setCallLevels(l); -+ } -+ break; -+ -+ case 34: -+ _diagramMode = !_diagramMode; -+ partAreaWidget->setTransparent(2,_diagramMode); -+ break; -+ -+ -+ case 40: -+ case 41: -+ showInfo(r==41); -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+void PartSelection::hiddenPartsChangedSlot(const TracePartList& list) -+{ -+ partAreaWidget->changeHidden(list); -+} -+ -+void PartSelection::readVisualisationConfig(KConfigGroup* config) -+{ -+ bool enable; -+ -+ TQString mode = config->readEntry("PartitionMode", "Inclusive"); -+ if (mode == "Inclusive") -+ partAreaWidget->setVisualisation(PartAreaWidget::Inclusive); -+ else -+ partAreaWidget->setVisualisation(PartAreaWidget::Partitioning); -+ -+ _diagramMode = config->readBoolEntry("DiagramMode", false); -+ partAreaWidget->setTransparent(2,_diagramMode); -+ -+ _drawFrames = config->readBoolEntry("DrawFrames", true); -+ partAreaWidget->drawFrame(2,_drawFrames); -+ partAreaWidget->drawFrame(3,_drawFrames); -+ -+ enable = config->readBoolEntry("GraphZoom", false); -+ partAreaWidget->setZoomFunction(enable); -+ -+ int levels = config->readNumEntry("GraphLevels", 1); -+ partAreaWidget->setCallLevels(levels); -+ -+ enable = config->readBoolEntry("GraphDrawName", true); -+ partAreaWidget->setFieldVisible(0, enable); -+ -+ enable = config->readBoolEntry("GraphDrawCost", true); -+ partAreaWidget->setFieldVisible(1, enable); -+ -+ enable = config->readBoolEntry("GraphForceStrings", false); -+ partAreaWidget->setFieldForced(0, enable); -+ partAreaWidget->setFieldForced(1, enable); -+ -+ enable = config->readBoolEntry("GraphAllowRotation", true); -+ partAreaWidget->setAllowRotation(enable); -+ -+ showInfo(config->readBoolEntry("ShowInfo", false)); -+} -+ -+void PartSelection::saveVisualisationConfig(KConfigGroup* config) -+{ -+ TQString mode; -+ if (partAreaWidget->visualisation() == PartAreaWidget::Inclusive) -+ mode = "Inclusive"; -+ else -+ mode = "Partitioning"; -+ config->writeEntry("PartitionMode", mode); -+ -+ config->writeEntry("DiagramMode", _diagramMode); -+ config->writeEntry("DrawFrames", _drawFrames); -+ -+ config->writeEntry("GraphZoom", partAreaWidget->zoomFunction()); -+ config->writeEntry("GraphLevels", partAreaWidget->callLevels()); -+ config->writeEntry("GraphDrawName", partAreaWidget->fieldVisible(0)); -+ config->writeEntry("GraphDrawCosts", partAreaWidget->fieldVisible(1)); -+ config->writeEntry("GraphForceStrings", partAreaWidget->fieldForced(0)); -+ config->writeEntry("GraphAllowRotation", partAreaWidget->allowRotation()); -+ -+ config->writeEntry("ShowInfo", _showInfo); -+} -+ -+void PartSelection::showInfo(bool enable) -+{ -+ if (_showInfo == enable) return; -+ -+ _showInfo = enable; -+ if (enable) { -+ rangeLabel->show(); -+ fillInfo(); -+ } -+ else -+ rangeLabel->hide(); -+} -+ -+void PartSelection::fillInfo() -+{ -+ if (!_data) { -+ rangeLabel->setText(i18n("(no trace loaded)")); -+ return; -+ } -+ -+ TQString info = _data->activePartRange(); -+ -+ TreeMapItem* i = partAreaWidget->current(); -+ while (i && i->rtti()!=2) i = i->parent(); -+ if (i) { -+ TracePart* part = ((PartItem*)i)->part(); -+ -+ //if (!part->trigger().isEmpty()) info += ", " + part->trigger(); -+ if (!part->timeframe().isEmpty()) -+ info += ", Time " + part->timeframe() + " BBs"; -+ } -+ else { -+ TracePart* part = _data->parts().first(); -+ -+ if (part && !part->version().isEmpty()) -+ info += ", Cachegrind " + part->version(); -+ } -+ -+ -+ rangeLabel->setText(info); -+} -+ -+#include "partselection.moc" -diff --git a/kdecachegrind/kdecachegrind/partselection.h b/kdecachegrind/kdecachegrind/partselection.h -new file mode 100644 -index 0000000..b8a195f ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partselection.h -@@ -0,0 +1,96 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * PartSelection for KCachegrind -+ * For part file selection, to be put into a TQDockWindow -+ */ -+ -+#ifndef PARTSELECTION_H -+#define PARTSELECTION_H -+ -+#include -+ -+#include "partselectionbase.h" -+#include "partgraph.h" -+#include "tracedata.h" -+ -+class KConfigGroup; -+class TraceFunction; -+class TraceData; -+class TreeMapItem; -+ -+class PartSelection: public PartSelectionBase -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ PartSelection( TQWidget* parent = 0, const char* name = 0); -+ ~PartSelection(); -+ -+ TraceData* data() { return _data; } -+ void setData(TraceData*); -+ -+ PartAreaWidget* graph() { return partAreaWidget; } -+ -+ void readVisualisationConfig(KConfigGroup*); -+ void saveVisualisationConfig(KConfigGroup*); -+ -+signals: -+ void activePartsChanged(const TracePartList& list); -+ void partsHideSelected(); -+ void partsUnhideAll(); -+ void groupChanged(TraceCostItem*); -+ void functionChanged(TraceItem*); -+ void showMessage(const TQString&, int); -+ void goBack(); -+ -+public slots: -+ void selectionChanged(); -+ void doubleClicked(TreeMapItem*); -+ void contextMenuRequested(TreeMapItem*, const TQPoint &); -+ void currentChangedSlot(TreeMapItem*, bool); -+ -+ void setPart(TracePart*); -+ void setCostType(TraceCostType*); -+ void setCostType2(TraceCostType*); -+ void setGroupType(TraceItem::CostType); -+ void setGroup(TraceCostItem*); -+ void setFunction(TraceFunction*); -+ void activePartsChangedSlot(const TracePartList& list); -+ void hiddenPartsChangedSlot(const TracePartList& list); -+ void refresh(); -+ void showInfo(bool); -+ -+private: -+ void fillInfo(); -+ -+ TraceData* _data; -+ TraceCostType *_costType, *_costType2; -+ TraceItem::CostType _groupType; -+ TraceCostItem* _group; -+ TraceFunction* _function; -+ bool _showInfo; -+ bool _diagramMode; -+ bool _drawFrames; -+ -+ bool _inSelectionUpdate; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/partselectionbase.ui b/kdecachegrind/kdecachegrind/partselectionbase.ui -new file mode 100644 -index 0000000..53320d5 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partselectionbase.ui -@@ -0,0 +1,89 @@ -+ -+PartSelectionBase -+ -+ -+ PartSelectionBase -+ -+ -+ -+ 0 -+ 0 -+ 460 -+ 402 -+ -+ -+ -+ Parts Overview -+ -+ -+ -+ unnamed -+ -+ -+ 6 -+ -+ -+ 6 -+ -+ -+ -+ partAreaWidget -+ -+ -+ -+ 5 -+ 7 -+ 0 -+ 0 -+ -+ -+ -+ -+ 0 -+ 50 -+ -+ -+ -+ -+ -+ rangeLabel -+ -+ -+ -+ 7 -+ 5 -+ 0 -+ 0 -+ -+ -+ -+ (no trace parts) -+ -+ -+ -+ -+ -+ -+ PartAreaWidget -+
partgraph.h
-+ -+ -1 -+ -1 -+ -+ 0 -+ -+ 5 -+ 7 -+ 0 -+ 0 -+ -+ image0 -+
-+
-+ -+ -+ 789c9597db4e1d4b0e86eff31428be8b46b5fb54dd551acd051020211c4320c0682eecaa5e9ccf90005bf3ee53cbbfe9d9c9c548a38ea27c2977b5cbfe6dd7fae3c3c2e1cee6c2873fde3d3cf2e3595a48a77cbff0213f5d5dbdfcf35ffff8f3ddfba65998fff161a179ffb777ef771f17d2c2d6cdf53807c705a889cdac6ee72c47736eebd637b5f2b672d70ecd30e744ca7d9b9a4ad7579587363433e527e5d072abefbb03636978ceb4a31c5bc13a91716ad41f89e0aec2fe74abcc6d6ad5f9e4945357375ef75f997357751dd61d19c71afb61bdef421b951f274ebaffb6716cb3f2b2f230f18d3183dd95b1b441d7d59f2e94757ccf1b27eceff69563618d0f5dcfd9d7beeb7a5dd7f3fac6fb4ee32b87c619f1168d976f7d6ff6df26d6ef4b301e1bac7f54f63e747a5e87f5c173276aff605c22a8fefc540e5e3af5972f956359577bf2c6d978cb78d6697edc9eb2f8b143fed7945359d778b0e6c3e7be81bf7465dce23cf4ac3c16567f19fecefaae53bd081b7baccbb131b7d05f679ca03f27c6b9d1f388c6bbaffab7f80dca4d1fed7bfafdbeedb9533d490f1e2ae8d5693ccacb83d77cd027e3d4416faa97beefa3d7f8f086f168f9d9020f43a3f5c5aa877e28eb88f74fe319becfaa873e0c15de775f95639f3dec37c143d361bf2be3cef4b76bdcb7d84ff5d2cbd0227facf1ecd360fa67d54b9f078ffcd10f636e11ff53e3847853ad3c1b668837e9fe43358c2df45a81430b3db2e6676842d368fd48abdc068b87e0fd2e788bf792b21f861e7afd0e0e5ce37dcdd7d0872218e5d789f57b3218a71ae7bb501eca3af67b510e21c05fd27a1b6218ac3ef17d0ed68fe8cb1be3fc6e5159863ca0bfed824340fe687d62c4838c23f677f0370de380fcdd2be7e03dfab1d6cf300bcd80fa80bfb358dbf9547fa18abe413d68fe421d63ade7737aded094cf63fdcc38f4d0bfee17dac2d08380a3a0dff24cb90bdc23ffaa87e0636c912fed87612e38d4df1e982bc4dbdd29872001f14aca319413eb793e83cbfbe8af27606e4c0f5f8d3bcb7763ec6b8da73b57e69083d61f9d82b9b5fada31f635fcaf8d7b7b5ffb41f16e34ff34fe214dfc0c8e1ef1a22330bfcdc345e31e4c33e3c1e6e181b1609e3ac43f8759803e8cd9f2e7e0ff18ab80ef5d8239e2fc0ef129f90ff0bf0773347fee8d13ce279bc6b34af5c61abf58157bf4b765b05435f4abfec726968c2b67e536fa80fe388279067f680d2c750dff75fe9766da07e44bc02521ba4e1d584c1fb261dcc23fd97f63f8c3af136bfc687362c4e76962ed8fac7a2ecdb7853f7c63ec6bf467bd3fc421c680780c60b6f9275fc045aea84fadaf18a2e0fc04ff0237bd9e8fefc0d236e8ef3f8d83c57fdd38daf94edeb886be74fec618b3ed7f3731e66b0fe67a403e76c0454ef8de9231dbfe9f8dc5fc47be38a6887ad2f950964d2fdc1a27d3c7b6710693f6ef9864b4fdb4ffc6cc5540fea0972c339c87afc1c9f4443a5fe2c84d40bd2f82cb3ae6c7b1716dbc37b1e68bf5be118b7e3dead78125d87d0bfa99bd7d8fb78c1bdb4fcfcfd51bcb9d716bebda3fb8966cf7cf57709103f2e327c6fe5a2fdc4ab4fb01deef5283fa65d50ffb54c13fd67ec37d61e845fb070f8571df7c341eec7e7a691c6ae453fb771937d1fa999ebfa43358bf573d3327c6fdd0a9de59b87414e59f60911ef3ff07380d16bf0b63b6fbb8ce0f4e523a80ee8ff8a5f21fe83f384f2e8cf9d419db7d4bb4bff32cb1dd871ae38c79417962dd9f8f2786bfaa3fa992ddbf68d5d8d6797d62dc27b4bf4a9bdeee5be7c619efbb169c2b9bb7aa67e972857a67d59bf8943cf4a6f5237dae3b9c3f4f8cef5713637e6a3c6548e546a7eb87e0b28e7cf7c68ddd2fb15f28acf166bd2f484c19f921f8cbc57de84ff52c397b8f7e178d7bbb7f7e9f18f743d593ccd210d12f9e8c05fd8417c1e5e704e2afefa7aa5cf850ff4fc6a1473debfc4d7561c4ebd3c48897f69fd4e4d8eb7e4efb736a0b23fe9adfd465bb3f388d6ff22933fa1df6f7597ad483c62371f6e6ff8671b6f89e198fb8cfb0ea3f49619c6f6562cc27d5474a7906e6b589d1df549f29e78479450fe0b1c2fc67d5731a0ba33ffc97a167fd7d92ebb1b1f9a87acdcdd8a23ff2e3c4a81fed0fb91bbb88f8e9f772f9b9c6b8bfac187bd41febbcc8c35831f4bb6edc227eeec8b847bc58ef0f398d91a1179d6f391746bdebfd60ac4716b0180bd8a97e473f8ea2dfdb7d9c3f8e1cff8f8760057b27e57f92cb6e743377e24efff29cb97377e12edd55b190c99eddb5bb71b7eeceddbb07f7e89edc0ff7d33dbb17f7ea16dd925b761fdd8a63d8174f52b15e756bee93fbecd6dd17b7e136dd96db763b6ed77d2dd67bee9bdb77078ed49e8b27b7c5fabb3b7447eed855ae768d6bcbd339ef7a37b8e022392a2734fbd1dd119350a24c23cde8844ee98ccee9c2f9c2977445d77443b793fd8ceee89e1ee8919ee807fdb4e7995ee8b5d82fd252b15ffe8bfd097da4155aa535fa34597fa6f5f2f717da28f69bb445dbb433d99fd22e7da53dfa3659efd3017da7c3f2af233aa68aeadfec1b6aa9236fd63d0d14ca15c0719913737b965fedcbf0c83cc29a677cc2a77cc6e77cc1977cc5d7c5fee637fbdbb2db9d5adff343b17ee427fec1737ee69762fffa9bfd222ff17259fdc82bbcca6bfc893ff33a7fe10ddee42ddee69ddfec77f92beff137dee703fece877cc4c7aee58a6b6ee8b8fc10ed7eb13f635f9a4bc5e54719477152ba671977a505c84845c57222a7bfd89fcb999ccb855cca955cbfc5546ee456ee68b14cf67b799047799aec2fdc92fc28999cef567224cff222afb2c85b32e36d599265f9282bb23ad95fba6559934f2593f3e798b74acc8fd5f6b3accb17d9904dd9926db3a7520d1fdd37d9915df95a72599e1291566df7e49beccb817c974339829eb55e56dc7e51ec0d2dcbb1545297a791563af1c5eff2d3beb4faf8562f568f0744745b9e9d5f1f7992d5e412a186ffef7afff7dfdffd077c99ae99 -+ -+ -+ -+
-diff --git a/kdecachegrind/kdecachegrind/partview.cpp b/kdecachegrind/kdecachegrind/partview.cpp -new file mode 100644 -index 0000000..3f344bb ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partview.cpp -@@ -0,0 +1,235 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Part View -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "partlistitem.h" -+#include "toplevel.h" -+#include "partview.h" -+ -+ -+ -+// -+// PartView -+// -+ -+ -+PartView::PartView(TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQListView(parent, name), TraceItemView(parentView) -+{ -+ _inSelectionUpdate = false; -+ -+ addColumn( i18n( "Profile Part" ) ); -+ addColumn( i18n( "Incl." ) ); -+ addColumn( i18n( "Self" ) ); -+ addColumn( i18n( "Called" ) ); -+ //addColumn( i18n( "Fixed" ) ); -+ addColumn( i18n( "Comment" ) ); -+ -+ setAllColumnsShowFocus(true); -+ setColumnAlignment(1, TQt::AlignRight); -+ setColumnAlignment(2, TQt::AlignRight); -+ setColumnAlignment(3, TQt::AlignRight); -+ setMinimumHeight(50); -+ setSelectionMode(Extended); -+ -+ connect( this, -+ TQT_SIGNAL( selectionChanged() ), -+ TQT_SLOT( selectionChangedSlot() ) ); -+ -+ connect( this, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int))); -+ -+ TQWhatsThis::add( this, whatsThis() ); -+} -+ -+TQString PartView::whatsThis() const -+{ -+ return i18n( "Trace Part List" -+ "

This list shows all trace parts of the loaded " -+ "trace. For each part, the " -+ "self/inclusive cost of the current selected " -+ "function, spent in the part, is shown; " -+ "percentage costs are always relative to the " -+ "total cost of the part (not to the whole " -+ "trace as in the Trace Part Overview). " -+ "Also shown are the calls happening to/from the " -+ "current function inside of the trace part.

" -+ "

By choosing one or more trace parts from the " -+ "list, the costs shown all over KCachegrind will " -+ "only be the ones spent in the selected part(s). " -+ "If no list selection is shown, in fact all trace " -+ "parts are selected implicitly.

" -+ "

This is a multi-selection list. You can select " -+ "ranges by dragging the mouse or use SHIFT/CTRL " -+ "modifiers. " -+ "Selection/Deselection of trace parts can also be " -+ "done by using the Trace Part Overview Dockable. " -+ "This one also supports multiple selection.

" -+ "

Note that the list is hidden if only one trace " -+ "part is loaded.

"); -+} -+ -+ -+void PartView::context(TQListViewItem* i, const TQPoint & pos, int) -+{ -+ TQPopupMenu popup; -+ -+ TracePart* p = i ? ((PartListItem*) i)->part() : 0; -+ -+ if (p) { -+ popup.insertItem(i18n("Select '%1'").arg(p->name()), 93); -+ popup.insertItem(i18n("Hide '%1'").arg(p->name()), 94); -+ popup.insertSeparator(); -+ } -+ -+ popup.insertItem(i18n("Hide Selected"), 95); -+ popup.insertItem(i18n("Show All"), 96); -+ popup.insertSeparator(); -+ -+ addGoMenu(&popup); -+ -+ int r = popup.exec(pos); -+ if (r == 95) { -+ ; -+ } -+ -+ // TODO: ... -+} -+ -+void PartView::selectionChangedSlot() -+{ -+ if (_inSelectionUpdate) return; -+ -+ TracePartList l; -+ TQListViewItem* item = firstChild(); -+ for(;item;item = item->nextSibling()) -+ if (item->isSelected()) -+ l.append( ((PartListItem*)item)->part() ); -+ -+ selected(l); -+} -+ -+ -+TraceItem* PartView::canShow(TraceItem* i) -+{ -+ if (!TraceItemView::data()) return 0; -+ if (TraceItemView::data()->parts().count()>1) return i; -+ return 0; -+} -+ -+void PartView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == costType2Changed) return; -+ if (changeType == selectedItemChanged) return; -+ -+ if (changeType == groupTypeChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) -+ ((PartListItem*)item)->setGroupType(_groupType); -+ -+ return; -+ } -+ -+ if (changeType == costTypeChanged) { -+ TQListViewItem *item; -+ for (item = firstChild();item;item = item->nextSibling()) -+ ((PartListItem*)item)->setCostType(_costType); -+ -+ return; -+ } -+ -+ if (changeType == partsChanged) { -+ -+ TracePart* part; -+ -+ TQListViewItem* item; -+ _inSelectionUpdate = true; -+ item = firstChild(); -+ for(;item;item = item->nextSibling()) { -+ part = ((PartListItem*)item)->part(); -+ -+ if (_partList.containsRef(part)>0) { -+ setSelected(item, true); -+ ensureItemVisible(item); -+ } -+ else -+ setSelected(item, false); -+ } -+ _inSelectionUpdate = false; -+ -+ return; -+ } -+ -+ refresh(); -+} -+ -+void PartView::refresh() -+{ -+ clear(); -+ setColumnWidth(1, 50); -+ setColumnWidth(2, 50); -+ -+ if (!_data || !_activeItem) return; -+ -+ TraceItem::CostType t = _activeItem->type(); -+ TraceFunction* f = 0; -+ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem; -+ if (!f) return; -+ -+ TracePart* part; -+ TracePartList hidden; -+ if (_topLevel) -+ hidden = _topLevel->hiddenParts(); -+ -+ TracePartList allParts = _data->parts(); -+ -+ _inSelectionUpdate = true; -+ -+ TQListViewItem* item = 0; -+ for (part = allParts.first(); part; part = allParts.next()) { -+ if (hidden.findRef(part)>=0) continue; -+ item = new PartListItem(this, f, _costType, _groupType, part); -+ -+ if (part->isActive()) { -+ setSelected(item, true); -+ ensureItemVisible(item); -+ } -+ } -+ -+ _inSelectionUpdate = false; -+ -+ if (item) { -+ int headerHeight = header()->height(); -+ int itemHeight = item->height(); -+ setMinimumHeight(headerHeight + 2*itemHeight + 2); -+ } -+} -+ -+#include "partview.moc" -diff --git a/kdecachegrind/kdecachegrind/partview.h b/kdecachegrind/kdecachegrind/partview.h -new file mode 100644 -index 0000000..92761cc ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/partview.h -@@ -0,0 +1,55 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Part View -+ */ -+ -+#ifndef PARTVIEW_H -+#define PARTVIEW_H -+ -+#include -+#include "tracedata.h" -+#include "traceitemview.h" -+ -+class PartView: public TQListView, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ PartView(TraceItemView* parentView, -+ TQWidget* parent=0, const char* name=0); -+ -+ virtual TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ -+ void refresh(); -+ -+private slots: -+ void context(TQListViewItem*,const TQPoint &, int); -+ void selectionChangedSlot(); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ -+ bool _inSelectionUpdate; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/pool.cpp b/kdecachegrind/kdecachegrind/pool.cpp -new file mode 100644 -index 0000000..d4a89a7 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/pool.cpp -@@ -0,0 +1,258 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002-2004 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include -+#include -+#include -+#include "pool.h" -+ -+// FixPool -+ -+#define CHUNK_SIZE 100000 -+ -+struct SpaceChunk -+{ -+ struct SpaceChunk* next; -+ unsigned int used; -+ char space[1]; -+}; -+ -+FixPool::FixPool() -+{ -+ _first = _last = 0; -+ _reservation = 0; -+ _count = 0; -+ _size = 0; -+} -+ -+FixPool::~FixPool() -+{ -+ struct SpaceChunk* chunk = _first, *next; -+ -+ while(chunk) { -+ next = chunk->next; -+ free(chunk); -+ chunk = next; -+ } -+ -+ if (0) qDebug("~FixPool: Had %d objects with total size %d\n", -+ _count, _size); -+} -+ -+void* FixPool::allocate(unsigned int size) -+{ -+ if (!ensureSpace(size)) return 0; -+ -+ _reservation = 0; -+ void* result = _last->space + _last->used; -+ _last->used += size; -+ -+ _count++; -+ _size += size; -+ -+ return result; -+} -+ -+void* FixPool::reserve(unsigned int size) -+{ -+ if (!ensureSpace(size)) return 0; -+ _reservation = size; -+ -+ return _last->space + _last->used; -+} -+ -+ -+bool FixPool::allocateReserved(unsigned int size) -+{ -+ if (_reservation < size) return false; -+ -+ _reservation = 0; -+ _last->used += size; -+ -+ _count++; -+ _size += size; -+ -+ return true; -+} -+ -+bool FixPool::ensureSpace(unsigned int size) -+{ -+ if (_last && _last->used + size <= CHUNK_SIZE) return true; -+ -+ struct SpaceChunk* newChunk; -+ -+ // we don't allow allocation sizes > CHUNK_SIZE -+ if (size > CHUNK_SIZE) return false; -+ -+ newChunk = (struct SpaceChunk*) malloc(sizeof(struct SpaceChunk) + -+ CHUNK_SIZE); -+ newChunk->next = 0; -+ newChunk->used = 0; -+ -+ if (!_last) { -+ _last = _first = newChunk; -+ } -+ else { -+ _last->next = newChunk; -+ _last = newChunk; -+ } -+ return true; -+} -+ -+ -+// DynPool -+ -+DynPool::DynPool() -+{ -+ _data = (char*) malloc(CHUNK_SIZE); -+ _used = 0; -+ _size = CHUNK_SIZE; -+ -+ // end marker -+ *(int*)_data = 0; -+} -+ -+DynPool::~DynPool() -+{ -+ // we could check for correctness by iteration over all objects -+ -+ ::free(_data); -+} -+ -+bool DynPool::allocate(char** ptr, unsigned int size) -+{ -+ // round up to multiple of 4 -+ size = (size+3) & ~3; -+ -+ /* need 12 bytes more: -+ * - 4 bytes for forward chain -+ * - 4 bytes for pointer to ptr -+ * - 4 bytes as end marker (not used for new object) -+ */ -+ if (!ensureSpace(size + 12)) return false; -+ -+ char** obj = (char**) (_data+_used); -+ obj[0] = (char*)(_data + _used + size + 8); -+ obj[1] = (char*)ptr; -+ *(int*)(_data+_used+size+8) = 0; -+ *ptr = _data+_used+8; -+ -+ _used += size + 8; -+ -+ return true; -+} -+ -+void DynPool::free(char** ptr) -+{ -+ if (!ptr || -+ !*ptr || -+ (*(char**)(*ptr - 4)) != (char*)ptr ) -+ qFatal("Chaining error in DynPool::free"); -+ -+ (*(char**)(*ptr - 4)) = 0; -+ *ptr = 0; -+} -+ -+bool DynPool::ensureSpace(unsigned int size) -+{ -+ if (_used + size <= _size) return true; -+ -+ unsigned int newsize = _size *3/2 + CHUNK_SIZE; -+ char* newdata = (char*) malloc(newsize); -+ -+ unsigned int freed = 0, len; -+ char **p, **pnext, **pnew; -+ -+ qDebug("DynPool::ensureSpace size: %d => %d, used %d. %p => %p", -+ _size, newsize, _used, _data, newdata); -+ -+ pnew = (char**) newdata; -+ p = (char**) _data; -+ while(*p) { -+ pnext = (char**) *p; -+ len = (char*)pnext - (char*)p; -+ -+ if (0) qDebug(" [%8p] Len %d (ptr %p), freed %d (=> %p)", -+ p, len, p[1], freed, pnew); -+ -+ /* skip freed space ? */ -+ if (p[1] == 0) { -+ freed += len; -+ p = pnext; -+ continue; -+ } -+ -+ // new and old still at same address ? -+ if (pnew == p) { -+ pnew = p = pnext; -+ continue; -+ } -+ -+ // copy object -+ pnew[0] = (char*)pnew + len; -+ pnew[1] = p[1]; -+ memcpy((char*)pnew + 8, (char*)p + 8, len-8); -+ -+ // update pointer to object -+ char** ptr = (char**) p[1]; -+ if (*ptr != ((char*)p)+8) -+ qFatal("Chaining error in DynPool::ensureSpace"); -+ *ptr = ((char*)pnew)+8; -+ -+ pnew = (char**) pnew[0]; -+ p = pnext; -+ } -+ pnew[0] = 0; -+ -+ unsigned int newused = (char*)pnew - (char*)newdata; -+ qDebug("DynPool::ensureSpace size: %d => %d, used %d => %d (%d freed)", -+ _size, newsize, _used, newused, freed); -+ -+ ::free(_data); -+ _data = newdata; -+ _size = newsize; -+ _used = newused; -+ -+ return true; -+} -+ -+/* Testing the DynPool -+int main() -+{ -+ char* bufs[CHUNK_SIZE]; -+ int i; -+ -+ DynPool p; -+ -+ for(i=0;i20)) -+ p.free(bufs+i-20); -+ } -+ -+ for(i=0;i -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#ifndef POOL_H -+#define POOL_H -+ -+/** -+ * Pool objects: containers for many small objects. -+ */ -+ -+struct SpaceChunk; -+ -+/** -+ * FixPool -+ * -+ * For objects with fixed size and life time -+ * ending with that of the pool. -+ */ -+class FixPool -+{ -+ public: -+ FixPool(); -+ ~FixPool(); -+ -+ /** -+ * Take bytes from the pool -+ */ -+ void* allocate(unsigned int size); -+ -+ /** -+ * Reserve space. If you call allocateReservedSpace(realsize) -+ * with realSize < reserved size directly after, you -+ * will get the same memory area. -+ */ -+ void* reserve(unsigned int size); -+ -+ /** -+ * Before calling this, you have to reserve at least bytes -+ * with reserveSpace(). -+ */ -+ bool allocateReserved(unsigned int size); -+ -+ private: -+ /* Checks that there is enough space in the last chunk. -+ * Returns false if this is not possible. -+ */ -+ bool ensureSpace(unsigned int); -+ -+ struct SpaceChunk *_first, *_last; -+ unsigned int _reservation; -+ int _count, _size; -+}; -+ -+/** -+ * DynPool -+ * -+ * For objects which probably need to be resized -+ * in the future. Objects also can be deleted to free up space. -+ * As objects can also be moved in a defragmentation step, -+ * access has to be done via the given pointer object. -+ */ -+class DynPool -+{ -+ public: -+ DynPool(); -+ ~DynPool(); -+ -+ /** -+ * Take bytes from the pool, changing <*ptr> -+ * to point to this allocated space. -+ * <*ptr> will be changed if the object is moved. -+ * Returns false if no space available. -+ */ -+ bool allocate(char** ptr, unsigned int size); -+ -+ /** -+ * To resize, first allocate new space, and free old -+ * afterwards. -+ */ -+ void free(char** ptr); -+ -+ private: -+ /* Checks that there is enough space. If not, -+ * it compactifies, possibly moving objects. -+ */ -+ bool ensureSpace(unsigned int); -+ -+ char* _data; -+ unsigned int _used, _size; -+}; -+ -+#endif // POOL_H -diff --git a/kdecachegrind/kdecachegrind/sourceitem.cpp b/kdecachegrind/kdecachegrind/sourceitem.cpp -new file mode 100644 -index 0000000..305b824 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/sourceitem.cpp -@@ -0,0 +1,444 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of source view. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "listutils.h" -+#include "sourceview.h" -+#include "sourceitem.h" -+ -+ -+// SourceItem -+ -+// for source lines -+SourceItem::SourceItem(SourceView* sv, TQListView* parent, -+ int fileno, unsigned int lineno, -+ bool inside, const TQString& src, -+ TraceLine* line) -+ : TQListViewItem(parent) -+{ -+ _view = sv; -+ _lineno = lineno; -+ _fileno = fileno; -+ _inside = inside; -+ _line = line; -+ _lineCall = 0; -+ _lineJump = 0; -+ -+ if (src == "...") -+ setText(0, src); -+ else -+ setText(0, TQString::number(lineno)); -+ -+ TQString s = src; -+ setText(4, s.replace( TQRegExp("\t"), " " )); -+ -+ updateGroup(); -+ updateCost(); -+} -+ -+// for call lines -+SourceItem::SourceItem(SourceView* sv, TQListViewItem* parent, -+ int fileno, unsigned int lineno, -+ TraceLine* line, TraceLineCall* lineCall) -+ : TQListViewItem(parent) -+{ -+ _view = sv; -+ _lineno = lineno; -+ _fileno = fileno; -+ _inside = true; -+ _line = line; -+ _lineCall = lineCall; -+ _lineJump = 0; -+ -+ //qDebug("SourceItem: (file %d, line %d) Linecall to %s", -+ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii()); -+ -+ SubCost cc = _lineCall->callCount(); -+ TQString templ = " "; -+ if (cc==0) -+ templ += i18n("Active call to '%1'"); -+ else -+ templ += i18n("%n call to '%1'", "%n calls to '%1'", cc); -+ -+ TQString callStr = templ.arg(_lineCall->call()->calledName()); -+ TraceFunction* calledF = _lineCall->call()->called(); -+ calledF->addPrettyLocation(callStr); -+ -+ setText(4, callStr); -+ -+ updateGroup(); -+ updateCost(); -+} -+ -+// for jump lines -+SourceItem::SourceItem(SourceView* sv, TQListViewItem* parent, -+ int fileno, unsigned int lineno, -+ TraceLine* line, TraceLineJump* lineJump) -+ : TQListViewItem(parent) -+{ -+ _view = sv; -+ _lineno = lineno; -+ _fileno = fileno; -+ _inside = true; -+ _line = line; -+ _lineCall = 0; -+ _lineJump = lineJump; -+ -+ //qDebug("SourceItem: (file %d, line %d) Linecall to %s", -+ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii()); -+ -+ TQString to; -+ if (_lineJump->lineTo()->functionSource() == _line->functionSource()) -+ to = _lineJump->lineTo()->name(); -+ else -+ to = _lineJump->lineTo()->prettyName(); -+ -+ TQString jStr; -+ if (_lineJump->isCondJump()) -+ jStr = i18n("Jump %1 of %2 times to %3") -+ .arg(_lineJump->followedCount().pretty()) -+ .arg(_lineJump->executedCount().pretty()) -+ .arg(to); -+ else -+ jStr = i18n("Jump %1 times to %2") -+ .arg(_lineJump->executedCount().pretty()) -+ .arg(to); -+ -+ setText(4, jStr); -+} -+ -+ -+void SourceItem::updateGroup() -+{ -+ if (!_lineCall) return; -+ -+ TraceFunction* f = _lineCall->call()->called(); -+ TQColor c = Configuration::functionColor(_view->groupType(), f); -+ setPixmap(4, colorPixmap(10, 10, c)); -+} -+ -+void SourceItem::updateCost() -+{ -+ _pure = SubCost(0); -+ _pure2 = SubCost(0); -+ -+ if (!_line) return; -+ if (_lineJump) return; -+ -+ TraceCost* lineCost = _lineCall ? (TraceCost*)_lineCall : (TraceCost*)_line; -+ -+ // don't show any cost inside of cycles -+ if (_lineCall && -+ ((_lineCall->call()->inCycle()>0) || -+ (_lineCall->call()->isRecursion()>0))) { -+ TQString str; -+ TQPixmap p; -+ -+ TQString icon = "undo"; -+ KIconLoader* loader = KApplication::kApplication()->iconLoader(); -+ p= loader->loadIcon(icon, KIcon::Small, 0, -+ KIcon::DefaultState, 0, true); -+ if (p.isNull()) -+ str = i18n("(cycle)"); -+ -+ setText(1, str); -+ setPixmap(1, p); -+ setText(2, str); -+ setPixmap(2, p); -+ return; -+ } -+ -+ TraceCost* totalCost; -+ if (Configuration::showExpanded()) -+ totalCost = _line->functionSource()->function()->inclusive(); -+ else -+ totalCost = _line->functionSource()->function()->data(); -+ -+ TraceCostType* ct = _view->costType(); -+ _pure = ct ? lineCost->subCost(ct) : SubCost(0); -+ if (_pure == 0) { -+ setText(1, TQString()); -+ setPixmap(1, TQPixmap()); -+ } -+ else { -+ double total = totalCost->subCost(ct); -+ double pure = 100.0 * _pure / total; -+ -+ if (Configuration::showPercentage()) -+ setText(1, TQString("%1") -+ .arg(pure, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(1, _pure.pretty()); -+ -+ setPixmap(1, costPixmap(ct, lineCost, total, false)); -+ } -+ -+ TraceCostType* ct2 = _view->costType2(); -+ _pure2 = ct2 ? lineCost->subCost(ct2) : SubCost(0); -+ if (_pure2 == 0) { -+ setText(2, TQString()); -+ setPixmap(2, TQPixmap()); -+ } -+ else { -+ double total = totalCost->subCost(ct2); -+ double pure2 = 100.0 * _pure2 / total; -+ -+ if (Configuration::showPercentage()) -+ setText(2, TQString("%1") -+ .arg(pure2, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(2, _pure2.pretty()); -+ -+ setPixmap(2, costPixmap(ct2, lineCost, total, false)); -+ } -+} -+ -+ -+int SourceItem::compare(TQListViewItem * i, int col, bool ascending ) const -+{ -+ const SourceItem* si1 = this; -+ const SourceItem* si2 = (SourceItem*) i; -+ -+ // we always want descending order -+ if (((col>0) && ascending) || -+ ((col==0) && !ascending) ) { -+ si1 = si2; -+ si2 = this; -+ } -+ -+ if (col==1) { -+ if (si1->_pure < si2->_pure) return -1; -+ if (si1->_pure > si2->_pure) return 1; -+ return 0; -+ } -+ if (col==2) { -+ if (si1->_pure2 < si2->_pure2) return -1; -+ if (si1->_pure2 > si2->_pure2) return 1; -+ return 0; -+ } -+ if (col==0) { -+ // Sort file numbers -+ if (si1->_fileno < si2->_fileno) return -1; -+ if (si1->_fileno > si2->_fileno) return 1; -+ -+ // Sort line numbers -+ if (si1->_lineno < si2->_lineno) return -1; -+ if (si1->_lineno > si2->_lineno) return 1; -+ -+ // Same line: code gets above calls/jumps -+ if (!si1->_lineCall && !si1->_lineJump) return -1; -+ if (!si2->_lineCall && !si2->_lineJump) return 1; -+ -+ // calls above jumps -+ if (si1->_lineCall && !si2->_lineCall) return -1; -+ if (si2->_lineCall && !si1->_lineCall) return 1; -+ -+ if (si1->_lineCall && si2->_lineCall) { -+ // Two calls: desending sort according costs -+ if (si1->_pure < si2->_pure) return 1; -+ if (si1->_pure > si2->_pure) return -1; -+ -+ // Two calls: sort according function names -+ TraceFunction* f1 = si1->_lineCall->call()->called(); -+ TraceFunction* f2 = si2->_lineCall->call()->called(); -+ if (f1->prettyName() > f2->prettyName()) return 1; -+ return -1; -+ } -+ -+ // Two jumps: descending sort according target line -+ if (si1->_lineJump->lineTo()->lineno() < -+ si2->_lineJump->lineTo()->lineno()) -+ return -1; -+ if (si1->_lineJump->lineTo()->lineno() > -+ si2->_lineJump->lineTo()->lineno()) -+ return 1; -+ return 0; -+ } -+ return TQListViewItem::compare(i, col, ascending); -+} -+ -+void SourceItem::paintCell( TQPainter *p, const TQColorGroup &cg, -+ int column, int width, int alignment ) -+{ -+ TQColorGroup _cg( cg ); -+ -+ if ( !_inside || ((column==1) || (column==2))) -+ _cg.setColor( TQColorGroup::Base, cg.button() ); -+ else if ((_lineCall || _lineJump) && column>2) -+ _cg.setColor( TQColorGroup::Base, cg.midlight() ); -+ -+ if (column == 3) -+ paintArrows(p, _cg, width); -+ else -+ TQListViewItem::paintCell( p, _cg, column, width, alignment ); -+} -+ -+void SourceItem::setJumpArray(const TQMemArray& a) -+{ -+ _jump.duplicate(a); -+} -+ -+void SourceItem::paintArrows(TQPainter *p, const TQColorGroup &cg, int width) -+{ -+ TQListView *lv = listView(); -+ if ( !lv ) return; -+ SourceView* sv = (SourceView*) lv; -+ -+ const BackgroundMode bgmode = lv->viewport()->backgroundMode(); -+ const TQColorGroup::ColorRole crole -+ = TQPalette::backgroundRoleFromMode( bgmode ); -+ if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) ) -+ p->fillRect( 0, 0, width, height(), cg.brush( crole ) ); -+ else -+ sv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) ); -+ -+ if ( isSelected() && lv->allColumnsShowFocus() ) -+ p->fillRect( 0, 0, width, height(), cg.brush( TQColorGroup::Highlight ) ); -+ -+ int marg = lv->itemMargin(); -+ int yy = height()/2, y1, y2; -+ TQColor c; -+ -+ int start = -1, end = -1; -+ -+ // draw line borders, detect start/stop of a line -+ for(int i=0;i< (int)_jump.size();i++) { -+ if (_jump[i] == 0) continue; -+ -+ y1 = 0; -+ y2 = height(); -+ if (_lineJump && -+ (_lineJump->lineTo() == _jump[i]->lineTo()) && -+ (_jump[i]->lineFrom()->lineno() == _lineno)) { -+ -+ if (start<0) start = i; -+ if (_lineJump == _jump[i]) { -+ if (_jump[i]->lineTo()->lineno() <= _lineno) -+ y2 = yy; -+ else -+ y1 = yy; -+ } -+ } -+ else if (!_lineJump && !_lineCall && -+ (_jump[i]->lineTo()->lineno() == _lineno)) { -+ if (end<0) end = i; -+ if (_jump[i]->lineFrom()->lineno() < _lineno) -+ y2 = yy; -+ else -+ y1 = yy; -+ } -+ -+ c = _jump[i]->isCondJump() ? red : blue; -+ p->fillRect( marg + 6*i, y1, 4, y2, c); -+ p->setPen(c.light()); -+ p->drawLine( marg + 6*i, y1, marg + 6*i, y2); -+ p->setPen(c.dark()); -+ p->drawLine( marg + 6*i +3, y1, marg + 6*i +3, y2); -+ } -+ -+ // draw start/stop horizontal line -+ int x, y = yy-2, w, h = 4; -+ if (start >= 0) { -+ c = _jump[start]->isCondJump() ? red : blue; -+ x = marg + 6*start; -+ w = 6*(sv->arrowLevels() - start) + 10; -+ p->fillRect( x, y, w, h, c); -+ p->setPen(c.light()); -+ p->drawLine(x, y, x+w-1, y); -+ p->drawLine(x, y, x, y+h-1); -+ p->setPen(c.dark()); -+ p->drawLine(x+w-1, y, x+w-1, y+h-1); -+ p->drawLine(x+1, y+h-1, x+w-1, y+h-1); -+ } -+ if (end >= 0) { -+ c = _jump[end]->isCondJump() ? red : blue; -+ x = marg + 6*end; -+ w = 6*(sv->arrowLevels() - end) + 10; -+ -+ TQPointArray a; -+ a.putPoints(0, 7, x, y+h, -+ x,y, x+w-8, y, x+w-8, y-2, -+ x+w, yy, -+ x+w-8, y+h+2, x+w-8, y+h); -+ p->setBrush(c); -+ p->drawConvexPolygon(a); -+ -+ p->setPen(c.light()); -+ p->drawPolyline(a, 0, 5); -+ p->setPen(c.dark()); -+ p->drawPolyline(a, 4, 2); -+ p->setPen(c.light()); -+ p->drawPolyline(a, 5, 2); -+ p->setPen(c.dark()); -+ p->drawPolyline(a, 6, 2); -+ } -+ -+ // draw inner vertical line for start/stop -+ // this overwrites borders of horizontal line -+ for(int i=0;i< (int)_jump.size();i++) { -+ if (_jump[i] == 0) continue; -+ -+ c = _jump[i]->isCondJump() ? red : blue; -+ -+ if (_jump[i]->lineFrom()->lineno() == _lineno) { -+ bool drawUp = true; -+ if (_jump[i]->lineTo()->lineno() == _lineno) -+ if (start<0) drawUp = false; -+ if (_jump[i]->lineTo()->lineno() > _lineno) drawUp = false; -+ if (drawUp) -+ p->fillRect( marg + 6*i +1, 0, 2, yy, c); -+ else -+ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c); -+ } -+ else if (_jump[i]->lineTo()->lineno() == _lineno) { -+ if (end<0) end = i; -+ if (_jump[i]->lineFrom()->lineno() < _lineno) -+ p->fillRect( marg + 6*i +1, 0, 2, yy, c); -+ else -+ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c); -+ } -+ } -+ -+} -+ -+int SourceItem::width( const TQFontMetrics& fm, -+ const TQListView* lv, int c ) const -+{ -+ if (c != 3) return TQListViewItem::width(fm, lv, c); -+ -+ SourceView* sv = (SourceView*) lv; -+ int levels = sv->arrowLevels(); -+ -+ if (levels == 0) return 0; -+ -+ // 10 pixels for the arrow -+ return 10 + 6*levels + lv->itemMargin() * 2; -+} -+ -diff --git a/kdecachegrind/kdecachegrind/sourceitem.h b/kdecachegrind/kdecachegrind/sourceitem.h -new file mode 100644 -index 0000000..925e575 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/sourceitem.h -@@ -0,0 +1,84 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of source view. -+ */ -+ -+#ifndef SOURCEITEM_H -+#define SOURCEITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class SourceView; -+ -+class SourceItem: public TQListViewItem -+{ -+public: -+ // for source lines -+ SourceItem(SourceView* sv, TQListView* parent, -+ int fileno, unsigned int lineno, -+ bool inside, const TQString& src, -+ TraceLine* line = 0); -+ -+ // for call lines -+ SourceItem(SourceView* sv, TQListViewItem* parent, -+ int fileno, unsigned int lineno, -+ TraceLine* line, TraceLineCall* lineCall); -+ -+ // for jump lines -+ SourceItem(SourceView* sv, TQListViewItem* parent, -+ int fileno, unsigned int lineno, -+ TraceLine* line, TraceLineJump* lineJump); -+ -+ uint lineno() const { return _lineno; } -+ int fileNumber() const { return _fileno; } -+ bool inside() const { return _inside; } -+ TraceLine* line() const { return _line; } -+ TraceLineCall* lineCall() const { return _lineCall; } -+ TraceLineJump* lineJump() const { return _lineJump; } -+ -+ int compare(TQListViewItem * i, int col, bool ascending ) const; -+ -+ void paintCell( TQPainter *p, const TQColorGroup &cg, -+ int column, int width, int alignment ); -+ int width( const TQFontMetrics& fm, -+ const TQListView* lv, int c ) const; -+ void updateGroup(); -+ void updateCost(); -+ -+ // arrow lines -+ void setJumpArray(const TQMemArray& a); -+ -+protected: -+ void paintArrows(TQPainter *p, const TQColorGroup &cg, int width); -+ TQMemArray _jump; -+ -+private: -+ SourceView* _view; -+ SubCost _pure, _pure2; -+ uint _lineno; -+ int _fileno; // for line sorting (even with multiple files) -+ bool _inside; -+ TraceLine* _line; -+ TraceLineJump* _lineJump; -+ TraceLineCall* _lineCall; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/sourceview.cpp b/kdecachegrind/kdecachegrind/sourceview.cpp -new file mode 100644 -index 0000000..dde291e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/sourceview.cpp -@@ -0,0 +1,813 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Source View -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "configuration.h" -+#include "sourceitem.h" -+#include "sourceview.h" -+ -+ -+// -+// SourceView -+// -+ -+ -+SourceView::SourceView(TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQListView(parent, name), TraceItemView(parentView) -+{ -+ _inSelectionUpdate = false; -+ -+ _arrowLevels = 0; -+ _lowList.setSortLow(true); -+ _highList.setSortLow(false); -+ -+ addColumn( i18n( "#" ) ); -+ addColumn( i18n( "Cost" ) ); -+ addColumn( i18n( "Cost 2" ) ); -+ addColumn( "" ); -+ addColumn( i18n( "Source (unknown)" ) ); -+ -+ setAllColumnsShowFocus(true); -+ setColumnAlignment(0, TQt::AlignRight); -+ setColumnAlignment(1, TQt::AlignRight); -+ setColumnAlignment(2, TQt::AlignRight); -+ setResizeMode(TQListView::LastColumn); -+ -+ connect(this, -+ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)), -+ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int))); -+ -+ connect(this, -+ TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ TQT_SLOT(selectedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(doubleClicked(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ connect(this, -+ TQT_SIGNAL(returnPressed(TQListViewItem*)), -+ TQT_SLOT(activatedSlot(TQListViewItem*))); -+ -+ TQWhatsThis::add( this, whatsThis()); -+} -+ -+void SourceView::paintEmptyArea( TQPainter * p, const TQRect & r) -+{ -+ TQListView::paintEmptyArea(p, r); -+} -+ -+ -+TQString SourceView::whatsThis() const -+{ -+ return i18n( "Annotated Source" -+ "

The annotated source list shows the " -+ "source lines of the current selected function " -+ "together with (self) cost spent while executing the " -+ "code of this source line. If there was a call " -+ "in a source line, lines with details on the " -+ "call happening are inserted into the source: " -+ "the cost spent inside of the call, the " -+ "number of calls happening, and the call destination.

" -+ "

Select a inserted call information line to " -+ "make the destination function current.

"); -+} -+ -+void SourceView::context(TQListViewItem* i, const TQPoint & p, int c) -+{ -+ TQPopupMenu popup; -+ -+ // Menu entry: -+ TraceLineCall* lc = i ? ((SourceItem*) i)->lineCall() : 0; -+ TraceLineJump* lj = i ? ((SourceItem*) i)->lineJump() : 0; -+ TraceFunction* f = lc ? lc->call()->called() : 0; -+ TraceLine* line = lj ? lj->lineTo() : 0; -+ -+ if (f) { -+ TQString name = f->name(); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ popup.insertItem(i18n("Go to '%1'").arg(name), 93); -+ popup.insertSeparator(); -+ } -+ else if (line) { -+ popup.insertItem(i18n("Go to Line %1").arg(line->name()), 93); -+ popup.insertSeparator(); -+ } -+ -+ if ((c == 1) || (c == 2)) { -+ addCostMenu(&popup); -+ popup.insertSeparator(); -+ } -+ addGoMenu(&popup); -+ -+ int r = popup.exec(p); -+ if (r == 93) { -+ if (f) activated(f); -+ if (line) activated(line); -+ } -+} -+ -+ -+void SourceView::selectedSlot(TQListViewItem * i) -+{ -+ if (!i) return; -+ // programatically selected items are not signalled -+ if (_inSelectionUpdate) return; -+ -+ TraceLineCall* lc = ((SourceItem*) i)->lineCall(); -+ TraceLineJump* lj = ((SourceItem*) i)->lineJump(); -+ -+ if (!lc && !lj) { -+ TraceLine* l = ((SourceItem*) i)->line(); -+ if (l) { -+ _selectedItem = l; -+ selected(l); -+ } -+ return; -+ } -+ -+ TraceFunction* f = lc ? lc->call()->called() : 0; -+ if (f) { -+ _selectedItem = f; -+ selected(f); -+ } -+ else { -+ TraceLine* line = lj ? lj->lineTo() : 0; -+ if (line) { -+ _selectedItem = line; -+ selected(line); -+ } -+ } -+} -+ -+void SourceView::activatedSlot(TQListViewItem * i) -+{ -+ if (!i) return; -+ TraceLineCall* lc = ((SourceItem*) i)->lineCall(); -+ TraceLineJump* lj = ((SourceItem*) i)->lineJump(); -+ -+ if (!lc && !lj) { -+ TraceLine* l = ((SourceItem*) i)->line(); -+ if (l) activated(l); -+ return; -+ } -+ -+ TraceFunction* f = lc ? lc->call()->called() : 0; -+ if (f) activated(f); -+ else { -+ TraceLine* line = lj ? lj->lineTo() : 0; -+ if (line) activated(line); -+ } -+} -+ -+TraceItem* SourceView::canShow(TraceItem* i) -+{ -+ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType; -+ TraceFunction* f = 0; -+ -+ switch(t) { -+ case TraceItem::Function: -+ f = (TraceFunction*) i; -+ break; -+ -+ case TraceItem::Instr: -+ f = ((TraceInstr*)i)->function(); -+ select(i); -+ break; -+ -+ case TraceItem::Line: -+ f = ((TraceLine*)i)->functionSource()->function(); -+ select(i); -+ break; -+ -+ default: -+ break; -+ } -+ -+ return f; -+} -+ -+void SourceView::doUpdate(int changeType) -+{ -+ // Special case ? -+ if (changeType == selectedItemChanged) { -+ -+ if (!_selectedItem) { -+ clearSelection(); -+ return; -+ } -+ -+ TraceLine* sLine = 0; -+ if (_selectedItem->type() == TraceItem::Line) -+ sLine = (TraceLine*) _selectedItem; -+ if (_selectedItem->type() == TraceItem::Instr) -+ sLine = ((TraceInstr*)_selectedItem)->line(); -+ -+ SourceItem* si = (SourceItem*)TQListView::selectedItem(); -+ if (si) { -+ if (si->line() == sLine) return; -+ if (si->lineCall() && -+ (si->lineCall()->call()->called() == _selectedItem)) return; -+ } -+ -+ TQListViewItem *item, *item2; -+ for (item = firstChild();item;item = item->nextSibling()) { -+ si = (SourceItem*)item; -+ if (si->line() == sLine) { -+ ensureItemVisible(item); -+ _inSelectionUpdate = true; -+ setCurrentItem(item); -+ _inSelectionUpdate = false; -+ break; -+ } -+ item2 = item->firstChild(); -+ for (;item2;item2 = item2->nextSibling()) { -+ si = (SourceItem*)item2; -+ if (!si->lineCall()) continue; -+ if (si->lineCall()->call()->called() == _selectedItem) { -+ ensureItemVisible(item2); -+ _inSelectionUpdate = true; -+ setCurrentItem(item2); -+ _inSelectionUpdate = false; -+ break; -+ } -+ } -+ if (item2) break; -+ } -+ return; -+ } -+ -+ if (changeType == groupTypeChanged) { -+ TQListViewItem *item, *item2; -+ for (item = firstChild();item;item = item->nextSibling()) -+ for (item2 = item->firstChild();item2;item2 = item2->nextSibling()) -+ ((SourceItem*)item2)->updateGroup(); -+ } -+ -+ refresh(); -+} -+ -+void SourceView::refresh() -+{ -+ clear(); -+ setColumnWidth(0, 20); -+ setColumnWidth(1, 50); -+ setColumnWidth(2, _costType2 ? 50:0); -+ setColumnWidth(3, 0); // arrows, defaults to invisible -+ setSorting(0); // always reset to line number sort -+ if (_costType) -+ setColumnText(1, _costType->name()); -+ if (_costType2) -+ setColumnText(2, _costType2->name()); -+ -+ _arrowLevels = 0; -+ -+ if (!_data || !_activeItem) { -+ setColumnText(4, i18n("(No Source)")); -+ return; -+ } -+ -+ TraceItem::CostType t = _activeItem->type(); -+ TraceFunction* f = 0; -+ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem; -+ if (t == TraceItem::Instr) { -+ f = ((TraceInstr*)_activeItem)->function(); -+ if (!_selectedItem) _selectedItem = _activeItem; -+ } -+ if (t == TraceItem::Line) { -+ f = ((TraceLine*)_activeItem)->functionSource()->function(); -+ if (!_selectedItem) _selectedItem = _activeItem; -+ } -+ -+ if (!f) return; -+ -+ // Allow resizing of column 2 -+ setColumnWidthMode(2, TQListView::Maximum); -+ -+ TraceFunctionSource* mainSF = f->sourceFile(); -+ -+ // skip first source if there's no debug info and there are more sources -+ // (this is for a bug in GCC 2.95.x giving unknown source for prologs) -+ if (mainSF && -+ (mainSF->firstLineno() == 0) && -+ (mainSF->lastLineno() == 0) && -+ (f->sourceFiles().count()>1) ) { -+ // skip -+ } -+ else -+ fillSourceFile(mainSF, 0); -+ -+ TraceFunctionSource* sf; -+ int fileno = 1; -+ TraceFunctionSourceList l = f->sourceFiles(); -+ for (sf=l.first();sf;sf=l.next(), fileno++) -+ if (sf != mainSF) -+ fillSourceFile(sf, fileno); -+ -+ if (!_costType2) { -+ setColumnWidthMode(2, TQListView::Manual); -+ setColumnWidth(2, 0); -+ } -+} -+ -+ -+// helper for fillSourceList: -+// search recursive for a file, starting from a base dir -+static bool checkFileExistance(TQString& dir, const TQString& name) -+{ -+ // we leave this in... -+ qDebug("Checking %s/%s", dir.ascii(), name.ascii()); -+ -+ if (TQFile::exists(dir + "/" + name)) return true; -+ -+ // check in subdirectories -+ TQDir d(dir); -+ d.setFilter( TQDir::Dirs | TQDir::NoSymLinks ); -+ d.setSorting( TQDir::Unsorted ); -+ TQStringList subdirs = d.entryList(); -+ TQStringList::Iterator it =subdirs.begin(); -+ for(; it != subdirs.end(); ++it ) { -+ if (*it == "." || *it == ".." || *it == "CVS") continue; -+ -+ dir = d.filePath(*it); -+ if (checkFileExistance(dir, name)) return true; -+ } -+ return false; -+} -+ -+ -+void SourceView::updateJumpArray(uint lineno, SourceItem* si, -+ bool ignoreFrom, bool ignoreTo) -+{ -+ TraceLineJump* lj; -+ uint lowLineno, highLineno; -+ int iEnd = -1, iStart = -1; -+ -+ if (0) qDebug("updateJumpArray(line %d, jump to %s)", -+ lineno, -+ si->lineJump() -+ ? si->lineJump()->lineTo()->name().ascii() : "?" ); -+ -+ -+ lj=_lowList.current(); -+ while(lj) { -+ lowLineno = lj->lineFrom()->lineno(); -+ if (lj->lineTo()->lineno() < lowLineno) -+ lowLineno = lj->lineTo()->lineno(); -+ -+ if (lowLineno > lineno) break; -+ -+ if (ignoreFrom && (lowLineno < lj->lineTo()->lineno())) break; -+ if (ignoreTo && (lowLineno < lj->lineFrom()->lineno())) break; -+ -+ if (si->lineJump() && (lj != si->lineJump())) break; -+ -+ int asize = (int)_jump.size(); -+#if 0 -+ for(iStart=0;iStartlineTo() == lj->lineTo())) break; -+#else -+ iStart = asize; -+#endif -+ -+ if (iStart == asize) { -+ for(iStart=0;iStart _arrowLevels) _arrowLevels = asize; -+ } -+ -+ if (0) qDebug(" start %d (%s to %s)", -+ iStart, -+ lj->lineFrom()->name().ascii(), -+ lj->lineTo()->name().ascii()); -+ -+ _jump[iStart] = lj; -+ } -+ lj=_lowList.next(); -+ } -+ -+ si->setJumpArray(_jump); -+ -+ lj=_highList.current(); -+ while(lj) { -+ highLineno = lj->lineFrom()->lineno(); -+ if (lj->lineTo()->lineno() > highLineno) { -+ highLineno = lj->lineTo()->lineno(); -+ if (ignoreTo) break; -+ } -+ else if (ignoreFrom) break; -+ -+ if (highLineno > lineno) break; -+ -+ for(iEnd=0;iEnd< (int)_jump.size();iEnd++) -+ if (_jump[iEnd] == lj) break; -+ if (iEnd == (int)_jump.size()) { -+ qDebug("LineView: no jump start for end at %x ?", highLineno); -+ iEnd = -1; -+ } -+ lj=_highList.next(); -+ -+ if (0 && (iEnd>=0)) -+ qDebug(" end %d (%s to %s)", -+ iEnd, -+ _jump[iEnd]->lineFrom()->name().ascii(), -+ _jump[iEnd]->lineTo()->name().ascii()); -+ -+ if (0 && lj) qDebug("next end: %s to %s", -+ lj->lineFrom()->name().ascii(), -+ lj->lineTo()->name().ascii()); -+ -+ if (highLineno > lineno) -+ break; -+ else { -+ if (iEnd>=0) _jump[iEnd] = 0; -+ iEnd = -1; -+ } -+ } -+ if (iEnd>=0) _jump[iEnd] = 0; -+} -+ -+ -+/* If sourceList is empty we set the source file name into the header, -+ * else this code is of a inlined function, and we add "inlined from..." -+ */ -+void SourceView::fillSourceFile(TraceFunctionSource* sf, int fileno) -+{ -+ if (!sf) return; -+ -+ if (0) qDebug("Selected Item %s", -+ _selectedItem ? _selectedItem->name().ascii() : "(none)"); -+ -+ TraceLineMap::Iterator lineIt, lineItEnd; -+ int nextCostLineno = 0, lastCostLineno = 0; -+ -+ bool validSourceFile = (!sf->file()->name().isEmpty()); -+ -+ TraceLine* sLine = 0; -+ if (_selectedItem) { -+ if (_selectedItem->type() == TraceItem::Line) -+ sLine = (TraceLine*) _selectedItem; -+ if (_selectedItem->type() == TraceItem::Instr) -+ sLine = ((TraceInstr*)_selectedItem)->line(); -+ } -+ -+ if (validSourceFile) { -+ TraceLineMap* lineMap = sf->lineMap(); -+ if (lineMap) { -+ lineIt = lineMap->begin(); -+ lineItEnd = lineMap->end(); -+ // get first line with cost of selected type -+ while(lineIt != lineItEnd) { -+ if (&(*lineIt) == sLine) break; -+ if ((*lineIt).hasCost(_costType)) break; -+ if (_costType2 && (*lineIt).hasCost(_costType2)) break; -+ ++lineIt; -+ } -+ -+ nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno(); -+ if (nextCostLineno<0) { -+ kdError() << "SourceView::fillSourceFile: Negative line number " -+ << nextCostLineno << endl -+ << " Function '" << sf->function()->name() << "'" << endl -+ << " File '" << sf->file()->name() << "'" << endl; -+ nextCostLineno = 0; -+ } -+ -+ } -+ -+ if (nextCostLineno == 0) { -+ new SourceItem(this, this, fileno, 0, false, -+ i18n("There is no cost of current selected type associated")); -+ new SourceItem(this, this, fileno, 1, false, -+ i18n("with any source line of this function in file")); -+ new SourceItem(this, this, fileno, 2, false, -+ TQString(" '%1'").arg(sf->function()->prettyName())); -+ new SourceItem(this, this, fileno, 3, false, -+ i18n("Thus, no annotated source can be shown.")); -+ return; -+ } -+ } -+ -+ TQString filename = sf->file()->shortName(); -+ TQString dir = sf->file()->directory(); -+ if (!dir.isEmpty()) -+ filename = dir + "/" + filename; -+ -+ if (nextCostLineno>0) { -+ // we have debug info... search for source file -+ if (!TQFile::exists(filename)) { -+ TQStringList list = Configuration::sourceDirs(_data, -+ sf->function()->object()); -+ TQStringList::Iterator it; -+ -+ for ( it = list.begin(); it != list.end(); ++it ) { -+ dir = *it; -+ if (checkFileExistance(dir, sf->file()->shortName())) break; -+ } -+ -+ if (it == list.end()) -+ nextCostLineno = 0; -+ else { -+ filename = dir + "/" + sf->file()->shortName(); -+ // no need to search again -+ sf->file()->setDirectory(dir); -+ } -+ } -+ } -+ -+ // do it here, because the source directory could have been set before -+ if (childCount()==0) { -+ setColumnText(4, validSourceFile ? -+ i18n("Source ('%1')").arg(filename) : -+ i18n("Source (unknown)")); -+ } -+ else { -+ new SourceItem(this, this, fileno, 0, true, -+ validSourceFile ? -+ i18n("--- Inlined from '%1' ---").arg(filename) : -+ i18n("--- Inlined from unknown source ---")); -+ } -+ -+ if (nextCostLineno == 0) { -+ new SourceItem(this, this, fileno, 0, false, -+ i18n("There is no source available for the following function:")); -+ new SourceItem(this, this, fileno, 1, false, -+ TQString(" '%1'").arg(sf->function()->prettyName())); -+ if (sf->file()->name().isEmpty()) { -+ new SourceItem(this, this, fileno, 2, false, -+ i18n("This is because no debug information is present.")); -+ new SourceItem(this, this, fileno, 3, false, -+ i18n("Recompile source and redo the profile run.")); -+ if (sf->function()->object()) { -+ new SourceItem(this, this, fileno, 4, false, -+ i18n("The function is located in this ELF object:")); -+ new SourceItem(this, this, fileno, 5, false, -+ TQString(" '%1'") -+ .arg(sf->function()->object()->prettyName())); -+ } -+ } -+ else { -+ new SourceItem(this, this, fileno, 2, false, -+ i18n("This is because its source file cannot be found:")); -+ new SourceItem(this, this, fileno, 3, false, -+ TQString(" '%1'").arg(sf->file()->name())); -+ new SourceItem(this, this, fileno, 4, false, -+ i18n("Add the folder of this file to the source folder list.")); -+ new SourceItem(this, this, fileno, 5, false, -+ i18n("The list can be found in the configuration dialog.")); -+ } -+ return; -+ } -+ -+ -+ // initialisation for arrow drawing -+ // create sorted list of jumps (for jump arrows) -+ TraceLineMap::Iterator it = lineIt, nextIt; -+ _lowList.clear(); -+ _highList.clear(); -+ while(1) { -+ -+ nextIt = it; -+ ++nextIt; -+ while(nextIt != lineItEnd) { -+ if (&(*nextIt) == sLine) break; -+ if ((*nextIt).hasCost(_costType)) break; -+ if (_costType2 && (*nextIt).hasCost(_costType2)) break; -+ ++nextIt; -+ } -+ -+ TraceLineJumpList jlist = (*it).lineJumps(); -+ TraceLineJump* lj; -+ for (lj=jlist.first();lj;lj=jlist.next()) { -+ if (lj->executedCount()==0) continue; -+ // skip jumps to next source line with cost -+ //if (lj->lineTo() == &(*nextIt)) continue; -+ -+ _lowList.append(lj); -+ _highList.append(lj); -+ } -+ it = nextIt; -+ if (it == lineItEnd) break; -+ } -+ _lowList.sort(); -+ _highList.sort(); -+ _lowList.first(); // iterators to list start -+ _highList.first(); -+ _jump.resize(0); -+ -+ -+ char buf[256]; -+ bool inside = false, skipLineWritten = true; -+ int readBytes; -+ int fileLineno = 0; -+ SubCost most = 0; -+ -+ TraceLine* currLine; -+ SourceItem *si, *si2, *item = 0, *first = 0, *selected = 0; -+ TQFile file(filename); -+ if (!file.open(IO_ReadOnly)) return; -+ while (1) { -+ readBytes=file.readLine(buf, sizeof( buf )); -+ if (readBytes<=0) { -+ // for nice empty 4 lines after function with EOF -+ buf[0] = 0; -+ } -+ -+ if (readBytes >= (int) sizeof( buf )) { -+ qDebug("%s:%d Line too long\n", -+ sf->file()->name().ascii(), fileLineno); -+ } -+ else if ((readBytes>0) && (buf[readBytes-1] == '\n')) -+ buf[readBytes-1] = 0; -+ -+ -+ // keep fileLineno inside [lastCostLineno;nextCostLineno] -+ fileLineno++; -+ if (fileLineno == nextCostLineno) { -+ currLine = &(*lineIt); -+ -+ // get next line with cost of selected type -+ ++lineIt; -+ while(lineIt != lineItEnd) { -+ if (&(*lineIt) == sLine) break; -+ if ((*lineIt).hasCost(_costType)) break; -+ if (_costType2 && (*lineIt).hasCost(_costType2)) break; -+ ++lineIt; -+ } -+ -+ lastCostLineno = nextCostLineno; -+ nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno(); -+ } -+ else -+ currLine = 0; -+ -+ // update inside -+ if (!inside) { -+ if (currLine) inside = true; -+ } -+ else { -+ if ( (fileLineno > lastCostLineno) && -+ ((nextCostLineno == 0) || -+ (fileLineno < nextCostLineno - Configuration::noCostInside()) )) -+ inside = false; -+ } -+ -+ int context = Configuration::context(); -+ -+ if ( ((lastCostLineno==0) || (fileLineno > lastCostLineno + context)) && -+ ((nextCostLineno==0) || (fileLineno < nextCostLineno - context))) { -+ if (lineIt == lineItEnd) break; -+ -+ if (!skipLineWritten) { -+ skipLineWritten = true; -+ // a "skipping" line: print "..." instead of a line number -+ strcpy(buf,"..."); -+ } -+ else -+ continue; -+ } -+ else -+ skipLineWritten = false; -+ -+ si = new SourceItem(this, this, -+ fileno, fileLineno, inside, TQString(buf), -+ currLine); -+ -+ if (!currLine) continue; -+ -+ if (!selected && (currLine == sLine)) selected = si; -+ if (!first) first = si; -+ -+ if (currLine->subCost(_costType) > most) { -+ item = si; -+ most = currLine->subCost(_costType); -+ } -+ -+ si->setOpen(true); -+ TraceLineCallList list = currLine->lineCalls(); -+ TraceLineCall* lc; -+ for (lc=list.first();lc;lc=list.next()) { -+ if ((lc->subCost(_costType)==0) && -+ (lc->subCost(_costType2)==0)) continue; -+ -+ if (lc->subCost(_costType) > most) { -+ item = si; -+ most = lc->subCost(_costType); -+ } -+ -+ si2 = new SourceItem(this, si, fileno, fileLineno, currLine, lc); -+ -+ if (!selected && (lc->call()->called() == _selectedItem)) -+ selected = si2; -+ } -+ -+ TraceLineJumpList jlist = currLine->lineJumps(); -+ TraceLineJump* lj; -+ for (lj=jlist.first();lj;lj=jlist.next()) { -+ if (lj->executedCount()==0) continue; -+ -+ new SourceItem(this, si, fileno, fileLineno, currLine, lj); -+ } -+ } -+ -+ if (selected) item = selected; -+ if (item) first = item; -+ if (first) { -+ ensureItemVisible(first); -+ _inSelectionUpdate = true; -+ setCurrentItem(first); -+ _inSelectionUpdate = false; -+ } -+ -+ file.close(); -+ -+ // for arrows: go down the list according to list sorting -+ sort(); -+ TQListViewItem *item1, *item2; -+ for (item1=firstChild();item1;item1 = item1->nextSibling()) { -+ si = (SourceItem*)item1; -+ updateJumpArray(si->lineno(), si, true, false); -+ -+ for (item2=item1->firstChild();item2;item2 = item2->nextSibling()) { -+ si2 = (SourceItem*)item2; -+ if (si2->lineJump()) -+ updateJumpArray(si->lineno(), si2, false, true); -+ else -+ si2->setJumpArray(_jump); -+ } -+ } -+ -+ if (arrowLevels()) -+ setColumnWidth(3, 10 + 6*arrowLevels() + itemMargin() * 2); -+ else -+ setColumnWidth(3, 0); -+} -+ -+ -+void SourceView::updateSourceItems() -+{ -+ setColumnWidth(1, 50); -+ setColumnWidth(2, _costType2 ? 50:0); -+ // Allow resizing of column 2 -+ setColumnWidthMode(2, TQListView::Maximum); -+ -+ if (_costType) -+ setColumnText(1, _costType->name()); -+ if (_costType2) -+ setColumnText(2, _costType2->name()); -+ -+ SourceItem* si; -+ TQListViewItem* item = firstChild(); -+ for (;item;item = item->nextSibling()) { -+ si = (SourceItem*)item; -+ TraceLine* l = si->line(); -+ if (!l) continue; -+ -+ si->updateCost(); -+ -+ TQListViewItem *next, *i = si->firstChild(); -+ for (;i;i = next) { -+ next = i->nextSibling(); -+ ((SourceItem*)i)->updateCost(); -+ } -+ } -+ -+ if (!_costType2) { -+ setColumnWidthMode(2, TQListView::Manual); -+ setColumnWidth(2, 0); -+ } -+} -+ -+#include "sourceview.moc" -diff --git a/kdecachegrind/kdecachegrind/sourceview.h b/kdecachegrind/kdecachegrind/sourceview.h -new file mode 100644 -index 0000000..b72fc7a ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/sourceview.h -@@ -0,0 +1,71 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Source View -+ */ -+ -+#ifndef SOURCEVIEW_H -+#define SOURCEVIEW_H -+ -+#include -+#include "traceitemview.h" -+ -+class SourceItem; -+ -+class SourceView : public TQListView, public TraceItemView -+{ -+ friend class SourceItem; -+ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ SourceView(TraceItemView* parentView, -+ TQWidget* parent = 0, const char* name = 0); -+ -+ TQWidget* widget() { return this; } -+ TQString whatsThis() const; -+ -+protected: -+ int arrowLevels() { return _arrowLevels; } -+ void paintEmptyArea( TQPainter *, const TQRect & ); -+ -+private slots: -+ void context(TQListViewItem*, const TQPoint &, int); -+ void selectedSlot(TQListViewItem *); -+ void activatedSlot(TQListViewItem *); -+ -+private: -+ TraceItem* canShow(TraceItem*); -+ void doUpdate(int); -+ void refresh(); -+ void updateJumpArray(uint,SourceItem*,bool,bool); -+ void fillSourceFile(TraceFunctionSource*, int); -+ void updateSourceItems(); -+ -+ bool _inSelectionUpdate; -+ -+ // arrows -+ int _arrowLevels; -+ // temporary needed on creation... -+ TQMemArray _jump; -+ TraceLineJumpList _lowList, _highList; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/stackbrowser.cpp b/kdecachegrind/kdecachegrind/stackbrowser.cpp -new file mode 100644 -index 0000000..78095eb ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackbrowser.cpp -@@ -0,0 +1,417 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include -+ -+#include "stackbrowser.h" -+ -+// Stack -+ -+Stack::Stack(TraceFunction* top, TraceCallList calls) -+{ -+ _refCount = 0; -+ _top = top; -+ _calls = calls; -+ -+ extendBottom(); -+} -+ -+Stack::Stack(TraceFunction* f) -+{ -+ _refCount = 0; -+ _top = f; -+ -+ extendBottom(); -+ extendTop(); -+} -+ -+void Stack::extendBottom() -+{ -+ TraceCallList l; -+ TraceCall *c, *call; -+ SubCost most; -+ TraceFunction* f; -+ -+ if (_calls.last()) -+ f = _calls.last()->called(); -+ else -+ f = _top; -+ -+ if (!f) return; -+ // don't follow calls from cycles -+ if (f->cycle() == f) return; -+ -+ -+ int max = 30; -+ -+ // try to extend to lower stack frames -+ while (f && (max-- >0)) { -+ l = f->callings(); -+ call = 0; -+ most = 0; -+ for (c=l.first();c;c=l.next()) { -+ // no cycle calls in stack: could be deleted without notice -+ if (c->called()->cycle() == c->called()) continue; -+ // no simple recursions -+ if (c->called() == _top) continue; -+ -+ if (c->called()->name().isEmpty()) continue; -+ SubCost sc = c->subCost(0); // FIXME -+ if (sc == 0) continue; -+ -+ if (sc > most) { -+ most = sc; -+ call = c; -+ } -+ } -+ if (!call) -+ break; -+ -+ _calls.append(call); -+ f = call->called(); -+ } -+} -+ -+ -+void Stack::extendTop() -+{ -+ TraceCallList l; -+ TraceCall *c, *call; -+ SubCost most; -+ -+ int max = 10; -+ -+ // don't follow calls from cycles -+ if (_top->cycle() == _top) return; -+ -+ // try to extend to upper stack frames -+ while (_top && (max-- >0)) { -+ l = _top->callers(); -+ call = 0; -+ most = 0; -+ for (c=l.first();c;c=l.next()) { -+ // no cycle calls in stack: could be deleted without notice -+ if (c->caller()->cycle() == c->caller()) continue; -+ // no simple recursions -+ if (c->caller() == _top) continue; -+ -+ if (c->caller()->name().isEmpty()) continue; -+ SubCost sc = c->subCost(0); // FIXME -+ if (sc == 0) continue; -+ -+ if (sc > most) { -+ most = sc; -+ call = c; -+ } -+ } -+ if (!call) -+ break; -+ -+ _calls.prepend(call); -+ _top = call->caller(); -+ } -+} -+ -+TraceFunction* Stack::caller(TraceFunction* fn, bool extend) -+{ -+ TraceFunction* f; -+ TraceCall* c; -+ -+ if (extend && (_top == fn)) { -+ // extend at top -+ extendTop(); -+ f = _top; -+ } -+ -+ for (c=_calls.first();c;c=_calls.next()) { -+ f = c->called(); -+ if (f == fn) -+ return c->caller(); -+ } -+ return 0; -+} -+ -+TraceFunction* Stack::called(TraceFunction* fn, bool extend) -+{ -+ TraceFunction* f; -+ TraceCall* c; -+ -+ for (c=_calls.first();c;c=_calls.next()) { -+ f = c->caller(); -+ if (f == fn) -+ return c->called(); -+ } -+ -+ if (extend && (c->called() == fn)) { -+ // extend at bottom -+ extendBottom(); -+ -+ // and search again -+ for (c=_calls.first();c;c=_calls.next()) { -+ f = c->caller(); -+ if (f == fn) -+ return c->called(); -+ } -+ } -+ -+ return 0; -+} -+ -+bool Stack::contains(TraceFunction* fn) -+{ -+ // cycles are listed on there own -+ if (fn->cycle() == fn) return false; -+ if (_top->cycle() == _top) return false; -+ -+ if (fn == _top) -+ return true; -+ -+ TraceFunction* f = _top; -+ TraceCall* c; -+ -+ for (c=_calls.first();c;c=_calls.next()) { -+ f = c->called(); -+ if (f == fn) -+ return true; -+ } -+ -+ TraceCallList l; -+ -+ // try to extend at bottom (even if callCount 0) -+ l = f->callings(); -+ for (c=l.first();c;c=l.next()) { -+ f = c->called(); -+ if (f == fn) -+ break; -+ } -+ -+ if (c) { -+ _calls.append(c); -+ -+ // extend at bottom after found one -+ extendBottom(); -+ return true; -+ } -+ -+ // try to extend at top (even if callCount 0) -+ l = _top->callers(); -+ for (c=l.first();c;c=l.next()) { -+ f = c->caller(); -+ if (f == fn) -+ break; -+ } -+ -+ if (c) { -+ _calls.prepend(c); -+ -+ // extend at top after found one -+ extendTop(); -+ return true; -+ } -+ -+ return false; -+} -+ -+Stack* Stack::split(TraceFunction* f) -+{ -+ TraceCallList calls = _calls; -+ TraceCall *c, *c2; -+ -+ // cycles are listed on there own -+ if (f->cycle() == f) return 0; -+ if (_top->cycle() == _top) return false; -+ -+ for (c=calls.first();c;c=calls.next()) { -+ TraceCallList l = c->called()->callings(); -+ for (c2=l.first();c2;c2=l.next()) { -+ if (c2 == c) continue; -+ if (c2->called() == f) -+ break; -+ } -+ if (c2) -+ break; -+ } -+ -+ if (!c) -+ return 0; -+ -+ // remove bottom part -+ calls.last(); -+ while (calls.current() && calls.current()!=c) -+ calls.removeLast(); -+ -+ calls.append(c2); -+ return new Stack(_top, calls ); -+} -+ -+TQString Stack::toString() -+{ -+ TQString res = _top->name(); -+ TraceCall *c; -+ for (c=_calls.first();c;c=_calls.next()) -+ res += "\n > " + c->called()->name(); -+ -+ return res; -+} -+ -+ -+// HistoryItem -+ -+HistoryItem::HistoryItem(Stack* stack, TraceFunction* function) -+{ -+ _stack = stack; -+ _function = function; -+ if (_stack) -+ _stack->ref(); -+ -+ _last = 0; -+ _next = 0; -+ -+/* -+ qDebug("New Stack History Item (sRef %d): %s\n %s", -+ _stack->refCount(), _function->name().ascii(), -+ _stack->toString().ascii()); -+*/ -+} -+ -+HistoryItem::~HistoryItem() -+{ -+ if (0) qDebug("Deleting Stack History Item (sRef %d): %s", -+ _stack->refCount(), -+ _function->name().ascii()); -+ -+ if (_last) -+ _last->_next = _next; -+ if (_stack) { -+ if (_stack->deref() == 0) -+ delete _stack; -+ } -+} -+ -+ -+// StackBrowser -+ -+StackBrowser::StackBrowser() -+{ -+ _current = 0; -+} -+ -+StackBrowser::~StackBrowser() -+{ -+ delete _current; -+} -+ -+HistoryItem* StackBrowser::select(TraceFunction* f) -+{ -+ if (!_current) { -+ Stack* s = new Stack(f); -+ _current = new HistoryItem(s, f); -+ } -+ else if (_current->function() != f) { -+ // make current item the last one -+ HistoryItem* item = _current; -+ if (item->next()) { -+ item = item->next(); -+ item->last()->setNext(0); -+ -+ while (item->next()) { -+ item = item->next(); -+ delete item->last(); -+ } -+ delete item; -+ } -+ -+ Stack* s = _current->stack(); -+ if (!s->contains(f)) { -+ s = s->split(f); -+ if (!s) -+ s = new Stack(f); -+ } -+ -+ item = _current; -+ _current = new HistoryItem(s, f); -+ item->setNext(_current); -+ _current->setLast(item); -+ } -+ -+ // qDebug("Selected %s in StackBrowser", f->name().ascii()); -+ -+ return _current; -+} -+ -+HistoryItem* StackBrowser::goBack() -+{ -+ if (_current && _current->last()) -+ _current = _current->last(); -+ -+ return _current; -+} -+ -+HistoryItem* StackBrowser::goForward() -+{ -+ if (_current && _current->next()) -+ _current = _current->next(); -+ -+ return _current; -+} -+ -+HistoryItem* StackBrowser::goUp() -+{ -+ if (_current) { -+ TraceFunction* f = _current->stack()->caller(_current->function(), true); -+ if (f) -+ _current = select(f); -+ } -+ -+ return _current; -+} -+ -+HistoryItem* StackBrowser::goDown() -+{ -+ if (_current) { -+ TraceFunction* f = _current->stack()->called(_current->function(), true); -+ if (f) -+ _current = select(f); -+ } -+ -+ return _current; -+} -+ -+bool StackBrowser::canGoBack() -+{ -+ return _current && _current->last(); -+} -+ -+bool StackBrowser::canGoForward() -+{ -+ return _current && _current->next(); -+} -+ -+bool StackBrowser::canGoUp() -+{ -+ if (!_current) return false; -+ -+ return _current->stack()->caller(_current->function(), false); -+} -+ -+bool StackBrowser::canGoDown() -+ { -+ if (!_current) return false; -+ -+ return _current->stack()->called(_current->function(), false); -+} -diff --git a/kdecachegrind/kdecachegrind/stackbrowser.h b/kdecachegrind/kdecachegrind/stackbrowser.h -new file mode 100644 -index 0000000..e7d6b80 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackbrowser.h -@@ -0,0 +1,109 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#ifndef STACKBROWSER_H -+#define STACKBROWSER_H -+ -+#include "tracedata.h" -+ -+// A history of selected functions within stacks -+ -+class Stack -+{ -+public: -+ Stack(TraceFunction*); -+ -+ // extend the stack at top/bottom if possible -+ bool contains(TraceFunction*); -+ -+ void extendBottom(); -+ void extendTop(); -+ -+ // search for a function on stack calling specified function. -+ // if found, return upper part with new function call -+ Stack* split(TraceFunction*); -+ -+ // increment reference count -+ void ref() { _refCount++; } -+ // decrement reference count -+ bool deref() { return --_refCount; } -+ int refCount() { return _refCount; } -+ -+ TraceFunction* top() { return _top; } -+ TraceCallList calls() { return _calls; } -+ TraceFunction* caller(TraceFunction*, bool extend); -+ TraceFunction* called(TraceFunction*, bool extend); -+ -+ TQString toString(); -+ -+private: -+ Stack(TraceFunction* top, TraceCallList list); -+ -+ // at the top of the stack we have a function... -+ TraceFunction* _top; -+ // list ordered from top to bottom -+ TraceCallList _calls; -+ int _refCount; -+}; -+ -+class HistoryItem -+{ -+public: -+ HistoryItem(Stack*, TraceFunction*); -+ ~HistoryItem(); -+ -+ Stack* stack() { return _stack; } -+ TraceFunction* function() { return _function; } -+ HistoryItem* last() { return _last; } -+ HistoryItem* next() { return _next; } -+ void setLast(HistoryItem* h) { _last = h; } -+ void setNext(HistoryItem* h) { _next = h; } -+ -+private: -+ -+ HistoryItem *_last, *_next; -+ Stack* _stack; -+ TraceFunction* _function; -+}; -+ -+ -+class StackBrowser -+{ -+public: -+ StackBrowser(); -+ ~StackBrowser(); -+ -+ // A function was selected. This creates a new history entry -+ HistoryItem* select(TraceFunction*); -+ -+ HistoryItem* current() { return _current; } -+ bool canGoBack(); -+ bool canGoForward(); -+ bool canGoUp(); -+ bool canGoDown(); -+ HistoryItem* goBack(); -+ HistoryItem* goForward(); -+ HistoryItem* goUp(); -+ HistoryItem* goDown(); -+ -+private: -+ HistoryItem* _current; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/stackitem.cpp b/kdecachegrind/kdecachegrind/stackitem.cpp -new file mode 100644 -index 0000000..e3763ab ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackitem.cpp -@@ -0,0 +1,116 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of stack dockable. -+ */ -+ -+#include -+#include -+ -+#include "configuration.h" -+#include "listutils.h" -+#include "stackitem.h" -+#include "stackselection.h" -+ -+// StackItem -+ -+StackItem::StackItem(StackSelection* ss, -+ TQListView* parent, TraceFunction* f) -+ :TQListViewItem(parent) -+{ -+ _view = ss; -+ _function = f; -+ _call = 0; -+ -+ updateGroup(); -+ updateCost(); -+ -+ setText(2, TQString("-- ")); -+ setText(3, f->prettyName()); -+} -+ -+StackItem::StackItem(StackSelection* ss, -+ TQListView* parent, TraceCall* call) -+ :TQListViewItem(parent) -+{ -+ _view = ss; -+ _call = call; -+ _function = call->called(); -+ -+ updateGroup(); -+ updateCost(); -+ -+ setText(3, _function->prettyName()); -+} -+ -+ -+void StackItem::updateGroup() -+{ -+ TQColor c = Configuration::functionColor(_view->groupType(), -+ _function); -+ setPixmap(3, colorPixmap(10, 10, c)); -+} -+ -+void StackItem::updateCost() -+{ -+ if (!_call) return; -+ -+ setText(2, _call->prettyCallCount()); -+ -+ TraceCostType* ct = _view->costType(); -+ _sum = _call->subCost(ct); -+ double total = _call->called()->data()->subCost(ct); -+ if (total == 0.0) { -+ setText(0, "-"); -+ setPixmap(0, TQPixmap()); -+ } -+ else { -+ double sum = 100.0 * _sum / total; -+ -+ if (Configuration::showPercentage()) -+ setText(0, TQString("%1") -+ .arg(sum, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(0, _call->prettySubCost(ct)); -+ -+ setPixmap(0, costPixmap(ct, _call, total, false)); -+ } -+ -+ // if _costType2 is 0, column1 is hidden, no change needed -+ TraceCostType* ct2 = _view->costType2(); -+ if (!ct2) return; -+ -+ _sum = _call->subCost(ct2); -+ total = _call->called()->data()->subCost(ct2); -+ if (total == 0.0) { -+ setText(1, "-"); -+ setPixmap(1, TQPixmap()); -+ } -+ else { -+ double sum = 100.0 * _sum / total; -+ -+ if (Configuration::showPercentage()) -+ setText(1, TQString("%1") -+ .arg(sum, 0, 'f', Configuration::percentPrecision())); -+ else -+ setText(1, _call->prettySubCost(ct2)); -+ -+ setPixmap(1, costPixmap(ct2, _call, total, false)); -+ } -+} -diff --git a/kdecachegrind/kdecachegrind/stackitem.h b/kdecachegrind/kdecachegrind/stackitem.h -new file mode 100644 -index 0000000..250e9f6 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackitem.h -@@ -0,0 +1,56 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003, 2004 -+ Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Items of stack dockable. -+ */ -+ -+#ifndef STACKITEM_H -+#define STACKITEM_H -+ -+#include -+#include "tracedata.h" -+ -+class StackSelection; -+ -+ -+// for the stack browser -+ -+class StackItem: public TQListViewItem -+{ -+public: -+ // for top -+ StackItem(StackSelection* ss, TQListView* parent, TraceFunction* f); -+ StackItem(StackSelection* ss, TQListView* parent, TraceCall* c); -+ -+ TraceFunction* function() { return _function; } -+ TraceCall* call() { return _call; } -+ void updateGroup(); -+ void updateCost(); -+ -+private: -+ StackSelection* _view; -+ SubCost _sum; -+ TraceFunction* _function; -+ TraceCall* _call; -+}; -+ -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/stackselection.cpp b/kdecachegrind/kdecachegrind/stackselection.cpp -new file mode 100644 -index 0000000..5909475 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackselection.cpp -@@ -0,0 +1,230 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * StackSelection for KCachegrind -+ * For function selection of a most expected stack, -+ * to be put into a TQDockWindow -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "stackbrowser.h" -+#include "stackselection.h" -+#include "stackitem.h" -+ -+StackSelection::StackSelection( TQWidget* parent, const char* name) -+ : StackSelectionBase(parent, name) -+{ -+ _data = 0; -+ _browser = new StackBrowser(); -+ _item = 0; -+ _function = 0; -+ _costType = 0; -+ _costType2 = 0; -+ _groupType = TraceItem::Function; -+ -+ stackList->setSorting(-1); -+ stackList->setAllColumnsShowFocus(true); -+ stackList->setResizeMode(TQListView::LastColumn); -+ stackList->setColumnAlignment(0, TQt::AlignRight); -+ stackList->setColumnAlignment(1, TQt::AlignRight); -+ stackList->setColumnAlignment(2, TQt::AlignRight); -+ stackList->setColumnWidth(0, 50); -+ // 2nd cost column hidden at first (_costType2 == 0) -+ stackList->setColumnWidth(1, 0); -+ stackList->setColumnWidth(2, 50); -+ -+ connect(stackList, TQT_SIGNAL(selectionChanged(TQListViewItem*)), -+ this, TQT_SLOT(stackSelected(TQListViewItem*))); -+} -+ -+StackSelection::~StackSelection() -+{ -+ delete _browser; -+} -+ -+void StackSelection::setData(TraceData* data) -+{ -+ if (_data == data) return; -+ -+ _data = data; -+ -+ stackList->clear(); -+ delete _browser; -+ _browser = new StackBrowser(); -+ _function = 0; -+} -+ -+ -+void StackSelection::setFunction(TraceFunction* f) -+{ -+ if (_function == f) return; -+ _function = f; -+ -+ if (!_data || !_function) return; -+ -+ //kdDebug() << "StackSelection::setFunction " << f->name() << endl; -+ -+ HistoryItem* item = _browser->current(); -+ if (!item || item->function() != f) { -+ _browser->select(f); -+ rebuildStackList(); -+ } -+} -+ -+ -+void StackSelection::rebuildStackList() -+{ -+ HistoryItem* item = _browser->current(); -+ stackList->clear(); -+ stackList->setColumnWidth(0, 50); -+ stackList->setColumnWidth(1, _costType2 ? 50:0); -+ stackList->setColumnWidth(2, 50); -+ if (!item || !item->stack()) return; -+ -+ TraceFunction* top = item->stack()->top(); -+ if (!top) return; -+ -+ stackList->setColumnWidthMode(1, TQListView::Maximum); -+ -+ TraceCallList l = item->stack()->calls(); -+ TraceCall* call; -+ for (call=l.last();call;call=l.prev()) -+ new StackItem(this, stackList, call); -+ -+ new StackItem(this, stackList, top); -+ -+ // select current function -+ TQListViewItem* i = stackList->firstChild(); -+ for (;i;i=i->nextSibling()) -+ if (((StackItem*)i)->function() == item->function()) -+ break; -+ -+ if (i) { -+ // this calls stackFunctionSelected() -+ stackList->setCurrentItem(i); -+ stackList->ensureItemVisible(i); -+ } -+ -+ if (!_costType2) { -+ stackList->setColumnWidthMode(1, TQListView::Manual); -+ stackList->setColumnWidth(1, 0); -+ } -+} -+ -+void StackSelection::stackSelected(TQListViewItem* i) -+{ -+ if (!i) return; -+ -+ TraceFunction* f = ((StackItem*)i)->function(); -+ emit functionSelected(f); -+} -+ -+ -+void StackSelection::browserBack() -+{ -+ if (_browser && _browser->canGoBack()) { -+ _browser->goBack(); -+ rebuildStackList(); -+ } -+} -+ -+void StackSelection::browserForward() -+{ -+ if (_browser && _browser->canGoForward()) { -+ _browser->goForward(); -+ rebuildStackList(); -+ } -+} -+ -+void StackSelection::browserUp() -+{ -+ if (_browser) { -+ _browser->goUp(); -+ rebuildStackList(); -+ } -+} -+ -+void StackSelection::browserDown() -+{ -+ if (_browser) { -+ _browser->goDown(); -+ rebuildStackList(); -+ } -+} -+ -+void StackSelection::refresh() -+{ -+ TQListViewItem* item = stackList->firstChild(); -+ for(;item;item = item->nextSibling()) -+ ((StackItem*)item)->updateCost(); -+} -+ -+void StackSelection::setCostType(TraceCostType* ct) -+{ -+ if (ct == _costType) return; -+ _costType = ct; -+ -+ stackList->setColumnWidth(0, 50); -+ if (_costType) -+ stackList->setColumnText(0, _costType->name()); -+ -+ TQListViewItem* item = stackList->firstChild(); -+ for(;item;item = item->nextSibling()) -+ ((StackItem*)item)->updateCost(); -+} -+ -+void StackSelection::setCostType2(TraceCostType* ct) -+{ -+ if (ct == _costType2) return; -+ _costType2 = ct; -+ -+ stackList->setColumnWidth(1, 50); -+ stackList->setColumnWidthMode(1, TQListView::Maximum); -+ if (_costType2) -+ stackList->setColumnText(1, _costType2->name()); -+ -+ TQListViewItem* item = stackList->firstChild(); -+ for(;item;item = item->nextSibling()) -+ ((StackItem*)item)->updateCost(); -+ -+ if (!_costType2) { -+ stackList->setColumnWidthMode(1, TQListView::Manual); -+ stackList->setColumnWidth(1, 0); -+ } -+} -+ -+void StackSelection::setGroupType(TraceItem::CostType gt) -+{ -+ if (_groupType == gt) return; -+ _groupType = gt; -+ -+ TQListViewItem* item = stackList->firstChild(); -+ for(;item;item = item->nextSibling()) -+ ((StackItem*)item)->updateGroup(); -+} -+ -+#include "stackselection.moc" -diff --git a/kdecachegrind/kdecachegrind/stackselection.h b/kdecachegrind/kdecachegrind/stackselection.h -new file mode 100644 -index 0000000..2bb3a75 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackselection.h -@@ -0,0 +1,81 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * StackSelection for KCachegrind -+ * For function selection of a most expected stack, -+ * to be put into a TQDockWindow -+ */ -+ -+#ifndef STACKSELECTION_H -+#define STACKSELECTION_H -+ -+#include "stackselectionbase.h" -+#include "tracedata.h" -+ -+class TraceFunction; -+class TraceData; -+class StackBrowser; -+class NestedAreaItem; -+ -+class StackSelection : public StackSelectionBase -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ StackSelection( TQWidget* parent = 0, const char* name = 0); -+ ~StackSelection(); -+ -+ TraceData* data() const { return _data; } -+ void setData(TraceData*); -+ StackBrowser* browser() const { return _browser; } -+ TraceCostType* costType() { return _costType; } -+ TraceCostType* costType2() { return _costType2; } -+ TraceItem::CostType groupType() { return _groupType; } -+ -+signals: -+ void functionSelected(TraceItem*); -+ -+public slots: -+ void setFunction(TraceFunction*); -+ void setCostType(TraceCostType*); -+ void setCostType2(TraceCostType*); -+ void setGroupType(TraceItem::CostType); -+ -+ void stackSelected( TQListViewItem* ); -+ void browserBack(); -+ void browserForward(); -+ void browserUp(); -+ void browserDown(); -+ void refresh(); -+ void rebuildStackList(); -+ -+private: -+ void selectFunction(); -+ -+ TraceData* _data; -+ StackBrowser* _browser; -+ TQListViewItem* _item; -+ TraceFunction* _function; -+ TraceCostType* _costType; -+ TraceCostType* _costType2; -+ TraceItem::CostType _groupType; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/stackselectionbase.ui b/kdecachegrind/kdecachegrind/stackselectionbase.ui -new file mode 100644 -index 0000000..c61010f ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/stackselectionbase.ui -@@ -0,0 +1,80 @@ -+ -+StackSelectionBase -+ -+ -+ StackSelectionBase -+ -+ -+ -+ 0 -+ 0 -+ 168 -+ 108 -+ -+ -+ -+ Stack Selection -+ -+ -+ -+ unnamed -+ -+ -+ 3 -+ -+ -+ 6 -+ -+ -+ -+ -+ Cost -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Cost2 -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Calls -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ -+ Function -+ -+ -+ true -+ -+ -+ true -+ -+ -+ -+ stackList -+ -+ -+ -+ -+ -+ -diff --git a/kdecachegrind/kdecachegrind/subcost.cpp b/kdecachegrind/kdecachegrind/subcost.cpp -new file mode 100644 -index 0000000..7b5034e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/subcost.cpp -@@ -0,0 +1,62 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2004 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include -+ -+#include "subcost.h" -+ -+//--------------------------------------------------- -+// SubCost -+ -+bool SubCost::set(const char** ps) -+{ -+ const char* s = *ps; -+ if (!s || (*s < '0') || (*s > '9')) return false; -+ -+ v = *s - '0'; -+ s++; -+ while(*s >= '0' && *s <= '9') { -+ v = 10* v + (*s-'0'); -+ s++; -+ } -+ while(*s == ' ') s++; -+ *ps = s; -+ -+ return true; -+} -+ -+TQString SubCost::pretty() -+{ -+ unsigned long long n = v; -+ -+ if (n==0) return TQString(" 0"); -+ -+ int i = 0; -+ TQString res = ""; -+ -+ while (n) { -+ if ((i>0) && !(i%3)) res = " " + res; -+ i++; -+ res = TQChar('0'+int(n%10)) + res; -+ n /= 10; -+ } -+ res = " " + res; -+ return res; -+} -+ -+ -diff --git a/kdecachegrind/kdecachegrind/subcost.h b/kdecachegrind/kdecachegrind/subcost.h -new file mode 100644 -index 0000000..8169280 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/subcost.h -@@ -0,0 +1,66 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002-2004 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#ifndef SUBCOST_H -+#define SUBCOST_H -+ -+#include "utils.h" -+ -+typedef unsigned long long uint64; -+ -+/** -+ * Cost event counter, simple wrapper around a 64bit entity -+ */ -+class SubCost -+{ -+ public: -+ SubCost() {} -+ SubCost(uint64 i) { v=i; } -+ SubCost(unsigned i) { v=i; } -+ SubCost(int i) { v=(unsigned)i; } -+ SubCost(double d) { v= (uint64)(d + .5); } -+ -+ SubCost& operator=(uint64 i) { v = i; return *this; } -+ SubCost& operator=(unsigned i) { v = i; return *this; } -+ SubCost& operator=(int i) { v = i; return *this; } -+ SubCost& operator=(double d) { v = (uint64)(d + .5); return *this; } -+ -+ bool set(const char** s); -+ bool set(FixString& s) { return s.stripUInt64(v); } -+ -+ operator uint64&() { return v; } -+ -+ bool operator==(unsigned i) const { return v == i; } -+ bool operator==(int i) const { return v == (unsigned)i; } -+ bool operator<(unsigned i) const { return v < i; } -+ bool operator<(int i) const { return v < (unsigned)i; } -+ bool operator<(const SubCost& s) const { return v < s.v; } -+ bool operator>(unsigned i) const { return v > i; } -+ bool operator>(int i) const { return v > (unsigned)i; } -+ bool operator>(const SubCost& s) const { return v > s.v; } -+ -+ /** -+ * Convert SubCost value into a TQString, -+ * spaced every 3 digits. -+ */ -+ TQString pretty(); -+ -+ uint64 v; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/tabview.cpp b/kdecachegrind/kdecachegrind/tabview.cpp -new file mode 100644 -index 0000000..0049d1e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/tabview.cpp -@@ -0,0 +1,890 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Tab View, enclosing detailed views for one trace item in -+ * two tab widgets, separated by a splitter -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "tabview.h" -+#include "costtypeview.h" -+#include "partview.h" -+#include "callview.h" -+#include "coverageview.h" -+#include "callmapview.h" -+#include "instrview.h" -+#include "sourceview.h" -+#include "callgraphview.h" -+ -+// TabBar -+ -+TabBar::TabBar(TabView* v, TQTabWidget* parent, const char *name) -+ : TQTabBar(parent, name) -+{ -+ _tabWidget = parent; -+ _tabView = v; -+} -+ -+void TabBar::mousePressEvent(TQMouseEvent *e) -+{ -+ if (e->button() == Qt::RightButton) { -+ TQTab *tab = selectTab( e->pos() ); -+ TQWidget* page; -+ page = tab ? _tabWidget->page( indexOf( tab->identifier() ) ) :0; -+ -+ TQPopupMenu popup, popup1, popup2, popup3; -+ if (page) { -+ TraceItemView::Position p = _tabView->tabPosition(page); -+ if (p != TraceItemView::Top) { -+ popup.insertItem(i18n("Move to Top"), 81); -+ popup2.insertItem(i18n("Top"), 91); -+ } -+ if (p != TraceItemView::Right) { -+ popup.insertItem(i18n("Move to Right"), 82); -+ popup2.insertItem(i18n("Right"), 92); -+ } -+ if (p != TraceItemView::Bottom) { -+ popup.insertItem(i18n("Move to Bottom"), 83); -+ popup2.insertItem(i18n("Bottom"), 93); -+ } -+ if (p != TraceItemView::Left) { -+ popup.insertItem(i18n("Move to Bottom Left"), 84); -+ popup2.insertItem(i18n("Bottom Left"), 94); -+ } -+ popup.insertItem(i18n("Move Area To"), &popup2, 2); -+ popup.insertSeparator(); -+ popup.insertItem(i18n("Hide This Tab"), 80); -+ popup.insertItem(i18n("Hide Area"), 90); -+ -+ if (_tabView->visibleTabs() <2) { -+ popup.setItemEnabled(80, false); -+ popup.setItemEnabled(90, false); -+ } -+ else if (_tabView->visibleAreas() <2) -+ popup.setItemEnabled(90, false); -+ } -+ popup3.insertItem(i18n("Top"), 101); -+ popup3.insertItem(i18n("Right"), 102); -+ popup3.insertItem(i18n("Bottom"), 103); -+ popup3.insertItem(i18n("Bottom Left"), 104); -+ popup.insertItem(i18n("Show Hidden On"), &popup3, 3); -+ -+ int r = popup.exec( mapToGlobal( e->pos() ) ); -+ -+ TraceItemView::Position p = TraceItemView::Hidden; -+ if ((r % 10) == 1) p = TraceItemView::Top; -+ if ((r % 10) == 2) p = TraceItemView::Right; -+ if ((r % 10) == 3) p = TraceItemView::Bottom; -+ if ((r % 10) == 4) p = TraceItemView::Left; -+ -+ if (r>=80 && r<100) _tabView->moveTab(page, p, r>=90); -+ if (r>=100 && r<110) _tabView->moveTab(0, p, true); -+ } -+ -+ TQTabBar::mousePressEvent( e ); -+} -+ -+ -+// -+// Splitter -+// -+ -+Splitter::Splitter(Qt::Orientation o, TQWidget* parent, const char* name) -+ : TQSplitter(o, parent, name) -+{} -+ -+void Splitter::moveEvent(TQMoveEvent* e) -+{ -+ TQSplitter::moveEvent(e); -+ -+ if (0) qDebug("Splitter %s: Move", name()); -+ checkVisiblity(); -+} -+ -+void Splitter::checkVisiblity() -+{ -+ const TQObjectList l = childrenListObject(); -+ TQObjectListIt it( l ); -+ TQObject *obj; -+ while ( (obj = it.current()) != 0 ) { -+ ++it; -+ if (obj->isA("Splitter")) ((Splitter*)obj)->checkVisiblity(); -+ else if (obj->isA("TabWidget")) ((TabWidget*)obj)->checkVisibility(); -+ } -+} -+ -+ -+ -+ -+// -+// TabWidget -+// -+ -+TabWidget::TabWidget(TabView* v, TQWidget* parent, -+ const char* name, WFlags f) -+ : TQTabWidget(parent, name, f) -+{ -+ _hasVisibleRect = false; -+ setTabBar(new TabBar(v, this)); -+} -+ -+void TabWidget::checkVisibility() -+{ -+ bool hasVisibleRect = (visibleRect().width()>1) && -+ (visibleRect().height()>1); -+ -+ if (0) qDebug("TabWidget %s: VR (%dx%d) HasVisibleRect: %s => %s", -+ name(), -+ visibleRect().width(), visibleRect().height(), -+ _hasVisibleRect ? "Yes":"No", -+ hasVisibleRect ? "Yes":"No"); -+ -+ if (hasVisibleRect != _hasVisibleRect) { -+ _hasVisibleRect = hasVisibleRect; -+ emit visibleRectChanged(this); -+ } -+} -+ -+void TabWidget::resizeEvent(TQResizeEvent *e) -+{ -+ TQTabWidget::resizeEvent(e); -+ if (0) qDebug("TabWidget %s:\n Resize from (%d/%d) to (%d/%d)", -+ name(), -+ e->oldSize().width(), e->oldSize().height(), -+ e->size().width(), e->size().height()); -+ checkVisibility(); -+} -+ -+void TabWidget::showEvent(TQShowEvent* e) -+{ -+ TQTabWidget::showEvent(e); -+ -+ if (0) qDebug("TabWidget %s: Show", name()); -+ checkVisibility(); -+} -+ -+void TabWidget::hideEvent(TQHideEvent* e) -+{ -+ TQTabWidget::hideEvent(e); -+ -+ if (0) qDebug("TabWidget %s: Hide", name()); -+ checkVisibility(); -+} -+ -+void TabWidget::moveEvent(TQMoveEvent* e) -+{ -+ TQTabWidget::moveEvent(e); -+ -+ if (0) qDebug("TabWidget %s: Move", name()); -+ checkVisibility(); -+} -+ -+ -+ -+// -+// TabView -+// -+ -+/* -+ * Areas for child views -+ * -+ * leftSplitter -+ * | -+ * | ----- ----- -+ * | _/ \_______________/ \____ -+ * | | Top | TopRight | -+ * | | | | -+ * -> |---------------------| | -+ * | BottomLeft | Bottom | | -+ * | | | | -+ * -\_____/------\____/-------------- -+ * -+ * ^ ^ -+ * bottomSplitter mainSplitter -+ */ -+ -+TabView::TabView(TraceItemView* parentView, -+ TQWidget* parent, const char* name) -+ : TQWidget(parent, name), TraceItemView(parentView) -+{ -+ setFocusPolicy(TQ_StrongFocus); -+ -+ _isCollapsed = true; -+ -+ TQVBoxLayout* vbox = new TQVBoxLayout( this, 6, 6); -+ -+ _nameLabel = new KSqueezedTextLabel( this, "nameLabel" ); -+ _nameLabel->setText(i18n("(No profile data file loaded)")); -+ vbox->addWidget( _nameLabel ); -+ -+ _mainSplitter = new TQSplitter(Qt::Horizontal, this); -+ _leftSplitter = new Splitter(Qt::Vertical, _mainSplitter, "Left"); -+ vbox->addWidget( _mainSplitter ); -+ -+ _rightTW = new TabWidget(this, _mainSplitter, "Right"); -+ connect(_rightTW, TQT_SIGNAL(currentChanged(TQWidget*)), -+ this, TQT_SLOT(tabChanged(TQWidget*))); -+ connect(_rightTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)), -+ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*))); -+ -+ _topTW = new TabWidget(this, _leftSplitter, "Top"); -+ connect(_topTW, TQT_SIGNAL(currentChanged(TQWidget*)), -+ this, TQT_SLOT(tabChanged(TQWidget*))); -+ connect(_topTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)), -+ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*))); -+ -+ _bottomSplitter = new Splitter(Qt::Horizontal, -+ _leftSplitter, "Bottom"); -+ -+ _leftTW = new TabWidget(this, _bottomSplitter, "Left"); -+ _leftTW->setTabPosition(TQTabWidget::Bottom); -+ connect(_leftTW, TQT_SIGNAL(currentChanged(TQWidget*)), -+ this, TQT_SLOT(tabChanged(TQWidget*))); -+ connect(_leftTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)), -+ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*))); -+ -+ _bottomTW = new TabWidget(this, _bottomSplitter, "Bottom"); -+ _bottomTW->setTabPosition(TQTabWidget::Bottom); -+ connect(_bottomTW, TQT_SIGNAL(currentChanged(TQWidget*)), -+ this, TQT_SLOT(tabChanged(TQWidget*))); -+ connect(_bottomTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)), -+ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*))); -+ -+ -+ // default positions... -+ -+ addTop( addTab( i18n("Types"), -+ new CostTypeView(this, _topTW, -+ "CostTypeView"))); -+ addTop( addTab( i18n("Callers"), -+ new CallView(true, this, _topTW, -+ "CallerView"))); -+ addTop( addTab( i18n("All Callers"), -+ new CoverageView(true, this, _topTW, -+ "AllCallerView"))); -+ addTop( addTab( i18n("Caller Map"), -+ new CallMapView(true, this, _bottomTW, -+ "CallerMapView"))); -+ addTop( addTab( i18n("Source"), -+ new SourceView(this, _topTW, -+ "SourceView"))); -+ -+ addBottom( addTab( i18n("Parts"), -+ new PartView(this, _bottomTW, -+ "PartView"))); -+ addBottom( addTab( i18n("Call Graph"), -+ new CallGraphView(this, _bottomTW, -+ "CallGraphView"))); -+ addBottom( addTab( i18n("Callees"), -+ new CallView(false, this, _bottomTW, -+ "CalleeView"))); -+ addBottom( addTab( i18n("All Callees"), -+ new CoverageView(false, this, _bottomTW, -+ "AllCalleeView"))); -+ -+ addBottom( addTab( i18n("Callee Map"), -+ new CallMapView(false, this, _topTW, -+ "CalleeMapView"))); -+ addBottom( addTab( i18n("Assembler"), -+ new InstrView(this, _bottomTW, -+ "InstrView"))); -+ -+ // after all child widgets are created... -+ _lastFocus = 0; -+ _active = false; -+ installFocusFilters(); -+ -+ updateVisibility(); -+ -+ TQWhatsThis::add( this, whatsThis() ); -+} -+ -+void TabView::setData(TraceData* d) -+{ -+ TraceItemView::setData(d); -+ -+ TraceItemView* v; -+ for (v=_tabs.first();v;v=_tabs.next()) -+ v->setData(d); -+} -+ -+TraceItemView* TabView::addTab(TQString label, TraceItemView* view) -+{ -+ view->setTitle(label); -+ _tabs.append(view); -+ return view; -+} -+ -+void TabView::addTop(TraceItemView* view) -+{ -+ view->setPosition(TraceItemView::Top); -+ _topTW->insertTab(view->widget(), view->title()); -+} -+ -+void TabView::addBottom(TraceItemView* view) -+{ -+ view->setPosition(TraceItemView::Bottom); -+ _bottomTW->insertTab(view->widget(), view->title()); -+} -+ -+TraceItemView::Position TabView::tabPosition(TQWidget* w) -+{ -+ TraceItemView* v; -+ for (v=_tabs.first();v;v=_tabs.next()) -+ if (v->widget() == w) return v->position(); -+ -+ return Hidden; -+} -+ -+int TabView::visibleTabs() -+{ -+ int c = 0; -+ TraceItemView* v; -+ for (v=_tabs.first();v;v=_tabs.next()) { -+ if (v->position() == Hidden) continue; -+ c++; -+ } -+ return c; -+} -+ -+ -+int TabView::visibleAreas() -+{ -+ int c = 0, t = 0, b = 0, r = 0, l = 0; -+ TraceItemView* v; -+ for (v=_tabs.first();v;v=_tabs.next()) { -+ switch(v->position()) { -+ case TraceItemView::Top: t++; break; -+ case TraceItemView::Bottom: b++; break; -+ case TraceItemView::Left: l++; break; -+ case TraceItemView::Right: r++; break; -+ default: break; -+ } -+ } -+ if (t>0) c++; -+ if (b>0) c++; -+ if (l>0) c++; -+ if (r>0) c++; -+ -+ return c; -+} -+ -+ -+ -+// This hides/shows splitters and tabwidgets according to tab childs -+void TabView::updateVisibility() -+{ -+ // calculate count of tabs in areas -+ int t = 0, b = 0, r = 0, l = 0; -+ TraceItemView* v; -+ for (v=_tabs.first();v;v=_tabs.next()) { -+ switch(v->position()) { -+ case TraceItemView::Top: t++; break; -+ case TraceItemView::Bottom: b++; break; -+ case TraceItemView::Left: l++; break; -+ case TraceItemView::Right: r++; break; -+ default: break; -+ } -+ } -+ -+ if (0) qDebug("TabView::updateVisiblity t %d, b %d, l %d, r %d", -+ t, b, l, r); -+ -+ TQValueList s; -+ s.append(100); -+ -+ -+ // children of mainSplitter -+ if (_rightTW->isHidden() != (r == 0)) { -+ if (r == 0) { -+ _rightTW->hide(); -+ -+ if (!_topTW->hasVisibleRect() && -+ !_bottomTW->hasVisibleRect() && -+ !_leftTW->hasVisibleRect()) _mainSplitter->setSizes(s); -+ } -+ else -+ _rightTW->show(); -+ } -+ if (_leftSplitter->isHidden() != (t+b+l == 0)) { -+ if (t+b+l == 0) { -+ _leftSplitter->hide(); -+ -+ if (!_rightTW->hasVisibleRect()) _mainSplitter->setSizes(s); -+ } -+ else -+ _leftSplitter->show(); -+ } -+ -+ // children of leftSplitter -+ if (_topTW->isHidden() != (t == 0)) { -+ if (t == 0) { -+ _topTW->hide(); -+ -+ if (!_bottomTW->hasVisibleRect() && -+ !_leftTW->hasVisibleRect()) _leftSplitter->setSizes(s); -+ } -+ else -+ _topTW->show(); -+ } -+ -+ if (_bottomSplitter->isHidden() != (b+l == 0)) { -+ if (b+l == 0) { -+ _bottomSplitter->hide(); -+ -+ if (!_topTW->hasVisibleRect()) _leftSplitter->setSizes(s); -+ } -+ else -+ _bottomSplitter->show(); -+ } -+ -+ // children of bottomSplitter -+ if (_bottomTW->isHidden() != (b == 0)) { -+ if (b == 0) { -+ _bottomTW->hide(); -+ -+ if (!_leftTW->hasVisibleRect()) _bottomSplitter->setSizes(s); -+ } -+ else -+ _bottomTW->show(); -+ } -+ if (_leftTW->isHidden() != (l == 0)) { -+ if (l == 0) { -+ _leftTW->hide(); -+ -+ if (!_bottomTW->hasVisibleRect()) _bottomSplitter->setSizes(s); -+ } -+ else -+ _leftTW->show(); -+ } -+} -+ -+TabWidget* TabView::tabWidget(Position p) -+{ -+ switch(p) { -+ case TraceItemView::Top: return _topTW; -+ case TraceItemView::Bottom: return _bottomTW; -+ case TraceItemView::Left: return _leftTW; -+ case TraceItemView::Right: return _rightTW; -+ default: break; -+ } -+ return 0; -+} -+ -+void TabView::moveTab(TQWidget* w, Position p, bool wholeArea) -+{ -+ TraceItemView *v; -+ Position origPos = Hidden; -+ if (w) { -+ for (v=_tabs.first();v;v=_tabs.next()) -+ if (v->widget() == w) break; -+ -+ if (!v) return; -+ origPos = v->position(); -+ } -+ if (origPos == p) return; -+ -+ TabWidget *from, *to; -+ from = tabWidget(origPos); -+ to = tabWidget(p); -+ -+ TQPtrList tabs; -+ for (v=_tabs.first();v;v=_tabs.next()) -+ if ((v->position() == origPos) && -+ (wholeArea || (v->widget() == w))) tabs.append(v); -+ -+ bool isEnabled; -+ for (v=tabs.first();v;v=tabs.next()) { -+ v->setPosition(p); -+ w = v->widget(); -+ -+ if (from) { -+ isEnabled = from->isTabEnabled(w); -+ from->removePage(w); -+ } -+ else isEnabled = (v->canShow(_activeItem)!=0); -+ -+ if (to) { -+ TraceItemView *vv; -+ int idx = -1, i; -+ for(vv = _tabs.first(); vv && (vv!=v); vv = _tabs.next()) { -+ i = to->indexOf(vv->widget()); -+ if (i>=0) idx = i; -+ } -+ to->insertTab(w, v->title(), idx+1); -+ to->setTabEnabled(w, isEnabled); -+ if (isEnabled) { -+ to->showPage(w); -+ v->updateView(); -+ } -+ } -+ } -+ updateVisibility(); -+} -+ -+ -+TQString TabView::whatsThis() const -+{ -+ return i18n( "Information Tabs" -+ "

This widget shows information for the " -+ "current selected function in different tabs: " -+ "

    " -+ "
  • The Costs tab shows a list of available event types " -+ "and the inclusive and self costs regarding to these types.
  • " -+ "
  • The Parts tab shows a list of trace parts " -+ "if the trace consists of more than one part (otherwise, " -+ "this tab is hided). " -+ "The cost of the selected function spent in the different " -+ "parts together with the calls happening is shown.
  • " -+ "
  • The Call Lists tab shows direct callers and " -+ "callees of the function in more detail.
  • " -+ "
  • The Coverage tab shows the same is the Call " -+ "Lists tab, but not only direct callers and callees " -+ "but also indirect ones.
  • " -+ "
  • The Call Graph tab shows a graphical " -+ "visualization of the calls done by this function.
  • " -+ "
  • The Source tab presents annotated source code " -+ "if debugging information and the source file " -+ "is available.
  • " -+ "
  • The Assembler tab presents annotated assembler code " -+ "if trace information on instruction level " -+ "is available.
" -+ "For more information, see the What's This? " -+ "help of the corresponding tab widget

"); -+} -+ -+void TabView::installFocusFilters() -+{ -+ TQObjectList *l = queryList(TQWIDGET_OBJECT_NAME_STRING); -+ TQObjectListIt it( *l ); -+ TQObject *obj; -+ -+ while ( (obj = it.current()) != 0 ) { -+ ++it; -+ if ( ((TQWidget*)obj)->isFocusEnabled() ) -+ obj->installEventFilter(this); -+ } -+ delete l; -+} -+ -+ -+bool TabView::eventFilter(TQObject* o, TQEvent* e) -+{ -+ if (e->type() == TQEvent::FocusIn) { -+ _lastFocus = o->isWidgetType() ? (TQWidget*) o : 0; -+ setActive(_lastFocus != 0); -+ } -+ return TQWidget::eventFilter(o,e); -+} -+ -+void TabView::mousePressEvent(TQMouseEvent*) -+{ -+ if (_lastFocus) -+ _lastFocus->setFocus(); -+ setActive(true); -+} -+ -+void TabView::setActive(bool a) -+{ -+ if (a == _active) return; -+ _active = a; -+ -+ TQFont nameLabel_font( _nameLabel->font() ); -+ nameLabel_font.setBold(a); -+ _nameLabel->setFont( nameLabel_font ); -+ -+ if (0) qDebug("%s::setActive(%s)", name(), a ? "true":"false"); -+ -+ if (a) emit activated(this); -+} -+ -+void TabView::doUpdate(int changeType) -+{ -+ if (changeType & (activeItemChanged | configChanged | dataChanged)) -+ -+ _nameLabel->setText( !_data ? i18n("(No Data loaded)") : -+ !_activeItem ? i18n("(No function selected)") : -+ _activeItem->prettyName()); -+ -+ -+ // we use our own list iterators because setTabEnabled can -+ // invoke tabChanged, which mangles with the lists, too -+ bool canShow; -+ TraceItemView *v; -+ TQPtrListIterator it( _tabs ); -+ while ( (v=it.current()) != 0) { -+ ++it; -+ -+ TabWidget *tw = 0; -+ switch(v->position()) { -+ case TraceItemView::Top: tw = _topTW; break; -+ case TraceItemView::Bottom: tw = _bottomTW; break; -+ case TraceItemView::Left: tw = _leftTW; break; -+ case TraceItemView::Right: tw = _rightTW; break; -+ default: break; -+ } -+ -+ // update even if hidden -+ if (tw) { -+ if (!tw->hasVisibleRect()) continue; -+ } -+ canShow = v->set(changeType, _data, _costType, _costType2, -+ _groupType, _partList, -+ _activeItem, _selectedItem); -+ v->notifyChange(changeType); -+ -+ if (!tw) continue; -+ if (tw->isTabEnabled(v->widget()) != canShow) -+ tw->setTabEnabled(v->widget(), canShow); -+ -+ if (v->widget() == tw->currentPage()) -+ v->updateView(); -+ } -+} -+ -+ -+void TabView::tabChanged(TQWidget* w) -+{ -+ TraceItemView *v; -+ for (v=_tabs.first();v;v=_tabs.next()) -+ if (v->widget() == w) v->updateView(); -+} -+ -+void TabView::visibleRectChangedSlot(TabWidget* tw) -+{ -+ if (0) qDebug("%s: %svisible !", -+ tw->name(), tw->hasVisibleRect() ? "":"un"); -+ -+ if (tw->hasVisibleRect()) doUpdate(0); -+} -+ -+void TabView::resizeEvent(TQResizeEvent* e) -+{ -+ TQWidget::resizeEvent(e); -+ -+ bool collapsed = (e->size().width()<=1) || (e->size().height()<=1); -+ if (_isCollapsed != collapsed) { -+ _isCollapsed = collapsed; -+ updateView(); -+ } -+ -+ if (0) qDebug("TabView::Resize from (%d/%d) to (%d/%d)", -+ e->oldSize().width(), e->oldSize().height(), -+ e->size().width(), e->size().height()); -+} -+ -+void TabView::selected(TraceItemView*, TraceItem* s) -+{ -+ // we set selected item for our own children -+ select(s); -+ updateView(); -+ -+ // still forward to parent -+ if (_parentView) _parentView->selected(this, s); -+} -+ -+ -+void TabView::readViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, -+ bool withOptions) -+{ -+ if (0) qDebug("%s::readConfig(%s%s)", name(), -+ prefix.ascii(), postfix.ascii()); -+ -+ KConfigGroup* g = configGroup(c, prefix, postfix); -+ -+ _mainSplitter->setSizes(g->readIntListEntry("MainSizes")); -+ _leftSplitter->setSizes(g->readIntListEntry("LeftSizes")); -+ _bottomSplitter->setSizes(g->readIntListEntry("BottomSizes")); -+ -+ TQString activeT = g->readEntry("ActiveTop", "CallerView"); -+ TQString activeB = g->readEntry("ActiveBottom", "CalleeView"); -+ TQString activeL = g->readEntry("ActiveLeft", ""); -+ TQString activeR = g->readEntry("ActiveRight", ""); -+ -+ TQStringList topTabs = g->readListEntry("TopTabs"); -+ TQStringList bottomTabs = g->readListEntry("BottomTabs"); -+ TQStringList leftTabs = g->readListEntry("LeftTabs"); -+ TQStringList rightTabs = g->readListEntry("RightTabs"); -+ -+ if (topTabs.isEmpty() && bottomTabs.isEmpty() && -+ rightTabs.isEmpty() && leftTabs.isEmpty()) { -+ // no tabs visible ?! Reset to default -+ topTabs << "CostTypeView" << "CallerView" << "AllCallerView" -+ << "CalleeMapView" << "SourceView"; -+ bottomTabs << "PartView" << "CalleeView" << "CallGraphView" -+ << "AllCalleeView" << "CallerMapView" << "InstrView"; -+ } -+ -+ TraceItemView *activeTop = 0, *activeBottom = 0; -+ TraceItemView *activeLeft = 0, *activeRight = 0; -+ -+ moveTab(0, TraceItemView::Top, true); -+ TraceItemView *v; -+ TQPtrListIterator it( _tabs ); -+ while ( (v=it.current()) != 0) { -+ ++it; -+ -+ TQString n = TQString(v->widget()->name()); -+ if (topTabs.contains(n)) { -+ moveTab(v->widget(), TraceItemView::Top); -+ if (n == activeT) activeTop = v; -+ } -+ else if (bottomTabs.contains(n)) { -+ moveTab(v->widget(), TraceItemView::Bottom); -+ if (n == activeB) activeBottom = v; -+ } -+ else if (leftTabs.contains(n)) { -+ moveTab(v->widget(), TraceItemView::Left); -+ if (n == activeL) activeLeft = v; -+ } -+ else if (rightTabs.contains(n)) { -+ moveTab(v->widget(), TraceItemView::Right); -+ if (n == activeR) activeRight = v; -+ } -+ else moveTab(v->widget(), Hidden); -+ -+ if (withOptions) -+ v->readViewConfig(c, TQString("%1-%2") -+ .arg(prefix).arg(v->widget()->name()), -+ postfix, true); -+ } -+ if (activeTop) _topTW->showPage(activeTop->widget()); -+ if (activeBottom)_bottomTW->showPage(activeBottom->widget()); -+ if (activeLeft) _leftTW->showPage(activeLeft->widget()); -+ if (activeRight) _rightTW->showPage(activeRight->widget()); -+ -+ TQString activeType = g->readEntry("ActiveItemType", ""); -+ TQString activeName = g->readEntry("ActiveItemName", ""); -+ TQString selectedType = g->readEntry("SelectedItemType", ""); -+ TQString selectedName = g->readEntry("SelectedItemName", ""); -+ delete g; -+ -+ if (!_data) return; -+ -+ if (withOptions) { -+ // restore active item -+ TraceItem::CostType t = TraceItem::costType(activeType); -+ if (t==TraceItem::NoCostType) t = TraceItem::Function; -+ TraceCost* activeItem = _data->search(t, activeName, _costType); -+ if (!activeItem) return; -+ activate(activeItem); -+ -+ // restore selected item -+ t = TraceItem::costType(selectedType); -+ if (t==TraceItem::NoCostType) t = TraceItem::Function; -+ TraceCost* selectedItem = _data->search(t, selectedName, -+ _costType, activeItem); -+ if (selectedItem) select(selectedItem); -+ } -+ -+ updateView(); -+} -+ -+void TabView::saveViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, -+ bool withOptions) -+{ -+ KConfigGroup g(c, (prefix+postfix).ascii()); -+ -+ g.writeEntry("MainSizes", _mainSplitter->sizes()); -+ g.writeEntry("LeftSizes", _leftSplitter->sizes()); -+ g.writeEntry("BottomSizes", _bottomSplitter->sizes()); -+ -+ TQString a; -+ if ((_topTW->count()>0) && -+ (_topTW->isTabEnabled(_topTW->currentPage()))) -+ a = TQString(_topTW->currentPage()->name()); -+ g.writeEntry("ActiveTop", a); -+ -+ a.setLength(0); -+ if ((_bottomTW->count()>0) && -+ (_bottomTW->isTabEnabled(_bottomTW->currentPage()))) -+ a = TQString(_bottomTW->currentPage()->name()); -+ g.writeEntry("ActiveBottom", a); -+ -+ a.setLength(0); -+ if ((_leftTW->count()>0) && -+ (_leftTW->isTabEnabled(_leftTW->currentPage()))) -+ a = TQString(_leftTW->currentPage()->name()); -+ g.writeEntry("ActiveLeft", a); -+ -+ a.setLength(0); -+ if ((_rightTW->count()>0) && -+ (_rightTW->isTabEnabled(_rightTW->currentPage()))) -+ a = TQString(_rightTW->currentPage()->name()); -+ g.writeEntry("ActiveRight", a); -+ -+ if (withOptions) -+ if (_activeItem) { -+ g.writeEntry("ActiveItemType", -+ TraceItem::typeName(_activeItem->type())); -+ g.writeEntry("ActiveItemName", _activeItem->name()); -+ if (_selectedItem) { -+ g.writeEntry("SelectedItemType", -+ TraceItem::typeName(_selectedItem->type())); -+ g.writeEntry("SelectedItemName", _selectedItem->name()); -+ } -+ } -+ -+ TQStringList topList, bottomList, leftList, rightList; -+ TraceItemView *v; -+ for (v=_tabs.first();v;v=_tabs.next()) { -+ switch(v->position()) { -+ case TraceItemView::Top: -+ topList << TQString(v->widget()->name()); -+ break; -+ -+ case TraceItemView::Bottom: -+ bottomList << TQString(v->widget()->name()); -+ break; -+ -+ case TraceItemView::Left: -+ leftList << TQString(v->widget()->name()); -+ break; -+ -+ case TraceItemView::Right: -+ rightList << TQString(v->widget()->name()); -+ break; -+ -+ default: break; -+ } -+ } -+ -+ g.writeEntry("TopTabs", topList); -+ g.writeEntry("BottomTabs", bottomList); -+ g.writeEntry("LeftTabs", leftList); -+ g.writeEntry("RightTabs", rightList); -+ -+ if (withOptions) -+ for (v=_tabs.first();v;v=_tabs.next()) -+ v->saveViewConfig(c, TQString("%1-%2").arg(prefix) -+ .arg(v->widget()->name()), postfix, true); -+} -+ -+#include "tabview.moc" -diff --git a/kdecachegrind/kdecachegrind/tabview.h b/kdecachegrind/kdecachegrind/tabview.h -new file mode 100644 -index 0000000..b9b4026 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/tabview.h -@@ -0,0 +1,174 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Tab View, enclosing detailed views for one trace item in -+ * two tab widgets, separated by a splitter -+ */ -+ -+#ifndef TABVIEW_H -+#define TABVIEW_H -+ -+#include -+#include -+#include -+#include -+#include -+#include "traceitemview.h" -+ -+class TQSplitter; -+class TabView; -+ -+/** -+ * Subclass of TQTabBar to enable context menu on tabs -+ */ -+class TabBar : public TQTabBar -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+ public: -+ TabBar(TabView*, TQTabWidget* parent, const char *name = 0); -+ protected: -+ void mousePressEvent(TQMouseEvent *e); -+ -+ private: -+ TQTabWidget* _tabWidget; -+ TabView* _tabView; -+}; -+ -+ -+/** -+ * Own Splitter: -+ * Call checkVisiblity for all TabWidget children of the splitter -+ * on a MoveEvent. This typically is produced when collapsing the widget -+ * inside of another splitter. -+ */ -+class Splitter: public TQSplitter -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ Splitter(Qt::Orientation o, TQWidget* parent = 0, const char* name = 0); -+ void checkVisiblity(); -+ -+protected: -+ void moveEvent(TQMoveEvent *); -+}; -+ -+ -+/** -+ * Own TabView: -+ * - A TQTabWidget able to track its visible rect via resizeEvents. -+ * This is needed to track if this widget is collapsed in a TQSplitter. -+ * - Use own TabBar for context menu -+ */ -+class TabWidget: public TQTabWidget -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ -+ TabWidget(TabView*, TQWidget* parent = 0, -+ const char* name = 0, WFlags f = 0); -+ -+ bool hasVisibleRect() { return _hasVisibleRect; } -+ void checkVisibility(); -+ -+signals: -+ void visibleRectChanged(TabWidget*); -+ -+protected: -+ void resizeEvent(TQResizeEvent *); -+ void showEvent(TQShowEvent *); -+ void hideEvent(TQHideEvent *); -+ void moveEvent(TQMoveEvent *); -+ -+private: -+ bool _hasVisibleRect; -+}; -+ -+ -+ -+class TabView : public TQWidget, public TraceItemView -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ -+ TabView(TraceItemView* parentView, -+ TQWidget* parent = 0, const char* name = 0); -+ -+ virtual TQWidget* widget() { return this; } -+ TQString whatsThis() const ; -+ void setData(TraceData*); -+ bool isViewVisible() const { return !_isCollapsed; } -+ void selected(TraceItemView*, TraceItem*); -+ bool active() const { return _active; } -+ void setActive(bool); -+ -+ /** -+ * Rearrange tabs -+ * if == 0, move hidden tabs -+ */ -+ void moveTab(TQWidget* w, Position, bool wholeArea = false); -+ -+ Position tabPosition(TQWidget*); -+ int visibleTabs(); -+ int visibleAreas(); -+ -+ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool); -+ -+public slots: -+ void tabChanged(TQWidget*); -+ void visibleRectChangedSlot(TabWidget*); -+ -+signals: -+ void activated(TabView*); -+ -+protected: -+ void resizeEvent(TQResizeEvent *); -+ bool eventFilter(TQObject*, TQEvent*); -+ void mousePressEvent(TQMouseEvent*); -+ -+private: -+ TraceItemView* addTab(TQString, TraceItemView*); -+ void addTop(TraceItemView*); -+ void addBottom(TraceItemView*); -+ TabWidget* tabWidget(Position); -+ void updateVisibility(); -+ void doUpdate(int); -+ void installFocusFilters(); -+ -+ // this is true if width or height <= 1, and no child updates are done -+ bool _isCollapsed; -+ -+ KSqueezedTextLabel* _nameLabel; -+ TQSplitter *_mainSplitter, *_leftSplitter, *_bottomSplitter; -+ TabWidget *_topTW, *_leftTW, *_bottomTW, *_rightTW; -+ TQPtrList _tabs; -+ -+ TQWidget* _lastFocus; -+ bool _active; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/kdecachegrind.desktop b/kdecachegrind/kdecachegrind/kdecachegrind.desktop -new file mode 100644 -index 0000000..7089370 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/kdecachegrind.desktop -@@ -0,0 +1,103 @@ -+# KDE Config File -+[Desktop Entry] -+Type=Application -+Exec=kdecachegrind -caption "%c" %i %m %u -+MimeType=application/x-kcachegrind; -+Icon=kdecachegrind -+DocPath=kdecachegrind/index.html -+Terminal=false -+Name=KCachegrind -+Name[hi]=के-केश-गà¥à¤°à¤¿à¤‚ड -+Name[sv]=Kcachegrind -+Name[ta]= இடைமாறà¯à®±à®•à®Ÿà¯à®Ÿà®®à¯ -+GenericName=Profiler Frontend -+GenericName[bs]=Profiler frontend -+GenericName[ca]=Interfície de Profiler -+GenericName[cs]=Rozhraní pro profilaci -+GenericName[cy]=Blaen-wyneb Proffilydd -+GenericName[da]=Grænseflade til profilering -+GenericName[de]=Profiler Oberfläche -+GenericName[el]=ΠÏόγÏαμμα Ï€Ïοφίλ -+GenericName[eo]=Fasado de Profililo -+GenericName[es]=Interfaz para Profiler -+GenericName[et]=Profileerimisrakendus -+GenericName[eu]=Profilatzailearen interfazea -+GenericName[fa]=پایانۀ گزارش‌گیر -+GenericName[fi]=Profiloijan käyttöliittymä -+GenericName[fr]=Interface de profilage -+GenericName[ga]=Comhéadan ar Phróifíleoir -+GenericName[gl]=Interface para o profiler -+GenericName[hi]=पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²à¤° फà¥à¤°à¤¨à¥à¤Ÿà¤à¤£à¥à¤¡ -+GenericName[hu]=Profilozó -+GenericName[is]=Myndrænt viðmót á afkastakönnuð -+GenericName[it]=Interfaccia a profiler -+GenericName[ja]=プロファイラフロントエンド -+GenericName[ka]=პრáƒáƒ¤áƒ˜áƒšáƒ”რის Frontend -+GenericName[kk]=Профильдеткіштің интерфейÑÑ– -+GenericName[lt]=Profiliuoklio naudotojo sÄ…saja -+GenericName[nb]=Grensesnitt for profilvisning -+GenericName[nds]=Profiler-Böversiet -+GenericName[ne]=पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤²à¤° फà¥à¤°à¤¨à¥à¤Ÿà¤‡à¤¨à¥à¤¡ -+GenericName[nl]=Profiler-hulpprogramma -+GenericName[nn]=Grensesnitt for profilvising -+GenericName[pa]=ਪਰੋਫਾਇਲਰ ਮà©à©±à¨– ਭੂਮੀ -+GenericName[pl]=Interfejs do profilera -+GenericName[pt]=Interface de Profiler -+GenericName[pt_BR]=Interface para o Profiler -+GenericName[ru]=Профилировщик -+GenericName[sk]=Rozhranie pre profiler -+GenericName[sl]=Vmesnik profilnika -+GenericName[sr]=Графички Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÑ˜Ñ Ð·Ð° профајлер -+GenericName[sr@Latn]=GrafiÄki interfejs za profajler -+GenericName[sv]=Profileringsgränssnitt -+GenericName[ta]= விவரகà¯à®•à¯à®±à®¿à®ªà¯à®ªà¯ à®®à¯à®©à¯à®ªà®•à¯à®¤à®¿ -+GenericName[tg]=Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð±Ð° профилкунанда -+GenericName[tr]=Profil Önyüzü -+GenericName[uk]=Ð†Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð¾ Profiler -+GenericName[zh_CN]=个性数æ®å‰ç«¯ -+GenericName[zh_TW]=分æžå™¨å‰ç«¯ -+Comment=Visualization of Performance Profiling Data -+Comment[bg]=Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° данните за производителноÑÑ‚ -+Comment[bs]=Vizualizacija podataka za profiliranje performansi -+Comment[ca]=Visualizació de dades de perfilat de rendiment -+Comment[cs]=Vizualizace profilovacích dat výkonu -+Comment[da]=Visualisering af profileringsdata -+Comment[de]=Visualisierung von Daten des Laufzeitverhaltens eines Programmes -+Comment[el]=ΑναπαÏάσταση δεδομένων ταχÏτητας Ï€Ïοφίλ -+Comment[en_GB]=Visualisation of Performance Profiling Data -+Comment[es]=Visualización de datos de análisis de rendimiento -+Comment[et]=Jõudluse profileerimise andmete visualiseerimise vahend -+Comment[eu]=Errendimendu profil datuen bistaratzea -+Comment[fa]=تجسم کارایی گزارش داده‌ها -+Comment[fi]=Visualisointi tehokkuusprofiloinnin tiedoista -+Comment[fr]=Visualisation des données de performance de profilage -+Comment[gl]=Visualización dos datos da análise de rendimento -+Comment[hi]=परफारà¥à¤®à¥‡à¤¸ पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤²à¤¿à¤‚ग डाटा का विजà¥à¤…लाइज़ेशन -+Comment[hu]=Teljesítményprofil-adatok megjelenítése -+Comment[is]=Sjónræn framsetning gagna úr afkastakönnun -+Comment[it]=Visualizzazione dei dati di profiling delle prestazioni -+Comment[ja]=パフォーマンスプロファイルデータを視覚化 -+Comment[ka]=წáƒáƒ áƒ›áƒáƒ“áƒáƒ‘ის მáƒáƒžáƒ áƒáƒ¤áƒ¤áƒ˜áƒšáƒ”ბელი მáƒáƒœáƒáƒªáƒ”მების ვიზუáƒáƒšáƒ˜áƒ–áƒáƒªáƒ˜áƒ -+Comment[kk]=Деректерді профильдеудің визуализациÑÑÑ‹ -+Comment[lt]=Veikimo profiliavimo duomenų vizualizacija -+Comment[nb]=Vis informasjon om ytelse. -+Comment[nds]=Visualiseren vun Programmleisten-Looptietdaten -+Comment[ne]=समà¥à¤ªà¤¾à¤¦à¤¨ पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤²à¤¿à¤™ डाटाको दृषà¥à¤Ÿà¤¿à¤•à¤°à¤£ -+Comment[nl]=Visualisatie van Performance Profiling Data -+Comment[nn]=Vis informasjon om yting -+Comment[pl]=Wizualizacja danych profilowania wydajnoÅ›ci -+Comment[pt]=Visualização dos Dados de Análise de Performance -+Comment[pt_BR]=Visualização de Dados de Perfil de Desempenho -+Comment[ru]=Утилита Ð´Ð»Ñ Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹ -+Comment[sk]=Vizualizácia dát o výkone -+Comment[sl]=Vizualizacija podatkov profilnih zmogljivosti -+Comment[sr]=Визуелизација података о профилиÑању перформанÑи -+Comment[sr@Latn]=Vizuelizacija podataka o profilisanju performansi -+Comment[sv]=Ã…skÃ¥dliggörande av profileringsdata för prestanda -+Comment[ta]= விவர தகவலை செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ காடà¯à®šà®¿à®¯à®¾à®³à®¿à®ªà¯à®ªà¯ -+Comment[tg]=Утилита барои гузориши профили визуалӣ -+Comment[uk]=Ð’Ñ–Ð·ÑƒÐ°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð´Ð°Ð½Ð¸Ñ… Ð¿Ñ€Ð¾Ñ„Ñ–Ð»ÑŽÐ²Ð°Ð½Ð½Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ð´Ñ–Ñ— -+Comment[zh_CN]=性能个性数æ®çš„å¯è§†åŒ–表现 -+Comment[zh_TW]=效能分æžè³‡æ–™è¦–覺化 -+X-DCOP-ServiceType=Multi -+Categories=Qt;KDE;Development; -diff --git a/kdecachegrind/kdecachegrind/kdecachegrindui.rc b/kdecachegrind/kdecachegrind/kdecachegrindui.rc -new file mode 100644 -index 0000000..9531829 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/kdecachegrindui.rc -@@ -0,0 +1,57 @@ -+ -+ -+ -+ &File -+ -+ -+ -+ -+ -+ &View -+ -+ -+ -+ -+ &Layout -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Sidebars -+ -+ -+ -+ -+ -+ -+ -+ -+ Main Toolbar -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ State Toolbar -+ -+ -+ -diff --git a/kdecachegrind/kdecachegrind/tips b/kdecachegrind/kdecachegrind/tips -new file mode 100644 -index 0000000..1f555c0 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/tips -@@ -0,0 +1,141 @@ -+ -+ -+

...that the What's This? help for every GUI widget -+in KCachegrind contains detailed usage information for this widget? -+It is highly recommended to read at least these help texts on first -+use. Request What's This? help by pressing -+Shift+F1 and clicking on the widget.

-+ -+
-+ -+ -+ -+

...that you can get profile information at instruction level -+with Calltree when you provide the option --dump-instr=yes? -+Use the Assembler View for the instruction annotations. -+

-+ -+
-+ -+ -+ -+

...that you can use Alt-Left/Right keys of your keyboard to go -+back/forward in the active object history ?

-+ -+
-+ -+ -+ -+

...that you can navigate in the Callee/Caller Map View using -+arrow keys? Use Left/Right to change to siblings of the current -+item; use Up/Down to go one nesting level up/down. To select -+the current item, press Space, and to activate it, press Return. -+

-+ -+
-+ -+ -+ -+

...that you can navigate in the Call Graph View using -+arrow keys? Use Up/Down to go one calling level up/down, alternating -+between calls and functions. Use Left/Right to change to siblings of a current -+selected call. To activate the current item, press Return. -+

-+ -+
-+ -+ -+ -+

...that you can rapidly locate a function by entering part of its -+name (case-insensitive) into the edit line of the toolbar -+and hit return?

-+ -+
-+ -+ -+ -+

...that you can assign custom colors to -+ELF objects/C++ Classes/Source Files for graph coloring -+in Settings->Configure KCachegrind...?

-+ -+
-+ -+ -+ -+

...that you can see if debug info is available for a selected -+function by looking at the location label in the Info tab or -+the source listing header in the source tab?

-+

There must be the name of the source file (with extension). -+If KCachegrind still doesn't show the source, make sure that you -+have added the directory of the source file to the -+Source Directories list in the configuration. -+ -+ -+ -+ -+ -+

...that you can configure whether KCachgrind should -+show absolute event counts or relative ones (percentage display)?

-+ -+
-+ -+ -+ -+

...that you can configure the maximum number of items -+for all function lists in KCachegrind? Limiting the number -+of items is done to get a fast reacting GUI. The last item in -+the list will show you the number of skipped functions, together -+with a cost condition for these skipped functions.

-+

To activate a function with small costs, search for it and select -+it in the flat profile. Selecting functions with small cost will -+temporarily add them to the flat profile list.

-+ -+
-+ -+ -+ -+

...that the Coverage tab - in contrast to the Call Lists tab - -+shows all functions that are calling the selected function -+(upper part) / are called by the selected function (bottom part), -+no matter how many function are between them on the stack?

-+

Examples:

-+

An entry in the upper list for function foo1() with a value of 50% -+with function bar() selected means that 50% of all the cost of function -+bar() happened while called from function foo1().

-+

An entry in the bottom list for function foo2() with a value of 50% -+with function bar() selected means that 50% of all the cost of function -+bar() happened while calling foo2() from bar().

-+ -+
-+ -+ -+ -+

...that waiting for the tool tip inside of a tree map -+shows the list of names of the nested rectangles the mouse -+pointer is over?

-+

Items from this list can be selected by pressing the right -+mouse button.

-+ -+
-+ -+ -+ -+

...that you can constrain the cost counts shown to only a -+few parts of the whole trace by selecting these parts in the -+"Trace Selection" Dockable?

-+

To generate multiple parts in a profiling run with -+cachegrind, use e.g. option --cachedumps=xxx for parts -+of a length of xxx basic blocks (A basic block is a run -+of not-branching assembler statements inside of your program -+code).

-+ -+
-+ -+ -+

...that by splitting the view to show information of -+two functions simultaniously, selecting a function in -+one panel shows the information for that function -+in the other panel?

-+ -+
-+ -diff --git a/kdecachegrind/kdecachegrind/toplevel.cpp b/kdecachegrind/kdecachegrind/toplevel.cpp -new file mode 100644 -index 0000000..5a2e1de ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/toplevel.cpp -@@ -0,0 +1,2389 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * KCachegrind top level window -+ */ -+ -+#define TRACE_UPDATES 0 -+#define ENABLE_DUMPDOCK 0 -+ -+#include // for system() -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if ENABLE_DUMPDOCK -+#include "dumpselection.h" -+#endif -+ -+#include "toplevel.h" -+#include "partselection.h" -+#include "functionselection.h" -+#include "stackselection.h" -+#include "stackbrowser.h" -+#include "tracedata.h" -+#include "configuration.h" -+#include "configdlg.h" -+#include "multiview.h" -+#include "callgraphview.h" -+ -+ -+TopLevel::TopLevel(const char *name) -+ : KMainWindow(0, name), DCOPObject("KCachegrindIface") -+{ -+ init(); -+ -+ createDocks(); -+ -+ _multiView = new MultiView(this, this, "MultiView"); -+ setCentralWidget(_multiView); -+ -+ createActions(); -+ -+ _partDockShown->setChecked(!_partDock->isHidden()); -+ _stackDockShown->setChecked(!_stackDock->isHidden()); -+ _functionDockShown->setChecked(!_functionDock->isHidden()); -+ -+ connect(_partDock, TQT_SIGNAL(visibilityChanged(bool)), -+ TQT_TQOBJECT(this), TQT_SLOT(partVisibilityChanged(bool))); -+ connect(_stackDock, TQT_SIGNAL(visibilityChanged(bool)), -+ TQT_TQOBJECT(this), TQT_SLOT(stackVisibilityChanged(bool))); -+ connect(_functionDock, TQT_SIGNAL(visibilityChanged(bool)), -+ TQT_TQOBJECT(this), TQT_SLOT(functionVisibilityChanged(bool))); -+ -+#if ENABLE_DUMPDOCK -+ _dumpDockShown->setChecked(!_dumpDock->isHidden()); -+ connect(_dumpDock, TQT_SIGNAL(visibilityChanged(bool)), -+ TQT_TQOBJECT(this), TQT_SLOT(dumpVisibilityChanged(bool))); -+#endif -+ -+ _statusbar = statusBar(); -+ _statusLabel = new TQLabel(_statusbar); -+#if 0 -+ // how to do avoid main window resizing on large statusbar label? -+ TQSizePolicy p(TQSizePolicy::Fixed, TQSizePolicy::Expanding); -+ _statusLabel->setSizePolicy(p); -+ _statusbar->setSizePolicy(p); -+#endif -+ _statusbar->addWidget(_statusLabel, 1); -+ -+ KConfig* kconfig = KGlobal::config(); -+ Configuration::readOptions( kconfig ); -+ _openRecent->loadEntries( kconfig ); -+ -+ // set toggle after reading configuration -+ _showPercentage = Configuration::showPercentage(); -+ _showExpanded = Configuration::showExpanded(); -+ _showCycles = Configuration::showCycles(); -+ _taPercentage->setChecked(_showPercentage); -+ _taExpanded->setChecked(_showExpanded); -+ _taCycles->setChecked(_showCycles); -+ -+ setupPartSelection(_partSelection); -+ -+ // KCachegrind for KDE 3.0.x does not allow to hide toolbars... -+#if KDE_VERSION >= 308 // KDE 3.1 -+ setStandardToolBarMenuEnabled(true); -+#endif -+ -+ // QT dock windows are created before (using QT position restoring) -+ createGUI(); -+ -+ setAutoSaveSettings(); -+ -+ // restore current state settings (not configuration options) -+ restoreCurrentState(TQString()); -+ -+ // if this is the first toplevel, show tip of day -+ if (memberList->count() == 1) -+ TQTimer::singleShot( 200, TQT_TQOBJECT(this), TQT_SLOT(slotShowTipOnStart()) ); -+} -+ -+void TopLevel::init() -+{ -+ _activeParts.clear(); -+ _hiddenParts.clear(); -+ -+ _progressBar = 0; -+ -+ _data = 0; -+ _function = 0; -+ _costType = 0; -+ _costType2 = 0; -+ _groupType = TraceCost::NoCostType; -+ _group = 0; -+ -+ _layoutCurrent = 0; -+ _layoutCount = 1; -+ -+ // for delayed slots -+ _traceItemDelayed = 0; -+ _costTypeDelayed = 0; -+ _costType2Delayed = 0; -+ _groupTypeDelayed = TraceCost::NoCostType; -+ _groupDelayed = 0; -+ _directionDelayed = TraceItemView::None; -+ _lastSender = 0; -+} -+ -+ -+/** -+ * Setup the part selection widget. -+ * Statusbar has to be created before. -+ */ -+void TopLevel::setupPartSelection(PartSelection* ps) -+{ -+ // setup connections from the part selection widget -+ -+ connect(ps, TQT_SIGNAL(activePartsChanged(const TracePartList&)), -+ TQT_TQOBJECT(this), TQT_SLOT(activePartsChangedSlot(const TracePartList&))); -+ connect(ps, TQT_SIGNAL(groupChanged(TraceCostItem*)), -+ TQT_TQOBJECT(this), TQT_SLOT(setGroupDelayed(TraceCostItem*))); -+ connect(ps, TQT_SIGNAL(functionChanged(TraceItem*)), -+ TQT_TQOBJECT(this), TQT_SLOT(setTraceItemDelayed(TraceItem*))); -+ -+ connect(ps, TQT_SIGNAL(goBack()), -+ _stackSelection, TQT_SLOT(browserBack())); -+ -+ connect(ps, TQT_SIGNAL(partsHideSelected()), -+ TQT_TQOBJECT(this), TQT_SLOT(partsHideSelectedSlotDelayed())); -+ connect(ps, TQT_SIGNAL(partsUnhideAll()), -+ TQT_TQOBJECT(this), TQT_SLOT(partsUnhideAllSlotDelayed())); -+ -+ connect(ps, TQT_SIGNAL(showMessage(const TQString&, int)), -+ _statusbar, TQT_SLOT(message(const TQString&, int))); -+} -+ -+/** -+ * This saves the current state of the main window and -+ * sub widgets. -+ * -+ * No positions are saved. These is done automatically for -+ * KToolbar, and manually in queryExit() for QT docks. -+ */ -+void TopLevel::saveCurrentState(TQString postfix) -+{ -+ KConfig* kconfig = KGlobal::config(); -+ TQCString pf = postfix.ascii(); -+ -+ KConfigGroup psConfig(kconfig, TQCString("PartOverview")+pf); -+ _partSelection->saveVisualisationConfig(&psConfig); -+ -+ KConfigGroup stateConfig(kconfig, TQCString("CurrentState")+pf); -+ stateConfig.writeEntry("CostType", -+ _costType ? _costType->name() : TQString("?")); -+ stateConfig.writeEntry("CostType2", -+ _costType2 ? _costType2->name() : TQString("?")); -+ stateConfig.writeEntry("GroupType", TraceItem::typeName(_groupType)); -+ -+ _multiView->saveViewConfig(kconfig, TQString("MainView"), postfix, true); -+} -+ -+/** -+ * This function is called when a trace is closed. -+ * Save browsing position for later restoring -+ */ -+void TopLevel::saveTraceSettings() -+{ -+ TQString key = traceKey(); -+ -+ KConfigGroup pConfig(KGlobal::config(), TQCString("TracePositions")); -+ pConfig.writeEntry(TQString("CostType%1").arg(key), -+ _costType ? _costType->name() : TQString("?")); -+ pConfig.writeEntry(TQString("CostType2%1").arg(key), -+ _costType2 ? _costType2->name() : TQString("?")); -+ pConfig.writeEntry(TQString("GroupType%1").arg(key), -+ TraceItem::typeName(_groupType)); -+ -+ if (!_data) return; -+ -+ KConfigGroup aConfig(KGlobal::config(), TQCString("Layouts")); -+ aConfig.writeEntry(TQString("Count%1").arg(key), _layoutCount); -+ aConfig.writeEntry(TQString("Current%1").arg(key), _layoutCurrent); -+ -+ saveCurrentState(key); -+ pConfig.writeEntry(TQString("Group%1").arg(key), -+ _group ? _group->name() : TQString()); -+} -+ -+/** -+ * This restores the current state of the main window and -+ * sub widgets. -+ * -+ * This does NOT restore any positions. This is done automatically for -+ * KToolbar, and manually in the createDocks() for QT docks.. -+ */ -+void TopLevel::restoreCurrentState(TQString postfix) -+{ -+ KConfig* kconfig = KGlobal::config(); -+ TQStringList gList = kconfig->groupList(); -+ TQCString pf = postfix.ascii(); -+ -+ // dock properties (not position, this should be have done before) -+ TQCString group = TQCString("PartOverview"); -+ if (gList.contains(group+pf)) group += pf; -+ KConfigGroup psConfig(kconfig, group); -+ _partSelection->readVisualisationConfig(&psConfig); -+ -+ _multiView->readViewConfig(kconfig, TQString("MainView"), postfix, true); -+ _taSplit->setChecked(_multiView->childCount()>1); -+ _taSplitDir->setEnabled(_multiView->childCount()>1); -+ _taSplitDir->setChecked(_multiView->orientation() == Qt::Horizontal); -+} -+ -+ -+void TopLevel::createDocks() -+{ -+ _partDock = new TQDockWindow(TQDockWindow::InDock, this); -+ _partDock->setCaption(i18n("Parts Overview")); -+ _partDock->setCloseMode( TQDockWindow::Always ); -+ _partSelection = new PartSelection(_partDock, "partSelection"); -+ _partDock->setWidget(_partSelection); -+ _partDock->setResizeEnabled(true); -+ _partDock->setFixedExtentWidth(200); -+ TQWhatsThis::add( _partSelection, i18n( -+ "The Parts Overview" -+ "

A trace consists of multiple trace parts when " -+ "there are several profile data files from one profile run. " -+ "The Trace Part Overview dockable shows these, " -+ "horizontally ordered in execution time; " -+ "the rectangle sizes are proportional to the total " -+ "cost spent in the parts. You can select one or several " -+ "parts to constrain all costs shown to these parts only." -+ "

" -+ "

The parts are further subdivided: there is a " -+ "partitioning and an callee split mode: " -+ "

  • Partitioning: You see the " -+ "partitioning into groups for a trace part, according to " -+ "the group type selected. E.g. if ELF object groups are " -+ "selected, you see colored rectangles for each " -+ "used ELF object (shared library or executable), sized " -+ "according to the cost spent therein.
  • " -+ "
  • Callee: A rectangle showing the inclusive " -+ "cost of the current selected function in the trace part " -+ "is shown. " -+ "This is split up into smaller rectangles to show the costs of its " -+ "callees.

")); -+ -+ _stackDock = new TQDockWindow(TQDockWindow::InDock, this); -+ _stackDock->setResizeEnabled(true); -+ // Why is the caption only correct with a close button? -+ _stackDock->setCloseMode( TQDockWindow::Always ); -+ _stackSelection = new StackSelection(_stackDock, "stackSelection"); -+ _stackDock->setWidget(_stackSelection); -+ _stackDock->setFixedExtentWidth(200); -+ _stackDock->setCaption(i18n("Top Cost Call Stack")); -+ TQWhatsThis::add( _stackSelection, i18n( -+ "The Top Cost Call Stack" -+ "

This is a purely fictional 'most probable' call stack. " -+ "It is built up by starting with the current selected " -+ "function and adds the callers/callees with highest cost " -+ "at the top and to bottom.

" -+ "

The Cost and Calls columns show the " -+ "cost used for all calls from the function in the line " -+ "above.

")); -+ -+ connect(_stackSelection, TQT_SIGNAL(functionSelected(TraceItem*)), -+ TQT_TQOBJECT(this), TQT_SLOT(setTraceItemDelayed(TraceItem*))); -+ -+ _functionDock = new TQDockWindow(TQDockWindow::InDock, this); -+ _functionDock->setCaption(i18n("Flat Profile")); -+ _functionDock->setCloseMode( TQDockWindow::Always ); -+ _functionSelection = new FunctionSelection(this, _functionDock, -+ "functionSelection"); -+ _functionSelection->setTopLevel(this); -+ -+ _functionDock->setWidget(_functionSelection); -+ _functionDock->setResizeEnabled(true); -+ _functionDock->setFixedExtentWidth(200); -+ TQWhatsThis::add( _functionSelection, i18n( -+ "The Flat Profile" -+ "

The flat profile contains a group and a function " -+ "selection list. The group list contains all groups " -+ "where costs " -+ "are spent in, depending on the chosen group type. " -+ "The group list is hidden when group type 'Function' " -+ "is selected.

" -+ "

The function list contains the functions of the " -+ "selected group (or all for 'Function' group type), " -+ "ordered by the costs spent therein. Functions with " -+ "costs less than 1% are hidden on default.

")); -+ -+#if ENABLE_DUMPDOCK -+ _dumpDock = new TQDockWindow(TQDockWindow::InDock, this); -+ _dumpDock->setCaption(i18n("Profile Dumps")); -+ _dumpDock->setCloseMode( TQDockWindow::Always ); -+ _dumpSelection = new DumpSelection(this, _dumpDock, -+ "dumpSelection"); -+ _dumpSelection->setTopLevel(this); -+ -+ _dumpDock->setWidget(_dumpSelection); -+ _dumpDock->setResizeEnabled(true); -+ _dumpDock->setFixedExtentWidth(200); -+ TQWhatsThis::add( _dumpSelection, i18n( -+ "Profile Dumps" -+ "

This dockable shows in the top part the list of " -+ "loadable profile dumps in all subdirectories of: " -+ "

  • current working directory of KCachegrind, " -+ "i.e. where it was started from, and " -+ "
  • the default profile dump directory given in the " -+ "configuration.
" -+ "The list is sorted according the the target command " -+ "profiled in the corresponding dump.

" -+ "

On selecting a profile dump, information for it " -+ "is shown in the bottom area of the dockable: " -+ "

  • Options allows you to view the profiled " -+ "command and profile options of this dump. By changing " -+ "any item, a new (yet unexisting) profile template " -+ "is created. Press Run Profile to start a" -+ "profile run with these options in the background. " -+ "
  • Info gives detailed info on the selected " -+ "dump like event cost summary and properties of the " -+ "simulated cache. " -+ "
  • State is only available for current happening " -+ "profiles runs. Press Update to see different " -+ "counters of the run, and a stack trace of the current " -+ "position in the program profiled. Check the Every " -+ "option to let KCachegrind regularly poll these data. " -+ "Check the Sync option to let the dockable activate " -+ "the top function in the current loaded dump.

")); -+#endif -+ -+ // Restore QT Dock positions... -+ KConfigGroup dockConfig(KGlobal::config(), TQCString("Docks")); -+ TQString str = dockConfig.readEntry("Position", TQString()); -+ if (0) qDebug("Docks/Position: '%s'", str.ascii()); -+ if (str.isEmpty()) { -+ // default positions -+ addDockWindow(_partDock, DockLeft); -+ addDockWindow(_stackDock, DockLeft); -+ addDockWindow(_functionDock, DockLeft); -+ _stackDock->hide(); -+#if ENABLE_DUMPDOCK -+ addDockWindow(_dumpDock, DockLeft); -+ _dumpDock->hide(); -+#endif -+ } -+ else { -+ TQTextStream ts( &str, IO_ReadOnly ); -+ ts >> *this; -+ } -+ _forcePartDock = dockConfig.readBoolEntry("ForcePartDockVisible", false); -+ -+#if 0 -+ // dock context menu -+ setAppropriate(_partDock, true); -+ setAppropriate(_stackDock, true); -+ setAppropriate(_dumpDock, true); -+ setAppropriate(_functionDock, true); -+ -+ connect( _partDock, TQT_SIGNAL(contextMenuRequested(const TQPoint &)), -+ TQT_TQOBJECT(this), TQT_SLOT(showDockMenu(const TQPoint &))); -+#endif -+} -+ -+ -+TopLevel::~TopLevel() -+{ -+ delete _data; -+} -+ -+ -+void TopLevel::saveProperties(KConfig* c) -+{ -+ c->writeEntry("TraceName", _data->traceName()); -+} -+ -+void TopLevel::readProperties(KConfig* c) -+{ -+ TQString traceName = c->readEntry("TraceName"); -+ if (!traceName.isEmpty()) { -+ TraceData* d = new TraceData(this); -+ d->load(traceName); -+ setData(d); -+ } -+} -+ -+void TopLevel::createLayoutActions() -+{ -+ TQString hint; -+ KAction* action; -+ -+ action = new KAction( i18n( "&Duplicate" ), -+ KShortcut(KKey("Ctrl+Plus")), -+ TQT_TQOBJECT(this), TQT_SLOT(layoutDuplicate()), -+ actionCollection(), "layout_duplicate" ); -+ hint = i18n("Duplicate Current Layout" -+ "

Make a copy of the current layout.

"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Remove" ), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(layoutRemove()), -+ actionCollection(), "layout_remove" ); -+ hint = i18n("Remove Current Layout" -+ "

Delete current layout and make the previous active.

"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Go to Next" ), -+ KShortcut(KKey("Ctrl+Right")), -+ TQT_TQOBJECT(this), TQT_SLOT(layoutNext()), -+ actionCollection(), "layout_next" ); -+ hint = i18n("Go to Next Layout"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Go to Previous" ), -+ KShortcut(KKey("Ctrl+Left")), -+ TQT_TQOBJECT(this), TQT_SLOT(layoutPrevious()), -+ actionCollection(), "layout_previous" ); -+ hint = i18n("Go to Previous Layout"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Restore to Default" ), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(layoutRestore()), -+ actionCollection(), "layout_restore" ); -+ hint = i18n("Restore Layouts to Default"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Save as Default" ), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(layoutSave()), -+ actionCollection(), "layout_save" ); -+ hint = i18n("Save Layouts as Default"); -+ action->setWhatsThis( hint ); -+} -+ -+// TODO: split this up... -+void TopLevel::createMiscActions() -+{ -+ TQString hint; -+ KAction* action; -+ -+ action = KStdAction::openNew(TQT_TQOBJECT(this), TQT_SLOT(newWindow()), actionCollection()); -+ hint = i18n("New

Open new empty KCachegrind window.

"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Add..." ), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(addTrace()), -+ actionCollection(), "file_add" ); -+ hint = i18n("Add Profile Data" -+ "

This opens an additional profile data file in the current window.

"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Reload" ), "reload", -+#if KDE_VERSION > 0x030190 -+ // for KDE 3.2: KStdAccel::key is deprecated -+ KStdAccel::shortcut(KStdAccel::Reload), -+#else -+ KStdAccel::key(KStdAccel::Reload), -+#endif -+ TQT_TQOBJECT(this), TQT_SLOT( reload() ), actionCollection(), "reload" ); -+ hint = i18n("Reload Profile Data" -+ "

This loads any new created parts, too.

"); -+ action->setWhatsThis( hint ); -+ -+ action = new KAction( i18n( "&Export Graph" ), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(exportGraph()), -+ actionCollection(), "export" ); -+ -+ hint = i18n("Export Call Graph" -+ "

Generates a file with extension .dot for the tools " -+ "of the GraphViz package.

"); -+ action->setWhatsThis( hint ); -+ -+ -+ _taDump = new KToggleAction( i18n( "&Force Dump" ), "redo", -+#if KDE_VERSION > 0x030190 -+ // for KDE 3.2: KStdAccel::key is deprecated -+ KStdAccel::shortcut(KStdAccel::Redo), -+#else -+ KStdAccel::key(KStdAccel::Redo), -+#endif -+ TQT_TQOBJECT(this), TQT_SLOT( forceTrace() ), -+ actionCollection(), "dump" ); -+ hint = i18n("Force Dump" -+ "

This forces a dump for a Callgrind profile run " -+ "in the current directory. This action is checked while " -+ "KCachegrind looks for the dump. If the dump is " -+ "finished, it automatically reloads the current trace. " -+ "If this is the one from the running Callgrind, the new " -+ "created trace part will be loaded, too.

" -+ "

Force dump creates a file 'callgrind.cmd', and " -+ "checks every second for its existence. A running " -+ "Callgrind will detect this file, dump a trace part, " -+ "and delete 'callgrind.cmd'. " -+ "The deletion is detected by KCachegrind, " -+ "and it does a Reload. If there's no Callgrind " -+ "running, press 'Force Dump' again to cancel the dump " -+ "request. This deletes 'callgrind.cmd' itself and " -+ "stops polling for a new dump.

" -+ "

Note: A Callgrind run only detects " -+ "existence of 'callgrind.cmd' when actively running " -+ "a few milliseconds, i.e. " -+ "not sleeping. Tip: For a profiled GUI program, " -+ "you can awake Callgrind e.g. by resizing a window " -+ "of the program.

"); -+ _taDump->setWhatsThis( hint ); -+ -+ action = KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(loadTrace()), actionCollection()); -+ hint = i18n("Open Profile Data" -+ "

This opens a profile data file, with possible multiple parts

"); -+ action->setToolTip( hint ); -+ action->setWhatsThis( hint ); -+ -+ _openRecent = KStdAction::openRecent(TQT_TQOBJECT(this), TQT_SLOT(loadTrace(const KURL&)), -+ actionCollection()); -+ -+ KStdAction::showStatusbar(TQT_TQOBJECT(this), -+ TQT_SLOT(toggleStatusBar()), actionCollection()); -+ -+ _partDockShown = new KToggleAction(i18n("Parts Overview"), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(togglePartDock()), -+ actionCollection(), -+ "settings_show_partdock"); -+ -+ hint = i18n("Show/Hide the Parts Overview Dockable"); -+ _partDockShown->setToolTip( hint ); -+ _partDockShown->setWhatsThis( hint ); -+ -+ _stackDockShown = new KToggleAction(i18n("Call Stack"), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(toggleStackDock()), -+ actionCollection(), -+ "settings_show_stackdock"); -+ -+ hint = i18n("Show/Hide the Call Stack Dockable"); -+ _stackDockShown->setToolTip( hint ); -+ _stackDockShown->setWhatsThis( hint ); -+ -+ _functionDockShown = new KToggleAction(i18n("Function Profile"), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(toggleFunctionDock()), -+ actionCollection(), -+ "settings_show_profiledock"); -+ -+ hint = i18n("Show/Hide the Function Profile Dockable"); -+ _functionDockShown->setToolTip( hint ); -+ _functionDockShown->setWhatsThis( hint ); -+ -+#if ENABLE_DUMPDOCK -+ _dumpDockShown = new KToggleAction(i18n("Profile Dumps"), KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(toggleDumpDock()), -+ actionCollection(), -+ "settings_show_dumpdock"); -+ -+ hint = i18n("Show/Hide the Profile Dumps Dockable"); -+ _dumpDockShown->setToolTip( hint ); -+ _dumpDockShown->setWhatsThis( hint ); -+#endif -+ -+ _taPercentage = new KToggleAction(i18n("Show Relative Costs"), "percent", -+ KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(togglePercentage()), -+ actionCollection(), -+ "view_percentage"); -+#if KDE_VERSION >= 0x030290 -+ // for KDE 3.3: show another text instead of a checkmark -+ _taPercentage->setCheckedState(i18n("Show Absolute Costs")); -+#endif -+ -+ hint = i18n("Show relative instead of absolute costs"); -+ _taPercentage->setToolTip( hint ); -+ _taPercentage->setWhatsThis( hint ); -+ -+ _taExpanded = new KToggleAction(i18n("Percentage Relative to Parent"), "move", -+ KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(toggleExpanded()), -+ actionCollection(), -+ "view_expanded"); -+ -+ hint = i18n("Show percentage costs relative to parent"); -+ _taExpanded->setToolTip( hint ); -+ _taExpanded->setWhatsThis( hint ); -+ -+ hint = i18n("Show percentage costs relative to parent" -+ "

If this is switched off, percentage costs are always shown " -+ "relative to the total cost of the profile part(s) that are " -+ "currently browsed. By turning on this option, percentage cost " -+ "of shown cost items will be relative to the parent cost item." -+ "

    " -+ "" -+ "" -+ "" -+ "" -+ "" -+ "
    Cost TypeParent Cost
    Function CumulativeTotal
    Function SelfFunction Group (*) / Total
    CallFunction Cumulative
    Source LineFunction Cumulative
    " -+ "

    (*) Only if function grouping is switched on (e.g. ELF object grouping)."); -+ _taExpanded->setWhatsThis( hint ); -+ -+ _taCycles = new KToggleAction( i18n( "Do Cycle Detection" ), "undo", -+ KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT( toggleCycles() ), actionCollection(), -+ "view_cycles" ); -+#if KDE_VERSION >= 0x030290 -+ // for KDE 3.3: show another text instead of a checkmark -+ _taCycles->setCheckedState(i18n("Skip Cycle Detection")); -+#endif -+ -+ hint = i18n("Detect recursive cycles" -+ "

    If this is switched off, the treemap drawing will show " -+ "black areas when a recursive call is made instead of drawing the " -+ "recursion ad infinitum. Note that " -+ "the size of black areas often will be wrong, as inside recursive " -+ "cycles the cost of calls cannot be determined; the error is small, " -+ "however, for false cycles (see documentation)." -+ "

    The correct handling for cycles is to detect them and collapse all " -+ "functions of a cycle into a virtual function, which is done when this " -+ "option is selected. Unfortunately, with GUI applications, this often will " -+ "lead to huge false cycles, making the analysis impossible; therefore, there " -+ "is the option to switch this off."); -+ _taCycles->setWhatsThis( hint ); -+ -+ KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection()); -+ KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(configure()), actionCollection()); -+ KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(configureKeys()), actionCollection()); -+ KStdAction::configureToolbars(TQT_TQOBJECT(this),TQT_SLOT(configureToolbars()), -+ actionCollection()); -+#if 0 -+ action = KStdAction::back(_stackSelection, TQT_SLOT(browserBack()), -+ actionCollection()); -+ hint = i18n("Go back in function selection history"); -+ action->setToolTip( hint ); -+ action->setWhatsThis( hint ); -+ -+ action = KStdAction::forward(_stackSelection, TQT_SLOT(browserForward()), -+ actionCollection()); -+ hint = i18n("Go forward in function selection history"); -+ action->setToolTip( hint ); -+ action->setWhatsThis( hint ); -+ -+ action = KStdAction::up(_stackSelection, TQT_SLOT(browserUp()), -+ actionCollection()); -+ hint = i18n("Go Up" -+ "

    Go to last selected caller of current function. " -+ "If no caller was visited, use that with highest cost.

    "); -+ action->setToolTip( hint ); -+ action->setWhatsThis( hint ); -+#else -+ _paUp = new KToolBarPopupAction( i18n( "&Up" ), "up", -+ ALT+Key_Up, -+ TQT_TQOBJECT(_stackSelection), TQT_SLOT( browserUp() ), -+ actionCollection(), "go_up" ); -+ connect( _paUp->popupMenu(), TQT_SIGNAL( aboutToShow() ), -+ TQT_TQOBJECT(this), TQT_SLOT( upAboutToShow() ) ); -+ connect( _paUp->popupMenu(), TQT_SIGNAL( activated( int ) ), -+ TQT_TQOBJECT(this), TQT_SLOT( upActivated( int ) ) ); -+ hint = i18n("Go Up" -+ "

    Go to last selected caller of current function. " -+ "If no caller was visited, use that with highest cost.

    "); -+ _paUp->setToolTip( hint ); -+ _paUp->setWhatsThis( hint ); -+ -+ TQPair< KGuiItem, KGuiItem > backForward = KStdGuiItem::backAndForward(); -+ _paBack = new KToolBarPopupAction( backForward.first, ALT+Key_Left, -+ TQT_TQOBJECT(_stackSelection), TQT_SLOT(browserBack()), -+ actionCollection(), "go_back" ); -+ connect( _paBack->popupMenu(), TQT_SIGNAL( aboutToShow() ), -+ TQT_TQOBJECT(this), TQT_SLOT( backAboutToShow() ) ); -+ connect( _paBack->popupMenu(), TQT_SIGNAL( activated( int ) ), -+ TQT_TQOBJECT(this), TQT_SLOT( backActivated( int ) ) ); -+ hint = i18n("Go back in function selection history"); -+ _paBack->setToolTip( hint ); -+ _paBack->setWhatsThis( hint ); -+ -+ _paForward = new KToolBarPopupAction( backForward.second, ALT+Key_Right, -+ TQT_TQOBJECT(_stackSelection), -+ TQT_SLOT(browserForward()), -+ actionCollection(), "go_forward" ); -+ connect( _paForward->popupMenu(), TQT_SIGNAL( aboutToShow() ), -+ this, TQT_SLOT( forwardAboutToShow() ) ); -+ connect( _paForward->popupMenu(), TQT_SIGNAL( activated( int ) ), -+ this, TQT_SLOT( forwardActivated( int ) ) ); -+ hint = i18n("Go forward in function selection history"); -+ _paForward->setToolTip( hint ); -+ _paForward->setWhatsThis( hint ); -+#endif -+ -+ _saCost = new KSelectAction( i18n("Primary Event Type"), KShortcut(), -+ actionCollection(), "view_cost_type"); -+ hint = i18n("Select primary event type of costs"); -+ _saCost->setComboWidth(300); -+ _saCost->setToolTip( hint ); -+ _saCost->setWhatsThis( hint ); -+ -+ // cost types are dependent on loaded data, thus KSelectAction -+ // is filled in setData() -+ connect( _saCost, TQT_SIGNAL(activated(const TQString&)), -+ TQT_TQOBJECT(this), TQT_SLOT(costTypeSelected(const TQString&))); -+ -+ _saCost2 = new KSelectAction( i18n("Secondary Event Type"), KShortcut(), -+ actionCollection(), "view_cost_type2"); -+ hint = i18n("Select secondary event type for cost e.g. shown in annotations"); -+ _saCost2->setComboWidth(300); -+ _saCost2->setToolTip( hint ); -+ _saCost2->setWhatsThis( hint ); -+ -+ connect( _saCost2, TQT_SIGNAL(activated(const TQString&)), -+ TQT_TQOBJECT(this), TQT_SLOT(costType2Selected(const TQString&))); -+ -+ saGroup = new KSelectAction( i18n("Grouping"), KShortcut(), -+ actionCollection(), "view_group_type"); -+ -+ hint = i18n("Select how functions are grouped into higher level cost items"); -+ saGroup->setToolTip( hint ); -+ saGroup->setWhatsThis( hint ); -+ -+ TQStringList args; -+ -+ args << i18n("(No Grouping)") -+ << TraceCost::i18nTypeName(TraceItem::Object) -+ << TraceCost::i18nTypeName(TraceItem::File) -+ << TraceCost::i18nTypeName(TraceItem::Class) -+ << TraceCost::i18nTypeName(TraceItem::FunctionCycle); -+ -+ saGroup->setItems(args); -+ connect( saGroup, TQT_SIGNAL(activated(int)), -+ TQT_TQOBJECT(this), TQT_SLOT(groupTypeSelected(int))); -+ -+ _taSplit = new KToggleAction(i18n("Split"), "view_left_right", KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(splitSlot()), -+ actionCollection(), "view_split"); -+ -+ hint = i18n("Show two information panels"); -+ _taSplit->setToolTip( hint ); -+ _taSplit->setWhatsThis( hint ); -+ -+ _taSplitDir = new KToggleAction(i18n("SplitQt::Horizontal"), -+ "view_left_right", KShortcut(), -+ TQT_TQOBJECT(this), TQT_SLOT(splitDirSlot()), -+ actionCollection(), "view_split_dir"); -+ -+ hint = i18n("Change Split Qt::Orientation when main window is split."); -+ _taSplitDir->setToolTip( hint ); -+ _taSplitDir->setWhatsThis( hint ); -+ -+ // copied from KMail... -+#if KDE_VERSION >= 308 // KDE 3.1 -+ KStdAction::tipOfDay( TQT_TQOBJECT(this), TQT_SLOT( slotShowTip() ), actionCollection() ); -+#else -+ (void) new KAction( KGuiItem( i18n("Tip of the &Day..."), "idea", -+ i18n("Show \"Tip of the Day\"") ), -+ 0, TQT_TQOBJECT(this), TQT_SLOT(slotShowTip()), -+ actionCollection(), "help_show_tip" ); -+#endif -+} -+ -+void TopLevel::createActions() -+{ -+ createMiscActions(); -+ createLayoutActions(); -+} -+ -+void TopLevel::toggleStatusBar() -+{ -+ if (statusBar()->isVisible()) -+ statusBar()->hide(); -+ else -+ statusBar()->show(); -+} -+ -+void TopLevel::togglePartDock() -+{ -+ if (!_partDock->isVisible()) -+ _partDock->show(); -+ else -+ _partDock->hide(); -+} -+ -+void TopLevel::toggleStackDock() -+{ -+ if (!_stackDock->isVisible()) -+ _stackDock->show(); -+ else -+ _stackDock->hide(); -+} -+ -+void TopLevel::toggleDumpDock() -+{ -+#if ENABLE_DUMPDOCK -+ if (!_dumpDock->isVisible()) -+ _dumpDock->show(); -+ else -+ _dumpDock->hide(); -+#endif -+} -+ -+void TopLevel::toggleFunctionDock() -+{ -+ if (!_functionDock->isVisible()) -+ _functionDock->show(); -+ else -+ _functionDock->hide(); -+} -+ -+void TopLevel::togglePercentage() -+{ -+ setPercentage(_taPercentage->isChecked()); -+} -+ -+void TopLevel::setAbsoluteCost() -+{ -+ setPercentage(false); -+} -+ -+void TopLevel::setRelativeCost() -+{ -+ setPercentage(true); -+} -+ -+void TopLevel::setPercentage(bool show) -+{ -+ if (_showPercentage == show) return; -+ _showPercentage = show; -+ if (_taPercentage->isChecked() != show) -+ _taPercentage->setChecked(show); -+ -+ // FIXME: Delete when no view gets this config from Configuration -+ Configuration::setShowPercentage(_showPercentage); -+ -+ _partSelection->refresh(); -+ _stackSelection->refresh(); -+ -+ _functionSelection->notifyChange(TraceItemView::configChanged); -+ _functionSelection->updateView(); -+ -+ _multiView->notifyChange(TraceItemView::configChanged); -+ _multiView->updateView(); -+} -+ -+void TopLevel::toggleExpanded() -+{ -+ bool show = _taExpanded->isChecked(); -+ if (_showExpanded == show) return; -+ _showExpanded = show; -+ -+ // FIXME: Delete when no view gets this config from Configuration -+ Configuration::setShowExpanded(_showExpanded); -+ -+ _partSelection->refresh(); -+ _stackSelection->refresh(); -+ -+ _functionSelection->notifyChange(TraceItemView::configChanged); -+ _functionSelection->updateView(); -+ -+ _multiView->notifyChange(TraceItemView::configChanged); -+ _multiView->updateView(); -+} -+ -+void TopLevel::toggleCycles() -+{ -+ bool show = _taCycles->isChecked(); -+ if (_showCycles == show) return; -+ _showCycles = show; -+ -+ // FIXME: Delete when no view gets this config from Configuration -+ Configuration::setShowCycles(_showCycles); -+ -+ if (!_data) return; -+ -+ _data->invalidateDynamicCost(); -+ _data->updateFunctionCycles(); -+ -+ _partSelection->refresh(); -+ _stackSelection->rebuildStackList(); -+ -+ _functionSelection->notifyChange(TraceItemView::configChanged); -+ _functionSelection->updateView(); -+ -+ _multiView->notifyChange(TraceItemView::configChanged); -+ _multiView->updateView(); -+} -+ -+void TopLevel::partVisibilityChanged(bool v) -+{ -+ _partDockShown->setChecked(v); -+} -+ -+void TopLevel::stackVisibilityChanged(bool v) -+{ -+ _stackDockShown->setChecked(v); -+} -+ -+#if ENABLE_DUMPDOCK -+void TopLevel::dumpVisibilityChanged(bool v) -+#else -+void TopLevel::dumpVisibilityChanged(bool) -+#endif -+{ -+#if ENABLE_DUMPDOCK -+ _dumpDockShown->setChecked(v); -+#endif -+} -+ -+void TopLevel::functionVisibilityChanged(bool v) -+{ -+ _functionDockShown->setChecked(v); -+ if (v) -+ _functionSelection->updateView(); -+} -+ -+ -+void TopLevel::querySlot() -+{ -+ _functionSelection->query(queryLineEdit->text()); -+} -+ -+void TopLevel::configureKeys() -+{ -+#if KDE_VERSION > 0x030190 -+ // for KDE 3.2: KKeyDialog::configureKeys is deprecated -+ KKeyDialog::configure(actionCollection(), this, true); -+#else -+ KKeyDialog::configureKeys(actionCollection(), xmlFile(), true, this); -+#endif -+} -+ -+ -+void TopLevel::configureToolbars() -+{ -+ KEditToolbar *dlg = new KEditToolbar(guiFactory(),this); -+ -+ if (dlg->exec()) -+ createGUI(); -+ -+ delete dlg; -+} -+ -+ -+void TopLevel::newTrace() -+{ -+ // start cachegrind on command... -+} -+ -+void TopLevel::newWindow() -+{ -+ TopLevel* t = new TopLevel(0); -+ t->show(); -+} -+ -+ -+void TopLevel::loadTrace() -+{ -+ KURL url = KFileDialog::getOpenURL(":", -+ i18n("cachegrind.out* callgrind.out*|Callgrind Profile Data\n*|All Files"), -+ this, -+ i18n("Select Callgrind Profile Data")); -+ loadTrace(url); -+} -+ -+void TopLevel::loadTrace(const KURL& url) -+{ -+ if (url.isEmpty()) return; -+ -+ // network transparancy -+ TQString tmpFile; -+#if KDE_VERSION > 0x030190 -+ // for KDE 3.2: KIO::NetAccess::download with 2 args is deprecated -+ if(KIO::NetAccess::download( url, tmpFile, this )) { -+#else -+ if(KIO::NetAccess::download( url, tmpFile )) { -+#endif -+ _openRecent->addURL(url); -+ _openRecent->saveEntries( KGlobal::config() ); -+ -+ loadTrace(tmpFile); -+ KIO::NetAccess::removeTempFile( tmpFile ); -+ } -+} -+ -+void TopLevel::loadTrace(TQString file) -+{ -+ if (file.isEmpty()) return; -+ -+ if (_data && _data->parts().count()>0) { -+ -+ // In new window -+ TopLevel* t = new TopLevel(); -+ t->show(); -+ t->loadDelayed(file); -+ return; -+ } -+ -+ // this constructor enables progress bar callbacks -+ TraceData* d = new TraceData(this); -+ d->load(file); -+ setData(d); -+} -+ -+ -+void TopLevel::addTrace() -+{ -+ KURL url = KFileDialog::getOpenURL(TQString(), -+ i18n("cachegrind.out* callgrind.out*|Callgrind Profile Data\n*|All Files"), -+ this, -+ i18n("Add Callgrind Profile Data")); -+ addTrace(url); -+} -+ -+void TopLevel::addTrace(const KURL& url) -+{ -+ if (url.isEmpty()) return; -+ -+ // network transparancy -+ TQString tmpFile; -+#if KDE_VERSION > 0x030190 -+ // for KDE 3.2: KIO::NetAccess::download with 2 args is deprecated -+ if(KIO::NetAccess::download( url, tmpFile, this )) { -+#else -+ if(KIO::NetAccess::download( url, tmpFile )) { -+#endif -+ _openRecent->addURL(url); -+ _openRecent->saveEntries( KGlobal::config() ); -+ -+ addTrace(tmpFile); -+ KIO::NetAccess::removeTempFile( tmpFile ); -+ } -+} -+ -+void TopLevel::addTrace(TQString file) -+{ -+ if (file.isEmpty()) return; -+ -+ if (_data) { -+ _data->load(file); -+ -+ // GUI update for added data -+ configChanged(); -+ return; -+ } -+ -+ // this constructor enables progress bar callbacks -+ TraceData* d = new TraceData(this); -+ d->load(file); -+ setData(d); -+} -+ -+ -+ -+void TopLevel::loadDelayed(TQString file) -+{ -+ _loadTraceDelayed = file; -+ TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(loadTraceDelayed())); -+} -+ -+void TopLevel::loadTraceDelayed() -+{ -+ if (_loadTraceDelayed.isEmpty()) return; -+ -+ loadTrace(_loadTraceDelayed); -+ _loadTraceDelayed = TQString(); -+} -+ -+ -+void TopLevel::reload() -+{ -+ TQString trace; -+ if (!_data || _data->parts().count()==0) -+ trace = "."; // open first trace found in dir -+ else -+ trace = _data->traceName(); -+ -+ // this also keeps sure we have the same browsing position... -+ TraceData* d = new TraceData(this); -+ d->load(trace); -+ setData(d); -+} -+ -+void TopLevel::exportGraph() -+{ -+ if (!_data || !_function) return; -+ -+ TQString n = TQString("callgraph.dot"); -+ GraphExporter ge(_data, _function, _costType, _groupType, n); -+ ge.writeDot(); -+ -+ TQString cmd = TQString("(dot %1 -Tps > %2.ps; kghostview %3.ps)&") -+ .arg(n).arg(n).arg(n); -+ system(TQFile::encodeName( cmd )); -+} -+ -+ -+bool TopLevel::setCostType(TQString s) -+{ -+ TraceCostType* ct; -+ -+ ct = (_data) ? _data->mapping()->type(s) : 0; -+ -+ // if costtype with given name not found, use first available -+ if (!ct && _data) ct = _data->mapping()->type(0); -+ -+ return setCostType(ct); -+} -+ -+bool TopLevel::setCostType2(TQString s) -+{ -+ TraceCostType* ct; -+ -+ // Special type i18n("(Hidden)") gives 0 -+ ct = (_data) ? _data->mapping()->type(s) : 0; -+ -+ return setCostType2(ct); -+} -+ -+void TopLevel::costTypeSelected(const TQString& s) -+{ -+ TraceCostType* ct; -+ -+ ct = (_data) ? _data->mapping()->typeForLong(s) : 0; -+ setCostType(ct); -+} -+ -+void TopLevel::costType2Selected(const TQString& s) -+{ -+ TraceCostType* ct; -+ -+ ct = (_data) ? _data->mapping()->typeForLong(s) : 0; -+ setCostType2(ct); -+} -+ -+bool TopLevel::setCostType(TraceCostType* ct) -+{ -+ if (_costType == ct) return false; -+ _costType = ct; -+ -+ if (ct) { -+ int idx=0; -+ TQStringList l = _saCost->items(); -+ for (TQStringList::Iterator it = l.begin(); it != l.end(); ++it, ++idx ) { -+ if (*it == ct->longName()) -+ _saCost->setCurrentItem(idx); -+ } -+ } -+ -+ _partSelection->setCostType(_costType); -+ _stackSelection->setCostType(_costType); -+ -+ _functionSelection->setCostType(_costType); -+ _functionSelection->updateView(); -+ -+ _multiView->setCostType(_costType); -+ _multiView->updateView(); -+ -+ updateStatusBar(); -+ -+ return true; -+} -+ -+bool TopLevel::setCostType2(TraceCostType* ct) -+{ -+ if (_costType2 == ct) return false; -+ _costType2 = ct; -+ -+ TQString longName = ct ? ct->longName() : i18n("(Hidden)"); -+ -+ int idx=0; -+ TQStringList l = _saCost2->items(); -+ for (TQStringList::Iterator it = l.begin(); it != l.end(); ++it, ++idx ) { -+ if (*it == longName) -+ _saCost2->setCurrentItem(idx); -+ } -+ -+ _partSelection->setCostType2(_costType2); -+ _stackSelection->setCostType2(_costType2); -+ -+ _functionSelection->setCostType2(_costType2); -+ _functionSelection->updateView(); -+ -+ _multiView->setCostType2(_costType2); -+ _multiView->updateView(); -+ -+ updateStatusBar(); -+ -+ return true; -+} -+ -+ -+void TopLevel::groupTypeSelected(int cg) -+{ -+ switch(cg) { -+ case 0: setGroupType( TraceItem::Function ); break; -+ case 1: setGroupType( TraceItem::Object ); break; -+ case 2: setGroupType( TraceItem::File ); break; -+ case 3: setGroupType( TraceItem::Class ); break; -+ case 4: setGroupType( TraceItem::FunctionCycle ); break; -+ default: break; -+ } -+} -+ -+bool TopLevel::setGroupType(TQString s) -+{ -+ TraceItem::CostType gt; -+ -+ gt = (_data) ? _data->costType(s) : TraceData::costType(s); -+ // only allow Function/Object/File/Class as grouptype -+ switch(gt) { -+ case TraceItem::Object: -+ case TraceItem::File: -+ case TraceItem::Class: -+ case TraceItem::FunctionCycle: -+ break; -+ default: -+ gt = TraceItem::Function; -+ } -+ -+ return setGroupType(gt); -+} -+ -+bool TopLevel::setGroupType(TraceItem::CostType gt) -+{ -+ if (_groupType == gt) return false; -+ _groupType = gt; -+ -+ int idx = -1; -+ switch(gt) { -+ case TraceItem::Function: idx = 0; break; -+ case TraceItem::Object: idx = 1; break; -+ case TraceItem::File: idx = 2; break; -+ case TraceItem::Class: idx = 3; break; -+ case TraceItem::FunctionCycle: idx = 4; break; -+ default: -+ break; -+ } -+ -+ if (idx==-1) return false; -+ -+ if (saGroup->currentItem() != idx) -+ saGroup->setCurrentItem(idx); -+ -+ _stackSelection->setGroupType(_groupType); -+ _partSelection->setGroupType(_groupType); -+ -+ _functionSelection->set(_groupType); -+ _functionSelection->updateView(); -+ -+ _multiView->set(_groupType); -+ _multiView->updateView(); -+ -+ updateStatusBar(); -+ -+ return true; -+} -+ -+bool TopLevel::setGroup(TQString s) -+{ -+ return true; -+ TraceCostItem* ci = _functionSelection->group(s); -+ if (!ci) -+ return false; -+ -+ return setGroup(ci); -+} -+ -+ -+bool TopLevel::setGroup(TraceCostItem* g) -+{ -+ _multiView->activate(g); -+ _multiView->updateView(); -+ _functionSelection->activate(g); -+ _functionSelection->updateView(); -+ -+ if (_group == g) return false; -+ _group = g; -+ -+ -+ updateStatusBar(); -+ -+ return true; -+} -+ -+bool TopLevel::setFunction(TQString s) -+{ -+ if (!_data) return false; -+ -+ TraceCost* f = _data->search(TraceItem::Function, s, _costType); -+ if (!f) return false; -+ -+ return setFunction((TraceFunction*)f); -+} -+ -+bool TopLevel::setFunction(TraceFunction* f) -+{ -+ _multiView->activate(f); -+ _multiView->updateView(); -+ -+ _functionSelection->activate(f); -+ _functionSelection->updateView(); -+ -+ if (_function == f) return false; -+ _function = f; -+ -+ _partSelection->setFunction(_function); -+ _stackSelection->setFunction(_function); -+ -+ StackBrowser* b = _stackSelection->browser(); -+ if (b) { -+ // don't disable up: a press forces stack-up extending... -+ _paForward->setEnabled(b->canGoForward()); -+ _paBack->setEnabled(b->canGoBack()); -+ } -+ -+#if TRACE_UPDATES -+ qDebug("TopLevel::setFunction(%s), lastSender %s", -+ f ? f->prettyName().ascii() : "0", -+ _lastSender ? _lastSender->name() :"0" ); -+#endif -+ -+ return true; -+} -+ -+ -+/** -+ * Delayed versions. -+ * We always have a pair of slots: One receiver to start the -+ * delay with a singleShot Timer. It stores the parameter into a -+ * temporary variable. And one parameterless slot for -+ * forwarding, using this temporary. -+ */ -+void TopLevel::setCostTypeDelayed(TraceCostType* ct) -+{ -+ _costTypeDelayed = ct; -+ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setCostTypeDelayed())); -+} -+ -+void TopLevel::setCostType2Delayed(TraceCostType* ct) -+{ -+ _costType2Delayed = ct; -+ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setCostType2Delayed())); -+} -+ -+void TopLevel::setCostTypeDelayed() -+{ -+ setCostType(_costTypeDelayed); -+} -+ -+void TopLevel::setCostType2Delayed() -+{ -+ setCostType2(_costType2Delayed); -+} -+ -+void TopLevel::setGroupTypeDelayed(TraceItem::CostType gt) -+{ -+ _groupTypeDelayed = gt; -+ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setGroupTypeDelayed())); -+} -+ -+void TopLevel::setGroupTypeDelayed() -+{ -+ setGroupType(_groupTypeDelayed); -+} -+ -+void TopLevel::setGroupDelayed(TraceCostItem* g) -+{ -+#if TRACE_UPDATES -+ qDebug("TopLevel::setGroupDelayed(%s), sender %s", -+ g ? g->prettyName().ascii() : "0", -+ _lastSender ? _lastSender->name() :"0" ); -+#endif -+ -+ _groupDelayed = g; -+ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setGroupDelayed())); -+} -+ -+void TopLevel::setGroupDelayed() -+{ -+ setGroup(_groupDelayed); -+} -+ -+void TopLevel::setDirectionDelayed(TraceItemView::Direction d) -+{ -+ _directionDelayed = d; -+ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setDirectionDelayed())); -+} -+ -+void TopLevel::setDirectionDelayed() -+{ -+ switch(_directionDelayed) { -+ case TraceItemView::Back: -+ _stackSelection->browserBack(); -+ break; -+ -+ case TraceItemView::Forward: -+ _stackSelection->browserForward(); -+ break; -+ -+ case TraceItemView::Up: -+ { -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ HistoryItem* hi = b ? b->current() : 0; -+ TraceFunction* f = hi ? hi->function() : 0; -+ -+ if (!f) break; -+ f = hi->stack()->caller(f, false); -+ if (f) setFunction(f); -+ } -+ break; -+ -+ default: break; -+ } -+ -+ _directionDelayed = TraceItemView::None; -+} -+ -+ -+void TopLevel::setTraceItemDelayed(TraceItem* i) -+{ -+ // no need to select same item a 2nd time... -+ if (_traceItemDelayed == i) return; -+ _traceItemDelayed = i; -+ _lastSender = TQT_TQOBJECT(const_cast(sender())); -+ -+ kdDebug() << "Selected " << (i ? i->prettyName() : "(none)") << endl; -+ -+#if TRACE_UPDATES -+ qDebug("TopLevel::setTraceItemDelayed(%s), sender %s", -+ i ? i->prettyName().ascii() : "0", -+ _lastSender ? _lastSender->name() :"0" ); -+#endif -+ -+ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setTraceItemDelayed())); -+} -+ -+void TopLevel::setTraceItemDelayed() -+{ -+ if (!_traceItemDelayed) return; -+ -+ switch(_traceItemDelayed->type()) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ setFunction((TraceFunction*)_traceItemDelayed); -+ break; -+ -+ case TraceItem::Object: -+ case TraceItem::File: -+ case TraceItem::Class: -+ setGroup((TraceCostItem*)_traceItemDelayed); -+ break; -+ -+#if 0 -+ // this conflicts with the selection policy of InstrView ?!? -+ case TraceItem::Instr: -+ case TraceItem::Line: -+ // only for multiview -+ _multiView->activate(_traceItemDelayed); -+ _multiView->updateView(); -+ break; -+#endif -+ -+ default: break; -+ } -+ -+ _traceItemDelayed = 0; -+ _lastSender = 0; -+} -+ -+/** -+ * A TraceData object cannot be viewed many times in different -+ * toplevel windows. Thus, this toplevel window takes ownership -+ * of the TraceData object: on closing the window or opening -+ * another trace, the object is destroyed. -+ */ -+void TopLevel::setData(TraceData* data) -+{ -+ if (data == _data) return; -+ -+ _lastSender = 0; -+ -+ saveTraceSettings(); -+ -+ if (_data) { -+ _partSelection->setData(0); -+ _stackSelection->setData(0); -+ -+ _functionSelection->setData(0); -+ _functionSelection->updateView(); -+ _multiView->setData(0); -+ _multiView->updateView(); -+ -+ // we are the owner... -+ delete _data; -+ } -+ -+ // reset members -+ init(); -+ -+ _data = data; -+ -+ // fill cost type list -+ TQStringList types; -+ -+ if (_data) { -+ /* add all supported virtual types */ -+ TraceCostMapping* m = _data->mapping(); -+ m->addKnownVirtualTypes(); -+ -+ /* first, fill selection list with available cost types */ -+ for (int i=0;irealCount();i++) -+ types << m->realType(i)->longName(); -+ for (int i=0;ivirtualCount();i++) -+ types << m->virtualType(i)->longName(); -+ } -+ _saCost->setItems(types); -+ _saCost->setComboWidth(300); -+ -+ if (types.count()>0) { -+ // second type list gets an additional "(Hidden)" -+ types.prepend(i18n("(Hidden)")); -+ } -+ _saCost2->setItems(types); -+ _saCost2->setComboWidth(300); -+ // default is hidden -+ if (types.count()>0) -+ _saCost2->setCurrentItem(0); -+ -+ _partSelection->setData(_data); -+ _stackSelection->setData(_data); -+ _functionSelection->setData(_data); -+ _functionSelection->updateView(); -+ _multiView->setData(_data); -+ _multiView->updateView(); -+ -+ /* this is needed to let the other widgets know the types */ -+ restoreTraceTypes(); -+ -+ restoreTraceSettings(); -+ -+ TQString caption; -+ if (_data) { -+ caption = _data->traceName(); -+ if (!_data->command().isEmpty()) -+ caption += " [" + _data->command() + "]"; -+ } -+ setCaption(caption); -+ -+ if (!_data || (!_forcePartDock && _data->parts().count()<2)) { -+ _partDock->hide(); -+ _partDockShown->setChecked(false); -+ } -+ else { -+ _partDock->show(); -+ _partDockShown->setChecked(true); -+ } -+ -+ updateStatusBar(); -+} -+ -+void TopLevel::addCostMenu(TQPopupMenu* popup, bool withCost2) -+{ -+ if (_data) { -+ TQPopupMenu *popup1 = new TQPopupMenu(popup); -+ TQPopupMenu *popup2 = 0; -+ popup1->setCheckable(true); -+ -+ if (withCost2) { -+ popup2 = new TQPopupMenu(popup); -+ popup2->setCheckable(true); -+ -+ if (_costType2) { -+ popup2->insertItem(i18n("Hide"),199); -+ popup2->insertSeparator(); -+ } -+ } -+ -+ TraceCostMapping* m = _data->mapping(); -+ TraceCostType* ct; -+ for (int i=0;irealCount();i++) { -+ ct = m->realType(i); -+ popup1->insertItem(ct->longName(), 100+i); -+ if (_costType == ct) popup1->setItemChecked(100+i,true); -+ if (popup2) { -+ popup2->insertItem(ct->longName(), 100+i); -+ if (_costType2 == ct) popup2->setItemChecked(100+i,true); -+ } -+ } -+ for (int i=0;ivirtualCount();i++) { -+ ct = m->virtualType(i); -+ popup1->insertItem(ct->longName(), 200+i); -+ if (_costType == ct) popup1->setItemChecked(200+i,true); -+ if (popup2) { -+ popup2->insertItem(ct->longName(), 200+i); -+ if (_costType2 == ct) popup2->setItemChecked(200+i,true); -+ } -+ } -+ popup->insertItem(i18n("Primary Event Type"), popup1); -+ connect(popup1,TQT_SIGNAL(activated(int)),this,TQT_SLOT(setCostType(int))); -+ if (popup2) { -+ popup->insertItem(i18n("Secondary Event Type"), popup2); -+ connect(popup2,TQT_SIGNAL(activated(int)),this,TQT_SLOT(setCostType2(int))); -+ } -+ } -+ if (_showPercentage) -+ popup->insertItem(i18n("Show Absolute Cost"), -+ TQT_TQOBJECT(this), TQT_SLOT(setAbsoluteCost())); -+ else -+ popup->insertItem(i18n("Show Relative Cost"), -+ TQT_TQOBJECT(this), TQT_SLOT(setRelativeCost())); -+} -+ -+bool TopLevel::setCostType(int id) -+{ -+ if (!_data) return false; -+ -+ TraceCostMapping* m = _data->mapping(); -+ TraceCostType* ct=0; -+ if (id >=100 && id<199) ct = m->realType(id-100); -+ if (id >=200 && id<299) ct = m->virtualType(id-200); -+ -+ return ct ? setCostType(ct) : false; -+} -+ -+bool TopLevel::setCostType2(int id) -+{ -+ if (!_data) return false; -+ -+ TraceCostMapping* m = _data->mapping(); -+ TraceCostType* ct=0; -+ if (id >=100 && id<199) ct = m->realType(id-100); -+ if (id >=200 && id<299) ct = m->virtualType(id-200); -+ -+ return setCostType2(ct); -+} -+ -+void TopLevel::addGoMenu(TQPopupMenu* popup) -+{ -+ popup->insertItem(i18n("Go Back"), TQT_TQOBJECT(this), TQT_SLOT(goBack())); -+ popup->insertItem(i18n("Go Forward"), TQT_TQOBJECT(this), TQT_SLOT(goForward())); -+ popup->insertItem(i18n("Go Up"), TQT_TQOBJECT(this), TQT_SLOT(goUp())); -+} -+ -+void TopLevel::goBack() -+{ -+ setDirectionDelayed(TraceItemView::Back); -+} -+ -+void TopLevel::goForward() -+{ -+ setDirectionDelayed(TraceItemView::Forward); -+} -+ -+void TopLevel::goUp() -+{ -+ setDirectionDelayed(TraceItemView::Up); -+} -+ -+TQString TopLevel::traceKey() -+{ -+ if (!_data || _data->command().isEmpty()) return TQString(); -+ -+ TQString name = _data->command(); -+ TQString key; -+ for (unsigned int l=0;litems().isEmpty()) -+ costTypeSelected(_saCost->items().first()); -+ -+ KConfigGroup aConfig(KGlobal::config(), TQCString("Layouts")); -+ _layoutCount = aConfig.readNumEntry(TQString("Count%1").arg(key), 0); -+ _layoutCurrent = aConfig.readNumEntry(TQString("Current%1").arg(key), 0); -+ if (_layoutCount == 0) layoutRestore(); -+ updateLayoutActions(); -+} -+ -+ -+/** -+ * This must be called after setting group/cost types in the function -+ * selection widget, because the group/function choosing depends on -+ * filled lists in the function selection widget -+ */ -+void TopLevel::restoreTraceSettings() -+{ -+ if (!_data) return; -+ -+ TQString key = traceKey(); -+ -+ KConfigGroup pConfig(KGlobal::config(), TQCString("TracePositions")); -+ TQString group = pConfig.readEntry(TQString("Group%1").arg(key)); -+ if (!group.isEmpty()) setGroup(group); -+ -+ restoreCurrentState(key); -+ -+ // restoreCurrentState() usually leads to a call to setTraceItemDelayed() -+ // to restore last active item... -+ if (!_traceItemDelayed) { -+ // function not available any more.. try with "main" -+ if (!setFunction("main")) -+ _functionSelection->setTopFunction(); -+ } -+} -+ -+ -+/* Layout */ -+ -+void TopLevel::layoutDuplicate() -+{ -+ // save current and allocate a new slot -+ _multiView->saveViewConfig(KGlobal::config(), -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ traceKey(), false); -+ _layoutCurrent = _layoutCount; -+ _layoutCount++; -+ -+ updateLayoutActions(); -+ -+ kdDebug() << "TopLevel::layoutDuplicate: count " << _layoutCount << endl; -+} -+ -+void TopLevel::layoutRemove() -+{ -+ if (_layoutCount <2) return; -+ -+ int from = _layoutCount-1; -+ if (_layoutCurrent == from) { _layoutCurrent--; from--; } -+ // restore from last and decrement count -+ _multiView->readViewConfig(KGlobal::config(), -+ TQString("Layout%1-MainView").arg(from), -+ traceKey(), false); -+ _layoutCount--; -+ -+ updateLayoutActions(); -+} -+ -+void TopLevel::layoutNext() -+{ -+ if (_layoutCount <2) return; -+ -+ KConfig* config = KGlobal::config(); -+ TQString key = traceKey(); -+ -+ _multiView->saveViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ _layoutCurrent++; -+ if (_layoutCurrent == _layoutCount) _layoutCurrent = 0; -+ -+ _multiView->readViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ -+ if (0) kdDebug() << "TopLevel::layoutNext: current " -+ << _layoutCurrent << endl; -+} -+ -+void TopLevel::layoutPrevious() -+{ -+ if (_layoutCount <2) return; -+ -+ KConfig* config = KGlobal::config(); -+ TQString key = traceKey(); -+ -+ _multiView->saveViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ _layoutCurrent--; -+ if (_layoutCurrent <0) _layoutCurrent = _layoutCount-1; -+ -+ _multiView->readViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ -+ if (0) kdDebug() << "TopLevel::layoutPrevious: current " -+ << _layoutCurrent << endl; -+} -+ -+void TopLevel::layoutSave() -+{ -+ KConfig* config = KGlobal::config(); -+ TQString key = traceKey(); -+ -+ _multiView->saveViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ -+ for(int i=0;i<_layoutCount;i++) { -+ _multiView->readViewConfig(config, -+ TQString("Layout%1-MainView").arg(i), -+ key, false); -+ _multiView->saveViewConfig(config, -+ TQString("Layout%1-MainView").arg(i), -+ TQString(), false); -+ } -+ -+ _multiView->readViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ -+ KConfigGroup aConfig(config, TQCString("Layouts")); -+ aConfig.writeEntry("DefaultCount", _layoutCount); -+ aConfig.writeEntry("DefaultCurrent", _layoutCurrent); -+} -+ -+void TopLevel::layoutRestore() -+{ -+ KConfig* config = KGlobal::config(); -+ KConfigGroup aConfig(config, TQCString("Layouts")); -+ _layoutCount = aConfig.readNumEntry("DefaultCount", 0); -+ _layoutCurrent = aConfig.readNumEntry("DefaultCurrent", 0); -+ if (_layoutCount == 0) { -+ _layoutCount++; -+ return; -+ } -+ -+ TQString key = traceKey(); -+ for(int i=0;i<_layoutCount;i++) { -+ _multiView->readViewConfig(config, -+ TQString("Layout%1-MainView").arg(i), -+ TQString(), false); -+ _multiView->saveViewConfig(config, -+ TQString("Layout%1-MainView").arg(i), -+ key, false); -+ } -+ -+ _multiView->readViewConfig(config, -+ TQString("Layout%1-MainView").arg(_layoutCurrent), -+ key, false); -+ -+ updateLayoutActions(); -+} -+ -+ -+void TopLevel::updateLayoutActions() -+{ -+ KAction* ka; -+ -+ ka = actionCollection()->action("layout_next"); -+ if (ka) ka->setEnabled(_layoutCount>1); -+ -+ ka = actionCollection()->action("layout_previous"); -+ if (ka) ka->setEnabled(_layoutCount>1); -+ -+ ka = actionCollection()->action("layout_remove"); -+ if (ka) ka->setEnabled(_layoutCount>1); -+ -+ _statusbar->message(i18n("Layout Count: %1").arg(_layoutCount), 1000); -+} -+ -+ -+void TopLevel::updateStatusBar() -+{ -+ if (!_data || _data->parts().count()==0) { -+ _statusLabel->setText(i18n("No profile data file loaded.")); -+ return; -+ } -+ -+ TQString status = TQString("%1 [%2] - ") -+ .arg(_data->shortTraceName()) -+ .arg(_data->activePartRange()); -+ -+ if (_costType) { -+ status += i18n("Total %1 Cost: %2") -+ .arg(_costType->longName()) -+ .arg(_data->prettySubCost(_costType)); -+ -+ /* this gets too long... -+ if (_costType2 && (_costType2 != _costType)) -+ status += i18n(", %1 Cost: %2") -+ .arg(_costType2->longName()) -+ .arg(_data->prettySubCost(_costType2)); -+ */ -+ } -+ else -+ status += i18n("No event type selected"); -+ -+ /* Not working... should give group of selected function -+ -+ if (_groupType != TraceItem::Function) { -+ status += TQString(" - %1 '%2'") -+ .arg(TraceItem::i18nTypeName(_groupType)) -+ .arg(_group ? _group->prettyName() : i18n("(None)")); -+ } -+ */ -+ -+ _statusLabel->setText(status); -+} -+ -+void TopLevel::configure() -+{ -+ if (ConfigDlg::configure(Configuration::config(), _data, this)) { -+ Configuration::saveOptions(KGlobal::config()); -+ -+ configChanged(); -+ } -+ else -+ Configuration::readOptions(KGlobal::config()); -+} -+ -+bool TopLevel::queryClose() -+{ -+ saveTraceSettings(); -+ -+ return true; -+} -+ -+bool TopLevel::queryExit() -+{ -+ // save current toplevel options as defaults... -+ Configuration::setShowPercentage(_showPercentage); -+ Configuration::setShowExpanded(_showExpanded); -+ Configuration::setShowCycles(_showCycles); -+ Configuration::saveOptions(KGlobal::config()); -+ -+ saveCurrentState(TQString()); -+ -+ // save QT dock positions... -+ -+ // We don't want to save the KToolbar position here. -+ // Its already stored. -+ delete toolBar(); -+ -+ KConfigGroup dockConfig(KGlobal::config(), TQCString("Docks")); -+ TQString str; -+ TQTextStream ts( &str, IO_WriteOnly ); -+ ts << *this; -+#if 1 -+ dockConfig.writeEntry("Position", str); -+#else -+ /* We store this with a localized key because for dock positions, -+ * QT uses the localized captions of docks. -+ * This way, when changing languages, you don't loose dock position -+ * settings. -+ * For the retrieval to work, we need to store a non-localized. -+ */ -+ dockConfig.writeEntry("Position", str, true, false, true); -+#endif -+ -+ // if part dock was chosen visible even for only 1 part loaded, -+ // keep this choice... -+ _forcePartDock = false; -+ if (_data && (_data->parts().count()<2) && _partDock->isVisible()) -+ _forcePartDock=true; -+ dockConfig.writeEntry("ForcePartDockVisible", _forcePartDock); -+ -+ return true; -+} -+ -+ -+void TopLevel::splitSlot() -+{ -+ int count = _multiView->childCount(); -+ if (count<1) count = 1; -+ if (count>2) count = 2; -+ count = 3-count; -+ _multiView->setChildCount(count); -+ -+ _taSplit->setChecked(count>1); -+ _taSplitDir->setEnabled(count>1); -+ _taSplitDir->setChecked(_multiView->orientation() == Qt::Horizontal); -+} -+ -+void TopLevel::splitDirSlot() -+{ -+ _multiView->setOrientation( _taSplitDir->isChecked() ? -+ Qt::Horizontal : Qt::Vertical ); -+} -+ -+ -+ -+// this is called after a config change in the dialog -+void TopLevel::configChanged() -+{ -+ //qDebug("TopLevel::configChanged"); -+ //_showPercentage->setChecked(Configuration::showPercentage()); -+ -+ // invalidate found/cached dirs of source files -+ _data->resetSourceDirs(); -+ -+ _partSelection->refresh(); -+ _stackSelection->refresh(); -+ -+ _functionSelection->notifyChange(TraceItemView::configChanged); -+ _functionSelection->updateView(); -+ -+ _multiView->notifyChange(TraceItemView::configChanged); -+ _multiView->updateView(); -+} -+ -+void TopLevel::slotShowTipOnStart() { -+ KTipDialog::showTip(this); -+} -+ -+void TopLevel::slotShowTip() { -+ KTipDialog::showTip( this, TQString(), true ); -+} -+ -+void TopLevel::dummySlot() -+{ -+} -+ -+void TopLevel::activePartsChangedSlot(const TracePartList& list) -+{ -+ if (!_data) return; -+ -+ if (!_data->activateParts(list)) { -+// qDebug("TopLevel::activePartsChangedSlot: No Change!"); -+ return; -+ } -+ _activeParts = list; -+ -+ _partSelection->activePartsChangedSlot(list); -+ -+ _multiView->set(list); -+ _multiView->updateView(); -+ -+ _functionSelection->set(list); -+ _functionSelection->updateView(); -+ -+ _stackSelection->refresh(); -+ -+ updateStatusBar(); -+} -+ -+void TopLevel::partsHideSelectedSlotDelayed() -+{ -+ TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT(partsHideSelectedSlot()) ); -+} -+ -+// this puts selected parts into hidden list, -+// deselects them and makes the remaining parts selected -+void TopLevel::partsHideSelectedSlot() -+{ -+ if (!_data) return; -+ -+ TracePart* part; -+ TracePartList newHidden, newActive; -+ TracePartList l = _data->parts(); -+ for (part=l.first();part;part=l.next()) { -+ if ((_activeParts.findRef(part)>=0) || -+ (_hiddenParts.findRef(part)>=0)) -+ newHidden.append(part); -+ else -+ newActive.append(part); -+ } -+ -+ _hiddenParts = newHidden; -+ _partSelection->hiddenPartsChangedSlot(_hiddenParts); -+ -+#if 0 -+ _mainWidget1->hiddenPartsChangedSlot(_hiddenParts); -+ _mainWidget2->hiddenPartsChangedSlot(_hiddenParts); -+#endif -+ -+ activePartsChangedSlot(newActive); -+} -+ -+void TopLevel::partsUnhideAllSlotDelayed() -+{ -+ TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT(partsUnhideAllSlot()) ); -+} -+ -+// this unhides all hidden parts. Does NOT change selection -+void TopLevel::partsUnhideAllSlot() -+{ -+ if (!_data) return; -+ -+ _hiddenParts.clear(); -+ _partSelection->hiddenPartsChangedSlot(_hiddenParts); -+#if 0 -+ _mainWidget1->hiddenPartsChangedSlot(_hiddenParts); -+ _mainWidget2->hiddenPartsChangedSlot(_hiddenParts); -+#endif -+} -+ -+void TopLevel::forceTrace() -+{ -+// qDebug("forceTrace"); -+ -+ // Needs Callgrind now... -+ TQFile cmd("callgrind.cmd"); -+ if (!cmd.exists()) { -+ cmd.open(IO_WriteOnly); -+ cmd.writeBlock("DUMP\n", 5); -+ cmd.close(); -+ } -+ if (_taDump->isChecked()) -+ TQTimer::singleShot( 1000, TQT_TQOBJECT(this), TQT_SLOT(forceTraceReload()) ); -+ else { -+ // cancel request -+ cmd.remove(); -+ } -+ -+} -+ -+void TopLevel::forceTraceReload() -+{ -+// qDebug("forceTraceReload"); -+ -+ TQFile cmd("callgrind.cmd"); -+ if (cmd.exists()) { -+ if (_taDump->isChecked()) -+ TQTimer::singleShot( 1000, TQT_TQOBJECT(this), TQT_SLOT(forceTraceReload()) ); -+ return; -+ } -+ _taDump->setChecked(false); -+ reload(); -+} -+ -+void TopLevel::forwardAboutToShow() -+{ -+ TQPopupMenu *popup = _paForward->popupMenu(); -+ -+ popup->clear(); -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ HistoryItem* hi = b ? b->current() : 0; -+ TraceFunction* f; -+ -+ if (!hi) { -+ popup->insertItem(i18n("(No Stack)")); -+ return; -+ } -+ -+ hi = hi->next(); -+ if (!hi) { -+ popup->insertItem(i18n("(No next function)")); -+ return; -+ } -+ -+ int count = 1; -+ while (countfunction(); -+ if (!f) break; -+ -+ TQString name = f->prettyName(); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ -+ //qDebug("forward: Adding %s", name.ascii()); -+ popup->insertItem(name, count); -+ hi = hi->next(); -+ count++; -+ } -+} -+ -+void TopLevel::backAboutToShow() -+{ -+ TQPopupMenu *popup = _paBack->popupMenu(); -+ -+ popup->clear(); -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ HistoryItem* hi = b ? b->current() : 0; -+ TraceFunction* f; -+ -+ if (!hi) { -+ popup->insertItem(i18n("(No Stack)")); -+ return; -+ } -+ -+ hi = hi->last(); -+ if (!hi) { -+ popup->insertItem(i18n("(No previous function)")); -+ return; -+ } -+ -+ int count = 1; -+ while (countfunction(); -+ if (!f) break; -+ -+ TQString name = f->prettyName(); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ -+ //qDebug("back: Adding %s", name.ascii()); -+ popup->insertItem(name, count); -+ hi = hi->last(); -+ count++; -+ } -+} -+ -+void TopLevel::upAboutToShow() -+{ -+ TQPopupMenu *popup = _paUp->popupMenu(); -+ -+ popup->clear(); -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ HistoryItem* hi = b ? b->current() : 0; -+ TraceFunction* f = hi ? hi->function() : 0; -+ -+ if (!f) { -+ popup->insertItem(i18n("(No Stack)")); -+ return; -+ } -+ f = hi->stack()->caller(f, false); -+ if (!f) { -+ popup->insertItem(i18n("(No Function Up)")); -+ return; -+ } -+ -+ int count = 1; -+ while (countprettyName(); -+ if ((int)name.length()>Configuration::maxSymbolLength()) -+ name = name.left(Configuration::maxSymbolLength()) + "..."; -+ -+ popup->insertItem(name, count); -+ f = hi->stack()->caller(f, false); -+ count++; -+ } -+ -+} -+ -+void TopLevel::forwardActivated(int id) -+{ -+ //qDebug("forwardActivated: %d", id); -+ -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ if (!b) return; -+ -+ while (id>1) { -+ b->goForward(); -+ id--; -+ } -+ _stackSelection->browserForward(); -+} -+ -+void TopLevel::backActivated(int id) -+{ -+ //qDebug("backActivated: %d", id); -+ -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ if (!b) return; -+ -+ while (id>1) { -+ b->goBack(); -+ id--; -+ } -+ _stackSelection->browserBack(); -+} -+ -+void TopLevel::upActivated(int id) -+{ -+ //qDebug("upActivated: %d", id); -+ -+ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0; -+ HistoryItem* hi = b ? b->current() : 0; -+ if (!hi) return; -+ -+ TraceFunction* f = hi->function(); -+ -+ while (id>0 && f) { -+ f = hi->stack()->caller(f, false); -+ id--; -+ } -+ -+ //qDebug("upActivated: %s", f ? f->prettyName().ascii() : "??" ); -+ if (f) -+ setFunction(f); -+ -+} -+ -+void TopLevel::showMessage(const TQString& msg, int ms) -+{ -+ if (_statusbar) -+ _statusbar->message(msg, ms); -+} -+ -+void TopLevel::showStatus(TQString msg, int progress) -+{ -+ static bool msgUpdateNeeded = true; -+ -+ if (msg.isEmpty()) { -+ if (_progressBar) { -+ _statusbar->removeWidget(_progressBar); -+ delete _progressBar; -+ _progressBar = 0; -+ } -+ _statusbar->clear(); -+ _progressMsg = msg; -+ return; -+ } -+ -+ if (_progressMsg.isEmpty()) _progressStart.start(); -+ -+ if (msg != _progressMsg) { -+ _progressMsg = msg; -+ msgUpdateNeeded = true; -+ } -+ -+ // do nothing if last change was less than 0.5 seconds ago -+ if (_progressStart.elapsed() < 500) return; -+ -+ if (!_progressBar) { -+ _progressBar = new TQProgressBar(_statusbar); -+ _progressBar->setMaximumSize(200, _statusbar->height()-4); -+ _statusbar->addWidget(_progressBar, 1, true); -+ _progressBar->show(); -+ msgUpdateNeeded = true; -+ } -+ -+ _progressStart.restart(); -+ -+ if (msgUpdateNeeded) { -+ _statusbar->message(msg); -+ msgUpdateNeeded = false; -+ } -+ _progressBar->setProgress(progress); -+ -+ // let the progress bar update itself -+ TQEventLoop* l = tqApp->eventLoop(); -+ if (l) l->processEvents(TQEventLoop::ExcludeUserInput); -+} -+ -+#include "toplevel.moc" -diff --git a/kdecachegrind/kdecachegrind/toplevel.h b/kdecachegrind/kdecachegrind/toplevel.h -new file mode 100644 -index 0000000..10e7cde ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/toplevel.h -@@ -0,0 +1,275 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * KCachegrind top level window -+ */ -+ -+#ifndef TOPLEVEL_H -+#define TOPLEVEL_H -+ -+#include -+ -+#include -+#include -+ -+#include "traceitemview.h" -+#include "tracedata.h" -+ -+class MultiView; -+class TQLineEdit; -+class TQDockWidget; -+class TQLabel; -+class TQProgressBar; -+class TQPopupMenu; -+ -+class KURL; -+class KSelectAction; -+class KToggleAction; -+class KToolBarPopupAction; -+ -+class TraceData; -+class KRecentFilesAction; -+class MainWidget; -+class PartSelection; -+class FunctionSelection; -+class DumpSelection; -+class StackSelection; -+class TraceFunction; -+ -+class TopLevel : public KMainWindow, public DCOPObject -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ TopLevel(const char *name = 0); -+ ~TopLevel(); -+ -+ TraceData* data() { return _data; } -+ void setData(TraceData*); -+ -+ virtual void saveProperties(KConfig*); -+ virtual void readProperties(KConfig*); -+ -+ void createActions(); -+ void createDocks(); -+ -+ TraceItem::CostType groupType() { return _groupType; } -+ TraceCostType* costType() { return _costType; } -+ TraceCostType* costType2() { return _costType2; } -+ TracePartList activeParts() { return _activeParts; } -+ TracePartList hiddenParts() { return _hiddenParts; } -+ -+ // current config -+ bool showPercentage() const { return _showPercentage; } -+ bool showExpanded() const { return _showExpanded; } -+ bool showCycles() const { return _showCycles; } -+ -+ /* convenience functions for often used context menu items */ -+ void addCostMenu(TQPopupMenu*,bool); -+ void addGoMenu(TQPopupMenu*); -+ -+public slots: -+ void newTrace(); -+ void loadTrace(); -+ void loadTrace(const KURL&); -+ void loadTrace(TQString); -+ void addTrace(); -+ void addTrace(const KURL&); -+ void addTrace(TQString); -+ -+ // for quick showing the main window... -+ void loadDelayed(TQString); -+ -+ void reload(); -+ void exportGraph(); -+ void newWindow(); -+ void configure(); -+ void querySlot(); -+ void dummySlot(); -+ -+ // layouts -+ void layoutDuplicate(); -+ void layoutRemove(); -+ void layoutNext(); -+ void layoutPrevious(); -+ void layoutSave(); -+ void layoutRestore(); -+ void updateLayoutActions(); -+ -+ void updateStatusBar(); -+ void costTypeSelected(const TQString&); -+ void costType2Selected(const TQString&); -+ void groupTypeSelected(int); -+ void splitSlot(); -+ void splitDirSlot(); -+ void configureToolbars(); -+ void configureKeys(); -+ bool queryExit(); -+ bool queryClose(); -+ void togglePartDock(); -+ void toggleStackDock(); -+ void toggleFunctionDock(); -+ void toggleDumpDock(); -+ void toggleStatusBar(); -+ void partVisibilityChanged(bool); -+ void dumpVisibilityChanged(bool); -+ void stackVisibilityChanged(bool); -+ void functionVisibilityChanged(bool); -+ void togglePercentage(); -+ void setPercentage(bool); -+ void setAbsoluteCost(); -+ void setRelativeCost(); -+ void toggleExpanded(); -+ void toggleCycles(); -+ void forceTrace(); -+ void forceTraceReload(); -+ void forwardAboutToShow(); -+ void backAboutToShow(); -+ void upAboutToShow(); -+ void forwardActivated(int); -+ void backActivated(int); -+ void upActivated(int); -+ -+ bool setCostType(TraceCostType*); -+ bool setCostType2(TraceCostType*); -+ bool setCostType(TQString); -+ bool setCostType2(TQString); -+ bool setCostType(int); -+ bool setCostType2(int); -+ bool setGroupType(TraceItem::CostType); -+ bool setGroupType(TQString); -+ bool setGroup(TraceCostItem*); -+ bool setGroup(TQString); -+ bool setFunction(TraceFunction*); -+ bool setFunction(TQString); -+ void activePartsChangedSlot(const TracePartList& list); -+ void partsHideSelectedSlot(); -+ void partsUnhideAllSlot(); -+ -+ /* These go back to mainloop first by using a timer. -+ * So they can be called from event handlers that -+ * aren't allowed to delete list entries. -+ */ -+ void setCostTypeDelayed(TraceCostType*); -+ void setCostType2Delayed(TraceCostType*); -+ void setGroupTypeDelayed(TraceItem::CostType); -+ void setGroupDelayed(TraceCostItem*); -+ void setTraceItemDelayed(TraceItem*); -+ void partsHideSelectedSlotDelayed(); -+ void partsUnhideAllSlotDelayed(); -+ void goBack(); -+ void goForward(); -+ void goUp(); -+ void setDirectionDelayed(TraceItemView::Direction); -+ -+ /* SingleShot Slots (without parameters) for the delayed versions */ -+ void setCostTypeDelayed(); -+ void setCostType2Delayed(); -+ void setGroupTypeDelayed(); -+ void setGroupDelayed(); -+ void setTraceItemDelayed(); -+ void loadTraceDelayed(); -+ void setDirectionDelayed(); -+ -+ // configuration has changed -+ void configChanged(); -+ -+ //void refresh(); -+ void slotShowTipOnStart(); -+ void slotShowTip(); -+ -+ // progress in status bar, empty message disables progress display -+ void showStatus(TQString msg, int progress); -+ void showMessage(const TQString&, int msec); -+ -+private: -+ void init(); -+ void createLayoutActions(); -+ void createMiscActions(); -+ void setupMainWidget(MainWidget*); -+ void setupPartSelection(PartSelection*); -+ void restoreCurrentState(TQString postfix); -+ void saveCurrentState(TQString postfix); -+ void saveTraceSettings(); -+ TQString traceKey(); -+ void restoreTraceTypes(); -+ void restoreTraceSettings(); -+ -+ KStatusBar* _statusbar; -+ TQLabel* _statusLabel; -+ KRecentFilesAction* _openRecent; -+ bool _twoMainWidgets; -+ Qt::Orientation _spOrientation; -+ -+ MultiView* _multiView; -+ FunctionSelection* _functionSelection; -+ DumpSelection* _dumpSelection; -+ PartSelection* _partSelection; -+ StackSelection* _stackSelection; -+ TQLineEdit* queryLineEdit; -+ -+ TQDockWindow *_partDock, *_stackDock, *_functionDock, *_dumpDock; -+ bool _forcePartDock; -+ -+ KSelectAction *_saCost, *_saCost2, *saGroup; -+ KToggleAction *_partDockShown, *_stackDockShown; -+ KToggleAction *_functionDockShown, *_dumpDockShown; -+ KToggleAction *_taPercentage, *_taExpanded, *_taCycles; -+ KToggleAction *_taDump, *_taSplit, *_taSplitDir; -+ KToolBarPopupAction *_paForward, *_paBack, *_paUp; -+ -+ TraceFunction* _function; -+ const TQObject* _lastSender; -+ -+ // trace data shown in this window -+ TraceData* _data; -+ // subcost types used for visualisation -+ TraceCostType* _costType; -+ TraceCostType* _costType2; -+ // grouping of function list -+ TraceItem::CostType _groupType; -+ // selected group -+ TraceCostItem* _group; -+ // selected parts -+ TracePartList _activeParts; -+ // hidden parts -+ TracePartList _hiddenParts; -+ // layouts -+ int _layoutCurrent, _layoutCount; -+ -+ // for delayed slots -+ TraceCostType* _costTypeDelayed; -+ TraceCostType* _costType2Delayed; -+ TraceItem::CostType _groupTypeDelayed; -+ TraceCostItem* _groupDelayed; -+ TraceItem* _traceItemDelayed; -+ TQString _loadTraceDelayed; -+ TraceItemView::Direction _directionDelayed; -+ -+ // for status progress display -+ TQString _progressMsg; -+ TQTime _progressStart; -+ TQProgressBar* _progressBar; -+ -+ // toplevel configuration options -+ bool _showPercentage, _showExpanded, _showCycles; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/tracedata.cpp b/kdecachegrind/kdecachegrind/tracedata.cpp -new file mode 100644 -index 0000000..f129c2e ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/tracedata.cpp -@@ -0,0 +1,5068 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "tracedata.h" -+#include "toplevel.h" -+#include "loader.h" -+#include "configuration.h" -+#include "utils.h" -+#include "fixcost.h" -+ -+ -+#define TRACE_DEBUG 0 -+#define TRACE_ASSERTIONS 0 -+ -+const int TraceCost::MaxRealIndex = MaxRealIndexValue; -+const int TraceCost::InvalidIndex = -1; -+ -+//--------------------------------------------------- -+// Addr -+ -+bool Addr::set(FixString& s) -+{ -+ return s.stripUInt64(_v); -+} -+ -+int Addr::set(const char *s) -+{ -+ int n = 0; -+ _v = 0; -+ -+ while((n<16) && *s) { -+ if ((*s>='0') && (*s<='9')) -+ _v = 16*_v + (*s-'0'); -+ else if ((*s>='a') && (*s<='f')) -+ _v = 16*_v + 10 + (*s-'a'); -+ else if ((*s>='A') && (*s<='F')) -+ _v = 16*_v + 10 + (*s-'A'); -+ else break; -+ s++; -+ n++; -+ } -+ -+ return n; -+} -+ -+ -+TQString Addr::toString() const -+{ -+ if (_v == 0) return TQString("0"); -+ -+ uint64 n = _v; -+ TQString hex; -+ hex.reserve(16); -+ -+ while(n>0) { -+ int d = (n & 15); -+ hex = TQChar((d<10) ? ('0'+d) : ('A'-10+d)) + hex; -+ n /= 16; -+ } -+ -+ return hex; -+} -+ -+TQString Addr::pretty() const -+{ -+ if (_v == 0) return TQString("0"); -+ -+ uint64 n = _v; -+ int p = 0; -+ TQString hex; -+ hex.reserve(20); -+ -+ while(n>0) { -+ int d = (n & 15); -+ if ((p>0) && ((p%4)==0)) hex = " " + hex; -+ hex = TQChar((d<10) ? ('0'+d) : ('A'-10+d)) + hex; -+ n /= 16; -+ p++; -+ } -+ -+ return hex; -+} -+ -+bool Addr::isInRange(Addr a, int distance) -+{ -+ uint64 diff = (a._v > _v) ? (a._v - _v) : (_v - a._v); -+ uint64 dist = (distance<0) ? distance : -distance; -+ return (diff < dist); -+} -+ -+//--------------------------------------------------- -+// TraceItem -+ -+TQString* TraceItem::_typeName = 0; -+TQString* TraceItem::_i18nTypeName = 0; -+ -+TraceItem::TraceItem() -+{ -+ _position = 0; -+ _dep = 0; -+ _dirty = true; -+} -+ -+TraceItem::~TraceItem() -+{} -+ -+void TraceItem::cleanup() -+{ -+ if (_typeName) { -+ delete [] _typeName; -+ _typeName = 0; -+ } -+ if (_i18nTypeName) { -+ delete [] _i18nTypeName; -+ _i18nTypeName = 0; -+ } -+} -+ -+TQString TraceItem::typeName(CostType t) -+{ -+ if (!_typeName) { -+ _typeName = new TQString [MaxCostType+1]; -+ TQString* strs = _typeName; -+ for(int i=0;i<=MaxCostType;i++) -+ strs[i] = TQString("?"); -+ -+ strs[Item] = I18N_NOOP("Abstract Item"); -+ strs[Cost] = I18N_NOOP("Cost Item"); -+ strs[PartLine] = I18N_NOOP("Part Source Line"); -+ strs[Line] = I18N_NOOP("Source Line"); -+ strs[PartLineCall] = I18N_NOOP("Part Line Call"); -+ strs[LineCall] = I18N_NOOP("Line Call"); -+ strs[PartLineJump] = I18N_NOOP("Part Jump"); -+ strs[LineJump] = I18N_NOOP("Jump"); -+ strs[PartInstr] = I18N_NOOP("Part Instruction"); -+ strs[Instr] = I18N_NOOP("Instruction"); -+ strs[PartInstrJump] = I18N_NOOP("Part Instruction Jump"); -+ strs[InstrJump] = I18N_NOOP("Instruction Jump"); -+ strs[PartInstrCall] = I18N_NOOP("Part Instruction Call"); -+ strs[InstrCall] = I18N_NOOP("Instruction Call"); -+ strs[PartCall] = I18N_NOOP("Part Call"); -+ strs[Call] = I18N_NOOP("Call"); -+ strs[PartFunction] = I18N_NOOP("Part Function"); -+ strs[FunctionSource] = I18N_NOOP("Function Source File"); -+ strs[Function] = I18N_NOOP("Function"); -+ strs[FunctionCycle] = I18N_NOOP("Function Cycle"); -+ strs[PartClass] = I18N_NOOP("Part Class"); -+ strs[Class] = I18N_NOOP("Class"); -+ strs[PartFile] = I18N_NOOP("Part Source File"); -+ strs[File] = I18N_NOOP("Source File"); -+ strs[PartObject] = I18N_NOOP("Part ELF Object"); -+ strs[Object] = I18N_NOOP("ELF Object"); -+ strs[Part] = I18N_NOOP("Profile Part"); -+ strs[Data] = I18N_NOOP("Program Trace"); -+ } -+ if (t<0 || t> MaxCostType) t = MaxCostType; -+ return _typeName[t]; -+} -+ -+TraceItem::CostType TraceItem::costType(TQString s) -+{ -+ // This is the default cost Type -+ if (s.isEmpty()) return Function; -+ -+ CostType type; -+ for (int i=0; i MaxCostType) t = MaxCostType; -+ return _i18nTypeName[t]; -+} -+ -+TraceItem::CostType TraceItem::i18nCostType(TQString s) -+{ -+ // This is the default cost Type -+ if (s.isEmpty()) return Function; -+ -+ CostType type; -+ for (int i=0; iname()) -+ .arg(part()->name()); -+ } -+ -+ if (_dep) -+ return _dep->name(); -+ -+ return i18n("(unknown)"); -+} -+ -+TQString TraceItem::prettyName() const -+{ -+ if (name().isEmpty()) return i18n("(unknown)"); -+ return name(); -+} -+ -+ -+TQString TraceItem::fullName() const -+{ -+ return TQString("%1 %2") -+ .arg(typeName(type())).arg(prettyName()); -+} -+ -+TQString TraceItem::toString() -+{ -+ return TQString("%1\n [%3]").arg(fullName()).arg(costString(0)); -+} -+ -+void TraceItem::invalidate() -+{ -+ if (_dirty) return; -+ _dirty = true; -+ -+ if (_dep) -+ _dep->invalidate(); -+} -+ -+void TraceItem::update() -+{ -+ _dirty = false; -+} -+ -+TracePart* TraceItem::part() -+{ -+ return _position ? _position->part() : 0; -+} -+ -+const TracePart* TraceItem::part() const -+{ -+ return _position ? _position->part() : 0; -+} -+ -+TraceData* TraceItem::data() -+{ -+ return _position ? _position->data() : 0; -+} -+ -+const TraceData* TraceItem::data() const -+{ -+ return _position ? _position->data() : 0; -+} -+ -+ -+//--------------------------------------------------- -+// TraceCost -+ -+TraceCost::TraceCost() -+ : TraceItem() -+{ -+ _cachedType = 0; // no virtual value cached -+ -+ TraceCost::clear(); -+} -+ -+TraceCost::~TraceCost() -+{} -+ -+ -+void TraceCost::clear() -+{ -+ // simple set usage count to 0 -+ _count = 0; -+ -+ TraceItem::clear(); -+} -+ -+ -+ -+void TraceCost::set(TraceSubMapping* sm, const char* s) -+{ -+ if (!sm) return; -+ if (!s) { -+ if (_count>0) clear(); -+ return; -+ } -+ -+ while(*s == ' ') s++; -+ -+ if (sm->isIdentity()) { -+ int i = 0; -+ while(icount()) { -+ if (!_cost[i].set(&s)) break; -+ i++; -+ } -+ _count = i; -+ } -+ else { -+ int i = 0, maxIndex = 0, index; -+ while(1) { -+ index = sm->realIndex(i); -+ if (maxIndexfirstUnused(); i<=maxIndex; i=sm->nextUnused(i)) -+ _cost[i] = 0; -+ _count = maxIndex; -+ } -+ // a cost change has to be propagated (esp. in subclasses) -+ invalidate(); -+} -+ -+void TraceCost::set(TraceSubMapping* sm, FixString & s) -+{ -+ if (!sm) return; -+ -+ s.stripSpaces(); -+ -+ if (sm->isIdentity()) { -+ int i = 0; -+ while(icount()) { -+ if (!s.stripUInt64(_cost[i])) break; -+ i++; -+ } -+ _count = i; -+ } -+ else { -+ int i = 0, maxIndex = 0, index; -+ while(1) { -+ index = sm->realIndex(i); -+ if (maxIndexfirstUnused(); i<=maxIndex; i=sm->nextUnused(i)) -+ _cost[i] = 0; -+ _count = maxIndex+1; -+ } -+ invalidate(); -+} -+ -+ -+void TraceCost::addCost(TraceSubMapping* sm, const char* s) -+{ -+ if (!sm || !s) return; -+ -+ SubCost v; -+ -+ if (sm->isIdentity()) { -+ int i = 0; -+ while(icount()) { -+ if (!v.set(&s)) break; -+ if (i<_count) -+ _cost[i] += v; -+ else -+ _cost[i] = v; -+ i++; -+ } -+ if (i > _count) _count = i; -+ } -+ else { -+ int i = 0, maxIndex = 0, index; -+ while(1) { -+ if (!v.set(&s)) break; -+ index = sm->realIndex(i); -+ if (maxIndex= _count) { -+ /* we have to set all costs of unused indexes in the interval -+ * [_count;maxIndex] to zero */ -+ for(i=sm->nextUnused(_count-1); i<=maxIndex; i=sm->nextUnused(i)) -+ _cost[i] = 0; -+ _count = maxIndex+1; -+ } -+ } -+ -+ // a cost change has to be propagated (esp. in subclasses) -+ invalidate(); -+ -+#if TRACE_DEBUG -+ _dirty = false; // don't recurse ! -+ qDebug("%s\n now %s", fullName().ascii(), -+ TraceCost::costString(0).ascii()); -+ _dirty = true; // because of invalidate() -+#endif -+} -+ -+void TraceCost::addCost(TraceSubMapping* sm, FixString & s) -+{ -+ if (!sm) return; -+ -+ s.stripSpaces(); -+ -+ SubCost v; -+ -+ if (sm->isIdentity()) { -+ int i = 0; -+ while(icount()) { -+ if (!s.stripUInt64(v)) break; -+ if (i<_count) -+ _cost[i] += v; -+ else -+ _cost[i] = v; -+ i++; -+ } -+ if (i > _count) _count = i; -+ } -+ else { -+ int i = 0, maxIndex = 0, index; -+ while(1) { -+ if (!s.stripUInt64(v)) break; -+ index = sm->realIndex(i); -+ if (maxIndex= _count) { -+ /* we have to set all costs of unused indexes in the interval -+ * [_count;maxIndex] to zero */ -+ for(i=sm->nextUnused(_count-1); i<=maxIndex; i=sm->nextUnused(i)) -+ _cost[i] = 0; -+ _count = maxIndex+1; -+ } -+ } -+ -+ invalidate(); -+ -+#if TRACE_DEBUG -+ _dirty = false; // don't recurse ! -+ qDebug("%s\n now %s", fullName().ascii(), -+ TraceCost::costString(0).ascii()); -+ _dirty = true; // because of invalidate() -+#endif -+} -+ -+ -+// update each subcost to be maximum of old and given costs -+void TraceCost::maxCost(TraceSubMapping* sm, FixString & s) -+{ -+ if (!sm) return; -+ -+ s.stripSpaces(); -+ -+ SubCost v; -+ -+ if (sm->isIdentity()) { -+ int i = 0; -+ while(icount()) { -+ if (!s.stripUInt64(v)) break; -+ if (i<_count) { -+ if (v>_cost[i]) _cost[i] = v; -+ } -+ else -+ _cost[i] = v; -+ i++; -+ } -+ if (i > _count) _count = i; -+ } -+ else { -+ int i = 0, maxIndex = 0, index; -+ while(1) { -+ if (!s.stripUInt64(v)) break; -+ index = sm->realIndex(i); -+ if (maxIndex_cost[index]) _cost[index] = v; -+ } -+ else -+ _cost[index] = v; -+ i++; -+ } -+ if (maxIndex >= _count) { -+ /* we have to set all costs of unused indexes in the interval -+ * [_count;maxIndex] to zero */ -+ for(i=sm->nextUnused(_count-1); i<=maxIndex; i=sm->nextUnused(i)) -+ _cost[i] = 0; -+ _count = maxIndex+1; -+ } -+ } -+ -+ invalidate(); -+ -+#if TRACE_DEBUG -+ _dirty = false; // don't recurse ! -+ qDebug("%s\n now %s", fullName().ascii(), -+ TraceCost::costString(0).ascii()); -+ _dirty = true; // because of invalidate() -+#endif -+} -+ -+ -+void TraceCost::addCost(TraceCost* item) -+{ -+ int i; -+ -+ if (!item) return; -+ -+ // we have to update the other item if needed -+ // because we access the item costs directly -+ if (item->_dirty) item->update(); -+ -+ if (item->_count < _count) { -+ for (i = 0; i_count; i++) -+ _cost[i] += item->_cost[i]; -+ } -+ else { -+ for (i = 0; i<_count; i++) -+ _cost[i] += item->_cost[i]; -+ for (; i_count; i++) -+ _cost[i] = item->_cost[i]; -+ _count = item->_count; -+ } -+ -+ // a cost change has to be propagated (esp. in subclasses) -+ invalidate(); -+ -+#if TRACE_DEBUG -+ _dirty = false; // don't recurse ! -+ qDebug("%s added cost item\n %s\n now %s", -+ fullName().ascii(), item->fullName().ascii(), -+ TraceCost::costString(0).ascii()); -+ _dirty = true; // because of invalidate() -+#endif -+} -+ -+void TraceCost::maxCost(TraceCost* item) -+{ -+ int i; -+ -+ if (!item) return; -+ -+ // we have to update the other item if needed -+ // because we access the item costs directly -+ if (item->_dirty) item->update(); -+ -+ if (item->_count < _count) { -+ for (i = 0; i_count; i++) -+ if (_cost[i] < item->_cost[i]) _cost[i] = item->_cost[i]; -+ } -+ else { -+ for (i = 0; i<_count; i++) -+ if (_cost[i] < item->_cost[i]) _cost[i] = item->_cost[i]; -+ for (; i_count; i++) -+ _cost[i] = item->_cost[i]; -+ _count = item->_count; -+ } -+ -+ // a cost change has to be propagated (esp. in subclasses) -+ invalidate(); -+ -+#if TRACE_DEBUG -+ _dirty = false; // don't recurse ! -+ qDebug("%s added cost item\n %s\n now %s", -+ fullName().ascii(), item->fullName().ascii(), -+ TraceCost::costString(0).ascii()); -+ _dirty = true; // because of invalidate() -+#endif -+} -+ -+void TraceCost::addCost(int type, SubCost value) -+{ -+ if (type<0 || type>=MaxRealIndex) return; -+ if (type<_count) -+ _cost[type] += value; -+ else { -+ for(int i=_count;i=MaxRealIndex) return; -+ if (type<_count) { -+ if (value>_cost[type]) _cost[type] = value; -+ } -+ else { -+ for(int i=_count;i_dirty) item->update(); -+ -+ int maxCount = (item->_count > _count) ? item->_count : _count; -+ -+ res._count = maxCount; -+ for (int i=0; isubCost(i) - subCost(i); -+ -+ return res; -+} -+ -+TQString TraceCost::costString(TraceCostMapping* m) -+{ -+ TQString res; -+ -+ if (_dirty) update(); -+ -+ int maxIndex = m ? m->realCount() : TraceCost::MaxRealIndex; -+ for (int i = 0; itype(i)->name() + " "; -+ -+ res += subCost(i).pretty(); -+ } -+ return res; -+} -+ -+ -+void TraceCost::invalidate() -+{ -+ if (_dirty) return; -+ _dirty = true; -+ _cachedType = 0; // cached value is invalid, too -+ -+ if (_dep) -+ _dep->invalidate(); -+} -+ -+void TraceCost::update() -+{ -+ _dirty = false; -+} -+ -+// this is only for real types -+SubCost TraceCost::subCost(int idx) -+{ -+ if (idx<0) return 0; -+ -+ /* update if needed as cost could be calculated dynamically in subclasses -+ * this can change _count !! */ -+ if (_dirty) update(); -+ if (idx>=_count) return 0; -+ -+ return _cost[idx]; -+} -+ -+SubCost TraceCost::subCost(TraceCostType* t) -+{ -+ if (!t) return 0; -+ if (_cachedType != t) { -+ _cachedType = t; -+ _cachedCost = t->subCost(this); -+ } -+ return _cachedCost; -+} -+ -+TQString TraceCost::prettySubCost(TraceCostType* t) -+{ -+ return subCost(t).pretty(); -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceJumpCost -+ -+TraceJumpCost::TraceJumpCost() -+ :TraceItem() -+{ -+ TraceJumpCost::clear(); -+} -+ -+TraceJumpCost::~TraceJumpCost() -+{} -+ -+SubCost TraceJumpCost::executedCount() -+{ -+ if (_dirty) update(); -+ -+ return _executedCount; -+} -+ -+SubCost TraceJumpCost::followedCount() -+{ -+ if (_dirty) update(); -+ -+ return _followedCount; -+} -+ -+TQString TraceJumpCost::costString(TraceCostMapping*) -+{ -+ if (_dirty) update(); -+ -+ return TQString("%1/%2") -+ .arg(_followedCount.pretty()) -+ .arg(_executedCount.pretty()); -+} -+ -+void TraceJumpCost::clear() -+{ -+ _followedCount = 0; -+ _executedCount = 0; -+} -+ -+void TraceJumpCost::addCost(TraceJumpCost* item) -+{ -+ if (item->_dirty) item->update(); -+ -+ _followedCount += item->followedCount(); -+ _executedCount += item->executedCount(); -+} -+ -+ -+//--------------------------------------------------- -+// TraceCostType -+ -+TQPtrList* TraceCostType::_knownTypes = 0; -+ -+TraceCostType::TraceCostType(TQString name, TQString longName, TQString formula) -+{ -+ _name = name; -+ _longName = longName; -+ _formula = formula; -+ _mapping = 0; -+ _realIndex = TraceCost::InvalidIndex; -+ _parsed = false; -+ _inParsing = false; -+ -+ for (int i=0; iTraceCost::MaxRealIndex) -+ i=TraceCost::InvalidIndex; -+ -+ _realIndex = i; -+ _formula = TQString(); -+} -+ -+// checks for existing types and sets coefficients -+bool TraceCostType::parseFormula() -+{ -+ if (_parsed) return true; -+ if (_inParsing) { -+ qDebug("TraceCostType::parseFormula: Recursion detected."); -+ return false; -+ } -+ -+ if (!_mapping) { -+ qDebug("TraceCostType::parseFormula: No mapping set!"); -+ return false; -+ } -+ -+ _inParsing = true; -+ -+ for (int i=0; itype(costName); -+ if (!costType) { -+ // qDebug("Cost type '%s': In formula cost '%s' unknown.", -+ // _name.ascii(), costName.ascii()); -+ -+ _inParsing = false; -+ return false; -+ } -+ -+ factor = (rx.cap(2).isEmpty()) ? 1 : rx.cap(2).toInt(); -+ if (rx.cap(1) == "-") factor = -factor; -+ -+ if (costType->isReal()) -+ _coefficient[costType->realIndex()] += factor; -+ else { -+ costType->parseFormula(); -+ for (int i=0; i_coefficient[i]; -+ } -+ } -+ -+ _inParsing = false; -+ _parsed = true; -+ -+ return true; -+} -+ -+TQString TraceCostType::parsedFormula() -+{ -+ TQString res; -+ -+ if (!parseFormula()) return res; -+ -+ for (int i=0; i0) res += "+ "; -+ } -+ if (c<0) { res += "- "; c = -c; } -+ res += TQString::number(c); -+ -+ TraceCostType* t = _mapping->type(i); -+ if (!t) continue; -+ -+ if (!t->name().isEmpty()) -+ res += TQString(" * %1").arg(t->name()); -+ } -+ -+ return res; -+} -+ -+SubCost TraceCostType::subCost(TraceCost* c) -+{ -+ if (_realIndex != TraceCost::InvalidIndex) -+ return c->subCost(_realIndex); -+ -+ if (!_parsed) { -+ if (!parseFormula()) return 0; -+ } -+ SubCost res = 0; -+ -+ int rc = _mapping->realCount(); -+ for (int i = 0;isubCost(i); -+ -+ return res; -+} -+ -+int TraceCostType::histCost(TraceCost* c, double total, double* hist) -+{ -+ if (total == 0.0) return 0; -+ -+ if (!_parsed) { -+ if (!parseFormula()) return 0; -+ } -+ -+ int rc = _mapping->realCount(); -+ for (int i = 0;isubCost(i) / total; -+ else -+ hist[i] = 0.0; -+ } -+ -+ return rc; -+} -+ -+ -+ -+ -+TraceCostType* TraceCostType::knownRealType(TQString n) -+{ -+ if (!_knownTypes) return 0; -+ -+ TraceCostType* t; -+ for (t=_knownTypes->first();t;t=_knownTypes->next()) -+ if (t->isReal() && (t->name() == n)) { -+ TraceCostType* type = new TraceCostType(*t); -+ return type; -+ } -+ -+ return 0; -+} -+ -+TraceCostType* TraceCostType::knownVirtualType(TQString n) -+{ -+ if (!_knownTypes) return 0; -+ -+ TraceCostType* t; -+ for (t=_knownTypes->first();t;t=_knownTypes->next()) -+ if (!t->isReal() && (t->name() == n)) { -+ TraceCostType* type = new TraceCostType(*t); -+ return type; -+ } -+ -+ return 0; -+} -+ -+// we take ownership -+void TraceCostType::add(TraceCostType* t) -+{ -+ if (!t) return; -+ -+ t->setMapping(0); -+ -+ if (!_knownTypes) -+ _knownTypes = new TQPtrList; -+ -+ /* Already known? */ -+ TraceCostType* kt; -+ for (kt=_knownTypes->first();kt;kt=_knownTypes->next()) -+ if (kt->name() == t->name()) break; -+ -+ if (kt) { -+ // Overwrite old type -+ if (!t->longName().isEmpty() && -+ (t->longName() != t->name())) kt->setLongName(t->longName()); -+ if (!t->formula().isEmpty()) kt->setFormula(t->formula()); -+ -+ delete t; -+ } -+ else { -+ if (t->longName().isEmpty()) t->setLongName(t->name()); -+ _knownTypes->append(t); -+ } -+} -+ -+ -+int TraceCostType::knownTypeCount() -+{ -+ if (!_knownTypes) return 0; -+ -+ return _knownTypes->count(); -+} -+ -+bool TraceCostType::remove(TQString n) -+{ -+ if (!_knownTypes) return false; -+ -+ TraceCostType* t; -+ for (t=_knownTypes->first();t;t=_knownTypes->next()) -+ if (!t->isReal() && (t->name() == n)) { -+ _knownTypes->removeRef(t); -+ delete t; -+ return true; -+ } -+ -+ return false; -+} -+ -+TraceCostType* TraceCostType::knownType(int i) -+{ -+ if (!_knownTypes) return 0; -+ if (i<0 || i>=(int)_knownTypes->count()) return 0; -+ -+ return _knownTypes->at(i); -+} -+ -+TQColor TraceCostType::color() -+{ -+ if (!_mapping) return TQColor(); -+ return _mapping->realColors()[_realIndex]; -+} -+ -+ -+//--------------------------------------------------- -+// TraceCostMapping -+ -+TraceCostMapping::TraceCostMapping() -+{ -+ _realCount = 0; -+ _virtualCount = 0; -+ for (int i=0;i0)) return 0; -+ -+ if (newCount+_realCount > TraceCost::MaxRealIndex) { -+ kdDebug() << "TraceCostMapping::subMapping: No space for " -+ << newCount << " sub costs." << endl; -+ return 0; -+ } -+ -+ TraceSubMapping* sm = new TraceSubMapping(this); -+ -+ pos = 0; -+ while (1) { -+ // skip space -+ while((posappend(addReal(types.mid(pos,pos2-pos))); -+ -+ pos = pos2; -+ } -+ -+ return sm; -+} -+ -+ -+int TraceCostMapping::addReal(TQString t) -+{ -+ int index = realIndex(t); -+ if (index>=0) return index; -+ -+ TraceCostType* ct = TraceCostType::knownRealType(t); -+ if (!ct) ct = new TraceCostType(t, t); -+ -+ // make it real -+ ct->setRealIndex(); -+ -+ return add(ct); -+} -+ -+// add a cost type to a mapping -+// this transfers ownership of the type! -+int TraceCostMapping::add(TraceCostType* ct) -+{ -+ if (!ct) return TraceCost::InvalidIndex; -+ -+ ct->setMapping(this); -+ -+ if (ct->isReal()) { -+ if (_realCount >= TraceCost::MaxRealIndex) { -+ qDebug("WARNING: Maximum for real cost types reached (on adding '%s')", -+ ct->name().ascii()); -+ return TraceCost::InvalidIndex; -+ } -+ _real[_realCount] = ct; -+ ct->setRealIndex(_realCount); -+ _realColor[_realCount] = Configuration::costTypeColor(ct); -+ -+ _realCount++; -+ return _realCount-1; -+ } -+ -+ if (_virtualCount >= TraceCost::MaxRealIndex) { -+ qDebug("WARNING: Maximum for virtual cost types reached (on adding '%s')", -+ ct->name().ascii()); -+ return TraceCost::InvalidIndex; -+ } -+ _virtual[_virtualCount] = ct; -+ _virtualCount++; -+ return _virtualCount-1; -+} -+ -+// we delete the type: t is invalid when returning true! -+bool TraceCostMapping::remove(TraceCostType* t) -+{ -+ if (!t) return false; -+ if (t->mapping() != this) return false; -+ -+ // don't delete real types -+ if (t->isReal()) return false; -+ -+ int i; -+ for(i=0;i<_virtualCount;i++) -+ if (_virtual[i] == t) break; -+ -+ // not found? -+ if (i == _virtualCount) return false; -+ -+ // delete known type with same name -+ TraceCostType::remove(t->name()); -+ -+ // delete this type -+ _virtual[i] = 0; -+ delete t; -+ if (i+1 == _virtualCount) { -+ // we can reuse the last index -+ _virtualCount--; -+ } -+ return true; -+} -+ -+ -+TraceCostType* TraceCostMapping::realType(int t) -+{ -+ if (t<0 || t>=_realCount) return 0; -+ return _real[t]; -+} -+ -+TraceCostType* TraceCostMapping::virtualType(int t) -+{ -+ if (t<0 || t>=_virtualCount) return 0; -+ return _virtual[t]; -+} -+ -+ -+TraceCostType* TraceCostMapping::type(int t) -+{ -+ if (t<0) return 0; -+ if (t<_realCount) return _real[t]; -+ -+ t -= TraceCost::MaxRealIndex; -+ if (t<0) return 0; -+ if (t<_virtualCount) return _virtual[t]; -+ -+ return 0; -+} -+ -+TraceCostType* TraceCostMapping::type(TQString name) -+{ -+ for (int i=0;i<_realCount;i++) -+ if (_real[i] && (_real[i]->name() == name)) -+ return _real[i]; -+ -+ for (int i=0;i<_virtualCount;i++) -+ if (_virtual[i] && (_virtual[i]->name() == name)) -+ return _virtual[i]; -+ -+ return 0; -+} -+ -+TraceCostType* TraceCostMapping::typeForLong(TQString name) -+{ -+ for (int i=0;i<_realCount;i++) -+ if (_real[i] && (_real[i]->longName() == name)) -+ return _real[i]; -+ -+ for (int i=0;i<_virtualCount;i++) -+ if (_virtual[i] && (_virtual[i]->longName() == name)) -+ return _virtual[i]; -+ -+ return 0; -+} -+ -+ -+int TraceCostMapping::realIndex(TQString name) -+{ -+ for (int i=0;i<_realCount;i++) -+ if (_real[i] && (_real[i]->name() == name)) -+ return i; -+ -+ return TraceCost::InvalidIndex; -+} -+ -+int TraceCostMapping::index(TQString name) -+{ -+ for (int i=0;i<_realCount;i++) -+ if (_real[i] && (_real[i]->name() == name)) -+ return i; -+ -+ for (int i=0;i<_virtualCount;i++) -+ if (_virtual[i] && (_virtual[i]->name() == name)) -+ return TraceCost::MaxRealIndex + 1 + i; -+ -+ return TraceCost::InvalidIndex; -+} -+ -+int TraceCostMapping::addKnownVirtualTypes() -+{ -+ int addCount = 0; -+ int addDiff, i; -+ int knownCount = TraceCostType::knownTypeCount(); -+ -+ while (1) { -+ addDiff = 0; -+ for (i=0; iisReal()) continue; -+ if (index(t->name()) != TraceCost::InvalidIndex) continue; -+ t->setMapping(this); -+ if (t->parseFormula()) { -+ addDiff++; -+ add(new TraceCostType(t->name(), t->longName(), t->formula())); -+ } -+ t->setMapping(0); -+ } -+ if (addDiff == 0) break; -+ addCount += addDiff; -+ } -+ return addCount; -+} -+ -+ -+//--------------------------------------------------- -+// TraceSubMapping -+ -+TraceSubMapping::TraceSubMapping(TraceCostMapping* mapping) -+{ -+ _mapping = mapping; -+ clear(); -+} -+ -+void TraceSubMapping::clear() -+{ -+ _count = 0; -+ _isIdentity = true; -+ _firstUnused = 0; -+ for(int i=0;iaddReal(type) : _mapping->realIndex(type); -+ -+ return append(index); -+} -+ -+bool TraceSubMapping::append(int type) -+{ -+ if (!_mapping) return false; -+ if ((type<0) || (type >= _mapping->realCount())) return false; -+ -+ if ( _count >= TraceCost::MaxRealIndex) return false; -+ -+ _realIndex[_count] = type; -+ -+ if (_isIdentity && (_count != type)) _isIdentity = false; -+ if (type == _firstUnused) -+ _firstUnused = _nextUnused[type]; -+ for(int i=0;i=0) { -+ qDebug("addDep: %s already in list!", -+ dep->fullName().ascii()); -+ return; -+ } -+#endif -+ -+ _deps.append(dep); -+ _lastDep = dep; -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), dep->fullName().ascii(), -+ _deps.count()); -+#endif -+} -+ -+TraceCost* TraceListCost::findDepFromPart(TracePart* part) -+{ -+ if (_lastDep && _lastDep->part() == part) -+ return _lastDep; -+ -+ TraceCost* dep; -+ for (dep = _deps.first(); dep; dep = _deps.next()) -+ if (dep->part() == part) { -+ _lastDep = dep; -+ return dep; -+ } -+ return 0; -+} -+ -+ -+void TraceListCost::update() -+{ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("update %s (count %d)", -+ fullName().ascii(), _deps.count()); -+#endif -+ -+ clear(); -+ TraceCost* item; -+ for (item = _deps.first(); item; item = _deps.next()) { -+ if (onlyActiveParts()) -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ } -+ -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceJumpListCost -+ -+TraceJumpListCost::TraceJumpListCost() -+{ -+ _lastDep = 0; -+} -+ -+TraceJumpListCost::~TraceJumpListCost() -+{} -+ -+void TraceJumpListCost::addDep(TraceJumpCost* dep) -+{ -+#if TRACE_ASSERTIONS -+ if (_deps.findRef(dep)>=0) { -+ qDebug("addDep: %s already in list!", -+ dep->fullName().ascii()); -+ return; -+ } -+#endif -+ -+ _deps.append(dep); -+ _lastDep = dep; -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), dep->fullName().ascii(), -+ _deps.count()); -+#endif -+} -+ -+TraceJumpCost* TraceJumpListCost::findDepFromPart(TracePart* part) -+{ -+ if (_lastDep && _lastDep->part() == part) -+ return _lastDep; -+ -+ TraceJumpCost* dep; -+ for (dep = _deps.first(); dep; dep = _deps.next()) -+ if (dep->part() == part) { -+ _lastDep = dep; -+ return dep; -+ } -+ return 0; -+} -+ -+ -+void TraceJumpListCost::update() -+{ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("update %s (count %d)", -+ fullName().ascii(), _deps.count()); -+#endif -+ -+ clear(); -+ TraceJumpCost* item; -+ for (item = _deps.first(); item; item = _deps.next()) { -+ if (onlyActiveParts()) -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ } -+ -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceCallListCost -+ -+TraceCallListCost::TraceCallListCost() -+{ -+ _lastDep = 0; -+} -+ -+TraceCallListCost::~TraceCallListCost() -+{} -+ -+void TraceCallListCost::addDep(TraceCallCost* dep) -+{ -+#if TRACE_ASSERTIONS -+ if (_deps.findRef(dep)>=0) { -+ qDebug("addDep: %s already in list!", -+ dep->fullName().ascii()); -+ return; -+ } -+#endif -+ -+ _deps.append(dep); -+ _lastDep = dep; -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), dep->fullName().ascii(), -+ _deps.count()); -+#endif -+} -+ -+TraceCallCost* TraceCallListCost::findDepFromPart(TracePart* part) -+{ -+ if (_lastDep && _lastDep->part() == part) -+ return _lastDep; -+ -+ TraceCallCost* dep; -+ for (dep = _deps.first(); dep; dep = _deps.next()) -+ if (dep->part() == part) { -+ _lastDep = dep; -+ return dep; -+ } -+ return 0; -+} -+ -+ -+void TraceCallListCost::update() -+{ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("update %s (count %d)", -+ fullName().ascii(), _deps.count()); -+#endif -+ -+ /* Without dependent cost items, assume fixed costs, -+ * i.e. don't change cost */ -+ if (_deps.count()>0) { -+ clear(); -+ TraceCallCost* item; -+ for (item = _deps.first(); item; item = _deps.next()) { -+ if (onlyActiveParts()) -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ addCallCount(item->callCount()); -+ } -+ } -+ -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+} -+ -+ -+//--------------------------------------------------- -+// TraceInclusiveListCost -+ -+TraceInclusiveListCost::TraceInclusiveListCost() -+{ -+ _lastDep = 0; -+} -+ -+TraceInclusiveListCost::~TraceInclusiveListCost() -+{} -+ -+ -+void TraceInclusiveListCost::addDep(TraceInclusiveCost* dep) -+{ -+#if TRACE_ASSERTIONS -+ if (_deps.findRef(dep)>=0) { -+ qDebug("addDep: %s already in list!", -+ dep->fullName().ascii()); -+ return; -+ } -+#endif -+ -+ _deps.append(dep); -+ _lastDep = dep; -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), dep->fullName().ascii(), -+ _deps.count()); -+#endif -+} -+ -+TraceInclusiveCost* TraceInclusiveListCost::findDepFromPart(TracePart* part) -+{ -+ if (_lastDep && _lastDep->part() == part) -+ return _lastDep; -+ -+ TraceInclusiveCost* dep; -+ for (dep = _deps.first(); dep; dep = _deps.next()) -+ if (dep->part() == part) { -+ _lastDep = dep; -+ return dep; -+ } -+ return 0; -+} -+ -+void TraceInclusiveListCost::update() -+{ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("update %s (count %d)", -+ fullName().ascii(), _deps.count()); -+#endif -+ -+ clear(); -+ TraceInclusiveCost* item; -+ for (item = _deps.first(); item; item = _deps.next()) { -+ if (onlyActiveParts()) -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ addInclusive(item->inclusive()); -+ } -+ -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+} -+ -+ -+ -+//--------------------------------------------------- -+// TracePartInstrJump -+ -+TracePartInstrJump::TracePartInstrJump(TraceInstrJump* instrJump, -+ TracePartInstrJump* next) -+{ -+ _dep = instrJump; -+ _next = next; -+} -+ -+TracePartInstrJump::~TracePartInstrJump() -+{} -+ -+ -+//--------------------------------------------------- -+// TracePartInstrCall -+ -+TracePartInstrCall::TracePartInstrCall(TraceInstrCall* instrCall) -+{ -+ _dep = instrCall; -+} -+ -+TracePartInstrCall::~TracePartInstrCall() -+{} -+ -+ -+ -+//--------------------------------------------------- -+// TracePartInstr -+ -+TracePartInstr::TracePartInstr(TraceInstr* instr) -+{ -+ _dep = instr; -+} -+ -+TracePartInstr::~TracePartInstr() -+{} -+ -+ -+ -+//--------------------------------------------------- -+// TracePartLineJump -+ -+TracePartLineJump::TracePartLineJump(TraceLineJump* lineJump) -+{ -+ _dep = lineJump; -+} -+ -+TracePartLineJump::~TracePartLineJump() -+{} -+ -+ -+//--------------------------------------------------- -+// TracePartLineCall -+ -+TracePartLineCall::TracePartLineCall(TraceLineCall* lineCall) -+{ -+ _dep = lineCall; -+} -+ -+TracePartLineCall::~TracePartLineCall() -+{} -+ -+ -+//--------------------------------------------------- -+// TracePartLine -+ -+TracePartLine::TracePartLine(TraceLine* line) -+{ -+ _dep = line; -+} -+ -+TracePartLine::~TracePartLine() -+{} -+ -+ -+ -+ -+//--------------------------------------------------- -+// TracePartCall -+ -+TracePartCall::TracePartCall(TraceCall* call) -+{ -+ _dep = call; -+ -+ _firstFixCallCost = 0; -+} -+ -+TracePartCall::~TracePartCall() -+{} -+ -+bool TracePartCall::isRecursion() -+{ -+ return call()->isRecursion(); -+} -+ -+void TracePartCall::update() -+{ -+#if !USE_FIXCOST -+ TraceCallListCost::update(); -+#else -+ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("update %s", fullName().ascii()); -+#endif -+ -+ /* Without dependent cost items, assume fixed costs, -+ * i.e. don't change cost */ -+ if (_firstFixCallCost) { -+ clear(); -+ FixCallCost* item; -+ for (item = _firstFixCallCost; item; item = item->nextCostOfPartCall()) -+ item->addTo(this); -+ } -+ -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+ -+#endif // USE_FIXCOST -+} -+ -+ -+//--------------------------------------------------- -+// TracePartFunction -+ -+TracePartFunction::TracePartFunction(TraceFunction* function, -+ TracePartObject* partObject, -+ TracePartFile *partFile) -+{ -+ _dep = function; -+ _partObject = partObject; -+ _partFile = partFile; -+ _partClass = 0; -+ -+ _calledCount = 0; -+ _callingCount = 0; -+ _calledContexts = 0; -+ _callingContexts = 0; -+ -+ _firstFixCost = 0; -+ _firstFixJump = 0; -+} -+ -+TracePartFunction::~TracePartFunction() -+{} -+ -+TQString TracePartFunction::prettyCalledCount() -+{ -+ return _calledCount.pretty(); -+} -+ -+TQString TracePartFunction::prettyCallingCount() -+{ -+ return _callingCount.pretty(); -+} -+ -+TQString TracePartFunction::costString(TraceCostMapping* m) -+{ -+ update(); -+ -+ TQString res = TraceInclusiveCost::costString(m); -+ res += TQString(", called from %1: %2") -+ .arg(_calledContexts).arg(prettyCalledCount()); -+ res += TQString(", calling from %1: %2") -+ .arg(_callingContexts).arg(prettyCallingCount()); -+ -+ return res; -+} -+ -+ -+void TracePartFunction::addPartInstr(TracePartInstr* ref) -+{ -+#if TRACE_ASSERTIONS -+ if (_partInstr.findRef(ref)>=0) { -+ qDebug("TracePartFunction::addPartInstr: %s already in list!", -+ ref->name().ascii()); -+ return; -+ } -+#endif -+ -+ _partInstr.append(ref); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), ref->fullName().ascii(), -+ _partInstr.count()); -+#endif -+} -+ -+ -+void TracePartFunction::addPartLine(TracePartLine* ref) -+{ -+#if TRACE_ASSERTIONS -+ if (_partLines.findRef(ref)>=0) { -+ qDebug("TracePartFunction::addPartLine: %s already in list!", -+ ref->name().ascii()); -+ return; -+ } -+#endif -+ -+ _partLines.append(ref); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), ref->fullName().ascii(), -+ _partLines.count()); -+#endif -+} -+ -+ -+void TracePartFunction::addPartCaller(TracePartCall* ref) -+{ -+#if TRACE_ASSERTIONS -+ if (_partCallers.findRef(ref)>=0) { -+ qDebug("TracePartFunction::addPartCaller: %s already in list!", -+ ref->name().ascii()); -+ return; -+ } -+#endif -+ -+ _partCallers.append(ref); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added Caller\n %s (now %d)", -+ fullName().ascii(), ref->fullName().ascii(), -+ _partCallers.count()); -+#endif -+} -+ -+ -+void TracePartFunction::addPartCalling(TracePartCall* ref) -+{ -+#if TRACE_ASSERTIONS -+ if (_partCallings.findRef(ref)>=0) { -+ qDebug("TracePartFunction::addPartCalling: %s already in list!", -+ ref->name().ascii()); -+ return; -+ } -+#endif -+ -+ _partCallings.append(ref); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added Calling\n %s (now %d)", -+ fullName().ascii(), ref->fullName().ascii(), -+ _partCallings.count()); -+#endif -+} -+ -+SubCost TracePartFunction::calledCount() -+{ -+ if (_dirty) update(); -+ -+ return _calledCount; -+} -+ -+int TracePartFunction::calledContexts() -+{ -+ if (_dirty) update(); -+ -+ return _calledContexts; -+} -+ -+SubCost TracePartFunction::callingCount() -+{ -+ if (_dirty) update(); -+ -+ return _callingCount; -+} -+ -+ -+int TracePartFunction::callingContexts() -+{ -+ if (_dirty) update(); -+ -+ return _callingContexts; -+} -+ -+ -+void TracePartFunction::update() -+{ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("TracePartFunction::update %s (Callers %d, Callings %d, lines %d)", -+ name().ascii(), _partCallers.count(), _partCallings.count(), -+ _partLines.count()); -+#endif -+ -+ _calledCount = 0; -+ _callingCount = 0; -+ _calledContexts = 0; -+ _callingContexts = 0; -+ -+ // calculate additional cost metrics -+ TracePartCall *caller, *calling; -+ for (caller=_partCallers.first();caller;caller=_partCallers.next()) { -+ -+ // FIXME -+ if (caller->subCost(0)>0) -+ _calledContexts++; -+ -+ SubCost c = caller->callCount(); -+ if (c>0) { -+ _calledCount += c; -+ } -+ } -+ for (calling=_partCallings.first();calling;calling=_partCallings.next()) { -+ // FIXME -+ if (calling->subCost(0)>0) -+ _callingContexts++; -+ -+ SubCost c = calling->callCount(); -+ if (c>0) { -+ _callingCount += c; -+ } -+ } -+ -+ // self cost -+#if !USE_FIXCOST -+ if (_partLines.count()>0) { -+ TraceCost::clear(); -+ -+ TracePartLine* line; -+ for (line = _partLines.first(); line; line = _partLines.next()) -+ addCost(line); -+ } -+#else -+ if (_firstFixCost) { -+ TraceCost::clear(); -+ -+ FixCost* item; -+ for (item = _firstFixCost; item; item = item->nextCostOfPartFunction()) -+ item->addTo(this); -+ } -+#endif -+ -+ -+ /* There are two possibilities to calculate inclusive cost: -+ * 1) sum of call costs to this function -+ * 2) sum of call costs from this function + self cost -+ * -+ * 1) is wrong if a function was called spontaneous, but also by a call. -+ * This eventually can happen with thread/process startup functions, -+ * and signal handlers. -+ * -+ * 2) is wrong with "skipped PLT" and the calltree skin, because -+ * cost of PLT is attributed to called function (?) -+ * -+ * For now, do 1) if there are callers, otherwise 2). -+ * Should this be fixed to take the maximum of 1) and 2) ? -+ */ -+ _inclusive.clear(); -+ if (_calledCount>0) { -+ // inclusive cost: if possible, use caller sums -+ for (caller=_partCallers.first();caller;caller=_partCallers.next()) { -+ // detect simple recursion (no cycle) -+ if (caller->isRecursion()) continue; -+ -+ addInclusive(caller); -+ } -+ } -+ else { -+ // without caller info, use calling sum + line costs -+ for (calling=_partCallings.first();calling;calling=_partCallings.next()) { -+ // detect simple recursion (no cycle) -+ if (calling->isRecursion()) continue; -+ -+ addInclusive(calling); -+ } -+ _dirty = false; // don't recurse! -+ addInclusive(this); -+ } -+ -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+} -+ -+ -+ -+//--------------------------------------------------- -+// TracePartClass -+ -+TracePartClass::TracePartClass(TraceClass* cls) -+{ -+ _dep = cls; -+} -+ -+TracePartClass::~TracePartClass() -+{} -+ -+TQString TracePartClass::prettyName() const -+{ -+ return TQString("%1 from %2") -+ .arg( _dep->name().isEmpty() ? TQString("(global)") : _dep->name()) -+ .arg(part()->name()); -+} -+ -+//--------------------------------------------------- -+// TracePartFile -+ -+TracePartFile::TracePartFile(TraceFile* file) -+{ -+ _dep = file; -+} -+ -+TracePartFile::~TracePartFile() -+{} -+ -+ -+//--------------------------------------------------- -+// TracePartObject -+ -+TracePartObject::TracePartObject(TraceObject* object) -+{ -+ _dep = object; -+} -+ -+TracePartObject::~TracePartObject() -+{} -+ -+ -+ -+ -+//--------------------------------------------------- -+// TraceInstrJump -+ -+TraceInstrJump::TraceInstrJump(TraceInstr* instrFrom, TraceInstr* instrTo, -+ bool isCondJump) -+{ -+ _first = 0; -+ -+ _instrFrom = instrFrom; -+ _instrTo = instrTo; -+ _isCondJump = isCondJump; -+} -+ -+TraceInstrJump::~TraceInstrJump() -+{ -+ // we are the owner of the TracePartInstrJump's generated in our factory -+ TracePartInstrJump* item = _first, *next; -+ while(item) { -+ next = item->next(); -+ delete item; -+ item = next; -+ } -+} -+ -+TracePartInstrJump* TraceInstrJump::partInstrJump(TracePart* part) -+{ -+ static TracePartInstrJump* item = 0; -+ -+ // shortcut -+ if (item && (item->instrJump()==this) && (item->part() == part)) return item; -+ -+ for(item = _first; item; item = item->next()) -+ if (item->part() == part) break; -+ -+ if (!item) { -+ item = new TracePartInstrJump(this, _first); -+ item->setPosition(part); -+ _first = item; -+ } -+ return item; -+} -+ -+void TraceInstrJump::update() -+{ -+ if (!_dirty) return; -+ -+ clear(); -+ TracePartInstrJump* item; -+ for (item = _first; item; item = item->next()) { -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ } -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug("updated %s", fullName().ascii()); -+#endif -+ -+#if TRACE_DEBUG -+ qDebug(" > %s", costString(0).ascii()); -+#endif -+} -+ -+TQString TraceInstrJump::name() const -+{ -+ return TQString("jump at 0x%1 to 0x%2") -+ .arg(_instrFrom->addr().toString()) -+ .arg(_instrTo->addr().toString()); -+} -+ -+ -+//--------------------------------------------------- -+// TraceInstrJumpList -+ -+ -+int TraceInstrJumpList::compareItems ( Item item1, Item item2 ) -+{ -+ TraceInstrJump* ij1 = (TraceInstrJump*) item1; -+ TraceInstrJump* ij2 = (TraceInstrJump*) item2; -+ -+ Addr addr1Low = ij1->instrFrom()->addr(); -+ Addr addr2Low = ij2->instrFrom()->addr(); -+ Addr addr1High = ij1->instrTo()->addr(); -+ Addr addr2High = ij2->instrTo()->addr(); -+ Addr t; -+ -+ if (addr1Low > addr1High) { -+ t = addr1Low; -+ addr1Low = addr1High; -+ addr1High = t; -+ } -+ -+ if (addr2Low > addr2High) { -+ t = addr2Low; -+ addr2Low = addr2High; -+ addr2High = t; -+ } -+ -+ if (_sortLow) { -+ // we sort according to smallest instruction address -+ if (addr1Low != addr2Low) return (addr1Low > addr2Low) ? 1:-1; -+ // jump ends come before jump starts -+ if (addr1Low == ij1->instrTo()->addr()) return -1; -+ if (addr2Low == ij2->instrTo()->addr()) return 1; -+ return (addr1High > addr2High) ? 1:-1; -+ } -+ -+ // we sort according to highest instruction address -+ if (addr1High != addr2High) return (addr1High > addr2High) ? 1:-1; -+ // jump ends come before jump starts -+ if (addr1High == ij1->instrTo()->addr()) return -1; -+ if (addr2High == ij2->instrTo()->addr()) return 1; -+ return (addr1Low > addr2Low) ? 1:-1; -+} -+ -+ -+//--------------------------------------------------- -+// TraceLineJump -+ -+TraceLineJump::TraceLineJump(TraceLine* lineFrom, TraceLine* lineTo, -+ bool isCondJump) -+{ -+ // we are the owner of TracePartLineJump's generated in our factory -+ _deps.setAutoDelete(true); -+ -+ _lineFrom = lineFrom; -+ _lineTo = lineTo; -+ _isCondJump = isCondJump; -+} -+ -+TraceLineJump::~TraceLineJump() -+{} -+ -+ -+TracePartLineJump* TraceLineJump::partLineJump(TracePart* part) -+{ -+ TracePartLineJump* item = (TracePartLineJump*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartLineJump(this); -+ item->setPosition(part); -+ addDep(item); -+ } -+ return item; -+} -+ -+ -+TQString TraceLineJump::name() const -+{ -+ return TQString("jump at %1 to %2") -+ .arg(_lineFrom->prettyName()) -+ .arg(_lineTo->prettyName()); -+} -+ -+ -+//--------------------------------------------------- -+// TraceLineJumpList -+ -+ -+int TraceLineJumpList::compareItems ( Item item1, Item item2 ) -+{ -+ TraceLineJump* lj1 = (TraceLineJump*) item1; -+ TraceLineJump* lj2 = (TraceLineJump*) item2; -+ -+ uint line1Low = lj1->lineFrom()->lineno(); -+ uint line2Low = lj2->lineFrom()->lineno(); -+ uint line1High = lj1->lineTo()->lineno(); -+ uint line2High = lj2->lineTo()->lineno(); -+ uint t; -+ -+ if (line1Low > line1High) { -+ t = line1Low; line1Low = line1High; line1High = t; -+ } -+ if (line2Low > line2High) { -+ t = line2Low; line2Low = line2High; line2High = t; -+ } -+ -+ if (_sortLow) { -+ // we sort according to smallest line number -+ if (line1Low != line2Low) return line1Low - line2Low; -+ // jump ends come before jump starts -+ if (line1Low == lj1->lineTo()->lineno()) return -1; -+ if (line2Low == lj2->lineTo()->lineno()) return 1; -+ return line1High - line2High; -+ } -+ -+ // we sort according to highest line number -+ if (line1High != line2High) return line1High - line2High; -+ // jump ends come before jump starts -+ if (line1High == lj1->lineTo()->lineno()) return -1; -+ if (line2High == lj2->lineTo()->lineno()) return 1; -+ return line1Low - line2Low; -+} -+ -+ -+//--------------------------------------------------- -+// TraceInstrCall -+ -+TraceInstrCall::TraceInstrCall(TraceCall* call, TraceInstr* instr) -+{ -+ // we are the owner of TracePartInstrCall's generated in our factory -+ _deps.setAutoDelete(true); -+ -+ _call = call; -+ _instr = instr; -+} -+ -+TraceInstrCall::~TraceInstrCall() -+{} -+ -+ -+TracePartInstrCall* TraceInstrCall::partInstrCall(TracePart* part, -+ TracePartCall*) -+{ -+ TracePartInstrCall* item = (TracePartInstrCall*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartInstrCall(this); -+ item->setPosition(part); -+ addDep(item); -+ // instruction calls are not registered in function calls -+ // as together with line calls calls are duplicated -+ //partCall->addDep(item); -+ } -+ return item; -+} -+ -+ -+TQString TraceInstrCall::name() const -+{ -+ return TQString("%1 at %2").arg(_call->name()).arg(_instr->name()); -+} -+ -+ -+//--------------------------------------------------- -+// TraceLineCall -+ -+TraceLineCall::TraceLineCall(TraceCall* call, TraceLine* line) -+{ -+ // we are the owner of TracePartLineCall's generated in our factory -+ _deps.setAutoDelete(true); -+ -+ _call = call; -+ _line = line; -+} -+ -+TraceLineCall::~TraceLineCall() -+{} -+ -+ -+TracePartLineCall* TraceLineCall::partLineCall(TracePart* part, -+ TracePartCall* partCall) -+{ -+ TracePartLineCall* item = (TracePartLineCall*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartLineCall(this); -+ item->setPosition(part); -+ addDep(item); -+ partCall->addDep(item); -+ } -+ return item; -+} -+ -+ -+TQString TraceLineCall::name() const -+{ -+ return TQString("%1 at %2").arg(_call->name()).arg(_line->name()); -+} -+ -+ -+//--------------------------------------------------- -+// TraceCall -+ -+TraceCall::TraceCall(TraceFunction* caller, TraceFunction* called) -+{ -+ // we are the owner of all items generated in our factory -+ _deps.setAutoDelete(true); -+ _lineCalls.setAutoDelete(true); -+ -+ _caller = caller; -+ _called = called; -+} -+ -+ -+TraceCall::~TraceCall() -+{} -+ -+TracePartCall* TraceCall::partCall(TracePart* part, -+ TracePartFunction* partCaller, -+ TracePartFunction* partCalling) -+{ -+ TracePartCall* item = (TracePartCall*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartCall(this); -+ item->setPosition(part); -+ addDep(item); -+ partCaller->addPartCalling(item); -+ partCalling->addPartCaller(item); -+ } -+ return item; -+} -+ -+TraceInstrCall* TraceCall::instrCall(TraceInstr* i) -+{ -+ TraceInstrCall* icall; -+ for (icall=_instrCalls.first();icall;icall=_instrCalls.next()) -+ if (icall->instr() == i) -+ break; -+ -+ if (!icall) { -+ icall = new TraceInstrCall(this, i); -+ -+ _instrCalls.append(icall); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceCall::instrCall]", icall->fullName().ascii()); -+#endif -+ i->addInstrCall(icall); -+ } -+ return icall; -+} -+ -+ -+TraceLineCall* TraceCall::lineCall(TraceLine* l) -+{ -+ TraceLineCall* lcall; -+ for (lcall=_lineCalls.first();lcall;lcall=_lineCalls.next()) -+ if (lcall->line() == l) -+ break; -+ -+ if (!lcall) { -+ lcall = new TraceLineCall(this, l); -+ -+ _lineCalls.append(lcall); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceCall::lineCall]", lcall->fullName().ascii()); -+#endif -+ l->addLineCall(lcall); -+ } -+ return lcall; -+} -+ -+ -+void TraceCall::invalidateDynamicCost() -+{ -+ TraceLineCall* lc; -+ for (lc=_lineCalls.first();lc;lc=_lineCalls.next()) -+ lc->invalidate(); -+ -+ TraceInstrCall* ic; -+ for (ic=_instrCalls.first();ic;ic=_instrCalls.next()) -+ ic->invalidate(); -+ -+ invalidate(); -+} -+ -+ -+TQString TraceCall::name() const -+{ -+ return TQString("%1 => %2") -+ .arg(_caller->name()) -+ .arg(_called->name()); -+} -+ -+int TraceCall::inCycle() -+{ -+ if (!_caller || !_called) return 0; -+ if (!_caller->cycle()) return 0; -+ if (_caller == _caller->cycle()) return 0; -+ if (_caller->cycle() != _called->cycle()) return 0; -+ -+ return _caller->cycle()->cycleNo(); -+} -+ -+void TraceCall::update() -+{ -+ if (!_dirty) return; -+ -+ // special handling for cycles -+ if (_caller && _caller->cycle() && _caller==_caller->cycle()) { -+ -+ // we have no part calls: use inclusive cost of called function -+ clear(); -+ if (_called) -+ addCost(_called->inclusive()); -+ _dirty = false; -+ return; -+ } -+ -+ TraceCallListCost::update(); -+} -+ -+TraceFunction* TraceCall::caller(bool /*skipCycle*/) const -+{ -+ return _caller; -+} -+ -+TraceFunction* TraceCall::called(bool skipCycle) const -+{ -+ if (!skipCycle && _called) { -+ // if this is a call to a cycle member from outside of the cycle, -+ // fake it to be a call to the whole cycle -+ if (_called->cycle() && _caller && -+ (_caller->cycle() != _called->cycle())) -+ return _called->cycle(); -+ } -+ -+ return _called; -+} -+ -+TQString TraceCall::callerName(bool skipCycle) const -+{ -+ if (!_caller) return i18n("(no caller)"); -+ -+ if (!skipCycle) { -+ // if this call goes into a cycle, add the entry function -+ TraceFunctionCycle* c = _called->cycle(); -+ if (c && _caller && (_caller->cycle() != c)) { -+ TQString via = _called->prettyName(); -+ return i18n("%1 via %2").arg(_caller->prettyName()).arg(via); -+ } -+ } -+ -+ return _caller->prettyName(); -+} -+ -+TQString TraceCall::calledName(bool skipCycle) const -+{ -+ if (!_called) return i18n("(no callee)"); -+ -+ if (!skipCycle) { -+ // if this call goes into a cycle, add the entry function -+ TraceFunctionCycle* c = _called->cycle(); -+ if (c && _caller && (_caller->cycle() != c)) { -+ // HACK to get rid of cycle postfix... -+ _called->setCycle(0); -+ TQString via = _called->prettyName(); -+ _called->setCycle(c); -+ return i18n("%1 via %2").arg(c->name()).arg(via); -+ } -+ } -+ return _called->prettyName(); -+} -+ -+ -+//--------------------------------------------------- -+// TraceInstr -+ -+TraceInstr::TraceInstr() -+{ -+ // we are the owner of TracePartInstr's generated in our factory -+ _deps.setAutoDelete(true); -+ _instrJumps.setAutoDelete(true); -+ -+ _addr = 0; -+ _line = 0; -+ _function = 0; -+} -+ -+TraceInstr::~TraceInstr() -+{} -+ -+bool TraceInstr::hasCost(TraceCostType* ct) -+{ -+ bool res = subCost(ct) > 0; -+ if (!res) { -+ TraceInstrCall* ic; -+ for(ic=_instrCalls.first();ic;ic=_instrCalls.next()) -+ if (ic->subCost(ct) > 0) break; -+ res = (ic != 0); -+ if (!res) { -+ TraceInstrJump* ij; -+ for(ij=_instrJumps.first();ij;ij=_instrJumps.next()) -+ if (ij->executedCount() > 0) break; -+ res = (ij != 0); -+ } -+ } -+ -+ return res; -+} -+ -+TracePartInstr* TraceInstr::partInstr(TracePart* part, -+ TracePartFunction* partFunction) -+{ -+ TracePartInstr* item = (TracePartInstr*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartInstr(this); -+ item->setPosition(part); -+ addDep(item); -+ //part->addDep(item); -+ partFunction->addPartInstr(item); -+ } -+ return item; -+} -+ -+TraceInstrJump* TraceInstr::instrJump(TraceInstr* to, bool isJmpCond) -+{ -+ TraceInstrJump* jump; -+ for (jump=_instrJumps.first();jump;jump=_instrJumps.next()) -+ if (jump->instrTo() == to) -+ break; -+ -+ if (!jump) { -+ jump = new TraceInstrJump(this, to, isJmpCond); -+ -+ _instrJumps.append(jump); -+ } -+ return jump; -+} -+ -+ -+ -+void TraceInstr::addInstrCall(TraceInstrCall* instrCall) -+{ -+#if TRACE_ASSERTIONS -+ if (_instrCalls.findRef(instrCall)>=0) return; -+ -+ if (instrCall->instr() != this) { -+ qDebug("Can't add instruction call to another instruction!"); -+ return; -+ } -+#endif -+ -+ _instrCalls.append(instrCall); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), -+ instrCall->fullName().ascii(), _instrCalls.count()); -+#endif -+} -+ -+ -+TQString TraceInstr::name() const -+{ -+ return TQString("0x%1").arg(_addr.toString()); -+} -+ -+TQString TraceInstr::prettyName() const -+{ -+ return TQString("0x%1").arg(_addr.toString()); -+} -+ -+ -+//--------------------------------------------------- -+// TraceLine -+ -+TraceLine::TraceLine() -+{ -+ // we are the owner of TracePartLine's generated in our factory -+ _deps.setAutoDelete(true); -+ _lineJumps.setAutoDelete(true); -+ -+ _lineno = 0; -+ _sourceFile = 0; -+} -+ -+TraceLine::~TraceLine() -+{} -+ -+bool TraceLine::hasCost(TraceCostType* ct) -+{ -+ bool res = subCost(ct) > 0; -+ if (!res) { -+ TraceLineCall* lc; -+ for(lc=_lineCalls.first();lc;lc=_lineCalls.next()) -+ if (lc->subCost(ct) > 0) break; -+ res = (lc != 0); -+ if (!res) { -+ TraceLineJump* lj; -+ for(lj=_lineJumps.first();lj;lj=_lineJumps.next()) -+ if (lj->executedCount() > 0) break; -+ res = (lj != 0); -+ } -+ } -+ -+ return res; -+} -+ -+TracePartLine* TraceLine::partLine(TracePart* part, -+ TracePartFunction* partFunction) -+{ -+ TracePartLine* item = (TracePartLine*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartLine(this); -+ item->setPosition(part); -+ addDep(item); -+#if !USE_FIXCOST -+ part->addDep(item); -+#endif -+ partFunction->addPartLine(item); -+ } -+ return item; -+} -+ -+TraceLineJump* TraceLine::lineJump(TraceLine* to, bool isJmpCond) -+{ -+ TraceLineJump* jump; -+ for (jump=_lineJumps.first();jump;jump=_lineJumps.next()) -+ if (jump->lineTo() == to) -+ break; -+ -+ if (!jump) { -+ jump = new TraceLineJump(this, to, isJmpCond); -+ -+ _lineJumps.append(jump); -+ } -+ return jump; -+} -+ -+ -+void TraceLine::addLineCall(TraceLineCall* lineCall) -+{ -+#if TRACE_ASSERTIONS -+ if (_lineCalls.findRef(lineCall)>=0) return; -+ -+ if (lineCall->line() != this) { -+ qDebug("Can't add line call to another line!"); -+ return; -+ } -+#endif -+ -+ TraceFunction* caller = lineCall->call()->caller(); -+ TraceFunction* function = _sourceFile->function(); -+ if (caller != function) { -+ // We regard 2 functions as the same if they have -+ // same class, name, object -+ if ((caller->cls() != function->cls()) || -+ (caller->name() != function->name()) || -+ (caller->object() != function->object())) { -+ -+ qDebug("ERROR: Adding line call, line %d\n of %s to\n %s ?!", -+ lineCall->line()->lineno(), -+ caller->info().ascii(), function->info().ascii()); -+ } -+ } -+ -+ _lineCalls.append(lineCall); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), -+ lineCall->fullName().ascii(), _lineCalls.count()); -+#endif -+} -+ -+ -+TQString TraceLine::name() const -+{ -+ TQString fileShortName = _sourceFile->file()->shortName(); -+ if (fileShortName.isEmpty()) -+ return i18n("(unknown)"); -+ -+ return TQString("%1:%2") -+ .arg(fileShortName).arg(_lineno); -+} -+ -+TQString TraceLine::prettyName() const -+{ -+ return TQString("%1 [%2]") -+ .arg(name()).arg(_sourceFile->function()->prettyName()); -+} -+ -+//--------------------------------------------------- -+// TraceCostItem -+ -+TraceCostItem::TraceCostItem() -+{ -+} -+ -+TraceCostItem::~TraceCostItem() -+{} -+ -+ -+//--------------------------------------------------- -+// TraceFunctionSource -+ -+TraceFunctionSource::TraceFunctionSource(TraceFunction* function, -+ TraceFile* file) -+{ -+ _file = file; -+ _function = function; -+ -+ // the function is dependent from our cost sum -+ _dep = _function; -+ -+ _lineMap = 0; -+ _lineMapFilled = false; -+ _line0 = 0; -+} -+ -+TraceFunctionSource::~TraceFunctionSource() -+{ -+ if (_lineMap) delete _lineMap; -+ if (_line0) delete _line0; -+} -+ -+TQString TraceFunctionSource::name() const -+{ -+ return TQString("%1 for %2").arg(_file->name()).arg(_function->name()); -+} -+ -+uint TraceFunctionSource::firstLineno() -+{ -+ // lazy generate the map if not done up to now -+ TraceLineMap* map = lineMap(); -+ // ignore line 0 here -+ if (!map || map->count() == 0) return 0; -+ TraceLineMap::Iterator it = map->begin(); -+ return (*it).lineno(); -+} -+ -+uint TraceFunctionSource::lastLineno() -+{ -+ // lazy generate the map if not done up to now -+ TraceLineMap* map = lineMap(); -+ // ignore line 0 here -+ if (!map || map->count() == 0) return 0; -+ TraceLineMap::Iterator it = map->end(); -+ --it; -+ return (*it).lineno(); -+} -+ -+/* factory */ -+TraceLine* TraceFunctionSource::line(uint lineno, bool createNew) -+{ -+ if (lineno == 0) { -+ if (!_line0) { -+ if (!createNew) return 0; -+ _line0 = new TraceLine; -+ _line0->setSourceFile(this); -+ _line0->setLineno(0); -+ } -+ return _line0; -+ } -+ -+ if (!createNew) { -+ if (!_lineMap) return 0; -+ TraceLineMap::Iterator it = _lineMap->find(lineno); -+ if (it == _lineMap->end()) return 0; -+ return &(it.data()); -+ } -+ -+ if (!_lineMap) _lineMap = new TraceLineMap; -+ -+ TraceLine& l = (*_lineMap)[lineno]; -+ if (!l.isValid()) { -+ l.setSourceFile(this); -+ l.setLineno(lineno); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceFunctionSource::line]", -+ l.fullName().ascii()); -+#endif -+ } -+ return &l; -+} -+ -+void TraceFunctionSource::update() -+{ -+ if (!_dirty) return; -+ -+ clear(); -+ -+ // no need to create lineMap if not already created -+ if (_lineMap) { -+ TraceLineMap::Iterator lit; -+ for ( lit = _lineMap->begin(); -+ lit != _lineMap->end(); ++lit ) -+ addCost( &(*lit) ); -+ } -+ -+ _dirty = false; -+} -+ -+void TraceFunctionSource::invalidateDynamicCost() -+{ -+ // no need to create lineMap if not already created -+ if (_lineMap) { -+ TraceLineMap::Iterator lit; -+ for ( lit = _lineMap->begin(); -+ lit != _lineMap->end(); ++lit ) -+ (*lit).invalidate(); -+ } -+ -+ invalidate(); -+} -+ -+TraceLineMap* TraceFunctionSource::lineMap() -+{ -+#if USE_FIXCOST -+ -+ if (_lineMapFilled) return _lineMap; -+ _lineMapFilled = true; -+ if (!_lineMap) -+ _lineMap = new TraceLineMap; -+ -+ TraceLine* l = 0; -+ TracePartLine* pl = 0; -+ TraceLineCall* lc = 0; -+ TracePartLineCall* plc = 0; -+ -+ /* go over all part objects for this function, and -+ * - build TraceLines (the line map) using FixCost objects -+ * - build TraceJumpLines using FixJump objects -+ */ -+ TraceInclusiveCostList pfList = _function->deps(); -+ TracePartFunction* pf = (TracePartFunction*) pfList.first(); -+ for(; pf; pf = (TracePartFunction*) pfList.next()) { -+ -+ if (0) qDebug("PartFunction %s:%d", -+ pf->function()->name().ascii(), pf->part()->partNumber()); -+ -+ FixCost* fc = pf->firstFixCost(); -+ for(; fc; fc = fc->nextCostOfPartFunction()) { -+ if (fc->line() == 0) continue; -+ if (fc->functionSource() != this) continue; -+ -+ if (!l || l->lineno() != fc->line()) { -+ l = &(*_lineMap)[fc->line()]; -+ if (!l->isValid()) { -+ l->setSourceFile(this); -+ l->setLineno(fc->line()); -+ } -+ pl = 0; -+ } -+ if (!pl || pl->part() != fc->part()) -+ pl = l->partLine(fc->part(), pf); -+ fc->addTo(pl); -+ } -+ -+ TraceLine* to = 0; -+ TraceLineJump* lj; -+ TracePartLineJump* plj; -+ FixJump* fj = pf->firstFixJump(); -+ for(; fj; fj = fj->nextJumpOfPartFunction()) { -+ if (fj->line() == 0) continue; -+ if (fj->source() != this) continue; -+ if (!fj->targetSource()) { -+ // be robust against buggy loaders -+ continue; -+ } -+ -+ // don't display jumps to same or following line -+ if ((fj->line() == fj->targetLine()) || -+ (fj->line()+1 == fj->targetLine())) continue; -+ -+ if (!l || l->lineno() != fj->line()) { -+ l = &(*_lineMap)[fj->line()]; -+ if (!l->isValid()) { -+ l->setSourceFile(this); -+ l->setLineno(fj->line()); -+ } -+ } -+ -+ to = fj->targetSource()->line(fj->targetLine(), true); -+ -+ lj = l->lineJump(to, fj->isCondJump()); -+ plj = lj->partLineJump(fj->part()); -+ -+ fj->addTo(plj); -+ } -+ -+ -+ TracePartCallList pcList = pf->partCallings(); -+ TracePartCall* pc = pcList.first(); -+ for(; pc; pc = pcList.next()) { -+ -+ if (0) qDebug("PartCall %s:%d", -+ pc->call()->name().ascii(), -+ pf->part()->partNumber()); -+ -+ FixCallCost* fcc = pc->firstFixCallCost(); -+ for(; fcc; fcc = fcc->nextCostOfPartCall()) { -+ if (fcc->line() == 0) continue; -+ if (fcc->functionSource() != this) continue; -+ -+ if (!l || l->lineno() != fcc->line()) { -+ l = &(*_lineMap)[fcc->line()]; -+ if (!l->isValid()) { -+ l->setSourceFile(this); -+ l->setLineno(fcc->line()); -+ } -+ } -+ if (!lc || lc->call() != pc->call() || lc->line() != l) { -+ lc = pc->call()->lineCall(l); -+ plc = 0; -+ } -+ if (!plc || plc->part() != fcc->part()) -+ plc = lc->partLineCall(fcc->part(), pc); -+ -+ fcc->addTo(plc); -+ if (0) qDebug("Add FixCallCost %s:%d/0x%s, CallCount %s", -+ fcc->functionSource()->file()->shortName().ascii(), -+ fcc->line(), fcc->addr().toString().ascii(), -+ fcc->callCount().pretty().ascii()); -+ } -+ } -+ } -+ -+#endif -+ -+ return _lineMap; -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceAssoziation -+ -+TraceAssoziation::TraceAssoziation() -+{ -+ _function = 0; -+ _valid = false; -+} -+ -+TraceAssoziation::~TraceAssoziation() -+{ -+ // don't delete from TraceFunction -+ if (_function) _function->removeAssoziation(this); -+} -+ -+bool TraceAssoziation::isAssoziated() -+{ -+ if (!_function) return false; -+ -+ return _function->assoziation(rtti())==this; -+} -+ -+bool TraceAssoziation::setFunction(TraceFunction* f) -+{ -+ if (_function == f) -+ return isAssoziated(); -+ -+ if (_function) { -+ // don't delete ourself -+ _function->removeAssoziation(this); -+ } -+ -+ _function = f; -+ if (f && f->assoziation(rtti()) == 0) { -+ f->addAssoziation(this); -+ return true; -+ } -+ return false; -+} -+ -+void TraceAssoziation::clear(TraceData* d, int rtti) -+{ -+ TraceFunctionMap::Iterator it; -+ for ( it = d->functionMap().begin(); -+ it != d->functionMap().end(); ++it ) -+ (*it).removeAssoziation(rtti); -+} -+ -+void TraceAssoziation::invalidate(TraceData* d, int rtti) -+{ -+ TraceFunctionMap::Iterator it; -+ for ( it = d->functionMap().begin(); -+ it != d->functionMap().end(); ++it ) -+ (*it).invalidateAssoziation(rtti); -+} -+ -+ -+//--------------------------------------------------- -+// TraceFunction -+ -+TraceFunction::TraceFunction() -+{ -+ _object = 0; -+ _file = 0; -+ _cls = 0; -+ _cycle = 0; -+ -+ // we are the owner of items generated in our factory -+ _deps.setAutoDelete(true); -+ _callings.setAutoDelete(true); -+ _sourceFiles.setAutoDelete(true); -+ -+ _calledCount = 0; -+ _callingCount = 0; -+ _calledContexts = 0; -+ _callingContexts = 0; -+ -+ _instrMap = 0; -+ _instrMapFilled = false; -+} -+ -+ -+TraceFunction::~TraceFunction() -+{ -+ _assoziations.setAutoDelete(true); -+ _assoziations.clear(); -+ -+ if (_instrMap) delete _instrMap; -+} -+ -+// no unique check is done! -+void TraceFunction::addAssoziation(TraceAssoziation* a) -+{ -+ if (!a) return; -+ _assoziations.append(a); -+} -+ -+void TraceFunction::removeAssoziation(TraceAssoziation* a) -+{ -+ _assoziations.removeRef(a); -+} -+ -+void TraceFunction::removeAssoziation(int rtti, bool reallyDelete) -+{ -+ if (rtti==0) { -+ if (reallyDelete) -+ _assoziations.setAutoDelete(true); -+ _assoziations.clear(); -+ _assoziations.setAutoDelete(false); -+ return; -+ } -+ -+ TraceAssoziation* a; -+ for (a=_assoziations.first();a;a=_assoziations.next()) -+ if (a->rtti() == rtti) { -+ if (reallyDelete) delete a; -+ _assoziations.remove(); -+ return; -+ } -+} -+ -+void TraceFunction::invalidateAssoziation(int rtti) -+{ -+ TraceAssoziation* a; -+ for (a=_assoziations.first();a;a=_assoziations.next()) -+ if ((rtti==0) || (a->rtti() == rtti)) -+ a->invalidate(); -+} -+ -+TraceAssoziation* TraceFunction::assoziation(int rtti) -+{ -+ TraceAssoziation* a; -+ for (a=_assoziations.first();a;a=_assoziations.next()) -+ if (a->rtti() == rtti) -+ return a; -+ return 0; -+} -+ -+ -+// helper for prettyName -+bool TraceFunction::isUniquePrefix(TQString prefix) const -+{ -+ TraceFunctionMap::ConstIterator it, it2; -+ it = it2 = _myMapIterator; -+ if (it != data()->functionBeginIterator()) { -+ it2--; -+ if ((*it2).name().startsWith(prefix)) return false; -+ } -+ if (it != data()->functionEndIterator()) { -+ it++; -+ if ((*it).name().startsWith(prefix)) return false; -+ } -+ return true; -+} -+ -+ -+TQString TraceFunction::prettyName() const -+{ -+ TQString res = _name; -+ -+ if (_name.isEmpty()) -+ return i18n("(unknown)"); -+ -+ int p = _name.find('('); -+ if (p>0) { -+ // handle C++ "operator()" correct -+ if ((_name[p+1] == ')') && (_name[p+2] == '(')) p+=2; -+ -+ // we have a C++ symbol with argument types: -+ // check for unique function name (inclusive '(' !) -+ if (isUniquePrefix(_name.left(p+1))) -+ res = _name.left(p); -+ } -+ -+ // cycle members -+ if (_cycle) { -+ if (_cycle != this) -+ res = TQString("%1 ").arg(res).arg(_cycle->cycleNo()); -+ else -+ res = TQString("").arg(_cycle->cycleNo()); -+ } -+ -+ -+ return res; -+} -+ -+/* -+ * Returns location string: ELF object and source file(s). -+ */ -+TQString TraceFunction::location(int maxFiles) const -+{ -+ TQString loc; -+ -+ // add object file with address range -+ if (_object) { -+ loc = _object->shortName(); -+ -+#if 0 -+ uint from = firstAddress(); -+ uint to = lastAddress(); -+ if (from != 0 && to != 0) { -+ if (from == to) -+ loc += TQString(" (0x%1)").arg(to, 0, 16); -+ else -+ loc += TQString(" (0x%1-0x%2)").arg(from, 0, 16).arg(to, 0, 16); -+ } -+#endif -+ } -+ -+ // add all source files -+ int filesAdded = 0; -+ TraceFunctionSourceList list = _sourceFiles; -+ TraceFunctionSource* sourceFile = list.first(); -+ for (;sourceFile;sourceFile=list.next()) { -+ if (!sourceFile->file() || -+ (sourceFile->file()->name().isEmpty()) ) -+ continue; -+ -+ if (!loc.isEmpty()) -+ loc += (filesAdded>0) ? ", " : ": "; -+ filesAdded++; -+ -+ if ((maxFiles>0) && (filesAdded>maxFiles)) { -+ loc += "..."; -+ break; -+ } -+ loc += sourceFile->file()->shortName(); -+ -+#if 0 -+ from = sourceFile->firstLineno(); -+ to = sourceFile->lastLineno(); -+ if (from != 0 && to != 0) { -+ if (from == to) -+ loc += TQString(" (%1)").arg(to); -+ else -+ loc += TQString(" (%1-%2)").arg(from).arg(to); -+ } -+#endif -+ } -+ -+ return loc; -+} -+ -+// pretty version is allowed to mangle the string... -+TQString TraceFunction::prettyLocation(int maxFiles) const -+{ -+ TQString l = location(maxFiles); -+ if (l.isEmpty()) return i18n("(unknown)"); -+ -+ return l; -+} -+ -+void TraceFunction::addPrettyLocation(TQString& s, int maxFiles) const -+{ -+ TQString l = location(maxFiles); -+ if (l.isEmpty()) return; -+ -+ s += TQString(" (%1)").arg(l); -+} -+ -+TQString TraceFunction::prettyNameWithLocation(int maxFiles) const -+{ -+ TQString l = location(maxFiles); -+ if (l.isEmpty()) return prettyName(); -+ -+ return TQString("%1 (%2)").arg(prettyName()).arg(l); -+} -+ -+TQString TraceFunction::info() const -+{ -+ TQString l = location(); -+ if (l.isEmpty()) -+ return TQString("Function %1").arg(name()); -+ -+ return TQString("Function %1 (location %2)") -+ .arg(name()).arg(l); -+} -+ -+ -+Addr TraceFunction::firstAddress() const -+{ -+ // ignore address 0 here -+ if (!_instrMap || _instrMap->count() == 0) return 0; -+ TraceInstrMap::ConstIterator it = _instrMap->begin(); -+ return (*it).addr(); -+} -+ -+Addr TraceFunction::lastAddress() const -+{ -+ // ignore address 0 here -+ if (!_instrMap || _instrMap->count() == 0) return 0; -+ TraceInstrMap::ConstIterator it = _instrMap->end(); -+ --it; -+ return (*it).addr(); -+} -+ -+/* factory */ -+TraceInstr* TraceFunction::instr(Addr addr, bool createNew) -+{ -+ // address 0 not allowed -+ if (addr == Addr(0)) return 0; -+ -+ if (!createNew) { -+ if (!_instrMap) return 0; -+ TraceInstrMap::Iterator it = _instrMap->find(addr); -+ if (it == _instrMap->end()) -+ return 0; -+ return &(it.data()); -+ } -+ -+ if (!_instrMap) _instrMap = new TraceInstrMap; -+ -+ TraceInstr& i = (*_instrMap)[addr]; -+ if (!i.isValid()) { -+ i.setAddr(addr); -+ i.setFunction(this); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceFunction::instr]", -+ i.fullName().ascii()); -+#endif -+ } -+ return &i; -+} -+ -+void TraceFunction::addCaller(TraceCall* caller) -+{ -+#if TRACE_ASSERTIONS -+ if (caller->called() != this) { -+ qDebug("Can't add call to another line!\n"); -+ return; -+ } -+ -+ if (_callers.findRef(caller)>=0) return; -+#endif -+ -+ _callers.append(caller); -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added Caller\n %s (now %d)", -+ fullName().ascii(), caller->fullName().ascii(), _callers.count()); -+#endif -+} -+ -+ -+ -+TraceCall* TraceFunction::calling(TraceFunction* called) -+{ -+ TraceCallMap::Iterator it = _callingMap.find(called); -+ TraceCall* calling = (it == _callingMap.end()) ? 0 : it.data(); -+ -+ if (!calling) { -+ calling = new TraceCall(this, called); -+ -+ _callingMap.insert(called, calling); -+ _callings.append(calling); -+ -+ // we have to invalidate ourself so invalidations from item propagate up -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceFunction::calling]", calling->fullName().ascii()); -+#endif -+ called->addCaller(calling); -+ } -+ return calling; -+} -+ -+TraceFunctionSource* TraceFunction::sourceFile(TraceFile* file, -+ bool createNew) -+{ -+ if (!file) file = _file; -+ -+ TraceFunctionSource* sourceFile = _sourceFiles.first(); -+ for (;sourceFile;sourceFile=_sourceFiles.next()) -+ if (sourceFile->file() == file) break; -+ -+ if (!sourceFile && createNew) { -+ sourceFile = new TraceFunctionSource(this, file); -+ -+ _sourceFiles.append(sourceFile); -+ -+ // we have to invalidate ourself so invalidations from item propagate up -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("Created SourceFile %s [TraceFunction::line]", -+ file->name().ascii()); -+#endif -+ file->addSourceFile(sourceFile); -+ } -+ return sourceFile; -+} -+ -+TraceLine* TraceFunction::line(TraceFile* file, uint lineno, -+ bool createNew) -+{ -+ Q_ASSERT(file!=0); -+ -+ TraceFunctionSource* sf = sourceFile(file, createNew); -+ if (!sf) -+ return 0; -+ else -+ return sf->line(lineno, createNew); -+} -+ -+ -+TracePartFunction* TraceFunction::partFunction(TracePart* part, -+ TracePartFile* partFile, -+ TracePartObject* partObject) -+{ -+ TracePartFunction* item = (TracePartFunction*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartFunction(this, partObject, partFile); -+ item->setPosition(part); -+ addDep(item); -+#if USE_FIXCOST -+ part->addDep(item); -+#endif -+ -+ if (_cls) { -+ TracePartClass* partClass = _cls->partClass(part); -+ partClass->addPartFunction(item); -+ item->setPartClass(partClass); -+ } -+ -+ partFile->addPartFunction(item); -+ if (partObject) -+ partObject->addPartFunction(item); -+ } -+ else if (item->partObject()==0 && partObject) { -+ item->setPartObject(partObject); -+ partObject->addPartFunction(item); -+ } -+ -+ return item; -+} -+ -+ -+SubCost TraceFunction::calledCount() -+{ -+ if (_dirty) update(); -+ -+ return _calledCount; -+} -+ -+int TraceFunction::calledContexts() -+{ -+ if (_dirty) update(); -+ -+ return _calledContexts; -+} -+ -+SubCost TraceFunction::callingCount() -+{ -+ if (_dirty) update(); -+ -+ return _callingCount; -+} -+ -+int TraceFunction::callingContexts() -+{ -+ if (_dirty) update(); -+ -+ return _callingContexts; -+} -+ -+TQString TraceFunction::prettyCalledCount() -+{ -+ return _calledCount.pretty(); -+} -+ -+TQString TraceFunction::prettyCallingCount() -+{ -+ return _callingCount.pretty(); -+} -+ -+ -+TraceCallList TraceFunction::callers(bool skipCycle) const -+{ -+ if (skipCycle) return _callers; -+ -+ // fake the callers for cycle members -+ if (_cycle && (_cycle != this)) { -+ TraceCallList l; -+ TraceCall* c; -+ -+ // inner-cycle-callers -+ TraceCallList list=_callers; -+ for (c=list.first();c;c=list.next()) -+ if (c->caller()->cycle() == _cycle) -+ l.append(c); -+ -+ // call from cycle itself -+ for (c=_cycle->_callings.first();c;c=_cycle->_callings.next()) -+ if (c->called() == this) { -+ l.append(c); -+ return l; -+ } -+ } -+ -+ return _callers; -+} -+ -+const TraceCallList& TraceFunction::callings(bool /* skipCycle */) const -+{ -+ return _callings; -+} -+ -+void TraceFunction::invalidateDynamicCost() -+{ -+ TraceCall* c; -+ for (c=_callings.first();c;c=_callings.next()) -+ c->invalidateDynamicCost(); -+ -+ TraceFunctionSource* sf; -+ for (sf=_sourceFiles.first();sf;sf=_sourceFiles.next()) -+ sf->invalidateDynamicCost(); -+ -+ if (_instrMap) { -+ TraceInstrMap::Iterator iit; -+ for ( iit = _instrMap->begin(); -+ iit != _instrMap->end(); ++iit ) -+ (*iit).invalidate(); -+ } -+ -+ invalidate(); -+} -+ -+void TraceFunction::update() -+{ -+ if (!_dirty) return; -+ -+#if TRACE_DEBUG -+ qDebug("Update %s (Callers %d, sourceFiles %d, instrs %d)", -+ _name.ascii(), _callers.count(), -+ _sourceFiles.count(), _instrMap ? _instrMap->count():0); -+#endif -+ -+ _calledCount = 0; -+ _callingCount = 0; -+ _calledContexts = 0; -+ _callingContexts = 0; -+ clear(); -+ -+ // context count is NOT the sum of part contexts -+ TraceCall *caller, *calling; -+ for (caller=_callers.first();caller;caller=_callers.next()) { -+ // FIXME -+ if (caller->subCost(0)>0) -+ _calledContexts++; -+ _calledCount += caller->callCount(); -+ } -+ -+ for (calling=_callings.first();calling;calling=_callings.next()) { -+ // FIXME -+ if (calling->subCost(0)>0) _callingContexts++; -+ _callingCount += calling->callCount(); -+ } -+ -+ if (data()->inFunctionCycleUpdate() || !_cycle) { -+ // usual case (no cycle member) -+ TraceInclusiveCost* item; -+ for (item=_deps.first();item;item=_deps.next()) { -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ addInclusive(item->inclusive()); -+ } -+ } -+ else { -+ // this is a cycle or cycle member -+ for (calling=_callings.first();calling;calling=_callings.next()) { -+ -+ // ignore inner-cycle member calls for inclusive cost -+ if ((_cycle != this) && -+ (calling->inCycle()>0)) continue; -+ -+ addInclusive(calling); -+ } -+ -+ // self cost -+ if (type() == FunctionCycle) { -+ // cycle: self cost is sum of cycle member self costs, but -+ // doesn't add to inclusive cost -+ TraceFunctionList mList = ((TraceFunctionCycle*)this)->members(); -+ TraceFunction* m; -+ for (m=mList.first();m;m=mList.next()) -+ addCost(m); -+ } -+ else { -+ // cycle member -+ TraceInclusiveCost* item; -+ for (item=_deps.first();item;item=_deps.next()) { -+ if (!item->part() || !item->part()->isActive()) continue; -+ -+ addCost(item); -+ } -+ _dirty = false; // don't recurse -+ addInclusive(this); -+ } -+ } -+ _dirty = false; -+ -+#if TRACE_DEBUG -+ qDebug("> %s", costString(0).ascii()); -+#endif -+} -+ -+bool TraceFunction::isCycle() -+{ -+ return _cycle == this; -+} -+ -+bool TraceFunction::isCycleMember() -+{ -+ return _cycle && (_cycle != this); -+} -+ -+void TraceFunction::cycleReset() -+{ -+ _cycle = 0; -+ _cycleStackDown = 0; -+ _cycleLow = 0; -+} -+ -+// this doesn't mark functions calling themself ! -+void TraceFunction::cycleDFS(int d, int& pNo, TraceFunction** pTop) -+{ -+ if (_cycleLow != 0) return; -+ -+ if (0) -+ qDebug("%s D%02d > %s (%d)", -+ TQString().fill(' ', d).ascii(), d, prettyName().ascii(), pNo+1); -+ -+ -+ -+ // initialize with prefix order -+ pNo++; -+ int prefixNo = pNo; -+ _cycleLow = prefixNo; -+ -+ // put myself on stack -+ _cycleStackDown = *pTop; -+ *pTop = this; -+ -+ /* cycle cut heuristic: -+ * skip calls for cycle detection if they make less than _cycleCut -+ * percent of the cost of the function. -+ * FIXME: Which cost type to use for this heuristic ?! -+ */ -+ -+ SubCost base = 0; -+ if (_callers.count()>0) { -+ TraceCallList l = _callers; -+ TraceCall *caller; -+ -+ for (caller=l.first();caller;caller=l.next()) -+ if (caller->subCost(0) > base) -+ base = caller->subCost(0); -+ } -+ else base = inclusive()->subCost(0); -+ -+ SubCost cutLimit = SubCost(base * Configuration::cycleCut()); -+ -+ if (0) -+ qDebug("%s Cum. %s, Max Caller %s, cut limit %s", -+ TQString().fill(' ', d).ascii(), -+ inclusive()->subCost(0).pretty().ascii(), -+ base.pretty().ascii(), -+ cutLimit.pretty().ascii()); -+ -+ TraceCall *calling; -+ TraceCallList l = _callings; -+ for (calling=l.first();calling;calling=l.next()) { -+ TraceFunction* called = calling->called(); -+ -+ // cycle cut heuristic -+ if (calling->subCost(0) < cutLimit) { -+ if (0) qDebug("%s Cut call to %s (cum. %s)", -+ TQString().fill(' ', d).ascii(), -+ called->prettyName().ascii(), -+ calling->subCost(0).pretty().ascii()); -+ -+ continue; -+ } -+ -+ if (called->_cycleLow==0) { -+ // not visited yet -+ called->cycleDFS(d+1, pNo, pTop); -+ if (called->_cycleLow < _cycleLow) -+ _cycleLow = called->_cycleLow; -+ } -+ else if (called->_cycleStackDown) { -+ // backlink to same SCC (still in stack) -+ if (called->_cycleLow < _cycleLow) -+ _cycleLow = called->_cycleLow; -+ -+ if (0) -+ qDebug("%s D%02d - %s (%d)", -+ TQString().fill(' ', d+1).ascii(), d+1, -+ called->prettyName().ascii(), called->_cycleLow); -+ } -+ else { -+ if (0) -+ qDebug("%s D%02d - %s (%d) [Not on stack]", -+ TQString().fill(' ', d+1).ascii(), d+1, -+ called->prettyName().ascii(), called->_cycleLow); -+ } -+ } -+ -+ if (prefixNo == _cycleLow) { -+ // this is the base of a SCC. -+ -+ if (*pTop == this) { -+ *pTop = _cycleStackDown; -+ _cycleStackDown = 0; -+ } -+ else { -+ // a SCC with >1 members -+ -+ TraceFunctionCycle* cycle = data()->functionCycle(this); -+ if (0) qDebug("BASE CYC %d %s", -+ cycle->cycleNo(), prettyName().ascii()); -+ while(*pTop) { -+ TraceFunction* top = *pTop; -+ cycle->add(top); -+ -+ // remove from stack -+ *pTop = top->_cycleStackDown; -+ top->_cycleStackDown = 0; -+ -+ if (0) qDebug("CYC %s", top->prettyName().ascii()); -+ if (top == this) break; -+ } -+ } -+ } -+ if (0) -+ qDebug("%s D%02d < %s (%d)", -+ TQString().fill(' ', d).ascii(), d, -+ prettyName().ascii(), _cycleLow); -+} -+ -+ -+TraceInstrMap* TraceFunction::instrMap() -+{ -+#if USE_FIXCOST -+ -+ if (_instrMapFilled) return _instrMap; -+ _instrMapFilled = true; -+ if (!_instrMap) -+ _instrMap = new TraceInstrMap; -+ -+ TraceLine* l = 0; -+ TraceInstr* i = 0; -+ TracePartInstr* pi = 0; -+ TraceInstrCall* ic = 0; -+ TracePartInstrCall* pic = 0; -+ -+ TraceInclusiveCostList pfList = deps(); -+ TracePartFunction* pf = (TracePartFunction*) pfList.first(); -+ for(; pf; pf = (TracePartFunction*) pfList.next()) { -+ -+ if (0) qDebug("PartFunction %s:%d", -+ pf->function()->name().ascii(), pf->part()->partNumber()); -+ -+ FixCost* fc = pf->firstFixCost(); -+ for(; fc; fc = fc->nextCostOfPartFunction()) { -+ if (fc->addr() == 0) continue; -+ -+ if (!l || (l->lineno() != fc->line()) || -+ (l->functionSource() != fc->functionSource())) -+ l = fc->functionSource()->line(fc->line(),true); -+ -+ if (!i || i->addr() != fc->addr()) { -+ i = &(*_instrMap)[fc->addr()]; -+ if (!i->isValid()) { -+ i->setFunction(this); -+ i->setAddr(fc->addr()); -+ i->setLine(l); -+ } -+ pi = 0; -+ } -+ if (!pi || pi->part() != fc->part()) -+ pi = i->partInstr(fc->part(), pf); -+ fc->addTo(pi); -+ } -+ -+ TraceInstr* to = 0; -+ TraceInstrJump* ij; -+ TracePartInstrJump* pij; -+ FixJump* fj = pf->firstFixJump(); -+ for(; fj; fj = fj->nextJumpOfPartFunction()) { -+ if (fj->addr() == 0) continue; -+ -+ if (!l || (l->lineno() != fj->line()) || -+ (l->functionSource() != fj->source())) -+ l = fj->source()->line(fj->line(),true); -+ -+ if (!i || i->addr() != fj->addr()) { -+ i = &(*_instrMap)[fj->addr()]; -+ if (!i->isValid()) { -+ i->setFunction(this); -+ i->setAddr(fj->addr()); -+ i->setLine(l); -+ } -+ } -+ -+ to = fj->targetFunction()->instr(fj->targetAddr(), true); -+ -+ ij = i->instrJump(to, fj->isCondJump()); -+ pij = ij->partInstrJump(fj->part()); -+ -+ fj->addTo(pij); -+ } -+ -+ TracePartCallList pcList = pf->partCallings(); -+ TracePartCall* pc = pcList.first(); -+ for(; pc; pc = pcList.next()) { -+ -+ if (0) qDebug("PartCall %s:%d", -+ pc->call()->name().ascii(), -+ pf->part()->partNumber()); -+ -+ FixCallCost* fcc = pc->firstFixCallCost(); -+ for(; fcc; fcc = fcc->nextCostOfPartCall()) { -+ if (fcc->addr() == 0) continue; -+ -+ if (!l || (l->lineno() != fcc->line()) || -+ (l->functionSource() != fcc->functionSource())) -+ l = fcc->functionSource()->line(fcc->line(),true); -+ -+ if (!i || i->addr() != fcc->addr()) { -+ i = &(*_instrMap)[fcc->addr()]; -+ if (!i->isValid()) { -+ i->setFunction(this); -+ i->setAddr(fcc->addr()); -+ i->setLine(l); -+ } -+ } -+ if (!ic || ic->call() != pc->call() || ic->instr() != i) { -+ ic = pc->call()->instrCall(i); -+ pic = 0; -+ } -+ if (!pic || pic->part() != fcc->part()) -+ pic = ic->partInstrCall(fcc->part(), pc); -+ -+ fcc->addTo(pic); -+ if (0) qDebug("Add FixCallCost %s:%d/0x%s, CallCount %s", -+ fcc->functionSource()->file()->shortName().ascii(), -+ fcc->line(), fcc->addr().toString().ascii(), -+ fcc->callCount().pretty().ascii()); -+ } -+ } -+ } -+ -+#endif -+ -+ return _instrMap; -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceFunctionCycle -+ -+TraceFunctionCycle::TraceFunctionCycle(TraceFunction* f, int n) -+{ -+ _base = f; -+ _cycleNo = n; -+ _cycle = this; -+ -+ setPosition(f->data()); -+ setName(TQString("").arg(n)); -+ -+ // reset to attributes of base function -+ setFile(_base->file()); -+ setClass(_base->cls()); -+ setObject(_base->object()); -+} -+ -+void TraceFunctionCycle::init() -+{ -+ _members.clear(); -+ _memberSet.clear(); -+ _callers.clear(); -+ // this deletes all TraceCall's to members -+ _callings.clear(); -+ -+ invalidate(); -+} -+ -+void TraceFunctionCycle::add(TraceFunction* f) -+{ -+ _members.append(f); -+ _memberSet.insert(f,1); -+} -+ -+void TraceFunctionCycle::setup() -+{ -+ if (_members.count()==0) return; -+ -+ TraceFunction* f; -+ for (f=_members.first();f;f=_members.next()) { -+ -+ // the cycle takes all outside callers from its members -+ TraceCall *call; -+ TraceCallList l = f->callers(); -+ for (call=l.first();call;call=l.next()) { -+ if ( _memberSet.contains(call->caller()) ) continue; -+ _callers.append(call); -+ } -+ -+ // the cycle has a call to each member -+ call = new TraceCall(this, f); -+ call->invalidate(); -+ _callings.append(call); -+ -+ // now do some faking... -+ f->setCycle(this); -+ } -+ invalidate(); -+} -+ -+ -+//--------------------------------------------------- -+// TraceClass -+ -+TraceClass::TraceClass() -+{ -+ // we are the owner of items generated in our factory -+ _deps.setAutoDelete(true); -+} -+ -+TraceClass::~TraceClass() -+{} -+ -+TQString TraceClass::prettyName() const -+{ -+ if (_name.isEmpty()) -+ return TQString("(global)"); -+ return _name; -+} -+ -+TracePartClass* TraceClass::partClass(TracePart* part) -+{ -+ TracePartClass* item = (TracePartClass*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartClass(this); -+ item->setPosition(part); -+ addDep(item); -+ } -+ return item; -+} -+ -+void TraceClass::addFunction(TraceFunction* function) -+{ -+#if TRACE_ASSERTIONS -+ if (function->cls() != this) { -+ qDebug("Can't add function to a class not enclosing this function\n"); -+ return; -+ } -+ -+ if (_functions.findRef(function)>=0) return; -+#endif -+ -+ _functions.append(function); -+ -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), -+ function->fullName().ascii(), _functions.count()); -+#endif -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceFile -+ -+TraceFile::TraceFile() -+{ -+ // we are the owner of items generated in our factory -+ _deps.setAutoDelete(true); -+} -+ -+TraceFile::~TraceFile() -+{} -+ -+TracePartFile* TraceFile::partFile(TracePart* part) -+{ -+ TracePartFile* item = (TracePartFile*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartFile(this); -+ item->setPosition(part); -+ addDep(item); -+ } -+ return item; -+} -+ -+void TraceFile::addFunction(TraceFunction* function) -+{ -+#if TRACE_ASSERTIONS -+ if (function->file() != this) { -+ qDebug("Can't add function to a file not enclosing this function\n"); -+ return; -+ } -+ -+ if (_functions.findRef(function)>=0) return; -+#endif -+ -+ _functions.append(function); -+ -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), -+ function->fullName().ascii(), _functions.count()); -+#endif -+} -+ -+ -+void TraceFile::addSourceFile(TraceFunctionSource* sourceFile) -+{ -+#if TRACE_ASSERTIONS -+ if (sourceFile->file() != this) { -+ qDebug("Can't add sourceFile to a file not having lines for it\n"); -+ return; -+ } -+#endif -+ -+ _sourceFiles.append(sourceFile); -+ // not truely needed, as we don't use the sourceFiles for cost update -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s \n added SourceFile %s (now %d)", -+ fullName().ascii(), sourceFile->fullName().ascii(), -+ _sourceFiles.count()); -+#endif -+} -+ -+ -+ -+void TraceFile::setDirectory(const TQString& dir) -+{ -+ if (dir.endsWith("/")) -+ _dir = dir.left(dir.length()-1); -+ else -+ _dir = dir; -+} -+ -+TQString TraceFile::directory() -+{ -+ if (!_dir.isEmpty()) return _dir; -+ -+ int lastIndex = 0, index; -+ while ( (index=_name.find("/", lastIndex)) >=0) -+ lastIndex = index+1; -+ -+ if (lastIndex==0) return TQString(); -+ -+ // without ending "/" -+ return _name.left(lastIndex-1); -+} -+ -+ -+TQString TraceFile::shortName() const -+{ -+ int lastIndex = 0, index; -+ while ( (index=_name.find("/", lastIndex)) >=0) -+ lastIndex = index+1; -+ -+ return _name.mid(lastIndex); -+} -+ -+TQString TraceFile::prettyName() const -+{ -+ TQString sn = shortName(); -+ -+ if (sn.isEmpty()) -+ return i18n("(unknown)"); -+ -+ return sn; -+} -+ -+TQString TraceFile::prettyLongName() const -+{ -+ if (_name.isEmpty()) -+ return i18n("(unknown)"); -+ return _name; -+} -+ -+ -+//--------------------------------------------------- -+// TraceObject -+ -+TraceObject::TraceObject() -+{ -+ // we are the owner of items generated in our factory -+ _deps.setAutoDelete(true); -+} -+ -+TraceObject::~TraceObject() -+{} -+ -+TracePartObject* TraceObject::partObject(TracePart* part) -+{ -+ TracePartObject* item = (TracePartObject*) findDepFromPart(part); -+ if (!item) { -+ item = new TracePartObject(this); -+ item->setPosition(part); -+ addDep(item); -+ } -+ return item; -+} -+ -+void TraceObject::addFunction(TraceFunction* function) -+{ -+#if TRACE_ASSERTIONS -+ if (function->object() != this) { -+ qDebug("Can't add function to an object not enclosing this function\n"); -+ return; -+ } -+ -+ if (_functions.findRef(function)>=0) return; -+#endif -+ -+ _functions.append(function); -+ -+ invalidate(); -+ -+#if TRACE_DEBUG -+ qDebug("%s added\n %s (now %d)", -+ fullName().ascii(), -+ function->fullName().ascii(), _functions.count()); -+#endif -+} -+ -+// strip path -+void TraceObject::setName(const TQString& name) -+{ -+ _name = name; -+ -+ int lastIndex = 0, index; -+ while ( (index=_name.find("/", lastIndex)) >=0) -+ lastIndex = index+1; -+ -+ _shortName = _name.mid(lastIndex); -+} -+ -+TQString TraceObject::prettyName() const -+{ -+ if (_shortName.isEmpty()) -+ return i18n("(unknown)"); -+ -+ return _shortName; -+} -+ -+//--------------------------------------------------- -+// TracePart -+ -+TracePart::TracePart(TraceData* data, TQFile* file) -+{ -+ setPosition(data); -+ -+ _dep = data; -+ _file = file; -+ if (_file) -+ _name = _file->name(); -+ _active = true; -+ -+ _number = 0; -+ _tid = 0; -+ _pid = 0; -+ -+ _fixSubMapping = 0; -+} -+ -+TracePart::~TracePart() -+{ -+ delete _file; -+ -+ delete _fixSubMapping; -+} -+ -+void TracePart::setPartNumber(int n) -+{ -+ if (data()->maxPartNumber() setMaxPartNumber(n); -+ _number = n; -+} -+ -+void TracePart::setThreadID(int tid) -+{ -+ if (data()->maxThreadID() setMaxThreadID(tid); -+ _tid = tid; -+} -+ -+void TracePart::setProcessID(int pid) -+{ -+ _pid = pid; -+} -+ -+ -+ -+// strip path -+TQString TracePart::shortName() const -+{ -+ int lastIndex = 0, index; -+ while ( (index=_name.find("/", lastIndex)) >=0) -+ lastIndex = index+1; -+ -+ return _name.mid(lastIndex); -+} -+ -+TQString TracePart::prettyName() const -+{ -+ TQString name = TQString("%1.%2").arg(_pid).arg(_number); -+ if (data()->maxThreadID()>1) -+ name += TQString("-%3").arg(_tid); -+ return name; -+} -+ -+bool TracePart::activate(bool active) -+{ -+ if (_active == active) return false; -+ _active = active; -+ -+ // to be done by the client of this function -+ // data()->invalidateDynamicCost(); -+ // So better use the TraceData functions... -+ -+ return true; -+} -+ -+ -+ -+//--------------------------------------------------- -+// TracePartList -+ -+int TracePartList::compareItems ( Item item1, Item item2 ) -+{ -+ TracePart* p1 = (TracePart*) item1; -+ TracePart* p2 = (TracePart*) item2; -+ int mTID = p1->data()->maxThreadID()+1; -+ int mNum = p1->data()->maxPartNumber()+1; -+ -+ return -+ (p1->processID() - p2->processID()) * mTID * mNum + -+ (p1->partNumber() - p2->partNumber()) * mTID + -+ (p1->threadID() - p2->threadID()); -+} -+ -+TQString TracePartList::names() const -+{ -+ TQString res; -+ TracePart* p; -+ TracePartList l = *this; -+ for (p=l.first();p;p=l.next()) { -+ if (!res.isEmpty()) res += ", "; -+ res += p->shortName(); -+ } -+ -+ return res; -+} -+ -+ -+ -+//--------------------------------------------------- -+// TraceData -+ -+ -+// create vectors with reasonable default sizes, but not wasting memory -+TraceData::TraceData(TopLevel* top) -+{ -+ _topLevel = top; -+ init(); -+} -+ -+TraceData::TraceData(const TQString& base) -+{ -+ _topLevel = 0; -+ init(); -+ load(base); -+} -+ -+void TraceData::init() -+{ -+ _parts.setAutoDelete(true); -+ -+ _functionCycleCount = 0; -+ _inFunctionCycleUpdate = false; -+ -+ _maxThreadID = 0; -+ _maxPartNumber = 0; -+ _fixPool = 0; -+ _dynPool = 0; -+} -+ -+TraceData::~TraceData() -+{ -+ if (_fixPool) delete _fixPool; -+ if (_dynPool) delete _dynPool; -+} -+ -+TQString TraceData::shortTraceName() const -+{ -+ int lastIndex = 0, index; -+ while ( (index=_traceName.find("/", lastIndex)) >=0) -+ lastIndex = index+1; -+ -+ return _traceName.mid(lastIndex); -+} -+ -+FixPool* TraceData::fixPool() -+{ -+ if (!_fixPool) -+ _fixPool = new FixPool(); -+ -+ return _fixPool; -+} -+ -+DynPool* TraceData::dynPool() -+{ -+ if (!_dynPool) -+ _dynPool = new DynPool(); -+ -+ return _dynPool; -+} -+ -+ -+/** -+ * Two cases: -+ * -+ * - is a directory: Load first profile data file available -+ * - is a file name without part/thread suffixes -+ */ -+void TraceData::load(const TQString& base) -+{ -+ bool baseExisting = true; -+ -+ _traceName = base; -+ TQFileInfo finfo(base); -+ TQString file = finfo.fileName(); -+ TQDir dir = finfo.dir(); -+ -+ if (!finfo.exists()) { -+ baseExisting = false; -+ } -+ else if (finfo.isDir()) { -+ // search for first profile data file in directory -+ dir = TQDir(base); -+ -+ TQStringList prefixList; -+ prefixList << "callgrind.out" << "cachegrind.out"; -+ for ( TQStringList::Iterator it = prefixList.begin(); -+ it != prefixList.end(); ++it ) { -+ file = *it; -+ -+ // search for ".pid" -+ TQStringList strList = dir.entryList(file+".*", TQDir::Files); -+ if (strList.count()>0) { -+ int l = file.length(); -+ file = strList.first(); -+ l++; -+ while(file[l] >= '0' && file[l] <= '9') l++; -+ file = file.left(l); -+ break; -+ } -+ } -+ -+ _traceName = dir.path() + "/" + file; -+ } -+ -+ TQStringList strList; -+ strList += dir.entryList(file+".*", TQDir::Files); -+ strList += dir.entryList(file+"-*", TQDir::Files); -+ -+ baseExisting = TQFile::exists(_traceName); -+ if (baseExisting) -+ strList << file; -+ -+ if (strList.count() == 0) { -+ _traceName = base + "/" + file + " " + i18n("(not found)"); -+ return; -+ } -+ -+ -+ // try to guess pid from file name -+ unsigned int pos = file.length(); -+ unsigned int pid = 0, f=1; -+ pos--; -+ while(pos>0) { -+ if (file[pos] < '0' || file[pos] > '9') break; -+ pid += f * (file[pos].latin1() - '0'); -+ pos--; -+ f *= 10; -+ } -+ -+ TQStringList::Iterator it; -+ unsigned int maxNumber = 0; -+ for (it = strList.begin(); it != strList.end(); ++it ) { -+ TracePart* p = addPart( dir.path(), *it ); -+ -+ if (!p) { -+ kdDebug() << "Error loading " << *it << endl; -+ continue; -+ } -+ -+ const TQString& str = *it; -+ unsigned int pos = file.length(); -+ -+ // try to guess part number from file name -+ unsigned int n = 0; -+ if ((str.length() > pos) && (str[pos] == '.')) { -+ pos++; -+ while(str.length()>pos) { -+ if ((int)str.at(pos) < '0' || (int)str.at(pos) > '9') break; -+ n = 10*n + (str[pos++] - '0'); -+ } -+ } -+ -+ // try to guess thread number from file name -+ unsigned int t = 0; -+ if ((str.length() > pos) && (str[pos] == '-')) { -+ pos++; -+ while(str.length()>pos) { -+ if ((int)str.at(pos) < '0' || (int)str.at(pos) > '9') break; -+ t = 10*t + (str[pos++] - '0'); -+ } -+ } -+ -+ //qDebug("File %s: Part %d, Thread %d", (*it).ascii(), n, t); -+ -+ if (p->partNumber()>0) n = p->partNumber(); -+ if (n>maxNumber) maxNumber = n; -+ if (n==0) n = maxNumber+1; -+ p->setPartNumber(n); -+ -+ if (p->threadID()==0) p->setThreadID(t); -+ if (p->processID()==0) p->setProcessID(pid); -+ -+ _parts.append(p); -+ } -+ _parts.sort(); -+ -+ invalidateDynamicCost(); -+ updateFunctionCycles(); -+ -+ // clear loading messages from status bar -+ if (_topLevel) _topLevel->showStatus(TQString(), 0); -+} -+ -+TracePart* TraceData::addPart(const TQString& dir, const TQString& name) -+{ -+ TQString filename = TQString("%1/%2").arg(dir).arg(name); -+#if TRACE_DEBUG -+ qDebug("TraceData::addPart('%s')", filename.ascii()); -+#endif -+ -+ TQFile* file = new TQFile(filename); -+ -+ Loader* l = Loader::matchingLoader(file); -+ if (!l) return 0; -+ -+ if (_topLevel) -+ _topLevel->connect(l, TQT_SIGNAL(updateStatus(TQString, int)), -+ TQT_SLOT(showStatus(TQString, int))); -+ -+ TracePart* part = new TracePart(this, file); -+ -+ if (! l->loadTrace(part)) { -+ delete part; -+ part = 0; -+ } -+ -+ if (_topLevel) l->disconnect(_topLevel); -+ -+ return part; -+} -+ -+bool TraceData::activateParts(const TracePartList& l) -+{ -+ bool changed = false; -+ -+ TracePart* part; -+ for (part=_parts.first();part;part=_parts.next()) -+ if (part->activate(l.containsRef(part)>0)) -+ changed = true; -+ -+ if (changed) { -+ // because active parts have changed, throw away calculated -+ // costs... -+ invalidateDynamicCost(); -+ updateFunctionCycles(); -+ } -+ -+ return changed; -+} -+ -+ -+bool TraceData::activateParts(TracePartList l, bool active) -+{ -+ bool changed = false; -+ -+ TracePart* part; -+ for (part=l.first();part;part=l.next()) -+ if (_parts.findRef(part)>=0) -+ if (part->activate(active)) -+ changed = true; -+ -+ if (changed) { -+ invalidateDynamicCost(); -+ updateFunctionCycles(); -+ } -+ -+ return changed; -+} -+ -+bool TraceData::activatePart(TracePart* p, bool active) -+{ -+ return p->activate(active); -+} -+ -+bool TraceData::activateAll(bool active) -+{ -+ return activateParts(_parts, active); -+} -+ -+ -+TracePart* TraceData::part(TQString& name) -+{ -+ TracePart* part; -+ for (part=_parts.first();part;part=_parts.next()) -+ if (part->name() == name) -+ return part; -+ return 0; -+} -+ -+TQString TraceData::activePartRange() -+{ -+ TQString res; -+ int r1=-1, r2=-1, count=1; -+ TracePart* part; -+ for (part=_parts.first();part;part=_parts.next(), count++) -+ if (part->isActive()) { -+ if (r1<0) { r1 = r2 = count; } -+ else if (r2 == count-1) { r2 = count; } -+ else { -+ if (!res.isEmpty()) res += ";"; -+ if (r1==r2) res += TQString::number(r1); -+ else res += TQString("%1-%2").arg(r1).arg(r2); -+ r1 = r2 = count; -+ } -+ } -+ if (r1>=0) { -+ if (!res.isEmpty()) res += ";"; -+ if (r1==r2) res += TQString::number(r1); -+ else res += TQString("%1-%2").arg(r1).arg(r2); -+ } -+ -+ return res; -+} -+ -+void TraceData::invalidateDynamicCost() -+{ -+ // invalidate all dynamic costs -+ -+ TraceObjectMap::Iterator oit; -+ for ( oit = _objectMap.begin(); -+ oit != _objectMap.end(); ++oit ) -+ (*oit).invalidate(); -+ -+ TraceClassMap::Iterator cit; -+ for ( cit = _classMap.begin(); -+ cit != _classMap.end(); ++cit ) -+ (*cit).invalidate(); -+ -+ TraceFileMap::Iterator fit; -+ for ( fit = _fileMap.begin(); -+ fit != _fileMap.end(); ++fit ) -+ (*fit).invalidate(); -+ -+ TraceFunctionMap::Iterator it; -+ for ( it = _functionMap.begin(); -+ it != _functionMap.end(); ++it ) { -+ (*it).invalidateDynamicCost(); -+ } -+ -+ invalidate(); -+ -+} -+ -+ -+TraceObject* TraceData::object(const TQString& name) -+{ -+ TraceObject& o = _objectMap[name]; -+ if (!o.data()) { -+ // was created -+ o.setPosition(this); -+ o.setName(name); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceData::object]", -+ o.fullName().ascii()); -+#endif -+ } -+ return &o; -+} -+ -+ -+TraceFile* TraceData::file(const TQString& name) -+{ -+ TraceFile& f = _fileMap[name]; -+ if (!f.data()) { -+ // was created -+ f.setPosition(this); -+ f.setName(name); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceData::file]", -+ f.fullName().ascii()); -+#endif -+ } -+ return &f; -+} -+ -+ -+// usually only called by function() -+TraceClass* TraceData::cls(const TQString& fnName, TQString& shortName) -+{ -+ int lastIndex = 0, index, pIndex; -+ -+ // we ignore any "::" after a '(' or a space -+ pIndex=fnName.find("(", 0); -+ -+#if 0 -+ int sIndex=fnName.find(" ", 0); -+ if (sIndex>=0) -+ if ((pIndex == -1) || (sIndex < pIndex)) -+ pIndex = sIndex; -+#endif -+ -+ while ((index=fnName.find("::", lastIndex)) >=0) { -+ if (pIndex>=0 && pIndexshortName(); -+ -+ TraceFunctionMap::Iterator it; -+ it = _functionMap.find(key); -+ if (it == _functionMap.end()) { -+ it = _functionMap.insert(key, TraceFunction()); -+ TraceFunction& f = it.data(); -+ -+ f.setPosition(this); -+ f.setName(name); -+ f.setClass(c); -+ f.setObject(object); -+ f.setFile(file); -+ f.setMapIterator(it); -+ -+#if TRACE_DEBUG -+ qDebug("Created %s [TraceData::function]\n for %s, %s, %s", -+ f.fullName().ascii(), -+ c->fullName().ascii(), file->fullName().ascii(), -+ object ? object->fullName().ascii() : "(unknown object)"); -+#endif -+ -+ c->addFunction(&f); -+ object->addFunction(&f); -+ file->addFunction(&f); -+ } -+ -+ return &(it.data()); -+} -+ -+TraceFunctionMap::Iterator TraceData::functionIterator(TraceFunction* f) -+{ -+ -+ // IMPORTANT: build as SAME key as used in function() above !! -+ TQString key; -+ -+ if (f->cls()) key = f->cls()->name() + "::"; -+ key += f->name(); -+ key += f->object()->shortName(); -+ -+ return _functionMap.find(key); -+} -+ -+TraceFunctionMap::ConstIterator TraceData::functionBeginIterator() const -+{ -+ return _functionMap.begin(); -+} -+ -+TraceFunctionMap::ConstIterator TraceData::functionEndIterator() const -+{ -+ return _functionMap.end(); -+} -+ -+ -+void TraceData::resetSourceDirs() -+{ -+ TraceFileMap::Iterator fit; -+ for ( fit = _fileMap.begin(); -+ fit != _fileMap.end(); ++fit ) -+ (*fit).resetDirectory(); -+} -+ -+void TraceData::update() -+{ -+ if (!_dirty) return; -+ -+ clear(); -+ _totals.clear(); -+ -+ TracePart* part; -+ for (part=_parts.first();part;part=_parts.next()) { -+ _totals.addCost(part->totals()); -+ if (part->isActive()) -+ addCost(part->totals()); -+ } -+ -+ _dirty = false; -+} -+ -+TraceCost* TraceData::search(TraceItem::CostType t, TQString name, -+ TraceCostType* ct, TraceCost* parent) -+{ -+ TraceCost* result = 0; -+ TraceItem::CostType pt = parent ? parent->type() : NoCostType; -+ SubCost sc, scTop = 0; -+ -+ switch(t) { -+ case Function: -+ { -+ TraceFunction *f; -+ TraceFunctionMap::Iterator it; -+ for ( it = _functionMap.begin(); -+ it != _functionMap.end(); ++it ) { -+ f = &(*it); -+ -+ if (f->name() != name) continue; -+ -+ if ((pt == Class) && (parent != f->cls())) continue; -+ if ((pt == File) && (parent != f->file())) continue; -+ if ((pt == Object) && (parent != f->object())) continue; -+ -+ if (ct) { -+ sc = f->inclusive()->subCost(ct); -+ if (sc <= scTop) continue; -+ scTop = sc; -+ } -+ -+ result = f; -+ } -+ } -+ break; -+ -+ case File: -+ { -+ TraceFile *f; -+ TraceFileMap::Iterator it; -+ for ( it = _fileMap.begin(); -+ it != _fileMap.end(); ++it ) { -+ f = &(*it); -+ if (f->name() != name) continue; -+ if (ct) { -+ sc = f->subCost(ct); -+ if (sc <= scTop) continue; -+ scTop = sc; -+ } -+ result = f; -+ } -+ } -+ break; -+ -+ case Class: -+ { -+ TraceClass *c; -+ TraceClassMap::Iterator it; -+ for ( it = _classMap.begin(); -+ it != _classMap.end(); ++it ) { -+ c = &(*it); -+ if (c->name() != name) continue; -+ if (ct) { -+ sc = c->subCost(ct); -+ if (sc <= scTop) continue; -+ scTop = sc; -+ } -+ result = c; -+ } -+ } -+ break; -+ -+ case Object: -+ { -+ TraceObject *o; -+ TraceObjectMap::Iterator it; -+ for ( it = _objectMap.begin(); -+ it != _objectMap.end(); ++it ) { -+ o = &(*it); -+ if (o->name() != name) continue; -+ if (ct) { -+ sc = o->subCost(ct); -+ if (sc <= scTop) continue; -+ scTop = sc; -+ } -+ result = o; -+ } -+ } -+ break; -+ -+ case Instr: -+ if (pt == Function) { -+ TraceInstrMap* instrMap = ((TraceFunction*)parent)->instrMap(); -+ if (!instrMap) break; -+ -+ TraceInstr *instr; -+ TraceInstrMap::Iterator it; -+ for ( it = instrMap->begin(); -+ it != instrMap->end(); ++it ) { -+ instr = &(*it); -+ if (instr->name() != name) continue; -+ result = instr; -+ } -+ } -+ break; -+ -+ case Line: -+ { -+ TraceFunctionSourceList sList; -+ if (pt == Function) -+ sList = ((TraceFunction*)parent)->sourceFiles(); -+ else if (pt == FunctionSource) -+ sList.append((TraceFunctionSource*) parent); -+ else break; -+ -+ TraceLineMap* lineMap; -+ TraceLine* line; -+ TraceLineMap::Iterator it; -+ TraceFunctionSource* fs; -+ for(fs = sList.first(); fs; fs = sList.next()) { -+ lineMap = fs->lineMap(); -+ if (!lineMap) continue; -+ -+ for ( it = lineMap->begin(); -+ it != lineMap->end(); ++it ) { -+ line = &(*it); -+ if (line->name() != name) continue; -+ result = line; -+ } -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return result; -+} -+ -+ -+TraceFunctionCycle* TraceData::functionCycle(TraceFunction* f) -+{ -+ TraceFunctionCycle* cycle; -+ for (cycle=_functionCycles.first();cycle;cycle=_functionCycles.next()) -+ if (cycle->base() == f) return cycle; -+ -+ _functionCycleCount++; -+ cycle = new TraceFunctionCycle(f, _functionCycleCount); -+ -+ _functionCycles.append(cycle); -+ return cycle; -+} -+ -+ -+void TraceData::updateFunctionCycles() -+{ -+ //qDebug("Updating cycles..."); -+ -+ // init cycle info -+ TraceFunctionCycle* cycle; -+ for (cycle=_functionCycles.first();cycle;cycle=_functionCycles.next()) -+ cycle->init(); -+ -+ TraceFunctionMap::Iterator it; -+ for ( it = _functionMap.begin(); it != _functionMap.end(); ++it ) -+ (*it).cycleReset(); -+ -+ if (!Configuration::showCycles()) return; -+ -+ _inFunctionCycleUpdate = true; -+ -+ -+#if 0 -+ int fCount = _functionMap.size(), fNo = 0, progress=0, p; -+ TQString msg = i18n("Recalculating Function Cycles..."); -+ if (_topLevel) _topLevel->showStatus(msg,0); -+#endif -+ -+ // DFS and collapse strong connected components (Tarjan) -+ int pNo = 0; -+ TraceFunction* stackTop; -+ for ( it = _functionMap.begin(); it != _functionMap.end(); ++it ) { -+ -+#if 0 -+ if (_topLevel) { -+ fNo++; -+ p = 100*fNo/fCount; -+ if (p> progress) { -+ progress = p; -+ _topLevel->showStatus(msg, p); -+ } -+ } -+#endif -+ -+ stackTop = 0; -+ (*it).cycleDFS(1, pNo, &stackTop); -+ } -+ -+ // postprocess cycles -+ for (cycle=_functionCycles.first();cycle;cycle=_functionCycles.next()) -+ cycle->setup(); -+ -+ _inFunctionCycleUpdate = false; -+ // we have to invalidate costs because cycles are now taken into account -+ invalidateDynamicCost(); -+ -+#if 0 -+ if (0) if (_topLevel) _topLevel->showStatus(TQString(),0); -+#endif -+} -+ -+void TraceData::updateObjectCycles() -+{ -+} -+ -+ -+void TraceData::updateClassCycles() -+{ -+} -+ -+ -+void TraceData::updateFileCycles() -+{ -+} -+ -+ -diff --git a/kdecachegrind/kdecachegrind/tracedata.h b/kdecachegrind/kdecachegrind/tracedata.h -new file mode 100644 -index 0000000..8fab2b6 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/tracedata.h -@@ -0,0 +1,1967 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Classes holding profiling data for -+ * multiple tracefiles for one command. -+ * See class TraceData first. -+ */ -+ -+#ifndef TRACEDATA_H -+#define TRACEDATA_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "subcost.h" -+#include "utils.h" -+ -+class TQFile; -+ -+/** -+ * All cost items are classes prefixed with "Trace". -+ * "TraceCost" holds basic cost metrics for the simplest, smallest -+ * trace entity: These are events counted for an instruction at -+ * a specific memory address of the traced program. -+ * All other cost items are derived from TraceCost, and add needed -+ * cost metrics, e.g. for a call the number of calls that happened. -+ * -+ * Abstract, i.e. never instantiated cost items are -+ * - TraceCost: Basic cost metrics (instr/read/write access + cache events) -+ * - TraceCallCost: Additional call count cost metric. -+ * - TraceInclusiveCost: Additional TraceCost aggregated. -+ * - TraceListCost: Adds dependency to a list of TraceCost's -+ * - TraceCallListCost: same for list of TraceCallCost's -+ * - TraceInclusiveListCost: same for list of TraceInclusiveCost's -+ * - TraceCostItem: Base for cost items for "interesting" costs: -+ * TraceFunction, TraceClass, TraceFile, TraceObject -+ * -+ * The smallest Cachegrind output is trace data indexed by a source -+ * line number, a TracePartLine. Another one is a call from one -+ * source line of a function to another function, a TracePartLineCall. -+ * All other cost items derive the value by summation of cost metrics -+ * from TraceLineItem and TracePartLineCall costs; their cost is -+ * calculated lazy on demand and cached afterwards. -+ * -+ * For cost items, which are sums over all trace files read in, the -+ * summed cost metrics change when e.g. a new trace file is read. -+ * Thus, their cached costs are invalidated, and again recalculated -+ * only on demand. In the following list, theses cost items are called -+ * "dynamic", the other "fixed" (but neverless calculated lazy). -+ * -+ * Cost Item Type Summation of ... -+ * -+ * TracePartLineCall fixed Read from trace file -+ * TracePartLine fixed Read from trace file -+ * TracePartCall fixed TracePartLineCall's -+ * TraceLineCall dynamic TracePartLineCall's -+ * TraceCall dynamic TraceLineCall's -+ * TraceLine dynamic TracePartLine's and TraceLineCall's -+ * TracePartFunction fixed TracePartLine's / TracePartCall's -+ * TraceFunction dynamic TraceLine's / TraceCall's (called from) -+ * TracePartClass fixed TracePartFunction's -+ * TraceClass dynamic TraceFunction's -+ * TracePartFile fixed TracePartFunction's -+ * TraceFile dynamic TraceFunction's -+ * TracePartObject fixed TracePartFunction's -+ * TraceObject dynamic TraceFunction's -+ * TracePart fixed TracePartLine's -+ * TraceData dynamic TracePart's -+ * -+ * As there exists only one TraceData object for a traced program, its the -+ * owner of some "high level" cost items. The following shows the owner -+ * relationship of the cost item classes, together with references. -+ * -+ * Cost Item Owner (& back ref) Other References to -+ * -+ * TracePartLineCall TraceLineCall -+ * TracePartCall TraceCall TracePartLineCall's -+ * TracePartLine TraceLine TracePartLineCall's -+ * TracePartFunction TraceFunction -+ * TracePartClass TraceClass TracePart -+ * TracePartFile TraceFile TracePart -+ * TracePartObject TraceObject TracePart -+ * TraceLineCall TraceCall TracePartLineCall's -+ * TraceCall TraceFunction TracePartCall's -+ * TraceLine TraceData TraceLineCall's -+ * TraceFunction TraceData TraceCall's (calling) -+ * TraceClass TraceData -+ * TraceFile TraceData -+ * TraceObject TraceData -+ * TracePart TraceData -+ * TraceData Main Application -+ * -+ * Convention: -+ * - The owner has a factory method for owned objects, -+ * and calls addXXX() to install references in other objects -+ * - The owner is first arg in a constructor. -+ */ -+ -+ -+class FixString; -+class FixCost; -+class FixCallCost; -+class FixJump; -+class FixPool; -+class DynPool; -+class TopLevel; -+ -+class TraceCost; -+class TraceCostType; -+class TraceCostMapping; -+class TraceSubMapping; -+class TraceJumpCost; -+class TraceCallCost; -+class TraceInclusiveCost; -+ -+class TracePartInstr; -+class TracePartInstrCall; -+class TracePartLine; -+class TracePartLineCall; -+class TracePartCall; -+class TracePartLineRegion; -+class TracePartFunction; -+class TracePartClass; -+class TracePartObject; -+class TracePartFile; -+ -+class TraceInstr; -+class TraceInstrJump; -+class TraceInstrCall; -+class TraceLine; -+class TraceLineJump; -+class TraceLineCall; -+class TraceCall; -+class TraceLineRegion; -+class TraceFunctionSource; -+class TraceFunction; -+class TraceFunctionCycle; -+class TraceClass; -+class TraceObject; -+class TraceFile; -+class TracePart; -+class TraceData; -+ -+typedef TQPtrList TraceCostList; -+typedef TQPtrList TraceJumpCostList; -+typedef TQPtrList TraceCallCostList; -+typedef TQPtrList TraceInclusiveCostList; -+ -+typedef TQPtrList TracePartCallList; -+typedef TQPtrList TracePartInstrList; -+typedef TQPtrList TracePartLineList; -+typedef TQPtrList TracePartLineRegionList; -+typedef TQPtrList TracePartFunctionList; -+typedef TQPtrList TracePartInstrCallList; -+typedef TQPtrList TracePartLineCallList; -+ -+ -+typedef TQPtrList TraceInstrList; -+typedef TQPtrList TraceLineList; -+typedef TQPtrList TraceInstrCallList; -+typedef TQPtrList TraceLineCallList; -+typedef TQPtrList TraceCallList; -+typedef TQPtrList TraceFileList; -+typedef TQPtrList TraceLineRegionList; -+typedef TQPtrList TraceFunctionSourceList; -+typedef TQPtrList TraceFunctionList; -+typedef TQPtrList TraceFunctionCycleList; -+typedef TQMap TraceObjectMap; -+typedef TQMap TraceClassMap; -+typedef TQMap TraceFileMap; -+typedef TQMap TraceFunctionMap; -+typedef TQMap TraceLineMap; -+ -+ -+/** -+ * Addresses are 64bit values like costs to be able -+ * to always load profile data produced on 64bit -+ * architectures. -+ */ -+class Addr -+{ -+ public: -+ Addr() { _v=0; } -+ Addr(uint64 v) { _v = v; } -+ -+ // Interpretes char data at s as hex (without "0x" prefix) -+ // and return number of interpreted chars. -+ int set(const char *s); -+ bool set(FixString& s); -+ TQString toString() const; -+ // similar to toString(), but adds a space every 4 digits -+ TQString pretty() const; -+ -+ // returns true if this address is in [a-distance;a+distance] -+ bool isInRange(Addr a, int distance); -+ -+ bool operator==(const Addr& a) const { return (_v == a._v); } -+ bool operator!=(const Addr& a) const { return (_v != a._v); } -+ bool operator>(const Addr& a) const { return _v > a._v; } -+ bool operator>=(const Addr& a) const { return _v >= a._v; } -+ bool operator<(const Addr& a) const { return _v < a._v; } -+ bool operator<=(const Addr& a) const { return _v <= a._v; } -+ -+ Addr operator+(int d) const { return Addr(_v + d); } -+ Addr operator-(int d) const { return Addr(_v - d); } -+ -+ private: -+ uint64 _v; -+}; -+ -+typedef TQMap TraceInstrMap; -+ -+ -+/** -+ * Base class for cost items. -+ */ -+class TraceItem -+{ -+public: -+ -+ // RTTI for trace item classes, using type() method -+ enum CostType { Item, Cost, -+ PartInstr, Instr, -+ PartLine, Line, -+ PartInstrJump, InstrJump, -+ PartLineJump, LineJump, -+ PartInstrCall, InstrCall, -+ PartLineCall, LineCall, -+ PartCall, Call, -+ PartLineRegion, LineRegion, -+ PartFunction, FunctionSource, Function, FunctionCycle, -+ PartClass, Class, ClassCycle, -+ PartFile, File, FileCycle, -+ PartObject, Object, ObjectCycle, -+ Part, Data, -+ MaxCostType, NoCostType }; -+ -+ TraceItem(); -+ virtual ~TraceItem(); -+ -+ virtual CostType type() const { return Item; } -+ -+ // conversion of item type to locale independent string (e.g. for config) -+ static TQString typeName(CostType); -+ static CostType costType(TQString); -+ // the versions below should be used for user visible strings, as -+ // these use localisation settings -+ static TQString i18nTypeName(CostType); -+ static CostType i18nCostType(TQString); -+ // clean up some static data -+ static void cleanup(); -+ -+ /** -+ * Returns dynamic name info (without type) -+ */ -+ virtual TQString name() const; -+ -+ /** -+ * Same as name, but sometimes nicer for humans :-) -+ */ -+ virtual TQString prettyName() const; -+ -+ /** -+ * Returns text of all cost metrics -+ */ -+ virtual TQString costString(TraceCostMapping*); -+ -+ /** -+ * Returns type name + dynamic name -+ */ -+ TQString fullName() const; -+ -+ /** -+ * Returns full name + cost text -+ */ -+ TQString toString(); -+ -+ /** -+ * Set all cost counters to zero -+ */ -+ virtual void clear(); -+ -+ /** Invalidate the cost attributes. -+ * An invalidated object needs to be recalculated when a cost -+ * attribute is requested (e.g. by subCost()). -+ * Has to be overwritten by subclasses when the cost influences costs of -+ * other cost items. If only one item depends on the cost of this item, -+ * it can by set with setDependant() without a need for overwriting. -+ */ -+ virtual void invalidate(); -+ -+ /** -+ * Sets a dependant to be invalidated when this cost is invalidated. -+ * Call this function directly after the constructor. -+ */ -+ void setDependant(TraceItem* d) { _dep = d; } -+ -+ TraceItem* dependant() { return _dep; } -+ -+ /** -+ * If this item is from a single profile data file, position -+ * points to a TracePart, otherwise to a TraceData object. -+ */ -+ void setPosition(TraceItem* p) { _position = p; } -+ -+ // getters for specific positions, to be overwritten -+ virtual TracePart* part(); -+ virtual const TracePart* part() const; -+ virtual TraceData* data(); -+ virtual const TraceData* data() const; -+ -+ protected: -+ /** Updates cost attributes. -+ * This has to be called by subclasses that access cost attributes -+ * directly -+ */ -+ virtual void update(); -+ -+ bool _dirty; -+ -+ TraceItem* _position; -+ TraceItem* _dep; -+ -+ private: -+ static TQString *_typeName, *_i18nTypeName; -+}; -+ -+ -+ -+/** -+ * An array of basic cost metrics for a trace item. -+ * -+ * The semantic of specific indexes is stored in the -+ * TraceCostMapping of the TraceData object holding this TraceCost. -+ */ -+class TraceCost: public TraceItem -+{ -+public: -+ /** -+ * The maximal number of subcosts a TraceCost can have. -+ */ -+ static const int MaxRealIndex; -+#define MaxRealIndexValue 13 -+ static const int InvalidIndex; -+ -+ -+ TraceCost(); -+ virtual ~TraceCost(); -+ -+ virtual CostType type() const { return Cost; } -+ virtual TQString costString(TraceCostMapping*); -+ -+ virtual void clear(); -+ -+ // set the cost according to a submapping and a list of ASCII numbers -+ void set(TraceSubMapping*, const char*); -+ void set(TraceSubMapping*, FixString&); -+ // add a cost according to a submapping and a list of ASCII numbers -+ void addCost(TraceSubMapping*, const char*); -+ void addCost(TraceSubMapping*, FixString&); -+ // add the cost of another item -+ void addCost(TraceCost* item); -+ void addCost(int index, SubCost value); -+ -+ // maximal cost -+ void maxCost(TraceSubMapping*, FixString&); -+ void maxCost(TraceCost* item); -+ void maxCost(int index, SubCost value); -+ TraceCost diff(TraceCost* item); -+ -+ virtual void invalidate(); -+ -+ /** Returns a sub cost. This automatically triggers -+ * a call to update() if needed. -+ */ -+ SubCost subCost(TraceCostType*); -+ -+ /** -+ * Same as above, but only for real types -+ */ -+ SubCost subCost(int); -+ -+ /** Returns a cost attribute converted to a string -+ * (with space after every 3 digits) -+ */ -+ TQString prettySubCost(TraceCostType*); -+ -+ protected: -+ virtual void update(); -+ -+ SubCost _cost[MaxRealIndexValue]; -+ int _count; // only _count first indexes of _cost are used -+ -+ // cache last virtual subcost for faster access -+ SubCost _cachedCost; -+ TraceCostType* _cachedType; -+}; -+ -+ -+ -+/** -+ * A cost type, e.g. "L1 Read Miss", short "l1rm". -+ * -+ * We distinguish "real" cost types, where the values come -+ * from the trace file, and "virtual" cost types, which -+ * are calculated from the real ones. -+ * -+ * For a virtual cost type, set a formula to calculate it: -+ * e.g. for "Read Misses" : "l1rm + l2rm". -+ * To allow for parsing, you must specify a TraceCostMapping -+ * with according cost types (e.g. "l1rm" and "l2rm" for above formula). -+ * -+ * The cost type with empty name is the "const" cost type. -+ */ -+class TraceCostType -+{ -+public: -+ -+ /** -+ * is a short (non-localized) identifier for the cost type, -+ * e.g. "l1rm". -+ * is a long localized string, e.g. "L1 Read Miss" -+ * uses short names to reference other types -+ */ -+ TraceCostType(TQString name, -+ TQString longName = TQString(), -+ TQString formula = TQString()); -+ -+ void setName(TQString n) { _name = n; } -+ void setLongName(TQString n) { _longName = n; } -+ void setMapping(TraceCostMapping* m); -+ void setFormula(TQString); -+ // default arg is for specifying a real type, but index unknown -+ void setRealIndex(int r = TraceCost::MaxRealIndex); -+ -+ const TQString& name() { return _name; } -+ const TQString& longName() { return _longName; } -+ const TQString& formula() { return _formula; } -+ TraceCostMapping* mapping() { return _mapping; } -+ int realIndex() { return _realIndex; } -+ bool isReal() { return _formula.isEmpty(); } -+ TQColor color(); -+ -+ /* -+ * returns true if all cost type names can be resolved in formula -+ */ -+ bool parseFormula(); -+ TQString parsedFormula(); -+ -+ SubCost subCost(TraceCost*); -+ -+ /* -+ * For virtual costs, returns a histogram for use with -+ * partitionPixmap(). -+ * Returns maximal real index. -+ */ -+ int histCost(TraceCost* c, double total, double* hist); -+ -+ // application wide known types, referenced by short name -+ // next 2 functions return a new type object instance -+ static TraceCostType* knownRealType(TQString); -+ static TraceCostType* knownVirtualType(TQString); -+ static void add(TraceCostType*); -+ static bool remove(TQString); -+ static int knownTypeCount(); -+ static TraceCostType* knownType(int); -+ -+private: -+ -+ TQString _name, _longName, _formula; -+ TraceCostMapping* _mapping; -+ bool _parsed, _inParsing; -+ // index MaxRealIndex is for constant addition -+ int _coefficient[MaxRealIndexValue]; -+ int _realIndex; -+ -+ static TQPtrList* _knownTypes; -+}; -+ -+ -+/** -+ * A class for managing a set of cost types. -+ * -+ * Each cost type has an index: -+ * - Real costs are in range [0 .. TraceCost:MaxRealIndex[ -+ * - Virtual costs are in range [MaxRealIndex, ...] -+ */ -+class TraceCostMapping -+{ -+public: -+ TraceCostMapping(); -+ ~TraceCostMapping(); -+ -+ /** -+ * Defines a sub mapping with a list of real types -+ * If is false, checks if this is a existing sub mapping. -+ */ -+ TraceSubMapping* subMapping(TQString types, bool create = true); -+ -+ // "knows" about some real types -+ int addReal(TQString); -+ int add(TraceCostType*); -+ bool remove(TraceCostType*); -+ int realCount() { return _realCount; } -+ int virtualCount() { return _virtualCount; } -+ int minVirtualIndex() { return TraceCost::MaxRealIndex; } -+ TraceCostType* type(int); -+ TraceCostType* realType(int); -+ TraceCostType* virtualType(int); -+ TraceCostType* type(TQString); -+ TraceCostType* typeForLong(TQString); -+ int realIndex(TQString); -+ int index(TQString); -+ TQColor* realColors() { return _realColor; } -+ -+ /** -+ * Adds all known virtual types that can be parsed -+ */ -+ int addKnownVirtualTypes(); -+ -+private: -+ // we support only a fixed number of real and virtual types -+ TraceCostType* _real[MaxRealIndexValue]; -+ TQColor _realColor[MaxRealIndexValue]; -+ TraceCostType* _virtual[MaxRealIndexValue]; -+ int _realCount, _virtualCount; -+}; -+ -+/** -+ * A submapping of a TraceCostMapping -+ * -+ * This is a fixed ordered list of indexes for real cost types -+ * in a mapping. -+ * -+ * You can define a mapping by requesting submappings. Undefined cost -+ * types will get a new real type index. -+ * TraceCostMapping m; -+ * sm1 = m.subMapping("Event1 Cost1 Cost2"); // returns submap [0,1,2] -+ * sm2 = m.subMapping("Event2 Cost3 Event1"); // returns submap [3,4,0] -+ * Real types of m will be: -+ * (0:Event1, 1:Cost1, 2:Cost2, 3:Event2, 4:Cost3) -+ */ -+class TraceSubMapping -+{ -+public: -+ TraceSubMapping(TraceCostMapping*); -+ -+ bool append(TQString, bool create=true); -+ bool append(int); -+ void clear(); -+ -+ /** -+ * Get number of used indexes -+ */ -+ int count() { return _count; } -+ -+ /** -+ * Is this submapping the identity( i.e. realIndex(i)=i ) ? -+ * This often allows for optimizations. -+ */ -+ bool isIdentity() { return _isIdentity; } -+ int realIndex(int i) -+ { return (i<0 || i>=_count) ? TraceCost::InvalidIndex : _realIndex[i]; } -+ -+ /* -+ * Allows an iteration over the sorted list of all real indexes not used in -+ * this submapping, up to topIndex (use TraceCost::MaxRealIndex for all). -+ * Usage: for(i = firstUnused(); i < topIndex; i = nextUnused(i)) { LOOP } -+ */ -+ int firstUnused() { return _firstUnused; } -+ int nextUnused(int i) { -+ if (i<0 || i>=TraceCost::MaxRealIndex) return TraceCost::InvalidIndex; -+ return _nextUnused[i]; } -+ -+private: -+ TraceCostMapping* _mapping; -+ int _count, _firstUnused; -+ bool _isIdentity; -+ int _realIndex[MaxRealIndexValue]; -+ int _nextUnused[MaxRealIndexValue]; -+}; -+ -+ -+/** -+ * Cost of a (conditional) jump. -+ */ -+class TraceJumpCost: public TraceItem -+{ -+ public: -+ TraceJumpCost(); -+ virtual ~TraceJumpCost(); -+ -+ // reimplementations for cost addition -+ virtual TQString costString(TraceCostMapping* m); -+ virtual void clear(); -+ -+ void addCost(TraceJumpCost*); -+ -+ // additional cost metrics -+ SubCost followedCount(); -+ SubCost executedCount(); -+ void addFollowedCount(SubCost c) { _followedCount += c; } -+ void addExecutedCount(SubCost c) { _executedCount += c; } -+ -+ protected: -+ SubCost _executedCount, _followedCount; -+}; -+ -+ -+ -+/** -+ * Cost item with additional call count metric. -+ */ -+class TraceCallCost: public TraceCost -+{ -+ public: -+ TraceCallCost(); -+ virtual ~TraceCallCost(); -+ -+ // reimplementations for cost addition -+ virtual TQString costString(TraceCostMapping* m); -+ virtual void clear(); -+ -+ // additional cost metric -+ SubCost callCount(); -+ TQString prettyCallCount(); -+ void addCallCount(SubCost c); -+ -+ protected: -+ SubCost _callCount; -+}; -+ -+ -+/** -+ * Cost item with additional inclusive metric -+ */ -+class TraceInclusiveCost: public TraceCost -+{ -+ public: -+ TraceInclusiveCost(); -+ virtual ~TraceInclusiveCost(); -+ -+ // reimplementations for cost addition -+ virtual TQString costString(TraceCostMapping* m); -+ virtual void clear(); -+ -+ // additional cost metric -+ TraceCost* inclusive(); -+ void addInclusive(TraceCost*); -+ -+ protected: -+ TraceCost _inclusive; -+}; -+ -+ -+/** -+ * Cost Item -+ * dependend on a list of cost items. -+ */ -+class TraceListCost: public TraceCost -+{ -+ public: -+ TraceListCost(); -+ virtual ~TraceListCost(); -+ -+ // reimplementation for dependency list -+ virtual void update(); -+ -+ TraceCostList& deps() { return _deps; } -+ void addDep(TraceCost*); -+ TraceCost* findDepFromPart(TracePart*); -+ -+ protected: -+ // overwrite in subclass to change update behaviour -+ virtual bool onlyActiveParts() { return false; } -+ -+ TraceCostList _deps; -+ -+ private: -+ // very temporary: cached -+ TraceCost* _lastDep; -+}; -+ -+ -+/** -+ * Jump Cost Item -+ * dependend on a list of Jump cost items. -+ */ -+class TraceJumpListCost: public TraceJumpCost -+{ -+ public: -+ TraceJumpListCost(); -+ virtual ~TraceJumpListCost(); -+ -+ // reimplementation for dependency list -+ virtual void update(); -+ -+ TraceJumpCostList deps() { return _deps; } -+ void addDep(TraceJumpCost*); -+ TraceJumpCost* findDepFromPart(TracePart*); -+ -+ protected: -+ // overwrite in subclass to change update behaviour -+ virtual bool onlyActiveParts() { return false; } -+ -+ TraceJumpCostList _deps; -+ -+ private: -+ // very temporary: cached -+ TraceJumpCost* _lastDep; -+}; -+ -+ -+ -+ -+/** -+ * Call Cost Item -+ * dependend on a list of Call cost items. -+ */ -+class TraceCallListCost: public TraceCallCost -+{ -+ public: -+ TraceCallListCost(); -+ virtual ~TraceCallListCost(); -+ -+ // reimplementation for dependency list -+ virtual void update(); -+ -+ TraceCallCostList deps() { return _deps; } -+ void addDep(TraceCallCost*); -+ TraceCallCost* findDepFromPart(TracePart*); -+ -+ protected: -+ // overwrite in subclass to change update behaviour -+ virtual bool onlyActiveParts() { return false; } -+ -+ TraceCallCostList _deps; -+ -+ private: -+ // very temporary: cached -+ TraceCallCost* _lastDep; -+}; -+ -+ -+/** -+ * Inclusive Cost Item dependend on a list of inclusive cost items. -+ */ -+class TraceInclusiveListCost: public TraceInclusiveCost -+{ -+ public: -+ TraceInclusiveListCost(); -+ virtual ~TraceInclusiveListCost(); -+ -+ // reimplementation for dependency -+ virtual void update(); -+ -+ TraceInclusiveCostList deps() { return _deps; } -+ void addDep(TraceInclusiveCost*); -+ TraceInclusiveCost* findDepFromPart(TracePart*); -+ -+ protected: -+ // overwrite in subclass to change update behaviour -+ virtual bool onlyActiveParts() { return false; } -+ -+ TraceInclusiveCostList _deps; -+ -+ private: -+ // very temporary: cached -+ TraceInclusiveCost* _lastDep; -+}; -+ -+ -+ -+ -+ -+/*----------------------------------------------------------------- -+ * Classes for cost items of one trace file, i.e. a "trace part" -+ *----------------------------------------------------------------- -+ */ -+ -+/** -+ * Cost of jump at a instruction code address from a trace file. -+ */ -+class TracePartInstrJump: public TraceJumpCost -+{ -+ public: -+ TracePartInstrJump(TraceInstrJump*, TracePartInstrJump*); -+ virtual ~TracePartInstrJump(); -+ -+ virtual CostType type() const { return PartInstrJump; } -+ // fix cost item -+ virtual void update() {} -+ TraceInstrJump* instrJump() const { return (TraceInstrJump*) _dep; } -+ TracePartInstrJump* next() const { return _next; } -+ -+ private: -+ // chaining all parts for InstrJump -+ TracePartInstrJump* _next; -+}; -+ -+ -+/** -+ * Cost of a call at a instruction code address from a trace file. -+ * Cost is always up to date, no lazy update needed. -+ */ -+class TracePartInstrCall: public TraceCallCost -+{ -+public: -+ TracePartInstrCall(TraceInstrCall*); -+ virtual ~TracePartInstrCall(); -+ -+ virtual CostType type() const { return PartInstrCall; } -+ // fix cost item -+ virtual void update() {} -+ TraceInstrCall* instrCall() const { return (TraceInstrCall*) _dep; } -+}; -+ -+ -+/** -+ * Cost of a code instruction address from a trace file. -+ * Cost is always up to date, no lazy update needed. -+ */ -+class TracePartInstr: public TraceCost -+{ -+public: -+ TracePartInstr(TraceInstr*); -+ virtual ~TracePartInstr(); -+ -+ virtual CostType type() const { return PartInstr; } -+ // fix cost item -+ virtual void update() {} -+ -+ TraceInstr* instr() const { return (TraceInstr*)_dep; } -+}; -+ -+ -+/** -+ * Cost of jump at a source line from a trace file. -+ */ -+class TracePartLineJump: public TraceJumpCost -+{ -+ public: -+ TracePartLineJump(TraceLineJump*); -+ virtual ~TracePartLineJump(); -+ -+ virtual CostType type() const { return PartLineJump; } -+ // fix cost item -+ virtual void update() {} -+ TraceLineJump* lineJump() const { return (TraceLineJump*) _dep; } -+}; -+ -+ -+/** -+ * Cost of a call at a line from a trace file. -+ * Cost is always up to date, no lazy update needed. -+ */ -+class TracePartLineCall: public TraceCallCost -+{ -+public: -+ TracePartLineCall(TraceLineCall*); -+ virtual ~TracePartLineCall(); -+ -+ virtual CostType type() const { return PartLineCall; } -+ // fix cost item -+ virtual void update() {} -+ TraceLineCall* lineCall() const { return (TraceLineCall*) _dep; } -+}; -+ -+ -+ -+/** -+ * Cost of a line from a trace file. -+ * Cost is always up to date, no lazy update needed. -+ */ -+class TracePartLine: public TraceCost -+{ -+public: -+ TracePartLine(TraceLine*); -+ virtual ~TracePartLine(); -+ -+ virtual CostType type() const { return PartLine; } -+ // fix cost item -+ virtual void update() {} -+ -+ TraceLine* line() const { return (TraceLine*)_dep; } -+}; -+ -+ -+/** -+ * Cost of a source region. -+ */ -+class TracePartLineRegion: public TraceInclusiveCost -+{ -+public: -+ TracePartLineRegion(TraceLineRegion*); -+ virtual ~TracePartLineRegion(); -+ -+ virtual CostType type() const { return PartLineRegion; } -+ virtual void update(); -+ -+ TraceLineRegion* region() const { return (TraceLineRegion*)_dep; } -+}; -+ -+ -+/** -+ * Cost of a call at a function to another function, -+ * from a single trace file. -+ */ -+class TracePartCall: public TraceCallListCost -+{ -+public: -+ TracePartCall(TraceCall* call); -+ virtual ~TracePartCall(); -+ -+ virtual CostType type() const { return PartCall; } -+ // calls a function itself? -+ bool isRecursion(); -+ -+ // reimplementation for dependency list -+ virtual void update(); -+ -+ TraceCall* call() const { return (TraceCall*)_dep; } -+ -+ FixCallCost* setFirstFixCallCost(FixCallCost* fc) -+ { FixCallCost* t = _firstFixCallCost; _firstFixCallCost = fc; return t; } -+ FixCallCost* firstFixCallCost() const { return _firstFixCallCost; } -+ -+private: -+ FixCallCost* _firstFixCallCost; -+}; -+ -+ -+/** -+ * Cost of a function, -+ * from a single trace file. -+ */ -+class TracePartFunction: public TraceInclusiveCost -+{ -+public: -+ TracePartFunction(TraceFunction*, -+ TracePartObject*, TracePartFile*); -+ virtual ~TracePartFunction(); -+ -+ virtual CostType type() const { return PartFunction; } -+ virtual void update(); -+ virtual TQString costString(TraceCostMapping* m); -+ -+ void addPartInstr(TracePartInstr*); -+ void addPartLine(TracePartLine*); -+ void addPartCaller(TracePartCall*); -+ void addPartCalling(TracePartCall*); -+ -+ TraceFunction* function() { return (TraceFunction*) _dep; } -+ TracePartObject* partObject() { return _partObject; } -+ TracePartClass* partClass() { return _partClass; } -+ TracePartFile* partFile() { return _partFile; } -+ const TracePartCallList& partCallers() { return _partCallers; } -+ const TracePartCallList& partCallings() { return _partCallings; } -+ void setPartObject(TracePartObject* o) { _partObject = o; } -+ void setPartClass(TracePartClass* c) { _partClass = c; } -+ void setPartFile(TracePartFile* f) { _partFile = f; } -+ -+ /* for linked list of FixXXX objects */ -+ FixCost* setFirstFixCost(FixCost* fc) -+ { FixCost* t = _firstFixCost; _firstFixCost = fc; return t; } -+ FixCost* firstFixCost() const { return _firstFixCost; } -+ FixJump* setFirstFixJump(FixJump* fj) -+ { FixJump* t = _firstFixJump; _firstFixJump = fj; return t; } -+ FixJump* firstFixJump() const { return _firstFixJump; } -+ -+ // additional cost metrics -+ SubCost calledCount(); -+ SubCost callingCount(); -+ TQString prettyCalledCount(); -+ TQString prettyCallingCount(); -+ int calledContexts(); -+ int callingContexts(); -+ -+private: -+ TracePartObject* _partObject; -+ TracePartClass* _partClass; -+ TracePartFile* _partFile; -+ -+ TracePartCallList _partCallings; -+ TracePartCallList _partCallers; -+ TracePartInstrList _partInstr; -+ TracePartLineList _partLines; -+ -+ // cached -+ SubCost _calledCount, _callingCount; -+ int _calledContexts, _callingContexts; -+ -+ FixCost* _firstFixCost; -+ FixJump* _firstFixJump; -+}; -+ -+ -+/** -+ * Cost of a class, -+ * from a single trace file. -+ */ -+class TracePartClass: public TraceInclusiveListCost -+{ -+public: -+ TracePartClass(TraceClass*); -+ virtual ~TracePartClass(); -+ -+ virtual CostType type() const { return PartClass; } -+ TQString prettyName() const; -+ -+ TraceClass* cls() { return (TraceClass*)_dep; } -+ void addPartFunction(TracePartFunction* f) { addDep(f); } -+}; -+ -+ -+/** -+ * Cost of a source file, -+ * from a single trace file. -+ */ -+class TracePartFile: public TraceInclusiveListCost -+{ -+public: -+ TracePartFile(TraceFile*); -+ virtual ~TracePartFile(); -+ -+ virtual CostType type() const { return PartFile; } -+ TraceFile* file() { return (TraceFile*)_dep; } -+ void addPartFunction(TracePartFunction* f) { addDep(f); } -+}; -+ -+ -+/** -+ * Cost of a object, -+ * from a single trace file. -+ */ -+class TracePartObject: public TraceInclusiveListCost -+{ -+public: -+ TracePartObject(TraceObject*); -+ virtual ~TracePartObject(); -+ -+ virtual CostType type() const { return PartObject; } -+ TraceObject* object() const { return (TraceObject*)_dep; } -+ void addPartFunction(TracePartFunction* f) { addDep(f); } -+}; -+ -+ -+ -+/** -+ * A Trace Part: All data read from a trace file, containing all costs -+ * that happened in a specified time interval of the executed command. -+ */ -+class TracePart: public TraceListCost -+{ -+public: -+ TracePart(TraceData*, TQFile* file); -+ virtual ~TracePart(); -+ -+ virtual CostType type() const { return Part; } -+ virtual TracePart* part() { return this; } -+ virtual const TracePart* part() const { return this; } -+ -+ TQString shortName() const; -+ TQString prettyName() const; -+ TQFile* file() const { return _file; } -+ TQString name() const { return _name; } -+ TQString description() const { return _descr; } -+ TQString trigger() const { return _trigger; } -+ TQString timeframe() const { return _timeframe; } -+ TQString version() const { return _version; } -+ int partNumber() { return _number; } -+ int threadID() { return _tid; } -+ int processID() { return _pid; } -+ void setDescription(const TQString& d) { _descr = d; } -+ void setTrigger(const TQString& t) { _trigger = t; } -+ void setTimeframe(const TQString& t) { _timeframe = t; } -+ void setVersion(const TQString& v) { _version = v; } -+ void setPartNumber(int n); -+ void setThreadID(int t); -+ void setProcessID(int p); -+ TraceCost* totals() { return &_totals; } -+ /* we get owner of the submapping */ -+ void setFixSubMapping(TraceSubMapping* sm) { _fixSubMapping = sm; } -+ TraceSubMapping* fixSubMapping() { return _fixSubMapping; } -+ -+ // returns true if something changed -+ bool activate(bool); -+ bool isActive() { return _active; } -+ -+private: -+ TQFile* _file; -+ TQString _name; -+ TQString _descr; -+ TQString _trigger; -+ TQString _timeframe; -+ TQString _version; -+ -+ int _number, _tid, _pid; -+ -+ bool _active; -+ -+ // the totals line -+ TraceCost _totals; -+ -+ // submapping for all fix costs of this part -+ TraceSubMapping* _fixSubMapping; -+}; -+ -+ -+class TracePartList: public TQPtrList -+{ -+ public: -+ TQString names() const; -+ protected: -+ int compareItems ( Item item1, Item item2 ); -+}; -+ -+ -+/*----------------------------------------------------------------- -+ * Classes for cost items summed up from multiple trace parts -+ *----------------------------------------------------------------- -+ */ -+ -+ -+/** -+ * A jump from an instruction to another inside of a function -+ */ -+class TraceInstrJump: public TraceJumpCost -+{ -+public: -+ TraceInstrJump(TraceInstr* instrFrom, TraceInstr* instrTo, -+ bool isCondJump); -+ virtual ~TraceInstrJump(); -+ -+ virtual CostType type() const { return InstrJump; } -+ virtual TQString name() const; -+ -+ virtual void update(); -+ -+ TraceInstr* instrFrom() const { return _instrFrom; } -+ TraceInstr* instrTo() const { return _instrTo; } -+ bool isCondJump() const { return _isCondJump; } -+ -+ // part factory -+ TracePartInstrJump* partInstrJump(TracePart*); -+ -+ private: -+ TraceInstr *_instrFrom, *_instrTo; -+ bool _isCondJump; -+ // list of parts for this InstrJump -+ TracePartInstrJump* _first; -+}; -+ -+class TraceInstrJumpList: public TQPtrList -+{ -+ public: -+ TraceInstrJumpList() { _sortLow = true; } -+ void setSortLow(bool s) { _sortLow = s; } -+ -+ protected: -+ int compareItems ( Item item1, Item item2 ); -+ -+ private: -+ bool _sortLow; -+}; -+ -+ -+/** -+ * A jump from one line to another inside of a function. -+ */ -+class TraceLineJump: public TraceJumpListCost -+{ -+ public: -+ TraceLineJump(TraceLine* lineFrom, TraceLine* lineTo, -+ bool isCondJump); -+ virtual ~TraceLineJump(); -+ -+ virtual CostType type() const { return LineJump; } -+ virtual TQString name() const; -+ -+ TraceLine* lineFrom() const { return _lineFrom; } -+ TraceLine* lineTo() const { return _lineTo; } -+ bool isCondJump() { return _isCondJump; } -+ -+ // part factory -+ TracePartLineJump* partLineJump(TracePart*); -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ private: -+ TraceLine *_lineFrom, *_lineTo; -+ bool _isCondJump; -+}; -+ -+ -+class TraceLineJumpList: public TQPtrList -+{ -+ public: -+ TraceLineJumpList() { _sortLow = true; } -+ void setSortLow(bool s) { _sortLow = s; } -+ -+ protected: -+ int compareItems ( Item item1, Item item2 ); -+ -+ private: -+ bool _sortLow; -+}; -+ -+ -+/** -+ * A call from an instruction of one function to another function -+ */ -+class TraceInstrCall: public TraceCallListCost -+{ -+ public: -+ TraceInstrCall(TraceCall* call, TraceInstr* instr); -+ virtual ~TraceInstrCall(); -+ -+ virtual CostType type() const { return InstrCall; } -+ virtual TQString name() const; -+ -+ TraceInstr* instr() const { return _instr; } -+ TraceCall* call() const { return _call; } -+ -+ // part factory -+ TracePartInstrCall* partInstrCall(TracePart*, TracePartCall*); -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ private: -+ TraceInstr* _instr; -+ TraceCall* _call; -+}; -+ -+ -+/** -+ * A call from a line of one function to another function. -+ */ -+class TraceLineCall: public TraceCallListCost -+{ -+ public: -+ TraceLineCall(TraceCall* call, TraceLine* line); -+ virtual ~TraceLineCall(); -+ -+ virtual CostType type() const { return LineCall; } -+ virtual TQString name() const; -+ -+ TraceLine* line() const { return _line; } -+ TraceCall* call() const { return _call; } -+ -+ // part factory -+ TracePartLineCall* partLineCall(TracePart*, TracePartCall*); -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ private: -+ TraceLine* _line; -+ TraceCall* _call; -+}; -+ -+ -+/** -+ * A call from one to another function. -+ * Consists of a list a TraceLineCalls -+ */ -+class TraceCall: public TraceCallListCost -+{ -+ public: -+ TraceCall(TraceFunction* caller, TraceFunction* called); -+ virtual ~TraceCall(); -+ -+ virtual CostType type() const { return Call; } -+ virtual TQString name() const; -+ -+ // calls a function itself? -+ bool isRecursion() { return _caller == _called; } -+ -+ // return cycle number >0 if call is inside of a cycle -+ int inCycle(); -+ // we need some special handling for cycle calls -+ void update(); -+ -+ void invalidateDynamicCost(); -+ -+ // factories -+ TracePartCall* partCall(TracePart*, -+ TracePartFunction*, TracePartFunction*); -+ TraceLineCall* lineCall(TraceLine*); -+ TraceInstrCall* instrCall(TraceInstr*); -+ -+ TraceFunction* caller(bool skipCycle=false) const; -+ TraceFunction* called(bool skipCycle=false) const; -+ TQString callerName(bool skipCycle=false) const; -+ TQString calledName(bool skipCycle=false) const; -+ const TraceLineCallList& lineCalls() const { return _lineCalls; } -+ const TraceInstrCallList& instrCalls() const { return _instrCalls; } -+ -+ FixCallCost* setFirstFixCost(FixCallCost* fc) -+ { FixCallCost* t = _firstFixCost; _firstFixCost = fc; return t; } -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ private: -+ TraceInstrCallList _instrCalls; -+ TraceLineCallList _lineCalls; -+ TraceFunction* _caller; -+ TraceFunction* _called; -+ -+ FixCallCost* _firstFixCost; -+}; -+ -+ -+/** -+ * A code instruction address of the program. -+ * Consists of a list a TracePartInstr from different trace files -+ * and a list of TraceInstrCalls if there are calls from this address. -+ */ -+class TraceInstr: public TraceListCost -+{ -+ public: -+ TraceInstr(); -+ virtual ~TraceInstr(); -+ -+ virtual CostType type() const { return Instr; } -+ virtual TQString name() const; -+ TQString prettyName() const; -+ -+ bool isValid() { return _addr != Addr(0); } -+ -+ // factories -+ TracePartInstr* partInstr(TracePart* part, -+ TracePartFunction* partFunction); -+ TraceInstrJump* instrJump(TraceInstr* to, bool isCondJump); -+ -+ void addInstrCall(TraceInstrCall*); -+ -+ Addr addr() const { return _addr; } -+ TraceFunction* function() const { return _function; } -+ TraceLine* line() const { return _line; } -+ const TraceInstrJumpList& instrJumps() const { return _instrJumps; } -+ const TraceInstrCallList& instrCalls() const { return _instrCalls; } -+ bool hasCost(TraceCostType*); -+ -+ // only to be called after default constructor -+ void setAddr(const Addr addr) { _addr = addr; } -+ void setFunction(TraceFunction* f) { _function = f; } -+ void setLine(TraceLine* l) { _line = l; } -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ private: -+ Addr _addr; -+ TraceFunction* _function; -+ TraceLine* _line; -+ -+ TraceInstrJumpList _instrJumps; -+ TraceInstrCallList _instrCalls; -+}; -+ -+ -+/** -+ * A source line of the program. -+ * Consists of a list a TracePartLines from different trace files -+ * and a list of TraceLineCalls if there are calls from this line. -+ */ -+class TraceLine: public TraceListCost -+{ -+public: -+ TraceLine(); -+ virtual ~TraceLine(); -+ -+ virtual CostType type() const { return Line; } -+ virtual TQString name() const; -+ TQString prettyName() const; -+ -+ // factories -+ TracePartLine* partLine(TracePart* part, -+ TracePartFunction* partFunction); -+ TraceLineJump* lineJump(TraceLine* to, bool isCondJump); -+ -+ void addLineCall(TraceLineCall*); -+ -+ -+ bool isValid() { return _sourceFile != 0; } -+ bool hasCost(TraceCostType*); -+ TraceFunctionSource* functionSource() const { return _sourceFile; } -+ uint lineno() const { return _lineno; } -+ const TraceLineCallList& lineCalls() const { return _lineCalls; } -+ const TraceLineJumpList& lineJumps() const { return _lineJumps; } -+ -+ // only to be called after default constructor -+ void setSourceFile(TraceFunctionSource* sf) { _sourceFile = sf; } -+ void setLineno(uint lineno) { _lineno = lineno; } -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ private: -+ TraceFunctionSource* _sourceFile; -+ uint _lineno; -+ -+ TraceLineJumpList _lineJumps; -+ TraceLineCallList _lineCalls; -+}; -+ -+ -+/* -+ * Base class for all costs which -+ * represent "interesting" items or group of items -+ * with settable name and inclusive cost -+ */ -+class TraceCostItem: public TraceInclusiveListCost -+{ -+ public: -+ TraceCostItem(); -+ virtual ~TraceCostItem(); -+ -+ virtual TQString name() const { return _name; } -+ virtual void setName(const TQString& name) { _name = name; } -+ -+ protected: -+ bool onlyActiveParts() { return true; } -+ -+ protected: -+ TQString _name; -+}; -+ -+ -+/** -+ * Cost of a source region. -+ */ -+class TraceLineRegion: public TraceInclusiveListCost -+{ -+public: -+ TraceLineRegion(uint from, uint to, TQString name); -+ virtual ~TraceLineRegion(); -+ -+ virtual CostType type() const { return LineRegion; } -+ virtual void update(); -+ -+ uint from() const { return _from; } -+ uint to() const { return _to; } -+ TQString name() const { return _name; } -+ -+ // factories -+ TracePartLine* partLineRegion(TracePart* part, -+ TracePartFunction* partFunction); -+ private: -+ uint _from, _to; -+ TQString _name; -+}; -+ -+ -+/** -+ * A container helper class for TraceFunction for source lines -+ * where a function is implemented in. -+ * With inlining, lines of the same function can come from -+ * different source files. -+ * An instance of this class holds all lines of one source file -+ * for a function in a map -+ */ -+class TraceFunctionSource: public TraceCost -+{ -+public: -+ TraceFunctionSource(TraceFunction*, TraceFile*); -+ virtual ~TraceFunctionSource(); -+ -+ virtual CostType type() const { return FunctionSource; } -+ virtual TQString name() const; -+ -+ // reimplementation for dependency map -+ virtual void update(); -+ -+ TraceFile* file() const { return _file; } -+ TraceFunction* function() const { return _function; } -+ uint firstLineno(); -+ uint lastLineno(); -+ TraceLineMap* lineMap(); -+ -+ void invalidateDynamicCost(); -+ -+ /* factories */ -+ TraceLine* line(uint lineno, bool createNew = true); -+ TraceLineRegion* region(uint from, uint to, TQString name, -+ bool createNew = true); -+ -+ private: -+ TraceFile* _file; -+ TraceFunction* _function; -+ TraceLineMap* _lineMap; -+ TraceLine* _line0; -+ TraceLineRegionList* _regions; -+ -+ bool _lineMapFilled; -+}; -+ -+ -+/** -+ * For temporary assoziation of objects with TraceFunctions. -+ * Used in coverage analysis and TreeMap drawing. -+ */ -+class TraceAssoziation -+{ -+ public: -+ /** -+ * Creates an invalid assoziation. -+ */ -+ TraceAssoziation(); -+ virtual ~TraceAssoziation(); -+ -+ // for runtime detection -+ virtual int rtti() { return 0; } -+ -+ /** -+ * Could we set the function assoziation to ourself? -+ * This only can return false if this is a unique assoziation. -+ */ -+ bool isAssoziated(); -+ -+ /** -+ * reset function to assoziate this object to. -+ * returns true if assoziation could be established -+ */ -+ bool setFunction(TraceFunction*); -+ TraceFunction* function() { return _function; } -+ -+ void invalidate() { _valid = false; } -+ bool isValid() { return _valid; } -+ -+ /** -+ * Delete all assoziations in TraceFunctions of data with -+ * rtti runtime info. rtti = 0: delete ALL assoziations. -+ */ -+ static void clear(TraceData* data, int rtti); -+ -+ /** -+ * Invalidate all assoziations in TraceFunctions of data with -+ * rtti runtime info. rtti = 0: Invalidate ALL assoziations. -+ */ -+ static void invalidate(TraceData* data, int rtti); -+ -+ protected: -+ TraceFunction* _function; -+ bool _valid; -+}; -+ -+typedef TQPtrList TraceAssoziationList; -+typedef TQMap TraceCallMap; -+ -+/** -+ * A traced function -+ * -+ * References to functions are stored in -+ * (1) a function map in TraceData (by value) -+ * (2) a TraceClass -+ */ -+class TraceFunction: public TraceCostItem -+{ -+ public: -+ TraceFunction(); -+ TraceFunction(TraceData* data, const TQString& name, -+ TraceClass* cls, TraceFile* file, TraceObject* object); -+ virtual ~TraceFunction(); -+ -+ virtual CostType type() const { return Function; } -+ virtual void update(); -+ -+ // this invalidate all subcosts of function depending on -+ // active status of parts -+ void invalidateDynamicCost(); -+ -+ void addCaller(TraceCall*); -+ -+ // factories -+ TraceCall* calling(TraceFunction* called); -+ TraceLine* line(TraceFile*, uint lineno, bool createNew = true); -+ TraceInstr* instr(Addr addr, bool createNew = true); -+ TracePartFunction* partFunction(TracePart*, -+ TracePartFile*, TracePartObject*); -+ -+ /** -+ * Returns empty string if location is fully unknown. -+ * Use prettyLocation for single user-visible string. -+ * A function can have a lot of code from different sources (inlined); -+ * maxItems limits this list. Default is full list -+ */ -+ TQString location(int maxFiles = 0) const; -+ -+ TQString prettyName() const; -+ TQString prettyLocation(int maxFiles = 0) const; -+ TQString prettyNameWithLocation(int maxFiles = 1) const; -+ void addPrettyLocation(TQString&, int maxFiles = 1) const; -+ // type + name + location -+ TQString info() const; -+ -+ TraceClass* cls() const { return _cls; } -+ TraceFile* file() const { return _file; } -+ TraceObject* object() const { return _object; } -+ // get the source file with lines from function declaration (not inlined) -+ TraceFunctionSource* sourceFile(TraceFile* file = 0, -+ bool createNew = false); -+ const TraceFunctionSourceList& sourceFiles() const -+ { return _sourceFiles; } -+ TraceCallList callers(bool skipCycle=false) const; -+ const TraceCallList& callings(bool skipCycle=false) const; -+ -+ Addr firstAddress() const; -+ Addr lastAddress() const; -+ TraceInstrMap* instrMap(); -+ -+ // cost metrics -+ SubCost calledCount(); -+ SubCost callingCount(); -+ TQString prettyCalledCount(); -+ TQString prettyCallingCount(); -+ int calledContexts(); -+ int callingContexts(); -+ -+ // only to be called after default constructor -+ void setFile(TraceFile* file) { _file = file; } -+ void setObject(TraceObject* object) { _object = object; } -+ void setClass(TraceClass* cls) { _cls = cls; } -+ void setMapIterator(TraceFunctionMap::Iterator it) { _myMapIterator = it; } -+ -+ // see TraceFunctionAssoziation -+ void addAssoziation(TraceAssoziation* a); -+ void removeAssoziation(TraceAssoziation* a); -+ void removeAssoziation(int rtti, bool reallyDelete = true); -+ void invalidateAssoziation(int rtti); -+ TraceAssoziation* assoziation(int rtti); -+ -+ // cycles -+ void setCycle(TraceFunctionCycle* c) { _cycle = c; } -+ TraceFunctionCycle* cycle() { return _cycle; } -+ bool isCycle(); -+ bool isCycleMember(); -+ void cycleReset(); -+ void cycleDFS(int d, int& pNo, TraceFunction** pTop); -+ -+ protected: -+ TraceCallList _callers; // list of calls we are called from -+ TraceCallList _callings; // list of calls we are calling (we are owner) -+ TraceCallMap _callingMap; // contains the same as _callings in a map -+ TraceFunctionCycle* _cycle; -+ -+ private: -+ bool isUniquePrefix(TQString) const; -+ TraceFunctionMap::Iterator _myMapIterator; -+ -+ TraceClass* _cls; -+ TraceObject* _object; -+ TraceFile* _file; -+ -+ TraceFunctionSourceList _sourceFiles; // we are owner -+ TraceInstrMap* _instrMap; // we are owner -+ bool _instrMapFilled; -+ -+ // see TraceAssoziation -+ TraceAssoziationList _assoziations; -+ -+ // for cycle detection -+ int _cycleLow; -+ TraceFunction* _cycleStackDown; -+ -+ // cached -+ SubCost _calledCount, _callingCount; -+ int _calledContexts, _callingContexts; -+}; -+ -+typedef TQMap TraceFunctionSet; -+ -+/** -+ * A cycle of recursive calling functions. -+ * -+ * This is itself shown as a function -+ */ -+class TraceFunctionCycle: public TraceFunction -+{ -+ public: -+ TraceFunctionCycle(TraceFunction*, int n); -+ -+ virtual CostType type() const { return FunctionCycle; } -+ -+ // this removes all members from this cycle -+ void init(); -+ void add(TraceFunction*); -+ // this sets up the cycle once members are added -+ void setup(); -+ -+ TraceFunction* base() const { return _base; } -+ int cycleNo() const { return _cycleNo; } -+ const TraceFunctionList& members() const { return _members; } -+ -+ private: -+ TraceFunction* _base; -+ int _cycleNo; -+ -+ TraceFunctionList _members; -+ TraceFunctionSet _memberSet; -+}; -+ -+ -+/** -+ * A C++ Class / Namespace -+ * -+ * If a function symbol has a prefix ending in "::", -+ * the prefix is supposed to be a class/namespace specifier. -+ * Without such a prefix, we put a symbol in the "(global)" namespace. -+ */ -+class TraceClass: public TraceCostItem -+{ -+ public: -+ TraceClass(); -+ virtual ~TraceClass(); -+ -+ virtual CostType type() const { return Class; } -+ virtual TQString prettyName() const; -+ -+ void addFunction(TraceFunction*); -+ const TraceFunctionList& functions() const { return _functions; } -+ -+ // part factory -+ TracePartClass* partClass(TracePart*); -+ -+ private: -+ TraceFunctionList _functions; -+}; -+ -+ -+ -+/** -+ * A source file containing function definitions -+ */ -+class TraceFile: public TraceCostItem -+{ -+ public: -+ TraceFile(); -+ virtual ~TraceFile(); -+ -+ virtual CostType type() const { return File; } -+ void setDirectory(const TQString& dir); -+ void resetDirectory() { _dir = TQString(); } -+ TQString directory(); -+ -+ void addFunction(TraceFunction*); -+ void addSourceFile(TraceFunctionSource*); -+ -+ // without path -+ TQString shortName() const; -+ TQString prettyName() const; -+ TQString prettyLongName() const; -+ const TraceFunctionList& functions() const { return _functions; } -+ const TraceFunctionSourceList& sourceFiles() const -+ { return _sourceFiles; } -+ -+ // part factory -+ TracePartFile* partFile(TracePart*); -+ -+ private: -+ TraceFunctionList _functions; -+ TraceFunctionSourceList _sourceFiles; -+ TQString _dir; -+}; -+ -+ -+/** -+ * A object containing a text segment (shared lib/executable) -+ * with defined functions -+ */ -+class TraceObject: public TraceCostItem -+{ -+ public: -+ TraceObject(); -+ virtual ~TraceObject(); -+ -+ virtual CostType type() const { return Object; } -+ -+ void addFunction(TraceFunction*); -+ -+ virtual void setName(const TQString& name); -+ TQString shortName() const { return _shortName; } -+ TQString prettyName() const; -+ const TraceFunctionList& functions() const { return _functions; } -+ -+ // part factory -+ TracePartObject* partObject(TracePart*); -+ -+ private: -+ TraceFunctionList _functions; -+ TQString _shortName; -+}; -+ -+ -+ -+/** -+ * This class holds profiling data of multiple tracefiles -+ * generated with cachegrind on one command. -+ * -+ */ -+class TraceData: public TraceCost -+{ -+ public: -+ TraceData(TopLevel* top = 0); -+ TraceData(const TQString& base); -+ virtual ~TraceData(); -+ -+ virtual CostType type() const { return Data; } -+ virtual TraceData* data() { return this; } -+ virtual const TraceData* data() const { return this; } -+ -+ /** -+ * Loads a trace file. -+ * -+ * This adjusts the TraceCostMapping according to given cost types -+ */ -+ void load(const TQString&); -+ -+ /** returns true if something changed. These do NOT -+ * invalidate the dynamic costs on a activation change, -+ * i.e. all cost items dependend on active parts. -+ * This has to be done by the caller when true is returned by -+ * calling invalidateDynamicCost(). -+ */ -+ bool activateParts(const TracePartList&); -+ bool activateParts(TracePartList, bool active); -+ bool activatePart(TracePart*, bool active); -+ bool activateAll(bool active=true); -+ -+ TracePartList parts() const { return _parts; } -+ TracePart* part(TQString& name); -+ -+ // with path -+ TQString traceName() const { return _traceName; } -+ -+ // without path -+ TQString shortTraceName() const; -+ TQString activePartRange(); -+ -+ TraceCostMapping* mapping() { return &_mapping; } -+ -+ // memory pools -+ FixPool* fixPool(); -+ DynPool* dynPool(); -+ -+ // factories for object/file/class/function/line instances -+ TraceObject* object(const TQString& name); -+ TraceFile* file(const TQString& name); -+ TraceClass* cls(const TQString& fnName, TQString& shortName); -+ // function creation involves class creation if needed -+ TraceFunction* function(const TQString& name, TraceFile*, TraceObject*); -+ // factory for function cycles -+ TraceFunctionCycle* functionCycle(TraceFunction*); -+ -+ /** -+ * Search for item with given name and highest subcost of given cost type. -+ * -+ * For some items, they will only be found if the parent cost is given: -+ * Instr, Line, Call => need parent of type Function -+ * For Function, a parent of type Obj/File/Class can be given, but -+ * isn't needed. -+ */ -+ TraceCost* search(TraceItem::CostType, TQString, -+ TraceCostType* ct = 0, TraceCost* parent = 0); -+ -+ // for pretty function names without signature if unique... -+ TraceFunctionMap::Iterator functionIterator(TraceFunction*); -+ TraceFunctionMap::ConstIterator functionBeginIterator() const; -+ TraceFunctionMap::ConstIterator functionEndIterator() const; -+ -+ TraceObjectMap& objectMap() { return _objectMap; } -+ TraceFileMap& fileMap() { return _fileMap; } -+ TraceClassMap& classMap() { return _classMap; } -+ TraceFunctionMap& functionMap() { return _functionMap; } -+ -+ const TraceFunctionCycleList& functionCycles() { return _functionCycles; } -+ -+ TraceCost* callMax() { return &_callMax; } -+ -+ void setCommand(const TQString& command) { _command = command; } -+ TQString command() const { return _command; } -+ TraceCost* totals() { return &_totals; } -+ void setMaxThreadID(int tid) { _maxThreadID = tid; } -+ int maxThreadID() const { return _maxThreadID; } -+ void setMaxPartNumber(int n) { _maxPartNumber = n; } -+ int maxPartNumber() const { return _maxPartNumber; } -+ -+ // reset all manually set directories for source files -+ void resetSourceDirs(); -+ -+ virtual void update(); -+ -+ // invalidates all cost items dependant on active state of parts -+ void invalidateDynamicCost(); -+ -+ // cycle detection -+ void updateFunctionCycles(); -+ void updateObjectCycles(); -+ void updateClassCycles(); -+ void updateFileCycles(); -+ bool inFunctionCycleUpdate() { return _inFunctionCycleUpdate; } -+ -+ private: -+ void init(); -+ // add trace part: events from one trace file -+ TracePart* addPart(const TQString& dir, const TQString& file); -+ -+ // for progress bar callbacks -+ TopLevel* _topLevel; -+ -+ TracePartList _parts; -+ -+ // The mapping for all costs -+ TraceCostMapping _mapping; -+ -+ FixPool* _fixPool; -+ DynPool* _dynPool; -+ -+ // always the trace totals (not dependent on active parts) -+ TraceCost _totals; -+ int _maxThreadID; -+ int _maxPartNumber; -+ -+ TraceObjectMap _objectMap; -+ TraceClassMap _classMap; -+ TraceFileMap _fileMap; -+ TraceFunctionMap _functionMap; -+ TQString _command; -+ TQString _traceName; -+ -+ // Max of all costs of calls: This allows to see if the incl. cost can -+ // be hidden for a cost type, as it's always the same as self cost -+ TraceCost _callMax; -+ -+ // cycles -+ TraceFunctionCycleList _functionCycles; -+ int _functionCycleCount; -+ bool _inFunctionCycleUpdate; -+}; -+ -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/traceitemview.cpp b/kdecachegrind/kdecachegrind/traceitemview.cpp -new file mode 100644 -index 0000000..d11f02b ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/traceitemview.cpp -@@ -0,0 +1,443 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Trace Item View -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "traceitemview.h" -+#include "toplevel.h" -+ -+#define TRACE_UPDATES 0 -+ -+TraceItemView::TraceItemView(TraceItemView* parentView, TopLevel* top) -+{ -+ _parentView = parentView; -+ _topLevel = top ? top : parentView->topLevel(); -+ -+ _data = _newData = 0; -+ // _partList and _newPartList is empty -+ _activeItem = _newActiveItem = 0; -+ _selectedItem = _newSelectedItem = 0; -+ _costType = _newCostType = 0; -+ _costType2 = _newCostType2 = 0; -+ _groupType = _newGroupType = TraceItem::NoCostType; -+ -+ _status = nothingChanged; -+ _inUpdate = false; -+ _pos = Hidden; -+} -+ -+TQString TraceItemView::whatsThis() const -+{ -+ return i18n("No description available"); -+} -+ -+void TraceItemView::select(TraceItem* i) -+{ -+ _newSelectedItem = i; -+} -+ -+KConfigGroup* TraceItemView::configGroup(KConfig* c, -+ TQString group, TQString post) -+{ -+ TQStringList gList = c->groupList(); -+ if (gList.contains((group+post).ascii()) ) group += post; -+ return new KConfigGroup(c, group); -+} -+ -+void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey, -+ TQString value, const char* def, bool bNLS) -+{ -+ if (!c) return; -+ if ((value.isEmpty() && ((def == 0) || (*def == 0))) || -+ (value == TQString(def))) -+ c->deleteEntry(pKey); -+ else -+ c->writeEntry(pKey, value, true, false, bNLS); -+} -+ -+void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey, -+ int value, int def) -+{ -+ if (!c) return; -+ if (value == def) -+ c->deleteEntry(pKey); -+ else -+ c->writeEntry(pKey, value); -+} -+ -+void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey, -+ double value, double def) -+{ -+ if (!c) return; -+ if (value == def) -+ c->deleteEntry(pKey); -+ else -+ c->writeEntry(pKey, value); -+} -+ -+void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey, -+ bool value, bool def) -+{ -+ if (!c) return; -+ if (value == def) -+ c->deleteEntry(pKey); -+ else -+ c->writeEntry(pKey, value); -+} -+ -+void TraceItemView::readViewConfig(KConfig*, TQString, TQString, bool) -+{} -+ -+#if 1 -+void TraceItemView::saveViewConfig(KConfig*, TQString, TQString, bool) -+{} -+#else -+void TraceItemView::saveViewConfig(KConfig* c, -+ TQString prefix, TQString postfix, bool) -+{ -+ // write a dummy config entry to see missing virtual functions -+ KConfigGroup g(c, (prefix+postfix).ascii()); -+ g.writeEntry("SaveNotImplemented", true); -+} -+#endif -+ -+bool TraceItemView::activate(TraceItem* i) -+{ -+ i = canShow(i); -+ _newActiveItem = i; -+ -+ return (i != 0); -+} -+ -+TraceFunction* TraceItemView::activeFunction() -+{ -+ TraceItem::CostType t = _activeItem->type(); -+ switch(t) { -+ case TraceItem::Function: -+ case TraceItem::FunctionCycle: -+ return (TraceFunction*) _activeItem; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+bool TraceItemView::set(int changeType, TraceData* d, -+ TraceCostType* t1, TraceCostType* t2, -+ TraceItem::CostType g, const TracePartList& l, -+ TraceItem* a, TraceItem* s) -+{ -+ _status |= changeType; -+ _newData = d; -+ _newGroupType = g; -+ _newCostType = t1; -+ _newCostType2 = t2; -+ _newPartList = l; -+ _newSelectedItem = s; -+ _newActiveItem = canShow(a); -+ if (!_newActiveItem) { -+ _newSelectedItem = 0; -+ return false; -+ } -+ -+ return true; -+} -+ -+ -+bool TraceItemView::isViewVisible() -+{ -+ TQWidget* w = widget(); -+ if (w) -+ return w->isVisible(); -+ return false; -+} -+ -+void TraceItemView::setData(TraceData* d) -+{ -+ _newData = d; -+ -+ // invalidate all pointers to old data -+ _activeItem = _newActiveItem = 0; -+ _selectedItem = _newSelectedItem = 0; -+ _costType = _newCostType = 0; -+ _costType2 = _newCostType2 = 0; -+ _groupType = _newGroupType = TraceItem::NoCostType; -+ _partList.clear(); -+ _newPartList.clear(); -+ -+ // updateView will change this to dataChanged -+ _status = nothingChanged; -+} -+ -+void TraceItemView::updateView(bool force) -+{ -+ if (!force && !isViewVisible()) return; -+ -+ if (_newData != _data) { -+ _status |= dataChanged; -+ _data = _newData; -+ } -+ else { -+ _status &= ~dataChanged; -+ -+ // if there's no data change and data is 0, no update needed -+ if (!_data) return; -+ } -+ -+ if (!(_newPartList == _partList)) { -+ _status |= partsChanged; -+ _partList = _newPartList; -+ } -+ else -+ _status &= ~partsChanged; -+ -+ if (_newActiveItem != _activeItem) { -+ -+ // when setting a new active item, there's no selection -+ _selectedItem = 0; -+ -+ _status |= activeItemChanged; -+ _activeItem = _newActiveItem; -+ } -+ else -+ _status &= ~activeItemChanged; -+ -+ if (_newCostType != _costType) { -+ _status |= costTypeChanged; -+ _costType = _newCostType; -+ } -+ else -+ _status &= ~costTypeChanged; -+ -+ if (_newCostType2 != _costType2) { -+ _status |= costType2Changed; -+ _costType2 = _newCostType2; -+ } -+ else -+ _status &= ~costType2Changed; -+ -+ if (_newGroupType != _groupType) { -+ _status |= groupTypeChanged; -+ _groupType = _newGroupType; -+ } -+ else -+ _status &= ~groupTypeChanged; -+ -+ -+ if (_newSelectedItem != _selectedItem) { -+ _status |= selectedItemChanged; -+ _selectedItem = _newSelectedItem; -+ } -+ else -+ _status &= ~selectedItemChanged; -+ -+ -+ if (!force && (_status == nothingChanged)) return; -+ -+#if TRACE_UPDATES -+ kdDebug() << (widget() ? widget()->name() : "TraceItemView") -+ << "::doUpdate ( " -+ << ((_status & dataChanged) ? "data ":"") -+ << ((_status & configChanged) ? "config ":"") -+ << ")" << endl; -+ -+ if (_status & partsChanged) -+ kdDebug() << " Part List " -+ << _partList.names() -+ << endl; -+ -+ if (_status & costTypeChanged) -+ kdDebug() << " Cost type " -+ << (_costType ? _costType->name().ascii() : "?") -+ << endl; -+ -+ if (_status & costType2Changed) -+ kdDebug() << " Cost type 2 " -+ << (_costType2 ? _costType2->name().ascii() : "?") -+ << endl; -+ -+ if (_status & groupTypeChanged) -+ kdDebug() << " Group type " -+ << TraceItem::typeName(_groupType) -+ << endl; -+ -+ if (_status & activeItemChanged) -+ kdDebug() << " Active: " -+ << (_activeItem ? _activeItem->fullName().ascii() : "?") -+ << endl; -+ -+ if (_status & selectedItemChanged) -+ kdDebug() << " Selected: " -+ << (_selectedItem ? _selectedItem->fullName().ascii() : "?") -+ << endl; -+#endif -+ -+ int st = _status; -+ _status = nothingChanged; -+ doUpdate(st); -+ return; -+ -+ if (_inUpdate) return; -+ _inUpdate = true; -+ doUpdate(_status); -+ _inUpdate = false; -+} -+ -+ -+void TraceItemView::selected(TraceItemView* /*sender*/, TraceItem* i) -+{ -+#if TRACE_UPDATES -+ kdDebug() << (widget() ? widget()->name() : "TraceItemView") -+ << "::selected " -+ << (i ? i->name().ascii(): "(nil)") -+ << ", sender " -+ << sender->widget()->name() << endl; -+#endif -+ -+ if (_parentView) _parentView->selected(this, i); -+} -+ -+void TraceItemView::selected(TraceItemView* /*sender*/, const TracePartList& l) -+{ -+#if TRACE_UPDATES -+ kdDebug() << (widget() ? widget()->name() : "TraceItemView") -+ << "::selected " -+ << l.names() -+ << ", sender " -+ << sender->widget()->name() << endl; -+#endif -+ -+ if (_parentView) -+ _parentView->selected(this, l); -+ else -+ if (_topLevel) _topLevel->activePartsChangedSlot(l); -+} -+ -+void TraceItemView::activated(TraceItemView* /*sender*/, TraceItem* i) -+{ -+#if TRACE_UPDATES -+ kdDebug() << (widget() ? widget()->name() : "TraceItemView") -+ << "::activated " -+ << (i ? i->name().ascii(): "(nil)") -+ << ", sender " -+ << sender->widget()->name() << endl; -+#endif -+ -+ if (_parentView) -+ _parentView->activated(this, i); -+ else -+ if (_topLevel) _topLevel->setTraceItemDelayed(i); -+} -+ -+void TraceItemView::selectedCostType(TraceItemView*, TraceCostType* t) -+{ -+ if (_parentView) -+ _parentView->selectedCostType(this, t); -+ else -+ if (_topLevel) _topLevel->setCostTypeDelayed(t); -+} -+ -+void TraceItemView::selectedCostType2(TraceItemView*, TraceCostType* t) -+{ -+ if (_parentView) -+ _parentView->selectedCostType2(this, t); -+ else -+ if (_topLevel) _topLevel->setCostType2Delayed(t); -+} -+ -+void TraceItemView::activated(TraceItemView*, Direction d) -+{ -+ if (_parentView) -+ _parentView->activated(this, d); -+ else -+ if (_topLevel) _topLevel->setDirectionDelayed(d); -+} -+ -+void TraceItemView::doUpdate(int) -+{ -+} -+ -+void TraceItemView::selected(TraceItem* i) -+{ -+ if (_parentView) -+ _parentView->selected(this, i); -+ -+} -+ -+void TraceItemView::selected(const TracePartList& l) -+{ -+ if (_parentView) -+ _parentView->selected(this, l); -+ else -+ if (_topLevel) _topLevel->activePartsChangedSlot(l); -+} -+ -+void TraceItemView::activated(TraceItem* i) -+{ -+#if TRACE_UPDATES -+ kdDebug() << (widget() ? widget()->name() : "TraceItemView") -+ << "::activated " -+ << (i ? i->name().ascii(): "(nil)") << endl; -+#endif -+ -+ if (_parentView) -+ _parentView->activated(this, i); -+ else -+ if (_topLevel) _topLevel->setTraceItemDelayed(i); -+} -+ -+void TraceItemView::selectedCostType(TraceCostType* t) -+{ -+ if (_parentView) -+ _parentView->selectedCostType(this, t); -+ else -+ if (_topLevel) _topLevel->setCostTypeDelayed(t); -+} -+ -+void TraceItemView::selectedCostType2(TraceCostType* t) -+{ -+ if (_parentView) -+ _parentView->selectedCostType2(this, t); -+ else -+ if (_topLevel) _topLevel->setCostType2Delayed(t); -+} -+ -+void TraceItemView::activated(Direction d) -+{ -+ if (_parentView) -+ _parentView->activated(this, d); -+ else -+ if (_topLevel) _topLevel->setDirectionDelayed(d); -+} -+ -+void TraceItemView::addCostMenu(TQPopupMenu* p, bool withCost2) -+{ -+ if (_topLevel) _topLevel->addCostMenu(p, withCost2); -+} -+ -+void TraceItemView::addGoMenu(TQPopupMenu* p) -+{ -+ if (_topLevel) _topLevel->addGoMenu(p); -+} -diff --git a/kdecachegrind/kdecachegrind/traceitemview.h b/kdecachegrind/kdecachegrind/traceitemview.h -new file mode 100644 -index 0000000..f83aa89 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/traceitemview.h -@@ -0,0 +1,206 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Trace Item View -+ */ -+ -+#ifndef TRACEITEMVIEW_H -+#define TRACEITEMVIEW_H -+ -+#include "tracedata.h" -+ -+class TQWidget; -+class TQPopupMenu; -+ -+class KConfig; -+class KConfigGroup; -+class KConfigBase; -+ -+class TopLevel; -+ -+/** -+ * Abstract Base Class for KCachegrind Views -+ * -+ * This class delivers the shared functionality of all KCachegrind -+ * Views for one TraceItem (like Function, Object...), the "active" -+ * item. Additional view attributes are current primary cost type, -+ * an optional secondary cost type, group type, -+ * and possibly a selected costitem in this view. -+ * Note that there is a difference in changing the selected item of -+ * a view (this usually changes selection in other views, too), and -+ * activating that item. -+ */ -+class TraceItemView -+{ -+public: -+ -+ /** -+ * Change type for update functions -+ * - is used if e.g. cycles are recalculated -+ */ -+ enum { nothingChanged = 0, -+ costTypeChanged = 1, -+ costType2Changed = 2, -+ groupTypeChanged = 4, -+ partsChanged = 8, -+ activeItemChanged = 16, -+ selectedItemChanged = 32, -+ dataChanged = 64, -+ configChanged = 128 }; -+ -+ enum Direction { None, Back, Forward, Up }; -+ -+ // a TraceItemView can have a position in a parent container -+ enum Position { Hidden, Top, Right, Left, Bottom }; -+ -+ TraceItemView(TraceItemView* parentView, TopLevel* top = 0); -+ virtual ~TraceItemView() {} -+ -+ virtual TQString whatsThis() const; -+ -+ static KConfigGroup* configGroup(KConfig*, TQString prefix, TQString postfix); -+ static void writeConfigEntry(KConfigBase*, const char* pKey, TQString value, -+ const char* def, bool bNLS = false); -+ static void writeConfigEntry(KConfigBase*, const char* pKey, -+ int value, int def); -+ static void writeConfigEntry(KConfigBase*, const char* pKey, -+ bool value, bool def); -+ static void writeConfigEntry(KConfigBase*, const char* pKey, -+ double value, double def); -+ virtual void readViewConfig(KConfig*, TQString prefix, TQString postfix, -+ bool withOptions); -+ virtual void saveViewConfig(KConfig*, TQString prefix, TQString postfix, -+ bool withOptions); -+ -+ // Immediate remove all references to old data, and set the new. -+ // This resets the visualization state. -+ // A GUI update has to be triggered with updateView(). -+ // Overwrite in container views to also set new data for all members. -+ virtual void setData(TraceData* d); -+ -+ // change from parent, call updateView() to update lazily (only if visible) -+ void setCostType(TraceCostType* t) { _newCostType = t; } -+ void setCostType2(TraceCostType* t) { _newCostType2 = t; } -+ void set(TraceItem::CostType g) { _newGroupType = g; } -+ void set(const TracePartList& l) { _newPartList = l; } -+ // returns false if nothing can be shown for this trace item -+ bool activate(TraceItem* i); -+ void select(TraceItem* i); -+ void notifyChange(int changeType) { _status |= changeType; } -+ // all in one -+ bool set(int, TraceData*, TraceCostType*, TraceCostType*, -+ TraceItem::CostType, const TracePartList&, -+ TraceItem*, TraceItem*); -+ -+ // general update request, call if view is/gets visible -+ void updateView(bool force = false); -+ -+ /** -+ * Notification from child views. -+ * Default implementation notifies parent -+ */ -+ virtual void selected(TraceItemView* sender, TraceItem*); -+ virtual void selected(TraceItemView* sender, const TracePartList&); -+ virtual void activated(TraceItemView* sender, Direction); -+ virtual void selectedCostType(TraceItemView* sender, TraceCostType*); -+ virtual void selectedCostType2(TraceItemView* sender, TraceCostType*); -+ virtual void activated(TraceItemView* sender, TraceItem*); -+ -+ // getters... -+ // always get the newest values -+ TraceData* data() const { return _newData; } -+ TraceItem* activeItem() const { return _newActiveItem; } -+ TraceItem* selectedItem() const { return _newSelectedItem; } -+ TraceCostType* costType() const { return _newCostType; } -+ TraceCostType* costType2() const { return _newCostType2; } -+ TraceItem::CostType groupType() const { return _newGroupType; } -+ const TracePartList& partList() const { return _newPartList; } -+ -+ TraceFunction* activeFunction(); -+ int status() const { return _status; } -+ -+ // pointer to top level window to e.g. show status messages -+ void setTopLevel(TopLevel* t) { _topLevel = t; } -+ TopLevel* topLevel() const { return _topLevel; } -+ -+ void setPosition(Position p) { _pos = p; } -+ Position position() const { return _pos; } -+ -+ void setTitle(TQString t) { _title = t; } -+ TQString title() const { return _title; } -+ -+ // We depend on derived class to be a widget. -+ // Force overiding by making this abstract. -+ virtual TQWidget* widget() = 0; -+ -+ /** -+ * This function is called when a new item should become active. -+ * Reimplement this in subclasses. -+ * -+ * Returns the real item to become active. You can call select() here. -+ * Return 0 if nothing can be shown. -+ * Use the methods like data() instead of _data here, as -+ * _data possibly will give old/wrong information. -+ */ -+ virtual TraceItem* canShow(TraceItem* i) { return i; } -+ -+ /* convenience functions for often used context menu items */ -+ void addCostMenu(TQPopupMenu*,bool withCost2 = true); -+ void addGoMenu(TQPopupMenu*); -+ -+protected: -+ // helpers to call selected()/activated() of parentView -+ void selected(TraceItem*); -+ void selected(const TracePartList&); -+ void activated(TraceItem*); -+ void selectedCostType(TraceCostType*); -+ void selectedCostType2(TraceCostType*); -+ void activated(Direction); -+ -+ /* Is this view visible? -+ * if not, doUpdate() won't be called by updateView() -+ */ -+ virtual bool isViewVisible(); -+ -+ // update handler (to be reimplemented) -+ virtual void doUpdate(int changeType); -+ -+ TraceItemView* _parentView; -+ TopLevel* _topLevel; -+ -+ TraceData* _data; -+ TracePartList _partList; -+ TraceItem *_activeItem, *_selectedItem; -+ TraceCostType *_costType, *_costType2; -+ TraceItem::CostType _groupType; -+ -+private: -+ TraceData* _newData; -+ TracePartList _newPartList; -+ TraceItem *_newActiveItem, *_newSelectedItem; -+ TraceCostType *_newCostType, *_newCostType2; -+ TraceItem::CostType _newGroupType; -+ -+ TQString _title; -+ int _status; -+ bool _inUpdate; -+ Position _pos; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/treemap.cpp b/kdecachegrind/kdecachegrind/treemap.cpp -new file mode 100644 -index 0000000..0d4b8dc ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/treemap.cpp -@@ -0,0 +1,3214 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * A Widget for visualizing hierarchical metrics as areas. -+ * The API is similar to TQListView. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "treemap.h" -+ -+ -+// set this to 1 to enable debug output -+#define DEBUG_DRAWING 0 -+#define MAX_FIELD 12 -+ -+ -+// -+// StoredDrawParams -+// -+StoredDrawParams::StoredDrawParams() -+{ -+ _selected = false; -+ _current = false; -+ _shaded = true; -+ _rotated = false; -+ -+ _backColor = TQt::white; -+ -+ // field array has size 0 -+} -+ -+StoredDrawParams::StoredDrawParams(TQColor c, -+ bool selected, bool current) -+{ -+ _backColor = c; -+ -+ _selected = selected; -+ _current = current; -+ _shaded = true; -+ _rotated = false; -+ _drawFrame = true; -+ -+ // field array has size 0 -+} -+ -+TQString StoredDrawParams::text(int f) const -+{ -+ if ((f<0) || (f >= (int)_field.size())) -+ return TQString(); -+ -+ return _field[f].text; -+} -+ -+TQPixmap StoredDrawParams::pixmap(int f) const -+{ -+ if ((f<0) || (f >= (int)_field.size())) -+ return TQPixmap(); -+ -+ return _field[f].pix; -+} -+ -+DrawParams::Position StoredDrawParams::position(int f) const -+{ -+ if ((f<0) || (f >= (int)_field.size())) -+ return Default; -+ -+ return _field[f].pos; -+} -+ -+int StoredDrawParams::maxLines(int f) const -+{ -+ if ((f<0) || (f >= (int)_field.size())) -+ return 0; -+ -+ return _field[f].maxLines; -+} -+ -+const TQFont& StoredDrawParams::font() const -+{ -+ static TQFont* f = 0; -+ if (!f) f = new TQFont(TQApplication::font()); -+ -+ return *f; -+} -+ -+void StoredDrawParams::ensureField(int f) -+{ -+ static Field* def = 0; -+ if (!def) { -+ def = new Field(); -+ def->pos = Default; -+ def->maxLines = 0; -+ } -+ -+ if (f<0 || f>=MAX_FIELD) return; -+ -+ if ((int)_field.size() < f+1) _field.resize(f+1, *def); -+} -+ -+ -+void StoredDrawParams::setField(int f, const TQString& t, TQPixmap pm, -+ Position p, int maxLines) -+{ -+ if (f<0 || f>=MAX_FIELD) return; -+ ensureField(f); -+ -+ _field[f].text = t; -+ _field[f].pix = pm; -+ _field[f].pos = p; -+ _field[f].maxLines = maxLines; -+} -+ -+void StoredDrawParams::setText(int f, const TQString& t) -+{ -+ if (f<0 || f>=MAX_FIELD) return; -+ ensureField(f); -+ -+ _field[f].text = t; -+} -+ -+void StoredDrawParams::setPixmap(int f, const TQPixmap& pm) -+{ -+ if (f<0 || f>=MAX_FIELD) return; -+ ensureField(f); -+ -+ _field[f].pix = pm; -+} -+ -+void StoredDrawParams::setPosition(int f, Position p) -+{ -+ if (f<0 || f>=MAX_FIELD) return; -+ ensureField(f); -+ -+ _field[f].pos = p; -+} -+ -+void StoredDrawParams::setMaxLines(int f, int m) -+{ -+ if (f<0 || f>=MAX_FIELD) return; -+ ensureField(f); -+ -+ _field[f].maxLines = m; -+} -+ -+ -+ -+// -+// RectDrawing -+// -+ -+RectDrawing::RectDrawing(TQRect r) -+{ -+ _fm = 0; -+ _dp = 0; -+ setRect(r); -+} -+ -+ -+RectDrawing::~RectDrawing() -+{ -+ delete _fm; -+ delete _dp; -+} -+ -+DrawParams* RectDrawing::drawParams() -+{ -+ if (!_dp) -+ _dp = new StoredDrawParams(); -+ -+ return _dp; -+} -+ -+ -+void RectDrawing::setDrawParams(DrawParams* dp) -+{ -+ if (_dp) delete _dp; -+ _dp = dp; -+} -+ -+void RectDrawing::setRect(TQRect r) -+{ -+ _rect = r; -+ -+ _usedTopLeft = 0; -+ _usedTopCenter = 0; -+ _usedTopRight = 0; -+ _usedBottomLeft = 0; -+ _usedBottomCenter = 0; -+ _usedBottomRight = 0; -+ -+ _fontHeight = 0; -+} -+ -+TQRect RectDrawing::remainingRect(DrawParams* dp) -+{ -+ if (!dp) dp = drawParams(); -+ -+ if ((_usedTopLeft >0) || -+ (_usedTopCenter >0) || -+ (_usedTopRight >0)) { -+ if (dp->rotated()) -+ _rect.setLeft(_rect.left() + _fontHeight); -+ else -+ _rect.setTop(_rect.top() + _fontHeight); -+ } -+ -+ if ((_usedBottomLeft >0) || -+ (_usedBottomCenter >0) || -+ (_usedBottomRight >0)) { -+ if (dp->rotated()) -+ _rect.setRight(_rect.right() - _fontHeight); -+ else -+ _rect.setBottom(_rect.bottom() - _fontHeight); -+ } -+ return _rect; -+} -+ -+ -+void RectDrawing::drawBack(TQPainter* p, DrawParams* dp) -+{ -+ if (!dp) dp = drawParams(); -+ if (_rect.width()<=0 || _rect.height()<=0) return; -+ -+ TQRect r = _rect; -+ TQColor normal = dp->backColor(); -+ if (dp->selected()) normal = normal.light(); -+ bool isCurrent = dp->current(); -+ -+ if (dp->drawFrame() || isCurrent) { -+ // 3D raised/sunken frame effect... -+ TQColor high = normal.light(); -+ TQColor low = normal.dark(); -+ p->setPen( isCurrent ? low:high); -+ p->drawLine(r.left(), r.top(), r.right(), r.top()); -+ p->drawLine(r.left(), r.top(), r.left(), r.bottom()); -+ p->setPen( isCurrent ? high:low); -+ p->drawLine(r.right(), r.top(), r.right(), r.bottom()); -+ p->drawLine(r.left(), r.bottom(), r.right(), r.bottom()); -+ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); -+ } -+ if (r.width()<=0 || r.height()<=0) return; -+ -+ if (dp->shaded()) { -+ // some shading -+ bool goDark = tqGray(normal.rgb())>128; -+ int rBase, gBase, bBase; -+ normal.rgb(&rBase, &gBase, &bBase); -+ p->setBrush(TQBrush::NoBrush); -+ -+ // shade parameters: -+ int d = 7; -+ float factor = 0.1, forth=0.7, back1 =0.9, toBack2 = .7, back2 = 0.97; -+ -+ // coefficient corrections because of rectangle size -+ int s = r.width(); -+ if (s > r.height()) s = r.height(); -+ if (s<100) { -+ forth -= .3 * (100-s)/100; -+ back1 -= .2 * (100-s)/100; -+ back2 -= .02 * (100-s)/100; -+ } -+ -+ -+ // maximal color difference -+ int rDiff = goDark ? -rBase/d : (255-rBase)/d; -+ int gDiff = goDark ? -gBase/d : (255-gBase)/d; -+ int bDiff = goDark ? -bBase/d : (255-bBase)/d; -+ -+ TQColor shadeColor; -+ while (factor<.95) { -+ shadeColor.setRgb((int)(rBase+factor*rDiff+.5), -+ (int)(gBase+factor*gDiff+.5), -+ (int)(bBase+factor*bDiff+.5)); -+ p->setPen(shadeColor); -+ p->drawRect(r); -+ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); -+ if (r.width()<=0 || r.height()<=0) return; -+ factor = 1.0 - ((1.0 - factor) * forth); -+ } -+ -+ // and back (1st half) -+ while (factor>toBack2) { -+ shadeColor.setRgb((int)(rBase+factor*rDiff+.5), -+ (int)(gBase+factor*gDiff+.5), -+ (int)(bBase+factor*bDiff+.5)); -+ p->setPen(shadeColor); -+ p->drawRect(r); -+ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); -+ if (r.width()<=0 || r.height()<=0) return; -+ factor = 1.0 - ((1.0 - factor) / back1); -+ } -+ -+ // and back (2nd half) -+ while ( factor>.01) { -+ shadeColor.setRgb((int)(rBase+factor*rDiff+.5), -+ (int)(gBase+factor*gDiff+.5), -+ (int)(bBase+factor*bDiff+.5)); -+ p->setPen(shadeColor); -+ p->drawRect(r); -+ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); -+ if (r.width()<=0 || r.height()<=0) return; -+ -+ factor = factor * back2; -+ } -+ } -+ -+ // fill inside -+ p->setPen(TQPen::NoPen); -+ p->setBrush(normal); -+ p->drawRect(r); -+} -+ -+ -+bool RectDrawing::drawField(TQPainter* p, int f, DrawParams* dp) -+{ -+ if (!dp) dp = drawParams(); -+ -+ if (!_fm) { -+ _fm = new TQFontMetrics(dp->font()); -+ _fontHeight = _fm->height(); -+ } -+ -+ TQRect r = _rect; -+ -+ if (0) kdDebug(90100) << "DrawField: Rect " << r.x() << "/" << r.y() -+ << " - " << r.width() << "x" << r.height() << endl; -+ -+ int h = _fontHeight; -+ bool rotate = dp->rotated(); -+ int width = (rotate ? r.height() : r.width()) -4; -+ int height = (rotate ? r.width() : r.height()); -+ int lines = height / h; -+ -+ // stop if we have no space available -+ if (lines<1) return false; -+ -+ // calculate free space in first line () -+ int pos = dp->position(f); -+ if (pos == DrawParams::Default) { -+ switch(f%4) { -+ case 0: pos = DrawParams::TopLeft; break; -+ case 1: pos = DrawParams::TopRight; break; -+ case 2: pos = DrawParams::BottomRight; break; -+ case 3: pos = DrawParams::BottomLeft; break; -+ } -+ } -+ -+ int unused = 0; -+ bool isBottom = false; -+ bool isCenter = false; -+ bool isRight = false; -+ int* used = 0; -+ switch(pos) { -+ case DrawParams::TopLeft: -+ used = &_usedTopLeft; -+ if (_usedTopLeft == 0) { -+ if (_usedTopCenter) -+ unused = (width - _usedTopCenter)/2; -+ else -+ unused = width - _usedTopRight; -+ } -+ break; -+ -+ case DrawParams::TopCenter: -+ isCenter = true; -+ used = &_usedTopCenter; -+ if (_usedTopCenter == 0) { -+ if (_usedTopLeft > _usedTopRight) -+ unused = width - 2 * _usedTopLeft; -+ else -+ unused = width - 2 * _usedTopRight; -+ } -+ break; -+ -+ case DrawParams::TopRight: -+ isRight = true; -+ used = &_usedTopRight; -+ if (_usedTopRight == 0) { -+ if (_usedTopCenter) -+ unused = (width - _usedTopCenter)/2; -+ else -+ unused = width - _usedTopLeft; -+ } -+ break; -+ -+ case DrawParams::BottomLeft: -+ isBottom = true; -+ used = &_usedBottomLeft; -+ if (_usedBottomLeft == 0) { -+ if (_usedBottomCenter) -+ unused = (width - _usedBottomCenter)/2; -+ else -+ unused = width - _usedBottomRight; -+ } -+ break; -+ -+ case DrawParams::BottomCenter: -+ isCenter = true; -+ isBottom = true; -+ used = &_usedBottomCenter; -+ if (_usedBottomCenter == 0) { -+ if (_usedBottomLeft > _usedBottomRight) -+ unused = width - 2 * _usedBottomLeft; -+ else -+ unused = width - 2 * _usedBottomRight; -+ } -+ break; -+ -+ case DrawParams::BottomRight: -+ isRight = true; -+ isBottom = true; -+ used = &_usedBottomRight; -+ if (_usedBottomRight == 0) { -+ if (_usedBottomCenter) -+ unused = (width - _usedBottomCenter)/2; -+ else -+ unused = width - _usedBottomLeft; -+ } -+ break; -+ } -+ -+ if (isBottom) { -+ if ((_usedTopLeft >0) || -+ (_usedTopCenter >0) || -+ (_usedTopRight >0)) -+ lines--; -+ } -+ else if (!isBottom) { -+ if ((_usedBottomLeft >0) || -+ (_usedBottomCenter >0) || -+ (_usedBottomRight >0)) -+ lines--; -+ } -+ if (lines<1) return false; -+ -+ -+ int y = isBottom ? height - h : 0; -+ -+ if (unused < 0) unused = 0; -+ if (unused == 0) { -+ // no space available in last line at this position -+ y = isBottom ? (y-h) : (y+h); -+ lines--; -+ -+ if (lines<1) return false; -+ -+ // new line: reset used space -+ if (isBottom) -+ _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0; -+ else -+ _usedTopLeft = _usedTopCenter = _usedTopRight = 0; -+ -+ unused = width; -+ } -+ -+ // stop as soon as possible when there's no space for "..." -+ static int dotW = 0; -+ if (!dotW) dotW = _fm->width("..."); -+ if (width < dotW) return false; -+ -+ // get text and pixmap now, only if we need to, because it is possible -+ // that they are calculated on demand (and this can take some time) -+ TQString name = dp->text(f); -+ if (name.isEmpty()) return 0; -+ TQPixmap pix = dp->pixmap(f); -+ -+ // check if pixmap can be drawn -+ int pixW = pix.width(); -+ int pixH = pix.height(); -+ int pixY = 0; -+ bool pixDrawn = true; -+ if (pixW>0) { -+ pixW += 2; // X distance from pix -+ if ((width < pixW + dotW) || (height < pixH)) { -+ // don't draw -+ pixW = 0; -+ } -+ else -+ pixDrawn = false; -+ } -+ -+ // width of text and pixmap to be drawn -+ int w = pixW + _fm->width(name); -+ -+ if (0) kdDebug(90100) << " For '" << name << "': Unused " << unused -+ << ", StrW " << w << ", Width " << width << endl; -+ -+ // if we have limited space at 1st line: -+ // use it only if whole name does fit in last line... -+ if ((unused < width) && (w > unused)) { -+ y = isBottom ? (y-h) : (y+h); -+ lines--; -+ -+ if (lines<1) return false; -+ -+ // new line: reset used space -+ if (isBottom) -+ _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0; -+ else -+ _usedTopLeft = _usedTopCenter = _usedTopRight = 0; -+ } -+ -+ p->save(); -+ p->setPen( (tqGray(dp->backColor().rgb())>100) ? TQt::black : TQt::white); -+ p->setFont(dp->font()); -+ if (rotate) { -+ //p->translate(r.x()+2, r.y()+r.height()); -+ p->translate(r.x(), r.y()+r.height()-2); -+ p->rotate(270); -+ } -+ else -+ p->translate(r.x()+2, r.y()); -+ -+ -+ // adjust available lines according to maxLines -+ int max = dp->maxLines(f); -+ if ((max > 0) && (lines>max)) lines = max; -+ -+ /* loop over name parts to break up string depending on available width. -+ * every char category change is supposed a possible break, -+ * with the exception Uppercase=>Lowercase. -+ * It's good enough for numbers, Symbols... -+ * -+ * If the text is to be written at the bottom, we start with the -+ * end of the string (so everything is reverted) -+ */ -+ TQString remaining; -+ int origLines = lines; -+ while (lines>0) { -+ -+ if (w>width && lines>1) { -+ int lastBreakPos = name.length(), lastWidth = w; -+ int len = name.length(); -+ TQChar::Category caOld, ca; -+ -+ if (!isBottom) { -+ // start with comparing categories of last 2 chars -+ caOld = name[len-1].category(); -+ while (len>2) { -+ len--; -+ ca = name[len-1].category(); -+ if (ca != caOld) { -+ // "Aa" has no break between... -+ if (ca == TQChar::Letter_Uppercase && -+ caOld == TQChar::Letter_Lowercase) { -+ caOld = ca; -+ continue; -+ } -+ caOld = ca; -+ lastBreakPos = len; -+ w = pixW + _fm->width(name, len); -+ lastWidth = w; -+ if (w <= width) break; -+ } -+ } -+ w = lastWidth; -+ remaining = name.mid(lastBreakPos); -+ // remove space on break point -+ if (name[lastBreakPos-1].category() == TQChar::Separator_Space) -+ name = name.left(lastBreakPos-1); -+ else -+ name = name.left(lastBreakPos); -+ } -+ else { // bottom -+ int l = len; -+ caOld = name[l-len].category(); -+ while (len>2) { -+ len--; -+ ca = name[l-len].category(); -+ -+ if (ca != caOld) { -+ // "Aa" has no break between... -+ if (caOld == TQChar::Letter_Uppercase && -+ ca == TQChar::Letter_Lowercase) { -+ caOld = ca; -+ continue; -+ } -+ caOld = ca; -+ lastBreakPos = len; -+ w = pixW + _fm->width(name.right(len)); -+ lastWidth = w; -+ if (w <= width) break; -+ } -+ } -+ w = lastWidth; -+ remaining = name.left(l-lastBreakPos); -+ // remove space on break point -+ if (name[l-lastBreakPos].category() == TQChar::Separator_Space) -+ name = name.right(lastBreakPos-1); -+ else -+ name = name.right(lastBreakPos); -+ } -+ } -+ else -+ remaining = TQString(); -+ -+ /* truncate and add ... if needed */ -+ if (w>width) { -+ int len = name.length(); -+ w += dotW; -+ while (len>2 && (w > width)) { -+ len--; -+ w = pixW + _fm->width(name, len) + dotW; -+ } -+ // stop drawing: we cannot draw 2 chars + "..." -+ if (w>width) break; -+ -+ name = name.left(len) + "..."; -+ } -+ -+ int x = 0; -+ if (isCenter) -+ x = (width - w)/2; -+ else if (isRight) -+ x = width - w; -+ -+ if (!pixDrawn) { -+ pixY = y+(h-pixH)/2; // default: center vertically -+ if (pixH > h) pixY = isBottom ? y-(pixH-h) : y; -+ -+ p->drawPixmap( x, pixY, pix); -+ -+ // for distance to next text -+ pixY = isBottom ? (pixY - h - 2) : (pixY + pixH + 2); -+ pixDrawn = true; -+ } -+ -+ -+ if (0) kdDebug(90100) << " Drawing '" << name << "' at " -+ << x+pixW << "/" << y << endl; -+ -+ p->drawText( x+pixW, y, -+ width - pixW, h, -+ TQt::AlignLeft, name); -+ y = isBottom ? (y-h) : (y+h); -+ lines--; -+ -+ if (remaining.isEmpty()) break; -+ name = remaining; -+ w = pixW + _fm->width(name); -+ } -+ -+ // make sure the pix stays visible -+ if (pixDrawn && (pixY>0)) { -+ if (isBottom && (pixYy)) y = pixY; -+ } -+ -+ if (origLines > lines) { -+ // if only 1 line written, don't reset _used* vars -+ if (lines - origLines >1) { -+ if (isBottom) -+ _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0; -+ else -+ _usedTopLeft = _usedTopCenter = _usedTopRight = 0; -+ } -+ -+ // take back one line -+ y = isBottom ? (y+h) : (y-h); -+ if (used) *used = w; -+ } -+ -+ // update free space -+ if (!isBottom) { -+ if (rotate) -+ _rect.setRect(r.x()+y, r.y(), r.width()-y, r.height()); -+ else -+ _rect.setRect(r.x(), r.y()+y, r.width(), r.height()-y); -+ } -+ else { -+ if (rotate) -+ _rect.setRect(r.x(), r.y(), y+h, r.height()); -+ else -+ _rect.setRect(r.x(), r.y(), r.width(), y+h); -+ } -+ -+ p->restore(); -+ -+ return true; -+} -+ -+ -+ -+ -+ -+ -+// -+// TreeMapItemList -+// -+ -+int TreeMapItemList::compareItems ( Item item1, Item item2 ) -+{ -+ bool ascending; -+ int result; -+ -+ TreeMapItem* parent = ((TreeMapItem*)item1)->parent(); -+ // shouldn't happen -+ if (!parent) return 0; -+ -+ int textNo = parent->sorting(&ascending); -+ -+ if (textNo < 0) { -+ double diff = ((TreeMapItem*)item1)->value() - -+ ((TreeMapItem*)item2)->value(); -+ result = (diff < -.9) ? -1 : (diff > .9) ? 1 : 0; -+ } -+ else -+ result = (((TreeMapItem*)item1)->text(textNo) < -+ ((TreeMapItem*)item2)->text(textNo)) ? -1 : 1; -+ -+ return ascending ? result : -result; -+} -+ -+ -+TreeMapItem* TreeMapItemList::commonParent() -+{ -+ TreeMapItem* parent, *item; -+ parent = first(); -+ if (parent) -+ while( (item = next()) != 0) -+ parent = parent->commonParent(item); -+ -+ return parent; -+} -+ -+ -+// TreeMapItem -+ -+TreeMapItem::TreeMapItem(TreeMapItem* parent, double value) -+{ -+ _value = value; -+ _parent = parent; -+ -+ _sum = 0; -+ _children = 0; -+ _widget = 0; -+ _index = -1; -+ _depth = -1; // not set -+ _unused_self = 0; -+ _freeRects = 0; -+ -+ if (_parent) { -+ // take sorting from parent -+ _sortTextNo = _parent->sorting(&_sortAscending); -+ _parent->addItem(this); -+ } -+ else { -+ _sortAscending = false; -+ _sortTextNo = -1; // default: no sorting -+ } -+} -+ -+ -+TreeMapItem::TreeMapItem(TreeMapItem* parent, double value, -+ TQString text1, TQString text2, -+ TQString text3, TQString text4) -+{ -+ _value = value; -+ _parent = parent; -+ -+ // this resizes the text vector only if needed -+ if (!text4.isEmpty()) setText(3, text4); -+ if (!text3.isEmpty()) setText(2, text3); -+ if (!text2.isEmpty()) setText(1, text2); -+ setText(0, text1); -+ -+ _sum = 0; -+ _children = 0; -+ _widget = 0; -+ _index = -1; -+ _depth = -1; // not set -+ _unused_self = 0; -+ _freeRects = 0; -+ -+ if (_parent) _parent->addItem(this); -+} -+ -+TreeMapItem::~TreeMapItem() -+{ -+ if (_children) delete _children; -+ if (_freeRects) delete _freeRects; -+ -+ // finally, notify widget about deletion -+ if (_widget) _widget->deletingItem(this); -+} -+ -+void TreeMapItem::setParent(TreeMapItem* p) -+{ -+ _parent = p; -+ if (p) _widget = p->_widget; -+} -+ -+bool TreeMapItem::isChildOf(TreeMapItem* item) -+{ -+ if (!item) return false; -+ -+ TreeMapItem* i = this; -+ while (i) { -+ if (item == i) return true; -+ i = i->_parent; -+ } -+ return false; -+} -+ -+TreeMapItem* TreeMapItem::commonParent(TreeMapItem* item) -+{ -+ while (item && !isChildOf(item)) { -+ item = item->parent(); -+ } -+ return item; -+} -+ -+void TreeMapItem::redraw() -+{ -+ if (_widget) -+ _widget->redraw(this); -+} -+ -+void TreeMapItem::clear() -+{ -+ if (_children) { -+ // delete selected items below this item from selection -+ if (_widget) _widget->clearSelection(this); -+ -+ delete _children; -+ _children = 0; -+ } -+} -+ -+ -+// invalidates current children and forces redraw -+// this is only usefull when children are created on demand in items() -+void TreeMapItem::refresh() -+{ -+ clear(); -+ redraw(); -+} -+ -+ -+TQStringList TreeMapItem::path(int textNo) const -+{ -+ TQStringList list(text(textNo)); -+ -+ TreeMapItem* i = _parent; -+ while (i) { -+ TQString text = i->text(textNo); -+ if (!text.isEmpty()) -+ list.prepend(i->text(textNo)); -+ i = i->_parent; -+ } -+ return list; -+} -+ -+int TreeMapItem::depth() const -+{ -+ if (_depth>0) return _depth; -+ -+ if (_parent) -+ return _parent->depth() + 1; -+ return 1; -+} -+ -+ -+bool TreeMapItem::initialized() -+{ -+ if (!_children) { -+ _children = new TreeMapItemList; -+ _children->setAutoDelete(true); -+ return false; -+ } -+ return true; -+} -+ -+void TreeMapItem::addItem(TreeMapItem* i) -+{ -+ if (!i) return; -+ -+ if (!_children) { -+ _children = new TreeMapItemList; -+ _children->setAutoDelete(true); -+ } -+ i->setParent(this); -+ -+ if (sorting(0) == -1) -+ _children->append(i); // preserve insertion order -+ else -+ _children->inSort(i); -+} -+ -+ -+// default implementations of virtual functions -+ -+double TreeMapItem::value() const -+{ -+ return _value; -+} -+ -+double TreeMapItem::sum() const -+{ -+ return _sum; -+} -+ -+DrawParams::Position TreeMapItem::position(int f) const -+{ -+ Position p = StoredDrawParams::position(f); -+ if (_widget && (p == Default)) -+ p = _widget->fieldPosition(f); -+ -+ return p; -+} -+ -+// use widget font -+const TQFont& TreeMapItem::font() const -+{ -+ return _widget->currentFont(); -+} -+ -+ -+bool TreeMapItem::isMarked(int) const -+{ -+ return false; -+} -+ -+ -+int TreeMapItem::borderWidth() const -+{ -+ if (_widget) -+ return _widget->borderWidth(); -+ -+ return 2; -+} -+ -+int TreeMapItem::sorting(bool* ascending) const -+{ -+ if (ascending) *ascending = _sortAscending; -+ return _sortTextNo; -+} -+ -+// do *not* set sorting recursively -+void TreeMapItem::setSorting(int textNo, bool ascending) -+{ -+ if (_sortTextNo == textNo) { -+ if(_sortAscending == ascending) return; -+ if (textNo == -1) { -+ // when no sorting is done, order change doesn't do anything -+ _sortAscending = ascending; -+ return; -+ } -+ } -+ _sortAscending = ascending; -+ _sortTextNo = textNo; -+ -+ if (_children && _sortTextNo != -1) _children->sort(); -+} -+ -+void TreeMapItem::resort(bool recursive) -+{ -+ if (!_children) return; -+ -+ if (_sortTextNo != -1) _children->sort(); -+ -+ if (recursive) -+ for (TreeMapItem* i=_children->first(); i; i=_children->next()) -+ i->resort(recursive); -+} -+ -+ -+TreeMapItem::SplitMode TreeMapItem::splitMode() const -+{ -+ if (_widget) -+ return _widget->splitMode(); -+ -+ return Best; -+} -+ -+int TreeMapItem::rtti() const -+{ -+ return 0; -+} -+ -+TreeMapItemList* TreeMapItem::children() -+{ -+ if (!_children) { -+ _children = new TreeMapItemList; -+ _children->setAutoDelete(true); -+ } -+ return _children; -+} -+ -+void TreeMapItem::clearItemRect() -+{ -+ _rect = TQRect(); -+ clearFreeRects(); -+} -+ -+void TreeMapItem::clearFreeRects() -+{ -+ if (_freeRects) _freeRects->clear(); -+} -+ -+void TreeMapItem::addFreeRect(const TQRect& r) -+{ -+ // don't add invalid rects -+ if ((r.width() < 1) || (r.height() < 1)) return; -+ -+ if (!_freeRects) { -+ _freeRects = new TQPtrList; -+ _freeRects->setAutoDelete(true); -+ } -+ -+ if (0) kdDebug(90100) << "addFree(" << path(0).join("/") << ", " -+ << r.x() << "/" << r.y() << "-" -+ << r.width() << "x" << r.height() << ")" << endl; -+ -+ TQRect* last = _freeRects->last(); -+ if (!last) { -+ _freeRects->append(new TQRect(r)); -+ return; -+ } -+ -+ // join rect with last rect if possible -+ // this saves memory and doesn't make the tooltip flicker -+ -+ bool replaced = false; -+ if ((last->left() == r.left()) && (last->width() == r.width())) { -+ if ((last->bottom()+1 == r.top()) || (r.bottom()+1 == last->top())) { -+ *last |= r; -+ replaced = true; -+ } -+ } -+ else if ((last->top() == r.top()) && (last->height() == r.height())) { -+ if ((last->right()+1 == r.left()) || (r.right()+1 == last->left())) { -+ *last |= r; -+ replaced = true; -+ } -+ } -+ -+ if (!replaced) { -+ _freeRects->append(new TQRect(r)); -+ return; -+ } -+ -+ if (0) kdDebug(90100) << " united with last to (" -+ << last->x() << "/" << last->y() << "-" -+ << last->width() << "x" << last->height() << ")" << endl; -+} -+ -+ -+// Tooltips for TreeMapWidget -+ -+class TreeMapTip: public TQToolTip -+{ -+public: -+ TreeMapTip( TQWidget* p ):TQToolTip(p) {} -+ -+protected: -+ void maybeTip( const TQPoint & ); -+}; -+ -+void TreeMapTip::maybeTip( const TQPoint& pos ) -+{ -+ if ( !parentWidget()->inherits( "TreeMapWidget" ) ) -+ return; -+ -+ TreeMapWidget* p = (TreeMapWidget*)parentWidget(); -+ TreeMapItem* i; -+ i = p->item(pos.x(), pos.y()); -+ TQPtrList* rList = i ? i->freeRects() : 0; -+ if (rList) { -+ TQRect* r; -+ for(r=rList->first();r;r=rList->next()) -+ if (r->contains(pos)) -+ tip(*r, p->tipString(i)); -+ } -+} -+ -+ -+ -+// TreeMapWidget -+ -+TreeMapWidget::TreeMapWidget(TreeMapItem* base, -+ TQWidget* parent, const char* name) -+ : TQWidget(parent, name) -+{ -+ _base = base; -+ _base->setWidget(this); -+ -+ _font = font(); -+ _fontHeight = fontMetrics().height(); -+ -+ -+ // default behaviour -+ _selectionMode = Single; -+ _splitMode = TreeMapItem::AlwaysBest; -+ _visibleWidth = 2; -+ _reuseSpace = false; -+ _skipIncorrectBorder = false; -+ _drawSeparators = false; -+ _allowRotation = true; -+ _borderWidth = 2; -+ _shading = true; // beautiful is default! -+ _maxSelectDepth = -1; // unlimited -+ _maxDrawingDepth = -1; // unlimited -+ _minimalArea = -1; // unlimited -+ _markNo = 0; -+ -+ for(int i=0;i<4;i++) { -+ _drawFrame[i] = true; -+ _transparent[i] = false; -+ } -+ -+ // _stopAtText will be unset on resizing (per default) -+ // _textVisible will be true on resizing (per default) -+ // _forceText will be false on resizing (per default) -+ -+ // start state: _selection is an empty list -+ _current = 0; -+ _oldCurrent = 0; -+ _pressed = 0; -+ _lastOver = 0; -+ _needsRefresh = _base; -+ -+ setBackgroundMode(TQt::NoBackground); -+ setFocusPolicy(TQ_StrongFocus); -+ _tip = new TreeMapTip(this); -+} -+ -+TreeMapWidget::~TreeMapWidget() -+{ -+ delete _base; -+ delete _tip; -+} -+ -+const TQFont& TreeMapWidget::currentFont() const -+{ -+ return _font; -+} -+ -+void TreeMapWidget::setSplitMode(TreeMapItem::SplitMode m) -+{ -+ if (_splitMode == m) return; -+ -+ _splitMode = m; -+ redraw(); -+} -+ -+TreeMapItem::SplitMode TreeMapWidget::splitMode() const -+{ -+ return _splitMode; -+} -+ -+bool TreeMapWidget::setSplitMode(TQString mode) -+{ -+ if (mode == "Bisection") setSplitMode(TreeMapItem::Bisection); -+ else if (mode == "Columns") setSplitMode(TreeMapItem::Columns); -+ else if (mode == "Rows") setSplitMode(TreeMapItem::Rows); -+ else if (mode == "AlwaysBest") setSplitMode(TreeMapItem::AlwaysBest); -+ else if (mode == "Best") setSplitMode(TreeMapItem::Best); -+ else if (mode == "HAlternate") setSplitMode(TreeMapItem::HAlternate); -+ else if (mode == "VAlternate") setSplitMode(TreeMapItem::VAlternate); -+ else if (mode == "Horizontal") setSplitMode(TreeMapItem::Horizontal); -+ else if (mode == "Vertical") setSplitMode(TreeMapItem::Vertical); -+ else return false; -+ -+ return true; -+} -+ -+TQString TreeMapWidget::splitModeString() const -+{ -+ TQString mode; -+ switch(splitMode()) { -+ case TreeMapItem::Bisection: mode = "Bisection"; break; -+ case TreeMapItem::Columns: mode = "Columns"; break; -+ case TreeMapItem::Rows: mode = "Rows"; break; -+ case TreeMapItem::AlwaysBest: mode = "AlwaysBest"; break; -+ case TreeMapItem::Best: mode = "Best"; break; -+ case TreeMapItem::HAlternate: mode = "HAlternate"; break; -+ case TreeMapItem::VAlternate: mode = "VAlternate"; break; -+ case TreeMapItem::Horizontal: mode = "Horizontal"; break; -+ case TreeMapItem::Vertical: mode = "Vertical"; break; -+ default: mode = "Unknown"; break; -+ } -+ return mode; -+} -+ -+ -+void TreeMapWidget::setShadingEnabled(bool s) -+{ -+ if (_shading == s) return; -+ -+ _shading = s; -+ redraw(); -+} -+ -+void TreeMapWidget::drawFrame(int d, bool b) -+{ -+ if ((d<0) || (d>=4) || (_drawFrame[d]==b)) return; -+ -+ _drawFrame[d] = b; -+ redraw(); -+} -+ -+void TreeMapWidget::setTransparent(int d, bool b) -+{ -+ if ((d<0) || (d>=4) || (_transparent[d]==b)) return; -+ -+ _transparent[d] = b; -+ redraw(); -+} -+ -+void TreeMapWidget::setAllowRotation(bool enable) -+{ -+ if (_allowRotation == enable) return; -+ -+ _allowRotation = enable; -+ redraw(); -+} -+ -+void TreeMapWidget::setVisibleWidth(int width, bool reuseSpace) -+{ -+ if (_visibleWidth == width && _reuseSpace == reuseSpace) return; -+ -+ _visibleWidth = width; -+ _reuseSpace = reuseSpace; -+ redraw(); -+} -+ -+void TreeMapWidget::setSkipIncorrectBorder(bool enable) -+{ -+ if (_skipIncorrectBorder == enable) return; -+ -+ _skipIncorrectBorder = enable; -+ redraw(); -+} -+ -+void TreeMapWidget::setBorderWidth(int w) -+{ -+ if (_borderWidth == w) return; -+ -+ _borderWidth = w; -+ redraw(); -+} -+ -+void TreeMapWidget::setMaxDrawingDepth(int d) -+{ -+ if (_maxDrawingDepth == d) return; -+ -+ _maxDrawingDepth = d; -+ redraw(); -+} -+ -+TQString TreeMapWidget::defaultFieldType(int f) const -+{ -+ return i18n("Text %1").arg(f+1); -+} -+ -+TQString TreeMapWidget::defaultFieldStop(int) const -+{ -+ return TQString(); -+} -+ -+bool TreeMapWidget::defaultFieldVisible(int f) const -+{ -+ return (f<2); -+} -+ -+bool TreeMapWidget::defaultFieldForced(int) const -+{ -+ return false; -+} -+ -+DrawParams::Position TreeMapWidget::defaultFieldPosition(int f) const -+{ -+ switch(f%4) { -+ case 0: return DrawParams::TopLeft; -+ case 1: return DrawParams::TopRight; -+ case 2: return DrawParams::BottomRight; -+ case 3: return DrawParams::BottomLeft; -+ default:break; -+ } -+ return DrawParams::TopLeft; -+} -+ -+bool TreeMapWidget::resizeAttr(int size) -+{ -+ if (size<0 || size>=MAX_FIELD) return false; -+ -+ if (size>(int)_attr.size()) { -+ struct FieldAttr a; -+ int oldSize = _attr.size(); -+ _attr.resize(size, a); -+ while (oldSize -1) -+ _selection.remove(); -+ -+ while(_tmpSelection.findRef(i) > -1) -+ _tmpSelection.remove(); -+ -+ if (_current == i) _current = 0; -+ if (_oldCurrent == i) _oldCurrent = 0; -+ if (_pressed == i) _pressed = 0; -+ if (_lastOver == i) _lastOver = 0; -+ -+ // don't redraw a deleted item -+ if (_needsRefresh == i) { -+ // we can savely redraw the parent, as deleting order is -+ // from child to parent; i.e. i->parent() is existing. -+ _needsRefresh = i->parent(); -+ } -+} -+ -+ -+TQString TreeMapWidget::tipString(TreeMapItem* i) const -+{ -+ TQString tip, itemTip; -+ -+ while (i) { -+ if (!i->text(0).isEmpty()) { -+ itemTip = i->text(0); -+ if (!i->text(1).isEmpty()) -+ itemTip += " (" + i->text(1) + ")"; -+ -+ if (!tip.isEmpty()) -+ tip += "\n"; -+ -+ tip += itemTip; -+ } -+ i = i->parent(); -+ } -+ return tip; -+} -+ -+TreeMapItem* TreeMapWidget::item(int x, int y) const -+{ -+ TreeMapItem* p = _base; -+ TreeMapItem* i; -+ -+ if (!TQT_TQRECT_OBJECT(rect()).contains(x, y)) return 0; -+ if (DEBUG_DRAWING) kdDebug(90100) << "item(" << x << "," << y << "):" << endl; -+ -+ while (1) { -+ TreeMapItemList* list = p->children(); -+ if (!list) -+ i = 0; -+ else { -+ int idx=0; -+ for (i=list->first();i;i=list->next(),idx++) { -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " Checking " << i->path(0).join("/") << " (" -+ << i->itemRect().x() << "/" << i->itemRect().y() -+ << "-" << i->itemRect().width() -+ << "x" << i->itemRect().height() << ")" << endl; -+ -+ if (i->itemRect().contains(x, y)) { -+ -+ if (DEBUG_DRAWING) kdDebug(90100) << " .. Got. Index " << idx << endl; -+ -+ p->setIndex(idx); -+ break; -+ } -+ } -+ } -+ -+ if (!i) { -+ static TreeMapItem* last = 0; -+ if (p != last) { -+ last = p; -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << "item(" << x << "," << y << "): Got " -+ << p->path(0).join("/") << " (Size " -+ << p->itemRect().width() << "x" << p->itemRect().height() -+ << ", Val " << p->value() << ")" << endl; -+ } -+ -+ return p; -+ } -+ p = i; -+ } -+ return 0; -+} -+ -+TreeMapItem* TreeMapWidget::possibleSelection(TreeMapItem* i) const -+{ -+ if (i) { -+ if (_maxSelectDepth>=0) { -+ int depth = i->depth(); -+ while(i && depth > _maxSelectDepth) { -+ i = i->parent(); -+ depth--; -+ } -+ } -+ } -+ return i; -+} -+ -+TreeMapItem* TreeMapWidget::visibleItem(TreeMapItem* i) const -+{ -+ if (i) { -+ /* Must have a visible area */ -+ while(i && ((i->itemRect().width() <1) || -+ (i->itemRect().height() <1))) { -+ TreeMapItem* p = i->parent(); -+ if (!p) break; -+ int idx = p->children()->findRef(i); -+ idx--; -+ if (idx<0) -+ i = p; -+ else -+ i = p->children()->at(idx); -+ } -+ } -+ return i; -+} -+ -+void TreeMapWidget::setSelected(TreeMapItem* item, bool selected) -+{ -+ item = possibleSelection(item); -+ setCurrent(item); -+ -+ TreeMapItem* changed = setTmpSelected(item, selected); -+ if (!changed) return; -+ -+ _selection = _tmpSelection; -+ if (_selectionMode == Single) -+ emit selectionChanged(item); -+ emit selectionChanged(); -+ redraw(changed); -+ -+ if (0) kdDebug(90100) << (selected ? "S":"Des") << "elected Item " -+ << (item ? item->path(0).join("") : TQString("(null)")) -+ << " (depth " << (item ? item->depth() : -1) -+ << ")" << endl; -+} -+ -+void TreeMapWidget::setMarked(int markNo, bool redrawWidget) -+{ -+ // if there's no marking, return -+ if ((_markNo == 0) && (markNo == 0)) return; -+ -+ _markNo = markNo; -+ if (!clearSelection() && redrawWidget) redraw(); -+} -+ -+/* Returns all items which appear only in one of the given lists */ -+TreeMapItemList TreeMapWidget::diff(TreeMapItemList& l1, -+ TreeMapItemList& l2) -+{ -+ TreeMapItemList l; -+ TreeMapItemListIterator it1(l1), it2(l2); -+ -+ TreeMapItem* item; -+ while ( (item = it1.current()) != 0 ) { -+ ++it1; -+ if (l2.containsRef(item) > 0) continue; -+ l.append(item); -+ } -+ while ( (item = it2.current()) != 0 ) { -+ ++it2; -+ if (l1.containsRef(item) > 0) continue; -+ l.append(item); -+ } -+ -+ return l; -+} -+ -+/* Only modifies _tmpSelection. -+ * Returns 0 when no change happened, otherwise the TreeMapItem that has -+ * to be redrawn for all changes. -+ */ -+TreeMapItem* TreeMapWidget::setTmpSelected(TreeMapItem* item, bool selected) -+{ -+ if (!item) return 0; -+ if (_selectionMode == NoSelection) return 0; -+ -+ TreeMapItemList old = _tmpSelection; -+ -+ if (_selectionMode == Single) { -+ _tmpSelection.clear(); -+ if (selected) _tmpSelection.append(item); -+ } -+ else { -+ if (selected) { -+ TreeMapItem* i=_tmpSelection.first(); -+ while (i) { -+ if (i->isChildOf(item) || item->isChildOf(i)) { -+ _tmpSelection.remove(); -+ i = _tmpSelection.current(); -+ } -+ else -+ i = _tmpSelection.next(); -+ } -+ _tmpSelection.append(item); -+ } -+ else -+ _tmpSelection.removeRef(item); -+ } -+ -+ return diff(old, _tmpSelection).commonParent(); -+} -+ -+ -+bool TreeMapWidget::clearSelection(TreeMapItem* parent) -+{ -+ TreeMapItemList old = _selection; -+ -+ TreeMapItem* i=_selection.first(); -+ while (i) { -+ if (i->isChildOf(parent)) { -+ _selection.remove(); -+ i = _selection.current(); -+ } -+ else -+ i = _selection.next(); -+ } -+ -+ TreeMapItem* changed = diff(old, _selection).commonParent(); -+ if (changed) { -+ changed->redraw(); -+ emit selectionChanged(); -+ } -+ return (changed != 0); -+} -+ -+bool TreeMapWidget::isSelected(TreeMapItem* i) const -+{ -+ return _selection.containsRef(i)>0; -+} -+ -+bool TreeMapWidget::isTmpSelected(TreeMapItem* i) -+{ -+ return _tmpSelection.containsRef(i)>0; -+} -+ -+ -+void TreeMapWidget::setCurrent(TreeMapItem* i, bool kbd) -+{ -+ TreeMapItem* old = _current; -+ _current = i; -+ -+ if (_markNo >0) { -+ // remove mark -+ _markNo = 0; -+ -+ if (1) kdDebug(90100) << "setCurrent(" << i->path(0).join("/") -+ << ") - mark removed" << endl; -+ -+ // always complete redraw needed to remove mark -+ redraw(); -+ -+ if (old == _current) return; -+ } -+ else { -+ if (old == _current) return; -+ -+ if (old) old->redraw(); -+ if (i) i->redraw(); -+ } -+ -+ //kdDebug(90100) << "Current Item " << (i ? i->path().ascii() : "(null)") << endl; -+ -+ emit currentChanged(i, kbd); -+} -+ -+void TreeMapWidget::setRangeSelection(TreeMapItem* i1, -+ TreeMapItem* i2, bool selected) -+{ -+ i1 = possibleSelection(i1); -+ i2 = possibleSelection(i2); -+ setCurrent(i2); -+ -+ TreeMapItem* changed = setTmpRangeSelection(i1, i2, selected); -+ if (!changed) return; -+ -+ _selection = _tmpSelection; -+ if (_selectionMode == Single) -+ emit selectionChanged(i2); -+ emit selectionChanged(); -+ redraw(changed); -+} -+ -+TreeMapItem* TreeMapWidget::setTmpRangeSelection(TreeMapItem* i1, -+ TreeMapItem* i2, -+ bool selected) -+{ -+ if ((i1 == 0) && (i2 == 0)) return 0; -+ if ((i1 == 0) || i1->isChildOf(i2)) return setTmpSelected(i2, selected); -+ if ((i2 == 0) || i2->isChildOf(i1)) return setTmpSelected(i1, selected); -+ -+ TreeMapItem* changed = setTmpSelected(i1, selected); -+ TreeMapItem* changed2 = setTmpSelected(i2, selected); -+ if (changed2) changed = changed2->commonParent(changed); -+ -+ TreeMapItem* commonParent = i1; -+ while (commonParent && !i2->isChildOf(commonParent)) { -+ i1 = commonParent; -+ commonParent = commonParent->parent(); -+ } -+ if (!commonParent) return changed; -+ while (i2 && i2->parent() != commonParent) -+ i2 = i2->parent(); -+ if (!i2) return changed; -+ -+ TreeMapItemList* list = commonParent->children(); -+ if (!list) return changed; -+ -+ TreeMapItem* i = list->first(); -+ bool between = false; -+ while (i) { -+ if (between) { -+ if (i==i1 || i==i2) break; -+ changed2 = setTmpSelected(i, selected); -+ if (changed2) changed = changed2->commonParent(changed); -+ } -+ else if (i==i1 || i==i2) -+ between = true; -+ i = list->next(); -+ } -+ -+ return changed; -+} -+ -+void TreeMapWidget::contextMenuEvent( TQContextMenuEvent* e ) -+{ -+ //kdDebug(90100) << "TreeMapWidget::contextMenuEvent" << endl; -+ -+ if ( receivers( TQT_SIGNAL(contextMenuRequested(TreeMapItem*, const TQPoint &)) ) ) -+ e->accept(); -+ -+ if ( e->reason() == TQContextMenuEvent::Keyboard ) { -+ TQRect r = (_current) ? _current->itemRect() : _base->itemRect(); -+ TQPoint p = TQPoint(r.left() + r.width()/2, r.top() + r.height()/2); -+ emit contextMenuRequested(_current, p); -+ } -+ else { -+ TreeMapItem* i = item(e->x(), e->y()); -+ emit contextMenuRequested(i, e->pos()); -+ } -+} -+ -+ -+void TreeMapWidget::mousePressEvent( TQMouseEvent* e ) -+{ -+ //kdDebug(90100) << "TreeMapWidget::mousePressEvent" << endl; -+ -+ _oldCurrent = _current; -+ -+ TreeMapItem* i = item(e->x(), e->y()); -+ -+ _pressed = i; -+ -+ _inShiftDrag = e->state() & ShiftButton; -+ _inControlDrag = e->state() & ControlButton; -+ _lastOver = _pressed; -+ -+ TreeMapItem* changed = 0; -+ TreeMapItem* item = possibleSelection(_pressed); -+ -+ switch(_selectionMode) { -+ case Single: -+ changed = setTmpSelected(item, true); -+ break; -+ case Multi: -+ changed = setTmpSelected(item, !isTmpSelected(item)); -+ break; -+ case Extended: -+ if (_inControlDrag) -+ changed = setTmpSelected(item, !isTmpSelected(item)); -+ else if (_inShiftDrag) { -+ TreeMapItem* sCurrent = possibleSelection(_current); -+ changed = setTmpRangeSelection(sCurrent, item, -+ !isTmpSelected(item)); -+ } -+ else { -+ _selectionMode = Single; -+ changed = setTmpSelected(item, true); -+ _selectionMode = Extended; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ // item under mouse always selected on right button press -+ if (e->button() == Qt::RightButton) { -+ TreeMapItem* changed2 = setTmpSelected(item, true); -+ if (changed2) changed = changed2->commonParent(changed); -+ } -+ -+ setCurrent(_pressed); -+ -+ if (changed) -+ redraw(changed); -+ -+ if (e->button() == Qt::RightButton) { -+ -+ // emit selection change -+ if (! (_tmpSelection == _selection)) { -+ _selection = _tmpSelection; -+ if (_selectionMode == Single) -+ emit selectionChanged(_lastOver); -+ emit selectionChanged(); -+ } -+ _pressed = 0; -+ _lastOver = 0; -+ emit rightButtonPressed(i, e->pos()); -+ } -+} -+ -+void TreeMapWidget::mouseMoveEvent( TQMouseEvent* e ) -+{ -+ //kdDebug(90100) << "TreeMapWidget::mouseMoveEvent" << endl; -+ -+ if (!_pressed) return; -+ TreeMapItem* over = item(e->x(), e->y()); -+ if (_lastOver == over) return; -+ -+ setCurrent(over); -+ if (over == 0) { -+ _lastOver = 0; -+ return; -+ } -+ -+ TreeMapItem* changed = 0; -+ TreeMapItem* item = possibleSelection(over); -+ -+ switch(_selectionMode) { -+ case Single: -+ changed = setTmpSelected(item, true); -+ break; -+ case Multi: -+ changed = setTmpSelected(item, !isTmpSelected(item)); -+ break; -+ case Extended: -+ if (_inControlDrag) -+ changed = setTmpSelected(item, !isTmpSelected(item)); -+ else { -+ TreeMapItem* sLast = possibleSelection(_lastOver); -+ changed = setTmpRangeSelection(sLast, item, true); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ _lastOver = over; -+ -+ if (changed) -+ redraw(changed); -+} -+ -+void TreeMapWidget::mouseReleaseEvent( TQMouseEvent* ) -+{ -+ //kdDebug(90100) << "TreeMapWidget::mouseReleaseEvent" << endl; -+ -+ if (!_pressed) return; -+ -+ if (!_lastOver) { -+ // take back -+ setCurrent(_oldCurrent); -+ TreeMapItem* changed = diff(_tmpSelection, _selection).commonParent(); -+ _tmpSelection = _selection; -+ if (changed) -+ redraw(changed); -+ } -+ else { -+ if (! (_tmpSelection == _selection)) { -+ _selection = _tmpSelection; -+ if (_selectionMode == Single) -+ emit selectionChanged(_lastOver); -+ emit selectionChanged(); -+ } -+ if (!_inControlDrag && !_inShiftDrag && (_pressed == _lastOver)) -+ emit clicked(_lastOver); -+ } -+ -+ _pressed = 0; -+ _lastOver = 0; -+} -+ -+ -+void TreeMapWidget::mouseDoubleClickEvent( TQMouseEvent* e ) -+{ -+ TreeMapItem* over = item(e->x(), e->y()); -+ -+ emit doubleClicked(over); -+} -+ -+ -+/* returns -1 if nothing visible found */ -+int nextVisible(TreeMapItem* i) -+{ -+ TreeMapItem* p = i->parent(); -+ if (!p || p->itemRect().isEmpty()) return -1; -+ -+ int idx = p->children()->findRef(i); -+ if (idx<0) return -1; -+ -+ while (idx < (int)p->children()->count()-1) { -+ idx++; -+ TQRect r = p->children()->at(idx)->itemRect(); -+ if (r.width()>1 && r.height()>1) -+ return idx; -+ } -+ return -1; -+} -+ -+/* returns -1 if nothing visible found */ -+int prevVisible(TreeMapItem* i) -+{ -+ TreeMapItem* p = i->parent(); -+ if (!p || p->itemRect().isEmpty()) return -1; -+ -+ int idx = p->children()->findRef(i); -+ if (idx<0) return -1; -+ -+ while (idx > 0) { -+ idx--; -+ TQRect r = p->children()->at(idx)->itemRect(); -+ if (r.width()>1 && r.height()>1) -+ return idx; -+ } -+ return -1; -+} -+ -+ -+ -+ -+void TreeMapWidget::keyPressEvent( TQKeyEvent* e ) -+{ -+ if (e->key() == Key_Escape && _pressed) { -+ -+ // take back -+ if (_oldCurrent != _lastOver) -+ setCurrent(_oldCurrent); -+ if (! (_tmpSelection == _selection)) { -+ TreeMapItem* changed = diff(_tmpSelection, _selection).commonParent(); -+ _tmpSelection = _selection; -+ if (changed) -+ redraw(changed); -+ } -+ _pressed = 0; -+ _lastOver = 0; -+ } -+ -+ if ((e->key() == Key_Space) || -+ (e->key() == Key_Return)) { -+ -+ switch(_selectionMode) { -+ case NoSelection: -+ break; -+ case Single: -+ setSelected(_current, true); -+ break; -+ case Multi: -+ setSelected(_current, !isSelected(_current)); -+ break; -+ case Extended: -+ if ((e->state() & ControlButton) || (e->state() & ShiftButton)) -+ setSelected(_current, !isSelected(_current)); -+ else { -+ _selectionMode = Single; -+ setSelected(_current, true); -+ _selectionMode = Extended; -+ } -+ } -+ -+ if (_current && (e->key() == Key_Return)) -+ emit returnPressed(_current); -+ -+ return; -+ } -+ -+ if (!_current) { -+ if (e->key() == Key_Down) { -+ setCurrent(_base, true); -+ } -+ return; -+ } -+ -+ TreeMapItem* old = _current, *newItem; -+ TreeMapItem* p = _current->parent(); -+ -+ bool goBack; -+ if (_current->sorting(&goBack) == -1) { -+ // noSorting -+ goBack = false; -+ } -+ -+ -+ if ((e->key() == Key_Backspace) || -+ (e->key() == Key_Up)) { -+ newItem = visibleItem(p); -+ setCurrent(newItem, true); -+ } -+ else if (e->key() == Key_Left) { -+ int newIdx = goBack ? nextVisible(_current) : prevVisible(_current); -+ if (p && newIdx>=0) { -+ p->setIndex(newIdx); -+ setCurrent(p->children()->at(newIdx), true); -+ } -+ } -+ else if (e->key() == Key_Right) { -+ int newIdx = goBack ? prevVisible(_current) : nextVisible(_current); -+ if (p && newIdx>=0) { -+ p->setIndex(newIdx); -+ setCurrent(p->children()->at(newIdx), true); -+ } -+ } -+ else if (e->key() == Key_Down) { -+ if (_current->children() && _current->children()->count()>0) { -+ int newIdx = _current->index(); -+ if (newIdx<0) -+ newIdx = goBack ? (_current->children()->count()-1) : 0; -+ if (newIdx>=(int)_current->children()->count()) -+ newIdx = _current->children()->count()-1; -+ newItem = visibleItem(_current->children()->at(newIdx)); -+ setCurrent(newItem, true); -+ } -+ } -+ -+ if (old == _current) return; -+ if (! (e->state() & ControlButton)) return; -+ if (! (e->state() & ShiftButton)) return; -+ -+ switch(_selectionMode) { -+ case NoSelection: -+ break; -+ case Single: -+ setSelected(_current, true); -+ break; -+ case Multi: -+ setSelected(_current, !isSelected(_current)); -+ break; -+ case Extended: -+ if (e->state() & ControlButton) -+ setSelected(_current, !isSelected(_current)); -+ else -+ setSelected(_current, isSelected(old)); -+ } -+} -+ -+void TreeMapWidget::fontChange( const TQFont& ) -+{ -+ redraw(); -+} -+ -+ -+void TreeMapWidget::resizeEvent( TQResizeEvent * ) -+{ -+ // this automatically redraws (as size is changed) -+ drawTreeMap(); -+} -+ -+void TreeMapWidget::paintEvent( TQPaintEvent * ) -+{ -+ drawTreeMap(); -+} -+ -+void TreeMapWidget::showEvent( TQShowEvent * ) -+{ -+ // refresh only if needed -+ drawTreeMap(); -+} -+ -+// Updates screen from shadow buffer, -+// but redraws before if needed -+void TreeMapWidget::drawTreeMap() -+{ -+ // no need to draw if hidden -+ if (!isVisible()) return; -+ -+ if (_pixmap.size() != size()) -+ _needsRefresh = _base; -+ -+ if (_needsRefresh) { -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << "Redrawing " << _needsRefresh->path(0).join("/") << endl; -+ -+ if (_needsRefresh == _base) { -+ // redraw whole widget -+ _pixmap = TQPixmap(size()); -+ _pixmap.fill(backgroundColor()); -+ } -+ TQPainter p(&_pixmap); -+ if (_needsRefresh == _base) { -+ p.setPen(black); -+ p.drawRect(TQRect(2, 2, TQWidget::width()-4, TQWidget::height()-4)); -+ _base->setItemRect(TQRect(3, 3, TQWidget::width()-6, TQWidget::height()-6)); -+ } -+ else { -+ // only subitem -+ if (!_needsRefresh->itemRect().isValid()) return; -+ } -+ -+ // reset cached font object; it could have been changed -+ _font = font(); -+ _fontHeight = fontMetrics().height(); -+ -+ drawItems(&p, _needsRefresh); -+ _needsRefresh = 0; -+ } -+ -+ bitBlt( TQT_TQPAINTDEVICE(this), 0, 0, TQT_TQPAINTDEVICE(&_pixmap), 0, 0, -+ TQWidget::width(), TQWidget::height(), CopyROP, true); -+ -+ if (hasFocus()) { -+ TQPainter p(this); -+ style().tqdrawPrimitive( TQStyle::PE_FocusRect, &p, -+ TQRect(0, 0, TQWidget::width(), TQWidget::height()), -+ colorGroup() ); -+ } -+} -+ -+ -+ -+void TreeMapWidget::redraw(TreeMapItem* i) -+{ -+ if (!i) return; -+ -+ if (!_needsRefresh) -+ _needsRefresh = i; -+ else { -+ if (!i->isChildOf(_needsRefresh)) -+ _needsRefresh = _needsRefresh->commonParent(i); -+ } -+ -+ if (isVisible()) { -+ // delayed drawing if we have multiple redraw requests -+ update(); -+ } -+} -+ -+void TreeMapWidget::drawItem(TQPainter* p, -+ TreeMapItem* item) -+{ -+ bool isSelected = false; -+ TreeMapItem* i; -+ -+ if (_markNo>0) { -+ for(i = item;i;i=i->parent()) -+ if (i->isMarked(_markNo)) break; -+ -+ isSelected = (i!=0); -+ } -+ else { -+ for (i=_tmpSelection.first();i;i=_tmpSelection.next()) -+ if (item->isChildOf(i)) break; -+ -+ isSelected = (i!=0); -+ } -+ -+ bool isCurrent = _current && item->isChildOf(_current); -+ int dd = item->depth(); -+ if (isTransparent(dd)) return; -+ -+ RectDrawing d(item->itemRect()); -+ item->setSelected(isSelected); -+ item->setCurrent(isCurrent); -+ item->setShaded(_shading); -+ item->drawFrame(drawFrame(dd)); -+ d.drawBack(p, item); -+} -+ -+ -+bool TreeMapWidget::horizontal(TreeMapItem* i, const TQRect& r) -+{ -+ switch(i->splitMode()) { -+ case TreeMapItem::HAlternate: -+ return (i->depth()%2)==1; -+ case TreeMapItem::VAlternate: -+ return (i->depth()%2)==0; -+ case TreeMapItem::Horizontal: -+ return true; -+ case TreeMapItem::Vertical: -+ return false; -+ default: -+ return r.width() > r.height(); -+ } -+ return false; -+} -+ -+ -+/** -+ * Draw TreeMapItems recursive, starting from item -+ */ -+void TreeMapWidget::drawItems(TQPainter* p, -+ TreeMapItem* item) -+{ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << "+drawItems(" << item->path(0).join("/") << ", " -+ << item->itemRect().x() << "/" << item->itemRect().y() -+ << "-" << item->itemRect().width() << "x" -+ << item->itemRect().height() << "), Val " << item->value() -+ << ", Sum " << item->sum() << endl; -+ -+ drawItem(p, item); -+ item->clearFreeRects(); -+ -+ TQRect origRect = item->itemRect(); -+ int bw = item->borderWidth(); -+ TQRect r = TQRect(origRect.x()+bw, origRect.y()+bw, -+ origRect.width()-2*bw, origRect.height()-2*bw); -+ -+ TreeMapItemList* list = item->children(); -+ TreeMapItem* i; -+ -+ bool stopDrawing = false; -+ -+ // only subdivide if there are children -+ if (!list || list->count()==0) -+ stopDrawing = true; -+ -+ // only subdivide if there is enough space -+ if (!stopDrawing && (r.width()<=0 || r.height()<=0)) -+ stopDrawing = true; -+ -+ // stop drawing if maximum depth is reached -+ if (!stopDrawing && -+ (_maxDrawingDepth>=0 && item->depth()>=_maxDrawingDepth)) -+ stopDrawing = true; -+ -+ // stop drawing if stopAtText is reached -+ if (!stopDrawing) -+ for (int no=0;no<(int)_attr.size();no++) { -+ TQString stopAt = fieldStop(no); -+ if (!stopAt.isEmpty() && (item->text(no) == stopAt)) { -+ stopDrawing = true; -+ break; -+ } -+ } -+ -+ // area size is checked later... -+#if 0 -+ // stop drawing if minimal area size is reached -+ if (!stopDrawing && -+ (_minimalArea > 0) && -+ (r.width() * r.height() < _minimalArea)) stopDrawing = true; -+#endif -+ -+ if (stopDrawing) { -+ if (list) { -+ // invalidate rects -+ for (i=list->first();i;i=list->next()) -+ i->clearItemRect(); -+ } -+ // tooltip apears on whole item rect -+ item->addFreeRect(item->itemRect()); -+ -+ // if we have space for text... -+ if ((r.height() < _fontHeight) || (r.width() < _fontHeight)) return; -+ -+ RectDrawing d(r); -+ item->setRotated(_allowRotation && (r.height() > r.width())); -+ for (int no=0;no<(int)_attr.size();no++) { -+ if (!fieldVisible(no)) continue; -+ d.drawField(p, no, item); -+ } -+ r = d.remainingRect(item); -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << "-drawItems(" << item->path(0).join("/") << ")" << endl; -+ return; -+ } -+ -+ double user_sum, child_sum, self; -+ -+ // user supplied sum -+ user_sum = item->sum(); -+ -+ // own sum -+ child_sum = 0; -+ for (i=list->first();i;i=list->next()) { -+ child_sum += i->value(); -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " child: " << i->text(0) << ", value " -+ << i->value() << endl; -+ } -+ -+ TQRect orig = r; -+ -+ // if we have space for text... -+ if ((r.height() >= _fontHeight) && (r.width() >= _fontHeight)) { -+ -+ RectDrawing d(r); -+ item->setRotated(_allowRotation && (r.height() > r.width())); -+ for (int no=0;no<(int)_attr.size();no++) { -+ if (!fieldVisible(no)) continue; -+ if (!fieldForced(no)) continue; -+ d.drawField(p, no, item); -+ } -+ r = d.remainingRect(item); -+ } -+ -+ if (orig.x() == r.x()) { -+ // Strings on top -+ item->addFreeRect(TQRect(orig.x(), orig.y(), -+ orig.width(), orig.height()-r.height())); -+ } -+ else { -+ // Strings on the left -+ item->addFreeRect(TQRect(orig.x(), orig.y(), -+ orig.width()-r.width(), orig.height())); -+ } -+ -+ if (user_sum == 0) { -+ // user didn't supply any sum -+ user_sum = child_sum; -+ self = 0; -+ } -+ else { -+ self = user_sum - child_sum; -+ -+ if (user_sum < child_sum) { -+ //kdDebug(90100) << "TreeMWidget " << -+ // item->path() << ": User sum " << user_sum << " < Child Items sum " << child_sum << endl; -+ -+ // invalid user supplied sum: ignore and use calculate sum -+ user_sum = child_sum; -+ self = 0.0; -+ } -+ else { -+ // Try to put the border waste in self -+ // percent of wasted space on border... -+ float borderArea = origRect.width() * origRect.height(); -+ borderArea = (borderArea - r.width()*r.height())/borderArea; -+ unsigned borderValue = (unsigned)(borderArea * user_sum); -+ -+ if (borderValue > self) { -+ if (_skipIncorrectBorder) { -+ r = origRect; -+ // should add my self to nested self and set my self =0 -+ } -+ else -+ self = 0.0; -+ } -+ else -+ self -= borderValue; -+ -+ user_sum = child_sum + self; -+ } -+ } -+ -+ bool rotate = (_allowRotation && (r.height() > r.width())); -+ int self_length = (int)( ((rotate) ? r.width() : r.height()) * -+ self / user_sum + .5); -+ if (self_length > 0) { -+ // take space for self cost -+ TQRect sr = r; -+ if (rotate) { -+ sr.setWidth( self_length ); -+ r.setRect(r.x()+sr.width(), r.y(), r.width()-sr.width(), r.height()); -+ } -+ else { -+ sr.setHeight( self_length ); -+ r.setRect(r.x(), r.y()+sr.height(), r.width(), r.height()-sr.height()); -+ } -+ -+ // set selfRect (not occupied by children) for tooltip -+ item->addFreeRect(sr); -+ -+ if (0) kdDebug(90100) << "Item " << item->path(0).join("/") << ": SelfR " -+ << sr.x() << "/" << sr.y() << "-" << sr.width() -+ << "/" << sr.height() << ", self " << self << "/" -+ << user_sum << endl; -+ -+ if ((sr.height() >= _fontHeight) && (sr.width() >= _fontHeight)) { -+ -+ RectDrawing d(sr); -+ item->setRotated(_allowRotation && (r.height() > r.width())); -+ for (int no=0;no<(int)_attr.size();no++) { -+ if (!fieldVisible(no)) continue; -+ if (fieldForced(no)) continue; -+ d.drawField(p, no, item); -+ } -+ } -+ -+ user_sum -= self; -+ } -+ -+ bool goBack; -+ if (item->sorting(&goBack) == -1) { -+ // noSorting -+ goBack = false; -+ } -+ -+ TreeMapItemListIterator it(*list); -+ if (goBack) it.toLast(); -+ -+ if (item->splitMode() == TreeMapItem::Columns) { -+ int len = list->count(); -+ bool drawDetails = true; -+ -+ while (len>0 && user_sum>0) { -+ TreeMapItemListIterator first = it; -+ double valSum = 0; -+ int lenLeft = len; -+ int columns = (int)(sqrt((double)len * r.width()/r.height())+.5); -+ if (columns==0) columns = 1; //should never be needed -+ -+ while (lenLeft>0 && ((double)valSum*(len-lenLeft) < -+ (double)len*user_sum/columns/columns)) { -+ valSum += it.current()->value(); -+ if (goBack) --it; else ++it; -+ lenLeft--; -+ } -+ -+ // we always split horizontally -+ int nextPos = (int)((double)r.width() * valSum / user_sum); -+ TQRect firstRect = TQRect(r.x(), r.y(), nextPos, r.height()); -+ -+ if (nextPos < _visibleWidth) { -+ if (item->sorting(0) == -1) { -+ // fill current rect with hash pattern -+ drawFill(item, p, firstRect); -+ } -+ else { -+ // fill rest with hash pattern -+ drawFill(item, p, r, first, len, goBack); -+ break; -+ } -+ } -+ else { -+ drawDetails = drawItemArray(p, item, firstRect, -+ valSum, first, len-lenLeft, goBack); -+ } -+ r.setRect(r.x()+nextPos, r.y(), r.width()-nextPos, r.height()); -+ user_sum -= valSum; -+ len = lenLeft; -+ -+ if (!drawDetails) { -+ if (item->sorting(0) == -1) -+ drawDetails = true; -+ else { -+ drawFill(item, p, r, it, len, goBack); -+ break; -+ } -+ } -+ } -+ } -+ else if (item->splitMode() == TreeMapItem::Rows) { -+ int len = list->count(); -+ bool drawDetails = true; -+ -+ while (len>0 && user_sum>0) { -+ TreeMapItemListIterator first = it; -+ double valSum = 0; -+ int lenLeft = len; -+ int rows = (int)(sqrt((double)len * r.height()/r.width())+.5); -+ if (rows==0) rows = 1; //should never be needed -+ -+ while (lenLeft>0 && ((double)valSum*(len-lenLeft) < -+ (double)len*user_sum/rows/rows)) { -+ valSum += it.current()->value(); -+ if (goBack) --it; else ++it; -+ lenLeft--; -+ } -+ -+ // we always split horizontally -+ int nextPos = (int)((double)r.height() * valSum / user_sum); -+ TQRect firstRect = TQRect(r.x(), r.y(), r.width(), nextPos); -+ -+ if (nextPos < _visibleWidth) { -+ if (item->sorting(0) == -1) { -+ drawFill(item, p, firstRect); -+ } -+ else { -+ drawFill(item, p, r, first, len, goBack); -+ break; -+ } -+ } -+ else { -+ drawDetails = drawItemArray(p, item, firstRect, -+ valSum, first, len-lenLeft, goBack); -+ } -+ r.setRect(r.x(), r.y()+nextPos, r.width(), r.height()-nextPos); -+ user_sum -= valSum; -+ len = lenLeft; -+ -+ if (!drawDetails) { -+ if (item->sorting(0) == -1) -+ drawDetails = true; -+ else { -+ drawFill(item, p, r, it, len, goBack); -+ break; -+ } -+ } -+ } -+ } -+ else -+ drawItemArray(p, item, r, user_sum, it, list->count(), goBack); -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << "-drawItems(" << item->path(0).join("/") << ")" << endl; -+} -+ -+// fills area with a pattern if to small to draw children -+void TreeMapWidget::drawFill(TreeMapItem* i, TQPainter* p, TQRect& r) -+{ -+ p->setBrush(TQt::Dense4Pattern); -+ p->setPen(TQt::NoPen); -+ p->drawRect(r); -+ i->addFreeRect(r); -+} -+ -+// fills area with a pattern if to small to draw children -+void TreeMapWidget::drawFill(TreeMapItem* i, TQPainter* p, TQRect& r, -+ TreeMapItemListIterator it, int len, bool goBack) -+{ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " +drawFill(" << r.x() << "/" << r.y() -+ << "-" << r.width() << "x" << r.height() -+ << ", len " << len << ")" << endl; -+ -+ p->setBrush(TQt::Dense4Pattern); -+ p->setPen(TQt::NoPen); -+ p->drawRect(r); -+ i->addFreeRect(r); -+ -+ // reset rects -+ while (len>0 && it.current()) { -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " Reset Rect " << (*it)->path(0).join("/") << endl; -+ -+ (*it)->clearItemRect(); -+ if (goBack) --it; else ++it; -+ len--; -+ } -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " -drawFill(" << r.x() << "/" << r.y() -+ << "-" << r.width() << "x" << r.height() -+ << ", len " << len << ")" << endl; -+} -+ -+// returns false if rect gets to small -+bool TreeMapWidget::drawItemArray(TQPainter* p, TreeMapItem* item, -+ TQRect& r, double user_sum, -+ TreeMapItemListIterator it, int len, -+ bool goBack) -+{ -+ if (user_sum == 0) return false; -+ -+ static bool b2t = true; -+ -+ // stop recursive bisection for small rectangles -+ if (((r.height() < _visibleWidth) && -+ (r.width() < _visibleWidth)) || -+ ((_minimalArea > 0) && -+ (r.width() * r.height() < _minimalArea))) { -+ -+ drawFill(item, p, r, it, len, goBack); -+ return false; -+ } -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " +drawItemArray(" << item->path(0).join("/") -+ << ", " << r.x() << "/" << r.y() << "-" << r.width() -+ << "x" << r.height() << ")" << endl; -+ -+ if (len>2 && (item->splitMode() == TreeMapItem::Bisection)) { -+ -+ TreeMapItemListIterator first = it; -+ double valSum = 0; -+ int lenLeft = len; -+ //while (lenLeft>0 && valSumlen/2) { -+ valSum += it.current()->value(); -+ if (goBack) --it; else ++it; -+ lenLeft--; -+ } -+ -+ // draw first half... -+ bool drawOn; -+ -+ if (r.width() > r.height()) { -+ int halfPos = (int)((double)r.width() * valSum / user_sum); -+ TQRect firstRect = TQRect(r.x(), r.y(), halfPos, r.height()); -+ drawOn = drawItemArray(p, item, firstRect, -+ valSum, first, len-lenLeft, goBack); -+ r.setRect(r.x()+halfPos, r.y(), r.width()-halfPos, r.height()); -+ } -+ else { -+ int halfPos = (int)((double)r.height() * valSum / user_sum); -+ TQRect firstRect = TQRect(r.x(), r.y(), r.width(), halfPos); -+ drawOn = drawItemArray(p, item, firstRect, -+ valSum, first, len-lenLeft, goBack); -+ r.setRect(r.x(), r.y()+halfPos, r.width(), r.height()-halfPos); -+ } -+ -+ // if no sorting, don't stop drawing -+ if (item->sorting(0) == -1) drawOn = true; -+ -+ // second half -+ if (drawOn) -+ drawOn = drawItemArray(p, item, r, user_sum - valSum, -+ it, lenLeft, goBack); -+ else { -+ drawFill(item, p, r, it, len, goBack); -+ } -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/") -+ << ")" << endl; -+ -+ return drawOn; -+ } -+ -+ bool hor = horizontal(item,r); -+ -+ TreeMapItem* i; -+ while (len>0) { -+ i = it.current(); -+ if (user_sum <= 0) { -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << "drawItemArray: Reset " << i->path(0).join("/") << endl; -+ -+ i->clearItemRect(); -+ if (goBack) --it; else ++it; -+ len--; -+ continue; -+ } -+ -+ // stop drawing for small rectangles -+ if (((r.height() < _visibleWidth) && -+ (r.width() < _visibleWidth)) || -+ ((_minimalArea > 0) && -+ (r.width() * r.height() < _minimalArea))) { -+ -+ drawFill(item, p, r, it, len, goBack); -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/") -+ << "): Stop" << endl; -+ return false; -+ } -+ -+ if (i->splitMode() == TreeMapItem::AlwaysBest) -+ hor = r.width() > r.height(); -+ -+ int lastPos = hor ? r.width() : r.height(); -+ double val = i->value(); -+ int nextPos = (user_sum <= 0.0) ? 0: (int)(lastPos * val / user_sum +.5); -+ if (nextPos>lastPos) nextPos = lastPos; -+ -+ if ((item->sorting(0) != -1) && (nextPos < _visibleWidth)) { -+ drawFill(item, p, r, it, len, goBack); -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/") -+ << "): Stop" << endl; -+ return false; -+ } -+ -+ TQRect currRect = r; -+ -+ if (hor) -+ currRect.setWidth(nextPos); -+ else { -+ if (b2t) -+ currRect.setRect(r.x(), r.bottom()-nextPos+1, r.width(), nextPos); -+ else -+ currRect.setHeight(nextPos); -+ } -+ -+ // don't draw very small rectangles: -+ if (nextPos >= _visibleWidth) { -+ i->setItemRect(currRect); -+ drawItems(p, i); -+ } -+ else { -+ i->clearItemRect(); -+ drawFill(item, p, currRect); -+ } -+ -+ // draw Separator -+ if (_drawSeparators && (nextPossetPen(black); -+ if (hor) { -+ if (r.top()<=r.bottom()) -+ p->drawLine(r.x() + nextPos, r.top(), r.x() + nextPos, r.bottom()); -+ } -+ else { -+ if (r.left()<=r.right()) -+ p->drawLine(r.left(), r.y() + nextPos, r.right(), r.y() + nextPos); -+ } -+ nextPos++; -+ } -+ -+ if (hor) -+ r.setRect(r.x() + nextPos, r.y(), lastPos-nextPos, r.height()); -+ else { -+ if (b2t) -+ r.setRect(r.x(), r.y(), r.width(), lastPos-nextPos); -+ else -+ r.setRect(r.x(), r.y() + nextPos, r.width(), lastPos-nextPos); -+ } -+ -+ user_sum -= val; -+ if (goBack) --it; else ++it; -+ len--; -+ } -+ -+ if (DEBUG_DRAWING) -+ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/") -+ << "): Continue" << endl; -+ -+ return true; -+} -+ -+ -+/*---------------------------------------------------------------- -+ * Popup menus for option setting -+ */ -+ -+void TreeMapWidget::splitActivated(int id) -+{ -+ if (id == _splitID) setSplitMode(TreeMapItem::Bisection); -+ else if (id == _splitID+1) setSplitMode(TreeMapItem::Columns); -+ else if (id == _splitID+2) setSplitMode(TreeMapItem::Rows); -+ else if (id == _splitID+3) setSplitMode(TreeMapItem::AlwaysBest); -+ else if (id == _splitID+4) setSplitMode(TreeMapItem::Best); -+ else if (id == _splitID+5) setSplitMode(TreeMapItem::VAlternate); -+ else if (id == _splitID+6) setSplitMode(TreeMapItem::HAlternate); -+ else if (id == _splitID+7) setSplitMode(TreeMapItem::Horizontal); -+ else if (id == _splitID+8) setSplitMode(TreeMapItem::Vertical); -+} -+ -+ -+void TreeMapWidget::addSplitDirectionItems(TQPopupMenu* popup, int id) -+{ -+ _splitID = id; -+ popup->setCheckable(true); -+ -+ connect(popup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(splitActivated(int))); -+ -+ popup->insertItem(i18n("Recursive Bisection"), id); -+ popup->insertItem(i18n("Columns"), id+1); -+ popup->insertItem(i18n("Rows"), id+2); -+ popup->insertItem(i18n("Always Best"), id+3); -+ popup->insertItem(i18n("Best"), id+4); -+ popup->insertItem(i18n("Alternate (V)"), id+5); -+ popup->insertItem(i18n("Alternate (H)"), id+6); -+ popup->insertItem(i18n("Horizontal"), id+7); -+ popup->insertItem(i18n("Vertical"), id+8); -+ -+ switch(splitMode()) { -+ case TreeMapItem::Bisection: popup->setItemChecked(id,true); break; -+ case TreeMapItem::Columns: popup->setItemChecked(id+1,true); break; -+ case TreeMapItem::Rows: popup->setItemChecked(id+2,true); break; -+ case TreeMapItem::AlwaysBest: popup->setItemChecked(id+3,true); break; -+ case TreeMapItem::Best: popup->setItemChecked(id+4,true); break; -+ case TreeMapItem::VAlternate: popup->setItemChecked(id+5,true); break; -+ case TreeMapItem::HAlternate: popup->setItemChecked(id+6,true); break; -+ case TreeMapItem::Horizontal: popup->setItemChecked(id+7,true); break; -+ case TreeMapItem::Vertical: popup->setItemChecked(id+8,true); break; -+ default: break; -+ } -+} -+ -+void TreeMapWidget::visualizationActivated(int id) -+{ -+ if (id == _visID+2) setSkipIncorrectBorder(!skipIncorrectBorder()); -+ else if (id == _visID+3) setBorderWidth(0); -+ else if (id == _visID+4) setBorderWidth(1); -+ else if (id == _visID+5) setBorderWidth(2); -+ else if (id == _visID+6) setBorderWidth(3); -+ else if (id == _visID+10) setAllowRotation(!allowRotation()); -+ else if (id == _visID+11) setShadingEnabled(!isShadingEnabled()); -+ else if (id<_visID+19 || id>_visID+100) return; -+ -+ id -= 20+_visID; -+ int f = id/10; -+ if ((id%10) == 1) setFieldVisible(f, !fieldVisible(f)); -+ else if ((id%10) == 2) setFieldForced(f, !fieldForced(f)); -+ else if ((id%10) == 3) setFieldPosition(f, DrawParams::TopLeft); -+ else if ((id%10) == 4) setFieldPosition(f, DrawParams::TopCenter); -+ else if ((id%10) == 5) setFieldPosition(f, DrawParams::TopRight); -+ else if ((id%10) == 6) setFieldPosition(f, DrawParams::BottomLeft); -+ else if ((id%10) == 7) setFieldPosition(f, DrawParams::BottomCenter); -+ else if ((id%10) == 8) setFieldPosition(f, DrawParams::BottomRight); -+} -+ -+void TreeMapWidget::addVisualizationItems(TQPopupMenu* popup, int id) -+{ -+ _visID = id; -+ -+ popup->setCheckable(true); -+ -+ TQPopupMenu* bpopup = new TQPopupMenu(); -+ bpopup->setCheckable(true); -+ -+ connect(popup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(visualizationActivated(int))); -+ connect(bpopup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(visualizationActivated(int))); -+ -+ TQPopupMenu* spopup = new TQPopupMenu(); -+ addSplitDirectionItems(spopup, id+100); -+ popup->insertItem(i18n("Nesting"), spopup, id); -+ -+ popup->insertItem(i18n("Border"), bpopup, id+1); -+ bpopup->insertItem(i18n("Correct Borders Only"), id+2); -+ bpopup->insertSeparator(); -+ bpopup->insertItem(i18n("Width %1").arg(0), id+3); -+ bpopup->insertItem(i18n("Width %1").arg(1), id+4); -+ bpopup->insertItem(i18n("Width %1").arg(2), id+5); -+ bpopup->insertItem(i18n("Width %1").arg(3), id+6); -+ bpopup->setItemChecked(id+2, skipIncorrectBorder()); -+ bpopup->setItemChecked(id+3, borderWidth()==0); -+ bpopup->setItemChecked(id+4, borderWidth()==1); -+ bpopup->setItemChecked(id+5, borderWidth()==2); -+ bpopup->setItemChecked(id+6, borderWidth()==3); -+ -+ popup->insertItem(i18n("Allow Rotation"), id+10); -+ popup->setItemChecked(id+10,allowRotation()); -+ popup->insertItem(i18n("Shading"), id+11); -+ popup->setItemChecked(id+11,isShadingEnabled()); -+ -+ if (_attr.size() ==0) return; -+ -+ popup->insertSeparator(); -+ int f; -+ TQPopupMenu* tpopup; -+ id += 20; -+ for (f=0;f<(int)_attr.size();f++, id+=10) { -+ tpopup = new TQPopupMenu(); -+ tpopup->setCheckable(true); -+ popup->insertItem(_attr[f].type, tpopup, id); -+ tpopup->insertItem(i18n("Visible"), id+1); -+ tpopup->insertItem(i18n("Take Space From Children"), id+2); -+ tpopup->insertSeparator(); -+ tpopup->insertItem(i18n("Top Left"), id+3); -+ tpopup->insertItem(i18n("Top Center"), id+4); -+ tpopup->insertItem(i18n("Top Right"), id+5); -+ tpopup->insertItem(i18n("Bottom Left"), id+6); -+ tpopup->insertItem(i18n("Bottom Center"), id+7); -+ tpopup->insertItem(i18n("Bottom Right"), id+8); -+ -+ tpopup->setItemChecked(id+1,_attr[f].visible); -+ tpopup->setItemEnabled(id+2,_attr[f].visible); -+ tpopup->setItemEnabled(id+3,_attr[f].visible); -+ tpopup->setItemEnabled(id+4,_attr[f].visible); -+ tpopup->setItemEnabled(id+5,_attr[f].visible); -+ tpopup->setItemEnabled(id+6,_attr[f].visible); -+ tpopup->setItemEnabled(id+7,_attr[f].visible); -+ tpopup->setItemEnabled(id+8,_attr[f].visible); -+ tpopup->setItemChecked(id+2,_attr[f].forced); -+ tpopup->setItemChecked(id+3,_attr[f].pos == DrawParams::TopLeft); -+ tpopup->setItemChecked(id+4,_attr[f].pos == DrawParams::TopCenter); -+ tpopup->setItemChecked(id+5,_attr[f].pos == DrawParams::TopRight); -+ tpopup->setItemChecked(id+6,_attr[f].pos == DrawParams::BottomLeft); -+ tpopup->setItemChecked(id+7,_attr[f].pos == DrawParams::BottomCenter); -+ tpopup->setItemChecked(id+8,_attr[f].pos == DrawParams::BottomRight); -+ -+ connect(tpopup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(visualizationActivated(int))); -+ } -+} -+ -+void TreeMapWidget::selectionActivated(int id) -+{ -+ TreeMapItem* i = _menuItem; -+ id -= _selectionID; -+ while (id>0 && i) { -+ i=i->parent(); -+ id--; -+ } -+ if (i) -+ setSelected(i, true); -+} -+ -+void TreeMapWidget::addSelectionItems(TQPopupMenu* popup, -+ int id, TreeMapItem* i) -+{ -+ if (!i) return; -+ -+ _selectionID = id; -+ _menuItem = i; -+ -+ connect(popup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(selectionActivated(int))); -+ -+ while (i) { -+ TQString name = i->text(0); -+ if (name.isEmpty()) break; -+ popup->insertItem(i->text(0), id++); -+ i = i->parent(); -+ } -+} -+ -+void TreeMapWidget::fieldStopActivated(int id) -+{ -+ if (id == _fieldStopID) setFieldStop(0, TQString()); -+ else { -+ TreeMapItem* i = _menuItem; -+ id -= _fieldStopID+1; -+ while (id>0 && i) { -+ i=i->parent(); -+ id--; -+ } -+ if (i) -+ setFieldStop(0, i->text(0)); -+ } -+} -+ -+void TreeMapWidget::addFieldStopItems(TQPopupMenu* popup, -+ int id, TreeMapItem* i) -+{ -+ _fieldStopID = id; -+ -+ connect(popup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(fieldStopActivated(int))); -+ -+ popup->insertItem(i18n("No %1 Limit").arg(fieldType(0)), id); -+ popup->setItemChecked(id, fieldStop(0).isEmpty()); -+ _menuItem = i; -+ bool foundFieldStop = false; -+ if (i) { -+ popup->insertSeparator(); -+ -+ while (i) { -+ id++; -+ TQString name = i->text(0); -+ if (name.isEmpty()) break; -+ popup->insertItem(i->text(0), id); -+ if (fieldStop(0) == i->text(0)) { -+ popup->setItemChecked(id, true); -+ foundFieldStop = true; -+ } -+ i = i->parent(); -+ } -+ } -+ -+ if (!foundFieldStop && !fieldStop(0).isEmpty()) { -+ popup->insertSeparator(); -+ popup->insertItem(fieldStop(0), id+1); -+ popup->setItemChecked(id+1, true); -+ } -+} -+ -+void TreeMapWidget::areaStopActivated(int id) -+{ -+ if (id == _areaStopID) setMinimalArea(-1); -+ else if (id == _areaStopID+1) { -+ int area = _menuItem ? (_menuItem->width() * _menuItem->height()) : -1; -+ setMinimalArea(area); -+ } -+ else if (id == _areaStopID+2) setMinimalArea(100); -+ else if (id == _areaStopID+3) setMinimalArea(400); -+ else if (id == _areaStopID+4) setMinimalArea(1000); -+ else if (id == _areaStopID+5) setMinimalArea(minimalArea()*2); -+ else if (id == _areaStopID+6) setMinimalArea(minimalArea()/2); -+} -+ -+void TreeMapWidget::addAreaStopItems(TQPopupMenu* popup, -+ int id, TreeMapItem* i) -+{ -+ _areaStopID = id; -+ _menuItem = i; -+ -+ connect(popup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(areaStopActivated(int))); -+ -+ bool foundArea = false; -+ -+ popup->insertItem(i18n("No Area Limit"), id); -+ popup->setItemChecked(id, minimalArea() == -1); -+ -+ if (i) { -+ int area = i->width() * i->height(); -+ popup->insertSeparator(); -+ popup->insertItem(i18n("Area of '%1' (%2)") -+ .arg(i->text(0)).arg(area), id+1); -+ if (area == minimalArea()) { -+ popup->setItemChecked(id+1, true); -+ foundArea = true; -+ } -+ } -+ -+ popup->insertSeparator(); -+ int area = 100, count; -+ for (count=0;count<3;count++) { -+ popup->insertItem(i18n("1 Pixel", "%n Pixels", area), id+2+count); -+ if (area == minimalArea()) { -+ popup->setItemChecked(id+2+count, true); -+ foundArea = true; -+ } -+ area = (area==100) ? 400 : (area==400) ? 1000 : 4000; -+ } -+ -+ if (minimalArea()>0) { -+ popup->insertSeparator(); -+ if (!foundArea) { -+ popup->insertItem(i18n("1 Pixel", "%n Pixels", minimalArea()), id+10); -+ popup->setItemChecked(id+10, true); -+ } -+ -+ popup->insertItem(i18n("Double Area Limit (to %1)") -+ .arg(minimalArea()*2), id+5); -+ popup->insertItem(i18n("Halve Area Limit (to %1)") -+ .arg(minimalArea()/2), id+6); -+ } -+} -+ -+ -+void TreeMapWidget::depthStopActivated(int id) -+{ -+ if (id == _depthStopID) setMaxDrawingDepth(-1); -+ else if (id == _depthStopID+1) { -+ int d = _menuItem ? _menuItem->depth() : -1; -+ setMaxDrawingDepth(d); -+ } -+ else if (id == _depthStopID+2) setMaxDrawingDepth(maxDrawingDepth()-1); -+ else if (id == _depthStopID+3) setMaxDrawingDepth(maxDrawingDepth()+1); -+} -+ -+void TreeMapWidget::addDepthStopItems(TQPopupMenu* popup, -+ int id, TreeMapItem* i) -+{ -+ _depthStopID = id; -+ _menuItem = i; -+ -+ connect(popup, TQT_SIGNAL(activated(int)), -+ this, TQT_SLOT(depthStopActivated(int))); -+ -+ bool foundDepth = false; -+ -+ popup->insertItem(i18n("No Depth Limit"), id); -+ popup->setItemChecked(id, maxDrawingDepth() == -1); -+ -+ if (i) { -+ int d = i->depth(); -+ popup->insertSeparator(); -+ popup->insertItem(i18n("Depth of '%1' (%2)") -+ .arg(i->text(0)).arg(d), id+1); -+ if (d == maxDrawingDepth()) { -+ popup->setItemChecked(id+1, true); -+ foundDepth = true; -+ } -+ } -+ -+ if (maxDrawingDepth()>1) { -+ popup->insertSeparator(); -+ if (!foundDepth) { -+ popup->insertItem(i18n("Depth %1").arg(maxDrawingDepth()), id+10); -+ popup->setItemChecked(id+10, true); -+ } -+ -+ popup->insertItem(i18n("Decrement (to %1)") -+ .arg(maxDrawingDepth()-1), id+2); -+ popup->insertItem(i18n("Increment (to %1)") -+ .arg(maxDrawingDepth()+1), id+3); -+ } -+} -+ -+ -+ -+/*---------------------------------------------------------------- -+ * Option saving/restoring -+ */ -+ -+void TreeMapWidget::saveOptions(KConfigGroup* config, TQString prefix) -+{ -+ config->writeEntry(prefix+"Nesting", splitModeString()); -+ config->writeEntry(prefix+"AllowRotation", allowRotation()); -+ config->writeEntry(prefix+"ShadingEnabled", isShadingEnabled()); -+ config->writeEntry(prefix+"OnlyCorrectBorder", skipIncorrectBorder()); -+ config->writeEntry(prefix+"BorderWidth", borderWidth()); -+ config->writeEntry(prefix+"MaxDepth", maxDrawingDepth()); -+ config->writeEntry(prefix+"MinimalArea", minimalArea()); -+ -+ int f, fCount = _attr.size(); -+ config->writeEntry(prefix+"FieldCount", fCount); -+ for (f=0;fwriteEntry(TQString(prefix+"FieldVisible%1").arg(f), -+ _attr[f].visible); -+ config->writeEntry(TQString(prefix+"FieldForced%1").arg(f), -+ _attr[f].forced); -+ config->writeEntry(TQString(prefix+"FieldStop%1").arg(f), -+ _attr[f].stop); -+ config->writeEntry(TQString(prefix+"FieldPosition%1").arg(f), -+ fieldPositionString(f)); -+ } -+} -+ -+ -+void TreeMapWidget::restoreOptions(KConfigGroup* config, TQString prefix) -+{ -+ bool enabled; -+ int num; -+ TQString str; -+ -+ str = config->readEntry(prefix+"Nesting"); -+ if (!str.isEmpty()) setSplitMode(str); -+ -+ if (config->hasKey(prefix+"AllowRotation")) { -+ enabled = config->readBoolEntry(prefix+"AllowRotation", true); -+ setAllowRotation(enabled); -+ } -+ -+ if (config->hasKey(prefix+"ShadingEnabled")) { -+ enabled = config->readBoolEntry(prefix+"ShadingEnabled", true); -+ setShadingEnabled(enabled); -+ } -+ -+ if (config->hasKey(prefix+"OnlyCorrectBorder")) { -+ enabled = config->readBoolEntry(prefix+"OnlyCorrectBorder", false); -+ setSkipIncorrectBorder(enabled); -+ } -+ -+ num = config->readNumEntry(prefix+"BorderWidth", -2); -+ if (num!=-2) setBorderWidth(num); -+ -+ num = config->readNumEntry(prefix+"MaxDepth", -2); -+ if (num!=-2) setMaxDrawingDepth(num); -+ -+ num = config->readNumEntry(prefix+"MinimalArea", -2); -+ if (num!=-2) setMinimalArea(num); -+ -+ num = config->readNumEntry(prefix+"FieldCount", -2); -+ if (num<=0 || num>MAX_FIELD) return; -+ -+ int f; -+ for (f=0;fhasKey(str)) -+ setFieldVisible(f, config->readBoolEntry(str)); -+ -+ str = TQString(prefix+"FieldForced%1").arg(f); -+ if (config->hasKey(str)) -+ setFieldForced(f, config->readBoolEntry(str)); -+ -+ str = config->readEntry(TQString(prefix+"FieldStop%1").arg(f)); -+ setFieldStop(f, str); -+ -+ str = config->readEntry(TQString(prefix+"FieldPosition%1").arg(f)); -+ if (!str.isEmpty()) setFieldPosition(f, str); -+ } -+} -+ -+#include "treemap.moc" -diff --git a/kdecachegrind/kdecachegrind/treemap.h b/kdecachegrind/kdecachegrind/treemap.h -new file mode 100644 -index 0000000..422cd35 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/treemap.h -@@ -0,0 +1,759 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2002, 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/** -+ * A Widget for visualizing hierarchical metrics as areas. -+ * The API is similar to TQListView. -+ * -+ * This file defines the following classes: -+ * DrawParams, RectDrawing, TreeMapItem, TreeMapWidget -+ * -+ * DrawParams/RectDrawing allows reusing of TreeMap drawing -+ * functions in other widgets. -+ */ -+ -+#ifndef TREEMAP_H -+#define TREEMAP_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+class TQPopupMenu; -+class TreeMapTip; -+class TreeMapWidget; -+class TreeMapItem; -+class TreeMapItemList; -+class TQString; -+ -+class KConfigGroup; -+ -+ -+/** -+ * Drawing parameters for an object. -+ * A Helper Interface for RectDrawing. -+ */ -+class DrawParams -+{ -+public: -+ /** -+ * Positions for drawing into a rectangle. -+ * -+ * The specified position assumes no rotation. -+ * If there is more than one text for one position, it is put -+ * nearer to the center of the item. -+ * -+ * Drawing at top positions cuts free space from top, -+ * drawing at bottom positions cuts from bottom. -+ * Default usually gives positions clockwise according to field number. -+ */ -+ enum Position { TopLeft, TopCenter, TopRight, -+ BottomLeft, BottomCenter, BottomRight, -+ Default, Unknown}; -+ -+ // no constructor as this is an abstract class -+ virtual ~DrawParams() {} -+ -+ virtual TQString text(int) const = 0; -+ virtual TQPixmap pixmap(int) const = 0; -+ virtual Position position(int) const = 0; -+ // 0: no limit, negative: leave at least -maxLines() free -+ virtual int maxLines(int) const { return 0; } -+ virtual int fieldCount() const { return 0; } -+ -+ virtual TQColor backColor() const { return TQt::white; } -+ virtual const TQFont& font() const = 0; -+ -+ virtual bool selected() const { return false; } -+ virtual bool current() const { return false; } -+ virtual bool shaded() const { return true; } -+ virtual bool rotated() const { return false; } -+ virtual bool drawFrame() const { return true; } -+}; -+ -+ -+/* -+ * DrawParam with attributes stored -+ */ -+class StoredDrawParams: public DrawParams -+{ -+public: -+ StoredDrawParams(); -+ StoredDrawParams(TQColor c, -+ bool selected = false, bool current = false); -+ -+ // getters -+ TQString text(int) const; -+ TQPixmap pixmap(int) const; -+ Position position(int) const; -+ int maxLines(int) const; -+ int fieldCount() const { return _field.size(); } -+ -+ TQColor backColor() const { return _backColor; } -+ bool selected() const { return _selected; } -+ bool current() const { return _current; } -+ bool shaded() const { return _shaded; } -+ bool rotated() const { return _rotated; } -+ bool drawFrame() const { return _drawFrame; } -+ -+ const TQFont& font() const; -+ -+ // attribute setters -+ void setField(int f, const TQString& t, TQPixmap pm = TQPixmap(), -+ Position p = Default, int maxLines = 0); -+ void setText(int f, const TQString&); -+ void setPixmap(int f, const TQPixmap&); -+ void setPosition(int f, Position); -+ void setMaxLines(int f, int); -+ void setBackColor(const TQColor& c) { _backColor = c; } -+ void setSelected(bool b) { _selected = b; } -+ void setCurrent(bool b) { _current = b; } -+ void setShaded(bool b) { _shaded = b; } -+ void setRotated(bool b) { _rotated = b; } -+ void drawFrame(bool b) { _drawFrame = b; } -+ -+protected: -+ TQColor _backColor; -+ bool _selected :1; -+ bool _current :1; -+ bool _shaded :1; -+ bool _rotated :1; -+ bool _drawFrame :1; -+ -+private: -+ // resize field array if needed to allow to access field -+ void ensureField(int f); -+ -+ struct Field { -+ TQString text; -+ TQPixmap pix; -+ Position pos; -+ int maxLines; -+ }; -+ -+ TQValueVector _field; -+}; -+ -+ -+/* State for drawing on a rectangle. -+ * -+ * Following drawing functions are provided: -+ * - background drawing with shading and 3D frame -+ * - successive pixmap/text drawing at various positions with wrap-around -+ * optimized for minimal space usage (e.g. if a text is drawn at top right -+ * after text on top left, the same line is used if space allows) -+ * -+ */ -+class RectDrawing -+{ -+public: -+ RectDrawing(TQRect); -+ ~RectDrawing(); -+ -+ // The default DrawParams object used. -+ DrawParams* drawParams(); -+ // we take control over the given object (i.e. delete at destruction) -+ void setDrawParams(DrawParams*); -+ -+ // draw on a given TQPainter, use this class as info provider per default -+ void drawBack(TQPainter*, DrawParams* dp = 0); -+ /* Draw field at position() from pixmap()/text() with maxLines(). -+ * Returns true if something was drawn -+ */ -+ bool drawField(TQPainter*, int f, DrawParams* dp = 0); -+ -+ // resets rectangle for free space -+ void setRect(TQRect); -+ -+ // Returns the rectangle area still free of text/pixmaps after -+ // a number of drawText() calls. -+ TQRect remainingRect(DrawParams* dp = 0); -+ -+private: -+ int _usedTopLeft, _usedTopCenter, _usedTopRight; -+ int _usedBottomLeft, _usedBottomCenter, _usedBottomRight; -+ TQRect _rect; -+ -+ // temporary -+ int _fontHeight; -+ TQFontMetrics* _fm; -+ DrawParams* _dp; -+}; -+ -+ -+class TreeMapItemList: public TQPtrList -+{ -+public: -+ TreeMapItem* commonParent(); -+protected: -+ int compareItems ( Item item1, Item item2 ); -+}; -+ -+typedef TQPtrListIterator TreeMapItemListIterator; -+ -+ -+/** -+ * Base class of items in TreeMap. -+ * -+ * This class supports an arbitrary number of text() strings -+ * positioned counterclock-wise starting at TopLeft. Each item -+ * has its own static value(), sum() and sorting(). The -+ * splitMode() and borderWidth() is taken from a TreeMapWidget. -+ * -+ * If you want more flexibility, reimplement TreeMapItem and -+ * override the corresponding methods. For dynamic creation of child -+ * items on demand, reimplement children(). -+ */ -+class TreeMapItem: public StoredDrawParams -+{ -+public: -+ -+ /** -+ * Split direction for nested areas: -+ * AlwaysBest: Choose split direction for every subitem according to -+ * longest side of rectangle left for drawing -+ * Best: Choose split direction for all subitems of an area -+ * depending on longest side -+ * HAlternate:Qt::Horizontal at top; alternate direction on depth step -+ * VAlternate:Qt::Vertical at top; alternate direction on depth step -+ * Qt::Horizontal: Always horizontal split direction -+ * Qt::Vertical: Always vertical split direction -+ */ -+ enum SplitMode { Bisection, Columns, Rows, -+ AlwaysBest, Best, -+ HAlternate, VAlternate, -+ Horizontal, Vertical }; -+ -+ TreeMapItem(TreeMapItem* parent = 0, double value = 1.0 ); -+ TreeMapItem(TreeMapItem* parent, double value, -+ TQString text1, TQString text2 = TQString(), -+ TQString text3 = TQString(), TQString text4 = TQString()); -+ virtual ~TreeMapItem(); -+ -+ bool isChildOf(TreeMapItem*); -+ -+ TreeMapItem* commonParent(TreeMapItem* item); -+ -+ // force a redraw of this item -+ void redraw(); -+ -+ // delete all children -+ void clear(); -+ -+ // force new child generation & refresh -+ void refresh(); -+ -+ // call in a reimplemented items() method to check if already called -+ // after a clear(), this will return false -+ bool initialized(); -+ -+ /** -+ * Adds an item to a parent. -+ * When no sorting is used, the item is appended (drawn at bottom). -+ * This is only needed if the parent was not already specified in the -+ * construction of the item. -+ */ -+ void addItem(TreeMapItem*); -+ -+ /** -+ * Returns a list of text strings of specified text number, -+ * from root up to this item. -+ */ -+ TQStringList path(int) const; -+ -+ /** -+ * Depth of this item. This is the distance to root. -+ */ -+ int depth() const; -+ -+ /** -+ * Parent Item -+ */ -+ TreeMapItem* parent() const { return _parent; } -+ -+ /** -+ * Temporary rectangle used for drawing this item the last time. -+ * This is internally used to map from a point to an item. -+ */ -+ void setItemRect(const TQRect& r) { _rect = r; } -+ void clearItemRect(); -+ const TQRect& itemRect() const { return _rect; } -+ int width() const { return _rect.width(); } -+ int height() const { return _rect.height(); } -+ -+ /** -+ * Temporary rectangle list of free space of this item. -+ * Used internally to enable tooltip. -+ */ -+ void clearFreeRects(); -+ TQPtrList* freeRects() const { return _freeRects; } -+ void addFreeRect(const TQRect& r); -+ -+ /** -+ * Temporary child item index of the child that was current() recently. -+ */ -+ int index() const { return _index; } -+ void setIndex(int i) { _index = i; } -+ -+ -+ /** -+ * TreeMap widget this item is put in. -+ */ -+ TreeMapWidget* widget() const { return _widget; } -+ -+ void setParent(TreeMapItem* p); -+ void setWidget(TreeMapWidget* w) { _widget = w; } -+ void setSum(double s) { _sum = s; } -+ void setValue(double s) { _value = s; } -+ -+ virtual double sum() const; -+ virtual double value() const; -+ // replace "Default" position with setting from TreeMapWidget -+ virtual Position position(int) const; -+ virtual const TQFont& font() const; -+ virtual bool isMarked(int) const; -+ -+ virtual int borderWidth() const; -+ -+ /** -+ * Returns the text number after that sorting is done or -+ * -1 for no sorting, -2 for value() sorting (default). -+ * If ascending != 0, a bool value is written at that location -+ * to indicate if sorting should be ascending. -+ */ -+ virtual int sorting(bool* ascending) const; -+ -+ /** -+ * Set the sorting for child drawing. -+ * -+ * Default is no sorting: = -1 -+ * For value() sorting, use = -2 -+ * -+ * For fast sorting, set this to -1 before child insertions and call -+ * again after inserting all children. -+ */ -+ void setSorting(int textNo, bool ascending = true); -+ -+ /** -+ * Resort according to the already set sorting. -+ * -+ * This has to be done if the sorting base changes (e.g. text or values -+ * change). If this is only true for the children of this item, you can -+ * set the recursive parameter to false. -+ */ -+ void resort(bool recursive = true); -+ -+ virtual SplitMode splitMode() const; -+ virtual int rtti() const; -+ // not const as this can create children on demand -+ virtual TreeMapItemList* children(); -+ -+protected: -+ TreeMapItemList* _children; -+ double _sum, _value; -+ -+private: -+ TreeMapWidget* _widget; -+ TreeMapItem* _parent; -+ -+ int _sortTextNo; -+ bool _sortAscending; -+ -+ // temporary layout -+ TQRect _rect; -+ TQPtrList* _freeRects; -+ int _depth; -+ -+ // temporary self value (when using level skipping) -+ double _unused_self; -+ -+ // index of last active subitem -+ int _index; -+}; -+ -+ -+/** -+ * Class for visualization of a metric of hierarchically -+ * nested items as 2D areas. -+ */ -+class TreeMapWidget: public TQWidget -+{ -+ Q_OBJECT -+ TQ_OBJECT -+ -+public: -+ -+ /** -+ * Same as in TQListBox/TQListView -+ */ -+ enum SelectionMode { Single, Multi, Extended, NoSelection }; -+ -+ /* The widget becomes owner of the base item */ -+ TreeMapWidget(TreeMapItem* base, TQWidget* parent=0, const char* name=0); -+ ~TreeMapWidget(); -+ -+ /** -+ * Returns the TreeMapItem filling out the widget space -+ */ -+ TreeMapItem* base() const { return _base; } -+ -+ /** -+ * Returns a reference to the current widget font. -+ */ -+ const TQFont& currentFont() const; -+ -+ /** -+ * Returns the area item at position x/y, independent from any -+ * maxSelectDepth setting. -+ */ -+ TreeMapItem* item(int x, int y) const; -+ -+ /** -+ * Returns the nearest item with a visible area; this -+ * can be the given item itself. -+ */ -+ TreeMapItem* visibleItem(TreeMapItem*) const; -+ -+ /** -+ * Returns the item possible for selection. this returns the -+ * given item itself or a parent thereof, -+ * depending on setting of maxSelectDepth(). -+ */ -+ TreeMapItem* possibleSelection(TreeMapItem*) const; -+ -+ /** -+ * Selects or unselects an item. -+ * In multiselection mode, the constrain that a selected item -+ * has no selected children or parents stays true. -+ */ -+ void setSelected(TreeMapItem*, bool selected = true); -+ -+ /** -+ * Switches on the marking . Marking 0 switches off marking. -+ * This is mutually exclusive to selection, and is automatically -+ * switched off when selection is changed (also by the user). -+ * Marking is visually the same as selection, and is based on -+ * TreeMapItem::isMarked(). -+ * This enables to programmatically show multiple selected items -+ * at once even in single selection mode. -+ */ -+ void setMarked(int markNo = 1, bool redraw = true); -+ -+ /** -+ * Clear selection of all selected items which are children of -+ * parent. When parent == 0, clears whole selection -+ * Returns true if selection changed. -+ */ -+ bool clearSelection(TreeMapItem* parent = 0); -+ -+ /** -+ * Selects or unselects items in a range. -+ * This is needed internally for Shift-Click in Extented mode. -+ * Range means for a hierarchical widget: -+ * - select/unselect i1 and i2 according selected -+ * - search common parent of i1 and i2, and select/unselect the -+ * range of direct children between but excluding the child -+ * leading to i1 and the child leading to i2. -+ */ -+ void setRangeSelection(TreeMapItem* i1, -+ TreeMapItem* i2, bool selected); -+ -+ /** -+ * Sets the current item. -+ * The current item is mainly used for keyboard navigation. -+ */ -+ void setCurrent(TreeMapItem*, bool kbd=false); -+ -+ /** -+ * Set the maximal depth a selected item can have. -+ * If you try to select a item with higher depth, the ancestor holding -+ * this condition is used. -+ * -+ * See also possibleSelection(). -+ */ -+ void setMaxSelectDepth(int d) { _maxSelectDepth = d; } -+ -+ -+ void setSelectionMode(SelectionMode m) { _selectionMode = m; } -+ -+ /** -+ * for setting/getting global split direction -+ */ -+ void setSplitMode(TreeMapItem::SplitMode m); -+ TreeMapItem::SplitMode splitMode() const; -+ // returns true if string was recognized -+ bool setSplitMode(TQString); -+ TQString splitModeString() const; -+ -+ -+ /* -+ * Shading of rectangles enabled ? -+ */ -+ void setShadingEnabled(bool s); -+ bool isShadingEnabled() const { return _shading; } -+ -+ /* Setting for a whole depth level: draw 3D frame (default) or solid */ -+ void drawFrame(int d, bool b); -+ bool drawFrame(int d) const { return (d<4)?_drawFrame[d]:true; } -+ -+ /* Setting for a whole depth level: draw items (default) or transparent */ -+ void setTransparent(int d, bool b); -+ bool isTransparent(int d) const { return (d<4)?_transparent[d]:false; } -+ -+ /** -+ * Items usually have a size proportional to their value(). -+ * With , you can give the minimum width -+ * of the resulting rectangle to still be drawn. -+ * For space not used because of to small items, you can specify -+ * with if the background should shine through or -+ * the space will be used to enlarge the next item to be drawn -+ * at this level. -+ */ -+ void setVisibleWidth(int width, bool reuseSpace = false); -+ -+ /** -+ * If a children value() is almost the parents sum(), -+ * it can happen that the border to be drawn for visibilty of -+ * nesting relations takes to much space, and the -+ * parent/child size relation can not be mapped to a correct -+ * area size relation. -+ * -+ * Either -+ * (1) Ignore the incorrect drawing, or -+ * (2) Skip drawing of the parent level alltogether. -+ */ -+ void setSkipIncorrectBorder(bool enable = true); -+ bool skipIncorrectBorder() const { return _skipIncorrectBorder; } -+ -+ /** -+ * Maximal nesting depth -+ */ -+ void setMaxDrawingDepth(int d); -+ int maxDrawingDepth() const { return _maxDrawingDepth; } -+ -+ /** -+ * Minimal area for rectangles to draw -+ */ -+ void setMinimalArea(int area); -+ int minimalArea() const { return _minimalArea; } -+ -+ /* defaults for text attributes */ -+ TQString defaultFieldType(int) const; -+ TQString defaultFieldStop(int) const; -+ bool defaultFieldVisible(int) const; -+ bool defaultFieldForced(int) const; -+ DrawParams::Position defaultFieldPosition(int) const; -+ -+ /** -+ * Set the type name of a field. -+ * This is important for the visualization menu generated -+ * with visualizationMenu() -+ */ -+ void setFieldType(int, TQString); -+ TQString fieldType(int) const; -+ -+ /** -+ * Stop drawing at item with name -+ */ -+ void setFieldStop(int, TQString); -+ TQString fieldStop(int) const; -+ -+ /** -+ * Should the text with number textNo be visible? -+ * This is only done if remaining space is enough to allow for -+ * proportional size constrains. -+ */ -+ void setFieldVisible(int, bool); -+ bool fieldVisible(int) const; -+ -+ /** -+ * Should the drawing of the name into the rectangle be forced? -+ * This enables drawing of the name before drawing subitems, and -+ * thus destroys proportional constrains. -+ */ -+ void setFieldForced(int, bool); -+ bool fieldForced(int) const; -+ -+ /** -+ * Set the field position in the area. See TreeMapItem::Position -+ */ -+ void setFieldPosition(int, DrawParams::Position); -+ DrawParams::Position fieldPosition(int) const; -+ void setFieldPosition(int, TQString); -+ TQString fieldPositionString(int) const; -+ -+ /** -+ * Do we allow the texts to be rotated by 90 degrees for better fitting? -+ */ -+ void setAllowRotation(bool); -+ bool allowRotation() const { return _allowRotation; } -+ -+ void setBorderWidth(int w); -+ int borderWidth() const { return _borderWidth; } -+ -+ /** -+ * Save/restore options. -+ */ -+ void saveOptions(KConfigGroup*, TQString prefix = TQString()); -+ void restoreOptions(KConfigGroup*, TQString prefix = TQString()); -+ -+ /** -+ * These functions populate given popup menus. -+ * The added items are already connected to handlers. -+ * -+ * The int is the menu id where to start for the items (100 IDs reserved). -+ */ -+ void addSplitDirectionItems(TQPopupMenu*, int); -+ void addSelectionItems(TQPopupMenu*, int, TreeMapItem*); -+ void addFieldStopItems(TQPopupMenu*, int, TreeMapItem*); -+ void addAreaStopItems(TQPopupMenu*, int, TreeMapItem*); -+ void addDepthStopItems(TQPopupMenu*, int, TreeMapItem*); -+ void addVisualizationItems(TQPopupMenu*, int); -+ -+ TreeMapWidget* widget() { return this; } -+ TreeMapItem* current() const { return _current; } -+ TreeMapItemList selection() const { return _selection; } -+ bool isSelected(TreeMapItem* i) const; -+ int maxSelectDepth() const { return _maxSelectDepth; } -+ SelectionMode selectionMode() const { return _selectionMode; } -+ -+ /** -+ * Return tooltip string to show for a item (can be rich text) -+ * Default implementation gives lines with "text0 (text1)" going to root. -+ */ -+ virtual TQString tipString(TreeMapItem* i) const; -+ -+ /** -+ * Redraws an item with all children. -+ * This takes changed values(), sums(), colors() and text() into account. -+ */ -+ void redraw(TreeMapItem*); -+ void redraw() { redraw(_base); } -+ -+ /** -+ * Resort all TreeMapItems. See TreeMapItem::resort(). -+ */ -+ void resort() { _base->resort(true); } -+ -+ // internal -+ void drawTreeMap(); -+ -+ // used internally when items are destroyed -+ void deletingItem(TreeMapItem*); -+ -+protected slots: -+ void splitActivated(int); -+ void selectionActivated(int); -+ void fieldStopActivated(int); -+ void areaStopActivated(int); -+ void depthStopActivated(int); -+ void visualizationActivated(int); -+ -+signals: -+ void selectionChanged(); -+ void selectionChanged(TreeMapItem*); -+ -+ /** -+ * This signal is emitted if the current item changes. -+ * If the change is done because of keyboard navigation, -+ * the is set to true -+ */ -+ void currentChanged(TreeMapItem*, bool keyboard); -+ void clicked(TreeMapItem*); -+ void returnPressed(TreeMapItem*); -+ void doubleClicked(TreeMapItem*); -+ void rightButtonPressed(TreeMapItem*, const TQPoint &); -+ void contextMenuRequested(TreeMapItem*, const TQPoint &); -+ -+protected: -+ void mousePressEvent( TQMouseEvent * ); -+ void contextMenuEvent( TQContextMenuEvent * ); -+ void mouseReleaseEvent( TQMouseEvent * ); -+ void mouseMoveEvent( TQMouseEvent * ); -+ void mouseDoubleClickEvent( TQMouseEvent * ); -+ void keyPressEvent( TQKeyEvent* ); -+ void paintEvent( TQPaintEvent * ); -+ void resizeEvent( TQResizeEvent * ); -+ void showEvent( TQShowEvent * ); -+ void fontChange( const TQFont& ); -+ -+private: -+ TreeMapItemList diff(TreeMapItemList&, TreeMapItemList&); -+ // returns true if selection changed -+ TreeMapItem* setTmpSelected(TreeMapItem*, bool selected = true); -+ TreeMapItem* setTmpRangeSelection(TreeMapItem* i1, -+ TreeMapItem* i2, bool selected); -+ bool isTmpSelected(TreeMapItem* i); -+ -+ void drawItem(TQPainter* p, TreeMapItem*); -+ void drawItems(TQPainter* p, TreeMapItem*); -+ bool horizontal(TreeMapItem* i, const TQRect& r); -+ void drawFill(TreeMapItem*,TQPainter* p, TQRect& r); -+ void drawFill(TreeMapItem*,TQPainter* p, TQRect& r, -+ TreeMapItemListIterator it, int len, bool goBack); -+ bool drawItemArray(TQPainter* p, TreeMapItem*, TQRect& r, double, -+ TreeMapItemListIterator it, int len, bool); -+ bool resizeAttr(int); -+ -+ TreeMapItem* _base; -+ TreeMapItem *_current, *_pressed, *_lastOver, *_oldCurrent; -+ TreeMapTip* _tip; -+ int _maxSelectDepth, _maxDrawingDepth; -+ -+ // attributes for field, per textNo -+ struct FieldAttr { -+ TQString type, stop; -+ bool visible, forced; -+ DrawParams::Position pos; -+ }; -+ TQValueVector _attr; -+ -+ SelectionMode _selectionMode; -+ TreeMapItem::SplitMode _splitMode; -+ int _visibleWidth, _stopArea, _minimalArea, _borderWidth; -+ bool _reuseSpace, _skipIncorrectBorder, _drawSeparators, _shading; -+ bool _allowRotation; -+ bool _transparent[4], _drawFrame[4]; -+ TreeMapItem * _needsRefresh; -+ TreeMapItemList _selection; -+ int _markNo; -+ -+ // for the context menus: start IDs -+ int _splitID, _selectionID, _visID; -+ int _fieldStopID, _areaStopID, _depthStopID; -+ TreeMapItem* _menuItem; -+ -+ // temporary selection while dragging, used for drawing -+ // most of the time, _selection == _tmpSelection -+ TreeMapItemList _tmpSelection; -+ bool _inShiftDrag, _inControlDrag; -+ -+ // temporary widget font metrics while drawing -+ TQFont _font; -+ int _fontHeight; -+ -+ // back buffer pixmap -+ TQPixmap _pixmap; -+}; -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/utils.cpp b/kdecachegrind/kdecachegrind/utils.cpp -new file mode 100644 -index 0000000..65c7e34 ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/utils.cpp -@@ -0,0 +1,483 @@ -+/* This file is part of KCachegrind. -+ Copyright (C) 2003 Josef Weidendorfer -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Utility classes for KCachegrind -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#ifdef HAVE_MMAP -+#include -+#include -+#endif -+ -+#include -+#include -+ -+#include "utils.h" -+ -+ -+// class FixString -+ -+FixString::FixString(const char* str, int len) -+{ -+ _str = str; -+ _len = len; -+} -+ -+bool FixString::stripFirst(char& c) -+{ -+ if (!_len) { -+ c = 0; -+ return false; -+ } -+ -+ c = *_str; -+ _str++; -+ _len--; -+ return true; -+ } -+ -+bool FixString::stripPrefix(const char* p) -+{ -+ if (_len == 0) return false; -+ if (!p || (*p != *_str)) return false; -+ -+ const char* s = _str+1; -+ int l = _len-1; -+ p++; -+ while(*p) { -+ if (l==0) return false; -+ if (*s != *p) return false; -+ p++; -+ s++; -+ l--; -+ } -+ _str = s; -+ _len = l; -+ return true; -+} -+ -+ -+// this parses hexadecimal (with prefix '0x' too) -+bool FixString::stripUInt(unsigned int& v, bool stripSpaces) -+{ -+ if (_len==0) { -+ v = 0; -+ return false; -+ } -+ -+ char c = *_str; -+ if (c<'0' || c>'9') { -+ v = 0; -+ return false; -+ } -+ -+ v = c-'0'; -+ const char* s = _str+1; -+ int l = _len-1; -+ c = *s; -+ -+ if ((l>0) && (c == 'x') && (v==0)) { -+ // hexadecimal -+ s++; -+ c = *s; -+ l--; -+ -+ while(l>0) { -+ if (c>='0' && c<='9') -+ v = 16*v + (c-'0'); -+ else if (c>='a' && c<='f') -+ v = 16*v + 10 + (c-'a'); -+ else if (c>='A' && c<='F') -+ v = 16*v + 10 + (c-'A'); -+ else -+ break; -+ s++; -+ c = *s; -+ l--; -+ } -+ } -+ else { -+ // decimal -+ -+ while(l>0) { -+ if (c<'0' || c>'9') break; -+ v = 10*v + (c-'0'); -+ s++; -+ c = *s; -+ l--; -+ } -+ } -+ -+ if (stripSpaces) -+ while(l>0) { -+ if (c != ' ') break; -+ s++; -+ c = *s; -+ l--; -+ } -+ -+ _str = s; -+ _len = l; -+ return true; -+} -+ -+ -+void FixString::stripSurroundingSpaces() -+{ -+ if (_len==0) return; -+ -+ // leading spaces -+ while((_len>0) && (*_str==' ')) { -+ _len--; -+ _str++; -+ } -+ -+ // trailing spaces -+ while((_len>0) && (_str[_len-1]==' ')) { -+ _len--; -+ } -+} -+ -+void FixString::stripSpaces() -+{ -+ while((_len>0) && (*_str==' ')) { -+ _len--; -+ _str++; -+ } -+} -+ -+bool FixString::stripName(FixString& s) -+{ -+ if (_len==0) return false; -+ -+ // first char has to be a letter or "_" -+ if (!TQChar(*_str).isLetter() && (*_str != '_')) return false; -+ -+ int newLen = 1; -+ const char* newStr = _str; -+ -+ _str++; -+ _len--; -+ -+ while(_len>0) { -+ if (!TQChar(*_str).isLetterOrNumber() -+ && (*_str != '_')) break; -+ -+ newLen++; -+ _str++; -+ _len--; -+ } -+ -+ s.set(newStr, newLen); -+ return true; -+} -+ -+FixString FixString::stripUntil(char c) -+{ -+ if (_len == 0) return FixString(); -+ -+ const char* newStr = _str; -+ int newLen = 0; -+ -+ while(_len>0) { -+ if (*_str == c) { -+ _str++; -+ _len--; -+ break; -+ } -+ -+ _str++; -+ _len--; -+ newLen++; -+ } -+ return FixString(newStr, newLen); -+} -+ -+bool FixString::stripUInt64(uint64& v, bool stripSpaces) -+{ -+ if (_len==0) { -+ v = 0; -+ return false; -+ } -+ -+ char c = *_str; -+ if (c<'0' || c>'9') { -+ v = 0; -+ return false; -+ } -+ -+ v = c-'0'; -+ const char* s = _str+1; -+ int l = _len-1; -+ c = *s; -+ -+ if ((l>0) && (c == 'x') && (v==0)) { -+ // hexadecimal -+ s++; -+ c = *s; -+ l--; -+ -+ while(l>0) { -+ if (c>='0' && c<='9') -+ v = 16*v + (c-'0'); -+ else if (c>='a' && c<='f') -+ v = 16*v + 10 + (c-'a'); -+ else if (c>='A' && c<='F') -+ v = 16*v + 10 + (c-'A'); -+ else -+ break; -+ s++; -+ c = *s; -+ l--; -+ } -+ } -+ else { -+ // decimal -+ while(l>0) { -+ if (c<'0' || c>'9') break; -+ v = 10*v + (c-'0'); -+ s++; -+ c = *s; -+ l--; -+ } -+ } -+ -+ if (stripSpaces) -+ while(l>0) { -+ if (c != ' ') break; -+ s++; -+ c = *s; -+ l--; -+ } -+ -+ _str = s; -+ _len = l; -+ return true; -+} -+ -+ -+bool FixString::stripInt64(int64& v, bool stripSpaces) -+{ -+ if (_len==0) { -+ v = 0; -+ return false; -+ } -+ -+ char c = *_str; -+ if (c<'0' || c>'9') { -+ v = 0; -+ return false; -+ } -+ -+ v = c-'0'; -+ const char* s = _str+1; -+ int l = _len-1; -+ c = *s; -+ -+ if ((l>0) && (c == 'x') && (v==0)) { -+ // hexadecimal -+ s++; -+ c = *s; -+ l--; -+ -+ while(l>0) { -+ if (c>='0' && c<='9') -+ v = 16*v + (c-'0'); -+ else if (c>='a' && c<='f') -+ v = 16*v + 10 + (c-'a'); -+ else if (c>='A' && c<='F') -+ v = 16*v + 10 + (c-'A'); -+ else -+ break; -+ s++; -+ c = *s; -+ l--; -+ } -+ } -+ else { -+ // decimal -+ -+ while(l>0) { -+ if (c<'0' || c>'9') break; -+ v = 10*v + (c-'0'); -+ s++; -+ c = *s; -+ l--; -+ } -+ } -+ -+ if (stripSpaces) -+ while(l>0) { -+ if (c != ' ') break; -+ s++; -+ c = *s; -+ l--; -+ } -+ -+ _str = s; -+ _len = l; -+ return true; -+} -+ -+ -+ -+// class FixFile -+ -+FixFile::FixFile(TQFile* file) -+{ -+ if (!file) { -+ _len = 0; -+ _currentLeft = 0; -+ _openError = true; -+ return; -+ } -+ -+ _filename = file->name(); -+ if (!file->isOpen() && !file->open( IO_ReadOnly ) ) { -+ qWarning( "%s: %s", (const char*) TQFile::encodeName(_filename), -+ strerror( errno ) ); -+ _len = 0; -+ _currentLeft = 0; -+ _openError = true; -+ return; -+ } -+ -+ _openError = false; -+ _used_mmap = false; -+ -+#ifdef HAVE_MMAP -+ char *addr = 0; -+ size_t len = file->size(); -+ if (len>0) addr = (char *) mmap( addr, len, -+ PROT_READ, MAP_PRIVATE, -+ file->handle(), 0 ); -+ if (addr && (addr != MAP_FAILED)) { -+ // mmap succeeded -+ _base = addr; -+ _len = len; -+ _used_mmap = true; -+ -+ if (0) qDebug("Mapped '%s'", _filename.ascii()); -+ } else { -+#endif // HAVE_MMAP -+ // try reading the data into memory instead -+ _data = file->readAll(); -+ _base = _data.data(); -+ _len = _data.size(); -+#ifdef HAVE_MMAP -+ } -+#endif // HAVE_MMAP -+ -+ _current = _base; -+ _currentLeft = _len; -+} -+ -+FixFile::~FixFile() -+{ -+ // if the file was read into _data, it will be deleted automatically -+ -+#ifdef HAVE_MMAP -+ if (_used_mmap) { -+ if (0) qDebug("Unmapping '%s'", _filename.ascii()); -+ if (munmap(_base, _len) != 0) -+ qWarning( "munmap: %s", strerror( errno ) ); -+ } -+#endif // HAVE_MMAP -+} -+ -+bool FixFile::nextLine(FixString& str) -+{ -+ if (_currentLeft == 0) return false; -+ -+ unsigned left = _currentLeft; -+ char* current = _current; -+ -+ while(left>0) { -+ if (*current == 0 || *current == '\n') break; -+ current++; -+ left--; -+ } -+ -+ if (0) { -+ char tmp[200]; -+ int l = _currentLeft-left; -+ if (l>199) l = 199; -+ strncpy(tmp, _current, l); -+ tmp[l] = 0; -+ qDebug("[FixFile::nextLine] At %d, len %d: '%s'", -+ _current - _base, _currentLeft-left, tmp); -+ } -+ -+ str.set(_current, _currentLeft-left); -+ -+ if (*current == '\n') { -+ current++; -+ left--; -+ } -+ _current = current; -+ _currentLeft = left; -+ -+ return true; -+} -+ -+bool FixFile::setCurrent(unsigned pos) -+{ -+ if (pos > _len) return false; -+ -+ _current = _base + pos; -+ _currentLeft = _len - pos; -+ return true; -+} -+ -+ -+#if 0 -+ -+// class AppendList -+ -+ -+AppendList::AppendList() -+{ -+ _next = 0; -+ _current = 0; -+ _last = 0; -+ -+ _count = 0; -+ _currentIndex = 0; -+ _lastIndex = 0; -+ _autoDelete = false; -+} -+ -+ -+void AppendList::clear() -+{ -+ int count = _count; -+ int i; -+ -+ if (count <= firstLen) { -+ if (_autoDelete) -+ for (i=0;i -+ -+ KCachegrind is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public -+ License as published by the Free Software Foundation, version 2. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+/* -+ * Utility classes for KCachegrind -+ */ -+ -+#ifndef UTILS_H -+#define UTILS_H -+ -+#include -+ -+class TQFile; -+ -+typedef unsigned long long uint64; -+typedef long long int64; -+ -+/** -+ * A simple, constant string class -+ * -+ * For use with zero-copy strings from mapped files. -+ */ -+class FixString { -+ -+ public: -+ // constructor for an invalid string -+ FixString() { _len = 0; _str = 0; } -+ -+ /** -+ * FixString never does a deep copy! You have to make sure that -+ * the string starting at the char pointer is valid trough the -+ * lifetime of FixString. -+ */ -+ FixString(const char*, int len); -+ -+ int len() { return _len; } -+ const char* ascii() { return _str; } -+ bool isEmpty() { return _len == 0; } -+ bool isValid() { return _str != 0; } -+ -+ // sets to first character and returns true if length >0 -+ bool first(char& c) -+ { if (_len==0) return false; c=_str[0]; return true; } -+ -+ void set(const char* s, int l) { _str=s; _len=l; } -+ bool stripFirst(char&); -+ bool stripPrefix(const char*); -+ -+ /** -+ * Strip leading and trailing spaces -+ */ -+ void stripSurroundingSpaces(); -+ -+ /** -+ * Strip leading spaces -+ */ -+ void stripSpaces(); -+ -+ /** -+ * Strip name: [A-Za-z_][0-9A_Za-z_]* -+ */ -+ bool stripName(FixString&); -+ -+ /** -+ * Strip string until char appears or end. Strips char, too. -+ */ -+ FixString stripUntil(char); -+ -+ bool stripUInt(uint&, bool stripSpaces = true); -+ bool stripUInt64(uint64&, bool stripSpaces = true); -+ bool stripInt64(int64&, bool stripSpaces = true); -+ -+ operator TQString() const -+ { return TQString::fromLatin1(_str,_len); } -+ -+ private: -+ const char* _str; -+ int _len; -+}; -+ -+ -+/** -+ * A class for fast line by line reading of a read-only ASCII file -+ */ -+class FixFile { -+ -+ public: -+ FixFile(TQFile*); -+ ~FixFile(); -+ -+ /** -+ * Read next line into . Returns false on error or EOF. -+ */ -+ bool nextLine(FixString& str); -+ bool exists() { return !_openError; } -+ unsigned len() { return _len; } -+ unsigned current() { return _current - _base; } -+ bool setCurrent(unsigned pos); -+ void rewind() { setCurrent(0); } -+ -+ private: -+ char *_base, *_current; -+ TQByteArray _data; -+ unsigned _len, _currentLeft; -+ bool _used_mmap, _openError; -+ TQString _filename; -+}; -+ -+ -+/** -+ * A list of pointers, only able to append items. -+ * Optimized for speed, not space. -+ */ -+template -+class AppendList { -+ -+ public: -+ AppendList(); -+ ~AppendList() { clear(); } -+ -+ void setAutoDelete(bool); -+ void clear(); -+ void append(const type*); -+ -+ unsigned count() const { return _count; } -+ unsigned containsRef(const type*) const; -+ -+ type* current(); -+ type* first(); -+ type* next(); -+ -+ private: -+ static const int firstLen = 8; -+ static const int maxLen = 256; -+ -+ struct AppendListChunk { -+ int size; -+ struct AppendListChunk* next; -+ type* data[1]; -+ }; -+ -+ struct AppendListChunk *_next, *_current, *_last; -+ int _count, _currentIndex, _lastIndex; -+ bool _autoDelete; -+ type* _first[firstLen]; -+}; -+ -+ -+#endif -diff --git a/kdecachegrind/kdecachegrind/x-kcachegrind.desktop b/kdecachegrind/kdecachegrind/x-kcachegrind.desktop -new file mode 100644 -index 0000000..b9bf93a ---- /dev/null -+++ b/kdecachegrind/kdecachegrind/x-kcachegrind.desktop -@@ -0,0 +1,44 @@ -+[Desktop Entry] -+Comment=Cachegrind/Callgrind Profile Dump -+Comment[ca]=Resultat del anàlisis de Cachegrind/Callgring -+Comment[cs]=Data profilace Cachegrind/Callgrind -+Comment[cy]=Tomen Proffil Cachegrind/Callgrind -+Comment[da]=Cachegrind/Callgrind profile-dump -+Comment[de]=Cachegrind/Callgrind Profil-Ausgabe -+Comment[el]=ΑποτÏπωση Ï€Ïοφίλ Cachegrind/Callgrind -+Comment[es]=Resultado de análisis de Cachegrind/Callgring -+Comment[et]=Cachegrind/Callgrind profileerimistõmmis -+Comment[eu]=Cachegrind/Callgrind profil iraulketa -+Comment[fa]=تخلیۀ Profile Cachegrind/Callgrind -+Comment[fi]=Cachegrind/Callgrind-profiilivedos -+Comment[fr]=Dépôt de profil Cachegrind / Callgrind -+Comment[gl]=Resultado da análise de Cachegrind/Callgrind -+Comment[hi]=केश-गà¥à¤°à¤¿à¤‚ड/काल-गà¥à¤°à¤¿à¤‚ड पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² डमà¥à¤ª -+Comment[hu]=Cachegrind/Callgrind teljesítményprofil-fájl -+Comment[is]=Niðurstaða afkastakönnunar á Cachegrind/Callgrind -+Comment[it]=Dump del profilo di Cachegrind/Callgrind -+Comment[ja]=Callgrind/Callgrind プロファイルダンプ -+Comment[ka]=Cachegrind/Callgrind პრáƒáƒ¤áƒ˜áƒšáƒ˜áƒ¡ დáƒáƒ›áƒžáƒ˜ -+Comment[kk]=Cachegrind/Callgrind профилінің дампы -+Comment[nds]=Cachegrind/Callgrind-Profilutgaav -+Comment[ne]=Cachegrind/Callgrind पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤² डमà¥à¤ª -+Comment[nl]=Cachegrind/Callgrind Profieldump -+Comment[nn]=Cachegrind/Callgrind-profildump -+Comment[pl]=Zrzut profilowania Cachegrind/Callgrind -+Comment[pt]=Resultado da Análise do Cachegrind/Callgrind -+Comment[pt_BR]=Depósito de Perfil Cachegrind/Callgrind -+Comment[ru]=Дамп Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Cachegrind/Callgrind -+Comment[sk]=Výpis volaní Cachegrind/Callgrind -+Comment[sr]=Cachegrind-ов/Callgrind-ов избачај профила -+Comment[sr@Latn]=Cachegrind-ov/Callgrind-ov izbaÄaj profila -+Comment[sv]=Profileringsdump frÃ¥n Cachegrind/Callgrind -+Comment[ta]=இடைமாறà¯à®±à®•à®Ÿà¯à®Ÿà®®à¯/ அழைபà¯à®ªà¯ கடà¯à®Ÿà®®à¯ விவரகà¯à®•à¯à®±à®¿ திணிபà¯à®ªà¯ -+Comment[tg]=Дампи профилкунии Cachegrind/Callgrind -+Comment[uk]=Ð—Ð²Ð°Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ„Ñ–Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Cachegrind/Callgrind -+Comment[zh_CN]=Cachegrind/Callgrind é…置文件转存 -+Comment[zh_TW]=Cachegrind/Callgrind 分æžè³‡æ–™å‚¾å° -+DefaultApp=kdecachegrind -+Icon=kdecachegrind -+Type=MimeType -+MimeType=application/x-kcachegrind -+Patterns=cachegrind.out*;callgrind.out* -diff --git a/kdecachegrind/tests/cg-badcompression1 b/kdecachegrind/tests/cg-badcompression1 -new file mode 100644 -index 0000000..6076bf9 ---- /dev/null -+++ b/kdecachegrind/tests/cg-badcompression1 -@@ -0,0 +1,17 @@ -+# Test with bad callgrind format -+# Expected: -+# :13 - Redefinition of compressed file index 2 (was 'file1.c') to '' -+# :14 - Redefinition of compressed function index 1 (was 'main') to 'main2' -+# :16 - Undefined compressed function index 2 -+# :16 - Invalid function, setting to unknown -+ -+events: Ir -+ -+fl=(2) file1.c -+fn=(1) main -+10 9 -+fl=(2 ) -+fn=(1) main2 -+11 1 -+fn=(2) -+12 1 -diff --git a/kdecachegrind/tests/cg-badcostline1 b/kdecachegrind/tests/cg-badcostline1 -new file mode 100644 -index 0000000..224ff67 ---- /dev/null -+++ b/kdecachegrind/tests/cg-badcostline1 -@@ -0,0 +1,11 @@ -+# Test with bad callgrind format -+# Expected: -+# :10 - ignored garbage at end of cost line ('30') -+# :11 - ignored garbage at end of cost line ('hello') -+ -+events: Ir -+ -+fn=main -+10 20 30 -+11 hello -+12 10 -diff --git a/kdecachegrind/tests/cg-badposition b/kdecachegrind/tests/cg-badposition -new file mode 100644 -index 0000000..1be582c ---- /dev/null -+++ b/kdecachegrind/tests/cg-badposition -@@ -0,0 +1,15 @@ -+# Test with bad callgrind format -+# Expected: -+# :11 - Negative line number -20 -+# :12 - Garbage at end of cost line ('a 21') -+# :13 - Negative line number -91 -+# :15 - Invalid line 'aa 40' -+ -+events: Ir -+ -+fn=main -+-20 1 -+9a 21 -+-100 20 -+0x9a 30 -+aa 40 -diff --git a/kdecachegrind/version.h.in b/kdecachegrind/version.h.in -new file mode 100644 -index 0000000..d88081b ---- /dev/null -+++ b/kdecachegrind/version.h.in -@@ -0,0 +1 @@ -+#define KCACHEGRIND_VERSION "@KCACHEGRIND_VERSION@" diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch.gz b/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch.gz deleted file mode 100644 index 7794f1af5..000000000 Binary files a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch.gz and /dev/null differ diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch b/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch deleted file mode 100644 index 269b9f526..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch +++ /dev/null @@ -1,159 +0,0 @@ -Index: b/cervisia/CMakeLists.txt -=================================================================== ---- a/cervisia/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/cervisia/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -58,6 +58,24 @@ - DESTINATION ${KCONF_UPDATE_INSTALL_DIR} ) - - -+macro( _pod2man ) -+ foreach( _pod ${ARGN} ) -+ add_custom_command( -+ OUTPUT ${_pod}.1 -+ COMMAND pod2man ${CMAKE_CURRENT_SOURCE_DIR}/${_pod}.pod > ${_pod}.1.in -+ COMMAND -+ sed -e 's%_KDEHTMLDIR_%'${HTML_INSTALL_DIR}'%g;' -+ -e 's%_KDECONFDIR_%'${CONFIG_INSTALL_DIR}'%g;' -+ < ${_pod}.1.in > ${_pod}.1 -+ DEPENDS ${_pod} ) -+ add_custom_target( "${_pod}-man" ALL DEPENDS ${_pod}.1 ) -+ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR}/man1 ) -+ endforeach( ) -+endmacro() -+ -+_pod2man( cervisia ) -+ -+ - ##### cervisia (static) ######################### - - tde_add_library( cervisia STATIC_PIC AUTOMOC -Index: b/cervisia/cvsservice/CMakeLists.txt -=================================================================== ---- a/cervisia/cvsservice/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/cervisia/cvsservice/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -41,7 +41,7 @@ - tde_add_library( cvsservice SHARED AUTOMOC - SOURCES - cvsservice.stub cvsjob.stub repository.stub -- VERSION 0.1.0 -+ VERSION 0.0.1 - LINK kdecore-shared - DESTINATION ${LIB_INSTALL_DIR} - ) -Index: b/kapptemplate/CMakeLists.txt -=================================================================== ---- a/kapptemplate/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/kapptemplate/CMakeLists.txt 2012-11-05 23:56:28.000000000 +0100 -@@ -23,7 +23,11 @@ - - install( PROGRAMS - ${CMAKE_CURRENT_BINARY_DIR}/kapptemplate -+ DESTINATION ${BIN_INSTALL_DIR} ) -+ -+install( PROGRAMS -+ ${CMAKE_CURRENT_SOURCE_DIR}/mkinstalldirs - DESTINATION ${DATA_INSTALL_DIR}/kapptemplate/bin ) - - install( FILES - kapptemplate.common kapptemplate.module - -Index: b/kapptemplate/admin/CMakeLists.txt -=================================================================== ---- a/kapptemplate/admin/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/kapptemplate/admin/CMakeLists.txt 2012-11-06 00:13:16.000000000 +0100 -@@ -9,4 +9,9 @@ - # - ################################################# - --tde_install_empty_directory( ${DATA_INSTALL_DIR}/kapptemplate/admin ) -+install( -+ DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../admin/ -+ DESTINATION ${DATA_INSTALL_DIR}/kapptemplate/admin -+ USE_SOURCE_PERMISSIONS -+ REGEX "Makefile(|\\.in|\\.am)$|.*-orig$" EXCLUDE -+) -Index: b/kmtrace/CMakeLists.txt -=================================================================== ---- a/kmtrace/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/kmtrace/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -31,12 +31,16 @@ - install( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kminspector - DESTINATION ${BIN_INSTALL_DIR} ) - -+install( FILES ktrace.h -+ DESTINATION ${INCLUDE_INSTALL_DIR} -+) -+ - - ##### ktrace_s (static) ######################### - - tde_add_library( ktrace_s STATIC - SOURCES ktrace.c -- DESTINATION ${LIB_INSTALL_DIR} -+ DESTINATION ${LIB_INSTALL_DIR}/kmtrace - ) - - -Index: b/kompare/interfaces/CMakeLists.txt -=================================================================== ---- a/kompare/interfaces/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/kompare/interfaces/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -23,6 +23,7 @@ - - tde_add_library( kompareinterface SHARED - SOURCES kompareinterface.cpp -+ VERSION 0.0.0 - LINK ${TQT_LIBRARIES} - DESTINATION ${LIB_INSTALL_DIR} - ) -Index: b/kunittest/CMakeLists.txt -=================================================================== ---- a/kunittest/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/kunittest/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -35,6 +35,7 @@ - - tde_add_library( kunittestgui SHARED AUTOMOC - SOURCES testerwidget.ui runnergui.cpp dcopinterface.skel -+ VERSION 0.0.0 - LINK kunittest-shared - DESTINATION ${LIB_INSTALL_DIR} - ) -Index: b/scheck/CMakeLists.txt -=================================================================== ---- a/scheck/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/scheck/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -30,5 +30,5 @@ - tde_add_kpart( scheck AUTOMOC - SOURCES scheck.cpp - LINK kdeui-shared -- DESTINATION ${PLUGIN_INSTALL_DIR} -+ DESTINATION ${PLUGIN_INSTALL_DIR}/plugins/styles - ) -Index: b/scripts/CMakeLists.txt -=================================================================== ---- a/scripts/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100 -+++ b/scripts/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100 -@@ -36,7 +36,7 @@ - COMMAND pod2man ${CMAKE_CURRENT_SOURCE_DIR}/${_pod} > ${_pod}.1 - DEPENDS ${_pod} ) - add_custom_target( "${_pod}-man" ALL DEPENDS ${_pod}.1 ) -- install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR} ) -+ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR}/man1 ) - endforeach( ) - endmacro() - -Index: b/kapptemplate/admin/Makefile.am -=================================================================== ---- a/kapptemplate/admin/Makefile.am 2012-11-06 00:36:24.000000000 +0100 -+++ b/kapptemplate/admin/Makefile.am 2012-11-06 00:48:24.000000000 +0100 -@@ -1,8 +1,8 @@ - install-data-local: - $(mkinstalldirs) $(DESTDIR)$(kde_datadir)/kapptemplate/admin - for file in $(srcdir)/*; do \ -- if [ -f $$file -a $$file != 'Makefile' -a $$file != 'Makefile.in' -a $$file != 'Makefile.am' ]; then \ -- destfile=`basename $$file` \ -+ destfile=`basename $$file`; \ -+ if [ -f $$file -a $$destfile != 'Makefile' -a $$destfile != 'Makefile.in' -a $$destfile != 'Makefile.am' ]; then \ - $(INSTALL_DATA) $$file \ - $(DESTDIR)$(kde_datadir)/kapptemplate/admin/$$destfile; \ - fi \ diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_xkcachegrind_installation.patch b/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_xkcachegrind_installation.patch deleted file mode 100644 index 991918396..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1-fix_xkcachegrind_installation.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- kdesdk-3.5.13.1/kdecachegrind/kdecachegrind/CMakeLists.txt.kcachegrind 2012-09-08 12:06:51.000000000 +0200 -+++ kdesdk-3.5.13.1/kdecachegrind/kdecachegrind/CMakeLists.txt 2012-09-30 21:43:25.863163587 +0200 -@@ -26,8 +26,8 @@ - - tde_install_icons( ) - install( FILES kdecachegrind.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) --install( FILES kdecachegrindui.rc tips DESTINATION ${DATA_INSTALL_DIR}/kcachegrind ) --install( FILES x-kdecachegrind.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) -+install( FILES kdecachegrindui.rc tips DESTINATION ${DATA_INSTALL_DIR}/kdecachegrind ) -+install( FILES x-kcachegrind.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) - - - ##### kdecachegrind (executable) ################## diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1-use_flex_instead_of_lex.patch b/redhat/main/tdesdk/kdesdk-3.5.13.1-use_flex_instead_of_lex.patch deleted file mode 100644 index 7ab267206..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1-use_flex_instead_of_lex.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kdesdk-3.5.13.1/kbabel/ConfigureChecks.cmake.ORI 2012-09-30 21:50:19.573288788 +0200 -+++ kdesdk-3.5.13.1/kbabel/ConfigureChecks.cmake 2012-09-30 21:50:26.499538745 +0200 -@@ -9,7 +9,7 @@ - # - ################################################# - --find_program( LEX_EXECUTABLE "lex" ) -+find_program( LEX_EXECUTABLE "flex" ) - if( NOT LEX_EXECUTABLE ) - tde_message_fatal( "lex is required, but was not found on your system" ) - endif( ) diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.1.spec b/redhat/main/tdesdk/kdesdk-3.5.13.1.spec deleted file mode 100644 index 3d4ec0056..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.1.spec +++ /dev/null @@ -1,1161 +0,0 @@ -# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt". -%if "%{?tde_prefix}" != "/usr" -%define _variant .opt -%endif - -# TDE 3.5.13 specific building variables -%define tde_bindir %{tde_prefix}/bin -%define tde_datadir %{tde_prefix}/share -%define tde_docdir %{tde_datadir}/doc -%define tde_includedir %{tde_prefix}/include -%define tde_libdir %{tde_prefix}/%{_lib} -%define tde_mandir %{tde_datadir}/man - -%define tde_tdeappdir %{tde_datadir}/applications/kde -%define tde_tdedocdir %{tde_docdir}/tde -%define tde_tdeincludedir %{tde_includedir}/tde -%define tde_tdelibdir %{tde_libdir}/trinity - - -Name: trinity-tdesdk -Summary: The KDE Software Development Kit (SDK) -Version: 3.5.13.1 -Release: 2%{?dist}%{?_variant} - -License: GPLv2 -Group: User Interface/Desktops -URL: http://www.trinitydesktop.org/ -Vendor: Trinity Project -Packager: Francois Andriot - -Prefix: %{tde_prefix} -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -Source: kdesdk-3.5.13.1.tar.gz - -# [tdesdk] Fix FTBFS on newer subversion libraries [Bug #872] [Commit #572169a2] -Patch5: kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch -# [tdesdk] Fix unknown macro 'tde_save_and_set' -Patch6: kdesdk-3.5.13.1-fix_cmake_macros.patch -# [tdesdk] Fix build of kcachegrind -Patch7: kdesdk-3.5.13.1-add_missing_files.patch -# [tdesdk] Use 'flex' instead of 'lex' -Patch8: kdesdk-3.5.13.1-use_flex_instead_of_lex.patch -# [tdesdk] Fix various cmake issues [Bug #1262] -Patch9: kdesdk-3.5.13.1-fix_various_cmake_issues.patch - -BuildRequires: cmake >= 2.8 -BuildRequires: libtool -BuildRequires: pcre-devel -BuildRequires: trinity-tqtinterface-devel >= %{version} -BuildRequires: trinity-tdelibs-devel >= %{version} -# for kbugbuster/libkcal -BuildRequires: trinity-tdepim-devel >= %{version} -%if 0%{?mgaversion} || 0%{?mdkversion} -#BuildRequires: %{_lib}db4.8-devel -%endif -%if 0%{?rhel} || 0%{?fedora} -BuildRequires: db4-devel -%endif -%if 0%{?suse_version} -BuildRequires: libdb-4_8-devel -%endif -BuildRequires: desktop-file-utils -# kbabel, F-7+: flex >= 2.5.33-9 -BuildRequires: flex -# umbrello -BuildRequires: libxslt-devel -BuildRequires: libxml2-devel -BuildRequires: perl -BuildRequires: subversion-devel -BuildRequires: neon-devel - -%if 0%{?mgaversion} || 0%{?mdkversion} -BuildRequires: %{_lib}ltdl-devel -BuildRequires: %{_lib}binutils-devel -%endif -%if 0%{?fedora} >= 6 || 0%{?rhel} >= 5 || 0%{?suse_version} -BuildRequires: libtool-ltdl-devel -BuildRequires: binutils-devel -%endif - -# KIOSLAVE -# Does not build on RHEL4 -%if 0%{?rhel} >= 5 || 0%{?fedora} || 0%{?suse_version} || 0%{?mgaversion} || 0%{?mdkversion} -%define build_kioslave 1 -%endif - -Obsoletes: trinity-kdesdk < %{version}-%{release} -Provides: trinity-kdesdk = %{version}-%{release} -Obsoletes: trinity-kdesdk-libs < %{version}-%{release} -Provides: trinity-kdesdk-libs = %{version}-%{release} - -Requires: trinity-cervisia = %{version}-%{release} -Requires: trinity-kapptemplate = %{version}-%{release} -Requires: trinity-kbabel = %{version}-%{release} -Requires: trinity-kbugbuster = %{version}-%{release} -Requires: trinity-tdecachegrind = %{version}-%{release} -Requires: trinity-tdecachegrind-converters = %{version}-%{release} -Requires: %{name}-kfile-plugins = %{version}-%{release} -Requires: %{name}-misc = %{version}-%{release} -Requires: %{name}-scripts = %{version}-%{release} -Requires: trinity-kmtrace = %{version}-%{release} -Requires: trinity-kompare = %{version}-%{release} -Requires: trinity-kspy = %{version}-%{release} -Requires: trinity-kuiviewer = %{version}-%{release} -Requires: trinity-libcvsservice0 = %{version}-%{release} -Requires: trinity-libcvsservice-devel = %{version}-%{release} -Requires: trinity-poxml = %{version}-%{release} -Requires: trinity-umbrello = %{version}-%{release} -%{?build_kioslave:Requires: %{name}-kio-plugins = %{version}-%{release}} -Requires: trinity-kunittest = %{version}-%{release} - - -%description -A collection of applications and tools used by developers, including: -* cervisia: a CVS frontend -* kbabel: PO file management -* kbugbuster: a tool to manage the TDE bug report system -* kcachegrind: a browser for data produced by profiling tools (e.g. cachegrind) -* kompare: diff tool -* kuiviewer: displays designer's UI files -* umbrello: UML modeller and UML diagram tool - -%files - -########## - -%package -n trinity-cervisia -Summary: A graphical CVS front end for Trinity -Group: Development/Utilities - -%description -n trinity-cervisia -Cervisia is a TDE-based graphical front end for the CVS client. - -As well as providing both common and advanced CVS operations, it offers -a variety of methods for graphically viewing information about the CVS -repository, your own sandbox and the relationships between different -versions of files. A Changelog editor is also included and is coupled -with the commit dialog. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-cervisia -%{tde_bindir}/cervisia -%{tde_libdir}/lib[kt]deinit_cervisia.la -%{tde_libdir}/lib[kt]deinit_cervisia.so -%{tde_tdelibdir}/cervisia.la -%{tde_tdelibdir}/cervisia.so -%{tde_tdelibdir}/libcervisiapart.la -%{tde_tdelibdir}/libcervisiapart.so -%{tde_tdeappdir}/cervisia.desktop -%{tde_datadir}/apps/cervisia/ -%{tde_datadir}/apps/cervisiapart/cervisiaui.rc -%{tde_datadir}/apps/kconf_update/cervisia.upd -%{tde_datadir}/apps/kconf_update/cervisia-change_repos_list.pl -%{tde_datadir}/apps/kconf_update/cervisia-normalize_cvsroot.pl -%{tde_datadir}/apps/kconf_update/move_repositories.pl -%{tde_datadir}/apps/kconf_update/change_colors.pl -%{tde_datadir}/config.kcfg/cervisiapart.kcfg -%{tde_datadir}/icons/hicolor/*/apps/cervisia.png -%{tde_datadir}/icons/crystalsvg/*/actions/vcs_*.png -%{tde_datadir}/icons/crystalsvg/scalable/actions/vcs_*.svgz -%{tde_mandir}/man1/cervisia.1* -%{tde_tdedocdir}/HTML/en/cervisia/ - -%post -n trinity-cervisia -/sbin/ldconfig || : -for f in crystalsvg hicolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-cervisia -/sbin/ldconfig || : -for f in crystalsvg hicolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-kapptemplate -Summary: Creates a framework to develop a Trinity application -Group: Development/Utilities - -%description -n trinity-kapptemplate -KAppTemplate is a shell script that will create the necessary -framework to develop various TDE applications. It takes care of the -autoconf/automake code as well as providing a skeleton and example of -what the code typically looks like. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kapptemplate -%{tde_bindir}/kapptemplate -%{tde_datadir}/apps/kapptemplate/ - -%pre -n trinity-kapptemplate -if [ -d "%{tde_bindir}/kapptemplate" ]; then - rm -rf "%{tde_bindir}/kapptemplate" -fi - -########## - -%package -n trinity-kbabel -Summary: PO-file editing suite for Trinity -Group: Development/Utilities - -%description -n trinity-kbabel -This is a suite of programs for editing gettext message files (PO-files). -It is designed to help you translate fast and consistently. - -This suite includes KBabel, CatalogManager and KBabelDict. KBabel is an -advanced and easy to use PO-file editor with full navigational and editing -capabilities, syntax checking and statistics. CatalogManager is a multi -functional catalog manager which allows you to keep track of many -PO-files at once. KBabelDict is a dictionary to assist with searching -for common translations. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kbabel -%{tde_bindir}/catalogmanager -%{tde_bindir}/kbabel -%{tde_bindir}/kbabeldict -%{tde_libdir}/libkbabelcommon.so.* -%{tde_libdir}/libkbabeldictplugin.so.* -%{tde_tdelibdir}/kfile_po.la -%{tde_tdelibdir}/kfile_po.so -%{tde_tdelibdir}/pothumbnail.la -%{tde_tdelibdir}/pothumbnail.so -%{tde_tdelibdir}/kbabel_accelstool.la -%{tde_tdelibdir}/kbabel_accelstool.so -%{tde_tdelibdir}/kbabel_argstool.la -%{tde_tdelibdir}/kbabel_argstool.so -%{tde_tdelibdir}/kbabel_contexttool.la -%{tde_tdelibdir}/kbabel_contexttool.so -%{tde_tdelibdir}/kbabel_equationstool.la -%{tde_tdelibdir}/kbabel_equationstool.so -%{tde_tdelibdir}/kbabel_gettextexport.la -%{tde_tdelibdir}/kbabel_gettextexport.so -%{tde_tdelibdir}/kbabel_gettextimport.la -%{tde_tdelibdir}/kbabel_gettextimport.so -%{tde_tdelibdir}/kbabel_lengthtool.la -%{tde_tdelibdir}/kbabel_lengthtool.so -%{tde_tdelibdir}/kbabel_linguistexport.la -%{tde_tdelibdir}/kbabel_linguistexport.so -%{tde_tdelibdir}/kbabel_linguistimport.la -%{tde_tdelibdir}/kbabel_linguistimport.so -%{tde_tdelibdir}/kbabel_nottranslatedtool.la -%{tde_tdelibdir}/kbabel_nottranslatedtool.so -%{tde_tdelibdir}/kbabel_pluraltool.la -%{tde_tdelibdir}/kbabel_pluraltool.so -%{tde_tdelibdir}/kbabel_punctuationtool.la -%{tde_tdelibdir}/kbabel_punctuationtool.so -%{tde_tdelibdir}/kbabel_regexptool.la -%{tde_tdelibdir}/kbabel_regexptool.so -%{tde_tdelibdir}/kbabel_setfuzzytool.la -%{tde_tdelibdir}/kbabel_setfuzzytool.so -%{tde_tdelibdir}/kbabel_whitespacetool.la -%{tde_tdelibdir}/kbabel_whitespacetool.so -%{tde_tdelibdir}/kbabel_xliffexport.la -%{tde_tdelibdir}/kbabel_xliffexport.so -%{tde_tdelibdir}/kbabel_xliffimport.la -%{tde_tdelibdir}/kbabel_xliffimport.so -%{tde_tdelibdir}/kbabel_xmltool.la -%{tde_tdelibdir}/kbabel_xmltool.so -%{tde_tdelibdir}/kbabeldict_dbsearchengine.la -%{tde_tdelibdir}/kbabeldict_dbsearchengine.so -%{tde_tdelibdir}/kbabeldict_poauxiliary.la -%{tde_tdelibdir}/kbabeldict_poauxiliary.so -%{tde_tdelibdir}/kbabeldict_pocompendium.la -%{tde_tdelibdir}/kbabeldict_pocompendium.so -%{tde_tdelibdir}/kbabeldict_tmxcompendium.la -%{tde_tdelibdir}/kbabeldict_tmxcompendium.so -%{tde_tdeappdir}/catalogmanager.desktop -%{tde_tdeappdir}/kbabel.desktop -%{tde_tdeappdir}/kbabeldict.desktop -%{tde_datadir}/apps/catalogmanager/catalogmanagerui.rc -%{tde_datadir}/apps/kbabel/ -%{tde_datadir}/apps/kconf_update/kbabel-difftoproject.upd -%{tde_datadir}/apps/kconf_update/kbabel-project.upd -%{tde_datadir}/apps/kconf_update/kbabel-projectrename.upd -%{tde_datadir}/config.kcfg/kbabel.kcfg -%{tde_datadir}/config.kcfg/kbprojectsettings.kcfg -%{tde_tdedocdir}/HTML/en/kbabel/ -%{tde_datadir}/icons/hicolor/*/apps/catalogmanager.png -%{tde_datadir}/icons/hicolor/*/apps/kbabel.png -%{tde_datadir}/icons/hicolor/*/apps/kbabeldict.png -%{tde_datadir}/icons/locolor/*/apps/catalogmanager.png -%{tde_datadir}/icons/locolor/*/apps/kbabel.png -%{tde_datadir}/icons/locolor/*/apps/kbabeldict.png -%{tde_datadir}/services/dbsearchengine.desktop -%{tde_datadir}/services/kfile_po.desktop -%{tde_datadir}/services/pothumbnail.desktop -%{tde_datadir}/services/kbabel_accelstool.desktop -%{tde_datadir}/services/kbabel_argstool.desktop -%{tde_datadir}/services/kbabel_contexttool.desktop -%{tde_datadir}/services/kbabel_equationstool.desktop -%{tde_datadir}/services/kbabel_gettext_export.desktop -%{tde_datadir}/services/kbabel_gettext_import.desktop -%{tde_datadir}/services/kbabel_lengthtool.desktop -%{tde_datadir}/services/kbabel_linguist_export.desktop -%{tde_datadir}/services/kbabel_linguist_import.desktop -%{tde_datadir}/services/kbabel_nottranslatedtool.desktop -%{tde_datadir}/services/kbabel_pluralformstool.desktop -%{tde_datadir}/services/kbabel_punctuationtool.desktop -%{tde_datadir}/services/kbabel_regexptool.desktop -%{tde_datadir}/services/kbabel_setfuzzytool.desktop -%{tde_datadir}/services/kbabel_whitespacetool.desktop -%{tde_datadir}/services/kbabel_xliff_export.desktop -%{tde_datadir}/services/kbabel_xliff_import.desktop -%{tde_datadir}/services/kbabel_xmltool.desktop -%{tde_datadir}/services/pocompendium.desktop -%{tde_datadir}/services/poauxiliary.desktop -%{tde_datadir}/services/tmxcompendium.desktop -%{tde_datadir}/servicetypes/kbabel_tool.desktop -%{tde_datadir}/servicetypes/kbabel_validator.desktop -%{tde_datadir}/servicetypes/kbabeldict_module.desktop -%{tde_datadir}/servicetypes/kbabelfilter.desktop - -%post -n trinity-kbabel -/sbin/ldconfig || : -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-kbabel -/sbin/ldconfig || : -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-kbabel-devel -Summary: PO-file editing suite for Trinity (development files) -Group: Development/Libraries -Requires: trinity-kbabel = %{version}-%{release} - -%description -n trinity-kbabel-devel -This is a suite of programs for editing gettext message files (PO-files). -It is designed to help you translate fast and consistently. - -This suite includes KBabel, CatalogManager and KBabelDict. KBabel is an -advanced and easy to use PO-file editor with full navigational and editing -capabilities, syntax checking and statistics. CatalogManager is a multi -functional catalog manager which allows you to keep track of many -PO-files at once. KBabelDict is a dictionary to assist with searching -for common translations. - -This package contains the KBabel development files. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kbabel-devel -%{tde_tdeincludedir}/kbabel/ -%{tde_libdir}/libkbabelcommon.la -%{tde_libdir}/libkbabelcommon.so -%{tde_libdir}/libkbabeldictplugin.la -%{tde_libdir}/libkbabeldictplugin.so - -%post -n trinity-kbabel-devel -/sbin/ldconfig || : - -%postun -n trinity-kbabel-devel -/sbin/ldconfig || : - -########## - -%package -n trinity-kbugbuster -Summary: a front end for the Trinity bug tracking system -Group: Development/Utilities - -%description -n trinity-kbugbuster -KBugBuster is a GUI front end for the TDE bug tracking system. -It allows the user to view and manipulate bug reports and provides a -variety of options for searching through reports. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kbugbuster -%{tde_bindir}/kbugbuster -%{tde_tdelibdir}/kcal_bugzilla.la -%{tde_tdelibdir}/kcal_bugzilla.so -%{tde_tdeappdir}/kbugbuster.desktop -%{tde_datadir}/apps/kbugbuster/ -%{tde_datadir}/icons/hicolor/*/apps/kbugbuster.png -%{tde_datadir}/icons/locolor/*/apps/kbugbuster.png -%{tde_datadir}/services/kresources/kcal/bugzilla.desktop -%{tde_tdedocdir}/HTML/en/kbugbuster/ - -%post -n trinity-kbugbuster -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-kbugbuster -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-tdecachegrind -Summary: visualisation tool for valgrind profiling output -Group: Development/Utilities - -%description -n trinity-tdecachegrind -KCachegrind is a visualisation tool for the profiling data generated -by calltree, a profiling skin for valgrind. Applications can be -profiled using calltree without being recompiled, and shared libraries -and plugin architectures are supported. - -For visualising the output from other profiling tools, several converters -can be found in the tdecachegrind-converters package. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-tdecachegrind -%{tde_bindir}/kcachegrind -%{tde_tdeappdir}/kcachegrind.desktop -%{tde_datadir}/apps/kcachegrind/ -%{tde_datadir}/icons/locolor/*/apps/kcachegrind.png -%{tde_datadir}/icons/hicolor/*/apps/kcachegrind.png -%{tde_datadir}/mimelnk/application/x-kcachegrind.desktop -%{tde_tdedocdir}/HTML/en/kcachegrind/ - -%post -n trinity-tdecachegrind -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-tdecachegrind -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-tdecachegrind-converters -Summary: format converters for KCachegrind profiling visualisation tool -Group: Development/Utilities -Requires: python -%if 0%{?suse_version} || 0%{?rhel} == 4 -Requires: php -%else -Requires: php-cli -%endif - -%description -n trinity-tdecachegrind-converters -This is a collection of scripts for converting the output from -different profiling tools into a format that KCachegrind can use. - -KCachegrind is a visualisation tool for the profiling data generated -by calltree, a profiling skin for valgrind. Applications can be -profiled using calltree without being recompiled, and shared libraries -and plugin architectures are supported. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-tdecachegrind-converters -%{tde_bindir}/dprof2calltree -%{tde_bindir}/hotshot2calltree -%{tde_bindir}/memprof2calltree -%{tde_bindir}/op2calltree -%{tde_bindir}/pprof2calltree - -########## - -%package kfile-plugins -Summary: Trinity file dialog plugins for software development files -Group: Environment/Libraries - -%description kfile-plugins -This is a collection of plugins for the TDE file dialog. These plugins -extend the file dialog to offer advanced meta-information for source files, -patch files and Qt Linguist data. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files kfile-plugins -%{tde_tdelibdir}/kfile_cpp.so -%{tde_tdelibdir}/kfile_cpp.la -%{tde_tdelibdir}/kfile_diff.so -%{tde_tdelibdir}/kfile_diff.la -%{tde_tdelibdir}/kfile_ts.so -%{tde_tdelibdir}/kfile_ts.la -%{tde_datadir}/services/kfile_cpp.desktop -%{tde_datadir}/services/kfile_diff.desktop -%{tde_datadir}/services/kfile_h.desktop -%{tde_datadir}/services/kfile_ts.desktop - -########## - -%package misc -Summary: various goodies from the Trinity Software Development Kit -Group: Development/Libraries - -%description misc -This package contains miscellaneous goodies provided with the official -TDE release to assist with TDE software development. - -Included are: -- headers to assist with profiling TDE code; -- a widget style for checking conformity with the TDE/Qt style guide; -- palettes that match the KDE standard colour palette; -- a TDE address book plugin that reads the list of TDE CVS accounts. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files misc -%{tde_tdeincludedir}/kprofilemethod.h -%{tde_tdelibdir}/kabcformat_kdeaccounts.la -%{tde_tdelibdir}/kabcformat_kdeaccounts.so -%{tde_tdelibdir}/plugins/styles/scheck.so -%{tde_tdelibdir}/plugins/styles/scheck.la -%{tde_datadir}/apps/kabc/formats/kdeaccountsplugin.desktop -%{tde_datadir}/apps/kstyle/themes/scheck.themerc -%{tde_datadir}/kdepalettes/ - -%{tde_libdir}/libkstartperf.so.* -%{tde_libdir}/libkstartperf.so -%{tde_libdir}/libkstartperf.la -%{tde_bindir}/kstartperf - -%post misc -/sbin/ldconfig || : - -%postun misc -/sbin/ldconfig || : - -########## - -%package scripts -Summary: a set of useful development scripts for Trinity -Group: Development/Utilities -Requires: python - -%description scripts -This package contains a number of scripts which can be used to help in -developing TDE-based applications. Many of these scripts however are -not specific to TDE, and in particular there are several general-use -scripts to help users in working with SVN and CVS repositories. - -In addition to these scripts, this package provides: -- gdb macros for Qt/TDE programming; -- vim and emacs helper files for Qt/TDE programming; -- bash and zsh completion controls for TDE apps; -- valgrind error suppressions for TDE apps. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files scripts -%{tde_bindir}/adddebug -%{tde_bindir}/build-progress.sh -%{tde_bindir}/cheatmake -%{tde_bindir}/create_cvsignore -%{tde_bindir}/create_makefile -%{tde_bindir}/create_makefiles -%{tde_bindir}/cvs-clean -%{tde_bindir}/cvs2dist -%{tde_bindir}/cvsbackport -%{tde_bindir}/cvsblame -%{tde_bindir}/cvscheck -%{tde_bindir}/cvsforwardport -%{tde_bindir}/cvslastchange -%{tde_bindir}/cvslastlog -%{tde_bindir}/cvsrevertlast -%{tde_bindir}/cvsversion -%{tde_bindir}/cxxmetric -%{tde_bindir}/extend_dmalloc -%{tde_bindir}/extractattr -%{tde_bindir}/extractrc -%{tde_bindir}/findmissingcrystal -%{tde_bindir}/fixkdeincludes -%{tde_bindir}/fixuifiles -%{tde_bindir}/includemocs -%{tde_bindir}/kde-build -%{tde_bindir}/kdedoc -%{tde_bindir}/kdekillall -%{tde_bindir}/kdelnk2desktop.py* -%{tde_bindir}/kdemangen.pl -%{tde_bindir}/makeobj -%{tde_bindir}/noncvslist -%{tde_bindir}/package_crystalsvg -%{tde_bindir}/png2mng.pl -%{tde_bindir}/pruneemptydirs -%{tde_bindir}/qtdoc -%{tde_bindir}/zonetab2pot.py* -%{tde_bindir}/svn2dist -%{tde_bindir}/svnrevertlast -%{tde_bindir}/svnforwardport -%{tde_bindir}/nonsvnlist -%{tde_bindir}/[kt]desvn-build -%{tde_bindir}/svnlastlog -%{tde_bindir}/svnversions -%{tde_bindir}/create_svnignore -%{tde_bindir}/svnlastchange -%{tde_bindir}/colorsvn -%{tde_bindir}/svnaddcurrentdir -%{tde_bindir}/svnbackport -%{tde_bindir}/svngettags -%{tde_bindir}/svnchangesince -%{tde_bindir}/svn-clean -%{tde_datadir}/apps/katepart/syntax/[kt]desvn-buildrc.xml -%{tde_mandir}/man1/cvsblame.1 -%{tde_mandir}/man1/cvscheck.1 -%{tde_mandir}/man1/cvsversion.1 -%{tde_mandir}/man1/kde-build.1 -%{tde_mandir}/man1/includemocs.1 -%{tde_mandir}/man1/noncvslist.1 -%{tde_mandir}/man1/[kt]desvn-build.1 -%{tde_tdedocdir}/HTML/en/[kt]desvn-build/ -#scripts/kde-devel-gdb /opt/trinity/share/tdesdk-scripts -#scripts/kde-devel-vim.vim /opt/trinity/share/tdesdk-scripts -#scripts/kde-emacs/*.el /opt/trinity/share/emacs/site-lisp/tdesdk-scripts -#scripts/kde.supp /opt/trinity/lib/valgrind -#scripts/completions /opt/trinity/share/tdesdk-scripts - -#debian/desktop-i18n/createdesktop.pl /opt/trinity/lib/kubuntu-desktop-i18n/ -#debian/desktop-i18n/findfiles /opt/trinity/lib/kubuntu-desktop-i18n/ -#debian/desktop-i18n/msgsplit /opt/trinity/lib/kubuntu-desktop-i18n/ - -%if "%{?tde_prefix}" != "/usr" -%{tde_bindir}/licensecheck -%else -%exclude %{tde_bindir}/licensecheck -%endif - -########## - -%package -n trinity-kmtrace -Summary: a Trinity memory leak tracer -Group: Development/Utilities -Requires: less - -%description -n trinity-kmtrace -KMtrace is a TDE tool to assist with malloc debugging using glibc's -"mtrace" functionality. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kmtrace -%{tde_bindir}/demangle -%{tde_bindir}/kminspector -%{tde_bindir}/kmmatch -%{tde_bindir}/kmtrace -%{tde_tdeincludedir}/ktrace.h -%{tde_libdir}/kmtrace/libktrace.la -%{tde_libdir}/kmtrace/libktrace.so -%{tde_libdir}/kmtrace/libktrace_s.a -%{tde_datadir}/apps/kmtrace/kde.excludes - -########## - -%package -n trinity-kompare -Summary: a Trinity GUI for viewing differences between files -Group: Development/Utilities - -%description -n trinity-kompare -Kompare is a graphical user interface for viewing the differences between -files. It can compare two documents, create a diff file, display a diff -file and/or blend a diff file back into the original documents. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kompare -%{tde_bindir}/kompare -%{tde_libdir}/libkompareinterface.la -%{tde_libdir}/libkompareinterface.so -%{tde_libdir}/libkompareinterface.so.* -%{tde_tdelibdir}/libkomparenavtreepart.la -%{tde_tdelibdir}/libkomparenavtreepart.so -%{tde_tdelibdir}/libkomparepart.la -%{tde_tdelibdir}/libkomparepart.so -%{tde_tdeappdir}/kompare.desktop -%{tde_datadir}/apps/kompare/komparepartui.rc -%{tde_datadir}/apps/kompare/kompareui.rc -%{tde_datadir}/services/komparenavtreepart.desktop -%{tde_datadir}/services/komparepart.desktop -%{tde_datadir}/servicetypes/komparenavigationpart.desktop -%{tde_datadir}/servicetypes/kompareviewpart.desktop -%{tde_datadir}/icons/hicolor/*/apps/kompare.png -%{tde_datadir}/icons/hicolor/scalable/apps/kompare.svgz -%{tde_tdedocdir}/HTML/en/kompare/ - -%post -n trinity-kompare -/sbin/ldconfig || : -for f in hicolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-kompare -/sbin/ldconfig || : -for f in hicolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-kspy -Summary: examines the internal state of a Qt/TDE app -Group: Environment/Libraries -Requires: trinity-tdelibs-devel - -%description -n trinity-kspy -KSpy is a tiny library which can be used to graphically display -the QObjects in use by a Qt/TDE app. In addition to the object tree, -you can also view the properties, signals and slots of any QObject. - -Basically it provides much the same info as QObject::dumpObjectTree() and -QObject::dumpObjectInfo(), but in a much more convenient form. KSpy has -minimal overhead for the application, because the kspy library is -loaded dynamically using KLibLoader. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kspy -%{tde_tdeincludedir}/kspy.h -%{tde_libdir}/libkspy.la -%{tde_libdir}/libkspy.so -%{tde_libdir}/libkspy.so.* - -%post -n trinity-kspy -/sbin/ldconfig || : - -%postun -n trinity-kspy -/sbin/ldconfig || : - -########## - -%package -n trinity-kuiviewer -Summary: viewer for Qt Designer user interface files -Group: Development/Utilities - -%description -n trinity-kuiviewer -KUIViewer is a utility to display and test the user interface (.ui) files -generated by Qt Designer. The interfaces can be displayed in a variety of -different widget styles. - -The Qt Designer itself is in the package qt3-designer. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kuiviewer -%{tde_bindir}/kuiviewer -%{tde_tdelibdir}/libkuiviewerpart.so -%{tde_tdelibdir}/libkuiviewerpart.la -%{tde_tdelibdir}/quithumbnail.so -%{tde_tdelibdir}/quithumbnail.la -%{tde_tdeappdir}/kuiviewer.desktop -%{tde_datadir}/apps/kuiviewer/kuiviewerui.rc -%{tde_datadir}/apps/kuiviewerpart/kuiviewer_part.rc -%{tde_datadir}/icons/hicolor/*/apps/kuiviewer.png -%{tde_datadir}/icons/locolor/*/apps/kuiviewer.png -%{tde_datadir}/services/designerthumbnail.desktop -%{tde_datadir}/services/kuiviewer_part.desktop - -%post -n trinity-kuiviewer -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done - -%postun -n trinity-kuiviewer -for f in hicolor locolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done - -########## - -%package -n trinity-libcvsservice0 -Summary: DCOP service for accessing CVS repositories -Group: Environment/Libraries -Requires: cvs - -%description -n trinity-libcvsservice0 -This library provides a DCOP service for accessing and working with -remote CVS repositories. Applications may link with this library to -access the DCOP service directly from C++. Alternatively, scripts may -access the service using the standard "dcop" command-line tool. - -DCOP is the Desktop Communication Protocol used throughout TDE. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-libcvsservice0 -%{tde_bindir}/cvsaskpass -%{tde_bindir}/cvsservice -%{tde_libdir}/libcvsservice.so.* -%{tde_libdir}/lib[kt]deinit_cvsaskpass.so -%{tde_libdir}/lib[kt]deinit_cvsservice.so -%{tde_tdelibdir}/cvsaskpass.la -%{tde_tdelibdir}/cvsaskpass.so -%{tde_tdelibdir}/cvsservice.la -%{tde_tdelibdir}/cvsservice.so -%{tde_datadir}/services/cvsservice.desktop - -%post -n trinity-libcvsservice0 -/sbin/ldconfig || : - -%postun -n trinity-libcvsservice0 -/sbin/ldconfig || : - -########## - -%package -n trinity-libcvsservice-devel -Summary: development files for CVS DCOP service -Group: Development/Libraries -Requires: trinity-libcvsservice0 = %{version}-%{release} - -%description -n trinity-libcvsservice-devel -The library libcvsservice provides a DCOP service for accessing and -working with remote CVS repositories. Applications may link with this -library to access the DCOP service directly from C++. Alternatively, -scripts may access the service using the standard "dcop" command-line -tool. - -Development files for libcvsservice are included in this package. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-libcvsservice-devel -%{tde_tdeincludedir}/cvsjob_stub.h -%{tde_tdeincludedir}/cvsservice_stub.h -%{tde_tdeincludedir}/repository_stub.h -%{tde_libdir}/libcvsservice.la -%{tde_libdir}/libcvsservice.so -%{tde_libdir}/lib[kt]deinit_cvsaskpass.la -%{tde_libdir}/lib[kt]deinit_cvsservice.la -%{tde_datadir}/cmake/cervisia.cmake - -%post -n trinity-libcvsservice-devel -/sbin/ldconfig || : - -%postun -n trinity-libcvsservice-devel -/sbin/ldconfig || : - -########## - -%package -n trinity-poxml -Summary: tools for using PO-files to translate DocBook XML files -Group: Development/Utilities - -%description -n trinity-poxml -This is a collection of tools that facilitate translating DocBook XML -files using gettext message files (PO-files). - -Also included are some miscellaneous command-line utilities for -manipulating DocBook XML files, PO-files and PO-template files. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-poxml -%{tde_bindir}/po2xml -%{tde_bindir}/split2po -%{tde_bindir}/swappo -%{tde_bindir}/transxx -%{tde_bindir}/xml2pot - -########## - -%package -n trinity-umbrello -Summary: UML modelling tool and code generator -Group: Development/Utilities - -%description -n trinity-umbrello -Umbrello UML Modeller is a Unified Modelling Language editor for TDE. -With UML you can create diagrams of software and other systems in an -industry standard format. Umbrello can also generate code from your -UML diagrams in a number of programming languages. - -The program supports class diagrams, sequence diagrams, collaboration -diagrams, use case diagrams, state diagrams, activity diagrams, component -diagrams and deployment diagrams. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-umbrello -%{tde_bindir}/umbodoc -%{tde_bindir}/umbrello -%{tde_tdeappdir}/umbrello.desktop -%{tde_datadir}/apps/umbrello/ -%{tde_datadir}/icons/crystalsvg/*/actions/umbrello_*.png -%{tde_datadir}/icons/crystalsvg/*/mimetypes/umbrellofile.png -%{tde_datadir}/icons/crystalsvg/scalable/mimetypes/umbrellofile.svgz -%{tde_datadir}/icons/hicolor/*/apps/umbrello.png -%{tde_datadir}/icons/hicolor/scalable/apps/umbrello.svgz -%{tde_datadir}/icons/hicolor/*/mimetypes/umbrellofile.png -%{tde_datadir}/mimelnk/application/x-umbrello.desktop -%{tde_tdedocdir}/HTML/en/umbrello/ - -%post -n trinity-umbrello -for f in crystalsvg hicolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-umbrello -for f in crystalsvg hicolor ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{tde_datadir}/applications > /dev/null 2>&1 || : - -########## - -%if 0%{?build_kioslave} - -%package kio-plugins -Summary: subversion ioslave for Trinity -Group: Environment/Libraries -Requires: subversion - -%description kio-plugins -This package provides easy access to remote SVN repositories from within -Konqueror, and TDE generally, by browsing them as if they were a -filesystem, using URLs like svn://hostname/path, or svn+ssh://, etc. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files kio-plugins -%{tde_bindir}/kio_svn_helper -%{tde_tdelibdir}/kded_ksvnd.la -%{tde_tdelibdir}/kded_ksvnd.so -%{tde_tdelibdir}/kio_svn.la -%{tde_tdelibdir}/kio_svn.so -%{tde_datadir}/apps/konqueror/servicemenus/subversion_toplevel.desktop -%{tde_datadir}/apps/konqueror/servicemenus/subversion.desktop -%{tde_datadir}/services/kded/ksvnd.desktop -%{tde_datadir}/services/svn+file.protocol_tdesdk -%{tde_datadir}/services/svn+http.protocol_tdesdk -%{tde_datadir}/services/svn+https.protocol_tdesdk -%{tde_datadir}/services/svn+ssh.protocol_tdesdk -%{tde_datadir}/services/svn.protocol_tdesdk -%{tde_datadir}/services/svn+file.protocol -%{tde_datadir}/services/svn+http.protocol -%{tde_datadir}/services/svn+https.protocol -%{tde_datadir}/services/svn+ssh.protocol -%{tde_datadir}/services/svn.protocol -%{tde_datadir}/icons/crystalsvg/*/actions/svn_switch.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_merge.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_branch.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_remove.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_add.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_status.png -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_add.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_status.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_remove.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_switch.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_branch.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_merge.svgz - -%post kio-plugins -for f in crystalsvg ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done - -for proto in svn+file svn+http svn+https svn+ssh svn; do -%if 0%{?suse_version} - update-alternatives --install \ -%else - alternatives --install \ -%endif - %{tde_datadir}/services/${proto}.protocol \ - ${proto}.protocol \ - %{tde_datadir}/services/${proto}.protocol_tdesdk \ - 10 -done - -%postun kio-plugins -for f in crystalsvg ; do - touch --no-create %{tde_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{tde_datadir}/icons/$f 2> /dev/null ||: -done - -%preun kio-plugins -if [ $1 -eq 0 ]; then - for proto in svn+file svn+http svn+https svn+ssh svn; do -%if 0%{?suse_version} - update-alternatives --remove \ -%else - alternatives --remove \ -%endif - ${proto}.protocol \ - %{tde_datadir}/services/${proto}.protocol_tdesdk - done -fi - -%endif - -########## - -%package -n trinity-kunittest -Summary: unit testing library for Trinity -Group: Development/Utilities - -%description -n trinity-kunittest -KUnitTest is a small library that facilitates the writing of tests for -TDE developers. There are two ways to use the KUnitTest library. One is -to create dynamically loadable modules and use the kunittestmodrunner or -kunittestguimodrunner programs to run the tests. The other is to use the -libraries to create your own testing application. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kunittest -%{tde_bindir}/kunittest -%{tde_bindir}/kunittest_debughelper -%{tde_bindir}/kunittestmod -%{tde_bindir}/kunittestguimodrunner -%{tde_libdir}/libkunittestgui.la -%{tde_libdir}/libkunittestgui.so -%{tde_libdir}/libkunittestgui.so.* -%{tde_tdeincludedir}/kunittest/runnergui.h - -%post -n trinity-kunittest -/sbin/ldconfig || : - -%postun -n trinity-kunittest -/sbin/ldconfig || : - -########## - -%package devel -Summary: Development files for %{name} -Group: Development/Libraries - -Requires: %{name} = %{version}-%{release} -Requires: trinity-kbabel-devel = %{version}-%{release} - -Obsoletes: trinity-kdesdk-devel < %{version}-%{release} -Provides: trinity-kdesdk-devel = %{version}-%{release} - -%description devel -%{summary}. - -%files devel - -########## - -%if 0%{?suse_version} || 0%{?pclinuxos} -%debug_package -%endif - -########## - - -%prep -%setup -q -n kdesdk-3.5.13.1 -%patch5 -p1 -b .svn -%patch6 -p1 -b .cmake -%patch7 -p1 -%patch8 -p1 -b .flex -%patch9 -p1 -b .cmake - - -%build -unset QTDIR || :; . /etc/profile.d/qt3.sh -export PATH="%{tde_bindir}:${PATH}" -export LD_LIBRARY_PATH="%{tde_libdir}" -export PKG_CONFIG_PATH="%{tde_libdir}/pkgconfig" -export CMAKE_INCLUDE_PATH="%{tde_includedir}:%{tde_includedir}/tqt" - -# Specific path for RHEL4 -if [ -d /usr/X11R6 ]; then - export CXXFLAGS="${RPM_OPT_FLAGS} -I/usr/X11R6/include -L/usr/X11R6/%{_lib}" -fi -%if 0%{?rhel} || 0%{?fedora} || 0%{?suse_version} -%__mkdir_p build -cd build -%endif - - -%cmake \ - -DBIN_INSTALL_DIR=%{tde_bindir} \ - -DINCLUDE_INSTALL_DIR=%{tde_tdeincludedir} \ - -DLIB_INSTALL_DIR=%{tde_libdir} \ - -DMAN_INSTALL_DIR=%{tde_mandir} \ - -DPKGCONFIG_INSTALL_DIR=%{tde_tdelibdir}/pkgconfig \ - -DSHARE_INSTALL_PREFIX=%{tde_datadir} \ - -DCMAKE_SKIP_RPATH="OFF" \ - -DWITH_DBSEARCHENGINE=ON \ - -DWITH_KCAL=ON \ - -DBUILD_ALL=ON \ - %{!?build_kioslave:-DBUILD_KIOSLAVE=OFF} \ - .. - -%__make %{?_smp_mflags} - - -%install -export PATH="%{tde_bindir}:${PATH}" -%__rm -rf %{buildroot} - -%__make install DESTDIR=%{?buildroot} -C build - -# make symlinks relative -if [ -d %{buildroot}%{tde_tdedocdir}/HTML/en ]; then - pushd %{buildroot}%{tde_tdedocdir}/HTML/en - for i in *; do - if [ -d $i -a -L $i/common ]; then - rm -f $i/common - ln -nfs ../common $i - fi - done - popd -fi - -# Installs kdepalettes -%__install -D -m 644 kdepalettes/kde_xpaintrc %{?buildroot}%{tde_datadir}/kdepalettes -%__install -D -m 644 kdepalettes/KDE_Gimp %{?buildroot}%{tde_datadir}/kdepalettes -%__install -D -m 644 kdepalettes/README %{?buildroot}%{tde_datadir}/kdepalettes - -# Installs SVN protocols as alternatives -%if 0%{?build_kioslave} -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+file.protocol %{?buildroot}%{tde_datadir}/services/svn+file.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+http.protocol %{?buildroot}%{tde_datadir}/services/svn+http.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+https.protocol %{?buildroot}%{tde_datadir}/services/svn+https.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+ssh.protocol %{?buildroot}%{tde_datadir}/services/svn+ssh.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn.protocol %{?buildroot}%{tde_datadir}/services/svn.protocol_tdesdk -%__ln_s /etc/alternatives/svn+file.protocol %{?buildroot}%{tde_datadir}/services/svn+file.protocol -%__ln_s /etc/alternatives/svn+http.protocol %{?buildroot}%{tde_datadir}/services/svn+http.protocol -%__ln_s /etc/alternatives/svn+https.protocol %{?buildroot}%{tde_datadir}/services/svn+https.protocol -%__ln_s /etc/alternatives/svn+ssh.protocol %{?buildroot}%{tde_datadir}/services/svn+ssh.protocol -%__ln_s /etc/alternatives/svn.protocol %{?buildroot}%{tde_datadir}/services/svn.protocol -%endif - -%clean -%__rm -rf %{buildroot} - - - -%changelog -* Wed Nov 07 2012 Francois Andriot - 3.5.13.1-2 -- Fix various cmake issues [Bug #1262] - -* Sun Sep 30 2012 Francois Andriot - 3.5.13.1-1 -- Initial release for TDE 3.5.13.1 diff --git a/redhat/main/tdesdk/kdesdk-3.5.13.spec b/redhat/main/tdesdk/kdesdk-3.5.13.spec deleted file mode 100644 index 6b096fdb9..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.13.spec +++ /dev/null @@ -1,1130 +0,0 @@ -# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt". -%if "%{?tde_prefix}" != "/usr" -%define _variant .opt -%endif - -# TDE 3.5.13 specific building variables -%define tde_bindir %{tde_prefix}/bin -%define tde_datadir %{tde_prefix}/share -%define tde_docdir %{tde_datadir}/doc -%define tde_includedir %{tde_prefix}/include -%define tde_libdir %{tde_prefix}/%{_lib} -%define tde_mandir %{tde_datadir}/man - -%define tde_tdeappdir %{tde_datadir}/applications/kde -%define tde_tdedocdir %{tde_docdir}/kde -%define tde_tdeincludedir %{tde_includedir}/kde -%define tde_tdelibdir %{tde_libdir}/trinity - - -Name: trinity-tdesdk -Summary: The KDE Software Development Kit (SDK) -Version: 3.5.13 -Release: 2%{?dist}%{?_variant} - -License: GPLv2 -Group: User Interface/Desktops -URL: http://www.trinitydesktop.org/ -Vendor: Trinity Project -Packager: Francois Andriot - -Prefix: %{tde_prefix} -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -Source: kdesdk-%{version}.tar.gz - -# RedHat Legacy patches -Patch1: kdesdk-3.5.7-subversion.patch -# [tdesdk] cmake port [Commit #bfb0bc00] -Patch2: kdesdk-3.5.13-cmake_port.patch -# [tdesdk/cmake] added forgotten files [Commit #adee843c] -Patch3: kdesdk-3.5.13-add_forgotten_cmake_files.patch -# [tdesdk] fixes for RHEL/Fedora/MGA2 after previous patch -Patch4: kdesdk-3.5.13-misc_ftbfs.patch -# [tdesdk] Fix FTBFS on newer subversion libraries [Bug #872] [Commit #572169a2] -Patch5: kdesdk-3.5.13-fix_ftbfs_on_newer_svn.patch - -BuildRequires: cmake >= 2.8 -BuildRequires: libtool -BuildRequires: tqtinterface-devel -BuildRequires: pcre-devel -BuildRequires: trinity-tdelibs-devel -# for kbugbuster/libkcal -BuildRequires: trinity-tdepim-devel -%if 0%{?mgaversion} || 0%{?mdkversion} -#BuildRequires: %{_lib}db4.8-devel -%else -BuildRequires: db4-devel -%endif -BuildRequires: desktop-file-utils -# kbabel, F-7+: flex >= 2.5.33-9 -BuildRequires: flex -# umbrello -BuildRequires: libxslt-devel libxml2-devel -BuildRequires: perl -BuildRequires: subversion-devel neon-devel - -%if 0%{?mgaversion} || 0%{?mdkversion} -BuildRequires: %{_lib}ltdl-devel -BuildRequires: %{_lib}binutils-devel -%else -BuildRequires: libtool-ltdl-devel -%if 0%{?fedora} > 5 || 0%{?rhel} > 4 -BuildRequires: binutils-devel -%endif -%endif - -Obsoletes: trinity-kdesdk < %{version}-%{release} -Provides: trinity-kdesdk = %{version}-%{release} -Obsoletes: trinity-kdesdk-libs < %{version}-%{release} -Provides: trinity-kdesdk-libs = %{version}-%{release} - -Requires: trinity-cervisia = %{version}-%{release} -Requires: trinity-kapptemplate = %{version}-%{release} -Requires: trinity-kbabel = %{version}-%{release} -Requires: trinity-kbugbuster = %{version}-%{release} -Requires: trinity-tdecachegrind = %{version}-%{release} -Requires: trinity-tdecachegrind-converters = %{version}-%{release} -Requires: %{name}-kfile-plugins = %{version}-%{release} -Requires: %{name}-misc = %{version}-%{release} -Requires: %{name}-scripts = %{version}-%{release} -Requires: trinity-kmtrace = %{version}-%{release} -Requires: trinity-kompare = %{version}-%{release} -Requires: trinity-kspy = %{version}-%{release} -Requires: trinity-kuiviewer = %{version}-%{release} -Requires: trinity-libcvsservice0 = %{version}-%{release} -Requires: trinity-libcvsservice-devel = %{version}-%{release} -Requires: trinity-poxml = %{version}-%{release} -Requires: trinity-umbrello = %{version}-%{release} -Requires: %{name}-kio-plugins = %{version}-%{release} -Requires: trinity-kunittest = %{version}-%{release} - - -%description -A collection of applications and tools used by developers, including: -* cervisia: a CVS frontend -* kbabel: PO file management -* kbugbuster: a tool to manage the TDE bug report system -* kcachegrind: a browser for data produced by profiling tools (e.g. cachegrind) -* kompare: diff tool -* kuiviewer: displays designer's UI files -* umbrello: UML modeller and UML diagram tool - -%files - -########## - -%package -n trinity-cervisia -Summary: A graphical CVS front end for Trinity -Group: Development/Utilities - -%description -n trinity-cervisia -Cervisia is a TDE-based graphical front end for the CVS client. - -As well as providing both common and advanced CVS operations, it offers -a variety of methods for graphically viewing information about the CVS -repository, your own sandbox and the relationships between different -versions of files. A Changelog editor is also included and is coupled -with the commit dialog. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-cervisia -%{tde_bindir}/cervisia -%{tde_libdir}/lib[kt]deinit_cervisia.la -%{tde_libdir}/lib[kt]deinit_cervisia.so -%{tde_tdelibdir}/cervisia.la -%{tde_tdelibdir}/cervisia.so -%{tde_tdelibdir}/libcervisiapart.la -%{tde_tdelibdir}/libcervisiapart.so -%{tde_tdeappdir}/cervisia.desktop -%{tde_datadir}/apps/cervisia/ -%{tde_datadir}/apps/cervisiapart/cervisiaui.rc -%{tde_datadir}/apps/kconf_update/cervisia.upd -%{tde_datadir}/apps/kconf_update/cervisia-change_repos_list.pl -%{tde_datadir}/apps/kconf_update/cervisia-normalize_cvsroot.pl -%{tde_datadir}/apps/kconf_update/move_repositories.pl -%{tde_datadir}/apps/kconf_update/change_colors.pl -%{tde_datadir}/config.kcfg/cervisiapart.kcfg -%{tde_datadir}/icons/hicolor/*/apps/cervisia.png -%{tde_datadir}/icons/crystalsvg/*/actions/vcs_*.png -%{tde_datadir}/icons/crystalsvg/scalable/actions/vcs_*.svgz -#%{tde_mandir}/man1/cervisia.1* -%{tde_tdedocdir}/HTML/en/cervisia/ - -%post -n trinity-cervisia -/sbin/ldconfig || : -for f in crystalsvg hicolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-cervisia -/sbin/ldconfig || : -for f in crystalsvg hicolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-kapptemplate -Summary: Creates a framework to develop a Trinity application -Group: Development/Utilities - -%description -n trinity-kapptemplate -KAppTemplate is a shell script that will create the necessary -framework to develop various TDE applications. It takes care of the -autoconf/automake code as well as providing a skeleton and example of -what the code typically looks like. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kapptemplate -%{tde_bindir}/kapptemplate -%{tde_datadir}/apps/kapptemplate/ - -########## - -%package -n trinity-kbabel -Summary: PO-file editing suite for Trinity -Group: Development/Utilities - -%description -n trinity-kbabel -This is a suite of programs for editing gettext message files (PO-files). -It is designed to help you translate fast and consistently. - -This suite includes KBabel, CatalogManager and KBabelDict. KBabel is an -advanced and easy to use PO-file editor with full navigational and editing -capabilities, syntax checking and statistics. CatalogManager is a multi -functional catalog manager which allows you to keep track of many -PO-files at once. KBabelDict is a dictionary to assist with searching -for common translations. - -This package is part of Trinity, and a component of the TDE SDK module. -See the 'kde-trinity' and 'tdesdk-trinity' packages for more information. - -%files -n trinity-kbabel -%{tde_bindir}/catalogmanager -%{tde_bindir}/kbabel -%{tde_bindir}/kbabeldict -%{tde_libdir}/libkbabelcommon.so.* -%{tde_libdir}/libkbabeldictplugin.so.* -%{tde_tdelibdir}/kfile_po.la -%{tde_tdelibdir}/kfile_po.so -%{tde_tdelibdir}/pothumbnail.la -%{tde_tdelibdir}/pothumbnail.so -%{tde_tdelibdir}/kbabel_accelstool.la -%{tde_tdelibdir}/kbabel_accelstool.so -%{tde_tdelibdir}/kbabel_argstool.la -%{tde_tdelibdir}/kbabel_argstool.so -%{tde_tdelibdir}/kbabel_contexttool.la -%{tde_tdelibdir}/kbabel_contexttool.so -%{tde_tdelibdir}/kbabel_equationstool.la -%{tde_tdelibdir}/kbabel_equationstool.so -%{tde_tdelibdir}/kbabel_gettextexport.la -%{tde_tdelibdir}/kbabel_gettextexport.so -%{tde_tdelibdir}/kbabel_gettextimport.la -%{tde_tdelibdir}/kbabel_gettextimport.so -%{tde_tdelibdir}/kbabel_lengthtool.la -%{tde_tdelibdir}/kbabel_lengthtool.so -%{tde_tdelibdir}/kbabel_linguistexport.la -%{tde_tdelibdir}/kbabel_linguistexport.so -%{tde_tdelibdir}/kbabel_linguistimport.la -%{tde_tdelibdir}/kbabel_linguistimport.so -%{tde_tdelibdir}/kbabel_nottranslatedtool.la -%{tde_tdelibdir}/kbabel_nottranslatedtool.so -%{tde_tdelibdir}/kbabel_pluraltool.la -%{tde_tdelibdir}/kbabel_pluraltool.so -%{tde_tdelibdir}/kbabel_punctuationtool.la -%{tde_tdelibdir}/kbabel_punctuationtool.so -%{tde_tdelibdir}/kbabel_regexptool.la -%{tde_tdelibdir}/kbabel_regexptool.so -%{tde_tdelibdir}/kbabel_setfuzzytool.la -%{tde_tdelibdir}/kbabel_setfuzzytool.so -%{tde_tdelibdir}/kbabel_whitespacetool.la -%{tde_tdelibdir}/kbabel_whitespacetool.so -%{tde_tdelibdir}/kbabel_xliffexport.la -%{tde_tdelibdir}/kbabel_xliffexport.so -%{tde_tdelibdir}/kbabel_xliffimport.la -%{tde_tdelibdir}/kbabel_xliffimport.so -%{tde_tdelibdir}/kbabel_xmltool.la -%{tde_tdelibdir}/kbabel_xmltool.so -%{tde_tdelibdir}/kbabeldict_dbsearchengine.la -%{tde_tdelibdir}/kbabeldict_dbsearchengine.so -%{tde_tdelibdir}/kbabeldict_poauxiliary.la -%{tde_tdelibdir}/kbabeldict_poauxiliary.so -%{tde_tdelibdir}/kbabeldict_pocompendium.la -%{tde_tdelibdir}/kbabeldict_pocompendium.so -%{tde_tdelibdir}/kbabeldict_tmxcompendium.la -%{tde_tdelibdir}/kbabeldict_tmxcompendium.so -%{tde_tdeappdir}/catalogmanager.desktop -%{tde_tdeappdir}/kbabel.desktop -%{tde_tdeappdir}/kbabeldict.desktop -%{tde_datadir}/apps/catalogmanager/catalogmanagerui.rc -%{tde_datadir}/apps/kbabel/ -%{tde_datadir}/apps/kconf_update/kbabel-difftoproject.upd -%{tde_datadir}/apps/kconf_update/kbabel-project.upd -%{tde_datadir}/apps/kconf_update/kbabel-projectrename.upd -%{tde_datadir}/config.kcfg/kbabel.kcfg -%{tde_datadir}/config.kcfg/kbprojectsettings.kcfg -%{tde_tdedocdir}/HTML/en/kbabel/ -%{tde_datadir}/icons/hicolor/*/apps/catalogmanager.png -%{tde_datadir}/icons/hicolor/*/apps/kbabel.png -%{tde_datadir}/icons/hicolor/*/apps/kbabeldict.png -%{tde_datadir}/icons/locolor/*/apps/catalogmanager.png -%{tde_datadir}/icons/locolor/*/apps/kbabel.png -%{tde_datadir}/icons/locolor/*/apps/kbabeldict.png -%{tde_datadir}/services/dbsearchengine.desktop -%{tde_datadir}/services/kfile_po.desktop -%{tde_datadir}/services/pothumbnail.desktop -%{tde_datadir}/services/kbabel_accelstool.desktop -%{tde_datadir}/services/kbabel_argstool.desktop -%{tde_datadir}/services/kbabel_contexttool.desktop -%{tde_datadir}/services/kbabel_equationstool.desktop -%{tde_datadir}/services/kbabel_gettext_export.desktop -%{tde_datadir}/services/kbabel_gettext_import.desktop -%{tde_datadir}/services/kbabel_lengthtool.desktop -%{tde_datadir}/services/kbabel_linguist_export.desktop -%{tde_datadir}/services/kbabel_linguist_import.desktop -%{tde_datadir}/services/kbabel_nottranslatedtool.desktop -%{tde_datadir}/services/kbabel_pluralformstool.desktop -%{tde_datadir}/services/kbabel_punctuationtool.desktop -%{tde_datadir}/services/kbabel_regexptool.desktop -%{tde_datadir}/services/kbabel_setfuzzytool.desktop -%{tde_datadir}/services/kbabel_whitespacetool.desktop -%{tde_datadir}/services/kbabel_xliff_export.desktop -%{tde_datadir}/services/kbabel_xliff_import.desktop -%{tde_datadir}/services/kbabel_xmltool.desktop -%{tde_datadir}/services/pocompendium.desktop -%{tde_datadir}/services/poauxiliary.desktop -%{tde_datadir}/services/tmxcompendium.desktop -%{tde_datadir}/servicetypes/kbabel_tool.desktop -%{tde_datadir}/servicetypes/kbabel_validator.desktop -%{tde_datadir}/servicetypes/kbabeldict_module.desktop -%{tde_datadir}/servicetypes/kbabelfilter.desktop - -%post -n trinity-kbabel -/sbin/ldconfig || : -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-kbabel -/sbin/ldconfig || : -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-kbabel-devel -Summary: PO-file editing suite for Trinity (development files) -Group: Development/Libraries -Requires: trinity-kbabel = %{version}-%{release} - -%description -n trinity-kbabel-devel -This is a suite of programs for editing gettext message files (PO-files). -It is designed to help you translate fast and consistently. - -This suite includes KBabel, CatalogManager and KBabelDict. KBabel is an -advanced and easy to use PO-file editor with full navigational and editing -capabilities, syntax checking and statistics. CatalogManager is a multi -functional catalog manager which allows you to keep track of many -PO-files at once. KBabelDict is a dictionary to assist with searching -for common translations. - -This package contains the KBabel development files. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kbabel-devel -%{tde_tdeincludedir}/kbabel/ -%{tde_libdir}/libkbabelcommon.la -%{tde_libdir}/libkbabelcommon.so -%{tde_libdir}/libkbabeldictplugin.la -%{tde_libdir}/libkbabeldictplugin.so - -%post -n trinity-kbabel-devel -/sbin/ldconfig || : - -%postun -n trinity-kbabel-devel -/sbin/ldconfig || : - -########## - -%package -n trinity-kbugbuster -Summary: a front end for the Trinity bug tracking system -Group: Development/Utilities - -%description -n trinity-kbugbuster -KBugBuster is a GUI front end for the TDE bug tracking system. -It allows the user to view and manipulate bug reports and provides a -variety of options for searching through reports. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kbugbuster -%{tde_bindir}/kbugbuster -%{tde_tdelibdir}/kcal_bugzilla.la -%{tde_tdelibdir}/kcal_bugzilla.so -%{tde_tdeappdir}/kbugbuster.desktop -%{tde_datadir}/apps/kbugbuster/ -%{tde_datadir}/icons/hicolor/*/apps/kbugbuster.png -%{tde_datadir}/icons/locolor/*/apps/kbugbuster.png -%{tde_datadir}/services/kresources/kcal/bugzilla.desktop -%{tde_tdedocdir}/HTML/en/kbugbuster/ - -%post -n trinity-kbugbuster -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-kbugbuster -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-tdecachegrind -Summary: visualisation tool for valgrind profiling output -Group: Development/Utilities - -%description -n trinity-tdecachegrind -KCachegrind is a visualisation tool for the profiling data generated -by calltree, a profiling skin for valgrind. Applications can be -profiled using calltree without being recompiled, and shared libraries -and plugin architectures are supported. - -For visualising the output from other profiling tools, several converters -can be found in the tdecachegrind-converters package. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-tdecachegrind -%{tde_bindir}/kcachegrind -%{tde_tdeappdir}/kcachegrind.desktop -%{tde_datadir}/apps/kcachegrind/ -%{tde_datadir}/icons/locolor/*/apps/kcachegrind.png -%{tde_datadir}/icons/hicolor/*/apps/kcachegrind.png -%{tde_datadir}/mimelnk/application/x-kcachegrind.desktop -%{tde_tdedocdir}/HTML/en/kcachegrind/ - -%post -n trinity-tdecachegrind -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-tdecachegrind -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-tdecachegrind-converters -Summary: format converters for KCachegrind profiling visualisation tool -Group: Development/Utilities -Requires: php-cli -Requires: python - -%description -n trinity-tdecachegrind-converters -This is a collection of scripts for converting the output from -different profiling tools into a format that KCachegrind can use. - -KCachegrind is a visualisation tool for the profiling data generated -by calltree, a profiling skin for valgrind. Applications can be -profiled using calltree without being recompiled, and shared libraries -and plugin architectures are supported. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-tdecachegrind-converters -%{tde_bindir}/dprof2calltree -%{tde_bindir}/hotshot2calltree -%{tde_bindir}/memprof2calltree -%{tde_bindir}/op2calltree -%{tde_bindir}/pprof2calltree - -########## - -%package kfile-plugins -Summary: Trinity file dialog plugins for software development files -Group: Environment/Libraries - -%description kfile-plugins -This is a collection of plugins for the TDE file dialog. These plugins -extend the file dialog to offer advanced meta-information for source files, -patch files and Qt Linguist data. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files kfile-plugins -%{tde_tdelibdir}/kfile_cpp.so -%{tde_tdelibdir}/kfile_cpp.la -%{tde_tdelibdir}/kfile_diff.so -%{tde_tdelibdir}/kfile_diff.la -%{tde_tdelibdir}/kfile_ts.so -%{tde_tdelibdir}/kfile_ts.la -%{tde_datadir}/services/kfile_cpp.desktop -%{tde_datadir}/services/kfile_diff.desktop -%{tde_datadir}/services/kfile_h.desktop -%{tde_datadir}/services/kfile_ts.desktop - -########## - -%package misc -Summary: various goodies from the Trinity Software Development Kit -Group: Development/Libraries - -%description misc -This package contains miscellaneous goodies provided with the official -TDE release to assist with TDE software development. - -Included are: -- headers to assist with profiling TDE code; -- a widget style for checking conformity with the TDE/Qt style guide; -- palettes that match the KDE standard colour palette; -- a TDE address book plugin that reads the list of TDE CVS accounts. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files misc -%{tde_tdeincludedir}/kprofilemethod.h -%{tde_tdelibdir}/kabcformat_kdeaccounts.la -%{tde_tdelibdir}/kabcformat_kdeaccounts.so -%{tde_tdelibdir}/scheck.so -%{tde_tdelibdir}/scheck.la -%{tde_datadir}/apps/kabc/formats/kdeaccountsplugin.desktop -%{tde_datadir}/apps/kstyle/themes/scheck.themerc -%{tde_datadir}/kdepalettes/ - -%{tde_libdir}/libkstartperf.so.* -%{tde_libdir}/libkstartperf.so -%{tde_libdir}/libkstartperf.la -%{tde_bindir}/kstartperf - -%post misc -/sbin/ldconfig || : - -%postun misc -/sbin/ldconfig || : - -########## - -%package scripts -Summary: a set of useful development scripts for Trinity -Group: Development/Utilities -Requires: python - -%description scripts -This package contains a number of scripts which can be used to help in -developing TDE-based applications. Many of these scripts however are -not specific to TDE, and in particular there are several general-use -scripts to help users in working with SVN and CVS repositories. - -In addition to these scripts, this package provides: -- gdb macros for Qt/TDE programming; -- vim and emacs helper files for Qt/TDE programming; -- bash and zsh completion controls for TDE apps; -- valgrind error suppressions for TDE apps. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files scripts -%{tde_bindir}/adddebug -%{tde_bindir}/build-progress.sh -%{tde_bindir}/cheatmake -%{tde_bindir}/create_cvsignore -%{tde_bindir}/create_makefile -%{tde_bindir}/create_makefiles -%{tde_bindir}/cvs-clean -%{tde_bindir}/cvs2dist -%{tde_bindir}/cvsbackport -%{tde_bindir}/cvsblame -%{tde_bindir}/cvscheck -%{tde_bindir}/cvsforwardport -%{tde_bindir}/cvslastchange -%{tde_bindir}/cvslastlog -%{tde_bindir}/cvsrevertlast -%{tde_bindir}/cvsversion -%{tde_bindir}/cxxmetric -%{tde_bindir}/extend_dmalloc -%{tde_bindir}/extractattr -%{tde_bindir}/extractrc -%{tde_bindir}/findmissingcrystal -%{tde_bindir}/fixkdeincludes -%{tde_bindir}/fixuifiles -%{tde_bindir}/includemocs -%{tde_bindir}/kde-build -%{tde_bindir}/kdedoc -%{tde_bindir}/kdekillall -%{tde_bindir}/kdelnk2desktop.py* -%{tde_bindir}/kdemangen.pl -%{tde_bindir}/makeobj -%{tde_bindir}/noncvslist -%{tde_bindir}/package_crystalsvg -%{tde_bindir}/png2mng.pl -%{tde_bindir}/pruneemptydirs -%{tde_bindir}/qtdoc -%{tde_bindir}/zonetab2pot.py* -%{tde_bindir}/svn2dist -%{tde_bindir}/svnrevertlast -%{tde_bindir}/svnforwardport -%{tde_bindir}/nonsvnlist -%{tde_bindir}/[kt]desvn-build -%{tde_bindir}/svnlastlog -%{tde_bindir}/svnversions -%{tde_bindir}/create_svnignore -%{tde_bindir}/svnlastchange -%{tde_bindir}/colorsvn -%{tde_bindir}/svnaddcurrentdir -%{tde_bindir}/svnbackport -%{tde_bindir}/svngettags -%{tde_bindir}/svnchangesince -%{tde_bindir}/svn-clean -%{tde_datadir}/apps/katepart/syntax/[kt]desvn-buildrc.xml -%{tde_mandir}/man1/cvsblame.1 -%{tde_mandir}/man1/cvscheck.1 -%{tde_mandir}/man1/cvsversion.1 -%{tde_mandir}/man1/kde-build.1 -%{tde_mandir}/man1/includemocs.1 -%{tde_mandir}/man1/noncvslist.1 -%{tde_mandir}/man1/[kt]desvn-build.1 -%{tde_tdedocdir}/HTML/en/[kt]desvn-build/ -#scripts/kde-devel-gdb /opt/trinity/share/tdesdk-scripts -#scripts/kde-devel-vim.vim /opt/trinity/share/tdesdk-scripts -#scripts/kde-emacs/*.el /opt/trinity/share/emacs/site-lisp/tdesdk-scripts -#scripts/kde.supp /opt/trinity/lib/valgrind -#scripts/completions /opt/trinity/share/tdesdk-scripts - -#debian/desktop-i18n/createdesktop.pl /opt/trinity/lib/kubuntu-desktop-i18n/ -#debian/desktop-i18n/findfiles /opt/trinity/lib/kubuntu-desktop-i18n/ -#debian/desktop-i18n/msgsplit /opt/trinity/lib/kubuntu-desktop-i18n/ - -%if "%{?tde_prefix}" != "/usr" -%{tde_bindir}/licensecheck -%else -%exclude %{tde_bindir}/licensecheck -%endif - -########## - -%package -n trinity-kmtrace -Summary: a Trinity memory leak tracer -Group: Development/Utilities -Requires: less - -%description -n trinity-kmtrace -KMtrace is a TDE tool to assist with malloc debugging using glibc's -"mtrace" functionality. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kmtrace -%{tde_bindir}/demangle -%{tde_bindir}/kminspector -%{tde_bindir}/kmmatch -%{tde_bindir}/kmtrace -#%{tde_tdeincludedir}/ktrace.h -%{tde_libdir}/kmtrace/libktrace.la -%{tde_libdir}/kmtrace/libktrace.so -%{tde_libdir}/libktrace_s.a -%{tde_datadir}/apps/kmtrace/kde.excludes - -########## - -%package -n trinity-kompare -Summary: a Trinity GUI for viewing differences between files -Group: Development/Utilities - -%description -n trinity-kompare -Kompare is a graphical user interface for viewing the differences between -files. It can compare two documents, create a diff file, display a diff -file and/or blend a diff file back into the original documents. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kompare -%{tde_bindir}/kompare -%{tde_libdir}/libkompareinterface.la -%{tde_libdir}/libkompareinterface.so -#%{tde_libdir}/libkompareinterface.so.* -%{tde_tdelibdir}/libkomparenavtreepart.la -%{tde_tdelibdir}/libkomparenavtreepart.so -%{tde_tdelibdir}/libkomparepart.la -%{tde_tdelibdir}/libkomparepart.so -%{tde_tdeappdir}/kompare.desktop -%{tde_datadir}/apps/kompare/komparepartui.rc -%{tde_datadir}/apps/kompare/kompareui.rc -%{tde_datadir}/services/komparenavtreepart.desktop -%{tde_datadir}/services/komparepart.desktop -%{tde_datadir}/servicetypes/komparenavigationpart.desktop -%{tde_datadir}/servicetypes/kompareviewpart.desktop -%{tde_datadir}/icons/hicolor/*/apps/kompare.png -%{tde_datadir}/icons/hicolor/scalable/apps/kompare.svgz -%{tde_tdedocdir}/HTML/en/kompare/ - -%post -n trinity-kompare -/sbin/ldconfig || : -for f in hicolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-kompare -/sbin/ldconfig || : -for f in hicolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package -n trinity-kspy -Summary: examines the internal state of a Qt/TDE app -Group: Environment/Libraries -Requires: trinity-tdelibs-devel - -%description -n trinity-kspy -KSpy is a tiny library which can be used to graphically display -the QObjects in use by a Qt/TDE app. In addition to the object tree, -you can also view the properties, signals and slots of any QObject. - -Basically it provides much the same info as QObject::dumpObjectTree() and -QObject::dumpObjectInfo(), but in a much more convenient form. KSpy has -minimal overhead for the application, because the kspy library is -loaded dynamically using KLibLoader. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kspy -%{tde_tdeincludedir}/kspy.h -%{tde_libdir}/libkspy.la -%{tde_libdir}/libkspy.so -%{tde_libdir}/libkspy.so.* - -%post -n trinity-kspy -/sbin/ldconfig || : - -%postun -n trinity-kspy -/sbin/ldconfig || : - -########## - -%package -n trinity-kuiviewer -Summary: viewer for Qt Designer user interface files -Group: Development/Utilities - -%description -n trinity-kuiviewer -KUIViewer is a utility to display and test the user interface (.ui) files -generated by Qt Designer. The interfaces can be displayed in a variety of -different widget styles. - -The Qt Designer itself is in the package qt3-designer. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kuiviewer -%{tde_bindir}/kuiviewer -%{tde_tdelibdir}/libkuiviewerpart.so -%{tde_tdelibdir}/libkuiviewerpart.la -%{tde_tdelibdir}/quithumbnail.so -%{tde_tdelibdir}/quithumbnail.la -%{tde_tdeappdir}/kuiviewer.desktop -%{tde_datadir}/apps/kuiviewer/kuiviewerui.rc -%{tde_datadir}/apps/kuiviewerpart/kuiviewer_part.rc -%{tde_datadir}/icons/hicolor/*/apps/kuiviewer.png -%{tde_datadir}/icons/locolor/*/apps/kuiviewer.png -%{tde_datadir}/services/designerthumbnail.desktop -%{tde_datadir}/services/kuiviewer_part.desktop - -%post -n trinity-kuiviewer -for f in hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done - -%postun -n trinity-kuiviewer -for f in crystalsvg hicolor locolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done - -########## - -%package -n trinity-libcvsservice0 -Summary: DCOP service for accessing CVS repositories -Group: Environment/Libraries -Requires: cvs - -%description -n trinity-libcvsservice0 -This library provides a DCOP service for accessing and working with -remote CVS repositories. Applications may link with this library to -access the DCOP service directly from C++. Alternatively, scripts may -access the service using the standard "dcop" command-line tool. - -DCOP is the Desktop Communication Protocol used throughout TDE. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-libcvsservice0 -%{tde_bindir}/cvsaskpass -%{tde_bindir}/cvsservice -%{tde_libdir}/libcvsservice.so.* -%{tde_libdir}/lib[kt]deinit_cvsaskpass.so -%{tde_libdir}/lib[kt]deinit_cvsservice.so -%{tde_tdelibdir}/cvsaskpass.la -%{tde_tdelibdir}/cvsaskpass.so -%{tde_tdelibdir}/cvsservice.la -%{tde_tdelibdir}/cvsservice.so -%{tde_datadir}/services/cvsservice.desktop - -%post -n trinity-libcvsservice0 -/sbin/ldconfig || : - -%postun -n trinity-libcvsservice0 -/sbin/ldconfig || : - -########## - -%package -n trinity-libcvsservice-devel -Summary: development files for CVS DCOP service -Group: Development/Libraries -Requires: trinity-libcvsservice0 = %{version}-%{release} - -%description -n trinity-libcvsservice-devel -The library libcvsservice provides a DCOP service for accessing and -working with remote CVS repositories. Applications may link with this -library to access the DCOP service directly from C++. Alternatively, -scripts may access the service using the standard "dcop" command-line -tool. - -Development files for libcvsservice are included in this package. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-libcvsservice-devel -%{tde_tdeincludedir}/cvsjob_stub.h -%{tde_tdeincludedir}/cvsservice_stub.h -%{tde_tdeincludedir}/repository_stub.h -%{tde_libdir}/libcvsservice.la -%{tde_libdir}/libcvsservice.so -%{tde_libdir}/lib[kt]deinit_cvsaskpass.la -%{tde_libdir}/lib[kt]deinit_cvsservice.la -%{tde_datadir}/cmake/cervisia.cmake - -%post -n trinity-libcvsservice-devel -/sbin/ldconfig || : - -%postun -n trinity-libcvsservice-devel -/sbin/ldconfig || : - -########## - -%package -n trinity-poxml -Summary: tools for using PO-files to translate DocBook XML files -Group: Development/Utilities - -%description -n trinity-poxml -This is a collection of tools that facilitate translating DocBook XML -files using gettext message files (PO-files). - -Also included are some miscellaneous command-line utilities for -manipulating DocBook XML files, PO-files and PO-template files. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-poxml -%{tde_bindir}/po2xml -%{tde_bindir}/split2po -%{tde_bindir}/swappo -%{tde_bindir}/transxx -%{tde_bindir}/xml2pot - -########## - -%package -n trinity-umbrello -Summary: UML modelling tool and code generator -Group: Development/Utilities - -%description -n trinity-umbrello -Umbrello UML Modeller is a Unified Modelling Language editor for TDE. -With UML you can create diagrams of software and other systems in an -industry standard format. Umbrello can also generate code from your -UML diagrams in a number of programming languages. - -The program supports class diagrams, sequence diagrams, collaboration -diagrams, use case diagrams, state diagrams, activity diagrams, component -diagrams and deployment diagrams. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-umbrello -%{tde_bindir}/umbodoc -%{tde_bindir}/umbrello -%{tde_tdeappdir}/umbrello.desktop -%{tde_datadir}/apps/umbrello/ -%{tde_datadir}/icons/crystalsvg/*/actions/umbrello_*.png -%{tde_datadir}/icons/crystalsvg/*/mimetypes/umbrellofile.png -%{tde_datadir}/icons/crystalsvg/scalable/mimetypes/umbrellofile.svgz -%{tde_datadir}/icons/hicolor/*/apps/umbrello.png -%{tde_datadir}/icons/hicolor/scalable/apps/umbrello.svgz -%{tde_datadir}/icons/hicolor/*/mimetypes/umbrellofile.png -%{tde_datadir}/mimelnk/application/x-umbrello.desktop -%{tde_tdedocdir}/HTML/en/umbrello/ - -%post -n trinity-umbrello -for f in crystalsvg hicolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -%postun -n trinity-umbrello -for f in crystalsvg hicolor ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done -update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || : - -########## - -%package kio-plugins -Summary: subversion ioslave for Trinity -Group: Environment/Libraries -Requires: subversion - -%description kio-plugins -This package provides easy access to remote SVN repositories from within -Konqueror, and TDE generally, by browsing them as if they were a -filesystem, using URLs like svn://hostname/path, or svn+ssh://, etc. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files kio-plugins -%{tde_bindir}/kio_svn_helper -%{tde_tdelibdir}/kded_ksvnd.la -%{tde_tdelibdir}/kded_ksvnd.so -%{tde_tdelibdir}/kio_svn.la -%{tde_tdelibdir}/kio_svn.so -%{tde_datadir}/apps/konqueror/servicemenus/subversion_toplevel.desktop -%{tde_datadir}/apps/konqueror/servicemenus/subversion.desktop -%{tde_datadir}/services/kded/ksvnd.desktop -%{tde_datadir}/services/svn+file.protocol_tdesdk -%{tde_datadir}/services/svn+http.protocol_tdesdk -%{tde_datadir}/services/svn+https.protocol_tdesdk -%{tde_datadir}/services/svn+ssh.protocol_tdesdk -%{tde_datadir}/services/svn.protocol_tdesdk -%{tde_datadir}/services/svn+file.protocol -%{tde_datadir}/services/svn+http.protocol -%{tde_datadir}/services/svn+https.protocol -%{tde_datadir}/services/svn+ssh.protocol -%{tde_datadir}/services/svn.protocol -%{tde_datadir}/icons/crystalsvg/*/actions/svn_switch.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_merge.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_branch.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_remove.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_add.png -%{tde_datadir}/icons/crystalsvg/*/actions/svn_status.png -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_add.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_status.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_remove.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_switch.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_branch.svgz -%{tde_datadir}/icons/crystalsvg/scalable/actions/svn_merge.svgz - -%post kio-plugins -for f in crystalsvg ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done - -for proto in svn+file svn+http svn+https svn+ssh svn; do - alternatives --install \ - %{tde_datadir}/services/${proto}.protocol \ - ${proto}.protocol \ - %{tde_datadir}/services/${proto}.protocol_tdesdk \ - 10 -done - -%postun kio-plugins -for f in crystalsvg ; do - touch --no-create %{_datadir}/icons/$f 2> /dev/null ||: - gtk-update-icon-cache -q %{_datadir}/icons/$f 2> /dev/null ||: -done - -%preun kio-plugins -if [ $1 -eq 0 ]; then - for proto in svn+file svn+http svn+https svn+ssh svn; do - alternatives --remove \ - ${proto}.protocol \ - %{tde_datadir}/services/${proto}.protocol_tdesdk - done -fi - -########## - -%package -n trinity-kunittest -Summary: unit testing library for Trinity -Group: Development/Utilities - -%description -n trinity-kunittest -KUnitTest is a small library that facilitates the writing of tests for -TDE developers. There are two ways to use the KUnitTest library. One is -to create dynamically loadable modules and use the kunittestmodrunner or -kunittestguimodrunner programs to run the tests. The other is to use the -libraries to create your own testing application. - -This package is part of Trinity, and a component of the TDE SDK module. - -%files -n trinity-kunittest -%{tde_bindir}/kunittest -%{tde_bindir}/kunittest_debughelper -%{tde_bindir}/kunittestmod -%{tde_bindir}/kunittestguimodrunner -%{tde_libdir}/libkunittestgui.la -%{tde_libdir}/libkunittestgui.so -#%{tde_libdir}/libkunittestgui.so.* -%{tde_tdeincludedir}/kunittest/runnergui.h - -%post -n trinity-kunittest -/sbin/ldconfig || : - -%postun -n trinity-kunittest -/sbin/ldconfig || : - -########## - -%package devel -Summary: Development files for %{name} -Group: Development/Libraries - -Requires: %{name} = %{version}-%{release} -Requires: trinity-kbabel-devel = %{version}-%{release} - -Obsoletes: trinity-kdesdk-devel < %{version}-%{release} -Provides: trinity-kdesdk-devel = %{version}-%{release} - -%description devel -%{summary}. - -%files devel - -########## - - -%prep -%setup -q -n kdesdk -%patch1 -p1 -b .subversion -%patch2 -p1 -b .cmake -%patch3 -p1 -b .cmake -%patch4 -p1 -b .ftbfs -%patch5 -p1 -b .svn - -%build -unset QTDIR || :; . /etc/profile.d/qt3.sh -export PATH="%{tde_bindir}:${PATH}" -export LD_LIBRARY_PATH="%{tde_libdir}" -export PKG_CONFIG_PATH="%{tde_libdir}/pkgconfig" -export CMAKE_INCLUDE_PATH="%{tde_includedir}:%{tde_includedir}/tqt" - -%if 0%{?rhel} || 0%{?fedora} -%__mkdir_p build -cd build -%endif - -%cmake \ - -DBIN_INSTALL_DIR=%{tde_bindir} \ - -DINCLUDE_INSTALL_DIR=%{tde_tdeincludedir} \ - -DLIB_INSTALL_DIR=%{tde_libdir} \ - -DMAN_INSTALL_DIR=%{tde_mandir}/man1 \ - -DPKGCONFIG_INSTALL_DIR=%{tde_tdelibdir}/pkgconfig \ - -DSHARE_INSTALL_PREFIX=%{tde_datadir} \ - -DCMAKE_SKIP_RPATH="OFF" \ - -DWITH_DBSEARCHENGINE=ON \ - -DWITH_KCAL=ON \ - -DBUILD_ALL=ON \ - .. - -%__make %{?_smp_mflags} - - -%install -export PATH="%{tde_bindir}:${PATH}" -%__rm -rf %{buildroot} - -%__make install DESTDIR=%{?buildroot} -C build - -# make symlinks relative -if [ -d %{buildroot}%{tde_tdedocdir}/HTML/en ]; then - pushd %{buildroot}%{tde_tdedocdir}/HTML/en - for i in *; do - if [ -d $i -a -L $i/common ]; then - rm -f $i/common - ln -nfs ../common $i - fi - done - popd -fi - -# Installs kdepalettes -%__install -D -m 644 kdepalettes/kde_xpaintrc %{?buildroot}%{tde_datadir}/kdepalettes -%__install -D -m 644 kdepalettes/KDE_Gimp %{?buildroot}%{tde_datadir}/kdepalettes -%__install -D -m 644 kdepalettes/README %{?buildroot}%{tde_datadir}/kdepalettes - -# Installs SVN protocols as alternatives -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+file.protocol %{?buildroot}%{tde_datadir}/services/svn+file.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+http.protocol %{?buildroot}%{tde_datadir}/services/svn+http.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+https.protocol %{?buildroot}%{tde_datadir}/services/svn+https.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn+ssh.protocol %{?buildroot}%{tde_datadir}/services/svn+ssh.protocol_tdesdk -%__mv -f %{?buildroot}%{tde_datadir}/services/svn.protocol %{?buildroot}%{tde_datadir}/services/svn.protocol_tdesdk -%__ln_s /etc/alternatives/svn+file.protocol %{?buildroot}%{tde_datadir}/services/svn+file.protocol -%__ln_s /etc/alternatives/svn+http.protocol %{?buildroot}%{tde_datadir}/services/svn+http.protocol -%__ln_s /etc/alternatives/svn+https.protocol %{?buildroot}%{tde_datadir}/services/svn+https.protocol -%__ln_s /etc/alternatives/svn+ssh.protocol %{?buildroot}%{tde_datadir}/services/svn+ssh.protocol -%__ln_s /etc/alternatives/svn.protocol %{?buildroot}%{tde_datadir}/services/svn.protocol - -%clean -%__rm -rf %{buildroot} - - -# trick to replace a dir by a symlink -- Rex -%pre -if [ $1 -gt 0 -a ! -L %{_docdir}/HTML/en/cervisia/common ]; then - rm -rf %{tde_tdedocdir}/HTML/en/cervisia/common ||: -fi - - - -%changelog -* Sun Jul 30 2012 Francois Andriot - 3.5.13-2 -- Split into several packages -- Renames to 'trinity-tdesdk' -- Add Mageia 2 support -- cmake port [Commit #bfb0bc00] -- added forgotten files [Commit #adee843c] -- installs SVN protocols as alternative to avoid conflict with kdesvn - -* Sun Oct 30 2011 Francois Andriot - 3.5.13-1 -- Initial release for RHEL 6, RHEL 5 and Fedora 15 - -* Mon Sep 05 2011 Francois Andriot - 3.5.13-0 -- Import to GIT diff --git a/redhat/main/tdesdk/kdesdk-3.5.7-subversion.patch b/redhat/main/tdesdk/kdesdk-3.5.7-subversion.patch deleted file mode 100644 index 4c3470e6d..000000000 --- a/redhat/main/tdesdk/kdesdk-3.5.7-subversion.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -up kdesdk-3.5.7/kioslave/svn/configure.in.in.svn kdesdk-3.5.7/kioslave/svn/configure.in.in ---- kdesdk-3.5.7/kioslave/svn/configure.in.in.svn 2005-10-10 09:58:25.000000000 -0500 -+++ kdesdk-3.5.7/kioslave/svn/configure.in.in 2007-09-12 09:39:42.000000000 -0500 -@@ -86,7 +86,7 @@ fi - AC_SUBST(SVNCONFIG) - if test -x "$SVNCONFIG"; then - SVNLD="`$SVNCONFIG --ldflags`" -- SVN_LIB="`$SVNCONFIG --libs` -lsvn_client-1" -+ SVN_LIB="`$SVNCONFIG --libs` -lsvn_client-1 -lsvn_subr-1" - SVN_CPPFLAGS="`$SVNCONFIG --cppflags`" - dnl ugly hack for subversion svn-config problems in 0.14.x, to be removed when svn-config is fixed - SVN_INCLUDE="`$SVNCONFIG --includes` -I$_SVNCONFIG/include/subversion-1/" -@@ -141,7 +141,7 @@ dnl AC_MSG_ERROR([Subversion headers ar - SVN_SUBDIR= - fi - fi --SVN_LIB="$SVN_LIB $APR_LIBS -lsvn_client-1" -+SVN_LIB="$SVN_LIB $APR_LIBS -lsvn_client-1 -lsvn_subr-1" - SVN_INCLUDE="$SVN_INCLUDE $APR_INCLUDE" - SVN_CPPFLAGS="$APR_CPPFLAGS $SVN_CPPFLAGS" - diff --git a/redhat/main/tdesdk/tdesdk-14.0.0.spec b/redhat/main/tdesdk/tdesdk-14.0.0.spec index 8e97c70b0..acec51c30 100644 --- a/redhat/main/tdesdk/tdesdk-14.0.0.spec +++ b/redhat/main/tdesdk/tdesdk-14.0.0.spec @@ -1,47 +1,75 @@ -# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt". -%if "%{?tde_prefix}" != "/usr" -%define _variant .opt -%endif - +# +# spec file for package tdenetwork (version R14.0.0) +# +# Copyright (c) 2014 Trinity Desktop Environment +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. +# +# Please submit bugfixes or comments via http:/www.trinitydesktop.org/ +# + +# BUILD WARNING: +# Remove qt-devel and qt3-devel and any kde*-devel on your system ! +# Having KDE libraries may cause FTBFS here ! + +# TDE variables +%define tde_epoch 2 %define tde_version 14.0.0 - -# TDE specific building variables +%define tde_pkg tdenetwork +%define tde_prefix /opt/trinity %define tde_bindir %{tde_prefix}/bin %define tde_datadir %{tde_prefix}/share %define tde_docdir %{tde_datadir}/doc %define tde_includedir %{tde_prefix}/include %define tde_libdir %{tde_prefix}/%{_lib} %define tde_mandir %{tde_datadir}/man - %define tde_tdeappdir %{tde_datadir}/applications/tde %define tde_tdedocdir %{tde_docdir}/tde %define tde_tdeincludedir %{tde_includedir}/tde %define tde_tdelibdir %{tde_libdir}/trinity +# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt". +%if "%{?tde_prefix}" != "/usr" +%define _variant .opt +%endif + -Name: trinity-tdesdk +Name: trinity-%{tde_pkg} Summary: The Trinity Software Development Kit (SDK) +Group: User Interface/Desktops Version: %{tde_version} Release: %{?!preversion:1}%{?preversion:0_%{preversion}}%{?dist}%{?_variant} - -License: GPLv2 -Group: User Interface/Desktops URL: http://www.trinitydesktop.org/ -Vendor: Trinity Project -Packager: Francois Andriot + +%if 0%{?suse_version} +License: GPL-2.0+ +%else +License: GPLv2+ +%endif + +#Vendor: Trinity Desktop +#Packager: Francois Andriot Prefix: %{tde_prefix} BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: %{name}-%{version}%{?preversion:~%{preversion}}.tar.gz +BuildRequires: trinity-tdelibs-devel >= %{tde_version} +BuildRequires: trinity-perl-dcop >= {tde_version} BuildRequires: cmake >= 2.8 +BuildRequires: gcc-c++ BuildRequires: libtool + +# PCRE support BuildRequires: pcre-devel -BuildRequires: trinity-tqtinterface-devel >= %{tde_version} -BuildRequires: trinity-tdelibs-devel >= %{tde_version} -BuildRequires: trinity-perl-dcop >= %{tde_version} # for kbugbuster/libkcal BuildRequires: trinity-tdepim-devel >= %{tde_version} BuildRequires: desktop-file-utils -- cgit v1.2.3