diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-01-30 20:20:24 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-01-30 20:20:24 -0600 |
commit | cfccedd9c8db3af36d7c5635ca212fa170bb6ff5 (patch) | |
tree | c80df038c9b6e40b4e28c26203de0dd9b1cd1593 /kcachegrind | |
parent | 2020f146a7175288d0aaf15cd91b95e545bbb915 (diff) | |
download | tdesdk-cfccedd9c8db3af36d7c5635ca212fa170bb6ff5.tar.gz tdesdk-cfccedd9c8db3af36d7c5635ca212fa170bb6ff5.zip |
Part 2 of prior commit
Diffstat (limited to 'kcachegrind')
125 files changed, 0 insertions, 38950 deletions
diff --git a/kcachegrind/AUTHORS b/kcachegrind/AUTHORS deleted file mode 100644 index ded6005d..00000000 --- a/kcachegrind/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Josef Weidendorfer <Josef.Weidendorfer@gmx.de> diff --git a/kcachegrind/COPYING b/kcachegrind/COPYING deleted file mode 100644 index c13faf0d..00000000 --- a/kcachegrind/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - 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. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - 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. - - <signature of Ty Coon>, 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/kcachegrind/ChangeLog b/kcachegrind/ChangeLog deleted file mode 100644 index 05f3081e..00000000 --- a/kcachegrind/ChangeLog +++ /dev/null @@ -1,89 +0,0 @@ -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, tdecachegrindui.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/kcachegrind/INSTALL b/kcachegrind/INSTALL deleted file mode 100644 index 02a4a074..00000000 --- a/kcachegrind/INSTALL +++ /dev/null @@ -1,167 +0,0 @@ -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/kcachegrind/Makefile.am b/kcachegrind/Makefile.am deleted file mode 100644 index e93f6afc..00000000 --- a/kcachegrind/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = tdecachegrind pics converters - -EXTRA_DIST = \ - AUTHORS COPYING NEWS ChangeLog INSTALL README TODO \ - tdecachegrind.lsm tdecachegrind.spec version.h - diff --git a/kcachegrind/NEWS b/kcachegrind/NEWS deleted file mode 100644 index e69de29b..00000000 --- a/kcachegrind/NEWS +++ /dev/null diff --git a/kcachegrind/README b/kcachegrind/README deleted file mode 100644 index 0866eb82..00000000 --- a/kcachegrind/README +++ /dev/null @@ -1,62 +0,0 @@ -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=<KDE base directory> - 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://tdecachegrind.sourceforge.net/cgi-bin/show.cgi ) - - - -Happy Profiling, - Josef Weidendorfer diff --git a/kcachegrind/TODO b/kcachegrind/TODO deleted file mode 100644 index 1eca67ed..00000000 --- a/kcachegrind/TODO +++ /dev/null @@ -1,100 +0,0 @@ -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/kcachegrind/configure.in.in b/kcachegrind/configure.in.in deleted file mode 100644 index dfc85085..00000000 --- a/kcachegrind/configure.in.in +++ /dev/null @@ -1,8 +0,0 @@ -TDECACHEGRIND_VERSION=0.4.6kde -AC_SUBST(TDECACHEGRIND_VERSION) - -AC_FUNC_MMAP - -dnl AC_OUTPUT( tdecachegrind/version.h ) -dnl AC_OUTPUT( tdecachegrind/tdecachegrind.spec ) -dnl AC_OUTPUT( tdecachegrind/tdecachegrind.lsm ) diff --git a/kcachegrind/converters/Makefile.am b/kcachegrind/converters/Makefile.am deleted file mode 100644 index 08b3696b..00000000 --- a/kcachegrind/converters/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -bin_SCRIPTS = hotshot2calltree op2calltree pprof2calltree dprof2calltree \ - memprof2calltree diff --git a/kcachegrind/converters/README b/kcachegrind/converters/README deleted file mode 100644 index c27d3c6d..00000000 --- a/kcachegrind/converters/README +++ /dev/null @@ -1,24 +0,0 @@ -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 <george@omniti.com> for - dprof2calltree and pprof2calltree, -* Jrg Beyer <job@webde-ag.de> for - hotshot2calltree - -If you want to write a converter, have a look at the calltree format -description on the web site (tdecachegrind.sf.net). - -Josef - diff --git a/kcachegrind/converters/dprof2calltree b/kcachegrind/converters/dprof2calltree deleted file mode 100644 index f276e188..00000000 --- a/kcachegrind/converters/dprof2calltree +++ /dev/null @@ -1,199 +0,0 @@ -#!/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 <george@omniti.com> -# 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 tdecachegrind 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 tdecachegrind 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 <tmon.out> [-o outfile]\n"; - exit -1; -} - - -# vim: set sts=2 ts=2 bs ai expandtab : diff --git a/kcachegrind/converters/hotshot2calltree b/kcachegrind/converters/hotshot2calltree deleted file mode 100644 index f62a46e3..00000000 --- a/kcachegrind/converters/hotshot2calltree +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/env python -# _*_ coding: latin1 _*_ - -# -# Copyright (c) 2003 by WEB.DE, Karlsruhe -# Autor: Jrg Beyer <job@webde-ag.de> -# -# 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 tdecachegrind. -# -# 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 <output> <input> -# or here: -# hotshot2cachegrind cachegrind.out.0 pythongrind.prof -# -# then call tdecachegrind: -# tdecachegrind 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 bercksichtigt, -# 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 tdecachegrind - 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 tdecachegrind - 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 tdecachegrind - 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 tdecachegrind, 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/kcachegrind/converters/memprof2calltree b/kcachegrind/converters/memprof2calltree deleted file mode 100755 index e82d6e85..00000000 --- a/kcachegrind/converters/memprof2calltree +++ /dev/null @@ -1,38 +0,0 @@ -#!/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/kcachegrind/converters/op2calltree b/kcachegrind/converters/op2calltree deleted file mode 100755 index ca121a2a..00000000 --- a/kcachegrind/converters/op2calltree +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) 2004 -# Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de> -# -# 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/kcachegrind/converters/pprof2calltree b/kcachegrind/converters/pprof2calltree deleted file mode 100644 index 0e70e1c2..00000000 --- a/kcachegrind/converters/pprof2calltree +++ /dev/null @@ -1,218 +0,0 @@ -#!/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 <george@omniti.com> -# 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 tdecachegrind. 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 - -<?php - -require "Console/Getopt.php"; - -$con = new Console_Getopt; -$args = $con->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 tdecachegrind compatible output to $outfile\n"; -fwrite($OUT, $buffer); - -function usage() -{ - print <<<EOD -pprof2calltree -f <tracefile> - -EOD; - exit(1); -} -?> diff --git a/kcachegrind/kcachegrind.lsm.in b/kcachegrind/kcachegrind.lsm.in deleted file mode 100644 index fab7ceda..00000000 --- a/kcachegrind/kcachegrind.lsm.in +++ /dev/null @@ -1,11 +0,0 @@ -Begin3 -Title: tdecachegrind -Version: @TDECACHEGRIND_VERSION@ -Description: KDE Profiling Visualisation Tool -Keywords: Profiling, Performance Analysis, Visualisation, Development -Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de> -Maintained-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de> -Home-page: http://tdecachegrind.sourceforge.net -Platforms: Linux and other Unices -Copying-policy: GNU Public License -End diff --git a/kcachegrind/kcachegrind.spec.in b/kcachegrind/kcachegrind.spec.in deleted file mode 100644 index 42b3e24e..00000000 --- a/kcachegrind/kcachegrind.spec.in +++ /dev/null @@ -1,55 +0,0 @@ -Summary: KDE Profiling Visualisation Tool -Name: tdecachegrind -Version: @TDECACHEGRIND_VERSION@ -Release: 1 -Copyright: GPL -Group: Development/Tools -Vendor: (none) -URL: http://tdecachegrind.sourceforge.net -Packager: Josef Weidendorfer <Josef.Weidendorfer@gmx.de> -Source: tdecachegrind-@TDECACHEGRIND_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.tdecachegrind -find . -type f | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.tdecachegrind -find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.tdecachegrind - -%clean -rm -rf $RPM_BUILD_ROOT/* -rm -rf $RPM_BUILD_DIR/tdecachegrind -rm -rf ../file.list.tdecachegrind - - -%files -f ../file.list.tdecachegrind diff --git a/kcachegrind/kcachegrind/Doxyfile b/kcachegrind/kcachegrind/Doxyfile deleted file mode 100644 index 9d5d0501..00000000 --- a/kcachegrind/kcachegrind/Doxyfile +++ /dev/null @@ -1,157 +0,0 @@ -# Doxygen configuration generated by Doxywizard version 0.1 -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = tdecachegrind -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/kcachegrind/kcachegrind/Makefile.am b/kcachegrind/kcachegrind/Makefile.am deleted file mode 100644 index 53cd35d8..00000000 --- a/kcachegrind/kcachegrind/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -bin_PROGRAMS = tdecachegrind - -tdecachegrind_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 - -tdecachegrind_COMPILE_FIRST = ../version.h - -tdecachegrind_LDADD = $(LIB_KIO) - -KDE_ICON = AUTO - -xdg_apps_DATA = tdecachegrind.desktop - -mimeapplicationdir = $(kde_mimedir)/application -mimeapplication_DATA = x-tdecachegrind.desktop - -EXTRA_DIST = \ - tdecachegrind.desktop \ - x-tdecachegrind.desktop \ - hi32-app-tdecachegrind.png \ - hi48-app-tdecachegrind.png \ - Doxyfile \ - tdecachegrindui.rc - -# set the include path for X, qt and KDE -INCLUDES= $(all_includes) - -METASOURCES = AUTO - -# the library search path. -tdecachegrind_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor - -rcdir = $(kde_datadir)/tdecachegrind -rc_DATA = tdecachegrindui.rc - -tipdir = $(kde_datadir)/tdecachegrind -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)/tdecachegrind.pot; \ - fi - rm -f tips.txt - diff --git a/kcachegrind/kcachegrind/cachegrindloader.cpp b/kcachegrind/kcachegrind/cachegrindloader.cpp deleted file mode 100644 index 4fe57d34..00000000 --- a/kcachegrind/kcachegrind/cachegrindloader.cpp +++ /dev/null @@ -1,1323 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <errno.h> - -#include <tqfile.h> -#include <tqcstring.h> - -#include <klocale.h> -#include <kdebug.h> - -#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 - * "(<Integer>) Name": this is a compression specification, - * mapping the integer number to Name and using Name. - * "(<Integer>)" : 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<TraceCostItem> _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:<name>[=<formula>][:<long name>] - 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 <line> 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 <line> 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/kcachegrind/kcachegrind/callgraphview.cpp b/kcachegrind/kcachegrind/callgraphview.cpp deleted file mode 100644 index bc01da8b..00000000 --- a/kcachegrind/kcachegrind/callgraphview.cpp +++ /dev/null @@ -1,2734 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <stdlib.h> -#include <math.h> - -#include <tqtooltip.h> -#include <tqfile.h> -#include <tqtextstream.h> -#include <tqwhatsthis.h> -#include <tqcanvas.h> -#include <tqwmatrix.h> -#include <tqpair.h> -#include <tqpainter.h> -#include <tqpopupmenu.h> -#include <tqstyle.h> -#include <tqprocess.h> - -#include <kdebug.h> -#include <klocale.h> -#include <kconfig.h> -#include <ktempfile.h> -#include <kapplication.h> -#include <kiconloader.h> -#include <kfiledialog.h> - -#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<TraceFunction*,TraceFunction*> 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<TraceCostItem*,TQPtrList<GraphNode> > 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<TraceCostItem*,TQPtrList<GraphNode> >::Iterator lit; - int cluster = 0; - for ( lit = nLists.begin(); - lit != nLists.end(); ++lit, cluster++ ) { - TQPtrList<GraphNode>& 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<TraceFunction*,TraceFunction*> 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<TraceFunction*,TraceFunction*> 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<TraceFunction*,TraceFunction*> 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<TraceFunction*,TraceFunction*> 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<len;i++) { - if (poly[i].x() < minX) minX = poly[i].x(); - if (poly[i].y() < minY) minY = poly[i].y(); - if (poly[i].x() > 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;i<len;i++) - a[2 * len - 1 -i] = b[i]; - - if (0) { - qDebug(" Result:"); - for (i=0;i<2*len;i++) - qDebug(" P %d: %d/%d", i, a[i].x(), a[i].y()); - } - - return a; -} - -void CanvasEdge::drawShape(TQPainter& p) -{ - if (isSelected()) p.setPen(TQt::red); - - p.drawPolyline(poly); -} - - -// -// CanvasFrame -// - -TQPixmap* CanvasFrame::_p = 0; - -CanvasFrame::CanvasFrame(CanvasNode* n, TQCanvas* c) - : TQCanvasRectangle(c) -{ - if (!_p) { - - int d = 5; - float v1 = 130.0, v2 = 10.0, v = v1, f = 1.03; - - // calculate pix size - TQRect r(0, 0, 30, 30); - while (v>v2) { - 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 (v<v1) { - v *= f; - p.setBrush(TQColor(265-(int)v, 265-(int)v, 265-(int)v)); - - p.drawRect(TQRect(r.x(), r.y(), r.width(), d)); - p.drawRect(TQRect(r.x(), r.bottom()-d, r.width(), d)); - p.drawRect(TQRect(r.x(), r.y()+d, d, r.height()-2*d)); - p.drawRect(TQRect(r.right()-d, r.y()+d, d, r.height()-2*d)); - - r.setRect(r.x()+d, r.y()+d, r.width()-2*d, r.height()-2*d); - } - } - - setSize(_p->width(), _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( "<b>Call Graph around active Function</b>" - "<p>Depending on configuration, this view shows " - "the call graph environment of the active function. " - "Note: the shown cost is <b>only</b> 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.</p>" - "<p>For cycles, blue call arrows indicate that this is an " - "artificial call added for correct drawing which " - "actually never happened.</p>" - "<p>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.<p>"); -} - -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<points;i++) { - if (lineStream.atEnd()) break; - 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(" 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() && (indexHead<points-2)) { - indexHead++; - arrowDir = pa.point(indexHead) - pa.point(indexHead+1); - } - } - } - - if (arrowDir.isNull()) { - indexHead = points; - // sometimes the last spline points from dot are the same... - while(arrowDir.isNull() && (indexHead>1)) { - 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/kcachegrind/kcachegrind/callgraphview.h b/kcachegrind/kcachegrind/callgraphview.h deleted file mode 100644 index 4db619db..00000000 --- a/kcachegrind/kcachegrind/callgraphview.h +++ /dev/null @@ -1,501 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqcanvas.h> -#include <tqwidget.h> -#include <tqmap.h> -#include <tqtimer.h> - -#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<GraphEdge> -{ - public: - GraphEdgeList(); - void setSortCallerPos(bool b) { _sortCallerPos = b; } - - protected: - int compareItems ( Item item1, Item item2 ); - - private: - bool _sortCallerPos; -}; - - -typedef TQMap<GraphEdge*, int> 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<TraceFunction*, GraphNode> GraphNodeMap; -typedef TQMap<TQPair<TraceFunction*, TraceFunction*>, 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 - - /* <toFunc> 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/kcachegrind/kcachegrind/callitem.cpp b/kcachegrind/kcachegrind/callitem.cpp deleted file mode 100644 index ebca4903..00000000 --- a/kcachegrind/kcachegrind/callitem.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <klocale.h> -#include <kapplication.h> -#include <kiconloader.h> - -#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/kcachegrind/kcachegrind/callitem.h b/kcachegrind/kcachegrind/callitem.h deleted file mode 100644 index 94191b8f..00000000 --- a/kcachegrind/kcachegrind/callitem.h +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/callmapview.cpp b/kcachegrind/kcachegrind/callmapview.cpp deleted file mode 100644 index 0e4d5e38..00000000 --- a/kcachegrind/kcachegrind/callmapview.cpp +++ /dev/null @@ -1,999 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqwhatsthis.h> -#include <tqpopupmenu.h> - -#include <klocale.h> -#include <kiconloader.h> -#include <kapplication.h> -#include <kconfig.h> - -#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( "<b>Caller Map</b>" - "<p>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).</p>") : - i18n("<b>Call Map</b>" - "<p>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).</p>"); - - s += i18n( "<p>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 " - "<em>very</em> 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 <em>before</em> drawing children. Note that " - "size proportions can get <em>heavily</em> wrong.</p>" - - "<p>This is a <em>TreeMap</em> 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. " - "<em>Return</em> activates the current item.</p>"); - - 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 (count<Configuration::maxSymbolCount() && item) { - TQString name = item->text(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 (count<Configuration::maxSymbolCount() && item) { - TQString name = item->text(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 && count<Configuration::maxSymbolCount()) { - 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()) 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/kcachegrind/kcachegrind/callmapview.h b/kcachegrind/kcachegrind/callmapview.h deleted file mode 100644 index 860743fe..00000000 --- a/kcachegrind/kcachegrind/callmapview.h +++ /dev/null @@ -1,130 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/callview.cpp b/kcachegrind/kcachegrind/callview.cpp deleted file mode 100644 index 317d137b..00000000 --- a/kcachegrind/kcachegrind/callview.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqwhatsthis.h> -#include <tqpopupmenu.h> -#include <klocale.h> - -#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( "<b>List of direct Callers</b>" - "<p>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.</p>" - "<p>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.</p>" - "<p>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.</p>") : - i18n( "<b>List of direct Callees</b>" - "<p>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.</p>" - "<p>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.</p>"); -} - - -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/kcachegrind/kcachegrind/callview.h b/kcachegrind/kcachegrind/callview.h deleted file mode 100644 index be644f97..00000000 --- a/kcachegrind/kcachegrind/callview.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/configdlg.cpp b/kcachegrind/kcachegrind/configdlg.cpp deleted file mode 100644 index e0b45470..00000000 --- a/kcachegrind/kcachegrind/configdlg.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqcombobox.h> -#include <tqcheckbox.h> -#include <tqlineedit.h> -#include <tqlistview.h> -#include <tqdict.h> -#include <tqmessagebox.h> - -#include <kcolorbutton.h> -#include <kfiledialog.h> -#include <klocale.h> -#include <knumvalidator.h> - -#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<Configuration::ColorSetting> 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/kcachegrind/kcachegrind/configdlg.h b/kcachegrind/kcachegrind/configdlg.h deleted file mode 100644 index 5ef6bab0..00000000 --- a/kcachegrind/kcachegrind/configdlg.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/configdlgbase.ui b/kcachegrind/kcachegrind/configdlgbase.ui deleted file mode 100644 index dc0ee9ec..00000000 --- a/kcachegrind/kcachegrind/configdlgbase.ui +++ /dev/null @@ -1,653 +0,0 @@ -<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> -<class>ConfigDlgBase</class> -<widget class="TQDialog"> - <property name="name"> - <cstring>configDlgBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>447</width> - <height>378</height> - </rect> - </property> - <property name="caption"> - <string>Configuration</string> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>11</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <widget class="TQTabWidget"> - <property name="name"> - <cstring>tabWidget2</cstring> - </property> - <widget class="TQWidget"> - <property name="name"> - <cstring>tab</cstring> - </property> - <attribute name="title"> - <string>General</string> - </attribute> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout10</cstring> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLineEdit" row="3" column="2" rowspan="1" colspan="2"> - <property name="name"> - <cstring>precisionEdit</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>2</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - <widget class="TQLabel" row="2" column="1"> - <property name="name"> - <cstring>TextLabel2</cstring> - </property> - <property name="text"> - <string>Truncated when more/longer than:</string> - </property> - </widget> - <widget class="TQLabel" row="3" column="0" rowspan="1" colspan="2"> - <property name="name"> - <cstring>TextLabel4_3</cstring> - </property> - <property name="text"> - <string>Precision of percentage values:</string> - </property> - </widget> - <widget class="TQLabel" row="1" column="0" rowspan="1" colspan="3"> - <property name="name"> - <cstring>TextLabel3</cstring> - </property> - <property name="text"> - <string>Symbols in tooltips and context menus</string> - </property> - </widget> - <widget class="TQLineEdit" row="2" column="3"> - <property name="name"> - <cstring>symbolLength</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>4</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - <spacer row="2" column="0"> - <property name="name"> - <cstring>Spacer6_2_2_2</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Fixed</enum> - </property> - <property name="sizeHint"> - <size> - <width>16</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQLineEdit" row="0" column="2" rowspan="1" colspan="2"> - <property name="name"> - <cstring>maxListEdit</cstring> - </property> - </widget> - <widget class="TQLineEdit" row="2" column="2"> - <property name="name"> - <cstring>symbolCount</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>4</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - <widget class="TQLabel" row="0" column="0" rowspan="1" colspan="2"> - <property name="name"> - <cstring>TextLabel5</cstring> - </property> - <property name="text"> - <string>Maximum number of items in lists:</string> - </property> - </widget> - </grid> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>TextLabel1</cstring> - </property> - <property name="font"> - <font> - <bold>1</bold> - </font> - </property> - <property name="frameShape"> - <enum>NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>Plain</enum> - </property> - <property name="text"> - <string>Cost Item Colors</string> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>Layout9</cstring> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>0</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <spacer row="1" column="1"> - <property name="name"> - <cstring>Spacer9</cstring> - </property> - <property name="orientation"> - <enum>Vertical</enum> - </property> - <property name="sizeType"> - <enum>Fixed</enum> - </property> - <property name="sizeHint"> - <size> - <width>20</width> - <height>16</height> - </size> - </property> - </spacer> - <spacer row="0" column="0"> - <property name="name"> - <cstring>Spacer6</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Fixed</enum> - </property> - <property name="sizeHint"> - <size> - <width>16</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQLayoutWidget" row="0" column="1"> - <property name="name"> - <cstring>Layout9</cstring> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>0</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <widget class="TQComboBox" row="1" column="1"> - <property name="name"> - <cstring>classCombo</cstring> - </property> - <property name="maximumSize"> - <size> - <width>300</width> - <height>32767</height> - </size> - </property> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - <widget class="TQCheckBox" row="2" column="2"> - <property name="name"> - <cstring>fileCheck</cstring> - </property> - <property name="text"> - <string>Automatic</string> - </property> - </widget> - <widget class="TQLabel" row="0" column="0"> - <property name="name"> - <cstring>TextLabel4</cstring> - </property> - <property name="text"> - <string>Object:</string> - </property> - </widget> - <widget class="TQLabel" row="1" column="0"> - <property name="name"> - <cstring>TextLabel4_2_2</cstring> - </property> - <property name="text"> - <string>Class:</string> - </property> - </widget> - <widget class="KColorButton" row="2" column="3"> - <property name="name"> - <cstring>fileColor</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string></string> - </property> - </widget> - <widget class="TQCheckBox" row="1" column="2"> - <property name="name"> - <cstring>classCheck</cstring> - </property> - <property name="text"> - <string>Automatic</string> - </property> - </widget> - <widget class="KColorButton" row="0" column="3"> - <property name="name"> - <cstring>objectColor</cstring> - </property> - <property name="text"> - <string></string> - </property> - </widget> - <widget class="TQCheckBox" row="0" column="2"> - <property name="name"> - <cstring>objectCheck</cstring> - </property> - <property name="text"> - <string>Automatic</string> - </property> - </widget> - <widget class="TQLabel" row="2" column="0"> - <property name="name"> - <cstring>TextLabel4_2</cstring> - </property> - <property name="text"> - <string>File:</string> - </property> - </widget> - <widget class="KColorButton" row="1" column="3"> - <property name="name"> - <cstring>classColor</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string></string> - </property> - </widget> - <widget class="TQComboBox" row="2" column="1"> - <property name="name"> - <cstring>fileCombo</cstring> - </property> - <property name="maximumSize"> - <size> - <width>300</width> - <height>32767</height> - </size> - </property> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - <widget class="TQComboBox" row="0" column="1"> - <property name="name"> - <cstring>objectCombo</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>3</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>300</width> - <height>32767</height> - </size> - </property> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - </grid> - </widget> - </grid> - </widget> - </vbox> - </widget> - <widget class="TQWidget"> - <property name="name"> - <cstring>tab</cstring> - </property> - <attribute name="title"> - <string>Annotations</string> - </attribute> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout8</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLabel"> - <property name="name"> - <cstring>TextLabel4_3_2</cstring> - </property> - <property name="text"> - <string>Context lines in annotations:</string> - </property> - </widget> - <widget class="TQLineEdit"> - <property name="name"> - <cstring>contextEdit</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>2</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </hbox> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>TextLabel1_2</cstring> - </property> - <property name="font"> - <font> - <bold>1</bold> - </font> - </property> - <property name="text"> - <string>Source Folders</string> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout11</cstring> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <spacer row="0" column="0"> - <property name="name"> - <cstring>Spacer6_2</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Fixed</enum> - </property> - <property name="sizeHint"> - <size> - <width>16</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQListView" row="0" column="1"> - <column> - <property name="text"> - <string>Object / Related Source Base</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>dirList</cstring> - </property> - <property name="rootIsDecorated"> - <bool>true</bool> - </property> - </widget> - <widget class="TQLayoutWidget" row="0" column="2"> - <property name="name"> - <cstring>layout10</cstring> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQPushButton"> - <property name="name"> - <cstring>addDirButton</cstring> - </property> - <property name="text"> - <string>Add...</string> - </property> - </widget> - <spacer> - <property name="name"> - <cstring>Spacer5</cstring> - </property> - <property name="orientation"> - <enum>Vertical</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>16</width> - <height>49</height> - </size> - </property> - </spacer> - <widget class="TQPushButton"> - <property name="name"> - <cstring>deleteDirButton</cstring> - </property> - <property name="text"> - <string>Delete</string> - </property> - </widget> - </vbox> - </widget> - <spacer row="1" column="1"> - <property name="name"> - <cstring>Spacer9_2</cstring> - </property> - <property name="orientation"> - <enum>Vertical</enum> - </property> - <property name="sizeType"> - <enum>Fixed</enum> - </property> - <property name="sizeHint"> - <size> - <width>20</width> - <height>16</height> - </size> - </property> - </spacer> - </grid> - </widget> - </vbox> - </widget> - </widget> - <widget class="Line"> - <property name="name"> - <cstring>Line1</cstring> - </property> - <property name="frameShape"> - <enum>HLine</enum> - </property> - <property name="frameShadow"> - <enum>Sunken</enum> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>Layout4</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>0</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <spacer> - <property name="name"> - <cstring>Spacer2</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>210</width> - <height>0</height> - </size> - </property> - </spacer> - <widget class="TQPushButton"> - <property name="name"> - <cstring>PushButton2</cstring> - </property> - <property name="text"> - <string>&OK</string> - </property> - <property name="default"> - <bool>true</bool> - </property> - </widget> - <widget class="TQPushButton"> - <property name="name"> - <cstring>PushButton1</cstring> - </property> - <property name="text"> - <string>&Cancel</string> - </property> - </widget> - </hbox> - </widget> - </vbox> -</widget> -<connections> - <connection> - <sender>PushButton2</sender> - <signal>clicked()</signal> - <receiver>configDlgBase</receiver> - <slot>accept()</slot> - </connection> - <connection> - <sender>PushButton1</sender> - <signal>clicked()</signal> - <receiver>configDlgBase</receiver> - <slot>reject()</slot> - </connection> - <connection> - <sender>classCheck</sender> - <signal>toggled(bool)</signal> - <receiver>classColor</receiver> - <slot>setDisabled(bool)</slot> - </connection> - <connection> - <sender>fileCheck</sender> - <signal>toggled(bool)</signal> - <receiver>fileColor</receiver> - <slot>setDisabled(bool)</slot> - </connection> - <connection> - <sender>objectCheck</sender> - <signal>toggled(bool)</signal> - <receiver>objectColor</receiver> - <slot>setDisabled(bool)</slot> - </connection> -</connections> -<tabstops> - <tabstop>objectCombo</tabstop> - <tabstop>objectCheck</tabstop> - <tabstop>classCombo</tabstop> - <tabstop>classCheck</tabstop> - <tabstop>classColor</tabstop> - <tabstop>fileCombo</tabstop> - <tabstop>fileCheck</tabstop> - <tabstop>fileColor</tabstop> - <tabstop>maxListEdit</tabstop> - <tabstop>PushButton1</tabstop> - <tabstop>PushButton2</tabstop> -</tabstops> -<includes> - <include location="global" impldecl="in implementation">kcolorbutton.h</include> -</includes> -<pixmapinproject/> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/kcachegrind/kcachegrind/configuration.cpp b/kcachegrind/kcachegrind/configuration.cpp deleted file mode 100644 index 02d5c096..00000000 --- a/kcachegrind/kcachegrind/configuration.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <kconfig.h> -#include <klocale.h> -#include <kdebug.h> - -#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<ColorSetting> 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<TQStringList> 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; i<ctCount; i++) { - TraceCostType* t = TraceCostType::knownType(i); - ctConfig.writeEntry( TQString("Name%1").arg(i+1), t->name()); - - // 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;i<ol->count();i++) - l.prepend( (*ol)[i] ); - } - if (ol2) { - for(unsigned int i=0;i<ol2->count();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/kcachegrind/kcachegrind/configuration.h b/kcachegrind/kcachegrind/configuration.h deleted file mode 100644 index 478f6176..00000000 --- a/kcachegrind/kcachegrind/configuration.h +++ /dev/null @@ -1,101 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqcolor.h> -#include <tqstringlist.h> -#include <tqdict.h> - -#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 <maxSymbolLength> - 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<ColorSetting> _colors; - - TQStringList _generalSourceDirs; - TQDict<TQStringList> _objectSourceDirs; - - bool _showPercentage, _showExpanded, _showCycles; - double _cycleCut; - int _percentPrecision; - int _maxSymbolLength, _maxSymbolCount, _maxListCount; - int _context, _noCostInside; - - static Configuration* _config; -}; - - -#endif diff --git a/kcachegrind/kcachegrind/costlistitem.cpp b/kcachegrind/kcachegrind/costlistitem.cpp deleted file mode 100644 index 1e777b05..00000000 --- a/kcachegrind/kcachegrind/costlistitem.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <math.h> - -#include <tqpainter.h> -#include <tqregexp.h> - -#include <klocale.h> -#include <kiconloader.h> -#include <kapplication.h> - -#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/kcachegrind/kcachegrind/costlistitem.h b/kcachegrind/kcachegrind/costlistitem.h deleted file mode 100644 index 99f654e1..00000000 --- a/kcachegrind/kcachegrind/costlistitem.h +++ /dev/null @@ -1,52 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/costtypeitem.cpp b/kcachegrind/kcachegrind/costtypeitem.cpp deleted file mode 100644 index dc35cb2b..00000000 --- a/kcachegrind/kcachegrind/costtypeitem.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <klocale.h> - -#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/kcachegrind/kcachegrind/costtypeitem.h b/kcachegrind/kcachegrind/costtypeitem.h deleted file mode 100644 index d34973db..00000000 --- a/kcachegrind/kcachegrind/costtypeitem.h +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/costtypeview.cpp b/kcachegrind/kcachegrind/costtypeview.cpp deleted file mode 100644 index 3f5417e9..00000000 --- a/kcachegrind/kcachegrind/costtypeview.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqwhatsthis.h> -#include <tqpopupmenu.h> -#include <klocale.h> - -#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( "<b>Cost Types List</b>" - "<p>This list shows all cost types available " - "and what the self/inclusive cost of the " - "current selected function is for that cost type.</p>" - "<p>By choosing a cost type from the list, " - "you change the cost type of costs shown " - "all over KCachegrind to be the selected one.</p>"); -} - - -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;i<m->realCount();i++) { - ct = m->realType(i); - if (ct) prev = ct; - } - for (int i=0;i<m->virtualCount();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; i<knownCount; i++) { - known = TraceCostType::knownType(i); - if (known->name() == 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/kcachegrind/kcachegrind/costtypeview.h b/kcachegrind/kcachegrind/costtypeview.h deleted file mode 100644 index ee9963e3..00000000 --- a/kcachegrind/kcachegrind/costtypeview.h +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/coverage.cpp b/kcachegrind/kcachegrind/coverage.cpp deleted file mode 100644 index 86e6f7ff..00000000 --- a/kcachegrind/kcachegrind/coverage.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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;i<maxHistogramDepth;i++) { - _selfHisto[i] = 0.0; - _inclHisto[i] = 0.0; - } - - _valid = true; -} - -int Coverage::inclusiveMedian() -{ - double maxP = _inclHisto[0]; - int medD = 0; - for (int i = 1;i<maxHistogramDepth;i++) - if (_inclHisto[i]>maxP) { - maxP = _inclHisto[i]; - medD = i; - } - - return medD; -} - -int Coverage::selfMedian() -{ - double maxP = _selfHisto[0]; - int medD = 0; - for (int i = 1;i<maxHistogramDepth;i++) - if (_selfHisto[i]>maxP) { - 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 (d<maxHistogramDepth) { - _inclHisto[d] += pBack; - } - else { - _inclHisto[maxHistogramDepth-1] += pBack; - } - -#ifdef DEBUG_COVERAGE - qDebug("CallerCov: D %d, %s (now active, new incl %f): newP %f", - d, _function->prettyName().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 (d<maxHistogramDepth) { - _inclHisto[d] += pForward; - _selfHisto[d] += self; - } - else { - _inclHisto[maxHistogramDepth-1] += pForward; - _selfHisto[maxHistogramDepth-1] += self; - } - -#ifdef DEBUG_COVERAGE - qDebug("CngCov:%s < %s (incl %f, self %f)", - spaces+strlen(spaces)-d, - _function->prettyName().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/kcachegrind/kcachegrind/coverage.h b/kcachegrind/kcachegrind/coverage.h deleted file mode 100644 index 50c5936a..00000000 --- a/kcachegrind/kcachegrind/coverage.h +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/coverageitem.cpp b/kcachegrind/kcachegrind/coverageitem.cpp deleted file mode 100644 index 26e5b36e..00000000 --- a/kcachegrind/kcachegrind/coverageitem.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <klocale.h> - -#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/kcachegrind/kcachegrind/coverageitem.h b/kcachegrind/kcachegrind/coverageitem.h deleted file mode 100644 index ba442aa6..00000000 --- a/kcachegrind/kcachegrind/coverageitem.h +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/coverageview.cpp b/kcachegrind/kcachegrind/coverageview.cpp deleted file mode 100644 index 6657e923..00000000 --- a/kcachegrind/kcachegrind/coverageview.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqwhatsthis.h> -#include <tqpopupmenu.h> -#include <klocale.h> - -#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( "<b>List of all Callers</b>" - "<p>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 <em>Distance</em> (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).</p>" - - "<p>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.</p>" - - "<p>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.</p>" - - "<p>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.</p>") : - - i18n( "<b>List of all Callees</b>" - "<p>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 <em>Distance</em> (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).</p>" - - "<p>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.</p>" - - "<p>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.</p>" - - "<p>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.</p>"); -} - -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/kcachegrind/kcachegrind/coverageview.h b/kcachegrind/kcachegrind/coverageview.h deleted file mode 100644 index 09c5de03..00000000 --- a/kcachegrind/kcachegrind/coverageview.h +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/dumpmanager.cpp b/kcachegrind/kcachegrind/dumpmanager.cpp deleted file mode 100644 index 2f0891a4..00000000 --- a/kcachegrind/kcachegrind/dumpmanager.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/** - * 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/kcachegrind/kcachegrind/dumpmanager.h b/kcachegrind/kcachegrind/dumpmanager.h deleted file mode 100644 index 4925819d..00000000 --- a/kcachegrind/kcachegrind/dumpmanager.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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 <tqstring.h> -#include <tqptrlist.h> - -class Dump; -class TraceData; - -typedef TQPtrList<Dump> 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/kcachegrind/kcachegrind/dumpselection.cpp b/kcachegrind/kcachegrind/dumpselection.cpp deleted file mode 100644 index 4d812ef9..00000000 --- a/kcachegrind/kcachegrind/dumpselection.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 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/kcachegrind/kcachegrind/dumpselection.h b/kcachegrind/kcachegrind/dumpselection.h deleted file mode 100644 index 49ca532d..00000000 --- a/kcachegrind/kcachegrind/dumpselection.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 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/kcachegrind/kcachegrind/dumpselectionbase.ui b/kcachegrind/kcachegrind/dumpselectionbase.ui deleted file mode 100644 index b8ad1b0c..00000000 --- a/kcachegrind/kcachegrind/dumpselectionbase.ui +++ /dev/null @@ -1,1082 +0,0 @@ -<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> -<class>DumpSelectionBase</class> -<widget class="TQWidget"> - <property name="name"> - <cstring>DumpSelectionBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>349</width> - <height>832</height> - </rect> - </property> - <property name="caption"> - <string>Profile Dumps</string> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQSplitter"> - <property name="name"> - <cstring>splitter1</cstring> - </property> - <property name="orientation"> - <enum>Vertical</enum> - </property> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Target</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string></string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Time</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Path</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>listView1</cstring> - </property> - </widget> - <widget class="TQTabWidget"> - <property name="name"> - <cstring>tabWidget2</cstring> - </property> - <widget class="TQWidget"> - <property name="name"> - <cstring>tab</cstring> - </property> - <attribute name="title"> - <string>Options</string> - </attribute> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel1</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Target command:</string> - </property> - </widget> - <widget class="TQLineEdit"> - <property name="name"> - <cstring>lineEdit1</cstring> - </property> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel2</cstring> - </property> - <property name="text"> - <string>Profiler options:</string> - </property> - </widget> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Option</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Value</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <item> - <property name="text"> - <string>Trace</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>Jumps</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Instructions</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Events</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>Full Cache</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Custom</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Collect</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>At Startup</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>While In</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Skip</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>PLT</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Function</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Dump Profile</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>Every BBs</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>On Entering</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>On Leaving</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Zero Events</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>On Entering</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Separate</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>Threads</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Recursions</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Call Chain</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <property name="name"> - <cstring>listView3</cstring> - </property> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel1_2</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Custom profiler options:</string> - </property> - </widget> - <widget class="TQLineEdit"> - <property name="name"> - <cstring>lineEdit1_2</cstring> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout3</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <spacer> - <property name="name"> - <cstring>spacer1</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>21</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton2</cstring> - </property> - <property name="text"> - <string>Run New Profile</string> - </property> - </widget> - </hbox> - </widget> - </vbox> - </widget> - <widget class="TQWidget"> - <property name="name"> - <cstring>tab</cstring> - </property> - <attribute name="title"> - <string>Info</string> - </attribute> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel8</cstring> - </property> - <property name="text"> - <string>Dump reason:</string> - </property> - </widget> - <widget class="TQLineEdit"> - <property name="name"> - <cstring>lineEdit3</cstring> - </property> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel6</cstring> - </property> - <property name="text"> - <string>Event summary:</string> - </property> - </widget> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Name</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Sum</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>listView4</cstring> - </property> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel7</cstring> - </property> - <property name="text"> - <string>Miscellaneous:</string> - </property> - </widget> - <widget class="TQTextEdit"> - <property name="name"> - <cstring>textEdit2</cstring> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout7</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <spacer> - <property name="name"> - <cstring>spacer3</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>50</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton6</cstring> - </property> - <property name="text"> - <string>Show</string> - </property> - </widget> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton5</cstring> - </property> - <property name="text"> - <string>Compare</string> - </property> - </widget> - </hbox> - </widget> - </vbox> - </widget> - <widget class="TQWidget"> - <property name="name"> - <cstring>tab</cstring> - </property> - <attribute name="title"> - <string>State</string> - </attribute> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout2</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton1</cstring> - </property> - <property name="text"> - <string>Update</string> - </property> - </widget> - <widget class="TQCheckBox"> - <property name="name"> - <cstring>checkBox1</cstring> - </property> - <property name="text"> - <string>Every [s]:</string> - </property> - </widget> - <widget class="TQLineEdit"> - <property name="name"> - <cstring>lineEdit3_2</cstring> - </property> - </widget> - </hbox> - </widget> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Counter</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Value</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <item> - <property name="text"> - <string>Dumps Done</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Is Collecting</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Executed</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>Basic Blocks</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Calls</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Jumps</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Events</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>Ir</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <item> - <property name="text"> - <string>Distinct</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <item> - <property name="text"> - <string>ELF Objects</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Functions</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - <item> - <property name="text"> - <string>Contexts</string> - </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> - </item> - </item> - <property name="name"> - <cstring>listView4_3</cstring> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout4</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLabel"> - <property name="name"> - <cstring>textLabel4</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Stack trace:</string> - </property> - </widget> - <widget class="TQCheckBox"> - <property name="name"> - <cstring>checkBox2</cstring> - </property> - <property name="text"> - <string>Sync.</string> - </property> - </widget> - </hbox> - </widget> - <widget class="TQListView"> - <column> - <property name="text"> - <string>#</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Incl.</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Called</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Function</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Location</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>listView7</cstring> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout6</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton7</cstring> - </property> - <property name="text"> - <string>Start</string> - </property> - </widget> - <spacer> - <property name="name"> - <cstring>spacer2</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton6_2</cstring> - </property> - <property name="text"> - <string>Zero</string> - </property> - </widget> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton4</cstring> - </property> - <property name="text"> - <string>Dump</string> - </property> - </widget> - </hbox> - </widget> - </vbox> - </widget> - <widget class="TQWidget"> - <property name="name"> - <cstring>tab</cstring> - </property> - <attribute name="title"> - <string>Messages</string> - </attribute> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQTextEdit"> - <property name="name"> - <cstring>textEdit2_2</cstring> - </property> - </widget> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout6</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton9</cstring> - </property> - <property name="text"> - <string>Kill Run</string> - </property> - </widget> - <spacer> - <property name="name"> - <cstring>spacer4</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>21</width> - <height>20</height> - </size> - </property> - </spacer> - <widget class="TQPushButton"> - <property name="name"> - <cstring>pushButton8</cstring> - </property> - <property name="text"> - <string>Clear</string> - </property> - </widget> - </hbox> - </widget> - </vbox> - </widget> - </widget> - </widget> - </vbox> -</widget> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/kcachegrind/kcachegrind/fixcost.cpp b/kcachegrind/kcachegrind/fixcost.cpp deleted file mode 100644 index 41029265..00000000 --- a/kcachegrind/kcachegrind/fixcost.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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(i<maxCount) { - if (!s.stripUInt64(_cost[i])) break; - i++; - } - _count = i; - - if (!pool->allocateReserved(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(i<maxCount) { - if (!s.stripUInt64(_cost[i])) break; - i++; - } - _count = i; - - if (!pool->allocateReserved(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/kcachegrind/kcachegrind/fixcost.h b/kcachegrind/kcachegrind/fixcost.h deleted file mode 100644 index 7e90fb40..00000000 --- a/kcachegrind/kcachegrind/fixcost.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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/kcachegrind/kcachegrind/functionitem.cpp b/kcachegrind/kcachegrind/functionitem.cpp deleted file mode 100644 index 3b694ddf..00000000 --- a/kcachegrind/kcachegrind/functionitem.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <math.h> - -//#include <tqpainter.h> -//#include <tqregexp.h> - -#include <klocale.h> -#include <kiconloader.h> -#include <kapplication.h> - -#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/kcachegrind/kcachegrind/functionitem.h b/kcachegrind/kcachegrind/functionitem.h deleted file mode 100644 index d8f98f49..00000000 --- a/kcachegrind/kcachegrind/functionitem.h +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/functionselection.cpp b/kcachegrind/kcachegrind/functionselection.cpp deleted file mode 100644 index c5646dd6..00000000 --- a/kcachegrind/kcachegrind/functionselection.cpp +++ /dev/null @@ -1,871 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqtimer.h> -#include <tqlistview.h> -#include <tqlabel.h> -#include <tqpushbutton.h> -#include <tqcombobox.h> -#include <tqlineedit.h> -#include <tqregexp.h> -#include <tqpopupmenu.h> - -#include <klocale.h> - -#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/kcachegrind/kcachegrind/functionselection.h b/kcachegrind/kcachegrind/functionselection.h deleted file mode 100644 index c5f78107..00000000 --- a/kcachegrind/kcachegrind/functionselection.h +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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<TraceCostItem*,int> _groupSize; - - HighestCostList _hc; - // when setting a - bool _inSetGroup, _inSetFunction; -}; - -#endif diff --git a/kcachegrind/kcachegrind/functionselectionbase.ui b/kcachegrind/kcachegrind/functionselectionbase.ui deleted file mode 100644 index eec019db..00000000 --- a/kcachegrind/kcachegrind/functionselectionbase.ui +++ /dev/null @@ -1,163 +0,0 @@ -<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> -<class>FunctionSelectionBase</class> -<widget class="TQWidget"> - <property name="name"> - <cstring>FunctionSelectionBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>223</width> - <height>485</height> - </rect> - </property> - <property name="caption"> - <string>Function Profile</string> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>3</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <widget class="TQLayoutWidget"> - <property name="name"> - <cstring>layout1</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLabel"> - <property name="name"> - <cstring>searchLabel</cstring> - </property> - <property name="text"> - <string>&Search:</string> - </property> - <property name="buddy" stdset="0"> - <cstring>searchEdit</cstring> - </property> - </widget> - <widget class="TQLineEdit"> - <property name="name"> - <cstring>searchEdit</cstring> - </property> - </widget> - <widget class="TQComboBox"> - <property name="name"> - <cstring>groupBox</cstring> - </property> - </widget> - </hbox> - </widget> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Self</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Group</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>groupList</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>32767</width> - <height>150</height> - </size> - </property> - </widget> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Incl.</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Self</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Called</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Function</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Location</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>functionList</cstring> - </property> - </widget> - </vbox> -</widget> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/kcachegrind/kcachegrind/hi32-app-kcachegrind.png b/kcachegrind/kcachegrind/hi32-app-kcachegrind.png Binary files differdeleted file mode 100644 index bd41daec..00000000 --- a/kcachegrind/kcachegrind/hi32-app-kcachegrind.png +++ /dev/null diff --git a/kcachegrind/kcachegrind/hi48-app-kcachegrind.png b/kcachegrind/kcachegrind/hi48-app-kcachegrind.png Binary files differdeleted file mode 100644 index 58c2efdb..00000000 --- a/kcachegrind/kcachegrind/hi48-app-kcachegrind.png +++ /dev/null diff --git a/kcachegrind/kcachegrind/instritem.cpp b/kcachegrind/kcachegrind/instritem.cpp deleted file mode 100644 index ce5e81bb..00000000 --- a/kcachegrind/kcachegrind/instritem.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <tqpainter.h> - -#include <klocale.h> -#include <kapplication.h> -#include <kiconloader.h> -#include <kdebug.h> - -#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<TraceInstrJump*>& 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/kcachegrind/kcachegrind/instritem.h b/kcachegrind/kcachegrind/instritem.h deleted file mode 100644 index 2bbce71f..00000000 --- a/kcachegrind/kcachegrind/instritem.h +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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<TraceInstrJump*>& a); - -protected: - void paintArrows(TQPainter *p, const TQColorGroup &cg, int width); - TQMemArray<TraceInstrJump*> _jump; - -private: - InstrView* _view; - SubCost _pure, _pure2; - Addr _addr; - TraceInstr* _instr; - TraceInstrJump* _instrJump; - TraceInstrCall* _instrCall; - bool _inside; -}; - - -#endif diff --git a/kcachegrind/kcachegrind/instrview.cpp b/kcachegrind/kcachegrind/instrview.cpp deleted file mode 100644 index 3df16793..00000000 --- a/kcachegrind/kcachegrind/instrview.cpp +++ /dev/null @@ -1,949 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqfile.h> -#include <tqregexp.h> -#include <tqwhatsthis.h> -#include <tqpopupmenu.h> -#include <klocale.h> -#include <kconfig.h> -#include <kdebug.h> - -#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: <space>* <hex address> ":" <space>* - 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: <space>* <hex address> ":" <space>* - - 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( "<b>Annotated Assembler</b>" - "<p>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.</p>" - "<p>The disassembler output shown is generated with " - "the 'objdump' utility from the 'binutils' package.</p>" - "<p>Select a line with call information to " - "make the destination function of this call current.</p>"); -} - -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 ((objAddr<dumpStartAddr) || (objAddr>dumpEndAddr)) - 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/kcachegrind/kcachegrind/instrview.h b/kcachegrind/kcachegrind/instrview.h deleted file mode 100644 index 79d3d763..00000000 --- a/kcachegrind/kcachegrind/instrview.h +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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<TraceInstrJump*> _jump; - TraceInstrJumpList _lowList, _highList; - - // remember width of hex code column if hidden - int _lastHexCodeWidth; - - // widget options - bool _showHexCode; -}; - -#endif diff --git a/kcachegrind/kcachegrind/kcachegrind.desktop b/kcachegrind/kcachegrind/kcachegrind.desktop deleted file mode 100644 index 70893707..00000000 --- a/kcachegrind/kcachegrind/kcachegrind.desktop +++ /dev/null @@ -1,103 +0,0 @@ -# KDE Config File -[Desktop Entry] -Type=Application -Exec=tdecachegrind -caption "%c" %i %m %u -MimeType=application/x-tdecachegrind; -Icon=tdecachegrind -DocPath=tdecachegrind/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/kcachegrind/kcachegrind/kcachegrindui.rc b/kcachegrind/kcachegrind/kcachegrindui.rc deleted file mode 100644 index 9531829e..00000000 --- a/kcachegrind/kcachegrind/kcachegrindui.rc +++ /dev/null @@ -1,57 +0,0 @@ -<!DOCTYPE kpartgui> -<kpartgui name="tdecachegrind" version="4"> - <MenuBar> - <Menu name="file"><text>&File</text> - <Action name="file_add" append="open_merge"/> - <Action name="reload" append="revert_merge"/> - <Action name="dump" append="revert_merge"/> - <Action name="export"/> - </Menu> - <Menu name="view"><text>&View</text> - <Action name="view_cost_type"/> - <Action name="view_cost_type2"/> - <Action name="view_group_type"/> - <Separator/> - <Menu name="layouts"><text>&Layout</text> - <Action name="layout_next"/> - <Action name="layout_previous"/> - <Action name="layout_duplicate"/> - <Action name="layout_remove"/> - <Separator/> - <Action name="layout_restore"/> - <Action name="layout_save"/> - </Menu> - <Action name="view_split"/> - <Action name="view_split_dir"/> - <Separator/> - <Action name="view_percentage"/> - <Action name="view_expanded"/> - <Action name="view_cycles"/> - </Menu> - <Menu name="settings"> - <Menu append="show_toolbar_merge"><text>Sidebars</text> - <Action name="settings_show_dumpdock"/> - <Action name="settings_show_partdock"/> - <Action name="settings_show_stackdock"/> - <Action name="settings_show_profiledock"/> - </Menu> - </Menu> - </MenuBar> - - <ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text> - <Action name="file_open"/> - <Action name="reload"/> - <Action name="dump"/> - <Separator/> - <Action name="go_up"/> - <Action name="go_back"/> - <Action name="go_forward"/> - <Separator/> - <Action name="view_percentage"/> - <Action name="view_expanded"/> - <Action name="view_cycles"/> - </ToolBar> - <ToolBar name="stateToolBar" noMerge="1"><text>State Toolbar</text> - <Action name="view_cost_type"/> - </ToolBar> -</kpartgui> diff --git a/kcachegrind/kcachegrind/listutils.cpp b/kcachegrind/kcachegrind/listutils.cpp deleted file mode 100644 index 0053646d..00000000 --- a/kcachegrind/kcachegrind/listutils.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpainter.h> -#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;d<maxIndex;d++) - if (hist[d]>0.0) { - sum += hist[d]; - if (dmin>d) dmin = d; - if (dmax<d) dmax = d; - } - - // inner rectangle to fill with bar - int iw, ix1, ix2, ih, iy1, iy2; - 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; - } - - int filled = (int)(iw*sum+1); - if (!framed && (filled < w)) w=filled; - 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); - - //qDebug("Sum %f, dw %d", sum,dw); - - TQColor c, cLast; - bool leftDrawn = false; - int x1, x2=0; - int lastDiff=0, diff; - d=dmin; - while (d<dmax+1) { - val += hist[d]; - nextPos = (int)(filled * val/sum); - - //qDebug(" hist[%d] %f, val %f, nextPos %d", d, hist[d], val, nextPos); - - diff = nextPos-lastPos; - if (diff==0) { d++; continue; } - - c = cArray ? cArray[d] : partitionColor(d,maxIndex); - - x1 = ix1+lastPos; - x2 = ix1+nextPos; - if (x2>=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/kcachegrind/kcachegrind/listutils.h b/kcachegrind/kcachegrind/listutils.h deleted file mode 100644 index e3e13fb5..00000000 --- a/kcachegrind/kcachegrind/listutils.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <tqstring.h> -#include <tqcolor.h> -#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 <maxSize> 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<TraceCost*> _item; - TQMemArray<SubCost> _cost; -}; - -#endif diff --git a/kcachegrind/kcachegrind/lo16-app-kcachegrind.png b/kcachegrind/kcachegrind/lo16-app-kcachegrind.png Binary files differdeleted file mode 100644 index 0985586b..00000000 --- a/kcachegrind/kcachegrind/lo16-app-kcachegrind.png +++ /dev/null diff --git a/kcachegrind/kcachegrind/lo32-app-kcachegrind.png b/kcachegrind/kcachegrind/lo32-app-kcachegrind.png Binary files differdeleted file mode 100644 index 12542c8a..00000000 --- a/kcachegrind/kcachegrind/lo32-app-kcachegrind.png +++ /dev/null diff --git a/kcachegrind/kcachegrind/loader.cpp b/kcachegrind/kcachegrind/loader.cpp deleted file mode 100644 index a4aecf56..00000000 --- a/kcachegrind/kcachegrind/loader.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/loader.h b/kcachegrind/kcachegrind/loader.h deleted file mode 100644 index f79f13d0..00000000 --- a/kcachegrind/kcachegrind/loader.h +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqobject.h> -#include <tqptrlist.h> -#include <tqstring.h> - -class TQFile; -class TraceData; -class TracePart; -class Loader; - - -typedef TQPtrList<Loader> 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/kcachegrind/kcachegrind/main.cpp b/kcachegrind/kcachegrind/main.cpp deleted file mode 100644 index fd9df1b8..00000000 --- a/kcachegrind/kcachegrind/main.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 TDECACHEGRIND_VERSION -#include "../version.h" - -#include <tqfile.h> -#include <kapplication.h> -#include <kcmdlineargs.h> -#include <kaboutdata.h> -#include <klocale.h> - -#include "toplevel.h" -#include "tracedata.h" -#include "loader.h" - -static KCmdLineOptions options[] = -{ - { "r <exec>", I18N_NOOP("Run <exec> under cachegrind"), 0 }, - { "+[trace]", I18N_NOOP("Show information of this trace"), 0 }, - KCmdLineLastOption // End of options. -}; - -int main( int argc, char ** argv ) -{ - KAboutData aboutData("tdecachegrind", - I18N_NOOP("KCachegrind"), - TDECACHEGRIND_VERSION, - I18N_NOOP("KDE Frontend for Cachegrind"), - KAboutData::License_GPL, - I18N_NOOP("(C) 2002, 2003, 2004"), 0, - "http://tdecachegrind.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/kcachegrind/kcachegrind/multiview.cpp b/kcachegrind/kcachegrind/multiview.cpp deleted file mode 100644 index 4288e2df..00000000 --- a/kcachegrind/kcachegrind/multiview.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqobjectlist.h> -#include <kconfig.h> -#include <kdebug.h> - -#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/kcachegrind/kcachegrind/multiview.h b/kcachegrind/kcachegrind/multiview.h deleted file mode 100644 index 9d771013..00000000 --- a/kcachegrind/kcachegrind/multiview.h +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqsplitter.h> -#include <tqptrlist.h> -#include "traceitemview.h" -#include "tabview.h" // because of TQPtrList<TabView> - -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<TabView> _views; -}; - -#endif diff --git a/kcachegrind/kcachegrind/partgraph.cpp b/kcachegrind/kcachegrind/partgraph.cpp deleted file mode 100644 index a20f53dc..00000000 --- a/kcachegrind/kcachegrind/partgraph.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <klocale.h> - -#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 && count<Configuration::maxSymbolCount() && i->rtti() == 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/kcachegrind/kcachegrind/partgraph.h b/kcachegrind/kcachegrind/partgraph.h deleted file mode 100644 index f28f12eb..00000000 --- a/kcachegrind/kcachegrind/partgraph.h +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/partlistitem.cpp b/kcachegrind/kcachegrind/partlistitem.cpp deleted file mode 100644 index 40c2db36..00000000 --- a/kcachegrind/kcachegrind/partlistitem.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <math.h> - -#include <tqpainter.h> -#include <tqregexp.h> - -#include <klocale.h> -#include <kiconloader.h> -#include <kapplication.h> - -#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/kcachegrind/kcachegrind/partlistitem.h b/kcachegrind/kcachegrind/partlistitem.h deleted file mode 100644 index 0ab99a9c..00000000 --- a/kcachegrind/kcachegrind/partlistitem.h +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/partselection.cpp b/kcachegrind/kcachegrind/partselection.cpp deleted file mode 100644 index 703dd75f..00000000 --- a/kcachegrind/kcachegrind/partselection.cpp +++ /dev/null @@ -1,567 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqtimer.h> -#include <tqlistview.h> -#include <tqlabel.h> -#include <tqpushbutton.h> -#include <tqcombobox.h> -#include <tqlineedit.h> -#include <tqpopupmenu.h> -#include <tqlayout.h> - -#include <klocale.h> -#include <kconfig.h> -#include <kdebug.h> - -#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/kcachegrind/kcachegrind/partselection.h b/kcachegrind/kcachegrind/partselection.h deleted file mode 100644 index b8a195f8..00000000 --- a/kcachegrind/kcachegrind/partselection.h +++ /dev/null @@ -1,96 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqobject.h> - -#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/kcachegrind/kcachegrind/partselectionbase.ui b/kcachegrind/kcachegrind/partselectionbase.ui deleted file mode 100644 index 53320d5b..00000000 --- a/kcachegrind/kcachegrind/partselectionbase.ui +++ /dev/null @@ -1,89 +0,0 @@ -<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> -<class>PartSelectionBase</class> -<widget class="TQWidget"> - <property name="name"> - <cstring>PartSelectionBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>460</width> - <height>402</height> - </rect> - </property> - <property name="caption"> - <string>Parts Overview</string> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>6</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <widget class="PartAreaWidget"> - <property name="name"> - <cstring>partAreaWidget</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>7</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>50</height> - </size> - </property> - </widget> - <widget class="TQLabel"> - <property name="name"> - <cstring>rangeLabel</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>(no trace parts)</string> - </property> - </widget> - </vbox> -</widget> -<customwidgets> - <customwidget> - <class>PartAreaWidget</class> - <header location="local">partgraph.h</header> - <sizehint> - <width>-1</width> - <height>-1</height> - </sizehint> - <container>0</container> - <sizepolicy> - <hordata>5</hordata> - <verdata>7</verdata> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - <pixmap>image0</pixmap> - </customwidget> -</customwidgets> -<images> - <image name="image0"> - <data format="XPM.GZ" length="5230">789c9597db4e1d4b0e86eff31428be8b46b5fb54dd551acd051020211c4320c0682eecaa5e9ccf90005bf3ee53cbbfe9d9c9c548a38ea27c2977b5cbfe6dd7fae3c3c2e1cee6c2873fde3d3cf2e3595a48a77cbff0213f5d5dbdfcf35ffff8f3ddfba65998fff161a179ffb777ef771f17d2c2d6cdf53807c705a889cdac6ee72c47736eebd637b5f2b672d70ecd30e744ca7d9b9a4ad7579587363433e527e5d072abefbb03636978ceb4a31c5bc13a91716ad41f89e0aec2fe74abcc6d6ad5f9e4945357375ef75f997357751dd61d19c71afb61bdef421b951f274ebaffb6716cb3f2b2f230f18d3183dd95b1b441d7d59f2e94757ccf1b27eceff69563618d0f5dcfd9d7beeb7a5dd7f3fac6fb4ee32b87c619f1168d976f7d6ff6df26d6ef4b301e1bac7f54f63e747a5e87f5c173276aff605c22a8fefc540e5e3af5972f956359577bf2c6d978cb78d6697edc9eb2f8b143fed7945359d778b0e6c3e7be81bf7465dce23cf4ac3c16567f19fecefaae53bd081b7baccbb131b7d05f679ca03f27c6b9d1f388c6bbaffab7f80dca4d1fed7bfafdbeedb9533d490f1e2ae8d5693ccacb83d77cd027e3d4416faa97beefa3d7f8f086f168f9d9020f43a3f5c5aa877e28eb88f74fe319becfaa873e0c15de775f95639f3dec37c143d361bf2be3cef4b76bdcb7d84ff5d2cbd0227facf1ecd360fa67d54b9f078ffcd10f636e11ff53e3847853ad3c1b668837e9fe43358c2df45a81430b3db2e6676842d368fd48abdc068b87e0fd2e788bf792b21f861e7afd0e0e5ce37dcdd7d0872218e5d789f57b3218a71ae7bb501eca3af67b510e21c05fd27a1b6218ac3ef17d0ed68fe8cb1be3fc6e5159863ca0bfed824340fe687d62c4838c23f677f0370de380fcdd2be7e03dfab1d6cf300bcd80fa80bfb358dbf9547fa18abe413d68fe421d63ade7737aded094cf63fdcc38f4d0bfee17dac2d08380a3a0dff24cb90bdc23ffaa87e0636c912fed87612e38d4df1e982bc4dbdd29872001f14aca319413eb793e83cbfbe8af27606e4c0f5f8d3bcb7763ec6b8da73b57e69083d61f9d82b9b5fada31f635fcaf8d7b7b5ffb41f16e34ff34fe214dfc0c8e1ef1a22330bfcdc345e31e4c33e3c1e6e181b1609e3ac43f8759803e8cd9f2e7e0ff18ab80ef5d8239e2fc0ef129f90ff0bf0773347fee8d13ce279bc6b34af5c61abf58157bf4b765b05435f4abfec726968c2b67e536fa80fe388279067f680d2c750dff75fe9766da07e44bc02521ba4e1d584c1fb261dcc23fd97f63f8c3af136bfc687362c4e76962ed8fac7a2ecdb7853f7c63ec6bf467bd3fc421c680780c60b6f9275fc045aea84fadaf18a2e0fc04ff0237bd9e8fefc0d236e8ef3f8d83c57fdd38daf94edeb886be74fec618b3ed7f3731e66b0fe67a403e76c0454ef8de9231dbfe9f8dc5fc47be38a6887ad2f950964d2fdc1a27d3c7b6710693f6ef9864b4fdb4ffc6cc5540fea0972c339c87afc1c9f4443a5fe2c84d40bd2f82cb3ae6c7b1716dbc37b1e68bf5be118b7e3dead78125d87d0bfa99bd7d8fb78c1bdb4fcfcfd51bcb9d716bebda3fb8966cf7cf57709103f2e327c6fe5a2fdc4ab4fb01deef5283fa65d50ffb54c13fd67ec37d61e845fb070f8571df7c341eec7e7a691c6ae453fb771937d1fa999ebfa43358bf573d3327c6fdd0a9de59b87414e59f60911ef3ff07380d16bf0b63b6fbb8ce0f4e523a80ee8ff8a5f21fe83f384f2e8cf9d419db7d4bb4bff32cb1dd871ae38c79417962dd9f8f2786bfaa3fa992ddbf68d5d8d6797d62dc27b4bf4a9bdeee5be7c619efbb169c2b9bb7aa67e972857a67d59bf8943cf4a6f5237dae3b9c3f4f8cef5713637e6a3c6548e546a7eb87e0b28e7cf7c68ddd2fb15f28acf166bd2f484c19f921f8cbc57de84ff52c397b8f7e178d7bbb7f7e9f18f743d593ccd210d12f9e8c05fd8417c1e5e704e2afefa7aa5cf850ff4fc6a1473debfc4d7561c4ebd3c48897f69fd4e4d8eb7e4efb736a0b23fe9adfd465bb3f388d6ff22933fa1df6f7597ad483c62371f6e6ff8671b6f89e198fb8cfb0ea3f49619c6f6562cc27d5474a7906e6b589d1df549f29e78479450fe0b1c2fc67d5731a0ba33ffc97a167fd7d92ebb1b1f9a87acdcdd8a23ff2e3c4a81fed0fb91bbb88f8e9f772f9b9c6b8bfac187bd41febbcc8c35831f4bb6edc227eeec8b847bc58ef0f398d91a1179d6f391746bdebfd60ac4716b0180bd8a97e473f8ea2dfdb7d9c3f8e1cff8f8760057b27e57f92cb6e743377e24efff29cb97377e12edd55b190c99eddb5bb71b7eeceddbb07f7e89edc0ff7d33dbb17f7ea16dd925b761fdd8a63d8174f52b15e756bee93fbecd6dd17b7e136dd96db763b6ed77d2dd67bee9bdb77078ed49e8b27b7c5fabb3b7447eed855ae768d6bcbd339ef7a37b8e022392a2734fbd1dd119350a24c23cde8844ee98ccee9c2f9c2977445d77443b793fd8ceee89e1ee8919ee807fdb4e7995ee8b5d82fd252b15ffe8bfd097da4155aa535fa34597fa6f5f2f717da28f69bb445dbb433d99fd22e7da53dfa3659efd3017da7c3f2af233aa68aeadfec1b6aa9236fd63d0d14ca15c0719913737b965fedcbf0c83cc29a677cc2a77cc6e77cc1977cc5d7c5fee637fbdbb2db9d5adff343b17ee427fec1737ee69762fffa9bfd222ff17259fdc82bbcca6bfc893ff33a7fe10ddee42ddee69ddfec77f92beff137dee703fece877cc4c7aee58a6b6ee8b8fc10ed7eb13f635f9a4bc5e54719477152ba671977a505c84845c57222a7bfd89fcb999ccb855cca955cbfc5546ee456ee68b14cf67b799047799aec2fdc92fc28999cef567224cff222afb2c85b32e36d599265f9282bb23ad95fba6559934f2593f3e798b74acc8fd5f6b3accb17d9904dd9926db3a7520d1fdd37d9915df95a72599e1291566df7e49beccb817c974339829eb55e56dc7e51ec0d2dcbb1545297a791563af1c5eff2d3beb4faf8562f568f0744745b9e9d5f1f7992d5e412a186ffef7afff7dfdffd077c99ae99</data> - </image> -</images> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/kcachegrind/kcachegrind/partview.cpp b/kcachegrind/kcachegrind/partview.cpp deleted file mode 100644 index 3f344bbc..00000000 --- a/kcachegrind/kcachegrind/partview.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqwhatsthis.h> -#include <tqpopupmenu.h> -#include <tqheader.h> -#include <klocale.h> - -#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( "<b>Trace Part List</b>" - "<p>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 <em>of the part</em> (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.</p>" - "<p>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.</p>" - "<p>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.</p>" - "<p>Note that the list is hidden if only one trace " - "part is loaded.</p>"); -} - - -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/kcachegrind/kcachegrind/partview.h b/kcachegrind/kcachegrind/partview.h deleted file mode 100644 index 92761cc1..00000000 --- a/kcachegrind/kcachegrind/partview.h +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/pool.cpp b/kcachegrind/kcachegrind/pool.cpp deleted file mode 100644 index d4a89a72..00000000 --- a/kcachegrind/kcachegrind/pool.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002-2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <string.h> -#include <stdlib.h> -#include <tqglobal.h> -#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;i<CHUNK_SIZE;i++) { - p.allocate(bufs+i, 10+i%10); - if (((i%3)==0) && (i>20)) - p.free(bufs+i-20); - } - - for(i=0;i<CHUNK_SIZE;i++) { - if ((bufs[i]==0) || ((i%7)==0)) continue; - p.free(bufs+i); - } - - for(i=0;i<CHUNK_SIZE;i++) { - if (bufs[i]) continue; - p.allocate(bufs+i, 10+i%10); - } -} -*/ diff --git a/kcachegrind/kcachegrind/pool.h b/kcachegrind/kcachegrind/pool.h deleted file mode 100644 index c9d70c14..00000000 --- a/kcachegrind/kcachegrind/pool.h +++ /dev/null @@ -1,107 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002-2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <size> 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 <size> 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 <size> 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/kcachegrind/kcachegrind/sourceitem.cpp b/kcachegrind/kcachegrind/sourceitem.cpp deleted file mode 100644 index 305b8244..00000000 --- a/kcachegrind/kcachegrind/sourceitem.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <tqregexp.h> -#include <tqpainter.h> - -#include <klocale.h> -#include <kiconloader.h> -#include <kapplication.h> - -#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<TraceLineJump*>& 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/kcachegrind/kcachegrind/sourceitem.h b/kcachegrind/kcachegrind/sourceitem.h deleted file mode 100644 index 925e575b..00000000 --- a/kcachegrind/kcachegrind/sourceitem.h +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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<TraceLineJump*>& a); - -protected: - void paintArrows(TQPainter *p, const TQColorGroup &cg, int width); - TQMemArray<TraceLineJump*> _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/kcachegrind/kcachegrind/sourceview.cpp b/kcachegrind/kcachegrind/sourceview.cpp deleted file mode 100644 index dde291ea..00000000 --- a/kcachegrind/kcachegrind/sourceview.cpp +++ /dev/null @@ -1,813 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqdir.h> -#include <tqfile.h> -#include <tqwhatsthis.h> -#include <tqpopupmenu.h> -#include <klocale.h> -#include <kdebug.h> - -#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( "<b>Annotated Source</b>" - "<p>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.</p>" - "<p>Select a inserted call information line to " - "make the destination function current.</p>"); -} - -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;iStart<asize;iStart++) - if (_jump[iStart] && - (_jump[iStart]->lineTo() == lj->lineTo())) break; -#else - iStart = asize; -#endif - - if (iStart == asize) { - for(iStart=0;iStart<asize;iStart++) - if (_jump[iStart] == 0) break; - - if (iStart== asize) { - asize++; - _jump.resize(asize); - if (asize > _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/kcachegrind/kcachegrind/sourceview.h b/kcachegrind/kcachegrind/sourceview.h deleted file mode 100644 index b72fc7ad..00000000 --- a/kcachegrind/kcachegrind/sourceview.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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<TraceLineJump*> _jump; - TraceLineJumpList _lowList, _highList; -}; - -#endif diff --git a/kcachegrind/kcachegrind/stackbrowser.cpp b/kcachegrind/kcachegrind/stackbrowser.cpp deleted file mode 100644 index 78095eb2..00000000 --- a/kcachegrind/kcachegrind/stackbrowser.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> - -#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/kcachegrind/kcachegrind/stackbrowser.h b/kcachegrind/kcachegrind/stackbrowser.h deleted file mode 100644 index e7d6b802..00000000 --- a/kcachegrind/kcachegrind/stackbrowser.h +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/stackitem.cpp b/kcachegrind/kcachegrind/stackitem.cpp deleted file mode 100644 index e3763ab4..00000000 --- a/kcachegrind/kcachegrind/stackitem.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqpixmap.h> -#include <klocale.h> - -#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/kcachegrind/kcachegrind/stackitem.h b/kcachegrind/kcachegrind/stackitem.h deleted file mode 100644 index 250e9f66..00000000 --- a/kcachegrind/kcachegrind/stackitem.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003, 2004 - Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqlistview.h> -#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/kcachegrind/kcachegrind/stackselection.cpp b/kcachegrind/kcachegrind/stackselection.cpp deleted file mode 100644 index 59094754..00000000 --- a/kcachegrind/kcachegrind/stackselection.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqtimer.h> -#include <tqlistview.h> -#include <tqlabel.h> -#include <tqpushbutton.h> -#include <tqcombobox.h> -#include <tqlineedit.h> - -#include <kdebug.h> - -#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/kcachegrind/kcachegrind/stackselection.h b/kcachegrind/kcachegrind/stackselection.h deleted file mode 100644 index 2bb3a750..00000000 --- a/kcachegrind/kcachegrind/stackselection.h +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/stackselectionbase.ui b/kcachegrind/kcachegrind/stackselectionbase.ui deleted file mode 100644 index c61010f9..00000000 --- a/kcachegrind/kcachegrind/stackselectionbase.ui +++ /dev/null @@ -1,80 +0,0 @@ -<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> -<class>StackSelectionBase</class> -<widget class="TQWidget"> - <property name="name"> - <cstring>StackSelectionBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>168</width> - <height>108</height> - </rect> - </property> - <property name="caption"> - <string>Stack Selection</string> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="margin"> - <number>3</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <widget class="TQListView"> - <column> - <property name="text"> - <string>Cost</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizeable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Cost2</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizeable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Calls</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizeable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Function</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizeable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>stackList</cstring> - </property> - </widget> - </vbox> -</widget> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/kcachegrind/kcachegrind/subcost.cpp b/kcachegrind/kcachegrind/subcost.cpp deleted file mode 100644 index 7b5034e3..00000000 --- a/kcachegrind/kcachegrind/subcost.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqstring.h> - -#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/kcachegrind/kcachegrind/subcost.h b/kcachegrind/kcachegrind/subcost.h deleted file mode 100644 index 81692808..00000000 --- a/kcachegrind/kcachegrind/subcost.h +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002-2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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/kcachegrind/kcachegrind/tabview.cpp b/kcachegrind/kcachegrind/tabview.cpp deleted file mode 100644 index 0049d1e2..00000000 --- a/kcachegrind/kcachegrind/tabview.cpp +++ /dev/null @@ -1,890 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqobjectlist.h> -#include <tqsplitter.h> -#include <tqtabwidget.h> -#include <tqlayout.h> -#include <tqwhatsthis.h> -#include <tqpopupmenu.h> - -#include <klocale.h> -#include <kconfig.h> - -#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<int> 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<TraceItemView> 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( "<b>Information Tabs</b>" - "<p>This widget shows information for the " - "current selected function in different tabs: " - "<ul>" - "<li>The Costs tab shows a list of available event types " - "and the inclusive and self costs regarding to these types.</li>" - "<li>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.</li>" - "<li>The Call Lists tab shows direct callers and " - "callees of the function in more detail.</li>" - "<li>The Coverage tab shows the same is the Call " - "Lists tab, but not only direct callers and callees " - "but also indirect ones.</li>" - "<li>The Call Graph tab shows a graphical " - "visualization of the calls done by this function.</li>" - "<li>The Source tab presents annotated source code " - "if debugging information and the source file " - "is available.</li>" - "<li>The Assembler tab presents annotated assembler code " - "if trace information on instruction level " - "is available.</li></ul>" - "For more information, see the <em>What's This?</em> " - "help of the corresponding tab widget</p>"); -} - -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<TraceItemView> 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<TraceItemView> 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/kcachegrind/kcachegrind/tabview.h b/kcachegrind/kcachegrind/tabview.h deleted file mode 100644 index b9b40269..00000000 --- a/kcachegrind/kcachegrind/tabview.h +++ /dev/null @@ -1,174 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqptrlist.h> -#include <tqwidget.h> -#include <tqtabwidget.h> -#include <tqtabbar.h> -#include <ksqueezedtextlabel.h> -#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 <w> == 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<TraceItemView> _tabs; - - TQWidget* _lastFocus; - bool _active; -}; - -#endif diff --git a/kcachegrind/kcachegrind/tips b/kcachegrind/kcachegrind/tips deleted file mode 100644 index 1f555c0e..00000000 --- a/kcachegrind/kcachegrind/tips +++ /dev/null @@ -1,141 +0,0 @@ -<tip category="KCachegrind|Help"> -<html> -<p>...that the <em>What's This?</em> 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 <em>What's This?</em> help by pressing -Shift+F1 and clicking on the widget.</p> -</html> -</tip> - -<tip category="KCachegrind|Explanation"> -<html> -<p>...that you can get profile information at instruction level -with Calltree when you provide the option <em>--dump-instr=yes</em>? -Use the Assembler View for the instruction annotations. -</p> -</html> -</tip> - -<tip category="KCachegrind|Keyboard"> -<html> -<p>...that you can use Alt-Left/Right keys of your keyboard to go -back/forward in the active object history ?</p> -</html> -</tip> - -<tip category="KCachegrind|Keyboard"> -<html> -<p>...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. -</p> -</html> -</tip> - -<tip category="KCachegrind|Keyboard"> -<html> -<p>...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. -</p> -</html> -</tip> - -<tip category="KCachegrind|Filters"> -<html> -<p>...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?</p> -</html> -</tip> - -<tip category="KCachegrind|Appearance"> -<html> -<p>...that you can assign custom colors to -ELF objects/C++ Classes/Source Files for graph coloring -in <em>Settings->Configure KCachegrind...</em>?</p> -</html> -</tip> - -<tip category="KCachegrind|Configuration"> -<html> -<p>...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?</p> -<p>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 -<em>Source Directories</em> list in the configuration. -</html> -</tip> - -<tip category="KCachegrind|Appearance"> -<html> -<p>...that you can configure whether KCachgrind should -show absolute event counts or relative ones (percentage display)?</p> -</html> -</tip> - -<tip category="KCachegrind|Appearance"> -<html> -<p>...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.</p> -<p>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.</p> -</html> -</tip> - -<tip category="KCachegrind|Explanation"> -<html> -<p>...that the Coverage tab - in contrast to the Call Lists tab - -shows <em>all</em> 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?</p> -<p>Examples:</p> -<p>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().</p> -<p>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().</p> -</html> -</tip> - -<tip category="KCachegrind|Explanation"> -<html> -<p>...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?</p> -<p>Items from this list can be selected by pressing the right -mouse button.</p> -</html> -</tip> - -<tip category="KCachegrind|Explanation"> -<html> -<p>...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?</p> -<p>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).</p> -</html> -</tip> - -<tip category="KCachegrind|Explanation"> -<p>...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?</p> -</html> -</tip> - diff --git a/kcachegrind/kcachegrind/toplevel.cpp b/kcachegrind/kcachegrind/toplevel.cpp deleted file mode 100644 index 5a2e1deb..00000000 --- a/kcachegrind/kcachegrind/toplevel.cpp +++ /dev/null @@ -1,2389 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <stdlib.h> // for system() - -#include <tqvbox.h> -#include <tqtimer.h> -#include <tqwhatsthis.h> -#include <tqlineedit.h> -#include <tqtextstream.h> -#include <tqsizepolicy.h> -#include <tqprogressbar.h> -#include <tqfile.h> -#include <tqeventloop.h> - -#include <kapplication.h> -#include <klocale.h> -#include <kstatusbar.h> -#include <kstdaccel.h> -#include <kstdaction.h> -#include <kaction.h> -#include <kurl.h> -#include <kfiledialog.h> -#include <kio/netaccess.h> -#include <kedittoolbar.h> -#include <kkeydialog.h> -#include <ktip.h> -#include <kpopupmenu.h> -#include <kdebug.h> - -#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 TDE_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( - "<b>The Parts Overview</b>" - "<p>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." - "</p>" - "<p>The parts are further subdivided: there is a " - "partitioning and an callee split mode: " - "<ul><li>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.</li>" - "<li>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.</li></ul></p>")); - - _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( - "<b>The Top Cost Call Stack</b>" - "<p>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.</p>" - "<p>The <b>Cost</b> and <b>Calls</b> columns show the " - "cost used for all calls from the function in the line " - "above.</p>")); - - 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( - "<b>The Flat Profile</b>" - "<p>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.<p>" - "<p>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.</p>")); - -#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( - "<b>Profile Dumps</b>" - "<p>This dockable shows in the top part the list of " - "loadable profile dumps in all subdirectories of: " - "<ul><li>current working directory of KCachegrind, " - "i.e. where it was started from, and " - "<li>the default profile dump directory given in the " - "configuration.</ul> " - "The list is sorted according the the target command " - "profiled in the corresponding dump.</p>" - "<p>On selecting a profile dump, information for it " - "is shown in the bottom area of the dockable: " - "<ul><li><b>Options</b> 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 <b>Run Profile</b> to start a" - "profile run with these options in the background. " - "<li><b>Info</b> gives detailed info on the selected " - "dump like event cost summary and properties of the " - "simulated cache. " - "<li><b>State</b> is only available for current happening " - "profiles runs. Press <b>Update</b> to see different " - "counters of the run, and a stack trace of the current " - "position in the program profiled. Check the <b>Every</b> " - "option to let KCachegrind regularly poll these data. " - "Check the <b>Sync</b> option to let the dockable activate " - "the top function in the current loaded dump.</ul></p>")); -#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("<b>Duplicate Current Layout</b>" - "<p>Make a copy of the current layout.</p>"); - action->setWhatsThis( hint ); - - action = new KAction( i18n( "&Remove" ), KShortcut(), - TQT_TQOBJECT(this), TQT_SLOT(layoutRemove()), - actionCollection(), "layout_remove" ); - hint = i18n("<b>Remove Current Layout</b>" - "<p>Delete current layout and make the previous active.</p>"); - 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("<b>New</b><p>Open new empty KCachegrind window.</p>"); - action->setWhatsThis( hint ); - - action = new KAction( i18n( "&Add..." ), KShortcut(), - TQT_TQOBJECT(this), TQT_SLOT(addTrace()), - actionCollection(), "file_add" ); - hint = i18n("<b>Add Profile Data</b>" - "<p>This opens an additional profile data file in the current window.</p>"); - action->setWhatsThis( hint ); - - action = new KAction( i18n( "&Reload" ), "reload", -#if TDE_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("<b>Reload Profile Data</b>" - "<p>This loads any new created parts, too.</p>"); - action->setWhatsThis( hint ); - - action = new KAction( i18n( "&Export Graph" ), KShortcut(), - TQT_TQOBJECT(this), TQT_SLOT(exportGraph()), - actionCollection(), "export" ); - - hint = i18n("<b>Export Call Graph</b>" - "<p>Generates a file with extension .dot for the tools " - "of the GraphViz package.</p>"); - action->setWhatsThis( hint ); - - - _taDump = new KToggleAction( i18n( "&Force Dump" ), "redo", -#if TDE_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("<b>Force Dump</b>" - "<p>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.</p>" - "<p>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 <em>no</em> Callgrind " - "running, press 'Force Dump' again to cancel the dump " - "request. This deletes 'callgrind.cmd' itself and " - "stops polling for a new dump.</p>" - "<p>Note: A Callgrind run <em>only</em> detects " - "existence of 'callgrind.cmd' when actively running " - "a few milliseconds, i.e. " - "<em>not</em> sleeping. Tip: For a profiled GUI program, " - "you can awake Callgrind e.g. by resizing a window " - "of the program.</p>"); - _taDump->setWhatsThis( hint ); - - action = KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(loadTrace()), actionCollection()); - hint = i18n("<b>Open Profile Data</b>" - "<p>This opens a profile data file, with possible multiple parts</p>"); - 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 TDE_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("<b>Show percentage costs relative to parent</b>" - "<p>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." - "<ul><table>" - "<tr><td><b>Cost Type</td><td><b>Parent Cost</td></tr>" - "<tr><td>Function Cumulative</td><td>Total</td></tr>" - "<tr><td>Function Self</td><td>Function Group (*) / Total</td></tr>" - "<tr><td>Call</td><td>Function Cumulative</td></tr>" - "<tr><td>Source Line</td><td>Function Cumulative</td></tr>" - "</table>" - "<p>(*) 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 TDE_VERSION >= 0x030290 - // for KDE 3.3: show another text instead of a checkmark - _taCycles->setCheckedState(i18n("Skip Cycle Detection")); -#endif - - hint = i18n("<b>Detect recursive cycles</b>" - "<p>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)." - "<p>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("<b>Go Up</b>" - "<p>Go to last selected caller of current function. " - "If no caller was visited, use that with highest cost.</p>"); - 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("<b>Go Up</b>" - "<p>Go to last selected caller of current function. " - "If no caller was visited, use that with highest cost.</p>"); - _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 TDE_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 TDE_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 TDE_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 TDE_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<TQT_BASE_OBJECT_NAME*>(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;i<m->realCount();i++) - types << m->realType(i)->longName(); - for (int i=0;i<m->virtualCount();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;i<m->realCount();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;i<m->virtualCount();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;l<name.length();l++) - if (name[l].isLetterOrNumber()) key += name[l]; - - return TQString("-") + key; -} - - -void TopLevel::restoreTraceTypes() -{ - TQString key = traceKey(); - - KConfigGroup cConfig(KGlobal::config(), TQCString("CurrentState")); - KConfigGroup pConfig(KGlobal::config(), TQCString("TracePositions")); - - TQString groupType, costType, costType2; - groupType = pConfig.readEntry(TQString("GroupType%1").arg(key)); - costType = pConfig.readEntry(TQString("CostType%1").arg(key)); - costType2 = pConfig.readEntry(TQString("CostType2%1").arg(key)); - - if (groupType.isEmpty()) groupType = cConfig.readEntry("GroupType"); - if (costType.isEmpty()) costType = cConfig.readEntry("CostType"); - if (costType2.isEmpty()) costType2 = cConfig.readEntry("CostType2"); - - setGroupType(groupType); - setCostType(costType); - setCostType2(costType2); - - // if still no cost type set, use first available - if (!_costType && !_saCost->items().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 (count<Configuration::maxSymbolCount() && hi) { - f = hi->function(); - 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 (count<Configuration::maxSymbolCount() && hi) { - f = hi->function(); - 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 (count<Configuration::maxSymbolCount() && f) { - TQString name = f->prettyName(); - 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/kcachegrind/kcachegrind/toplevel.h b/kcachegrind/kcachegrind/toplevel.h deleted file mode 100644 index 10e7cde5..00000000 --- a/kcachegrind/kcachegrind/toplevel.h +++ /dev/null @@ -1,275 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqdatetime.h> - -#include <dcopobject.h> -#include <kmainwindow.h> - -#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/kcachegrind/kcachegrind/tracedata.cpp b/kcachegrind/kcachegrind/tracedata.cpp deleted file mode 100644 index f129c2e5..00000000 --- a/kcachegrind/kcachegrind/tracedata.cpp +++ /dev/null @@ -1,5068 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <stdlib.h> - -#include <tqfile.h> -#include <tqdir.h> -#include <tqfileinfo.h> -#include <tqregexp.h> - -#include <klocale.h> -#include <kdebug.h> - -#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;i++) { - type = (CostType) i; - if (typeName(type) == s) - return type; - } - return NoCostType; -} - -// all strings of typeName() are translatable because of I18N_NOOP there -TQString TraceItem::i18nTypeName(CostType t) -{ - if (!_i18nTypeName) { - _i18nTypeName = new TQString [MaxCostType+1]; - for(int i=0;i<=MaxCostType;i++) - _i18nTypeName[i] = i18n(typeName((CostType)i).utf8().data()); - } - if (t<0 || t> 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; i<MaxCostType;i++) { - type = (CostType) i; - if (i18nTypeName(type) == s) - return type; - } - return NoCostType; -} - - -void TraceItem::clear() -{ - invalidate(); -} - - -TQString TraceItem::costString(TraceCostMapping*) -{ - return TQString("(no cost)"); -} - -TQString TraceItem::name() const -{ - if (part()) { - return i18n("%1 from %2") - .arg(_dep->name()) - .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(i<sm->count()) { - if (!_cost[i].set(&s)) break; - i++; - } - _count = i; - } - else { - int i = 0, maxIndex = 0, index; - while(1) { - index = sm->realIndex(i); - if (maxIndex<index) maxIndex=index; - if (index == TraceCost::InvalidIndex) break; - if (!_cost[index].set(&s)) break; - i++; - } - // we have to set all costs of unused indexes till maxIndex to zero - for(i=sm->firstUnused(); 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(i<sm->count()) { - if (!s.stripUInt64(_cost[i])) break; - i++; - } - _count = i; - } - else { - int i = 0, maxIndex = 0, index; - while(1) { - index = sm->realIndex(i); - if (maxIndex<index) maxIndex=index; - if (index == TraceCost::InvalidIndex) break; - if (!s.stripUInt64(_cost[index])) break; - i++; - } - // we have to set all costs of unused indexes till maxIndex to zero - for(i=sm->firstUnused(); 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(i<sm->count()) { - 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<index) maxIndex=index; - if (index == TraceCost::InvalidIndex) break; - if (index<_count) - _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; - } - } - - // 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(i<sm->count()) { - 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<index) maxIndex=index; - if (index == TraceCost::InvalidIndex) break; - if (index<_count) - _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 -} - - -// 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(i<sm->count()) { - 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<index) maxIndex=index; - if (index == TraceCost::InvalidIndex) break; - if (index<_count) { - if (v>_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<item->_count; i++) - _cost[i] += item->_cost[i]; - } - else { - for (i = 0; i<_count; i++) - _cost[i] += item->_cost[i]; - for (; i<item->_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<item->_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<item->_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<type;i++) - _cost[i] = 0; - _cost[type] = value; - _count = type+1; - } - - // a cost change has to be propagated (esp. in subclasses) - invalidate(); -} - -void TraceCost::maxCost(int type, SubCost value) -{ - if (type<0 || type>=MaxRealIndex) return; - if (type<_count) { - if (value>_cost[type]) _cost[type] = value; - } - else { - for(int i=_count;i<type;i++) - _cost[i] = 0; - _cost[type] = value; - _count = type+1; - } - - // a cost change has to be propagated (esp. in subclasses) - invalidate(); -} - - -TraceCost TraceCost::diff(TraceCost* item) -{ - TraceCost res; - - // we have to update the other item if needed - // because we access the item costs directly - if (item->_dirty) item->update(); - - int maxCount = (item->_count > _count) ? item->_count : _count; - - res._count = maxCount; - for (int i=0; i<maxCount;i++) - res._cost[i] = item->subCost(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; i<maxIndex; i++) { - if (!res.isEmpty()) res += ", "; - if (m) res += m->type(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>* 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; i<TraceCost::MaxRealIndex;i++) - _coefficient[i] = 0; -} - -void TraceCostType::setFormula(TQString formula) -{ - _formula = formula; - _realIndex = TraceCost::InvalidIndex; - _parsed = false; -} - -void TraceCostType::setMapping(TraceCostMapping* m) -{ - _parsed = false; - _mapping = m; -} - -// setting the index to TraceCost::MaxRealIndex makes it a -// real type with unspecified index -void TraceCostType::setRealIndex(int i) -{ - if (i<0 || i>TraceCost::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; i<TraceCost::MaxRealIndex;i++) - _coefficient[i] = 0; - - TQRegExp rx( "((?:\\+|\\-)?)\\s*(\\d*)\\s*\\*?\\s*(\\w+)" ); - - int factor, pos; - TQString costName; - TraceCostType* costType; - - pos = 0; - while (1) { - pos = rx.search(_formula, pos); - if (pos<0) break; - pos += rx.matchedLength(); - if (rx.cap(0).isEmpty()) break; - - //qDebug("parseFormula: matched '%s','%s','%s'", - // rx.cap(1).ascii(), rx.cap(2).ascii(), rx.cap(3).ascii()); - - costName = rx.cap(3); - costType = _mapping->type(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<TraceCost::MaxRealIndex;i++) - _coefficient[i] += factor * costType->_coefficient[i]; - } - } - - _inParsing = false; - _parsed = true; - - return true; -} - -TQString TraceCostType::parsedFormula() -{ - TQString res; - - if (!parseFormula()) return res; - - for (int i=0; i<TraceCost::MaxRealIndex;i++) { - int c = _coefficient[i]; - if (c == 0) continue; - - if (!res.isEmpty()) { - res += " "; - if (c>0) 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;i<rc;i++) - if (_coefficient[i] != 0) - res += _coefficient[i] * c->subCost(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;i<rc;i++) { - if (_coefficient[i] != 0) - hist[i] = _coefficient[i] * c->subCost(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<TraceCostType>; - - /* 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;i<TraceCost::MaxRealIndex;i++) _real[i] = 0; - for (int i=0;i<TraceCost::MaxRealIndex;i++) _virtual[i] = 0; -} - -TraceCostMapping::~TraceCostMapping() -{ - for (int i=0;i<TraceCost::MaxRealIndex;i++) - if (_real[i]) delete _real[i]; - - for (int i=0;i<TraceCost::MaxRealIndex;i++) - if (_virtual[i]) delete _virtual[i]; -} - -TraceSubMapping* TraceCostMapping::subMapping(TQString types, bool create) -{ - // first check if there's enough space in the mapping - int newCount = 0; - int pos = 0, pos2, len = types.length(); - - while (1) { - // skip space - while((pos<len) && types[pos].isSpace()) pos++; - - pos2 = pos; - while((pos2<len) && !types[pos2].isSpace()) pos2++; - if (pos2 == pos) break; - - if (realIndex(types.mid(pos,pos2-pos)) == TraceCost::InvalidIndex) - newCount++; - - pos = pos2; - } - - if (!create && (newCount>0)) 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((pos<len) && types[pos].isSpace()) pos++; - - pos2 = pos; - while((pos2<len) && !types[pos2].isSpace()) pos2++; - if (pos2 == pos) break; - - sm->append(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; i<knownCount; i++) { - TraceCostType* t = TraceCostType::knownType(i); - if (t->isReal()) 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;i<TraceCost::MaxRealIndex;i++) { - _realIndex[i] = TraceCost::InvalidIndex; - _nextUnused[i] = i+1; - } -} - -bool TraceSubMapping::append(TQString type, bool create) -{ - if (!_mapping) return false; - int index = create ? _mapping->addReal(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<type;i++) - if (_nextUnused[i] == type) - _nextUnused[i]=_nextUnused[type]; - - _count++; - return true; -} - - -//--------------------------------------------------- -// TraceCallCost - -TraceCallCost::TraceCallCost() -{ - _callCount = 0; -} - -TraceCallCost::~TraceCallCost() -{} - - -TQString TraceCallCost::costString(TraceCostMapping* m) -{ - return TQString("%1, Calls %2") - .arg(TraceCost::costString(m)) - .arg(_callCount.pretty()); -} - -TQString TraceCallCost::prettyCallCount() -{ - return _callCount.pretty(); -} - -void TraceCallCost::clear() -{ - _callCount = 0; - TraceCost::clear(); -} - -SubCost TraceCallCost::callCount() -{ - if (_dirty) update(); - - return _callCount; -} - -void TraceCallCost::addCallCount(SubCost c) -{ - _callCount += c; - - invalidate(); -} - - -//--------------------------------------------------- -// TraceInclusiveCost - -TraceInclusiveCost::TraceInclusiveCost() -{} - -TraceInclusiveCost::~TraceInclusiveCost() -{} - -TQString TraceInclusiveCost::costString(TraceCostMapping* m) -{ - return TQString("%1, Inclusive %2") - .arg(TraceCost::costString(m)) - .arg(_inclusive.costString(m)); -} - -void TraceInclusiveCost::clear() -{ - _inclusive.clear(); - TraceCost::clear(); -} - -TraceCost* TraceInclusiveCost::inclusive() -{ - if (_dirty) update(); - - return &_inclusive; -} - -void TraceInclusiveCost::addInclusive(TraceCost* c) -{ - _inclusive.addCost(c); - - invalidate(); -} - - -//--------------------------------------------------- -// TraceListCost - -TraceListCost::TraceListCost() -{ - _lastDep = 0; -} - -TraceListCost::~TraceListCost() -{} - -void TraceListCost::addDep(TraceCost* 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 -} - -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 <cycle %2>").arg(res).arg(_cycle->cycleNo()); - else - res = TQString("<cycle %2>").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("<cycle %1>").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() <n) data()->setMaxPartNumber(n); - _number = n; -} - -void TracePart::setThreadID(int tid) -{ - if (data()->maxThreadID() <tid) data()->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: - * - * - <base> is a directory: Load first profile data file available - * - <base> 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 && pIndex<index) break; - lastIndex = index+2; - } - - TQString clsName = (lastIndex < 3) ? TQString() : - fnName.left(lastIndex-2); - shortName = fnName.mid(lastIndex); - - TraceClass& c = _classMap[clsName]; - if (!c.data()) { - // was created - c.setPosition(this); - c.setName(clsName); - -#if TRACE_DEBUG - qDebug("Created %s [TraceData::cls]", - c.fullName().ascii()); -#endif - } - return &c; -} - - -// name is inclusive class/namespace prefix -TraceFunction* TraceData::function(const TQString& name, - TraceFile* file, TraceObject* object) -{ - // strip class name - TQString shortName; - TraceClass* c = cls(name, shortName); - - if (!file || !object || !c) { - qDebug("ERROR - no file/object/class for %s ?!", name.ascii()); - return 0; - } - - // Don't use file in key: A function can go over many files - // (inlined parts), but still is ONE function. - TQString key = name + object->shortName(); - - 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/kcachegrind/kcachegrind/tracedata.h b/kcachegrind/kcachegrind/tracedata.h deleted file mode 100644 index 8fab2b68..00000000 --- a/kcachegrind/kcachegrind/tracedata.h +++ /dev/null @@ -1,1967 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqstring.h> -#include <tqstringlist.h> -#include <tqptrlist.h> -#include <tqmap.h> -#include <tqptrvector.h> -#include <tqcolor.h> - -#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<TraceCost> TraceCostList; -typedef TQPtrList<TraceJumpCost> TraceJumpCostList; -typedef TQPtrList<TraceCallCost> TraceCallCostList; -typedef TQPtrList<TraceInclusiveCost> TraceInclusiveCostList; - -typedef TQPtrList<TracePartCall> TracePartCallList; -typedef TQPtrList<TracePartInstr> TracePartInstrList; -typedef TQPtrList<TracePartLine> TracePartLineList; -typedef TQPtrList<TracePartLineRegion> TracePartLineRegionList; -typedef TQPtrList<TracePartFunction> TracePartFunctionList; -typedef TQPtrList<TracePartInstrCall> TracePartInstrCallList; -typedef TQPtrList<TracePartLineCall> TracePartLineCallList; - - -typedef TQPtrList<TraceInstr> TraceInstrList; -typedef TQPtrList<TraceLine> TraceLineList; -typedef TQPtrList<TraceInstrCall> TraceInstrCallList; -typedef TQPtrList<TraceLineCall> TraceLineCallList; -typedef TQPtrList<TraceCall> TraceCallList; -typedef TQPtrList<TraceFile> TraceFileList; -typedef TQPtrList<TraceLineRegion> TraceLineRegionList; -typedef TQPtrList<TraceFunctionSource> TraceFunctionSourceList; -typedef TQPtrList<TraceFunction> TraceFunctionList; -typedef TQPtrList<TraceFunctionCycle> TraceFunctionCycleList; -typedef TQMap<TQString, TraceObject> TraceObjectMap; -typedef TQMap<TQString, TraceClass> TraceClassMap; -typedef TQMap<TQString, TraceFile> TraceFileMap; -typedef TQMap<TQString, TraceFunction> TraceFunctionMap; -typedef TQMap<uint, TraceLine> 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<Addr, TraceInstr> 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: - - /** - * <name> is a short (non-localized) identifier for the cost type, - * e.g. "l1rm". - * <longName> is a long localized string, e.g. "L1 Read Miss" - * <formula> 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<TraceCostType>* _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 <create> 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<TracePart> -{ - 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<TraceInstrJump> -{ - 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<TraceLineJump> -{ - 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<TraceAssoziation> TraceAssoziationList; -typedef TQMap<TraceFunction*, TraceCall*> 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<TraceFunction*,int> 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/kcachegrind/kcachegrind/traceitemview.cpp b/kcachegrind/kcachegrind/traceitemview.cpp deleted file mode 100644 index d11f02b6..00000000 --- a/kcachegrind/kcachegrind/traceitemview.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqwidget.h> -#include <kconfig.h> -#include <klocale.h> -#include <kdebug.h> - -#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/kcachegrind/kcachegrind/traceitemview.h b/kcachegrind/kcachegrind/traceitemview.h deleted file mode 100644 index f83aa896..00000000 --- a/kcachegrind/kcachegrind/traceitemview.h +++ /dev/null @@ -1,206 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 - * - <dataChanged> 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/kcachegrind/kcachegrind/treemap.cpp b/kcachegrind/kcachegrind/treemap.cpp deleted file mode 100644 index 0d4b8dc9..00000000 --- a/kcachegrind/kcachegrind/treemap.cpp +++ /dev/null @@ -1,3214 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <math.h> - -#include <tqpainter.h> -#include <tqtooltip.h> -#include <tqregexp.h> -#include <tqstyle.h> -#include <tqpopupmenu.h> - -#include <klocale.h> -#include <kconfig.h> -#include <kdebug.h> - -#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 (<unused>) - 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 && (pixY<y)) y = pixY; - if (!isBottom && (pixY>y)) 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<TQRect>; - _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<TQRect>* 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<size) { - _attr[oldSize].type = defaultFieldType(oldSize); - _attr[oldSize].stop = defaultFieldStop(oldSize); - _attr[oldSize].visible = defaultFieldVisible(oldSize); - _attr[oldSize].forced = defaultFieldForced(oldSize); - _attr[oldSize].pos = defaultFieldPosition(oldSize); - oldSize++; - } - } - return true; -} - -void TreeMapWidget::setFieldType(int f, TQString type) -{ - if (((int)_attr.size() < f+1) && - (type == defaultFieldType(f))) return; - if (resizeAttr(f+1)) _attr[f].type = type; - - // no need to redraw: the type string is not visible in the TreeMap -} - -TQString TreeMapWidget::fieldType(int f) const -{ - if (f<0 || (int)_attr.size()<f+1) return defaultFieldType(f); - return _attr[f].type; -} - -void TreeMapWidget::setFieldStop(int f, TQString stop) -{ - if (((int)_attr.size() < f+1) && - (stop == defaultFieldStop(f))) return; - if (resizeAttr(f+1)) { - _attr[f].stop = stop; - redraw(); - } -} - -TQString TreeMapWidget::fieldStop(int f) const -{ - if (f<0 || (int)_attr.size()<f+1) return defaultFieldStop(f); - return _attr[f].stop; -} - -void TreeMapWidget::setFieldVisible(int f, bool enable) -{ - if (((int)_attr.size() < f+1) && - (enable == defaultFieldVisible(f))) return; - - if (resizeAttr(f+1)) { - _attr[f].visible = enable; - redraw(); - } -} - -bool TreeMapWidget::fieldVisible(int f) const -{ - if (f<0 || (int)_attr.size()<f+1) - return defaultFieldVisible(f); - - return _attr[f].visible; -} - -void TreeMapWidget::setFieldForced(int f, bool enable) -{ - if (((int)_attr.size() < f+1) && - (enable == defaultFieldForced(f))) return; - - if (resizeAttr(f+1)) { - _attr[f].forced = enable; - if (_attr[f].visible) redraw(); - } -} - -bool TreeMapWidget::fieldForced(int f) const -{ - if (f<0 || (int)_attr.size()<f+1) - return defaultFieldForced(f); - - return _attr[f].forced; -} - -void TreeMapWidget::setFieldPosition(int f, TreeMapItem::Position pos) -{ - if (((int)_attr.size() < f+1) && - (pos == defaultFieldPosition(f))) return; - - if (resizeAttr(f+1)) { - _attr[f].pos = pos; - if (_attr[f].visible) redraw(); - } -} - -DrawParams::Position TreeMapWidget::fieldPosition(int f) const -{ - if (f<0 || (int)_attr.size()<f+1) - return defaultFieldPosition(f); - - return _attr[f].pos; -} - -void TreeMapWidget::setFieldPosition(int f, TQString pos) -{ - if (pos == "TopLeft") - setFieldPosition(f, DrawParams::TopLeft); - else if (pos == "TopCenter") - setFieldPosition(f, DrawParams::TopCenter); - else if (pos == "TopRight") - setFieldPosition(f, DrawParams::TopRight); - else if (pos == "BottomLeft") - setFieldPosition(f, DrawParams::BottomLeft); - else if (pos == "BottomCenter") - setFieldPosition(f, DrawParams::BottomCenter); - else if (pos == "BottomRight") - setFieldPosition(f, DrawParams::BottomRight); - else if (pos == "Default") - setFieldPosition(f, DrawParams::Default); -} - -TQString TreeMapWidget::fieldPositionString(int f) const -{ - TreeMapItem::Position pos = fieldPosition(f); - if (pos == DrawParams::TopLeft) return TQString("TopLeft"); - if (pos == DrawParams::TopCenter) return TQString("TopCenter"); - if (pos == DrawParams::TopRight) return TQString("TopRight"); - if (pos == DrawParams::BottomLeft) return TQString("BottomLeft"); - if (pos == DrawParams::BottomCenter) return TQString("BottomCenter"); - if (pos == DrawParams::BottomRight) return TQString("BottomRight"); - if (pos == DrawParams::Default) return TQString("Default"); - return TQString("unknown"); -} - -void TreeMapWidget::setMinimalArea(int area) -{ - if (_minimalArea == area) return; - - _minimalArea = area; - redraw(); -} - - -void TreeMapWidget::deletingItem(TreeMapItem* i) -{ - // remove any references to the item to be deleted - while(_selection.findRef(i) > -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 && valSum<user_sum/2) { - while (lenLeft>len/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 && (nextPos<lastPos)) { - p->setPen(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;f<fCount;f++) { - config->writeEntry(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;f<num;f++) { - str = TQString(prefix+"FieldVisible%1").arg(f); - if (config->hasKey(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/kcachegrind/kcachegrind/treemap.h b/kcachegrind/kcachegrind/treemap.h deleted file mode 100644 index 422cd35c..00000000 --- a/kcachegrind/kcachegrind/treemap.h +++ /dev/null @@ -1,759 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqstring.h> -#include <tqwidget.h> -#include <tqpixmap.h> -#include <tqptrlist.h> -#include <tqvaluevector.h> -#include <tqcolor.h> -#include <tqapplication.h> -#include <tqstringlist.h> - -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 <f> - void ensureField(int f); - - struct Field { - TQString text; - TQPixmap pix; - Position pos; - int maxLines; - }; - - TQValueVector<Field> _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<TreeMapItem> -{ -public: - TreeMapItem* commonParent(); -protected: - int compareItems ( Item item1, Item item2 ); -}; - -typedef TQPtrListIterator<TreeMapItem> 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<TQRect>* 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: <textNo> = -1 - * For value() sorting, use <textNo> = -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<TQRect>* _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 <markNo>. 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(<markNo>). - * 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 <width>, 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 <reuseSpace> 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 <kbd> 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<FieldAttr> _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/kcachegrind/kcachegrind/utils.cpp b/kcachegrind/kcachegrind/utils.cpp deleted file mode 100644 index 65c7e347..00000000 --- a/kcachegrind/kcachegrind/utils.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <config.h> -#endif - -#ifdef HAVE_MMAP -#include <unistd.h> -#include <sys/mman.h> -#endif - -#include <tqfile.h> -#include <errno.h> - -#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<count;i++) - delete _first[i]; - } -} - -#endif diff --git a/kcachegrind/kcachegrind/utils.h b/kcachegrind/kcachegrind/utils.h deleted file mode 100644 index 7256f054..00000000 --- a/kcachegrind/kcachegrind/utils.h +++ /dev/null @@ -1,164 +0,0 @@ -/* This file is part of KCachegrind. - Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> - - 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 <tqstring.h> - -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 <c> 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 <str>. 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 type> -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/kcachegrind/kcachegrind/x-kcachegrind.desktop b/kcachegrind/kcachegrind/x-kcachegrind.desktop deleted file mode 100644 index b9bf93aa..00000000 --- a/kcachegrind/kcachegrind/x-kcachegrind.desktop +++ /dev/null @@ -1,44 +0,0 @@ -[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=tdecachegrind -Icon=tdecachegrind -Type=MimeType -MimeType=application/x-tdecachegrind -Patterns=cachegrind.out*;callgrind.out* diff --git a/kcachegrind/pics/Makefile.am b/kcachegrind/pics/Makefile.am deleted file mode 100644 index f4a31867..00000000 --- a/kcachegrind/pics/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -tdecachegrindicondir = $(kde_datadir)/tdecachegrind/icons -tdecachegrindicon_ICON = AUTO -SUBDIRS = hicolor diff --git a/kcachegrind/pics/hicolor/Makefile.am b/kcachegrind/pics/hicolor/Makefile.am deleted file mode 100644 index 068e3192..00000000 --- a/kcachegrind/pics/hicolor/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -tdecachegrindicondir = $(kde_datadir)/tdecachegrind/icons -tdecachegrindicon_ICON = AUTO diff --git a/kcachegrind/pics/hicolor/hi16-action-fromrec.png b/kcachegrind/pics/hicolor/hi16-action-fromrec.png Binary files differdeleted file mode 100644 index a5cb430d..00000000 --- a/kcachegrind/pics/hicolor/hi16-action-fromrec.png +++ /dev/null diff --git a/kcachegrind/pics/hicolor/hi16-action-percent.png b/kcachegrind/pics/hicolor/hi16-action-percent.png Binary files differdeleted file mode 100644 index 7a4ba47e..00000000 --- a/kcachegrind/pics/hicolor/hi16-action-percent.png +++ /dev/null diff --git a/kcachegrind/pics/hicolor/hi16-action-recrec.png b/kcachegrind/pics/hicolor/hi16-action-recrec.png Binary files differdeleted file mode 100644 index ec11bfa4..00000000 --- a/kcachegrind/pics/hicolor/hi16-action-recrec.png +++ /dev/null diff --git a/kcachegrind/pics/hicolor/hi16-action-torec.png b/kcachegrind/pics/hicolor/hi16-action-torec.png Binary files differdeleted file mode 100644 index c092c018..00000000 --- a/kcachegrind/pics/hicolor/hi16-action-torec.png +++ /dev/null diff --git a/kcachegrind/pics/hicolor/hi22-action-percent.png b/kcachegrind/pics/hicolor/hi22-action-percent.png Binary files differdeleted file mode 100644 index c64a3785..00000000 --- a/kcachegrind/pics/hicolor/hi22-action-percent.png +++ /dev/null diff --git a/kcachegrind/pics/hicolor/hi32-action-percent.png b/kcachegrind/pics/hicolor/hi32-action-percent.png Binary files differdeleted file mode 100644 index e876c30d..00000000 --- a/kcachegrind/pics/hicolor/hi32-action-percent.png +++ /dev/null diff --git a/kcachegrind/tests/cg-badcompression1 b/kcachegrind/tests/cg-badcompression1 deleted file mode 100644 index 6076bf92..00000000 --- a/kcachegrind/tests/cg-badcompression1 +++ /dev/null @@ -1,17 +0,0 @@ -# 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/kcachegrind/tests/cg-badcostline1 b/kcachegrind/tests/cg-badcostline1 deleted file mode 100644 index 224ff670..00000000 --- a/kcachegrind/tests/cg-badcostline1 +++ /dev/null @@ -1,11 +0,0 @@ -# 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/kcachegrind/tests/cg-badposition b/kcachegrind/tests/cg-badposition deleted file mode 100644 index 1be582c7..00000000 --- a/kcachegrind/tests/cg-badposition +++ /dev/null @@ -1,15 +0,0 @@ -# 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/kcachegrind/version.h.in b/kcachegrind/version.h.in deleted file mode 100644 index d88081be..00000000 --- a/kcachegrind/version.h.in +++ /dev/null @@ -1 +0,0 @@ -#define TDECACHEGRIND_VERSION "@TDECACHEGRIND_VERSION@" |