From 3af5832abe7c802a384cd58d34f7cc4433595ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Mon, 7 Oct 2013 23:28:24 +0200 Subject: [PATCH] Initial import of kscope 1.6.2 --- AUTHORS | 1 + COPYING | 20 + ChangeLog | 408 ++ Doxyfile | 259 + INSTALL | 167 + Makefile.am | 22 + NEWS | 1 + README | 1 + TODO | 17 + acinclude.m4 | 11345 ++++++++++++++++++++++++++++++++++ aclocal.m4 | 902 +++ config.h.in | 252 + configure.files | 2 + configure.in | 93 + configure.in.in | 17 + doc/Makefile.am | 6 + doc/en/Makefile.am | 5 + doc/en/about.docbook | 31 + doc/en/autocomp_dlg.png | Bin 0 -> 12457 bytes doc/en/bookmarks.docbook | 28 + doc/en/bookmarks.png | Bin 0 -> 23860 bytes doc/en/call_graph.png | Bin 0 -> 23525 bytes doc/en/call_tree.png | Bin 0 -> 94329 bytes doc/en/config_dlg.docbook | 206 + doc/en/editing.docbook | 138 + doc/en/index.docbook | 174 + doc/en/main_menu.docbook | 465 ++ doc/en/main_window.docbook | 24 + doc/en/main_window.png | Bin 0 -> 719478 bytes doc/en/pos_history.docbook | 101 + doc/en/pref_clrs.png | Bin 0 -> 43746 bytes doc/en/pref_fonts.png | Bin 0 -> 30787 bytes doc/en/pref_opts.png | Bin 0 -> 41987 bytes doc/en/pref_progs.png | Bin 0 -> 47959 bytes doc/en/project_details.png | Bin 0 -> 31041 bytes doc/en/project_files.png | Bin 0 -> 72430 bytes doc/en/project_make.png | Bin 0 -> 106302 bytes doc/en/project_open.png | Bin 0 -> 22418 bytes doc/en/project_opts.png | Bin 0 -> 28292 bytes doc/en/project_types.png | Bin 0 -> 20111 bytes doc/en/projects.docbook | 394 ++ doc/en/query_dlg.png | Bin 0 -> 24116 bytes doc/en/query_filter.png | Bin 0 -> 16118 bytes doc/en/query_system.docbook | 434 ++ doc/en/quick_start.docbook | 41 + po/Makefile.am | 1 + po/kscope.pot | 1515 +++++ po/zh_CN.po | 1642 +++++ src/Makefile.am | 68 + src/autocompletionlayout.ui | 217 + src/bookmark.png | Bin 0 -> 690 bytes src/bookmarksdlg.cpp | 60 + src/bookmarksdlg.h | 53 + src/bookmarkslayout.ui | 116 + src/call_graph.png | Bin 0 -> 741 bytes src/called_tree.png | Bin 0 -> 463 bytes src/calling_tree.png | Bin 0 -> 445 bytes src/calltreedlg.cpp | 336 + src/calltreedlg.h | 111 + src/calltreelayout.ui | 430 ++ src/calltreemanager.cpp | 136 + src/calltreemanager.h | 71 + src/configfrontend.cpp | 172 + src/configfrontend.h | 77 + src/cscopefrontend.cpp | 524 ++ src/cscopefrontend.h | 186 + src/cscopemsgdlg.cpp | 66 + src/cscopemsgdlg.h | 49 + src/cscopemsglayout.ui | 79 + src/ctagsfrontend.cpp | 179 + src/ctagsfrontend.h | 77 + src/ctagslist.cpp | 446 ++ src/ctagslist.h | 108 + src/dirscanner.cpp | 164 + src/dirscanner.h | 144 + src/dotfrontend.cpp | 297 + src/dotfrontend.h | 76 + src/dotparse.ypp | 234 + src/dotscan.lpp | 36 + src/editormanager.cpp | 89 + src/editormanager.h | 56 + src/editorpage.cpp | 720 +++ src/editorpage.h | 215 + src/editortabs.cpp | 640 ++ src/editortabs.h | 129 + src/encoder.cpp | 114 + src/encoder.h | 53 + src/file_ro.png | Bin 0 -> 892 bytes src/file_rw.png | Bin 0 -> 647 bytes src/file_save.png | Bin 0 -> 838 bytes src/filelist.cpp | 197 + src/filelist.h | 75 + src/fileview.cpp | 131 + src/fileview.h | 80 + src/fileviewlayout.ui | 136 + src/frontend.cpp | 365 ++ src/frontend.h | 212 + src/graphedge.cpp | 306 + src/graphedge.h | 143 + src/graphnode.cpp | 192 + src/graphnode.h | 123 + src/graphprefdlg.cpp | 82 + src/graphprefdlg.h | 54 + src/graphpreflayout.ui | 262 + src/graphwidget.cpp | 1162 ++++ src/graphwidget.h | 213 + src/hi16-app-kscope.png | Bin 0 -> 815 bytes src/hi32-app-kscope.png | Bin 0 -> 1828 bytes src/historypage.cpp | 124 + src/historypage.h | 72 + src/historyview.cpp | 124 + src/historyview.h | 91 + src/kscope.cpp | 1754 ++++++ src/kscope.desktop | 12 + src/kscope.h | 235 + src/kscope.lsm | 16 + src/kscope_config | 165 + src/kscopeactions.cpp | 533 ++ src/kscopeactions.h | 98 + src/kscopeconfig.cpp | 768 +++ src/kscopeconfig.h | 218 + src/kscopepixmaps.cpp | 376 ++ src/kscopepixmaps.h | 77 + src/kscopeui.rc | 141 + src/lo16-app-kscope.png | Bin 0 -> 326 bytes src/lo32-app-kscope.png | Bin 0 -> 308 bytes src/main.cpp | 97 + src/makedlg.cpp | 267 + src/makedlg.h | 78 + src/makefrontend.cpp | 134 + src/makefrontend.h | 61 + src/makelayout.ui | 245 + src/newprojectdlg.cpp | 354 ++ src/newprojectdlg.h | 112 + src/newprojectlayout.ui | 778 +++ src/openprojectdlg.cpp | 131 + src/openprojectdlg.h | 61 + src/openprojectlayout.ui | 202 + src/prefcolor.cpp | 172 + src/prefcolor.h | 59 + src/prefcolorlayout.ui | 69 + src/preferencesdlg.cpp | 206 + src/preferencesdlg.h | 93 + src/preffont.cpp | 174 + src/preffont.h | 60 + src/preffontlayout.ui | 69 + src/preffrontend.cpp | 238 + src/preffrontend.h | 65 + src/preffrontendlayout.ui | 193 + src/prefopt.cpp | 145 + src/prefopt.h | 58 + src/prefoptlayout.ui | 217 + src/progressdlg.cpp | 116 + src/progressdlg.h | 66 + src/project.cpp | 442 ++ src/project.h | 92 + src/projectbase.cpp | 190 + src/projectbase.h | 281 + src/projectfilesdlg.cpp | 439 ++ src/projectfilesdlg.h | 104 + src/projectfileslayout.ui | 201 + src/projectmanager.cpp | 180 + src/projectmanager.h | 56 + src/query_locked.png | Bin 0 -> 774 bytes src/query_unlocked.png | Bin 0 -> 923 bytes src/querypage.cpp | 211 + src/querypage.h | 86 + src/querypagebase.cpp | 194 + src/querypagebase.h | 148 + src/queryresultsmenu.cpp | 170 + src/queryresultsmenu.h | 110 + src/queryview.cpp | 444 ++ src/queryview.h | 217 + src/queryviewdlg.cpp | 111 + src/queryviewdlg.h | 88 + src/queryviewdriver.cpp | 180 + src/queryviewdriver.h | 84 + src/queryviewlayout.ui | 167 + src/querywidget.cpp | 601 ++ src/querywidget.h | 152 + src/querywidgetlayout.ui | 62 + src/scanprogressdlg.cpp | 82 + src/scanprogressdlg.h | 69 + src/scanprogresslayout.ui | 115 + src/searchlist.cpp | 270 + src/searchlist.h | 144 + src/searchresultsdlg.cpp | 160 + src/searchresultsdlg.h | 74 + src/searchresultslayout.ui | 214 + src/symbolcompletion.cpp | 344 ++ src/symbolcompletion.h | 195 + src/symboldlg.cpp | 334 + src/symboldlg.h | 91 + src/symbollayout.ui | 297 + src/tab_list.png | Bin 0 -> 279 bytes src/tabwidget.cpp | 84 + src/tabwidget.h | 59 + src/treewidget.cpp | 260 + src/treewidget.h | 82 + src/welcomedlg.ui | 126 + stamp-h.in | 0 subdirs | 3 + templates/cpp | 26 + templates/h | 26 + 204 files changed, 46362 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Doxyfile create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100644 config.h.in create mode 100644 configure.files create mode 100644 configure.in create mode 100644 configure.in.in create mode 100644 doc/Makefile.am create mode 100644 doc/en/Makefile.am create mode 100644 doc/en/about.docbook create mode 100644 doc/en/autocomp_dlg.png create mode 100644 doc/en/bookmarks.docbook create mode 100644 doc/en/bookmarks.png create mode 100644 doc/en/call_graph.png create mode 100644 doc/en/call_tree.png create mode 100644 doc/en/config_dlg.docbook create mode 100644 doc/en/editing.docbook create mode 100644 doc/en/index.docbook create mode 100644 doc/en/main_menu.docbook create mode 100644 doc/en/main_window.docbook create mode 100644 doc/en/main_window.png create mode 100644 doc/en/pos_history.docbook create mode 100644 doc/en/pref_clrs.png create mode 100644 doc/en/pref_fonts.png create mode 100644 doc/en/pref_opts.png create mode 100644 doc/en/pref_progs.png create mode 100644 doc/en/project_details.png create mode 100644 doc/en/project_files.png create mode 100644 doc/en/project_make.png create mode 100644 doc/en/project_open.png create mode 100644 doc/en/project_opts.png create mode 100644 doc/en/project_types.png create mode 100644 doc/en/projects.docbook create mode 100644 doc/en/query_dlg.png create mode 100644 doc/en/query_filter.png create mode 100644 doc/en/query_system.docbook create mode 100644 doc/en/quick_start.docbook create mode 100644 po/Makefile.am create mode 100644 po/kscope.pot create mode 100644 po/zh_CN.po create mode 100644 src/Makefile.am create mode 100644 src/autocompletionlayout.ui create mode 100644 src/bookmark.png create mode 100644 src/bookmarksdlg.cpp create mode 100644 src/bookmarksdlg.h create mode 100644 src/bookmarkslayout.ui create mode 100644 src/call_graph.png create mode 100644 src/called_tree.png create mode 100644 src/calling_tree.png create mode 100644 src/calltreedlg.cpp create mode 100644 src/calltreedlg.h create mode 100644 src/calltreelayout.ui create mode 100644 src/calltreemanager.cpp create mode 100644 src/calltreemanager.h create mode 100644 src/configfrontend.cpp create mode 100644 src/configfrontend.h create mode 100644 src/cscopefrontend.cpp create mode 100644 src/cscopefrontend.h create mode 100644 src/cscopemsgdlg.cpp create mode 100644 src/cscopemsgdlg.h create mode 100644 src/cscopemsglayout.ui create mode 100644 src/ctagsfrontend.cpp create mode 100644 src/ctagsfrontend.h create mode 100644 src/ctagslist.cpp create mode 100644 src/ctagslist.h create mode 100644 src/dirscanner.cpp create mode 100644 src/dirscanner.h create mode 100644 src/dotfrontend.cpp create mode 100644 src/dotfrontend.h create mode 100644 src/dotparse.ypp create mode 100644 src/dotscan.lpp create mode 100644 src/editormanager.cpp create mode 100644 src/editormanager.h create mode 100644 src/editorpage.cpp create mode 100644 src/editorpage.h create mode 100644 src/editortabs.cpp create mode 100644 src/editortabs.h create mode 100644 src/encoder.cpp create mode 100644 src/encoder.h create mode 100644 src/file_ro.png create mode 100644 src/file_rw.png create mode 100644 src/file_save.png create mode 100644 src/filelist.cpp create mode 100644 src/filelist.h create mode 100644 src/fileview.cpp create mode 100644 src/fileview.h create mode 100644 src/fileviewlayout.ui create mode 100644 src/frontend.cpp create mode 100644 src/frontend.h create mode 100644 src/graphedge.cpp create mode 100644 src/graphedge.h create mode 100644 src/graphnode.cpp create mode 100644 src/graphnode.h create mode 100644 src/graphprefdlg.cpp create mode 100644 src/graphprefdlg.h create mode 100644 src/graphpreflayout.ui create mode 100644 src/graphwidget.cpp create mode 100644 src/graphwidget.h create mode 100644 src/hi16-app-kscope.png create mode 100644 src/hi32-app-kscope.png create mode 100644 src/historypage.cpp create mode 100644 src/historypage.h create mode 100644 src/historyview.cpp create mode 100644 src/historyview.h create mode 100644 src/kscope.cpp create mode 100644 src/kscope.desktop create mode 100644 src/kscope.h create mode 100644 src/kscope.lsm create mode 100644 src/kscope_config create mode 100644 src/kscopeactions.cpp create mode 100644 src/kscopeactions.h create mode 100644 src/kscopeconfig.cpp create mode 100644 src/kscopeconfig.h create mode 100644 src/kscopepixmaps.cpp create mode 100644 src/kscopepixmaps.h create mode 100644 src/kscopeui.rc create mode 100644 src/lo16-app-kscope.png create mode 100644 src/lo32-app-kscope.png create mode 100644 src/main.cpp create mode 100644 src/makedlg.cpp create mode 100644 src/makedlg.h create mode 100644 src/makefrontend.cpp create mode 100644 src/makefrontend.h create mode 100644 src/makelayout.ui create mode 100644 src/newprojectdlg.cpp create mode 100644 src/newprojectdlg.h create mode 100644 src/newprojectlayout.ui create mode 100644 src/openprojectdlg.cpp create mode 100644 src/openprojectdlg.h create mode 100644 src/openprojectlayout.ui create mode 100644 src/prefcolor.cpp create mode 100644 src/prefcolor.h create mode 100644 src/prefcolorlayout.ui create mode 100644 src/preferencesdlg.cpp create mode 100644 src/preferencesdlg.h create mode 100644 src/preffont.cpp create mode 100644 src/preffont.h create mode 100644 src/preffontlayout.ui create mode 100644 src/preffrontend.cpp create mode 100644 src/preffrontend.h create mode 100644 src/preffrontendlayout.ui create mode 100644 src/prefopt.cpp create mode 100644 src/prefopt.h create mode 100644 src/prefoptlayout.ui create mode 100644 src/progressdlg.cpp create mode 100644 src/progressdlg.h create mode 100644 src/project.cpp create mode 100644 src/project.h create mode 100644 src/projectbase.cpp create mode 100644 src/projectbase.h create mode 100644 src/projectfilesdlg.cpp create mode 100644 src/projectfilesdlg.h create mode 100644 src/projectfileslayout.ui create mode 100644 src/projectmanager.cpp create mode 100644 src/projectmanager.h create mode 100644 src/query_locked.png create mode 100644 src/query_unlocked.png create mode 100644 src/querypage.cpp create mode 100644 src/querypage.h create mode 100644 src/querypagebase.cpp create mode 100644 src/querypagebase.h create mode 100644 src/queryresultsmenu.cpp create mode 100644 src/queryresultsmenu.h create mode 100644 src/queryview.cpp create mode 100644 src/queryview.h create mode 100644 src/queryviewdlg.cpp create mode 100644 src/queryviewdlg.h create mode 100644 src/queryviewdriver.cpp create mode 100644 src/queryviewdriver.h create mode 100644 src/queryviewlayout.ui create mode 100644 src/querywidget.cpp create mode 100644 src/querywidget.h create mode 100644 src/querywidgetlayout.ui create mode 100644 src/scanprogressdlg.cpp create mode 100644 src/scanprogressdlg.h create mode 100644 src/scanprogresslayout.ui create mode 100644 src/searchlist.cpp create mode 100644 src/searchlist.h create mode 100644 src/searchresultsdlg.cpp create mode 100644 src/searchresultsdlg.h create mode 100644 src/searchresultslayout.ui create mode 100644 src/symbolcompletion.cpp create mode 100644 src/symbolcompletion.h create mode 100644 src/symboldlg.cpp create mode 100644 src/symboldlg.h create mode 100644 src/symbollayout.ui create mode 100644 src/tab_list.png create mode 100644 src/tabwidget.cpp create mode 100644 src/tabwidget.h create mode 100644 src/treewidget.cpp create mode 100644 src/treewidget.h create mode 100644 src/welcomedlg.ui create mode 100644 stamp-h.in create mode 100644 subdirs create mode 100644 templates/cpp create mode 100644 templates/h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..347a597 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Elad Lahav diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..1c86e1a --- /dev/null +++ b/COPYING @@ -0,0 +1,20 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. 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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. \ No newline at end of file diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..6e6f7c9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,408 @@ +1.6.2 (?) + +* New: Support for hidden project folders under the source root +* Bug fix: Make the configuration script sh-friendly +* Bug fix: Handle unicode characters on gcc's output +* Bug fix: KScope crashes when clicking on empty area in the tree view +* Bug fix: Do not show the "Function" column in the error list +* Bug fix: Do not close KScope when choosing "Cancel" in the "Save Files?" + message box + +1.6.1 (9-Jan-2008) + +* New: Support for case-insensitive queries +* New: Per-project Ctags command line (for advanced users only) +* Bug fix: Stop queries when their result windows are destroyed +* Bug fix: Query results sorted by line numbers are sorted numerically +* Translation: Chinese + +1.6.0 (10-Jul-2007) + +* Improved: Updated the documentation +* Improved: Implemented multiple-call nodes in the call-graph +* Improved: Workspace toolbar buttons re-arranged +* Improved: Hitting Enter in the "Open Project" dialogue's list of + recent projects opens the selected project +* Bug fix: Handle file extensions correctly in the file list +* Bug fix: Avoid hanging status bar messages when a project is closed +* Bug fix: Prevent infinite loops in the file finder in the presence of + recursive symbolic links +* Bug fix: Child windows should not disappear when dialogues are invoked +* Bug fix: Added padding to the call graph, to avoid chopped-off drawing + of nodes close to the borders +* Bug fix: Honour the preferred font when drawing the graph +* Bug fix: Delete temporary dot files used for drawing graphs +* Bug fix: Save call-tree files when a project is closed +* Bug fix: Clean-up a project's directory name after it is created + +1.5.2 (7-May-2007) + +* New: Useable global bookmarks system +* Improved: Better infrastructure for handling projects +* Improved: The soure root is set in the project properties dialogue +* Improved: When saving a new file, the user is asked whether to include + it in the project +* Improved: New toolbar layout +* Improved: Temporary projects appear in the list of recently open + projects +* Improved: Load a temporary project's cscope.files file, if it exists +* Bug fix: Enable file/project menu items only when a file/project is + open +* Bug fix: Handle column numbers in make output +* Bug fix: Do not allow multiple instances of the same command in the + make history +* Bug fix: Dropped project semaphores (too much hassle for a minor + feature) +* Compilation fix: Support for automake 1.10 + +1.5.1 (15-Feb-2007) + +* Improved: Support for recursive builds (make changing directories) +* Improved: Show build errors/warnings on a separate list +* Bug fix: The main window was not activated when requesting a source + position in a child window (call tree or the make window) +* Bug fix: Maintain Call-tree child item order (by line) +* Bug fix: Build output occasionally mixed standard output with standard + error + +1.5.0 (6-Feb-2007) + +* New: Make front-end (Rudimentary) +* New: Global bookmarks list +* New: Support for Cscope's -c and -D command-line options (-D requires + a patch to Cscope) +* Improved: Detect Cscope's executable and capabilities on each load +* Improved: Graph windows are no longer top-level (can be minimised or + hidden behind the main window) +* Improved: Do not automatically open a project if it was already loaded + by another instance of KScope +* Improved: Show #include directives in the tag list +* Bug fix: Better calculation of the area defined by a graph arrow +* Bug fix: Files could not be found in the file list when using a common + root ($) + +1.4.3 (15-Jan-2007) + +* New: Option for negating filters on query result lists +* New: Command for setting the keyboard focus to the tag list +* Improved: Restrict tag/file list navigation to current search pattern +* Improved: Show goto labels in the tag list +* Bug fix: Crash due to in-edges not being removed along with a function +* Bug fix: Connected components disappeared after filtering calling/ + called functions +* Bug fix: Use only sh-style ouput redirection in kscope_config + +1.4.2 (16-Oct-2006) + +* New: Tool-tips for the project's file list +* New: "Find Definition" entry in the query-results popup menu +* Improved: Added '*.S' (kernel assembly files) to the list of standard + file types +* Improved: Some code clean-ups in the query-results popup menu +* Bug fix: All query results following a global definition were omitted + +1.4.1 (23-Aug-2006) + +* Improved: Speed-up result list filtering +* Improved: Keyboard shortcuts for the first entries in the Window menu +* Improved: Show assmebly labels in the tag list +* Bug fix: KScope crashes when a node is removed from the graph +* Bug fix: KScope crashes when Next/Previous Result is invoked on an + empty query results list +* Bug fix: Prevent whitespace in project names +* Bug fix: Add entries to the results query list in the right order +* Bug fix: Fixed several memory leaks + +1.4.0 (9-Aug-2006) + +* New: Option for sorting the file list when a project is loaded (on by + default) +* Improved: The documentation is now up to date +* Improved: Nicer layout for the "New Project" dialogue +* Improved: Corrections to the desktop file (thanks to Tom Albers) +* Improved: Close a project automatically before a new one is created +* Bug fix: Do not show the progress dialogue if building fails to start +* Compilation fix: Include stdlib.h in graphwidget.cpp +* Compilation fix: Support for autoconf 2.6x +* Compilation fix: Removed unnecessary options from the YACC source file +* Compilation fix: Abort configuration if lex/flex and yacc/bison are not + found + +1.3.4 (14-Apr-2006) + +* New: Use graphviz from the command-line (dot). Should finally solve _all_ + licensing issues +* New: Informative welcome message +* Improved: Allow multiple files on "File->Open..." +* Improved: Better tool-tips for the tag list +* Bug fix: KScope crashes after startup when attempting to set the cursor + to a non-existing line + +1.3.3 (5-Jan-2006) + +* License changed to BSD due to incompatibility between the GPL and the CPL + (graphviz) +* New: Multiple-view call graph/tree dialogue +* Improved: Function name is displayed first (consistent behaviour for query + views and call tree widgets) +* Improved: Updated to the latest KDE 'configure' template + +1.3.2 (16-Nov-2005) + +* New: Support for graphviz 2.6 +* Improved: The 'configure' script detects he graphviz version and build flags +* Improved: Better automatic configuration script for Cscope and Ctags +* Improved: Added 'exctags' to the search for exuberant-ctags (FreeBSD) +* Bug fix: Cursor set to the end of the line when jumping to a location in the + code +* Bug fix: Draw the call graph using the current DPI settings +* Bug fix: Automatic configuration script no longer depends on "source" (which + is not available for all shells) +* Bug fix: Editor GUI not merged upon opening a project if the selected file is + the last one loaded + +1.3.1 (14-Oct-2005) + +* New: "Save All" menu command (was not included in previous release, despite + a claim to the contrary) +* New: List and filter called/calling functions in the call graph +* New: Delete graph nodes +* New: Limit graph node in/out degree (requires latest Cscope CVS snapshot) +* Improved: Redesigned node menu in the graph widget +* Improved: All query result views share the same widget +* Improved: Session management remembers file locations and last open file + (thanks to Alexander Kern) +* Bug Fix: Delete graph files when they are no longer required (i.e., after + a graph dialogue is manually closed) +* Bug fix: Do not show a border around the graph (nasty fix, but it works) +* Bug fix: Nodes are now always drawn on top of edges +* Compilation fix: Use QPtrList instead of the deprecated QList +* Compilation fix: Should now compile with gcc 4.x + +1.3.0 (29-Jun-2005) + +* New: A new call graph based on the graphviz library +* New: Use a special dialogue for executing and displaying quick + definition queries +* New: Use the project's root in the file list (root directory replaced + by a $ symbol) +* Improved: Faster compilation through the inclusion of moc files +* Improved: Better organised menu and toolbars +* Improved: Quick definition does not write into the query widget + +1.2.0 (25-May-2005) + +* New: Keyboard shortcut for setting the focus to the file list +* Improved: Documentation is now up to date +* Improved: Use standard configuration actions +* Improved: Faster loading times for projects +* Bug fix: Incorrect sorting of the symbol history combo-box +* Bug fix: Query window hidden unnecessarily on some occasions +* Bug fix: A hidden query window is shown by the "Position History" menu + command +* Bug fix: Modifying non-project files triggered a database rebuild + +1.1.1 (17-Mar-2005) + +* New: A new tab widget that displays a popup-menu with all open tabs +* New: Automatic configuration of Cscope/Ctags paths and parameters +* New: Filter query results +* New: Tag list can be hidden +* Improved: Display unique entries in the completion list +* Improved: Two options for the editor's popup menu: Cscope actions embedded + in the editor's own menu, or the old-style KScope-only menu +* Improved: The process of closing all editor windows (explicitly, when closing a + project or when exiting KScope) is much faster +* Bug fix: Do not show a hidden query window when browsing through position + history +* Bug fix: Refreshing a locked query opened a new page +* Bug fix: Possibly wrong tag-highlighting if cursor was moved while Ctags is + working +* Compilation Fix: Compiles under KDE 3.2 again + +1.1.0 (1-Feb-2005) + +* New: Cross-reference database is rebuilt automatically +* New: Symbol completion (manual and automatic) +* New: Allow multiple queries to be issued simultaneously +* New: Query dialogue with symbol hinting, history, substring search option + and and the ability to change the query type +* New: System profiles (fast/slow) determine default settings for + time-consuming operations +* New: Multiple position history paths +* New: Postion history can be saved and restored +* New: Drag&Drop support +* New: Optional warnings when file is modified outside KScope (Supports Kate + part only) +* New: Call Tree support for both Called and Calling tree modes +* New: Call Tree save/restore support within the project +* New: Unobtrusive progress information for all Cscope queries +* New: Query results popup-menu for copying and removing items +* New: Menu option for showing/hiding the toolbar +* New: Configurable keyboard shortcuts +* Improved: More command line options +* Improved: External editor can be invoked in read-write mode +* Improved: Faster project load times (file list is not sorted by default) +* Bug fix: Symbol list last entry was not found +* Bug fix: Crashed when jumping to a new position and no pages are open +* Bug fix: Synchronise splitter sizes whenever a page gains focus +* Bug fix: Query dialogue suggested text did not check current character +* Bug fix: the progress information did not work with inverted index or + regular expressions + + +1.0 (7-Dec-2004) +* Bug fix: Selecting entries in the position history dialogue messes up the + history (thanks to Fekete Gabor) +* Bug fix: Double clicking a directory name in the file system tree view opens + an editor page (thanks to Fekete Gabor) +* Bug fix: "No source file found" message not detected since error output may + be broken (fix allows Cscope restart mechanism to be re-enabled) +* Bug fix: Return file-system root as the root directory of a temporary project +* Bug fix: Handle file names without an extension in the file list (thanks to + Anton G. Alvedro) +* Bug fix: Show the main window before loading the last project (fixes + problems with the width of the tag list) +* Bug fix: Use CTRL-5 for the EGrep pattern shortcut (CTRL-6 is already used + by Kate) +* Bug fix: Do not restart Cscope when a file of the wrong format is opened as + a cscope.out file +* Bug fix: Open editor pages were not found when using relative paths in + cscope.files (thanks to Chris Mason) +* Bug fix: Cannot rebuild database when working with temporary projects, + re-run Cscope instead (thanks to Chris Mason) +* Bug fix: Do not populate file tree recursively (may significantly + increase the project loading time) (thanks to Albert Yosher) +* Bug fix: Maximise main window before displaying the welcome message (on + first time usage) +* Bug fix: Empty position history was added if jumping when no files were + open (thanks to Fekete Gabor) +* Bug fix: Editor was not set to read-write mode if the edited file changed + its permission (thanks to Albert Yosher) +* Bug fix: Clean paths from '.' and '..' before opening a file (thanks to + Albert Yosher) +* Bug fix: KScope Crashes after applying new configuration if an empty query page + exists +* Bug fix: Use Ctrl-\ for a call tree (Ctrl-- is already used by Kate) +* Improved project loading process +* Made documentation compliant with KDE's conventions + +0.9 (14-Oct-2004) +* Option for using an external editor +* File-system tree-view +* Use application icons for tabs (for consistent look across themes) +* Option for shorter query captions (thanks to Fekete Gabor) +* Store current location before jumping (fixes position history behaviour) +* Show current file path in KScope's title bar +* Handle read-only files correctly +* Show a special tab icon for a read-only file +* Vim-style quick definition +* Bug fix: ignore Cscope's "Possible references retrieved" messages + (thanks to Fekete Gabor) +* Bug fix: report Cscope is working when rebuilding the cross-reference + database + +0.8 (2-Aug-2004) +* Select word from cursor position when initiating a query +* Show cursor position in status bar +* Highlight relevant tag based on cursor position +* Allow running KScope in read-only mode +* "Fonts" preference page +* "Options" preference page +* A "refresh query" command for the query pages +* Query file format changed to include query type and text (old files will + not be loaded) +* Bug fix: restore file icon to unchanged when all undo levels have been + applied (thanks to Fekete Gabor) +* Bug fix: better handling of the tag list width +* Bug fix: accept any file name containing "ctags" as the Ctags executable + (since Gentoo is using exuberant-ctags) +* Bug fix: files could not be reopened after "Close All Windows" (thanks to + Fekete Gabor) +* Bug fix: query window may be incorrectly hidden if query returns a + single record + +0.7 (15-Jun-2004) +* Restore project session (open files and locked queries) +* Lock/unlock queries +* Prompt to save files before any file is closed +* Use KTabWidget for both the Editors window and the Query window +* Mark modified files +* Show/hide the file list and the query window (thanks to Fekete Gabor) +* Save/restore main window layout +* Better Ctags support (using native Ctags files) +* Open Cscope.out files in temporary projects, also available from the + command line (thanks to Fekete Gabor) +* Removed sort buttons (requires further consideration) +* Tag list sorting order is saved +* Query page buttons to the right of the query widget +* Bug fix: project was not closed if program was terminated from the main + window's title-bar +* Bug fix: allow ctags-exuberant as the programme name for Ctags + +0.6 (21-Apr-2004) +* Adjusted to KDE 3.2 (previous versions are no longer supported) +* Implemented standard "New File" and "Open File" commands +* Line numbers are aligned to the right +* Display the type of each file in the file list +* Use unsigned int for the entry size in Frontend (fixes compiler warnings) +* Implemented Cscope's search for file query +* Files are opened automatically if only one record was returned by a query +* Close buttons for the editor tabs +* Display Cscope error messages in a modeless dialogue +* Basic navigation through position history +* Open last project on restart +* Option to build inverted index for projects (thanks to Fekete Gabor) +* Project properties dialogue +* Bug fix: calling for an including files query prompts for an EGrep pattern + (thanks to Fekete Gabor) +* Bug fix: program crashes on including files query +* Bug fix: set keyboard focus to editor when moving between tabs + +0.5 (3-Jan-2004) +* Moved project to KDevelop 3.0 format +* A new "Window" menu displaying a list of open files +* The full path name appears as a tool-tip on each editor tab +* Close buttons for query results windows +* Fixed Tab order in dialogues + +0.4 (9-Oct-2003) +* New integrated manual +* Project files dialogue (add/remove source files) +* Prompt for files when a project is empty +* Bug fix: Error in rebuild command to cscope (string too long) +* Bug fix: Directory names in the paths configuration were mistaken as legal + executable files +* Bug fix: The directory scanner did not clean its list between consecutive + searches (thanks to Craig Graham for this fix) +* Bug fix: Initial file count in the dir scanning progress dialogue showed + '123456' instead of '0' +* Prompt the user to close the active project before creating a new one +* Prevent the user from cancelling an already-finished query (i.e., while + results are written to the query window) + +0.3 (3-Aug-2003) +* Context menu for running queries from an editor window +* A dummy progress dialogue is displayed when progress information is + unavailable (simply to indicate that KScope is working) +* Bug fix: Mix-up between the "Calling functions" and "Called functions" in + the query page titles +* Bug fix: Only ".c" and ".h" files could be added to a project +* New query type: find #including files +* Inform the user when a query ends with no results +* Menu command to close the active project +* All query pages are removed when a project is closed + +0.2 (21-Jul-2003) +* Call tree window +* High-colour icons +* Sort buttons for the tag list +* Partial fix for the cursor positioning bug in Kate + +0.1 (3-Jul-2003) +* First public release +* Front-end to most CScope features +* Basic editing environment (multiple windows) +* Tag list for each open editor +* Multiple query windows +* Basic project management diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..beead8d --- /dev/null +++ b/Doxyfile @@ -0,0 +1,259 @@ +# Doxyfile 1.4.1-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = KScope +PROJECT_NUMBER = 1.3.3 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = src +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +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 = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = YES +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..02a4a07 --- /dev/null +++ b/INSTALL @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..cac2bf1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = $(TOPSUBDIRS) + +$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ; + +$(top_srcdir)/subdirs: + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs + +$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in + @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4 + +MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files + +package-messages: + $(MAKE) -f admin/Makefile.common package-messages + $(MAKE) -C po merge + +EXTRA_DIST = admin COPYING configure.in.in + +dist-hook: + cd $(top_distdir) && perl admin/am_edit -padmin + cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/README @@ -0,0 +1 @@ + diff --git a/TODO b/TODO new file mode 100644 index 0000000..0eb7e72 --- /dev/null +++ b/TODO @@ -0,0 +1,17 @@ +KScope TODO List +================ + +No. Problem Type Target Version +~~~ ~~~~~~~ ~~~~ ~~~~~~~~~~~~~~ + +01. Project bookmark infrastructure/GUI Feat ? + +02. "Find Next" in search lists Feat ? + +03. New call tree widget Feat ? + +04. Plugin architecture Feat ? + +05. New GUI Feat ? + * IDEAl-style main window (?) + * True MDI (?) diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..e6a6582 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,11345 @@ +## -*- autoconf -*- + +dnl This file is part of the KDE libraries/packages +dnl Copyright (C) 1997 Janos Farkas (chexum@shadow.banki.hu) +dnl (C) 1997,98,99 Stephan Kulow (coolo@kde.org) + +dnl This file is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Library General Public +dnl License as published by the Free Software Foundation; either +dnl version 2 of the License, or (at your option) any later version. + +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Library General Public License for more details. + +dnl You should have received a copy of the GNU Library General Public License +dnl along with this library; see the file COPYING.LIB. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +dnl Boston, MA 02110-1301, USA. + +dnl IMPORTANT NOTE: +dnl Please do not modify this file unless you expect your modifications to be +dnl carried into every other module in the repository. +dnl +dnl Single-module modifications are best placed in configure.in for kdelibs +dnl and kdebase or configure.in.in if present. + +# KDE_PATH_X_DIRECT +dnl Internal subroutine of AC_PATH_X. +dnl Set ac_x_includes and/or ac_x_libraries. +AC_DEFUN([KDE_PATH_X_DIRECT], +[ +AC_REQUIRE([KDE_CHECK_LIB64]) + +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. +AC_TRY_CPP([#include <$x_direct_test_include>], +[# We can compile using X headers with no special include directory. +ac_x_includes=], +[# Look for the header file in a standard set of common directories. +# Check X11 before X11Rn because it is often a symlink to the current release. + for ac_dir in \ + /usr/X11/include \ + /usr/X11R6/include \ + /usr/X11R5/include \ + /usr/X11R4/include \ + \ + /usr/include/X11 \ + /usr/include/X11R6 \ + /usr/include/X11R5 \ + /usr/include/X11R4 \ + \ + /usr/local/X11/include \ + /usr/local/X11R6/include \ + /usr/local/X11R5/include \ + /usr/local/X11R4/include \ + \ + /usr/local/include/X11 \ + /usr/local/include/X11R6 \ + /usr/local/include/X11R5 \ + /usr/local/include/X11R4 \ + \ + /usr/X386/include \ + /usr/x386/include \ + /usr/XFree86/include/X11 \ + \ + /usr/include \ + /usr/local/include \ + /usr/unsupported/include \ + /usr/athena/include \ + /usr/local/x11r5/include \ + /usr/lpp/Xamples/include \ + \ + /usr/openwin/include \ + /usr/openwin/share/include \ + ; \ + do + if test -r "$ac_dir/$x_direct_test_include"; then + ac_x_includes=$ac_dir + break + fi + done]) +fi # $ac_x_includes = NO + +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" +AC_TRY_LINK([#include ], [${x_direct_test_function}(1)], +[LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries=], +[LIBS="$ac_save_LIBS" +# First see if replacing the include by lib works. +# Check X11 before X11Rn because it is often a symlink to the current release. +for ac_dir in `echo "$ac_x_includes" | sed s/include/lib${kdelibsuff}/` \ + /usr/X11/lib${kdelibsuff} \ + /usr/X11R6/lib${kdelibsuff} \ + /usr/X11R5/lib${kdelibsuff} \ + /usr/X11R4/lib${kdelibsuff} \ + \ + /usr/lib${kdelibsuff}/X11 \ + /usr/lib${kdelibsuff}/X11R6 \ + /usr/lib${kdelibsuff}/X11R5 \ + /usr/lib${kdelibsuff}/X11R4 \ + \ + /usr/local/X11/lib${kdelibsuff} \ + /usr/local/X11R6/lib${kdelibsuff} \ + /usr/local/X11R5/lib${kdelibsuff} \ + /usr/local/X11R4/lib${kdelibsuff} \ + \ + /usr/local/lib${kdelibsuff}/X11 \ + /usr/local/lib${kdelibsuff}/X11R6 \ + /usr/local/lib${kdelibsuff}/X11R5 \ + /usr/local/lib${kdelibsuff}/X11R4 \ + \ + /usr/X386/lib${kdelibsuff} \ + /usr/x386/lib${kdelibsuff} \ + /usr/XFree86/lib${kdelibsuff}/X11 \ + \ + /usr/lib${kdelibsuff} \ + /usr/local/lib${kdelibsuff} \ + /usr/unsupported/lib${kdelibsuff} \ + /usr/athena/lib${kdelibsuff} \ + /usr/local/x11r5/lib${kdelibsuff} \ + /usr/lpp/Xamples/lib${kdelibsuff} \ + /lib/usr/lib${kdelibsuff}/X11 \ + \ + /usr/openwin/lib${kdelibsuff} \ + /usr/openwin/share/lib${kdelibsuff} \ + ; \ +do +dnl Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl; do + if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done]) +fi # $ac_x_libraries = NO +]) + + +dnl ------------------------------------------------------------------------ +dnl Find a file (or one of more files in a list of dirs) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_FIND_FILE], +[ +$3=NO +for i in $2; +do + for j in $1; + do + echo "configure: __oline__: $i/$j" >&AC_FD_CC + if test -r "$i/$j"; then + echo "taking that" >&AC_FD_CC + $3=$i + break 2 + fi + done +done +]) + +dnl KDE_FIND_PATH(program-name, variable-name, list-of-dirs, +dnl if-not-found, test-parameter, prepend-path) +dnl +dnl Look for program-name in list-of-dirs+$PATH. +dnl If prepend-path is set, look in $PATH+list-of-dirs instead. +dnl If found, $variable-name is set. If not, if-not-found is evaluated. +dnl test-parameter: if set, the program is executed with this arg, +dnl and only a successful exit code is required. +AC_DEFUN([KDE_FIND_PATH], +[ + AC_MSG_CHECKING([for $1]) + if test -n "$$2"; then + kde_cv_path="$$2"; + else + kde_cache=`echo $1 | sed 'y%./+-%__p_%'` + + AC_CACHE_VAL(kde_cv_path_$kde_cache, + [ + kde_cv_path="NONE" + kde_save_IFS=$IFS + IFS=':' + dirs="" + for dir in $PATH; do + dirs="$dirs $dir" + done + if test -z "$6"; then dnl Append dirs in PATH (default) + dirs="$3 $dirs" + else dnl Prepend dirs in PATH (if 6th arg is set) + dirs="$dirs $3" + fi + IFS=$kde_save_IFS + + for dir in $dirs; do + if test -x "$dir/$1"; then + if test -n "$5" + then + evalstr="$dir/$1 $5 2>&1 " + if eval $evalstr; then + kde_cv_path="$dir/$1" + break + fi + else + kde_cv_path="$dir/$1" + break + fi + fi + done + + eval "kde_cv_path_$kde_cache=$kde_cv_path" + + ]) + + eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" + + fi + + if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then + AC_MSG_RESULT(not found) + $4 + else + AC_MSG_RESULT($kde_cv_path) + $2=$kde_cv_path + + fi +]) + +AC_DEFUN([KDE_MOC_ERROR_MESSAGE], +[ + AC_MSG_ERROR([No Qt meta object compiler (moc) found! +Please check whether you installed Qt correctly. +You need to have a running moc binary. +configure tried to run $ac_cv_path_moc and the test didn't +succeed. If configure shouldn't have tried this one, set +the environment variable MOC to the right one before running +configure. +]) +]) + +AC_DEFUN([KDE_UIC_ERROR_MESSAGE], +[ + AC_MSG_WARN([No Qt ui compiler (uic) found! +Please check whether you installed Qt correctly. +You need to have a running uic binary. +configure tried to run $ac_cv_path_uic and the test didn't +succeed. If configure shouldn't have tried this one, set +the environment variable UIC to the right one before running +configure. +]) +]) + + +AC_DEFUN([KDE_CHECK_UIC_FLAG], +[ + AC_MSG_CHECKING([whether uic supports -$1 ]) + kde_cache=`echo $1 | sed 'y% .=/+-%____p_%'` + AC_CACHE_VAL(kde_cv_prog_uic_$kde_cache, + [ + cat >conftest.ui < +EOT + ac_uic_testrun="$UIC_PATH -$1 $2 conftest.ui >/dev/null" + if AC_TRY_EVAL(ac_uic_testrun); then + eval "kde_cv_prog_uic_$kde_cache=yes" + else + eval "kde_cv_prog_uic_$kde_cache=no" + fi + rm -f conftest* + ]) + + if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then + AC_MSG_RESULT([yes]) + : + $3 + else + AC_MSG_RESULT([no]) + : + $4 + fi +]) + + +dnl ------------------------------------------------------------------------ +dnl Find the meta object compiler and the ui compiler in the PATH, +dnl in $QTDIR/bin, and some more usual places +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_PATH_QT_MOC_UIC], +[ + AC_REQUIRE([KDE_CHECK_PERL]) + qt_bindirs="" + for dir in $kde_qt_dirs; do + qt_bindirs="$qt_bindirs $dir/bin $dir/src/moc" + done + qt_bindirs="$qt_bindirs /usr/bin /usr/X11R6/bin /usr/local/qt/bin" + if test ! "$ac_qt_bindir" = "NO"; then + qt_bindirs="$ac_qt_bindir $qt_bindirs" + fi + + KDE_FIND_PATH(moc, MOC, [$qt_bindirs], [KDE_MOC_ERROR_MESSAGE]) + if test -z "$UIC_NOT_NEEDED"; then + KDE_FIND_PATH(uic, UIC_PATH, [$qt_bindirs], [UIC_PATH=""]) + if test -z "$UIC_PATH" ; then + KDE_UIC_ERROR_MESSAGE + exit 1 + else + UIC=$UIC_PATH + + if test $kde_qtver = 3; then + KDE_CHECK_UIC_FLAG(L,[/nonexistent],ac_uic_supports_libpath=yes,ac_uic_supports_libpath=no) + KDE_CHECK_UIC_FLAG(nounload,,ac_uic_supports_nounload=yes,ac_uic_supports_nounload=no) + + if test x$ac_uic_supports_libpath = xyes; then + UIC="$UIC -L \$(kde_widgetdir)" + fi + if test x$ac_uic_supports_nounload = xyes; then + UIC="$UIC -nounload" + fi + fi + fi + else + UIC="echo uic not available: " + fi + + AC_SUBST(MOC) + AC_SUBST(UIC) + + UIC_TR="i18n" + if test $kde_qtver = 3; then + UIC_TR="tr2i18n" + fi + + AC_SUBST(UIC_TR) +]) + +AC_DEFUN([KDE_1_CHECK_PATHS], +[ + KDE_1_CHECK_PATH_HEADERS + + KDE_TEST_RPATH= + + if test -n "$USE_RPATH"; then + + if test -n "$kde_libraries"; then + KDE_TEST_RPATH="-R $kde_libraries" + fi + + if test -n "$qt_libraries"; then + KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries" + fi + + if test -n "$x_libraries"; then + KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries" + fi + + KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH" + fi + +AC_MSG_CHECKING([for KDE libraries installed]) +ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5' + +if AC_TRY_EVAL(ac_link) && test -s conftest; then + AC_MSG_RESULT(yes) +else + AC_MSG_ERROR([your system fails at linking a small KDE application! +Check, if your compiler is installed correctly and if you have used the +same compiler to compile Qt and kdelibs as you did use now. +For more details about this problem, look at the end of config.log.]) +fi + +if eval `KDEDIR= ./conftest 2>&5`; then + kde_result=done +else + kde_result=problems +fi + +KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log +kde_have_all_paths=yes + +KDE_SET_PATHS($kde_result) + +]) + +AC_DEFUN([KDE_SET_PATHS], +[ + kde_cv_all_paths="kde_have_all_paths=\"yes\" \ + kde_htmldir=\"$kde_htmldir\" \ + kde_appsdir=\"$kde_appsdir\" \ + kde_icondir=\"$kde_icondir\" \ + kde_sounddir=\"$kde_sounddir\" \ + kde_datadir=\"$kde_datadir\" \ + kde_locale=\"$kde_locale\" \ + kde_cgidir=\"$kde_cgidir\" \ + kde_confdir=\"$kde_confdir\" \ + kde_kcfgdir=\"$kde_kcfgdir\" \ + kde_mimedir=\"$kde_mimedir\" \ + kde_toolbardir=\"$kde_toolbardir\" \ + kde_wallpaperdir=\"$kde_wallpaperdir\" \ + kde_templatesdir=\"$kde_templatesdir\" \ + kde_bindir=\"$kde_bindir\" \ + kde_servicesdir=\"$kde_servicesdir\" \ + kde_servicetypesdir=\"$kde_servicetypesdir\" \ + kde_moduledir=\"$kde_moduledir\" \ + kde_styledir=\"$kde_styledir\" \ + kde_widgetdir=\"$kde_widgetdir\" \ + xdg_appsdir=\"$xdg_appsdir\" \ + xdg_menudir=\"$xdg_menudir\" \ + xdg_directorydir=\"$xdg_directorydir\" \ + kde_result=$1" +]) + +AC_DEFUN([KDE_SET_DEFAULT_PATHS], +[ +if test "$1" = "default"; then + + if test -z "$kde_htmldir"; then + kde_htmldir='\${datadir}/doc/HTML' + fi + if test -z "$kde_appsdir"; then + kde_appsdir='\${datadir}/applnk' + fi + if test -z "$kde_icondir"; then + kde_icondir='\${datadir}/icons' + fi + if test -z "$kde_sounddir"; then + kde_sounddir='\${datadir}/sounds' + fi + if test -z "$kde_datadir"; then + kde_datadir='\${datadir}/apps' + fi + if test -z "$kde_locale"; then + kde_locale='\${datadir}/locale' + fi + if test -z "$kde_cgidir"; then + kde_cgidir='\${exec_prefix}/cgi-bin' + fi + if test -z "$kde_confdir"; then + kde_confdir='\${datadir}/config' + fi + if test -z "$kde_kcfgdir"; then + kde_kcfgdir='\${datadir}/config.kcfg' + fi + if test -z "$kde_mimedir"; then + kde_mimedir='\${datadir}/mimelnk' + fi + if test -z "$kde_toolbardir"; then + kde_toolbardir='\${datadir}/toolbar' + fi + if test -z "$kde_wallpaperdir"; then + kde_wallpaperdir='\${datadir}/wallpapers' + fi + if test -z "$kde_templatesdir"; then + kde_templatesdir='\${datadir}/templates' + fi + if test -z "$kde_bindir"; then + kde_bindir='\${exec_prefix}/bin' + fi + if test -z "$kde_servicesdir"; then + kde_servicesdir='\${datadir}/services' + fi + if test -z "$kde_servicetypesdir"; then + kde_servicetypesdir='\${datadir}/servicetypes' + fi + if test -z "$kde_moduledir"; then + if test "$kde_qtver" = "2"; then + kde_moduledir='\${libdir}/kde2' + else + kde_moduledir='\${libdir}/kde3' + fi + fi + if test -z "$kde_styledir"; then + kde_styledir='\${libdir}/kde3/plugins/styles' + fi + if test -z "$kde_widgetdir"; then + kde_widgetdir='\${libdir}/kde3/plugins/designer' + fi + if test -z "$xdg_appsdir"; then + xdg_appsdir='\${datadir}/applications/kde' + fi + if test -z "$xdg_menudir"; then + xdg_menudir='\${sysconfdir}/xdg/menus' + fi + if test -z "$xdg_directorydir"; then + xdg_directorydir='\${datadir}/desktop-directories' + fi + + KDE_SET_PATHS(defaults) + +else + + if test $kde_qtver = 1; then + AC_MSG_RESULT([compiling]) + KDE_1_CHECK_PATHS + else + AC_MSG_ERROR([path checking not yet supported for KDE 2]) + fi + +fi +]) + +AC_DEFUN([KDE_CHECK_PATHS_FOR_COMPLETENESS], +[ if test -z "$kde_htmldir" || test -z "$kde_appsdir" || + test -z "$kde_icondir" || test -z "$kde_sounddir" || + test -z "$kde_datadir" || test -z "$kde_locale" || + test -z "$kde_cgidir" || test -z "$kde_confdir" || + test -z "$kde_kcfgdir" || + test -z "$kde_mimedir" || test -z "$kde_toolbardir" || + test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" || + test -z "$kde_bindir" || test -z "$kde_servicesdir" || + test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" || + test -z "$kde_styledir" || test -z "kde_widgetdir" || + test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_directorydir" || + test "x$kde_have_all_paths" != "xyes"; then + kde_have_all_paths=no + fi +]) + +AC_DEFUN([KDE_MISSING_PROG_ERROR], +[ + AC_MSG_ERROR([The important program $1 was not found! +Please check whether you installed KDE correctly. +]) +]) + +AC_DEFUN([KDE_MISSING_ARTS_ERROR], +[ + AC_MSG_ERROR([The important program $1 was not found! +Please check whether you installed aRts correctly or use +--without-arts to compile without aRts support (this will remove functionality). +]) +]) + +AC_DEFUN([KDE_SET_DEFAULT_BINDIRS], +[ + kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin" + test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs" + if test -n "$KDEDIRS"; then + kde_save_IFS=$IFS + IFS=: + for dir in $KDEDIRS; do + kde_default_bindirs="$dir/bin $kde_default_bindirs " + done + IFS=$kde_save_IFS + fi +]) + +AC_DEFUN([KDE_SUBST_PROGRAMS], +[ + AC_ARG_WITH(arts, + AC_HELP_STRING([--without-arts],[build without aRts [default=no]]), + [build_arts=$withval], + [build_arts=yes] + ) + AM_CONDITIONAL(include_ARTS, test "$build_arts" '!=' "no") + if test "$build_arts" = "no"; then + AC_DEFINE(WITHOUT_ARTS, 1, [Defined if compiling without arts]) + fi + + KDE_SET_DEFAULT_BINDIRS + kde_default_bindirs="$exec_prefix/bin $prefix/bin $kde_libs_prefix/bin $kde_default_bindirs" + KDE_FIND_PATH(dcopidl, DCOPIDL, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl)]) + KDE_FIND_PATH(dcopidl2cpp, DCOPIDL2CPP, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl2cpp)]) + if test "$build_arts" '!=' "no"; then + KDE_FIND_PATH(mcopidl, MCOPIDL, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(mcopidl)]) + KDE_FIND_PATH(artsc-config, ARTSCCONFIG, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(artsc-config)]) + fi + KDE_FIND_PATH(meinproc, MEINPROC, [$kde_default_bindirs]) + + kde32ornewer=1 + kde33ornewer=1 + if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then + kde32ornewer= + kde33ornewer= + else + if test "$kde_qtver" = "3"; then + if test "$kde_qtsubver" -le 1; then + kde32ornewer= + fi + if test "$kde_qtsubver" -le 2; then + kde33ornewer= + fi + if test "$KDECONFIG" != "compiled"; then + if test `$KDECONFIG --version | grep KDE | sed 's/KDE: \(...\).*/\1/'` = 3.2; then + kde33ornewer= + fi + fi + fi + fi + + if test -n "$kde32ornewer"; then + KDE_FIND_PATH(kconfig_compiler, KCONFIG_COMPILER, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kconfig_compiler)]) + KDE_FIND_PATH(dcopidlng, DCOPIDLNG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidlng)]) + fi + if test -n "$kde33ornewer"; then + KDE_FIND_PATH(makekdewidgets, MAKEKDEWIDGETS, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(makekdewidgets)]) + AC_SUBST(MAKEKDEWIDGETS) + fi + KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin], [XMLLINT=""]) + + if test -n "$MEINPROC" -a "$MEINPROC" != "compiled"; then + kde_sharedirs="/usr/share/kde /usr/local/share /usr/share /opt/kde3/share /opt/kde/share $prefix/share" + test -n "$KDEDIR" && kde_sharedirs="$KDEDIR/share $kde_sharedirs" + AC_FIND_FILE(apps/ksgmltools2/customization/kde-chunk.xsl, $kde_sharedirs, KDE_XSL_STYLESHEET) + if test "$KDE_XSL_STYLESHEET" = "NO"; then + KDE_XSL_STYLESHEET="" + else + KDE_XSL_STYLESHEET="$KDE_XSL_STYLESHEET/apps/ksgmltools2/customization/kde-chunk.xsl" + fi + fi + + DCOP_DEPENDENCIES='$(DCOPIDL)' + if test -n "$kde32ornewer"; then + KCFG_DEPENDENCIES='$(KCONFIG_COMPILER)' + DCOP_DEPENDENCIES='$(DCOPIDL) $(DCOPIDLNG)' + AC_SUBST(KCONFIG_COMPILER) + AC_SUBST(KCFG_DEPENDENCIES) + AC_SUBST(DCOPIDLNG) + fi + AC_SUBST(DCOPIDL) + AC_SUBST(DCOPIDL2CPP) + AC_SUBST(DCOP_DEPENDENCIES) + AC_SUBST(MCOPIDL) + AC_SUBST(ARTSCCONFIG) + AC_SUBST(MEINPROC) + AC_SUBST(KDE_XSL_STYLESHEET) + AC_SUBST(XMLLINT) +])dnl + +AC_DEFUN([AC_CREATE_KFSSTND], +[ +AC_REQUIRE([AC_CHECK_RPATH]) + +AC_MSG_CHECKING([for KDE paths]) +kde_result="" +kde_cached_paths=yes +AC_CACHE_VAL(kde_cv_all_paths, +[ + KDE_SET_DEFAULT_PATHS($1) + kde_cached_paths=no +]) +eval "$kde_cv_all_paths" +KDE_CHECK_PATHS_FOR_COMPLETENESS +if test "$kde_have_all_paths" = "no" && test "$kde_cached_paths" = "yes"; then + # wrong values were cached, may be, we can set better ones + kde_result= + kde_htmldir= kde_appsdir= kde_icondir= kde_sounddir= + kde_datadir= kde_locale= kde_cgidir= kde_confdir= kde_kcfgdir= + kde_mimedir= kde_toolbardir= kde_wallpaperdir= kde_templatesdir= + kde_bindir= kde_servicesdir= kde_servicetypesdir= kde_moduledir= + kde_have_all_paths= + kde_styledir= + kde_widgetdir= + xdg_appsdir = xdg_menudir= xdg_directorydir= + KDE_SET_DEFAULT_PATHS($1) + eval "$kde_cv_all_paths" + KDE_CHECK_PATHS_FOR_COMPLETENESS + kde_result="$kde_result (cache overridden)" +fi +if test "$kde_have_all_paths" = "no"; then + AC_MSG_ERROR([configure could not run a little KDE program to test the environment. +Since it had compiled and linked before, it must be a strange problem on your system. +Look at config.log for details. If you are not able to fix this, look at +http://www.kde.org/faq/installation.html or any www.kde.org mirror. +(If you're using an egcs version on Linux, you may update binutils!) +]) +else + rm -f conftest* + AC_MSG_RESULT($kde_result) +fi + +bindir=$kde_bindir + +KDE_SUBST_PROGRAMS + +]) + +AC_DEFUN([AC_SUBST_KFSSTND], +[ +AC_SUBST(kde_htmldir) +AC_SUBST(kde_appsdir) +AC_SUBST(kde_icondir) +AC_SUBST(kde_sounddir) +AC_SUBST(kde_datadir) +AC_SUBST(kde_locale) +AC_SUBST(kde_confdir) +AC_SUBST(kde_kcfgdir) +AC_SUBST(kde_mimedir) +AC_SUBST(kde_wallpaperdir) +AC_SUBST(kde_bindir) +dnl X Desktop Group standards +AC_SUBST(xdg_appsdir) +AC_SUBST(xdg_menudir) +AC_SUBST(xdg_directorydir) +dnl for KDE 2 +AC_SUBST(kde_templatesdir) +AC_SUBST(kde_servicesdir) +AC_SUBST(kde_servicetypesdir) +AC_SUBST(kde_moduledir) +AC_SUBST(kdeinitdir, '$(kde_moduledir)') +AC_SUBST(kde_styledir) +AC_SUBST(kde_widgetdir) +if test "$kde_qtver" = 1; then + kde_minidir="$kde_icondir/mini" +else +# for KDE 1 - this breaks KDE2 apps using minidir, but +# that's the plan ;-/ + kde_minidir="/dev/null" +fi +dnl AC_SUBST(kde_minidir) +dnl AC_SUBST(kde_cgidir) +dnl AC_SUBST(kde_toolbardir) +]) + +AC_DEFUN([KDE_MISC_TESTS], +[ + dnl Checks for libraries. + AC_CHECK_LIB(util, main, [LIBUTIL="-lutil"]) dnl for *BSD + AC_SUBST(LIBUTIL) + AC_CHECK_LIB(compat, main, [LIBCOMPAT="-lcompat"]) dnl for *BSD + AC_SUBST(LIBCOMPAT) + kde_have_crypt= + AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"; kde_have_crypt=yes], + AC_CHECK_LIB(c, crypt, [kde_have_crypt=yes], [ + AC_MSG_WARN([you have no crypt in either libcrypt or libc. +You should install libcrypt from another source or configure with PAM +support]) + kde_have_crypt=no + ])) + AC_SUBST(LIBCRYPT) + if test $kde_have_crypt = yes; then + AC_DEFINE_UNQUOTED(HAVE_CRYPT, 1, [Defines if your system has the crypt function]) + fi + AC_CHECK_SOCKLEN_T + AC_CHECK_LIB(dnet, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"]) + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + AC_CHECK_LIB(dnet_stub, dnet_ntoa, + [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"]) + fi + AC_CHECK_FUNC(inet_ntoa) + if test $ac_cv_func_inet_ntoa = no; then + AC_CHECK_LIB(nsl, inet_ntoa, X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl") + fi + AC_CHECK_FUNC(connect) + if test $ac_cv_func_connect = no; then + AC_CHECK_LIB(socket, connect, X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS", , + $X_EXTRA_LIBS) + fi + + AC_CHECK_FUNC(remove) + if test $ac_cv_func_remove = no; then + AC_CHECK_LIB(posix, remove, X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix") + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + AC_CHECK_FUNC(shmat, , + AC_CHECK_LIB(ipc, shmat, X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc")) + + # more headers that need to be explicitly included on darwin + AC_CHECK_HEADERS(sys/types.h stdint.h) + + # sys/bitypes.h is needed for uint32_t and friends on Tru64 + AC_CHECK_HEADERS(sys/bitypes.h) + + # darwin requires a poll emulation library + AC_CHECK_LIB(poll, poll, LIB_POLL="-lpoll") + + # for some image handling on Mac OS X + AC_CHECK_HEADERS(Carbon/Carbon.h) + + # CoreAudio framework + AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [ + AC_DEFINE(HAVE_COREAUDIO, 1, [Define if you have the CoreAudio API]) + FRAMEWORK_COREAUDIO="-Xlinker -framework -Xlinker CoreAudio" + ]) + + AC_CHECK_RES_INIT + AC_SUBST(LIB_POLL) + AC_SUBST(FRAMEWORK_COREAUDIO) + LIBSOCKET="$X_EXTRA_LIBS" + AC_SUBST(LIBSOCKET) + AC_SUBST(X_EXTRA_LIBS) + AC_CHECK_LIB(ucb, killpg, [LIBUCB="-lucb"]) dnl for Solaris2.4 + AC_SUBST(LIBUCB) + + case $host in dnl this *is* LynxOS specific + *-*-lynxos* ) + AC_MSG_CHECKING([LynxOS header file wrappers]) + [CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"] + AC_MSG_RESULT(disabled) + AC_CHECK_LIB(bsd, gethostbyname, [LIBSOCKET="-lbsd"]) dnl for LynxOS + ;; + esac + + KDE_CHECK_TYPES + KDE_CHECK_LIBDL + KDE_CHECK_STRLCPY + KDE_CHECK_PIE_SUPPORT + +# darwin needs this to initialize the environment +AC_CHECK_HEADERS(crt_externs.h) +AC_CHECK_FUNC(_NSGetEnviron, [AC_DEFINE(HAVE_NSGETENVIRON, 1, [Define if your system needs _NSGetEnviron to set up the environment])]) + +AH_VERBATIM(_DARWIN_ENVIRON, +[ +#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) +# include +# include +# define environ (*_NSGetEnviron()) +#endif +]) + +AH_VERBATIM(_AIX_STRINGS_H_BZERO, +[ +/* + * AIX defines FD_SET in terms of bzero, but fails to include + * that defines bzero. + */ + +#if defined(_AIX) +#include +#endif +]) + +AC_CHECK_FUNCS([vsnprintf snprintf]) + +AH_VERBATIM(_TRU64,[ +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +#if !defined(HAVE_VSNPRINTF) || defined(hpux) +#if __STDC__ +#include +#include +#else +#include +#endif +#ifdef __cplusplus +extern "C" +#endif +int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); +#ifdef __cplusplus +extern "C" +#endif +int snprintf(char *str, size_t n, char const *fmt, ...); +#endif +]) + +]) + +dnl ------------------------------------------------------------------------ +dnl Find the header files and libraries for X-Windows. Extended the +dnl macro AC_PATH_X +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([K_PATH_X], +[ +AC_REQUIRE([KDE_MISC_TESTS])dnl +AC_REQUIRE([KDE_CHECK_LIB64]) + +AC_ARG_ENABLE( + embedded, + AC_HELP_STRING([--enable-embedded],[link to Qt-embedded, don't use X]), + kde_use_qt_emb=$enableval, + kde_use_qt_emb=no +) + +AC_ARG_ENABLE( + qtopia, + AC_HELP_STRING([--enable-qtopia],[link to Qt-embedded, link to the Qtopia Environment]), + kde_use_qt_emb_palm=$enableval, + kde_use_qt_emb_palm=no +) + +AC_ARG_ENABLE( + mac, + AC_HELP_STRING([--enable-mac],[link to Qt/Mac (don't use X)]), + kde_use_qt_mac=$enableval, + kde_use_qt_mac=no +) + +# used to disable x11-specific stuff on special platforms +AM_CONDITIONAL(include_x11, test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no") + +if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then + +AC_MSG_CHECKING(for X) + +AC_CACHE_VAL(kde_cv_have_x, +[# One or both of the vars are not set, and there is no cached value. +if test "{$x_includes+set}" = set || test "$x_includes" = NONE; then + kde_x_includes=NO +else + kde_x_includes=$x_includes +fi +if test "{$x_libraries+set}" = set || test "$x_libraries" = NONE; then + kde_x_libraries=NO +else + kde_x_libraries=$x_libraries +fi + +# below we use the standard autoconf calls +ac_x_libraries=$kde_x_libraries +ac_x_includes=$kde_x_includes + +KDE_PATH_X_DIRECT +dnl AC_PATH_X_XMKMF picks /usr/lib as the path for the X libraries. +dnl Unfortunately, if compiling with the N32 ABI, this is not the correct +dnl location. The correct location is /usr/lib32 or an undefined value +dnl (the linker is smart enough to pick the correct default library). +dnl Things work just fine if you use just AC_PATH_X_DIRECT. +dnl Solaris has a similar problem. AC_PATH_X_XMKMF forces x_includes to +dnl /usr/openwin/include, which doesn't work. /usr/include does work, so +dnl x_includes should be left alone. +case "$host" in +mips-sgi-irix6*) + ;; +*-*-solaris*) + ;; +*) + _AC_PATH_X_XMKMF + if test -z "$ac_x_includes"; then + ac_x_includes="." + fi + if test -z "$ac_x_libraries"; then + ac_x_libraries="/usr/lib${kdelibsuff}" + fi +esac +#from now on we use our own again + +# when the user already gave --x-includes, we ignore +# what the standard autoconf macros told us. +if test "$kde_x_includes" = NO; then + kde_x_includes=$ac_x_includes +fi + +# for --x-libraries too +if test "$kde_x_libraries" = NO; then + kde_x_libraries=$ac_x_libraries +fi + +if test "$kde_x_includes" = NO; then + AC_MSG_ERROR([Can't find X includes. Please check your installation and add the correct paths!]) +fi + +if test "$kde_x_libraries" = NO; then + AC_MSG_ERROR([Can't find X libraries. Please check your installation and add the correct paths!]) +fi + +# Record where we found X for the cache. +kde_cv_have_x="have_x=yes \ + kde_x_includes=$kde_x_includes kde_x_libraries=$kde_x_libraries" +])dnl + +eval "$kde_cv_have_x" + +if test "$have_x" != yes; then + AC_MSG_RESULT($have_x) + no_x=yes +else + AC_MSG_RESULT([libraries $kde_x_libraries, headers $kde_x_includes]) +fi + +if test -z "$kde_x_includes" || test "x$kde_x_includes" = xNONE; then + X_INCLUDES="" + x_includes="."; dnl better than nothing :- + else + x_includes=$kde_x_includes + X_INCLUDES="-I$x_includes" +fi + +if test -z "$kde_x_libraries" || test "x$kde_x_libraries" = xNONE; then + X_LDFLAGS="" + x_libraries="/usr/lib"; dnl better than nothing :- + else + x_libraries=$kde_x_libraries + X_LDFLAGS="-L$x_libraries" +fi +all_includes="$X_INCLUDES" +all_libraries="$X_LDFLAGS $LDFLAGS_AS_NEEDED $LDFLAGS_NEW_DTAGS" + +# Check for libraries that X11R6 Xt/Xaw programs need. +ac_save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $X_LDFLAGS" +# SM needs ICE to (dynamically) link under SunOS 4.x (so we have to +# check for ICE first), but we must link in the order -lSM -lICE or +# we get undefined symbols. So assume we have SM if we have ICE. +# These have to be linked with before -lX11, unlike the other +# libraries we check for below, so use a different variable. +# --interran@uluru.Stanford.EDU, kb@cs.umb.edu. +AC_CHECK_LIB(ICE, IceConnectionNumber, + [LIBSM="-lSM -lICE"], , $X_EXTRA_LIBS) +LDFLAGS="$ac_save_LDFLAGS" + +LIB_X11='-lX11 $(LIBSOCKET)' + +AC_MSG_CHECKING(for libXext) +AC_CACHE_VAL(kde_cv_have_libXext, +[ +kde_ldflags_safe="$LDFLAGS" +kde_libs_safe="$LIBS" + +LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS" +LIBS="-lXext -lX11 $LIBSOCKET" + +AC_TRY_LINK([ +#include +#ifdef STDC_HEADERS +# include +#endif +], +[ +printf("hello Xext\n"); +], +kde_cv_have_libXext=yes, +kde_cv_have_libXext=no +) + +LDFLAGS=$kde_ldflags_safe +LIBS=$kde_libs_safe +]) + +AC_MSG_RESULT($kde_cv_have_libXext) + +if test "$kde_cv_have_libXext" = "no"; then + AC_MSG_ERROR([We need a working libXext to proceed. Since configure +can't find it itself, we stop here assuming that make wouldn't find +them either.]) +fi + +LIB_XEXT="-lXext" +QTE_NORTTI="" + +elif test "$kde_use_qt_emb" = "yes"; then + dnl We're using QT Embedded + CPPFLAGS=-DQWS + CXXFLAGS="$CXXFLAGS -fno-rtti" + QTE_NORTTI="-fno-rtti -DQWS" + X_PRE_LIBS="" + LIB_X11="" + LIB_XEXT="" + LIB_XRENDER="" + LIBSM="" + X_INCLUDES="" + X_LDFLAGS="" + x_includes="" + x_libraries="" +elif test "$kde_use_qt_mac" = "yes"; then + dnl We're using QT/Mac (I use QT_MAC so that qglobal.h doesn't *have* to + dnl be included to get the information) --Sam + CXXFLAGS="$CXXFLAGS -DQT_MAC -no-cpp-precomp" + CFLAGS="$CFLAGS -DQT_MAC -no-cpp-precomp" + X_PRE_LIBS="" + LIB_X11="" + LIB_XEXT="" + LIB_XRENDER="" + LIBSM="" + X_INCLUDES="" + X_LDFLAGS="" + x_includes="" + x_libraries="" +fi +AC_SUBST(X_PRE_LIBS) +AC_SUBST(LIB_X11) +AC_SUBST(LIB_XRENDER) +AC_SUBST(LIBSM) +AC_SUBST(X_INCLUDES) +AC_SUBST(X_LDFLAGS) +AC_SUBST(x_includes) +AC_SUBST(x_libraries) +AC_SUBST(QTE_NORTTI) +AC_SUBST(LIB_XEXT) + +]) + +AC_DEFUN([KDE_PRINT_QT_PROGRAM], +[ +AC_REQUIRE([KDE_USE_QT]) +cat > conftest.$ac_ext < +#include +EOF +if test "$kde_qtver" = "2"; then +cat >> conftest.$ac_ext < +#include +#include +EOF + +if test $kde_qtsubver -gt 0; then +cat >> conftest.$ac_ext <> conftest.$ac_ext < +#include +#include +EOF +fi + +echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext +cat >> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <&AC_FD_CC + cat conftest.$ac_ext >&AC_FD_CC +fi + +rm -f conftest* +CXXFLAGS="$ac_cxxflags_safe" +LDFLAGS="$ac_ldflags_safe" +LIBS="$ac_libs_safe" + +LD_LIBRARY_PATH="$ac_LD_LIBRARY_PATH_safe" +export LD_LIBRARY_PATH +LIBRARY_PATH="$ac_LIBRARY_PATH" +export LIBRARY_PATH +AC_LANG_RESTORE +]) + +if test "$kde_cv_qt_direct" = "yes"; then + AC_MSG_RESULT(yes) + $1 +else + AC_MSG_RESULT(no) + $2 +fi +]) + +dnl ------------------------------------------------------------------------ +dnl Try to find the Qt headers and libraries. +dnl $(QT_LDFLAGS) will be -Lqtliblocation (if needed) +dnl and $(QT_INCLUDES) will be -Iqthdrlocation (if needed) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_PATH_QT_1_3], +[ +AC_REQUIRE([K_PATH_X]) +AC_REQUIRE([KDE_USE_QT]) +AC_REQUIRE([KDE_CHECK_LIB64]) + +dnl ------------------------------------------------------------------------ +dnl Add configure flag to enable linking to MT version of Qt library. +dnl ------------------------------------------------------------------------ + +AC_ARG_ENABLE( + mt, + AC_HELP_STRING([--disable-mt],[link to non-threaded Qt (deprecated)]), + kde_use_qt_mt=$enableval, + [ + if test $kde_qtver = 3; then + kde_use_qt_mt=yes + else + kde_use_qt_mt=no + fi + ] +) + +USING_QT_MT="" + +dnl ------------------------------------------------------------------------ +dnl If we not get --disable-qt-mt then adjust some vars for the host. +dnl ------------------------------------------------------------------------ + +KDE_MT_LDFLAGS= +KDE_MT_LIBS= +if test "x$kde_use_qt_mt" = "xyes"; then + KDE_CHECK_THREADING + if test "x$kde_use_threading" = "xyes"; then + CPPFLAGS="$USE_THREADS -DQT_THREAD_SUPPORT $CPPFLAGS" + KDE_MT_LDFLAGS="$USE_THREADS" + KDE_MT_LIBS="$LIBPTHREAD" + else + kde_use_qt_mt=no + fi +fi +AC_SUBST(KDE_MT_LDFLAGS) +AC_SUBST(KDE_MT_LIBS) + +kde_qt_was_given=yes + +dnl ------------------------------------------------------------------------ +dnl If we haven't been told how to link to Qt, we work it out for ourselves. +dnl ------------------------------------------------------------------------ +if test -z "$LIBQT_GLOB"; then + if test "x$kde_use_qt_emb" = "xyes"; then + LIBQT_GLOB="libqte.*" + else + LIBQT_GLOB="libqt.*" + fi +fi + +dnl ------------------------------------------------------------ +dnl If we got --enable-embedded then adjust the Qt library name. +dnl ------------------------------------------------------------ +if test "x$kde_use_qt_emb" = "xyes"; then + qtlib="qte" +else + qtlib="qt" +fi + +kde_int_qt="-l$qtlib" + +if test -z "$LIBQPE"; then +dnl ------------------------------------------------------------ +dnl If we got --enable-palmtop then add -lqpe to the link line +dnl ------------------------------------------------------------ + if test "x$kde_use_qt_emb" = "xyes"; then + if test "x$kde_use_qt_emb_palm" = "xyes"; then + LIB_QPE="-lqpe" + else + LIB_QPE="" + fi + else + LIB_QPE="" + fi +fi + +dnl ------------------------------------------------------------------------ +dnl If we got --enable-qt-mt then adjust the Qt library name for the host. +dnl ------------------------------------------------------------------------ + +if test "x$kde_use_qt_mt" = "xyes"; then + LIBQT="-l$qtlib-mt" + kde_int_qt="-l$qtlib-mt" + LIBQT_GLOB="lib$qtlib-mt.*" + USING_QT_MT="using -mt" +else + LIBQT="-l$qtlib" +fi + +if test $kde_qtver != 1; then + + AC_REQUIRE([AC_FIND_PNG]) + AC_REQUIRE([AC_FIND_JPEG]) + LIBQT="$LIBQT $LIBPNG $LIBJPEG" +fi + +if test $kde_qtver = 3; then + AC_REQUIRE([KDE_CHECK_LIBDL]) + LIBQT="$LIBQT $LIBDL" +fi + +AC_MSG_CHECKING([for Qt]) + +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBQT="$LIBQT $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET" +fi +ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO +qt_libraries="" +qt_includes="" +AC_ARG_WITH(qt-dir, + AC_HELP_STRING([--with-qt-dir=DIR],[where the root of Qt is installed ]), + [ ac_qt_includes="$withval"/include + ac_qt_libraries="$withval"/lib${kdelibsuff} + ac_qt_bindir="$withval"/bin + ]) + +AC_ARG_WITH(qt-includes, + AC_HELP_STRING([--with-qt-includes=DIR],[where the Qt includes are. ]), + [ + ac_qt_includes="$withval" + ]) + +kde_qt_libs_given=no + +AC_ARG_WITH(qt-libraries, + AC_HELP_STRING([--with-qt-libraries=DIR],[where the Qt library is installed.]), + [ ac_qt_libraries="$withval" + kde_qt_libs_given=yes + ]) + +AC_CACHE_VAL(ac_cv_have_qt, +[#try to guess Qt locations + +qt_incdirs="" +for dir in $kde_qt_dirs; do + qt_incdirs="$qt_incdirs $dir/include $dir" +done +qt_incdirs="$QTINC $qt_incdirs /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/X11R6/include/qt2 /usr/include/qt3 $x_includes" +if test ! "$ac_qt_includes" = "NO"; then + qt_incdirs="$ac_qt_includes $qt_incdirs" +fi + +if test "$kde_qtver" != "1"; then + kde_qt_header=qstyle.h +else + kde_qt_header=qglobal.h +fi + +AC_FIND_FILE($kde_qt_header, $qt_incdirs, qt_incdir) +ac_qt_includes="$qt_incdir" + +qt_libdirs="" +for dir in $kde_qt_dirs; do + qt_libdirs="$qt_libdirs $dir/lib${kdelibsuff} $dir" +done +qt_libdirs="$QTLIB $qt_libdirs /usr/X11R6/lib /usr/lib /usr/local/qt/lib $x_libraries" +if test ! "$ac_qt_libraries" = "NO"; then + qt_libdir=$ac_qt_libraries +else + qt_libdirs="$ac_qt_libraries $qt_libdirs" + # if the Qt was given, the chance is too big that libqt.* doesn't exist + qt_libdir=NONE + for dir in $qt_libdirs; do + try="ls -1 $dir/${LIBQT_GLOB}" + if test -n "`$try 2> /dev/null`"; then qt_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi + done +fi +for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do + if test -e "$a"; then + LIBQT="$LIBQT ${kde_int_qt}_incremental" + break + fi +done + +ac_qt_libraries="$qt_libdir" + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +ac_cxxflags_safe="$CXXFLAGS" +ac_ldflags_safe="$LDFLAGS" +ac_libs_safe="$LIBS" + +CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" +LDFLAGS="$LDFLAGS -L$qt_libdir $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" +LIBS="$LIBS $LIBQT $KDE_MT_LIBS" + +KDE_PRINT_QT_PROGRAM + +if AC_TRY_EVAL(ac_link) && test -s conftest; then + rm -f conftest* +else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&AC_FD_CC + ac_qt_libraries="NO" +fi +rm -f conftest* +CXXFLAGS="$ac_cxxflags_safe" +LDFLAGS="$ac_ldflags_safe" +LIBS="$ac_libs_safe" + +AC_LANG_RESTORE +if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then + ac_cv_have_qt="have_qt=no" + ac_qt_notfound="" + missing_qt_mt="" + if test "$ac_qt_includes" = NO; then + if test "$ac_qt_libraries" = NO; then + ac_qt_notfound="(headers and libraries)"; + else + ac_qt_notfound="(headers)"; + fi + else + if test "x$kde_use_qt_mt" = "xyes"; then + missing_qt_mt=" +Make sure that you have compiled Qt with thread support!" + ac_qt_notfound="(library $qtlib-mt)"; + else + ac_qt_notfound="(library $qtlib)"; + fi + fi + + AC_MSG_ERROR([Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation! +For more details about this problem, look at the end of config.log.$missing_qt_mt]) +else + have_qt="yes" +fi +]) + +eval "$ac_cv_have_qt" + +if test "$have_qt" != yes; then + AC_MSG_RESULT([$have_qt]); +else + ac_cv_have_qt="have_qt=yes \ + ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries" + AC_MSG_RESULT([libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT]) + + qt_libraries="$ac_qt_libraries" + qt_includes="$ac_qt_includes" +fi + +if test ! "$kde_qt_libs_given" = "yes" && test ! "$kde_qtver" = 3; then + KDE_CHECK_QT_DIRECT(qt_libraries= ,[]) +fi + +AC_SUBST(qt_libraries) +AC_SUBST(qt_includes) + +if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then + QT_INCLUDES="" +else + QT_INCLUDES="-I$qt_includes" + all_includes="$QT_INCLUDES $all_includes" +fi + +if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then + QT_LDFLAGS="" +else + QT_LDFLAGS="-L$qt_libraries" + all_libraries="$QT_LDFLAGS $all_libraries" +fi +test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS" + +AC_SUBST(QT_INCLUDES) +AC_SUBST(QT_LDFLAGS) +AC_PATH_QT_MOC_UIC + +KDE_CHECK_QT_JPEG + +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)' +else +LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG)' +fi +test -z "$KDE_MT_LIBS" || LIB_QT="$LIB_QT $KDE_MT_LIBS" +for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do + if test -e "$a"; then + LIB_QT="$LIB_QT ${kde_int_qt}_incremental" + break + fi +done + +AC_SUBST(LIB_QT) +AC_SUBST(LIB_QPE) + +AC_SUBST(kde_qtver) +]) + +AC_DEFUN([AC_PATH_QT], +[ +AC_PATH_QT_1_3 +]) + +AC_DEFUN([KDE_CHECK_UIC_PLUGINS], +[ +AC_REQUIRE([AC_PATH_QT_MOC_UIC]) + +if test x$ac_uic_supports_libpath = xyes; then + +AC_MSG_CHECKING([if UIC has KDE plugins available]) +AC_CACHE_VAL(kde_cv_uic_plugins, +[ +cat > actest.ui << EOF + +NewConnectionDialog + + + + testInput + + + + +EOF + + + +kde_cv_uic_plugins=no +kde_line="$UIC_PATH -L $kde_widgetdir" +if test x$ac_uic_supports_nounload = xyes; then + kde_line="$kde_line -nounload" +fi +kde_line="$kde_line -impl actest.h actest.ui > actest.cpp" +if AC_TRY_EVAL(kde_line); then + # if you're trying to debug this check and think it's incorrect, + # better check your installation. The check _is_ correct - your + # installation is not. + if test -f actest.cpp && grep klineedit actest.cpp > /dev/null; then + kde_cv_uic_plugins=yes + fi +fi +rm -f actest.ui actest.cpp +]) + +AC_MSG_RESULT([$kde_cv_uic_plugins]) +if test "$kde_cv_uic_plugins" != yes; then + AC_MSG_ERROR([ +you need to install kdelibs first. + +If you did install kdelibs, then the Qt version that is picked up by +this configure is not the same version you used to compile kdelibs. +The Qt Plugin installed by kdelibs is *ONLY* loadable if it is the +_same Qt version_, compiled with the _same compiler_ and the same Qt +configuration settings. +]) +fi +fi +]) + +AC_DEFUN([KDE_CHECK_FINAL], +[ + AC_ARG_ENABLE(final, + AC_HELP_STRING([--enable-final], + [build size optimized apps (experimental - needs lots of memory)]), + kde_use_final=$enableval, kde_use_final=no) + + if test "x$kde_use_final" = "xyes"; then + KDE_USE_FINAL_TRUE="" + KDE_USE_FINAL_FALSE="#" + else + KDE_USE_FINAL_TRUE="#" + KDE_USE_FINAL_FALSE="" + fi + AC_SUBST(KDE_USE_FINAL_TRUE) + AC_SUBST(KDE_USE_FINAL_FALSE) +]) + +AC_DEFUN([KDE_CHECK_CLOSURE], +[ + AC_ARG_ENABLE(closure, + AC_HELP_STRING([--enable-closure],[delay template instantiation]), + kde_use_closure=$enableval, kde_use_closure=no) + + KDE_NO_UNDEFINED="" + if test "x$kde_use_closure" = "xyes"; then + KDE_USE_CLOSURE_TRUE="" + KDE_USE_CLOSURE_FALSE="#" +# CXXFLAGS="$CXXFLAGS $REPO" + else + KDE_USE_CLOSURE_TRUE="#" + KDE_USE_CLOSURE_FALSE="" + KDE_NO_UNDEFINED="" + case $host in + *-*-linux-gnu) + KDE_CHECK_COMPILER_FLAG([Wl,--no-undefined], + [KDE_CHECK_COMPILER_FLAG([Wl,--allow-shlib-undefined], + [KDE_NO_UNDEFINED="-Wl,--no-undefined -Wl,--allow-shlib-undefined"], + [KDE_NO_UNDEFINED=""])], + [KDE_NO_UNDEFINED=""]) + ;; + esac + fi + AC_SUBST(KDE_USE_CLOSURE_TRUE) + AC_SUBST(KDE_USE_CLOSURE_FALSE) + AC_SUBST(KDE_NO_UNDEFINED) +]) + +dnl Check if the linker supports --enable-new-dtags and --as-needed +AC_DEFUN([KDE_CHECK_NEW_LDFLAGS], +[ + AC_ARG_ENABLE(new_ldflags, + AC_HELP_STRING([--enable-new-ldflags], + [enable the new linker flags]), + kde_use_new_ldflags=$enableval, + kde_use_new_ldflags=no) + + LDFLAGS_AS_NEEDED="" + LDFLAGS_NEW_DTAGS="" + if test "x$kde_use_new_ldflags" = "xyes"; then + LDFLAGS_NEW_DTAGS="" + KDE_CHECK_COMPILER_FLAG([Wl,--enable-new-dtags], + [LDFLAGS_NEW_DTAGS="-Wl,--enable-new-dtags"],) + + KDE_CHECK_COMPILER_FLAG([Wl,--as-needed], + [LDFLAGS_AS_NEEDED="-Wl,--as-needed"],) + fi + AC_SUBST(LDFLAGS_AS_NEEDED) + AC_SUBST(LDFLAGS_NEW_DTAGS) +]) + +AC_DEFUN([KDE_CHECK_NMCHECK], +[ + AC_ARG_ENABLE(nmcheck,AC_HELP_STRING([--enable-nmcheck],[enable automatic namespace cleanness check]), + kde_use_nmcheck=$enableval, kde_use_nmcheck=no) + + if test "$kde_use_nmcheck" = "yes"; then + KDE_USE_NMCHECK_TRUE="" + KDE_USE_NMCHECK_FALSE="#" + else + KDE_USE_NMCHECK_TRUE="#" + KDE_USE_NMCHECK_FALSE="" + fi + AC_SUBST(KDE_USE_NMCHECK_TRUE) + AC_SUBST(KDE_USE_NMCHECK_FALSE) +]) + +AC_DEFUN([KDE_EXPAND_MAKEVAR], [ +savex=$exec_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +tmp=$$2 +while $1=`eval echo "$tmp"`; test "x$$1" != "x$tmp"; do tmp=$$1; done +exec_prefix=$savex +]) + +dnl ------------------------------------------------------------------------ +dnl Now, the same with KDE +dnl $(KDE_LDFLAGS) will be the kdeliblocation (if needed) +dnl and $(kde_includes) will be the kdehdrlocation (if needed) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_BASE_PATH_KDE], +[ +AC_REQUIRE([KDE_CHECK_STL]) +AC_REQUIRE([AC_PATH_QT])dnl +AC_REQUIRE([KDE_CHECK_LIB64]) + +AC_CHECK_RPATH +AC_MSG_CHECKING([for KDE]) + +if test "${prefix}" != NONE; then + kde_includes=${includedir} + KDE_EXPAND_MAKEVAR(ac_kde_includes, includedir) + + kde_libraries=${libdir} + KDE_EXPAND_MAKEVAR(ac_kde_libraries, libdir) + +else + ac_kde_includes= + ac_kde_libraries= + kde_libraries="" + kde_includes="" +fi + +AC_CACHE_VAL(ac_cv_have_kde, +[#try to guess kde locations + +if test "$kde_qtver" = 1; then + kde_check_header="ksock.h" + kde_check_lib="libkdecore.la" +else + kde_check_header="ksharedptr.h" + kde_check_lib="libkio.la" +fi + +if test -z "$1"; then + +kde_incdirs="$kde_libs_prefix/include /usr/lib/kde/include /usr/local/kde/include /usr/local/include /usr/kde/include /usr/include/kde /usr/include /opt/kde3/include /opt/kde/include $x_includes $qt_includes" +test -n "$KDEDIR" && kde_incdirs="$KDEDIR/include $KDEDIR/include/kde $KDEDIR $kde_incdirs" +kde_incdirs="$ac_kde_includes $kde_incdirs" +AC_FIND_FILE($kde_check_header, $kde_incdirs, kde_incdir) +ac_kde_includes="$kde_incdir" + +if test -n "$ac_kde_includes" && test ! -r "$ac_kde_includes/$kde_check_header"; then + AC_MSG_ERROR([ +in the prefix, you've chosen, are no KDE headers installed. This will fail. +So, check this please and use another prefix!]) +fi + +kde_libdirs="$kde_libs_prefix/lib${kdelibsuff} /usr/lib/kde/lib${kdelibsuff} /usr/local/kde/lib${kdelibsuff} /usr/kde/lib${kdelibsuff} /usr/lib${kdelibsuff}/kde /usr/lib${kdelibsuff}/kde3 /usr/lib${kdelibsuff} /usr/X11R6/lib${kdelibsuff} /usr/local/lib${kdelibsuff} /opt/kde3/lib${kdelibsuff} /opt/kde/lib${kdelibsuff} /usr/X11R6/kde/lib${kdelibsuff}" +test -n "$KDEDIR" && kde_libdirs="$KDEDIR/lib${kdelibsuff} $KDEDIR $kde_libdirs" +kde_libdirs="$ac_kde_libraries $libdir $kde_libdirs" +AC_FIND_FILE($kde_check_lib, $kde_libdirs, kde_libdir) +ac_kde_libraries="$kde_libdir" + +kde_widgetdir=NO +dnl this might be somewhere else +AC_FIND_FILE("kde3/plugins/designer/kdewidgets.la", $kde_libdirs, kde_widgetdir) + +if test -n "$ac_kde_libraries" && test ! -r "$ac_kde_libraries/$kde_check_lib"; then +AC_MSG_ERROR([ +in the prefix, you've chosen, are no KDE libraries installed. This will fail. +So, check this please and use another prefix!]) +fi + +if test -n "$kde_widgetdir" && test ! -r "$kde_widgetdir/kde3/plugins/designer/kdewidgets.la"; then +AC_MSG_ERROR([ +I can't find the designer plugins. These are required and should have been installed +by kdelibs]) +fi + +if test -n "$kde_widgetdir"; then + kde_widgetdir="$kde_widgetdir/kde3/plugins/designer" +fi + + +if test "$ac_kde_includes" = NO || test "$ac_kde_libraries" = NO || test "$kde_widgetdir" = NO; then + ac_cv_have_kde="have_kde=no" +else + ac_cv_have_kde="have_kde=yes \ + ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" +fi + +else dnl test -z $1, e.g. from kdelibs + + ac_cv_have_kde="have_kde=no" + +fi +])dnl + +eval "$ac_cv_have_kde" + +if test "$have_kde" != "yes"; then + if test "${prefix}" = NONE; then + ac_kde_prefix="$ac_default_prefix" + else + ac_kde_prefix="$prefix" + fi + if test "$exec_prefix" = NONE; then + ac_kde_exec_prefix="$ac_kde_prefix" + AC_MSG_RESULT([will be installed in $ac_kde_prefix]) + else + ac_kde_exec_prefix="$exec_prefix" + AC_MSG_RESULT([will be installed in $ac_kde_prefix and $ac_kde_exec_prefix]) + fi + + kde_libraries="${libdir}" + kde_includes="${includedir}" + +else + ac_cv_have_kde="have_kde=yes \ + ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" + AC_MSG_RESULT([libraries $ac_kde_libraries, headers $ac_kde_includes]) + + kde_libraries="$ac_kde_libraries" + kde_includes="$ac_kde_includes" +fi +AC_SUBST(kde_libraries) +AC_SUBST(kde_includes) + +if test "$kde_includes" = "$x_includes" || test "$kde_includes" = "$qt_includes" || test "$kde_includes" = "/usr/include"; then + KDE_INCLUDES="" +else + KDE_INCLUDES="-I$kde_includes" + all_includes="$KDE_INCLUDES $all_includes" +fi + +KDE_DEFAULT_CXXFLAGS="-DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION" + +KDE_LDFLAGS="-L$kde_libraries" +if test ! "$kde_libraries" = "$x_libraries" && test ! "$kde_libraries" = "$qt_libraries" ; then + all_libraries="$KDE_LDFLAGS $all_libraries" +fi + +AC_SUBST(KDE_LDFLAGS) +AC_SUBST(KDE_INCLUDES) + +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + +all_libraries="$all_libraries $USER_LDFLAGS" +all_includes="$all_includes $USER_INCLUDES" +AC_SUBST(all_includes) +AC_SUBST(all_libraries) + +if test -z "$1"; then +KDE_CHECK_UIC_PLUGINS +fi + +ac_kde_libraries="$kde_libdir" + +AC_SUBST(AUTODIRS) + + +]) + +AC_DEFUN([KDE_CHECK_EXTRA_LIBS], +[ +AC_MSG_CHECKING(for extra includes) +AC_ARG_WITH(extra-includes,AC_HELP_STRING([--with-extra-includes=DIR],[adds non standard include paths]), + kde_use_extra_includes="$withval", + kde_use_extra_includes=NONE +) +kde_extra_includes= +if test -n "$kde_use_extra_includes" && \ + test "$kde_use_extra_includes" != "NONE"; then + + ac_save_ifs=$IFS + IFS=':' + for dir in $kde_use_extra_includes; do + kde_extra_includes="$kde_extra_includes $dir" + USER_INCLUDES="$USER_INCLUDES -I$dir" + done + IFS=$ac_save_ifs + kde_use_extra_includes="added" +else + kde_use_extra_includes="no" +fi +AC_SUBST(USER_INCLUDES) + +AC_MSG_RESULT($kde_use_extra_includes) + +kde_extra_libs= +AC_MSG_CHECKING(for extra libs) +AC_ARG_WITH(extra-libs,AC_HELP_STRING([--with-extra-libs=DIR],[adds non standard library paths]), + kde_use_extra_libs=$withval, + kde_use_extra_libs=NONE +) +if test -n "$kde_use_extra_libs" && \ + test "$kde_use_extra_libs" != "NONE"; then + + ac_save_ifs=$IFS + IFS=':' + for dir in $kde_use_extra_libs; do + kde_extra_libs="$kde_extra_libs $dir" + KDE_EXTRA_RPATH="$KDE_EXTRA_RPATH -R $dir" + USER_LDFLAGS="$USER_LDFLAGS -L$dir" + done + IFS=$ac_save_ifs + kde_use_extra_libs="added" +else + kde_use_extra_libs="no" +fi + +AC_SUBST(USER_LDFLAGS) + +AC_MSG_RESULT($kde_use_extra_libs) + +]) + +AC_DEFUN([KDE_1_CHECK_PATH_HEADERS], +[ + AC_MSG_CHECKING([for KDE headers installed]) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS +cat > conftest.$ac_ext < +#endif +#include +#include "confdefs.h" +#include + +int main() { + printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data()); + printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data()); + printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data()); + printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data()); + printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data()); + printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data()); + printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data()); + printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data()); + printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data()); + printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data()); + printf("kde_wallpaperdir=\\"%s\\"\n", + KApplication::kde_wallpaperdir().data()); + printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data()); + printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data()); + printf("kde_servicesdir=\\"/tmp/dummy\\"\n"); + printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n"); + printf("kde_moduledir=\\"/tmp/dummy\\"\n"); + printf("kde_styledir=\\"/tmp/dummy\\"\n"); + printf("kde_widgetdir=\\"/tmp/dummy\\"\n"); + printf("xdg_appsdir=\\"/tmp/dummy\\"\n"); + printf("xdg_menudir=\\"/tmp/dummy\\"\n"); + printf("xdg_directorydir=\\"/tmp/dummy\\"\n"); + printf("kde_kcfgdir=\\"/tmp/dummy\\"\n"); + return 0; + } +EOF + + ac_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$all_includes $CPPFLAGS" + if AC_TRY_EVAL(ac_compile); then + AC_MSG_RESULT(yes) + else + AC_MSG_ERROR([your system is not able to compile a small KDE application! +Check, if you installed the KDE header files correctly. +For more details about this problem, look at the end of config.log.]) + fi + CPPFLAGS=$ac_save_CPPFLAGS + + AC_LANG_RESTORE +]) + +AC_DEFUN([KDE_CHECK_KDEQTADDON], +[ +AC_MSG_CHECKING(for kde-qt-addon) +AC_CACHE_VAL(kde_cv_have_kdeqtaddon, +[ + kde_ldflags_safe="$LDFLAGS" + kde_libs_safe="$LIBS" + kde_cxxflags_safe="$CXXFLAGS" + + LIBS="-lkde-qt-addon $LIBQT $LIBS" + CXXFLAGS="$CXXFLAGS -I$prefix/include -I$prefix/include/kde $all_includes" + LDFLAGS="$LDFLAGS $all_libraries $USER_LDFLAGS" + + AC_TRY_LINK([ + #include + ], + [ + QDomDocument doc; + ], + kde_cv_have_kdeqtaddon=yes, + kde_cv_have_kdeqtaddon=no + ) + + LDFLAGS=$kde_ldflags_safe + LIBS=$kde_libs_safe + CXXFLAGS=$kde_cxxflags_safe +]) + +AC_MSG_RESULT($kde_cv_have_kdeqtaddon) + +if test "$kde_cv_have_kdeqtaddon" = "no"; then + AC_MSG_ERROR([Can't find libkde-qt-addon. You need to install it first. +It is a separate package (and CVS module) named kde-qt-addon.]) +fi +]) + +AC_DEFUN([KDE_CREATE_LIBS_ALIASES], +[ + AC_REQUIRE([KDE_MISC_TESTS]) + AC_REQUIRE([KDE_CHECK_LIBDL]) + AC_REQUIRE([K_PATH_X]) + +if test $kde_qtver = 3; then + case $host in + *cygwin*) lib_kded="-lkdeinit_kded" ;; + *) lib_kded="" ;; + esac + AC_SUBST(LIB_KDED, $lib_kded) + AC_SUBST(LIB_KDECORE, "-lkdecore") + AC_SUBST(LIB_KDEUI, "-lkdeui") + AC_SUBST(LIB_KIO, "-lkio") + AC_SUBST(LIB_KJS, "-lkjs") + AC_SUBST(LIB_SMB, "-lsmb") + AC_SUBST(LIB_KAB, "-lkab") + AC_SUBST(LIB_KABC, "-lkabc") + AC_SUBST(LIB_KHTML, "-lkhtml") + AC_SUBST(LIB_KSPELL, "-lkspell") + AC_SUBST(LIB_KPARTS, "-lkparts") + AC_SUBST(LIB_KDEPRINT, "-lkdeprint") + AC_SUBST(LIB_KUTILS, "-lkutils") + AC_SUBST(LIB_KDEPIM, "-lkdepim") + AC_SUBST(LIB_KIMPROXY, "-lkimproxy") + AC_SUBST(LIB_KNEWSTUFF, "-lknewstuff") + AC_SUBST(LIB_KDNSSD, "-lkdnssd") + AC_SUBST(LIB_KUNITTEST, "-lkunittest") +# these are for backward compatibility + AC_SUBST(LIB_KSYCOCA, "-lkio") + AC_SUBST(LIB_KFILE, "-lkio") +elif test $kde_qtver = 2; then + AC_SUBST(LIB_KDECORE, "-lkdecore") + AC_SUBST(LIB_KDEUI, "-lkdeui") + AC_SUBST(LIB_KIO, "-lkio") + AC_SUBST(LIB_KSYCOCA, "-lksycoca") + AC_SUBST(LIB_SMB, "-lsmb") + AC_SUBST(LIB_KFILE, "-lkfile") + AC_SUBST(LIB_KAB, "-lkab") + AC_SUBST(LIB_KHTML, "-lkhtml") + AC_SUBST(LIB_KSPELL, "-lkspell") + AC_SUBST(LIB_KPARTS, "-lkparts") + AC_SUBST(LIB_KDEPRINT, "-lkdeprint") +else + AC_SUBST(LIB_KDECORE, "-lkdecore -lXext $(LIB_QT)") + AC_SUBST(LIB_KDEUI, "-lkdeui $(LIB_KDECORE)") + AC_SUBST(LIB_KFM, "-lkfm $(LIB_KDECORE)") + AC_SUBST(LIB_KFILE, "-lkfile $(LIB_KFM) $(LIB_KDEUI)") + AC_SUBST(LIB_KAB, "-lkab $(LIB_KIMGIO) $(LIB_KDECORE)") +fi +]) + +AC_DEFUN([AC_PATH_KDE], +[ + AC_BASE_PATH_KDE + AC_ARG_ENABLE(path-check,AC_HELP_STRING([--disable-path-check],[don't try to find out, where to install]), + [ + if test "$enableval" = "no"; + then ac_use_path_checking="default" + else ac_use_path_checking="" + fi + ], + [ + if test "$kde_qtver" = 1; + then ac_use_path_checking="" + else ac_use_path_checking="default" + fi + ] + ) + + AC_CREATE_KFSSTND($ac_use_path_checking) + + AC_SUBST_KFSSTND + KDE_CREATE_LIBS_ALIASES +]) + +dnl KDE_CHECK_FUNC_EXT(, [headers], [sample-use], [C prototype], [autoheader define], [call if found]) +AC_DEFUN([KDE_CHECK_FUNC_EXT], +[ +AC_MSG_CHECKING(for $1) +AC_CACHE_VAL(kde_cv_func_$1, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +save_CXXFLAGS="$CXXFLAGS" +kde_safe_LIBS="$LIBS" +LIBS="$LIBS $X_EXTRA_LIBS" +if test "$GXX" = "yes"; then +CXXFLAGS="$CXXFLAGS -pedantic-errors" +fi +AC_TRY_COMPILE([ +$2 +], +[ +$3 +], +kde_cv_func_$1=yes, +kde_cv_func_$1=no) +CXXFLAGS="$save_CXXFLAGS" +LIBS="$kde_safe_LIBS" +AC_LANG_RESTORE +]) + +AC_MSG_RESULT($kde_cv_func_$1) + +AC_MSG_CHECKING([if $1 needs custom prototype]) +AC_CACHE_VAL(kde_cv_proto_$1, +[ +if test "x$kde_cv_func_$1" = xyes; then + kde_cv_proto_$1=no +else + case "$1" in + setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat) + kde_cv_proto_$1="yes - in libkdefakes" + ;; + *) + kde_cv_proto_$1=unknown + ;; + esac +fi + +if test "x$kde_cv_proto_$1" = xunknown; then + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + kde_safe_libs=$LIBS + LIBS="$LIBS $X_EXTRA_LIBS" + AC_TRY_LINK([ +$2 + +extern "C" $4; +], +[ +$3 +], +[ kde_cv_func_$1=yes + kde_cv_proto_$1=yes ], + [kde_cv_proto_$1="$1 unavailable"] +) +LIBS=$kde_safe_libs +AC_LANG_RESTORE +fi +]) +AC_MSG_RESULT($kde_cv_proto_$1) + +if test "x$kde_cv_func_$1" = xyes; then + AC_DEFINE(HAVE_$5, 1, [Define if you have $1]) + $6 +fi +if test "x$kde_cv_proto_$1" = xno; then + AC_DEFINE(HAVE_$5_PROTO, 1, + [Define if you have the $1 prototype]) +fi + +AH_VERBATIM([_HAVE_$5_PROTO], +[ +#if !defined(HAVE_$5_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +$4; +#ifdef __cplusplus +} +#endif +#endif +]) +]) + +AC_DEFUN([AC_CHECK_SETENV], +[ + KDE_CHECK_FUNC_EXT(setenv, [ +#include +], + [setenv("VAR", "VALUE", 1);], + [int setenv (const char *, const char *, int)], + [SETENV]) +]) + +AC_DEFUN([AC_CHECK_UNSETENV], +[ + KDE_CHECK_FUNC_EXT(unsetenv, [ +#include +], + [unsetenv("VAR");], + [void unsetenv (const char *)], + [UNSETENV]) +]) + +AC_DEFUN([AC_CHECK_GETDOMAINNAME], +[ + KDE_CHECK_FUNC_EXT(getdomainname, [ +#include +#include +#include +], + [ +char buffer[200]; +getdomainname(buffer, 200); +], + [#include + int getdomainname (char *, size_t)], + [GETDOMAINNAME]) +]) + +AC_DEFUN([AC_CHECK_GETHOSTNAME], +[ + KDE_CHECK_FUNC_EXT(gethostname, [ +#include +#include +], + [ +char buffer[200]; +gethostname(buffer, 200); +], + [int gethostname (char *, unsigned int)], + [GETHOSTNAME]) +]) + +AC_DEFUN([AC_CHECK_USLEEP], +[ + KDE_CHECK_FUNC_EXT(usleep, [ +#include +], + [ +usleep(200); +], + [int usleep (unsigned int)], + [USLEEP]) +]) + + +AC_DEFUN([AC_CHECK_RANDOM], +[ + KDE_CHECK_FUNC_EXT(random, [ +#include +], + [ +random(); +], + [long int random(void)], + [RANDOM]) + + KDE_CHECK_FUNC_EXT(srandom, [ +#include +], + [ +srandom(27); +], + [void srandom(unsigned int)], + [SRANDOM]) + +]) + +AC_DEFUN([AC_CHECK_INITGROUPS], +[ + KDE_CHECK_FUNC_EXT(initgroups, [ +#include +#include +#include +], + [ +char buffer[200]; +initgroups(buffer, 27); +], + [int initgroups(const char *, gid_t)], + [INITGROUPS]) +]) + +AC_DEFUN([AC_CHECK_MKSTEMPS], +[ + KDE_CHECK_FUNC_EXT(mkstemps, [ +#include +#include +], + [ +mkstemps("/tmp/aaaXXXXXX", 6); +], + [int mkstemps(char *, int)], + [MKSTEMPS]) +]) + +AC_DEFUN([AC_CHECK_MKSTEMP], +[ + KDE_CHECK_FUNC_EXT(mkstemp, [ +#include +#include +], + [ +mkstemp("/tmp/aaaXXXXXX"); +], + [int mkstemp(char *)], + [MKSTEMP]) +]) + +AC_DEFUN([AC_CHECK_MKDTEMP], +[ + KDE_CHECK_FUNC_EXT(mkdtemp, [ +#include +#include +], + [ +mkdtemp("/tmp/aaaXXXXXX"); +], + [char *mkdtemp(char *)], + [MKDTEMP]) +]) + + +AC_DEFUN([AC_CHECK_RES_INIT], +[ + AC_MSG_CHECKING([if res_init needs -lresolv]) + kde_libs_safe="$LIBS" + LIBS="$LIBS $X_EXTRA_LIBS -lresolv" + AC_TRY_LINK( + [ +#include +#include +#include +#include + ], + [ + res_init(); + ], + [ + LIBRESOLV="-lresolv" + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_RES_INIT, 1, [Define if you have the res_init function]) + ], + [ AC_MSG_RESULT(no) ] + ) + LIBS=$kde_libs_safe + AC_SUBST(LIBRESOLV) + + KDE_CHECK_FUNC_EXT(res_init, + [ +#include +#include +#include +#include + ], + [res_init()], + [int res_init(void)], + [RES_INIT]) +]) + +AC_DEFUN([AC_CHECK_STRLCPY], +[ + KDE_CHECK_FUNC_EXT(strlcpy, [ +#include +], +[ char buf[20]; + strlcpy(buf, "KDE function test", sizeof(buf)); +], + [unsigned long strlcpy(char*, const char*, unsigned long)], + [STRLCPY]) +]) + +AC_DEFUN([AC_CHECK_STRLCAT], +[ + KDE_CHECK_FUNC_EXT(strlcat, [ +#include +], +[ char buf[20]; + buf[0]='\0'; + strlcat(buf, "KDE function test", sizeof(buf)); +], + [unsigned long strlcat(char*, const char*, unsigned long)], + [STRLCAT]) +]) + +AC_DEFUN([AC_CHECK_RES_QUERY], +[ + KDE_CHECK_FUNC_EXT(res_query, [ +#include +#include +#include +#include +#include +], +[ +res_query(NULL, 0, 0, NULL, 0); +], + [int res_query(const char *, int, int, unsigned char *, int)], + [RES_QUERY]) +]) + +AC_DEFUN([AC_CHECK_DN_SKIPNAME], +[ + KDE_CHECK_FUNC_EXT(dn_skipname, [ +#include +#include +#include +#include +], +[ +dn_skipname (NULL, NULL); +], + [int dn_skipname (unsigned char *, unsigned char *)], + [DN_SKIPNAME]) +]) + + +AC_DEFUN([AC_FIND_GIF], + [AC_MSG_CHECKING([for giflib]) +AC_CACHE_VAL(ac_cv_lib_gif, +[ac_save_LIBS="$LIBS" +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBS="$all_libraries -lgif -lX11 $LIBSOCKET" +else +LIBS="$all_libraries -lgif" +fi +AC_TRY_LINK(dnl +[ +#ifdef __cplusplus +extern "C" { +#endif +int GifLastError(void); +#ifdef __cplusplus +} +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +], + [return GifLastError();], + eval "ac_cv_lib_gif=yes", + eval "ac_cv_lib_gif=no") +LIBS="$ac_save_LIBS" +])dnl +if eval "test \"`echo $ac_cv_lib_gif`\" = yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_LIBGIF, 1, [Define if you have libgif]) +else + AC_MSG_ERROR(You need giflib30. Please install the kdesupport package) +fi +]) + +AC_DEFUN([KDE_FIND_JPEG_HELPER], +[ +AC_MSG_CHECKING([for libjpeg$2]) +AC_CACHE_VAL(ac_cv_lib_jpeg_$1, +[ +ac_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS -ljpeg$2 -lm" +ac_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK( +[ +#ifdef __cplusplus +extern "C" { +#endif +void jpeg_CreateDecompress(); +#ifdef __cplusplus +} +#endif +], +[jpeg_CreateDecompress();], + eval "ac_cv_lib_jpeg_$1=-ljpeg$2", + eval "ac_cv_lib_jpeg_$1=no") +LIBS="$ac_save_LIBS" +CFLAGS="$ac_save_CFLAGS" +]) + +if eval "test ! \"`echo $ac_cv_lib_jpeg_$1`\" = no"; then + LIBJPEG="$ac_cv_lib_jpeg_$1" + AC_MSG_RESULT($ac_cv_lib_jpeg_$1) +else + AC_MSG_RESULT(no) + $3 +fi + +]) + +AC_DEFUN([AC_FIND_JPEG], +[ +dnl first look for libraries +KDE_FIND_JPEG_HELPER(6b, 6b, + KDE_FIND_JPEG_HELPER(normal, [], + [ + LIBJPEG= + ] + ) +) + +dnl then search the headers (can't use simply AC_TRY_xxx, as jpeglib.h +dnl requires system dependent includes loaded before it) +jpeg_incdirs="$includedir /usr/include /usr/local/include $kde_extra_includes" +AC_FIND_FILE(jpeglib.h, $jpeg_incdirs, jpeg_incdir) +test "x$jpeg_incdir" = xNO && jpeg_incdir= + +dnl if headers _and_ libraries are missing, this is no error, and we +dnl continue with a warning (the user will get no jpeg support in khtml) +dnl if only one is missing, it means a configuration error, but we still +dnl only warn +if test -n "$jpeg_incdir" && test -n "$LIBJPEG" ; then + AC_DEFINE_UNQUOTED(HAVE_LIBJPEG, 1, [Define if you have libjpeg]) +else + if test -n "$jpeg_incdir" || test -n "$LIBJPEG" ; then + AC_MSG_WARN([ +There is an installation error in jpeg support. You seem to have only one +of either the headers _or_ the libraries installed. You may need to either +provide correct --with-extra-... options, or the development package of +libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/ +Disabling JPEG support. +]) + else + AC_MSG_WARN([libjpeg not found. disable JPEG support.]) + fi + jpeg_incdir= + LIBJPEG= +fi + +AC_SUBST(LIBJPEG) +AH_VERBATIM(_AC_CHECK_JPEG, +[/* + * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system + * headers and I'm too lazy to write a configure test as long as only + * unixware is related + */ +#ifdef _UNIXWARE +#define HAVE_BOOLEAN +#endif +]) +]) + +AC_DEFUN([KDE_CHECK_QT_JPEG], +[ +if test -n "$LIBJPEG"; then +AC_MSG_CHECKING([if Qt needs $LIBJPEG]) +AC_CACHE_VAL(kde_cv_qt_jpeg, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +ac_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS $LIBQT" +LIBS=`echo $LIBS | sed "s/$LIBJPEG//"` +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK( +[#include ], + [ + int argc; + char** argv; + QApplication app(argc, argv);], + eval "kde_cv_qt_jpeg=no", + eval "kde_cv_qt_jpeg=yes") +LIBS="$ac_save_LIBS" +CXXFLAGS="$ac_save_CXXFLAGS" +AC_LANG_RESTORE +fi +]) + +if eval "test ! \"`echo $kde_cv_qt_jpeg`\" = no"; then + AC_MSG_RESULT(yes) + LIBJPEG_QT='$(LIBJPEG)' +else + AC_MSG_RESULT(no) + LIBJPEG_QT= +fi + +]) + +AC_DEFUN([AC_FIND_ZLIB], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_MSG_CHECKING([for libz]) +AC_CACHE_VAL(ac_cv_lib_z, +[ +kde_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS -lz $LIBSOCKET" +kde_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK(dnl +[ +#include +], +[ + char buf[42]; + gzFile f = (gzFile) 0; + /* this would segfault.. but we only link, don't run */ + (void) gzgets(f, buf, sizeof(buf)); + + return (zlibVersion() == ZLIB_VERSION); +], + eval "ac_cv_lib_z='-lz'", + eval "ac_cv_lib_z=no") +LIBS="$kde_save_LIBS" +CFLAGS="$kde_save_CFLAGS" +])dnl +if test ! "$ac_cv_lib_z" = no; then + AC_DEFINE_UNQUOTED(HAVE_LIBZ, 1, [Define if you have libz]) + LIBZ="$ac_cv_lib_z" + AC_MSG_RESULT($ac_cv_lib_z) +else + AC_MSG_ERROR(not found. + Possibly configure picks up an outdated version + installed by XFree86. Remove it from your system. + + Check your installation and look into config.log) + LIBZ="" +fi +AC_SUBST(LIBZ) +]) + +AC_DEFUN([KDE_TRY_TIFFLIB], +[ +AC_MSG_CHECKING([for libtiff $1]) + +AC_CACHE_VAL(kde_cv_libtiff_$1, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +kde_save_LIBS="$LIBS" +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lX11 $LIBSOCKET -lm" +else +LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lm" +fi +kde_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" + +AC_TRY_LINK(dnl +[ +#include +], + [return (TIFFOpen( "", "r") == 0); ], +[ + kde_cv_libtiff_$1="-l$1 $LIBJPEG $LIBZ" +], [ + kde_cv_libtiff_$1=no +]) + +LIBS="$kde_save_LIBS" +CXXFLAGS="$kde_save_CXXFLAGS" +AC_LANG_RESTORE +]) + +if test "$kde_cv_libtiff_$1" = "no"; then + AC_MSG_RESULT(no) + LIBTIFF="" + $3 +else + LIBTIFF="$kde_cv_libtiff_$1" + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_LIBTIFF, 1, [Define if you have libtiff]) + $2 +fi + +]) + +AC_DEFUN([AC_FIND_TIFF], +[ +AC_REQUIRE([K_PATH_X]) +AC_REQUIRE([AC_FIND_ZLIB]) +AC_REQUIRE([AC_FIND_JPEG]) +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + +KDE_TRY_TIFFLIB(tiff, [], + KDE_TRY_TIFFLIB(tiff34)) + +AC_SUBST(LIBTIFF) +]) + +AC_DEFUN([KDE_FIND_LIBEXR], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_REQUIRE([AC_FIND_ZLIB]) +AC_CACHE_VAL(ac_cv_libexr, +[ + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + AC_MSG_CHECKING([for OpenEXR libraries]) + + if test "$PKG_CONFIG" = "no" ; then + AC_MSG_RESULT(no) + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + if !(`$PKG_CONFIG --exists OpenEXR`) ; then + AC_MSG_RESULT(no) + EXRSTATUS=no + else + if !(`$PKG_CONFIG --atleast-version="1.1.1" OpenEXR`) ; then + AC_MSG_RESULT(no) + EXRSTATUS=old + else + kde_save_LIBS="$LIBS" + LIBS="$LIBS $all_libraries $USER_LDFLAGS $LIBZ `pkg-config --libs OpenEXR`" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + kde_save_CXXFLAGS="$CXXFLAGS" + EXR_FLAGS=`$PKG_CONFIG --cflags OpenEXR` + CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES $EXR_FLAGS" + + AC_TRY_LINK(dnl + [ + #include + ], + [ + using namespace Imf; + RgbaInputFile file ("dummy"); + return 0; + ], + eval "ac_cv_libexr='`pkg-config --libs OpenEXR`'", + eval "ac_cv_libexr=no" + ) + LIBS="$kde_save_LIBS" + CXXFLAGS="$kde_save_CXXFLAGS" + AC_LANG_RESTORE + ])dnl + if eval "test ! \"`echo $ac_cv_libexr`\" = no"; then + AC_DEFINE_UNQUOTED(HAVE_EXR, 1, [Define if you have OpenEXR]) + LIB_EXR="$ac_cv_libexr" + AC_MSG_RESULT($ac_cv_libexr) + else + AC_MSG_RESULT(no) + LIB_EXR="" + fi + fi + fi + fi + AC_SUBST(LIB_EXR) + AC_SUBST(EXR_FLAGS) +]) + + + +AC_DEFUN([AC_FIND_PNG], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_REQUIRE([AC_FIND_ZLIB]) +AC_MSG_CHECKING([for libpng]) +AC_CACHE_VAL(ac_cv_lib_png, +[ +kde_save_LIBS="$LIBS" +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm -lX11 $LIBSOCKET" +else +LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm" +fi +kde_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" + +AC_TRY_LINK(dnl + [ + #include + ], + [ + png_structp png_ptr = png_create_read_struct( /* image ptr */ + PNG_LIBPNG_VER_STRING, 0, 0, 0 ); + return( png_ptr != 0 ); + ], + eval "ac_cv_lib_png='-lpng $LIBZ -lm'", + eval "ac_cv_lib_png=no" +) +LIBS="$kde_save_LIBS" +CFLAGS="$kde_save_CFLAGS" +])dnl +if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then + AC_DEFINE_UNQUOTED(HAVE_LIBPNG, 1, [Define if you have libpng]) + LIBPNG="$ac_cv_lib_png" + AC_SUBST(LIBPNG) + AC_MSG_RESULT($ac_cv_lib_png) +else + AC_MSG_RESULT(no) + LIBPNG="" + AC_SUBST(LIBPNG) +fi +]) + + +AC_DEFUN([AC_FIND_JASPER], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_REQUIRE([AC_FIND_JPEG]) +AC_MSG_CHECKING([for jasper]) +AC_CACHE_VAL(ac_cv_jasper, +[ +kde_save_LIBS="$LIBS" +LIBS="$LIBS $all_libraries $USER_LDFLAGS -ljasper $LIBJPEG -lm" +kde_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" + +AC_TRY_LINK(dnl + [ + #include + ], + [ + return( jas_init() ); + ], + eval "ac_cv_jasper='-ljasper $LIBJPEG -lm'", + eval "ac_cv_jasper=no" +) +LIBS="$kde_save_LIBS" +CFLAGS="$kde_save_CFLAGS" +])dnl +if eval "test ! \"`echo $ac_cv_jasper`\" = no"; then + AC_DEFINE_UNQUOTED(HAVE_JASPER, 1, [Define if you have jasper]) + LIB_JASPER="$ac_cv_jasper" + AC_MSG_RESULT($ac_cv_jasper) +else + AC_MSG_RESULT(no) + LIB_JASPER="" +fi +AC_SUBST(LIB_JASPER) +]) + +AC_DEFUN([AC_CHECK_BOOL], +[ + AC_DEFINE_UNQUOTED(HAVE_BOOL, 1, [You _must_ have bool]) +]) + +AC_DEFUN([AC_CHECK_GNU_EXTENSIONS], +[ +AC_MSG_CHECKING(if you need GNU extensions) +AC_CACHE_VAL(ac_cv_gnu_extensions, +[ +cat > conftest.c << EOF +#include + +#ifdef __GNU_LIBRARY__ +yes +#endif +EOF + +if (eval "$ac_cpp conftest.c") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_gnu_extensions=yes +else + ac_cv_gnu_extensions=no +fi +]) + +AC_MSG_RESULT($ac_cv_gnu_extensions) +if test "$ac_cv_gnu_extensions" = "yes"; then + AC_DEFINE_UNQUOTED(_GNU_SOURCE, 1, [Define if you need to use the GNU extensions]) +fi +]) + +AC_DEFUN([KDE_CHECK_COMPILER_FLAG], +[ +AC_MSG_CHECKING([whether $CXX supports -$1]) +kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'` +AC_CACHE_VAL(kde_cv_prog_cxx_$kde_cache, +[ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -$1" + AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cxx_$kde_cache=yes"], []) + CXXFLAGS="$save_CXXFLAGS" + AC_LANG_RESTORE +]) +if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then + AC_MSG_RESULT(yes) + : + $2 +else + AC_MSG_RESULT(no) + : + $3 +fi +]) + +AC_DEFUN([KDE_CHECK_C_COMPILER_FLAG], +[ +AC_MSG_CHECKING([whether $CC supports -$1]) +kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'` +AC_CACHE_VAL(kde_cv_prog_cc_$kde_cache, +[ + AC_LANG_SAVE + AC_LANG_C + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -$1" + AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cc_$kde_cache=yes"], []) + CFLAGS="$save_CFLAGS" + AC_LANG_RESTORE +]) +if eval "test \"`echo '$kde_cv_prog_cc_'$kde_cache`\" = yes"; then + AC_MSG_RESULT(yes) + : + $2 +else + AC_MSG_RESULT(no) + : + $3 +fi +]) + + +dnl AC_REMOVE_FORBIDDEN removes forbidden arguments from variables +dnl use: AC_REMOVE_FORBIDDEN(CC, [-forbid -bad-option whatever]) +dnl it's all white-space separated +AC_DEFUN([AC_REMOVE_FORBIDDEN], +[ __val=$$1 + __forbid=" $2 " + if test -n "$__val"; then + __new="" + ac_save_IFS=$IFS + IFS=" " + for i in $__val; do + case "$__forbid" in + *" $i "*) AC_MSG_WARN([found forbidden $i in $1, removing it]) ;; + *) # Careful to not add spaces, where there were none, because otherwise + # libtool gets confused, if we change e.g. CXX + if test -z "$__new" ; then __new=$i ; else __new="$__new $i" ; fi ;; + esac + done + IFS=$ac_save_IFS + $1=$__new + fi +]) + + +AC_DEFUN([KDE_CHECK_FOR_BAD_COMPILER], +[ + AC_MSG_CHECKING([whether $CC is blacklisted]) + + dnl In theory we have tu run this test against $CC and $CXX + dnl in C and in C++ mode, because its perfectly legal for + dnl the user to mix compiler versions, since C has a defined + dnl ABI. + dnl + dnl For now, we assume the user is not on crack. + + AC_TRY_COMPILE([ +#ifdef __GNUC__ +#if __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 0 +choke me +#endif +#endif +], , + kde_bad_compiler=no, + kde_bad_compiler=yes +) + + AC_MSG_RESULT($kde_bad_compiler) + +if test "$kde_bad_compiler" = "yes"; then + AC_MSG_ERROR([ + +This particular compiler version is blacklisted because it +is known to miscompile KDE. Please use a newer version, or +if that is not yet available, choose an older version. + +Please do not report a bug or bother us reporting this +configure error. We know about it, and we introduced +it by intention to avoid untraceable bugs or crashes in KDE. + +]) +fi + +]) + +dnl AC_VALIDIFY_CXXFLAGS checks for forbidden flags the user may have given +AC_DEFUN([AC_VALIDIFY_CXXFLAGS], +[dnl +if test "x$kde_use_qt_emb" != "xyes"; then + AC_REMOVE_FORBIDDEN(CXX, [-fno-rtti -rpath]) + AC_REMOVE_FORBIDDEN(CXXFLAGS, [-fno-rtti -rpath]) +else + AC_REMOVE_FORBIDDEN(CXX, [-rpath]) + AC_REMOVE_FORBIDDEN(CXXFLAGS, [-rpath]) +fi +]) + +AC_DEFUN([AC_CHECK_COMPILERS], +[ + AC_ARG_ENABLE(debug, + AC_HELP_STRING([--enable-debug=ARG],[enables debug symbols (yes|no|full) [default=no]]), + [ + case $enableval in + yes) + kde_use_debug_code="yes" + kde_use_debug_define=no + ;; + full) + kde_use_debug_code="full" + kde_use_debug_define=no + ;; + *) + kde_use_debug_code="no" + kde_use_debug_define=yes + ;; + esac + ], + [kde_use_debug_code="no" + kde_use_debug_define=no + ]) + + dnl Just for configure --help + AC_ARG_ENABLE(dummyoption, + AC_HELP_STRING([--disable-debug], + [disables debug output and debug symbols [default=no]]), + [],[]) + + AC_ARG_ENABLE(strict, + AC_HELP_STRING([--enable-strict], + [compiles with strict compiler options (may not work!)]), + [ + if test $enableval = "no"; then + kde_use_strict_options="no" + else + kde_use_strict_options="yes" + fi + ], [kde_use_strict_options="no"]) + + AC_ARG_ENABLE(warnings,AC_HELP_STRING([--disable-warnings],[disables compilation with -Wall and similar]), + [ + if test $enableval = "no"; then + kde_use_warnings="no" + else + kde_use_warnings="yes" + fi + ], [kde_use_warnings="yes"]) + + dnl enable warnings for debug build + if test "$kde_use_debug_code" != "no"; then + kde_use_warnings=yes + fi + + AC_ARG_ENABLE(profile,AC_HELP_STRING([--enable-profile],[creates profiling infos [default=no]]), + [kde_use_profiling=$enableval], + [kde_use_profiling="no"] + ) + + dnl this prevents stupid AC_PROG_CC to add "-g" to the default CFLAGS + CFLAGS=" $CFLAGS" + + AC_PROG_CC + + AC_PROG_CPP + + if test "$GCC" = "yes"; then + if test "$kde_use_debug_code" != "no"; then + if test $kde_use_debug_code = "full"; then + CFLAGS="-g3 -fno-inline $CFLAGS" + else + CFLAGS="-g -O2 $CFLAGS" + fi + else + CFLAGS="-O2 $CFLAGS" + fi + fi + + if test "$kde_use_debug_define" = "yes"; then + CFLAGS="-DNDEBUG $CFLAGS" + fi + + + case "$host" in + *-*-sysv4.2uw*) CFLAGS="-D_UNIXWARE $CFLAGS";; + *-*-sysv5uw7*) CFLAGS="-D_UNIXWARE7 $CFLAGS";; + esac + + if test -z "$LDFLAGS" && test "$kde_use_debug_code" = "no" && test "$GCC" = "yes"; then + LDFLAGS="" + fi + + CXXFLAGS=" $CXXFLAGS" + + AC_PROG_CXX + + KDE_CHECK_FOR_BAD_COMPILER + + if test "$GXX" = "yes" || test "$CXX" = "KCC"; then + if test "$kde_use_debug_code" != "no"; then + if test "$CXX" = "KCC"; then + CXXFLAGS="+K0 -Wall -pedantic -W -Wpointer-arith -Wwrite-strings $CXXFLAGS" + else + if test "$kde_use_debug_code" = "full"; then + CXXFLAGS="-g3 -fno-inline $CXXFLAGS" + else + CXXFLAGS="-g -O2 $CXXFLAGS" + fi + fi + KDE_CHECK_COMPILER_FLAG(fno-builtin,[CXXFLAGS="-fno-builtin $CXXFLAGS"]) + + dnl convenience compiler flags + KDE_CHECK_COMPILER_FLAG(Woverloaded-virtual, [WOVERLOADED_VIRTUAL="-Woverloaded-virtual"], [WOVERLOADED_VRITUAL=""]) + AC_SUBST(WOVERLOADED_VIRTUAL) + else + if test "$CXX" = "KCC"; then + CXXFLAGS="+K3 $CXXFLAGS" + else + CXXFLAGS="-O2 $CXXFLAGS" + fi + fi + fi + + if test "$kde_use_debug_define" = "yes"; then + CXXFLAGS="-DNDEBUG -DNO_DEBUG $CXXFLAGS" + fi + + if test "$kde_use_profiling" = "yes"; then + KDE_CHECK_COMPILER_FLAG(pg, + [ + CFLAGS="-pg $CFLAGS" + CXXFLAGS="-pg $CXXFLAGS" + ]) + fi + + if test "$kde_use_warnings" = "yes"; then + if test "$GCC" = "yes"; then + CXXFLAGS="-Wall -W -Wpointer-arith $CXXFLAGS" + case $host in + *-*-linux-gnu) + CFLAGS="-std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE $CFLAGS" + CXXFLAGS="-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts $CXXFLAGS" + KDE_CHECK_COMPILER_FLAG(Wmissing-format-attribute, [CXXFLAGS="$CXXFLAGS -Wformat-security -Wmissing-format-attribute"]) + KDE_CHECK_C_COMPILER_FLAG(Wmissing-format-attribute, [CFLAGS="$CFLAGS -Wformat-security -Wmissing-format-attribute"]) + ;; + esac + KDE_CHECK_COMPILER_FLAG(Wundef,[CXXFLAGS="-Wundef $CXXFLAGS"]) + KDE_CHECK_COMPILER_FLAG(Wno-long-long,[CXXFLAGS="-Wno-long-long $CXXFLAGS"]) + dnl ### FIXME: revert for KDE 4 + KDE_CHECK_COMPILER_FLAG(Wno-non-virtual-dtor,[CXXFLAGS="$CXXFLAGS -Wno-non-virtual-dtor"]) + fi + fi + + if test "$GXX" = "yes" && test "$kde_use_strict_options" = "yes"; then + CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS" + fi + + AC_ARG_ENABLE(pch, + AC_HELP_STRING([--enable-pch], + [enables precompiled header support (currently only KCC or gcc >=3.4+unsermake) [default=no]]), + [ kde_use_pch=$enableval ],[ kde_use_pch=no ]) + + HAVE_GCC_VISIBILITY=0 + AC_SUBST([HAVE_GCC_VISIBILITY]) + + if test "$GXX" = "yes"; then + KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"]) + KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"]) + KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"]) + KDE_CHECK_COMPILER_FLAG(fexceptions, [USE_EXCEPTIONS="-fexceptions"], USE_EXCEPTIONS= ) + ENABLE_PERMISSIVE_FLAG="-fpermissive" + + if test "$kde_use_pch" = "yes"; then + AC_MSG_CHECKING(whether gcc supports precompiling c header files) + echo >conftest.h + if $CC -x c-header conftest.h >/dev/null 2>/dev/null; then + kde_gcc_supports_pch=yes + AC_MSG_RESULT(yes) + else + kde_gcc_supports_pch=no + AC_MSG_RESULT(no) + fi + if test "$kde_gcc_supports_pch" = "yes"; then + AC_MSG_CHECKING(whether gcc supports precompiling c++ header files) + if $CXX -x c++-header conftest.h >/dev/null 2>/dev/null; then + kde_gcc_supports_pch=yes + AC_MSG_RESULT(yes) + else + kde_gcc_supports_pch=no + AC_MSG_RESULT(no) + fi + fi + rm -f conftest.h conftest.h.gch + fi + fi + AM_CONDITIONAL(unsermake_enable_pch, test "$kde_use_pch" = "yes" && test "$kde_gcc_supports_pch" = "yes") + if test "$CXX" = "KCC"; then + dnl unfortunately we currently cannot disable exception support in KCC + dnl because doing so is binary incompatible and Qt by default links with exceptions :-( + dnl KDE_CHECK_COMPILER_FLAG(-no_exceptions,[CXXFLAGS="$CXXFLAGS --no_exceptions"]) + dnl KDE_CHECK_COMPILER_FLAG(-exceptions, [USE_EXCEPTIONS="--exceptions"], USE_EXCEPTIONS= ) + + if test "$kde_use_pch" = "yes"; then + dnl TODO: support --pch-dir! + KDE_CHECK_COMPILER_FLAG(-pch,[CXXFLAGS="$CXXFLAGS --pch"]) + dnl the below works (but the dir must exist), but it's + dnl useless for a whole package. + dnl The are precompiled headers for each source file, so when compiling + dnl from scratch, it doesn't make a difference, and they take up + dnl around ~5Mb _per_ sourcefile. + dnl KDE_CHECK_COMPILER_FLAG(-pch_dir /tmp, + dnl [CXXFLAGS="$CXXFLAGS --pch_dir `pwd`/pcheaders"]) + fi + dnl this flag controls inlining. by default KCC inlines in optimisation mode + dnl all implementations that are defined inside the class {} declaration. + dnl because of templates-compatibility with broken gcc compilers, this + dnl can cause excessive inlining. This flag limits it to a sane level + KDE_CHECK_COMPILER_FLAG(-inline_keyword_space_time=6,[CXXFLAGS="$CXXFLAGS --inline_keyword_space_time=6"]) + KDE_CHECK_COMPILER_FLAG(-inline_auto_space_time=2,[CXXFLAGS="$CXXFLAGS --inline_auto_space_time=2"]) + KDE_CHECK_COMPILER_FLAG(-inline_implicit_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_implicit_space_time=2.0"]) + KDE_CHECK_COMPILER_FLAG(-inline_generated_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_generated_space_time=2.0"]) + dnl Some source files are shared between multiple executables + dnl (or libraries) and some of those need template instantiations. + dnl In that case KCC needs to compile those sources with + dnl --one_instantiation_per_object. To make it easy for us we compile + dnl _all_ objects with that flag (--one_per is a shorthand). + KDE_CHECK_COMPILER_FLAG(-one_per, [CXXFLAGS="$CXXFLAGS --one_per"]) + fi + AC_SUBST(USE_EXCEPTIONS) + dnl obsolete macro - provided to keep things going + USE_RTTI= + AC_SUBST(USE_RTTI) + + case "$host" in + *-*-irix*) test "$GXX" = yes && CXXFLAGS="-D_LANGUAGE_C_PLUS_PLUS -D__LANGUAGE_C_PLUS_PLUS $CXXFLAGS" ;; + *-*-sysv4.2uw*) CXXFLAGS="-D_UNIXWARE $CXXFLAGS";; + *-*-sysv5uw7*) CXXFLAGS="-D_UNIXWARE7 $CXXFLAGS";; + *-*-solaris*) + if test "$GXX" = yes; then + libstdcpp=`$CXX -print-file-name=libstdc++.so` + if test ! -f $libstdcpp; then + AC_MSG_ERROR([You've compiled gcc without --enable-shared. This doesn't work with KDE. Please recompile gcc with --enable-shared to receive a libstdc++.so]) + fi + fi + ;; + esac + + AC_VALIDIFY_CXXFLAGS + + AC_PROG_CXXCPP + + if test "$GCC" = yes; then + NOOPT_CFLAGS=-O0 + fi + KDE_CHECK_COMPILER_FLAG(O0,[NOOPT_CXXFLAGS=-O0]) + + AC_ARG_ENABLE(coverage, + AC_HELP_STRING([--enable-coverage],[use gcc coverage testing]), [ + if test "$am_cv_CC_dependencies_compiler_type" = "gcc3"; then + ac_coverage_compiler="-fprofile-arcs -ftest-coverage" + ac_coverage_linker="-lgcc" + elif test "$am_cv_CC_dependencies_compiler_type" = "gcc"; then + ac_coverage_compiler="-fprofile-arcs -ftest-coverage" + ac_coverage_linker="" + else + AC_MSG_ERROR([coverage with your compiler is not supported]) + fi + CFLAGS="$CFLAGS $ac_coverage_compiler" + CXXFLAGS="$CXXFLAGS $ac_coverage_compiler" + LDFLAGS="$LDFLAGS $ac_coverage_linker" + ]) + + AC_SUBST(NOOPT_CXXFLAGS) + AC_SUBST(NOOPT_CFLAGS) + AC_SUBST(ENABLE_PERMISSIVE_FLAG) + + KDE_CHECK_NEW_LDFLAGS + KDE_CHECK_FINAL + KDE_CHECK_CLOSURE + KDE_CHECK_NMCHECK + + ifdef([AM_DEPENDENCIES], AC_REQUIRE([KDE_ADD_DEPENDENCIES]), []) +]) + +AC_DEFUN([KDE_CHECK_VISIBILITY_GCC_BUG], + [ + AC_CACHE_CHECK([for gcc -fvisibility-inlines-hidden bug], kde_cv_val_gcc_visibility_bug, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + safe_CXXFLAGS=$CXXFLAGS + safe_LDFLAGS=$LDFLAGS + CXXFLAGS="$CXXFLAGS -fPIC -fvisibility-inlines-hidden -O0" + LDFLAGS="$LDFLAGS -shared -fPIC" + + AC_TRY_LINK( + [ + /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19664 */ + #include + int some_function( void ) __attribute__ ((visibility("default"))); + int some_function( void ) + { + std::string s("blafasel"); + return 0; + } + ], [/* elvis is alive */], + kde_cv_val_gcc_visibility_bug=no, kde_cv_val_gcc_visibility_bug=yes) + + CXXFLAGS=$safe_CXXFLAGS + LDFLAGS=$safe_LDFLAGS + AC_LANG_RESTORE + ] + ) + + if test x$kde_cv_val_gcc_visibility_bug = xno; then + CXXFLAGS="$CXXFLAGS -fvisibility-inlines-hidden" + fi + ] +) + +AC_DEFUN([KDE_ENABLE_HIDDEN_VISIBILITY], +[ + AC_BEFORE([AC_PATH_QT_1_3], [KDE_ENABLE_HIDDEN_VISIBILITY]) + + AC_MSG_CHECKING([grepping for visibility push/pop in headers]) + + if test "x$GXX" = "xyes"; then + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_EGREP_CPP( + [GCC visibility push], + [ #include + ], + [ + AC_MSG_RESULT(yes) + kde_stdc_visibility_patched=yes ], + [ + AC_MSG_RESULT(no) + AC_MSG_WARN([Your libstdc++ doesn't appear to be patched for + visibility support. Disabling -fvisibility=hidden]) + + kde_stdc_visibility_patched=no ]) + + AC_LANG_RESTORE + + kde_have_gcc_visibility=no + KDE_CHECK_COMPILER_FLAG(fvisibility=hidden, + [ + kde_have_gcc_visibility=yes + dnl the whole toolchain is just a mess, gcc is just too buggy + dnl to handle STL with visibility enabled. Lets reconsider + dnl when gcc 4.2 is out or when things get fixed in the compiler. + dnl Contact mueller@kde.org for details. + AC_ARG_ENABLE(gcc-hidden-visibility, + AC_HELP_STRING([--enable-gcc-hidden-visibility],[toolchain hidden visibility [default=no]]), + [kde_have_gcc_visibility=$enableval], + [kde_have_gcc_visibility=no]) + + AC_CACHE_CHECK([if Qt is patched for -fvisibility], kde_cv_val_qt_gcc_visibility_patched, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + safe_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $all_includes" + + AC_TRY_COMPILE( + [ +#include +#if Q_EXPORT - 0 != 0 +/* if this compiles, then Q_EXPORT is undefined */ +/* if Q_EXPORT is nonempty, this will break compilation */ +#endif + ], [/* elvis is alive */], + kde_cv_val_qt_gcc_visibility_patched=no, kde_cv_val_qt_gcc_visibility_patched=yes) + + CXXFLAGS=$safe_CXXFLAGS + AC_LANG_RESTORE + ] + ) + + if test x$kde_have_gcc_visibility = "xyes" && test x$kde_stdc_visibility_patched = "xyes" && test x$kde_cv_val_qt_gcc_visibility_patched = "xyes"; then + CXXFLAGS="$CXXFLAGS -fvisibility=hidden" + KDE_CHECK_VISIBILITY_GCC_BUG + HAVE_GCC_VISIBILITY=1 + AC_DEFINE_UNQUOTED(__KDE_HAVE_GCC_VISIBILITY, "$HAVE_GCC_VISIBILITY", [define to 1 if -fvisibility is supported]) + fi + ]) + fi +]) + +AC_DEFUN([KDE_ADD_DEPENDENCIES], +[ + [A]M_DEPENDENCIES(CC) + [A]M_DEPENDENCIES(CXX) +]) + +dnl just a wrapper to clean up configure.in +AC_DEFUN([KDE_PROG_LIBTOOL], +[ +AC_REQUIRE([AC_CHECK_COMPILERS]) +AC_REQUIRE([AC_ENABLE_SHARED]) +AC_REQUIRE([AC_ENABLE_STATIC]) + +AC_REQUIRE([AC_LIBTOOL_DLOPEN]) +AC_REQUIRE([KDE_CHECK_LIB64]) + +AC_OBJEXT +AC_EXEEXT + +AM_PROG_LIBTOOL +AC_LIBTOOL_CXX + +LIBTOOL_SHELL="/bin/sh ./libtool" +# LIBTOOL="$LIBTOOL --silent" +KDE_PLUGIN="-avoid-version -module -no-undefined \$(KDE_NO_UNDEFINED) \$(KDE_RPATH) \$(KDE_MT_LDFLAGS)" +AC_SUBST(KDE_PLUGIN) + +# This hack ensures that libtool creates shared libs for kunittest plugins. By default check_LTLIBRARIES makes static libs. +KDE_CHECK_PLUGIN="\$(KDE_PLUGIN) -rpath \$(libdir)" +AC_SUBST(KDE_CHECK_PLUGIN) + +# we patch configure quite some so we better keep that consistent for incremental runs +AC_SUBST(AUTOCONF,'$(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure') +]) + +AC_DEFUN([KDE_CHECK_LIB64], +[ + kdelibsuff="$kde_libs_suffix" + if test -z "$kdelibsuff"; then + kdelibsuff=no + fi + AC_ARG_ENABLE(libsuffix, + AC_HELP_STRING([--enable-libsuffix], + [/lib directory suffix (64,32,none[=default])]), + kdelibsuff=$enableval) + # TODO: add an auto case that compiles a little C app to check + # where the glibc is + if test "$kdelibsuff" = "no"; then + kdelibsuff= + fi + if test -z "$kdelibsuff"; then + AC_MSG_RESULT([not using lib directory suffix]) + AC_DEFINE(KDELIBSUFF, [""], Suffix for lib directories) + else + if test "$libdir" = '${exec_prefix}/lib'; then + libdir="$libdir${kdelibsuff}" + AC_SUBST([libdir], ["$libdir"]) dnl ugly hack for lib64 platforms + fi + AC_DEFINE_UNQUOTED(KDELIBSUFF, ["${kdelibsuff}"], Suffix for lib directories) + AC_MSG_RESULT([using lib directory suffix $kdelibsuff]) + fi +]) + +AC_DEFUN([KDE_CHECK_TYPES], +[ AC_CHECK_SIZEOF(int, 4)dnl + AC_CHECK_SIZEOF(short)dnl + AC_CHECK_SIZEOF(long, 4)dnl + AC_CHECK_SIZEOF(char *, 4)dnl +])dnl + +dnl Not used - kept for compat only? +AC_DEFUN([KDE_DO_IT_ALL], +[ +AC_CANONICAL_SYSTEM +AC_ARG_PROGRAM +AM_INIT_AUTOMAKE($1, $2) +AM_DISABLE_LIBRARIES +AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde}) +AC_CHECK_COMPILERS +KDE_PROG_LIBTOOL +AM_KDE_WITH_NLS +AC_PATH_KDE +]) + +AC_DEFUN([AC_CHECK_RPATH], +[ +AC_MSG_CHECKING(for rpath) +AC_ARG_ENABLE(rpath, + AC_HELP_STRING([--disable-rpath],[do not use the rpath feature of ld]), + USE_RPATH=$enableval, USE_RPATH=yes) + +if test -z "$KDE_RPATH" && test "$USE_RPATH" = "yes"; then + + KDE_RPATH="-R \$(libdir)" + + if test "$kde_libraries" != "$libdir"; then + KDE_RPATH="$KDE_RPATH -R \$(kde_libraries)" + fi + + if test -n "$qt_libraries"; then + KDE_RPATH="$KDE_RPATH -R \$(qt_libraries)" + fi + dnl $x_libraries is set to /usr/lib in case + if test -n "$X_LDFLAGS"; then + X_RPATH="-R \$(x_libraries)" + KDE_RPATH="$KDE_RPATH $X_RPATH" + fi + if test -n "$KDE_EXTRA_RPATH"; then + KDE_RPATH="$KDE_RPATH \$(KDE_EXTRA_RPATH)" + fi +fi +AC_SUBST(KDE_EXTRA_RPATH) +AC_SUBST(KDE_RPATH) +AC_SUBST(X_RPATH) +AC_MSG_RESULT($USE_RPATH) +]) + +dnl Check for the type of the third argument of getsockname +AC_DEFUN([AC_CHECK_SOCKLEN_T], +[ + AC_MSG_CHECKING(for socklen_t) + AC_CACHE_VAL(kde_cv_socklen_t, + [ + AC_LANG_PUSH(C++) + kde_cv_socklen_t=no + AC_TRY_COMPILE([ + #include + #include + ], + [ + socklen_t len; + getpeername(0,0,&len); + ], + [ + kde_cv_socklen_t=yes + kde_cv_socklen_t_equiv=socklen_t + ]) + AC_LANG_POP(C++) + ]) + AC_MSG_RESULT($kde_cv_socklen_t) + if test $kde_cv_socklen_t = no; then + AC_MSG_CHECKING([for socklen_t equivalent for socket functions]) + AC_CACHE_VAL(kde_cv_socklen_t_equiv, + [ + kde_cv_socklen_t_equiv=int + AC_LANG_PUSH(C++) + for t in int size_t unsigned long "unsigned long"; do + AC_TRY_COMPILE([ + #include + #include + ], + [ + $t len; + getpeername(0,0,&len); + ], + [ + kde_cv_socklen_t_equiv="$t" + break + ]) + done + AC_LANG_POP(C++) + ]) + AC_MSG_RESULT($kde_cv_socklen_t_equiv) + fi + AC_DEFINE_UNQUOTED(kde_socklen_t, $kde_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined]) + AC_DEFINE_UNQUOTED(ksize_t, $kde_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined (deprecated, use kde_socklen_t)]) +]) + +dnl This is a merge of some macros out of the gettext aclocal.m4 +dnl since we don't need anything, I took the things we need +dnl the copyright for them is: +dnl > +dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +dnl This Makefile.in is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. +dnl > +dnl for this file it is relicensed under LGPL + +AC_DEFUN([AM_KDE_WITH_NLS], + [ + dnl If we use NLS figure out what method + + AM_PATH_PROG_WITH_TEST_KDE(MSGFMT, msgfmt, + [test -n "`$ac_dir/$ac_word --version 2>&1 | grep 'GNU gettext'`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + if test -z "`$GMSGFMT --version 2>&1 | grep 'GNU gettext'`"; then + AC_MSG_RESULT([found msgfmt program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + MSGFMT=$GMSGFMT + AC_SUBST(GMSGFMT) + AC_SUBST(MSGFMT) + + AM_PATH_PROG_WITH_TEST_KDE(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + AC_SUBST(XGETTEXT) + + ]) + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. + +# serial 1 +# Stephan Kulow: I appended a _KDE against name conflicts + +dnl AM_PATH_PROG_WITH_TEST_KDE(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST_KDE], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. + +# serial 1 + +AC_DEFUN([AM_LC_MESSAGES], + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your locale.h file contains LC_MESSAGES]) + fi + fi]) + +dnl From Jim Meyering. +dnl FIXME: migrate into libit. + +AC_DEFUN([AM_FUNC_OBSTACK], +[AC_CACHE_CHECK([for obstacks], am_cv_func_obstack, + [AC_TRY_LINK([#include "obstack.h"], + [struct obstack *mem;obstack_free(mem,(char *) 0)], + am_cv_func_obstack=yes, + am_cv_func_obstack=no)]) + if test $am_cv_func_obstack = yes; then + AC_DEFINE(HAVE_OBSTACK) + else + LIBOBJS="$LIBOBJS obstack.o" + fi +]) + +dnl From Jim Meyering. Use this if you use the GNU error.[ch]. +dnl FIXME: Migrate into libit + +AC_DEFUN([AM_FUNC_ERROR_AT_LINE], +[AC_CACHE_CHECK([for error_at_line], am_cv_lib_error_at_line, + [AC_TRY_LINK([],[error_at_line(0, 0, "", 0, "");], + am_cv_lib_error_at_line=yes, + am_cv_lib_error_at_line=no)]) + if test $am_cv_lib_error_at_line = no; then + LIBOBJS="$LIBOBJS error.o" + fi + AC_SUBST(LIBOBJS)dnl +]) + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. + +# serial 1 +# Stephan Kulow: I put a KDE in it to avoid name conflicts + +AC_DEFUN([AM_KDE_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([AM_KDE_WITH_NLS])dnl + AC_CHECK_HEADERS([limits.h locale.h nl_types.h string.h values.h alloca.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next]) + + AC_MSG_CHECKING(for stpcpy) + AC_CACHE_VAL(kde_cv_func_stpcpy, + [ + kde_safe_cxxflags=$CXXFLAGS + CXXFLAGS="-Werror" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([ + #include + ], + [ + char buffer[200]; + stpcpy(buffer, buffer); + ], + kde_cv_func_stpcpy=yes, + kde_cv_func_stpcpy=no) + AC_LANG_RESTORE + CXXFLAGS=$kde_safe_cxxflags + ]) + AC_MSG_RESULT($kde_cv_func_stpcpy) + if eval "test \"`echo $kde_cv_func_stpcpy`\" = yes"; then + AC_DEFINE(HAVE_STPCPY, 1, [Define if you have stpcpy]) + fi + + AM_LC_MESSAGES + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + ]) + +AC_DEFUN([AC_HAVE_XPM], + [AC_REQUIRE_CPP()dnl + AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + + test -z "$XPM_LDFLAGS" && XPM_LDFLAGS= + test -z "$XPM_INCLUDE" && XPM_INCLUDE= + + AC_ARG_WITH(xpm,AC_HELP_STRING([--without-xpm],[disable color pixmap XPM tests]), + xpm_test=$withval, xpm_test="yes") + if test "x$xpm_test" = xno; then + ac_cv_have_xpm=no + else + AC_MSG_CHECKING(for XPM) + AC_CACHE_VAL(ac_cv_have_xpm, + [ + ac_save_ldflags="$LDFLAGS" + ac_save_cflags="$CFLAGS" + if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then + LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm -lX11 -lXext $LIBZ $LIBSOCKET" + else + LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm $LIBZ $LIBSOCKET" + fi + CFLAGS="$CFLAGS $X_INCLUDES $USER_INCLUDES" + test -n "$XPM_INCLUDE" && CFLAGS="-I$XPM_INCLUDE $CFLAGS" + AC_TRY_LINK([#include ],[], + ac_cv_have_xpm="yes",ac_cv_have_xpm="no") + LDFLAGS="$ac_save_ldflags" + CFLAGS="$ac_save_cflags" + ])dnl + + if test "$ac_cv_have_xpm" = no; then + AC_MSG_RESULT(no) + XPM_LDFLAGS="" + XPMINC="" + $2 + else + AC_DEFINE(HAVE_XPM, 1, [Define if you have XPM support]) + if test "$XPM_LDFLAGS" = ""; then + XPMLIB='-lXpm $(LIB_X11)' + else + XPMLIB="-L$XPM_LDFLAGS -lXpm "'$(LIB_X11)' + fi + if test "$XPM_INCLUDE" = ""; then + XPMINC="" + else + XPMINC="-I$XPM_INCLUDE" + fi + AC_MSG_RESULT(yes) + $1 + fi + fi + AC_SUBST(XPMINC) + AC_SUBST(XPMLIB) +]) + +AC_DEFUN([AC_HAVE_DPMS], + [AC_REQUIRE_CPP()dnl + AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + + test -z "$DPMS_LDFLAGS" && DPMS_LDFLAGS= + test -z "$DPMS_INCLUDE" && DPMS_INCLUDE= + DPMS_LIB= + + AC_ARG_WITH(dpms,AC_HELP_STRING([--without-dpms],[disable DPMS power saving]), + dpms_test=$withval, dpms_test="yes") + if test "x$dpms_test" = xno; then + ac_cv_have_dpms=no + else + AC_MSG_CHECKING(for DPMS) + dnl Note: ac_cv_have_dpms can be no, yes, or -lXdpms. + dnl 'yes' means DPMS_LIB="", '-lXdpms' means DPMS_LIB="-lXdpms". + AC_CACHE_VAL(ac_cv_have_dpms, + [ + if test "x$kde_use_qt_emb" = "xyes" || test "x$kde_use_qt_mac" = "xyes"; then + AC_MSG_RESULT(no) + ac_cv_have_dpms="no" + else + ac_save_ldflags="$LDFLAGS" + ac_save_cflags="$CFLAGS" + ac_save_libs="$LIBS" + LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries" + LIBS="-lX11 -lXext $LIBSOCKET" + CFLAGS="$CFLAGS $X_INCLUDES" + test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" + AC_TRY_LINK([ + #include + #include + #include + #include + int foo_test_dpms() + { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[], + ac_cv_have_dpms="yes", [ + LIBS="-lXdpms $LIBS" + AC_TRY_LINK([ + #include + #include + #include + #include + int foo_test_dpms() + { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[], + [ + ac_cv_have_dpms="-lXdpms" + ],ac_cv_have_dpms="no") + ]) + LDFLAGS="$ac_save_ldflags" + CFLAGS="$ac_save_cflags" + LIBS="$ac_save_libs" + fi + ])dnl + + if test "$ac_cv_have_dpms" = no; then + AC_MSG_RESULT(no) + DPMS_LDFLAGS="" + DPMSINC="" + $2 + else + AC_DEFINE(HAVE_DPMS, 1, [Define if you have DPMS support]) + if test "$ac_cv_have_dpms" = "-lXdpms"; then + DPMS_LIB="-lXdpms" + fi + if test "$DPMS_LDFLAGS" = ""; then + DPMSLIB="$DPMS_LIB "'$(LIB_X11)' + else + DPMSLIB="$DPMS_LDFLAGS $DPMS_LIB "'$(LIB_X11)' + fi + if test "$DPMS_INCLUDE" = ""; then + DPMSINC="" + else + DPMSINC="-I$DPMS_INCLUDE" + fi + AC_MSG_RESULT(yes) + $1 + fi + fi + ac_save_cflags="$CFLAGS" + CFLAGS="$CFLAGS $X_INCLUDES" + test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" + AH_TEMPLATE(HAVE_DPMSCAPABLE_PROTO, + [Define if you have the DPMSCapable prototype in ]) + AC_CHECK_DECL(DPMSCapable, + AC_DEFINE(HAVE_DPMSCAPABLE_PROTO),, + [#include + #include ]) + AH_TEMPLATE(HAVE_DPMSINFO_PROTO, + [Define if you have the DPMSInfo prototype in ]) + AC_CHECK_DECL(DPMSInfo, + AC_DEFINE(HAVE_DPMSINFO_PROTO),, + [#include + #include ]) + CFLAGS="$ac_save_cflags" + AC_SUBST(DPMSINC) + AC_SUBST(DPMSLIB) +]) + +AC_DEFUN([AC_HAVE_GL], + [AC_REQUIRE_CPP()dnl + AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + + test -z "$GL_LDFLAGS" && GL_LDFLAGS= + test -z "$GL_INCLUDE" && GL_INCLUDE= + + AC_ARG_WITH(gl,AC_HELP_STRING([--without-gl],[disable 3D GL modes]), + gl_test=$withval, gl_test="yes") + if test "x$kde_use_qt_emb" = "xyes"; then + # GL and Qt Embedded is a no-go for now. + ac_cv_have_gl=no + elif test "x$gl_test" = xno; then + ac_cv_have_gl=no + else + AC_MSG_CHECKING(for GL) + AC_CACHE_VAL(ac_cv_have_gl, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_ldflags=$LDFLAGS + ac_save_cxxflags=$CXXFLAGS + ac_save_libs=$LIBS + LDFLAGS="$LDFLAGS $GL_LDFLAGS $X_LDFLAGS $all_libraries" + LIBS="$LIBS -lGL -lGLU" + test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LIBS="$LIBS -lX11" + LIBS="$LIBS $LIB_XEXT -lm $LIBSOCKET" + CXXFLAGS="$CFLAGS $X_INCLUDES" + test -n "$GL_INCLUDE" && CFLAGS="-I$GL_INCLUDE $CFLAGS" + AC_TRY_LINK([#include +#include +], [], + ac_cv_have_gl="yes", ac_cv_have_gl="no") + AC_LANG_RESTORE + LDFLAGS=$ac_save_ldflags + CXXFLAGS=$ac_save_cxxflags + LIBS=$ac_save_libs + ])dnl + + if test "$ac_cv_have_gl" = "no"; then + AC_MSG_RESULT(no) + GL_LDFLAGS="" + GLINC="" + $2 + else + AC_DEFINE(HAVE_GL, 1, [Defines if you have GL (Mesa, OpenGL, ...)]) + if test "$GL_LDFLAGS" = ""; then + GLLIB='-lGLU -lGL $(LIB_X11)' + else + GLLIB="$GL_LDFLAGS -lGLU -lGL "'$(LIB_X11)' + fi + if test "$GL_INCLUDE" = ""; then + GLINC="" + else + GLINC="-I$GL_INCLUDE" + fi + AC_MSG_RESULT($ac_cv_have_gl) + $1 + fi + fi + AC_SUBST(GLINC) + AC_SUBST(GLLIB) +]) + + + dnl shadow password and PAM magic - maintained by ossi@kde.org + +AC_DEFUN([KDE_PAM], [ + AC_REQUIRE([KDE_CHECK_LIBDL]) + + want_pam= + AC_ARG_WITH(pam, + AC_HELP_STRING([--with-pam[=ARG]],[enable support for PAM: ARG=[yes|no|service name]]), + [ if test "x$withval" = "xyes"; then + want_pam=yes + pam_service=kde + elif test "x$withval" = "xno"; then + want_pam=no + else + want_pam=yes + pam_service=$withval + fi + ], [ pam_service=kde ]) + + use_pam= + PAMLIBS= + if test "x$want_pam" != xno; then + AC_CHECK_LIB(pam, pam_start, [ + AC_CHECK_HEADER(security/pam_appl.h, + [ pam_header=security/pam_appl.h ], + [ AC_CHECK_HEADER(pam/pam_appl.h, + [ pam_header=pam/pam_appl.h ], + [ + AC_MSG_WARN([PAM detected, but no headers found! +Make sure you have the necessary development packages installed.]) + ] + ) + ] + ) + ], , $LIBDL) + if test -z "$pam_header"; then + if test "x$want_pam" = xyes; then + AC_MSG_ERROR([--with-pam was specified, but cannot compile with PAM!]) + fi + else + AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM (Pluggable Authentication Modules)]) + PAMLIBS="$PAM_MISC_LIB -lpam $LIBDL" + use_pam=yes + + dnl darwin claims to be something special + if test "$pam_header" = "pam/pam_appl.h"; then + AC_DEFINE(HAVE_PAM_PAM_APPL_H, 1, [Define if your PAM headers are in pam/ instead of security/]) + fi + + dnl test whether struct pam_message is const (Linux) or not (Sun) + AC_MSG_CHECKING(for const pam_message) + AC_EGREP_HEADER([struct pam_message], $pam_header, + [ AC_EGREP_HEADER([const struct pam_message], $pam_header, + [AC_MSG_RESULT([const: Linux-type PAM])], + [AC_MSG_RESULT([nonconst: Sun-type PAM]) + AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM support takes non-const arguments (Solaris)])] + )], + [AC_MSG_RESULT([not found - assume const, Linux-type PAM])]) + fi + fi + + AC_SUBST(PAMLIBS) +]) + +dnl DEF_PAM_SERVICE(arg name, full name, define name) +AC_DEFUN([DEF_PAM_SERVICE], [ + AC_ARG_WITH($1-pam, + AC_HELP_STRING([--with-$1-pam=[val]],[override PAM service from --with-pam for $2]), + [ if test "x$use_pam" = xyes; then + $3_PAM_SERVICE=$withval + else + AC_MSG_ERROR([Cannot use use --with-$1-pam, as no PAM was detected. +You may want to enforce it by using --with-pam.]) + fi + ], + [ if test "x$use_pam" = xyes; then + $3_PAM_SERVICE="$pam_service" + fi + ]) + if test -n "$$3_PAM_SERVICE"; then + AC_MSG_RESULT([The PAM service used by $2 will be $$3_PAM_SERVICE]) + AC_DEFINE_UNQUOTED($3_PAM_SERVICE, "$$3_PAM_SERVICE", [The PAM service to be used by $2]) + fi + AC_SUBST($3_PAM_SERVICE) +]) + +AC_DEFUN([KDE_SHADOWPASSWD], [ + AC_REQUIRE([KDE_PAM]) + + AC_CHECK_LIB(shadow, getspent, + [ LIBSHADOW="-lshadow" + ac_use_shadow=yes + ], + [ dnl for UnixWare + AC_CHECK_LIB(gen, getspent, + [ LIBGEN="-lgen" + ac_use_shadow=yes + ], + [ AC_CHECK_FUNC(getspent, + [ ac_use_shadow=yes ], + [ ac_use_shadow=no ]) + ]) + ]) + AC_SUBST(LIBSHADOW) + AC_SUBST(LIBGEN) + + AC_MSG_CHECKING([for shadow passwords]) + + AC_ARG_WITH(shadow, + AC_HELP_STRING([--with-shadow],[If you want shadow password support]), + [ if test "x$withval" != "xno"; then + use_shadow=yes + else + use_shadow=no + fi + ], [ + use_shadow="$ac_use_shadow" + ]) + + if test "x$use_shadow" = xyes; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SHADOW, 1, [Define if you use shadow passwords]) + else + AC_MSG_RESULT(no) + LIBSHADOW= + LIBGEN= + fi + + dnl finally make the relevant binaries setuid root, if we have shadow passwds. + dnl this still applies, if we could use it indirectly through pam. + if test "x$use_shadow" = xyes || + ( test "x$use_pam" = xyes && test "x$ac_use_shadow" = xyes ); then + case $host in + *-*-freebsd* | *-*-netbsd* | *-*-openbsd*) + SETUIDFLAGS="-m 4755 -o root";; + *) + SETUIDFLAGS="-m 4755";; + esac + fi + AC_SUBST(SETUIDFLAGS) + +]) + +AC_DEFUN([KDE_PASSWDLIBS], [ + AC_REQUIRE([KDE_MISC_TESTS]) dnl for LIBCRYPT + AC_REQUIRE([KDE_PAM]) + AC_REQUIRE([KDE_SHADOWPASSWD]) + + if test "x$use_pam" = "xyes"; then + PASSWDLIBS="$PAMLIBS" + else + PASSWDLIBS="$LIBCRYPT $LIBSHADOW $LIBGEN" + fi + + dnl FreeBSD uses a shadow-like setup, where /etc/passwd holds the users, but + dnl /etc/master.passwd holds the actual passwords. /etc/master.passwd requires + dnl root to read, so kcheckpass needs to be root (even when using pam, since pam + dnl may need to read /etc/master.passwd). + case $host in + *-*-freebsd*) + SETUIDFLAGS="-m 4755 -o root" + ;; + *) + ;; + esac + + AC_SUBST(PASSWDLIBS) +]) + +AC_DEFUN([KDE_CHECK_LIBDL], +[ +AC_CHECK_LIB(dl, dlopen, [ +LIBDL="-ldl" +ac_cv_have_dlfcn=yes +]) + +AC_CHECK_LIB(dld, shl_unload, [ +LIBDL="-ldld" +ac_cv_have_shload=yes +]) + +AC_SUBST(LIBDL) +]) + +AC_DEFUN([KDE_CHECK_DLOPEN], +[ +KDE_CHECK_LIBDL +AC_CHECK_HEADERS(dlfcn.h dl.h) +if test "$ac_cv_header_dlfcn_h" = "no"; then + ac_cv_have_dlfcn=no +fi + +if test "$ac_cv_header_dl_h" = "no"; then + ac_cv_have_shload=no +fi + +dnl XXX why change enable_dlopen? its already set by autoconf's AC_ARG_ENABLE +dnl (MM) +AC_ARG_ENABLE(dlopen, +AC_HELP_STRING([--disable-dlopen],[link statically [default=no]]), +enable_dlopen=$enableval, +enable_dlopen=yes) + +# override the user's opinion, if we know it better ;) +if test "$ac_cv_have_dlfcn" = "no" && test "$ac_cv_have_shload" = "no"; then + enable_dlopen=no +fi + +if test "$ac_cv_have_dlfcn" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_DLFCN, 1, [Define if you have dlfcn]) +fi + +if test "$ac_cv_have_shload" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_SHLOAD, 1, [Define if you have shload]) +fi + +if test "$enable_dlopen" = no ; then + test -n "$1" && eval $1 +else + test -n "$2" && eval $2 +fi + +]) + +AC_DEFUN([KDE_CHECK_DYNAMIC_LOADING], +[ +KDE_CHECK_DLOPEN(libtool_enable_shared=yes, libtool_enable_static=no) +KDE_PROG_LIBTOOL +AC_MSG_CHECKING([dynamic loading]) +eval "`egrep '^build_libtool_libs=' libtool`" +if test "$build_libtool_libs" = "yes" && test "$enable_dlopen" = "yes"; then + dynamic_loading=yes + AC_DEFINE_UNQUOTED(HAVE_DYNAMIC_LOADING) +else + dynamic_loading=no +fi +AC_MSG_RESULT($dynamic_loading) +if test "$dynamic_loading" = "yes"; then + $1 +else + $2 +fi +]) + +AC_DEFUN([KDE_ADD_INCLUDES], +[ +if test -z "$1"; then + test_include="Pix.h" +else + test_include="$1" +fi + +AC_MSG_CHECKING([for libg++ ($test_include)]) + +AC_CACHE_VAL(kde_cv_libgpp_includes, +[ +kde_cv_libgpp_includes=no + + for ac_dir in \ + \ + /usr/include/g++ \ + /usr/include \ + /usr/unsupported/include \ + /opt/include \ + $extra_include \ + ; \ + do + if test -r "$ac_dir/$test_include"; then + kde_cv_libgpp_includes=$ac_dir + break + fi + done +]) + +AC_MSG_RESULT($kde_cv_libgpp_includes) +if test "$kde_cv_libgpp_includes" != "no"; then + all_includes="-I$kde_cv_libgpp_includes $all_includes $USER_INCLUDES" +fi +]) +]) + +AC_DEFUN([KDE_CHECK_LIBPTHREAD], +[ + dnl This code is here specifically to handle the + dnl various flavors of threading library on FreeBSD + dnl 4-, 5-, and 6-, and the (weird) rules around it. + dnl There may be an environment PTHREAD_LIBS that + dnl specifies what to use; otherwise, search for it. + dnl -pthread is special cased and unsets LIBPTHREAD + dnl below if found. + LIBPTHREAD="" + + if test -n "$PTHREAD_LIBS"; then + if test "x$PTHREAD_LIBS" = "x-pthread" ; then + LIBPTHREAD="PTHREAD" + else + PTHREAD_LIBS_save="$PTHREAD_LIBS" + PTHREAD_LIBS=`echo "$PTHREAD_LIBS_save" | sed -e 's,^-l,,g'` + AC_MSG_CHECKING([for pthread_create in $PTHREAD_LIBS]) + KDE_CHECK_LIB($PTHREAD_LIBS, pthread_create, [ + LIBPTHREAD="$PTHREAD_LIBS_save"]) + PTHREAD_LIBS="$PTHREAD_LIBS_save" + fi + fi + + dnl Is this test really needed, in the face of the Tru64 test below? + if test -z "$LIBPTHREAD"; then + AC_CHECK_LIB(pthread, pthread_create, [LIBPTHREAD="-lpthread"]) + fi + + dnl This is a special Tru64 check, see BR 76171 issue #18. + if test -z "$LIBPTHREAD" ; then + AC_MSG_CHECKING([for pthread_create in -lpthread]) + kde_safe_libs=$LIBS + LIBS="$LIBS -lpthread" + AC_TRY_LINK([#include ],[(void)pthread_create(0,0,0,0);],[ + AC_MSG_RESULT(yes) + LIBPTHREAD="-lpthread"],[ + AC_MSG_RESULT(no)]) + LIBS=$kde_safe_libs + fi + + dnl Un-special-case for FreeBSD. + if test "x$LIBPTHREAD" = "xPTHREAD" ; then + LIBPTHREAD="" + fi + + AC_SUBST(LIBPTHREAD) +]) + +AC_DEFUN([KDE_CHECK_PTHREAD_OPTION], +[ + USE_THREADS="" + if test -z "$LIBPTHREAD"; then + KDE_CHECK_COMPILER_FLAG(pthread, [USE_THREADS="-D_THREAD_SAFE -pthread"]) + fi + + AH_VERBATIM(__svr_define, [ +#if defined(__SVR4) && !defined(__svr4__) +#define __svr4__ 1 +#endif +]) + case $host_os in + solaris*) + KDE_CHECK_COMPILER_FLAG(mt, [USE_THREADS="-mt"]) + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4" + ;; + freebsd*) + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE $PTHREAD_CFLAGS" + ;; + aix*) + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" + LIBPTHREAD="$LIBPTHREAD -lc_r" + ;; + linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" + if test "$CXX" = "KCC"; then + CXXFLAGS="$CXXFLAGS --thread_safe" + NOOPT_CXXFLAGS="$NOOPT_CXXFLAGS --thread_safe" + fi + ;; + *) + ;; + esac + AC_SUBST(USE_THREADS) + AC_SUBST(LIBPTHREAD) +]) + +AC_DEFUN([KDE_CHECK_THREADING], +[ + AC_REQUIRE([KDE_CHECK_LIBPTHREAD]) + AC_REQUIRE([KDE_CHECK_PTHREAD_OPTION]) + dnl default is yes if libpthread is found and no if no libpthread is available + if test -z "$LIBPTHREAD"; then + if test -z "$USE_THREADS"; then + kde_check_threading_default=no + else + kde_check_threading_default=yes + fi + else + kde_check_threading_default=yes + fi + AC_ARG_ENABLE(threading,AC_HELP_STRING([--disable-threading],[disables threading even if libpthread found]), + kde_use_threading=$enableval, kde_use_threading=$kde_check_threading_default) + if test "x$kde_use_threading" = "xyes"; then + AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have a working libpthread (will enable threaded code)]) + fi +]) + +AC_DEFUN([KDE_TRY_LINK_PYTHON], +[ +if test "$kde_python_link_found" = no; then + +if test "$1" = normal; then + AC_MSG_CHECKING(if a Python application links) +else + AC_MSG_CHECKING(if Python depends on $2) +fi + +AC_CACHE_VAL(kde_cv_try_link_python_$1, +[ +kde_save_cflags="$CFLAGS" +CFLAGS="$CFLAGS $PYTHONINC" +kde_save_libs="$LIBS" +LIBS="$LIBS $LIBPYTHON $2 $LIBDL $LIBSOCKET" +kde_save_ldflags="$LDFLAGS" +LDFLAGS="$LDFLAGS $PYTHONLIB" + +AC_TRY_LINK( +[ +#include +],[ + PySys_SetArgv(1, 0); +], + [kde_cv_try_link_python_$1=yes], + [kde_cv_try_link_python_$1=no] +) +CFLAGS="$kde_save_cflags" +LIBS="$kde_save_libs" +LDFLAGS="$kde_save_ldflags" +]) + +if test "$kde_cv_try_link_python_$1" = "yes"; then + AC_MSG_RESULT(yes) + kde_python_link_found=yes + if test ! "$1" = normal; then + LIBPYTHON="$LIBPYTHON $2" + fi + $3 +else + AC_MSG_RESULT(no) + $4 +fi + +fi + +]) + +AC_DEFUN([KDE_CHECK_PYTHON_DIR], +[ +AC_MSG_CHECKING([for Python directory]) + +AC_CACHE_VAL(kde_cv_pythondir, +[ + if test -z "$PYTHONDIR"; then + kde_cv_pythondir=/usr/local + else + kde_cv_pythondir="$PYTHONDIR" + fi +]) + +AC_ARG_WITH(pythondir, +AC_HELP_STRING([--with-pythondir=pythondir],[use python installed in pythondir]), +[ + ac_python_dir=$withval +], ac_python_dir=$kde_cv_pythondir +) + +AC_MSG_RESULT($ac_python_dir) +]) + +AC_DEFUN([KDE_CHECK_PYTHON_INTERN], +[ +AC_REQUIRE([KDE_CHECK_LIBDL]) +AC_REQUIRE([KDE_CHECK_LIBPTHREAD]) +AC_REQUIRE([KDE_CHECK_PYTHON_DIR]) + +if test -z "$1"; then + version="1.5" +else + version="$1" +fi + +AC_MSG_CHECKING([for Python$version]) + +python_incdirs="$ac_python_dir/include /usr/include /usr/local/include/ $kde_extra_includes" +AC_FIND_FILE(Python.h, $python_incdirs, python_incdir) +if test ! -r $python_incdir/Python.h; then + AC_FIND_FILE(python$version/Python.h, $python_incdirs, python_incdir) + python_incdir=$python_incdir/python$version + if test ! -r $python_incdir/Python.h; then + python_incdir=no + fi +fi + +PYTHONINC=-I$python_incdir + +python_libdirs="$ac_python_dir/lib$kdelibsuff /usr/lib$kdelibsuff /usr/local /usr/lib$kdelibsuff $kde_extra_libs" +AC_FIND_FILE(libpython$version.so, $python_libdirs, python_libdir) +if test ! -r $python_libdir/libpython$version.so; then + AC_FIND_FILE(libpython$version.a, $python_libdirs, python_libdir) + if test ! -r $python_libdir/libpython$version.a; then + AC_FIND_FILE(python$version/config/libpython$version.a, $python_libdirs, python_libdir) + python_libdir=$python_libdir/python$version/config + if test ! -r $python_libdir/libpython$version.a; then + python_libdir=no + fi + fi +fi + +PYTHONLIB=-L$python_libdir +kde_orig_LIBPYTHON=$LIBPYTHON +if test -z "$LIBPYTHON"; then + LIBPYTHON=-lpython$version +fi + +AC_FIND_FILE(python$version/copy.py, $python_libdirs, python_moddir) +python_moddir=$python_moddir/python$version +if test ! -r $python_moddir/copy.py; then + python_moddir=no +fi + +PYTHONMODDIR=$python_moddir + +AC_MSG_RESULT(header $python_incdir library $python_libdir modules $python_moddir) + +if test x$python_incdir = xno || test x$python_libdir = xno || test x$python_moddir = xno; then + LIBPYTHON=$kde_orig_LIBPYTHON + test "x$PYTHONLIB" = "x-Lno" && PYTHONLIB="" + test "x$PYTHONINC" = "x-Ino" && PYTHONINC="" + $2 +else + dnl Note: this test is very weak + kde_python_link_found=no + KDE_TRY_LINK_PYTHON(normal) + KDE_TRY_LINK_PYTHON(m, -lm) + KDE_TRY_LINK_PYTHON(pthread, $LIBPTHREAD) + KDE_TRY_LINK_PYTHON(tcl, -ltcl) + KDE_TRY_LINK_PYTHON(db2, -ldb2) + KDE_TRY_LINK_PYTHON(m_and_thread, [$LIBPTHREAD -lm]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_util, [$LIBPTHREAD -lm -lutil]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_db3, [$LIBPTHREAD -lm -ldb-3 -lutil]) + KDE_TRY_LINK_PYTHON(pthread_and_db3, [$LIBPTHREAD -ldb-3]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_db, [$LIBPTHREAD -lm -ldb -ltermcap -lutil]) + KDE_TRY_LINK_PYTHON(pthread_and_dl, [$LIBPTHREAD $LIBDL -lutil -lreadline -lncurses -lm]) + KDE_TRY_LINK_PYTHON(pthread_and_panel_curses, [$LIBPTHREAD $LIBDL -lm -lpanel -lcurses]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_db_special, [$LIBPTHREAD -lm -ldb -lutil], [], + [AC_MSG_WARN([it seems, Python depends on another library. + Please set LIBPYTHON to '-lpython$version -lotherlib' before calling configure to fix this + and contact the authors to let them know about this problem]) + ]) + + LIBPYTHON="$LIBPYTHON $LIBDL $LIBSOCKET" + AC_SUBST(PYTHONINC) + AC_SUBST(PYTHONLIB) + AC_SUBST(LIBPYTHON) + AC_SUBST(PYTHONMODDIR) + AC_DEFINE(HAVE_PYTHON, 1, [Define if you have the development files for python]) +fi + +]) + + +AC_DEFUN([KDE_CHECK_PYTHON], +[ + KDE_CHECK_PYTHON_INTERN("2.4", + [KDE_CHECK_PYTHON_INTERN("2.3", + [KDE_CHECK_PYTHON_INTERN("2.2", + [KDE_CHECK_PYTHON_INTERN("2.1", + [KDE_CHECK_PYTHON_INTERN("2.0", + [KDE_CHECK_PYTHON_INTERN($1, $2) ]) + ]) + ]) + ]) + ]) +]) + +AC_DEFUN([KDE_CHECK_STL], +[ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="`echo $CXXFLAGS | sed s/-fno-exceptions//`" + + AC_MSG_CHECKING([if C++ programs can be compiled]) + AC_CACHE_VAL(kde_cv_stl_works, + [ + AC_TRY_COMPILE([ +#include +using namespace std; +],[ + string astring="Hallo Welt."; + astring.erase(0, 6); // now astring is "Welt" + return 0; +], kde_cv_stl_works=yes, + kde_cv_stl_works=no) +]) + + AC_MSG_RESULT($kde_cv_stl_works) + + if test "$kde_cv_stl_works" = "yes"; then + # back compatible + AC_DEFINE_UNQUOTED(HAVE_SGI_STL, 1, [Define if you have a STL implementation by SGI]) + else + AC_MSG_ERROR([Your Installation isn't able to compile simple C++ programs. +Check config.log for details - if you're using a Linux distribution you might miss +a package named similar to libstdc++-dev.]) + fi + + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE +]) + +AC_DEFUN([AC_FIND_QIMGIO], + [AC_REQUIRE([AC_FIND_JPEG]) +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_MSG_CHECKING([for qimgio]) +AC_CACHE_VAL(ac_cv_lib_qimgio, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +ac_save_LIBS="$LIBS" +ac_save_CXXFLAGS="$CXXFLAGS" +LIBS="$all_libraries -lqimgio -lpng -lz $LIBJPEG $LIBQT" +CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" +AC_TRY_RUN(dnl +[ +#include +#include +int main() { + QString t = "hallo"; + t.fill('t'); + qInitImageIO(); +} +], + ac_cv_lib_qimgio=yes, + ac_cv_lib_qimgio=no, + ac_cv_lib_qimgio=no) +LIBS="$ac_save_LIBS" +CXXFLAGS="$ac_save_CXXFLAGS" +AC_LANG_RESTORE +])dnl +if eval "test \"`echo $ac_cv_lib_qimgio`\" = yes"; then + LIBQIMGIO="-lqimgio -lpng -lz $LIBJPEG" + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_QIMGIO, 1, [Define if you have the Qt extension qimgio available]) + AC_SUBST(LIBQIMGIO) +else + AC_MSG_RESULT(not found) +fi +]) + +AC_DEFUN([AM_DISABLE_LIBRARIES], +[ + AC_PROVIDE([AM_ENABLE_STATIC]) + AC_PROVIDE([AM_ENABLE_SHARED]) + enable_static=no + enable_shared=yes +]) + + +AC_DEFUN([AC_CHECK_UTMP_FILE], +[ + AC_MSG_CHECKING([for utmp file]) + + AC_CACHE_VAL(kde_cv_utmp_file, + [ + kde_cv_utmp_file=no + + for ac_file in \ + \ + /var/run/utmp \ + /var/adm/utmp \ + /etc/utmp \ + ; \ + do + if test -r "$ac_file"; then + kde_cv_utmp_file=$ac_file + break + fi + done + ]) + + if test "$kde_cv_utmp_file" != "no"; then + AC_DEFINE_UNQUOTED(UTMP, "$kde_cv_utmp_file", [Define the file for utmp entries]) + $1 + AC_MSG_RESULT($kde_cv_utmp_file) + else + $2 + AC_MSG_RESULT([non found]) + fi +]) + + +AC_DEFUN([KDE_CREATE_SUBDIRSLIST], +[ + +DO_NOT_COMPILE="$DO_NOT_COMPILE CVS debian bsd-port admin" +TOPSUBDIRS="" + +if test ! -s $srcdir/subdirs; then + dnl Note: Makefile.common creates subdirs, so this is just a fallback + files=`cd $srcdir && ls -1` + dirs=`for i in $files; do if test -d $i; then echo $i; fi; done` + for i in $dirs; do + echo $i >> $srcdir/subdirs + done +fi + +ac_topsubdirs= +if test -s $srcdir/inst-apps; then + ac_topsubdirs="`cat $srcdir/inst-apps`" +elif test -s $srcdir/subdirs; then + ac_topsubdirs="`cat $srcdir/subdirs`" +fi + +for i in $ac_topsubdirs; do + AC_MSG_CHECKING([if $i should be compiled]) + if test -d $srcdir/$i; then + install_it="yes" + for j in $DO_NOT_COMPILE; do + if test $i = $j; then + install_it="no" + fi + done + else + install_it="no" + fi + AC_MSG_RESULT($install_it) + vari=`echo $i | sed -e 's,[[-+.@]],_,g'` + if test $install_it = "yes"; then + TOPSUBDIRS="$TOPSUBDIRS $i" + eval "$vari""_SUBDIR_included=yes" + else + eval "$vari""_SUBDIR_included=no" + fi +done + +AC_SUBST(TOPSUBDIRS) +]) + +AC_DEFUN([KDE_CHECK_NAMESPACES], +[ +AC_MSG_CHECKING(whether C++ compiler supports namespaces) +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_TRY_COMPILE([ +], +[ +namespace Foo { + extern int i; + namespace Bar { + extern int i; + } +} + +int Foo::i = 0; +int Foo::Bar::i = 1; +],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NAMESPACES) +], [ +AC_MSG_RESULT(no) +]) +AC_LANG_RESTORE +]) + +dnl ------------------------------------------------------------------------ +dnl Check for S_ISSOCK macro. Doesn't exist on Unix SCO. faure@kde.org +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_CHECK_S_ISSOCK], +[ +AC_MSG_CHECKING(for S_ISSOCK) +AC_CACHE_VAL(ac_cv_have_s_issock, +[ +AC_TRY_LINK( +[ +#include +], +[ +struct stat buff; +int b = S_ISSOCK( buff.st_mode ); +], +ac_cv_have_s_issock=yes, +ac_cv_have_s_issock=no) +]) +AC_MSG_RESULT($ac_cv_have_s_issock) +if test "$ac_cv_have_s_issock" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_S_ISSOCK, 1, [Define if sys/stat.h declares S_ISSOCK.]) +fi + +AH_VERBATIM(_ISSOCK, +[ +#ifndef HAVE_S_ISSOCK +#define HAVE_S_ISSOCK +#define S_ISSOCK(mode) (1==0) +#endif +]) + +]) + +dnl ------------------------------------------------------------------------ +dnl Check for MAXPATHLEN macro, defines KDEMAXPATHLEN. faure@kde.org +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_CHECK_KDEMAXPATHLEN], +[ +AC_MSG_CHECKING(for MAXPATHLEN) +AC_CACHE_VAL(ac_cv_maxpathlen, +[ +cat > conftest.$ac_ext < +#endif +#include +#include +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +KDE_HELLO MAXPATHLEN + +EOF + +ac_try="$ac_cpp conftest.$ac_ext 2>/dev/null | grep '^KDE_HELLO' >conftest.out" + +if AC_TRY_EVAL(ac_try) && test -s conftest.out; then + ac_cv_maxpathlen=`sed 's#KDE_HELLO ##' conftest.out` +else + ac_cv_maxpathlen=1024 +fi + +rm conftest.* + +]) +AC_MSG_RESULT($ac_cv_maxpathlen) +AC_DEFINE_UNQUOTED(KDEMAXPATHLEN,$ac_cv_maxpathlen, [Define a safe value for MAXPATHLEN] ) +]) + +AC_DEFUN([KDE_CHECK_HEADER], +[ + kde_safe_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $all_includes" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_CHECK_HEADER([$1], [$2], [$3], [$4]) + AC_LANG_RESTORE + CPPFLAGS=$kde_safe_cppflags +]) + +AC_DEFUN([KDE_CHECK_HEADERS], +[ + AH_CHECK_HEADERS([$1]) + AC_LANG_SAVE + kde_safe_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $all_includes" + AC_LANG_CPLUSPLUS + AC_CHECK_HEADERS([$1], [$2], [$3], [$4]) + CPPFLAGS=$kde_safe_cppflags + AC_LANG_RESTORE +]) + +AC_DEFUN([KDE_FAST_CONFIGURE], +[ + dnl makes configure fast (needs perl) + AC_ARG_ENABLE(fast-perl, AC_HELP_STRING([--disable-fast-perl],[disable fast Makefile generation (needs perl)]), + with_fast_perl=$enableval, with_fast_perl=yes) +]) + +AC_DEFUN([KDE_CONF_FILES], +[ + val= + if test -f $srcdir/configure.files ; then + val=`sed -e 's%^%\$(top_srcdir)/%' $srcdir/configure.files` + fi + CONF_FILES= + if test -n "$val" ; then + for i in $val ; do + CONF_FILES="$CONF_FILES $i" + done + fi + AC_SUBST(CONF_FILES) +])dnl + +dnl This sets the prefix, for arts and kdelibs +dnl Do NOT use in any other module. +dnl It only looks at --prefix, KDEDIR and falls back to /usr/local/kde +AC_DEFUN([KDE_SET_PREFIX_CORE], +[ + unset CDPATH + dnl make $KDEDIR the default for the installation + AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde}) + + if test "x$prefix" = "xNONE"; then + prefix=$ac_default_prefix + ac_configure_args="$ac_configure_args --prefix=$prefix" + fi + # And delete superfluous '/' to make compares easier + prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + + kde_libs_prefix='$(prefix)' + kde_libs_htmldir='$(kde_htmldir)' + AC_SUBST(kde_libs_prefix) + AC_SUBST(kde_libs_htmldir) + KDE_FAST_CONFIGURE + KDE_CONF_FILES +]) + + +AC_DEFUN([KDE_SET_PREFIX], +[ + unset CDPATH + dnl We can't give real code to that macro, only a value. + dnl It only matters for --help, since we set the prefix in this function anyway. + AC_PREFIX_DEFAULT(${KDEDIR:-the kde prefix}) + + KDE_SET_DEFAULT_BINDIRS + if test "x$prefix" = "xNONE"; then + dnl no prefix given: look for kde-config in the PATH and deduce the prefix from it + KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend) + else + dnl prefix given: look for kde-config, preferrably in prefix, otherwise in PATH + kde_save_PATH="$PATH" + PATH="$exec_prefix/bin:$prefix/bin:$PATH" + KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend) + PATH="$kde_save_PATH" + fi + + kde_libs_prefix=`$KDECONFIG --prefix` + if test -z "$kde_libs_prefix" || test ! -x "$kde_libs_prefix"; then + AC_MSG_ERROR([$KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs. + This means it has been moved since you installed it. + This won't work. Please recompile kdelibs for the new prefix. + ]) + fi + kde_libs_htmldir=`$KDECONFIG --install html --expandvars` + kde_libs_suffix=`$KDECONFIG --libsuffix` + + AC_MSG_CHECKING([where to install]) + if test "x$prefix" = "xNONE"; then + prefix=$kde_libs_prefix + AC_MSG_RESULT([$prefix (as returned by kde-config)]) + else + dnl --prefix was given. Compare prefixes and warn (in configure.in.bot.end) if different + given_prefix=$prefix + AC_MSG_RESULT([$prefix (as requested)]) + fi + + # And delete superfluous '/' to make compares easier + prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + given_prefix=`echo "$given_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + + AC_SUBST(KDECONFIG) + AC_SUBST(kde_libs_prefix) + AC_SUBST(kde_libs_htmldir) + + KDE_FAST_CONFIGURE + KDE_CONF_FILES +]) + +pushdef([AC_PROG_INSTALL], +[ + dnl our own version, testing for a -p flag + popdef([AC_PROG_INSTALL]) + dnl as AC_PROG_INSTALL works as it works we first have + dnl to save if the user didn't specify INSTALL, as the + dnl autoconf one overwrites INSTALL and we have no chance to find + dnl out afterwards + test -n "$INSTALL" && kde_save_INSTALL_given=$INSTALL + test -n "$INSTALL_PROGRAM" && kde_save_INSTALL_PROGRAM_given=$INSTALL_PROGRAM + test -n "$INSTALL_SCRIPT" && kde_save_INSTALL_SCRIPT_given=$INSTALL_SCRIPT + AC_PROG_INSTALL + + if test -z "$kde_save_INSTALL_given" ; then + # OK, user hasn't given any INSTALL, autoconf found one for us + # now we test, if it supports the -p flag + AC_MSG_CHECKING(for -p flag to install) + rm -f confinst.$$.* > /dev/null 2>&1 + echo "Testtest" > confinst.$$.orig + ac_res=no + if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then + if test -f confinst.$$.new ; then + # OK, -p seems to do no harm to install + INSTALL="${INSTALL} -p" + ac_res=yes + fi + fi + rm -f confinst.$$.* + AC_MSG_RESULT($ac_res) + fi + dnl the following tries to resolve some signs and wonders coming up + dnl with different autoconf/automake versions + dnl e.g.: + dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s + dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS) + dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s + dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has + dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the + dnl install-@DIR@PROGRAMS targets to explicitly use that flag + dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as + dnl INSTALL_SCRIPT, which breaks with automake <= 1.4 + dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure + dnl *sometimes KDE does not use the install-@DIR@PROGRAM targets from + dnl automake (due to broken Makefile.am or whatever) to install programs, + dnl and so does not see the -s flag in automake > 1.4 + dnl to clean up that mess we: + dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG + dnl which cleans KDE's program with automake > 1.4; + dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems + dnl with automake<=1.4 + dnl note that dues to this sometimes two '-s' flags are used (if KDE + dnl properly uses install-@DIR@PROGRAMS, but I don't care + dnl + dnl And to all this comes, that I even can't write in comments variable + dnl names used by automake, because it is so stupid to think I wanted to + dnl _use_ them, therefor I have written A_M_... instead of AM_ + dnl hmm, I wanted to say something ... ahh yes: Arghhh. + + if test -z "$kde_save_INSTALL_PROGRAM_given" ; then + INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)' + fi + if test -z "$kde_save_INSTALL_SCRIPT_given" ; then + INSTALL_SCRIPT='${INSTALL}' + fi +])dnl + +AC_DEFUN([KDE_LANG_CPLUSPLUS], +[AC_LANG_CPLUSPLUS +ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&AC_FD_CC' +pushdef([AC_LANG_CPLUSPLUS], [popdef([AC_LANG_CPLUSPLUS]) KDE_LANG_CPLUSPLUS]) +]) + +pushdef([AC_LANG_CPLUSPLUS], +[popdef([AC_LANG_CPLUSPLUS]) +KDE_LANG_CPLUSPLUS +]) + +AC_DEFUN([KDE_CHECK_LONG_LONG], +[ +AC_MSG_CHECKING(for long long) +AC_CACHE_VAL(kde_cv_c_long_long, +[ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_LINK([], [ + long long foo = 0; + foo = foo+1; + ], + kde_cv_c_long_long=yes, kde_cv_c_long_long=no) + AC_LANG_RESTORE +]) +AC_MSG_RESULT($kde_cv_c_long_long) +if test "$kde_cv_c_long_long" = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have long long as datatype]) +fi +]) + +AC_DEFUN([KDE_CHECK_LIB], +[ + kde_save_LDFLAGS="$LDFLAGS" + dnl AC_CHECK_LIB modifies LIBS, so save it here + kde_save_LIBS="$LIBS" + LDFLAGS="$LDFLAGS $all_libraries" + case $host_os in + aix*) LDFLAGS="-brtl $LDFLAGS" + test "$GCC" = yes && LDFLAGS="-Wl,$LDFLAGS" + ;; + esac + AC_CHECK_LIB($1, $2, $3, $4, $5) + LDFLAGS="$kde_save_LDFLAGS" + LIBS="$kde_save_LIBS" +]) + +AC_DEFUN([KDE_JAVA_PREFIX], +[ + dir=`dirname "$1"` + base=`basename "$1"` + list=`ls -1 $dir 2> /dev/null` + for entry in $list; do + if test -d $dir/$entry/bin; then + case $entry in + $base) + javadirs="$javadirs $dir/$entry/bin" + ;; + esac + elif test -d $dir/$entry/jre/bin; then + case $entry in + $base) + javadirs="$javadirs $dir/$entry/jre/bin" + ;; + esac + fi + done +]) + +dnl KDE_CHEC_JAVA_DIR(onlyjre) +AC_DEFUN([KDE_CHECK_JAVA_DIR], +[ + +AC_ARG_WITH(java, +AC_HELP_STRING([--with-java=javadir],[use java installed in javadir, --without-java disables]), +[ ac_java_dir=$withval +], ac_java_dir="" +) + +AC_MSG_CHECKING([for Java]) + +dnl at this point ac_java_dir is either a dir, 'no' to disable, or '' to say look in $PATH +if test "x$ac_java_dir" = "xno"; then + kde_java_bindir=no + kde_java_includedir=no + kde_java_libjvmdir=no + kde_java_libgcjdir=no + kde_java_libhpidir=no +else + if test "x$ac_java_dir" = "x"; then + + + dnl No option set -> collect list of candidate paths + if test -n "$JAVA_HOME"; then + KDE_JAVA_PREFIX($JAVA_HOME) + fi + KDE_JAVA_PREFIX(/usr/j2se) + KDE_JAVA_PREFIX(/usr/lib/j2se) + KDE_JAVA_PREFIX(/usr/j*dk*) + KDE_JAVA_PREFIX(/usr/lib/j*dk*) + KDE_JAVA_PREFIX(/opt/j*sdk*) + KDE_JAVA_PREFIX(/usr/lib/java*) + KDE_JAVA_PREFIX(/usr/java*) + KDE_JAVA_PREFIX(/usr/java/j*dk*) + KDE_JAVA_PREFIX(/usr/java/j*re*) + KDE_JAVA_PREFIX(/usr/lib/SunJava2*) + KDE_JAVA_PREFIX(/usr/lib/SunJava*) + KDE_JAVA_PREFIX(/usr/lib/IBMJava2*) + KDE_JAVA_PREFIX(/usr/lib/IBMJava*) + KDE_JAVA_PREFIX(/opt/java*) + + kde_cv_path="NONE" + kde_save_IFS=$IFS + IFS=':' + for dir in $PATH; do + if test -d "$dir"; then + javadirs="$javadirs $dir" + fi + done + IFS=$kde_save_IFS + jredirs= + + dnl Now javadirs contains a list of paths that exist, all ending with bin/ + for dir in $javadirs; do + dnl Check for the java executable + if test -x "$dir/java"; then + dnl And also check for a libjvm.so somewhere under there + dnl Since we have to go to the parent dir, /usr/bin is excluded, /usr is too big. + if test "$dir" != "/usr/bin"; then + libjvmdir=`find $dir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1` + if test ! -f $libjvmdir/libjvm.so; then continue; fi + jredirs="$jredirs $dir" + fi + fi + done + + dnl Now jredirs contains a reduced list, of paths where both java and ../**/libjvm.so was found + JAVAC= + JAVA= + kde_java_bindir=no + for dir in $jredirs; do + JAVA="$dir/java" + kde_java_bindir=$dir + if test -x "$dir/javac"; then + JAVAC="$dir/javac" + break + fi + done + + if test -n "$JAVAC"; then + dnl this substitution might not work - well, we test for jni.h below + kde_java_includedir=`echo $JAVAC | sed -e 's,bin/javac$,include/,'` + else + kde_java_includedir=no + fi + else + dnl config option set + kde_java_bindir=$ac_java_dir/bin + if test -x $ac_java_dir/bin/java && test ! -x $ac_java_dir/bin/javac; then + kde_java_includedir=no + else + kde_java_includedir=$ac_java_dir/include + fi + fi +fi + +dnl At this point kde_java_bindir and kde_java_includedir are either set or "no" +if test "x$kde_java_bindir" != "xno"; then + + dnl Look for libjvm.so + kde_java_libjvmdir=`find $kde_java_bindir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1` + dnl Look for libgcj.so + kde_java_libgcjdir=`find $kde_java_bindir/.. -name libgcj.so | sed 's,libgcj.so,,'|head -n 1` + dnl Look for libhpi.so and avoid green threads + kde_java_libhpidir=`find $kde_java_bindir/.. -name libhpi.so | grep -v green | sed 's,libhpi.so,,' | head -n 1` + + dnl Now check everything's fine under there + dnl the include dir is our flag for having the JDK + if test -d "$kde_java_includedir"; then + if test ! -x "$kde_java_bindir/javac"; then + AC_MSG_ERROR([javac not found under $kde_java_bindir - it seems you passed a wrong --with-java.]) + fi + if test ! -x "$kde_java_bindir/javah"; then + AC_MSG_ERROR([javah not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) + fi + if test ! -x "$kde_java_bindir/jar"; then + AC_MSG_ERROR([jar not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) + fi + if test ! -r "$kde_java_includedir/jni.h"; then + AC_MSG_ERROR([jni.h not found under $kde_java_includedir. Use --with-java or --without-java.]) + fi + + jni_includes="-I$kde_java_includedir" + dnl Strange thing, jni.h requires jni_md.h which is under genunix here.. + dnl and under linux here.. + + dnl not needed for gcj + + if test "x$kde_java_libgcjdir" = "x"; then + test -d "$kde_java_includedir/linux" && jni_includes="$jni_includes -I$kde_java_includedir/linux" + test -d "$kde_java_includedir/solaris" && jni_includes="$jni_includes -I$kde_java_includedir/solaris" + test -d "$kde_java_includedir/genunix" && jni_includes="$jni_includes -I$kde_java_includedir/genunix" + fi + + else + JAVAC= + jni_includes= + fi + + if test "x$kde_java_libgcjdir" = "x"; then + if test ! -r "$kde_java_libjvmdir/libjvm.so"; then + AC_MSG_ERROR([libjvm.so not found under $kde_java_libjvmdir. Use --without-java.]) + fi + else + if test ! -r "$kde_java_libgcjdir/libgcj.so"; then + AC_MSG_ERROR([libgcj.so not found under $kde_java_libgcjdir. Use --without-java.]) + fi + fi + + if test ! -x "$kde_java_bindir/java"; then + AC_MSG_ERROR([java not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) + fi + + dnl not needed for gcj compile + + if test "x$kde_java_libgcjdir" = "x"; then + if test ! -r "$kde_java_libhpidir/libhpi.so"; then + AC_MSG_ERROR([libhpi.so not found under $kde_java_libhpidir. Use --without-java.]) + fi + fi + + if test -n "$jni_includes"; then + dnl Check for JNI version + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_cxxflags_safe="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $all_includes $jni_includes" + + AC_TRY_COMPILE([ + #include + ], + [ + #ifndef JNI_VERSION_1_2 + Syntax Error + #endif + ],[ kde_jni_works=yes ], + [ kde_jni_works=no ]) + + if test $kde_jni_works = no; then + AC_MSG_ERROR([Incorrect version of $kde_java_includedir/jni.h. + You need to have Java Development Kit (JDK) version 1.2. + + Use --with-java to specify another location. + Use --without-java to configure without java support. + Or download a newer JDK and try again. + See e.g. http://java.sun.com/products/jdk/1.2 ]) + fi + + CXXFLAGS="$ac_cxxflags_safe" + AC_LANG_RESTORE + + dnl All tests ok, inform and subst the variables + + JAVAC=$kde_java_bindir/javac + JAVAH=$kde_java_bindir/javah + JAR=$kde_java_bindir/jar + AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) + if test "x$kde_java_libgcjdir" = "x"; then + JVMLIBS="-L$kde_java_libjvmdir -ljvm -L$kde_java_libhpidir -lhpi" + else + JVMLIBS="-L$kde_java_libgcjdir -lgcj" + fi + AC_MSG_RESULT([java JDK in $kde_java_bindir]) + + else + AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) + AC_MSG_RESULT([java JRE in $kde_java_bindir]) + fi +elif test -d "/Library/Java/Home"; then + kde_java_bindir="/Library/Java/Home/bin" + jni_includes="-I/Library/Java/Home/include" + + JAVAC=$kde_java_bindir/javac + JAVAH=$kde_java_bindir/javah + JAR=$kde_java_bindir/jar + JVMLIBS="-Xlinker -framework -Xlinker JavaVM" + + AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) + AC_MSG_RESULT([Apple Java Framework]) +else + AC_MSG_RESULT([none found]) +fi + +AC_SUBST(JAVAC) +AC_SUBST(JAVAH) +AC_SUBST(JAR) +AC_SUBST(JVMLIBS) +AC_SUBST(jni_includes) + +# for backward compat +kde_cv_java_includedir=$kde_java_includedir +kde_cv_java_bindir=$kde_java_bindir +]) + +dnl this is a redefinition of autoconf 2.5x's AC_FOREACH. +dnl When the argument list becomes big, as in KDE for AC_OUTPUT in +dnl big packages, m4_foreach is dog-slow. So use our own version of +dnl it. (matz@kde.org) +m4_define([mm_foreach], +[m4_pushdef([$1])_mm_foreach($@)m4_popdef([$1])]) +m4_define([mm_car], [[$1]]) +m4_define([mm_car2], [[$@]]) +m4_define([_mm_foreach], +[m4_if(m4_quote($2), [], [], + [m4_define([$1], mm_car($2))$3[]_mm_foreach([$1], + mm_car2(m4_shift($2)), + [$3])])]) +m4_define([AC_FOREACH], +[mm_foreach([$1], m4_split(m4_normalize([$2])), [$3])]) + +AC_DEFUN([KDE_NEED_FLEX], +[ +kde_libs_safe=$LIBS +LIBS="$LIBS $USER_LDFLAGS" +AM_PROG_LEX +LIBS=$kde_libs_safe +if test -z "$LEXLIB"; then + AC_MSG_ERROR([You need to have flex installed.]) +fi +AC_SUBST(LEXLIB) +]) + +AC_DEFUN([AC_PATH_QTOPIA], +[ + dnl TODO: use AC_CACHE_VAL + + if test -z "$1"; then + qtopia_minver_maj=1 + qtopia_minver_min=5 + qtopia_minver_pat=0 + else + qtopia_minver_maj=`echo "$1" | sed -e "s/^\(.*\)\..*\..*$/\1/"` + qtopia_minver_min=`echo "$1" | sed -e "s/^.*\.\(.*\)\..*$/\1/"` + qtopia_minver_pat=`echo "$1" | sed -e "s/^.*\..*\.\(.*\)$/\1/"` + fi + + qtopia_minver="$qtopia_minver_maj$qtopia_minver_min$qtopia_minver_pat" + qtopia_minverstr="$qtopia_minver_maj.$qtopia_minver_min.$qtopia_minver_pat" + + AC_REQUIRE([AC_PATH_QT]) + + AC_MSG_CHECKING([for Qtopia]) + + LIB_QTOPIA="-lqpe" + AC_SUBST(LIB_QTOPIA) + + kde_qtopia_dirs="$QPEDIR /opt/Qtopia" + + ac_qtopia_incdir=NO + + AC_ARG_WITH(qtopia-dir, + AC_HELP_STRING([--with-qtopia-dir=DIR],[where the root of Qtopia is installed]), + [ ac_qtopia_incdir="$withval"/include] ) + + qtopia_incdirs="" + for dir in $kde_qtopia_dirs; do + qtopia_incdirs="$qtopia_incdirs $dir/include" + done + + if test ! "$ac_qtopia_incdir" = "NO"; then + qtopia_incdirs="$ac_qtopia_incdir $qtopia_incdirs" + fi + + qtopia_incdir="" + AC_FIND_FILE(qpe/qpeapplication.h, $qtopia_incdirs, qtopia_incdir) + ac_qtopia_incdir="$qtopia_incdir" + + if test -z "$qtopia_incdir"; then + AC_MSG_ERROR([Cannot find Qtopia headers. Please check your installation.]) + fi + + qtopia_ver_maj=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION "\(.*\)\..*\..*".*,\1,p'`; + qtopia_ver_min=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\.\(.*\)\..*".*,\1,p'`; + qtopia_ver_pat=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\..*\.\(.*\)".*,\1,p'`; + + qtopia_ver="$qtopia_ver_maj$qtopia_ver_min$qtopia_ver_pat" + qtopia_verstr="$qtopia_ver_maj.$qtopia_ver_min.$qtopia_ver_pat" + if test "$qtopia_ver" -lt "$qtopia_minver"; then + AC_MSG_ERROR([found Qtopia version $qtopia_verstr but version $qtopia_minverstr +is required.]) + fi + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + ac_cxxflags_safe="$CXXFLAGS" + ac_ldflags_safe="$LDFLAGS" + ac_libs_safe="$LIBS" + + CXXFLAGS="$CXXFLAGS -I$qtopia_incdir $all_includes" + LDFLAGS="$LDFLAGS $QT_LDFLAGS $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" + LIBS="$LIBS $LIB_QTOPIA $LIBQT" + + cat > conftest.$ac_ext < +#include + +int main( int argc, char **argv ) +{ + QPEApplication app( argc, argv ); + return 0; +} +EOF + + if AC_TRY_EVAL(ac_link) && test -s conftest; then + rm -f conftest* + else + rm -f conftest* + AC_MSG_ERROR([Cannot link small Qtopia Application. For more details look at +the end of config.log]) + fi + + CXXFLAGS="$ac_cxxflags_safe" + LDFLAGS="$ac_ldflags_safe" + LIBS="$ac_libs_safe" + + AC_LANG_RESTORE + + QTOPIA_INCLUDES="-I$qtopia_incdir" + AC_SUBST(QTOPIA_INCLUDES) + + AC_MSG_RESULT([found version $qtopia_verstr with headers at $qtopia_incdir]) +]) + + +AC_DEFUN([KDE_INIT_DOXYGEN], +[ +AC_MSG_CHECKING([for Qt docs]) +kde_qtdir= +if test "${with_qt_dir+set}" = set; then + kde_qtdir="$with_qt_dir" +fi + +AC_FIND_FILE(qsql.html, [ $kde_qtdir/doc/html $QTDIR/doc/html /usr/share/doc/packages/qt3/html /usr/lib/qt/doc /usr/lib/qt3/doc /usr/lib/qt3/doc/html /usr/doc/qt3/html /usr/doc/qt3 /usr/share/doc/qt3-doc /usr/share/qt3/doc/html /usr/X11R6/share/doc/qt/html ], QTDOCDIR) +AC_MSG_RESULT($QTDOCDIR) + +AC_SUBST(QTDOCDIR) + +KDE_FIND_PATH(dot, DOT, [], []) +if test -n "$DOT"; then + KDE_HAVE_DOT="YES" +else + KDE_HAVE_DOT="NO" +fi +AC_SUBST(KDE_HAVE_DOT) +KDE_FIND_PATH(doxygen, DOXYGEN, [], []) +AC_SUBST(DOXYGEN) + +DOXYGEN_PROJECT_NAME="$1" +DOXYGEN_PROJECT_NUMBER="$2" +AC_SUBST(DOXYGEN_PROJECT_NAME) +AC_SUBST(DOXYGEN_PROJECT_NUMBER) + +KDE_HAS_DOXYGEN=no +if test -n "$DOXYGEN" && test -x "$DOXYGEN" && test -f $QTDOCDIR/qsql.html; then + KDE_HAS_DOXYGEN=yes +fi +AC_SUBST(KDE_HAS_DOXYGEN) + +]) + + +AC_DEFUN([AC_FIND_BZIP2], +[ +AC_MSG_CHECKING([for bzDecompress in libbz2]) +AC_CACHE_VAL(ac_cv_lib_bzip2, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +kde_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS -lbz2 $LIBSOCKET" +kde_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK(dnl +[ +#define BZ_NO_STDIO +#include +], + [ bz_stream s; (void) bzDecompress(&s); ], + eval "ac_cv_lib_bzip2='-lbz2'", + eval "ac_cv_lib_bzip2=no") +LIBS="$kde_save_LIBS" +CXXFLAGS="$kde_save_CXXFLAGS" +AC_LANG_RESTORE +])dnl +AC_MSG_RESULT($ac_cv_lib_bzip2) + +if test ! "$ac_cv_lib_bzip2" = no; then + BZIP2DIR=bzip2 + + LIBBZ2="$ac_cv_lib_bzip2" + AC_SUBST(LIBBZ2) + +else + + cxx_shared_flag= + ld_shared_flag= + KDE_CHECK_COMPILER_FLAG(shared, [ + ld_shared_flag="-shared" + ]) + KDE_CHECK_COMPILER_FLAG(fPIC, [ + cxx_shared_flag="-fPIC" + ]) + + AC_MSG_CHECKING([for BZ2_bzDecompress in (shared) libbz2]) + AC_CACHE_VAL(ac_cv_lib_bzip2_prefix, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + kde_save_LIBS="$LIBS" + LIBS="$all_libraries $USER_LDFLAGS $ld_shared_flag -lbz2 $LIBSOCKET" + kde_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CFLAGS $cxx_shared_flag $all_includes $USER_INCLUDES" + + AC_TRY_LINK(dnl + [ + #define BZ_NO_STDIO + #include + ], + [ bz_stream s; (void) BZ2_bzDecompress(&s); ], + eval "ac_cv_lib_bzip2_prefix='-lbz2'", + eval "ac_cv_lib_bzip2_prefix=no") + LIBS="$kde_save_LIBS" + CXXFLAGS="$kde_save_CXXFLAGS" + AC_LANG_RESTORE + ])dnl + + AC_MSG_RESULT($ac_cv_lib_bzip2_prefix) + + if test ! "$ac_cv_lib_bzip2_prefix" = no; then + BZIP2DIR=bzip2 + + LIBBZ2="$ac_cv_lib_bzip2_prefix" + AC_SUBST(LIBBZ2) + + AC_DEFINE(NEED_BZ2_PREFIX, 1, [Define if the libbz2 functions need the BZ2_ prefix]) + dnl else, we just ignore this + fi + +fi +AM_CONDITIONAL(include_BZIP2, test -n "$BZIP2DIR") +]) + +dnl ------------------------------------------------------------------------ +dnl Try to find the SSL headers and libraries. +dnl $(SSL_LDFLAGS) will be -Lsslliblocation (if needed) +dnl and $(SSL_INCLUDES) will be -Isslhdrlocation (if needed) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([KDE_CHECK_SSL], +[ +LIBSSL="-lssl -lcrypto" +AC_REQUIRE([KDE_CHECK_LIB64]) + +ac_ssl_includes=NO ac_ssl_libraries=NO +ssl_libraries="" +ssl_includes="" +AC_ARG_WITH(ssl-dir, + AC_HELP_STRING([--with-ssl-dir=DIR],[where the root of OpenSSL is installed]), + [ ac_ssl_includes="$withval"/include + ac_ssl_libraries="$withval"/lib$kdelibsuff + ]) + +want_ssl=yes +AC_ARG_WITH(ssl, + AC_HELP_STRING([--without-ssl],[disable SSL checks]), + [want_ssl=$withval]) + +if test $want_ssl = yes; then + +AC_MSG_CHECKING(for OpenSSL) + +AC_CACHE_VAL(ac_cv_have_ssl, +[#try to guess OpenSSL locations + + ssl_incdirs="/usr/include /usr/local/include /usr/ssl/include /usr/local/ssl/include $prefix/include $kde_extra_includes" + ssl_incdirs="$ac_ssl_includes $ssl_incdirs" + AC_FIND_FILE(openssl/ssl.h, $ssl_incdirs, ssl_incdir) + ac_ssl_includes="$ssl_incdir" + + ssl_libdirs="/usr/lib$kdelibsuff /usr/local/lib$kdelibsuff /usr/ssl/lib$kdelibsuff /usr/local/ssl/lib$kdelibsuff $libdir $prefix/lib$kdelibsuff $exec_prefix/lib$kdelibsuff $kde_extra_libs" + if test ! "$ac_ssl_libraries" = "NO"; then + ssl_libdirs="$ac_ssl_libraries $ssl_libdirs" + fi + + test=NONE + ssl_libdir=NONE + for dir in $ssl_libdirs; do + try="ls -1 $dir/libssl*" + if test=`eval $try 2> /dev/null`; then ssl_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi + done + + ac_ssl_libraries="$ssl_libdir" + + ac_ldflags_safe="$LDFLAGS" + ac_libs_safe="$LIBS" + + LDFLAGS="$LDFLAGS -L$ssl_libdir $all_libraries" + LIBS="$LIBS $LIBSSL -lRSAglue -lrsaref" + + AC_TRY_LINK(,void RSAPrivateEncrypt(void);RSAPrivateEncrypt();, + ac_ssl_rsaref="yes" + , + ac_ssl_rsaref="no" + ) + + LDFLAGS="$ac_ldflags_safe" + LIBS="$ac_libs_safe" + + if test "$ac_ssl_includes" = NO || test "$ac_ssl_libraries" = NO; then + have_ssl=no + else + have_ssl=yes; + fi + + ]) + + eval "$ac_cv_have_ssl" + + AC_MSG_RESULT([libraries $ac_ssl_libraries, headers $ac_ssl_includes]) + + AC_MSG_CHECKING([whether OpenSSL uses rsaref]) + AC_MSG_RESULT($ac_ssl_rsaref) + + AC_MSG_CHECKING([for easter eggs]) + AC_MSG_RESULT([none found]) + +else + have_ssl=no +fi + +if test "$have_ssl" = yes; then + AC_MSG_CHECKING(for OpenSSL version) + dnl Check for SSL version + AC_CACHE_VAL(ac_cv_ssl_version, + [ + + cat >conftest.$ac_ext < +#include + int main() { + +#ifndef OPENSSL_VERSION_NUMBER + printf("ssl_version=\\"error\\"\n"); +#else + if (OPENSSL_VERSION_NUMBER < 0x00906000) + printf("ssl_version=\\"old\\"\n"); + else + printf("ssl_version=\\"ok\\"\n"); +#endif + return (0); + } +EOF + + ac_save_CPPFLAGS=$CPPFLAGS + if test "$ac_ssl_includes" != "/usr/include"; then + CPPFLAGS="$CPPFLAGS -I$ac_ssl_includes" + fi + + if AC_TRY_EVAL(ac_link); then + + if eval `./conftest 2>&5`; then + if test $ssl_version = error; then + AC_MSG_ERROR([$ssl_incdir/openssl/opensslv.h doesn't define OPENSSL_VERSION_NUMBER !]) + else + if test $ssl_version = old; then + AC_MSG_WARN([OpenSSL version too old. Upgrade to 0.9.6 at least, see http://www.openssl.org. SSL support disabled.]) + have_ssl=no + fi + fi + ac_cv_ssl_version="ssl_version=$ssl_version" + else + AC_MSG_ERROR([Your system couldn't run a small SSL test program. + Check config.log, and if you can't figure it out, send a mail to + David Faure , attaching your config.log]) + fi + + else + AC_MSG_ERROR([Your system couldn't link a small SSL test program. + Check config.log, and if you can't figure it out, send a mail to + David Faure , attaching your config.log]) + fi + CPPFLAGS=$ac_save_CPPFLAGS + + ]) + + eval "$ac_cv_ssl_version" + AC_MSG_RESULT($ssl_version) +fi + +if test "$have_ssl" != yes; then + LIBSSL=""; +else + AC_DEFINE(HAVE_SSL, 1, [If we are going to use OpenSSL]) + ac_cv_have_ssl="have_ssl=yes \ + ac_ssl_includes=$ac_ssl_includes ac_ssl_libraries=$ac_ssl_libraries ac_ssl_rsaref=$ac_ssl_rsaref" + + + ssl_libraries="$ac_ssl_libraries" + ssl_includes="$ac_ssl_includes" + + if test "$ac_ssl_rsaref" = yes; then + LIBSSL="-lssl -lcrypto -lRSAglue -lrsaref" + fi + + if test $ssl_version = "old"; then + AC_DEFINE(HAVE_OLD_SSL_API, 1, [Define if you have OpenSSL < 0.9.6]) + fi +fi + +SSL_INCLUDES= + +if test "$ssl_includes" = "/usr/include"; then + if test -f /usr/kerberos/include/krb5.h; then + SSL_INCLUDES="-I/usr/kerberos/include" + fi +elif test "$ssl_includes" != "/usr/local/include" && test -n "$ssl_includes"; then + SSL_INCLUDES="-I$ssl_includes" +fi + +if test "$ssl_libraries" = "/usr/lib" || test "$ssl_libraries" = "/usr/local/lib" || test -z "$ssl_libraries" || test "$ssl_libraries" = "NONE"; then + SSL_LDFLAGS="" +else + SSL_LDFLAGS="-L$ssl_libraries -R$ssl_libraries" +fi + +AC_SUBST(SSL_INCLUDES) +AC_SUBST(SSL_LDFLAGS) +AC_SUBST(LIBSSL) +]) + +AC_DEFUN([KDE_CHECK_STRLCPY], +[ + AC_REQUIRE([AC_CHECK_STRLCAT]) + AC_REQUIRE([AC_CHECK_STRLCPY]) + AC_CHECK_SIZEOF(size_t) + AC_CHECK_SIZEOF(unsigned long) + + AC_MSG_CHECKING([sizeof size_t == sizeof unsigned long]) + AC_TRY_COMPILE(,[ + #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_LONG + choke me + #endif + ],AC_MSG_RESULT([yes]),[ + AC_MSG_RESULT(no) + AC_MSG_ERROR([ + Apparently on your system our assumption sizeof size_t == sizeof unsigned long + does not apply. Please mail kde-devel@kde.org with a description of your system! + ]) + ]) +]) + +AC_DEFUN([KDE_CHECK_BINUTILS], +[ + AC_MSG_CHECKING([if ld supports unversioned version maps]) + + kde_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" + echo "{ local: extern \"C++\" { foo }; };" > conftest.map + AC_TRY_LINK([int foo;], +[ +#ifdef __INTEL_COMPILER +icc apparently does not support libtools version-info and version-script +at the same time. Dunno where the bug is, but until somebody figured out, +better disable the optional version scripts. +#endif + + foo = 42; +], kde_supports_versionmaps=yes, kde_supports_versionmaps=no) + LDFLAGS="$kde_save_LDFLAGS" + rm -f conftest.map + AM_CONDITIONAL(include_VERSION_SCRIPT, + [test "$kde_supports_versionmaps" = "yes" && test "$kde_use_debug_code" = "no"]) + + AC_MSG_RESULT($kde_supports_versionmaps) +]) + +AC_DEFUN([AM_PROG_OBJC],[ +AC_CHECK_PROGS(OBJC, gcc, gcc) +test -z "$OBJC" && AC_MSG_ERROR([no acceptable objective-c gcc found in \$PATH]) +if test "x${OBJCFLAGS-unset}" = xunset; then + OBJCFLAGS="-g -O2" +fi +AC_SUBST(OBJCFLAGS) +_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES(OBJC)]) +]) + +AC_DEFUN([KDE_CHECK_PERL], +[ + KDE_FIND_PATH(perl, PERL, [$bindir $exec_prefix/bin $prefix/bin], [ + AC_MSG_ERROR([No Perl found in your $PATH. +We need perl to generate some code.]) + ]) + AC_SUBST(PERL) +]) + +AC_DEFUN([KDE_CHECK_LARGEFILE], +[ +AC_SYS_LARGEFILE +if test "$ac_cv_sys_file_offset_bits" != no; then + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" +fi + +if test "x$ac_cv_sys_large_files" != "xno"; then + CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=1" +fi + +]) + +dnl A small extension to PKG_CHECK_MODULES (defined in pkg.m4.in) +dnl which allows to search for libs that get installed into the KDE prefix. +dnl +dnl Syntax: KDE_PKG_CHECK_MODULES(KSTUFF, libkexif >= 0.2 glib = 1.3.4, action-if, action-not) +dnl defines KSTUFF_LIBS, KSTUFF_CFLAGS, see pkg-config man page +dnl also defines KSTUFF_PKG_ERRORS on error +AC_DEFUN([KDE_PKG_CHECK_MODULES], [ + + PKG_CONFIG_PATH="$prefix/lib/pkgconfig:$PKG_CONFIG_PATH" + if test "$prefix" != "$kde_libs_prefix"; then + PKG_CONFIG_PATH="$kde_libs_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" + fi + export PKG_CONFIG_PATH + PKG_CHECK_MODULES($1,$2,$3,$4) +]) + + +dnl Check for PIE support in the compiler and linker +AC_DEFUN([KDE_CHECK_PIE_SUPPORT], +[ + AC_CACHE_CHECK([for PIE support], kde_cv_val_pie_support, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + safe_CXXFLAGS=$CXXFLAGS + safe_LDFLAGS=$LDFLAGS + CXXFLAGS="$CXXFLAGS -fpie" + LDFLAGS="$LDFLAGS -pie" + + AC_TRY_LINK([int foo;], [], [kde_cv_val_pie_support=yes], [kde_cv_val_pie_support=no]) + + CXXFLAGS=$safe_CXXFLAGS + LDFLAGS=$safe_LDFLAGS + AC_LANG_RESTORE + ]) + + AC_MSG_CHECKING(if enabling -pie/fpie support) + + AC_ARG_ENABLE(pie, + AC_HELP_STRING([--enable-pie],[platform supports PIE linking [default=detect]]), + [kde_has_pie_support=$enableval], + [kde_has_pie_support=detect]) + + if test "$kde_has_pie_support" = "detect"; then + kde_has_pie_support=$kde_cv_val_pie_support + fi + + AC_MSG_RESULT([$kde_has_pie_support]) + + KDE_USE_FPIE="" + KDE_USE_PIE="" + + AC_SUBST([KDE_USE_FPIE]) + AC_SUBST([KDE_USE_PIE]) + + if test "$kde_has_pie_support" = "yes"; then + KDE_USE_FPIE="-fpie" + KDE_USE_PIE="-pie" + fi +]) +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 47 AC_PROG_LIBTOOL + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool --silent' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([LT_AC_PROG_SED])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" +])# _LT_AC_SYS_COMPILER + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-linux*) + # Test if the compiler is 64bit + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *"ELF 32"*) + LINUX_64_MODE="32" + ;; + *"ELF 64"*) + LINUX_64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $3" + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + if (eval $ac_compile 2>conftest.err) && test -s $ac_outfile; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + else + $2=yes + fi + fi + $rm conftest* + CFLAGS="$save_CFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + testring="ABCD" + + case $host_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$testring" 2>/dev/null` \ + = "XX$testring") >/dev/null 2>&1 && + new_result=`expr "X$testring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + testring=$testring$testring + done + testring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + ifelse([$1],[],[save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"], + [$1],[CXX],[save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -o out/conftest2.$ac_objext"], + [$1],[GCJ],[save_GCJFLAGS="$GCJFLAGS" + GCJFLAGS="$GCJFLAGS -o out/conftest2.$ac_objext"]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + # According to Tom Tromey, Ian Lance Taylor reported there are C compilers + # that will create temporary files in the current directory regardless of + # the output directory. Thus, making CWD read-only will cause this test + # to fail, enabling locking or at least warning the user not to do parallel + # builds. + chmod -w . + + if (eval $ac_compile 2>out/conftest.err) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + # Append any errors to the config.log. + cat out/conftest.err 1>&AS_MESSAGE_LOG_FD + else + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + ifelse([$1],[],[CFLAGS="$save_CFLAGS"], + [$1],[CXX],[CXXFLAGS="$save_CXXFLAGS"], + [$1],[GCJ],[GCJFLAGS="$save_GCJFLAGS"]) + chmod u+w . + $rm conftest* out/* + rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var $1)"; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + sys_lib_search_path_spec="/lib /lib/w32api /usr/lib /usr/local/lib" + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://"` + if echo "$sys_lib_search_path_spec" | [egrep ';[C-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | sed -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | sed -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + if test "$host_cpu" = ia64; then + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + else + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + fi + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + libsuff= + if test "x$LINUX_64_MODE" = x64; then + # Some platforms are per default 64-bit, so there's no /lib64 + if test -d /lib64; then + libsuff=64 + fi + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags=TAGS], + [include additional configurations @<:@CXX,GCJ@:>@])], + [tagnames="$withval"], + [tagnames="CXX,GCJ" + case $host_os in + mingw*|cygwin*) tagnames="$tagnames,RC" ;; + esac]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | sed -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + AC_LIBTOOL_LANG_CXX_CONFIG + ;; + + GCJ) + AC_LIBTOOL_LANG_GCJ_CONFIG + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + available_tags="$available_tags $tagname" + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +#- set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +])# AC_PROG_LD + + +# AC_PROG_LD_GNU +# -------------- +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# AC_PROG_LD_GNU + + +# AC_PROG_LD_RELOAD_FLAG +# ---------------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +])# AC_PROG_LD_RELOAD_FLAG + + +# AC_DEPLIBS_CHECK_METHOD +# ----------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[[012]]) + lt_cv_file_magic_test_file=`/System/Library/Frameworks/System.framework/System` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + if test "$host_cpu" = ia64; then + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + else + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + fi + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + case $host_cpu in + alpha* | hppa* | i*86 | ia64* | m68* | mips | mipsel | powerpc* | sparc* | s390* | sh* | x86_64* ) + lt_cv_deplibs_check_method=pass_all ;; + # the debian people say, arm and glibc 2.3.1 works for them with pass_all + arm* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + esac + ;; + +sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/${ac_tool_prefix}nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ("$tmp_nm" -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ("$tmp_nm" -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$lt_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided and an installed libltdl is not found, it is +# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' +# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_builddir and top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# If this macro is not defined by Autoconf, define it here. +ifdef([AC_PROVIDE_IFELSE], + [], + [define([AC_PROVIDE_IFELSE], + [ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +])# _LT_AC_LANG_CXX + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# -------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([AC_PROG_RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='main(){return(0);}' + +_LT_AC_SYS_COMPILER + +# +# Check for any special shared library compilation flags. +# +_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= +if test "$GCC" = no; then + case $host_os in + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' + ;; + esac +fi +if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then + AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$]_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) + _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no + fi +fi + + +# +# Check to make sure the static flag actually works. +# +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_DLOPEN_SELF($1) + +# Report which librarie types wil actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C test sources. +ac_ext=cc + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int char *[]) { return(0); }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${CXX-"c++"} +set dummy $CC +compiler="[$]2" +_LT_AC_TAGVAR(compiler, $1)=$CC +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if eval "`$CC -print-prog-name=ld` --version 2>&1" | \ + egrep 'GNU ld' > /dev/null; then + with_gnu_ld=yes + + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + egrep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # KDE requires run time linking. Make it the default. + aix_use_runtimelinking=yes + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='-qmkshrobj ${wl}-G' + else + shared_flag='-qmkshrobj' + fi + fi + fi + + # Let the compiler handle the export list. + _LT_AC_TAGVAR(always_export_symbols, $1)=no + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '" $shared_flag" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux*) + if test $with_gnu_ld = no; then + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + else + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + fi + fi + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + else + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + fi + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + case $host_os in + hpux9*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + ;; + *) + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + fi + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_os in + hpux9*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + ;; + *) + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + fi + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest.so 2>&1 | egrep "ld"`; rm -f libconftest.so; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc) + # Intel C++ + with_gnu_ld=yes + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + cxx) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | sed "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + # NetBSD uses g++ - do we need to do anything? + ;; + osf3*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | sed "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | sed "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sco*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | egrep "\-R|\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | egrep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $linker_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $linker_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | egrep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# Figure out "hidden" C++ library dependencies from verbose +# compiler output whening linking a shared library. +cat > conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A sed program that does not truncate output. +SED=$lt_SED + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "$cfgfile" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments + _LT_AC_FILE_LTDLL_C + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments + _LT_AC_FILE_IMPGEN_C +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions -c conftest.$ac_ext], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[[ABCDGISTW]]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + cygwin* | mingw* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX, but not for PA HP-UX. + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + fi + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + *) + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + cxx) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX, but not for PA HP-UX. + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + fi + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + if test "$CC" = "icc"; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + fi + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + if test "x$host_vendor" = xsni; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-LD' + else + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + fi + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) -DPIC], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) -DPIC" + ;; +esac +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | egrep '(GNU)' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + cygwin* | mingw* | pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an egrep regular expression of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left by newer dlltools. + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`head -n 1 $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + ;; + esac + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | egrep '(GNU)' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + + # KDE requires run time linking. Make it the default. + aix_use_runtimelinking=yes + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='-qmkshrobj ${wl}-G' + else + shared_flag='-qmkshrobj' + fi + fi + fi + + # Let the compiler handle the export list. + _LT_AC_TAGVAR(always_export_symbols, $1)=no + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '" $shared_flag" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi4*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + esac + + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + _LT_AC_TAGVAR(archive_cmds, $1)='$CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring' + # We need to add '_' to the symbols in $export_symbols first + #_LT_AC_TAGVAR(archive_expsym_cmds, $1)="$_LT_AC_TAGVAR(archive_cmds, $1)"' && strip -s $export_symbols' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9* | hpux10* | hpux11*) + if test "$GCC" = yes; then + case $host_os in + hpux9*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + ;; + *) + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + esac + else + case $host_os in + hpux9*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + ;; + *) + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + ;; + esac + fi + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + else + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + fi + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + if test "x$host_vendor" = xsni; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + fi + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4.2uw2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv5*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac +fi +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_FILE_IMPGEN_C +# -------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_IMPGEN_C], [ +# /* impgen.c starts here */ +# /* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo $ECHO_N "0123456789$ECHO_C" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break; + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 10000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" +]) +AC_MSG_RESULT([$SED]) +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..583efff --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,902 @@ +# generated automatically by aclocal 1.10.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(AC_AUTOCONF_VERSION, [2.62],, +[m4_warning([this file was generated for autoconf 2.62. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.10.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 13 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.60])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_PROG_LEX +# ----------- +# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a +# "missing" invocation, for better error output. +AC_DEFUN([AM_PROG_LEX], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AM_MISSING_HAS_RUN])dnl +AC_REQUIRE([AC_PROG_LEX])dnl +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..c22241f --- /dev/null +++ b/config.h.in @@ -0,0 +1,252 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_CARBON_CARBON_H + +/* Define if you have the CoreAudio API */ +#undef HAVE_COREAUDIO + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRT_EXTERNS_H + +/* Defines if your system has the crypt function */ +#undef HAVE_CRYPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if you have libjpeg */ +#undef HAVE_LIBJPEG + +/* Define if you have libpng */ +#undef HAVE_LIBPNG + +/* Define if you have a working libpthread (will enable threaded code) */ +#undef HAVE_LIBPTHREAD + +/* Define if you have libz */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if your system needs _NSGetEnviron to set up the environment */ +#undef HAVE_NSGETENVIRON + +/* Define if you have res_init */ +#undef HAVE_RES_INIT + +/* Define if you have the res_init prototype */ +#undef HAVE_RES_INIT_PROTO + +/* Define if you have a STL implementation by SGI */ +#undef HAVE_SGI_STL + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have strlcat */ +#undef HAVE_STRLCAT + +/* Define if you have the strlcat prototype */ +#undef HAVE_STRLCAT_PROTO + +/* Define if you have strlcpy */ +#undef HAVE_STRLCPY + +/* Define if you have the strlcpy prototype */ +#undef HAVE_STRLCPY_PROTO + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Suffix for lib directories */ +#undef KDELIBSUFF + +/* Define a safe value for MAXPATHLEN */ +#undef KDEMAXPATHLEN + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Defined if compiling without arts */ +#undef WITHOUT_ARTS + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +#elif ! defined __LITTLE_ENDIAN__ +# undef WORDS_BIGENDIAN +#endif + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* + * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system + * headers and I'm too lazy to write a configure test as long as only + * unixware is related + */ +#ifdef _UNIXWARE +#define HAVE_BOOLEAN +#endif + + + +/* + * AIX defines FD_SET in terms of bzero, but fails to include + * that defines bzero. + */ + +#if defined(_AIX) +#include +#endif + + + +#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) +# include +# include +# define environ (*_NSGetEnviron()) +#endif + + + +#if !defined(HAVE_RES_INIT_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +int res_init(void); +#ifdef __cplusplus +} +#endif +#endif + + + +#if !defined(HAVE_STRLCAT_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +unsigned long strlcat(char*, const char*, unsigned long); +#ifdef __cplusplus +} +#endif +#endif + + + +#if !defined(HAVE_STRLCPY_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +unsigned long strlcpy(char*, const char*, unsigned long); +#ifdef __cplusplus +} +#endif +#endif + + + +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +#if !defined(HAVE_VSNPRINTF) || defined(hpux) +#if __STDC__ +#include +#include +#else +#include +#endif +#ifdef __cplusplus +extern "C" +#endif +int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); +#ifdef __cplusplus +extern "C" +#endif +int snprintf(char *str, size_t n, char const *fmt, ...); +#endif + + + +#if defined(__SVR4) && !defined(__svr4__) +#define __svr4__ 1 +#endif + + +/* type to use in place of socklen_t if not defined */ +#undef kde_socklen_t + +/* type to use in place of socklen_t if not defined (deprecated, use + kde_socklen_t) */ +#undef ksize_t diff --git a/configure.files b/configure.files new file mode 100644 index 0000000..030bce8 --- /dev/null +++ b/configure.files @@ -0,0 +1,2 @@ +./admin/configure.in.min +configure.in.in diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..f15e1ab --- /dev/null +++ b/configure.in @@ -0,0 +1,93 @@ +dnl This file is part of the KDE libraries/packages +dnl Copyright (C) 2001 Stephan Kulow (coolo@kde.org) + +dnl This file is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Library General Public +dnl License as published by the Free Software Foundation; either +dnl version 2 of the License, or (at your option) any later version. + +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Library General Public License for more details. + +dnl You should have received a copy of the GNU Library General Public License +dnl along with this library; see the file COPYING.LIB. If not, write to +dnl the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +dnl Boston, MA 02111-1307, USA. + +# Original Author was Kalle@kde.org +# I lifted it in some mater. (Stephan Kulow) +# I used much code from Janos Farkas + +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(acinclude.m4) dnl a source file from your sub dir + +dnl This is so we can use kde-common +AC_CONFIG_AUX_DIR(admin) + +dnl This ksh/zsh feature conflicts with `cd blah ; pwd` +unset CDPATH + +dnl Checking host/target/build systems, for make, install etc. +AC_CANONICAL_SYSTEM +dnl Perform program name transformation +AC_ARG_PROGRAM + +dnl Automake doc recommends to do this only here. (Janos) +AM_INIT_AUTOMAKE(kscope, 1.6.2) dnl searches for some needed programs + +KDE_SET_PREFIX + +dnl generate the config header +AM_CONFIG_HEADER(config.h) dnl at the distribution this done + +dnl Checks for programs. +AC_CHECK_COMPILERS +AC_ENABLE_SHARED(yes) +AC_ENABLE_STATIC(no) +KDE_PROG_LIBTOOL + +dnl for NLS support. Call them in this order! +dnl WITH_NLS is for the po files +AM_KDE_WITH_NLS + +KDE_USE_QT(3.3) +AC_PATH_KDE +#MIN_CONFIG(3.3) + +dnl PACKAGE set before +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN + +AM_PROG_LEX +AC_CHECK_PROG(HAVE_LEX, $LEX, yes, no) +if [[ "$HAVE_LEX" = "no" ]]; then + AC_MSG_ERROR(Lex/Flex is required in order to build KScope) +fi + +AC_PROG_YACC +AC_CHECK_PROG(HAVE_YACC, $YACC, yes, no) +if [[ "$HAVE_YACC" = "no" ]]; then + AC_MSG_ERROR(Yacc/Bison is required in order to build KScope) +fi +KDE_CREATE_SUBDIRSLIST +AC_CONFIG_FILES([ Makefile ]) +AC_CONFIG_FILES([ doc/Makefile ]) +AC_CONFIG_FILES([ doc/en/Makefile ]) +AC_CONFIG_FILES([ po/Makefile ]) +AC_CONFIG_FILES([ src/Makefile ]) +AC_OUTPUT +if test "$all_tests" = "bad"; then + if test ! "$cache_file" = "/dev/null"; then + echo "" + echo "Please remove the file $cache_file after changing your setup" + echo "so that configure will find the changes next time." + echo "" + fi +else + echo "" + echo "Good - your configure finished. Start make now" + echo "" +fi diff --git a/configure.in.in b/configure.in.in new file mode 100644 index 0000000..032475b --- /dev/null +++ b/configure.in.in @@ -0,0 +1,17 @@ +#MIN_CONFIG(3.3) + +AM_INIT_AUTOMAKE(kscope, 1.6.2) +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN + +AM_PROG_LEX +AC_CHECK_PROG(HAVE_LEX, $LEX, yes, no) +if [[ "$HAVE_LEX" = "no" ]]; then + AC_MSG_ERROR(Lex/Flex is required in order to build KScope) +fi + +AC_PROG_YACC +AC_CHECK_PROG(HAVE_YACC, $YACC, yes, no) +if [[ "$HAVE_YACC" = "no" ]]; then + AC_MSG_ERROR(Yacc/Bison is required in order to build KScope) +fi diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..7e7a4a8 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,6 @@ +# the SUBDIRS is filled automatically by am_edit. If files are +# in this directory they are installed into the english dir + +KDE_LANG = en +KDE_DOCS = kscope +SUBDIRS = $(AUTODIRS) diff --git a/doc/en/Makefile.am b/doc/en/Makefile.am new file mode 100644 index 0000000..fef2a0a --- /dev/null +++ b/doc/en/Makefile.am @@ -0,0 +1,5 @@ +KDE_DOCS = kscope +KDE_LANG = en +kde_docs_KDEDOCS = call_tree.png main_window.png pref.png project_files.png \ + project_new.png project_open.png query_dlg.png autocomp_dlg.png query_filter.png \ + call_graph.png diff --git a/doc/en/about.docbook b/doc/en/about.docbook new file mode 100644 index 0000000..1bb7173 --- /dev/null +++ b/doc/en/about.docbook @@ -0,0 +1,31 @@ + +About &kapp; + + +&kapp; is a KDE-based source-editing environment for C and C-style languages. Primarily, it is a front-end to the veteran Cscope, a source-code browser originally developed at Bell Labs. Cscope works by parsing a set of source files, creating a cross-reference database, and allowing the user to query this database. &kapp; extends the feature-set of Cscope with a contemporary user interface, editor integration, project management capabilities, multiple query result windows, call trees and graphs, and more. + + + +&kapp; implements (almost) all of Cscope's query types. Among these are: + +Browse for all references to a symbol; +Get the global definition of a symbol; +Find all functions calling to or called by a function; +Find a text string or an EGrep pattern; +and more. + + + + +The main purpose of &kapp; is to provide developers with a rich environment for code editing and analysis. It is specifically geared towards large projects, with thousands of source files and millions of lines of code. Many traditional C/C++ IDEs do not scale well to handle projects of this magnitude, either because they do not provide adequate tools for understanding the code base, or because they are unable to efficiently digest that much information. By using Cscope as its underlying engine, &kapp; can easily handle projects such as the Linux kernel, WINE, PostgreSQL, etc. + + + +It has been reported by some users that &kapp; can be successfully used for C++ development. Nonetheless, &kapp; is mainly a tool for developing in pure C (either ANSI or K&R style). Most C++ features will not be recognised by the cross-reference generator. + + + +&kapp; is a part of an ongoing effort to expand the range of open source applications. It could not have been created without the previous work of many devoted developers. &kapp; is therefore freely distributed, along with its source code, for the benefit of the open source community. I hope it can be of use to others, and I would appreciate any help in the form of bug reports or improvement suggestions. + + + diff --git a/doc/en/autocomp_dlg.png b/doc/en/autocomp_dlg.png new file mode 100644 index 0000000000000000000000000000000000000000..21d39e403669a42df8b5ad401d1ff2cfafd46704 GIT binary patch literal 12457 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 literal 0 HcmV?d00001 diff --git a/doc/en/bookmarks.docbook b/doc/en/bookmarks.docbook new file mode 100644 index 0000000..8607645 --- /dev/null +++ b/doc/en/bookmarks.docbook @@ -0,0 +1,28 @@ + +Bookmarks + + +Bookmarks provide an easy way to navigate through a defined set of positions in the source code. Most editors support the concept of bookmarks as tags attached to lines in a source file. &kapp; can enhance the usablity of per-file markers by enabling users to access the bookmarks currently defined in all open files. &kapp; also saves and restores these bookmarks as part of its session-management services. + + + +The Bookmarks dialogue is invoked by the GoGlobal Bookmarks menu command. Once open, it displays the set bookmarks among all currently-open files. This includes the file path, the source line and the line's text (similar to other source views available in &kapp;). + + + +The Bookmarks dialogue + + + + + +The Bookmarks dialogue + + + + + +Navigating to a defined bookmark can be done by either double-clicking an entry in the dialogue, or by choosing the View Source item from the context menu (available by right-clicking over a bookmark entry). Other choices presented by the context menu include Copy [FIELD] for copying the contents of the current field to the clipboard, Filter... for selecting entries based on some criteria, Show All for removing all filters and Remove Item for deleting the bookmark. + + + \ No newline at end of file diff --git a/doc/en/bookmarks.png b/doc/en/bookmarks.png new file mode 100644 index 0000000000000000000000000000000000000000..2f20be78d4043f36b18763ec0bded57632cbfd8f GIT binary patch literal 23860 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 YRIKZfO{0@~A#j~^I_voAnBSeh0~U1$(*OVf literal 0 HcmV?d00001 diff --git a/doc/en/call_graph.png b/doc/en/call_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..719f3f7cccc5c46c2adc9f7b8d3c576315f5e743 GIT binary patch literal 23525 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 +The Configuration Dialogue + + +The configuration dialogue is the main tool for setting parameters required by &kapp;, or adjusting the user's preferences. The dialogue is displayed the first time &kapp; is run, and can be invoked later by using the SettingsConfigure KScope... menu command. + + + +The dialogue is composed of several pages, each of which handles a different set of parameters. + + + +The Programmes Page + + +&kapp; serves as a front-end to several console-based programmes: Cscope, Ctags and Dot (which is part of the Graphviz suite). Since &kapp; invokes these programmes directly, without using a shell, it cannot determine their paths. Therefore, it is required to inform &kapp; of the paths where the relevant executable files reside. Note that &kapp; needs the full path to each programme, along with the name of the executable. + + + +Another parameter required by &kapp; is whether Cscope supports the command line option. This is a relatively new feature, added to Cscope in version 15.5. It allows &kapp; to display accurate progress information during time-consuming operations, such as building the cross-reference database, or running a long query. It is highly recommended that you upgrade Cscope to a version that supports the option, as the user experience of &kapp; is much improved with it. However, if you choose to use an older version of Cscope, make sure the check-box for using the option is cleared. + + + +You can determine whether your version of Cscope supports this option by running . + + + +The easiest way to configure programme paths is by using the automated script provided with &kapp;. This script can be activated by clicking the Guess... button. Once invoked, the script looks for the required programmes (using the shell's which utility). The script also makes sure that the found executables adhere to the standards required by &kapp; (e.g., that Ctags is the one provided by Exuberant-Ctags and that Dot supports the command-line option). &kapp; uses the results of the script to adjust the values in the dialogue's controls. + + + +The script will not override paths already set by the user. Instead, it will only verify the validity of these paths. For the script to determine paths automatically, the relevant text fields in the dialogue need to be cleared. + + + + +The Programmes page + + + + + +The Programmes page + + + + + + +Cscope Path +The full path of the Cscope executable. The name of this executable must be cscope. + + +Use verbose mode (-v) +Instructs Cscope to produce verbose progress output, by appending to the command line. + + +Ctags Path +The full path of the Ctags executable. The name of this executable must contain the string ctags. + + +Dot Path +The full path of the Dot executable. The name of this executable must be dot. + + +Guess +Runs a script which attempts to determine the previous values automatically. This script should work in most cases, by may fail to correctly obtain some or all of the values. + + +If the file names on your system do not conform to the limitations described above, please create symbolic links to the executables. + + + + + +The Colours Page + + + +The Colours page + + + + + +The Colours page + + + + +The Colours page allows you to configure &kapp; to look the way you want it to, by changing the foreground and background colours of some of &kapp;'s GUI elements. The elements that can be modified are: + +The project's file list (to the right of the editing area) +The editor's symbol (or tag) list (to the left of each editor window) +The query results window +The call graph's background and nodes + + + + +To change the colour of a GUI element, double-click over the element's entry in the list (or select this element and click Enter). + + + +The editor's own colours are determined by the settings of the embedded editor, and are not controlled by &kapp;. + + + + + +The Fonts Page + + + +The Fonts page + + + + + +The Fonts page + + + + +The Fonts page allows you to determine the fonts used by any of &kapp;'s windows (see The Colours Page section for a description of these windows.) + + + +To change the colour of a GUI element, double-click over the element's entry in the list (or select this element and click Enter). + + + +As with the colour scheme, the fonts used by the embedded editor are not determined by &kapp;. + + + + + +The Options Page + + +This page allows the user to configure certain parameters that affect the behaviour of &kapp;. + + + + +The Options page + + + + + +The Options page + + + + + +External Editor +Specifies a command line for invoking an external editor application. &kapp; will replace the escape sequence %F with the file path, and the sequence %L with the current line number. + + +Read-Only Mode +If set, the embedded editor will be work in read-only mode, i.e., &kapp; will not allow any changes to the displayed source files (but you can still use the external editor). + + +Open Last Project on Start-Up +Determines whether &kapp; should automatically attempt to load the last active project when started. + + +Automatic Tag Highlighting +If set, &kapp; will highlight tags in the tag list based on the current position of the text cursor. + + +Brief Tab Captions for Query Pages +This option allows some space to be saved by using shortcuts for the page titles in the query window. + + +Warn When a File is Modified Outside &kapp; +If set, &kapp; will issue a warning whenever a file is changed on the hard drive, while it is open for editing in &kapp;. This option will only work in conjunction with the Kate text editor). + + +Automatically Sort Files in the File List +By default, &kapp; will sort the files in the project's file list whenever a project is loaded. However, such behaviour may not be suitable for large projects on older machines, causing &kapp; to hang for long periods when loading such projects. Uncheck this option to avoid automatic sorting. + + +System Profile +Allows the choice between a fast and a slow system configuration. The fast profile will take certain actions automatically which are not appropriate for a slower system (for example, automatic database rebuilds and auto-completion are enabled by default for fast systems and disabled for slow systems). Note that the terms "fast" and "slow" do not necessarily refer to the particular machine which runs &kapp;, but rather to the complete environment (e.g., a fast machine may still be using a relatively slow file server). + + +Editor Popup Menu +Provides two choices for the embedded editor's context menu: + +Embedded: A menu with Cscope actions is included as a sub-menu of the editor's own context menu. +&kapp; Only: Only Cscope actions are available through the context menu. + +The second choice provides quicker access to Cscope commands, but the editor's menu is discarded. + + + + + + + + diff --git a/doc/en/editing.docbook b/doc/en/editing.docbook new file mode 100644 index 0000000..2aeeece --- /dev/null +++ b/doc/en/editing.docbook @@ -0,0 +1,138 @@ + +Editing Source Files + + +The Editor + + +&kapp; does not provide its own editor. Instead, it utilises KDE's KTextEditor infrastructure to embed the system's default editor. This means that any editor that supports the KTextEditor interface (e.g., &kate;, KVim) can be used with &kapp;. The editor is defined in KDE's control centre. + + +In any matter related to operating or configuring the editor, please refer to the manual of the editor itself. + + + + + +Opening Files for Editing + + +Files are usually opened for editing as part of a project. However, &kapp; enables the user to edit an occasional file that is not related to the project, through the FileOpen... menu command. Note, however, that query results on files outside a project are meaningless. + + + +Once a project has been opened, the list of all project files appears in the file list, to the right of the editing area. Each file entry in the list shows the file's type, its name, and its full path. Files are opened by either double-clicking their entry in the list, or by selecting the entry, and hitting the Enter key. The edit-box above the list can be used to quickly search for a file. Typing in this box selects the first list entry whose file name begins with the entered text. + + + +Files can also be opened through the file tree, which shares its location with the project's file list (using a tabbed-window.) The file tree displays all files in the system, starting with a specific root directory. A root directory for the file tree is set on a per-project basis by using the Set Root... button. The file tree also sports a Find File... button for launching the file search Cscope query. + + + + +To decrease the loading time of projects, files and directories are only added to the tree when their parent directory is expanded. Therefore directories will not be marked as expandable by default, even if they are not empty. + + + + +For each file opened, &kapp; creates a separate editor window, inside the editing area. Each editor is associated with a tab, displaying the name of the edited file. Thus &kapp; provides a convenient multi-editor environment. You can switch between open files by selecting their respective tabs, or by using the Window menu. + + + +To work on a new file, the user first needs to create it using the FileNew... menu command. This opens an empty editor, that is not associated with a file name or path. Upon saving the work in this new editor, &kapp; will prompt the user for a file name and directory. Note that this does not add the file to the project. The user still needs to invoke the Project Files dialogue and add the new file to an open project. + + + + + +File Tags + + +In addition to being a front-end to Cscope, &kapp; also uses Ctags to display a list of symbols defined in the current file. Each editor window is added a list of these symbols to its left. This list displays the name of a symbol, its type (as a graphic shape), and the line where it is defined. Double-clicking a symbol, or selecting it and hitting the Enter key, sets the cursor to the beginning of this symbol's definition line. The list of symbols is refreshed whenever a file is saved. + + + +The edit-box above the list of symbols can be used for quick symbol look-ups. Entering text in this box selects the first symbol whose name begins with this text. + + + +By default, tags are sorted by to their name in ascending order. Click on a column header to sort the tags according to that column. A triangle to the side of a column name indicates this is the sorting column, and shows the sorting order (ascending or descending.) Once a sorting order is chosen, it becomes the default, and is used for all newly created lists (though not for currently open, unmodified, editor windows.) + + + + + +Other File Options + + +&kapp;'s File menu includes further options, such as saving, printing and closing files. In addition, specific editors can offer extended features under the Tools menu (e.g., syntax highlighting, indentation, etc.) + + + + + +Symbol Completion + + +Symbol completion is a convenient feature that enables the user to enter previously declared symbols with fewer key strokes. Since the cross-reference database keeps record of all globally declared symbols, it can be queried for a complete symbol name based on a given prefix. + +There are two types of symbol completion: manual and automatic. Manual symbol completion is always available, and can be invoked by the EditComplete Symbol menu command (or, more conveniently, by pressing CtrlSpace). Once a completion request has been issued, &kapp; uses the characters immediately preceding the current cursor position as a prefix, and queries the database for possible completions. These completions are displayed in a list box, which can be browsed using the arrow keys. Pressing Enter replaces the prefix with the selected symbol. The Esc key hides the list without completing the symbol. + + + +Automatic Symbol Completion + + +In addition to manual symbol completion, &kapp; can also provide automatic completion based on changes made by the user to the edited source code. Specifically, &kapp; tracks changes to the edited file, and if certain criteria are met, initiates a symbol completion query to the cross-reference database. Once a completion list is displayed, symbol completion behaves in the same way as in the manual case. + + + +Automatic symbol completion is configured on a per-project basis. This feature is enabled or disabled via the Use Symbol Auto-Completion check-box in the New Project dialogue (this option can also be changed after a project has been created by invoking the Project Properties dialogue). + + + + +For performance reasons, it is highly recommended that automatic symbol completion will be used in conjunction with the inverted-index option. + + + + +As mentioned above, &kapp; uses several parameters to decide whether automatic symbol completion should be initiated. These parameters can be configured by clicking on the Options... button in the New Project dialogue (or, later, in the Project Properties dialogue). Clicking this button invokes the Auto-Completion Properties dialogue. + + +The auto-completion properties dialogue + + + + + +The auto-completion properties dialogue + + + + + + +Minimum Characters +The minimal length of a symbol for which completion is provided. + + +Delay (ms) +Specifies a time interval that should elapse after the last change to the edited text and before the symbol completion query is executed. + + +Maximum Entries +The symbol completion list will display at most this number of possible completions. If the number of matched symbols in the database is greater, a message will be displayed (and no symbols will be available). + + + + + +The main purpose of these parameters is to reduce the load on the system caused by frequent queries to the database. The default values have been tested in various scenarios, and are usually adequate. + + + + + + + diff --git a/doc/en/index.docbook b/doc/en/index.docbook new file mode 100644 index 0000000..705988d --- /dev/null +++ b/doc/en/index.docbook @@ -0,0 +1,174 @@ + +KScope'> + + + + + + + + + + + + + + + + +]> + + + + + + + + +The &kapp; Handbook + + + +Elad + +Lahav + +
elad_lahav@users.sourceforge.net
+
+
+
+ + + + +2003-2007 +Elad Lahav + + + +&FDLNotice; + + + +08/07/2007 +1.6.0 + + + + + +&kapp; is a source-editing environment for KDE, based on Cscope. + + + + + + +KDE +KScope +Cscope +source +editor +browser + + +
+ + + + +Introduction + +&about; +&quick-start; + + + + +Using &kapp; + +&main-window; +&projects; +&editing; +&query-system; +&position-history; +&bookmarks; + + + + +Configuring &kapp; + +&config-dlg; + + + + +Command Reference + +&main-menu; + + + + + + + +Credits and License + + +&kapp; + + +Programme copyright 2003-2007 Elad Lahav elad_lahav@users.sourceforge.net + + +I would like to thank: + +The KDE team +The KDevelop team +Hans-Bernhard Broker, who maintains Cscope + + + + +Documentation copyright 2007-2006 Elad Lahav elad_lahav@users.sourceforge.net + + + + +&underFDL; + + + + +&underBSDLicense; + + + +
diff --git a/doc/en/main_menu.docbook b/doc/en/main_menu.docbook new file mode 100644 index 0000000..18a4d2b --- /dev/null +++ b/doc/en/main_menu.docbook @@ -0,0 +1,465 @@ + +&kapp;'s Main Menu + + +This section describes the menu entries declared by &kapp; only. Additional entries may be added to the main menu by the embedded editor (e.g., Edit, View or Tools.) Please refer to the editor's manual for a description of the commands under these sub-menus. + + + +The File Menu + + + + + + +CtrlN + +File +New + +Opens an empty editor window. + + + + +CtrlO + +File +Open... + +Opens a file for editing. + + + + +CtrlW + +File +Close + +Closes the active editor window + + + + +CtrlQ + +File +Quit + +Quits &kapp; + + + + +Other file operations such as Save and Print are not integral &kapp; actions, but are rather defined by the type of editor used. + + + + + +The Edit Menu + + + + + + +CtrlE + +Edit +Edit in External Editor + +Launches an editor application for the current file and line number + + + + +CtrlShiftT + +Edit +Go To Tag + +Moves the cursor to the tag list, used for browsing through the file's tags + + + + +CtrlSpace + +Edit +Complete Symbol + +Generates a list of possible symbol completions for the text to the left of the cursor. Note that this option is available even if automatic completion is disabled. + + + + + + + +The View Menu + + + + + + +Ctrl/ + +View +Toggle File List + +Shows or hides the project's file list window. + + + + +Ctrl. + +View +Toggle Query Window + +Shows or hides the query window. + + + + +Ctrl. + +View +Toggle Tag List + +Shows or hides the tag lists attached to the editor windows. + + + + + + + +The Project Menu + + + + + +Project +New... + +Displays the New Project dialogue box.Use this dialogue to create a new project. + + + +Project +Open... + +Displays the Open Project dialogue box, which lets you search for an existing project to open. + + + +Project +Open Cscope.out... + +Prompts for an existing Cscope.out, which can be opened as a temporary project. + + + +Project +Add/Remove Files... + +Displays the Project Files dialogue box, which allows you to add source files to the current project, or remove files from it. + + + +Project +Properties... + +Displays the Project Properties dialogue box. + + + + +CtrlM + +Project +Make Project... + +Displays the Build dialogue. + + + + +CtrlShiftM + +Project +Remake Project + +Displays the Build dialogue and executes the last build command. + + + +Project +Close + +Closes the active project, along with all open editor windows. + + + + + + + +The Cscope Menu + + + + + +Cscope +Rebuild Database + +Updates the cross-reference database for the current project + + + + +Ctrl0 + +Cscope +References... + +Finds all references to a given symbol + + + + +Ctrl1 + +Cscope +Definition... + +Finds the global definition of a symbol + + + + +Ctrl2 + +Cscope +Called Functions... + +Finds all functions called by a given function + + + + +Ctrl3 + +Cscope +Calling Functions... + +Finds all functions calling a given function + + + + +Ctrl4 + +Cscope +Find Text... + +Finds all occurrences of a text string + + + + +Ctrl5 + +Cscope +Find EGrep Pattern... + +Finds all text strings matching a regular expression + + + + +Ctrl8 + +Cscope +Find Including Files... + +Finds all files #including a given file + + + + +Ctrl] + +Cscope +Quick Definition + +Finds the global definition of the symbol currently under the cursor. The symbol dialogue appears only if a symbol cannot be determined automatically. + + + + +Ctrl\ + +Cscope +Call Graph... + +Displays a call-graph and/or a call-tree for a given function + + + + + + + +The Go Menu + + + + + + +AltUp Arrow + +Go +Previous Result + +Selects the previous result in the current query window. + + + + +AltDown Arrow + +Go +Next Result + +Selects the next result in the current query window. + + + + +AltLeft Arrow + +Go +Previous Position + +Jumps to the previous stored position in the active history list. + + + + +AltRight Arrow + +Go +Next Position + +Jumps to the next stored position in the active history list. + + + + +CtrlH + +Go +Position History... + +Selects the active position history page in the query window. If the query window is hidden, it becomes visible. + + + + +CtrlShiftG + +Go +Global Bookmarks... + +Displays the Bookmarks dialogue. + + + + + + + +The Window Menu + + + + + +Window +Close All + +Closes all open editor windows + + + + +AltShiftLeft Arrow + +Window +Go Left + +Selects the editor window to the left of the current one. + + + + +AltShiftRight Arrow + +Window +Go Right + +Selects the editor window to the right of the current one. + + + + +This menu displays the full path of each file edited in an open window. Clicking a +file name will make its editor window active. + + + + + +The Settings Menu + + + + + +Settings +Toolbars + +Toggles the different toolbars. + + + +Settings +Configure Shortcuts... + +Allows the user to assign different shortcuts to &kapp; commands. + + + +Settings +Configure KScope... + +Displays the &kapp; configuration dialogue + + + + +A menu item to configure the embedded editor may also appear under this menu. + + + + + diff --git a/doc/en/main_window.docbook b/doc/en/main_window.docbook new file mode 100644 index 0000000..ada3fd8 --- /dev/null +++ b/doc/en/main_window.docbook @@ -0,0 +1,24 @@ + +The Main Window + + +&kapp;'s main window is divided into three. The central area is dedicated to source editing, and holds a set of editor windows, one for each source file being viewed or edited. This area is greyed-out if no files are open for editing. The window to the right is the file browser, comprised of a list of project files, and a tree-like view of the file system. The project file list will only display files after a project has been created and source files have been added to it. The bottom area contains the query windows, which hold the results of Cscope queries, and the history pages that display locations in the source code visited by the user. + + +The Main Window + + + + + +&kapp;'s main window + + + + +The size of each of these sub-windows can be changed to meet the user's personal preferences. This is done by dragging the lines that separate one area from the other. The new sizes will be kept and used on the next sessions as well. + + +The file browser and the query window can be hidden in order to free up desktop space (especially on low resolution displays). Hiding and showing these windows is done through the View menu. A window can also be hidden by clicking on its close button, at the upper right corner. As with window sizes, the visibility status will be saved when &kapp; is closed. + + diff --git a/doc/en/main_window.png b/doc/en/main_window.png new file mode 100644 index 0000000000000000000000000000000000000000..b5842af14cef794365fd12f1a2bd999c0843622e GIT binary patch literal 719478 zcmZsCWl$Wz(k%-t?(QrhxVyt*!QI_GxI2p{BmsiE2X_tb?(XjHE-&|f@74F`ovNv+ z>Z<-TRXuag>7H-Oic+XZL`YCjP^dD}5~@&8Fj!Df(ApSq{~~`jQMmtYaHeun5+DBs zqV~h;zX+m}w2te)UHZT4%aEP$e}W!PqE`PeABwme{$Fkol#GO^y4UjQn!6XSR>$Sr zMQRF@Gu4+M3nHdqZx!@|3m!J4=ar{15>@Px%>?1$R_jO3qZ0bR$u~#qjxF z`l_g1(N9yVBKvv?G*LtF*5fwurHjJX;Sr-QzO^UcYJ%Sb7Uwvm6gN5^a&q1n)Ke1t zXz|MO6x{z`e0Wy(AfivU=SNV3?G4ylvT1l%xlm$}!SspaQQqKBHs&AS+yc$WS139( zr?_izdrkedUb?cs=pZRLc0CrHR=y)WhYXwSkyy9z7Oy>5(y+iyiE;+z2LI;y<7ym0 ziOMzz(!EaMMR1Ansa_;MWg$vD`2+C?_icT~K0?n9v4*vjk_+FX#_`}<=*Pve`%}=c z$8@MgoOKwSlk+%^MZyT%~lT?tF2FfVi0Ril~FDLW`)7?Y_BTO2XnfL{i!vd%iv zidfO%tov+JOX znAJXLxWoxB2P88@Ol&hTnD#pCoeX2Eb(JysnFrIRNdTpf?29%hH|n&&-~PB+bX0JvU&mO zfN20Gw5muBHVs6bedw(*{&J!^@z+I*#5G=1FN`4oPhCBmSOF1kDl}F7G0-NO(S;8B z3?s=KT97K-{GDJRDDb8$0b-~A0(aT#L`W_X*4N}S#F4|Io`cTP?Vj89{` z{RAsvPro&=v5$E6@TxZW8C}Ac2&-2_B>MII!MQPZqY0?qPp*Vvu+g}%aV_H|vhlvI zGzV{Mb%zJa!}kD9BwhCsfYQ6UVc8hMoKKM86N*4xd@&>*DTC6CbU%d1 zGu?>18oXy=Aom(LlhmYIK8y*&eKYz)So78u&?>C%4E3QFFyNO57S8i4(+5`AE^rAs z1?vd{KdpZ-fB7PIIdCzstlkaZL}`i4LK~o(ZrF;oPO8w9N`$s7?_;~tc~Ny?P?>3r zZ~yUk4bQlYTTgGCeBngMMiiA+fi&|bTz!+sL;_}@kANbCYd+QX3>L8#`%~O~(5HsT ziG1Nsc+*%nz%EMy)wI6T`%-mV4kf{7e{l=O{GTID3D;2RJj56M=a3*ncm4!o0Ag0Y zdt?T}x{TsbHQT1}oY{{By21AJ#>G!T3fsi|@Bdq`1wfAEi!O^Q@xVM{6uqUtnjv~l zr#&b5pGw5XgcI6t-k?ZoPfLz3dMcSJ>X0X3uOP{wZ~)%-kLgZ{?Uyjtr|)hOp+O-_ z=f85$Y42SOY@l(37`@GfQ6yuj_D1w?oy6$+L7w?Bz#2xX$keySxWe?>VHQ+=r8@IS_icw3A@{v0@Q?7(>T0WQkU)9G45)!Yd9N^Mv69STpptK} z)yTI!2^P}<*2%g|_4+zR%DXoSD}_}Z1AX73Yr(|%LRM}^&aYW@7!LyFw+MS3Mg%;s z`Fiv$fV1-XggoPOGd5iXu+;IU+H*z+GD?w&uICxE+og4D;V`U|z+T-VGkn0?(Q(YB zC5Rb=X7%IdxpZh5;f&6Wo?Nx@*u}}iiI#o0+wr9W?fWG#=No%2*+;u`j69ro_A5Pl z(yt(P{ddu3RH`(2QpO3W1oLhv$SwL^(ue%`3s3-)!s8nY_#kif_q|wo4@BgpJt)~@&A^hn&ay5EJbVzKpf!tTwYw!QttR>2*ynOn2)d7lpIjXPZfDa0T`$PkzwB{Zx3T2IiprAhZFQOyQ#(x z{gdKW=#q$kj`sJAE9}nA-f(Xf;;o;E7Nv;Q?y!vs3{HvDLvMsGJOb9Ca=jY4-*BYU zKDRx#b4GXMcD!H6!dNwXUxRE22t+s!-SBfJwf&Z7VP++dozH+5Fgm|Jy8T!%WN`>G z?lcQ<2cJ~&kEn6pb=f=XNTlb;T!SADibbkpE|mm&NDYIoq~7of2;xIr+Bu<-#&JK) zi2%CaEwexIwsJDhz=tF=E=N8q3r^sejzdN4_eVT`%PvbaD+pJ9O|Z$cfWjeT&@s`4 z!m*xO-8B-)T3-AQUO!~A4?*EUhxC>@i9rFOTPdQzErx+X4)97Iu1#zZ#(kizcoI3j zq|&4jM=wEE(4{C=arTcH`#B+4?_cAF9r(%FYg6}7Y@bvFp?3ttjn=e`n<~jG7+_UW zKqW!Vz0$TnEC zva%!!`s}Z!CNUZn`Y24fVW;~%2WEcew51C0l>1m@_ADZIiK=l-Pt>sT>u>Jhio$o~ zH#g;E%Cop(2m;oI^b@GU^$R0ReIa+6P|Tb2_{l3}%q6J0yKPxnry^P2KzcovkJ*{L z^_M(Cpg&3G8_7xuFB%paRXN=<^7gmZF)v&RVh=mJ zI2EQ~lC&vV>NzmY95gGt>q5xsTh3J5$uP{+w?&U~cc@++V8MEuWT=-VcKq$f`qEWZ z;NjlyK{n;|Zk!{e$R)Qv^g5c>FOYq!V{=XUh~q|jSRc3$y{aDQHhh9yRQpq5h<_Y& zIU+HPdx<*tlSk+|PbzceGg9W?J~G)ixOVcIljA*<7#Lg`8EAH|@p_R!!MVg`<}tM4 z`CC=}Qt^RQR09Sc*hY+j!f=A37ZVE>^1wx&w=%avq{zZ&MKmmHqhiP2 zTk>T<%W6R1$^Dwd9#FuhoG@Iq*e&LHHkAzk1z6wF@WmHem1nC{9K+$0q(0D2?Jkoa zc6ii{__&V5C*7X=&$9lc)nLvm3TZS~Dk%8k@Z~t`m$BF!SwfH^llYFb6o2koo+*nsHbopu=}YDj6H_y5}GN~ z#trIZDw1`!!7R${{u>$%sx)rW66`j-W#m++LxT;m=t+ftm!;EV=Xqi~jN4o5P<6>& zmv5Y%rV4@4#NC*P)nKcm7t{s>LNA`w>F(ygsjGKdIFe2W=V<$E2wzatM zhgaPK>=vPf8`s1$@Ve6!iqF0MHswRU3$JDhMeW`AjS(k<%`m6L*WoGA9FcAHS14iqQo@dG1|yiHLI9m;y;V^Kup^4 zsP<0RGbXxhg}HGXBm@n83kvHI-cHnPo(yZ$^gWb=pngsY*h!~s#=}t;N*h#^Yr6~W z1=t=%x96e&0Hc}b7_y2}z*|Uqvh?AdbFEcZWsbS+)zY@$rQfc)fe2K7?LPX=aM1iu z6n!X-R8RqgQ!O+SOZmYLQ5Wj6_@1-{Z2q0n&v5zT-OwgTVx`N5EC{d2zf(0PQ|3m3 zl~q+Q`wW^%*0lfz0pB^RAbZS;!3t7wYYB?n3f%-OYwye#^ zMCbALHfIV)YSGXm%J6}uW1bMVidsacE^L;VKap_VD92c5nU?5Z=h2)I|CMGW;(FndW5TX(xWlt-4;a0Bq&vBF07+jfSHK)- z=P5wtPj@a{c)BIbJl7D=c7BKc%}9#j4_2$AmWR!}Qf>h@eNwwM66w$>(L*f(!nu8I zY&mBwn#oc9?a4V>)INSLp;zQuB3pVb%-XCQ9Zl>2(L*OA_d7yy(aK_)-{6*il=45Mg_nNUcrpzYD_nWXv&-n z4~qyNCZV9*ilUK!ZpWk;~fe*lkX6yC0( zi@#tCbvFkx>d>lkdYkW_aqkiY6PMw@$VrOR0dSm^`9D9v2**0eFo{;sDg71(uoyLB z-k)q5bUdC{-iylg{oX8ur(is_nCnJVp4PlcTcLL-MCLw#}I14BN2Cr%Csk`Vu5EE>3Y;chb>hdjA5Sz`5*rPE7SCXT)* z@r)(_c`O9*bT)m=47*WqeuS3QS?gZi9PfotpVxME(<6|#P(H&&SdJvWk=wwH)>GJp1QCFU*dHqolbN%nmp z#ig7H>{o90=N1;t39JrP3=@|O>nxx~ZxINLp8iya9|6W0fp>c|c0XgG_sb5c7$bfH z3I~(_x?nT#hT$TmZ@;&N&KygJqh&T;Gkz*Er=oqkC18f!NBZAxMX$Yk=Wv#f@RA05D2kCcVXfs1Y>moO&ej1g)7DqoWBe&l;6w};W617J?(f+~rkedhmS zN{i4fg%ddmQTd&wWjNU%?j*ALW)H_+$6BZ#s$%6L+d_MAxe4rHVtC(-wQ!=2!>yh? zyU=oOsGrnAITCo4pS3L4gLb4FvO7N;+xhId3$=-l(k1RozQ)_T{S%wFO+s&_gAk`2syP!T4*Cp>k~ z7NF0^y+{z;)3p8`JP^7)|DCEXSrN6RNEkpPQ};JXs=}_A5AdV!$G+SR<3;x?X;Zfg zE-5mrAI9+N`;Z~@J!Jb+te4<7S*a=53*)u?p-_2CX&H+hKUorPC0soWa~?PhBN z0wpm`^js7i$Y^g~eZsi{O^ME!idxxg<IuFgA+V>BwH(+-K zmgUq)2h-A%RK5bgHx+BZmj@I5*$?5CUl~PFJ{UQ>70MoIqL#rG%$aDIm#Oy<9j?1g zE?WbQM~WQ*^lwm0uPm7bPf56_x1dIggxxgK1e|zpT+XU0E?*m8;X*V-* zD!Y$jPi(3z-W)jw1UI5%VZ{YPHr*4(eSe7o9WE?-nwwz}32@%w&(q~xZq z#hmJS@9S4kb_`w^9c?O*`m>4JDmTh3#lvp3;e^0!IYn%YL;DGCv}dnEpA_P z&!ufqF5!pxASH zcj-5g5u_b{PWBaSSH`r59V0c8BI{p-sZt&Cz;o&3{CH}GyLD66Wu-eF7DN;q zhODXCgg)UM3eZle0*kf}I|eC%XuICQKfA<4h^8UMu-zGUS16EMx=D#CI#6QUA&;)LgeZzaP9^s(W|g~0M#dz2DWTAL)Z>Z@H=JR#D+234Y~hm0J*PE-#g3=p#evTEDc?e!| z0~0Joy7n>}Q-y8O@mJQKww6#Axox*@t|~WgX%_Oxse7il7uK=@V13%o^RWRT4c}zC_v3o zHu9kY-by0_3ZW|^l783o$ilo!0oEB9)*kiqc}QU~$MIV+wHVhTOw5kn0C=;C&`_h0 z{BK7|H>TMRZj*!?43q7eZqwqanq66A}H zXZq>?+sMF{rr!a}js7l?tpu0RDSVXF zsXSv6&=-s_fgcognEheM+m86#wrs7NN^NgymM}IzCi<#WtbA!ky8PW4m6RerJ7^Bn z1DMbL#>M8Tx~tf?5vOk%cc5_Tmp!s<`?>9UG7wypxT+OKM!x;En%6CBiOe*PwRidW zm24O*MgGN#We7#HZFkoXy2*i6(||i*m03@v+C(ZyYK$!734w&H$?jd9Re--O?Q+ba1fBp1t2h*12c#(43*h7HiA^$0yI!|4D zH{~|9K11QRE{oWlYHnhO?~z1~fsn+5V{>)&O{tHpjt?fp?fv|~cq6<-l=r&5&MBvx z!8~r364AN)y#p@=sF#Lm&*%B>RwzlhqXREI(G96g z3zKNAh`;OSP$d?_@NQ3W_!ft|;m> zC-BcYlg37SbbBJO3uNO_r$(akagAAhcfe|~^rT-9l1c_ULEx#D6rLqC7af*aP=u;D zAAYZzeJMAx*N}j!C>ecafj)E z)5QFx-#Kz2zJ1O!x<&xfS48hjpjnh{mm?_)XWI>v+qhlI!^# ziA#Ub?Y>C&NU+v8o1#et7zuFa5gt4?uOuddpQ z&0^*X%V*hr!>nlghtJrtNXLV zw`#StxvoN~DWQ)Ys-vhlI5JZSLyv)p*(n%U8)-XuNSZyk4=fQ-(q>(K(u|B3%h6iw z&LdW^yF(14q3c=J5F$#sE_@}|0r;N2j&Dehri&48Edhvj)FiC|T)6b1-U}{oh(r-^ z{ufl8#tlY0ix~8<@hSTlh|B0y7A~@#H;`I$6v&KGYiW!sxupToN>ioKA=S_lJK8U% zmP6MT+(r8ukxehceBQfqK729FIWNr|=GG>%1oAe-22Or;r*^DGDP9M+@sN}>8kCEi zZka*`vkQyPgmUyizd2MlDb(oGZcvq3LQ234#UI&pscSf=C^x;mbA%?>n6B)!B9z!? z(Wrqt2Q5Pct>Lvh#57b~y+;j~KseF3H+kl+s`lZE=7D+9Mml>-&H!jibkAbVMrsMa z`{kE4G3$SHl`y-z?>5c(!4cxsrCd(VX|G%A*olpR{Ojx8D^;)c6^!byp2z(**R*<= z6Eyo2P1K6n4*$m~8ELx=P0Blb)^+ES^Cvz8d=+sNSl1eha35qt9)-*p9vnA#RC504 zh~|M1DJ|Ksbgm~6y!5c!rXR>hJm3Lx}&*MRH>%uWtv}086 zFn*6Z4>e=_5J9ENT3?`D+S~m~Mpq1ymAz>@0`I zxjW%mf9zK^3xPrY#2ao;7W1;vqVy@^U4d|KMOV>Y88R2G>`3)r5Y6bMGPr1o1@T`g zn>Dim`R_OqN>P|?!T>q%qj^5|nur^%9vcIV)8yo5Keuob+J|bhO&gAFv zer$5r;W8T!zH@cZUwu6neYObV?;bLaHDLZY5}nRo<0lLG&wQIf`kX0k6x%{9*78Nr zPlH@>qIG?Hi?T}2Nqfr!Wmt%Qrr!c1T_5vZ!<_v`$?`=S8ol;HiVxlw(Z$_`Z*=b2 zfAz}W06iv#gUf3#0l+oc9jX^@)*QKuCk6PfV^R31%2MT%f$v_K6m)X%G+|M%WsF-7>$Aw=bG`u6)Te*<`NTF)# z35Qcd=I|37(bHV+g$13-0@B>-N-tZ9W++qa#I0*5RORyB>-E z#WF8E@FV3xZzbpb+gglT5;84Wil!u(DeT_}?U(M>KQ5#Er-O~s3sGA_l;_C`Lyjs6 z2dy_!YFZ2}V_y>WJmbj&&QulPLXn2;~L**yTQ&7yfFU-(`-r8#F~ zUF(W}N+V}4Yr($}AS;_squ2&cDmuwc2RsE^(xw3Ar%P<|M90)tN(V$=wB_bCg9O3D zvHC%G>Xzue(em~QZD`$vQbvk0p+iZ}jbFKO@$l{6HygcU*qWRe*{VJ}Tvv@VWnaA? zTZ}vem1dBIw=bh^1UA2%*tJjQ+c9m(Mj2lZwl|6egcB2AY@mI>Df+qHnC1&ebH!(6 z7(wmS`{oKn66QjbyL=Qf2C==oc5F%yL#l>NKGI8-Ov*QsID`dZ&bE*BZ_yzuS6gbP zq@9=LYv7l5FhL$26qUYn%!&9;mTks^BQ!SoE#I^ks=lGm%G(qsFUOAJWmG0eWD?cm z8CYjz!_p6!@rt6co>?p)g{qDmP!$1bkjw>lPA?M`%?GbX>1iT3pzWmIlFWD!`Cb?L`j`TyZL`o*k_%K2nhw@e{U3w4L&20 zdHy>8t%=}Xdt6t|3^(vCT=9A$`*j#3=Ueoe|CJ^B&8cjH@95bPV~W4R(m{mvE88eL zCtRh;FP2@sY_i7ts`>EK$JRoi8HLz)synpgp4pRAh?NT44ps-yjBlX0!YpT1uo5Ph zpTKPQ+E%aVwtJ#ah?xB(U+dZpO1vVV{hZ?Sx%@lGo?Balp*>juu>>Agk@*E7m!}_H z+6JZHv?bP~5>%D8;T0Vbv;66<=>Vw*if+JAOzT=U(2jT(UDU2q zLl}0z&$o1o%&l^5l%WaF>(zKe{VR+ez8z($(4&k+MN=Jog#EDl3IAqjg8@TmBPurb zG`#rZCJ$lCMYd}}u*`gjvhZkW!Ydy^PJ$1E#GpRI<)4qdLU;R_au=Y7hcgiM>T!$h z*!9a7;91X%oyaOeM<;_>ln+XN9ZOcY^N{&{%qdN3-KzwPidf^vb0d;0J_6iY@wfzcVi z>`*SUzgkRi9=s_JsP~onxnmUOe>#HBx0ek}BtxgVyRJOQ5B9DsXlRB;;`q*!>>;l5 z`Q-FoZ0QF(vS5ZNkDoD4~9^$U!545VK2sMcoZ&>|1{WE z)#3E&U#UKZG)Vg9>59%`E7nEqnh?s>CiTP_RI9NUij{WPsf49Wy18?0S-_q7)_P7U z$Fy@Sw=}@1M$V%JH$+Iu!(8+`)TZ+Xo00FJJRu{r+zm5avC*FY3d@``agrWDb2t+v zEdG->LA2TocKl%IDCsxF|IDLns zD!}SZ#vf%`!&%1x(5=(DOQQYCn59i4b_F}b@vo^TsRzv%O>qHJ+rrp+*?(2{ui4wK z)iJ#a_KFg7#>@XqC)+D_8588X?nqJQ{ zimY(iV7lE|2bi3#JdfR!bSgX_IZ2`RGE@9#O2Q}NoR_&DQK$!M-6#0-*BPpI=*;o6 zGS_Qa#;IV;(2i3)eSYM=`Qc;;rwielTqPzG3Yep?!HRE^i%KUGt2Y|Snl%V@*=Ki6 zU!!>4EX~?U3flYO5OjlaX?S{7ek1NAm{(VK3lv){;|hM1qZ{F<5ceA4Nvnkh9ocL4 zmda;a8=7F4U_OHx4(dXu(u<`JI%s1b5$fI{gENqKnPq>$3S|e;V2TPdM{4 z`a)5O?-Io<%3^?&z`MEppZ|eEF*q{{WL(`uZ4b?+!WnlRq_Q21gYw#`!UR2wJ}00{ z3W|W1eGhSyWi`*BI8Yyn*UV>WW6xM7^N1^ktIiwVGw~g<##J(#i@=-1FDx zKh9SUgDpCz4pRVwZx|<##%W$U1RPA70@|z)uBGMtU4nc@xdd`D-+8z|Nd7R1&k8 zM%jKapVr}sagZlTR0QozP5EcQ&qoS`3)a6<|2vZKq&O| zhA>Vo9m3I1NamSc7N_OE0ICw^X6Oq6Ih*t+1XqJt;vX1zz$eA-)2pIiV=PA~Kn+8A zdq|xgv3**`&z@wSw?37{s_k=Dxy8Th?4xT@O$Lx6Xk;xDDw?bVO_ zR2cbvE(#DDf=DqI!p~S!v=HmnCYzVQK5W`ih;!KedKMHV~ggQu$>hF%)m_^8GJ06|aYj zV6FVl4So5bhW{iH9}HD=279x#;VRFOZ8f5_*6EPb&4(P>Q`LDt)CnyC)3{Q zFu+^6J-PJIJ3?QnjK8P}x44CxUttl`;#vyp!*gxspHxZm6^7dljsK~xtgF8pIL(>% z+$G__Wv&X5!fhg6&X?|Fc)CuN?q1 z**{fm!h%+41oN?ODCyuSdQMTc?Ch14;=)_VT<4^Ucft)7mXCQuE>DZ}g#@5Q0%cv{ z-)YrJX4BRR3~l2CFTr*H>{<4%;@3XWF#;uC$M-90s%>#n~cn6}rE`Of-bx|J-4)hyW+3Bpkqo_e4SrxOrLu z#1Z5P=M9juyr&La5y%U&QPXF}pb`f9fGrVtzX(0k+eV5#+ve0-M3Q}4!+B|K3|>p~ zh>NX4$^nmcmhkR`KMnI3k8Y+PnhN8hD_riS>eleYst@qd8XXfZRe-tX#!5kM~%` zzrtucU(c8cHGq9g`(w)_oet6v{7*3^N!^|+!Ma;Ql;-`7P}0V)F95su{Oq?=jlC?%g;r4w zTf$w$I#h}$5h^7V*g`zJGat>Q1FB5$lOWF)gqtGUU0&A1M3S+c4-NK=@h{JAr9;$R zu#Y#OL=7fZH#7>sm5}%1dS!~)$gBFY#W?7bkff4~h8xH%Fj&f7hj*8%6#xr}@MB*? zxioh+ml{K56rJCicNA^u`Q!{6?31vuBZTy+T|r$zCR=!(%sLh$MvJ?X0kDkb@LJTb zh#+{-IF*Mg5g$l){mPeoo|>3E7PC-PK`z#=&(9>+>&nnQ>U9R;R?fXTF&}@m5^?hF}e647p zDhJM8$iSH)qyGx21g?9!7yJ*ceqtWTtorvjBJlQdd{>IV)(WnkRmM3IN5|8lZuBs# zXP?wO+MKajt(nL=I&_DHg<+F=XtLB5@-%-}fpGLos}SPd09+P|a`t6NYm$!5C4HGW zL1kx6U5fr5k9A;^Oq6aCMIUn@w;A|NC!?4eEN?x1cFHyR)v*n|1ULAu;M6e?xSovF zt-3F+`!edY1OxWXwXn_rIf40x{@otst6r{m|1>d4*8X|@mdVOMQqLR3!A@|BqyojO zliSU%*`=kks@oUVbbo)xg^}h>k@nFEW?za%SC!CZ%wFE3nsjs=xt3i6uyC>NtdT$0 z|BNlE(Z^`!;zk~+CeI@Ag6@(?L|6I_rlmGHrh5*nP=pURDqPCZ!6~3H877Dr65S&u zA)6|%3z;H$yX#G#xtGt)S?X;+s6<+dN(;Y24L($PVExK4xJD!M)Xs70s zt}W0M`HB_pac3vt}1uGOOZz^WDnWB+8Sy*bMaq4E(~p+_{lz7#bs{=*ppL2QZ?@dn_D8h zAd{B;BWhc>RIrIW4qjss9x?7(ApZ&SSJqj41U@@KyR{AiNql^;b%o;N_jNTE1_WMLi>h-%7z&4Je~eBrbW#6)C!1 zu?bqbVeVn4dEO?#0FaQg?O8g4)J~;Gz;6JdW6kq{LKr2wgWuyTA`T0SzDfXVU6Ur| zs3)J`fklcI)0R&CVOi6`=3T5EFv5vfcvE$*#dAylIb(T(UsS2X!;YvW=*4|UuwFo) z&Sw|P9?m_5f7}Nve_`5%j{weFEA!+p+PUBJB#|>7J9`b!elr+sZ9#bI*ze))|c%dh_f^;9dt!+EyX;!j^DiMOxoMt5ON`d zOufI#E_>6?thjaz48$}EbP+sI85i2Cql>5AF5A62c2`IGj$fLzUw<5pi5CT#O8g#-I4ngh))DDUA>`R>l~G=7%#VHI&?bLcX%#RMOH1V9xF*IV*u+^7UEy8+4$%03HZ&GGFg& z^b`<3{(&;^6(7Ow#@2RP!D~(Rl-Uoc8Y%c?6jI2rt}gw8H0}F2@b#Q{kb5ssr4@F* zj8Fe=->^t^%{TK(521PQqu5G~xBaXJK?ngcj4pxWMC^6B8y(fm*f9f{!bAwXY^Iy} z24!mWS!sw6?(Dd}^Mq*i7Fmc;6FwiIuWJ$u2`{NvH!j<7t&^htTg-Xl6X%J5_WQ2S z*^2@Jng!>g zEQ78w8+-!spQLWzFct)4WNL#gqVCn-aZEj_Uv~GpQ)C*)LkGm1V~4&vAkwg`dEup? zUCqbm5T1Zr>tA@wQE+~Y4vjg%*c2Ci4uCB5hX#+9IC<0^S>F>6wrCvcsS;{#2=02= z;mu}fZiUC;21`A0|A9__y&vB49g2yG$<4o7P-}VPsun%lzS!eAeHuuc9}rhwY1YpbyVh zTnvBmU}#eH3+LhEkc__YS|P@#PteKgpaYeZ4T!q`yqZ;B_yfufVex%Y!(15B_Xo+l zqP5|=qhmWqz?@X@r0R} zVMd$eD3!Ed5O)eRnGKmenEYJvjCOJ7RI&dvAKo$N70J=F(O$XG=t-gPX;Wx=NooV3 zJ6u>NVINU7vu4x_of!qepL7o1aP(I>$p%`!#w%}uepagnhW-=v9sOO zrHU%kF^I;35xA$4p6P)$6pu&$R#9#8pjH>R8Z{!yVe-ZTK4l1_&VJ*!dFTgwK_XVp{O1AP*^V z`O6vY64SuSA?QfR_^`a?s|tP|49=S`Hx?rBWV_K?Y}wO)ir@ehuufs%qYwT0THwVn zsF)bhSHE?ZvLbHUD!L%%O-B=aVb=jrS{Kz;eoTrz%W-zeAf1~4`?-|(kAJFKmYK=$ z?Yv6hNt6gcMLbZ0=GYe>WH0{V1qfGoUV0vz+_ad?XDl`OmqS5@$bHvIr4R3<7+;d>LnnbhctwqzC!pQZlbG50B?Z94^K_{;#(jtyIigZzsMH~ob5Ks4M z{bzZtZ|q1PTqrlCI|O_;P@v*MY+{Fqk?^g`l$xMZ70b=hLj5UO`on$2(wMn^#mj_K z`D~47^H$?l@cBj*npE3QBF;wUYWfdZ_6-ry0^mlZ}RYnzEQz!3Q2!n3!i7 zBiWO#_Gq?VR$`(6wI_iIDW}rAH_v~gDQ0FB)WYZRPZP5jqz>KJJ}tutak9b6HLOU4p6H3U#BX8S6^Nknc%(;b~UUU|M$C;h$LotGGO~J zLY!65;^(_0a)>swM(jRJ>SgRRc+1m!%+&+JHIJiQg(D#z9wiz0nKCm{FzB>RChp(7 z`#%COctwoCP%uzKda3Kvv7SlIm1qS8ca(gKn!KPLVbch*Gm9W2^&nKH9 zYA!dEuav{v%Q?{u!wq*PyhHiY9xAD9x^ndue%c!WL_5t(^ z0}LHfBCUcnN+SX@bcnQcN+aDpfV44fo9ZzIWaKr@Mb^opnCV zhnX|yJbUlwc@ECRPF&dcxs0ufy^s0#u*aUNphdJLc%?iG#2CK0cO+QBQ@q*BXhZ=b z6s6ZYp2sfv*zx68Da=pNxndFbmuHvOuX4k1=C`&#u^70+(|$_BcQSNd4s`_Wj4C^b zM3=ug4CSQ;q8g3NUW0kc|D~4`dy<%p9IWWiLIt;-V+&Z(d0Hm5Dq{NaPG}*{a6ro+e+yWVgP%P%g>F1xK!i>2x70P-t7OOg}bi6v%$Ofu{G!#FoUU~ zg=?qix7+wnt5IptLOl(ejO$Fa@floB56w9s$N46)X8v1p!guh`$7;H$Z^W!JaY6f; zIf0gMwm4=*oeoe{l5E3{sWe4-UDyxsHz>Q*Pi_OYq`dk98x;<1b+LGe4CG}E*>&E% z5PjwxbFr>_5RkycBE#8sCfn?1_9oOW2W49z^dp)PK|72jjEC^z#CCql@ValjMS!A{ z{rEc%5!%Wtt3XF-zs{$S6NL^rX=y^?PDUftft)Clqa4_Fe+dIgs|1H7LVfCn3)~nn zcQef%G}lwfcU(h%7@n3eUgJXY}?#@lWne-?zvrN%m@hqCYmhRtem6~#7y~;+ zwU+T&;L3A?Xae}S#^Lg7+=12bJ;&QXj^V2eA10X!XF*qbr4v=(kAF}{BL5PU6++&} zo}Q-}9_aCKyNTMX;iwKGA~(s3q0MY9s&_EAj)P29jk4;h$qHZ8gc8Z$b==U!k*moC zyt|gmo!xq}Cr-q{f9yc&Pw(aq{AHpKcLG{JvvX}cU|M~XG=D(Jjy!R`e#2CVOFM0V z?h-Pi?SxU7k?p6?xHUXe$Pof9_~mV30VybbmW7Yul$#md2tnAE-|3bUd)LQ1xSgU` zs4AN+Q1>wNnf8!HTR+u*YY-5-aQ*Y=8$`;a@Pr=NhSO#phB)9Z4C04Qo06~0p%2hY zx}3&BFLRpx>8Y}3JUK&hmAKd!Isa0}xu<3=;D2c;$$0}FXqHU#=+WT zv;M7Pq)}#;R1}mRcqQY>fCpagr2GJ1W0Gb`gzDuDeIyUuF)KE8KsSoVkT-|rb8;pU zXXutqp(ch$|KnVDnK4}|KQ6m9EYnw3t;{jJ&&yLCq8kx)%iE4c+flOd&%@ow3BsS2 zhPCwi<~RwAs1*FtMXzvEZfZP5FzCF}6aic2&MCWMtj9O^9FQ(OADr|E*p6uD5S)N{ z51UlIjq_XP?&-keTKL5;ivy2EHO*9|3sqdxxRFv)dod-PMa462^%d)DNFFiLo$Z9E4~+-~sp#U>P6o$4#N)w^L0+U8QWz{;#sM(TVKtb9T1 z|8CO$j}a(TG85{Jvt_|1g8nx))+5LtVO`*>oI)UCd%#Jx2n~o$iqRs=j>o?hJ`7w> z%Xd5m>gL#Ik_`wps3@AM8>rFF&pGTg@I_8^1T1qgIVkMbldZ(mG!4?tjT-Or7r-!Gy8}QDccd81* z6yXpfPHjjkpVMcUq%{7@?X3m=BxvK%pF(EEoY1<^Va%HfO_=h_M8r#U;FZ05gU4zGn#^TjKz9Rfz7M(>lIEdRoEU;q zmsQkImp9V7V5%d;yCpI79WYsVFWAw&<5MgACy$cw1dA0l)6XP7wikrXs%Phsqjb{G zd>t?`oMaqM+hq|_KSVfn(b`!w#_-V2tLtYRBQ6hHr?HF^^H>#78B`61+#x1H_gF$g zN>ji-x1GO-Q;c64+T7oj;zQ`gC?1b9T5pk%aS>#LqRR!_8F6nBKR^x>D=EyQ({<@} zT{xPbP~>o%MNyfLEv?{hACF|seW)gNcH5tMYlC50egGGtAo)(;-$q%f{FQtWKCR>} z_(+{s?xBCINhmVLQ3qyS)6Kv7 z_#n|LMrP;#S9cX8)BTeE9CA-_3*A(wvkg5^5y%_e!P*rIRq%0p(*_=A-=Qo9p?xTM zoxSG}E!0EHathPS;rQ)~#rW9n;&FknvvZrupp`jrw4TpJ_!R1ml(&u7=E?egicVci za-<#Ef5TVhhZ{y2d)8Y4bM_KowX~sD_&ZNb%TV)W>xC@-hif{81QE9xkV*KEwmAZv zWr31ON^F7ROe}8!(I(zU2g8Jmg^30(|Hpil*YKlr)WmHkGJYtbi|t(l~%DE}h3 z;vnT!Q*&S{N%S35M)vOlP)YPwm^(4bn)UHJu*seSWbX^a)E|}I-yGhM_x?p|D2_fH zWT(7-=omFIWW5W*5-x!U1e3lFcT@unti@oNSaQ}82&{;s&|#rd8%_+6fL(z=1WwK? z=>_$A{OrY}#s>XTEuW0-9;WS#j$J8{2EJ$yL}|rxLj{pyaT`XxT8Hy29ATCzNzfQ} zQrOWcdOaRu)5_Q?8cjsOu6=QmAQa#O#kH_n#^&X5^q< z5?F>LwsC=DaSu)}m^0l8Be6Ghi)t@ZsqJ+;`-@Q|YnSlywBHEA!zqaA zaJ+Ogc+8_mKcVc|)1gGm)3#?Bw&M5Dhby6&e1+$nd7-j0A~gHyN$tr<^S~z7rL|xI zOg}4BGWIAQDCa^=R)8=KJcEapzfTEcD|gV4Rx|x)ph5_&{ChAru&r?Y>AoBIn?`Ns zoWBNR%-OHqHz=m~ztew$|D*C9HVS=88Dv14qZi(El!f!wa)57MbD4Yj)KmhfUxFk@wRPte*4{lZUl~opXyV+a*C&9{ZlDs?Ar$MxB zD4NWm@JhB=5IGTae#~Q)V~OrAPk)9(D`&M8x2GM%zjPnFN_*djui=gIsxM*&{)O5W z9!3@GKQ$w0176}_89|)YlA~hWVWMD%zQSM{k9Efr!0{_MdT4WcW;lu6i{2>dQxCdu z4?XeYe{giq4FZkM2u`A!N{ZirJ+!Ha;1Nvn?5&}~Y49,`EUWXxUqDP8-oEIQtSNA9Yt!{Uo_f4o7P-8CVI@l4ugtG{<_6_ z3RV9YTPa3aZWF}c`dvGdIB&IBWYS_JSnJb!AJ{_f*UA1?{xLKl{ju8enRv$gynd0} z{SjmR_+ed9W7^7DX!Y%zc1O=heeaGB?M)x9X_1;BpddzzOPSi5yA($2d z{~C^q$@32M;vo*C7S05+2}*#nT3i%)y0lan&itTwRzqQ1<0*UN{aT^{|JV}L=_EOe z{R3EaK+$Tnqm|oqd2t|+m_|$O|1L8Wg-x5D5lY&3>+qjB`KMFSQ1Z4+Y71H|uO#la zgDa>*B8Uac2}ul!$AAy#ZkXP&JY7Z zTCeCDY?_<13FGW7nOgi8RZ1NXlnt-CUiT5=&M>pb>Jo}~YSTQh4_J#@HjZ4)3CJ!e+8pMo#LTj{Ox&diPSVzH)Rou01 zDE3P^*3yr>pxxh}Rbr@_ETfp5sx)9&GVsXJKB57ZvnKX%#g{yle?2bh70P1u|6oy_qfb|fS8Ln#q9@JEfc~G!Yi}^-L}BA zP%%+=%_j+psoQjw%9w=6oxkJi?OO$Y=JmEVz&m1YT2-zX%>7Tf*CTmM^azN;JspUfk?wN&)AJIh4{=zYUAKU-Z&;K9zj47D$$xRKyA6DSNQ8!WiQ^ zru;}3)-LKIycbD?qv>X)a781*ZrV&wn+FZOLa8)OXlBT#<0K@nnuIcvef4AU5#mw0 zJi@}Z2<&v27b2Vw8ECAn2)KC6N#FW!@!9`M&?@emmv&@bWu(;Nz4)K@JEgHKsR~PRXjGF2mcC!w5D%-MTr{|>i1o2OEmE8*5e`&P|;3) z{B|R=^&0h|(hx1WU#Q*xb7tKod1db4ZEMTd=E{~vQI6@(qv%Ue0mRP*^xydLVeqAI z3wVr%a|vy;QXUFIKRncZ{5~a%iiNc$Cq0U9FByWRRMvrB+b5icV&|UKwCrOj0d!<6 z%%SvqHmbyfQlRS3)p|(zJ5%N*q_#tEe?c^+S@fZub_*&m27Sq=pr3H_hb;QPVb_0R zum5|vz9gDfs3zMnBh`NAh-Rsjp9AgBqt3-iE}<|Ii$T>(X=yB=nRu#_tPpuxghAaC+3& z3mnx6Z6qj1gC7qoPg}IHnX}7aTP%D(|7^xWpJpsyOKVl7C2lRKxoy3(T z+8V{In4HTDjSoBR$KBlMiVoqb2&sH!D-tCMB1u1&)0SteF8RsU$(iuEexVW;nbz@#kz zy)$=3^_aOQtvq)ROY`?b?^NpjB75@Za+uFA5!H0iRNauv!yUKge}C5huH1coPypW)3#-=!MKjUlk-JC;Y6aVN}Q43zh2D|e6-EE*JX*3%YLG? z!{ie8md?Ca%aN?-)f({$R&+o%9rKofM#T0HL080oH9}6@{GOBm4Oms%r$Y3!K;^sguhF{0c@JUCI1t>T$!&= zDtbtMGv^d4a=rFQeD23Y6CM)nK(`A01Nx_4UTC6$73yQ0{_oPR$ehMw&ENjXhjy&& zx-nf#j%ZoNpL8F>zpuOm+D_@Ka6a&*hglG@XTod>_|%id29AC#zv+Pa6gI0bK3p5i z{LR@ObC%JJEqiH%wRc$4viRUj=N2c_NBtOi{wRI#o2JK+5V20jpFr6k3Hz3iwQdnz z)2FjuOji}FEn9pgYKOwKFS=4*%f=DtY*5cR4|yW{lBo09Z>b^>vv^-L*Mq=e;#X!0 zRW1x;x6Xsmc~E9^9_P;EMC9q_y-ikl%O2-#U>-|Bc!A%g|KjFgGH?wrhU%;&)OIc2 z9QsMwAo!FhTfdD8NgY1LLubd)CaXkKR!}3Jc-YaN{ZCi9{~hi$?sGv{+d@b(^YQhp zF63;nClnwf0M2~1@rH}yNa1>(&Ni?Me8MFiy{JvS(Ff8xKgQa~JjBHbN#IQdsX zwNdJckr2AdB}^L7uVh(W77yF#8nT?*48nJlk2Mc1=OO4FWVkx7ahqq)=SvP<+rkMn zylYp)d!o75a4E7k$DFnWnF=ylShmuTpzT>-q_Lt9wF(Z&D}2#f{1vuldQ38GfG-u1 z!+avMPvh7anA{1!j=lG|*ql!9uyoK)Av65IoeM1WehDQcLR~2nV8a)e z>i?QR!M+@RPkPIG5#7w`V{p?fI>|2?AVY|Su+9ZQ>W`7=(!$JFD0({9j80w?4z+6u z1U_Yu3R9-jkCgY3 zbWN;Ii35#@Aya~6O>!LoTkdEN2_o=+-Hr*?idWY{*UKnT(!g{it_z#{BI=s$N0l3 zx5@roOf%O25Yi(V6Y-qf|21~j>wuK!xjoE?imB<{JsAG?jH0|Ql}&{7!lY87fpFCR9l}Ch9nRImk%P?wHFq-S*4W?At7T$1ha$((n^qkCJzg zc^{-`4mt9i2q>ABiT~3Ve?s3N_LN+igrIJU0D^4NF>Fh8Kb+4G9liu}O(dLM@-hT+ zfPg?3{7FGgNJ6A0pYb&2zpKxyz%@YUZGW|N)JAs`@sKGh!=3YU?EOgU1OR>g_lc$l zP|0;%cSXgN@g>%;(fy|NGN@rNOaG_gEQ&Z+=dQQ z7AaKzWPg>V0FTL8=2Sk3OOsQ~c_kB)Ej~uC^oMmd{uq(X#4Lxsm9`5Aq@siLfDi*} zW-Q#WM1=eZ!`*Ks8GOODJ3S$qaq4mEyH6=Hwz0`;7{=dzyx6!?ZeBe7J88LF=|VWg zU1F}QIP%f5uu`4wF#fX73wFTame>$T!iFy2hR{Jmsdqr~V=H>BxR*J5(j>uoHL;f-!Z0WmaAty`KcD5R27BF`kI!KwPUH@A(3INTM*K;}>z@vlMOz6G| ztUzVNo;=z5wF?L=sRHm~HjUs2|6pT`=tVtFT@~tfduX6O^3>woeYB-Y#3*@i4e3wE z(~UnMOnj0f!Azw8&iDAL>yvxgW?LG>>*2?uitmSO!FBUcZ^~=F6Lu!YK`cttDbizo|u2UkYPtEVJl7mb3)R z8mTic@~wIF+-!3jp?pMXC$)1nPl!M;M#+9k48wNU3M*3|i$w>Zu$C zg!IpIy0y$vpB;F*H3?~MY6HZ~LI&`EQbX0A#7i(JRkO~Sf*(`Dm-hYf>W(fL)*zVPx) zw(Kd{((n2Zxr@X-&S`>AW>G(d&G<$lZJoiNh>=EGMggGX$SWyt@K+<;Pf#W?BJ7t| zVcMA(1m+?s*Y=FHTe{91Z!yDg0AQa?5#@Bu8Lj;y*Nb6|wacL99*>yQ=bNzI!D9ZJ z1>AM+e)EK3v;(K~+oi?{kHXWBOwY7=DlM4in449-bDy$tkda5=nAi@@rPNVmcep=>N#YJR@d*fh16gk#qv$;u6zk6=)B%juL)nDy6LT_3)*j$ zA`({mnh&LQG=c$6~D{{o#$Y#{M9S zG-9n?YT5LwEk7YwJIxAfszLYAu?c59Rn1LhUY0PG2mq>!a-!W73En^-#7QED?!=F? z=4&i%hv%}UmB9ZqQ1UJ%n>crTK=njOer(PbLrE1IxKVes*PX&3V%% z+%aGV5FhF@-XCs10d4c>Zsc=%C_lZpE=>;nF}$AbS(ZV*;S0W9+ai=vlmi4P>qy&B zSCLwEjfdxxf_JD~zP;U~-71Zgcrl83VAs-e|KM8t)0unQ?1{75TNY~4GTmxGFjXRe zysQKX{z_l5G0h$JRRchd_6?JYNC4H!Cci3Yl8k9j|6fy?(A@3bg88KgSpO)1oN$E- zfO}z!L|FgY*=S2lrZK^t{rK7VL*9jSm1uyRB8zbT8Cv^A$Uea=fz}P1PXdkO+fC=8 zZQS#_o$HCyz>^n!QB0z!;fkc`EF$QaE=bYWFHdDRh%NqA8_fpWv~dmr@GEDuZHoB} z+rMlpR(?+{BX*6hVYAa(;QBY^YjEqcpYhpq`mB6=L^#_^=8~|-EAf)!klJLR_s91) z5Y6@{2~ZU&0LC1xqhHTG{nFS(PNBSpMaq~!jsy17+-HD?-%1bWvJKgKV;t@?50G;Zng z#d-JR&hR9#SINEPNOxJ#KGYe2W|>>5I)gR0N^?o)?RvF$G;R2rasY$7R>QS)PoF|e zBe(=t4=c7|jiXLH>n3uCzkuK%Vvf9y6SX*JQpNguGm1Fl%M)w`r{oR3!JyV2fXu&- zemeIy=SC}4VN;Cy;9=o3uXmTwgP6G&b<#`UT%{Yb{MSUg z3uI~p6XNG^{eCa@!zwDSc_cay&6Bb;~(&eJfq zCs)C0U$^Bry8c|CW%(}nloG0yTckP(v&tR+ke|8)J@elJkNVAlrrp(6l_RD7k6BkW z{*=-=$!)|9FdtP;{?%5rhBYe!2zq`y7E$3StR#2xhe2{3Kdh(pwaK?6`f}bcY4uga znKLg{|FMajeRdRf4Dg3@flN{RTJM!FrRQnUE&u-gm8%ev4XO-UBaI1C1f5gZvE5N8r z@HIj@>K-<4(sv1rN|2)8a=Do7$b`B^0?@0nW|a3aA%6*e(Y}YUi}#OkwJJ>jNU8LN z8eQE77s=`$_C8p%tKm$DwfSb=OWcMLs_rV|T>DJ!?5KxFf@kz{hJ#r>8hphoJ_Ws?KliA?7yvise{+g;l0L*_nTvBV{BN z(6;)e8!L)<>3F1DoR%O++Th*I$|$+L$x%$3G=_L)920|_eci+QP2z5#;6JL*_!!Sd zL!} zz%E1oT6zcZmEhLpi4YB1eY{_4ss+rXLj%Ixmjk+?XOV!Q5u6NiF-~Y_WvC_5-zA6S zZX22!|3ZaQzNQ(H%Ho-iHmp>U@1A+^Jc-3%z>|B1#t)gJvUft6E3&U>AH-Iw&9RqX zCX+c*0H8PcxZdtv_}`1)hFlP|F;OsNq3N!(Xgr2JXy34%kJJJLwv6`xUobx4r92aW zWmQMc@LA!ozpdGt%jE9#`U7Y$;cb}Q(+2NgxCGXNjH^38hfSkO-iBY0?gy^we6tg5 zM%R~W{OV2t`gwp9ZJG#xTn^0(xgApJeyB~c7X*bnMgWW+1MdkgMB(Fysx6B5H2Bw4 zC%_WAMxXw*-@n`8t%8Co2ioS11NNq9F}sXQ7CP#jES_z>XfuCtRb{0(76llZvIJqw z0_^Pzs)$<`4V{IQ72qMvg-MyQPXd#YoR8x(Rh&=5-mK{&hF@ySkO5@N$c8xZ-VfKleUi{?#*O43c7`1dlne7m9BV~`TFDh;e0OEbA$X$DuN+e3S%I^M z^S*}{US&Cx3EDbV{sq7Y_#?fVb?m?OFnXVL+mY03%~<*q7kGNGcDFbE^ZI>h+*UUY zpvaRJ-nl=%RkO>l8P`#|Fq#fAr41<8m@eE4+KK~^gf37u33_s8O_yM}6!R4|zl zz58)u*cZsGWa<-tu0GjubF;f!T1p^06qnu>ug z(JrY3$&+%ZGdcGN^GA6Md>Wbm3kWQN15kS0c~>XCYS3q^$mB%JjohtoaPs?6I3}#K z^=n~Jw)20n!wkXI2xjd-uQ^<3_PXWRYiKw;Xl^j9{{#U4dW&ReX#@aC1&$i>z#SR@ zLjNXb0pc^1mUh`qAe~7&trk-sqhH&xoC)5)*Km4flWKVFSS1vql4y9TFE|z&+z*XI z7pYnVeYx*=_H!*o6~N}7kp5|#TE`cwFKuRulHb=c>3*nBaTdgKJ)fR1*Ptc*uuSry z_EQr8-39&@N`3U|>_=2B6GwPNG<&&ZH9SItQ@_cbl!L0#{-_-$;J0+=e+r@VHM(oR z3PN~f1JFWPs0!@!P<4A6qTT2TsKUh^n2!EVrw=_ilX2;oRS$f|dam{*T&bt{ht8Xt z=WII-d54+JgrCCSbp2RzZJ6D+tqHU-PX5OTZDut1UV49hd$QCP2qB<(=YI5`6F*iofYNDtRiVG`yM2e+{tupKP%zdBqWs5Bka<_cu-Nr4!N3yp%%x}uQXkU)*pbrsW za{s;B^^H7m&tv+ue6x)=-CAVI8!@|L8_~cXtWWBxzNHRg*)OiF8PiunZXCqZarQ-= zJdX=wBi3Sk@*H1^>Z<_eU^gG_tT)@1&Njfmk=d><*$=vK7djcxM>X+G-CC`f=${Z0 z^sH*jdUT4ez(B1f&zI2g&6;tKBql4-$LB?8!&I;9x*em|X#zWZ2rh-^$e*}`)k{#n zJW!ZRt|cED78QNG^Ugzlx5gZEgSE*H{NSNIfr`}u{MxFu$ygovCGVB%&eJeL5q@vm zE8VilN&uQ`S>WdDm!ip{c40N0I%VelY3yFrt*;0~JdS$70(xuCF@GfyLsf65c67m} zwOqOs_{H^=J7Wbn&NQC;T-a z`qY?76i5imUjU3;UxD+Ed|GU4hwi8-T3S(>k{0{>pj}R=%I|Dr*{-E>PpzgRvDvBF z=7kFv_u^~oK?7_2^S&uogVJ|#ip=RMBIr8`1^oF7FY`{M;`s|2K|5A1RrNQD15h%$n4FtY|%c77HaUUg~yk< zQ!y<4i6}ZpYJ>B^m|)prB>?R>=Ss!FqBvX+O3 zo7>%v_GO$9PAdG~e57ddSODrh>mxcM6z$A55$)|(|3JJF8#k$0(hb+xWvs`;rrlff`9nbxvnWQ4lEKj5i?{}csv!n z03*ejv`S%1`=N~_V1n|EKGGJPJpSRW?+HKi(cdf031vHit~d$ zu6aV5mZuqWtrQaU`g(mcF`Yn||6=Z+(+dd`q}KDFQ|9{VSUNUHBMs7rG)-R6ARoRVL(Wm=5*1<0{Lx2xkp7p!iCAst^ z3cAU)d_luaB|!l6v*GRZzoL-(!7aY5S==%+ZSLZqK|ifPg{U9VivmErkZ~#{;v|mG z^<~>)wOI?whj~g|nI;mwm_Rks-TbNB@=TJobxE=R>GtN|;oOdW>>Ad&5|nszwKQc9 zjK|-Xt$t#u1s~LN#S&BXTwSNJNPP>ARD;r&bdR07hDk$c%^qH#hWsqEUMUG{U=-8- z0Klh`7ftYGqkgjR-kp0{LFQjdnV=E3u3Sr;FEjP?0!g)qJPdUL4Po8$*W(5Tem?i- zO8NkMjRNYE_x$dA0*=$ZKzEJ+Vy9DWl9=OHsfR)={_U{9X?(MoAm3(=bUxeF(H z#&-a!%t8r`uoBcZ{s23)MYyleo|eDfBMV~y)WweG5FdiTx=;XSr}b*p zu{P#80RS?Xn8e9DT=C)YboCdeBvZ5?r<4B1JAsF#tH4!)rGI;$DxwC1U+8^v792y* zT+IUD$hT8d`#7JC0%dj-0IXx`6`@Wyc>gKKaKk$SE-%xIzCH96^W%yuigDr{taG%u zJ>_!gUYe2q834A=#o6>`lt z$*put9h&~Qj67uD%ia?Ih)MjSt|cR z&+{!v-+>%#AQ^r(0)WB}8JZKXXnyql1dvKGl8>Ww)B4@Pkn?!!0PAl6{59So>y)Xd zXW{yztZ*{+8Bvbv&uoCwfB3LucJ4z6N$wxn$Y)w^g|lfEK>M>RGxa{7=*NQ(feGE7u5ski}Eu ztYi!CRV31pRiuV>qc*tGr3%p2)DBot{3>r_rAo=7iG(=Mp8T$@h??%^vvBS~9xhE1 z#Y6+r=+|R+tD^eRkOT;Lk|DuFWH@69!1~`(@tMu`>{tyfoVhE`7`6W?l0AVl0L?On z%o4PShQ#Dkcvd`CgMj5?q&{;FaC~ICjB_#6aOh_x)Jvi{3%Po!V_|FIkRZ(N5ExmJ~>o`rvtI2u63b{OIJm1Y#Dww z0ia=tKM8(`3;I|d8*jMt2>`CX{CqgQ5SX1WtNQ(y*i2ESmSsh&NIwAQJ+}g&jbi_+ ztCYBId@YNEIzrRrcaL$*64LEZO#8C(z;d2`$7*~cuaNNAtTUO&PAt9V zrg37EUDMfQG)7Vy>ZS%DnQLdCLsfChJ@_z>hvkc8_{_#Zh zULywJT;M+FdE5^3gzA##+Ii1z%+Y+}qR;hwB2>|HjCj0s0zhvn*B2MZ98LE`A^=5| z66rM`4*+e`3Q5L?^So*Nl8&AiKsq3}LFI)1-|QM*gS>08L2_*C5^229XN0^cEDY*$ z1#xIMuYG=q;GX$KhSUQBV9&B)0s31(`tUi{%f6DP z?Z8cfE%_>-2W;8qFTZ{6^D~qXTgyaXp{`lG5WrjO(gpwRtjocGiO^j4<#>+ znCc4r6$C)wa^WjbN?#N+>FYU!GAuc-} z!2fn`Q>3TLu~-);m=n+7Su@)nySmbIWn2<)7xZ-+58z89jtBV(2g!wu`@5avyzVS) zFWDb`Nbn|q04RH2w&A-gBsKu4wXjG-tF)Z31aB(X+UWe>#3zlYAQmI__JS{M-$@le zzS9Cxba927k_2*W)~D<`;%g3CeFUHW=x*E`nMEZlLzM9tRFxL^sPD5{oGTRCY5Rc5 z$#r$@9YCM47M?URJhiIIo5=i#gE>oC&HtHGt-mBekDZb&kR1S{&50V5_V2k^fem4Y^i3)S2Fd+c<(O*AA!!G5g=oVts$5MjeT698Hz0-YUO{yCXICe9G& zMKMw|O)LO4N<&!x+?}-6tsWpIV+-JLUKsHZ-^4qT@yQlZF*;2dbmANK?_*^xEowZe zi{c(uD$Ji4w<4@(c2?bDeCp-7xBWY}jjICyKBL_d9q~hP5>2`tor{7pm&R%Ii5pI} zmiX(nxsC#etk9+~ONekuFV*H$9SE+pz1f=++HqB5n7JewO>WEq;wowYk~OLx!DuHG z+z>nf%t;J@>YiNVam#7I_y5ih|2t9apk1rsemPkd%xlPD4uCvN-IZP&tZJP~D2OAC z`2Mddl`#q{9BWaEKqQS$^!ojkc#4+aMkME0RRu^zxCSQ%ZYx& z`04$hrxs4-gS~vOjJzfs9P(BQDG;B?81aSMk3I3E;~$tDMBgmckY7(icRUGP;J@eQl4q z?`k)@g+&kiOOt))&vt)BtFYv#$uV1uHcQ@;?Jv(1Syz+{2K*cXe8AMDsui$*6SuEc ztvdZ-sn21(*3q!V7eFII`7nJn94x+FD(|OvW6kujShLD_0ZnJ^mH>pW|zsi|O>cERr*9g4+)+U0Z5y zg?|vger5Opnju_nYck(cA47OR3m}NkVwKkT7K~m@R;fLLeL+3z_IdG*Me4}g3>VZ; zn#>S)nvhQ7v?H{uw8Lwf#u87x^LlL7;o^5SCsgm#MSUL5uFGss>j!uF#Iu?rFZgC~ zG6I3>GW_6YFRZ@iy+I|DX8)#5g)UU?W^&jQoZ!oTuYCg>6_Pw8X#$%jCg^FqG7mTn z13G>Ob(7KPU>5gPv&5rI_Nze|{@<5xIxsW4RYBMDc2%cHZ5A+MF(VWd zIEt(UOpSZyD<9?%4glQ2i}c!#4-mY;lPg%pXr?fb^i(sZ^0}qt6P|*ZJgck%!gr$X zzDM2`YQL4cq)3grrb*2;Qi6CLBXwV7)MWv{1M7o;wnOul^m|{7?%8iO)OH=mGu_s- zrFbFoG#nnaFXKMS7v`wH=H&vQ;yZ+j54SYG4iOyiAISqS<=I!aPh*>BjE|~F%TovK z_)mZfA!0Iy06Mk9k4-w~wg{VS0GjXjd&XM@jC%#7BZ_VAG4q!_qmGqSdRz7ar@j^;$X{0s7U%X9Yv+#7n zfA4ui565suDT#^j!TscPS^xS*=;DH;PWDzo5W+;j^3TiOG^+DH1z=|wZY z<2|L??#AKnT6F0=If*ijU$g|`fUM@Jwd zz`rw>=ahvA&_FN6)<;kS?ztI~Pm-Ig<&ngdt`R4&b=au{0IgGFh4q*enYX>9F;<#w zAY1ks3I46>?c|Oo4p)h(ZhtL?SK^*txf@nzGvTe+9uA#~WPuENOTTa8JxAb08bIGj zw(W3lak{0VBWcz8Td5%aASJ)uT%&^#vHkzI1dDvc9{GV|5|D#&z2)wCi`Gfnu2;!n z9e&NTIV<}@kmifxm`NF>1$97B-** z0C$q#_in~>MaCCYy%hI_M_l!1J#02%o{wh_+xM{fi~}V%xKRiI^230)#mbkIN-AX3 z2<=oCsppz*Gcbh!JK6a5@MLkl1*enljSMd8-oM|E_+5|)Ln2&`hW>-{j*GEbc{@%# z=Jagu*b}TZkzSwJTeM1>DnOf3F954=keNSsj>>}YFWoQLdm{`Oj8QsR13+GzR0r^P zvpgJI$Z5N3I`&$BZj_3hKJN1Kq~$$J2t zEOex#A1^Fyeyfj@{sEv?{W9@t-3`0b3TAthj>UNu$E=Wy@}sJ+jrLY_->$6`k-G)I zTR_yGIrMArrQky3IW<+MP>!CiaJCpqHya;#*Dpe37{e6N5@7o)^R2Z3;j>Swm`qeV zNbKVH6~f}vPxxs0@U5r^h0)yOfCgUJ)!U;VD;B`Q008-Z?E!$k!O?kssRmyA+a_U* zk|#P#Zsg1H$<2q^kQQ3er9;=|ZYRt$902N($cjhHHmvO{z-~=^U^jPKqFiia3kl}* z9)Ob(oe2O>mnjN7_*SLvo&IXUZ>Bu7Z!D+pk%$W*xhfln>y3-a%^CnGTTHI}m-oDE zjjOy`XD;&3M<>Npk0Mw^Uc2XRz*Z_7_7337v&~gLriA`q$o!KA`1F|{L*4d^{}um( zuvL||BQ=W3>jLucWqc`00gN<79E#{sb{7D#a&~ z?~vpaXmjt&`ocS85&rb8p4jO3AlElacK78E#5 zO70&vXu)TJNUr#vfQb0lFC<56Pi0 zazDM!$$3Cibt&w$9w4wo_YWXb;sX$}r7?(}0k7D!jQQq)HFe&Q>f~8Su)lTr9BW-b zv2WPqve}mEDs>lpeedeZ} z9=QadkGw(Bu=)04Iy1>xMX30*GznR+g4^-(dUK!8>v!lzD_t#-emI?X-w}pq4N0xy z0e+Y6{q-HUMZ8X}GFU5ZqTt(pRa69KeoyU_!{XN9-@nNm3KkLuLzw zr`4E<1;ee$jKSr=e`)B(~Uh3IjcX zeSeN-^n$;(7nLjPC0BOMcp1(*8Dmg%^F>+VhPPCmwhi85$A3oZC@Fxy-AxEfcbh?;_FqB$vZZlJZ;I+K=n{A{qzdes0um#=oJJtS#czu*ZhFz`*?q!9{}*u5|LcBTfeTn z>CD+x_bTl=DetSIZO4|u3!_96fH@mBJ01KaovgE4;OA^awg$gEMl5Z6Zz5 z*>30*3{3%al`~BS+x9ebSBSQ;t04TDFG$dzu}~b{m_F zwmbkWa1@b!CW4X0js#`2DvG~bzuNr2YMZnV2Eomi+QAzxY*kt&#Vs9+f1OT#!Wuc9 z-!JB;X{mlKhVnlHpgpfLFsX0B=2KA|V6FD72S5;+cWS}t3pz-I8cg{r(xljU7=0q6 zZb?@g5`IS?Ry%4xDUoslzT`FmGHsYxSQXe*Lj7M#6w!vk(!iXk1}MF3>TbXe0ssoT zcIKe?-blxDYhIk^%bWli>p`_ltQlS;GYMM&rh5|gvqu=?-^`^ZKE16l>t=vh%0H8m zfXqWecg79Hemp`i1!GOJxl!+*;aU02WmtqQ4897-ab3A6kf_&0P!xI4b@0aR$0H?a zI~8rpj1foc@FnJk0Vgv`d%$4rCmEx^PtrR?{{V4_W#Aj1vozbP10RsBJ&afKZQPa-p_cL4BB4H9&3z`uqzU+Dv_8Y)sp z-7p~Drrwax#&Wbj8+<8(q|p|PxY^tb|F5|nq{@O+eO?cM0C(X-k?2zY(wzUHR}r*I zp5G8=bmCfrk~4aqnMvKw69f<4r`>X5sJn&{Lv8vg+<$wByCKeo{gH6l6?Ee&NU+We z>F!}}@fOrcs$5MSFBSQow5(kEFYY;2|2DAr{=;nE5r7*wkRFKTo@&IT7m7)?#y}mo zeKUHIV_3!_i%E}W8K?G<%?zg+GKbQk`v;J0gT5QK!qz)P!mZtci>8j7O)gA?!h)ub znGHIPYhkD&85O%3kCucB^g6`Nk{sKwO?Q<;##HnN*lXe{y6C*+NuVX~|Cx)XAV(O$ z5Bf+@NkY090^hCbzw`utZ|4G6ScU<(bW$1L_J+alkz-X>g#gBv(Vj0c$i`zRm(Ek!k-8B-($D}u>>Lk^)K8JKuc277BB z8~NAg{VHcLnPY+zK;}8|P!FF*bD8lJ7oor4x#NyL9B&1VcYHf=#L}JzOY|&ap?GrFEw{GLD}JXaqVlQ}xB;Qx5{Hu$*|`p@b}PBR)C00wX<7?ReO0f5hq zk)*kjhc@^gsu};zdt|Tf&n=As2)-ffXixA?IT2}rILDnBbh)Xt&spuZUJTo0jPVfW zy&vn{hMP{d7ljO%4vz)xTbQo->%;pweNC{bxlHK%f;KKDxPMz=%8{dNNg{P93f2&L z^8O+>R(r>$cF?fkQokC8Ja9Kry5^o`N7q%_8UOj!^?-HDvY!W%912WBJP$7+&QiA( z{o)#QEVAn{waq$4oupRj17ZxJ+=>2ezzw+I`VRsqjF25uGV)$lMbed!&YL3OuRsMqC7zu^ zhY$M>|AyvV>}|$L7;e?q3xif&0_rWEXv8dY4&-K3$dXk%g>8@oTTcD)1HDSzr-Em;#k%%PWA+Eh zz+foJZjey(Jf6z8Pv45d0u9?ZSGT0nui45{b5~KNGb`2ffN`iFfD`U4xc&Iu_RK*D zBO*#h^9>29f=qxi;2+u5+1SQVmA8gi8I80=8SNVaE!&Qp@`2fAN0!9_Z|Ls(n*zx( z+)-h-zjss@R=shgbyxKOnT!bK3|9WPkH5F4?RNRSD9h-Oj`tCWq5crbUMx4+Y|wYb z@(FvGdrBeoBjx;Ig3wAN1*&~Wefz>=J2XAolx4M}YPkS_QjlQFxNux`t8X)}?~QI% zSfe@LzY1KD=wr{MGZe(IqAYMA!LW!+Le3shu$~dVF`d@CfCwnR(n^MbP%y7o+rB(*t)$QhkU$lhE~1<9Pr@9dSKC zW>FDHJGND|DF=2X6WE}c%UhJ}V^tgwdT{kHb;gpuBGI`^2TBr0DeQY(k z5BaShxK34H0>8($GMv8x6ULrsB|NdQcR_o0!LQ}e`69kReFh{>FFhNyg}>dbbr5uGWWxx z&qLkM1lxaQmDgL9~MMeM`+Y@1n6r3tMP zI?KBKHlLVAKDu2dDV%zP=WVn>^xN>xke0{A;3Je5ncbdHVC4R>p?-7CrO=FKzg*shINy^^H%2CY_h zA5VF#NQ9q?{T6kU7F&q>84}*oJjZwiYYG?XawkVI22-J`C3*F?{eEC5;`qm1(vG@s zBXx^75@Y6a{rEm#zap~)L5_lfeuGwt>Xa?0=t27_IeDn)Il50wKm`Y;?W54Yf8yIs zm_G}DQvD2tldWHM2;sBJl84?oe31C>xpVwD8v{Hj*p{Ca|9Z7t;*9D;hctdL4S>Aj zL`t&bdsT9u=3T?Aydu$hz9@A2`T^e49i}!-^}oBro~^=quZ~S7q)r9Ywad~=i54}0%h<1YzN=7oZ8?C zyGl^4Zm(VC7C!i8=U&~t8AtPnqEcX1dg}e+pz*{&lD3%4;Ac+yu)&Df@d;ez&g3yE|ea6tZ+c=AFT={qT}v_3f2{%8ku@AZf@Zm@3^aZ?&FT*PwxLoMWN^p z@;md{sgkZVO{|4qN#$V(54(-y5(Own4GyF#^ePg13wwImlJqasBs!i8?IIekU2@VN zzq#F)Uz?^Wr93TGu+s=e0&V8IYlvV11>d|C0_6XdlWk!8w1Ypl^chw8*PHg1MY{*P zoX6VjM5))E2)EhX8}N{MjRooPu!B< z#bL9n&;9)YL3FsFZ0#E=biPn>zeksG6-sYvs3d)~E@9S_0<@#(soSp>f9%88<2)M9 zo+dH7M|AzU8hR{|=%$h)LOb<9L>T}pOK#6ky~Eo|M)k;02P#P%b{F$wXQyUHQ7MK{ z{cc^x|ByZ3c&oz3>KxZ^Ie9K=b7KkFec0K~pmwg7~ga$2Uul zQ}cyE+_8e70=8GKurgK@d7*JMyX-8_q_Yk4rm#|sxkqkAaqp5BIrPn{K%xSd*?$8m zGXB8WJ_LjCuB^Z{JPU)l&Z)8k;*)c(a5Q|Q6Xu1JbH&9dKwGUanx0mh-%Q6epxoDyIw>&b6W5nP?0M@y-4G=8 zT3Td*F4z)C`MK@B#qa?O;$sUqkC~G*@%a=bKgHg??i)PQXms(lfSk0xWhe=aPoFI& zoqE{CZNl^IVWhzN3wukS2HUFJYO&_bXF=oW-#m3_q8)$WR{G8T4oek!l+)sKx)K^s z@IrFRu#1b2XfnPeVDXiHwFN2{ocTb2Cu{ zXUe-#^lxCNhsKBHZR!-ja4S#FJ!UtUlGw80*sc+H`;Y^W8?eFbQp_nn1EWP+00m5T zXeyw#A$0}Jn=$Evb-t?TBrRL{%+qZ2omwDx$1{HOqffqM#6up-JHjA1F|FoRb2wQ) zkf3D!5O;9@?1sas0QPM0s;g^^K|xv>q*BP(<=0BY#>v2Xa-ZBwH2^NM0Jj4sDP~m& zSktyog`HCHexYju^+UX1J#a&=%YxSK1j&#YDA< zii}GJp8|E%MV0M8{qGDw%0(a1D7jxXmY|M*rsao>xH*C*zUCWGn0bRXEc*en zVWl7W9;!El$`@O@-P;}}vHy->ZfFq@j;y;CibS+fpSt%C<^L|@wZ{eC@}sg(FxvD! z;Dfuk1Y>HTi81;qD3Zy0jTk*=Xkt7sJ&UkiRewWeOt$_7(WYwh;XS}B5Kc?1F9}`Z zMz6!lIGtm&I)V@x)MmudjTlo!d{*U0>_>)SY|;)XcYL2k`&7z<3XTtQfU4_a}OyFkq3@{o+zbNe`f#T417T%{K@2~I`@>2`P~y{ z4R4O-)EuB0v7PrFcrM}~W>$`8h0j^AjUY>L>Z2HJa4rTSTlSJrL-7p@h*ent1vZJe zb))!33@X6YQ2=R(K6+T4hL~o5Ljx&%m1gD1Y;D0Dw7a0&2>n}C@y65jVDe&)ild|5 zxg)#78!j~U_y=|Yy(D@@6*?!cF9=eU%@Z||zqs4eyQOna{URC)9TdN9T6ocf5~_uG zq*aI9fq`zbPy@x_F?q8mac^;A3yEJmiIX;oUYcnVfCg$z4ECC!8oxM@Iq)X@&dQb! z)~$O62EQIFOnIVnf}tXj8a^56en)`VjhQJR*GT+@hD!QX)eg=amM+u!we17V#x02z zXrnE8FQ=LMNi_3QWwl6#d4)<0mwPF)qrd<2&ntc6goy5hh@1iMW7JE`W^!-deTJB2 z^M*ORd5hXU>kp7KP9$t?A{>+JGa{c}$PZF;(cZL}c3cteZ2`9#uw48Dld%I_oU93d zcW8GAbQpc;LIht}f6%=|9npUUN8b%K>H-1BA$Cei+2vr)gtAIGe3!a#zo3bv;sJ+y0u#zY{+^J_>0W$h~lhRp|5_F?1`mDy17wYSHO70>Go5Mw0e< z3BbhWoBQv5Gjf7#@`%^!@Xi>lYNF*j$7PJ*wvT8qt{r z;C`cdgS4<6tqHw#47t(7Y?@Kc{70F`@I!oIYcXrFT6%aijMHQf>Zxw)K5kEF)st>c z*>AZu;2|B=!Yl+v;k?-<|3J`VXpXtDKggC&M)0AzN9eUPCPmKvbd3WjwO4B64NuC9 zm0f!Hs@}>sA5F|ka{ie|VxBhpecK(}_)ROcxuNY}#`k8M$KRVYkK|MxjO9+KSvQUO z2c(`nS545aOOR>fl1eTOrhnNfiiq=7;79F!{e#tz{-2_IbKM%SQ_#I9xfU*37F>x7 zT6V}9D4=*7kmd7vHIm^s-2XxJ*!gIBQV=4Kr70V+A(r;!u_xl9myDb6DRmcS=3b4r z&4=hlzmqDKqsWR~5k4Pg+u$i`YX~{ZFj6jv0CO z<77Hzq(t=);#^qE zXcI@OYSJw8Y$ec+XWis8wG77|rTVrNCe~j+*!px30{QTRrGrIJ5xCC6Ls>a)vyTB? zWY-N$lN{PW5+nQza?3E9UU=ASjYb${a(FOV`r82HbO$Ov=`(d+{Mz%H-OC@=wdSam z31pTe&I`RP1F&Wceg=exXg`)byy{&1cW~|<)>I34(ZB58ur#8rWIo#dP0!?`-UjKo z^E4oGeDq6>9I(-(1t4xo$%mJT&NGb!dgX?c^n*|L_tW4HC21u^{oxVEJwDo0()O!$ zI+-8M_{a)Yq-Ra8#RCa>RQh`%1X~mHA0m72Nzq|_x*jCvGk@xloEfQ0 z$cP;4iH8PhH_9;;T;NRrq(|0WK`hB-fO})vW|nozCMBK$JEKqNIrtTjWHdque>xkB zlF6QDeNIwAN25T-9$wpc_9K9?QEha032o7A&+jvSy!I=$sOF?)o&YUph3cch+_YAz z;o|3}|1Lu>8!wZrG5Tvy&$X2d+fZApc3wkm6YW0nkI1NRzSsg^eLX2JSq(e0QP$Lo z2tOum69Rf%wFJd7N16-l7?|N_OaKZu03(+)jXGdcs5si@|7QD(}U7; z8^~Ej3uYf?0n5JvN=v%Y068a=4>LtZ-kZ|0whJ7Ghw#8ouaEWc`iZ4fBUXRmV;I+y zu3tCl6I3#K+5y_yq#G9V(u$#KOyT0WtM4Y?o1CNUHO#ntUkx)&13Yasb!-0{T+G8W zl43W=Z*^LcGTNR!hC?m=UH(-C)N!AvnBKxoJ^NHb+?}a?=NCx1^8E9lq(;#%WoJm< zU|Ntl4T%(GNcm< zfFu?=Ht?D6Lgd^8PL7D)VUGjn9b?lc@$tME^Fu4(W(v#+K>I7D>_^{#-|x67h7gTF zyCoB%j`+mUo%U8w&a7fpQu{R_-H*i2(9-_-QD3q)3 zO)LG;RMw+Zf77D+b?^xv)90smPq#BnO1ASSSEd8VBAl=nNq%B^Iw3*#-pqWh&^F6< z0O0T!u|MRW%uvq+q9x`{H~qDE`LHrS=?R*muZgr4?H}1?zK|>%nF`>;pUNHd%|x>& z^$Kmlsi~NJ$sD#IoAZnXwxH3(v@Y#b$(0-nWhv*_Al9H_BcA?fW?w~Dg(f?IqcE<6 zA*X6g_ew5ldqbH5oHcEpZOz-?+W*w@+Rp`{~ks;Ff2%zq*W<` zgcN^8TcI;xu_Flmov&Xy01=5&P(wc@SNqfM+V;Qi3|Yn{0*DUE0XSJ6NJ%G}zm+KH zLeClj!gD|80ijRId)R;6?cvDsfPF(%f0eQ`emReyjC$fjfBa?jW!@)g8=UxZ@dbC~)k8|E*`6c7(5eFxU*nUaOT|9nz7?y zd15Mth%tu9Jc3;2UD26~<}t%t*%U$`e<`rLnNW#(U>iO+Y9Ypb-C3ymfva~6P4AW7 zD<8RBN>PVUgv43E?><6a7IXF3nQ_)%nw}%gaP6_u+*z)qO-qsa#8n!%|B4IDjggD_ zYOtw?*Y35i!*3IBfALY*+}dDl)`u>w`EBR?Gvl=9dN&nj#BMkk0I%G1&fn==?l(65 z3K^XrrK)U8nh@KoUn2N289Ch+GFRm5ZYU()6WgAJt-6wPqXvzIxBaA2gp%< z^CQb0P7JQ{mh*M*Ych0>3TV1=*Vy7XOGPC8VJuZrC(vjvU!FcBq#*@B zc9EmLXtE4Q()`3D^0iVL_D6YyG6hZ7gejhVJI`MF>zY3C3a;GZ|Gh`C zY_(P9y*+oR-zUHLcWgzKzV6~@hQc0~8@=y2JMW?Iu9c-&Pp$i#I@I$Cu$_%<@RAC? ze>uXl?B_TwU1c2qGp##J_@`I6-!WU{MF57;cYp1GDkkBx4OD$%N5+Zj6VuH40t8+C3I3pt}lQfe2EiZ z>gr{q$xU!~$~%oJ_08*~ps}9`vOg%}&TVeC7-7j)gfkuamLNX!doc zPx&&wWp*dTLQ$s(zG7YSaz#5xSz1X1QZEw3wLP6=?8j3`ggBsv`x+b++ zzuK@tx(`EVV9XFe9&@{D^xHJ_#&fJ0db+yKZfoYrmH z4as~hpVHY4`~DTc#_E#_B-Rmre;b4HA$@@=rmACkhNn~aX?&*n$3qTRd3LE9T%*Dq zN?kc`s|)lG^yS~yRsTZQ-+C+WCuOFIkiW1L7!~IrhOW#07DU?^9Vw3lPmQXGTyVzN zUA%2dL(9ZFAXvVFniY*Wp-|=Y zFcl8VU*}P8GK};jEh)^qUBiGFZfWA@v`_{8Q2&BEO6KDYwN}^@5>)FmtXeP?^Evb~Hs@KWuW@`4n{eEwgr^JYwq~hr zkz7LZG>4urPTQZL)gPSbvrMyudUAyL69%@>Esf#vqFh&($yU;d=#GHas+BoP{wslo zURyY=k21wi@DlebEjzR*vg9Tg#feLjwQo#jHBA$!o^%gbp788<}nUi zM<+#;^3S{BcEhllX8T;;qiAy{)DXd7tb#_?LGmPCz7s!ckJCnRt`FhP#Q>||4ppj` z?_U8RK|V;;l??!l;uj9y^f6fYn%DQ9TQbbLvjFb(Stq6`*{ZB|T2Nns!44 zl}c4AL$Tb%5WZ(=sm=$l5iZK}`UV~hm^Dyc?r@!t<)Ac__LW+o24zcXgy7yuHe_o` zhPU8Vx@FCnt>!c@A}Gxs%c2N_I@qz zETdDY<0igpj$TYa|vMW>+2hCl2_-AeJg4M&*#k> z4i3Pnw_U$BNE;t!WRZfF4QGSS^HJi-=QXPypW1e5n4m7D&|~tGMyPIeE!+9&1$C{B zJ~M8g)R87;H?X~@Z&p%Q^5V55`%(3gk^VOHKIs?we!_vz#@p(=!G&Uci~vtvDKEmJ z);xQ?RdB#^MbxgGE2mE|G$7PF>IDme!*?&|l4V^;&T!Xw+zGf-i-*5}vwW)s`R*$x z{7S`JZCCCGaWDoIr+3324J`-1!3CViF zU~)zjU248{m0wENs4+Qd zI~Bb~_f7vPh>m!>@<|CXs}>p7ID#YI0k$`8$|UaKd%6a~#UwGyz5D2pk5JeC7y_%! z^Z33SHRtC>b=KAKz}npCOBD7ArSj%0;WCT0m7-JiJFHpY$?w1CXY7%rU`gW_QyR6@ z-oej^EZL$1O=p*`)1K3wS5F+jH`gDoEf5-sHF_V@`-<#r=39$mB1AVF9-o>>G&3jwU>37bi#(z~gH-~@x`812TAd4}aM%0h!p zH8V-=O|<@mQ4cXWGl!L2x=}iqvC?H*NE^<%=}KRfpWC>7y+J}$*TNZuzZi?OV|htJ zcOWW$P5)z}1>tG%M}gp>wYxqRx)oL|vO^Oug%6?c@>*xU*%7fWe|u}>%I!K-R9$G% zL7n?AWK&RDjV%X4J0P|lXx|;2SKdlD8bynxprkth&g+(Jc>d?HM;QC0?$VyX-}UL# z>nVzFSeQjyl;T87o!y0@u>HfNd26-hT;vvMRYHvl7d0Fs7TVtSZC(k>Hhmy*fX15P*3dNMT!Z(>L>d!QjCK+$HtNGv;&g0Rk&eG;;e_Q#bf2-v9 zKau~|C_`3#*DX2^gb)?vY+*Rj_tZg-1` z1)`2^!G|S>PX@gj?+;q(C&2K=qTSRh`j%JM4fLk4SydAYPOFa0UB{y=EWcTr_c>Vk z_iqi=o5|c4t))gEu+151x#RO7R#z#R+V1S)!|G-BV__V#bit`7=>0#3-*MJ`!uy?S zgtNJQYdk6mOb$O^Q|;DTp~EoAl)Ej1Owezb;mHdLO?- z$-b-njjw%EpYs3F$Hk!ewlL5?V*|ICUhX>Yp>GLp&6JSII43V|jE)(=4o;^?2clpP#kOJhmu+cy z(3@Y97JScsKZ7v&gcfjiDMcIjQO>*k{U-vyB9D7ukoN)lelTV+k^28jO~EMdw6CV@ zC=;+xFktP!E~2~N!8o;0Uq@Nwy{C$g+)6AEc@v#P_uaTU%p*s2jmGtU;}YW9zPF1F z&pPFI?GhNd5QT9p7h|{{x(3rf=@c0iQ55aGDA@}O#B|TJFQUo*74$C78P}HG;m{pr zZj?6|&EN%zG&0%R#kELSi<&J-oZrv(RKs^C5D>BRZ{km3snkfd_EspDEZLX$AO|c5 zHwQPK3jSfCVNf@1_tS0yvo;q=EA(N5+L;Q}5tR|LERm#OF$qBl(!)E~?PxJ6*rVU$ z*~7NXdhyAmFF4ckVG?FC{@jSOG);R*W~Qt{Q@^mIWf*`fyNVwqcJ4GTjs%+32h5vN zu-XLMmAS<~y_cy~sFhU%JrPzp>vAeKJNdC(zYNkSSC-IBB29T=NQPl;>XB1zPuR-5 zb$hLzUkAiVCet7P%KIaREl>EO>|-A9i35{74sOp-E~UChlt_g=-Q2?CRKWZYe7}@{ z-CRkWOwddqv)!m{hWVD{4P za}!4^gQoyL<>Bp|Fn#dt zT@_HIjj#DS)LB|GhV8+dWH>KPnQw#ZpARM-2a|;?CvYP(L1bLs=Pgig6 z=hm{2uoCGpRL=E{|Laxf{y7>2D+a3usfTAXZuk2(hTK0~2!lU%e(cZN7ELjw|#w|F-&+=2$*{N;fhiU7KCZp=0dd_LY@mbSg*iO7;Xfx{(XT z+A@`jKbgMsAb64paa(-H2sSV;B4<+!TNmhaNSy89?E_#0nw|y?Tru$|QWVB(MizfA zlV@Vr+yU*fQoX4da4dj`x6EI$S2 z$2f5a{y1$xEGEhoojh21qO5YWwNUrpd30^5lJHdfFyVn&B!R+r<{}=T% zwnIBnaW3?ATCrp(l^s9E_e`Y_=xupFd&zaEo~)`(&GmKWA1({&2!s7wA5@*Zl7==K zPWi_429;5qdF81=6C$NH3p(RlMXkO&UOa89HHKK+uJLUT_iY+x$^%-QiQwdOx%fR$ z^qo4sf8utdnWQeMj)IQHZ?^Rmx1`M+0G_U0sxB7&7NJKBMT91KWN0Y`53^akZ}cZ< zx@eh)!SLLchzfU9jPNCD ziPK-E6!gCUq2j8 z+*{I{nFf|XBjhc9jK&_JgURv8%ilVGZk+=fe?9SfLI-1(eU`m}2pGLrjw+yu^TwQz zZJ=59ZlMM>2OJ*yIiff^Hvc$yKqG(Sq*2dR-1)QrXa6Zz|A~7`_Wh!HEP4U{W=BrG zr&g7miA40G6)NFS4}Vhk{D=i+E;;`o3t
fc|sFPV;I{z6D^N7eCx%24oxLxnA$x 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�|1flE+tp_kdF$Z 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

XysrcDZ$^XirxpvYbxEVYC^5I7@fSir~SW(8`- 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�UgoF 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⩔)8~WdrvBBR5cTGM$UDJx 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

%L} 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

h#k8a(?pd_NIa-Okm~ulUTY{iD_wI{a^vjD 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 literal 0 HcmV?d00001 diff --git a/doc/en/pos_history.docbook b/doc/en/pos_history.docbook new file mode 100644 index 0000000..7bd6f74 --- /dev/null +++ b/doc/en/pos_history.docbook @@ -0,0 +1,101 @@ + +Position History + + +Introduction + + +In its capacity as a source code browser, &kapp; allows the user to quickly browse through different lines in the code base. We refer to a combination of a source file and a line number as a "position" in the project. While browsing the code, it is often required to go back to a position visited in the past, e.g., to return to the caller after visiting the callee. To achieve this task, &kapp; provides a sophisticated position history mechanism, which not only allows the user to go back and forth between visited locations, but also to save and restore snapshots of "tours" through the code, as well as other manipulations of the position history. For the sake of both consistency and ease of use, recorded position history is viewed and handled in a way similar to the query results system. + + + + +In the context of this section, a "jump" is defined as the action taken by &kapp; after a query result record is selected for viewing (either by the user from a query page or a call-tree window, or automatically). + + + + +Position history records appear in pages incorporated into the Query Results window. These pages can be immediately distinguished from query results by their tab labels, which always read "History X" (where X is a unique number that identifies the page). Other than that the two types of pages look very much the same: a history page is composed of a list of records, each comprised of the following fields: + +File +Line +Text + + + + +Note that the "Function" field is not provided for position history records. + + + +A history page behaves like a stack: entries are always added at the top of the list, and represent the most recently visited positions. The user can then go backwards in time, by moving the lower records, or forward, by moving to upper records. If the current record in the list is not the top one, all records above it are removed before new records are added at the top (the future history is thus "forgotten"). + + + +At any given moment, at most one history page is considered as "active". This is the page to which history position records are added as the user browses through the code, and to which position navigation commands apply. See Using Multiple Histories for a detailed description of the active page concept. + + + +A newly created project contains no position history pages. An initial page is created and set as active automatically when the first jump is made to a location in the code. + + + +Each jump may add up to two entries to the active history list: + +The current position of the cursor (before the cursor jumps to the requested position), and +The new position of the cursor. + +Duplicates never occur in the list. If the location of the cursor is the same as the location that appears at the top of the history list, only the new position of the cursor will be added. + + + + + +Navigation + + +The key feature of the position history mechanism is the ability to navigate through the recorded locations in the source code. There are two ways to navigate through a history list: moving back and forth through the list, and jumping directly to a specific position. + + + +To go back to the last position visited, select the GoPrevious Position menu item. This command selects the item immediately below the current one in the active history list (and moves the cursor to that position). Similarly, the menu command GoNext Position selects the position record immediately above the current one in the active history page, and moves the editing cursor to the appropriate location. + + + +In addition to these commands, any position recorded in a history list can be accessed directly, by selecting the relevant item in the list (either by double-clicking the item, or by highlighting it and pressing the Enter key. This action can be applied to any history list, and not just to the active one. + + + + +Selecting a history record from a non-active list will add the selected item to the top of the active list, similar to a jump from a query result page. + + + + + + +Using Multiple Histories + + +The position history is a dynamic object, which changes as the user navigates through the code. In some cases, however, it is convenient to create a snapshot of a tour through the code, and keep it for later reference. &kapp; provides this feature through the availability of multiple history pages. + + + +As mentioned earlier, a history page is created automatically for a project when the first jump through the code is made. This page is considered as the active history page, which means that locations are added to this page, and that all navigational commands apply to the list contained in it. + + + +The user can decide to freeze the contents of the history recorded by the current page. This is done by locking the page, in a way similar to locking query results (see The Query Window). Once the page is locked, its contents remain the same, even if jumps are made to other locations in the code. To record any successive jumps, &kapp; creates a new history page, which becomes the active one. A locked history page can also be activated by unlocking it. However, there can only be one unlocked history page at any given time (the active one), which means that unlocking one history page locks the previously unlocked one. + + + +Navigational commands (GoNext Position and GoPrevious Position) always apply to the active history page. This is usually the unlocked history page, but may also be a locked one. This happens after the active page is locked, and before a new page is created due to a jump in the code. Other locked pages can still be used by manually selecting location records from these pages. Such a selection will move the editing cursor to the appropriate location, and hence add an entry in the active history page. + + + +As with query pages, locked history pages are saved when a project is closed, and restored when it is opened. + + + + + diff --git a/doc/en/pref_clrs.png b/doc/en/pref_clrs.png new file mode 100644 index 0000000000000000000000000000000000000000..31e2f24d050d82a1f120cffb5904b7dcfe7e4aca GIT binary patch literal 43746 zcmaHT1yGey-zP}7AR!>3AR$P%a0#U@-6bL2NOwvo(j8LLEg)Ue-QCjN-FvRz`+YmR zv$Hc8^9biT`9Ht9ev_9K$3iDThl7K|l9c$M2nY9s9u5vZ85J2kfp>+whl8Vpll&m8 z?DAu8!P!MwW%1APVM<&N^~=Uc#3zVZ+zL-H)ZuKAa6jOG_@MBV2wzxRh#tM3u3kbx zxxMPUx;n$j8^S-s!Vx-O{Dnl^n8(=IFYgVyBiJNqgxFs4rfu@d86OBZZqS_e)ow0E z8fqX@?rq%e;UEe>1z+=Y`{7u4KInV!y;f8d&Nkuy_4rrUYcp@lh^*n%w)HtN$Y8A$ z@4-PdC8{4K>XYm3Z}>Vq`e~BzzY?$x_QL-?72#F$!;eN)g#CENOIE^leNIAcN7w90 z(&FkzEG1o0BV)x772~>6Z|+p`35x8MUamqcX=4U4do-=f7Y3_?htKERzS;zJU0d$w z8WMaab3T(HaIbVn^FlznV@bk3_pvlmeyGw|MH#(s^TBsA&A zo&I3%+REW>fb6dDWfkFM|3M2?8_KeoK+jStx!kV<#Zbp!>L`g<-@tE!(G%*@@q;NP z`C&{c?>=!7E8_{N>O}$6M&up!i9}vrfb#$h@wOdji9DaPXf)4D^PQ#o+eiS&JoGI(+`TZ~UEJ@xUiFC2@e zd+2+M9MhV#2pi=p0g3&AgZjxI zYR>bb#X@`f(b^KZ4#>yV6VDgrDCtY{7byjq;RdOxmx=KMMAm(IrVG`6JkaWVvZ}51 zq&{q7K@Xs2wOyRMtJqH2ZtPt+NXs3vb?BecUGqG_FXliskPJ@vfJ=fHo<3Q$Kr-~(_LAk7v$*u*4Pvpky{y-bNUcXX zW(v7RFm;Q6^M(Fi`hh?*SK;Iepgvw}tUmes$J+nKJvvpZ{jrLC`OBeqmy_#f0$st(T7QbmAI8gF$*l3} z@E_em5i=kv&V1RI_hT=@FFh;JeSTjFqSkK{=AJ7%yX9DF6U0txSABFmU*O(swsf(2 zqK6~h3t^s$i@y0mpIo@3ywTilK

  • c9^A`mRs|<7<6@$JFxf8DX@a5Vr$m;iPcX& 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 UzC|CrhzNv-E5YTFQ^28qj?(Vu9zxTUy@60=c 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 literal 0 HcmV?d00001 diff --git a/doc/en/project_files.png b/doc/en/project_files.png new file mode 100644 index 0000000000000000000000000000000000000000..94fdb325edb7ca6521235762e729e097f54d25bd GIT binary patch literal 72430 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

    ^Z41x2ROXIh0X&cCyp3gn~ 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 literal 0 HcmV?d00001 diff --git a/doc/en/project_make.png b/doc/en/project_make.png new file mode 100644 index 0000000000000000000000000000000000000000..1db4500b98f51f1e18601197a9898c7c3e745154 GIT binary patch literal 106302 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 NXy;~I@yo@8zX3&+ntcEO literal 0 HcmV?d00001 diff --git a/doc/en/project_opts.png b/doc/en/project_opts.png new file mode 100644 index 0000000000000000000000000000000000000000..9500b67a850895abce6dfc69a1f78009bf707b57 GIT binary patch literal 28292 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 literal 0 HcmV?d00001 diff --git a/doc/en/project_types.png b/doc/en/project_types.png new file mode 100644 index 0000000000000000000000000000000000000000..8998f037976eb865b7b35391243cff46d2f3ea06 GIT binary patch literal 20111 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�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 +Working with Projects + + +Before any significant work can be done with &kapp;, the user needs to define a project. A &kapp; project is a set of source files, which Cscope uses to create its cross-reference database. Unlike many other project-based environments, &kapp; is not intrusive: it only uses three files to define the project (with additional two files if the inverted index option is used). These files reside on a user-specified folder that does not have to be related to the location of the source files. Thus, &kapp; does not require any source files to be moved, and does not affect the structure of the source tree. + + +The files used by a &kapp; project are: + + +cscope.proj +The project's configuration file + + +cscope.files +A list of all source files included in the project + + +cscope.out +Cscope's cross-reference database + + +cscope.in.out +An inverted index file (optional) + + +cscope.po.out +An inverted index file (optional) + + + + + +The only limitation imposed by &kapp; is that these files have to reside in the same directory, referred to as the project's directory. The project's directory has the same name as the project (which means that project names should conform to the file-system conventions), and can be placed by the user under any directory. Normally, a user will create a projects sub-directory under his or her home directory, and create all projects there. However, this is only a convention, and, as explained above, the user can choose any other method he or she prefers. Furthermore, the project's directory can later be moved to another parent directory, without any risk of data loss. + + + +Creating a New Project + + +The first step in working with projects is to create a new one. This is done by choosing the ProjectsNew... command from the main menu. Issuing this command opens the New Project dialogue. The dialogue consists of three pages: Details, File Types and Options. + + +Note that this dialogue is intended for creating an empty project only, and has nothing to do with the actual source files of the project. This task is left to the Project Files dialogue. + + + +Details + + +The Project Details page + + + + + +The Project Details page + + + + + + +Name +The name of the project. Note that this name will be given to the project's directory, and should therefore comply with the file-system convention for directory names (e.g., no spaces). + + +Path +The full path of the directory under which the new project will be created. &kapp; will create a new directory under this one, and name it after the project. Thus this path does not need to point directly to the project's directory, but rather to the project's parent directory. For example, if a user wants to create a project called "my_project" under his local projects directory, the project's name should be set to "my_project" and the path to /home/my_username/projects. This will set the project's directory to /home/my_username/projects/my_project. + + +Source Root (Optional) +The top-level directory that contains the source files to be included in the project. This path only serves as a hint to &kapp;, as files may later be added from different directories as well By default, this value is set to the root directory. + + + + + +File Types + + +The File Types page + + + + + +The File Types page + + + + + + +This Project +A list of file name patterns that are used to define the type of source files to be included in the project. By default, C source files (.c) and C header files (.h) are included, but other types (including Lex's .l files and Yacc's .y files) can be added. + + +Available Types +A list of standard file types that can be included in a project. To add a type, highlight its entry in the list, and click the Add button. Custom types can also be added, by typing in shell-style patterns in the edit-box at the top of the list. + + +Add +Adds the currently selected file type to the project. + + +Remove +Removes the currently selected file types from the project. The file type is added to the list of available types. + + + + + +Options + + +The Project Options page + + + + + +The Project Options page + + + + + + +Kernel project +Mark this check-box if the project is designated to be a kernel-style project. For kernel projects, Cscope ignores the system's include files when building the cross-reference database (i.e., printf will not be found in /usr/include/stdio.h). + + +Build inverted index +Cscope can build an inverted index for the project to speed up queries (though at the expense of more time spent on building and refreshing the database). + + +Do not compress the database +Builds cross-reference database without compression. This will create a larger, but human-readable database. + + +Slower, but more accurate, function definition detection +Applies a huristic that can overcome Cscope's inability to detect function declarations with function pointers as parameters. Requires a patch to Cscope. + + +Refresh database automatically +&kapp; can rebuild the cross-reference database automatically, a process which is triggered when a source file is saved. If this option is selected, the user needs to specify the time (in seconds) that should elapse after each file save operation and before the database is rebuilt. + + +Use symbol auto-completion +Enables automatic "as-you-type" symbol completion. Note that manual symbol completion is always available, regardless of whether this option is selected. +If you choose to enable this option, it is recommended that you also select the inverted index option. + + +Options... +Displays the symbol auto-completion configuration dialogue. This button is only enabled if the symbol auto-completion is selected (see Automatic Symbol Completion for a description of this dialogue). + + +Override default tab width (Kate only) +Use a per-project tab-width (overriding the editor's settings). Helps when browsing code bases that use different styles than the user's preferred one. + + + + + +Common Buttons + + +OK +Accepts the values entered in the dialogue, and creates a new project. If any mandatory values were omitted, or not entered correctly, the user is prompted. + + +Cancel +Closes the dialogue without creating a new project. + + + + + + +Adding and Removing Project Files + + +The project's list of source files is maintained by the Project Files dialogue. This dialogue allows the user to add source files to a project, or remove files currently included in it. The dialogue is invoked automatically after a new project has been created, or manually by selecting the ProjectAdd/Remove Files... command from the main menu. + + + +The Project Files dialogue + + + + + +The Project Files dialogue + + + + + + + +File Path +Displays a list of all source files included in the project. Note that when adding and removing files, the project itself is not modified until the OK button is clicked. + + +Filter +Hides all files whose path names do not include the text entered in the edit-box to the left of the button. This can simplify the task of finding files in the project. The filter text can be any simplified regular expression (as given to file commands in a shell). + + +Show All +Reveals any files formerly hidden with the Filter button. + + +Add +All buttons in this group add files to the current project. + + +Files... +Adds user-selected files to the current project. + + +Directory... +Adds all source files in a directory to the current project. Source files are scanned according to the file-types associated with the project. Note that sub-directories are not scanned for files. + + +Tree... +Adds all source files in a selected directory and its sub-directories to the current project. Source files are scanned according to the file-types associated with the project. + + + + + +Remove +All buttons in this group remove files from the current project. + + +Selected +Removes all selected files from the current project. Files can be selected for removal by clicking their path name in the file list. The Ctrl key can be used to select multiple files, and the Shift key can be used to select ranges of files. + + +Directory... +Removes all source files in a directory from the current project. Note that sub-directories are not included. + + +Tree... +Removes all source files in a directory and any of its sub-directories from the current project. + + + + + +OK +Accepts the new list of source files, and updates the project. + + +Cancel +Closes the dialogue without modifying the list of project files. + + + + + +Once the list of project files changes (either when files are first added to the project, or upon any subsequent modification), &kapp; informs Cscope to rebuild the cross-reference database. + + + + + +Opening an Existing Project + + +Existing projects can be opened using the ProjectOpen... menu command. Choosing this command invokes the Open Project dialogue, which allows the user to select the project to open. + + + +The Open Project dialogue + + + + + +The Open Project dialogue + + + + + + +Project Path +The full path of the project directory. Use the browser button to locate a project by its configuration file (cscope.proj). + + +Recent Projects +Displays a list of recently-opened projects. Clicking a list item copies its path to the Project Path edit-box, while double-clicking an item opens the project. + + +Remove +Removes an entry from the list of recently-opened projects. + + +Open +Opens the project whose directory is set in the Project Path edit-box. + + +Cancel +Closes the dialogue without opening a project. + + + + +When a project is closed, it saves session information, such as source files being edited and the contents of locked queries. The session is restored when that project is opened again. + + + +After the project has been opened, &kapp; will invoke Cscope, which, in turn, will check whether any files have been modified since the last time the project had been closed. If any files have changed, Cscope will rebuild the cross-reference database. + + + + + +Changing Project Properties + + +The properties of an open project can be changed by choosing the ProjectProperties... menu command. This command invokes the Project Properties dialogue, which is similar to the New Project dialogue, except that the name and path of the project cannot be changed. + + + +See the New Project dialogue for a description of the available project options. + + + + + +Temporary Projects + + +Temporary projects are created when a user opens a cscope.out file directly. This option is useful for working on projects created by some other Cscope front-end (Cscope's ncurses interface, Vi, >Emacs, etc.), or simply using Cscope's command-line parameter. + + + +To open a database file, use the ProjectOpen Cscope.out... menu command. If the file is a valid Cscope cross-reference database, &kapp; will invoke Cscope using this file, and will be ready to accept queries on the database. Cscope.out files can also be opened through the command line, which means that you can simply drag a Cscope.out file, and drop it over &kapp;'s programme icon. + + + +Note, however, that most project management options provided by &kapp; will not be available for temporary projects: the file list for the project will be empty, users will not be able to add or remove files, and the project properties dialogue will not be available. You will also need to rebuild the database manually when making any changes. &kapp;'s rebuild command assumes the database has been updated, and only re-runs Cscope. + + + + + +Building Projects + + +While &kapp; was not designed as an IDE with a complete write-build-debug cycle, it does provide a simple GUI for building projects. The command ProjectMake Project displays a dialogue, which can be used to invoke any external tool on a given directory. By default, it runs make on the project's source root. The output of the command will be displayed in the dialogue's Output pane, with any errors or warnings marked-up, similar to links in a browser. Clicking on a link will jump to an editor page showing the source file and line responsible for the message. A list of all abnormal messages also appears in the dialogue's Errors and Warnings pane. + + + +The Make Project dialogue + + + + + +The Make Project dialogue + + + + + + +Root Directory +The directory in which to run the build command. + + +Command +The command to execute. + + +Make +Executes the build command. + + +Stop +Halts an executing build process. + + +Close +Closes the dialogue. + + + + + + diff --git a/doc/en/query_dlg.png b/doc/en/query_dlg.png new file mode 100644 index 0000000000000000000000000000000000000000..120ddb75f573e52ac1184e9fd5588f024001cac5 GIT binary patch literal 24116 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 Hb`1SDdVC4! literal 0 HcmV?d00001 diff --git a/doc/en/query_filter.png b/doc/en/query_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..de3a69c67367dfd0b23a6f32cacbd75fcfe4ccee GIT binary patch literal 16118 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 W9=lAZDeycy +The Query System + + +The most important task of &kapp; is to execute Cscope queries and display their results. Queries are always performed on the cross-reference database of the active project. + + +&kapp; currently supports the following query types: + +Find all references to a symbol +Find a symbol's global definition +Find all functions called by a given function +Find all functions calling a given function +Find a text string +Find an EGrep pattern (regular expression) +Find a file's path by its name +Find all files including a given file +Display a call-tree for a given function + +A symbol, as referred to in the above list, may be a function, a global variable, a structure, a union or a type definition. + + + +The cross-reference database may become obsolete when source files are modified, resulting in inaccurate (or simply wrong) query results. &kapp; has two ways for refreshing the database, manual and automatic. Manual database rebuilds are available through the CscopeRebuild Database menu command. Selecting this command will instruct Cscope to immediately rebuild the cross-reference database. + + + +Automatic database rebuilds are enabled per-project, an option controlled by the Project Properties dialogue. Since a database rebuild may be a time and resource-consuming operation, &kapp; does not invoke this procedure after every change to the source code. Instead, changes to the code initiate a timer (whose value is determined by the user in the Project Properties dialogue). Once this timer elapses, &kapp; instructs Cscope to rebuild the database. Code modifications that occur while the timer is running reset its value. + + + +A project's database is also updated whenever that project is opened. + + + +Running a Query + + +A query can be started in one of three ways: + +The main menu +Keyboard shortcuts +The editor's context-menu + + + + +To start a query from the main menu, select the desired query type from the Cscope menu. This will display a dialogue box prompting you for the query's text. The text to enter depends upon the query's type. + +The query dialogue + + + + + +The query dialogue + + + + + + + +Type +The type of query to perform. This value defaults to the requested type, by can be changed by selecting a different entry in the list. + + +Symbol +Enter the symbol to query in this box. The default value is the symbol currently under the editor's cursor (if any). + + +Search for a Sub-String +Mark this check-box to treat the entered text as part of a symbol (will query all symbols containing the entered text as a sub-string). + + +OK +Runs the query. + + +Hint +Provides a list of possible matches to the entered symbol. + + +Cancel +Closes the dialogue without running the query. + + +Suggested Symbols +A list of known symbols matching the text in the symbol box. + + +Hint Options +These buttons affect the way text in the symbol box is matched to fill the suggested symbols list. + + +Symbols Beginning With... +Choose this option to match symbols starting with the given text. + + +Symbols Containing... +Choose this option to match symbols containing the given text. + + + + +Any text selected in the editor when a query is requested will be automatically copied to the query dialogue. If no text is selected, KScope attempts to guess the requested symbol from the current location of the cursor. + + + +Each menu item is associated with a keyboard shortcut. These shortcuts follow the convention of using the Ctrl key, together with the numeric query index used by Cscope (this should allow experienced Cscope users to get quickly acquainted with &kapp;). For example, use Ctrl1 to look-up a symbol's definition. The call-tree is an exception to this convention (as it is not a native Cscope query). See the Command Reference for a complete listing of all menu and shortcut options. + + + + +The EGrep query is invoked using Ctrl5, as Ctrl6 is already used by &kate;. + + + + +The third way of starting a query is by right-clicking inside an editor window. This invokes the context-menu, that displays the same options as in the Cscope section of the main menu. Using a context-menu is easy when combined with a symbol selection in the editor: position the text cursor inside a symbol, and then right click to display the context-menu. + + + +A query may take some time to complete, depending on its type and the size of the project. &kapp; displays a progress indicator during long queries. If Cscope's command line option is used, this progress indication is accurate, and displays the percentage of files already searched in. In case this option was omitted (e.g., if working with a version of Cscope prior to 15.5), &kapp; will present a dummy progress bar, used simply to indicate that a query is running, and that &kapp; has not frozen. Please refer to the section Configuring &kapp; for more information. + + + + + +The Query Results Window + + +When a query has terminated, its output is displayed in the query window, at the bottom of &kapp;'s main window. This window can manage several result pages simultaneously, with each page holding the results of a different query. Each page is associated with a tab that displays a summary of the query that generated these results. This tab is used to bring the results page forward, and is also associated with several page operations through a close button and a context menu. + + + +By default, query results are displayed in the currently active page, overriding any prior contents. To keep a results page unchanged, the page needs to be "locked". Locked query pages are never overridden. The contents of these pages are also saved when the project is closed, and are restored when the project is reopened. To lock a project, either click the Lock/Unlock Query toggle button to the right of the query window, or use the context menu (available by right-clicking the page's tab.) The same methods can also be used to unlock a query. + + + +New query pages can also be created explicitly, by using either the New Query button to the right of the query window, or the context menu available by right-clicking the tab area of the query window. + + + +Each entry in a query results page represents a symbol or text string that complies to the search criteria. The entry is composed of four sections: + +The path of the file in which the symbol or string were found +The name of the function containing the symbol or text string +The line number in this file +The text of this line + + + + +By default, results are sorted according to the file name. This can be changed by clicking the column headers of the results list. + + + +The entries in a query results page can be used as shortcuts to editing the line in which the symbol or text string were found (or lines in that vicinity.) This is done by either double-clicking a result entry, or by selecting this entry and hitting the Enter key. As a result, &kapp; will open an editor window displaying the file referred to in the selected entry, and set the cursor to the beginning of the appropriate line. + + + +If a query results in a single entry, this entry is automatically selected for display. + + + +The results of a query can be refreshed by clicking the Refresh Query button to the right of the query window, or by using the context menu. This command is useful to rerun queries after the database has changed (such as after a Rebuild Database command had been issued). + + + +Query results pages can be closed by either clicking the icon on their tab, by clicking on the Close Query button to the right of the query window, by using the context menu (available by right-clicking the page's tab), or by selecting the CscopeClose Query main-menu command. + + + +If the query window is not visible when a query is executed, it is temporarily displayed, and then re-hidden when the user selects an entry for viewing. + + + + + +Query Results Options + + +Right-clicking a query result in either a query window or a call-tree dialogue displays a context menu. This menu includes several actions that can be used to either extract information or fine tune these results. + + + + + + +Copy File + +Copies the file path part of a result record to the clipboard (the copy commands are available depending on the position of the mouse cursor). + + + +Copy Function + +Copies the function name part of a result record to the clipboard. + + + +Copy Line + +Copies the line number part of a result record. + + + +Copy Text + +Copies the function name part of a result record to the clipboard. + + + +Filter... + +Displays the Filter Query Results dialogue. See the section Filtering Query Results for a detailed description of this option. + + + +Show All + +Displays all query results. This option reverts the effects of any filters previously applied. + + + +Remove Item + +Permanently removes a record from a query results window. This action can only be undone by rerunning the query. + + + + + + +Filtering Query Results + + +It is often the case the a query results in an abundance of information. &kapp; allows the user to filter query results in order to show only those results that the user finds interesting, an action referred to as "Filtering". Filtering is done by matching patterns on any of the query record fields (file name, function, line number and line text). + + + +The Filter Query Results dialogue is invoked from the query context menu (see Query Result Options). + +The Filter Query Results dialogue + + + + + +The Filter Query Results dialogue + + + + + + + +Search For +Enter the pattern to match in the query result records. This pattern is interpreted based on the Search Type selection. + + +Search In +The record field in which to look for the search pattern. By default, this is the field over which the context menu was invoked. + + +Search Type +Defines the way in which the pattern should be interpreted. + + +Plain Text +Choose this option to treat the pattern as a simple text string to search for. + + +RegExp +Choose this option to treat the pattern as a regular expression. + + +Simplified RegExp +Choose this option to treat the pattern as a simplified regular expression (a-la file expressions in a Unix shell). + + +Case Sensitive +Check for a case sensitive search, uncheck for a case insensitive one. + + +OK +Filters the query results based on the given information. + + +Cancel +Closes the dialogue without filtering the results. + + + + + + +Displaying Call-Trees and Graphs + + +Tracing a sequence of calls in the code base is a common task in code analysis. To facilitate this task, &kapp; offers two mechanisms for visualising the relationships between different functions in a project: the Call-Tree and the Call-Graph. Both of these mechanisms are provided through the Call Graph Dialogue which can be invoked on a function name in a similar way to a regular Cscope query. + + + +Call Trees + + +The Call-Tree has two modes, "Called Functions" and "Calling Functions". In the first case, the call chain starts with a root function, and goes on to display all the functions it references. The second mode shows all functions calling the root function. In both modes each function in the second level can be further expanded to show functions calling it (or functions it calls). This process can be further applied to functions in the third level, an so on. + + + +Both modes use a standard tree widget to display the call chain. Expanding a function to the next level is performed by clicking the plus sign to the left of the function's name. Double-clicking a function (or selecting it and then hitting Enter) points the editor to the call's actual text. Right-clicking an entry provides a popup-menu with further options, similar to the query results menu (see Query Result Options). + + + + +A Call-Tree + + + + + +A Call-Tree in "Called Functions" mode + + + + + + + + +Call Graphs + + +A Call-Tree often misses the true nature of a call sequence, since many such sequences contain loops, that is, functions calling back functions that precede them in the sequence. (Recursive calls provide a natural example for such a state of affairs.) A Call-Graph provides a more accurate description of the relationships between functions by depicting calls using a directed graph. Each node in the graph represents a function and each edge a function call. An edge is directed from the caller to the callee. + + + + +A Call-Graph + + + + + +A Call-Graph + + + + + + +When a Call-Graph is created, it only displays a single function. Right-clicking on this function opens a popup menu that allows the user to display or hide either the functions called by or calling to this one. This menu consists of the following entries: + + + + +Called Functions +Show + +Shows all functions called by this one. + + + +Called Functions +List/Filter... + +Displays a detailed list of called functions. This list can also be used to select which calling functions to show. + + + +Called Functions +Hide + +Removes any functions called by this one. This will also remove any unconnected graph components resulting from the removal of the corresponding nodes. + + + +Calling Functions +Show + +Shows all functions calling this one. + + + +Calling Functions +List/Filter... + +Displays a detailed list of calling functions. This list can also be used to select which calling functions to show. + + + +Calling Functions +Hide + +Removes any functions calling this one. This will also remove any unconnected graph components resulting from the removal of the corresponding nodes. + + + +This Function +Find Definition + +Queries the database for the definition of the selected function. + + + +This Function +Remove + +Deletes the selected node from the graph. + + + + + +Another popup menu is displayed when an arrow head is right-clicked: + + + + +Open Call + +Opens an editor page at the location of the call represented by this edge. + + + + + + + + + diff --git a/doc/en/quick_start.docbook b/doc/en/quick_start.docbook new file mode 100644 index 0000000..02ff501 --- /dev/null +++ b/doc/en/quick_start.docbook @@ -0,0 +1,41 @@ + +Quick Start + + +This section provides information for the impatient user who would like to start using &kapp; right away. While using &kapp; should be straight-forward for anyone who has ever used similar tools in the past, and is familiar with KDE applications, there are, nonetheless, some points that require attention. Even if you do not have the time or patience to browse through this entire manual, please make sure to read at least this section. + + + +Configure Paths + + +&kapp; needs to be informed of the absolute paths to several executables, including Cscope, Ctags and (optionally) Dot. These can be configured in the Programmes page of the main configuration dialogue. See The Configuration Dialogue section for more information. +&kapp; will not work properly if these paths are not configured correctly! + + + + +Create a Project + + +While &kapp; can be used to edit individual files, most of its browsing, analysis and editing features will not be available outside of a project. A project is a set of source files for which &kapp; creates a cross-reference database, the key to most of &kapp;'s capabilities. See Creating a New Project for detailed instructions. + + + + +Populate the Project + + +As mentioned above, a project is associated with a set of source files. These need to be added to the project, before any useful work can be done. Files can be added (or removed) using the Project Files dialogue. + + + + +Browse and Edit Files + + +Once a project has been defined, &kapp; is ready for use. You can now open files for viewing and editing, and use the query system for browsing and analysing the project's code base. See the rest of this manual for more information. + + + + diff --git a/po/Makefile.am b/po/Makefile.am new file mode 100644 index 0000000..0fa209c --- /dev/null +++ b/po/Makefile.am @@ -0,0 +1 @@ +POFILES = AUTO diff --git a/po/kscope.pot b/po/kscope.pot new file mode 100644 index 0000000..12f8ce6 --- /dev/null +++ b/po/kscope.pot @@ -0,0 +1,1515 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-08-02 09:22-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "" + +#: calltreedlg.cpp:308 rc.cpp:73 rc.cpp:80 +#, no-c-format +msgid "Call Graph" +msgstr "" + +#: calltreedlg.cpp:310 +msgid "Right-click a function node or an arrow head for more options." +msgstr "" + +#: calltreedlg.cpp:316 rc.cpp:86 +#, no-c-format +msgid "Called Functions Tree" +msgstr "" + +#: calltreedlg.cpp:318 calltreedlg.cpp:327 +msgid "Right-click a tree item for more options." +msgstr "" + +#: calltreedlg.cpp:325 rc.cpp:92 +#, no-c-format +msgid "Calling Functions Tree" +msgstr "" + +#: cscopefrontend.cpp:416 +msgid "Processing query results, please wait..." +msgstr "" + +#: ctagsfrontend.cpp:104 +msgid "Ctags cannot be found in the given path" +msgstr "" + +#: ctagslist.cpp:147 rc.cpp:221 +#, no-c-format +msgid "Name" +msgstr "" + +#: ctagslist.cpp:148 queryview.cpp:53 rc.cpp:580 +#, no-c-format +msgid "Line" +msgstr "" + +#: ctagslist.cpp:149 rc.cpp:613 +#, no-c-format +msgid "Type" +msgstr "" + +#: ctagslist.cpp:189 queryview.cpp:51 rc.cpp:574 +#, no-c-format +msgid "Function" +msgstr "" + +#: ctagslist.cpp:194 +msgid "Variable" +msgstr "" + +#: ctagslist.cpp:199 +msgid "Struct" +msgstr "" + +#: ctagslist.cpp:204 +msgid "Macro" +msgstr "" + +#: ctagslist.cpp:209 +msgid "Member" +msgstr "" + +#: ctagslist.cpp:214 +msgid "Enum" +msgstr "" + +#: ctagslist.cpp:219 +msgid "Enumerator" +msgstr "" + +#: ctagslist.cpp:224 +msgid "Typedef" +msgstr "" + +#: ctagslist.cpp:229 +msgid "Label" +msgstr "" + +#: ctagslist.cpp:234 +msgid "Include" +msgstr "" + +#: dotfrontend.cpp:99 +msgid "Dot cannot be found in the given path" +msgstr "" + +#: editortabs.cpp:190 +msgid "" +"Some files contain unsaved changes.\n" +"Would you like to save these files?" +msgstr "" + +#: editortabs.cpp:295 +msgid "Untitled " +msgstr "" + +#: editortabs.cpp:299 +msgid "New unsaved file" +msgstr "" + +#: filelist.cpp:47 rc.cpp:215 +#, no-c-format +msgid "Path" +msgstr "" + +#: frontend.cpp:84 +msgid "Cannot restart while another process is still running" +msgstr "" + +#: frontend.cpp:104 +msgid ": Failed to start process" +msgstr "" + +#: frontend.cpp:108 +msgid "No error" +msgstr "" + +#: graphwidget.cpp:161 +msgid "Called Functions" +msgstr "" + +#: graphwidget.cpp:163 graphwidget.cpp:172 +msgid "Show" +msgstr "" + +#: graphwidget.cpp:165 graphwidget.cpp:174 +msgid "List/Filter..." +msgstr "" + +#: graphwidget.cpp:167 graphwidget.cpp:176 rc.cpp:135 +#, no-c-format +msgid "Hide" +msgstr "" + +#: graphwidget.cpp:170 +msgid "Calling Functions" +msgstr "" + +#: graphwidget.cpp:179 +msgid "This Function" +msgstr "" + +#: graphwidget.cpp:181 +msgid "Find Definition" +msgstr "" + +#: graphwidget.cpp:187 +msgid "List..." +msgstr "" + +#: graphwidget.cpp:195 +msgid "Open Call" +msgstr "" + +#: graphwidget.cpp:341 kscope.cpp:559 main.cpp:58 +msgid "KScope" +msgstr "" + +#: graphwidget.cpp:342 +msgid "Generating graph, please wait" +msgstr "" + +#: graphwidget.cpp:889 +msgid "" +"The query produced too many results.\n" +"A multiple-call node will appear in the graph instead.\n" +"Hint: The maximum number of in/out edges\n" +"can be adjusted by clicking the dialogue's \"Preferences\" button" +msgstr "" + +#: historypage.cpp:111 +msgid "HIS " +msgstr "" + +#: historypage.cpp:111 +msgid "History " +msgstr "" + +#: kscope.cpp:206 +msgid " Line: N/A Col: N/A " +msgstr "" + +#: kscope.cpp:287 +msgid "" +"The current project needs to be closed before a new one is created.\n" +"Would you like to close it now?" +msgstr "" + +#: kscope.cpp:348 +msgid "The Add/Remove Files dialogue is not available for temporary projects." +msgstr "" + +#: kscope.cpp:381 +msgid "" +"The Project Properties dialogue is not available for temporary projects." +msgstr "" + +#: kscope.cpp:559 +msgid "Please wait while KScope builds the database" +msgstr "" + +#: kscope.cpp:934 +msgid "Verifying Cscope installation..." +msgstr "" + +#: kscope.cpp:1122 +msgid "Verifying Cscope installation...Done" +msgstr "" + +#: kscope.cpp:1130 +msgid "" +"Cscope may not be properly installed on this system.\n" +"Please check the Cscope path specified in KScope's configuration dialogue." +msgstr "" + +#: kscope.cpp:1553 +msgid "Rebuilding the cross reference database..." +msgstr "" + +#: kscope.cpp:1566 +msgid "Please wait while KScope builds the inverted index" +msgstr "" + +#: kscope.cpp:1572 +msgid "Rebuilding inverted index..." +msgstr "" + +#: kscope.cpp:1590 +msgid "Rebuilding the cross reference database...Done!" +msgstr "" + +#: kscope.cpp:1607 +msgid "" +"The database could not be built.\n" +"Cross-reference information will not be available for this project.\n" +"Please ensure that the Cscope parameters were correctly entered in the " +"\"Settings\" dialogue." +msgstr "" + +#: kscope.cpp:1616 +msgid "Rebuilding the cross reference database...Failed" +msgstr "" + +#: kscope.cpp:1687 +msgid "Whould you like to add this file to the active project?" +msgstr "" + +#: kscope.cpp:1692 +msgid "Failed to write the file list." +msgstr "" + +#: kscopeactions.cpp:58 +msgid "Go to File List" +msgstr "" + +#: kscopeactions.cpp:66 +msgid "Save Al&l" +msgstr "" + +#: kscopeactions.cpp:75 +msgid "Edit in E&xternal Editor" +msgstr "" + +#: kscopeactions.cpp:83 +msgid "Go To Tag" +msgstr "" + +#: kscopeactions.cpp:91 +msgid "Complete Symbol" +msgstr "" + +#: kscopeactions.cpp:100 +msgid "&New Project..." +msgstr "" + +#: kscopeactions.cpp:108 +msgid "&Open Project..." +msgstr "" + +#: kscopeactions.cpp:116 +msgid "Open &Cscope.out..." +msgstr "" + +#: kscopeactions.cpp:124 +msgid "Add/Remove &Files..." +msgstr "" + +#: kscopeactions.cpp:140 +msgid "&Make Project" +msgstr "" + +#: kscopeactions.cpp:148 +msgid "&Remake Project" +msgstr "" + +#: kscopeactions.cpp:156 +msgid "&Close Project" +msgstr "" + +#: kscopeactions.cpp:165 +msgid "&References..." +msgstr "" + +#: kscopeactions.cpp:173 +msgid "&Definition..." +msgstr "" + +#: kscopeactions.cpp:181 +msgid "&Called Functions..." +msgstr "" + +#: kscopeactions.cpp:189 +msgid "C&alling Functions..." +msgstr "" + +#: kscopeactions.cpp:197 +msgid "Find &Text..." +msgstr "" + +#: kscopeactions.cpp:205 +msgid "Find &EGrep Pattern..." +msgstr "" + +#: kscopeactions.cpp:213 +msgid "Find &File..." +msgstr "" + +#: kscopeactions.cpp:221 +msgid "&Including Files..." +msgstr "" + +#: kscopeactions.cpp:229 +msgid "&Quick Definition" +msgstr "" + +#: kscopeactions.cpp:237 +msgid "Call &Graph..." +msgstr "" + +#: kscopeactions.cpp:245 +msgid "Re&build database" +msgstr "" + +#: kscopeactions.cpp:254 +msgid "P&revious Result" +msgstr "" + +#: kscopeactions.cpp:262 +msgid "N&ext Result" +msgstr "" + +#: kscopeactions.cpp:270 +msgid "&Previous Position" +msgstr "" + +#: kscopeactions.cpp:278 +msgid "&Next Position" +msgstr "" + +#: kscopeactions.cpp:286 +msgid "Position &History" +msgstr "" + +#: kscopeactions.cpp:294 +msgid "Global &Bookmarks" +msgstr "" + +#: kscopeactions.cpp:303 +msgid "Toggle File List" +msgstr "" + +#: kscopeactions.cpp:311 +msgid "Toggle Query Window" +msgstr "" + +#: kscopeactions.cpp:319 +msgid "Toggle Tag List" +msgstr "" + +#: kscopeactions.cpp:328 +msgid "Close &All" +msgstr "" + +#: kscopeactions.cpp:336 +msgid "Go &Left" +msgstr "" + +#: kscopeactions.cpp:344 +msgid "Go &Right" +msgstr "" + +#: kscopeactions.cpp:357 +msgid "Show &Welcome Message..." +msgstr "" + +#: kscopeactions.cpp:366 +msgid "&New" +msgstr "" + +#: kscopeactions.cpp:374 +msgid "&Refresh" +msgstr "" + +#: kscopeactions.cpp:382 +msgid "&Lock/Unlock" +msgstr "" + +#: main.cpp:36 +msgid "" +"KScope\n" +"A source-editing environment for KDE, based on Cscope" +msgstr "" + +#: main.cpp:42 +msgid "Opens a cscope.out file in a temporary project" +msgstr "" + +#: main.cpp:44 +msgid "Opens a KScope project" +msgstr "" + +#: makedlg.cpp:134 +msgid "A make process is running. Would you like to stop it first?" +msgstr "" + +#: makedlg.cpp:135 +msgid "Close Make Window" +msgstr "" + +#: newprojectdlg.cpp:77 +msgid "Project Properties" +msgstr "" + +#: newprojectdlg.cpp:200 +msgid "Project names must not contain whitespace." +msgstr "" + +#: newprojectdlg.cpp:239 +msgid "This is not a valid file type!" +msgstr "" + +#: preferencesdlg.cpp:56 rc.cpp:123 +#, no-c-format +msgid "Preferences" +msgstr "" + +#: preferencesdlg.cpp:63 +msgid "Programmes" +msgstr "" + +#: preferencesdlg.cpp:64 +msgid "Paths to back-end programmes" +msgstr "" + +#: preferencesdlg.cpp:71 rc.cpp:156 +#, no-c-format +msgid "Colours" +msgstr "" + +#: preferencesdlg.cpp:71 +msgid "Window colours" +msgstr "" + +#: preferencesdlg.cpp:78 +msgid "Window fonts" +msgstr "" + +#: preferencesdlg.cpp:85 +msgid "Misc. Options" +msgstr "" + +#: preferencesdlg.cpp:187 +msgid "This would reset all your configuration settings! Continue?" +msgstr "" + +#: preffont.cpp:77 preffont.cpp:87 +msgid "Sample" +msgstr "" + +#: preffrontend.cpp:137 +msgid "Looking for Cscope..." +msgstr "" + +#: preffrontend.cpp:141 +msgid "Checking Cscope version..." +msgstr "" + +#: preffrontend.cpp:145 +msgid "Cscope support for line mode verbose output..." +msgstr "" + +#: preffrontend.cpp:150 +msgid "Cscope support slow path definitions... " +msgstr "" + +#: preffrontend.cpp:154 +msgid "Looking for Ctags..." +msgstr "" + +#: preffrontend.cpp:158 +msgid "Ctags compatibilty with ctags-exuberant..." +msgstr "" + +#: preffrontend.cpp:163 +msgid "Looking for Dot..." +msgstr "" + +#: preffrontend.cpp:167 +msgid "Checking -Tplain..." +msgstr "" + +#: project.cpp:98 +msgid "Project directory does not exist" +msgstr "" + +#: project.cpp:111 +msgid "" +"Your project is not compatible with this version of KScope.\n" +"Please re-create the project." +msgstr "" + +#: project.cpp:120 +msgid "Cannot read project name" +msgstr "" + +#: projectfilesdlg.cpp:204 +#, c-format +msgid "Would you like to add %d files to your project?" +msgstr "" + +#: projectfilesdlg.cpp:299 +msgid "Are you sure you want to remove the selected files from the project?" +msgstr "" + +#: projectfilesdlg.cpp:329 +msgid "" +"Are you sure you want to remove the selected directory from the project?" +msgstr "" + +#: projectfilesdlg.cpp:362 +msgid "" +"Are you sure you want to remove all files in the selected tree from the " +"project?" +msgstr "" + +#: projectmanager.cpp:67 +msgid "Cannot create a project inside an existing directory" +msgstr "" + +#: projectmanager.cpp:74 +msgid "Failed to create the project's directory" +msgstr "" + +#: projectmanager.cpp:151 +msgid "No Project" +msgstr "" + +#: queryresultsmenu.cpp:41 +msgid "&View Source" +msgstr "" + +#: queryresultsmenu.cpp:43 +msgid "Find &Definition" +msgstr "" + +#: queryresultsmenu.cpp:48 +msgid "&Filter..." +msgstr "" + +#: queryresultsmenu.cpp:49 +msgid "&Show All" +msgstr "" + +#: queryresultsmenu.cpp:51 +msgid "&Remove Item" +msgstr "" + +#: queryview.cpp:54 rc.cpp:583 +#, no-c-format +msgid "Text" +msgstr "" + +#: queryview.cpp:213 +msgid "No results" +msgstr "" + +#: querywidget.cpp:446 +msgid "" +"You about about to close a locked page.\n" +"Are you sure?" +msgstr "" + +#: rc.cpp:12 +#, no-c-format +msgid "&Project" +msgstr "" + +#: rc.cpp:15 +#, no-c-format +msgid "&Cscope" +msgstr "" + +#: rc.cpp:18 +#, no-c-format +msgid "&Go" +msgstr "" + +#: rc.cpp:21 +#, no-c-format +msgid "&Window" +msgstr "" + +#: rc.cpp:30 +#, no-c-format +msgid "&Query" +msgstr "" + +#: rc.cpp:33 +#, no-c-format +msgid "Cscope" +msgstr "" + +#: rc.cpp:36 +#, no-c-format +msgid "Project" +msgstr "" + +#: rc.cpp:39 +#, no-c-format +msgid "Navigation" +msgstr "" + +#: rc.cpp:42 +#, no-c-format +msgid "Query" +msgstr "" + +#: rc.cpp:45 +#, no-c-format +msgid "Workspace" +msgstr "" + +#: rc.cpp:48 +#, no-c-format +msgid "Auto-Completion Properties" +msgstr "" + +#: rc.cpp:51 +#, no-c-format +msgid "Minimum Characters" +msgstr "" + +#: rc.cpp:54 +#, no-c-format +msgid "Delay (ms)" +msgstr "" + +#: rc.cpp:57 +#, no-c-format +msgid "Maximum Entries" +msgstr "" + +#: rc.cpp:66 +#, no-c-format +msgid "Global Bookmarks" +msgstr "" + +#: rc.cpp:77 rc.cpp:83 rc.cpp:89 rc.cpp:159 rc.cpp:165 +#, no-c-format +msgid "..." +msgstr "" + +#: rc.cpp:96 rc.cpp:102 rc.cpp:108 rc.cpp:114 rc.cpp:120 +#, no-c-format +msgid "a" +msgstr "" + +#: rc.cpp:105 +#, no-c-format +msgid "Zoom In" +msgstr "" + +#: rc.cpp:111 +#, no-c-format +msgid "Zoom Out" +msgstr "" + +#: rc.cpp:117 +#, no-c-format +msgid "Rotate" +msgstr "" + +#: rc.cpp:126 +#, no-c-format +msgid "Help Message" +msgstr "" + +#: rc.cpp:129 +#, no-c-format +msgid "Cscope Error Messages" +msgstr "" + +#: rc.cpp:138 +#, no-c-format +msgid "Form1" +msgstr "" + +#: rc.cpp:143 +#, no-c-format +msgid "Project File List" +msgstr "" + +#: rc.cpp:147 +#, no-c-format +msgid "File Tree" +msgstr "" + +#: rc.cpp:150 +#, no-c-format +msgid "Call Graph Preferences" +msgstr "" + +#: rc.cpp:153 +#, no-c-format +msgid "Maximal In/Out Node Degree" +msgstr "" + +#: rc.cpp:176 +#, no-c-format +msgid "KScope - Make" +msgstr "" + +#: rc.cpp:179 +#, no-c-format +msgid "Root Directory:" +msgstr "" + +#: rc.cpp:182 +#, no-c-format +msgid "Command:" +msgstr "" + +#: rc.cpp:185 +#, no-c-format +msgid "Output" +msgstr "" + +#: rc.cpp:188 +#, no-c-format +msgid "Errors a&nd Warnings" +msgstr "" + +#: rc.cpp:191 +#, no-c-format +msgid "&Make" +msgstr "" + +#: rc.cpp:194 +#, no-c-format +msgid "Alt+M" +msgstr "" + +#: rc.cpp:197 +#, no-c-format +msgid "&Stop" +msgstr "" + +#: rc.cpp:200 +#, no-c-format +msgid "Alt+S" +msgstr "" + +#: rc.cpp:206 +#, no-c-format +msgid "Alt+C" +msgstr "" + +#: rc.cpp:209 +#, no-c-format +msgid "Create Project" +msgstr "" + +#: rc.cpp:212 +#, no-c-format +msgid "Detai&ls" +msgstr "" + +#: rc.cpp:218 +#, no-c-format +msgid "Source Root (Optional)" +msgstr "" + +#: rc.cpp:224 +#, no-c-format +msgid "" +"Enter a name for this project.\n" +"The name must conform to the file system's naming conventions for " +"directories (e.g., no spaces, exclamaion marks, etc.)." +msgstr "" + +#: rc.cpp:228 +#, no-c-format +msgid "" +"The path to hold this project.\n" +"KScope will create a directory with the given name under this project, and " +"populate it with the project configuration and database files.\n" +"This does not need to be the path in which the source files reside." +msgstr "" + +#: rc.cpp:233 +#, no-c-format +msgid "" +"

    A project consists of several files located in a directory\n" +" with the given name and path. The project's name needs to be a valid " +"directory\n" +"name and must not contain any whitespace.
    \n" +"
    \n" +"
    The Source Root is a convinient way to specify a common\n" +"path for all source files, but is not required.
    " +msgstr "" + +#: rc.cpp:241 +#, no-c-format +msgid "File T&ypes" +msgstr "" + +#: rc.cpp:244 +#, no-c-format +msgid "This Project" +msgstr "" + +#: rc.cpp:247 +#, no-c-format +msgid "" +"KScope uses these filters to locate source files to include in this project." +msgstr "" + +#: rc.cpp:250 +#, no-c-format +msgid "<< &Add" +msgstr "" + +#: rc.cpp:253 rc.cpp:649 +#, no-c-format +msgid "Alt+A" +msgstr "" + +#: rc.cpp:256 +#, no-c-format +msgid "Adds the selected file type to the current project." +msgstr "" + +#: rc.cpp:259 +#, no-c-format +msgid ">> &Remove" +msgstr "" + +#: rc.cpp:262 +#, no-c-format +msgid "Alt+R" +msgstr "" + +#: rc.cpp:265 +#, no-c-format +msgid "Remove the selected file type from the project." +msgstr "" + +#: rc.cpp:268 +#, no-c-format +msgid "Available Types" +msgstr "" + +#: rc.cpp:271 +#, no-c-format +msgid "You can enter custom file types here." +msgstr "" + +#: rc.cpp:274 +#, no-c-format +msgid "*.c" +msgstr "" + +#: rc.cpp:277 +#, no-c-format +msgid "*.h" +msgstr "" + +#: rc.cpp:280 +#, no-c-format +msgid "*.l" +msgstr "" + +#: rc.cpp:283 +#, no-c-format +msgid "*.y" +msgstr "" + +#: rc.cpp:286 +#, no-c-format +msgid "*.S" +msgstr "" + +#: rc.cpp:289 +#, no-c-format +msgid "*.cc" +msgstr "" + +#: rc.cpp:292 +#, no-c-format +msgid "*.cpp" +msgstr "" + +#: rc.cpp:295 +#, no-c-format +msgid "*.cxx" +msgstr "" + +#: rc.cpp:298 +#, no-c-format +msgid "*.C" +msgstr "" + +#: rc.cpp:301 +#, no-c-format +msgid "*.hh" +msgstr "" + +#: rc.cpp:304 +#, no-c-format +msgid "*.hpp" +msgstr "" + +#: rc.cpp:307 +#, no-c-format +msgid "*.hxx" +msgstr "" + +#: rc.cpp:310 +#, no-c-format +msgid "*.H" +msgstr "" + +#: rc.cpp:313 +#, no-c-format +msgid "A list of standard file types." +msgstr "" + +#: rc.cpp:319 +#, no-c-format +msgid "Kernel project (-k)" +msgstr "" + +#: rc.cpp:323 +#, no-c-format +msgid "" +"For kernel projects, symbols are not looked up in the standard include path." +msgstr "" + +#: rc.cpp:326 +#, no-c-format +msgid "Build inverted inde&x (-q)" +msgstr "" + +#: rc.cpp:329 +#, no-c-format +msgid "Alt+X" +msgstr "" + +#: rc.cpp:332 +#, no-c-format +msgid "" +"An inverted index may greatly speed up searches in a large project. The " +"project's building process is longer, though." +msgstr "" + +#: rc.cpp:335 +#, no-c-format +msgid "Do not compress the database (-c)" +msgstr "" + +#: rc.cpp:339 +#, no-c-format +msgid "Slower, but more accurate, function definition detection (-D)" +msgstr "" + +#: rc.cpp:342 +#, no-c-format +msgid "Refresh data&base automatically" +msgstr "" + +#: rc.cpp:345 +#, no-c-format +msgid "Alt+B" +msgstr "" + +#: rc.cpp:348 +#, no-c-format +msgid "Rebuild the database after changed files are saved to disk." +msgstr "" + +#: rc.cpp:351 +#, no-c-format +msgid "(Seconds)" +msgstr "" + +#: rc.cpp:354 +#, no-c-format +msgid "" +"Wait this number of seconds after the last save before rebuilding the " +"database." +msgstr "" + +#: rc.cpp:357 +#, no-c-format +msgid "&Use symbol auto-completion" +msgstr "" + +#: rc.cpp:360 +#, no-c-format +msgid "Alt+U" +msgstr "" + +#: rc.cpp:363 +#, no-c-format +msgid "As-you-type symbol completion." +msgstr "" + +#: rc.cpp:366 +#, no-c-format +msgid "Options..." +msgstr "" + +#: rc.cpp:369 +#, no-c-format +msgid "Override default tab width (Kate only)" +msgstr "" + +#: rc.cpp:372 +#, no-c-format +msgid "Overrides the editor's configured tab width" +msgstr "" + +#: rc.cpp:375 +#, no-c-format +msgid "Cre&ate" +msgstr "" + +#: rc.cpp:378 +#, no-c-format +msgid "Ca&ncel" +msgstr "" + +#: rc.cpp:381 +#, no-c-format +msgid "Open Project" +msgstr "" + +#: rc.cpp:384 +#, no-c-format +msgid "Project Path" +msgstr "" + +#: rc.cpp:387 +#, no-c-format +msgid "Recent Projects" +msgstr "" + +#: rc.cpp:393 +#, no-c-format +msgid "&Open" +msgstr "" + +#: rc.cpp:396 +#, no-c-format +msgid "Alt+O" +msgstr "" + +#: rc.cpp:399 +#, no-c-format +msgid "C&ancel" +msgstr "" + +#: rc.cpp:402 rc.cpp:411 rc.cpp:435 +#, no-c-format +msgid "Form4" +msgstr "" + +#: rc.cpp:405 rc.cpp:414 +#, no-c-format +msgid "GUI Element" +msgstr "" + +#: rc.cpp:408 +#, no-c-format +msgid "Colour" +msgstr "" + +#: rc.cpp:420 +#, no-c-format +msgid "Form3" +msgstr "" + +#: rc.cpp:423 +#, no-c-format +msgid "Cscope path:" +msgstr "" + +#: rc.cpp:426 +#, no-c-format +msgid "Ctags path:" +msgstr "" + +#: rc.cpp:429 +#, no-c-format +msgid "Dot path:" +msgstr "" + +#: rc.cpp:432 +#, no-c-format +msgid "G&uess" +msgstr "" + +#: rc.cpp:438 +#, no-c-format +msgid "" +"Determines whether KScope should automatically load the last project when " +"started." +msgstr "" + +#: rc.cpp:441 +#, no-c-format +msgid "External Editor" +msgstr "" + +#: rc.cpp:444 +#, no-c-format +msgid "Read-Onl&y Mode" +msgstr "" + +#: rc.cpp:447 +#, no-c-format +msgid "Alt+Y" +msgstr "" + +#: rc.cpp:450 +#, no-c-format +msgid "" +"Forces all editor windows to work in a read-only mode, so that the user " +"cannot modify the displayed files." +msgstr "" + +#: rc.cpp:453 +#, no-c-format +msgid "Open Last Project on Start-Up" +msgstr "" + +#: rc.cpp:456 +#, no-c-format +msgid "Automatic Tag Highlighting" +msgstr "" + +#: rc.cpp:459 +#, no-c-format +msgid "" +"Determines whether the tag list should highlight the relevant tag based on " +"the cursor's position." +msgstr "" + +#: rc.cpp:462 +#, no-c-format +msgid "Brief Tab Captions for &Query Pages" +msgstr "" + +#: rc.cpp:465 +#, no-c-format +msgid "" +"If set, the tab captions for query pages will be shortened, by using aliases " +"for the query types." +msgstr "" + +#: rc.cpp:468 +#, no-c-format +msgid "Warn When a File is Modified Outside KScope" +msgstr "" + +#: rc.cpp:471 +#, no-c-format +msgid "" +"If set, the user is prompted whenever the currently edited file is changed " +"by an external programme." +msgstr "" + +#: rc.cpp:474 +#, no-c-format +msgid "Automatically Sort Files in the File List" +msgstr "" + +#: rc.cpp:478 +#, no-c-format +msgid "" +"Sorts files in the project's file list when a project is loaded. This may be " +"too slow for large projects on older machines." +msgstr "" + +#: rc.cpp:481 +#, no-c-format +msgid "System Profile" +msgstr "" + +#: rc.cpp:484 +#, no-c-format +msgid "Fast" +msgstr "" + +#: rc.cpp:487 +#, no-c-format +msgid "Slow" +msgstr "" + +#: rc.cpp:490 +#, no-c-format +msgid "Editor Popup Menu" +msgstr "" + +#: rc.cpp:493 +#, no-c-format +msgid "Embedded" +msgstr "" + +#: rc.cpp:496 +#, no-c-format +msgid "KScope Only" +msgstr "" + +#: rc.cpp:499 +#, no-c-format +msgid "Project Files" +msgstr "" + +#: rc.cpp:502 +#, no-c-format +msgid "Filter" +msgstr "" + +#: rc.cpp:505 +#, no-c-format +msgid "Show All" +msgstr "" + +#: rc.cpp:511 +#, no-c-format +msgid "Files..." +msgstr "" + +#: rc.cpp:514 rc.cpp:526 +#, no-c-format +msgid "Directory..." +msgstr "" + +#: rc.cpp:517 rc.cpp:529 +#, no-c-format +msgid "Tree..." +msgstr "" + +#: rc.cpp:523 +#, no-c-format +msgid "Selected" +msgstr "" + +#: rc.cpp:539 +#, no-c-format +msgid "Query Results" +msgstr "" + +#: rc.cpp:542 +#, no-c-format +msgid "Right-click inside the list for more options." +msgstr "" + +#: rc.cpp:553 +#, no-c-format +msgid "Form2" +msgstr "" + +#: rc.cpp:556 +#, no-c-format +msgid "Scanning Directory" +msgstr "" + +#: rc.cpp:559 +#, no-c-format +msgid "Scanned 0 files..." +msgstr "" + +#: rc.cpp:565 +#, no-c-format +msgid "Filter Query Results" +msgstr "" + +#: rc.cpp:568 +#, no-c-format +msgid "Search For:" +msgstr "" + +#: rc.cpp:571 +#, no-c-format +msgid "Search In:" +msgstr "" + +#: rc.cpp:586 +#, no-c-format +msgid "Search Type" +msgstr "" + +#: rc.cpp:589 +#, no-c-format +msgid "Plain Text" +msgstr "" + +#: rc.cpp:592 +#, no-c-format +msgid "RegE&xp" +msgstr "" + +#: rc.cpp:595 +#, no-c-format +msgid "Simplified RegExp" +msgstr "" + +#: rc.cpp:598 +#, no-c-format +msgid "Case Sensitive" +msgstr "" + +#: rc.cpp:601 +#, no-c-format +msgid "Negate Search" +msgstr "" + +#: rc.cpp:610 +#, no-c-format +msgid "KScope Query" +msgstr "" + +#: rc.cpp:616 +#, no-c-format +msgid "Symbol" +msgstr "" + +#: rc.cpp:619 +#, no-c-format +msgid "References to" +msgstr "" + +#: rc.cpp:622 +#, no-c-format +msgid "Definition of" +msgstr "" + +#: rc.cpp:625 +#, no-c-format +msgid "Functions called by" +msgstr "" + +#: rc.cpp:628 +#, no-c-format +msgid "Functions calling" +msgstr "" + +#: rc.cpp:631 +#, no-c-format +msgid "Find text" +msgstr "" + +#: rc.cpp:634 +#, no-c-format +msgid "Find EGrep pattern" +msgstr "" + +#: rc.cpp:637 +#, no-c-format +msgid "Find file" +msgstr "" + +#: rc.cpp:640 +#, no-c-format +msgid "Files #including" +msgstr "" + +#: rc.cpp:643 +#, no-c-format +msgid "Call graph for" +msgstr "" + +#: rc.cpp:646 +#, no-c-format +msgid "Search for &a Sub-String" +msgstr "" + +#: rc.cpp:655 +#, no-c-format +msgid "Hi&nt" +msgstr "" + +#: rc.cpp:661 +#, no-c-format +msgid "Hint Options" +msgstr "" + +#: rc.cpp:664 +#, no-c-format +msgid "S&ymbols Beginning With..." +msgstr "" + +#: rc.cpp:667 +#, no-c-format +msgid "Sym&bols Containing..." +msgstr "" + +#: rc.cpp:670 +#, no-c-format +msgid "Welcome" +msgstr "" + +#: rc.cpp:673 +#, no-c-format +msgid "" +"

    Welcome to KScope!

    \n" +"\n" +"If this is the first time you are running Kscope, please follow these steps " +"(click on the links for detailed instructions):\n" +"

    \n" +"1. Configure " +"paths to the required back-end executables
    \n" +"2. Create a new " +"project
    \n" +"3. Populate the " +"project with source files
    \n" +"4. Browse the project and edit files
    \n" +"\n" +"

    \n" +"\n" +"

    \n" +"For more information, please take a look at KScope's manual, or visit the KScope website.\n" +"

    \n" +"\n" +"

    \n" +"Enjoy!\n" +"

    \n" +"\n" +"

    \n" +"This message will only appear once. Use the \"Help-" +">Show Welcome Message...\" menu command to show it again at any time.\n" +"

    " +msgstr "" + +#: scanprogressdlg.cpp:76 +#, c-format +msgid "Scanned %d files..." +msgstr "" + +#: symbolcompletion.cpp:272 +msgid "No matching completion found..." +msgstr "" + +#: symbolcompletion.cpp:277 +msgid "Too many options..." +msgstr "" + +#: symboldlg.cpp:55 +msgid "Suggested Symbols" +msgstr "" + +#: tabwidget.cpp:50 +msgid "Shows a list of all open tabs" +msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..c60c706 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,1642 @@ +# translation of kscope.po to Simplified Chinese +# translation of kscope.po to +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Roy Qu , 2007. +# Roy Qu , 2007. +msgid "" +msgstr "" +"Project-Id-Version: kscope\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-08-02 09:22-0400\n" +"PO-Revision-Date: 2007-07-29 11:45+0800\n" +"Last-Translator: Roy Qu \n" +"Language-Team: Simplified Chinese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "" + +#: calltreedlg.cpp:308 rc.cpp:73 rc.cpp:80 +#, no-c-format +msgid "Call Graph" +msgstr "调用图" + +#: calltreedlg.cpp:310 +msgid "Right-click a function node or an arrow head for more options." +msgstr "右击函数节点或箭头以获取更多选项。" + +#: calltreedlg.cpp:316 rc.cpp:86 +#, no-c-format +msgid "Called Functions Tree" +msgstr "函数调用情况树" + +#: calltreedlg.cpp:318 calltreedlg.cpp:327 +msgid "Right-click a tree item for more options." +msgstr "右击树中的节点以获取更多选项。" + +#: calltreedlg.cpp:325 rc.cpp:92 +#, no-c-format +msgid "Calling Functions Tree" +msgstr "被其它函数调用情况树" + +#: cscopefrontend.cpp:416 +msgid "Processing query results, please wait..." +msgstr "正在处理查询请求,请等待..." + +#: ctagsfrontend.cpp:104 +msgid "Ctags cannot be found in the given path" +msgstr "在所给的路径中找不到ctags" + +#: ctagslist.cpp:147 rc.cpp:221 +#, no-c-format +msgid "Name" +msgstr "名称" + +#: ctagslist.cpp:148 queryview.cpp:53 rc.cpp:580 +#, no-c-format +msgid "Line" +msgstr "行号" + +#: ctagslist.cpp:149 rc.cpp:613 +#, no-c-format +msgid "Type" +msgstr "类型" + +#: ctagslist.cpp:189 queryview.cpp:51 rc.cpp:574 +#, no-c-format +msgid "Function" +msgstr "函数" + +#: ctagslist.cpp:194 +msgid "Variable" +msgstr "Variable" + +#: ctagslist.cpp:199 +msgid "Struct" +msgstr "Struct" + +#: ctagslist.cpp:204 +msgid "Macro" +msgstr "Macro" + +#: ctagslist.cpp:209 +msgid "Member" +msgstr "Member" + +#: ctagslist.cpp:214 +msgid "Enum" +msgstr "Enum" + +#: ctagslist.cpp:219 +msgid "Enumerator" +msgstr "Enumerator" + +#: ctagslist.cpp:224 +msgid "Typedef" +msgstr "Typedef" + +#: ctagslist.cpp:229 +msgid "Label" +msgstr "Label" + +#: ctagslist.cpp:234 +msgid "Include" +msgstr "Include" + +#: dotfrontend.cpp:99 +msgid "Dot cannot be found in the given path" +msgstr "在给定的路径中找不到" + +#: editortabs.cpp:190 +msgid "" +"Some files contain unsaved changes.\n" +"Would you like to save these files?" +msgstr "" +"某些文件中含有未保存的修改。\n" +"您是否想保存这些文件?" + +#: editortabs.cpp:295 +msgid "Untitled " +msgstr "无标题" + +#: editortabs.cpp:299 +msgid "New unsaved file" +msgstr "新未保存的文件" + +#: filelist.cpp:47 rc.cpp:215 +#, no-c-format +msgid "Path" +msgstr "路径" + +#: frontend.cpp:84 +msgid "Cannot restart while another process is still running" +msgstr "正在运行其它处理,无法重启" + +#: frontend.cpp:104 +msgid ": Failed to start process" +msgstr ":启动处理失败" + +#: frontend.cpp:108 +msgid "No error" +msgstr "无错误" + +#: graphwidget.cpp:161 +msgid "Called Functions" +msgstr "调用的函数" + +#: graphwidget.cpp:163 graphwidget.cpp:172 +msgid "Show" +msgstr "显示" + +#: graphwidget.cpp:165 graphwidget.cpp:174 +msgid "List/Filter..." +msgstr "列表/过滤..." + +#: graphwidget.cpp:167 graphwidget.cpp:176 rc.cpp:135 +#, no-c-format +msgid "Hide" +msgstr "隐藏" + +#: graphwidget.cpp:170 +msgid "Calling Functions" +msgstr "调用它的函数" + +#: graphwidget.cpp:179 +msgid "This Function" +msgstr "此函数" + +#: graphwidget.cpp:181 +msgid "Find Definition" +msgstr "查找定义" + +#: graphwidget.cpp:187 +msgid "List..." +msgstr "列表..." + +#: graphwidget.cpp:195 +msgid "Open Call" +msgstr "" + +#: graphwidget.cpp:341 kscope.cpp:559 main.cpp:58 +msgid "KScope" +msgstr "KScope" + +#: graphwidget.cpp:342 +msgid "Generating graph, please wait" +msgstr "正在生成图形,请等待" + +#: graphwidget.cpp:889 +msgid "" +"The query produced too many results.\n" +"A multiple-call node will appear in the graph instead.\n" +"Hint: The maximum number of in/out edges\n" +"can be adjusted by clicking the dialogue's \"Preferences\" button" +msgstr "" +"这次查询获得的结果太多。\n" +"将在图形中使用多重调用节点来替代。\n" +"提示:可以通过点击对话框的\"偏好设置\"按扭来调整出/入边的最大数量。" + +#: historypage.cpp:111 +msgid "HIS " +msgstr "历史" + +#: historypage.cpp:111 +msgid "History " +msgstr "历史" + +#: kscope.cpp:206 +msgid " Line: N/A Col: N/A " +msgstr "行: N/A 列: N/A " + +#: kscope.cpp:287 +msgid "" +"The current project needs to be closed before a new one is created.\n" +"Would you like to close it now?" +msgstr "" +"为了创建新工程,必须关闭当前工程。\n" +"您要关闭当前工程吗?" + +#: kscope.cpp:348 +msgid "The Add/Remove Files dialogue is not available for temporary projects." +msgstr "在临时工程中不能使用添加/删除文件对话框。" + +#: kscope.cpp:381 +msgid "" +"The Project Properties dialogue is not available for temporary projects." +msgstr "在临时工程中不能使用工程属性对话框。" + +#: kscope.cpp:559 +msgid "Please wait while KScope builds the database" +msgstr "KScope正在建立数据库,请等待" + +#: kscope.cpp:934 +msgid "Verifying Cscope installation..." +msgstr "正在验证Cscope安装..." + +#: kscope.cpp:1122 +msgid "Verifying Cscope installation...Done" +msgstr "正在验证Cscope安装...完成" + +#: kscope.cpp:1130 +msgid "" +"Cscope may not be properly installed on this system.\n" +"Please check the Cscope path specified in KScope's configuration dialogue." +msgstr "" +"此系统上似乎没有安装Cscope。\n" +"请在KScope配置对话框中检查Cscope路径。" + +#: kscope.cpp:1553 +msgid "Rebuilding the cross reference database..." +msgstr "正在重建交叉引用数据库..." + +#: kscope.cpp:1566 +msgid "Please wait while KScope builds the inverted index" +msgstr "KScope正在建立反向索引,请等待" + +#: kscope.cpp:1572 +msgid "Rebuilding inverted index..." +msgstr "正在重建反向索引..." + +#: kscope.cpp:1590 +msgid "Rebuilding the cross reference database...Done!" +msgstr "正在重建反向索引...完成!" + +#: kscope.cpp:1607 +msgid "" +"The database could not be built.\n" +"Cross-reference information will not be available for this project.\n" +"Please ensure that the Cscope parameters were correctly entered in the " +"\"Settings\" dialogue." +msgstr "" +"无法建立数据库。\n" +"在此工程中将无法使用交叉引用信息。\n" +"请检查\"设置\"对话框中的Cscope参数设置是否正确。" + +#: kscope.cpp:1616 +msgid "Rebuilding the cross reference database...Failed" +msgstr "正在重建交叉引用数据库...失败" + +#: kscope.cpp:1687 +msgid "Whould you like to add this file to the active project?" +msgstr "您想要把此文件加入当前工程吗?" + +#: kscope.cpp:1692 +msgid "Failed to write the file list." +msgstr "写文件列表失败。" + +#: kscopeactions.cpp:58 +msgid "Go to File List" +msgstr "转到文件列表" + +#: kscopeactions.cpp:66 +msgid "Save Al&l" +msgstr "全部保存(&L)" + +#: kscopeactions.cpp:75 +msgid "Edit in E&xternal Editor" +msgstr "在外部编辑器中编辑(&X)" + +#: kscopeactions.cpp:83 +msgid "Go To Tag" +msgstr "转到标签" + +#: kscopeactions.cpp:91 +msgid "Complete Symbol" +msgstr "完整符号" + +#: kscopeactions.cpp:100 +msgid "&New Project..." +msgstr "新建工程(&N)..." + +#: kscopeactions.cpp:108 +msgid "&Open Project..." +msgstr "打开工程(&O)..." + +#: kscopeactions.cpp:116 +msgid "Open &Cscope.out..." +msgstr "打开Cscope.out(&C)..." + +#: kscopeactions.cpp:124 +msgid "Add/Remove &Files..." +msgstr "添加/删除文件(&F)..." + +#: kscopeactions.cpp:140 +msgid "&Make Project" +msgstr "Make工程(&M)" + +#: kscopeactions.cpp:148 +msgid "&Remake Project" +msgstr "重新Make工程(&R)" + +#: kscopeactions.cpp:156 +msgid "&Close Project" +msgstr "关闭工程(&C)" + +#: kscopeactions.cpp:165 +msgid "&References..." +msgstr "引用(&R)..." + +#: kscopeactions.cpp:173 +msgid "&Definition..." +msgstr "定义(&D)..." + +#: kscopeactions.cpp:181 +msgid "&Called Functions..." +msgstr "调用的函数(&C)..." + +#: kscopeactions.cpp:189 +msgid "C&alling Functions..." +msgstr "调用它的函数(&A)..." + +#: kscopeactions.cpp:197 +msgid "Find &Text..." +msgstr "查找文字(&T)..." + +#: kscopeactions.cpp:205 +msgid "Find &EGrep Pattern..." +msgstr "查找EGrep模式(&E)..." + +#: kscopeactions.cpp:213 +msgid "Find &File..." +msgstr "查找文件(&F)..." + +#: kscopeactions.cpp:221 +msgid "&Including Files..." +msgstr "包含的文件(&I)..." + +#: kscopeactions.cpp:229 +msgid "&Quick Definition" +msgstr "快速查找定义(&Q)" + +#: kscopeactions.cpp:237 +msgid "Call &Graph..." +msgstr "调用图(&G)..." + +#: kscopeactions.cpp:245 +msgid "Re&build database" +msgstr "重建数据库(&B)" + +#: kscopeactions.cpp:254 +msgid "P&revious Result" +msgstr "前一个结果(&R)" + +#: kscopeactions.cpp:262 +msgid "N&ext Result" +msgstr "下一个结果(&E)" + +#: kscopeactions.cpp:270 +msgid "&Previous Position" +msgstr "前一次定位(&P)" + +#: kscopeactions.cpp:278 +msgid "&Next Position" +msgstr "后一次定位(&N)" + +#: kscopeactions.cpp:286 +msgid "Position &History" +msgstr "定位历史" + +#: kscopeactions.cpp:294 +msgid "Global &Bookmarks" +msgstr "全局书签(&B)" + +#: kscopeactions.cpp:303 +msgid "Toggle File List" +msgstr "切换文件列表" + +#: kscopeactions.cpp:311 +msgid "Toggle Query Window" +msgstr "切换查询窗口" + +#: kscopeactions.cpp:319 +msgid "Toggle Tag List" +msgstr "切换标签列表" + +#: kscopeactions.cpp:328 +msgid "Close &All" +msgstr "全部关闭(&A)" + +#: kscopeactions.cpp:336 +msgid "Go &Left" +msgstr "转到左边(&L)" + +#: kscopeactions.cpp:344 +msgid "Go &Right" +msgstr "转到右边(&R)" + +#: kscopeactions.cpp:357 +msgid "Show &Welcome Message..." +msgstr "显示欢迎信息(&W)..." + +#: kscopeactions.cpp:366 +msgid "&New" +msgstr "新建(&N)" + +#: kscopeactions.cpp:374 +msgid "&Refresh" +msgstr "刷新(&R)" + +#: kscopeactions.cpp:382 +msgid "&Lock/Unlock" +msgstr "锁定/解锁(&L)" + +#: main.cpp:36 +msgid "" +"KScope\n" +"A source-editing environment for KDE, based on Cscope" +msgstr "" + +#: main.cpp:42 +msgid "Opens a cscope.out file in a temporary project" +msgstr "" + +#: main.cpp:44 +#, fuzzy +msgid "Opens a KScope project" +msgstr "打开工程" + +#: makedlg.cpp:134 +msgid "A make process is running. Would you like to stop it first?" +msgstr "一个make进程正在运行。您要先停止它吗?" + +#: makedlg.cpp:135 +msgid "Close Make Window" +msgstr "关闭Make窗口" + +#: newprojectdlg.cpp:77 +msgid "Project Properties" +msgstr "工程属性" + +#: newprojectdlg.cpp:200 +msgid "Project names must not contain whitespace." +msgstr "工程名中不能有空格。" + +#: newprojectdlg.cpp:239 +msgid "This is not a valid file type!" +msgstr "非法的文件类型!" + +#: preferencesdlg.cpp:56 rc.cpp:123 +#, no-c-format +msgid "Preferences" +msgstr "偏好设置" + +#: preferencesdlg.cpp:63 +msgid "Programmes" +msgstr "程序" + +#: preferencesdlg.cpp:64 +msgid "Paths to back-end programmes" +msgstr "后台程序路径" + +#: preferencesdlg.cpp:71 rc.cpp:156 +#, no-c-format +msgid "Colours" +msgstr "配色" + +#: preferencesdlg.cpp:71 +msgid "Window colours" +msgstr "窗口颜色" + +#: preferencesdlg.cpp:78 +msgid "Window fonts" +msgstr "窗口字体" + +#: preferencesdlg.cpp:85 +msgid "Misc. Options" +msgstr "杂项" + +#: preferencesdlg.cpp:187 +msgid "This would reset all your configuration settings! Continue?" +msgstr "这将会重设您的全部配置设定。要继续吗?" + +#: preffont.cpp:77 preffont.cpp:87 +msgid "Sample" +msgstr "例子" + +#: preffrontend.cpp:137 +msgid "Looking for Cscope..." +msgstr "正在查找Cscope..." + +#: preffrontend.cpp:141 +msgid "Checking Cscope version..." +msgstr "正在检查Cscope版本..." + +#: preffrontend.cpp:145 +msgid "Cscope support for line mode verbose output..." +msgstr "Cscope对行模式详细输出的支持..." + +#: preffrontend.cpp:150 +msgid "Cscope support slow path definitions... " +msgstr "Cscope对慢路径定义的支持..." + +#: preffrontend.cpp:154 +msgid "Looking for Ctags..." +msgstr "正在查找Ctags..." + +#: preffrontend.cpp:158 +msgid "Ctags compatibilty with ctags-exuberant..." +msgstr "Ctags对ctags-exuberant的兼容性..." + +#: preffrontend.cpp:163 +msgid "Looking for Dot..." +msgstr "正在查找Dot..." + +#: preffrontend.cpp:167 +msgid "Checking -Tplain..." +msgstr "正在检查-Tplian参数..." + +#: project.cpp:98 +msgid "Project directory does not exist" +msgstr "工程目录不存在" + +#: project.cpp:111 +msgid "" +"Your project is not compatible with this version of KScope.\n" +"Please re-create the project." +msgstr "此版本的KScope不兼容您的工程。请重新创建此工程。" + +#: project.cpp:120 +msgid "Cannot read project name" +msgstr "无法读工程名。" + +#: projectfilesdlg.cpp:204 +#, c-format +msgid "Would you like to add %d files to your project?" +msgstr "您想要将%d个文件添加到您的工程中吗?" + +#: projectfilesdlg.cpp:299 +msgid "Are you sure you want to remove the selected files from the project?" +msgstr "您确定要从工程中删除选中的文件吗?" + +#: projectfilesdlg.cpp:329 +msgid "" +"Are you sure you want to remove the selected directory from the project?" +msgstr "您确定要从工程中删除选中的目录吗?" + +#: projectfilesdlg.cpp:362 +msgid "" +"Are you sure you want to remove all files in the selected tree from the " +"project?" +msgstr "您确定要从工程中删除选中树里的全部文件吗?" + +#: projectmanager.cpp:67 +msgid "Cannot create a project inside an existing directory" +msgstr "无法在已存在的目录中创建工程" + +#: projectmanager.cpp:74 +msgid "Failed to create the project's directory" +msgstr "创建工程目录失败" + +#: projectmanager.cpp:151 +msgid "No Project" +msgstr "无工程" + +#: queryresultsmenu.cpp:41 +msgid "&View Source" +msgstr "查看源文件(&V)" + +#: queryresultsmenu.cpp:43 +msgid "Find &Definition" +msgstr "查找定义(&D)" + +#: queryresultsmenu.cpp:48 +msgid "&Filter..." +msgstr "过滤(&F)..." + +#: queryresultsmenu.cpp:49 +msgid "&Show All" +msgstr "显示全部(&S)..." + +#: queryresultsmenu.cpp:51 +msgid "&Remove Item" +msgstr "删除项(R)..." + +#: queryview.cpp:54 rc.cpp:583 +#, no-c-format +msgid "Text" +msgstr "文字" + +#: queryview.cpp:213 +msgid "No results" +msgstr "无结果" + +#: querywidget.cpp:446 +msgid "" +"You about about to close a locked page.\n" +"Are you sure?" +msgstr "" +"您将要关闭一个已锁定的页。\n" +"确定要这么做吗?" + +#: rc.cpp:12 +#, no-c-format +msgid "&Project" +msgstr "工程(&P)" + +#: rc.cpp:15 +#, no-c-format +msgid "&Cscope" +msgstr "&Cscope" + +#: rc.cpp:18 +#, no-c-format +msgid "&Go" +msgstr "跳转(&G)" + +#: rc.cpp:21 +#, no-c-format +msgid "&Window" +msgstr "窗口(&W)" + +#: rc.cpp:30 +#, no-c-format +msgid "&Query" +msgstr "查询(&Q)" + +#: rc.cpp:33 +#, no-c-format +msgid "Cscope" +msgstr "Cscope" + +#: rc.cpp:36 +#, no-c-format +msgid "Project" +msgstr "工程" + +#: rc.cpp:39 +#, no-c-format +msgid "Navigation" +msgstr "导航" + +#: rc.cpp:42 +#, no-c-format +msgid "Query" +msgstr "查询" + +#: rc.cpp:45 +#, no-c-format +msgid "Workspace" +msgstr "工作空间" + +#: rc.cpp:48 +#, no-c-format +msgid "Auto-Completion Properties" +msgstr "自动补全属性" + +#: rc.cpp:51 +#, no-c-format +msgid "Minimum Characters" +msgstr "最短字符数" + +#: rc.cpp:54 +#, no-c-format +msgid "Delay (ms)" +msgstr "延迟(毫秒)" + +#: rc.cpp:57 +#, no-c-format +msgid "Maximum Entries" +msgstr "最大条目数" + +#: rc.cpp:66 +#, no-c-format +msgid "Global Bookmarks" +msgstr "全局书签" + +#: rc.cpp:77 rc.cpp:83 rc.cpp:89 rc.cpp:159 rc.cpp:165 +#, no-c-format +msgid "..." +msgstr "..." + +#: rc.cpp:96 rc.cpp:102 rc.cpp:108 rc.cpp:114 rc.cpp:120 +#, no-c-format +msgid "a" +msgstr "a" + +#: rc.cpp:105 +#, no-c-format +msgid "Zoom In" +msgstr "放大" + +#: rc.cpp:111 +#, no-c-format +msgid "Zoom Out" +msgstr "缩小" + +#: rc.cpp:117 +#, no-c-format +msgid "Rotate" +msgstr "旋转" + +#: rc.cpp:126 +#, no-c-format +msgid "Help Message" +msgstr "帮助信息" + +#: rc.cpp:129 +#, no-c-format +msgid "Cscope Error Messages" +msgstr "Cscope错误信息" + +#: rc.cpp:138 +#, no-c-format +msgid "Form1" +msgstr "Form1" + +#: rc.cpp:143 +#, no-c-format +msgid "Project File List" +msgstr "工程文件列表" + +#: rc.cpp:147 +#, no-c-format +msgid "File Tree" +msgstr "文件树" + +#: rc.cpp:150 +#, no-c-format +msgid "Call Graph Preferences" +msgstr "调用图偏好设置" + +#: rc.cpp:153 +#, no-c-format +msgid "Maximal In/Out Node Degree" +msgstr "最大出/入节点数" + +#: rc.cpp:176 +#, no-c-format +msgid "KScope - Make" +msgstr "KScope - Make" + +#: rc.cpp:179 +#, no-c-format +msgid "Root Directory:" +msgstr "根目录:" + +#: rc.cpp:182 +#, no-c-format +msgid "Command:" +msgstr "命令:" + +#: rc.cpp:185 +#, no-c-format +msgid "Output" +msgstr "输出" + +#: rc.cpp:188 +#, no-c-format +msgid "Errors a&nd Warnings" +msgstr "错误与警告(&N)" + +#: rc.cpp:191 +#, no-c-format +msgid "&Make" +msgstr "&Make" + +#: rc.cpp:194 +#, no-c-format +msgid "Alt+M" +msgstr "Alt+M" + +#: rc.cpp:197 +#, no-c-format +msgid "&Stop" +msgstr "停止(&S)" + +#: rc.cpp:200 +#, no-c-format +msgid "Alt+S" +msgstr "Alt+S" + +#: rc.cpp:206 +#, no-c-format +msgid "Alt+C" +msgstr "Alt+C" + +#: rc.cpp:209 +#, no-c-format +msgid "Create Project" +msgstr "新建工程" + +#: rc.cpp:212 +#, no-c-format +msgid "Detai&ls" +msgstr "详细信息(&L)" + +#: rc.cpp:218 +#, no-c-format +msgid "Source Root (Optional)" +msgstr "源文件根目录(可选)" + +#: rc.cpp:224 +#, no-c-format +msgid "" +"Enter a name for this project.\n" +"The name must conform to the file system's naming conventions for " +"directories (e.g., no spaces, exclamaion marks, etc.)." +msgstr "" +"输入此工程的名称。\n" +"此名称的格式必须遵循文件系统对目录名的格式要求(例如:不包含空格、特殊符号等)。" + +#: rc.cpp:228 +#, no-c-format +msgid "" +"The path to hold this project.\n" +"KScope will create a directory with the given name under this project, and " +"populate it with the project configuration and database files.\n" +"This does not need to be the path in which the source files reside." +msgstr "" +"存放此工程的路径。\n" +"KScope将在此工程下创建一个以工程名称命名的目录,并将工程配置和数据库 文件保存" +"在里面。\n" +"此路径不需要和项目源文件所在的目录路径相同。" + +#: rc.cpp:233 +#, no-c-format +msgid "" +"
    A project consists of several files located in a directory\n" +" with the given name and path. The project's name needs to be a valid " +"directory\n" +"name and must not contain any whitespace.
    \n" +"
    \n" +"
    The Source Root is a convinient way to specify a common\n" +"path for all source files, but is not required.
    " +msgstr "" +"
    在一个工程中包含保存在给定的名称和路径下的多个文件。 因此,工程名" +"称和路径必须是合法的目录名,其中不能含有空格。
    \n" +"
    \n" +"
    源文件根目录可以被用来为所有源文件指定一个公共路径,不过它并不是" +"必须的。
    " + +#: rc.cpp:241 +#, no-c-format +msgid "File T&ypes" +msgstr "文件类型(&Y)" + +#: rc.cpp:244 +#, no-c-format +msgid "This Project" +msgstr "此工程" + +#: rc.cpp:247 +#, no-c-format +msgid "" +"KScope uses these filters to locate source files to include in this project." +msgstr "KScope使用这些过滤器来定位包含在此工程中的源文件。" + +#: rc.cpp:250 +#, no-c-format +msgid "<< &Add" +msgstr "<< 添加(&A)" + +#: rc.cpp:253 rc.cpp:649 +#, no-c-format +msgid "Alt+A" +msgstr "Alt+A" + +#: rc.cpp:256 +#, no-c-format +msgid "Adds the selected file type to the current project." +msgstr "将选中类型的文件添加到当前项目中。" + +#: rc.cpp:259 +#, no-c-format +msgid ">> &Remove" +msgstr ">> 删除(&R)" + +#: rc.cpp:262 +#, no-c-format +msgid "Alt+R" +msgstr "Alt+R" + +#: rc.cpp:265 +#, no-c-format +msgid "Remove the selected file type from the project." +msgstr "从工程中删除选中类型的文件。" + +#: rc.cpp:268 +#, no-c-format +msgid "Available Types" +msgstr "可用类型" + +#: rc.cpp:271 +#, no-c-format +msgid "You can enter custom file types here." +msgstr "您可以在这里输入自定义文件类型。" + +#: rc.cpp:274 +#, no-c-format +msgid "*.c" +msgstr "*.c" + +#: rc.cpp:277 +#, no-c-format +msgid "*.h" +msgstr "*.h" + +#: rc.cpp:280 +#, no-c-format +msgid "*.l" +msgstr "*.l" + +#: rc.cpp:283 +#, no-c-format +msgid "*.y" +msgstr "*.y" + +#: rc.cpp:286 +#, no-c-format +msgid "*.S" +msgstr "*.S" + +#: rc.cpp:289 +#, no-c-format +msgid "*.cc" +msgstr "*.cc" + +#: rc.cpp:292 +#, no-c-format +msgid "*.cpp" +msgstr "*.cpp" + +#: rc.cpp:295 +#, no-c-format +msgid "*.cxx" +msgstr "*.cxx" + +#: rc.cpp:298 +#, no-c-format +msgid "*.C" +msgstr "*.C" + +#: rc.cpp:301 +#, no-c-format +msgid "*.hh" +msgstr "*.hh" + +#: rc.cpp:304 +#, no-c-format +msgid "*.hpp" +msgstr "*.hpp" + +#: rc.cpp:307 +#, no-c-format +msgid "*.hxx" +msgstr "*.hxx" + +#: rc.cpp:310 +#, no-c-format +msgid "*.H" +msgstr "*.H" + +#: rc.cpp:313 +#, no-c-format +msgid "A list of standard file types." +msgstr "标准文件类型列表" + +#: rc.cpp:319 +#, no-c-format +msgid "Kernel project (-k)" +msgstr "内核工程(-k)" + +#: rc.cpp:323 +#, no-c-format +msgid "" +"For kernel projects, symbols are not looked up in the standard include path." +msgstr "对于内核工程,不在标准的包含路径中寻找符号声明。" + +#: rc.cpp:326 +#, no-c-format +msgid "Build inverted inde&x (-q)" +msgstr "建立反向索引(-q)(&X)" + +#: rc.cpp:329 +#, no-c-format +msgid "Alt+X" +msgstr "Alt+X" + +#: rc.cpp:332 +#, no-c-format +msgid "" +"An inverted index may greatly speed up searches in a large project. The " +"project's building process is longer, though." +msgstr "" +"在大工程中使用反向索引可以大大提高检索速度。不过,这也会增加创建过程所需要的" +"时间。" + +#: rc.cpp:335 +#, no-c-format +msgid "Do not compress the database (-c)" +msgstr "不压缩数据库(-c)" + +#: rc.cpp:339 +#, no-c-format +msgid "Slower, but more accurate, function definition detection (-D)" +msgstr "更慢,但是更准确,检测函数定义(-D)" + +#: rc.cpp:342 +#, no-c-format +msgid "Refresh data&base automatically" +msgstr "自动更新数据库(&B)" + +#: rc.cpp:345 +#, no-c-format +msgid "Alt+B" +msgstr "Alt+B" + +#: rc.cpp:348 +#, no-c-format +msgid "Rebuild the database after changed files are saved to disk." +msgstr "当被修改的文件保存到磁盘上之后,重建数据库。" + +#: rc.cpp:351 +#, no-c-format +msgid "(Seconds)" +msgstr "(秒)" + +#: rc.cpp:354 +#, no-c-format +msgid "" +"Wait this number of seconds after the last save before rebuilding the " +"database." +msgstr "在最后一次保存后,等待这些秒数再开始重建数据库。" + +#: rc.cpp:357 +#, no-c-format +msgid "&Use symbol auto-completion" +msgstr "使用符号自动补全(&U)" + +#: rc.cpp:360 +#, no-c-format +msgid "Alt+U" +msgstr "Alt+U" + +#: rc.cpp:363 +#, no-c-format +msgid "As-you-type symbol completion." +msgstr "输入符号时自动补全。" + +#: rc.cpp:366 +#, no-c-format +msgid "Options..." +msgstr "选项..." + +#: rc.cpp:369 +#, no-c-format +msgid "Override default tab width (Kate only)" +msgstr "覆盖缺省标签页宽度(只用于Kate)" + +#: rc.cpp:372 +#, no-c-format +msgid "Overrides the editor's configured tab width" +msgstr "覆盖编辑器中配置的标签页宽度" + +#: rc.cpp:375 +#, no-c-format +msgid "Cre&ate" +msgstr "新建(&A)" + +#: rc.cpp:378 +#, no-c-format +msgid "Ca&ncel" +msgstr "取消(&N)" + +#: rc.cpp:381 +#, no-c-format +msgid "Open Project" +msgstr "打开工程" + +#: rc.cpp:384 +#, no-c-format +msgid "Project Path" +msgstr "工程路径" + +#: rc.cpp:387 +#, no-c-format +msgid "Recent Projects" +msgstr "最近的工程" + +#: rc.cpp:393 +#, no-c-format +msgid "&Open" +msgstr "打开(&O)" + +#: rc.cpp:396 +#, no-c-format +msgid "Alt+O" +msgstr "Alt+O" + +#: rc.cpp:399 +#, no-c-format +msgid "C&ancel" +msgstr "取消(&A)" + +#: rc.cpp:402 rc.cpp:411 rc.cpp:435 +#, no-c-format +msgid "Form4" +msgstr "Form4" + +#: rc.cpp:405 rc.cpp:414 +#, no-c-format +msgid "GUI Element" +msgstr "图形界面元素" + +#: rc.cpp:408 +#, no-c-format +msgid "Colour" +msgstr "颜色" + +#: rc.cpp:420 +#, no-c-format +msgid "Form3" +msgstr "Form3" + +#: rc.cpp:423 +#, no-c-format +msgid "Cscope path:" +msgstr "Cscope路径:" + +#: rc.cpp:426 +#, no-c-format +msgid "Ctags path:" +msgstr "Ctags路径:" + +#: rc.cpp:429 +#, no-c-format +msgid "Dot path:" +msgstr "Dot路径:" + +#: rc.cpp:432 +#, no-c-format +msgid "G&uess" +msgstr "猜测(&U)" + +#: rc.cpp:438 +#, no-c-format +msgid "" +"Determines whether KScope should automatically load the last project when " +"started." +msgstr "决定当KScope启动时,是否自动载入上次的工程。" + +#: rc.cpp:441 +#, no-c-format +msgid "External Editor" +msgstr "外部编辑器" + +#: rc.cpp:444 +#, no-c-format +msgid "Read-Onl&y Mode" +msgstr "只读模式(&Y)" + +#: rc.cpp:447 +#, no-c-format +msgid "Alt+Y" +msgstr "Alt+Y" + +#: rc.cpp:450 +#, no-c-format +msgid "" +"Forces all editor windows to work in a read-only mode, so that the user " +"cannot modify the displayed files." +msgstr "强制全部编辑窗口在只读模式下工作,以确保读者无法修改显示的文件。" + +#: rc.cpp:453 +#, no-c-format +msgid "Open Last Project on Start-Up" +msgstr "启动时打开上次的工程" + +#: rc.cpp:456 +#, no-c-format +msgid "Automatic Tag Highlighting" +msgstr "自动高亮标签" + +#: rc.cpp:459 +#, no-c-format +msgid "" +"Determines whether the tag list should highlight the relevant tag based on " +"the cursor's position." +msgstr "决定在标签列表中是否高亮显示与当前光标位置对应的标签" + +#: rc.cpp:462 +#, no-c-format +msgid "Brief Tab Captions for &Query Pages" +msgstr "在查询页面中简写标签页标题" + +#: rc.cpp:465 +#, no-c-format +msgid "" +"If set, the tab captions for query pages will be shortened, by using aliases " +"for the query types." +msgstr "如果设置了此选项,在查询页中将会使用查询类型的别名来简写标签页标题。" + +#: rc.cpp:468 +#, no-c-format +msgid "Warn When a File is Modified Outside KScope" +msgstr "当文件在KScope外面被修改时发出警告" + +#: rc.cpp:471 +#, no-c-format +msgid "" +"If set, the user is prompted whenever the currently edited file is changed " +"by an external programme." +msgstr "如果设置了此选项,当有外部程序改动了当前正在编辑的文件时,会提示用户。" + +#: rc.cpp:474 +#, no-c-format +msgid "Automatically Sort Files in the File List" +msgstr "自动对文件列表中的文件进行排序" + +#: rc.cpp:478 +#, no-c-format +msgid "" +"Sorts files in the project's file list when a project is loaded. This may be " +"too slow for large projects on older machines." +msgstr "" +"当载入一个工程时,自动在工程的文件列表中对文件进行排序。如果在旧机器 上编辑很" +"大的项目,这可能会导致响应变慢。" + +#: rc.cpp:481 +#, no-c-format +msgid "System Profile" +msgstr "系统偏好文件" + +#: rc.cpp:484 +#, no-c-format +msgid "Fast" +msgstr "快" + +#: rc.cpp:487 +#, no-c-format +msgid "Slow" +msgstr "慢" + +#: rc.cpp:490 +#, no-c-format +msgid "Editor Popup Menu" +msgstr "编辑器弹出菜单" + +#: rc.cpp:493 +#, no-c-format +msgid "Embedded" +msgstr "嵌入" + +#: rc.cpp:496 +#, no-c-format +msgid "KScope Only" +msgstr "仅KScope" + +#: rc.cpp:499 +#, no-c-format +msgid "Project Files" +msgstr "工程文件" + +#: rc.cpp:502 +#, no-c-format +msgid "Filter" +msgstr "过滤" + +#: rc.cpp:505 +#, no-c-format +msgid "Show All" +msgstr "显示全部" + +#: rc.cpp:511 +#, no-c-format +msgid "Files..." +msgstr "文件..." + +#: rc.cpp:514 rc.cpp:526 +#, no-c-format +msgid "Directory..." +msgstr "目录..." + +#: rc.cpp:517 rc.cpp:529 +#, no-c-format +msgid "Tree..." +msgstr "树..." + +#: rc.cpp:523 +#, no-c-format +msgid "Selected" +msgstr "已有选择" + +#: rc.cpp:539 +#, no-c-format +msgid "Query Results" +msgstr "查询结果" + +#: rc.cpp:542 +#, no-c-format +msgid "Right-click inside the list for more options." +msgstr "在列表内右击以获取更多选项。" + +#: rc.cpp:553 +#, no-c-format +msgid "Form2" +msgstr "Form2" + +#: rc.cpp:556 +#, no-c-format +msgid "Scanning Directory" +msgstr "正在扫描目录" + +#: rc.cpp:559 +#, no-c-format +msgid "Scanned 0 files..." +msgstr "已扫描0个文件..." + +#: rc.cpp:565 +#, no-c-format +msgid "Filter Query Results" +msgstr "过滤查询结果" + +#: rc.cpp:568 +#, no-c-format +msgid "Search For:" +msgstr "查找:" + +#: rc.cpp:571 +#, no-c-format +msgid "Search In:" +msgstr "在...中查找:" + +#: rc.cpp:586 +#, no-c-format +msgid "Search Type" +msgstr "查找类型" + +#: rc.cpp:589 +#, no-c-format +msgid "Plain Text" +msgstr "纯文本" + +#: rc.cpp:592 +#, no-c-format +msgid "RegE&xp" +msgstr "正则表达式(&X)" + +#: rc.cpp:595 +#, no-c-format +msgid "Simplified RegExp" +msgstr "简化的正则表达式" + +#: rc.cpp:598 +#, no-c-format +msgid "Case Sensitive" +msgstr "大小写敏感" + +#: rc.cpp:601 +#, no-c-format +msgid "Negate Search" +msgstr "反转查找" + +#: rc.cpp:610 +#, no-c-format +msgid "KScope Query" +msgstr "KScope查询" + +#: rc.cpp:616 +#, no-c-format +msgid "Symbol" +msgstr "符号" + +#: rc.cpp:619 +#, no-c-format +msgid "References to" +msgstr "对它的引用" + +#: rc.cpp:622 +#, no-c-format +msgid "Definition of" +msgstr "定义" + +#: rc.cpp:625 +#, no-c-format +msgid "Functions called by" +msgstr "被它调用的函数" + +#: rc.cpp:628 +#, no-c-format +msgid "Functions calling" +msgstr "调用它的函数" + +#: rc.cpp:631 +#, no-c-format +msgid "Find text" +msgstr "查找文字" + +#: rc.cpp:634 +#, no-c-format +msgid "Find EGrep pattern" +msgstr "查找EGrep模式" + +#: rc.cpp:637 +#, no-c-format +msgid "Find file" +msgstr "查找文件" + +#: rc.cpp:640 +#, no-c-format +msgid "Files #including" +msgstr "#include它的文件" + +#: rc.cpp:643 +#, no-c-format +msgid "Call graph for" +msgstr "调用图" + +#: rc.cpp:646 +#, no-c-format +msgid "Search for &a Sub-String" +msgstr "查找子字符串(&A)" + +#: rc.cpp:655 +#, no-c-format +msgid "Hi&nt" +msgstr "提示(&N)" + +#: rc.cpp:661 +#, no-c-format +msgid "Hint Options" +msgstr "提示选项" + +#: rc.cpp:664 +#, no-c-format +msgid "S&ymbols Beginning With..." +msgstr "以...开头的符号(&Y)..." + +#: rc.cpp:667 +#, no-c-format +msgid "Sym&bols Containing..." +msgstr "包含...的符号(&B)..." + +#: rc.cpp:670 +#, no-c-format +msgid "Welcome" +msgstr "欢迎" + +#: rc.cpp:673 +#, no-c-format +msgid "" +"

    Welcome to KScope!

    \n" +"\n" +"If this is the first time you are running Kscope, please follow these steps " +"(click on the links for detailed instructions):\n" +"

    \n" +"1. Configure " +"paths to the required back-end executables
    \n" +"2. Create a new " +"project
    \n" +"3. Populate the " +"project with source files
    \n" +"4. Browse the project and edit files
    \n" +"\n" +"

    \n" +"\n" +"

    \n" +"For more information, please take a look at KScope's manual, or visit the KScope website.\n" +"

    \n" +"\n" +"

    \n" +"Enjoy!\n" +"

    \n" +"\n" +"

    \n" +"This message will only appear once. Use the \"Help-" +">Show Welcome Message...\" menu command to show it again at any time.\n" +"

    " +msgstr "" +"

    欢迎使用 KScope!

    \n" +"\n" +"如果这是您第一次使用KScope,请按照下面的步骤做(点击连接可以获取更详细 的指" +"示):\n" +"

    \n" +"1. 配置 必要的后" +"台程序所在的路径
    \n" +"2. 创建 一个新工程" +"
    \n" +"3. 向工程中添加源文" +"件
    \n" +"4. 浏览 工程,编辑文件
    \n" +"\n" +"

    \n" +"\n" +"

    \n" +"请查看KScope手册, 或访问KScope 网站以获取更多信息.\n" +"

    \n" +"\n" +"

    \n" +"请尽情享受KScope吧!\n" +"

    \n" +"\n" +"

    \n" +"此消息只会显示一次。可以使用菜单中的\"帮助->显示欢迎信" +"息...\"项来再次显示它。\n" +"

    " + +#: scanprogressdlg.cpp:76 +#, c-format +msgid "Scanned %d files..." +msgstr "已扫描%d个文件..." + +#: symbolcompletion.cpp:272 +msgid "No matching completion found..." +msgstr "未找到匹配的补足" + +#: symbolcompletion.cpp:277 +msgid "Too many options..." +msgstr "选项太多..." + +#: symboldlg.cpp:55 +msgid "Suggested Symbols" +msgstr "建议的符号" + +#: tabwidget.cpp:50 +msgid "Shows a list of all open tabs" +msgstr "显示包含全部已打开标签页的列表" + +#~ msgid "OK" +#~ msgstr "确定" + +#~ msgid "Cancel" +#~ msgstr "取消" + +#~ msgid "Close" +#~ msgstr "关闭" + +#~ msgid "Save As..." +#~ msgstr "另存为..." + +#~ msgid "Clear" +#~ msgstr "清除" + +#~ msgid "Fonts" +#~ msgstr "字体" + +#~ msgid "&OK" +#~ msgstr "确定(&O)" + +#~ msgid "&Cancel" +#~ msgstr "取消(&C)" + +#~ msgid "&Close" +#~ msgstr "关闭(&C)" + +#~ msgid "&Options" +#~ msgstr "选项(&O)" + +#~ msgid "Remove" +#~ msgstr "删除" + +#~ msgid "Font" +#~ msgstr "字体" + +#~ msgid "Add" +#~ msgstr "添加" + +#~ msgid "File" +#~ msgstr "文件" + +#~ msgid "&File" +#~ msgstr "文件(&F)" + +#~ msgid "&Edit" +#~ msgstr "编辑(&E)" + +#~ msgid "&View" +#~ msgstr "查看(&V)" + +#~ msgid "&Settings" +#~ msgstr "设置(&S)" + +#~ msgid "&Help" +#~ msgstr "帮助(&H)" + +#~ msgid "&Properties..." +#~ msgstr "偏好设置(&P)..." + +#~ msgid "Options" +#~ msgstr "选项" + +#~ msgid "&Copy" +#~ msgstr "复制(&C)" diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..e82522d --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,68 @@ +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# these are the headers for your project +noinst_HEADERS = bookmarksdlg.h calltreedlg.h calltreemanager.h \ + configfrontend.h cscopefrontend.h cscopemsgdlg.h ctagsfrontend.h ctagslist.h \ + dirscanner.h dotfrontend.h editormanager.h editorpage.h editortabs.h encoder.h \ + filelist.h fileview.h frontend.h graphedge.h graphnode.h graphprefdlg.h \ + graphwidget.h historypage.h historyview.h kscope.h kscopeactions.h kscopeconfig.h \ + kscopepixmaps.h makedlg.h makefrontend.h newprojectdlg.h openprojectdlg.h prefcolor.h \ + preferencesdlg.h preffont.h preffrontend.h prefopt.h progressdlg.h project.h \ + projectbase.h projectfilesdlg.h projectmanager.h querypage.h querypagebase.h \ + queryresultsmenu.h queryview.h queryviewdlg.h queryviewdriver.h querywidget.h \ + scanprogressdlg.h searchlist.h searchresultsdlg.h symbolcompletion.h symboldlg.h \ + tabwidget.h treewidget.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kscope.pot + +KDE_ICON = kscope + +######################################################################### +# APPLICATION SECTION +######################################################################### +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = kscope + +# the application source, library search path, and link libraries +kscope_SOURCES = autocompletionlayout.ui bookmarksdlg.cpp bookmarkslayout.ui \ + calltreedlg.cpp calltreelayout.ui calltreemanager.cpp configfrontend.cpp \ + cscopefrontend.cpp cscopemsgdlg.cpp cscopemsglayout.ui ctagsfrontend.cpp ctagslist.cpp \ + dirscanner.cpp dotfrontend.cpp dotparse.ypp dotscan.lpp editormanager.cpp \ + editorpage.cpp editortabs.cpp encoder.cpp filelist.cpp fileview.cpp fileviewlayout.ui \ + frontend.cpp graphedge.cpp graphnode.cpp graphprefdlg.cpp graphpreflayout.ui \ + graphwidget.cpp historypage.cpp historyview.cpp kscope.cpp kscopeactions.cpp \ + kscopeconfig.cpp kscopepixmaps.cpp main.cpp makedlg.cpp makefrontend.cpp makelayout.ui \ + newprojectdlg.cpp newprojectlayout.ui openprojectdlg.cpp openprojectlayout.ui \ + prefcolor.cpp prefcolorlayout.ui preferencesdlg.cpp preffont.cpp preffontlayout.ui \ + preffrontend.cpp preffrontendlayout.ui prefopt.cpp prefoptlayout.ui progressdlg.cpp \ + project.cpp projectbase.cpp projectfilesdlg.cpp projectfileslayout.ui \ + projectmanager.cpp querypage.cpp querypagebase.cpp queryresultsmenu.cpp queryview.cpp \ + queryviewdlg.cpp queryviewdriver.cpp queryviewlayout.ui querywidget.cpp \ + querywidgetlayout.ui scanprogressdlg.cpp scanprogresslayout.ui searchlist.cpp \ + searchresultsdlg.cpp searchresultslayout.ui symbolcompletion.cpp symboldlg.cpp \ + symbollayout.ui tabwidget.cpp treewidget.cpp welcomedlg.ui + +kscope_LDFLAGS = $(KDE_RPATH) $(all_libraries) +kscope_LDADD = -lkateinterfaces -lktexteditor $(LIB_KDEUI) + +# this is where the desktop file will go +shelldesktopdir = $(kde_appsdir)/Development +shelldesktop_DATA = kscope.desktop + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/kscope +shellrc_DATA = kscopeui.rc kscope_config + +picsdir = $(kde_datadir)/kscope/pics +pics_DATA = file_ro.png file_rw.png file_save.png query_locked.png \ + query_unlocked.png tab_list.png call_graph.png called_tree.png calling_tree.png \ + bookmark.png + +BUILT_SOURCES = dotparse.h +AM_YFLAGS = -d diff --git a/src/autocompletionlayout.ui b/src/autocompletionlayout.ui new file mode 100644 index 0000000..2c8c274 --- /dev/null +++ b/src/autocompletionlayout.ui @@ -0,0 +1,217 @@ + +AutoCompletionLayout + + + AutoCompletionLayout + + + + 0 + 0 + 287 + 183 + + + + Auto-Completion Properties + + + + unnamed + + + + layout20 + + + + unnamed + + + + textLabel1 + + + Minimum Characters + + + + + spacer15 + + + Horizontal + + + Expanding + + + + 71 + 21 + + + + + + m_pMinCharsSpin + + + + + + + layout21 + + + + unnamed + + + + textLabel2 + + + Delay (ms) + + + + + spacer16 + + + Horizontal + + + Expanding + + + + 101 + 21 + + + + + + m_pDelaySpin + + + 10000 + + + 100 + + + + + + + layout22 + + + + unnamed + + + + textLabel3 + + + Maximum Entries + + + + + spacer17 + + + Horizontal + + + Expanding + + + + 81 + 21 + + + + + + m_pMaxEntriesSpin + + + 1000 + + + 1 + + + + + + + spacer19 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + layout23 + + + + unnamed + + + + spacer18 + + + Horizontal + + + Expanding + + + + 111 + 21 + + + + + + m_pOKButton + + + OK + + + + + m_pCancelButton + + + Cancel + + + + + + + + diff --git a/src/bookmark.png b/src/bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..5e761587198608815a4625f26923e4c2c59d5ed1 GIT binary patch literal 690 zcmV;j0!{siP)5r00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!L`g(JRCwBA zV88=DRWZzeU(PTepBjJwV#Fo!p^`y>iJ$%c@81jzzux>*l$^-$0h>C20Aj*r!2kaY z1+2RA0&IF(0)PK76yQ<^5I{H$U|?g4XLHbF;Br!C_{Yi=k4qUq0AV%YZ5cxXv#PWL zBj;lVM()Q99O?=RPntv<{{7o6fUXuGfEfREG0gw_k3r!t(64_v*&P0H^D}_h+!2-x z%pxzrivGNmV|YH}0K?zE3=H32d}Lr?=lJmP{-+B-uRQ<=AjZF)4D*8l(j07*qoM6N<$f~cq`1poj5 literal 0 HcmV?d00001 diff --git a/src/bookmarksdlg.cpp b/src/bookmarksdlg.cpp new file mode 100644 index 0000000..577476a --- /dev/null +++ b/src/bookmarksdlg.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#include "bookmarksdlg.h" +#include "queryview.h" + +BookmarksDlg::BookmarksDlg(QWidget* pParent, const char* szName) : + BookmarksLayout (pParent, szName, true) +{ + // Do not show the "Function" column + m_pView->setColumnWidth(0, 0); + + // Handle requests for source locations + connect(m_pView, SIGNAL(lineRequested(const QString&, uint)), this, + SLOT(slotLineRequested(const QString&, uint))); +} + +BookmarksDlg::~BookmarksDlg() +{ +} + +void BookmarksDlg::getBookmark(QString& sPath, uint& nLine) +{ + sPath = m_sPath; + nLine = m_nLine; +} + +void BookmarksDlg::slotLineRequested(const QString& sPath, uint nLine) +{ + m_sPath = sPath; + m_nLine = nLine; + accept(); +} + +#include "bookmarksdlg.moc" + diff --git a/src/bookmarksdlg.h b/src/bookmarksdlg.h new file mode 100644 index 0000000..ab74f9d --- /dev/null +++ b/src/bookmarksdlg.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef BOOKMARKSDLG_H +#define BOOKMARKSDLG_H + +#include "bookmarkslayout.h" + +class BookmarksDlg : public BookmarksLayout +{ +Q_OBJECT + +public: + BookmarksDlg(QWidget* pParent = 0, const char* szName = 0); + ~BookmarksDlg(); + + QueryView* getView() { return m_pView; } + void getBookmark(QString&, uint&); + +private: + QString m_sPath; + uint m_nLine; + +private slots: + void slotLineRequested(const QString&, uint); +}; + +#endif + diff --git a/src/bookmarkslayout.ui b/src/bookmarkslayout.ui new file mode 100644 index 0000000..f1f8135 --- /dev/null +++ b/src/bookmarkslayout.ui @@ -0,0 +1,116 @@ + +BookmarksLayout + + + BookmarksLayout + + + + 0 + 0 + 600 + 480 + + + + Global Bookmarks + + + + unnamed + + + + m_pView + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + layout1 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Expanding + + + + 291 + 21 + + + + + + m_pCloseButton + + + Close + + + + + + + + + + + + QueryView +
    queryview.h
    + + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
    +
    + + + 789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f + + + + + m_pCloseButton + clicked() + BookmarksLayout + reject() + + + + + queryview.h + +
    diff --git a/src/call_graph.png b/src/call_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..0b87ddd6c36c1cd9ac953dcc71819cbee5fd833b GIT binary patch literal 741 zcmVe<21(+!7$%Xdq8pKR5nhB6b&+%-F4|Qf5@~rC1Q9`6 z-BoxcNd(d#S~iMsA$I$NmBvyK1)?Z)cGo@5dAgVp&aQiodC>ze%)Ik^zVAH0XXfF5 zj%7Hg>@@aaNh@J+U$8!?+z7fBb<5NY3f-n8YUr54sK}$O(lliBeO@< z7QCQKw-mdZp#2!dIc&xy+>7p_x_vAY0PH)09U7VcahYGPSmHNh{Y)&1&nbq(Mo_&~aF^~~=Fo+!q7ZSe6t6G^d z*~KfEsIn!aGz{CN>NW|_2^(Z+U`=7eJ3-X=9#7#2KE_X!&vT@({MvdyDA#g3*rmf5 z8cN2oEx0RqFPJGZ{*2s)Q^6BOi{57QmAT;ES6TGg{ALc|S1b+&gSVP8J_-&MYki?# zlUKJtKJwvE?gHKn81U<)+TUY3vi0B zaC?jAb7CXLX4z9fuS5=5C?3P1{{p=h?|#bX1^7%G-G{h){${yN!i%%~QCy#Gp;>~Z zn7kSA#SL7L&x7%%{f*d!59Br+Z^O7gf>JOY#GAZ~-b%%pG?lGbVJ1m5lEhzFe6!&D zgJ@7+np^SOs#RuAoDid<;@B}!D!GcS3+1=!G&}$aCogh5P3_&eQ)f>xOjoaFXh>8l z_TCU2RGV%e!K~bdSIcFWr>Ey8*J>JB=5m{tBe*m8r@c z;lm?=#f{RF4jiA{Lt{ICQaY^po7w--n&S9AO^W2BILmv?g1qb@+=?0t$R)gQcuV7&i z&}%_6SPY&75o`zLBG5|kJ*hkyl!M2?{i14@lEN2-KpEg#0x$L3o9R<98a%|Alo}51 zq;o8zWd=jNC|wU)No^#bH`6(vA#dJ@mpJ-2RmuU6;QPou`r=ZT})@je2u-)M!OD-sDn6&JbrYo7?6jShpx~k(Y8R<~_Py4Kj=hnJ{ zYt+5b@VTqvF%4nWS1nibJU)z{@Rqr0*1PDuYr+j1J|&MoX4VDOwuzYS2;BwGJLEOS zJJtm^6LcqMZuiDT47VrpJU*B1_a(md0N(e@=WVFzbg%RP?LC5b$%blC(5ax3-e;4) zPY0oJCHN7{1&`9M7##$7t!=!P)2=8U!FX^hb94P?`~g8(qS{{tR!IN=002ovPDHLk FV1l%J(^~)l literal 0 HcmV?d00001 diff --git a/src/calling_tree.png b/src/calling_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..89e40d2acb9f45df4514bdabe315c2953659829d GIT binary patch literal 445 zcmV;u0Yd(XP)-l!F2F3!>@yjdF&n* zt|z{Zb2gakYElHvU^S0x-AM_j2EbLtvj(kg+*)QH3wduk@v>J^8l$zBWb+*=~dd})bDt^M}hpb>1mj8#+ zx#M#K3au(0HCX?`?QfjMF}z5e8IapI>iAycJOnHGMcgStp~8`jPUhbh!KG68PXvd% z-tbhvvtvWr`}6!E@otpxzC7O@GVkvQYQdha^W;g{i!HMX6;|<3zn{}M1?S|qb00000NkvXXu0mjfVmZsM literal 0 HcmV?d00001 diff --git a/src/calltreedlg.cpp b/src/calltreedlg.cpp new file mode 100644 index 0000000..65ee4f8 --- /dev/null +++ b/src/calltreedlg.cpp @@ -0,0 +1,336 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "calltreedlg.h" +#include "graphwidget.h" +#include "treewidget.h" +#include "kscopepixmaps.h" +#include "kscopeconfig.h" +#include "graphprefdlg.h" + +/** The currently supported version of saved call-tree files. */ +#define FILE_VERSION 5 + +/** Window flags for call-tree widgets. */ +#define CALL_TREE_W_FLAGS \ + WStyle_Customize | \ + WStyle_NormalBorder | \ + WStyle_Title | \ + WDestructiveClose + +/** File Name index for the file name generation */ +int CallTreeDlg::s_nFileNameIndex = 0; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +CallTreeDlg::CallTreeDlg(QWidget* pParent, const char* szName) : + CallTreeLayout(pParent, szName, CALL_TREE_W_FLAGS) +{ + // Set button pixmaps + m_pCalledButton->setPixmap(GET_PIXMAP(CalledTree)); + m_pCallingButton->setPixmap(GET_PIXMAP(CallingTree)); + m_pGraphButton->setPixmap(GET_PIXMAP(CallGraph)); + m_pSaveButton->setPixmap(GET_PIXMAP(ButtonSaveAs)); + m_pZoomInButton->setPixmap(GET_PIXMAP(ButtonZoomIn)); + m_pZoomOutButton->setPixmap(GET_PIXMAP(ButtonZoomOut)); + m_pRotateButton->setPixmap(GET_PIXMAP(ButtonRotate)); + m_pPrefButton->setPixmap(GET_PIXMAP(ButtonPref)); + + // Open the location of a call + connect(m_pGraphWidget, SIGNAL(lineRequested(const QString&, uint)), + this, SIGNAL(lineRequested(const QString&, uint))); + connect(m_pCalledWidget, SIGNAL(lineRequested(const QString&, uint)), + this, SIGNAL(lineRequested(const QString&, uint))); + connect(m_pCallingWidget, SIGNAL(lineRequested(const QString&, uint)), + this, SIGNAL(lineRequested(const QString&, uint))); + + m_pCallingWidget->setMode(TreeWidget::Calling); + + // Get the default view from KScope's configuration + m_nDefView = Config().getDefGraphView(); +} + +/** + * Class destructor. + */ +CallTreeDlg::~CallTreeDlg() +{ +} + +/** + * @param sFunc The function to use as the root of the call tree + */ +void CallTreeDlg::setRoot(const QString& sFunc) +{ + m_sRoot = sFunc; + + // Generate unique file name to save call tree later + m_sFileName = sFunc; + m_sFileName.replace(' ', '_'); + m_sFileName += QString::number(++s_nFileNameIndex); + + // Set the root item in all views + m_pGraphWidget->setRoot(sFunc); + m_pCalledWidget->setRoot(sFunc); + m_pCallingWidget->setRoot(sFunc); +} + +/** + * Displays the dialogue. + */ +void CallTreeDlg::show() +{ + // Set the default view. + m_pViewGroup->setButton(m_nDefView); + m_pStack->raiseWidget(m_nDefView); + slotViewChanged(m_nDefView); + + CallTreeLayout::show(); +} + +/** + * Informs the call tree manager that this object should be removed from the + * list of call tree dialogues. + * The close event is received when the dialogue is explicitly closed by the + * user. This dialogue will not appear when the project is reopened, and it + * is therefore safe to delete the graph file at this point. + * @param pEvent Information on the closing event + */ +void CallTreeDlg::closeEvent(QCloseEvent* pEvent) +{ + if (!m_sFilePath.isEmpty()) + QFile::remove(m_sFilePath); + + emit closed(this); + QWidget::closeEvent(pEvent); +} + +extern void yyinit(CallTreeDlg*, FILE*, Encoder*); +extern int yyparse(); + +/** + * Restores a call tree from the given call tree file. + * NOTE: The call tree file is deleted when loading is complete. + * @param sProjPath The full path of the project directory + * @param sFileName The name of the call tree file to load + * @return true if successful, false otherwise + */ +bool CallTreeDlg::load(const QString& sProjPath, const QString& sFileName) +{ + QString sPath; + FILE* pFile; + int nVersion, nView, nResult; + Encoder enc; + + // Create the full path name + sPath = sProjPath + "/" + sFileName; + + // Open the file for reading + pFile = fopen(sPath.latin1(), "r"); + if (pFile == NULL) + return false; + + // Check file version + if ((fscanf(pFile, "VERSION=%d\n", &nVersion) != 1) || + (nVersion != FILE_VERSION)) { + fclose(pFile); + return false; + } + + // Get default view + if ((fscanf(pFile, "View=%d\n", &nView) == 1) && + (nView >= 0) && + (nView <= 2)) { + m_nDefView = nView; + } + + // Read the call trees and the graph stored on this file + yyinit(this, pFile, &enc); + nResult = yyparse(); + + // Close the file + fclose(pFile); + + // Check the result returned by the parser + if (nResult != 0) + return false; + + // Store the file name + m_sFileName = sFileName; + m_sFilePath = sPath; + + // Draw the graph + m_pGraphWidget->draw(); + return true; +} + +/** + * Writes the contents of the call tree dialog to a call tree file. + * This method is called for call trees before the owner project is + * closed. + * @param sProjPath The full path of the project directory + */ +void CallTreeDlg::store(const QString& sProjPath) +{ + QString sPath; + FILE* pFile; + + // Create the full file path + sPath = sProjPath + "/" + m_sFileName; + m_sFilePath = sPath; + + // Open a file for writing (create if necessary) + pFile = fopen(sPath.latin1(), "w+"); + if (pFile == NULL) + return; + + // Write header + fprintf(pFile, "VERSION=%d\n", FILE_VERSION); + fprintf(pFile, "View=%d\n", m_pViewGroup->selectedId()); + + // Save the contents of all widgets + m_pCalledWidget->save(pFile); + m_pCallingWidget->save(pFile); + m_pGraphWidget->save(pFile); + + // Close the file + fclose(pFile); +} + +/** + * Saves the graph to a dot file. + * The user is prompted for a name to use for the file, and then graph + * widget writes its information to this file (using the dot language). + * This slot is connected to the clicked() signal of the "Save As..." button. + */ +void CallTreeDlg::slotSaveClicked() +{ + QString sFile; + + // Prompt the user for a file name + sFile = KFileDialog::getSaveFileName(":kscope"); + + // Save the graph to a file (unless the user did not give a file name) + if (!sFile.isEmpty()) + m_pGraphWidget->save(sFile); +} + +/** + * Increases the zoom factor of the graph. + * This slot is connected to the clicked() signal of the "Zoom In" button. + */ +void CallTreeDlg::slotZoomInClicked() +{ + m_pGraphWidget->zoom(true); + m_pGraphWidget->draw(); +} + +/** + * Decreases the zoom factor of the graph. + * This slot is connected to the clicked() signal of the "Zoom Out" button. + */ +void CallTreeDlg::slotZoomOutClicked() +{ + m_pGraphWidget->zoom(false); + m_pGraphWidget->draw(); +} + +/** + * Changes the graph's layout direction. + * This slot is connected to the clicked() signal of the "Rotate" button. + */ +void CallTreeDlg::slotRotateClicked() +{ + m_pGraphWidget->rotate(); + m_pGraphWidget->draw(); +} + +/** + * Opens the call graph preferences dialogue. + * This slot is connected to the clicked() signal of the "Preferences" button. + */ +void CallTreeDlg::slotPrefClicked() +{ + GraphPrefDlg dlg(this); + int nMaxNodeDegree; + + if (dlg.exec() == QDialog::Accepted) { + nMaxNodeDegree = dlg.getMaxNodeDegree(); + Config().setGraphMaxNodeDegree(nMaxNodeDegree); + m_pGraphWidget->setMaxNodeDegree(nMaxNodeDegree); + } +} + +/** + * Prepares the selected view. + * This slot is called when the user chooses a different view through the + * toggle buttons in the dialogue's toolbar. + * @param nView Identifies the selected view + */ +void CallTreeDlg::slotViewChanged(int nView) +{ + switch (nView) { + case 0: + // Call graph + setCaption(i18n("Call Graph")); + m_pGraphGroup->setEnabled(true); + m_pHelpLabel->setText(i18n("Right-click a function node or an arrow " + "head for more options.")); + break; + + case 1: + // Called functions tree + setCaption(i18n("Called Functions Tree")); + m_pGraphGroup->setEnabled(false); + m_pHelpLabel->setText(i18n("Right-click a tree item for more " + "options.")); + m_pCalledWidget->queryRoot(); + break; + + case 2: + // Calling functions tree + setCaption(i18n("Calling Functions Tree")); + m_pGraphGroup->setEnabled(false); + m_pHelpLabel->setText(i18n("Right-click a tree item for more " + "options.")); + m_pCallingWidget->queryRoot(); + break; + } + + Config().setDefGraphView(nView); +} + +#include "calltreedlg.moc" diff --git a/src/calltreedlg.h b/src/calltreedlg.h new file mode 100644 index 0000000..d5f567b --- /dev/null +++ b/src/calltreedlg.h @@ -0,0 +1,111 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CALLTREEDLG_H +#define CALLTREEDLG_H + +#include +#include +#include + +/** + * A multiple-view window showing function call information. + * The available views are: + * - Call graph, showing both calling and call functions + * - Called functions tree + * - Calling functions tree + * NOTE: This is class is now derived from QWidget instead of QDialog. This + * means that call-trees are independent windows, which can be maximised or + * minimised. + * @author Elad Lahav + */ +class CallTreeDlg : public CallTreeLayout +{ + Q_OBJECT + +public: + CallTreeDlg(QWidget* pParent = 0, const char* szName = 0); + ~CallTreeDlg(); + + void setRoot(const QString&); + bool load(const QString&, const QString&); + void store(const QString&); + + /** Returns Call Tree filename */ + QString getFileName() { return m_sFileName; } + +public slots: + virtual void show(); + +signals: + /** + * Emitted when the user makes a request to view the contents of a + * location in the source code. + * This can be the location of a call, the definition of a function, + * etc. + * @param sPath The full path of the file to show + * @param nLine The line number in this file + */ + void lineRequested(const QString& sPath, uint nLine); + + /** + * Emitted when the user closes the tree view. + */ + void closed(const CallTreeDlg*); + +protected: + virtual void closeEvent(QCloseEvent*); + +protected slots: + virtual void slotSaveClicked(); + virtual void slotZoomInClicked(); + virtual void slotZoomOutClicked(); + virtual void slotRotateClicked(); + virtual void slotPrefClicked(); + virtual void slotViewChanged(int); + +private: + /** The root function. */ + QString m_sRoot; + + /** A unique file name used for storing the call tree on a file. + The name is a combination of the root function and an incremented + index. */ + QString m_sFileName; + + /** The full path of the file on which the call tree was saved + (empty if this graph was never stored). */ + QString m_sFilePath; + + /** The view to show when the dialogue is first displayed. */ + int m_nDefView; + + /** An index for the generating unique file names. */ + static int s_nFileNameIndex; +}; + +#endif diff --git a/src/calltreelayout.ui b/src/calltreelayout.ui new file mode 100644 index 0000000..2562977 --- /dev/null +++ b/src/calltreelayout.ui @@ -0,0 +1,430 @@ + +CallTreeLayout + + + CallTreeLayout + + + + 0 + 0 + 695 + 578 + + + + Call Graph + + + + unnamed + + + + layout2 + + + + unnamed + + + + m_pViewGroup + + + NoFrame + + + 0 + + + + + + true + + + + unnamed + + + 0 + + + + m_pGraphButton + + + ... + + + true + + + true + + + Call Graph + + + + + m_pCalledButton + + + ... + + + true + + + true + + + Called Functions Tree + + + + + m_pCallingButton + + + ... + + + true + + + true + + + Calling Functions Tree + + + + + + + line1 + + + VLine + + + Sunken + + + Vertical + + + + + m_pGraphGroup + + + NoFrame + + + 0 + + + + + + true + + + + unnamed + + + 0 + + + + m_pSaveButton + + + a + + + true + + + Save As... + + + + + m_pZoomInButton + + + a + + + false + + + true + + + Zoom In + + + + + m_pZoomOutButton + + + a + + + false + + + true + + + Zoom Out + + + + + m_pRotateButton + + + a + + + false + + + true + + + Rotate + + + + + m_pPrefButton + + + a + + + false + + + true + + + Preferences + + + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 110 + 21 + + + + + + + + m_pStack + + + + 7 + 7 + 0 + 0 + + + + + WStackPage + + + 0 + + + + unnamed + + + 0 + + + + m_pGraphWidget + + + + + + + WStackPage + + + 1 + + + + unnamed + + + 0 + + + + m_pCalledWidget + + + + + + + WStackPage + + + 2 + + + + unnamed + + + 0 + + + + m_pCallingWidget + + + + + + + + m_pHelpLabel + + + Help Message + + + + + + + GraphWidget +
    graphwidget.h
    + + -1 + -1 + + 0 + + 7 + 7 + 0 + 0 + + image0 +
    + + TreeWidget +
    treewidget.h
    + + -1 + -1 + + 0 + + 7 + 7 + 0 + 0 + + image0 +
    +
    + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082 + + + + + m_pPrefButton + clicked() + CallTreeLayout + slotPrefClicked() + + + m_pRotateButton + clicked() + CallTreeLayout + slotRotateClicked() + + + m_pZoomOutButton + clicked() + CallTreeLayout + slotZoomOutClicked() + + + m_pZoomInButton + clicked() + CallTreeLayout + slotZoomInClicked() + + + m_pSaveButton + clicked() + CallTreeLayout + slotSaveClicked() + + + m_pViewGroup + clicked(int) + CallTreeLayout + slotViewChanged(int) + + + m_pViewGroup + clicked(int) + m_pStack + raiseWidget(int) + + + + slotSaveClicked() + slotZoomInClicked() + slotZoomOutClicked() + slotRotateClicked() + slotViewChanged(int) + slotViewChanged(QWidget*) + slotPrefClicked() + + + + graphwidget.h + treewidget.h + treewidget.h + +
    diff --git a/src/calltreemanager.cpp b/src/calltreemanager.cpp new file mode 100644 index 0000000..5dc8e9f --- /dev/null +++ b/src/calltreemanager.cpp @@ -0,0 +1,136 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include "calltreemanager.h" +#include "calltreedlg.h" +#include "projectmanager.h" + +/** + * Class constructor. + * @param pParent The widget to use as the parent of all Call Tree + * dialogues + */ +CallTreeManager::CallTreeManager(QWidget* pParent) : QObject(pParent) +{ + // Delete dialogue objects when they are removed from the list + m_lstDialogs.setAutoDelete(true); +} + +/** + * Class destructor. + */ +CallTreeManager::~CallTreeManager() +{ +} + +/** + * Saves all call trees into the project directory. + * @param sProjPath The project's directory + * @param slFiles Holds a list of saved file names, upon return + */ +void CallTreeManager::saveOpenDialogs(const QString& sProjPath, + QStringList& slFiles) +{ + CallTreeDlg *pDlg; + + // Iterate over the open dialogues + for (pDlg = m_lstDialogs.first(); pDlg != NULL; + pDlg = m_lstDialogs.next()) { + pDlg->store(sProjPath); + slFiles += pDlg->getFileName(); + } +} + +/** + * Loads all call trees according to the list of files + * @param sProjPath The project's directory + * @param slFiles A list of file names to open + */ +void CallTreeManager::loadOpenDialogs(const QString& sProjPath, + const QStringList& slFiles) +{ + QStringList::ConstIterator itr; + CallTreeDlg *pDlg; + + for (itr = slFiles.begin(); itr != slFiles.end(); ++itr) { + // Create a new dialogue for this file + pDlg = addDialog(); + + // Try to load the graph from the file + if (!pDlg->load(sProjPath, *itr)) { + m_lstDialogs.remove(pDlg); + continue; + } + + // Show the call tree + pDlg->show(); + } +} + +/** + * Creates a new Call Tree dialogue. + * @return The newly allocated dialogue object + */ +CallTreeDlg* CallTreeManager::addDialog() +{ + CallTreeDlg* pDlg; + + // Create a modeless call tree dialogue + pDlg = new CallTreeDlg(); + m_lstDialogs.append(pDlg); + + // Open an editor whenever a function name is double-clicked + connect(pDlg, SIGNAL(lineRequested(const QString&, uint)), + this, SIGNAL(lineRequested(const QString&, uint))); + + // Track the closing of the call tree dialog + connect(pDlg, SIGNAL(closed(const CallTreeDlg*)), this, + SLOT(slotRemoveDialog(const CallTreeDlg*))); + + return pDlg; +} + +/** + * Closes all Call Tree dialogues. + */ +void CallTreeManager::closeAll() +{ + m_lstDialogs.clear(); +} + +/** + * Removes a Call Tree dialogue from the list of open Call Trees. + * This slot is connected to the closed() signal emitted by the dialogue. + * @param pDlg The dialogue to remove from the list + */ +void CallTreeManager::slotRemoveDialog(const CallTreeDlg* pDlg) +{ + m_lstDialogs.remove(pDlg); +} + +#include "calltreemanager.moc" + diff --git a/src/calltreemanager.h b/src/calltreemanager.h new file mode 100644 index 0000000..adb91e6 --- /dev/null +++ b/src/calltreemanager.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CALLTREEMANAGER_H +#define CALLTREEMANAGER_H + +#include +#include + +class CallTreeDlg; + +/** + * Manages all call tree dialogs within the project. + * Responsible for saving/loading of the call tree dialogs. + * @author Albert Yosher + */ +class CallTreeManager : public QObject +{ + Q_OBJECT + +public: + CallTreeManager(QWidget*); + ~CallTreeManager(); + + void saveOpenDialogs(const QString&, QStringList&); + void loadOpenDialogs(const QString&, const QStringList&); + CallTreeDlg* addDialog(); + void closeAll(); + +signals: + /** + * Emitted when any call tree dialogue sends a request to view a location + * in the source code. + * @param sPath The full path of the file to show + * @param nLine The line number in this file + */ + void lineRequested(const QString& sPath, uint nLine); + +private: + /** The list of open call tree dialogues. */ + QPtrList m_lstDialogs; + +private slots: + void slotRemoveDialog(const CallTreeDlg*); +}; + +#endif diff --git a/src/configfrontend.cpp b/src/configfrontend.cpp new file mode 100644 index 0000000..27e4e32 --- /dev/null +++ b/src/configfrontend.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "configfrontend.h" + +/** + * Class constructor. + * @param bAutoDelete True to destroy the object when the process ends, + * false otherwise + */ +ConfigFrontend::ConfigFrontend(bool bAutoDelete) : + Frontend(1, bAutoDelete) +{ +} + +/** + * Class destructor. + */ +ConfigFrontend::~ConfigFrontend() +{ +} + +/** + * Executes the script using the "sh" shell. + * @param sCscopePath If given, overrides the automatic check for Cscope's + * path + * @param sCtagsPath If given, overrides the automatic check for Ctags' + * path + * @param sDotPath If given, overrides the automatic check for Dot's + * path + * @param bCscopeOptsOnly Only verify cscope's path and options + * @return true if successful, false otherwise + */ +bool ConfigFrontend::run(const QString& sCscopePath, + const QString& sCtagsPath, const QString& sDotPath, + bool bCscopeOptsOnly) +{ + QStringList slArgs; + KStandardDirs sd; + QString sScript; + + // Execute using the user's shell + setUseShell(true); + + // Find the configuration script + sScript = sd.findResource("data", "kscope/kscope_config"); + if (sScript.isEmpty()) + return false; + + // Set command line arguments + slArgs.append("sh"); + slArgs.append(sScript); + + if (bCscopeOptsOnly) + slArgs.append("-co"); + + // Initialise environment + setEnvironment("CSCOPE_PATH", sCscopePath); + setEnvironment("CTAGS_PATH", sCtagsPath); + setEnvironment("DOT_PATH", sDotPath); + + // Parser initialisation + m_delim = Newline; + m_nNextResult = CscopePath; + + if (!Frontend::run("sh", slArgs)) + return false; + + emit test(CscopePath); + return true; +} + +/** + * Handles tokens generated by the script. + * Each token represents a line in the script's output, and is the result of + * a different test. + * @param sToken The generated token + */ +Frontend::ParseResult ConfigFrontend::parseStdout(QString& sToken, + ParserDelim) +{ + uint nResult; + + // Store the type of test for which the given token in the result + nResult = m_nNextResult; + + // Determine the next test + switch (m_nNextResult) { + case CscopePath: + if (sToken == "ERROR") + m_nNextResult = CtagsPath; + else + m_nNextResult = CscopeVersion; + break; + + case CscopeVersion: + if (sToken == "ERROR") + m_nNextResult = CtagsPath; + else + m_nNextResult = CscopeVerbose; + break; + + case CscopeVerbose: + m_nNextResult = CscopeSlowPath; + break; + + case CscopeSlowPath: + m_nNextResult = CtagsPath; + break; + + case CtagsPath: + if (sToken == "ERROR") + m_nNextResult = END; + else + m_nNextResult = CtagsExub; + break; + + case CtagsExub: + if (sToken == "ERROR") + m_nNextResult = END; + else + m_nNextResult = DotPath; + break; + + case DotPath: + if (sToken == "ERROR") + m_nNextResult = END; + else + m_nNextResult = DotPlain; + break; + + case DotPlain: + m_nNextResult = END; + break; + + case END: + return DiscardToken; + } + + // Publish the result and the type of the next test + emit result(nResult, sToken); + emit test(m_nNextResult); + + return DiscardToken; +} + +#include "configfrontend.moc" diff --git a/src/configfrontend.h b/src/configfrontend.h new file mode 100644 index 0000000..df5e303 --- /dev/null +++ b/src/configfrontend.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CONFIGFRONTEND_H +#define CONFIGFRONTEND_H + +#include + +/** + * Frontend to the kscope_config shell script. + * The script executes a set of tests and outputs their results. + * @author Elad Lahav + */ +class ConfigFrontend : public Frontend +{ + Q_OBJECT + +public: + ConfigFrontend(bool bAutoDelete = false); + ~ConfigFrontend(); + + bool run(const QString&, const QString&, const QString&, + bool bCscopeOptsOnly = false); + + /** + * The types of tests executed by the script. + */ + enum { CscopePath, CscopeVersion, CscopeVerbose, CscopeSlowPath, + CtagsPath, CtagsExub, DotPath, DotPlain, END }; + +signals: + /** + * Indicates that the script is now running a given test. + * @param nType The type of test being executed + */ + void test(uint nType); + + /** + * Called after a test has produced a result. + * @param nType The type of test executed + * @param sResult The obtained result + */ + void result(uint nType, const QString& sResult); + +protected: + virtual ParseResult parseStdout(QString&, ParserDelim); + +private: + /** The type of test whose result is expected next. */ + uint m_nNextResult; +}; + +#endif diff --git a/src/cscopefrontend.cpp b/src/cscopefrontend.cpp new file mode 100644 index 0000000..7c8f288 --- /dev/null +++ b/src/cscopefrontend.cpp @@ -0,0 +1,524 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "cscopefrontend.h" +#include "kscopeconfig.h" +#include "configfrontend.h" + +#define BUILD_STR "Building symbol database %d of %d" +#define SEARCH_STR "Search %d of %d" +#define INV_STR "Possible references retrieved %d of %d" +#define REGEXP_STR "Symbols matched %d of %d" +#define SEARCHEND_STR "%d lines" + +QString CscopeFrontend::s_sProjPath; +uint CscopeFrontend::s_nProjArgs; +uint CscopeFrontend::s_nSupArgs; + +/** + * Class constructor. + * @param bAutoDelete true to delete the object once the process has + * terminated, false otherwise + */ +CscopeFrontend::CscopeFrontend(bool bAutoDelete) : + Frontend(CSCOPE_RECORD_SIZE, bAutoDelete), + m_state(Unknown), + m_sErrMsg(""), + m_bRebuildOnExit(false) +{ +} + +/** + * Class destructor. + */ +CscopeFrontend::~CscopeFrontend() +{ +} + +/** + * Executes a Cscope process using the given command line arguments. + * The full path to the Cscope executable should be set in the "Path" key + * under the "Cscope" group. + * @param slArgs Command line arguments for Cscope + * @return true if successful, false otherwise + */ +bool CscopeFrontend::run(const QStringList& slArgs) +{ + QStringList slCmdLine; + + // Set the command line arguments + slCmdLine.append(Config().getCscopePath()); + slCmdLine += slArgs; + + // Use verbose mode, if supported + if (s_nSupArgs & VerboseOut) + slCmdLine << "-v"; + + // Project-specific options + if (s_nProjArgs & Kernel) + slCmdLine << "-k"; + if (s_nProjArgs & InvIndex) + slCmdLine << "-q"; + if (s_nProjArgs & NoCompression) + slCmdLine << "-c"; + if (s_nProjArgs & s_nSupArgs & SlowPathDef) + slCmdLine << "-D"; + + // Run a new process + if (!Frontend::run("cscope", slCmdLine, s_sProjPath)) { + emit aborted(); + return false; + } + + return true; +} + +/** + * Executes a Cscope query. + * A query is composed of a numeric type and a query text, which are written + * to the stndard input of the currently running Cscope process. + * @param nType The type of query to run + * @param sText The query's text + * @param bCase true for case-sensitive queries, false otherwise + * @param nMaxRecords The maximal number of records to return (abort if this + * number is exceeded) + */ +void CscopeFrontend::query(uint nType, const QString& sText, bool bCase, + uint nMaxRecords) +{ + QString sQuery; + QStringList slArgs; + + m_nMaxRecords = nMaxRecords; + + // Create the Cscope command line + slArgs.append(QString("-L") + QString::number(nType)); + slArgs.append(sText); + slArgs.append("-d"); + if (!bCase) + slArgs.append("-C"); + + run(slArgs); + + // Initialise stdout parsing + m_state = SearchSymbol; + m_delim = WSpace; + + emit progress(0, 1); +} + +/** + * Rebuilds the symbol database of the current project. + */ +void CscopeFrontend::rebuild() +{ + QStringList slArgs; + + // If a process is already running, kill it start a new one + if (isRunning()) { + m_bRebuildOnExit = true; + kill(); + return; + } + + // Run the database building process + slArgs.append("-b"); + run(slArgs); + + // Initialise output parsing + m_state = BuildStart; + m_delim = Newline; + + emit progress(0, 1); +} + +/** + * Sets default parameters for all CscopeFrontend projects based on the + * current project. + * @param sProjPath The full path of the project's directory + * @param nArgs Project-specific command-line arguments + */ +void CscopeFrontend::init(const QString& sProjPath, uint nArgs) +{ + s_sProjPath = sProjPath; + s_nProjArgs = nArgs; +} + +/** + * Stops a Cscope action. + */ +void CscopeFrontend::slotCancel() +{ + kill(); +} + +/** + * Parses the output of a Cscope process. + * Implements a state machine, where states correspond to the output of the + * controlled Cscope process. + * @param sToken The current token read (the token delimiter is determined + * by the current state) + * @return A value indicating the way this token should be treated: dropped, + * added to the token queue, or finishes a new record + */ +Frontend::ParseResult CscopeFrontend::parseStdout(QString& sToken, + ParserDelim /* ignored */) +{ + int nFiles, nTotal, nRecords; + ParseResult result = DiscardToken; + ParserState stPrev; + + // Remember previous state + stPrev = m_state; + + // Handle the token according to the current state + switch (m_state) { + case BuildStart: + if (sToken == "Building cross-reference...") { + m_state = BuildSymbol; + m_delim = WSpace; + } + else if (sToken == "Building inverted index...") { + emit buildInvIndex(); + } + + result = DiscardToken; + break; + + case BuildSymbol: + // A single angle bracket is the prefix of a progress indication, + // while double brackets is Cscope's prompt for a new query + if (sToken == ">") { + m_state = Building; + m_delim = Newline; + } + + result = DiscardToken; + break; + + case Building: + // Try to get building progress + if (sscanf(sToken.latin1(), BUILD_STR, &nFiles, &nTotal) == 2) { + emit progress(nFiles, nTotal); + + // Check for last progress message + if (nFiles == nTotal) { + m_state = BuildStart; + m_delim = Newline; + + result = DiscardToken; + break; + } + } + + // Wait for another progress line or the "ready" symbol + m_state = BuildSymbol; + m_delim = WSpace; + + result = DiscardToken; + break; + + case SearchSymbol: + // Check for more search progress, or the end of the search, + // designated by a line in the format of "cscope: X lines" + if (sToken == ">") { + m_state = Searching; + m_delim = Newline; + result = DiscardToken; + break; + } + else if (sToken == "cscope:") { + m_state = SearchEnd; + m_delim = Newline; + result = DiscardToken; + break; + } + + case File: + // Is this the first entry? If so, signal that the query is complete + if (stPrev != LineText) + emit progress(1, 1); + + // Treat the token as the name of the file in this record + m_state = Func; + result = AcceptToken; + break; + + case Searching: + // Try to get the search progress value (ignore other messages) + if ((sscanf(sToken.latin1(), SEARCH_STR, &nFiles, &nTotal) == 2) || + (sscanf(sToken.latin1(), INV_STR, &nFiles, &nTotal) == 2) || + (sscanf(sToken.latin1(), REGEXP_STR, &nFiles, &nTotal) == 2)) { + emit progress(nFiles, nTotal); + } + + m_state = SearchSymbol; + m_delim = WSpace; + result = DiscardToken; + break; + + case SearchEnd: + // Get the number of results found in this search + if ((sscanf(sToken.latin1(), SEARCHEND_STR, &nRecords) == 1) && + (m_nMaxRecords > 0) && + (nRecords > m_nMaxRecords)) { + result = Abort; + } + else { + m_state = File; + m_delim = WSpace; + result = DiscardToken; + } + + break; + + case Func: + // Treat the token as the name of the function in this record + if (sToken.toInt()) { + // In case of a global definition, there is no function name, and + // instead the line number is given immediately + m_state = LineText; + m_delim = Newline; + } + else { + // Not a number, it is the name of the function + m_state = Line; + } + + result = AcceptToken; + break; + + case Line: + // Treat the token as the line number in this record + m_state = LineText; + m_delim = Newline; + result = AcceptToken; + break; + + case LineText: + // Treat the token as the text of this record, and report a new + // record + m_state = File; + m_delim = WSpace; + result = RecordReady; + break; + + default: + // Do nothing (prevents a compilation warning for unused enum values) + break; + } + + return result; +} + +/** + * Handles Cscope messages sent to the standard error stream. + * @param sText The error message text + */ +void CscopeFrontend::parseStderr(const QString& sText) +{ + // Wait for a complete line to arrive + m_sErrMsg += sText; + if (!sText.endsWith("\n")) + return; + + // Display the error message + emit error(m_sErrMsg); + + // Line displayed, reset the text accumulator + m_sErrMsg = ""; +} + +/** + * Called when the underlying process exits. + * Checks if the rebuild flag was raised, and if so restarts the building + * process. + */ +void CscopeFrontend::finalize() +{ + // Reset the parser state machine + m_state = Unknown; + + // Restart the building process, if required + if (m_bRebuildOnExit) { + m_bRebuildOnExit = false; + rebuild(); + } +} + +/** + * Class constructor. + * @param pMainWidget The parent widget to use for the progress bar and + * label + */ +CscopeProgress::CscopeProgress(QWidget* pMainWidget) : QObject(), + m_pMainWidget(pMainWidget), + m_pProgressBar(NULL), + m_pLabel(NULL) +{ +} + +/** + * Class destructor. + */ +CscopeProgress::~CscopeProgress() +{ +} + +/** + * Displays query progress information. + * If the progress value is below the expected final value, a progress bar is + * used to show the advance of the query process. Otherwise, a label is + * displayed asking the user to wait ahile the query output is processed. + * @param nProgress The current progress value + * @param nTotal The expected final value + */ +void CscopeProgress::setProgress(int nProgress, int nTotal) +{ + // Was the final value is reached? + if (nProgress == nTotal) { + // Destroy the progress bar + if (m_pProgressBar != NULL) { + delete m_pProgressBar; + m_pProgressBar = NULL; + } + + // Show the "Please wait..." label + if (m_pLabel == NULL) { + m_pLabel = new QLabel(i18n("Processing query results, " + "please wait..."), m_pMainWidget); + m_pLabel->setFrameStyle(QFrame::Box | QFrame::Plain); + m_pLabel->setLineWidth(1); + m_pLabel->adjustSize(); + + m_pLabel->setPaletteBackgroundColor( + KGlobalSettings::highlightColor()); + m_pLabel->setPaletteForegroundColor( + KGlobalSettings::highlightedTextColor()); + + QTimer::singleShot(1000, this, SLOT(slotShowLabel())); + } + + return; + } + + // Create the progress bar, if it does not exist. + // Note that the progress bar will only be displayed one second after the + // first progress signal is received. Thus the bar will not be displayed + // on very short queries. + if (m_pProgressBar == NULL) { + m_pProgressBar = new QProgressBar(m_pMainWidget); + QTimer::singleShot(1000, this, SLOT(slotShowProgressBar())); + } + + // Set the current progress value + m_pProgressBar->setProgress(nProgress, nTotal); +} + +/** + * detsroys any progress widgets when the process is terminated. + */ +void CscopeProgress::finished() +{ + // Destroy the progress bar + if (m_pProgressBar != NULL) { + delete m_pProgressBar; + m_pProgressBar = NULL; + } + + // Destroy the label + if (m_pLabel != NULL) { + delete m_pLabel; + m_pLabel = NULL; + } +} + +/** + * Shows the progress bar. + * This slot is connected to a timer activated when the first progress signal + * is received. + */ +void CscopeProgress::slotShowProgressBar() +{ + if (m_pProgressBar != NULL) + m_pProgressBar->show(); +} + +/** + * Shows the "Please wait...". + * This slot is connected to a timer activated when the progress bar + * reaches its final value. + */ +void CscopeProgress::slotShowLabel() +{ + if (m_pLabel != NULL) + m_pLabel->show(); +} + +void CscopeVerifier::verify() +{ + ConfigFrontend* pConf; + + pConf = new ConfigFrontend(true); + connect(pConf, SIGNAL(result(uint, const QString&)), this, + SLOT(slotConfigResult(uint, const QString&))); + connect(pConf, SIGNAL(finished(uint)), this, SLOT(slotFinished())); + + pConf->run(Config().getCscopePath(), "", "", true); +} + +void CscopeVerifier::slotConfigResult(uint nType, const QString& sResult) +{ + switch (nType) { + case ConfigFrontend::CscopeVerbose: + if (sResult == "Yes") + m_nArgs |= CscopeFrontend::VerboseOut; + break; + + case ConfigFrontend::CscopeSlowPath: + if (sResult == "Yes") + m_nArgs |= CscopeFrontend::SlowPathDef; + + // If we got this far, then Cscope is configured properly + m_bResult = true; + break; + } +} + +void CscopeVerifier::slotFinished() +{ + emit done(m_bResult, m_nArgs); + delete this; +} + +#include "cscopefrontend.moc" diff --git a/src/cscopefrontend.h b/src/cscopefrontend.h new file mode 100644 index 0000000..2b2c569 --- /dev/null +++ b/src/cscopefrontend.h @@ -0,0 +1,186 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CSCOPEFRONTEND_H +#define CSCOPEFRONTEND_H + +#include +#include +#include +#include "frontend.h" + +#define CSCOPE_RECORD_SIZE 4 + +/** + * Controls a Cscope process for the current project. + * This class creates a Cscope process, using the project's files for + * configuration. Once the process is running, KScope uses the query() method + * to initiate Cscope queries on the project's files. The queries' output is + * parsed into a set of records, each consisting of the following fields: + * - File name + * - Function name + * - Line number + * - The line's text + * These records are used to display the output in different windows, such as + * QueryWidget and CallTreeDlg. + * @author Elad Lahav + */ + +class CscopeFrontend : public Frontend +{ + Q_OBJECT + +public: + CscopeFrontend(bool bAutoDelete = false); + ~CscopeFrontend(); + + /** + * The available Cscope query types. + */ + enum QueryType { Reference = 0, Definition = 1, Called = 2, Calling = 3, + Text = 4, Pattern = 6, FileName = 7, Including = 8, None = 9 }; + + /** + * Options for running Cscope, used to construct the command line. + * Some of these options are global, while some are project specific. + */ + enum Options { VerboseOut = 0x01, SlowPathDef = 0x02, + Kernel = 0x04, InvIndex = 0x08, NoCompression = 0x10 }; + + void query(uint, const QString&, bool bCase = true, uint nMaxRecords = 0); + void rebuild(); + + static void init(const QString&, uint); + + /** + * @param nArgs The command-line arguments supported by the version of + * Cscope currently in use + */ + static void setSupArgs(uint nArgs) { s_nSupArgs = nArgs; } + +public slots: + void slotCancel(); + +signals: + /** + * Emitted when Cscope starts building the inverted index. + */ + void buildInvIndex(); + +protected: + virtual ParseResult parseStdout(QString&, ParserDelim); + virtual void parseStderr(const QString&); + virtual void finalize(); + +private: + /** + * The possible states of the parser state machine. + */ + enum ParserState { Unknown = 0, BuildStart, BuildSymbol, Building, + SearchSymbol, Searching, SearchEnd, File, Func, Line, LineText }; + + /** The current state of the parser state machine. */ + ParserState m_state; + + /** Accumulates text sent by Cscope to the standard error stream. */ + QString m_sErrMsg; + + /** If true, the rebuild process will be restarted when the process + exits. */ + bool m_bRebuildOnExit; + + /** The maximal number of records requested for the current query. + The process aborts if this number if reached. */ + int m_nMaxRecords; + + /** The full path of the directory holding the project files. */ + static QString s_sProjPath; + + /** Project-specific options for the command-line arguments. */ + static uint s_nProjArgs; + + /** The command line arguments supported by this version of Cscope. */ + static uint s_nSupArgs; + + bool run(const QStringList&); +}; + +/** + * Provides progress information on a Cscope query. + * Classes used to display query results can use this class to show a + * progress bar while a query is running, and a "Please Wait..." label while + * output is being processed. + * @author Elad Lahav + */ +class CscopeProgress : public QObject +{ + Q_OBJECT + +public: + CscopeProgress(QWidget*); + ~CscopeProgress(); + + void setProgress(int, int); + void finished(); + +private: + /** The parent widget for the progress bar and label. */ + QWidget* m_pMainWidget; + + /** A bar used to display query progress information. */ + QProgressBar* m_pProgressBar; + + /** A label used to display a "Please wait..." message. */ + QLabel* m_pLabel; + +private slots: + void slotShowProgressBar(); + void slotShowLabel(); +}; + +class CscopeVerifier : public QObject +{ + Q_OBJECT + +public: + CscopeVerifier() : m_bResult(false), m_nArgs(0) {} + + void verify(); + +signals: + void done(bool, uint); + +private: + bool m_bResult; + uint m_nArgs; + +private slots: + void slotConfigResult(uint, const QString&); + void slotFinished(); +}; + +#endif diff --git a/src/cscopemsgdlg.cpp b/src/cscopemsgdlg.cpp new file mode 100644 index 0000000..1bf6656 --- /dev/null +++ b/src/cscopemsgdlg.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "cscopemsgdlg.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +CscopeMsgDlg::CscopeMsgDlg(QWidget* pParent, const char* szName) + : CscopeMsgLayout(pParent, szName, false, 0) +{ + // Hide the dialog when the "Hide" button is clicked + connect(m_pHideButton, SIGNAL(clicked()), this, SLOT(hide())); + + // Clear all messages when the "Clear" button is clicked + connect(m_pClearButton, SIGNAL(clicked()), m_pMsgText, SLOT(clear())); +} + +/** + * Class destructor. + */ +CscopeMsgDlg::~CscopeMsgDlg() +{ +} + +/** + * Appends a given message to the text box. + * After a new messsage is added, the dialog becomes visible. + * @param sText The text of the message to add + */ +void CscopeMsgDlg::addText(const QString& sText) +{ + m_pMsgText->append(sText); + show(); +} + +#include "cscopemsgdlg.moc" + diff --git a/src/cscopemsgdlg.h b/src/cscopemsgdlg.h new file mode 100644 index 0000000..0cd45cd --- /dev/null +++ b/src/cscopemsgdlg.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CSCOPEMSGDLG_H +#define CSCOPEMSGDLG_H + +#include "cscopemsglayout.h" + +/** + * Displays messages sent by Cscope to its standard error stream. + * @author Elad Lahav + */ +class CscopeMsgDlg : public CscopeMsgLayout +{ + Q_OBJECT + +public: + CscopeMsgDlg(QWidget* pParent = 0, const char* szName = 0); + ~CscopeMsgDlg(); + + void addText(const QString&); +}; + +#endif + diff --git a/src/cscopemsglayout.ui b/src/cscopemsglayout.ui new file mode 100644 index 0000000..1a6458d --- /dev/null +++ b/src/cscopemsglayout.ui @@ -0,0 +1,79 @@ + +CscopeMsgLayout + + + CscopeMsgLayout + + + + 0 + 0 + 600 + 451 + + + + Cscope Error Messages + + + + unnamed + + + + m_pMsgText + + + PlainText + + + true + + + + + layout1 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Expanding + + + + 321 + 31 + + + + + + m_pClearButton + + + Clear + + + + + m_pHideButton + + + Hide + + + + + + + + diff --git a/src/ctagsfrontend.cpp b/src/ctagsfrontend.cpp new file mode 100644 index 0000000..73f7519 --- /dev/null +++ b/src/ctagsfrontend.cpp @@ -0,0 +1,179 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "ctagsfrontend.h" +#include "kscopeconfig.h" + +QStringList CtagsFrontend::s_slExtraArgs; + +/** + * Class constructor. + */ +CtagsFrontend::CtagsFrontend() : Frontend(CTAGS_RECORD_SIZE) +{ +} + +/** + * Class destructor. + */ +CtagsFrontend::~CtagsFrontend() +{ +} + +/** + * Executes a Ctags process on a source file. + * @param sFileName The full path to the source file + * @return true if successful, false otherwise + */ +bool CtagsFrontend::run(const QString& sFileName) +{ + QString sPath; + QStringList slArgs; + + // Make sure the executable exists + sPath = Config().getCtagsPath(); + + // Set the command line arguments + slArgs.append(sPath); + slArgs.append("--excmd=n"); + slArgs.append("-u"); // don't sort + slArgs.append("-f"); + slArgs.append("-"); + + // Per-project command-line arguments + slArgs += s_slExtraArgs; + + slArgs.append(sFileName); + + // Run a new process + if (!Frontend::run("ctags", slArgs)) + return false; + + // Initialize stdout parsing + m_state = Name; + m_delim = Tab; + + return true; +} + +/** + * Tests that the given file path leads to an executable. + * @param sPath The path to check + * @return true if the file in the given path exists and has executable + * permissions, false otherwise + */ +bool CtagsFrontend::verify(const QString& sPath) +{ + QFileInfo fi(sPath); + + if (!fi.exists() || !fi.isFile() || !fi.isExecutable() || + fi.fileName().find("ctags", 0, false) == -1) { + KMessageBox::error(0, i18n("Ctags cannot be found in the given " + "path")); + return false; + } + + return true; +} + +/** + * Turns the per-project string of additional arguments into a list of + * command-line arguments. + * @param sArgs The per-project command string + */ +void CtagsFrontend::setExtraArgs(const QString& sArgs) +{ + s_slExtraArgs = KShell::splitArgs(sArgs); +} + +/** + * Parses the output of a Ctags process. + * @param sToken The current token read (the token delimiter is determined + * by the current state) + * @param delim The delimiter that ends this token + * @return A value indicating the way this token should be treated: dropped, + * added to the token queue, or finishes a new record + */ +Frontend::ParseResult CtagsFrontend::parseStdout(QString& sToken, + ParserDelim delim) +{ + ParseResult result = DiscardToken; + + // Handle the token according to the current state + switch (m_state) { + case Name: + if (sToken.left(6) == "ctags:") { + m_state = Other; + m_delim = Newline; + break; + } + + m_state = File; + result = AcceptToken; + break; + + case File: + m_state = Line; + result = DiscardToken; + break; + + case Line: + sToken = sToken.left(sToken.length() - 2); + m_state = Type; + m_delim = All; + result = AcceptToken; + break; + + case Type: + if (delim == Newline) { + m_state = Name; + m_delim = Tab; + } + else { + m_state = Other; + m_delim = Newline; + } + + result = RecordReady; + break; + + case Other: + m_state = Name; + m_delim = Tab; + result = DiscardToken; + break; + + } + + return result; +} + +#include "ctagsfrontend.moc" diff --git a/src/ctagsfrontend.h b/src/ctagsfrontend.h new file mode 100644 index 0000000..3c0c452 --- /dev/null +++ b/src/ctagsfrontend.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CTAGSFRONTEND_H +#define CTAGSFRONTEND_H + +#include + +#define CTAGS_RECORD_SIZE 3 + +/** + * Controls a Ctags process for an file in an EditorPage window. + * A new Ctags process is run each time the file in the editor window is + * loaded (including the initial load, and any subsequent ones which follow a + * 'save' operation.) + * The output of the process is parsed into a set of records, each composed of + * the following fields: + * - Tag type + * - Tag name + * - Line number + * The records are then displayed in the CtagsList widget that is attached to + * each EditorPage window. + * @author Elad Lahav + */ + +class CtagsFrontend : public Frontend +{ + Q_OBJECT + +public: + CtagsFrontend(); + ~CtagsFrontend(); + + bool run(const QString&); + + static bool verify(const QString&); + static void setExtraArgs(const QString&); + +protected: + virtual ParseResult parseStdout(QString&, ParserDelim); + +private: + /** State values for the parser state machine. */ + enum ParserState { Name = 0, File, Line, Type, Other }; + + /** The current state of the parser state machine. */ + ParserState m_state; + + /** Additional ommand-line arguments (per-project). */ + static QStringList s_slExtraArgs; +}; + +#endif diff --git a/src/ctagslist.cpp b/src/ctagslist.cpp new file mode 100644 index 0000000..687e9fb --- /dev/null +++ b/src/ctagslist.cpp @@ -0,0 +1,446 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "ctagslist.h" +#include "kscopeconfig.h" +#include "kscopepixmaps.h" + +/** + * Defines a special list item for the tag list. + * This special definition allows the tag list to be sorted according to + * symbol line numbers. By default, all items are treated as text, hence the + * comparison of line numbers such as "123" and "24" sets "24" to be the + * larger item. By overriding the comparison function, this class allows for + * correct sorting. + * @author Elad Lahav + */ +class CtagsListItem : public QListViewItem +{ +public: + /** + * Class constructor. + * @param pParent The owning list view widget + * @param sName The name of the tag + * @param sLine The line in which the tag is defined + * @param sType The type of the tag + */ + CtagsListItem(QListView* pParent, QString sName, QString sLine, + QString sType) : QListViewItem(pParent, sName, sLine, sType), + m_nPendLine (sLine.toUInt()) {} + + /** + * Compares two tag list items, and determines their order. + * If comparison is based on a text-column, the default behaviour is + * used. Otherwise, the text is converted to unsigned integers, and then + * compared as numbers. + * @param pItem The item to compare against the local object + * @param nCol The column index by which to compare + * @param bAscend true if sorting in ascending order, false otherwise + * @return 0 if the items are equal, 1 if the local item is greater, -1 + * if the local item is lesser + */ + virtual int compare(QListViewItem* pItem, int nCol, bool bAscend) const { + if (nCol == 1) { + uint nLineCur, nLineOther; + int nResult; + + // Get the line numbers of each item + nLineCur = text(1).toUInt(); + nLineOther = pItem->text(1).toUInt(); + + // Compare the line numbers + nResult = nLineCur - nLineOther; + if (nResult == 0) + return 0; // Items are equal + else if (nResult > 0) + return 1; // The first item is greater + else + return -1; // The second item is greater + } + + // Use default comparison for text columns + return QListViewItem::compare(pItem, nCol, bAscend); + } + + /** + * @return The line number associated with this item + */ + inline uint getLine() { return m_nPendLine; } + +private: + /** The numeric value of the line number column of this item. */ + uint m_nPendLine; +}; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +CtagsList::CtagsList(QWidget* pParent, const char* szName) : + SearchList(0, pParent, szName), + m_arrLines(16), + m_nItems(0), + m_nCurItem(0), + m_bReady(false), + m_nCurLine(0), + m_nPendLine(0) +{ + m_pList->setShowSortIndicator(true); + connect(m_pList->header(), SIGNAL(clicked(int)), this, + SLOT(slotSortChanged(int))); + + // Determine the default sorting order + switch (Config().getCtagSortOrder()) { + case KScopeConfig::NameAsc: + m_pList->setSorting(0, true); + break; + + case KScopeConfig::NameDes: + m_pList->setSorting(0, false); + break; + + case KScopeConfig::LineAsc: + m_pList->setSorting(1, true); + break; + + case KScopeConfig::LineDes: + m_pList->setSorting(1, false); + break; + + case KScopeConfig::TypeAsc: + m_pList->setSorting(2, true); + break; + + case KScopeConfig::TypeDes: + m_pList->setSorting(2, false); + break; + } + + // Add the list columns + m_pList->addColumn(i18n("Name")); + m_pList->addColumn(i18n("Line")); + m_pList->addColumn(i18n("Type")); + m_pList->setColumnAlignment(1, Qt::AlignRight); + + // Set colours and font + applyPrefs(); +} + +/** + * Class destructor. + */ +CtagsList::~CtagsList() +{ +} + +/** + * Adds a Ctags output entry to the list. + * This slot is connected to the dataReady() signal of a CtagsFrontend object. + * @param pToken The first token in the entry + */ +void CtagsList::slotDataReady(FrontendToken* pToken) +{ + QString sName, sType, sLine; + CtagsListItem* pItem; + KScopePixmaps::PixName pix; + + // Get the name of the symbol + sName = pToken->getData(); + pToken = pToken->getNext(); + + // Get the line number + sLine = pToken->getData(); + pToken = pToken->getNext(); + + // Get the type of the symbol + sType = pToken->getData(); + pToken = pToken->getNext(); + + // Set the appropriate pixmap + switch (sType[0].latin1()) { + case 'f': + sType = i18n("Function"); + pix = KScopePixmaps::SymFunc; + break; + + case 'v': + sType = i18n("Variable"); + pix = KScopePixmaps::SymVar; + break; + + case 's': + sType = i18n("Struct"); + pix = KScopePixmaps::SymStruct; + break; + + case 'd': + sType = i18n("Macro"); + pix = KScopePixmaps::SymMacro; + break; + + case 'm': + sType = i18n("Member"); + pix = KScopePixmaps::SymMember; + break; + + case 'g': + sType = i18n("Enum"); + pix = KScopePixmaps::SymEnum; + break; + + case 'e': + sType = i18n("Enumerator"); + pix = KScopePixmaps::SymEnumerator; + break; + + case 't': + sType = i18n("Typedef"); + pix = KScopePixmaps::SymTypedef; + break; + + case 'l': + sType = i18n("Label"); + pix = KScopePixmaps::SymLabel; + break; + + case 'i': + sType = i18n("Include"); + pix = KScopePixmaps::SymInclude; + break; + + default: + sType = "Unknown"; + pix = KScopePixmaps::SymUnknown; + } + + // Add a new item to the list + pItem = new CtagsListItem(m_pList, sName, sLine, sType); + pItem->setPixmap(0, Pixmaps().getPixmap(pix)); + m_nItems++; + + // Resize the line array, if required + if (m_arrLines.size() < m_nItems) + m_arrLines.resize(m_nItems, QGArray::SpeedOptim); + + // Add the new item to the line array + m_arrLines[m_nItems - 1] = pItem; +} + +/** + * Handles the "resize" event, which occurs when the size of the widget + * changes. + * @param pEvent The event data + */ +void CtagsList::resizeEvent(QResizeEvent* pEvent) +{ + SearchList::resizeEvent(pEvent); + emit resized(); +} + +/** + * Emits the lineRequested() signal when a list item is selected. + * This function is called if either an item is double-clicked, or an item is + * highlighted and the ENTER key is pressed. + * @param pItem The selected list item + */ +void CtagsList::processItemSelected(QListViewItem* pItem) +{ + QString sLine; + + sLine = pItem->text(1); + emit lineRequested(sLine.toUInt()); +} + +/** + * Constructs a tool-tip for the given item. + * @param pItem The item for which a tip is required + * @param sTip The constructed tip string (on return) + * @return Always true + */ +bool CtagsList::getTip(QListViewItem* pItem, QString& sTip) +{ + sTip = QString("Type: %1
    Name: %2
    Line: %3"). + arg(pItem->text(2)).arg(pItem->text(0)).arg(pItem->text(1)); + return true; +} + +/** + * Sets the list's colours and font, according the user's preferences. + */ +void CtagsList::applyPrefs() +{ + // Apply colour settings + m_pList->setPaletteBackgroundColor(Config().getColor( + KScopeConfig::TagListBack)); + m_pList->setPaletteForegroundColor(Config().getColor( + KScopeConfig::TagListFore)); + m_pList->setFont(Config().getFont(KScopeConfig::TagList)); +} + +/** + * Selects the symbol that dominates the given line in the source file. + * @param nLine The requested line + */ +void CtagsList::gotoLine(uint nLine) +{ + CtagsListItem* pItem; + int nFrom, nTo, nItem, nDiff; + + // Wait until Ctags finishes + if (!m_bReady) { + m_nPendLine = nLine; + return; + } + + // Do nothing if no tags are available + if (m_nItems == 0) + return; + + // Calculate the difference from the current line + nDiff = (int)(nLine - m_nCurLine); + m_nCurLine = nLine; + + // In most cases, all the user does is move to the next or prevuious lines + // Handle these simple cases first + if (nDiff == 1) { + if ((m_nCurItem < m_nItems - 1) && + (m_arrLines[m_nCurItem + 1]->getLine() == nLine)) { + m_nCurItem++; + } + else { + return; // New line corresponds to the same tag + } + } + else if (nDiff == -1) { + if ((m_nCurItem > 0) && + (m_arrLines[m_nCurItem]->getLine() > nLine)) { + m_nCurItem--; + } + else { + return; // New line corresponds to the same tag + } + } + else { + // Initialise binary search + nFrom = 0; + nTo = m_nItems - 1; + m_nCurItem = 0; // use the first item if nothing else works + + // Perform a binary search + // This algorithm finds the greatest line that is smaller or equal to + // the requested line + do { + nItem = (nFrom + nTo) / 2; + pItem = m_arrLines[nItem]; + + if (pItem->getLine() == nLine) { + m_nCurItem = nItem; + break; + } + else if (nLine > pItem->getLine()) { + m_nCurItem = nItem; + nFrom = nItem + 1; + } + else { + nTo = nItem - 1; + } + } while (nFrom <= nTo); + } + + // Mark the selected item + pItem = m_arrLines[m_nCurItem]; + m_pList->setSelected(pItem, true); + m_pList->ensureItemVisible(pItem); + + m_nPendLine = 0; +} + +/** + * Deletes all items in the list. + */ +void CtagsList::clear() +{ + m_pList->clear(); + m_nItems = 0; + m_nCurItem = 0; + m_nCurLine = 0; + m_nPendLine = 0; + m_bReady = false; +} + +/** + * Indicates Ctags has finished processing the current file. + * If a goto operation has been scheduled, it is processed. + * @param nRecords The number of records generated by Ctags + */ +void CtagsList::slotCtagsFinished(uint nRecords) +{ + if (nRecords) { + m_bReady = true; + if (m_nPendLine) + gotoLine(m_nPendLine); + } +} + +/** + * Determines the new sort order in the tags list. + * This slot is connected to the clicked() signal of the tag list's header. + * @param nSection Identifies the column whose header button was clicked. + */ +void CtagsList::slotSortChanged(int nSection) +{ + Qt::SortOrder order; + + // Determine whether the new order is ascending or descending + order = m_pList->sortOrder(); + + // Translate the section number into the order constant + switch (nSection) { + case 0: + // Sort by name + Config().setCtagSortOrder(order == Qt::Ascending ? + KScopeConfig::NameAsc : KScopeConfig::NameDes); + break; + + case 1: + // Sort by line + Config().setCtagSortOrder(order == Qt::Ascending ? + KScopeConfig::LineAsc : KScopeConfig::LineDes); + break; + + case 2: + // Sort by type + Config().setCtagSortOrder(order == Qt::Ascending ? + KScopeConfig::TypeAsc : KScopeConfig::TypeDes); + break; + } +} + +#include "ctagslist.moc" diff --git a/src/ctagslist.h b/src/ctagslist.h new file mode 100644 index 0000000..4d318cc --- /dev/null +++ b/src/ctagslist.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef CTAGSLIST_H +#define CTAGSLIST_H + +#include +#include +#include +#include "searchlist.h" +#include "frontend.h" + +class CtagsListItem; +class CtagsToolTip; + +/** + * Displays a list of tags for a source file. + * The list is embedded inside an editor page. Whenever a new document is + * opened in that editor, or the current document is changed and saved, the + * source file is re-scanned for tags, and the results are displayed in this + * list. + * @author Elad Lahav + */ + +class CtagsList : public SearchList +{ + Q_OBJECT + +public: + CtagsList(QWidget* pParent = 0, const char* szName = 0); + ~CtagsList(); + + void applyPrefs(); + void gotoLine(uint); + void clear(); + + virtual bool getTip(QListViewItem*, QString&); + +public slots: + void slotDataReady(FrontendToken*); + void slotCtagsFinished(uint); + +signals: + /** + * Emitted when the size of the list is changed (usually as the result + * of moving the separator between the list and the editor.) + */ + void resized(); + + /** + * Emitted when the user selects a tag item from the list. + * @param nLine The line number associated with the selected tag + */ + void lineRequested(uint nLine); + +protected: + virtual void resizeEvent(QResizeEvent*); + virtual void processItemSelected(QListViewItem*); + +private: + /** An array of pointers to the tag list items, sorted by the line + number. */ + QMemArray m_arrLines; + + /** The number of items in the tag list. */ + uint m_nItems; + + /** The last item selected by gotoLine(). */ + uint m_nCurItem; + + /** This value is set to 'false' while the Ctags process is running. */ + bool m_bReady; + + /** The current line number. */ + uint m_nCurLine; + + /** Stores the requested line number during Ctags operation. */ + uint m_nPendLine; + +private slots: + void slotSortChanged(int); +}; + +#endif diff --git a/src/dirscanner.cpp b/src/dirscanner.cpp new file mode 100644 index 0000000..517237e --- /dev/null +++ b/src/dirscanner.cpp @@ -0,0 +1,164 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "dirscanner.h" + +/** + * Class constructor. + * @param nFiles The number of files scanned since the previous event + * @param bFinished true if all files were scanned, false otherwise + */ +DirScanEvent::DirScanEvent(int nFiles, bool bFinished) + : QCustomEvent(EventId), + m_nFiles(nFiles), + m_bFinished(bFinished) +{ +} + +/** + * Class constructor. + * @param pEventReceiver Pointer to an object to receive DirScanEvent + * updates + * @param pDicFiles Pointer to a map of current project files (to + avoid duplication) + */ +DirScanner::DirScanner(QObject* pEventReceiver, + QDict* pDicFiles) : QThread(), + m_pEventReceiver(pEventReceiver), + m_pDicFiles(pDicFiles) +{ +} + +/** + * Class destructor. + */ +DirScanner::~DirScanner() +{ +} + +/** + * Begins a new search for source files. + * Invokes the search thread on a given directory. The search may be either + * recursive (i.e., the search will descend to each sub-directory) or flat + * (will search the given directory only.) + * @param sDir The name of the directory to search + * @param sNameFilter Defines the search pattern + * @param bRecursive true to descend into sub-dorectories, false otherwise + */ +void DirScanner::start(const QString& sDir, const QString& sNameFilter, + bool bRecursive) +{ + // Initialise the search parameters + m_dir = QDir(sDir); + m_sNameFilter = sNameFilter; + m_bCancel = false; + m_bRecursive = bRecursive; + m_slFiles.clear(); + + // Invoke the thread + QThread::start(); +} + +/** + * Begins a scan of files on the directory associated with this object. + * Note that this function is synchronous: it returns when the scan ends. + */ +void DirScanner::run() +{ + int nFiles; + + nFiles = scanDir(m_dir); + QApplication::postEvent(m_pEventReceiver, + new DirScanEvent(nFiles, true)); + + m_setScanned.clear(); +} + +/** + * Recursively scans a directory for a files matching the current filter. + * @param dir A directory object set to the folder from which files are + * added + * @return The total number of files added + */ +int DirScanner::scanDir(QDir& dir) +{ + QString sCanon; + QStringList slDirFiles, slDirs; + QStringList::const_iterator itr; + QString sFile; + int nFiles = 0; + + if (m_bCancel) + return -1; + + // Make sure this directory has not been previously visited (e.g., through a + // symbolic link) + sCanon = dir.canonicalPath(); + if (m_setScanned.exists(sCanon)) + return 0; + + m_setScanned.insert(sCanon); + + // Add all files in this directory + slDirFiles = dir.entryList(m_sNameFilter, QDir::Files); + for (itr = slDirFiles.begin(); itr != slDirFiles.end(); ++itr) { + sFile = dir.absPath() + "/" + *itr; + + // Make sure an entry for this file does not exist + if (m_pDicFiles->find(sFile) == NULL) { + m_slFiles.append(sFile); + nFiles++; + } + } + + QApplication::postEvent(m_pEventReceiver, + new DirScanEvent(nFiles, false)); + + // Recurse into sub-directories, if requested + if (!m_bRecursive) + return nFiles; + + slDirs = dir.entryList(QDir::Dirs); + + // Iterate the list of sub-directories + for (itr = slDirs.begin(); itr != slDirs.end(); ++itr) { + if (m_bCancel) + return -1; + + // Skip the "." and ".." directories + if (*itr == "." || *itr == "..") + continue; + + // Add the files in each sub-directory + QDir dirSub(dir); + if (dirSub.cd(*itr)) + nFiles += scanDir(dirSub); + } + + return nFiles; +} diff --git a/src/dirscanner.h b/src/dirscanner.h new file mode 100644 index 0000000..b25fc2d --- /dev/null +++ b/src/dirscanner.h @@ -0,0 +1,144 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef DIRSCANNER_H +#define DIRSCANNER_H + +#include +#include +#include +#include +#include +#include +#include + +class DirScanner; + +/** + * Defines a new event that can be used to pass progress information from the + * dir scanning thread to the main application thread. + * @author Elad Lahav + */ +class DirScanEvent : public QCustomEvent +{ +public: + /** The event's unique ID. */ + enum { EventId = 6924 }; + + DirScanEvent(int, bool); + + /** The number of files already scanned. */ + int m_nFiles; + + /** True if the dir scanning thread has finished, false otherwise. */ + bool m_bFinished; +}; + +/** + * A set of unique strings. + * Qt3 does not have a set class, so this is a simple implementation based on + * a QDict of dummy int pointers. + * @author Elad Lahav + */ +class StringSet : public QDict +{ +public: + StringSet() : QDict() {} + + void insert(const QString& sItem) { + static int nDummy = 0; + QDict::insert(sItem, &nDummy); + } + + bool exists(const QString& sItem) { + return find(sItem) != NULL; + } +}; + +/** + * Scans a directory for files matching a given pattern, using a separate thread. + * @author Elad Lahav + */ +class DirScanner : public QThread +{ +public: + DirScanner(QObject*, QDict*); + ~DirScanner(); + + void start(const QString&, const QString&, bool); + + /** + * @return The list of files scanned by this thread. + */ + const QStringList& getFiles() { return m_slFiles; } + + /** + * Stops a scanning process, by setting the object's cancel flag. + */ + void cancel() { m_bCancel = true; } + + /** + * @return true if the user has cancelled the process, false otherwise + */ + bool wasCancelled() { return m_bCancel; } + +protected: + virtual void run(); + +private: + /** Pointer to an object that receives the scanner update events. */ + QObject* m_pEventReceiver; + + /** Currently scanned directory. */ + QDir m_dir; + + /** + * A set of already-scanned directories (prevents infinite loops in case + * of cyclic symbolic links in the scanned file system). + */ + StringSet m_setScanned; + + /** Pointer to a list of files indexed by the file path (used to identify + files that should not appear in the scan results.) */ + QDict* m_pDicFiles; + + /** Regular expression for scanning source files. */ + QString m_sNameFilter; + + /** The list of scanned file paths. */ + QStringList m_slFiles; + + /** A cancellation flag. Stops the scanning process when raised. */ + bool m_bCancel; + + /** true to descend to child directories, false otherwise. */ + bool m_bRecursive; + + int scanDir(QDir&); +}; + +#endif diff --git a/src/dotfrontend.cpp b/src/dotfrontend.cpp new file mode 100644 index 0000000..e0cfbed --- /dev/null +++ b/src/dotfrontend.cpp @@ -0,0 +1,297 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sf.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "dotfrontend.h" +#include "graphwidget.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pGraph The graph widget on which to draw the output + */ +DotFrontend::DotFrontend(GraphWidget* pGraph) : Frontend(1), + m_pGraph(pGraph) +{ +} + +/** + * Class destructor. + */ +DotFrontend::~DotFrontend() +{ +} + +/** + * Executes dot on the goven input file. + * @param sFile The path to a temporary file holding the graph's + * description + * @return true if successful, false otherwise + */ +bool DotFrontend::run(const QString& sFile) +{ + QString sPath; + QStringList slArgs; + QPaintDeviceMetrics pdm(m_pGraph); + + // Set the horizontal and vertical DPI values + m_dDpiX = (double)pdm.logicalDpiX(); + m_dDpiY = (double)pdm.logicalDpiY(); + + // Make sure the executable exists + sPath = Config().getDotPath(); + + // Set the command line arguments + slArgs.append(sPath); + slArgs.append("-Tplain"); + slArgs.append(sFile); + + // Run a new process + if (!Frontend::run("dot", slArgs)) + return false; + + // Initialize stdout parsing + m_state = Graph; + m_delim = All; + + return true; +} + +/** + * Tests that the given file path leads to an executable. + * @param sPath The path to check + * @return true if the file in the given path exists and has executable + * permissions, false otherwise + */ +bool DotFrontend::verify(const QString& sPath) +{ + QFileInfo fi(sPath); + + if (!fi.exists() || !fi.isFile() || !fi.isExecutable() || + fi.fileName() != "dot") { + KMessageBox::error(0, i18n("Dot cannot be found in the given " + "path")); + return false; + } + + return true; +} + +#define PAD 5 + +/** + * Parses the output of a Dot process. + * @param sToken The current token read (the token delimiter is determined + * by the current state) + * @param delim The delimiter that ends this token + * @return A value indicating the way this token should be treated: dropped, + * added to the token queue, or finishes a new record + */ +Frontend::ParseResult DotFrontend::parseStdout(QString& sToken, + ParserDelim delim) +{ + static int nWidth, nHeight, nXpos, nYpos, nCurveSize, nCurveCount; + static QPointArray arrCurve; + static QString sNode, sEdgeHead, sEdgeTail; + ParseResult result = DiscardToken; + double dVal; + bool bOK; + + // Handle the token according to the current state + switch (m_state) { + case Graph: + if (sToken == "graph") + m_state = GraphScale; + break; + + case GraphScale: + sToken.toDouble(&bOK); + if (bOK) + m_state = GraphWidth; + break; + + case GraphWidth: + // Read and transform the graph's width + dVal = sToken.toDouble(&bOK); + if (bOK) { + nWidth = (int)(dVal * m_dDpiX) + (PAD * 2); + m_state = GraphHeight; + } + break; + + case GraphHeight: + // Read and transform the graph's height + dVal = sToken.toDouble(&bOK); + if (bOK) { + nHeight = (int)(dVal * m_dDpiY) + (PAD * 2); + + // Set the graph's size + m_pGraph->resize(nWidth, nHeight); + + m_state = NodeEdgeStop; + } + break; + + case NodeEdgeStop: + // "node" starts a new node + // "edge" starts a new edge + // "stop" ends this graph + if (sToken == "node") { + m_state = NodeName; + } + else if (sToken == "edge") { + m_state = EdgeHead; + } + else if (sToken == "stop") { + m_state = Graph; + } + break; + + case NodeName: + // Get a node's name + sNode = sToken; + m_state = NodeCentreX; + break; + + case NodeCentreX: + // Read and transform the node's centre location (X coordinate) + dVal = sToken.toDouble(&bOK); + if (bOK) { + nXpos = (int)(dVal * m_dDpiX) + PAD; + m_state = NodeCentreY; + } + break; + + case NodeCentreY: + // Read and transform the node's centre location (Y coordinate) + dVal = sToken.toDouble(&bOK); + if (bOK) { + nYpos = (int)(dVal * m_dDpiY) + PAD; + m_state = NodeWidth; + } + break; + + case NodeWidth: + // Read and transform the node's width + dVal = sToken.toDouble(&bOK); + if (bOK) { + nWidth = (int)(dVal * m_dDpiX); + m_state = NodeHeight; + } + break; + + case NodeHeight: + // Read and transform the node's height + dVal = sToken.toDouble(&bOK); + if (bOK) { + nHeight = (int)(dVal * m_dDpiY); + + // Create the bounding rectangle of the node + QRect rect; + rect.setX(nXpos - (nWidth / 2)); + rect.setY(nYpos - (nHeight / 2)); + rect.setWidth(nWidth); + rect.setHeight(nHeight); + + // Draw the node + m_pGraph->drawNode(sNode, rect); + + m_state = EndNodeEdge; + } + break; + + case EdgeHead: + // Get the edge's head node + sEdgeHead = sToken; + m_state = EdgeTail; + break; + + case EdgeTail: + // Get the edge's tail node + sEdgeTail = sToken; + m_state = EdgeCurveSize; + break; + + case EdgeCurveSize: + // Get the number of control points in the edge's spline + nCurveSize = sToken.toInt(&bOK); + if (bOK) { + arrCurve.resize(nCurveSize); + nCurveCount = 0; + m_state = EdgeCurveX; + } + break; + + case EdgeCurveX: + // Read and a control point (X coordinate) + dVal = sToken.toDouble(&bOK); + if (bOK) { + nXpos = (int)(dVal * m_dDpiX) + PAD; + m_state = EdgeCurveY; + } + break; + + case EdgeCurveY: + // Read and a control point (Y coordinate) + dVal = sToken.toDouble(&bOK); + if (bOK) { + nYpos = (int)(dVal * m_dDpiY) + PAD; + + // Add the control point to the spline array + arrCurve.setPoint(nCurveCount++, nXpos, nYpos); + + // Check if this is the last control point + if (nCurveCount == nCurveSize) { + // Draw the edge + m_pGraph->drawEdge(sEdgeHead, sEdgeTail, arrCurve); + + // Must detach from contents since a QPointArray shares data + arrCurve.detach(); + + m_state = EndNodeEdge; + } + else { + // Another control point available + m_state = EdgeCurveX; + } + } + break; + + case EndNodeEdge: + // Discard everything else on a node or edge line + if (delim == Newline) + m_state = NodeEdgeStop; + break; + } + + return result; +} + +#include "dotfrontend.moc" diff --git a/src/dotfrontend.h b/src/dotfrontend.h new file mode 100644 index 0000000..24f14f0 --- /dev/null +++ b/src/dotfrontend.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sf.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ +#ifndef DOTFRONTEND_H +#define DOTFRONTEND_H + +#include +#include + +class GraphWidget; + +/** + * Front-end for executing graphviz's command-line tool. + * This tool accepts the description of a graph in the 'dot' language, and + * outputs a set of drawing instructions for the graph. + * @author Elad Lahav + */ +class DotFrontend : public Frontend +{ + Q_OBJECT + +public: + DotFrontend(GraphWidget*); + ~DotFrontend(); + + bool run(const QString&); + + static bool verify(const QString&); + +protected: + virtual ParseResult parseStdout(QString&, ParserDelim); + +private: + /** The owner graph widget on which to draw. */ + GraphWidget* m_pGraph; + + /** State values for the parser state machine. */ + enum ParserState { Graph, GraphScale, GraphWidth, GraphHeight, + NodeEdgeStop, NodeName, NodeCentreX, NodeCentreY, NodeWidth, NodeHeight, + EdgeHead, EdgeTail, EdgeCurveSize, EdgeCurveX, EdgeCurveY, + EndNodeEdge }; + + /** The current state of the parser state machine. */ + ParserState m_state; + + /** The horizontal DPI value of the graph widget. */ + double m_dDpiX; + + /** The vertical DPI value of the graph widget. */ + double m_dDpiY; +}; + +#endif diff --git a/src/dotparse.ypp b/src/dotparse.ypp new file mode 100644 index 0000000..f21b9e3 --- /dev/null +++ b/src/dotparse.ypp @@ -0,0 +1,234 @@ +/* dot.y */ + +%{ +#include +#include +#include +#include "calltreedlg.h" +#include "graphwidget.h" +#include "treewidget.h" +#include "encoder.h" + +extern FILE* yyin; +int yylex(); +void yyinit(CallTreeDlg*, FILE*, Encoder*); +void yyerror(const char*); + +static QMap s_pMapAttr; +static QStack s_pParentStack; +static QListView* s_pTree; + +static GraphWidget* s_pGraph; +static TreeWidget* s_pCallTree; +static TreeWidget* s_pCallingTree; +static Encoder* s_pEncoder; + +// Avoid compiler warnings +#define YYENABLE_NLS 0 +#ifndef YYLTYPE_IS_TRIVIAL +#define YYLTYPE_IS_TRIVIAL 0 +#endif +%} + +%union { + QString* pText; +} + +%token GRAPH DIGRAPH NODE NAME STRING NUMBER DIR_EDGE UNDIR_EDGE +%token CALL_TREE CALLING_TREE +%type NAME STRING NUMBER attr_val + +%start file + +%% + +file + : call_tree calling_tree graph + +graph + : graph_type NAME '{' graph_desc_list '}' { delete $2; } + ; + +graph_type + : GRAPH + | DIGRAPH + ; + +graph_desc_list + : + | graph_desc_entry graph_desc_list + ; + +graph_desc_entry + : def_node_attr + | graph_attr + | node_record + | edge_record + ; + +def_node_attr + : NODE attributes ';' + ; + +graph_attr + : GRAPH attributes ';' + { + if (s_pMapAttr.find("kscope_zoom") != s_pMapAttr.end()) + s_pGraph->setZoom(s_pMapAttr["kscope_zoom"].toDouble()); + } + ; + +node_record + : NAME attributes ';' + { + s_pGraph->addNode(*$1); + delete $1; + s_pMapAttr.clear(); + } + ; + +edge_record + : NAME edge_type NAME attributes ';' + { + GraphWidget::CallData cd; + + cd.m_sCaller = *$1; + cd.m_sCallee = *$3; + cd.m_sFile = s_pMapAttr["kscope_file"]; + cd.m_sLine = s_pMapAttr["kscope_line"]; + cd.m_sText = s_pEncoder->decode(s_pMapAttr["kscope_text"]); + s_pGraph->addCall(cd); + + delete $1; + delete $3; + s_pMapAttr.clear(); + } + ; + +edge_type + : DIR_EDGE + | UNDIR_EDGE + ; + +attributes + : + | '[' attr_list ']' + ; + +attr_list + : + | non_empty_attr_list + ; + +non_empty_attr_list + : attr + | attr ',' attr_list + ; + +attr + : NAME '=' attr_val + { + s_pMapAttr.insert(*$1, *$3); + delete $1; + delete $3; + } + ; + +attr_val + : NAME + | STRING + | NUMBER + ; + +call_tree + : call_tree_prepare '{' root_node '}' + ; + +call_tree_prepare + : CALL_TREE { s_pTree = s_pCallTree; } + ; + +calling_tree + : calling_tree_prepare '{' root_node '}' + ; + +calling_tree_prepare + : CALLING_TREE { s_pTree = s_pCallingTree; } + ; + +root_node + : root_tree_node '{' child_list '}' + { + QListViewItem* pItem; + + pItem = s_pParentStack.pop(); + if (pItem->firstChild() != NULL) + pItem->setOpen(true); + } + ; + +root_tree_node + : NAME + { + QListViewItem* pItem; + + pItem = new QListViewItem(s_pTree, *$1); + s_pParentStack.push(pItem); + delete $1; + } + ; + +child_list + : + | child_node child_list + ; + +child_node + : tree_node tree_attributes '{' child_list '}' + { + QListViewItem* pItem; + + pItem = s_pParentStack.pop(); + if (pItem->firstChild() != NULL) + pItem->setOpen(true); + } + ; + +tree_node + : NAME + { + QListViewItem* pItem; + + pItem = new QListViewItem(s_pParentStack.top(), *$1); + s_pParentStack.push(pItem); + delete $1; + } + ; + +tree_attributes + : attributes + { + QListViewItem* pItem; + + pItem = s_pParentStack.top(); + pItem->setText(1, s_pMapAttr["kscope_file"]); + pItem->setText(2, s_pMapAttr["kscope_line"]); + pItem->setText(3, s_pEncoder->decode(s_pMapAttr["kscope_text"])); + } + ; + +%% + +void yyinit(CallTreeDlg* pDlg, FILE* pFile, Encoder* pEnc) +{ + yyin = pFile; + s_pCallTree = pDlg->m_pCalledWidget; + s_pCallingTree = pDlg->m_pCallingWidget; + s_pGraph = pDlg->m_pGraphWidget; + s_pEncoder = pEnc; +} + +void yyerror(const char* szError) +{ + fprintf(stderr, "%s\n", szError); +} diff --git a/src/dotscan.lpp b/src/dotscan.lpp new file mode 100644 index 0000000..0667d33 --- /dev/null +++ b/src/dotscan.lpp @@ -0,0 +1,36 @@ +/* dot.l */ + +%{ +#include +#include "dotparse.h" +%} + +%option noyywrap + +name [a-zA-Z_][a-zA-Z0-9_]* +string \"(\\.|[^\"])*\" +space [ \t\n]+ +number [1-9][0-9]* +float [0-9]*\.[0-9]+ + +%% + +"graph" return GRAPH; +"digraph" return DIGRAPH; +"calltree" return CALL_TREE; +"callingtree" return CALLING_TREE; +"node" return NODE; +"->" return DIR_EDGE; +"--" return UNDIR_EDGE; +{name} { yylval.pText = new QString(yytext); return NAME; } +{string} { + QString str = &yytext[1]; + yylval.pText = new QString(str.left(yyleng - 2)); + return STRING; + } +{number} { yylval.pText = new QString(yytext); return NUMBER; } +{float} { yylval.pText = new QString(yytext); return NUMBER; } +{space} ; +. return yytext[0]; + +%% diff --git a/src/editormanager.cpp b/src/editormanager.cpp new file mode 100644 index 0000000..253bf6c --- /dev/null +++ b/src/editormanager.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "editormanager.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +EditorManager::EditorManager(QWidget* pParent, const char* szName) : + KParts::PartManager(pParent, szName) +{ + applyPrefs(); +} + +/** + * Class destructor. + */ +EditorManager::~EditorManager() +{ +} + +/** + * Creates a new document part. + * @return A pointer to the new document + */ +KTextEditor::Document* EditorManager::add() +{ + KTextEditor::Document* pDoc; + + // Create the document + pDoc = KTextEditor::EditorChooser::createDocument(this); + addPart(pDoc); + + return pDoc; +} + +/** + * Deletes a document part. + * @param pDoc The document to remove + */ +void EditorManager::remove(KTextEditor::Document* pDoc) +{ + removePart(pDoc); + delete pDoc; +} + +/** + * Applies the user preferences. + * Determines if Kate warnings are displayed in case the currently edited + * file is modified outside KScope. + * NOTE: This behaviour is determined by a static function, which is why this + * code appears here, rather then for every EditorPage object. + */ +void EditorManager::applyPrefs() +{ + Kate::Document::setFileChangedDialogsActivated( + Config().getWarnModifiedOnDisk()); +} + +#include "editormanager.moc" diff --git a/src/editormanager.h b/src/editormanager.h new file mode 100644 index 0000000..413ffed --- /dev/null +++ b/src/editormanager.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef EDITORMANAGER_H +#define EDITORMANAGER_H + +#include +#include +#include +#include + +/** + * Creates text editor parts, used to open source files. + * The EditorManager is responsible for creating parts, and managing their + * GUI integration. + * @author Elad Lahav + */ + +class EditorManager : public KParts::PartManager +{ + Q_OBJECT + +public: + EditorManager(QWidget* pParent = 0, const char* szName = 0); + ~EditorManager(); + + KTextEditor::Document* add(); + void remove(KTextEditor::Document*); + void applyPrefs(); +}; + +#endif diff --git a/src/editorpage.cpp b/src/editorpage.cpp new file mode 100644 index 0000000..5c183b9 --- /dev/null +++ b/src/editorpage.cpp @@ -0,0 +1,720 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "editorpage.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pDoc The document object associated with this page + * @param pMenu A Cscope queries popup menu to use with the editor + * @param pParent The parent widget + * @param szName The widget's name + */ +EditorPage::EditorPage(KTextEditor::Document* pDoc, QPopupMenu* pMenu, + QTabWidget* pParent, const char* szName) : QHBox(pParent, szName), + m_pParentTab(pParent), + m_pDoc(pDoc), + m_bOpen(false), + m_bNewFile(false), + m_sName(""), + m_bWritable(true), /* new documents are writable by default */ + m_bModified(false), + m_nLine(0), + m_bSaveNewSizes(false) +{ + KTextEditor::PopupMenuInterface* pMenuIf; + KTextEditor::ViewCursorInterface* pCursorIf; + + // Create code-completion objects (will be deleted by QObject destructor) + m_pCompletion = new SymbolCompletion(this, this); + + // Set read-only mode, if required + if (Config().getReadOnlyMode()) + m_pDoc->setReadWrite(false); + + // Create the child widgets + m_pSplit = new QSplitter(this); + m_pCtagsList = new CtagsList(m_pSplit); + m_pView = m_pDoc->createView(m_pSplit); + m_pSplit->setResizeMode(m_pCtagsList, QSplitter::KeepSize); + + // Perform tasks only when the document has been loaded completely + connect(m_pDoc, SIGNAL(completed()), this, SLOT(slotFileOpened())); + + // Be notified when the text in the editor changes + connect(m_pDoc, SIGNAL(textChanged()), this, SLOT(slotSetModified())); + connect(m_pDoc, SIGNAL(undoChanged()), this, SLOT(slotUndoChanged())); + + // Store the sizes of the child windows when the tag list is resized + // (since it may imply a move of the splitter divider) + connect(m_pCtagsList, SIGNAL(resized()), this, SLOT(slotChildResized())); + + // Go to a symbol's line if it is selected in the tag list + connect(m_pCtagsList, SIGNAL(lineRequested(uint)), this, + SLOT(slotGotoLine(uint))); + + // Add Ctag records to the tag list + connect(&m_ctags, SIGNAL(dataReady(FrontendToken*)), m_pCtagsList, + SLOT(slotDataReady(FrontendToken*))); + + // Monitor Ctags' operation + connect(&m_ctags, SIGNAL(finished(uint)), m_pCtagsList, + SLOT(slotCtagsFinished(uint))); + + // Set the context menu + pMenuIf = dynamic_cast(m_pView); + if (pMenuIf) + pMenuIf->installPopup(pMenu); + + // Emit a signal whenever the cursor's position changes + pCursorIf = dynamic_cast(m_pView); + if (pCursorIf) { + connect(m_pView, SIGNAL(cursorPositionChanged()), this, + SLOT(slotCursorPosChange())); + } +} + +/** + * Class destructor. + */ +EditorPage::~EditorPage() +{ +} + +/** + * Returns a pointer to the editor document object embedded in this page. + * @returns the document pointer + */ +KTextEditor::Document* EditorPage::getDocument() +{ + return m_pDoc; +} + +/** + * Returns a pointer to the editor view object embedded in this page. + * @returns the view pointer + */ +KTextEditor::View* EditorPage::getView() +{ + return m_pView; +} + +/** + * Returns the full path of the file being edited. + * @return The path of the file associated with the Document object, empty + * string if no file is currently open + */ +QString EditorPage::getFilePath() +{ + return m_pDoc->url().path(); +} + +/** + * Returns the name of the file being edited. + * @return The name of the file associated with the Document object, empty + * string if no file is currently open + */ +QString EditorPage::getFileName() +{ + return m_sName; +} + +/** + * Determines whether this file can be modified, according to the file-system + * permissions, and KScope's global settings. + * @return true if this document can be changed, false otherwise + */ +bool EditorPage::isWritable() +{ + // Check global settings first + if (Config().getReadOnlyMode()) + return false; + + // Return FS write permissions + return m_bWritable; +} + +/** + * Determines if the file edited in this page was modified, and the changes + * were not yet saved. + * @return true if the file was modified, false otherwise + */ +bool EditorPage::isModified() +{ + return m_pDoc->isModified(); +} + +/** + * Opens a file for editing. + * @param sFileName The full path name of the file to edit. + */ +void EditorPage::open(const QString& sFileName) +{ + // Open the given file + m_bOpen = false; + m_pDoc->openURL(sFileName); +} + +/** + * Marks the page as containing a new unnamed file. + */ +void EditorPage::setNewFile() +{ + m_bNewFile = true; + emit newFile(this); +} + +/** + * Saves the edited file. + */ +void EditorPage::save() +{ + if (m_pDoc->isModified()) + m_pDoc->save(); +} + +/** + * Closes an edited file. + * @param bForce true to close the file regardless of any modifications, + * false to prompt the user in case of unsaved chnages + * @return true if the file has been closed, false if the user has aborted + */ +bool EditorPage::close(bool bForce) +{ + QString sPath; + + // To override the prompt-on-close behaviour, we need to mark the file + // as unmodified + if (bForce) + m_pDoc->setModified(false); + + // Close the file, unless the user aborts the action + sPath = m_pDoc->url().path(); + if (!m_pDoc->closeURL()) + return false; + + emit fileClosed(sPath); + return true; +} + +/** + * Applies any changes to the user preferences concerning an editor window. + */ +void EditorPage::applyPrefs() +{ + // Determine whether the editor should work in a read-only mode + if (m_bWritable) + m_pDoc->setReadWrite(!Config().getReadOnlyMode()); + + // Apply preferences to the tag list of this window + m_pCtagsList->applyPrefs(); +} + +/** + * Sets the keyboard focus to the editor part of the page. + * This method is called whenever the page is activated. It is more reasonable + * to set the focus to the editor than to the tag list. + */ +void EditorPage::setEditorFocus() +{ + m_pView->setFocus(); + slotCursorPosChange(); +} + +/** + * Sets the keyboard focus to the tag list. + * This method is called when the "Go To Tag" menu command is invoked. + */ +void EditorPage::setTagListFocus() +{ + m_pCtagsList->slotSetFocus(); +} + +/** + * Sets a bookmark at the given line. + * @param nLine The line to mark + */ +void EditorPage::addBookmark(uint nLine) +{ + KTextEditor::MarkInterface* pMarkIf; + + pMarkIf = dynamic_cast(m_pDoc); + if (pMarkIf) + pMarkIf->setMark(nLine, KTextEditor::MarkInterface::markType01); +} + +/** + * Retrieves a list of all bookmarks in this page. + */ +void EditorPage::getBookmarks(FileLocationList& fll) +{ + KTextEditor::MarkInterface* pMarkIf; + QPtrList plMarks; + KTextEditor::Mark* pMark; + + // Get the marks interface + pMarkIf = dynamic_cast(m_pDoc); + if (!pMarkIf) + return; + + // Find all bookmarks + plMarks = pMarkIf->marks(); + for (pMark = plMarks.first(); pMark; pMark = plMarks.next()) { + if (pMark->type == KTextEditor::MarkInterface::markType01) + fll.append(new FileLocation(getFilePath(), pMark->line, 0)); + } +} + +/** + * Returns the currently selected text in an open file. + * @return The selected text, or a null string if no text is currently + * selected + */ +QString EditorPage::getSelection() +{ + KTextEditor::SelectionInterface* pSelect; + + // Get the selected text + pSelect = dynamic_cast(m_pDoc); + if (!pSelect || !pSelect->hasSelection()) + return QString::null; + + // Return the selected text + return pSelect->selection(); +} +/** + * Returns a the complete word defined by the current cursor position. + * Attempts to extract a valid C symbol from the location of the cursor, by + * starting at the current line and column, and looking forward and backward + * for non-symbol characters. + * @return A C symbol under the cursor, if any, or QString::null otherwise + */ +QString EditorPage::getWordUnderCursor(uint* pPosInWord) +{ + KTextEditor::ViewCursorInterface* pCursor; + KTextEditor::EditInterface* pEditIf; + QString sLine; + uint nLine, nCol, nFrom, nTo, nLast, nLength; + QChar ch; + + // Get a cursor object + pCursor = dynamic_cast(m_pView); + if (pCursor == NULL) + return QString::null; + + // Get a pointer to the edit interface + pEditIf = dynamic_cast(m_pDoc); + if (!pEditIf) + return QString::null; + + // Get the line on which the cursor is positioned + pCursor->cursorPositionReal(&nLine, &nCol); + sLine = pEditIf->textLine(nLine); + + // Find the beginning of the current word + for (nFrom = nCol; nFrom > 0;) { + ch = sLine.at(nFrom - 1); + if (!ch.isLetter() && !ch.isDigit() && ch != '_') + break; + + nFrom--; + } + + // Find the end of the current word + nLast = sLine.length(); + for (nTo = nCol; nTo < nLast;) { + ch = sLine.at(nTo); + if (!ch.isLetter() && !ch.isDigit() && ch != '_') + break; + + nTo++; + } + + // Mark empty words + nLength = nTo - nFrom; + if (nLength == 0) + return QString::null; + + // Return the in-word position, if required + if (pPosInWord != NULL) + *pPosInWord = nCol - nFrom; + + // Extract the word under the cursor from the entire line + return sLine.mid(nFrom, nLength); +} + +/** + * Combines getSelection() and getWordUnderCursor() to return a suggested + * text for queries. + * The function first looks if any text is selected. If so, the selected text + * is returned. Otherwise, the word under the cursor location is returned, if + * one exists. + * @return Either the currently selected text, or the word under the cursor, + * or QString::null if both options fail + */ +QString EditorPage::getSuggestedText() +{ + QString sText; + + sText = getSelection(); + if (sText == QString::null) + sText = getWordUnderCursor(); + + return sText; +} + +/** + * Returns the contents of the requested line. + * Truncates the leading and trailing white spaces. + * @param nLine The line number + * @return The text of the requested line, if successful, QString::null + * otherwise + */ +QString EditorPage::getLineContents(uint nLine) +{ + KTextEditor::EditInterface* pEditIf; + QString sLine; + + // Cannot accept line 0 + if (nLine == 0) + return QString::null; + + // Get a pointer to the edit interface + pEditIf = dynamic_cast(m_pDoc); + if (!pEditIf) + return QString::null; + + // Get the line on which the cursor is positioned + sLine = pEditIf->textLine(nLine - 1); + return sLine.stripWhiteSpace(); +} + +/** + * Moves the editing caret to the beginning of a given line. + * @param nLine The line number to move to + */ +void EditorPage::slotGotoLine(uint nLine) +{ + // Ensure there is an open document + if (!m_bOpen) + return; + + // Set the cursor to the requested line + if (!setCursorPos(nLine)) + return; + + // Update Ctags view + m_pCtagsList->gotoLine(nLine); + + // Set the focus to the selected line + m_pView->setFocus(); +} + +/** + * Sets this editor as the current page, when the edited file's name is + * selected in the "Window" menu. + */ +void EditorPage::slotMenuSelect() +{ + m_pParentTab->setCurrentPage(m_pParentTab->indexOf(this)); +} + +/** + * Displays a list of possible completions for the symbol currently under the + * cursor. + */ +void EditorPage::slotCompleteSymbol() +{ + m_pCompletion->slotComplete(); +} + +/** + * Stores the sizes of the child widgets whenever they are changed. + * This slot is connected to the resized() signal of the CtagsList child + * widget. + */ +void EditorPage::slotChildResized() +{ + SPLIT_SIZES si; + + // Only store sizes when allowed to + if (!m_bSaveNewSizes) { + m_bSaveNewSizes = true; + return; + } + + // Get the current widths of the child widgets + si = m_pSplit->sizes(); + if (si.count() == 2) + Config().setEditorSizes(si); +} + +/** + * Sets the visibility status and sizes of the child widgets. + * @param bShowTagList true to show the tag list, false otherwise + * @param si The new sizes to use + */ +void EditorPage::setLayout(bool bShowTagList, const SPLIT_SIZES& si) +{ + // Make sure sizes are not stored during this process + m_bSaveNewSizes = false; + + // Adjust the layout + m_pCtagsList->setShown(bShowTagList); + if (bShowTagList) + m_pSplit->setSizes(si); +} + +/** + * Returns the current position of the cursor. + * @param nLine Holds the line on which the cursor is currently located + * @param nCol Holds the column on which the cursor is currently located + * @return true if successful, false otherwise (cursor interface was not + * obtained) + */ +bool EditorPage::getCursorPos(uint& nLine, uint& nCol) +{ + KTextEditor::ViewCursorInterface* pCursorIf; + + // Acquire the view cursor + pCursorIf = dynamic_cast(m_pView); + if (pCursorIf == NULL) + return false; + + // Get the cursor position (adjusted to 1-based counting) + pCursorIf->cursorPosition(&nLine, &nCol); + nLine++; + nCol++; + + return true; +} + +/** + * Moves the cursor to a given position. + * @param nLine The cursor's new line number + * @param nCol The cursor's new column number + * @return true if successful, false otherwise (cursor interface was not + * obtained) + */ +bool EditorPage::setCursorPos(uint nLine, uint nCol) +{ + Kate::View* pKateView; + KTextEditor::ViewCursorInterface* pCursorIf; + + // Cannot accept line 0 + if (nLine == 0) + return false; + + // Adjust to 0-based counting + nLine--; + nCol--; + + // Acquire the view cursor + pCursorIf = dynamic_cast(m_pView); + if (pCursorIf == NULL) + return false; + + // NOTE: The following code is a fix to a bug in Kate, which wrongly + // calculates the column number in setCursorPosition. + pKateView = dynamic_cast(m_pView); + if (pKateView != NULL) { + KTextEditor::EditInterface* pEditIf; + const char* szLine; + uint nRealCol; + uint nTabAdjust; + + // Get a pointer to the edit interface + pEditIf = dynamic_cast(m_pDoc); + if (!pEditIf) + return false; + + nRealCol = 0; + + // Check for out of bound line numbers + if (nLine < pEditIf->numLines()) { + // Get the contents of the requested line + szLine = pEditIf->textLine(nLine).latin1(); + + // Check for empty line + if (szLine != NULL) { + // The number of columns which a tab character adds + nTabAdjust = pKateView->tabWidth() - 1; + + // Calculate the real column, based on the tab width + for (; nRealCol < nCol && szLine[nRealCol] != 0; nRealCol++) { + if (szLine[nRealCol] == '\t') + nCol -= nTabAdjust; + } + } + } + else { + // Marker set beyond end of file, move to the last line + nLine = pEditIf->numLines() - 1; + } + // Set the cursor position + pCursorIf->setCursorPositionReal(nLine, nRealCol); + } + else { + // Non-Kate editors: set the cursor position normally + pCursorIf->setCursorPosition(nLine, nCol); + } + + return true; +} + +void EditorPage::setTabWidth(uint nTabWidth) +{ + Kate::Document* pKateDoc; + Kate::Command* pKateCmd; + QString sCmd, sResult; + + pKateDoc = dynamic_cast(m_pDoc); + if ((pKateDoc) && + (pKateCmd = pKateDoc->queryCommand("set-tab-width"))) { + sCmd.sprintf("set-tab-width %u", nTabWidth); + pKateCmd->exec((Kate::View*)m_pView, sCmd, sResult); + } +} + +/** + * Called when a document has completed loading. + * Determines the file's properties and refreshes the tag list of the editor + * window. + * This slot is connected to the completed() signal of the document object. + * The signal is emitted when a new file is opened, or when a modified file is + * saved. + */ +void EditorPage::slotFileOpened() +{ + QFileInfo fi(m_pDoc->url().path()); + + // Get file information + m_sName = fi.fileName(); + m_bWritable = fi.isWritable(); + + // Set read/write or read-only mode + m_pDoc->setReadWrite(!Config().getReadOnlyMode() && m_bWritable); + + // Refresh the tag list + m_pCtagsList->clear(); + m_ctags.run(m_pDoc->url().path()); + + // Check if this is a modified file that has just been saved + if (m_bModified) + emit fileSaved(m_pDoc->url().path(), m_bNewFile); + + // Notify that the document has loaded + m_bOpen = true; + m_bModified = false; + emit fileOpened(this, m_pDoc->url().path()); + + // Set initial position of the cursor + m_nLine = 0; + slotCursorPosChange(); + + // This is no longer a new file + m_bNewFile = false; +} + +/** + * Marks a file as modified when the contents of the editor change. + * This slot is conncted to the textChanged() signal of the Document object. + * In addition to marking the file, this method also emits the modified() + * signal. + */ +void EditorPage::slotSetModified() +{ + // Only perform tasks if the file is not already marked + if (!m_bModified && m_pDoc->isModified()) { + m_bModified = true; + emit modified(this, m_bModified); + +#if KDE_IS_VERSION(3,3,0) + Kate::DocumentExt* pKateDoc; + + // If the editor is a Kate part, check whether it was modified on + // disk as well, and issue a warning if so + pKateDoc = dynamic_cast(m_pDoc); + if (pKateDoc) + pKateDoc->slotModifiedOnDisk(dynamic_cast(m_pView)); +#endif + } + + // Start/restart the auto-completion timer + m_pCompletion->slotAutoComplete(); +} + +/** + * Marks a file as not modified if all undo levels have been applied. + * This slot is conncted to the undoChanged() signal of the Document object. + * In addition to marking the file, this method also emits the modified() + * signal. + */ +void EditorPage::slotUndoChanged() +{ + // Check if the file contents have been fully restored + if (m_bModified && !m_pDoc->isModified()) { + m_bModified = false; + emit modified(this, m_bModified); + } +} + +/** + * Handles changes in the cursor position. + * Emits a signal with the new line and column numbers. + */ +void EditorPage::slotCursorPosChange() +{ + uint nLine, nCol; + + // Find the new line and column number, and emit the signal + if (!getCursorPos(nLine, nCol)) + return; + + emit cursorPosChanged(nLine, nCol); + + // Select the relevant symbol in the tag list + if (Config().getAutoTagHl() && (m_nLine != nLine)) { + m_pCtagsList->gotoLine(nLine); + m_nLine = nLine; + } + + // Abort code completion on cursor changes during the completion + // process + m_pCompletion->abort(); +} + +#include "editorpage.moc" diff --git a/src/editorpage.h b/src/editorpage.h new file mode 100644 index 0000000..0af3aaf --- /dev/null +++ b/src/editorpage.h @@ -0,0 +1,215 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef EDITORPAGE_H +#define EDITORPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ctagsfrontend.h" +#include "ctagslist.h" +#include "kscopeconfig.h" +#include "symbolcompletion.h" +#include "projectbase.h" + +/** + * An editor window based on the system's current editing application. + * The page is divided into two panes. One holds an embedded editor, and the + * other holds a list of tags (generated by Ctags) of the file currently being + * edited. + * The widget creates an instance of the editor application, and uses its + * document and view objects that allow KScope to control it. A page also + * Each page is inserted in a separate tab in the EditorTabs widget. + * @author Elad Lahav + */ + +class EditorPage : public QHBox, SymbolCompletion::Interface +{ + Q_OBJECT + +public: + EditorPage(KTextEditor::Document*, QPopupMenu*, QTabWidget* pParent = 0, + const char* szName = 0); + ~EditorPage(); + + void open(const QString&); + void setNewFile(); + void save(); + bool close(bool bForce = false); + void applyPrefs(); + void setEditorFocus(); + void setTagListFocus(); + void addBookmark(uint); + void getBookmarks(FileLocationList&); + + KTextEditor::Document* getDocument(); + KTextEditor::View* getView(); + QString getFilePath(); + QString getFileName(); + bool isWritable(); + bool isModified(); + QString getSelection(); + QString getSuggestedText(); + QString getLineContents(uint); + void setLayout(bool bShowTagList, const SPLIT_SIZES&); + bool getCursorPos(uint&, uint&); + bool setCursorPos(uint, uint nCol = 1); + void setTabWidth(uint); + + virtual QString getWordUnderCursor(uint* pPosInWord = NULL); + + /** + * Implements the SymbolCompletion interface method for returning an + * object that supports KTextEditor::CodeCompletionInterface. + * @return A pointer to the View object of the editor + */ + virtual QObject* getCCObject() { return m_pView; } + + /** + * @return true if a previously unsaved file is currently being edited, + * false otherwise + */ + bool isNewFile() { return m_bNewFile; } + + /** The identifier of the Window menu item which activates this page. */ + int m_nMenuId; + +public slots: + void slotGotoLine(uint); + void slotMenuSelect(); + void slotCompleteSymbol(); + +signals: + /** + * Emitted when a file has been fully loaded into the editor. + * @param pPage The emitting object + * @param sPath The full path of the loaded file + */ + void fileOpened(EditorPage* pPage, const QString& sPath); + + /** + * Emitted when an editor is opened for editing a new file. + * @param pPage The emitting object + */ + void newFile(EditorPage* pPage); + + /** + * Emitted when the 'modified' status of the editor changes. + * This happens when the contents of the editor change, or when the file + * being edited is saved. + * @param pPage The emitting object + * @param bModified true if the new state is 'modified', false if the + * new state is 'unmodified' + */ + void modified(EditorPage* pPage, bool bModified); + + /** + * Emitted when the position of the cursor changes. + * @param nLine The new line number + * @param nCol The new column number + */ + void cursorPosChanged(uint nLine, uint nCol); + + /** + * Emitted when a file is saved after it was modified. + * Indicates the project's cross-reference database needs to be updated. + * @param sPath The full path of the saved file + * @param bIsNew true if this is a new file, false otherwise + */ + void fileSaved(const QString& sPath, bool bIsNew); + + /** + * Emitted when a file is closed. + * @param sPath The full path of the closed file + */ + void fileClosed(const QString& sPath); + +private: + /** The tab widget holding this page. */ + QTabWidget* m_pParentTab; + + /** A Ctags process to use on the edited source file. */ + CtagsFrontend m_ctags; + + /** An adjustable splitter for separating the tag list from the editor + part. */ + QSplitter* m_pSplit; + + /** A list view for displaying Ctags results. */ + CtagsList* m_pCtagsList; + + /** The document part of the editor. */ + KTextEditor::Document* m_pDoc; + + /** The view part of the editor. */ + KTextEditor::View* m_pView; + + /** Whether a source file is currently loaded. */ + bool m_bOpen; + + /** Whether the file being edited is a new one (i.e., never saved + before.) */ + bool m_bNewFile; + + /** The name of the file being edited. */ + QString m_sName; + + /** true if the file system allows this file to be modified, false + otherwise. */ + bool m_bWritable; + + /** This variable is required in addition to m_pDoc->isModified() so + that the modified() signal is emitted only once. */ + bool m_bModified; + + /** The current line position of the cursor. */ + uint m_nLine; + + /** Provides symbol completion. */ + SymbolCompletion* m_pCompletion; + + /** Determines whether size changes in the child widgets should be + stored in the global configuration file. + Needs to be explicitly set to false before _each_ operation that + does not wish to change the defaults. */ + bool m_bSaveNewSizes; + +private slots: + void slotChildResized(); + void slotFileOpened(); + void slotSetModified(); + void slotUndoChanged(); + void slotCursorPosChange(); +}; + +#endif diff --git a/src/editortabs.cpp b/src/editortabs.cpp new file mode 100644 index 0000000..5af9be1 --- /dev/null +++ b/src/editortabs.cpp @@ -0,0 +1,640 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include "editortabs.h" +#include "kscopepixmaps.h" +#include "queryview.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +EditorTabs::EditorTabs(QWidget* pParent, const char* szName) : + TabWidget(pParent, szName), + m_pCurPage(NULL), + m_pWindowMenu(NULL), + m_nWindowMenuItems(0), + m_nNewFiles(0) +{ + // Display close buttons + setHoverCloseButton(true); + + // Accept file drops + setAcceptDrops(true); + + // Close an editor page when its close button is clicked + connect(this, SIGNAL(closeRequest(QWidget*)), this, + SLOT(slotRemovePage(QWidget*))); + + // Set an editor page as the active part, when its tab is selected + connect(this, SIGNAL(currentChanged(QWidget*)), this, + SLOT(slotCurrentChanged(QWidget*))); + + // Start dragging a file from a tab + connect(this, SIGNAL(initiateDrag(QWidget*)), this, + SLOT(slotInitiateDrag(QWidget*))); +} + +/** + * Class destructor. + */ +EditorTabs::~EditorTabs() +{ +} + +/** + * @param pWindowMenu Pointer to the main window's "Window" menu (used to + * add an activation menu item for each editor page) + */ +void EditorTabs::setWindowMenu(QPopupMenu* pWindowMenu) +{ + m_pWindowMenu = pWindowMenu; + connect(pWindowMenu, SIGNAL(aboutToShow()), this, + SLOT(slotFillWindowMenu())); + connect(pWindowMenu, SIGNAL(activated(int)), this, + SLOT(slotSetCurrentPage(int))); +} + +/** + * Adds a new editor page to the tab widget. + * @param pNewPage The page to add + */ +void EditorTabs::addEditorPage(EditorPage* pNewPage) +{ + // Create a new tab and set is as the current one + insertTab(pNewPage, ""); + showPage(pNewPage); + + // Add the file edited by this page to the map, and display its name, + // once the file is opened + connect(pNewPage, SIGNAL(fileOpened(EditorPage*, const QString&)), this, + SLOT(slotAttachFile(EditorPage*, const QString&))); + + // Handle new unnamed files + connect(pNewPage, SIGNAL(newFile(EditorPage*)), this, + SLOT(slotNewFile(EditorPage*))); + + // Change tab icon when a file is modified + connect(pNewPage, SIGNAL(modified(EditorPage*, bool)), this, + SLOT(slotFileModified(EditorPage*, bool))); + + // If this is the first page, the current page will not be set by the + // signal handler, so we need to do it manually + if (count() == 1) + slotCurrentChanged(pNewPage); +} + +/** + * Finds and displays a page editing the given file. + * NOTE: The bForceChange parameters is used as a fix for the GUI merge + * problem arising when the found page is the current one. + * @param sFileName The name of the file to search + * @param bForceChange If set to true, the method will emit the signal + * editorChanged() even if the found page is the + * current one + * @return The editor page object, if found, NULL otherwise + */ +EditorPage* EditorTabs::findEditorPage(const QString& sFileName, + bool bForceChange) +{ + EditorMap::iterator itr; + EditorPage* pPage; + bool bEmit; + + // Find the page according to the associated file name + itr = m_mapEdit.find(sFileName); + if (itr == m_mapEdit.end()) + return NULL; + + // Set the page as the current one + pPage = *itr; + bEmit = (bForceChange && (pPage == m_pCurPage)); + showPage(pPage); + + // Emit the editorChanged() signal, if required + if (bEmit) + emit editorChanged(NULL, m_pCurPage); + + return *itr; +} + +/** + * Returns the page associated with the selected tab. + * @return The current editor page + */ +EditorPage* EditorTabs::getCurrentPage() +{ + return (EditorPage*)currentPage(); +} + +/** + * Deletes the currently active page. + * Finds the current page, closes its editor window and deletes the page. + * If other editors are open, another page becomes active. + */ +void EditorTabs::removeCurrentPage() +{ + QWidget* pPage; + + // Get the active page, if any + pPage = currentPage(); + if (pPage == NULL) + return; + + // Close the editor window + removePage(pPage, false); +} + +/** + * Removes all editor pages. + * @return true if successful, false if the user aborts the operation + */ +bool EditorTabs::removeAllPages() +{ + QWidget* pPage; + + // Check if there are any modified files + if (getModifiedFilesCount()) { + // Prompt the user to save these files + switch (KMessageBox::questionYesNoCancel(NULL, + i18n("Some files contain unsaved changes.\nWould you like to " + "save these files?"))) { + case KMessageBox::Yes: + // Save files + slotSaveAll(); + break; + + case KMessageBox::No: + // Close files, ignoring changes + break; + + case KMessageBox::Cancel: + // Abort + return false; + } + } + + // Avoid warning about modification on disk + Kate::Document::setFileChangedDialogsActivated(false); + + // Iterate pages until none is left + while ((pPage = currentPage()) != NULL) + removePage(pPage, true); + + // Restore kate warning if enabled + Kate::Document::setFileChangedDialogsActivated( + Config().getWarnModifiedOnDisk()); + + // All pages were successfully removed + return true; +} + +/** + * Keeps track of the currently active editor page, and notifies on a change + * in the active page. + * This slot is connected to the currentChanged() signal of the QTabWidget + * object. + * @param pWidget The new active page + */ +void EditorTabs::slotCurrentChanged(QWidget* pWidget) +{ + EditorPage* pOldPage; + + // TODO: + // For some reason, this slot is being called twice for every external + // tab activation (e.g., through the Window menu). + // We avoid it, but this really needs to be fixed properly. + if (pWidget == m_pCurPage) + return; + + // Set the new active page + pOldPage = m_pCurPage; + m_pCurPage = (EditorPage*)pWidget; + + if (m_pCurPage) { + // Set the keyboard focus to the editor part of the page + m_pCurPage->setEditorFocus(); + + // Adjust the splitter sizes + m_pCurPage->setLayout(Config().getShowTagList(), + Config().getEditorSizes()); + } + + /* Notify the main window */ + emit editorChanged(pOldPage, m_pCurPage); +} + +/** + * Updates the tab of an editor page to reflect the newly opened file. + * This slot is attached to the fileOpened() signal of an EditorPage object. + * @param pEditPage Pointer to the calling object + * @param sFilePath The full path of the file edited in this page + */ +void EditorTabs::slotAttachFile(EditorPage* pEditPage, + const QString& sFilePath) +{ + // Set the appropriate tab icon, according to the file permissions + if (pEditPage->isWritable()) + setTabIconSet(pEditPage, Pixmaps().getPixmap(KScopePixmaps::TabRW)); + else + setTabIconSet(pEditPage, Pixmaps().getPixmap(KScopePixmaps::TabRO)); + + // Do nothing if the file name has not changed + if (m_mapEdit[sFilePath] == pEditPage) + return; + + // Set the tab caption to the file name, and a tool-tip to the full path + changeTab(pEditPage, pEditPage->getFileName()); + setTabToolTip(pEditPage, sFilePath); + + // Associate the EditorPage object with its file name + m_mapEdit[sFilePath] = pEditPage; +} + +/** + * Marks a page as containing a new unnamed file. + * This slot is attached to the newFile() signal of an EditorPage object. + * @param pEditPage Pointer to the calling object + */ +void EditorTabs::slotNewFile(EditorPage* pEditPage) +{ + QString sCaption; + + // Set the tab caption to mark a new file + m_nNewFiles++; + sCaption = i18n("Untitled ") + QString::number(m_nNewFiles); + changeTab(pEditPage, + Pixmaps().getPixmap(KScopePixmaps::TabRW), + sCaption); + setTabToolTip(pEditPage, i18n("New unsaved file")); +} + +/** + * Applies the user's colour and font preferences to all pages. + */ +void EditorTabs::applyPrefs() +{ + EditorPage* pPage; + int i; + + // Iterate editor pages + for (i = 0; i < count(); i++) { + pPage = (EditorPage*)page(i); + pPage->applyPrefs(); + setTabIconSet(pPage, Pixmaps().getPixmap(pPage->isWritable() ? + KScopePixmaps::TabRW : KScopePixmaps::TabRO)); + } +} + +/** + * Fills a list with the paths and cursor positions of all files currently + * open. + * @param list The list to fill + */ +void EditorTabs::getOpenFiles(FileLocationList& list) +{ + int i; + EditorPage* pPage; + uint nLine, nCol; + + // Iterate over all editor pages + for (i = 0; i < count(); i++) { + // Obtain file and cursor position information + pPage = (EditorPage*)page(i); + if (!pPage->getCursorPos(nLine, nCol)) { + nLine = 1; + nCol = 1; + } + + // Create a new list item + list.append(new FileLocation(pPage->getFilePath(), nLine, nCol)); + } +} + +/** + * Constructs a list bookmarks set to open files. + * Used to store all currently set bookmarks when a session is closed. + * @param fll The list to fill + */ +void EditorTabs::getBookmarks(FileLocationList& fll) +{ + int i; + EditorPage* pPage; + + // Iterate over all editor pages + for (i = 0; i < count(); i++) { + pPage = (EditorPage*)page(i); + pPage->getBookmarks(fll); + } +} + +/** + * Assigns bookmarks to open files. + * Called when a session is opened, to restore any bookmarks set to existing + * editor pages. + * @param fll A list of bookmark positions + */ +void EditorTabs::setBookmarks(FileLocationList& fll) +{ + FileLocation* pLoc; + EditorMap::iterator itr; + EditorPage* pPage; + + // Iterate over the list of bookmarks + for (pLoc = fll.first(); pLoc; pLoc = fll.next()) { + itr = m_mapEdit.find(pLoc->m_sPath); + // Get the relevant page, if any + if (itr != m_mapEdit.end()) { + pPage = *itr; + pPage->addBookmark(pLoc->m_nLine); + } + } +} + +/** + * Fills a QueryView object with the list of currently active bookmarks. + * @param pView The widget to use for displaying bookmarks + */ +void EditorTabs::showBookmarks(QueryView* pView) +{ + int i; + EditorPage* pPage; + FileLocationList fll; + FileLocation* pLoc; + + fll.setAutoDelete(true); + + // Iterate over all editor pages + for (i = 0; i < count(); i++) { + // Obtain file and cursor position information + pPage = (EditorPage*)page(i); + pPage->getBookmarks(fll); + + // Populate the view + for (pLoc = fll.first(); pLoc; pLoc = fll.next()) { + pView->addRecord("", pLoc->m_sPath, + QString::number(pLoc->m_nLine + 1), + pPage->getLineContents(pLoc->m_nLine + 1)); + } + + fll.clear(); + } +} + +/** + * Removes an editor page. + * If there are unsaved changes, the user is prompted, and the file is closed + * according to the user's choice. + * This slot is connected to the clicked() signal of the tab's close button. + * @param pPage The EditorPage object to remove + */ +void EditorTabs::slotRemovePage(QWidget* pPage) +{ + removePage(pPage, false); +} + +/** + * Handles the "View->Show/Hide Tag List" menu item. + * Shows/hides the tag list for the current page, and sets the default values + * for all pages. + */ +void EditorTabs::slotToggleTagList() +{ + EditorPage* pPage; + + // Change the default value + Config().setShowTagList(!Config().getShowTagList()); + + // Apply for the current page, if any + if ((pPage = (EditorPage*)currentPage()) != NULL) { + pPage->setLayout(Config().getShowTagList(), + Config().getEditorSizes()); + } +} + +/** + * Handles drag events over an empty tab widget, or over the tab bar. + * The event is accepted if the dragged object is a list of file paths. + * @param pEvent The drag move event object + */ +void EditorTabs::dragMoveEvent(QDragMoveEvent* pEvent) +{ + KURL::List list; + bool bAccept; + + bAccept = KURLDrag::decode(pEvent, list); + pEvent->accept(bAccept); +} + +/** + * Handles file drops over an empty tab widget, or over the tab bar. + * @param pEvent The drop event object + */ +void EditorTabs::dropEvent(QDropEvent* pEvent) +{ + emit filesDropped(pEvent); +} + +/** + * Called when an editor tab is dragged from the tab widget. + * Initialises the drag operation with a URL that corresponds to the path of + * the file being edited in the corresponding page. + * This slot is connected to the initiateDrag() signal emitted by the tab + * widget. + * @param pWidget The page whose tab is being dragged + */ +void EditorTabs::slotInitiateDrag(QWidget* pWidget) +{ + KURL url; + KURLDrag* pDrag; + + // Create a URL list containing the appropriate file path + url.setPath(((EditorPage*)pWidget)->getFilePath()); + pDrag = new KURLDrag(KURL::List(url), this); + + // Start the drag + pDrag->dragCopy(); +} + +/** + * Changes the tab icon of a modified file. + * @param pEditPage The editor page whose file was modified + * @param bModified true if the file has changed its status to modified, + * false otherwise (i.e., when undo operations restore it + * to its original contents.) + */ +void EditorTabs::slotFileModified(EditorPage* pEditPage, bool bModified) +{ + if (bModified) + setTabIconSet(pEditPage, Pixmaps().getPixmap(KScopePixmaps::TabSave)); + else + setTabIconSet(pEditPage, Pixmaps().getPixmap(KScopePixmaps::TabRW)); +} + +/** + * Counts the number of pages containing modified files. + * @return The number of modified files + */ +int EditorTabs::getModifiedFilesCount() +{ + int i, nResult; + + // Iterate through pages + for (i = 0, nResult = 0; i < count(); i++) { + if (((EditorPage*)page(i))->isModified()) + nResult++; + } + + return nResult; +} + +/** + * Saves all files open for editing. + */ +void EditorTabs::slotSaveAll() +{ + int i; + + // Iterate through pages + for (i = 0; i < count(); i++) + ((EditorPage*)page(i))->save(); +} + +/** + * Selects the page to the left of the current one. + */ +void EditorTabs::slotGoLeft() +{ + int nIndex; + + nIndex = currentPageIndex(); + if (nIndex > 0) { + nIndex--; + setCurrentPage(nIndex); + } +} + +/** + * Selects the page to the right of the current one. + */ +void EditorTabs::slotGoRight() +{ + int nIndex; + + nIndex = currentPageIndex(); + if (nIndex < count() - 1) { + nIndex++; + setCurrentPage(nIndex); + } +} + +/** + * Fills the main window's "Window" menu with the current list of file tabs. + * This slot is attached to the aboutToShow() signal, emitted by the Window + * popup menu. + */ +void EditorTabs::slotFillWindowMenu() +{ + QString sLabel; + int i; + + // Delete old menu items + // NOTE: We can't use aboutToHide() to do that, since it is emitted + // _before_ the activated() signal + for (i = 0; i < m_nWindowMenuItems; i++) + m_pWindowMenu->removeItem(i); + + // Add new items + for (i = 0; i < count(); i++) { + sLabel = (i < 10) ? QString("&%1 %2").arg(i).arg(label(i)) : label(i); + m_pWindowMenu->insertItem(sLabel, i); + } + + // Store the number of items added + m_nWindowMenuItems = i; +} + +/** + * Sets the current page to the given one. + * This slot is attached to the activated() signal, emitted by the "Window" + * popup menu. The tab number to switch to is given by the menu item ID. + * Note that we do not trust setCurrentPage() to filter out the IDs of other + * menu items (which are supposed to be negative numbers). + */ +void EditorTabs::slotSetCurrentPage(int nId) +{ + if (nId >= 0 && nId < count()) + setCurrentPage(nId); +} + +/** + * Closes an edited file, and removes its page. + * Once a file has been closed, its page is removed from the tab widget stack, + * its menu item in the "Windows" menu is deleted and all other references to + * it are removed. + * Note that the operation may fail if the user chooses not to close the file + * when prompted for unsaved changes. + * @param pPage The EditorPage object to remove + * @param bForce true to close the page even if there are unsaved changes, + * false otherwise + * @return true if the page was removed, false otherwise + */ +bool EditorTabs::removePage(QWidget* pPage, bool bForce) +{ + EditorPage* pEditPage; + QString sFilePath; + + // Store the file path for later + pEditPage = (EditorPage*)pPage; + sFilePath = pEditPage->getFilePath(); + + // Close the edited file (may fail if the user aborts the action) + if (!pEditPage->close(bForce)) + return false; + + // Remove the page and all references to it + m_mapEdit.remove(sFilePath); + TabWidget::removePage(pPage); + + // Update the new state if no other page exists (if another page has + // become active, it will update the new state, so there is no need for + // special handling) + if (currentPage() == NULL) + slotCurrentChanged(NULL); + + // Notify the page has been removed + emit editorRemoved(pEditPage); + return true; +} + +#include "editortabs.moc" diff --git a/src/editortabs.h b/src/editortabs.h new file mode 100644 index 0000000..67d0c17 --- /dev/null +++ b/src/editortabs.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef EDITORTABS_H +#define EDITORTABS_H + +#include +#include +#include "tabwidget.h" +#include "editorpage.h" +#include "projectmanager.h" + +typedef QMap EditorMap; +class QueryView; + +/** + * A tab widget that holds several editor windows. + * This class provides the main widget in the KScope window. All editors are + * opened as pages of the tab widgets. + * @author Elad Lahav + */ + +class EditorTabs : public TabWidget +{ + Q_OBJECT + +public: + EditorTabs(QWidget* pParent = 0, const char* szName = 0); + ~EditorTabs(); + + void setWindowMenu(QPopupMenu*); + void addEditorPage(EditorPage*); + EditorPage* findEditorPage(const QString&, bool bForceChange = false); + EditorPage* getCurrentPage(); + void removeCurrentPage(); + bool removeAllPages(); + void applyPrefs(); + void getOpenFiles(FileLocationList&); + void getBookmarks(FileLocationList&); + void setBookmarks(FileLocationList&); + void showBookmarks(QueryView*); + +public slots: + void slotRemovePage(QWidget*); + void slotToggleTagList(); + void slotSaveAll(); + void slotGoLeft(); + void slotGoRight(); + +signals: + /** + * Emitted when the current editor page changes. + * @param pOld The previous current page + * @param pNew The new current page + */ + void editorChanged(EditorPage* pOld, EditorPage* pNew); + + /** + * Emitted when an editor page is closed. + * @param pPage The removed page + */ + void editorRemoved(EditorPage* pPage); + + /** + * Indicates that files were dragged and dropped over the tab widget. + * @param pEvent The drop event information + */ + void filesDropped(QDropEvent* pEvent); + +protected: + virtual void dragMoveEvent(QDragMoveEvent*); + virtual void dropEvent(QDropEvent*); + +private: + /** Links a file name with an editor page that has this file open. */ + EditorMap m_mapEdit; + + /** We need to keep track of the current page in order to implement the + editorChanged() signal. */ + EditorPage* m_pCurPage; + + /** A popup menu with Cscope operations for the editor windows. */ + QPopupMenu* m_pWindowMenu; + + /** The number of items added to the window menu (used for removing old + items). */ + int m_nWindowMenuItems; + + /** A counter for creating unique tab captions for new files. */ + int m_nNewFiles; + + int getModifiedFilesCount(); + bool removePage(QWidget*, bool); + +private slots: + void slotCurrentChanged(QWidget*); + void slotAttachFile(EditorPage*, const QString&); + void slotNewFile(EditorPage*); + void slotFileModified(EditorPage*, bool); + void slotInitiateDrag(QWidget*); + void slotFillWindowMenu(); + void slotSetCurrentPage(int); +}; + +#endif diff --git a/src/encoder.cpp b/src/encoder.cpp new file mode 100644 index 0000000..5d04744 --- /dev/null +++ b/src/encoder.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sf.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#include "qstring.h" +#include "encoder.h" + +#define CHAR_TO_HEX(c) ((c) < 0xA ? '0' + (c) : ('A' - 0xA) + (c)) +#define HEX_TO_CHAR(h) ((h) > 'A' ? (h) - ('A' - 0xA) : (h) - '0') + +/** + * Class constructor. + */ +Encoder::Encoder() : m_pBuf(NULL), m_nBufLen(0) +{ +} + +/** + * Class destructor. + */ +Encoder::~Encoder() { + if (m_pBuf) + delete[] m_pBuf; +} + +/** + * Encodes a string. + * @param str The string to encode + * @return The hex-encoded ASCII string + */ +const char* Encoder::encode(const QString& str) +{ + const char* szStr; + int nLen, i, j; + + szStr = str.latin1(); + nLen = str.length(); + + // Ensure the buffer is big enough to contain the result + resize((nLen * 2) + 1); + + // Encode the string + for (i = 0, j = 0; i < nLen; i++, j += 2) { + m_pBuf[j] = CHAR_TO_HEX(szStr[i] >> 4); + m_pBuf[j + 1] = CHAR_TO_HEX(szStr[i] & 0x0f); + } + + m_pBuf[j] = 0; + return m_pBuf; +} + +/** + * Decodes a string. + * @param str The string to decode + * @return The decoded string. + */ +const char* Encoder::decode(const QString& str) +{ + const char* szStr; + int nLen, i, j; + + szStr = str.latin1(); + nLen = str.length(); + + // Ensure the buffer is big enough to contain the result + nLen /= 2; + resize(nLen + 1); + + // Decode the string + for (i = 0, j = 0; i < nLen; i++, j += 2) { + m_pBuf[i] = HEX_TO_CHAR(szStr[j]) << 4; + m_pBuf[i] |= HEX_TO_CHAR(szStr[j + 1]); + } + + m_pBuf[i] = 0; + return m_pBuf; +} + +/** + * Sets a new size to the buffer. + * @param nNewLen The new size of the buffer + */ +void Encoder::resize(int nNewLen) +{ + if (m_nBufLen < nNewLen) { + if (m_pBuf) + delete[] m_pBuf; + + m_pBuf = new char[nNewLen]; + } +} diff --git a/src/encoder.h b/src/encoder.h new file mode 100644 index 0000000..2e35cde --- /dev/null +++ b/src/encoder.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sf.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef __ENCODER_H +#define __ENCODER_H + +/** + * Translates strings to hex-encoded ASCII, and vice-versa. + * @author Elad Lahav + */ +class Encoder +{ +public: + Encoder(); + ~Encoder(); + const char* encode(const QString&); + const char* decode(const QString&); + +private: + /** A buffer to contain the result of encoding/decoding. */ + char* m_pBuf; + + /** The buffer's length. */ + int m_nBufLen; + + void resize(int); +}; + +#endif diff --git a/src/file_ro.png b/src/file_ro.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0d29d760d37e78d0ce975bc20f681369335a84 GIT binary patch literal 892 zcmV-?1B3jDP)g`JI!TT@Mjg8>Qr2O9R{*FT28e;63<-ha%%!_CQc_rdf1PoBLDWoKtU zfUFiEfS4Gt07gbe2B1X@j7^5sJtOdUV~VRZq>b|#=V{`~&KplhJP@aqRKFhBof zc=!A{11l>V!>JQT;c5W_2;qW%e;F9ApJHIRd6wZHkoyPdk3X!e3}5cuV_@nkVqo37 zj)9en8|W=o24-evxHf zQ|=hUZ*4OMCNXJXAR}B05I_h6B$XK$J1ZC%UVmixYh=Ojk6W05_3RA>VINlp z_H95HadJUzN4NkWfZ(yfa%2Ys>(mYgh8J%benloTd|tSd;cM?KhW~v049u@yF$fgr zGBCY*!SEj#jmQ8XfDm3Vb7Ek0@?-cfqr&hjr4XDSe*5||d|17afvc>5;cI#p!#`f2 zVZgM3>;-@TVu7V=Zb3c{w_fL{F1!2R_X0}Bf)N+1FR z5X;9;pT4$rPX5Eh!~)F+|A0PZ0&4yTHsC)rXZ#0q{sT2LF?{(1OqNgp5MTgah5&9K SO7D080000z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ-{YgYYRCwBA?C^QBY98uxj&Xh9{4I zGW`DfkKxxhApZK7;U^G-_#pbBe+-{Le+Ih-WGFHK2q3soApe3eNHG@|7sLDa@4*;kz{igt!C?a8v$C?H zxBwu4;KqSM9Hc-;M~6X5N(vlsckkY1U}tA%`1$iE0}l@m10NqBSR7<1$Py3$2q3rt zA|fIT{QUgjzysN$rltmV5lA!0=^%r4?%atH-~a&xHvnV6{{8>=@8ADv%Z~mJ$)5fH z#KlKoK03a7@9qEM+79gQtT&gPo-|gSM&^Rs(+g_`&ex z;bVs1zkmG&@c{w|V!$_$KYuYi`}K>##zYlp`(K9F@4qrUd;JH@{s(l;?|=UozI^`5 zaPstZhEJb9F#x>-HV_~HhjWYrAP59e^xyxM6jX-An2oTbA+8jY-@VKR+y|kTQqRQ1 zn87{&D&gRA$BvFQLm{5rTKfQ>0D>3*4E4`IL;eFH9}hbND=Q-dGb01Tf1r!L|NF(j z`12 z@&hRPpJCzZJq*__U4a__5J1pCgv9aBAAcEMz5EGu5zuB}lzazi28x3W`14!<#qn7=*akf!_HB=70YV(F8N-`}gk*OpHuG{#Rf?ego=)!~#G7L1WJ0tjNjr!TA@UcO;?$Gsl>91cufEcLhKO@73*RL7=eg6d1#mEZM3lKnzpuphg_qfNz_+N;D z@izlEHwQS8{Qdh6Yzrt!gVewh&eyLWfvNB_kj45An3 +#include +#include +#include "filelist.h" +#include "kscope.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +FileList::FileList(QWidget* pParent, const char* szName) : + SearchList(1, pParent, szName), + m_sRoot("/") +{ + // Set the list's columns + m_pList->addColumn(""); + m_pList->addColumn(i18n("File")); + m_pList->addColumn(i18n("Path")); + + // Sort only when asked to by the user + if (Config().getAutoSortFiles()) + m_pList->setSortColumn(1); + else + m_pList->setSortColumn(m_pList->columns() + 1); + + m_pList->setAllColumnsShowFocus(true); + + // Set colours and font + applyPrefs(); +} + +/** + * Class destructor. + */ +FileList::~FileList() +{ +} + +/** + * Adds a single entry to the file list. + * Implements the addItem() virtual method of the FileListTarget base + * class. When a FileList object is given as a parameter to + * ProjectManager::fillList(), this method is called for each file included + * in the project. A new list item is created, containing the file's name and + * path, and is added to the list. + * @param sFilePath The full path of a source file + */ +void FileList::addItem(const QString& sFilePath) +{ + QString sFileType, sFileName, sPath; + int nTypePos; + + // Extract the file name + sFileName = sFilePath.mid(sFilePath.findRev('/') + 1); + + // Get the file's extension (empty string for file names without an + // extension) + nTypePos = sFileName.findRev('.'); + if (nTypePos > -1) + sFileType = sFileName.mid(nTypePos + 1); + + // If a root path has been set, use a $ sign instead of that part of the + // path + sPath = sFilePath; + if (m_sRoot != "/") + sPath.replace(m_sRoot, "$"); + + // Create the list item + new QListViewItem(m_pList, sFileType, sFileName, sPath); +} + +/** + * Searches the list for the given file path. + * @param sPath The full path of the file to find + * @return true if the file was found in the list, false otherwise + */ +bool FileList::findFile(const QString& sPath) +{ + QString sFindPath(sPath); + + if (m_sRoot != "/") + sFindPath.replace(m_sRoot, "$"); + + return (m_pList->findItem(sFindPath, 2) != NULL); +} + +/** + * Removes all items from the file list. + */ +void FileList::clear() +{ + m_pList->clear(); + m_pEdit->setText(""); +} + +/** + * Opens a file for editing when its entry is clicked in the file list. + * @param pItem The clicked list item + */ +void FileList::processItemSelected(QListViewItem* pItem) +{ + QString sPath; + + // Get the file path (replace the root symbol, if required) + sPath = pItem->text(2); + if (sPath.startsWith("$")) + sPath.replace("$", m_sRoot); + + // Submit a request to open the file for editing + emit fileRequested(sPath, 0); +} + +/** + * Sets the list's colours and font, according the user's preferences. + */ +void FileList::applyPrefs() +{ + // Apply colour settings + m_pList->setPaletteBackgroundColor(Config().getColor( + KScopeConfig::FileListBack)); + m_pList->setPaletteForegroundColor(Config().getColor( + KScopeConfig::FileListFore)); + m_pList->setFont(Config().getFont(KScopeConfig::FileList)); +} + +/** + * Associates a root directory with this list. + * For each file in the list, the part of the path corresponding to the root + * is replaced with a $ sign. + * @param sRoot The new root path + */ +void FileList::setRoot(const QString& sRoot) +{ + QListViewItem* pItem; + QString sPath; + + // Update all items in the list + for (pItem = m_pList->firstChild(); pItem != NULL; + pItem = pItem->nextSibling()) { + sPath = pItem->text(2); + + // Restore the full path + sPath.replace("$", m_sRoot); + + // Replace the root with a $ sign + if (sRoot != "/") + sPath.replace(sRoot, "$"); + + pItem->setText(2, sPath); + } + + // Store the new root + m_sRoot = sRoot; +} + +/** + * Constructs a tool-tip for the given item. + * @param pItem The item for which a tip is required + * @param sTip The constructed tip string (on return) + * @return Always true + */ +bool FileList::getTip(QListViewItem* pItem, QString& sTip) +{ + sTip = pItem->text(2); + return true; +} + +#include "filelist.moc" diff --git a/src/filelist.h b/src/filelist.h new file mode 100644 index 0000000..8585dc6 --- /dev/null +++ b/src/filelist.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef FILELIST_H +#define FILELIST_H + +#include +#include "searchlist.h" +#include "projectmanager.h" + +/** + * Implements a searchable list of files. + * The file list is composed of a list view, and a search box, into which the + * user can enter a file name. The name is matched against the contents of + * the list, and matching items are selected. + * @author Elad Lahav + */ + +class FileList : public SearchList, public FileListTarget +{ + Q_OBJECT + +public: + FileList(QWidget* pParent = 0, const char* szName = 0); + ~FileList(); + + virtual void addItem(const QString&); + bool findFile(const QString&); + void clear(); + void applyPrefs(); + void setRoot(const QString&); + virtual bool getTip(QListViewItem*, QString&); + +signals: + /** + * Emitted when a file is selected, by either double-clicking a list + * item, or by highlighting an item and pressing the ENTER key. + * @param sPath The full path of the selected file + * @param nLine Line number, always set to 0 + */ + void fileRequested(const QString& sPath, uint nLine); + +protected: + virtual void processItemSelected(QListViewItem*); + +private: + /** A common root path for all items in the list. */ + QString m_sRoot; +}; + +#endif diff --git a/src/fileview.cpp b/src/fileview.cpp new file mode 100644 index 0000000..029c20a --- /dev/null +++ b/src/fileview.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "fileview.h" +#include "filelist.h" +#include "kscopepixmaps.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + * @param fl Widget creation flags + */ +FileView::FileView(QWidget* pParent, const char* szName, WFlags fl) : + FileViewLayout(pParent, szName, fl), + m_pCurBranch(0), + m_sRoot("") +{ + QWidget* pPage; + + // Set the tab widget icons + pPage = m_pTabWidget->page(0); + m_pTabWidget->setTabIconSet(pPage, GET_PIXMAP(TabFileList)); + pPage = m_pTabWidget->page(1); + m_pTabWidget->setTabIconSet(pPage, GET_PIXMAP(TabFileTree)); + + // Create a single column for the file tree + m_pFileTree->addColumn(""); + + // Send the fileRequested() signal whenever a file is selected in either + // the list or the tree + connect(m_pFileList, SIGNAL(fileRequested(const QString&, uint)), this, + SIGNAL(fileRequested(const QString&, uint))); + connect(m_pFileTree, SIGNAL(doubleClicked(QListViewItem*)), + this, SLOT(slotTreeItemSelected(QListViewItem*))); + connect(m_pFileTree, SIGNAL(returnPressed(QListViewItem*)), this, + SLOT(slotTreeItemSelected(QListViewItem*))); +} + +/** + * Class destructor. + */ +FileView::~FileView() +{ +} + +/** + * Sets a new common root path to both the file list and the tree. + * @param sRoot The full path of the new root + */ +void FileView::setRoot(const QString& sRoot) +{ + // Nothing to do if the given root is the same as the old one + if (sRoot == m_sRoot) + return; + + m_sRoot = sRoot; + + // Remove the current branch + if (m_pCurBranch) + m_pFileTree->removeBranch(m_pCurBranch); + + // Update the file list + m_pFileList->setRoot(sRoot); + + // Nothing more to do for an empty root directory + if (sRoot.isEmpty()) + return; + + // Create and open a new branch, with the newly specified root + QFileInfo fi(sRoot); + m_pCurBranch = m_pFileTree->addBranch(KURL(sRoot), fi.fileName()); + m_pCurBranch->setChildRecurse(false); + m_pFileTree->setOpen(m_pCurBranch->root(), true); +} + +/** + * Clears the contents of the file view and file tree. + */ +void FileView::clear() +{ + m_pFileList->clear(); + setRoot(""); +} + +/** + * Emits the fileRequested() signal when a file name is selected in the file + * tree. An item is selected by either double-clicking it or by hittin + * "ENTER" when it is highlighted. + * This slot is connected to the doubleClicked() and returnPressed() signals + * of the KFileTreeView object. + * @param pItem The selected tree item + */ +void FileView::slotTreeItemSelected(QListViewItem* pItem) +{ + KFileTreeViewItem* pTreeItem; + + pTreeItem = (KFileTreeViewItem*)pItem; + if (pTreeItem && !pTreeItem->isDir()) + emit fileRequested(pTreeItem->path(), 0); +} + +#include "fileview.moc" diff --git a/src/fileview.h b/src/fileview.h new file mode 100644 index 0000000..5fc1fe3 --- /dev/null +++ b/src/fileview.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef FILEVIEW_H +#define FILEVIEW_H + +#include +#include "fileviewlayout.h" + +/** + * A tabbed widget that contains a file list and a file tree. + * The list is an object of type FileList, which displays all files included + * in the current project. The tree is a standard KFileTreeView, which can + * browse through the entire file system. Optionally, the root of the tree + * can be set per project. + * @author Elad Lahav + */ + +class FileView : public FileViewLayout +{ + Q_OBJECT + +public: + FileView(QWidget* pParent = 0, const char* szName = 0, WFlags fl = 0); + ~FileView(); + + /** + * @return The file list widget which is a child of this widget. + */ + FileList* getFileList() { return m_pFileList; } + + void setRoot(const QString&); + void clear(); + +signals: + /** + * Emitted when a file is selected, by either double-clicking a list + * item, or by highlighting an item and pressing the ENTER key. + * @param sPath The full path of the selected file + * @param nLine Line number, always set to 0 + */ + void fileRequested(const QString& sPath, uint nLine); + +private: + /** The current branch in the file tree. */ + KFileTreeBranch* m_pCurBranch; + + /** The current root of the file tree. */ + QString m_sRoot; + +private slots: + void slotTreeItemSelected(QListViewItem*); +}; + +#endif + diff --git a/src/fileviewlayout.ui b/src/fileviewlayout.ui new file mode 100644 index 0000000..24bb1f5 --- /dev/null +++ b/src/fileviewlayout.ui @@ -0,0 +1,136 @@ + +FileViewLayout + + + FileViewLayout + + + + 0 + 0 + 364 + 639 + + + + Form1 + + + + unnamed + + + 0 + + + 0 + + + + m_pTabWidget + + + + + + + tab + + + + + + + unnamed + + + 0 + + + 0 + + + + m_pFileList + + + Project File List + + + + + + + tab + + + + + + + unnamed + + + 0 + + + 0 + + + + m_pFileTree + + + File Tree + + + + + + + + + + FileList +
    filelist.h
    + + -1 + -1 + + 0 + + 7 + 7 + 0 + 0 + + image0 +
    + + KFileTreeView +
    kfiletreeview.h
    + + -1 + -1 + + 0 + + 7 + 7 + 0 + 0 + + image0 +
    +
    + + + 789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f + + + + + filelist.h + kfiletreeview.h + +
    diff --git a/src/frontend.cpp b/src/frontend.cpp new file mode 100644 index 0000000..fee1c1b --- /dev/null +++ b/src/frontend.cpp @@ -0,0 +1,365 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include "frontend.h" + +/** + * Class constructor. + * @param nRecordSize The number of fields in each record + * @param bAutoDelete (Optional) true to delete the object when the process + * terminates, false (default) otherwise + */ +Frontend::Frontend(uint nRecordSize, bool bAutoDelete) : KProcess(), + m_nRecords(0), + m_pHeadToken(NULL), + m_pTailToken(NULL), + m_pCurToken(NULL), + m_bAutoDelete(bAutoDelete), + m_bInToken(false), + m_nRecordSize(nRecordSize) +{ + // Parse data on the standard output + connect(this, SIGNAL(receivedStdout(KProcess*, char*, int)), this, + SLOT(slotReadStdout(KProcess*, char*, int))); + + // Parse data on the standard error + connect(this, SIGNAL(receivedStderr(KProcess*, char*, int)), this, + SLOT(slotReadStderr(KProcess*, char*, int))); + + // Delete the process object when the process exits + connect(this, SIGNAL(processExited(KProcess*)), this, + SLOT(slotProcessExit(KProcess*))); +} + +/** + * Class destructor. + */ +Frontend::~Frontend() +{ + // Delete all pending tokens + while (m_pHeadToken) + removeToken(); +} + +/** + * Executes the back-end process. + * @param sName The name of the process (for error messages) + * @param slArgs A list containing the command-line arguments + * @param sWorkDir (Optional) working directory + * @param bBlock (Optional) true to block, false otherwise + * @return true if the process was executed successfully, false otherwise + */ +bool Frontend::run(const QString& sName, const QStringList& slArgs, + const QString& sWorkDir, bool bBlock) +{ + // Cannot start if another controlled process is currently running + if (isRunning()) { + m_sError = i18n("Cannot restart while another process is still " + "running"); + return false; + } + + // Reset variables + m_nRecords = 0; + m_bKilled = false; + + // Setup the command-line arguments + clearArguments(); + *this << slArgs; + + // Set the working directory, if requested + if (!sWorkDir.isEmpty()) + setWorkingDirectory(sWorkDir); + + // Execute the child process + if (!start(bBlock ? KProcess::Block : KProcess::NotifyOnExit, + KProcess::All)) { + m_sError = sName + i18n(": Failed to start process"); + return false; + } + + m_sError = i18n("No error"); + return true; +} + +/** + * Kills the process, and emits the aborted() signal. + * This function should not be called unless the process needs to be + * interrupted. + */ +void Frontend::kill() +{ + m_bKilled = true; + KProcess::kill(); + + emit aborted(); +} + +/** + * Appends a token to the end of the token list. + * @param pToken The token to add + */ +void Frontend::addToken(FrontendToken* pToken) +{ + // Check if this is the firt token + if (m_pHeadToken == NULL) { + m_pHeadToken = pToken; + m_pTailToken = pToken; + } + else { + // Not the first token, append and reset the tail token + m_pTailToken->m_pNext = pToken; + m_pTailToken = pToken; + } +} + +/** + * Removes and deletes the token at the head of the token list. + */ +void Frontend::removeToken() +{ + FrontendToken* pToken; + + if (m_pHeadToken == NULL) + return; + + pToken = m_pHeadToken; + m_pHeadToken = m_pHeadToken->m_pNext; + delete pToken; + + if (m_pHeadToken == NULL) + m_pTailToken = NULL; +} + +/** + * Removes tokens from the head of the list, according to the size of a + * record. + */ +void Frontend::removeRecord() +{ + uint i; + + for (i = 0; (i < m_nRecordSize) && (m_pHeadToken != NULL); i++) + removeToken(); +} + +/** + * Extracts tokens of text out of a given buffer. + * @param ppBuf Points to the buffer to parse, and is set to the + * beginning of the next token, upon return + * @param pBufSize Points to the size of the buffer, and is set to the + * remaining size, upon return + * @param sResult Holds the token's text, upon successful return + * @param delim Holds the delimiter by which the token's end was + * determined + * @return true if a token was extracted up to the given delimter(s), false + * if the buffer ended before a delimiter could be identified + */ +bool Frontend::tokenize(char** ppBuf, int* pBufSize, QString& sResult, + ParserDelim& delim) +{ + int nSize; + char* pBuf; + bool bDelim, bWhiteSpace, bFoundToken = false; + + // Iterate buffer + for (nSize = *pBufSize, pBuf = *ppBuf; (nSize > 0) && !bFoundToken; + nSize--, pBuf++) { + // Test if this is a delimiter character + switch (*pBuf) { + case '\n': + bDelim = ((m_delim & Newline) != 0); + bWhiteSpace = true; + delim = Newline; + break; + + case ' ': + bDelim = ((m_delim & Space) != 0); + bWhiteSpace = true; + delim = Space; + break; + + case '\t': + bDelim = ((m_delim & Tab) != 0); + bWhiteSpace = true; + delim = Tab; + break; + + default: + bDelim = false; + bWhiteSpace = false; + } + + if (m_bInToken && bDelim) { + m_bInToken = false; + *pBuf = 0; + bFoundToken = true; + } + else if (!m_bInToken && !bWhiteSpace) { + m_bInToken = true; + *ppBuf = pBuf; + } + } + + // Either a token was found, or the search through the buffer was + // finished without a delimiter character + if (bFoundToken) { + sResult = *ppBuf; + *ppBuf = pBuf; + *pBufSize = nSize; + } + else if (m_bInToken) { + sResult = QString::fromLatin1(*ppBuf, *pBufSize); + } + else { + sResult = QString::null; + } + + return bFoundToken; +} + +/** + * Handles text sent by the back-end process to the standard error stream. + * By default, this method emits the error() signal with the given text. + * @param sText The text sent to the standard error stream + */ +void Frontend::parseStderr(const QString& sText) +{ + emit error(sText); +} + +/** + * Deletes the process object upon the process' exit. + */ +void Frontend::slotProcessExit(KProcess*) +{ + // Allow specialised clean-up by inheriting classes + finalize(); + + // Signal the process has terminated + emit finished(m_nRecords); + + // Delete the object, if required + if (m_bAutoDelete) + delete this; +} + +/** + * Reads data written on the standard output by the controlled process. + * This is a private slot called attached to the readyReadStdout() signal of + * the controlled process, which means that it is called whenever data is + * ready to be read from the process' stream. + * The method reads whatever data is queued, and sends it to be interpreted + * by parseStdout(). + */ +void Frontend::slotReadStdout(KProcess*, char* pBuffer, int nSize) +{ + char* pLocalBuf; + QString sToken; + bool bTokenEnded; + ParserDelim delim; + + // Do nothing if waiting for process to die + if (m_bKilled) + return; + + pLocalBuf = pBuffer; + + // Iterate over the given buffer + while (nSize > 0) { + // Create a new token, if the last iteration has completed one + if (m_pCurToken == NULL) + m_pCurToken = new FrontendToken(); + + // Extract text until the requested delimiter + bTokenEnded = tokenize(&pLocalBuf, &nSize, sToken, delim); + + // Add the extracted text to the current token + m_pCurToken->m_sData += sToken; + + // If the buffer has ended before the requested delimiter, we need + // to wait for more output from the process + if (!bTokenEnded) + return; + + // Call the process-specific parser function + switch (parseStdout(m_pCurToken->m_sData, delim)) { + case DiscardToken: + // Token should not be saved + delete m_pCurToken; + break; + + case AcceptToken: + // Store token in linked list + addToken(m_pCurToken); + break; + + case RecordReady: + // Store token, and notify the target object that an entry can + // be read + m_nRecords++; + addToken(m_pCurToken); + emit dataReady(m_pHeadToken); + + // Delete all tokens in the entry + removeRecord(); + break; + + case Abort: + kill(); + nSize = 0; + break; + } + + m_pCurToken = NULL; + } +} + +/** + * Reads data written on the standard error by the controlled process. + * This is a private slot called attached to the readyReadStderr() signal of + * the controlled process, which means that it is called whenever data is + * ready to be read from the process' stream. + * The method reads whatever data is queued, and sends it to be interpreted + * by parseStderr(). + */ +void Frontend::slotReadStderr(KProcess*, char* pBuffer, int nSize) +{ + QString sBuf; + + // Do nothing if waiting for process to die + if (m_bKilled) + return; + + sBuf.setLatin1(pBuffer, nSize); + parseStderr(sBuf); +} + +#include "frontend.moc" diff --git a/src/frontend.h b/src/frontend.h new file mode 100644 index 0000000..246128a --- /dev/null +++ b/src/frontend.h @@ -0,0 +1,212 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef FRONTEND_H +#define FRONTEND_H + +#include +#include + + +/** + * Represents a single token in the parsed output stream. + * @author Elad Lahav + */ + +class FrontendToken +{ +public: + /** + * Class constructor. + */ + FrontendToken() : m_pNext(NULL) {} + + /** + * @return The text associated with this token + */ + const QString& getData() const { return m_sData; } + + /** + * @return A pointer to the next token in the strem. + */ + FrontendToken* getNext() const { return m_pNext; } + +protected: + /** Free text associated with the token. */ + QString m_sData; + + /** A pointer to the next token in the stream. */ + FrontendToken* m_pNext; + + friend class Frontend; +}; + +/** + * Abstract base class that provides a front-end to console-based programmes. + * Provides a parsing infrastructure which is based on a list of records, all + * of the same structure. Each record is composed of a number of delimited + * fields (tokens.) + * @author Elad Lahav + */ + +class Frontend : public KProcess +{ + Q_OBJECT + +public: + Frontend(uint, bool bAutoDelete = false); + ~Frontend(); + + virtual bool run(const QString&, const QStringList&, + const QString& sWorkDir = "", bool bBlock = false); + void kill(); + + /** + * @return An string describing the error which made run() fail + */ + const QString& getRunError() { return m_sError; } + +signals: + /** + * Indicates tokens can be read. + * The Frontend object parses the back-end output and creates a list of + * tokens. This signal is emitted when a batch of characters has been + * converted into a token list. + * @param pToken The head of the token list + */ + void dataReady(FrontendToken* pToken); + + /** + * Emitted when the back-end process terminates. + * @param nRecords The number of complete records parsed + */ + void finished(uint nRecords); + + /** + * Indicates that the Cscope process was terminated. + */ + void aborted(); + + /** + * This signal is used to report the progress of the back-end process. + * @param nProgress The current progress value + * @param nTotal The progress value that indicates the process + * is finished + */ + void progress(int nProgress, int nTotal); + + /** + * Emitted when an error message is produced by the back-end process. + */ + void error(const QString& sMsg); + +protected: + /** A set of possible delimiters for parsing process output. */ + enum ParserDelim { Newline = 0x01, Space = 0x02, Tab = 0x04, + WSpace = Space | Tab, All = WSpace | Newline }; + + /** Defines the set of return values for parseStdout(). Determines what + needs to be done with a new token passed to this method. */ + enum ParseResult { + DiscardToken /** Delete this token */, + AcceptToken /** Add this token to the list */, + RecordReady /** This token completes a record */, + Abort /** Kill the process */ + }; + + /** Number of complete records read so far. */ + uint m_nRecords; + + /** The head of the list of parsed output tokens. */ + FrontendToken* m_pHeadToken; + + /** The tail of the list of parsed output tokens. */ + FrontendToken* m_pTailToken; + + /** An iterator on the list of parsed output tokens. */ + FrontendToken* m_pCurToken; + + /** The current delimiters used for parsing the output. */ + ParserDelim m_delim; + + /** An error string produced if run() fails. */ + QString m_sError; + + /** + * Handles a text token received on the Standard Output stream of the + * controlled process. + * This is called by slotReadStdout whenever a new token is recognised. + * Inheriting classes should implement this method to parse the resutling + * stream of tokens. + * @param sToken A part of the text received on the Standard Output, + * disected according to current delimiter settings + * @param delim The delimiter that ended this token + * @result A ParseResult value, indicating what should be done with the + * new token + */ + virtual ParseResult parseStdout(QString& sToken, ParserDelim delim) = 0; + + virtual void parseStderr(const QString&); + + /** + * Called when the process exits. + * Allows inheriting classes to implement process termination handlers. + */ + virtual void finalize() {} + +protected slots: + virtual void slotProcessExit(KProcess*); + +private: + /** Determines whether the object should be deleted once the process has + exited */ + bool m_bAutoDelete; + + /** Determines whether the parser is in the middle of a token, or between + two tokens */ + bool m_bInToken; + + /** The number of fields in each parsed record. Should be defined for + every sub-class. */ + uint m_nRecordSize; + + /** This flag is raised when kill() is called. It signifies that even + though the process may not be dead yet, it should be considered as + such. */ + bool m_bKilled; + + void addToken(FrontendToken*); + void removeToken(); + void removeRecord(); + bool tokenize(char**, int*, QString&, ParserDelim&); + +private slots: + void slotReadStdout(KProcess*, char*, int); + void slotReadStderr(KProcess*, char*, int); +}; + +#endif diff --git a/src/graphedge.cpp b/src/graphedge.cpp new file mode 100644 index 0000000..283a5fe --- /dev/null +++ b/src/graphedge.cpp @@ -0,0 +1,306 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include "graphedge.h" +#include "graphnode.h" + +int GraphEdge::RTTI = 1002; + +// Some definitions required by the ConvexHull class +typedef int (*CompFunc)(const void*, const void*); +#define ISLEFT(P0, P1, P2) \ + (P1.x() - P0.x()) * (P2.y() - P0.y()) - \ + (P2.x() - P0.x()) * (P1.y() - P0.y()) +#define FARTHEST(P0, P1, P2) \ + ((P1.x() - P0.x()) * (P1.x() - P0.x()) - \ + (P1.y() - P0.y()) * (P1.y() - P0.y())) - \ + ((P2.x() - P0.x()) * (P2.x() - P0.x()) - \ + (P2.y() - P0.y()) * (P2.y() - P0.y())) + + +/** + * An array of QPoint objects that can compute the convex hull surrounding all + * points in the array. + * @author Elad Lahav + */ +class ConvexHull : public QPointArray +{ +public: + /** + * Class constructor. + */ + ConvexHull() : QPointArray() {} + + /** + * Computes the convex hull of the points stored in the array, using + * Graham's scan. + * @param arrHull Holds the coordinates of the convex hull, upon return + */ + void compute(QPointArray& arrHull) { + uint i, nPivot, nTop; + + // Find the pivot point + nPivot = 0; + for (i = 1; i < size(); i++) { + if ((*this)[i].y() < (*this)[nPivot].y()) { + nPivot = i; + } + else if ((*this)[i].y() == (*this)[nPivot].y() && + (*this)[i].x() < (*this)[nPivot].x()) { + nPivot = i; + } + } + + // Sort points in radial order, relative to the pivot + s_ptPivot = (*this)[nPivot]; + (*this)[nPivot] = (*this)[0]; + (*this)[0] = s_ptPivot; + qsort(&(*this).data()[1], (*this).size() - 1, sizeof(QPoint), + (CompFunc)compRadial); + + // Initialise Graham's scan algorithm + arrHull.resize(size() + 1); + arrHull[0] = (*this)[0]; + arrHull[1] = (*this)[1]; + nTop = 1; + + // Compute the convex hull + for (i = 2; i < size();) { + // TODO: According to the algorithm, the condition should be >0 + // for pushing the point into the stack. For some reason, it works + // only with <0. Why? + if (ISLEFT(arrHull[nTop - 1], arrHull[nTop], (*this)[i]) < 0) { + arrHull[++nTop] = (*this)[i]; + i++; + } + else { + nTop--; + } + } + + // Close the hull + arrHull[++nTop] = (*this)[0]; + arrHull.truncate(nTop + 1); + } + +private: + /** The current pivot point, required by compRadial. */ + static QPoint s_ptPivot; + + /** + * Compares two points based on their angle relative to the current + * pivot point. + * This function is passed as the comparison function of qsort(). + * @param pPt1 A pointer to the first point + * @param pPt2 A pointer to the second point + * @return >0 if the first point is to the left of the second, <0 otherwise + */ + static int compRadial(const QPoint* pPt1, const QPoint* pPt2) { + int nResult; + + // Determine which point is to the left of the other. If the angle is + // the same, the greater point is the one farther from the pivot + nResult = ISLEFT(s_ptPivot, (*pPt1), (*pPt2)); + if (nResult == 0) + return FARTHEST(s_ptPivot, (*pPt1), (*pPt2)); + + return nResult; + } +}; + +QPoint ConvexHull::s_ptPivot; + +/** + * Class constructor. + * @param pCanvas The canvas on which to draw the edge + * @param pHead The edge's starting point + * @param pTail The edge's end point + */ +GraphEdge::GraphEdge(QCanvas* pCanvas, GraphNode* pHead, GraphNode* pTail) : + QCanvasPolygonalItem(pCanvas), + m_pHead(pHead), + m_pTail(pTail), + m_arrPoly(4) +{ +} + +/** + * Class destructor. + */ +GraphEdge::~GraphEdge() +{ + // Classes derived from QCanvasPolygonalItem must call hide() in their + // detructor (according to the Qt documentation) + hide(); +} + +/** + * Calculates the area surrounding the edge, and the bounding rectangle of + * the edge's polygonal head. + * The calculated area is used to find items on the canvas and to display + * tips. The bounding rectangle defines the tip's region (@see QToolTip). + * TODO: The function assumes that the we can simply append the polygon's + * array to that of the splines. Is this always the case, or should we sort + * the points of the polygon in radial order? + * @param arrCurve The control points of the edge's spline + * @param ai Used to calculate the arrow head polygon + */ +void GraphEdge::setPoints(const QPointArray& arrCurve, const ArrowInfo& ai) +{ + ConvexHull ch; + uint i; + int nXpos, nYpos; + + // Redraw an existing edge + if (m_arrArea.size() > 0) + invalidate(); + + // Store the point array for drawing + m_arrCurve = arrCurve; + + // Calculate the arrowhead's polygon + makeArrowhead(ai); + + // Compute the convex hull of the edge + ch.resize(m_arrCurve.size() + m_arrPoly.size() - 2); + ch.putPoints(0, m_arrCurve.size() - 1, m_arrCurve); + ch.putPoints(m_arrCurve.size() - 1, m_arrPoly.size() - 1, m_arrPoly); + ch.compute(m_arrArea); + + // Calculate the head's bounding rectangle + m_rcTip = QRect(m_arrPoly[0], m_arrPoly[0]); + for (i = 1; i < m_arrPoly.size(); i++) { + nXpos = m_arrPoly[i].x(); + if (nXpos < m_rcTip.left()) + m_rcTip.setLeft(nXpos); + else if (nXpos > m_rcTip.right()) + m_rcTip.setRight(nXpos); + + nYpos = m_arrPoly[i].y(); + if (nYpos < m_rcTip.top()) + m_rcTip.setTop(nYpos); + else if (nYpos > m_rcTip.bottom()) + m_rcTip.setBottom(nYpos); + } +} + +/** + * Sets the call information associated with this edge. + * @param sFile The call's file path + * @param sLine The call's line number + * @param sText The call's text + */ +void GraphEdge::setCallInfo(const QString& sFile, const QString& sLine, + const QString& sText) +{ + m_sFile = sFile; + m_sLine = sLine; + m_sText = sText; +} + +/** + * Constructs a tool-tip string for this edge. + * @return The tool-tip text + */ +QString GraphEdge::getTip() const +{ + QString sTip; + + sTip = m_sText + "
    " + m_sFile + ":" + m_sLine; + return sTip; +} + +/** + * Draws the spline as a sequence of cubic Bezier curves. + * @param painter Used for drawing the item on the canvas view + */ +void GraphEdge::drawShape(QPainter& painter) +{ + uint i; + + // Draw the polygon + painter.drawConvexPolygon(m_arrPoly); + + // Draw the Bezier curves + for (i = 0; i < m_arrCurve.size() - 1; i += 3) + painter.drawCubicBezier(m_arrCurve, i); + +#if 0 + // Draws the convex hull of the edge + QPen pen = painter.pen(); + QBrush br = painter.brush(); + painter.setPen(QPen(QColor(255, 0, 0))); + painter.setBrush(QBrush()); + painter.drawPolygon(m_arrArea); + painter.setPen(pen); + painter.setBrush(br); +#endif +} + +/** + * Computes the coordinates of the edge's arrow head, based on its curve. + * @param ai Pre-computed values used for all edges + */ +void GraphEdge::makeArrowhead(const ArrowInfo& ai) +{ + QPoint ptLast, ptPrev; + double dX1, dY1, dX0, dY0, dX, dY, dDeltaX, dDeltaY, dNormLen; + + // The arrowhead follows the line from the second last to the last points + // in the curve + ptLast = m_arrCurve[m_arrCurve.size() - 1]; + ptPrev = m_arrCurve[m_arrCurve.size() - 2]; + + // The first and last points of the polygon are the end of the curve + m_arrPoly.setPoint(0, ptLast.x(), ptLast.y()); + m_arrPoly.setPoint(3, ptLast.x(), ptLast.y()); + + // Convert integer points to double precision values + dX1 = (double)ptLast.x(); + dY1 = (double)ptLast.y(); + dX0 = (double)ptPrev.x(); + dY0 = (double)ptPrev.y(); + + // The values (x1-x0), (y1-y0) and sqrt(1 + tan(theta)^2) are useful + dDeltaX = dX1 - dX0; + dDeltaY = dY1 - dY0; + + // The normalised length of the arrow's sides + dNormLen = ai.m_dLength / sqrt(dDeltaX * dDeltaX + dDeltaY * dDeltaY); + + // Compute the other two points + dX = dX1 - ((dDeltaX - ai.m_dTan * dDeltaY) / ai.m_dSqrt) * dNormLen; + dY = dY1 - ((dDeltaY + ai.m_dTan * dDeltaX) / ai.m_dSqrt) * dNormLen; + m_arrPoly.setPoint(1, (int)dX, (int)dY); + + dX = dX1 - ((dDeltaX + ai.m_dTan * dDeltaY) / ai.m_dSqrt) * dNormLen; + dY = dY1 - ((dDeltaY - ai.m_dTan * dDeltaX) / ai.m_dSqrt) * dNormLen; + m_arrPoly.setPoint(2, (int)dX, (int)dY); +} diff --git a/src/graphedge.h b/src/graphedge.h new file mode 100644 index 0000000..ce399b3 --- /dev/null +++ b/src/graphedge.h @@ -0,0 +1,143 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef GRAPHEDGE_H +#define GRAPHEDGE_H + +#include + +class GraphNode; + +/** + * Information used to draw arrow heads at the end of graph edges. + */ +struct ArrowInfo +{ + /** The length of the arrow. */ + double m_dLength; + + /** The tangent of the arrow's angle from the main line. */ + double m_dTan; + + /** Holds the value sqrt(1 + dTan^2). */ + double m_dSqrt; +}; + +/** + * Draws a directed edge on a canvas. + * The edge is composed of a spline, which is its body, and a polygon, which + * is its head. + * @author Elad Lahav + */ +class GraphEdge : public QCanvasPolygonalItem +{ +public: + GraphEdge(QCanvas*, GraphNode*, GraphNode*); + ~GraphEdge(); + + void setCallInfo(const QString&, const QString&, const QString&); + void setPoints(const QPointArray&, const ArrowInfo&); + QString getTip() const; + + /** + * @return The coordinates of the convex hull surrounding the edge + */ + virtual QPointArray areaPoints() const { return m_arrArea; } + + /** + * @return The head node of the edge + */ + GraphNode* getHead() { return m_pHead; } + + /** + * @return The tail node of the edge + */ + GraphNode* getTail() { return m_pTail; } + + /** + * @return The bounding rectangle of the edge's head + */ + QRect tipRect() const { return m_rcTip; } + + /** + * @return The file path for this call + */ + const QString& getFile() const { return m_sFile; } + + /** + * @return The line number for this call + */ + uint getLine() const { return m_sLine.toUInt(); } + + /** + * @return The call's text + */ + const QString& getText() const { return m_sText; } + + /** Identifies this class among other QCanvasItem classes. */ + static int RTTI; + + /** + * @return The class identifier + */ + virtual int rtti() const { return RTTI; } + +protected: + virtual void drawShape(QPainter&); + +private: + /** The edge's starting point. */ + GraphNode* m_pHead; + + /** The edge's end point. */ + GraphNode* m_pTail; + + /** The points of the polygon part of the edge. */ + QPointArray m_arrPoly; + + /** Control points for the spline part of the edge. */ + QPointArray m_arrCurve; + + QPointArray m_arrArea; + + /** The bounding rectangle of the edge's head, used for displaying the + edge's tool-tip. */ + QRect m_rcTip; + + /** The call's source file. */ + QString m_sFile; + + /** The call's line number. */ + QString m_sLine; + + /** The call's text. */ + QString m_sText; + + void makeArrowhead(const ArrowInfo&); +}; + +#endif diff --git a/src/graphnode.cpp b/src/graphnode.cpp new file mode 100644 index 0000000..28a219d --- /dev/null +++ b/src/graphnode.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "graphnode.h" + +int GraphNode::RTTI = 1001; + +/** + * Class constructor. + * @param pCanvas The owner canvas + * @param sFunc The node's function + * @param bMultiCall Whether this node represents multiple calls + */ +GraphNode::GraphNode(QCanvas* pCanvas, const QString& sFunc, bool bMultiCall) : + QCanvasPolygon(pCanvas), + m_sFunc(sFunc), + m_bMultiCall(bMultiCall), + m_bDfsFlag(false) +{ + // Every node deletes its out-edges only + m_dictOutEdges.setAutoDelete(true); +} + +/** + * Class destructor. + */ +GraphNode::~GraphNode() +{ +} + +/** + * Finds an edge leaving this node and reaching the given node. + * If such an edge does not exist, a new one is created. + * @param pTail The destination node + * @return The edge that ends at the given node + */ +GraphEdge* GraphNode::addOutEdge(GraphNode* pTail) +{ + GraphEdge* pEdge; + + // Look for the edge + if ((pEdge = m_dictOutEdges.find(pTail->getFunc())) == NULL) { + // Create a new edge + pEdge = new GraphEdge(canvas(), this, pTail); + m_dictOutEdges.insert(pTail->getFunc(), pEdge); + pTail->m_dictInEdges.replace(m_sFunc, pEdge); + } + + // Return the new/constructed edge + return pEdge; +} + +/** + * Performs a weak depth-first-search on the graph. + * The search continues along all edges, both incoming and outgoing. + */ +void GraphNode::dfs() +{ + // Stop if this node is already marked + if (m_bDfsFlag) + return; + + // Mark the node as visited + m_bDfsFlag = true; + + // Continue along outgoing edges + QDictIterator itrOut(m_dictOutEdges); + for (; itrOut.current(); ++itrOut) + (*itrOut)->getTail()->dfs(); + + // Continue along incoming edges + QDictIterator itrIn(m_dictInEdges); + for (; itrIn.current(); ++itrIn) + (*itrIn)->getHead()->dfs(); +} + +/** + * Deletes all outgoing edges. + * Uses the auto-delete property of the dictionary. + */ +void GraphNode::removeOutEdges() +{ + m_dictOutEdges.clear(); +} + +/** + * Deletes all incoming edges. + * To avoid double deletions, the function lets the head node of the edge remove + * it. + */ +void GraphNode::removeInEdges() +{ + QDictIterator itr(m_dictInEdges); + + // Delete edges through their head nodes + for (; itr.current(); ++itr) + (*itr)->getHead()->m_dictOutEdges.remove(m_sFunc); + + // remove edges from the local dictionary (will not delete them) + m_dictInEdges.clear(); +} + +/** + * Returns the first found node connected to this one. + * This function is used with multi-call nodes for retrieving the parent node. + * @param pNode + * @param bCalled + */ +void GraphNode::getFirstNeighbour(GraphNode*& pNode, bool& bCalled) +{ + QDictIterator itrIn(m_dictInEdges); + QDictIterator itrOut(m_dictOutEdges); + + if (itrIn.current()) { + pNode = itrIn.current()->getHead(); + bCalled = false; + } + else if (itrOut.current()) { + pNode = itrOut.current()->getTail(); + bCalled = true; + } + else { + pNode = NULL; + } +} + +/** + * Modifies the bounding rectangle of the node. + * @param rect The new coordinates to set + */ +void GraphNode::setRect(const QRect& rect) +{ + QPointArray arr(4); + + m_rect = rect; + + arr.setPoint(0, m_rect.topLeft()); + arr.setPoint(1, m_rect.topRight()); + arr.setPoint(2, m_rect.bottomRight()); + arr.setPoint(3, m_rect.bottomLeft()); + setPoints(arr); +} + +/** + * Draws the node. + * @param painter Used for drawing the item on the canvas view + */ +void GraphNode::drawShape(QPainter& painter) +{ + const QPen& pen = painter.pen(); + const QFont& font = painter.font(); + + // Draw the rectangle + painter.setPen(QPen(Qt::black)); + painter.drawRect(m_rect); + + // Draw the text + painter.setPen(pen); + painter.setFont(m_font); + if (m_bMultiCall) + painter.drawText(m_rect, Qt::AlignCenter, "..."); + else + painter.drawText(m_rect, Qt::AlignCenter, m_sFunc); + + painter.setFont(font); +} diff --git a/src/graphnode.h b/src/graphnode.h new file mode 100644 index 0000000..9f48639 --- /dev/null +++ b/src/graphnode.h @@ -0,0 +1,123 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef GRAPHNODE_H +#define GRAPHNODE_H + +#include +#include +#include "graphedge.h" + +/** + * A canvas item that draws the name of a function insider a filled rectangle. + * This item represents a function in the call graph. + * @author Elad Lahav + */ +class GraphNode : public QCanvasPolygon +{ +public: + GraphNode(QCanvas* pCanvas, const QString&, bool bMultiCall = false); + ~GraphNode(); + + GraphEdge* addOutEdge(GraphNode*); + void dfs(); + void removeOutEdges(); + void removeInEdges(); + void getFirstNeighbour(GraphNode*&, bool&); + + /** + * @param rect The bounding rectangle of the node + */ + void setRect(const QRect& rect); + + /** + * @param font The font to use for drawing the text + */ + void setFont(const QFont& font) { m_font = font; } + + /** + * @return The name of the function + */ + const QString& getFunc() const { return m_sFunc; } + + /** + * @return true for a multiple-call node, false otherwise + */ + bool isMultiCall() { return m_bMultiCall; } + + /** + * @return The set of outgoing edges + */ + QDict& getOutEdges() { return m_dictOutEdges; } + + /** + * @return true if this node was already visited during the current DFS, + * false otherwise + */ + bool dfsVisited() { return m_bDfsFlag; } + + /** + * Clears the 'DFS-visited' flag, in preparation for the next DFS. + */ + void dfsReset() { m_bDfsFlag = false; } + + /** Identifies this class among other QCanvasItem classes. */ + static int RTTI; + + /** + * @return The class identifier + */ + virtual int rtti() const { return RTTI; } + +protected: + virtual void drawShape(QPainter&); + +private: + /** Function name. */ + QString m_sFunc; + + /** A list of outgoing edges indexed by destination. */ + QDict m_dictOutEdges; + + /** A list of incoming edges indexed by destination. */ + QDict m_dictInEdges; + + /** The bounding rectangle for the node. */ + QRect m_rect; + + /** The font to use for drawing the text. */ + QFont m_font; + + /** true for a multiple-call node, false otherwise. */ + bool m_bMultiCall; + + /** Determines whether this node was visited during a depth-first + search. */ + bool m_bDfsFlag; +}; + +#endif diff --git a/src/graphprefdlg.cpp b/src/graphprefdlg.cpp new file mode 100644 index 0000000..c8d381c --- /dev/null +++ b/src/graphprefdlg.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "graphprefdlg.h" +#include "preferencesdlg.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +GraphPrefDlg::GraphPrefDlg(QWidget* pParent, const char* szName) : + GraphPrefLayout(pParent, szName, true, 0) +{ + m_pMaxDegSpin->setValue(Config().getGraphMaxNodeDegree()); +} + +/** + * Class destructor. + */ +GraphPrefDlg::~GraphPrefDlg() +{ +} + +/** + * @return The maximal degree value set in the spin box + */ +int GraphPrefDlg::getMaxNodeDegree() +{ + return m_pMaxDegSpin->value(); +} + +/** + * Displays the general preferences dialogue, showing the "Colours" page. + * This slot is connected to the clicked() signal of the colours button. + */ +void GraphPrefDlg::slotFontClicked() +{ + PreferencesDlg dlg(PreferencesDlg::Fonts); + + dlg.exec(); +} + +/** + * Displays the general preferences dialogue, showing the "Fonts" page. + * This slot is connected to the clicked() signal of the fonts button. + */ +void GraphPrefDlg::slotColorClicked() +{ + PreferencesDlg dlg(PreferencesDlg::Colors); + + dlg.exec(); +} + +#include "graphprefdlg.moc" + diff --git a/src/graphprefdlg.h b/src/graphprefdlg.h new file mode 100644 index 0000000..7a4a3c0 --- /dev/null +++ b/src/graphprefdlg.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef GRAPHPREFDLG_H +#define GRAPHPREFDLG_H + +#include "graphpreflayout.h" + +/** + * A dialogue that allows the user to configure the appearance and behaviour + * of the call graph. + * @author Elad Lahav + */ +class GraphPrefDlg : public GraphPrefLayout +{ + Q_OBJECT + +public: + GraphPrefDlg(QWidget* pParent = 0, const char* szName = 0); + ~GraphPrefDlg(); + + int getMaxNodeDegree(); + +protected slots: + virtual void slotFontClicked(); + virtual void slotColorClicked(); +}; + +#endif + diff --git a/src/graphpreflayout.ui b/src/graphpreflayout.ui new file mode 100644 index 0000000..a94a206 --- /dev/null +++ b/src/graphpreflayout.ui @@ -0,0 +1,262 @@ + +GraphPrefLayout + + + GraphPrefLayout + + + + 0 + 0 + 328 + 164 + + + + Call Graph Preferences + + + true + + + + unnamed + + + + layout6 + + + + unnamed + + + + textLabel1 + + + Maximal In/Out Node Degree + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 81 + 21 + + + + + + m_pMaxDegSpin + + + + + + + layout7 + + + + unnamed + + + + textLabel2 + + + Colours + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 131 + 21 + + + + + + m_pColorButton + + + ... + + + + + + + layout8 + + + + unnamed + + + + textLabel3 + + + Fonts + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 121 + 31 + + + + + + m_pFontButton + + + ... + + + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + + + buttonOk + clicked() + GraphPrefLayout + accept() + + + buttonCancel + clicked() + GraphPrefLayout + reject() + + + m_pColorButton + clicked() + GraphPrefLayout + slotColorClicked() + + + m_pFontButton + clicked() + GraphPrefLayout + slotFontClicked() + + + + slotColorClicked() + slotFontClicked() + + + diff --git a/src/graphwidget.cpp b/src/graphwidget.cpp new file mode 100644 index 0000000..00ca733 --- /dev/null +++ b/src/graphwidget.cpp @@ -0,0 +1,1162 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "graphwidget.h" +#include "graphnode.h" +#include "graphedge.h" +#include "kscopeconfig.h" +#include "queryviewdlg.h" +#include "encoder.h" +#include "progressdlg.h" + +const char* GRAPH_DIRS[] = { "TB", "LR", "BT", "RL" }; + +const char TMP_TMPL[] = "/tmp/kscope_dot.XXXXXX"; +#define TMP_TMPL_SIZE (sizeof(TMP_TMPL) + 1) + +/** + * Displays a tool tip on the graph. + * Note that we cannot use the standard tool tip class here, since graph + * items are neither rectangular nor is their position known in advance. + * @author Elad Lahav + */ +class GraphTip : public QToolTip +{ +public: + /** + * Class constructor. + * @param pWidget Owner graph widget + */ + GraphTip(GraphWidget* pWidget) : QToolTip(pWidget->viewport()), + m_pGraphWidget(pWidget) {} + + /** + * Class destructor. + */ + virtual ~GraphTip() {} + +protected: + /** + * Called when the pre-conditions for a tool tip are met. + * Asks the owner for a tip to display and, if one is returned, shows + * the tool tip. + * @param ptPos Current mouse position + */ + virtual void maybeTip(const QPoint& ptPos) { + QString sText; + QRect rc; + + // Display a tip, if required by the owner + sText = m_pGraphWidget->getTip(ptPos, rc); + if (sText != QString::null) + tip(rc, sText); + } + +private: + /** The parent graph widget. */ + GraphWidget* m_pGraphWidget; +}; + +/** + * Provides a menu separator with text. + * The separator is added with QMenuData::insertItem(QWidget*). + * @author Elad Lahav + */ +class MenuLabel : public QLabel +{ +public: + /** + * Class constructor. + * @param sText The text to display + * @param pParent The parent widget + */ + MenuLabel(const QString& sText, QWidget* pParent) : + QLabel(sText, pParent) { + // Set the appropriate visual properties + setFrameShape(MenuBarPanel); + setAlignment(AlignHCenter | AlignVCenter); + setIndent(0); + } +}; + +ArrowInfo GraphWidget::s_ai; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +GraphWidget::GraphWidget(QWidget* pParent, const char* szName) : + QCanvasView(pParent, szName), + m_progress(this), + m_dot(this), + m_dZoom(1.0), + m_nMaxNodeDegree(10), // will be overriden by CallTreeDlg + m_nMultiCallNum(0), + m_pProgressDlg(NULL) +{ + // Automatically delete nodes when they are removed + m_dictNodes.setAutoDelete(true); + + // Create a canvas + setCanvas(new QCanvas(this)); + canvas()->setBackgroundColor(Config().getColor(KScopeConfig::GraphBack)); + + // Create a persistent Cscope process + m_pCscope = new CscopeFrontend(); + + // Add records output by the Cscope process + connect(m_pCscope, SIGNAL(dataReady(FrontendToken*)), this, + SLOT(slotDataReady(FrontendToken*))); + + // Display query progress information + connect(m_pCscope, SIGNAL(progress(int, int)), this, + SLOT(slotProgress(int, int))); + + // Draw the graph when the process has finished + connect(m_pCscope, SIGNAL(finished(uint)), this, + SLOT(slotFinished(uint))); + + // Show a multi-call node when a query results in too many records + connect(m_pCscope, SIGNAL(aborted()), this, + SLOT(slotAborted())); + + // Redraw the graph when Dot exits + connect(&m_dot, SIGNAL(finished(uint)), this, SLOT(slotDotFinished())); + + // Create the node popup menu + m_pNodePopup = new QPopupMenu(this); + + m_pNodePopup->insertItem(new MenuLabel(i18n("Called Functions"), + m_pNodePopup)); + m_pNodePopup->insertItem(i18n("Show"), this, + SLOT(slotShowCalled())); + m_pNodePopup->insertItem(i18n("List/Filter..."), this, + SLOT(slotListCalled())); + m_pNodePopup->insertItem(i18n("Hide"), this, + SLOT(slotHideCalled())); + + m_pNodePopup->insertItem(new MenuLabel(i18n("Calling Functions"), + m_pNodePopup)); + m_pNodePopup->insertItem(i18n("Show"), this, + SLOT(slotShowCalling())); + m_pNodePopup->insertItem(i18n("List/Filter..."), this, + SLOT(slotListCalling())); + m_pNodePopup->insertItem(i18n("Hide"), this, + SLOT(slotHideCalling())); + + m_pNodePopup->insertItem(new MenuLabel(i18n("This Function"), + m_pNodePopup)); + m_pNodePopup->insertItem(i18n("Find Definition"), this, + SLOT(slotFindDef())); + m_pNodePopup->insertItem(i18n("Remove"), this, SLOT(slotRemoveNode())); + + // Create the multi-call node popup menu + m_pMultiCallPopup = new QPopupMenu(this); + m_pMultiCallPopup->insertItem(i18n("List..."), this, + SLOT(slotMultiCallDetails())); + m_pMultiCallPopup->insertSeparator(); + m_pMultiCallPopup->insertItem(i18n("Remove"), this, + SLOT(slotRemoveNode())); + + // Create the edge menu + m_pEdgePopup = new QPopupMenu(this); + m_pEdgePopup->insertItem(i18n("Open Call"), this, SLOT(slotOpenCall())); + + (void)new GraphTip(this); +} + +/** + * Class destructor. + */ +GraphWidget::~GraphWidget() +{ +} + +/** + * Creates a root node for the graph. + * The root node defines the connected component which is always displayed + * (all other connected components are removed when they are no longer + * strongly connected to the root). + * @param sFunc The function name for the root node + */ +void GraphWidget::setRoot(const QString& sFunc) +{ + // Insert a new node to the graph + addNode(sFunc); + draw(); +} + +/** + * Locates a node by its name and, if one does not exist, creates a new node. + * @param sFunc The name of a function + * @return The node corresponding to the given name + */ +GraphNode* GraphWidget::addNode(const QString& sFunc, bool bMultiCall) +{ + GraphNode* pNode; + + // Look for a node with the given name + if ((pNode = m_dictNodes.find(sFunc)) == NULL) { + // Node not found, create it + pNode = new GraphNode(canvas(), sFunc, bMultiCall); + m_dictNodes.insert(sFunc, pNode); + } + + // Return the found/created node + return pNode; +} + +/** + * Adds a call to the graph. + * A call is made between two functions, the caller and the callee. + * @param data Contains information on the call + */ +void GraphWidget::addCall(const CallData& data) +{ + GraphNode* pCaller, * pCallee; + GraphEdge* pEdge; + + // Find the relevant nodes (create new nodes if necessary) + pCaller = addNode(data.m_sCaller); + pCallee = addNode(data.m_sCallee); + + // Create a new edge + pEdge = pCaller->addOutEdge(pCallee); + pEdge->setCallInfo(data.m_sFile, data.m_sLine, data.m_sText); +} + +/** + * Creates a special node representing multiple calls to/from a function. + * Such a node is creates when the number of calls to/from a function exceeds + * a certain number. Thus the graph does not become too cluttered. + * A multiple call node can be replaced by some/all of the actual calls by + * using the "Details..." action in the node's popup menu. + * @param sFunc The parent function + * @param bCalled true if the multiple calls are called from that function, + * false if they are calling the function + */ +void GraphWidget::addMultiCall(const QString& sFunc, bool bCalled) +{ + QString sMulti; + GraphNode* pCaller, * pCallee; + GraphEdge* pEdge; + + // Create a unique name for the new node. + // The name is of the form 0XXX, where XXX is a hexadecimal number. + // We assume that no function starts with a digit, and that there are no + // more than 0xfff multi-call nodes in the graph. + sMulti.sprintf("0%.3x", m_nMultiCallNum); + m_nMultiCallNum = (m_nMultiCallNum + 1) & 0xfff; + + // Find the relevant nodes (create new nodes if necessary) + if (bCalled) { + pCaller = addNode(sFunc); + pCallee = addNode(sMulti, true); + } + else { + pCaller = addNode(sMulti, true); + pCallee = addNode(sFunc); + } + + // Create a new edge + pEdge = pCaller->addOutEdge(pCallee); +} + +/** + * Draws the graph on the canvas using the graphviz engine. + * A new canvas is created, so all items need to be regenerated. + * TODO: Can we use the same canvas and only reposition existing items? + */ +void GraphWidget::draw() +{ + QWMatrix mtx; + char szTempFile[TMP_TMPL_SIZE]; + int nFd; + FILE* pFile; + + // Do nothing if drawing process has already started + if (m_dot.isRunning()) + return; + + // Apply the zoom factor + mtx.scale(m_dZoom, m_dZoom); + setWorldMatrix(mtx); + + // Do not draw until the Dot process finishes + setUpdatesEnabled(false); + + // Open a temporary file + strcpy(szTempFile, TMP_TMPL); + nFd = mkstemp(szTempFile); + if ((pFile = fdopen(nFd, "w")) == NULL) + return; + + // Remember the file name (so it can be deleted later) + m_sDrawFilePath = szTempFile; + + // Write the graph contents to the temporary file + { + QTextStream str(pFile, IO_WriteOnly); + write(str, "graph", "--", false); + } + + // Close the file + fclose(pFile); + + // Draw the graph + if (m_dot.run(szTempFile)) { + // Create the progress dialogue + m_pProgressDlg = new ProgressDlg(i18n("KScope"), + i18n("Generating graph, please wait"), this); + m_pProgressDlg->setMinimumDuration(1000); + m_pProgressDlg->setValue(0); + + // TODO: + // Implement cancel (what do we do when the drawing process is + // terminated, even though the nodes and edges were already added by + // Cscope?) + // m_pProgressDlg->setAllowCancel(true); + } +} + +/** + * Stores a graph on a file. + * The file uses the dot language to describe the graph. + * @param pFile An open file to write to + */ +void GraphWidget::save(FILE* pFile) +{ + // Write the graph using the dot language + QTextStream str(pFile, IO_WriteOnly); + write(str, "digraph", "->", true); +} + +/** + * Exports a graph to a dot file. + * @param sFile The full path of the file to export to + */ +void GraphWidget::save(const QString& sFile) +{ + QFile file(sFile); + + // Open/create the file + if (!file.open(IO_WriteOnly)) + return; + + QTextStream str(&file); + write(str, "digraph", "->", false); +} + +/** + * Changes the zoom factor. + * @param bIn true to zoom in, false to zoom out + */ +void GraphWidget::zoom(bool bIn) +{ + QWMatrix mtx; + + // Set the new zoom factor + if (bIn) + m_dZoom *= 2.0; + else + m_dZoom /= 2.0; + + // Apply the transformation matrix + mtx.scale(m_dZoom, m_dZoom); + setWorldMatrix(mtx); +} + +/** + * Determines the initial zoom factor. + * This method is called from the file parser and therefore does not redraw + * the widget. + * @param dZoom The zoom factor to use + */ +void GraphWidget::setZoom(double dZoom) +{ + m_dZoom = dZoom; +} + +/** + * Changes the graph's direction 90 degrees counter-clockwise. + */ +void GraphWidget::rotate() +{ + QString sDir; + int i; + + // Get the current direction + sDir = Config().getGraphOrientation(); + + // Find the next direction + for (i = 0; i < 4 && sDir != GRAPH_DIRS[i]; i++); + if (i == 4) + i = 0; + else + i = (i + 1) % 4; + + // Set the new direction + sDir = GRAPH_DIRS[i]; + Config().setGraphOrientation(sDir); +} + +/** + * Checks if a tool tip is required for the given position. + * NOTE: We currently return a tool tip for edges only + * @param ptPos The position to query + * @param rc Holds the tip's rectangle, upon return + * @return The tip's text, or QString::null if no tip is required + */ +QString GraphWidget::getTip(const QPoint& ptPos, QRect& rc) +{ + QPoint ptRealPos, ptTopLeft, ptBottomRight; + QCanvasItemList il; + QCanvasItemList::Iterator itr; + GraphEdge* pEdge; + QString sText, sFile, sLine; + + ptRealPos = viewportToContents(ptPos); + ptRealPos /= m_dZoom; + pEdge = NULL; + + // Check if there is an edge at this position + il = canvas()->collisions(ptRealPos); + for (itr = il.begin(); itr != il.end(); ++itr) { + pEdge = dynamic_cast(*itr); + if (pEdge != NULL) + break; + } + + // No tip if no edge was found + if (pEdge == NULL) + return QString::null; + + // Set the rectangle for the tip (the tip is closed when the mouse leaves + // this area) + rc = pEdge->tipRect(); + ptTopLeft = rc.topLeft(); + ptBottomRight = rc.bottomRight(); + ptTopLeft *= m_dZoom; + ptBottomRight *= m_dZoom; + ptTopLeft = contentsToViewport(ptTopLeft); + ptBottomRight = contentsToViewport(ptBottomRight); + rc = QRect(ptTopLeft, ptBottomRight); + + // Create a tip for this edge + return pEdge->getTip(); +} + +/** + * Resizes the canvas. + * @param nWidth The new width + * @param nHiehgt The new height + */ +void GraphWidget::resize(int nWidth, int nHeight) +{ + canvas()->resize(nWidth + 2, nHeight + 2); +} + +/** + * Displays a node on the canvas. + * Sets the parameters used for drawing the node on the canvas. + * @param sFunc The function corresponding to the node to draw + * @param rect The coordinates of the node's rectangle + */ +void GraphWidget::drawNode(const QString& sFunc, const QRect& rect) +{ + GraphNode* pNode; + + // Find the node + pNode = addNode(sFunc); + + // Set the visual aspects of the node + pNode->setRect(rect); + pNode->setZ(2.0); + pNode->setPen(QPen(Qt::black)); + pNode->setFont(Config().getFont(KScopeConfig::Graph)); + + if (pNode->isMultiCall()) + pNode->setBrush(Config().getColor(KScopeConfig::GraphMultiCall)); + else + pNode->setBrush(Config().getColor(KScopeConfig::GraphNode)); + + // Draw the node + pNode->show(); +} + +/** + * Displays an edge on the canvas. + * Sets the parameters used for drawing the edge on the canvas. + * @param sCaller Identifies the edge's head node + * @param sCallee Identifies the edge's tail node + * @param arrCurve Control points for the edge's spline + */ +void GraphWidget::drawEdge(const QString& sCaller, const QString& sCallee, + const QPointArray& arrCurve) +{ + GraphNode* pCaller, * pCallee; + GraphEdge* pEdge; + + // Find the edge + pCaller = addNode(sCaller); + pCallee = addNode(sCallee); + pEdge = pCaller->addOutEdge(pCallee); + + // Set the visual aspects of the edge + pEdge->setPoints(arrCurve, s_ai); + pEdge->setZ(1.0); + pEdge->setPen(QPen(Qt::black)); + pEdge->setBrush(QBrush(Qt::black)); + + // Draw the edge + pEdge->show(); +} + +#define PI 3.14159265 + +/** + * Sets and computes values used for drawing arrows. + * Initialises the static ArroInfo structure, which is passed in drawEdge(). + * @param nLength The arrow head length + * @param nDegrees The angle, in degrees, between the base line and each + * of the arrow head's sides + */ +void GraphWidget::setArrowInfo(int nLength, int nDegrees) +{ + double dRad; + + // Turn degrees into radians + dRad = ((double)nDegrees) * PI / 180.0; + + s_ai.m_dLength = (double)nLength; + s_ai.m_dTan = tan(dRad); + s_ai.m_dSqrt = sqrt(1 + s_ai.m_dTan * s_ai.m_dTan); +} + +/** + * Draws the contents of the canvas on this view. + * NOTE: This method is overriden to fix a strange bug in Qt that leaves + * a border around the canvas part of the view. It should be deleted once + * this bug is fixed. + * TODO: Is there a better way of erasing the border? + * @param pPainter Used to paint on the view + * @param nX The horizontal origin of the area to draw + * @param nY The vertical origin of the area to draw + * @param nWidth The width of the area to draw + * @param nHeight The height of the area to draw + */ +void GraphWidget::drawContents(QPainter* pPainter, int nX, int nY, + int nWidth, int nHeight) +{ + // Draw the contents of the canvas + QCanvasView::drawContents(pPainter, nX, nY, nWidth, nHeight); + + // Erase the canvas's area border + if (canvas() != NULL) { + QRect rect = canvas()->rect(); + pPainter->setBrush(QBrush()); // Null brush + pPainter->setPen(Config().getColor(KScopeConfig::GraphBack)); + pPainter->drawRect(-1, -1, rect.width() + 2, rect.height() + 2); + } +} + +/** + * Handles mouse clicks over the graph view. + * @param pEvent Includes information on the mouse press event + */ +void GraphWidget::contentsMousePressEvent(QMouseEvent* pEvent) +{ + QPoint ptRealPos; + QCanvasItemList il; + QCanvasItemList::Iterator itr; + QString sFunc; + GraphNode* pNode; + GraphEdge* pEdge; + + pNode = NULL; + pEdge = NULL; + + // Handle right-clicks only + if (pEvent->button() != Qt::RightButton) { + QCanvasView::contentsMousePressEvent(pEvent); + return; + } + + // Take the zoom factor into consideration + ptRealPos = pEvent->pos(); + ptRealPos /= m_dZoom; + + // Check if an item was clicked + il = canvas()->collisions(ptRealPos); + for (itr = il.begin(); itr != il.end(); ++itr) { + if (dynamic_cast(*itr) != NULL) + pNode = dynamic_cast(*itr); + else if (dynamic_cast(*itr) != NULL) + pEdge = dynamic_cast(*itr); + } + + // Handle clicks over different types of items + if (pNode != NULL) { + // Show a context menu for nodes + showNodeMenu(pNode, pEvent->globalPos()); + } + else if (pEdge != NULL) { + // Show a context menu for edges + showEdgeMenu(pEdge, pEvent->globalPos()); + } + else { + // Take the default action + QCanvasView::contentsMousePressEvent(pEvent); + } +} + +/** + * Writes a description of the graph to the given stream, using the Dot + * language. + * The method allows for both directed graphs and non-directed graphs, the + * latter are required for drawing purposes (since Dot will not produce the + * arrow heads and the splines terminate before reaching the nodes). + * @param str The stream to write to + * @param sType Either "graph" or "digraph" + * @param sEdge The edge connector ("--" or "->") + * @param bWriteCall true to write call information, false otherwise + */ +void GraphWidget::write(QTextStream& str, const QString& sType, + const QString& sEdge, bool bWriteCall) +{ + QFont font; + QDictIterator itr(m_dictNodes); + GraphEdge* pEdge; + Encoder enc; + + font = Config().getFont(KScopeConfig::Graph); + + // Header + str << sType << " G {\n"; + + // Graph attributes + str << "\tgraph [rankdir=" << Config().getGraphOrientation() << ", " + << "kscope_zoom=" << m_dZoom + << "];\n"; + + // Default node attributes + str << "\tnode [shape=box, height=\"0.01\", style=filled, " + << "fillcolor=\"" << Config().getColor(KScopeConfig::GraphNode).name() + << "\", " + << "fontcolor=\"" << Config().getColor(KScopeConfig::GraphText).name() + << "\", " + << "fontname=\"" << font.family() << "\", " + << "fontsize=" << QString::number(font.pointSize()) + << "];\n"; + + // Iterate over all nodes + for (; itr.current(); ++itr) { + // Write a node + str << "\t" << itr.current()->getFunc() << ";\n"; + + // Iterate over all edges leaving this node + QDictIterator itrEdge(itr.current()->getOutEdges()); + for (; itrEdge.current(); ++itrEdge) { + pEdge = itrEdge.current(); + str << "\t" << pEdge->getHead()->getFunc() << sEdge + << pEdge->getTail()->getFunc(); + + // Write call information + if (bWriteCall) { + str << " [" + << "kscope_file=\"" << pEdge->getFile() << "\"," + << "kscope_line=" << pEdge->getLine() << "," + << "kscope_text=\"" << enc.encode(pEdge->getText()) << "\"" + << "]"; + } + + str << ";\n"; + } + } + + // Close the graph + str << "}\n"; +} + +/** + * Removes all edges attached to a function node at the given direction. + * Any strongly connected components that are no longer connected to that + * function are deleted. + * @param pNode The node for which to remove the edges + * @param bOut true for outgoing edges, false for incoming + */ +void GraphWidget::removeEdges(GraphNode* pNode, bool bOut) +{ + // Remove the edges + if (bOut) + pNode->removeOutEdges(); + else + pNode->removeInEdges(); + + // Remove all graph components no longer connected to this one + removeDisconnected(pNode); +} + +/** + * Removes all edges and nodes that are not weakly connected to the given node. + * This function is called to clean up the graph after edges were removed from + * the given node. + * @param pNode The node to which all other nodes have to be connected + */ +void GraphWidget::removeDisconnected(GraphNode* pNode) +{ + QDictIterator itr(m_dictNodes); + + // Find all weakly connected components attached to this node + pNode->dfs(); + + // Delete all unmarked nodes, reset marked ones + while (itr.current()) { + if (!(*itr)->dfsVisited()) { + m_dictNodes.remove((*itr)->getFunc()); + } + else { + (*itr)->dfsReset(); + ++itr; + } + } +} + +/** + * Shows a popup menu for a node. + * This menu is shown after a node has been right-clicked. + * @param pNode The node for which to show the menu + * @param ptPos The position of the menu + */ +void GraphWidget::showNodeMenu(GraphNode* pNode, const QPoint& ptPos) +{ + // Remember the node + m_pMenuItem = pNode; + + // Show the popup menu. + if (pNode->isMultiCall()) + m_pMultiCallPopup->popup(ptPos); + else + m_pNodePopup->popup(ptPos); +} + +/** + * Shows a popup menu for an edge. + * This menu is shown after an edge has been right-clicked. + * @param pEdge The edge for which to show the menu + * @param ptPos The position of the menu + */ +void GraphWidget::showEdgeMenu(GraphEdge* pEdge, const QPoint& ptPos) +{ + // Remember the edge + m_pMenuItem = pEdge; + + // Show the popup menu. + m_pEdgePopup->popup(ptPos); +} + +/** + * Redraws the widget when new instructions are available. + * This slot is connected to the finished() signal emitted by the dot front- + * end. + */ +void GraphWidget::slotDotFinished() +{ + // Delete the temporary file + if (m_sDrawFilePath != "") { + QFile::remove(m_sDrawFilePath); + m_sDrawFilePath = ""; + } + + // Delete the progress dialogue + if (m_pProgressDlg) { + delete m_pProgressDlg; + m_pProgressDlg = NULL; + } + + setUpdatesEnabled(true); + canvas()->update(); +} + +/** + * Adds an entry to the tree, as the child of the active item. + * Called by a CscopeFrontend object, when a new entry was received in its + * whole from the Cscope back-end process. The entry contains the data of a + * function calling the function described by the active item. + * @param pToken The first token in the entry + */ +void GraphWidget::slotDataReady(FrontendToken* pToken) +{ + CallData data; + QString sFunc; + + // Get the file name + data.m_sFile = pToken->getData(); + pToken = pToken->getNext(); + + // Get the function name + sFunc = pToken->getData(); + pToken = pToken->getNext(); + + // Get the line number (do not accept global information on a call tree) + data.m_sLine = pToken->getData(); + if (data.m_sLine.toUInt() == 0) + return; + + pToken = pToken->getNext(); + + // Get the line's text + data.m_sText = pToken->getData(); + + // Determine the caller and the callee + if (m_bCalled) { + data.m_sCaller = m_sQueriedFunc; + data.m_sCallee = sFunc; + } + else { + data.m_sCaller = sFunc; + data.m_sCallee = m_sQueriedFunc; + } + + // Add the call to the graph + addCall(data); +} + +/** + * Displays search progress information. + * This slot is connected to the progress() signal emitted by a + * CscopeFrontend object. + * @param nProgress The current progress value + * @param nTotal The expected final value + */ +void GraphWidget::slotProgress(int nProgress, int nTotal) +{ + m_progress.setProgress(nProgress, nTotal); +} + +/** + * Disables the expandability feature of an item, if no functions calling it + * were found. + * @param nRecords Number of records reported by the query + */ +void GraphWidget::slotFinished(uint /*nRecords*/) +{ + // Destroy the progress bar + m_progress.finished(); + + // Redraw the graph + draw(); +} + +/** + * Adds a multiple call node when a query results in too many entries. + * This slot is attached to the aborted() signal of the Cscope process. + */ +void GraphWidget::slotAborted() +{ + KMessageBox::information(this, i18n("The query produced too many results.\n" + "A multiple-call node will appear in the graph instead.\n" + "Hint: The maximum number of in/out edges\n" + "can be adjusted by clicking the dialogue's \"Preferences\" button")); + + addMultiCall(m_sQueriedFunc, m_bCalled); + draw(); +} + +/** + * Shows functions called from the current function node. + * This slot is connected to the "Show Called Functions" popup menu + * action. + */ +void GraphWidget::slotShowCalled() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + // Run a query for called functions + m_sQueriedFunc = pNode->getFunc(); + m_bCalled = true; + m_pCscope->query(CscopeFrontend::Called, m_sQueriedFunc, true, + Config().getGraphMaxNodeDegree()); +} + +/** + * Shows a list of function calls from the current node. + * The list is displayed in a query dialogue. The user can the select which + * calls should be displayed in the graph. + * This slot is connected to the "List Called Functions" popup menu + * action. + */ +void GraphWidget::slotListCalled() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + QueryViewDlg dlg(0, (QWidget*)parent()); + + // Show the query view dialogue + dlg.query(CscopeFrontend::Called, pNode->getFunc()); + if (dlg.exec() != QDialog::Accepted) + return; + + // The OK button was clicked, replace current calls with the listed ones + pNode->removeOutEdges(); + + QueryView::Iterator itr; + CallData data; + + data.m_sCaller = pNode->getFunc(); + + // Add all listed calls + for (itr = dlg.getIterator(); !itr.isEOF(); itr.next()) { + data.m_sCallee = itr.getFunc(); + data.m_sFile = itr.getFile(); + data.m_sLine = itr.getLine(); + data.m_sText = itr.getText(); + + addCall(data); + } + + // Clean-up and redraw the graph + removeDisconnected(pNode); + draw(); +} + +/** + * Hides functions called from the current function node. + * This slot is connected to the "Hide Called Functions" popup menu + * action. + */ +void GraphWidget::slotHideCalled() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + // Remove edges and redraw the graph + removeEdges(pNode, true); + draw(); +} + +/** + * Shows functions calling tothe current function node. + * This slot is connected to the "Show Calling Functions" popup menu + * action. + */ +void GraphWidget::slotShowCalling() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + // Run a query for called functions + m_sQueriedFunc = pNode->getFunc(); + m_bCalled = false; + m_pCscope->query(CscopeFrontend::Calling, m_sQueriedFunc, true, + Config().getGraphMaxNodeDegree()); +} + +/** + * Shows a list of function calls to the current node. + * The list is displayed in a query dialogue. The user can the select which + * calls should be displayed in the graph. + * This slot is connected to the "List Calling Functions" popup menu + * action. + */ +void GraphWidget::slotListCalling() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + QueryViewDlg dlg(0, (QWidget*)parent()); + + // Show the query view dialogue + dlg.query(CscopeFrontend::Calling, pNode->getFunc()); + if (dlg.exec() != QDialog::Accepted) + return; + + // The OK button was clicked, replace current calls with the listed ones + pNode->removeInEdges(); + + QueryView::Iterator itr; + CallData data; + + data.m_sCallee = pNode->getFunc(); + + // Add all listed calls + for (itr = dlg.getIterator(); !itr.isEOF(); itr.next()) { + data.m_sCaller = itr.getFunc(); + data.m_sFile = itr.getFile(); + data.m_sLine = itr.getLine(); + data.m_sText = itr.getText(); + + addCall(data); + } + + // Clean-up and redraw the graph + removeDisconnected(pNode); + draw(); +} + +/** + * Hides functions calling to the current function node. + * This slot is connected to the "Hide CallingFunctions" popup menu + * action. + */ +void GraphWidget::slotHideCalling() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + // Remove edges and redraw the graph + removeEdges(pNode, false); + draw(); +} + +/** + * Looks up the definition of the current function node. + * This slot is connected to the "Find Definition" popup menu action. + */ +void GraphWidget::slotFindDef() +{ + GraphNode* pNode; + QueryViewDlg* pDlg; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + // Create a query view dialogue + pDlg = new QueryViewDlg(QueryViewDlg::DestroyOnSelect, this); + + // Display a line when it is selected in the dialogue + connect(pDlg, SIGNAL(lineRequested(const QString&, uint)), this, + SIGNAL(lineRequested(const QString&, uint))); + + // Start the query + pDlg->query(CscopeFrontend::Definition, pNode->getFunc()); +} + +/** + * Deletes a node from the graph (alogn with all edges connected to this + * node). + * The node removed is the one over which the context menu was invoked. + * This slot is connected to the "Remove" popup menu action. + */ +void GraphWidget::slotRemoveNode() +{ + GraphNode* pNode; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL) + return; + + // Remove all incoming edges + pNode->removeInEdges(); + + // Remove the node (also deletes the object and its outgoing edges) + m_dictNodes.remove(pNode->getFunc()); + + // Redraw the graph + draw(); +} + +/** + * Shows the list of calls that is represented by a single multi-call node. + * This slot handles the "Details..." command of the multi-call node menu. + */ +void GraphWidget::slotMultiCallDetails() +{ + GraphNode* pNode, * pParent; + bool bCalled; + + // Make sure the menu item is a node + pNode = dynamic_cast(m_pMenuItem); + if (pNode == NULL || !pNode->isMultiCall()) + return; + + // Get the required information from the node + pNode->getFirstNeighbour(pParent, bCalled); + if (!pParent) + return; + + QueryViewDlg dlg(0, (QWidget*)parent()); + + dlg.query(bCalled ? CscopeFrontend::Calling : CscopeFrontend::Called, + pParent->getFunc()); + dlg.exec(); +} + +/** + * Emits a signal to open an editor at the file and line matching the call + * information of the current edge. + * This slot is connected to the "Open Call" popup menu action (for edges). + */ +void GraphWidget::slotOpenCall() +{ + GraphEdge* pEdge; + QString sFile, sLine; + + // Make sure the menu item is an edge + pEdge = dynamic_cast(m_pMenuItem); + if (pEdge != NULL && pEdge->getFile() != "") + emit lineRequested(pEdge->getFile(), pEdge->getLine()); +} + +#include "graphwidget.moc" diff --git a/src/graphwidget.h b/src/graphwidget.h new file mode 100644 index 0000000..119ddbb --- /dev/null +++ b/src/graphwidget.h @@ -0,0 +1,213 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef GRAPHWIDGET_H +#define GRAPHWIDGET_H + +#include +#include +#include +#include "cscopefrontend.h" +#include "graphnode.h" +#include "dotfrontend.h" + +class ProgressDlg; + +/** + * A widget that displays call tree graphs generated by graphviz. + * This class is based on a QCanvasView widget, and displays two types of + * canvas items: GraphNode, which draws the name of a function inside a + * polygon, and ArrowEdge, which is a directed graph edge shaped like an + * arrow. + * The call tree graph is populated using the addNode() method. The first + * call creates a root node. Subsequent calls add nodes which represent either + * functions called by a previously inserted node, or that are calling such + * a node. A directed edge is created to depict the relationship between a + * node and its parent. + * Drawing is done through the embedded Agraph_t object (a graph, as defined + * by the graphviz libraray). When the draw() method is called, the graph is + * layed out in memory. The class then uses the CodeGenerator class to + * obtain a set of instructions on how to actually draw the graph. These + * instructions are used to create the appropriate canvas items. + * An application _must_ call GraphWidget::init() before attempting to use + * this class. It should also call GraphWidget::fini() when it no longer needs + * any of these widgets. + * @author Elad Lahav + */ +class GraphWidget : public QCanvasView +{ + Q_OBJECT + +public: + GraphWidget(QWidget* pParent = 0, const char* szName = 0); + ~GraphWidget(); + + /** + * Information on a function call, as produced by a Cscope query. + * This structure is used for adding calls to the graph. + * @see addCall() + */ + struct CallData + { + /** The name of the calling function. */ + QString m_sCaller; + + /** The name of the called function. */ + QString m_sCallee; + + /** Path of the file in which the call appears. */ + QString m_sFile; + + /** The line number of the call. */ + QString m_sLine; + + /** The call's text. */ + QString m_sText; + }; + + /** Graph orientation values. */ + enum Orientation { Portrait, Landscape }; + + void setRoot(const QString&); + GraphNode* addNode(const QString&, bool bMultiCall = false); + void addCall(const CallData&); + void addMultiCall(const QString&, bool); + void draw(); + void save(FILE*); + void save(const QString&); + void zoom(bool); + void setZoom(double); + void rotate(); + QString getTip(const QPoint&, QRect&); + + void resize(int, int); + void drawNode(const QString&, const QRect&); + void drawEdge(const QString&, const QString&, const QPointArray&); + + /** + * Adjusts the maximal number of calling/called functions shown for + * every node (@see m_nMaxNodeDegree). + * @param nMaxNodeDegree The new value to set + */ + void setMaxNodeDegree(int nMaxNodeDegree) { m_nMaxNodeDegree = + nMaxNodeDegree; } + + static void setArrowInfo(int, int); + +signals: + /** + * Emitted when the user makes a request to view the contents of a + * location in the source code. + * This can be the location of a call, the definition of a function, + * etc. + * @param sPath The full path of the file to show + * @param nLine The line number in this file + */ + void lineRequested(const QString& sPath, uint nLine); + +protected: + virtual void drawContents(QPainter*, int, int, int, int); + virtual void contentsMousePressEvent(QMouseEvent*); + +private: + /** The graph is stored as a map of nodes indexed by their names. + Each node holds a list of outgoing edges. */ + QDict m_dictNodes; + + /** A Cscope process to use for running queries. */ + CscopeFrontend* m_pCscope; + + /** Displays query progress information. */ + CscopeProgress m_progress; + + /** A Dot process used to draw the graph. */ + DotFrontend m_dot; + + /** Remembers the function the was last queried for calling/called + functions. */ + QString m_sQueriedFunc; + + /** Remembers whether the last query was for calling or called + functions. */ + bool m_bCalled; + + /** The node over which the popup menu has been invoked. */ + QCanvasPolygonalItem* m_pMenuItem; + + /** A popup menu that appears when a node is right-clicked. */ + QPopupMenu* m_pNodePopup; + + /** A popup menu that appears when a node is right-clicked. */ + QPopupMenu* m_pMultiCallPopup; + + /** A popup menu that appears when an edge is right-clicked. */ + QPopupMenu* m_pEdgePopup; + + /** The zoom factor for the graph. */ + double m_dZoom; + + /** Maximal number of in/out edges per node. If this number is exceeded, + the graph shows a single "multi-call" node. */ + int m_nMaxNodeDegree; + + /** Holds information used to draw arrow heads. */ + static ArrowInfo s_ai; + + /** Used for generating unique names for multi-call nodes. */ + uint m_nMultiCallNum; + + /** Holds the path of the temporary dot file used for drawing the graph. */ + QString m_sDrawFilePath; + + /** Allows lengthy drawing operations to be cancelled. */ + ProgressDlg* m_pProgressDlg; + + void write(QTextStream&, const QString&, const QString&, bool); + void removeEdges(GraphNode*, bool); + void removeDisconnected(GraphNode*); + void showNodeMenu(GraphNode*, const QPoint&); + void showEdgeMenu(GraphEdge*, const QPoint&); + +private slots: + void slotDotFinished(); + void slotDataReady(FrontendToken*); + void slotProgress(int, int); + void slotFinished(uint); + void slotAborted(); + void slotShowCalled(); + void slotListCalled(); + void slotHideCalled(); + void slotShowCalling(); + void slotListCalling(); + void slotHideCalling(); + void slotFindDef(); + void slotRemoveNode(); + void slotMultiCallDetails(); + void slotOpenCall(); +}; + +#endif diff --git a/src/hi16-app-kscope.png b/src/hi16-app-kscope.png new file mode 100644 index 0000000000000000000000000000000000000000..76599661e07de7107141065c9ff451921e947101 GIT binary patch literal 815 zcmV+~1JL}5P)Z{E3xCGPUU>qXY|qJ*X+$csAn(P3JEn#huhH zT+dMS6Fwox>{+D~5oeMTqM8%NUG&!7udT@%BnAtEG5rxX-fMfcZGJwU_G{JKr`md0&ccHr&|@bpDL z#cZa!q=vXSLgYt+^iO51)Co5;6jT|SjvUH&DKK396=H)ht*v4NcQf)v?kv&|pZ6{t?tJ tSVHr?N8D-sdb0n~^(&M8#eawc`~nZ6Mjq+Yz-Ise002ovPDHLkV1lh}dK>@% literal 0 HcmV?d00001 diff --git a/src/hi32-app-kscope.png b/src/hi32-app-kscope.png new file mode 100644 index 0000000000000000000000000000000000000000..54d2af037a03b0f9c08a7fcf00da3cc27d1e5c33 GIT binary patch literal 1828 zcmV+<2iy3GP)WzRMi#7KW}%F&_MWANFYG`0SGBS2FedRATWhdv9$=Lqexrrv{-17GT6ej z)WXyj`UAnQ%zh4yNUxn+fh7I;^OC|B=As^S(N;#9t(jJn|Tu zw-+$!2SL8RDnwzyKmoK?JDyAcEw!XR5M}YN_qO@3J`iQ;b9=E}g;EMv2})AG9h(_5 zrVc3a7s-+(74*-4m~mt8Ousw+$pAY_2V8f7h_vf(zh5sgQ;AYao?2TjN-5cM_+wG3 z{ah%TkV_$58ZJfU%%@l6pYPR6iN8p6sIK8V-xxtOd=kfv10Ixeu$7LTFuBqaByM#Kf9oF~ z@z)oQXaKjBga8Uq3Tn?i!@$DXIIe}`m{5k>-=!SujFf+odUOYOH7p~j6tzA$bi1N_9Tz2n#nlYokNXh2sG0Z5sVW8gxK6A{< zcDA}KK!D{d2C;Md7V`U#;n`*E1Ni@Z7>~z;*Q<4Cztdf?e%m2}XBM%ww3Kc+1^BXiBnyoZ zg(#J*EvtX{H7crWm^d;YCAZ;$R=0bzdgH-|kq8ktqg)O* z-vB?te*eD^S0N&3nuZ`C!ldE?AUW4%0WX$32i`oC>kzl&7*?E6EYc3Xbm#^SZm7o6 z9TKL4rCTHnCp}K+36{O_y$%^SO~QR|?#8wa;%0MBz&#C$@pFny`s}gL~6EKaV$FI!0cfT*MJvSD{je zRplhR>tyzFyAVu%u!kJ4T1UTrj}q4#nLB$jf7o$?%IYHot~OIzeuOpC%g{6ppU;Cg z%R@YDQhz#_gto%n){}B7G;|z>HUefZ=pzUBZl_nzDMVubrM4-6t9kMIe9XCfBhPOC zJ8Pzu@xT+489re!p?ijdFgPIS*|4cRmrj7roTAl zdPVZfl^~8FZsr{Dy}n}>r_P4>LieGBuQd}j;%RtoRRgvImZN~yI|S)%r9N|)P)cxB zviP`4p#&tgP9#$XfbYJ^i}>lfrx-o@IQ{zr=~TB4@fw2nuizr zd1(4bDv#Gwcc@VVCVXB{5&3s|ux#yEsckHicTcaCg)7HN{{4fcqwCt|)&B>;r+p!} SSigt>0000 +#include "historypage.h" +#include "historyview.h" + +int HistoryPage::s_nMaxPageID = 0; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +HistoryPage::HistoryPage(QWidget* pParent, const char* szName) : + QueryPageBase(pParent, szName), + m_nPageID(++s_nMaxPageID) +{ + m_pView = new HistoryView(this); + + connect(m_pView, SIGNAL(lineRequested(const QString&, uint)), this, + SIGNAL(lineRequested(const QString&, uint))); + + // Set colours and font + applyPrefs(); +} + +/** + * Class destructor. + */ +HistoryPage::~HistoryPage() +{ + if (s_nMaxPageID == m_nPageID) + s_nMaxPageID--; +} + +/** + * Creates a new position history record at the top of the list. + * @param sFile The file name associated with the record + * @param nLine The line number + * @param sText The text of the file at the given line + */ +void HistoryPage::addRecord(const QString& sFile, uint nLine, + const QString& sText) +{ + HistoryItem* pItem, * pNextItem; + + pItem = (HistoryItem*)m_pView->currentItem(); + if (pItem != NULL) { + // Do not add duplicate items + if ((pItem->text(1) == sFile) && (pItem->text(2).toUInt() == nLine)) + return; + + // Remove all items above the current one, so the new item is added to + // the top of the list + pItem = pItem->m_pPrevSibling; + while (pItem != NULL) { + pNextItem = pItem; + pItem = pItem->m_pPrevSibling; + delete pNextItem; + } + } + + // Create the new item at the top of the list + m_pView->addRecord("", sFile, QString::number(nLine), sText, NULL); +} + +/** + * Creates a new history item. + * This version is used when history records are read from a file. + * @param sFile The file name + * @param sLine The line number + * @param sText The contents of the line + */ +void HistoryPage::addRecord(const QString&, const QString& sFile, + const QString& sLine, const QString& sText) +{ + m_pView->addRecord("", sFile, sLine, sText, NULL); +} + +/** + * Creates a tab caption for this page, based on the unique page ID. + * @param bBrief true to use brief caption names, false otherwise + */ +QString HistoryPage::getCaption(bool bBrief) const +{ + return (bBrief ? QString(i18n("HIS ")) : QString(i18n("History "))) + + QString::number(m_nPageID); +} + +/** + * Creates a unique file name for saving the contents of the history page. + * @return The unique file name to use + */ +QString HistoryPage::getFileName(const QString&) const +{ + return QString("History_") + QString::number(m_nPageID); +} + +#include "historypage.moc" diff --git a/src/historypage.h b/src/historypage.h new file mode 100644 index 0000000..9ff614f --- /dev/null +++ b/src/historypage.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef HISTORYPAGE_H +#define HISTORYPAGE_H + +#include "querypagebase.h" + +/** + * A QueryWidget page for holding position history. + * @author Elad Lahav + */ +class HistoryPage : public QueryPageBase +{ + Q_OBJECT + +public: + HistoryPage(QWidget* pParent = 0, const char* szName = 0); + ~HistoryPage(); + + void addRecord(const QString&, uint, const QString&); + + virtual QString getCaption(bool bBrief = false) const; + +protected: + virtual void addRecord(const QString&, const QString&, const QString&, + const QString&); + virtual QString getFileName(const QString&) const; + + /** + * @return Always true, since History files do not contain a header + */ + virtual bool readHeader(QTextStream&) { return true; } + + /** + * This method does nothing, since History files do not contain a header. + */ + virtual void writeHeader(QTextStream&) {} + +private: + /** A unique ID used to create a tab caption for this page. */ + int m_nPageID; + + /** Used to generate the unique page ID for each object. */ + static int s_nMaxPageID; +}; + +#endif diff --git a/src/historyview.cpp b/src/historyview.cpp new file mode 100644 index 0000000..519c4dc --- /dev/null +++ b/src/historyview.cpp @@ -0,0 +1,124 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include "historyview.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +HistoryView::HistoryView(QWidget* pParent, const char* szName) : + QueryView(pParent, szName) +{ + // Disable sorting + setSortColumn(-1); + + // Don't show the "Function" column + setColumnWidthMode(0, QListView::Manual); + setColumnWidth(0, 0); +} + +/** + * Class destructor. + */ +HistoryView::~HistoryView() +{ +} + +/** + * Creates a new list item showing a history record. + * @param sFunc The name of the function + * @param sFile The file path + * @param sLine The line number in the above file + * @param sText The line's text + */ +void HistoryView::addRecord(const QString& /* sFunc */, const QString& sFile, + const QString& sLine, const QString& sText, QListViewItem*) +{ + HistoryItem* pItem; + + pItem = new HistoryItem(this, sFile, sLine, sText); + setSelected(pItem, true); +} + +/** + * Moves to the previous item in the history, selecting it for display. + * Note that this function move to the item which chronologically precedes + * the current one, which, in list view terms, is the next item. + */ +void HistoryView::selectPrev() +{ + QListViewItem* pItem; + + // Get the current item + pItem = currentItem(); + + // Select the next item in the list + if (pItem != NULL && pItem->nextSibling() != NULL) { + pItem = pItem->nextSibling(); + select(pItem); + } +} + +/** + * Moves to the next item in the history, selecting it for display. + * Note that this function move to the item which chronologically succedes + * the current one, which, in list view terms, is the previous item. + */ +void HistoryView::selectNext() +{ + HistoryItem* pItem; + + // Get the current item + pItem = (HistoryItem*)currentItem(); + + // Select the previous item in the list + if (pItem != NULL && pItem->m_pPrevSibling != NULL) { + pItem = pItem->m_pPrevSibling; + select(pItem); + } +} + +/** + * Deletes the item on which a popup-menu has been invoked. + * This slot is connected to the remove() signal of the QueryResultsMenu + * object. + * @param pItem The item to remove + */ +void HistoryView::slotRemoveItem(QListViewItem* pItem) +{ + HistoryItem* pCurItem, * pNextItem; + + pCurItem = (HistoryItem*)pItem; + if ((pNextItem = (HistoryItem*)pCurItem->nextSibling()) != NULL) + pNextItem->m_pPrevSibling = pCurItem->m_pPrevSibling; + + delete pCurItem; +} + +#include "historyview.moc" diff --git a/src/historyview.h b/src/historyview.h new file mode 100644 index 0000000..38a0c46 --- /dev/null +++ b/src/historyview.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef HISTORYVIEW_H +#define HISTORYVIEW_H + +#include "queryview.h" + +/** + * A list view item for holding position history records. + * A QListViewItem cannot reference its preceding item, which is required to + * create a stack-like history list. Therefore a HistoryItem object + * stores a pointer to the item just above it in the list. The pointer is + * persistent, since the list cannot be sorted. + * @author Elad Lahav + */ + +class HistoryItem : public QListViewItem +{ +public: + /** + * Class constructor. + * @param pList The parent list view + * @param sFile The file path in this record + * @param sLine The line number + * @param sText The contents of the line in the given file + */ + HistoryItem(QListView* pList, QString sFile, QString sLine, + QString sText) : + QListViewItem(pList, "", sFile, sLine, sText), + m_pPrevSibling(NULL) { + HistoryItem* pNext; + + // Mark the new item as the predecessor of its next sibling + if ((pNext = (HistoryItem*)nextSibling()) != NULL) + pNext->m_pPrevSibling = this; + } + + /** The item immediately above this one in the list. */ + HistoryItem* m_pPrevSibling; +}; + +/** + * A list view widget for holding position history. + * Position history is kept in a stack-like list. Positions are always added + * to the top of the list, immediately before the current item. If the + * current item is not the top one, all items above it are purged first. + * To keep the stack-like structure, the list cannot be sorted. + * @author Elad Lahav + */ +class HistoryView : public QueryView +{ +Q_OBJECT +public: + HistoryView(QWidget* pParent = 0, const char* szName = 0); + ~HistoryView(); + + virtual void addRecord(const QString&, const QString&, const QString&, + const QString&, QListViewItem*); + virtual void selectNext(); + virtual void selectPrev(); + +protected slots: + virtual void slotRemoveItem(QListViewItem*); +}; + +#endif diff --git a/src/kscope.cpp b/src/kscope.cpp new file mode 100644 index 0000000..4a4ab60 --- /dev/null +++ b/src/kscope.cpp @@ -0,0 +1,1754 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kscope.h" +#include "kscopeconfig.h" +#include "projectmanager.h" +#include "editortabs.h" +#include "fileview.h" +#include "filelist.h" +#include "querywidget.h" +#include "editormanager.h" +#include "cscopefrontend.h" +#include "ctagslist.h" +#include "newprojectdlg.h" +#include "openprojectdlg.h" +#include "preferencesdlg.h" +#include "dirscanner.h" +#include "querypage.h" +#include "calltreedlg.h" +#include "calltreemanager.h" +#include "kscopepixmaps.h" +#include "progressdlg.h" +#include "projectfilesdlg.h" +#include "cscopemsgdlg.h" +#include "symboldlg.h" +#include "symbolcompletion.h" +#include "queryviewdlg.h" +#include "graphwidget.h" +#include "makedlg.h" +#include "welcomedlg.h" +#include "bookmarksdlg.h" +#include "kscopeactions.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +KScope::KScope(QWidget* pParent, const char* szName) : + KParts::DockMainWindow(pParent, szName), + m_pCscopeBuild(NULL), + m_sCurFilePath(""), + m_nCurLine(0), + m_pProgressDlg(NULL), + m_bUpdateGUI(true), + m_bCscopeVerified(false), + m_bRebuildDB(false), + m_pMakeDlg(NULL) +{ + QString sPath; + + // Load configuration + Config().load(); + + // Create the main child widgets + m_pEditTabs = new EditorTabs(this, NULL); + m_pQueryWidget = new QueryWidget(this); + m_pFileView = new FileView(this); + m_pFileList = m_pFileView->getFileList(); + m_pMsgDlg = new CscopeMsgDlg(this); + m_pQueryDock = createDockWidget("Query Window", QPixmap()); + m_pFileViewDock = createDockWidget("File List Window", QPixmap()); + + // Connect menu and toolbar items with the object's slots + m_pActions = new KScopeActions(this); + m_pActions->init(); + m_pActions->slotEnableProjectActions(false); + + // Show a toolbar show/hide menu + setStandardToolBarMenuEnabled(true); + + // Create the initial GUI (no active part) + setXMLFile("kscopeui.rc"); + createShellGUI(); + + // Create all child widgets + initMainWindow(); + + // Create control objects + m_pProjMgr = new ProjectManager(); + m_pEditMgr = new EditorManager(this); + m_pCallTreeMgr = new CallTreeManager(this); + + // Initialise the icon manager + Pixmaps().init(); + + // Open a file for editing when selected in the project's file list or the + // file tree + connect(m_pFileView, SIGNAL(fileRequested(const QString&, uint)), this, + SLOT(slotShowEditor(const QString&, uint))); + + // Delete an editor page object after it is removed + connect(m_pEditTabs, SIGNAL(editorRemoved(EditorPage*)), + this, SLOT(slotDeleteEditor(EditorPage*))); + + connect(m_pEditTabs, SIGNAL(filesDropped(QDropEvent*)), this, + SLOT(slotDropEvent(QDropEvent*))); + + // Set an editor as the active part whenever its owner tab is selected + connect(m_pEditTabs, SIGNAL(editorChanged(EditorPage*, EditorPage*)), + this, SLOT(slotChangeEditor(EditorPage*, EditorPage*))); + + // Display a file at a specific line when selected in a query list + connect(m_pQueryWidget, SIGNAL(lineRequested(const QString&, uint)), + this, SLOT(slotQueryShowEditor(const QString&, uint))); + + // Display the symbol dialogue when the user opens a new query page + connect(m_pQueryWidget, SIGNAL(newQuery()), + this, SLOT(slotQueryReference())); + + // Rebuild the project database after a certain time period has elapsed + // since the last save + connect(&m_timerRebuild, SIGNAL(timeout()), this, SLOT(slotRebuildDB())); + + // Display a file at a specific line when selected in a call tree dialogue + connect(m_pCallTreeMgr, SIGNAL(lineRequested(const QString&, uint)), + this, SLOT(slotQueryShowEditor(const QString&, uint))); + + // Store main window settings when closed + setAutoSaveSettings(); + + // Initialise arrow head drawing + GraphWidget::setArrowInfo(20, 15); + + // Use a maximised window the first time + if (Config().isFirstTime()) + showMaximized(); + + // Show the Welcome message + if (Config().showWelcomeDlg()) { + show(); + slotShowWelcome(); + } + + // If this is the first time the user has launched KScope, prompt him/her + // to configure the global parameters + if (Config().isFirstTime()) + slotConfigure(); +} + +/** + * Class destructor. + */ +KScope::~KScope() +{ + // Save configuration + Config().store(); + Config().storeWorkspace(this); + + delete m_pCallTreeMgr; + delete m_pEditMgr; + delete m_pCscopeBuild; + delete m_pProjMgr; + + if (m_pMakeDlg != NULL) + delete m_pMakeDlg; +} + +/** + * Positions child widgets into their docking stations, and performs some + * other main window initialisation. + */ +void KScope::initMainWindow() +{ + KStatusBar* pStatus; + KDockWidget* pMainDock; + QPopupMenu* pPopup; + + // Create the status bar + pStatus = statusBar(); + pStatus->insertItem(i18n(" Line: N/A Col: N/A "), 0, 0, true); + + // Create the main dock for the editor tabs widget + pMainDock = createDockWidget("Editors Window", QPixmap()); + pMainDock->setWidget(m_pEditTabs); + pMainDock->setDockSite(KDockWidget::DockCorner); + setMainDockWidget(pMainDock); + setView(pMainDock); + pMainDock->setEnableDocking(KDockWidget::DockNone); + + // Create the query window dock + m_pQueryDock->setWidget(m_pQueryWidget); + m_pQueryDock->manualDock(pMainDock, KDockWidget::DockBottom, 65); + + // Update the relevant shell action when the dock is hidden through its + // close button + connect(m_pQueryDock, SIGNAL(headerCloseButtonClicked()), m_pActions, + SLOT(slotQueryDockClosed())); + + // Create the file view dock + m_pFileViewDock->setWidget(m_pFileView); + m_pFileViewDock->manualDock(pMainDock, KDockWidget::DockRight, 80); + + // Update the relevant shell action when the dock is hidden through its + // close button + connect(m_pFileViewDock, SIGNAL(headerCloseButtonClicked()), m_pActions, + SLOT(slotFileViewDockClosed())); + + // Associate the "Window" menu with the editor tabs widdget + pPopup = (QPopupMenu*)factory()->container("window", this); + m_pEditTabs->setWindowMenu(pPopup); + + // Associate the "Query" popup menu with the query widget + pPopup = (QPopupMenu*)factory()->container("query_popup", this); + m_pQueryWidget->setPageMenu(pPopup, m_pActions->getLockAction()); + + // Restore dock configuration + Config().loadWorkspace(this); + m_bHideQueryOnSelection = m_pQueryDock->isHidden(); + m_pActions->initLayoutActions(); +} + +/** + * Handles the "File->Quit" command. Closes the main window, which terminates + * the application. + */ +void KScope::slotClose() +{ + // Destroy the main window + KParts::DockMainWindow::close(); +} + +/** + * Called when a request has been issued to close the main window. + * Tries to close the active project. + * @return true if the main window can be closed, false otherwise + */ +bool KScope::queryClose() +{ + bool bResult; + + m_bUpdateGUI = false; + bResult = slotCloseProject(); + m_bUpdateGUI = true; + + return bResult; +} + +/** + * Handles the "Project->New..." command. + * Prompts the user for the name and folder for the project, and then creates + * the project. + */ +void KScope::slotCreateProject() +{ + NewProjectDlg dlg(true, this); + ProjectBase::Options opt; + QString sProjPath; + + // Prompt the user to close any active projects + if (m_pProjMgr->curProject()) { + if (KMessageBox::questionYesNo(0, + i18n("The current project needs to be closed before a new one is" + " created.\nWould you like to close it now?")) != + KMessageBox::Yes) { + return; + } + + // Try to close the project. + if (!slotCloseProject()) + return; + } + + // Display the "New Project" dialog + if (dlg.exec() != QDialog::Accepted) + return; + + // Create and open the new project + dlg.getOptions(opt); + if (m_pProjMgr->create(dlg.getName(), dlg.getPath(), opt, sProjPath)) + openProject(sProjPath); +} + +/** + * Handles the "Project->Open..." command. + * Prompts the user for a project file ("cscope.proj"), and opens the + * selected project. + */ +void KScope::slotOpenProject() +{ + OpenProjectDlg dlg; + QString sPath; + + if (dlg.exec() == QDialog::Rejected) + return; + + sPath = dlg.getPath(); + + // Check if the path refers to a permanent or temporary project + if (QFileInfo(sPath).isDir()) + openProject(sPath); + else + openCscopeOut(sPath); +} + +/** + * Handles the "Project->Add/Remove Files..." command. + * Opens the project's files dialog, which allows the user to add and remove + * source files. + */ +void KScope::slotProjectFiles() +{ + ProjectBase* pProj; + + // A project must be open + pProj = m_pProjMgr->curProject(); + if (!pProj) + return; + + // Cannot update the file list of a temporary project + if (pProj->isTemporary()) { + KMessageBox::error(0, i18n("The Add/Remove Files dialogue is not " + "available for temporary projects.")); + return; + } + + // Display the files dialog + ProjectFilesDlg dlg((Project*)pProj, this); + if (dlg.exec() != QDialog::Accepted) + return; + + // Update the project's file list + if (pProj->storeFileList(&dlg)) + slotProjectFilesChanged(); +} + +/** + * Handles the "Project->Properties..." command. + * Opens the project's properties dialog, which allows the user to change + * some attributes of the current project. + * source files. + */ +void KScope::slotProjectProps() +{ + ProjectBase* pProj; + ProjectBase::Options opt; + + // A project must be open + pProj = m_pProjMgr->curProject(); + if (!pProj) + return; + + // No properties for a temporary project + if (pProj->isTemporary()) { + KMessageBox::error(0, i18n("The Project Properties dialogue is not " + "available for temporary projects.")); + return; + } + + // Create the properties dialog + NewProjectDlg dlg(false, this); + pProj->getOptions(opt); + dlg.setProperties(pProj->getName(), pProj->getPath(), opt); + + // Display the properties dialog + if (dlg.exec() != QDialog::Accepted) + return; + + // Set new properties + dlg.getOptions(opt); + pProj->setOptions(opt); + + // Reset the CscopeFrontend class and the builder object + initCscope(); + + // Set auto-completion parameters + SymbolCompletion::initAutoCompletion(opt.bACEnabled, opt.nACMinChars, + opt.nACDelay, opt.nACMaxEntries); + + // Set per-project command-line arguments for Ctags + CtagsFrontend::setExtraArgs(opt.sCtagsCmd); + + // Set the source root + m_pFileView->setRoot(pProj->getSourceRoot()); +} + +/** + * Handles the "Cscope->Open Cscope.out..." menu command. + * Prompts the user for a Cscope.out file, and, if successful, opens a new + * session for working with this file. + */ +void KScope::slotProjectCscopeOut() +{ + QString sFilePath; + + // Prompt for a Cscope.out file + sFilePath = KFileDialog::getOpenFileName(); + if (sFilePath.isEmpty()) + return; + + // Open a temporary project + openCscopeOut(sFilePath); +} + +/** + * Handles the "Cscope->References..." menu command. + * Prompts the user for a symbol name, and initiates a query to find all + * references to that symbol. + */ +void KScope::slotQueryReference() +{ + slotQuery(SymbolDlg::Reference, true); +} + +/** + * Handles the "Cscope->Definition..." menu command. + * Prompts the user for a symbol name, and initiates a query to find the + * global definition of that symbol. + */ +void KScope::slotQueryDefinition() +{ + slotQuery(SymbolDlg::Definition, true); +} + +/** + * Handles the "Cscope->Called Functions..." menu command. + * Prompts the user for a function name, and initiates a query to find all + * function calls from that function. + */ +void KScope::slotQueryCalled() +{ + slotQuery(SymbolDlg::Called, true); +} + +/** + * Handles the "Cscope->Calling Functions..." menu command. + * Prompts the user for a function name, and initiates a query to find all + * functions calling that function. + */ +void KScope::slotQueryCalling() +{ + slotQuery(SymbolDlg::Calling, true); +} + +/** + * Handles the "Cscope->Find Text..." menu command. + * Prompts the user for a string, and initiates a query to find all +occurances + * of that string. + */ +void KScope::slotQueryText() +{ + slotQuery(SymbolDlg::Text, true); +} + +/** + * Handles the "Cscope->Find EGrep Pattern..." menu command. + * Prompts the user for a regular expression, and initiates a query to find + * all strings matching that pattern. + */ +void KScope::slotQueryPattern() +{ + slotQuery(SymbolDlg::Pattern, true); +} + +/** + * Handles the "Cscope->Find File..." menu command. + * Prompts the user for a file name, and initiates a query to find all files + * having that name. + */ +void KScope::slotQueryFile() +{ + slotQuery(SymbolDlg::FileName, true); +} + +/** + * Handles the "Cscope->Find Including Files..." menu command. + * Prompts the user for a file name, and initiates a query to find all files + * having an '#include' directive to that file. + */ +void KScope::slotQueryIncluding() +{ + slotQuery(SymbolDlg::Including, true); +} + +/** + * Handles the "Cscope->Quick Definition" menu command. + * Initiates a query to find the global definition of the symbol currently + * selected or under the cursor. The user is prompted only if no symbol can + * be found. + */ +void KScope::slotQueryQuickDef() +{ + QString sSymbol; + QueryViewDlg* pDlg; + uint nType; + bool bCase; + + // Get the requested symbol and query type + nType = SymbolDlg::Definition; + if (!getSymbol(nType, sSymbol, bCase, false)) + return; + + // Create a modeless query view dialogue + pDlg = new QueryViewDlg(QueryViewDlg::DestroyOnSelect, this); + + // Display a line when it is selected in the dialogue + connect(pDlg, SIGNAL(lineRequested(const QString&, uint)), this, + SLOT(slotShowEditor(const QString&, uint))); + + // Start the query + pDlg->query(nType, sSymbol); +} + +/** + * Handles the "Cscope->Call Tree..." menu command. + * Displays a tree of functions calling the requested function. + */ +void KScope::slotCallTree() +{ + slotQuery(SymbolDlg::CallTree, true); +} + +/** + * Handles the "Cscope->Rebuild Database..." command. + * Rebuilds Cscope's database for the current project. + */ +void KScope::slotRebuildDB() +{ + ProjectBase* pProj; + + pProj = m_pProjMgr->curProject(); + if (!pProj) + return; + + if (!pProj->dbExists()) { + m_pProgressDlg = new ProgressDlg(i18n("KScope"), i18n("Please wait " + "while KScope builds the database"), this); + m_pProgressDlg->setAllowCancel(false); + m_pProgressDlg->setValue(0); + } + + m_pCscopeBuild->rebuild(); +} + +/** + * Handles the "Settings->Configure Shortcuts..." command. + * Displays the prferences dialog, which allows the user + * to change the shortcuts for KScope. + */ +void KScope::slotShortcuts() +{ + KKeyDialog::configure(actionCollection(), this); +} + +/** + * Handles the "Settings->Configure KScope..." command. + * Displays the prferences dialog, which allows the user to set different + * configuration parameters for KScope. + */ +void KScope::slotConfigure() +{ + PreferencesDlg dlg; + + // Apply the preferences if either the "Apply" or the "OK" buttons are + // clicked + connect(&dlg, SIGNAL(applyPref()), this, SLOT(slotApplyPref())); + + // Show the dialog + if (dlg.exec() == QDialog::Accepted) { + // Verify Cscope's installation + verifyCscope(); + } +} + +/** + * Refreshes the file list when files are added to or removed from a project, + * and rebuilds the Cscope database. + * This slot is attached to the fileListChanged() signal emitted by + * the ProjectManager object. + */ +void KScope::slotProjectFilesChanged() +{ + QStringList slArgs; + + // Refresh the file list + m_pFileList->setUpdatesEnabled(false); + m_pFileList->clear(); + m_pProjMgr->curProject()->loadFileList(m_pFileList); + m_pFileList->setUpdatesEnabled(true); + + // Rebuild the symbol database + if (isAutoRebuildEnabled()) + slotRebuildDB(); +} + +/** + * Adds a list of files to the current project. + * This slot is connected to the filesAdded() signal of the ProjectManager + * object. Once files are added to the project, they are also added to the + * file list, and the project's database is rebuilt. + * @param slFiles The list of file paths added to the project + */ +void KScope::slotFilesAdded(const QStringList& slFiles) +{ + QStringList::const_iterator itr; + + // Add the file paths to the project's file list + for (itr = slFiles.begin(); itr != slFiles.end(); ++itr) + m_pFileList->addItem(*itr); + + // Rebuild the database + if (isAutoRebuildEnabled()) + slotRebuildDB(); +} + +/** + * Promts the user for a symbol, an starts a new Cscope query. + * @param nType The numeric query type code + * @param bPrompt true to always prompt for a symbol, false to try to + * obtain the symbol automatically + */ +void KScope::slotQuery(uint nType, bool bPrompt) +{ + QString sSymbol; + CallTreeDlg* pCallTreeDlg; + bool bCase; + + // Get the requested symbol and query type + if (!getSymbol(nType, sSymbol, bCase, bPrompt)) + return; + + if (nType == SymbolDlg::CallTree) { + // Create and display a call tree dialogue + pCallTreeDlg = m_pCallTreeMgr->addDialog(); + pCallTreeDlg->setRoot(sSymbol); + pCallTreeDlg->show(); + } + else { + // Run the requested query + nType = SymbolDlg::getQueryType(nType); + m_pQueryWidget->initQuery(nType, sSymbol, bCase); + + // Ensure Query Window is visible + toggleQueryWindow(true); + } +} + +/** + * Opens a project. + * If another project is currently active, it is closed first. + * @param sDir The directory of the project to open. + */ +void KScope::openProject(const QString& sDir) +{ + QString sProjDir; + ProjectBase* pProj; + QStringList slQueryFiles; + QStringList slCallTreeFiles; + QStringList slArgs; + ProjectBase::Options opt; + + // Close the current project (may return false if the user clicks on the + // "Cancel" button while prompted to save a file) + if (!slotCloseProject()) + return; + + // Open the project in the project manager + sProjDir = QDir::cleanDirPath(sDir); + if (!m_pProjMgr->open(sProjDir)) + return; + + // Change main window title + pProj = m_pProjMgr->curProject(); + setCaption(pProj->getName()); + + // Set the root of the file tree + m_pFileView->setRoot(pProj->getSourceRoot()); + + // Initialise Cscope and create a builder object + initCscope(); + + // Set auto-completion parameters + pProj->getOptions(opt); + SymbolCompletion::initAutoCompletion(opt.bACEnabled, opt.nACMinChars, + opt.nACDelay, opt.nACMaxEntries); + + // Set per-project command-line arguments for Ctags + CtagsFrontend::setExtraArgs(opt.sCtagsCmd); + + // Create an initial query page + m_pQueryWidget->addQueryPage(); + + // Enable project-related actions + m_pActions->slotEnableProjectActions(true); + + // If this is a new project (i.e., no source files are yet included), + // display the project files dialogue + if (pProj->isEmpty()) { + slotProjectFiles(); + return; + } + + // Fill the file list with all files in the project. + m_pFileList->setUpdatesEnabled(false); + pProj->loadFileList(m_pFileList); + m_pFileList->setUpdatesEnabled(true); + + // Restore the last session + restoreSession(); + + // Rebuild the cross-reference database + if (isAutoRebuildEnabled()) { + // If Cscope installation was not yet verified, postpone the build + // process + if (m_bCscopeVerified) + slotRebuildDB(); + else + m_bRebuildDB = true; + } +} + +/** + * Opens a temporary project for a Cscope.out file. + * @param sFilePath The full path of the Cscope.out file + * @return true if successful, false otherwise + */ +bool KScope::openCscopeOut(const QString& sFilePath) +{ + ProjectBase* pProj; + + // Close the current project (may return false if the user clicks on the + // "Cancel" button while prompted to save a file) + if (!slotCloseProject()) + return false; + + // Open a temporary project for this cscope.out file + if (!m_pProjMgr->openCscopeOut(sFilePath)) + return false; + + // Change main window title + pProj = m_pProjMgr->curProject(); + setCaption(pProj->getName()); + + // Set the root folder in the file tree + m_pFileView->setRoot(pProj->getSourceRoot()); + + // Initialise Cscope and create a builder object + initCscope(); + + // Create an initial query page + m_pQueryWidget->addQueryPage(); + + // Enable project-related actions + m_pActions->slotEnableProjectActions(true); + + // Fill the file list with all files in the project. + m_pFileList->setUpdatesEnabled(false); + pProj->loadFileList(m_pFileList); + m_pFileList->setUpdatesEnabled(true); + + return true; +} + +/** + * Opens the most recently used project. + * This method is called when KScope starts, but only if the relevant + * configuration flag (Reload Last Project) is set. + */ +void KScope::openLastProject() +{ + const QStringList slProjects = Config().getRecentProjects(); + QString sPath; + + if (slProjects.empty()) + return; + + // Get the project's path + sPath = *slProjects.begin(); + + // Check if the path refers to a temporary project + if (!QFileInfo(sPath).isDir()) { + openCscopeOut(sPath); + return; + } + + openProject(sPath); +} + +/** + * Reopens all files which were open when the project was last closed. + * In order to reduce the time required by this operation, the GUI of all + * but the last editor part is not merged with that of the main window. + */ +void KScope::restoreSession() +{ + ProjectBase* pProj; + Project::Session sess; + FileLocation* pLoc; + EditorPage* pPage; + + // A session is available for persistent projects only + pProj = m_pProjMgr->curProject(); + if (!pProj || pProj->isTemporary()) + return; + + // Make sure all FileLocation objects are deleted + sess.fllOpenFiles.setAutoDelete(true); + sess.fllBookmarks.setAutoDelete(true); + + // Load the session + ((Project*)pProj)->loadSession(sess); + + // Do not update the GUI when loading the editor parts of the initially + // hidden windows + m_bUpdateGUI = false; + + for (pLoc = sess.fllOpenFiles.first(); pLoc != NULL; + pLoc = sess.fllOpenFiles.next()) { + if (QFile::exists(pLoc->m_sPath)) { + pPage = addEditor(pLoc->m_sPath); + pPage->setCursorPos(pLoc->m_nLine, pLoc->m_nCol); + } + } + + // Merge the GUI of the visible editor part + m_bUpdateGUI = true; + + // Set the active editor (or choose a default one) + if (m_pEditTabs->findEditorPage(sess.sLastFile, true) == NULL) + m_pEditTabs->findEditorPage(sess.fllOpenFiles.last()->m_sPath, true); + + // Reload bookmarks + m_pEditTabs->setBookmarks(sess.fllBookmarks); + + // Load previously stored queries and call trees + m_pQueryWidget->loadPages(pProj->getPath(), sess.slQueryFiles); + m_pCallTreeMgr->loadOpenDialogs(pProj->getPath(), sess.slCallTreeFiles); +} + +/** + * Shows or hides the query dock window. + * This function is only called internally, not as a result of a user's + * workspace action (e.g., clicking the "Show/Hide Query Window" toolbar + * button). Therefore it does not reflect the user's preference, which is + * kept through the m_bHideQueryOnSelection variable. + * @param bShow true to show the window, false to hide it + */ +void KScope::toggleQueryWindow(bool bShow) +{ + // Remember the user's preferences + if (bShow) + m_bHideQueryOnSelection = m_pQueryDock->isHidden(); + else + m_bHideQueryOnSelection = false; + + // Change the visibility state of the widget, if required + if (m_pQueryDock->isShown() != bShow) + m_pQueryDock->changeHideShowState(); + + // Synchronise with the menu command's state + m_pActions->slotQueryDockToggled(bShow); +} + +/** + * Parses the command line, after it was stripped of its KDE options. + * The command line may contain one of the following options: + * 1. A project file (named cscope.proj) + * 2. A Cscope cross-reference database + * 3. A list of source files + * @param pArgs Command line arguments + */ +void KScope::parseCmdLine(KCmdLineArgs* pArgs) +{ + QString sArg; + QFileInfo fi; + int i; + + // Loop over all arguments + for (i = 0; i < pArgs->count(); i++) { + // Verify the argument is a file or directory name + sArg = pArgs->arg(i); + fi.setFile(sArg); + if (!fi.exists()) + continue; + + // Handle the current argument + if (fi.isFile()) { + if (fi.fileName() == "cscope.proj") { + // Open a project file + openProject(fi.dirPath(true)); + return; + } else if (openCscopeOut(sArg)) { + // Opened the file as a cross-reference database + return; + } else { + // Assume this is a source file + slotShowEditor(sArg, 0); + } + } else if (fi.isDir()) { + // Treat the given path as a project directory + openProject(fi.absFilePath()); + return; + } + } +} + +/** + * Starts a shell script to ensure that Cscope is properly installed and to + * extract the supported command-line arguments. + */ +void KScope::verifyCscope() +{ + CscopeVerifier* pVer; + + statusBar()->message(i18n("Verifying Cscope installation...")); + + pVer = new CscopeVerifier(); + connect(pVer, SIGNAL(done(bool, uint)), this, + SLOT(slotCscopeVerified(bool, uint))); + + pVer->verify(); +} + +/** + * Initialises the CscopeFrontend class with the current project arguments, + * and creates an object used for rebuilding the symbol database. + */ +void KScope::initCscope() +{ + ProjectBase* pProj; + + // Delete the current object, if one exists + if (m_pCscopeBuild) + delete m_pCscopeBuild; + + // Initialise CscopeFrontend + pProj = m_pProjMgr->curProject(); + CscopeFrontend::init(pProj->getPath(), pProj->getArgs()); + + // Create a persistent Cscope process + m_pCscopeBuild = new CscopeFrontend(); + + // Show build progress information in the main status bar + connect(m_pCscopeBuild, SIGNAL(progress(int, int)), this, + SLOT(slotBuildProgress(int, int))); + connect(m_pCscopeBuild, SIGNAL(buildInvIndex()), this, + SLOT(slotBuildInvIndex())); + connect(m_pCscopeBuild, SIGNAL(finished(uint)), this, + SLOT(slotBuildFinished(uint))); + connect(m_pCscopeBuild, SIGNAL(aborted()), this, + SLOT(slotBuildAborted())); + + // Show errors in a modeless dialogue + connect(m_pCscopeBuild, SIGNAL(error(const QString&)), this, + SLOT(slotCscopeError(const QString&))); +} + +/** + * Closes the active project. + * Closing a project involves closing all of the editor windows (prompting + * the user for unsaved changes); terminating the Cscope process; and further + * clean-up of the project's data. + */ +bool KScope::slotCloseProject() +{ + ProjectBase* pProj; + Project::Session sess; + + // Do nothing if no project is open + pProj = m_pProjMgr->curProject(); + if (!pProj) + return true; + + // Make sure all FileLocation objects are deleted + sess.fllOpenFiles.setAutoDelete(true); + sess.fllBookmarks.setAutoDelete(true); + + // Close all open editor pages + if (m_pEditTabs->count() > 0) { + // Save session information for persistent projects + if (!pProj->isTemporary()) { + sess.sLastFile = m_pEditTabs->getCurrentPage()->getFilePath(); + m_pEditTabs->getOpenFiles(sess.fllOpenFiles); + m_pEditTabs->getBookmarks(sess.fllBookmarks); + } + + if (!m_pEditTabs->removeAllPages()) + return false; + } + + // Disable project-related actions + m_pActions->slotEnableProjectActions(false); + + // Destroy the make dialogue + if (m_pMakeDlg != NULL) { + // Save session information for persistent projects + if (!pProj->isTemporary()) { + sess.sMakeCmd = m_pMakeDlg->getCommand(); + sess.sMakeRoot = m_pMakeDlg->getDir(); + } + + delete m_pMakeDlg; + m_pMakeDlg = NULL; + } + + // Save session information for persistent projects + if (!pProj->isTemporary()) { + m_pQueryWidget->savePages(pProj->getPath(), sess.slQueryFiles); + m_pCallTreeMgr->saveOpenDialogs(pProj->getPath(), sess.slCallTreeFiles); + } + + // Close all query pages and call trees + m_pQueryWidget->slotCloseAll(); + m_pCallTreeMgr->closeAll(); + + // Store session information for persistent projects + if (!pProj->isTemporary()) + ((Project*)pProj)->storeSession(sess); + + // Close the project in the project manager, and terminate the Cscope + // process + m_pProjMgr->close(); + delete m_pCscopeBuild; + m_pCscopeBuild = NULL; + setCaption(QString::null); + + // Clear the contents of the file list + m_pFileView->clear(); + + // Reset queried symbols history + SymbolDlg::resetHistory(); + + // Remove any remaining status bar messages + statusBar()->message(""); + + return true; +} + +/** + * Handles the "Edit->Edit in External Editor" menu command. + * Invokes an external editor for the current file and line number. + */ +void KScope::slotExtEdit() +{ + QString sCmdLine; + KProcess proc; + + // Create the command line for the external editor + sCmdLine = Config().getExtEditor(); + sCmdLine.replace("%F", m_sCurFilePath); + sCmdLine.replace("%L", QString::number(m_nCurLine)); + + // Run the external editor + proc.setUseShell(true); + proc << sCmdLine; + proc.start(KProcess::DontCare); +} + +/** + * Handles the "Edit->Complete Symbol" menu command. + * Creates a list of possible completions for the symbol currently under the + * cursor. + */ +void KScope::slotCompleteSymbol() +{ + EditorPage* pPage; + + pPage = m_pEditTabs->getCurrentPage(); + if (pPage != NULL) + pPage->slotCompleteSymbol(); +} + +/** + * Handles the "Help->Show Welcome Message..." menu command. + * Displays the "Welcome" dialogue. + */ +void KScope::slotShowWelcome() +{ + WelcomeDlg dlg; + dlg.exec(); +} + +/** + * Handles the "Edit->Go To Tag" menu command. + * Sets the cursor to the edit box of the current tag list. + */ +void KScope::slotGotoTag() +{ + EditorPage* pPage; + + pPage = m_pEditTabs->getCurrentPage(); + if (pPage) + pPage->setTagListFocus(); +} + +/** + * Reports the results of the Cscope verification script. + * This slot is connected to the done() signal emitted by the CscopeVerifier + * object constructed in verifyCscope(). + */ +void KScope::slotCscopeVerified(bool bResult, uint nArgs) +{ + statusBar()->message(i18n("Verifying Cscope installation...Done"), 3000); + + // Mark the flag even if Cscope was not found, to avoid nagging the user + // (who may wish to use KScope even with Cscope disabled) + m_bCscopeVerified = true; + + // Prompt the user in case Cscope is not properly installed + if (!bResult) { + KMessageBox::error(0, i18n("Cscope may not be properly installed on " + "this system.\nPlease check the Cscope path specified in KScope's " + "configuration dialogue.")); + slotConfigure(); + return; + } + + // Set the discoverred supported command-line arguments + CscopeFrontend::setSupArgs(nArgs); + + // Build the database, if required + if (m_bRebuildDB) { + m_bRebuildDB = false; + slotRebuildDB(); + } +} + +/** + * Handles the "Project->Make..." menu command. + * Displays the make dialogue. + */ +void KScope::slotProjectMake() +{ + QString sCmd, sDir; + + // Create the make dialogue, if it does not exist + if (m_pMakeDlg == NULL) { + // Create the dialogue + m_pMakeDlg = new MakeDlg(); + + // Set make parameters for this project + m_pProjMgr->curProject()->getMakeParams(sCmd, sDir); + m_pMakeDlg->setCommand(sCmd); + m_pMakeDlg->setDir(sDir); + + // Show the relevant source location when an error link is clicked + connect(m_pMakeDlg, SIGNAL(fileRequested(const QString&, uint)), this, + SLOT(slotShowEditor(const QString&, uint))); + + // Show the dialogue + m_pMakeDlg->show(); + } + else if (m_pMakeDlg->isShown()) { + // The dialogue exists, and is visible, just raise it + m_pMakeDlg->raise(); + m_pMakeDlg->setActiveWindow(); + } + else { + // The dialogue exists but is closed, show it + m_pMakeDlg->show(); + } +} + +/** + * Handles the "Project->Remake..." menu command. + * Displays the make dialogue and runs the make command. + */ +void KScope::slotProjectRemake() +{ + // Make sure the make dialogue exists and is displayed + slotProjectMake(); + + // Run the make command + m_pMakeDlg->slotMake(); +} + +/** + * Handles the "Go->Global Bookmarks" menu command. + * Displays a dialogue with the set of all bookmarks currently set in this + * project. + */ +void KScope::slotShowBookmarks() +{ + BookmarksDlg dlg; + QString sPath; + uint nLine; + + // Load the bookmark list + m_pEditTabs->showBookmarks(dlg.getView()); + + // Show the dialogue + if (dlg.exec() != QDialog::Accepted) + return; + + // Go to the selected bookmark + dlg.getBookmark(sPath, nLine); + slotShowEditor(sPath, nLine); +} + +/** + * Prompts the user for a symbol to query. + * Shows a dialog with a line edit widget, where the user can enter a symbol + * on which to query Cscope. The meaning of the symbol depends on the type of + * query. + * @param nType The requested type of query (may be changed in the + * dialogue) + * @param sSymbol Holds the requested symbol, upon successful return + * @param bPrompt If false, the user is prompted only if a symbol cannot be + * determined automatically + * @return true if the user hs enetered a symbol, false otherwise + */ +bool KScope::getSymbol(uint& nType, QString& sSymbol, bool& bCase, + bool bPrompt) +{ + EditorPage* pPage; + QString sSuggested; + + // Set the currently selected text, if any + if ((pPage = m_pEditTabs->getCurrentPage()) != NULL) + sSuggested = pPage->getSuggestedText(); + + // Return if a symbol was found, and prompting is turned off + if (!sSuggested.isEmpty() && !bPrompt) { + sSymbol = sSuggested; + return true; + } + + // Show the symbol dialogue + sSymbol = SymbolDlg::promptSymbol(this, nType, sSuggested, bCase); + + // Cannot accept empty strings + if (sSymbol.isEmpty()) + return false; + + return true; +} + +/** + * Opens a file in a new editor tab. + * If an editor page already exists for the requested file, it is selected. + * Otherwise, a new page is created, and the requested file is loaded. + * @param sFilePath The path of the file to open + * @return A pointer to the found or newly created editor page + */ +EditorPage* KScope::addEditor(const QString& sFilePath) +{ + EditorPage* pPage; + QString sAbsFilePath; + ProjectBase* pProj; + + // If the file name is given using a relative path, we need to convert + // it to an absolute one + // TODO: Project needs a translatePath() method + pProj = m_pProjMgr->curProject(); + if (sFilePath[0] != '/' && pProj) { + sAbsFilePath = QDir::cleanDirPath(pProj->getSourceRoot() + "/" + + sFilePath); + } + else { + sAbsFilePath = QDir::cleanDirPath(sFilePath); + } + + // Do not open a new editor if one exists for this file + pPage = m_pEditTabs->findEditorPage(sAbsFilePath); + if (pPage != NULL) + return pPage; + + // Create a new page + pPage = createEditorPage(); + + // Open the requested file + pPage->open(sAbsFilePath); + + return pPage; +} + +/** + * Creates a new editor page, and adds it to the editors tab widget. + * @return A pointer to the new page + */ +EditorPage* KScope::createEditorPage() +{ + KTextEditor::Document* pDoc; + EditorPage* pPage; + QPopupMenu* pMenu; + ProjectBase* pProj; + + // Load a new document part + pDoc = m_pEditMgr->add(); + if (pDoc == NULL) + return NULL; + + // Create the new editor page + pMenu = (QPopupMenu*)factory()->container(Config().getEditorPopupName(), + this); + pPage = new EditorPage(pDoc, pMenu, m_pEditTabs); + m_pEditTabs->addEditorPage(pPage); + + // Show the file's path in the main title + connect(pPage, SIGNAL(fileOpened(EditorPage*, const QString&)), this, + SLOT(slotFileOpened(EditorPage*, const QString&))); + + // Show cursor position in the status bar + connect(pPage, SIGNAL(cursorPosChanged(uint, uint)), this, + SLOT(slotShowCursorPos(uint, uint))); + + // Rebuild the database after a file has changed + connect(pPage, SIGNAL(fileSaved(const QString&, bool)), this, + SLOT(slotFileSaved(const QString&, bool))); + + // Handle file drops + connect(pPage->getView(), SIGNAL(dropEventPass(QDropEvent*)), this, + SLOT(slotDropEvent(QDropEvent*))); + + // Apply per-project configuration + pProj = m_pProjMgr->curProject(); + if (pProj && pProj->getTabWidth() > 0) + pPage->setTabWidth(pProj->getTabWidth()); + + return pPage; +} + +/** + * @return true if database auto-rebuild is enabled for the current project, + * false otherwise + */ +inline bool KScope::isAutoRebuildEnabled() +{ + ProjectBase* pProj; + + pProj = m_pProjMgr->curProject(); + return (pProj && pProj->getAutoRebuildTime() >= 0); +} + +/** + * Deletes an editor page after it has been removed. + * The document object associated with the page is removed from the part + * manager, and the view object is removed from the GUI manager. + * This slot is connected to the editorRemoved() signal of the EditorTabs + * object. + * @param pPage The editor page to delete + */ +void KScope::slotDeleteEditor(EditorPage* pPage) +{ + guiFactory()->removeClient(pPage->getView()); + m_pEditMgr->remove(pPage->getDocument()); + delete pPage; +} + +/** + * Sets an editor part as active when its owner tab is chosen. + * Whenever a different editor tab is chosen, its editor part should become + * the active part. This means that this part's GUI is merged with the + * application's, and that it responds to actions. + * @param pOldPage The editor page that has ceased to be active + * @param pNewPage The newly chosen editor page + */ +void KScope::slotChangeEditor(EditorPage* pOldPage, EditorPage* pNewPage) +{ + KXMLGUIFactory* pFactory = guiFactory(); + + // Remove the current GUI + if (pOldPage) + pFactory->removeClient(pOldPage->getView()); + + // Set the new active part and create its GUI + if (m_bUpdateGUI && pNewPage) { + m_pEditMgr->setActivePart(pNewPage->getDocument()); + pFactory->addClient(pNewPage->getView()); + m_sCurFilePath = pNewPage->getFilePath(); + setCaption(m_pProjMgr->getProjName() + " - " + m_sCurFilePath); + } + + // Enable/disable file-related actions, if necessary + if (pOldPage && !pNewPage) + m_pActions->slotEnableFileActions(false); + else if (!pOldPage && pNewPage) + m_pActions->slotEnableFileActions(true); +} + +/** + * Opens an editor for the given file and sets the cursor to the beginning of + * the requested line. + * @param sFilePath The full path of the file to open for editing + * @param nLine The number of the line on which to position the + * cursor, or 0 to maintain the cursor in its current + * position (which does not affect the position history) + */ +void KScope::slotShowEditor(const QString& sFilePath, uint nLine) +{ + EditorPage* pPage; + + // Save current position in the position history + if (nLine != 0 && (pPage = m_pEditTabs->getCurrentPage())) { + m_pQueryWidget->addHistoryRecord(m_sCurFilePath, m_nCurLine, + pPage->getLineContents(m_nCurLine)); + } + + // Open the requested file (or select an already-open editor page) + pPage = addEditor(sFilePath); + if (pPage == NULL) + return; + + // Make sure the main window is visible + raise(); + setWindowState(windowState() & ~WindowMinimized | WindowActive); + + if (nLine != 0) { + // Set the cursor to the requested line + pPage->slotGotoLine(nLine); + + // Add the new position to the position history + m_pQueryWidget->addHistoryRecord(m_sCurFilePath, m_nCurLine, + pPage->getLineContents(m_nCurLine)); + } +} + +/** + * A wrapper around slotShowEditor, that enables auto-hiding of the query + * widget after a query result has been chosen. + * This slot is connected to the lineRequested() signal emitted by a QueryPage + * object. + * @param sFilePath The full path of the file to open for editing + * @param nLine The number of the line on which to position the cursor + */ +void KScope::slotQueryShowEditor(const QString& sFilePath, uint nLine) +{ + // Hide the query window, if it was hidden before a query was initiated + if (m_bHideQueryOnSelection) + toggleQueryWindow(false); + + // Open an editor at the requested line + slotShowEditor(sFilePath, nLine); +} + +/** + * Handles the "Go->Position History" menu command. + * Ensures that the query window is visible, and selects the active history + * page. + */ +void KScope::slotHistoryShow() +{ + toggleQueryWindow(true); + m_pQueryWidget->selectActiveHistory(); +} + +/** + * Handles the "File->New" menu command. + * Creates an editor page for a new unnamed file. + */ +void KScope::slotNewFile() +{ + EditorPage* pPage; + + // Create the new editor page + pPage = createEditorPage(); + + // Mark the page as containing a new file + pPage->setNewFile(); +} + +/** + * Handles the "File->Open" menu command. + * Prompts the user for a file name, and opens it in a new editor page. + */ +void KScope::slotOpenFile() +{ + ProjectBase* pProj; + QStringList slFiles; + QStringList::Iterator itr; + + // Prompt the user for the file(s) to open. + pProj = m_pProjMgr->curProject(); + slFiles = KFileDialog::getOpenFileNames(pProj ? pProj->getSourceRoot() : + QString::null); + + // Open all selected files. + for (itr = slFiles.begin(); itr != slFiles.end(); ++itr) { + if (!(*itr).isEmpty()) + slotShowEditor(*itr, 0); + } +} + +/** + * Handles the "File->Close" menu command. + * Closes the currently active editor page. + */ +void KScope::slotCloseEditor() +{ + m_pEditTabs->removeCurrentPage(); +} + +/** + * Handles the "Window->Close All" menu command. + * Closes all open editor pages. + */ +void KScope::slotCloseAllWindows() +{ + m_bUpdateGUI = false; + m_pEditTabs->removeAllPages(); + m_bUpdateGUI = true; +} + +/** + * Displays error messages from a Cscope process. + * This slot is connected to the progress() signal emitted by the any + * Cscope process. + * @param sMsg The error message + */ +void KScope::slotCscopeError(const QString& sMsg) +{ + m_pMsgDlg->addText(sMsg); +} + +/** + * Reports progress information from the Cscope process responsible for + * rebuilding the cross-reference database. + * This slot is connected to the progress() signal emitted by the builder + * process. + * Progress information is displayed in the status bar. + * @param nFiles The number of files scanned + * @param nTotal The total number of files in the project + */ +void KScope::slotBuildProgress(int nFiles, int nTotal) +{ + QString sMsg; + + // Use the progress dialogue, if it exists (first time builds) + if (m_pProgressDlg) { + m_pProgressDlg->setValue((nFiles * 100) / nTotal); + return; + } + + // Show progress information + sMsg = i18n("Rebuilding the cross reference database...") + " " + + QString::number((nFiles * 100) / nTotal) + "%"; + statusBar()->message(sMsg); +} + +/** + * Reports to the user that Cscope has started building the inverted index. + * This slot is connected to the buildInvIndex() signal emitted by the + * builder process. + */ +void KScope::slotBuildInvIndex() +{ + if (m_pProgressDlg) { + m_pProgressDlg->setLabel(i18n("Please wait while KScope builds the " + "inverted index")); + m_pProgressDlg->setIdle(); + return; + } + + statusBar()->message(i18n("Rebuilding inverted index...")); +} + +/** + * Informs the user the database rebuild process has finished. + * This slot is connected to the finished() signal emitted by the builder + * process. + */ +void KScope::slotBuildFinished(uint) +{ + // Delete the progress dialogue, if it exists (first time builds) + if (m_pProgressDlg) { + delete m_pProgressDlg; + m_pProgressDlg = NULL; + return; + } + + // Show a message in the status bar + statusBar()->message(i18n("Rebuilding the cross reference database..." + "Done!"), 3000); +} + +/** + * Called if the build process failed to complete. + * This slot is connected to the aborted() signal emitted by the builder + * process. + */ +void KScope::slotBuildAborted() +{ + // Delete the progress dialogue, if it exists (first time builds) + if (m_pProgressDlg) { + delete m_pProgressDlg; + m_pProgressDlg = NULL; + + // Display a failure message + KMessageBox::error(0, i18n("The database could not be built.\n" + "Cross-reference information will not be available for this " + "project.\n" + "Please ensure that the Cscope parameters were correctly " + "entered in the \"Settings\" dialogue.")); + return; + } + + // Show a message in the status bar + statusBar()->message(i18n("Rebuilding the cross reference database..." + "Failed"), 3000); +} + +/** + * Applies the selected user preferences once the "Apply" or "OK" buttons in + * the preferences dialog is clicked. + */ +void KScope::slotApplyPref() +{ + m_pQueryWidget->applyPrefs(); + m_pFileList->applyPrefs(); + m_pEditTabs->applyPrefs(); + m_pEditMgr->applyPrefs(); + + // Enable/disable the external editor menu item + m_pActions->enableExtEditor(Config().useExtEditor()); +} + +/** + * Displays the current cursor position, whenever it is moved by the user. + * This slot is connected to the cursorPosChanged() signal emitted by an + * EditorPage object. + * @param nLine The new line number + * @param nCol The new column number + */ +void KScope::slotShowCursorPos(uint nLine, uint nCol) +{ + KStatusBar* pStatus = statusBar(); + QString sText; + + /* Show the line and column numbers. */ + QTextOStream(&sText) << " Line: " << nLine << " Col: " << nCol << " "; + pStatus->changeItem(sText, 0); + + /* Store the current line. */ + m_nCurLine = nLine; +} + +/** + * Stores the path of a newly opened file. + * This slot is connected to the fileOpened() signal emitted by an + * EditorPage object. + * @param sFilePath The full path of the opened file + */ +void KScope::slotFileOpened(EditorPage*, const QString& sFilePath) +{ + m_sCurFilePath = sFilePath; + setCaption(m_pProjMgr->getProjName() + " - " + m_sCurFilePath); +} + +/** + * Sets a timer for rebuilding the database after a file has been saved. + * This slot is connected to the fileSaved() signal emitted by an EditorPage + * object. + * The time period before rebuilding is determined on a per-project basis. + * @param sPath The full path of the modified file that caused this event + * @param bIsNew true if this is a new file, false otherwise + */ +void KScope::slotFileSaved(const QString& sPath, bool bIsNew) +{ + ProjectBase* pProj; + int nTime; + + pProj = m_pProjMgr->curProject(); + if (!pProj) + return; + + // Prompt the user to add this file to the current project + if (bIsNew && !pProj->isTemporary()) { + if (KMessageBox::questionYesNo(0, + i18n("Whould you like to add this file to the active project?")) == + KMessageBox::Yes) { + + // Add the path to the 'cscope.files' file + if (!((Project*)pProj)->addFile(sPath)) { + KMessageBox::error(0, i18n("Failed to write the file list.")); + return; + } + + // Add the path to the file list widget + m_pFileList->addItem(sPath); + + // Rebuild immediately + slotRebuildDB(); + return; + } + } + + // Get the project's auto-rebuild time + nTime = pProj->getAutoRebuildTime(); + + // Do nothing if the time is set to -1 + if (nTime == -1) + return; + + // Check if the file is included in the project (external files should + // not trigger the timer) + if (!m_pFileList->findFile(sPath)) + return; + + // Rebuild immediately for a time set to 0 + if (nTime == 0) { + slotRebuildDB(); + return; + } + + // Reset the rebuild timer + m_timerRebuild.start(nTime * 1000, true); +} + +/** + * Handles file drops inside the editors tab widget. + * Opens all files dropped over the widget. + * @param pEvent Pointer to an object containing the list of dropped files + */ +void KScope::slotDropEvent(QDropEvent* pEvent) +{ + KURL::List list; + KURL::List::Iterator itr; + + // Create a list of file URLs + if (!KURLDrag::decode(pEvent, list)) + return; + + // Open all files in the list + for (itr = list.begin(); itr != list.end(); ++itr) + addEditor((*itr).path()); +} + +#include "kscope.moc" diff --git a/src/kscope.desktop b/src/kscope.desktop new file mode 100644 index 0000000..453a4fc --- /dev/null +++ b/src/kscope.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=KScope +Exec=kscope +Icon=kscope +Type=Application +Comment=Source-editing environment for large C projects +Comment[fr]=Editeur de codes sources pour de gros projets en C +GenericName=Source editing environment +GenericName[fr]=Editeur de code source +Categories=Qt;KDE;Development + diff --git a/src/kscope.h b/src/kscope.h new file mode 100644 index 0000000..f1b646e --- /dev/null +++ b/src/kscope.h @@ -0,0 +1,235 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef KSCOPE_H +#define KSCOPE_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +class ProjectManager; +class EditorTabs; +class FileView; +class FileList; +class QueryWidget; +class EditorManager; +class CscopeFrontend; +class EditorPage; +class ProgressDlg; +class CscopeMsgDlg; +class MakeDlg; +class CallTreeManager; +class KScopeActions; + +/** + * Defines the main window of KScope. + * The main window has both UI and functional tasks. As a window, it is + * composed of three parts: + * 1. The editing area (EditorTabs - a tab widget with editor pages) + * 2. The project pane (FileList - listing the files in the project) + * 3. The query pane (QueryWidget - a tab widget with pages displaying query + * results in lists) + * The main window also maintains the main menu, the toolbar and the status- + * bar, and is responsible for handling all the actions connected to these + * bars. + * As the application's main class, it is responsible for managing projects + * (using a ProjectManager object) and for running instances of Cscope + * (through a CscopeFrontend object). + * @author Elad Lahav + */ +class KScope : public KParts::DockMainWindow +{ + Q_OBJECT + +public: + KScope(QWidget* pParent = 0, const char* szName = 0); + ~KScope(); + + void openProject(const QString&); + void openLastProject(); + bool openCscopeOut(const QString&); + void parseCmdLine(KCmdLineArgs *pArgs); + void verifyCscope(); + +public slots: + void slotClose(); + +protected: + virtual bool queryClose(); + +private: + /** A project manager used to load projects and read their properties. */ + ProjectManager* m_pProjMgr; + + /** The editors tabbed window. */ + EditorTabs* m_pEditTabs; + + /** The file selection widget (project file list and OS file system + tree.) */ + FileView* m_pFileView; + + /** Pointer to the file list part of the FileView widget. */ + FileList* m_pFileList; + + /** The query results tabbed window. */ + QueryWidget* m_pQueryWidget; + + /** A KDE editor part manager, responsible for creating KTextEditor + parts. */ + EditorManager* m_pEditMgr; + + /** A Cscope process for building the database. */ + CscopeFrontend* m_pCscopeBuild; + + /** A timer for rebuilding the database after a file has been saved. */ + QTimer m_timerRebuild; + + /** Whether the query window should be hidden after the user selects an + item. */ + bool m_bHideQueryOnSelection; + + /** The file view docking area. */ + KDockWidget* m_pFileViewDock; + + /** The query window docking area. */ + KDockWidget* m_pQueryDock; + + /** A persistent dialog used to display error messages from Cscope. */ + CscopeMsgDlg* m_pMsgDlg; + + /** The path of the file currently being edited. */ + QString m_sCurFilePath; + + /** The line number of the current cursor position. */ + int m_nCurLine; + + /** Creates and maintains call tree dialogues. */ + CallTreeManager* m_pCallTreeMgr; + + /** A progress dialogue that is displayed when building the database for + the first time. */ + ProgressDlg* m_pProgressDlg; + + /** A flag indicating whether the GUI of the embedded editor should be + merged with that of KScope's. Can be turned off to save time when + loading/closing a number of editor parts. */ + bool m_bUpdateGUI; + + /** Set to true after a shell script has verified that Cscope is installed + and correctly configured on this system. + No Cscope operations should be run if this flag is set to false. */ + bool m_bCscopeVerified; + + /** + * Used to postpone rebuilding of the database, until Cscope is ready. + */ + bool m_bRebuildDB; + + /** + * A widget for running make. + */ + MakeDlg* m_pMakeDlg; + + /** + * Manages menu and tool-bar commands. + */ + KScopeActions* m_pActions; + + void initMainWindow(); + void initCscope(); + bool getSymbol(uint&, QString&, bool&, bool bPrompt = true); + EditorPage* addEditor(const QString&s); + EditorPage* createEditorPage(); + inline bool isAutoRebuildEnabled(); + void restoreSession(); + void toggleQueryWindow(bool); + + friend class KScopeActions; + +private slots: + // Menu actions + void slotNewFile(); + void slotOpenFile(); + void slotCloseEditor(); + void slotCreateProject(); + void slotOpenProject(); + void slotProjectFiles(); + void slotProjectProps(); + void slotProjectCscopeOut(); + bool slotCloseProject(); + void slotQueryReference(); + void slotQueryDefinition(); + void slotQueryCalled(); + void slotQueryCalling(); + void slotQueryText(); + void slotQueryPattern(); + void slotQueryFile(); + void slotQueryIncluding(); + void slotQueryQuickDef(); + void slotCallTree(); + void slotRebuildDB(); + void slotHistoryShow(); + void slotShortcuts(); + void slotConfigure(); + void slotCloseAllWindows(); + void slotExtEdit(); + void slotCompleteSymbol(); + void slotShowWelcome(); + void slotGotoTag(); + void slotProjectMake(); + void slotProjectRemake(); + void slotShowBookmarks(); + + // Other slots + void slotProjectFilesChanged(); + void slotFilesAdded(const QStringList&); + void slotQuery(uint, bool); + void slotDeleteEditor(EditorPage*); + void slotChangeEditor(EditorPage*, EditorPage*); + void slotShowEditor(const QString&, uint); + void slotFileOpened(EditorPage*, const QString&); + void slotFileSaved(const QString&, bool); + void slotCscopeError(const QString&); + void slotBuildProgress(int, int); + void slotBuildInvIndex(); + void slotBuildFinished(uint); + void slotBuildAborted(); + void slotApplyPref(); + void slotShowCursorPos(uint, uint); + void slotQueryShowEditor(const QString&, uint); + void slotDropEvent(QDropEvent*); + void slotCscopeVerified(bool, uint); +}; + +#endif diff --git a/src/kscope.lsm b/src/kscope.lsm new file mode 100644 index 0000000..1062526 --- /dev/null +++ b/src/kscope.lsm @@ -0,0 +1,16 @@ +Begin4 +Title: KScope +Version: 1.4.0 +Entered-date: ? +Description: A source-editing environment for KDE bsaed on Cscope +Keywords: KDE Cscope Source Browser Editor IDE C +Author: elad_lahav@users.sourceforge.net (Elad Lahav) +Maintained-by: elad_lahav@users.sourceforge.net (Elad Lahav) +Home-page: http://kscope.sourceforge.net +Alternate-site: +Primary-site: http://download.sourceforge.net/kscope/ + ?M kscope-1.4.0.tar.gz + ? kscope-1.4.0.lsm +Platform: Linux/Unix. Requires KDE. +Copying-policy: BSD +End diff --git a/src/kscope_config b/src/kscope_config new file mode 100644 index 0000000..25fad0f --- /dev/null +++ b/src/kscope_config @@ -0,0 +1,165 @@ +# Configures KScope parameters + +# Checks that the given executable is indeed a Cscope-compatible application +# and determines which options it supports. +verifyCscope() +{ + CSCOPE_EXE=`basename $CSCOPE_PATH` + + if [ $DEBUG ] + then + echo -n Checking $CSCOPE_EXE version... + fi + + # Get the executable's version + CSCOPE_VER_MAJOR=`$CSCOPE_PATH -V 2>&1 | grep -i $CSCOPE_EXE | sed -e "s/.*version \([1-9][0-9]*\)\.\([0-9]\).*/\1/"` + CSCOPE_VER_MINOR=`$CSCOPE_PATH -V 2>&1 | grep -i $CSCOPE_EXE | sed -e "s/.*version \([1-9][0-9]*\)\.\([0-9]\).*/\2/"` + + if [ -n "$CSCOPE_VER_MAJOR" -a "$CSCOPE_VER_MINOR" ] + then + echo $CSCOPE_VER_MAJOR.$CSCOPE_VER_MINOR + + if [ $DEBUG ] + then + echo -n Cscope support for line mode verbose output... + fi + + # Check for verbose output + if [ "`$CSCOPE_PATH -h 2>&1 | grep "\-v"`" ] + then + CSCOPE_VERBOSE=Yes + else + CSCOPE_VERBOSE=No + fi + echo $CSCOPE_VERBOSE + + if [ $DEBUG ] + then + echo -n Cscope support slow path definitions... + fi + + # Check for slow-path definitions + if [ "`$CSCOPE_PATH -h 2>&1 | grep "\-D"`" ] + then + CSCOPE_SLOWPATH=Yes + else + CSCOPE_SLOWPATH=No + fi + echo $CSCOPE_SLOWPATH + else + echo ERROR + if [ $DEBUG ] + then + echo -e "\n *** ERROR *** The \"cscope\" executable does not appear to be a Cscope compatible programme" + fi + fi +} + +DEBUG=0 +CSCOPE_OPTIONS_ONLY= + +# Parse command-line parameters +# Supported options: +# -d: Debug mode +# -co: Check Cscope options only +for opt in $@ +do + case "$opt" in + "-d") DEBUG=1 + ;; + "-co") CSCOPE_OPTIONS_ONLY=1 + ;; + esac +done + +if [ $DEBUG ] +then + echo -n Looking for cscope... +fi + +if [ -z "$CSCOPE_PATH" ] +then + CSCOPE_PATH=`which cscope` +fi + +if [ -n "$CSCOPE_PATH" -a -x "$CSCOPE_PATH" ] +then + echo $CSCOPE_PATH + verifyCscope +else + echo ERROR + if [ $DEBUG ] + then + echo -e "\n *** ERROR *** No Cscope executable found" + fi +fi + +if [ -n "$CSCOPE_OPTIONS_ONLY" ] +then + exit +fi + +if [ $DEBUG ] +then + echo -n Looking for Ctags... +fi + +if [ -z "$CTAGS_PATH" ] +then + for CTAGS_NAME in exctags ctags-exuberant exuberant-ctags ctags + do + CTAGS_PATH=`which $CTAGS_NAME` + if [ -n "$CTAGS_PATH" -a -x "$CTAGS_PATH" ] + then + break + fi + done +fi + +if [ -n "$CTAGS_PATH" ] +then + echo $CTAGS_PATH + + # echo -n Checking for Exuberant-Ctags compatibility... + + CTAGS_EXUB=`$CTAGS_PATH --help | grep -c "\-\-excmd=number"` + if [ $CTAGS_EXUB -gt 0 ] + then + CTAGS_EXUB_PATH=$CTAGS_PATH + echo Yes + else + echo ERROR + # echo -e "\n *** ERROR *** The \"ctags\" executable does not appear to be compatible with Exuberant Ctags" + fi + +else + echo ERROR + # echo -e "\n *** ERROR *** No Ctags executable found" +fi + +# echo -n Looking for Dot... + +if [ -z "$DOT_PATH" ] +then + DOT_PATH=`which dot` +fi + +if [ -n "$DOT_PATH" -a -x "$DOT_PATH" ] +then + echo $DOT_PATH + + # echo -n Checking if dot handles the -Tplain option... + + echo "digraph G {Hello->World}" | $DOT_PATH -Tplain 2>&1 /dev/null + if [ $? -eq 0 ] + then + echo Yes + else + echo ERROR + # echo -e "\n *** ERROR *** The \"dot\" executable does not support -Tplain" + fi + +else + echo ERROR + # echo -e "\n *** ERROR *** No Dot executable found" +fi diff --git a/src/kscopeactions.cpp b/src/kscopeactions.cpp new file mode 100644 index 0000000..d5c64fc --- /dev/null +++ b/src/kscopeactions.cpp @@ -0,0 +1,533 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, m_pWindow list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, m_pWindow list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "kscope.h" +#include "kscopeactions.h" +#include "kscopeconfig.h" +#include "filelist.h" +#include "editortabs.h" +#include "querywidget.h" + +KScopeActions::KScopeActions(KScope* pWindow) : QObject(), + m_pWindow(pWindow), + m_pCollection(pWindow->actionCollection()) +{ +} + +KScopeActions::~KScopeActions() +{ +} + +/** + * Connects menu bar and toolbar commands with class members. These members + * handle the actions associated with each command. + */ +void KScopeActions::init() +{ + // File menu + KStdAction::openNew(m_pWindow, SLOT(slotNewFile()), m_pCollection); + KStdAction::open(m_pWindow, SLOT(slotOpenFile()), m_pCollection); + KStdAction::close(m_pWindow, SLOT(slotCloseEditor()), m_pCollection); + KStdAction::quit(m_pWindow, SLOT(slotClose()), m_pCollection); + + addAction(i18n("Go to File List"), + NULL, + "Ctrl+Shift+O", + m_pWindow->m_pFileList, + SLOT(slotSetFocus()), + "file_open_file_from_list", + SIGNAL(toggleProject(bool))); + + addAction(i18n("Save Al&l"), + "save_all", + "Ctrl+L", + m_pWindow->m_pEditTabs, + SLOT(slotSaveAll()), + "file_save_all", + NULL); + + // Edit menu + m_pExtEditAction = addAction(i18n("Edit in E&xternal Editor"), + NULL, + "Ctrl+E", + m_pWindow, + SLOT(slotExtEdit()), + "edit_external_editor", + SIGNAL(toggleFile(bool))); + + addAction(i18n("Go To Tag"), + NULL, + "Ctrl+Shift+T", + m_pWindow, + SLOT(slotGotoTag()), + "edit_goto_tag", + SIGNAL(toggleFile(bool))); + + addAction(i18n("Complete Symbol"), + NULL, + "Ctrl+Space", + m_pWindow, + SLOT(slotCompleteSymbol()), + "edit_comp_symbol", + SIGNAL(toggleFile(bool))); + + // Project menu + addAction(i18n("&New Project..."), + NULL, + NULL, + m_pWindow, + SLOT(slotCreateProject()), + "project_new", + NULL); + + addAction(i18n("&Open Project..."), + "project_open", + NULL, + m_pWindow, + SLOT(slotOpenProject()), + "project_open", + NULL); + + addAction(i18n("Open &Cscope.out..."), + NULL, + NULL, + m_pWindow, + SLOT(slotProjectCscopeOut()), + "project_cscope_out", + NULL); + + addAction(i18n("Add/Remove &Files..."), + NULL, + NULL, + m_pWindow, + SLOT(slotProjectFiles()), + "project_add_rem_files", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Properties..."), + NULL, + NULL, + m_pWindow, + SLOT(slotProjectProps()), + "project_properties", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Make Project"), + "make_kdevelop", + "Ctrl+M", + m_pWindow, + SLOT(slotProjectMake()), + "project_make", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Remake Project"), + "rebuild", + "Ctrl+Shift+M", + m_pWindow, + SLOT(slotProjectRemake()), + "project_remake", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Close Project"), + "fileclose", + NULL, + m_pWindow, + SLOT(slotCloseProject()), + "project_close", + SIGNAL(toggleProject(bool))); + + // Cscope menu + addAction(i18n("&References..."), + NULL, + "Ctrl+0", + m_pWindow, + SLOT(slotQueryReference()), + "cscope_references", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Definition..."), + NULL, + "Ctrl+1", + m_pWindow, + SLOT(slotQueryDefinition()), + "cscope_definition", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Called Functions..."), + NULL, + "Ctrl+2", + m_pWindow, + SLOT(slotQueryCalled()), + "cscope_called", + SIGNAL(toggleProject(bool))); + + addAction(i18n("C&alling Functions..."), + NULL, + "Ctrl+3", + m_pWindow, + SLOT(slotQueryCalling()), + "cscope_calling", + SIGNAL(toggleProject(bool))); + + addAction(i18n("Find &Text..."), + NULL, + "Ctrl+4", + m_pWindow, + SLOT(slotQueryText()), + "cscope_text", + SIGNAL(toggleProject(bool))); + + addAction(i18n("Find &EGrep Pattern..."), + NULL, + "Ctrl+5", + m_pWindow, + SLOT(slotQueryPattern()), + "cscope_pattern", + SIGNAL(toggleProject(bool))); + + addAction(i18n("Find &File..."), + NULL, + "Ctrl+7", + m_pWindow, + SLOT(slotQueryFile()), + "cscope_file", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Including Files..."), + NULL, + "Ctrl+8", + m_pWindow, + SLOT(slotQueryIncluding()), + "cscope_including", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Quick Definition"), + NULL, + "Ctrl+]", + m_pWindow, + SLOT(slotQueryQuickDef()), + "cscope_quick_def", + SIGNAL(toggleProject(bool))); + + addAction(i18n("Call &Graph..."), + NULL, + "Ctrl+\\", + m_pWindow, + SLOT(slotCallTree()), + "cscope_call_tree", + SIGNAL(toggleProject(bool))); + + addAction(i18n("Re&build database"), + "vcs_update", + NULL, + m_pWindow, + SLOT(slotRebuildDB()), + "cscope_rebuild", + SIGNAL(toggleProject(bool))); + + // Go menu + addAction(i18n("P&revious Result"), + "up", + "Alt+Up", + m_pWindow->m_pQueryWidget, + SLOT(slotPrevResult()), + "go_prev_result", + SIGNAL(toggleProject(bool))); + + addAction(i18n("N&ext Result"), + "down", + "Alt+Down", + m_pWindow->m_pQueryWidget, + SLOT(slotNextResult()), + "go_next_result", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Previous Position"), + "back", + "Alt+Left", + m_pWindow->m_pQueryWidget, + SLOT(slotHistoryPrev()), + "go_prev_pos", + NULL); + + addAction(i18n("&Next Position"), + "forward", + "Alt+Right", + m_pWindow->m_pQueryWidget, + SLOT(slotHistoryNext()), + "go_next_pos", + NULL); + + addAction(i18n("Position &History"), + "history", + "Ctrl+h", + m_pWindow, + SLOT(slotHistoryShow()), + "go_history", + NULL); + + addAction(i18n("Global &Bookmarks"), + "bookmark", + "Ctrl+Shift+G", + m_pWindow, + SLOT(slotShowBookmarks()), + "go_bookmarks", + NULL); + + // View menu + m_pToggleFileViewAction = addToggle(i18n("Toggle File List"), + "view_sidetree", + "Ctrl+/", + m_pWindow->m_pFileViewDock, + SLOT(changeHideShowState()), + "view_toggle_filelist_dock", + NULL); + + m_pToggleQueryWindowAction = addToggle(i18n("Toggle Query Window"), + "view_top_bottom", + "Ctrl+.", + m_pWindow->m_pQueryDock, + SLOT(changeHideShowState()), + "view_toggle_query_dock", + NULL); + + m_pToggleTagListAction = addToggle(i18n("Toggle Tag List"), + "view_detailed", + "Ctrl+'", + m_pWindow->m_pEditTabs, + SLOT(slotToggleTagList()), + "view_toggle_tag_list", + NULL); + + // Window menu + addAction(i18n("Close &All"), + "fileclose", + NULL, + m_pWindow, + SLOT(slotCloseAllWindows()), + "window_close_all", + NULL); + + addAction(i18n("Go &Left"), + "back", + "Alt+Shift+Left", + m_pWindow->m_pEditTabs, + SLOT(slotGoLeft()), + "window_go_left", + NULL); + + addAction(i18n("Go &Right"), + "forward", + "Alt+Shift+Right", + m_pWindow->m_pEditTabs, + SLOT(slotGoRight()), + "window_go_right", + NULL); + + // Settings menu + KStdAction::preferences(m_pWindow, SLOT(slotConfigure()), m_pCollection); + KStdAction::keyBindings(m_pWindow, SLOT(slotShortcuts()), m_pCollection); + + // Help menu + addAction(i18n("Show &Welcome Message..."), + NULL, + NULL, + m_pWindow, + SLOT(slotShowWelcome()), + "help_welcome", + NULL); + + // Query widget popup menu + addAction(i18n("&New"), + "filenew", + NULL, + m_pWindow->m_pQueryWidget, + SLOT(slotNewQueryPage()), + "query_new", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Refresh"), + "reload", + NULL, + m_pWindow->m_pQueryWidget, + SLOT(slotRefreshCurrent()), + "query_refresh", + SIGNAL(toggleProject(bool))); + + m_pLockAction = addToggle(i18n("&Lock/Unlock"), + "encrypted", + NULL, + m_pWindow->m_pQueryWidget, + SLOT(slotLockCurrent()), + "query_toggle_locked", + SIGNAL(toggleProject(bool))); + + addAction(i18n("&Close"), + "fileclose", + NULL, + m_pWindow->m_pQueryWidget, + SLOT(slotCloseCurrent()), + "query_close", + SIGNAL(toggleProject(bool))); + + m_pExtEditAction->setEnabled(Config().useExtEditor()); +} + +void KScopeActions::initLayoutActions() +{ + m_pToggleFileViewAction->setChecked(m_pWindow->m_pFileViewDock->isShown()); + m_pToggleQueryWindowAction->setChecked(m_pWindow->m_pQueryDock->isShown()); + m_pToggleTagListAction->setChecked(Config().getShowTagList()); +} + +/** + * Enables/disables the "Edit in External Editor" command. + * @param bEnable true to enable the command, false to disable it + */ +void KScopeActions::enableExtEditor(bool bEnable) +{ + m_pExtEditAction->setEnabled(bEnable); +} + +void KScopeActions::slotQueryDockToggled(bool bVisible) +{ + m_pToggleQueryWindowAction->setChecked(bVisible); +} + +/** + * Ensures the "Show/Hide Query Window" action is unchecked when the dock + * is closed through its close button. + * This slot is conncted to the headerCloseButtonClicked() signal of the + * query window dock widget. + */ +void KScopeActions::slotQueryDockClosed() +{ + m_pToggleQueryWindowAction->setChecked(false); +} + +/** + * Ensures the "Show/Hide File View" action is unchecked when the dock + * is closed through its close button. + * This slot is conncted to the headerCloseButtonClicked() signal of the + * file view dock widget. + */ +void KScopeActions::slotFileViewDockClosed() +{ + m_pToggleFileViewAction->setChecked(false); +} + +/** + * Enables/disables all actions related to open projects. + * This slot should be called whenever a project is opened or closed. + * @param bEnable true to enable actions, false to disable + */ +void KScopeActions::slotEnableProjectActions(bool bEnable) +{ + emit toggleProject(bEnable); +} + +/** + * Enables/disables all actions related to open files. + * This slot should be called the first file is opened, or when the last one + * is closed. + * @param bEnable true to enable actions, false to disable + */ +void KScopeActions::slotEnableFileActions(bool bEnable) +{ + emit toggleFile(bEnable); +} + +/** + * Creates a new action. + * @param sCaption The text to display in the menu item + * @param szIcon Optional icon associated with the action + * @param szShortcut Optional key-combination string + * @param pReceiver The widget to receive the action's signal + * @param szSlot The widget's slot that connect to the signal + * @param szName The XML entry corresponding to the action + * @param szSignal Optional signal to connect to the setEnabled() slot of + * the action + * @return The newly created action object + */ +KAction* KScopeActions::addAction(const QString& sCaption, const char* szIcon, + const char* szShortcut, QWidget* pReceiver, const char* szSlot, + const char* szName, const char* szSignal) +{ + KAction* pAction; + + // Create the action + pAction = new KAction(sCaption, + szIcon, + szShortcut == NULL ? KShortcut() : KShortcut(szShortcut), + pReceiver, + szSlot, + m_pCollection, + szName); + + // Add to the given action list, if any + if (szSignal) + connect(this, szSignal, pAction, SLOT(setEnabled(bool))); + + return pAction; +} + +/** + * Creates a new toggle action. + * @param sCaption The text to display in the menu item + * @param szIcon Optional icon associated with the action + * @param szShortcut Optional key-combination string + * @param pReceiver The widget to receive the action's signal + * @param szSlot The widget's slot that connect to the signal + * @param szName The XML entry corresponding to the action + * @param szSignal Optional signal to connect to the setEnabled() slot of + * the action + * @return The newly created action object + */ +KToggleAction* KScopeActions::addToggle(const QString& sCaption, + const char* szIcon, const char* szShortcut, QWidget* pReceiver, + const char* szSlot, const char* szName, const char* szSignal) +{ + KToggleAction* pAction; + + // Create the action + pAction = new KToggleAction(sCaption, + szIcon, + szShortcut == NULL ? KShortcut() : KShortcut(szShortcut), + pReceiver, + szSlot, + m_pCollection, + szName); + + // Add to the given action list, if any + if (szSignal) + connect(this, szSignal, pAction, SLOT(setEnabled(bool))); + + return pAction; +} + +#include "kscopeactions.moc" diff --git a/src/kscopeactions.h b/src/kscopeactions.h new file mode 100644 index 0000000..4836310 --- /dev/null +++ b/src/kscopeactions.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef KSCOPEACTIONS_H +#define KSCOPEACTIONS_H + +#include + +class KScope; + +typedef QPtrList ActionList; + +/** + * A helper class for managing KScope's menu commands. + * @author Elad Lahav + */ +class KScopeActions : public QObject +{ + Q_OBJECT + +public: + KScopeActions(KScope*); + ~KScopeActions(); + + void init(); + void initPopups(); + void initLayoutActions(); + void enableExtEditor(bool); + + KToggleAction* getLockAction() { return m_pLockAction; } + +public slots: + void slotQueryDockToggled(bool); + void slotQueryDockClosed(); + void slotFileViewDockClosed(); + void slotEnableProjectActions(bool); + void slotEnableFileActions(bool); + +signals: + void toggleProject(bool bEnable); + void toggleFile(bool bEnable); + +private: + KScope* m_pWindow; + KActionCollection* m_pCollection; + + /** A list of actions that require an active project. */ + ActionList m_lstProjActions; + + /** A list of actions that require an active file. */ + ActionList m_lstFileActions; + + /** A toggle menu item for locking/unlocking query pages. */ + KToggleAction* m_pLockAction; + + /** The "Edit in External Editor" menu command. */ + KAction* m_pExtEditAction; + + /** The "Show/Hide File View" menu command. */ + KToggleAction* m_pToggleFileViewAction; + + /** The "Show/Hide Query Window" menu command. */ + KToggleAction* m_pToggleQueryWindowAction; + + /** The "Show/Hide Tag List" menu command. */ + KToggleAction* m_pToggleTagListAction; + + KAction* addAction(const QString&, const char*, const char*, QWidget*, + const char*, const char*, const char*); + KToggleAction* addToggle(const QString&, const char*, const char*, + QWidget*, const char*, const char*, const char*); +}; + +#endif diff --git a/src/kscopeconfig.cpp b/src/kscopeconfig.cpp new file mode 100644 index 0000000..3cc5094 --- /dev/null +++ b/src/kscopeconfig.cpp @@ -0,0 +1,768 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include "kscopeconfig.h" + +// NOTE: +// This configuration file entry controls whether the welcome dialogue is +// displayed. Normally it only needs to be shown once, but the entry's name +// can be changed across versions to force the display of new information. +#define SHOW_WELCOME_ENTRY "ShowWelcomeDlg" + +/** + * Stores the display name and the configuration file entry for a configurable + * GUI element. + * @author Elad Lahav + */ +struct ElementInfo +{ + /** The display name of the element. */ + const char* szName; + + /** The configuration file entry. */ + const char* szEntry; +}; + +/** + * A list of GUI elements for which the colour can be configured. + */ +const ElementInfo eiColors[] = { + { "File List (Foreground)", "FileListFore" }, + { "File List (Background)", "FileListBack" }, + { "Tag List (Foreground)", "TagListFore" }, + { "Tag List (Background)", "TagListBack" }, + { "Query Window (Foreground)", "QueryListFore" }, + { "Query Window (Background)", "QueryListBack" }, + { "Call Graph (Background)", "GraphBack" }, + { "Call Graph (Nodes)", "GraphNode" }, + { "Call Graph (Text)", "GraphText" }, + { "Call Graph (Multi-Call Nodes)", "GraphMultiCall" } +}; + +/** + * A list of GUI elements for which the font can be configured. + */ +const ElementInfo eiFonts[] = { + { "File List", "FileList" }, + { "Tag List", "TagList" }, + { "Query Page", "QueryList" }, + { "Call Graph", "Graph" } +}; + +#define COLOR_NAME(_i) eiColors[_i].szName +#define COLOR_ENTRY(_i) eiColors[_i].szEntry +#define FONT_NAME(_i) eiFonts[_i].szName +#define FONT_ENTRY(_i) eiFonts[_i].szEntry + +KScopeConfig::ConfParams KScopeConfig::s_cpDef = { + "/usr/bin/cscope", // Cscope path + "/usr/bin/ctags", // Ctags path + "/usr/bin/dot", // Dot path + true, // Show the tag list + SPLIT_SIZES(), // Tag list width + { + QColor(black), // File list foreground + QColor(white), // File list background + QColor(black), // Tag list foreground + QColor(white), // Tag list background + QColor(black), // Query page foreground + QColor(white), // Query page background + QColor("#c0c0c0"), // Call graph background + QColor("#c0ff80"), // Call graph nodes + QColor(black), // Call graph text + QColor("#ff8000") + }, + { + QFont(), // Font definitions are overriden in load() + QFont(), + QFont(), + QFont() + }, + NameAsc, // Ctags sort order + false, // Read-only mode + true, // Load last project + true, // Automatic tag highlighting + false, // Brief query captions + true, // Warn when file is modified on the disk + true, // Sort files when a project is loaded + "kate --line %L %F", // External editor example + Fast, // System profile + Embedded, // Editor context menu + "TB", // Call graph orientation + 10, // Maximum calls per graph node + 0 // Default graph view +}; + +/** + * Class constructor. + */ +KScopeConfig::KScopeConfig() : m_bFontsChanged(false) +{ +} + +/** + * Class destructor. + */ +KScopeConfig::~KScopeConfig() +{ +} + +/** + * Reads KScope's parameters from the standard configuration file. + */ +void KScopeConfig::load() +{ + uint i; + + KConfig* pConf = kapp->config(); + + // Need a working instance to get the system's default font (cannot be + // initialised statically) + s_cpDef.fonts[FileList] = KGlobalSettings::generalFont(); + s_cpDef.fonts[TagList] = KGlobalSettings::generalFont(); + s_cpDef.fonts[QueryWindow] = KGlobalSettings::generalFont(); + s_cpDef.fonts[Graph] = KGlobalSettings::generalFont(); + + // Read the paths to required executables + pConf->setGroup("Programs"); + m_cp.sCscopePath = pConf->readEntry("CScope"); + m_cp.sCtagsPath = pConf->readEntry("CTags"); + m_cp.sDotPath = pConf->readEntry("Dot"); + + // Read size and position parameters + pConf->setGroup("Geometry"); + m_cp.bShowTagList = pConf->readBoolEntry("ShowTagList", + s_cpDef.bShowTagList); + m_cp.siEditor = pConf->readIntListEntry("Editor"); + if (m_cp.siEditor.empty()) + m_cp.siEditor << 200 << 800; + + // Read the recent projects list + pConf->setGroup("Projects"); + m_slProjects = pConf->readListEntry("Recent"); + + // Read colour settings + pConf->setGroup("Colors"); + for (i = 0; i <= LAST_COLOR; i++) { + m_cp.clrs[i] = pConf->readColorEntry(COLOR_ENTRY(i), + &s_cpDef.clrs[i]); + } + + // Read font settings + pConf->setGroup("Fonts"); + for (i = 0; i <= LAST_FONT; i++) { + m_cp.fonts[i] = pConf->readFontEntry(FONT_ENTRY(i), + &s_cpDef.fonts[i]); + } + + // Other options + pConf->setGroup("Options"); + m_cp.ctagSortOrder = + (CtagSort)pConf->readUnsignedNumEntry("CtagSortOrder", + s_cpDef.ctagSortOrder); + m_cp.bReadOnlyMode = pConf->readBoolEntry("ReadOnlyMode", + s_cpDef.bReadOnlyMode); + m_cp.bLoadLastProj = pConf->readBoolEntry("LoadLastProj", + s_cpDef.bLoadLastProj); + m_cp.bAutoTagHl = pConf->readBoolEntry("AutoTagHl", + s_cpDef.bAutoTagHl); + m_cp.bBriefQueryCaptions = pConf->readBoolEntry("BriefQueryCaptions", + s_cpDef.bBriefQueryCaptions); + m_cp.bWarnModifiedOnDisk = pConf->readBoolEntry("WarnModifiedOnDisk", + s_cpDef.bWarnModifiedOnDisk); + m_cp.bAutoSortFiles = pConf->readBoolEntry("AutoSortFiles", + s_cpDef.bAutoSortFiles); + m_cp.sExtEditor = pConf->readEntry("ExternalEditor", s_cpDef.sExtEditor); + m_cp.profile = (SysProfile)pConf->readUnsignedNumEntry("SystemProfile", + s_cpDef.profile); + m_cp.popup = (EditorPopup)pConf->readUnsignedNumEntry("EditorPopup", + s_cpDef.popup); + m_cp.sGraphOrient = pConf->readEntry("GraphOrientation", + s_cpDef.sGraphOrient); + m_cp.nGraphMaxNodeDegree = pConf->readNumEntry("GraphMaxNodeDegree", + s_cpDef.nGraphMaxNodeDegree); + m_cp.nDefGraphView = pConf->readNumEntry("DefGraphView", + s_cpDef.nDefGraphView); +} + +/** + * Sets default values to he configuration parameters (except for those where + * a default value has no meaning, such as the recent projects list). + */ +void KScopeConfig::loadDefault() +{ + m_cp = s_cpDef; +} + +/** + * Loads the layout of the main window. + * @param pMainWindow Pointer to the main docking window + */ +void KScopeConfig::loadWorkspace(KDockMainWindow* pMainWindow) +{ + pMainWindow->readDockConfig(kapp->config(), "Workspace"); +} + +/** + * Writes KScope's parameters from the standard configuration file. + */ +void KScopeConfig::store() +{ + uint i; + + KConfig* pConf = kapp->config(); + + // Write the paths to required executables + pConf->setGroup("Programs"); + pConf->writeEntry("CScope", m_cp.sCscopePath); + pConf->writeEntry("CTags", m_cp.sCtagsPath); + pConf->writeEntry("Dot", m_cp.sDotPath); + + // Write size and position parameters + pConf->setGroup("Geometry"); + pConf->writeEntry("ShowTagList", m_cp.bShowTagList); + pConf->writeEntry("Editor", m_cp.siEditor); + + // Write the recent projects list + pConf->setGroup("Projects"); + pConf->writeEntry("Recent", m_slProjects); + + // Write colour settings + pConf->setGroup("Colors"); + for (i = 0; i <= LAST_COLOR; i++) + pConf->writeEntry(COLOR_ENTRY(i), m_cp.clrs[i]); + + // Write font settings + if (m_bFontsChanged) { + pConf->setGroup("Fonts"); + for (i = 0; i <= LAST_FONT; i++) + pConf->writeEntry(FONT_ENTRY(i), m_cp.fonts[i]); + + m_bFontsChanged = false; + } + + // Other options + pConf->setGroup("Options"); + pConf->writeEntry("CtagSortOrder", (uint)m_cp.ctagSortOrder); + pConf->writeEntry("ReadOnlyMode", m_cp.bReadOnlyMode); + pConf->writeEntry("LoadLastProj", m_cp.bLoadLastProj); + pConf->writeEntry("AutoTagHl", m_cp.bAutoTagHl); + pConf->writeEntry("BriefQueryCaptions", m_cp.bBriefQueryCaptions); + pConf->writeEntry("WarnModifiedOnDisk", m_cp.bWarnModifiedOnDisk); + pConf->writeEntry("AutoSortFiles", m_cp.bAutoSortFiles); + pConf->writeEntry("ExternalEditor", m_cp.sExtEditor); + pConf->writeEntry("SystemProfile", (uint)m_cp.profile); + pConf->writeEntry("EditorPopup", (uint)m_cp.popup); + pConf->writeEntry("GraphOrientation", m_cp.sGraphOrient); + pConf->writeEntry("GraphMaxNodeDegree", m_cp.nGraphMaxNodeDegree); + pConf->writeEntry("DefGraphView", m_cp.nDefGraphView); + + // Do not report it's the first time on the next run + pConf->setGroup("General"); + pConf->writeEntry("FirstTime", false); + pConf->writeEntry(SHOW_WELCOME_ENTRY, false); +} + +/** + * Stores the layout of the main window. + * @param pMainWindow Pointer to the main docking window + */ +void KScopeConfig::storeWorkspace(KDockMainWindow* pMainWindow) +{ + pMainWindow->writeDockConfig(kapp->config(), "Workspace"); +} + +/** + * Determines if this is the first time KScope was launched by the current + * user. + * @return true if this is the first time, false otherwise + */ +bool KScopeConfig::isFirstTime() +{ + KConfig* pConf = kapp->config(); + + pConf->setGroup("General"); + return pConf->readBoolEntry("FirstTime", true); +} + +/** + * Determines if the welcome dialogue should be displayed. + * Note that while the dialogue is displayed on the first invocation of KScope, + * it may be required on other occasions (e.g., to display important information + * on a per-version basis) and thus it is separated from isFirstTime(). + * @return true if the dialogue should be shown, false otherwise + */ +bool KScopeConfig::showWelcomeDlg() +{ + KConfig* pConf = kapp->config(); + + pConf->setGroup("General"); + return pConf->readBoolEntry(SHOW_WELCOME_ENTRY, true); +} + +/** + * @return The full path of the Cscope executable + */ +const QString& KScopeConfig::getCscopePath() const +{ + return m_cp.sCscopePath; +} + +/** + * @param sPath The full path of the Cscope executable + */ +void KScopeConfig::setCscopePath(const QString& sPath) +{ + m_cp.sCscopePath = sPath; +} + +/** + * @return The full path of the Ctags executable + */ +const QString& KScopeConfig::getCtagsPath() const +{ + return m_cp.sCtagsPath; +} + +/** + * @param sPath The full path of the Ctags executable + */ +void KScopeConfig::setCtagsPath(const QString& sPath) +{ + m_cp.sCtagsPath = sPath; +} + +/** + * @return The full path of the Dot executable + */ +const QString& KScopeConfig::getDotPath() const +{ + return m_cp.sDotPath; +} + +/** + * @param sPath The full path of the Dot executable + */ +void KScopeConfig::setDotPath(const QString& sPath) +{ + m_cp.sDotPath = sPath; +} + +/** + * @return A sorted list of recently used project paths. + */ +const QStringList& KScopeConfig::getRecentProjects() const +{ + return m_slProjects; +} + +/** + * Adds the given project path to the beginning of the recently used projects + * list. + * @param sProjPath The path of the project to add + */ +void KScopeConfig::addRecentProject(const QString& sProjPath) +{ + QStringList::Iterator itr; + + itr = m_slProjects.find(sProjPath); + if (itr != m_slProjects.end()) + m_slProjects.remove(itr); + + m_slProjects.prepend(sProjPath); +} + +/** + * Removes the given project path from recently used projects list. + * @param sProjPath The path of the project to remove + */ +void KScopeConfig::removeRecentProject(const QString& sProjPath) +{ + m_slProjects.remove(sProjPath); +} + +/** + * @return true if the tag list should be visible, false otherwise + */ +bool KScopeConfig::getShowTagList() const +{ + return m_cp.bShowTagList; +} + +/** + * @param bShowTagList true to make the tag list visible, false otherwise + */ +void KScopeConfig::setShowTagList(bool bShowTagList) +{ + m_cp.bShowTagList = bShowTagList; +} + +/** + * @return A list containing the widths of the Ctags list part and the + * editor part in an editor page. + */ +const SPLIT_SIZES& KScopeConfig::getEditorSizes() const +{ + return m_cp.siEditor; +} + +/** + * @param siEditor A list containing the widths of the Ctags list part + * and the editor part in an editor page. + */ +void KScopeConfig::setEditorSizes(const SPLIT_SIZES& siEditor) +{ + m_cp.siEditor = siEditor; +} + +/** + * Finds a colour to use for a GUI element. + * @param ce Identifies the GUI element + * @return A reference to the colour object to use + */ +const QColor& KScopeConfig::getColor(ColorElement ce) const +{ + return m_cp.clrs[ce]; +} + +/** + * Returns the display name of a GUI element whose colour can be configured. + * @param ce The GUI element + * @return A name used in the colour configuration page + */ +QString KScopeConfig::getColorName(ColorElement ce) const +{ + return COLOR_NAME(ce); +} + +/** + * Sets a new colour to a GUI element. + * @param ce Identifies the GUI element + * @param clr The colour to use + */ +void KScopeConfig::setColor(ColorElement ce, const QColor& clr) +{ + m_cp.clrs[ce] = clr; +} + +/** + * Finds a font to use for a GUI element. + * @param fe Identifies the GUI element + * @return A reference to the font object to use + */ +const QFont& KScopeConfig::getFont(FontElement fe) const +{ + return m_cp.fonts[fe]; +} + +/** + * Returns the display name of a GUI element whose font can be configured. + * @param ce The GUI element + * @return A name used in the font configuration page + */ +QString KScopeConfig::getFontName(FontElement ce) const +{ + return FONT_NAME(ce); +} + +/** + * Sets a new font to a GUI element. + * @param fe Identifies the GUI element + * @param font The font to use + */ +void KScopeConfig::setFont(FontElement fe, const QFont& font) +{ + m_bFontsChanged = true; + m_cp.fonts[fe] = font; +} + +/** + * @return The column and direction by which the tags should be sorted + */ +KScopeConfig::CtagSort KScopeConfig::getCtagSortOrder() +{ + return m_cp.ctagSortOrder; +} + +/** + * @param ctagSortOrder The column and direction by which the tags should + * be sorted + */ +void KScopeConfig::setCtagSortOrder(CtagSort ctagSortOrder) +{ + m_cp.ctagSortOrder = ctagSortOrder; +} + +/** + * @return true to work in Read-Only mode, false otherwise + */ +bool KScopeConfig::getReadOnlyMode() +{ + return m_cp.bReadOnlyMode; +} + +/** + * @param bReadOnlyMode true to work in Read-Only mode, false otherwise + */ +void KScopeConfig::setReadOnlyMode(bool bReadOnlyMode) +{ + m_cp.bReadOnlyMode = bReadOnlyMode; +} + +/** + * @return true to load the last project on start-up, false otherwise + */ +bool KScopeConfig::getLoadLastProj() +{ + return m_cp.bLoadLastProj; +} + +/** + * @param bLoadLastProj true to load the last project on start-up, false + * otherwise + */ +void KScopeConfig::setLoadLastProj(bool bLoadLastProj) +{ + m_cp.bLoadLastProj = bLoadLastProj; +} + +/** + * @return true to enable tag highlighting based on cursor position, false + * to disable this feature + */ +bool KScopeConfig::getAutoTagHl() +{ + return m_cp.bAutoTagHl; +} + +/** + * @param bAutoTagHl true to enable tag highlighting based on cursor + * position, false to disable this feature + */ +void KScopeConfig::setAutoTagHl(bool bAutoTagHl) +{ + m_cp.bAutoTagHl = bAutoTagHl; +} + +/** + * @return true to use the short version of the query captions, false to use + * the long version + */ +bool KScopeConfig::getUseBriefQueryCaptions() +{ + return m_cp.bBriefQueryCaptions; +} + +/** + * @param bBrief true to use the short version of the query captions, false + * to use the long version + */ +void KScopeConfig::setUseBriefQueryCaptions(bool bBrief) +{ + m_cp.bBriefQueryCaptions = bBrief; +} + +/** + * @return true to warn user when file is modified on disk, false + * otherwise + */ +bool KScopeConfig::getWarnModifiedOnDisk() +{ + return m_cp.bWarnModifiedOnDisk; +} + +/** + * @param bWarn true to warn user when file is modified on disk, + * false otherwise + */ +void KScopeConfig::setWarnModifiedOnDisk(bool bWarn) +{ + m_cp.bWarnModifiedOnDisk = bWarn; +} + +/** + * @return true to sort files when a project is loaded, false otherwise + */ +bool KScopeConfig::getAutoSortFiles() +{ + return m_cp.bAutoSortFiles; +} + +/** + * @param bSort true to sort files when a project is loaded, false + * otherwise + */ +void KScopeConfig::setAutoSortFiles(bool bSort) +{ + m_cp.bAutoSortFiles = bSort; +} + +/** + * @return A command line for launching an external editor + */ +const QString& KScopeConfig::getExtEditor() +{ + return m_cp.sExtEditor; +} + +/** + * @param sExtEditor A command line for launching an external editor + */ +void KScopeConfig::setExtEditor(const QString& sExtEditor) +{ + m_cp.sExtEditor = sExtEditor; +} + +/** + * Determines if an external editor should be used. + * An external editor is used if KScope is in Read-Only mode, and a command- + * line for the editor was specified. + * @return true to use an external editor, false otherwise + */ +bool KScopeConfig::useExtEditor() +{ + return !m_cp.sExtEditor.isEmpty(); +} + +/** + * @return The chosen profile for this system (@see SysProfile) + */ +KScopeConfig::SysProfile KScopeConfig::getSysProfile() const +{ + return m_cp.profile; +} + +/** + * @param profile The system profile to use (@see SysProfile) + */ +void KScopeConfig::setSysProfile(KScopeConfig::SysProfile profile) +{ + m_cp.profile = profile; +} + +/** + * @return The chosen popup menu type for the embedded editor (@see + * EditorPopup) + */ +KScopeConfig::EditorPopup KScopeConfig::getEditorPopup() const +{ + return m_cp.popup; +} + +/** + * @return The name of the popup menu to use in the embedded editor + */ +QString KScopeConfig::getEditorPopupName() const +{ + switch (m_cp.popup) { + case Embedded: + return "ktexteditor_popup"; + + case KScopeOnly: + return "kscope_popup"; + } + + // Will not happen, but the compiler complains if no return statement is + // given here + return ""; +} + +/** + * @param popup The popup menu to use for the embedded editor (@see + * EditorPopup) + */ +void KScopeConfig::setEditorPopup(KScopeConfig::EditorPopup popup) +{ + m_cp.popup = popup; +} + +/** + * @return The default orientation for call graphs + */ +QString KScopeConfig::getGraphOrientation() const +{ + return m_cp.sGraphOrient; +} + +/** + * @param sOrient The default orientation for call graphs + */ +void KScopeConfig::setGraphOrientation(const QString& sOrient) +{ + m_cp.sGraphOrient = sOrient; +} + +/** + * @return The maximal number of calls per graph node + */ +int KScopeConfig::getGraphMaxNodeDegree() const +{ + return m_cp.nGraphMaxNodeDegree; +} + +/** + * @param nMaxNodeDegree The maximal number of calls per graph node + */ +void KScopeConfig::setGraphMaxNodeDegree(int nMaxNodeDegree) +{ + m_cp.nGraphMaxNodeDegree = nMaxNodeDegree; +} + +/** + * @return The default view in the call graph dialogue + */ +int KScopeConfig::getDefGraphView() const +{ + return m_cp.nDefGraphView; +} + +/** + * @param nDefGraphView The default view in the call graph dialogue + */ +void KScopeConfig::setDefGraphView(int nDefGraphView) +{ + m_cp.nDefGraphView = nDefGraphView; +} + +/** + * Returns a reference to a global configuration object. + * The static object defined is this function should be the only KSCopeConfig + * object in this programme. Any code that wishes to get or set global + * configuration parameters, should call Config(), instead of defining its + * own object. + * @return Reference to a statically allocated configuration object + */ +KScopeConfig& Config() +{ + static KScopeConfig conf; + return conf; +} + +#include "kscopeconfig.moc" diff --git a/src/kscopeconfig.h b/src/kscopeconfig.h new file mode 100644 index 0000000..8a047cf --- /dev/null +++ b/src/kscopeconfig.h @@ -0,0 +1,218 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef KSCOPECONFIG_H +#define KSCOPECONFIG_H + +#include +#include +#include +#include + +typedef QValueList SPLIT_SIZES; + +/** + * Loads and stores global configuration parameters. + * @author Elad Lahav + */ + +class KScopeConfig : public QObject +{ + Q_OBJECT + +public: + KScopeConfig(); + ~KScopeConfig(); + + /** GUI elements whose colours can be set. */ + enum ColorElement { FileListFore = 0, FileListBack, TagListFore, + TagListBack, QueryWindowFore, QueryWindowBack, GraphBack, + GraphNode, GraphText, GraphMultiCall, LAST_COLOR = GraphMultiCall }; + + /** GUI elements whose fonts can be set. */ + enum FontElement { FileList = 0, TagList, QueryWindow, Graph, + LAST_FONT = Graph }; + + /** Sort order values for the tags list. */ + enum CtagSort { NameAsc = 0, NameDes, LineAsc, LineDes, TypeAsc, + TypeDes }; + + /** Types of systems that determine certain aspects in KScope's + behaviour. + For fast systems, certain time-consuming operations, such as + rebuilding the database, may be performed automatically. Such + behaviour, however, is not desired on slow systems, in which the user + should handle such operations manually. */ + enum SysProfile { Fast, Slow }; + + /** The different options for a popup menu to be installed in the editor + parts. */ + enum EditorPopup { Embedded, KScopeOnly }; + + void load(); + void loadDefault(); + void loadWorkspace(KDockMainWindow*); + void store(); + void storeWorkspace(KDockMainWindow*); + bool isFirstTime(); + bool showWelcomeDlg(); + + const QString& getCscopePath() const; + void setCscopePath(const QString&); + const QString& getCtagsPath() const; + void setCtagsPath(const QString&); + const QString& getDotPath() const; + void setDotPath(const QString&); + const QStringList& getRecentProjects() const; + void addRecentProject(const QString&); + void removeRecentProject(const QString&); + bool getShowTagList() const; + void setShowTagList(bool); + const SPLIT_SIZES& getEditorSizes() const; + void setEditorSizes(const SPLIT_SIZES&); + const QColor& getColor(ColorElement) const; + QString getColorName(ColorElement) const; + void setColor(ColorElement, const QColor&); + const QFont& getFont(FontElement) const; + QString getFontName(FontElement) const; + void setFont(FontElement, const QFont&); + CtagSort getCtagSortOrder(); + void setCtagSortOrder(CtagSort); + bool getReadOnlyMode(); + void setReadOnlyMode(bool); + bool getLoadLastProj(); + void setLoadLastProj(bool); + bool getAutoTagHl(); + void setAutoTagHl(bool); + bool getUseBriefQueryCaptions(); + void setUseBriefQueryCaptions(bool); + bool getWarnModifiedOnDisk(); + void setWarnModifiedOnDisk(bool); + bool getAutoSortFiles(); + void setAutoSortFiles(bool); + const QString& getExtEditor(); + void setExtEditor(const QString&); + bool useExtEditor(); + SysProfile getSysProfile() const; + void setSysProfile(SysProfile); + EditorPopup getEditorPopup() const; + QString getEditorPopupName() const; + void setEditorPopup(EditorPopup); + QString getGraphOrientation() const; + void setGraphOrientation(const QString&); + int getGraphMaxNodeDegree() const; + void setGraphMaxNodeDegree(int); + int getDefGraphView() const; + void setDefGraphView(int); + +private: + /** A list of previously loaded projects. */ + QStringList m_slProjects; + + /** Defines the list of all configurable parameters in KScope. + The use of a structure helps define default values (@see s_cpDef) */ + struct ConfParams { + /** The full path of the Cscope executable. */ + QString sCscopePath; + + /** The full path of the Ctags executable. */ + QString sCtagsPath; + + /** The full path of the Dot executable. */ + QString sDotPath; + + /** Whether the tag list should be visible. */ + bool bShowTagList; + + /** The widths of the tag list and editor panes inside an editor + page. */ + SPLIT_SIZES siEditor; + + /** Colours for GUI elements. */ + QColor clrs[LAST_COLOR + 1]; + + /** Fonts for GUI elements. */ + QFont fonts[LAST_FONT + 1]; + + /** Sort order of the tag lists. */ + CtagSort ctagSortOrder; + + /** Whether KScope should operate in code read-only mode. */ + bool bReadOnlyMode; + + /** Whether the last open project should be reloaded on start-up. */ + bool bLoadLastProj; + + /** Whether tags should be highlighted based on the current cursor + position. */ + bool bAutoTagHl; + + /** Whether query page captions should use mnemonics for query types, + instead of the full description. */ + bool bBriefQueryCaptions; + + /** Whether the warning should be displayed when file is modified on + disk by external process. */ + bool bWarnModifiedOnDisk; + + /** Should files be sorted automatically when a project is loaded. */ + bool bAutoSortFiles; + + /** A command line pattern for an external editor (in read-only + mode.)*/ + QString sExtEditor; + + /** How KScope should treat time-consuming operations. */ + SysProfile profile; + + /** The type of popup menu to use in the embedded editor. */ + EditorPopup popup; + + /** The default orientation of call graphs. */ + QString sGraphOrient; + + /** Maximal number of called/calling functions per call graph node. */ + int nGraphMaxNodeDegree; + + /** Default view for the call graph dialogue. */ + int nDefGraphView; + }; + + /** The current configuration parameters */ + ConfParams m_cp; + + /** Holds default values for the configuration parameters */ + static ConfParams s_cpDef; + + /** Write font preferences only if modified by the user (keep default + setting otherwise) */ + bool m_bFontsChanged; +}; + +extern KScopeConfig& Config(); + +#endif diff --git a/src/kscopepixmaps.cpp b/src/kscopepixmaps.cpp new file mode 100644 index 0000000..495d756 --- /dev/null +++ b/src/kscopepixmaps.cpp @@ -0,0 +1,376 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "kscopepixmaps.h" + +static const char* XPM_FUNC[] = { + "12 12 2 1", + ". c #000000", + "# c #58a8ff", + "............", + ".##########.", + ".###....###.", + ".###.######.", + ".###.######.", + ".###.######.", + ".###....###.", + ".###.######.", + ".###.######.", + ".###.######.", + ".##########.", + "............" +}; + +static const char* XPM_VAR[] = { + "12 12 3 1", + ". c #000000", + "a c #c00000", + "# c #ff0000", + "............", + ".##########.", + ".##########.", + ".##.####.##.", + ".##.####.##.", + ".##.a##a.##.", + ".##a.##.a##.", + ".###.aa.###.", + ".###a..a###.", + ".####..####.", + ".##########.", + "............" +}; + +static const char* XPM_STRUCT[] = { + "12 12 2 1", + ". c #000000", + "# c #ffff00", + "............", + ".##########.", + ".####...###.", + ".###.###.##.", + ".###.######.", + ".####.#####.", + ".#####.####.", + ".######.###.", + ".##.###.###.", + ".###...####.", + ".##########.", + "............" +}; + +static const char* XPM_MACRO[] = { + "12 12 2 1", + ". c #000000", + "# c #00c000", + "............", + ".##########.", + ".##.####.##.", + ".##..##..##.", + ".##.#..#.##.", + ".##.####.##.", + ".##.####.##.", + ".##.####.##.", + ".##.####.##.", + ".##.####.##.", + ".##########.", + "............" +}; + +static const char* XPM_MEMBER[] = { + "12 12 3 1", + ". c #000000", + "a c #0000c0", + "# c #c0c0ff", + "............", + ".##########.", + ".##########.", + ".##########.", + ".##a.##.a##.", + ".##.a..a.##.", + ".##.#aa#.##.", + ".##.####.##.", + ".##.####.##.", + ".##########.", + ".##########.", + "............" +}; + +static const char* XPM_ENUM[] = { + "12 12 2 1", + ". c #000000", + "# c #ff00ff", + "............", + ".##########.", + ".##########.", + ".##......##.", + ".##.#######.", + ".##.#######.", + ".##.....###.", + ".##.#######.", + ".##.#######.", + ".##......##.", + ".##########.", + "............" +}; + +static const char* XPM_ENUMERATOR[] = { + "12 12 2 1", + ". c #000000", + "# c #ffc0c0", + "............", + ".##########.", + ".##########.", + ".###...####.", + ".##.###.###.", + ".##.###.###.", + ".##.....###.", + ".##.#######.", + ".##.###.###.", + ".###...####.", + ".##########.", + "............" +}; + +static const char* XPM_TYPEDEF[] = { + "12 12 2 1", + ". c #000000", + "# c #c0ffc0", + "............", + ".##########.", + ".#.......##.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".##########.", + "............" +}; + +static const char* XPM_LABEL[] = { + "12 12 2 1", + ". c #000000", + "# c #c0ff00", + "............", + ".##########.", + ".#.########.", + ".#.########.", + ".#.########.", + ".#.########.", + ".#.########.", + ".#.########.", + ".#.########.", + ".#.......##.", + ".##########.", + "............" +}; + +static const char* XPM_INCLUDE[] = { + "12 12 2 1", + ". c #000000", + "# c #c0c0c0", + "............", + ".##########.", + ".##.....###.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".####.#####.", + ".##.....###.", + ".##########.", + "............" +}; + +static const char* XPM_UNKNOWN[] = { + "12 12 2 1", + ". c #000000", + "# c #ffffff", + "............", + ".##########.", + ".##.....###.", + ".#.#####.##.", + ".########.#.", + ".########.#.", + ".#######.##.", + ".######.###.", + ".####.#####.", + ".##########.", + ".####.#####.", + "............" +}; + +/** + * Class constructor. + */ +KScopePixmaps::KScopePixmaps() : + m_pPixArray(NULL), + m_loader() +{ +} + +/** + * Class destructor. + */ +KScopePixmaps::~KScopePixmaps() +{ + int i; + + for (i = 0; i < PIX_ARRAY_SIZE; i++) + delete m_pPixArray[i]; + + delete [] m_pPixArray; +} + +/** + * Creates the array of embedded pixmaps. + * This function is separated from the constructor since QPixmap objects + * cannot be created at the time the static KScopePixmaps object is + * allocated. + */ +void KScopePixmaps::init() +{ + // Create the pixmap array + m_pPixArray = new QPixmap * [PIX_ARRAY_SIZE]; + + // Create all pixmaps + m_pPixArray[SymFunc] = new QPixmap(XPM_FUNC); + m_pPixArray[SymVar] = new QPixmap(XPM_VAR); + m_pPixArray[SymStruct] = new QPixmap(XPM_STRUCT); + m_pPixArray[SymMacro] = new QPixmap(XPM_MACRO); + m_pPixArray[SymMember] = new QPixmap(XPM_MEMBER); + m_pPixArray[SymEnum] = new QPixmap(XPM_ENUM); + m_pPixArray[SymEnumerator] = new QPixmap(XPM_ENUMERATOR); + m_pPixArray[SymTypedef] = new QPixmap(XPM_TYPEDEF); + m_pPixArray[SymLabel] = new QPixmap(XPM_LABEL); + m_pPixArray[SymInclude] = new QPixmap(XPM_INCLUDE); + m_pPixArray[SymUnknown] = new QPixmap(XPM_UNKNOWN); +} + +/** + * Returns a reference to an embedded pixmap. + * @param name The pixmap's identifier + * @return A reference to the requested pixmap + */ +const QPixmap& KScopePixmaps::getPixmap(PixName name) const +{ + return *m_pPixArray[name]; +} + +/** + * Loads a pixmap with the KIconLoader mechanism. + * @param name The pixmap's identifier + * @return The requested pixmap + */ +QPixmap KScopePixmaps::getPixmap(LoadPixName name) +{ + switch (name) { + case TabUnlocked: + return m_loader.loadIcon("query_unlocked", KIcon::Small, 0, + false); + + case TabLocked: + return m_loader.loadIcon("query_locked", KIcon::Small, 0, + false); + + case TabBookmark: + return m_loader.loadIcon("bookmark", KIcon::Small, 0, + false); + + case TabRW: + return m_loader.loadIcon("file_rw", KIcon::Small, 0, + false); + + case TabRO: + return m_loader.loadIcon("file_ro", KIcon::Small, 0, + false); + + case TabSave: + return m_loader.loadIcon("file_save", KIcon::Small, 0, + false); + + case TabFileList: + return m_loader.loadIcon("view_detailed", KIcon::Small, 0, + false); + + case TabFileTree: + return m_loader.loadIcon("view_tree", KIcon::Small, 0, + false); + + case TabList: + return m_loader.loadIcon("tab_list", KIcon::Small, 0, + false); + + case ButtonSaveAs: + return m_loader.loadIcon("filesaveas", KIcon::Toolbar, + 0, false); + + case ButtonZoomIn: + return m_loader.loadIcon("viewmag+", KIcon::Toolbar, + 0, false); + + case ButtonZoomOut: + return m_loader.loadIcon("viewmag-", KIcon::Toolbar, + 0, false); + + case ButtonRotate: + return m_loader.loadIcon("rotate", KIcon::Toolbar, + 0, false); + + case ButtonPref: + return m_loader.loadIcon("configure", KIcon::Toolbar, + 0, false); + + case CalledTree: + return m_loader.loadIcon("called_tree", KIcon::Toolbar, + 0, false); + + case CallingTree: + return m_loader.loadIcon("calling_tree", KIcon::Toolbar, + 0, false); + + case CallGraph: + return m_loader.loadIcon("call_graph", KIcon::Toolbar, + 0, false); + } + + return QPixmap(); +} + +/** + * @return A reference to a global KScopePixmaps object + */ +KScopePixmaps& Pixmaps() +{ + static KScopePixmaps pix; + return pix; +} diff --git a/src/kscopepixmaps.h b/src/kscopepixmaps.h new file mode 100644 index 0000000..e5f321b --- /dev/null +++ b/src/kscopepixmaps.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef KSCOPEPIXMAPS_H +#define KSCOPEPIXMAPS_H + +#include +#include + +#define GET_PIXMAP(_pix) \ + Pixmaps().getPixmap(KScopePixmaps::_pix) + +/** + * Handles all pixmaps required by KScope. + * There are two types of pixmaps: embedded, i.e., pixmaps whose pixels are + * given by static two-dimensional arrays, and loadable, which are retrieved + * through the KIconLoader mechanism. + * The application uses a single global instance of this class. + * @author Elad Lahav + */ + +class KScopePixmaps +{ +public: + KScopePixmaps(); + ~KScopePixmaps(); + + /** Identifiers for embedded pixmaps. */ + enum PixName { SymFunc, SymVar, SymStruct, SymMacro, SymMember, SymEnum, + SymEnumerator, SymTypedef, SymLabel, SymInclude, SymUnknown, + PIX_ARRAY_SIZE }; + + /** Identifiers for loadable pixmaps. */ + enum LoadPixName { TabUnlocked, TabLocked, TabBookmark, TabRW, TabRO, + TabSave, TabFileList, TabFileTree, TabList, ButtonSaveAs, ButtonZoomIn, + ButtonZoomOut, ButtonRotate, ButtonPref, CalledTree, + CallingTree, CallGraph }; + + void init(); + const QPixmap& getPixmap(PixName name) const; + QPixmap getPixmap(LoadPixName name); + +private: + /** An array of pointers to the embedded pixmaps. */ + QPixmap** m_pPixArray; + + /** An icon loader used to retrieve pixmaps through the KDE mechanism. */ + KIconLoader m_loader; +}; + +extern KScopePixmaps& Pixmaps(); + +#endif diff --git a/src/kscopeui.rc b/src/kscopeui.rc new file mode 100644 index 0000000..81d3646 --- /dev/null +++ b/src/kscopeui.rc @@ -0,0 +1,141 @@ + + + + &File + + + &Edit + + + + + + + &View + + + + + + + &Project + + + + + + + + + + + + &Cscope + + + + + + + + + + + + + + + &Go + + + + + + + + + + + &Window + + + + + + &Settings + + + &Help + + + + +&Query + + + + + + + + + Cscope + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Project + + + +Navigation + + + + + +Query + + + + + + + + +Workspace + + + + + diff --git a/src/lo16-app-kscope.png b/src/lo16-app-kscope.png new file mode 100644 index 0000000000000000000000000000000000000000..fd8ef48b821568ca4a2b45f0ee6c41b0c1f979a8 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G^tAk28_ZrvZCAbW|YuPggyHYpBflQ#kdTYy5BJzX3_D(1YMw2}9afq-kgKyAi~ z##wE=@2aLHFuQdaGf5jbw0+2RVBE6A&5296<&dI)<^z!_G2d(N``>@={Uh$2<@DOD zs`rxa3@5@EHtbehx#fA8xk#!A^Ogl6hn9A3lj>j&V~=>l!*{^$$hPHjOfyy#2_8Hn zkU4JyNrTv>#Gf$RCo>m~23d~%`$LeD*~Rs5}pH=_PIuT)g80`UkC zk+%T9?pOayL|_=c8`#260{2_`xb3=p<5~mFmXVZ;wazzgP< +#include +#include + +#include "kscope.h" +#include "kscopeconfig.h" + +static const char *description = + I18N_NOOP("KScope\nA source-editing environment for KDE, based on " + "Cscope"); + +static KCmdLineOptions options[] = +{ + { "+[CSCOPE.OUT path]", + I18N_NOOP("Opens a cscope.out file in a temporary project"), 0 }, + { "+[CSCOPE.PROJ path | KScope project directory path]", + I18N_NOOP("Opens a KScope project"), 0 }, + KCmdLineLastOption +}; + +/** + * Defines the programme's entry point. + * Creates KScope's main window, and starts the event loop. + * @param argc Number of command line arguments + * @param argv Command line arguments + * @return Programme's exit value + */ +int main(int argc, char *argv[]) +{ + // Create the "About" dialogue + KAboutData aboutData( "kscope", I18N_NOOP("KScope"), + VERSION, description, KAboutData::License_BSD, + "(c) 2003-2007, Elad Lahav", 0, "http://kscope.sourceforge.net", + "elad_lahav@users.sf.net"); + aboutData.addAuthor("Elad Lahav", "Developer", + "elad_lahav@users.sf.net"); + aboutData.addCredit("Albert Yosher", + "Code completion, patches and bug fixes", "ayosher@users.sf.net"); + aboutData.addCredit("Gabor Fekete", "Bug fixes and patches", + "feketgai@index.hu"); + + // Initialise command-line argument parsing + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + // Parse command line arguments + KCmdLineArgs* pArgs = KCmdLineArgs::parsedArgs(); + + // Create the main window + KApplication a; + KScope* pKScope = new KScope(); + a.setMainWidget(pKScope); + + // Display the main window + pKScope->show(); + + // Handle command-line arguments + if (pArgs->count() > 0) { + pKScope->parseCmdLine(pArgs); + } else if (Config().getLoadLastProj()) { + // No arguments given, load the most recent project + pKScope->openLastProject(); + } + + // Make sure Cscope is properly installed + pKScope->verifyCscope(); + + // Start the event loop + return a.exec(); +} diff --git a/src/makedlg.cpp b/src/makedlg.cpp new file mode 100644 index 0000000..ac60129 --- /dev/null +++ b/src/makedlg.cpp @@ -0,0 +1,267 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "makedlg.h" +#include "makefrontend.h" +#include "queryview.h" + +/** Window flags for call-tree widgets. */ +#define MAKE_DLG_W_FLAGS \ + WStyle_Customize | \ + WStyle_NormalBorder | \ + WStyle_Title + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +MakeDlg::MakeDlg(QWidget* pParent, const char* szName) : + MakeLayout(pParent, szName, MAKE_DLG_W_FLAGS) +{ + // Don't show the "Function" column + m_pErrorView->setColumnWidthMode(0, QListView::Manual); + m_pErrorView->setColumnWidth(0, 0); + + // Create a new make front-end + m_pMake = new MakeFrontend(); + connect(m_pMake, SIGNAL(dataReady(FrontendToken*)), this, + SLOT(slotShowOutput(FrontendToken*))); + connect(m_pMake, SIGNAL(finished(uint)), this, SLOT(slotFinished(uint))); + connect(m_pMake, + SIGNAL(error(const QString&, const QString&, const QString&)), + this, + SLOT(slotAddError(const QString&, const QString&, const QString&))); + + // The Root URL control should browse directories + m_pRootURL->setMode(KFile::Directory); + + // Handle URL links in the browser + m_pOutputBrowser->setNotifyClick(true); + connect(m_pOutputBrowser, SIGNAL(urlClick(const QString&)), this, + SLOT(slotBrowserClicked(const QString&))); + + // Handle selections in the error view + connect(m_pErrorView, SIGNAL(lineRequested(const QString& , uint)), this, + SIGNAL(fileRequested(const QString&, uint))); + + // Do not allow duplicates in the command history + m_pCommandHistory->setDuplicatesEnabled(false); +} + +/** + * Class destructor. + */ +MakeDlg::~ MakeDlg() +{ + delete m_pMake; +} + +/** + * @return The currently set make command + */ +QString MakeDlg::getCommand() const +{ + return m_pCommandHistory->currentText(); +} + +/** + * @param sCmd The new make command to use + */ +void MakeDlg::setCommand(const QString& sCmd) +{ + m_pCommandHistory->setCurrentText(sCmd); + m_pCommandHistory->addToHistory(sCmd); +} + +/** + * @return The directory in which to run the make command + */ +QString MakeDlg::getDir() const +{ + return m_pRootURL->url(); +} + +/** + * @param sURL The new root directory to use + */ +void MakeDlg::setDir(const QString& sURL) +{ + m_pRootURL->setURL(sURL); +} + +/** + * Overrides the default close behaviour. + * Makes sure that a window is not closed while a make process is running, + * unless the user explicitly requests it. In this case, the make process + * is killed. + * @param pEvent The close event descriptor + */ +void MakeDlg::closeEvent(QCloseEvent* pEvent) +{ + // Check if a process is currently running + if (m_pMake->isRunning()) { + // Prompt the user + switch (KMessageBox::questionYesNoCancel(this, + i18n("A make process is running. Would you like to stop it first?"), + i18n("Close Make Window"))) { + case KMessageBox::Yes: + // Stop the process first + m_pMake->kill(); + break; + + case KMessageBox::No: + // Do nothing + break; + + case KMessageBox::Cancel: + // Abort closing + pEvent->ignore(); + return; + } + } + + QWidget::closeEvent(pEvent); +} + +/** + * Starts a make process using the user-supplied command. + * This slot is connected to the clicked() signal of the "Make" button. + */ +void MakeDlg::slotMake() +{ + QString sCommand; + + // Clear the current contents + m_pOutputBrowser->clear(); + m_pErrorView->clear(); + + // Run the make command + sCommand = m_pCommandHistory->currentText(); + if (!m_pMake->run("make", QStringList::split(" ", sCommand), + m_pRootURL->url())) { + KMessageBox::error(this, m_pMake->getRunError()); + return; + } + + // Add the command to the command history + m_pCommandHistory->addToHistory(sCommand); + + // Disbale the make button + m_pMakeButton->setEnabled(false); + m_pStopButton->setEnabled(true); +} + +/** + * Terminates the current make process. + * This slot is connected to the clicked() signal of the stop button. + */ +void MakeDlg::slotStop() +{ + m_pMake->kill(); +} + +/** + * Displays the parsed output, as generated by the MakeFrontend object. + * This slot is connected to the dataReady() signal of the make front-end. + * @param pToken Holds the parsed data + */ +void MakeDlg::slotShowOutput(FrontendToken* pToken) +{ + QString sData; + + // GCC uses unicode quote characters - this should ensure that they are + // treated correctly by the text browser widget + sData = QTextCodec::codecForLocale()->toUnicode(pToken->getData()); + m_pOutputBrowser->append(sData); +} + +/** + * Displays the results of the make command. + * This slot is connected to the finished() signal of the make front-end. + */ +void MakeDlg::slotFinished(uint) +{ + // Add "Success" or "Error" at the end of the output + if (m_pMake->exitStatus() == 0) { + m_pOutputBrowser->append("Success" + ""); + } + else { + m_pOutputBrowser->append("Error"); + } + + // Re-enable the "Make" button + m_pMakeButton->setEnabled(true); + m_pStopButton->setEnabled(false); +} + +/** + * Emits the fileRequested() signal when a browser link is clicked. + * This slot is connected to the urlClick() signal of the browser. + * @param sURL The requested URL + */ +void MakeDlg::slotBrowserClicked(const QString& sURL) +{ + QString sFile; + QString sLine; + + // Exract the file name and the line number from the URL + sFile = sURL.section('&', 0, 0); + sLine = sURL.section('&', 1, 1); + + // Add root path for relative paths + if (!sFile.startsWith("/")) + sFile = m_pRootURL->url() + "/" + sFile; + + // Emit the signal + emit fileRequested(sFile, sLine.toUInt()); +} + +/** + * Show an error/warning on a deidicated list. + * This slot is connected to the error() signal of the make front-end. + * @param sFile The file name containing the error/warning + * @param sLine The line number + * @param sText An explanation of the error + */ +void MakeDlg::slotAddError(const QString& sFile, const QString& sLine, + const QString& sText) +{ + QString sUniText; + + sUniText = QTextCodec::codecForLocale()->toUnicode(sText); + m_pErrorView->addRecord("", sFile, sLine, sUniText); +} + +#include "makedlg.moc" diff --git a/src/makedlg.h b/src/makedlg.h new file mode 100644 index 0000000..3120b95 --- /dev/null +++ b/src/makedlg.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef MAKEDLG_H +#define MAKEDLG_H + +#include "makelayout.h" + +class MakeFrontend; +class FrontendToken; + +/** + * A window that displays the output of make-like commands. + * The window contains a text browser showing errors as links to source + * locations. + * The make process is determined by a user-specified command, and is run in + * a user-specified directory. Controls are provided for modifying these values. + * @author Elad Lahav + */ +class MakeDlg: public MakeLayout +{ + Q_OBJECT + +public: + MakeDlg(QWidget* pParent = 0, const char* szName = 0); + virtual ~MakeDlg(); + + QString getCommand() const; + void setCommand(const QString&); + QString getDir() const; + void setDir(const QString&); + +public slots: + virtual void slotMake(); + +signals: + void fileRequested(const QString&, uint); + +protected: + virtual void closeEvent(QCloseEvent*); + +protected slots: + virtual void slotStop(); + void slotShowOutput(FrontendToken*); + void slotFinished(uint); + void slotBrowserClicked(const QString&); + void slotAddError(const QString&, const QString&, const QString&); + +private: + /** Handles the make process. */ + MakeFrontend* m_pMake; +}; + +#endif diff --git a/src/makefrontend.cpp b/src/makefrontend.cpp new file mode 100644 index 0000000..80ea9b8 --- /dev/null +++ b/src/makefrontend.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "makefrontend.h" + +// TODO: +// This should probably be configurable on a per-project basis. +#define PATH_ELEM "[a-zA-Z0-9_\\.\\-]+" + +#define RE_FILE_LINE \ + "((?:\\/)?(?:"PATH_ELEM"\\/)*"PATH_ELEM"):([0-9]+)(:[0-9]+)?: (.*)" +#define RE_ENTER_DIR \ + "Entering directory " \ + "\\`((\\/)?("PATH_ELEM"\\/)*"PATH_ELEM")" +#define RE_EXIT_DIR "Leaving directory" + +/** + * Class constructor. + * @param bAutoDelete If true, the object is deleted when the process + * terminates (false by default) + */ +MakeFrontend::MakeFrontend(bool bAutoDelete) : Frontend(1, bAutoDelete) +{ + // Execute inside a shell + setUseShell(true); + + // Each token represent a complete line + m_delim = Newline; +} + +/** + * Class destructor. + */ +MakeFrontend::~MakeFrontend() +{ +} + +/** + * Executes the make command. + * @param sName The name of the process (for error messages) + * @param slArgs A list containing the command-line arguments + * @param sWorkDir Initial build directory + * @param bBlock (Optional) true to block, false otherwise + * @return true if the process was executed successfully, false otherwise + */ +bool MakeFrontend::run(const QString& sName, const QStringList& slArgs, + const QString& sWorkDir, bool bBlock) +{ + QStringList slShellArgs; + + // Store the current build directory + m_slPathStack.push_back(sWorkDir); + + // Join the output streams, so that they can both be parsed by + // parseStdout() + slShellArgs = slArgs; + slShellArgs << "2>&1"; + + // Execute the command + return Frontend::run(sName, slShellArgs, sWorkDir, bBlock); +} + +/** + * Parses lines of output produced by the make command. + * @param sToken A single line of output + */ +Frontend::ParseResult MakeFrontend::parseStdout(QString& sToken, ParserDelim) +{ + static QRegExp reErrWarn(RE_FILE_LINE); + static QRegExp reEntDir(RE_ENTER_DIR); + static QRegExp reExtDir(RE_EXIT_DIR); + QString sRep; + int nPos; + QString sFile, sLine, sText; + + if ((nPos = reErrWarn.search(sToken)) >= 0) { + // An error/warning message + if (sToken.at(nPos) == '/') { + sFile = reErrWarn.capturedTexts()[1]; + } + else { + sFile = m_slPathStack.last() + "/" + + reErrWarn.capturedTexts()[1]; + } + + sLine = reErrWarn.capturedTexts()[2]; + sText = reErrWarn.capturedTexts()[4]; + emit error(sFile, sLine, sText); + + sRep = QString("\\1:\\2\\3: \\4"; + sToken.replace(reErrWarn, sRep); + } + else if ((nPos = reEntDir.search(sToken)) >= 0) { + // Recursing into a directory + m_slPathStack.push_back(reEntDir.capturedTexts()[1]); + sToken = QString("Entering directory ") + + m_slPathStack.last(); + } + else if ((nPos = reExtDir.search(sToken)) >= 0) { + // Leaving a directory + sToken = QString("Leaving directory ") + + m_slPathStack.last(); + m_slPathStack.pop_back(); + } + + return RecordReady; +} + +#include "makefrontend.moc" diff --git a/src/makefrontend.h b/src/makefrontend.h new file mode 100644 index 0000000..4ed575f --- /dev/null +++ b/src/makefrontend.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * + * Copyright (C) 2006 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef MAKEFRONTEND_H +#define MAKEFRONTEND_H + +#include + +/** + * A shell-process front-end intended for running make-like tasks. + * Records are single-line tokens delimited by newline characters. The parser + * replaces references to source lines (e.g., filename:123) with hypertext + * links for use in a browser. + * @author Elad Lahav + */ +class MakeFrontend : public Frontend +{ + Q_OBJECT + +public: + MakeFrontend(bool bAutoDelete = false); + ~MakeFrontend(); + + virtual bool run(const QString&, const QStringList&, + const QString&, bool bBlock = false); + virtual ParseResult parseStdout(QString&, ParserDelim); + +signals: + void error(const QString& sFile, const QString& sLine, + const QString& sText); + +private: + /** A stack of paths used to track the current build directory. */ + QStringList m_slPathStack; +}; + +#endif diff --git a/src/makelayout.ui b/src/makelayout.ui new file mode 100644 index 0000000..e47acf8 --- /dev/null +++ b/src/makelayout.ui @@ -0,0 +1,245 @@ + +MakeLayout + + + MakeLayout + + + + 0 + 0 + 768 + 642 + + + + KScope - Make + + + + unnamed + + + + layout10 + + + + unnamed + + + + textLabel1 + + + Root Directory: + + + + + m_pCommandHistory + + + + 7 + 0 + 0 + 0 + + + + + + m_pRootURL + + + + + textLabel2 + + + Command: + + + + + + + tabWidget2 + + + + tab + + + Output + + + + unnamed + + + + m_pOutputBrowser + + + + + + + tab + + + Errors a&nd Warnings + + + + unnamed + + + + m_pErrorView + + + + + + + + layout7 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Expanding + + + + 520 + 21 + + + + + + m_pMakeButton + + + &Make + + + Alt+M + + + true + + + + + m_pStopButton + + + false + + + &Stop + + + Alt+S + + + + + m_pCloseButton + + + &Close + + + Alt+C + + + + + + + + + QueryView +
    queryview.h
    + + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
    +
    + + + 789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f + + + + + m_pCloseButton + clicked() + MakeLayout + close() + + + m_pMakeButton + clicked() + MakeLayout + slotMake() + + + m_pStopButton + clicked() + MakeLayout + slotStop() + + + m_pCommandHistory + returnPressed() + MakeLayout + slotMake() + + + + m_pRootURL + m_pCommandHistory + m_pMakeButton + m_pStopButton + m_pCloseButton + + + slotStop() + slotMake() + + + + kcombobox.h + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + ktextbrowser.h + queryview.h + +
    diff --git a/src/newprojectdlg.cpp b/src/newprojectdlg.cpp new file mode 100644 index 0000000..ec8fbca --- /dev/null +++ b/src/newprojectdlg.cpp @@ -0,0 +1,354 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "newprojectdlg.h" + +/** + * Class constructor. + * @param bNewProj true to create a new project dialog, false to display + * the properties of an existing project + * @param pParent The parent widget + * @param szName The widget's name + */ +NewProjectDlg::NewProjectDlg(bool bNewProj, QWidget* pParent, + const char* szName) : + NewProjectLayout(pParent, szName), + m_bNewProj(bNewProj) +{ + ProjectBase::Options opt; + + // Create the auto-completion sub-dialogue + m_pAutoCompDlg = new AutoCompletionDlg(this); + + // Restrict the path requester to existing directories. + m_pPathRequester->setMode(KFile::Directory | KFile::ExistingOnly | + KFile::LocalOnly); + m_pSrcRootRequester->setMode(KFile::Directory | KFile::ExistingOnly | + KFile::LocalOnly); + + // Set up the Create/Cancel buttons + connect(m_pCreateButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + // Show the auto-completion properties dialogue + connect(m_pACButton, SIGNAL(clicked()), m_pAutoCompDlg, SLOT(exec())); + + // Perform actions specific to the type of dialog (new project or + // project properties) + if (bNewProj) { + // Set default project properties + ProjectBase::getDefOptions(opt); + setProperties("", "", opt); + } + else { + // Give appropriate titles to the dialog and the accept button + setCaption(i18n("Project Properties")); + m_pCreateButton->setText(i18n("OK")); + + // Disable the non-relevant widgets + m_pNameEdit->setEnabled(false); + m_pPathRequester->setEnabled(false); + } +} + +/** + * Class destructor. + */ +NewProjectDlg::~NewProjectDlg() +{ +} + +/** + * Configures the dialog's widget to display the properties of the current + * project. + * @param sName The project's name + * @param sPath The project's path + * @param opt Project parameters configurable in this dialogue + */ +void NewProjectDlg::setProperties(const QString& sName, const QString& sPath, + const ProjectBase::Options& opt) +{ + QStringList::ConstIterator itr; + + // Set values for current project + m_pNameEdit->setText(sName); + m_pPathRequester->setURL(sPath); + m_pSrcRootRequester->setURL(opt.sSrcRootPath); + m_pKernelCheck->setChecked(opt.bKernel); + m_pInvCheck->setChecked(opt.bInvIndex); + m_pNoCompCheck->setChecked(opt.bNoCompress); + m_pSlowPathCheck->setChecked(opt.bSlowPathDef); + + if (opt.nAutoRebuildTime >= 0) { + m_pAutoRebuildCheck->setChecked(true); + m_pAutoRebuildSpin->setValue(opt.nAutoRebuildTime); + } + + if (opt.bACEnabled) { + m_pACCheck->setChecked(true); + } + + if (opt.nTabWidth > 0) { + m_pTabWidthCheck->setChecked(true); + m_pTabWidthSpin->setValue(opt.nTabWidth); + } + + // Initialise the auto-completion sub-dialogue + m_pAutoCompDlg->m_nMinChars = opt.nACMinChars; + m_pAutoCompDlg->m_nDelay = opt.nACDelay; + m_pAutoCompDlg->m_nMaxEntries = opt.nACMaxEntries; + + // Add type strings to the types list box + for (itr = opt.slFileTypes.begin(); itr != opt.slFileTypes.end(); ++itr) + m_pTypesList->insertItem(*itr); + + m_pCtagsCmdEdit->setText(opt.sCtagsCmd); +} + +/** + * Retrieves the text entered by the user in the dialog's "Project Name" edit + * box. + * @return The name of the new project + */ +QString NewProjectDlg::getName() +{ + return m_pNameEdit->text(); +} + +/** + * Retrieves the text entered by the user in the dialog's "Project Path" edit + * box. + * Note that the chosen path will be the parent of the new project's + * directory, created under it using the project's name. + * @return The full path of the parent directory for the new project + */ +QString NewProjectDlg::getPath() +{ + if (m_pHiddenDirCheck->isChecked()) + return QString(m_pSrcRootRequester->url()) + "/.cscope"; + + return m_pPathRequester->url(); +} + +/** + * Fills a structure with all user-configured project options. + * @param opt The structure to fill + */ +void NewProjectDlg::getOptions(ProjectBase::Options& opt) +{ + opt.sSrcRootPath = m_pSrcRootRequester->url(); + opt.slFileTypes = m_slTypes; + opt.bKernel = m_pKernelCheck->isChecked(); + opt.bInvIndex = m_pInvCheck->isChecked(); + opt.bNoCompress = m_pNoCompCheck->isChecked(); + opt.bSlowPathDef = m_pSlowPathCheck->isChecked(); + + if (m_pAutoRebuildCheck->isChecked()) + opt.nAutoRebuildTime = m_pAutoRebuildSpin->value(); + else + opt.nAutoRebuildTime = -1; + + if (m_pTabWidthCheck->isChecked()) + opt.nTabWidth = m_pTabWidthSpin->value(); + else + opt.nTabWidth = 0; + + opt.bACEnabled = m_pACCheck->isChecked(); + opt.nACMinChars = m_pAutoCompDlg->m_nMinChars; + opt.nACDelay = m_pAutoCompDlg->m_nDelay; + opt.nACMaxEntries = m_pAutoCompDlg->m_nMaxEntries; + + opt.sCtagsCmd = m_pCtagsCmdEdit->text(); +} + +/** + * Ends the dialog after the user has clicked the "OK" button. + */ +void NewProjectDlg::accept() +{ + int i, nCount; + + // Validate the name of a new project + if (m_bNewProj) { + QRegExp re("[^ \\t\\n]+"); + if (!re.exactMatch(m_pNameEdit->text())) { + KMessageBox::error(0, i18n("Project names must not contain " + "whitespace.")); + return; + } + } + + // Fill the string list with all file types + nCount = (int)m_pTypesList->count(); + for (i = 0; i < nCount; i++) + m_slTypes.append(m_pTypesList->text(i)); + + // Clean-up the source root + QDir dir(m_pSrcRootRequester->url()); + if (dir.exists()) + m_pSrcRootRequester->setURL(dir.absPath()); + else + m_pSrcRootRequester->setURL("/"); + + // Close the dialog + QDialog::accept(); +} + +/** + * Adds the the file type string in the edit-box to the list of project types. + * This slot is called when the "Add.." button is clicked. + */ +void NewProjectDlg::slotAddType() +{ + QString sType; + + // Try the custom type edit-box first. + sType = m_pTypesEdit->text(); + sType.stripWhiteSpace(); + if (sType.isEmpty()) + return; + + // Validate the type string + QRegExp reg("[ \\t\\n\\|\\\\\\/]"); + if (sType.contains(reg)) { + KMessageBox::error(0, i18n("This is not a valid file type!")); + return; + } + + // Do not add an existing type. + if (m_pTypesList->findItem(sType, Qt::CaseSensitive | Qt::ExactMatch) != + NULL) { + return; + } + + // Add the file type to the list + m_pTypesList->insertItem(sType); + m_pTypesEdit->clear(); +} + +/** + * Removes the selected item from the list of file types. + * This slot is called when the "Remove" button is clicked. + */ +void NewProjectDlg::slotRemoveType() +{ + int nItem; + QString sType; + + // Verify an item is selected + nItem = m_pTypesList->currentItem(); + if (nItem == -1) + return; + + // Remove the selected item + sType = m_pTypesList->currentText(); + m_pTypesList->removeItem(nItem); + + // Add to the list of available types. + if (m_pAvailTypesList->findItem(sType, Qt::CaseSensitive | Qt::ExactMatch) + == NULL) { + m_pAvailTypesList->insertItem(sType); + } + +} + +/** + * Changes the text in the types edit-box to reflect the current selection in + * the list of available types. + * This slot is called whenever a new item is highlighted in the list of + * available types. + * @param sType The newly selected type + */ +void NewProjectDlg::slotAvailTypesChanged(const QString& sType) +{ + m_pTypesEdit->setText(sType); +} + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +AutoCompletionDlg::AutoCompletionDlg(QWidget* pParent, + const char* szName ) : + AutoCompletionLayout(pParent, szName) +{ + connect(m_pOKButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); +} + +/** + * Class destructor. + */ +AutoCompletionDlg::~AutoCompletionDlg() +{ +} + +/** + * Displays the dialogue, and waits for either the "OK" or "Cancel" button to + * be clicked. + * Before the dialogue is displayed, the stored values are set to the widgets. + * @return The dialogue's termination code + */ +int AutoCompletionDlg::exec() +{ + // Set current values + m_pMinCharsSpin->setValue(m_nMinChars); + m_pDelaySpin->setValue(m_nDelay); + m_pMaxEntriesSpin->setValue(m_nMaxEntries); + + // Show the dialogue + return QDialog::exec(); +} + +/** + * Stores the values set by the user in the dialogue widgets, and terminates + * the dialogue. + * This slot is connected to the clicked() signal of the "OK" button. + */ +void AutoCompletionDlg::accept() +{ + // Store widget values + m_nMinChars = m_pMinCharsSpin->value(); + m_nDelay = m_pDelaySpin->value(); + m_nMaxEntries = m_pMaxEntriesSpin->value(); + + // Close the dialogue, indicating acceptance + QDialog::accept(); +} + + +#include "newprojectdlg.moc" diff --git a/src/newprojectdlg.h b/src/newprojectdlg.h new file mode 100644 index 0000000..5d8e556 --- /dev/null +++ b/src/newprojectdlg.h @@ -0,0 +1,112 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef NEWPROJECTDLG_H +#define NEWPROJECTDLG_H + +#include +#include +#include +#include +#include "projectbase.h" + +/** + * A sub-dialogue of the New Project dialogue. + * Allows the user to configure auto-completion parameters. + * @author Elad Lahav + */ +class AutoCompletionDlg : public AutoCompletionLayout +{ + Q_OBJECT + +public: + AutoCompletionDlg(QWidget* pParent, const char* szName = NULL); + ~AutoCompletionDlg(); + +public slots: + int exec(); + +protected slots: + virtual void accept(); + +private: + /** The minimum number of characters in a symbol required for automatic + completion. */ + uint m_nMinChars; + + /** The time, in seconds, to wait before automatic completion is + attempted. */ + uint m_nDelay; + + /** The maximal number of results. */ + uint m_nMaxEntries; + + friend class NewProjectDlg; +}; + +/** + * A dialog for creating new projects. + * Prompts the user for the project's name, the directory for Cscope's files, + * the types of files included in the project and several options. + * Can also be used to change some of the properties of a project after it + * has been created. + * @author Elad Lahav + */ + +class NewProjectDlg : public NewProjectLayout +{ + Q_OBJECT + +public: + NewProjectDlg(bool, QWidget* pParent = NULL, const char* szName = NULL); + ~NewProjectDlg(); + + void setProperties(const QString&, const QString&, + const ProjectBase::Options&); + + QString getName(); + QString getPath(); + void getOptions(ProjectBase::Options&); + +protected slots: + virtual void accept(); + virtual void slotAddType(); + virtual void slotRemoveType(); + virtual void slotAvailTypesChanged(const QString&); + +private: + /** The file MIME-types associated with the new project. */ + QStringList m_slTypes; + + /** A sub-dialogue for configuring symbol auto-completion parameters. */ + AutoCompletionDlg* m_pAutoCompDlg; + + /** Whether the dialogue represents a new or existing project. */ + bool m_bNewProj; +}; + +#endif diff --git a/src/newprojectlayout.ui b/src/newprojectlayout.ui new file mode 100644 index 0000000..841b059 --- /dev/null +++ b/src/newprojectlayout.ui @@ -0,0 +1,778 @@ + +NewProjectLayout + + + NewProjectLayout + + + + 0 + 0 + 539 + 383 + + + + Create Project + + + + unnamed + + + + tabWidget2 + + + + tab + + + Detai&ls + + + + unnamed + + + + layout18 + + + + unnamed + + + + textLabel2 + + + Path + + + + + m_pNameEdit + + + Enter a name for this project. +The name must conform to the file system's naming conventions for directories (e.g., no spaces, exclamaion marks, etc.). + + + + + textLabel1 + + + Name + + + + + m_pPathRequester + + + The path to hold this project. +KScope will create a directory with the given name under this project, and populate it with the project configuration and database files. +This does not need to be the path in which the source files reside. + + + + + + + m_pHiddenDirCheck + + + &Use a hidden folder under the source root directory + + + Alt+U + + + + + layout19 + + + + unnamed + + + + textLabel1_2 + + + Source Root (Optional) + + + + + m_pSrcRootRequester + + + + + + + textLabel1_3 + + + <blockquote>A project consists of several files located in a directory + with the given name and path. The project's name needs to be a valid directory +name and must not contain any whitespace.</blockquote> +<br> +<blockquote>The Source Root is a convinient way to specify a common +path for all source files, but is not required.</blockquote> + + + WordBreak|AlignVCenter + + + + + spacer29 + + + Vertical + + + Expanding + + + + 31 + 50 + + + + + + + + tab + + + File T&ypes + + + + unnamed + + + + groupBox1 + + + This Project + + + + unnamed + + + + m_pTypesList + + + KScope uses these filters to locate source files to include in this project. + + + + + + + layout5 + + + + unnamed + + + + spacer7 + + + Vertical + + + Expanding + + + + 21 + 61 + + + + + + m_pAddButton + + + << &Add + + + Alt+A + + + Adds the selected file type to the current project. + + + + + m_pRemoveButton + + + >> &Remove + + + Alt+R + + + Remove the selected file type from the project. + + + + + spacer2 + + + Vertical + + + Expanding + + + + 21 + 50 + + + + + + + + groupBox2 + + + Available Types + + + + unnamed + + + + m_pTypesEdit + + + You can enter custom file types here. + + + + + + *.c + + + + + *.h + + + + + *.l + + + + + *.y + + + + + *.S + + + + + *.cc + + + + + *.cpp + + + + + *.cxx + + + + + *.C + + + + + *.hh + + + + + *.hpp + + + + + *.hxx + + + + + *.H + + + + m_pAvailTypesList + + + A list of standard file types. + + + + + + + spacer8_2 + + + Horizontal + + + Expanding + + + + 61 + 21 + + + + + + + + TabPage + + + &Options + + + + unnamed + + + + m_pKernelCheck + + + Kernel project (-k) + + + + + + For kernel projects, symbols are not looked up in the standard include path. + + + + + m_pInvCheck + + + Build inverted inde&x (-q) + + + Alt+X + + + An inverted index may greatly speed up searches in a large project. The project's building process is longer, though. + + + + + m_pNoCompCheck + + + Do not compress the database (-c) + + + + + + + + m_pSlowPathCheck + + + Slower, but more accurate, function definition detection (-D) + + + + + layout31 + + + + unnamed + + + + m_pAutoRebuildCheck + + + Refresh data&base automatically + + + Alt+B + + + Rebuild the database after changed files are saved to disk. + + + + + spacer32 + + + Horizontal + + + Expanding + + + + 125 + 21 + + + + + + m_pAutoRebuildLabel + + + false + + + (Seconds) + + + + + m_pAutoRebuildSpin + + + false + + + Wait this number of seconds after the last save before rebuilding the database. + + + + + + + layout30 + + + + unnamed + + + + m_pACCheck + + + &Use symbol auto-completion + + + Alt+U + + + As-you-type symbol completion. + + + + + spacer33 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + m_pACButton + + + false + + + Options... + + + + + + + layout6 + + + + unnamed + + + + m_pTabWidthCheck + + + Override default tab width (Kate only) + + + Overrides the editor's configured tab width + + + + + spacer9 + + + Horizontal + + + Expanding + + + + 211 + 31 + + + + + + m_pTabWidthSpin + + + false + + + + + + + spacer31 + + + Vertical + + + Expanding + + + + 21 + 40 + + + + + + + + TabPage + + + &Advanced + + + + unnamed + + + + textLabel1_4 + + + Ctags command line (Do not change unless you know what you are doing!) + + + + + m_pCtagsCmdEdit + + + PlainText + + + AutoAll + + + + + + + + layout19 + + + + unnamed + + + + spacer8 + + + Horizontal + + + Expanding + + + + 141 + 21 + + + + + + m_pCreateButton + + + &Create + + + true + + + + + m_pCancelButton + + + Ca&ncel + + + + + + + + + m_pAddButton + clicked() + NewProjectLayout + slotAddType() + + + m_pRemoveButton + clicked() + NewProjectLayout + slotRemoveType() + + + m_pAutoRebuildCheck + toggled(bool) + m_pAutoRebuildSpin + setEnabled(bool) + + + m_pACCheck + toggled(bool) + m_pACButton + setEnabled(bool) + + + m_pAvailTypesList + highlighted(const QString&) + NewProjectLayout + slotAvailTypesChanged(const QString&) + + + m_pTabWidthCheck + toggled(bool) + m_pTabWidthSpin + setEnabled(bool) + + + m_pAutoRebuildCheck + toggled(bool) + m_pAutoRebuildLabel + setEnabled(bool) + + + m_pHiddenDirCheck + toggled(bool) + m_pPathRequester + setDisabled(bool) + + + + m_pNameEdit + m_pPathRequester + m_pHiddenDirCheck + m_pSrcRootRequester + m_pAddButton + m_pRemoveButton + m_pKernelCheck + m_pInvCheck + m_pNoCompCheck + m_pSlowPathCheck + m_pAutoRebuildCheck + m_pAutoRebuildSpin + m_pACCheck + m_pACButton + m_pTabWidthCheck + m_pTabWidthSpin + m_pCreateButton + m_pCancelButton + tabWidget2 + m_pTypesList + m_pTypesEdit + m_pAvailTypesList + m_pCtagsCmdEdit + + + slotAddType() + slotRemoveType() + slotAutoRebuildChanged(bool) + slotAutoCompletionChanged(bool) + slotAvailTypesChanged(const QString&) + + + + kurlrequester.h + klineedit.h + kpushbutton.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/src/openprojectdlg.cpp b/src/openprojectdlg.cpp new file mode 100644 index 0000000..722fde6 --- /dev/null +++ b/src/openprojectdlg.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "openprojectdlg.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +OpenProjectDlg::OpenProjectDlg(QWidget* pParent, const char* szName) : + OpenProjectLayout(pParent, szName) +{ + loadRecent(); + m_pProjPathRequester->setFilter("cscope.proj"); +} + +/** + * Class destructor. + */ +OpenProjectDlg::~OpenProjectDlg() +{ +} + +/** + * @return The selected project path + */ +QString OpenProjectDlg::getPath() const +{ + return m_pProjPathRequester->url(); +} + +/** + * Sets the requester to reflect the selected project's directory, instead of + * the cscope.proj file. + * @param sProjPath The full path of the selected cscope.proj file + */ +void OpenProjectDlg::slotProjectSelected(const QString& sProjPath) +{ + QFileInfo fi(sProjPath); + m_pProjPathRequester->setURL(fi.dirPath(true)); +} + +/** + * Removes a project from the recent projects list. + * This slot is connected to the clicked() signal of the "Remove" button. + */ +void OpenProjectDlg::slotRemoveRecent() +{ + QListBoxItem* pItem; + + // Remove the selected item, if any + pItem = m_pRecentList->selectedItem(); + if (pItem != NULL) { + Config().removeRecentProject(pItem->text()); + m_pRecentList->removeItem(m_pRecentList->currentItem()); + } +} + +/** + * Selects a project for opening when an item is highlighted in the recent + * projects list. + * This slot is connected to the highlighted() signal of the recent projects + * list box. + * @param pItem The selected project item + */ +void OpenProjectDlg::slotSelectRecent(QListBoxItem* pItem) +{ + if (pItem != NULL) + m_pProjPathRequester->setURL(pItem->text()); +} + +/** + * Selects a project for opening and closes the dialogue when an item in the + * recent projects list is double-clicked. + * This slot is connected to the doubleClicked() signal of the recent + * projects list box. + * @param pItem The selected project item + */ +void OpenProjectDlg::slotOpenRecent(QListBoxItem* pItem) +{ + if (pItem != NULL) { + m_pProjPathRequester->setURL(pItem->text()); + accept(); + } +} + +/** + * Fills the recent projects list box with the project paths read from the + * configuration file. + */ +void OpenProjectDlg::loadRecent() +{ + const QStringList& slProjects = Config().getRecentProjects(); + QStringList::const_iterator itr; + + // Create a list item for each project in the list + for (itr = slProjects.begin(); itr != slProjects.end(); ++itr) + m_pRecentList->insertItem(*itr); +} + +#include "openprojectdlg.moc" diff --git a/src/openprojectdlg.h b/src/openprojectdlg.h new file mode 100644 index 0000000..cf492ad --- /dev/null +++ b/src/openprojectdlg.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef OPENPROJECTDLG_H +#define OPENPROJECTDLG_H + +#include +#include + +/** + * A dialogue for selecting a project to open. + * Allows projects to be searched, and displays a list of previosuly loaded + * projects. + * @author Elad Lahav + */ + +class OpenProjectDlg : public OpenProjectLayout +{ + Q_OBJECT + +public: + OpenProjectDlg(QWidget* pParent = 0, const char* szName = 0); + ~OpenProjectDlg(); + + QString getPath() const; + +protected slots: + virtual void slotProjectSelected(const QString&); + virtual void slotRemoveRecent(); + virtual void slotSelectRecent(QListBoxItem*); + virtual void slotOpenRecent(QListBoxItem*); + +private: + void loadRecent(); +}; + +#endif diff --git a/src/openprojectlayout.ui b/src/openprojectlayout.ui new file mode 100644 index 0000000..88d52be --- /dev/null +++ b/src/openprojectlayout.ui @@ -0,0 +1,202 @@ + +OpenProjectLayout + + + OpenProjectLayout + + + + 0 + 0 + 417 + 384 + + + + Open Project + + + + unnamed + + + + buttonGroup5 + + + Project Path + + + + unnamed + + + + m_pProjPathRequester + + + + + + + buttonGroup6 + + + Recent Projects + + + + unnamed + + + + m_pRecentList + + + + + layout9 + + + + unnamed + + + + spacer4 + + + Horizontal + + + Expanding + + + + 281 + 21 + + + + + + m_pRemoveButton + + + Remove + + + + + + + + + layout9 + + + + unnamed + + + + spacer6 + + + Horizontal + + + Expanding + + + + 201 + 31 + + + + + + m_pOpenButton + + + &Open + + + Alt+O + + + true + + + + + m_pCancelButton + + + C&ancel + + + + + + + + + + + m_pOpenButton + clicked() + OpenProjectLayout + accept() + + + m_pCancelButton + clicked() + OpenProjectLayout + reject() + + + m_pRemoveButton + clicked() + OpenProjectLayout + slotRemoveRecent() + + + m_pRecentList + highlighted(QListBoxItem*) + OpenProjectLayout + slotSelectRecent(QListBoxItem*) + + + m_pRecentList + doubleClicked(QListBoxItem*) + OpenProjectLayout + slotOpenRecent(QListBoxItem*) + + + m_pProjPathRequester + urlSelected(const QString&) + OpenProjectLayout + slotProjectSelected(const QString&) + + + m_pRecentList + returnPressed(QListBoxItem*) + OpenProjectLayout + slotOpenRecent(QListBoxItem*) + + + + slotRemoveRecent() + slotSelectRecent(QListBoxItem*) + slotOpenRecent(QListBoxItem*) + slotProjectSelected(const QString&) + + + + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/src/prefcolor.cpp b/src/prefcolor.cpp new file mode 100644 index 0000000..85beb4b --- /dev/null +++ b/src/prefcolor.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include "prefcolor.h" +#include "kscopeconfig.h" + +/** + * A list view item that shows the name of a GUI element and the colour + * associated with it. + * The colour is presented in the form of a rectangle filled with that + * colour. + * @author Elad Lahav + */ +class ColorListItem : public QListViewItem +{ +public: + /** + * Class constructor. + * @param pList The owner list view + * @param ce The GUI element shown by this item + */ + ColorListItem(QListView* pList, KScopeConfig::ColorElement ce) : + QListViewItem(pList, Config().getColorName(ce), ""), + m_ce(ce) { + setColor(Config().getColor(ce)); + } + + /** + * @return The GUI element shown by this item + */ + KScopeConfig::ColorElement getElement() { return m_ce; } + + /** + * Changes the colour associated with this item. + * The function assigns a pixmap to the item which shows a rectangle + * filled with the requested colour. + * The colour set by this function is returned by getColor(). + * @param clr The colour to set + */ + void setColor(QColor clr) { + QPixmap pix; + QPainter painter; + int nWidth, nHeight; + + // Remember the colour + m_clr = clr; + + // Set the pixmap's size to fit into the list field + nWidth = listView()->columnWidth(1) - 1; + nHeight = height(); + pix.resize(nWidth, nHeight); + + // Draw on the pixmap + painter.begin(&pix); + painter.setBrush(clr); + painter.drawRect(0, 0, nWidth, nHeight); + painter.end(); + + // Set the pixmap to the item + setPixmap(1, pix); + } + + /** + * @return The colour associated with this item + */ + QColor getColor() { return m_clr; } + +private: + /** The GUI element shown by this item. */ + KScopeConfig::ColorElement m_ce; + + /** The colour associated with this item. */ + QColor m_clr; +}; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +PrefColor::PrefColor(QWidget* pParent, const char* szName) : + PrefColorLayout(pParent, szName) +{ + m_pList->setColumnWidthMode(1, QListView::Manual); + + // Set initial values + load(); +} + +/** + * Class destructor. + */ +PrefColor::~PrefColor() +{ +} + +/** + * Reads the current settings from the configuration object, and applies them + * the the page's widget. + */ +void PrefColor::load() +{ + uint i; + ColorListItem* pItem; + + // Create a list item for every GUI element + for (i = 0; i <= KScopeConfig::LAST_COLOR; i++) + pItem = new ColorListItem(m_pList, (KScopeConfig::ColorElement)i); +} + +/** + * Commits settings changes to the configuration object. + */ +void PrefColor::apply() +{ + ColorListItem* pItem; + + // Create a list item for every GUI element + for (pItem = (ColorListItem*)m_pList->firstChild(); pItem != NULL; + pItem = (ColorListItem*)pItem->nextSibling()) { + Config().setColor(pItem->getElement(), pItem->getColor()); + } +} + +/** + * Displays a colour selection dialogue when an item is selected. + * If the user chooses a new colour, it is set to the selected item. + * This slot is connected to both the doubleClicked() and the returnPressed() + * signals of the list view. + * @param pItem The selected item + */ +void PrefColor::slotItemSelected(QListViewItem* pItem) +{ + ColorListItem* pClrItem; + QColor clr; + + pClrItem = (ColorListItem*)pItem; + if (KColorDialog::getColor(clr, pClrItem->getColor()) == + QDialog::Accepted) { + pClrItem->setColor(clr); + emit modified(); + } +} + +#include "prefcolor.moc" diff --git a/src/prefcolor.h b/src/prefcolor.h new file mode 100644 index 0000000..b26bed2 --- /dev/null +++ b/src/prefcolor.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PREFCOLORDLG_H +#define PREFCOLORDLG_H + +#include + +/** + * A widget for selecting colours for KScope's main child-windows. + * @author Elad Lahav + */ +class PrefColor : public PrefColorLayout +{ + Q_OBJECT + +public: + PrefColor(QWidget* pParent = 0, const char* szName = 0); + ~PrefColor(); + + void load(); + void apply(); + +signals: + /** + * Emitted whenever the user makes a change to the dialogue's input + * widgets. + */ + void modified(); + +protected slots: + void slotItemSelected(QListViewItem*); +}; + +#endif diff --git a/src/prefcolorlayout.ui b/src/prefcolorlayout.ui new file mode 100644 index 0000000..8e15bda --- /dev/null +++ b/src/prefcolorlayout.ui @@ -0,0 +1,69 @@ + +PrefColorLayout + + + PrefColorLayout + + + + 0 + 0 + 350 + 210 + + + + Form4 + + + + unnamed + + + + + GUI Element + + + true + + + true + + + + + Colour + + + true + + + false + + + + m_pList + + + + + + + m_pList + doubleClicked(QListViewItem*) + PrefColorLayout + slotItemSelected(QListViewItem*) + + + m_pList + returnPressed(QListViewItem*) + PrefColorLayout + slotItemSelected(QListViewItem*) + + + + slotItemSelected(QListViewItem*) + + + diff --git a/src/preferencesdlg.cpp b/src/preferencesdlg.cpp new file mode 100644 index 0000000..ab13c33 --- /dev/null +++ b/src/preferencesdlg.cpp @@ -0,0 +1,206 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "preferencesdlg.h" +#include "preffrontend.h" +#include "prefcolor.h" +#include "preffont.h" +#include "prefopt.h" +#include "kscopeconfig.h" +#include "cscopefrontend.h" +#include "ctagsfrontend.h" +#include "dotfrontend.h" + + +/** + * Class constructor. + * @param nPage The initial page to show + * @param pParent The parent widget + * @param szName The widget's name + */ +PreferencesDlg::PreferencesDlg(uint nPage, QWidget* pParent, + const char* szName) : + KDialogBase(IconList, i18n("Preferences"), Default | Ok | Apply | Cancel, + Ok, pParent, szName, 0) +{ + QFrame* pFrame; + QVBoxLayout* pLayout; + + // Create and add the "Frontend" page + pFrame = addPage(i18n("Programmes"), + i18n("Paths to back-end programmes"), + KGlobal::iconLoader()->loadIcon("run", KIcon::Panel, 0, false)); + pLayout = new QVBoxLayout(pFrame, 0, 0); + m_pPrefFrontend = new PrefFrontend(pFrame); + pLayout->addWidget(m_pPrefFrontend); + + // Create and add the "Colours" page + pFrame = addPage(i18n("Colours"), i18n("Window colours"), + KGlobal::iconLoader()->loadIcon("colors", KIcon::Panel, 0, false)); + pLayout = new QVBoxLayout(pFrame, 0, 0); + m_pPrefColor = new PrefColor(pFrame); + pLayout->addWidget(m_pPrefColor); + + // Create and add the "Fonts" page + pFrame = addPage(i18n("Fonts"), i18n("Window fonts"), + KGlobal::iconLoader()->loadIcon("fonts", KIcon::Panel, 0, false)); + pLayout = new QVBoxLayout(pFrame, 0, 0); + m_pPrefFont = new PrefFont(pFrame); + pLayout->addWidget(m_pPrefFont); + + // Create and add the "Options" page + pFrame = addPage(i18n("Options"), i18n("Misc. Options"), + KGlobal::iconLoader()->loadIcon("package_settings", + KIcon::Panel, 0, false)); + pLayout = new QVBoxLayout(pFrame, 0, 0); + m_pPrefOpt = new PrefOpt(pFrame); + pLayout->addWidget(m_pPrefOpt); + + // Make sure the "Apply" button is initially disabled + enableButtonApply(false); + + // Enable the "Apply" button when a parameter changes its value + connect(m_pPrefFrontend, SIGNAL(modified()), this, + SLOT(slotModified())); + connect(m_pPrefColor, SIGNAL(modified()), this, SLOT(slotModified())); + connect(m_pPrefFont, SIGNAL(modified()), this, SLOT(slotModified())); + connect(m_pPrefOpt, SIGNAL(modified()), this, SLOT(slotModified())); + + // Set the active page + showPage(nPage); +} + +/** + * Class destructor. + */ +PreferencesDlg::~PreferencesDlg() +{ +} + +/** + * Updates the dialog's widgets with the current configuration parameters. + */ +void PreferencesDlg::loadConfig() +{ + m_pPrefFrontend->load(); + m_pPrefColor->load(); + m_pPrefFont->load(); + m_pPrefOpt->load(); +} + +/** + * Sets the configured parameters to the global configuration object. + * This method is called when either the "OK" or the "Apply" button are + * clicked. Before the new settings are applied, their values are verified. + * @return true if the new parameters were applied successfully, false + * otherwise + */ +bool PreferencesDlg::updateConfig() +{ + // Verify configured paths lead to the executables + if (!verifyPaths()) + return false; + + // Apply the changes + m_pPrefFrontend->apply(); + m_pPrefColor->apply(); + m_pPrefFont->apply(); + m_pPrefOpt->apply(); + + emit applyPref(); + return true; +} + +/** + * Tests whether the paths set for Cscope and Ctags lead to executables. + * Cscope is verified by a different process. + */ +bool PreferencesDlg::verifyPaths() +{ + return (CtagsFrontend::verify(m_pPrefFrontend->m_pCtagsURL->url()) && + DotFrontend::verify(m_pPrefFrontend->m_pDotURL->url())); +} + +/** + * Updates the global configuration based on the values given in the + * preferences dialogue, and then closes the dialogue. + * This function is called after the user clicks the dialogue's "OK" button. + */ +void PreferencesDlg::accept() +{ + if (updateConfig()) + KDialogBase::accept(); +} + +/** + * Updates the global configuration based on the values given in the + * preferences dialogue, leaving the dialogue open. + * This function is called after the user clicks the dialogue's "Apply" + * button. + */ +void PreferencesDlg::slotApply() +{ + if (updateConfig()) + enableButtonApply(false); +} + +/** + * Resets all configuration parameters to their default values. + * This slot is called when the user clicks the "Default" button. + */ +void PreferencesDlg::slotDefault() +{ + // Prompt the user before applying default values + if (KMessageBox::questionYesNo(0, i18n("This would reset all your " + "configuration settings! Continue?")) == KMessageBox::Yes) { + // Load the default values + Config().loadDefault(); + loadConfig(); + + // Apply the default values + slotApply(); + } +} + +/** + * Enables the "Apply" button. + */ +void PreferencesDlg::slotModified() +{ + enableButtonApply(true); +} + +#include "preferencesdlg.moc" diff --git a/src/preferencesdlg.h b/src/preferencesdlg.h new file mode 100644 index 0000000..51fa2cb --- /dev/null +++ b/src/preferencesdlg.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PREFERENCESDLG_H +#define PREFERENCESDLG_H + +#include +#include + +class PrefFrontend; +class PrefColor; +class PrefFont; +class PrefOpt; + +/** + * The main configuration dialog for KScope. + * This dialog displays a set of configuration pages, each dedicated to a + * different subject (frontend programme paths, colours, etc.) + * This code is based on a tutorial by Andreas Nicolai which can be found at + * http://www.kdevelop.org/doc/tutorial_settings + * @author Elad Lahav + */ + +class PreferencesDlg : public KDialogBase +{ + Q_OBJECT + +public: + PreferencesDlg(uint nPage = Frontend, QWidget* pParent = 0, const char* + szName = 0); + ~PreferencesDlg(); + + /** Available pages. */ + enum { Frontend = 0, Colors, Fonts, Options }; + +signals: + /** + * Emitted when the global configuration changes as a result of using + * this dialogue. + */ + void applyPref(); + +protected slots: + virtual void accept(); + virtual void slotApply(); + virtual void slotDefault(); + +private: + /** The front-end programmes page. */ + PrefFrontend* m_pPrefFrontend; + + /** The colours preference page. */ + PrefColor* m_pPrefColor; + + /** The fonts preference page. */ + PrefFont* m_pPrefFont; + + /** The additional options page. */ + PrefOpt* m_pPrefOpt; + + void loadConfig(); + bool updateConfig(); + bool verifyPaths(); + +private slots: + void slotModified(); +}; + +#endif diff --git a/src/preffont.cpp b/src/preffont.cpp new file mode 100644 index 0000000..288c699 --- /dev/null +++ b/src/preffont.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "preffont.h" +#include "kscopeconfig.h" + +/** + * A list view item that shows the name of a GUI element and the font + * associated with it. + * The font is presented in the form of a sample text drawn using this font. + * @author Elad Lahav + */ +class FontListItem : public QListViewItem +{ +public: + /** + * Class constructor. + * @param pList The owner list view + * @param fe The GUI element shown by this item + */ + FontListItem(QListView* pList, KScopeConfig::FontElement fe) : + QListViewItem(pList, Config().getFontName(fe), ""), + m_fe(fe) { + setFont(Config().getFont(fe)); + } + + /** + * @return The GUI element shown by this item + */ + KScopeConfig::FontElement getElement() { return m_fe; } + + /** + * Changes the font associated with this item. + * The function a sample text on a pixmap using this font, and then + * assigns the pixmap to the list item. + * The font set by this function is returned by getFont(). + * @param font The font to set + */ + void setFont(QFont font) { + QPixmap pix; + QFontMetrics fm(font); + QPainter painter; + QRect rc; + + // Remember the font + m_font = font; + + // Set the pixmap's size so it can contain the sample text + rc = fm.boundingRect(i18n("Sample")); + rc.moveTopLeft(QPoint(0, 0)); + pix.resize(rc.width(), rc.height()); + + // Draw on the pixmap + pix.fill(); + painter.begin(&pix); + painter.setFont(font); + painter.setPen(black); + painter.drawText(rc, Qt::AlignHCenter | Qt::AlignVCenter, + i18n("Sample")); + painter.end(); + + // Set the pixmap to the item + setPixmap(1, pix); + } + + /** + * @return The font associated with this item + */ + QFont getFont() { return m_font; } + +private: + /** The GUI element shown by this item. */ + KScopeConfig::FontElement m_fe; + + /** The font associated with this item. */ + QFont m_font; +}; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +PrefFont::PrefFont(QWidget* pParent, const char* szName) : + PrefFontLayout(pParent, szName) +{ + // Set initial values + load(); +} + +/** + * Class destructor. + */ +PrefFont::~PrefFont() +{ +} + +/** + * Reads the current settings from the configuration object, and applies them + * the the page's widget. + */ +void PrefFont::load() +{ + uint i; + FontListItem* pItem; + + // Create a list item for every GUI element + for (i = 0; i <= KScopeConfig::LAST_FONT; i++) + pItem = new FontListItem(m_pList, (KScopeConfig::FontElement)i); +} + +/** + * Commits settings changes to the configuration object. + */ +void PrefFont::apply() +{ + FontListItem* pItem; + + // Create a list item for every GUI element + for (pItem = (FontListItem*)m_pList->firstChild(); pItem != NULL; + pItem = (FontListItem*)pItem->nextSibling()) { + Config().setFont(pItem->getElement(), pItem->getFont()); + } +} + +/** + * Displays a font selection dialogue when an item is selected. + * If the user chooses a new font, it is set to the selected item. + * This slot is connected to both the doubleClicked() and the returnPressed() + * signals of the list view. + * @param pItem The selected item + */ +void PrefFont::slotItemSelected(QListViewItem* pItem) +{ + FontListItem* pFontItem; + QFont font; + + pFontItem = (FontListItem*)pItem; + font = pFontItem->getFont(); + if (KFontDialog::getFont(font) == QDialog::Accepted) { + pFontItem->setFont(font); + emit modified(); + } +} + +#include "preffont.moc" diff --git a/src/preffont.h b/src/preffont.h new file mode 100644 index 0000000..66fdebc --- /dev/null +++ b/src/preffont.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PREFFONT_H +#define PREFFONT_H + +#include "preffontlayout.h" + +/** + * A widget for selecting fonts for KScope's main child-windows. + * @author Elad Lahav + */ + +class PrefFont : public PrefFontLayout +{ + Q_OBJECT + +public: + PrefFont(QWidget* pParent = 0, const char* szName = 0); + ~PrefFont(); + + void load(); + void apply(); + +signals: + /** + * Emitted whenever the user makes a change to the dialogue's input + * widgets. + */ + void modified(); + +protected slots: + void slotItemSelected(QListViewItem*); +}; + +#endif diff --git a/src/preffontlayout.ui b/src/preffontlayout.ui new file mode 100644 index 0000000..983da52 --- /dev/null +++ b/src/preffontlayout.ui @@ -0,0 +1,69 @@ + +PrefFontLayout + + + PrefFontLayout + + + + 0 + 0 + 363 + 210 + + + + Form4 + + + + unnamed + + + + + GUI Element + + + true + + + true + + + + + Font + + + true + + + false + + + + m_pList + + + + + + + m_pList + doubleClicked(QListViewItem*) + PrefFontLayout + slotItemSelected(QListViewItem*) + + + m_pList + returnPressed(QListViewItem*) + PrefFontLayout + slotItemSelected(QListViewItem*) + + + + slotItemSelected(QListViewItem*) + + + diff --git a/src/preffrontend.cpp b/src/preffrontend.cpp new file mode 100644 index 0000000..3bedda7 --- /dev/null +++ b/src/preffrontend.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "preffrontend.h" +#include "kscopeconfig.h" +#include "configfrontend.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +PrefFrontend::PrefFrontend(QWidget* pParent, const char* szName) : + PrefFrontendLayout(pParent, szName) +{ + // Set initial values + load(); + + // Attempt to guess paths based on the user's PATH environment variable + connect(m_pGuessButton, SIGNAL(clicked()), this, + SLOT(slotGuessPaths())); + + // Emit the modified() signal when a new path is set + connect(m_pCscopeURL, SIGNAL(textChanged(const QString&)), this, + SIGNAL(modified())); + connect(m_pCtagsURL, SIGNAL(textChanged(const QString&)), this, + SIGNAL(modified())); + connect(m_pDotURL, SIGNAL(textChanged(const QString&)), this, + SIGNAL(modified())); +} + +/** + * Class destructor. + */ +PrefFrontend::~PrefFrontend() +{ +} + +/** + * Reads the current settings from the configuration object, and applies them + * the the page's widget. + */ +void PrefFrontend::load() +{ + m_pCscopeURL->lineEdit()->setText(Config().getCscopePath()); + m_pCtagsURL->lineEdit()->setText(Config().getCtagsPath()); + m_pDotURL->lineEdit()->setText(Config().getDotPath()); +} + +/** + * Commits settings changes to the configuration object. + */ +void PrefFrontend::apply() +{ + Config().setCscopePath(m_pCscopeURL->url()); + Config().setCtagsPath(m_pCtagsURL->url()); + Config().setDotPath(m_pDotURL->url()); +} + +/** + * Emits the modified() signal whenever any of the paths edit widgets changes + * its contents. + * This slot is connected to the textChanged() signal of each of the path + * edit widgets. By emitting the modified() signal, the widget notifies the + * parent dialog it should enable the "Apply" button. + */ +void PrefFrontend::slotChanged(const QString&) +{ + emit modified(); +} + +/** + * Checks the user's PATH environment variable for a Cscope and Ctags + * executables. + * This is done by running the kscope_config script. + */ +void PrefFrontend::slotGuessPaths() +{ + ConfigFrontend* pConf; + + // Start with an empty results text widget + m_pScriptText->clear(); + + // Create a frontend object for the script + pConf = new ConfigFrontend(true); + + // Show tests and results in the text widget + connect(pConf, SIGNAL(test(uint)), this, + SLOT(slotAutoConfigTest(uint))); + connect(pConf, SIGNAL(result(uint, const QString&)), this, + SLOT(slotAutoConfigResult(uint, const QString&))); + + // Run the script + pConf->run(m_pCscopeURL->url(), m_pCtagsURL->url(), + m_pDotURL->url()); +} + +/** + * Shows the test being executed by the script in the text widget. + * This slot is connected to the test() signal of the ConfigFrontend object. + * @param nType The type of test being executed + */ +void PrefFrontend::slotAutoConfigTest(uint nType) +{ + switch (nType) { + case ConfigFrontend::CscopePath: + m_pScriptText->insert(i18n("Looking for Cscope...")); + break; + + case ConfigFrontend::CscopeVersion: + m_pScriptText->insert(i18n("Checking Cscope version...")); + break; + + case ConfigFrontend::CscopeVerbose: + m_pScriptText->insert(i18n("Cscope support for line mode verbose " + "output...")); + break; + + case ConfigFrontend::CscopeSlowPath: + m_pScriptText->insert(i18n("Cscope support slow path definitions... ")); + break; + + case ConfigFrontend::CtagsPath: + m_pScriptText->insert(i18n("Looking for Ctags...")); + break; + + case ConfigFrontend::CtagsExub: + m_pScriptText->insert(i18n("Ctags compatibilty with ctags-exuberant" + "...")); + break; + + case ConfigFrontend::DotPath: + m_pScriptText->insert(i18n("Looking for Dot...")); + break; + + case ConfigFrontend::DotPlain: + m_pScriptText->insert(i18n("Checking -Tplain...")); + break; + } +} + +/** + * Shows the result of a test executed by the configuration script, and + * adjusts the configuration widgets accordingly. + * @param nType The type of test that was executed + * @param sResult The test's result + */ +void PrefFrontend::slotAutoConfigResult(uint nType, const QString& sResult) +{ + QString sLine; + + sLine = sResult + "\n"; + + switch (nType) { + case ConfigFrontend::CscopePath: + m_pScriptText->insert(sLine); + if (sResult == "ERROR") + m_pCscopeURL->lineEdit()->setText(""); + else + m_pCscopeURL->lineEdit()->setText(sResult); + + break; + + case ConfigFrontend::CscopeVersion: + m_pScriptText->insert(sLine); + if (sResult == "ERROR") + m_pCscopeURL->lineEdit()->setText(""); + break; + + case ConfigFrontend::CscopeVerbose: + m_pScriptText->insert(sLine); + break; + + case ConfigFrontend::CscopeSlowPath: + m_pScriptText->insert(sLine); + break; + + case ConfigFrontend::CtagsPath: + m_pScriptText->insert(sLine); + if (sResult == "ERROR") + m_pCtagsURL->lineEdit()->setText(""); + else + m_pCtagsURL->lineEdit()->setText(sResult); + break; + + case ConfigFrontend::CtagsExub: + m_pScriptText->insert(sLine); + if (sResult == "ERROR") + m_pCtagsURL->lineEdit()->setText(""); + break; + + case ConfigFrontend::DotPath: + m_pScriptText->insert(sLine); + if (sResult == "ERROR") + m_pDotURL->lineEdit()->setText(""); + else + m_pDotURL->lineEdit()->setText(sResult); + break; + + case ConfigFrontend::DotPlain: + m_pScriptText->insert(sLine); + if (sResult == "ERROR") + m_pDotURL->lineEdit()->setText(""); + break; + } +} + +#include "preffrontend.moc" diff --git a/src/preffrontend.h b/src/preffrontend.h new file mode 100644 index 0000000..fb46242 --- /dev/null +++ b/src/preffrontend.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PREFFRONTENDDLG_H +#define PREFFRONTENDDLG_H + +#include +#include + +/** + * A widget for setting the paths to various programmes to which KScope + * provides a front-end. + * @author Elad Lahav + */ + +class PrefFrontend : public PrefFrontendLayout +{ + Q_OBJECT + +public: + PrefFrontend(QWidget* pParent = 0, const char* szName = 0); + ~PrefFrontend(); + + void load(); + void apply(); + +signals: + /** + * Emitted whenever the user makes a change to the dialogue's input + * widgets. + */ + void modified(); + +private slots: + void slotChanged(const QString&); + void slotGuessPaths(); + void slotAutoConfigTest(uint); + void slotAutoConfigResult(uint, const QString&); +}; + +#endif diff --git a/src/preffrontendlayout.ui b/src/preffrontendlayout.ui new file mode 100644 index 0000000..e6b00c9 --- /dev/null +++ b/src/preffrontendlayout.ui @@ -0,0 +1,193 @@ + +PrefFrontendLayout + + + PrefFrontendLayout + + + + 0 + 0 + 415 + 368 + + + + Form3 + + + + unnamed + + + + layout20 + + + + unnamed + + + + layout19 + + + + unnamed + + + + textLabel1 + + + + 0 + 5 + 0 + 0 + + + + Cscope path: + + + + + textLabel2 + + + + 0 + 5 + 0 + 0 + + + + Ctags path: + + + + + textLabel1_2 + + + Dot path: + + + + + + + layout18 + + + + unnamed + + + + m_pCscopeURL + + + + 5 + 5 + 0 + 0 + + + + + + m_pCtagsURL + + + + + m_pDotURL + + + + + + + + + line2 + + + HLine + + + Sunken + + + Horizontal + + + + + layout4 + + + + unnamed + + + + spacer8 + + + Horizontal + + + Expanding + + + + 261 + 21 + + + + + + m_pGuessButton + + + G&uess + + + + + + + m_pScriptText + + + true + + + true + + + + + + + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + kurlrequester.h + klineedit.h + kpushbutton.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/src/prefopt.cpp b/src/prefopt.cpp new file mode 100644 index 0000000..7b52d8f --- /dev/null +++ b/src/prefopt.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "prefopt.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +PrefOpt::PrefOpt(QWidget* pParent, const char* szName) + : PrefOptLayout(pParent, szName) +{ + // Set initial values + load(); + + // Emit the "modified" signal whenever any of the widgets changes its + // its. This will notify the parent dialogue to enable its "Apply" + // button + connect(m_pReadOnlyCheck, SIGNAL(toggled(bool)), this, + SIGNAL(modified())); + connect(m_pLastProjCheck, SIGNAL(toggled(bool)), this, + SIGNAL(modified())); + connect(m_pTagHlCheck, SIGNAL(toggled(bool)), this, + SIGNAL(modified())); + connect(m_pBriefQueryCaptCheck, SIGNAL(toggled(bool)), this, + SIGNAL(modified())); + connect(m_pWarnModifiedOnDiskCheck, SIGNAL(toggled(bool)), this, + SIGNAL(modified())); + connect(m_pAutoSortCheck, SIGNAL(toggled(bool)), this, + SIGNAL(modified())); + connect(m_pExtEditorEdit, SIGNAL(textChanged(const QString&)), this, + SIGNAL(modified())); + connect(m_pSysProfileCB, SIGNAL(activated(int)), this, + SIGNAL(modified())); + connect(m_pEditorPopupCB, SIGNAL(activated(int)), this, + SIGNAL(modified())); +} + +/** + * Class destructor. + */ +PrefOpt::~PrefOpt() +{ +} + +/** + * Reads the current settings from the configuration object, and applies them + * the the page's widget. + */ +void PrefOpt::load() +{ + m_pReadOnlyCheck->setChecked(Config().getReadOnlyMode()); + m_pLastProjCheck->setChecked(Config().getLoadLastProj()); + m_pTagHlCheck->setChecked(Config().getAutoTagHl()); + m_pBriefQueryCaptCheck->setChecked(Config().getUseBriefQueryCaptions()); + m_pWarnModifiedOnDiskCheck->setChecked(Config().getWarnModifiedOnDisk()); + m_pAutoSortCheck->setChecked(Config().getAutoSortFiles()); + m_pExtEditorEdit->setText(Config().getExtEditor()); + + switch (Config().getSysProfile()) { + case KScopeConfig::Fast: + m_pSysProfileCB->setCurrentItem(0); + break; + + case KScopeConfig::Slow: + m_pSysProfileCB->setCurrentItem(1); + break; + } + + switch (Config().getEditorPopup()) { + case KScopeConfig::Embedded: + m_pEditorPopupCB->setCurrentItem(0); + break; + + case KScopeConfig::KScopeOnly: + m_pEditorPopupCB->setCurrentItem(1); + break; + } +} + +/** + * Commits settings changes to the configuration object. + */ +void PrefOpt::apply() +{ + Config().setReadOnlyMode(m_pReadOnlyCheck->isChecked()); + Config().setLoadLastProj(m_pLastProjCheck->isChecked()); + Config().setAutoTagHl(m_pTagHlCheck->isChecked()); + Config().setUseBriefQueryCaptions(m_pBriefQueryCaptCheck->isChecked()); + Config().setWarnModifiedOnDisk(m_pWarnModifiedOnDiskCheck->isChecked()); + Config().setAutoSortFiles(m_pAutoSortCheck->isChecked()); + Config().setExtEditor(m_pExtEditorEdit->text()); + + switch (m_pSysProfileCB->currentItem()) { + case 0 : + Config().setSysProfile(KScopeConfig::Fast); + break; + + case 1: + Config().setSysProfile(KScopeConfig::Slow); + break; + } + + switch (m_pEditorPopupCB->currentItem()) { + case 0: + Config().setEditorPopup(KScopeConfig::Embedded); + break; + + case 1: + Config().setEditorPopup(KScopeConfig::KScopeOnly); + break; + } +} + +#include "prefopt.moc" diff --git a/src/prefopt.h b/src/prefopt.h new file mode 100644 index 0000000..26e2572 --- /dev/null +++ b/src/prefopt.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PREFOPT_H +#define PREFOPT_H + +#include "prefoptlayout.h" + +/** + * A widget for setting different global options. + * @author Elad Lahav + */ + +class PrefOpt : public PrefOptLayout +{ + Q_OBJECT + +public: + PrefOpt(QWidget* pParent = 0, const char* szName = 0); + ~PrefOpt(); + + void load(); + void apply(); + +signals: + /** + * Emitted whenever the user makes a change to the dialogue's input + * widgets. + */ + void modified(); +}; + +#endif + diff --git a/src/prefoptlayout.ui b/src/prefoptlayout.ui new file mode 100644 index 0000000..cbc8d07 --- /dev/null +++ b/src/prefoptlayout.ui @@ -0,0 +1,217 @@ + +PrefOptLayout + + + PrefOptLayout + + + + 0 + 0 + 354 + 312 + + + + Form4 + + + Determines whether KScope should automatically load the last project when started. + + + + unnamed + + + + layout7 + + + + unnamed + + + + m_pExtEditorLabel + + + true + + + External Editor + + + + + m_pExtEditorEdit + + + true + + + + 7 + 0 + 1 + 0 + + + + + + + + m_pReadOnlyCheck + + + Read-Onl&y Mode + + + Alt+Y + + + Forces all editor windows to work in a read-only mode, so that the user cannot modify the displayed files. + + + + + m_pLastProjCheck + + + Open Last Project on Start-Up + + + + + m_pTagHlCheck + + + Automatic Tag Highlighting + + + Determines whether the tag list should highlight the relevant tag based on the cursor's position. + + + + + m_pBriefQueryCaptCheck + + + Brief Tab Captions for &Query Pages + + + If set, the tab captions for query pages will be shortened, by using aliases for the query types. + + + + + m_pWarnModifiedOnDiskCheck + + + Warn When a File is Modified Outside KScope + + + If set, the user is prompted whenever the currently edited file is changed by an external programme. + + + + + m_pAutoSortCheck + + + Automatically Sort Files in the File List + + + + + + Sorts files in the project's file list when a project is loaded. This may be too slow for large projects on older machines. + + + + + layout2 + + + + unnamed + + + + textLabel1 + + + System Profile + + + + + + Fast + + + + + Slow + + + + m_pSysProfileCB + + + + + + + layout3 + + + + unnamed + + + + textLabel2 + + + Editor Popup Menu + + + + + + Embedded + + + + + KScope Only + + + + m_pEditorPopupCB + + + + + + + spacer11 + + + Vertical + + + Expanding + + + + 21 + 20 + + + + + + + diff --git a/src/progressdlg.cpp b/src/progressdlg.cpp new file mode 100644 index 0000000..418a3c9 --- /dev/null +++ b/src/progressdlg.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include "progressdlg.h" + +/** + * Class constructor. + * @param sCaption The dialogue's title + * @param sText The text to display + * @param pParent The parent widget + * @param szName The widget's name + */ +ProgressDlg::ProgressDlg(const QString& sCaption, const QString& sText, + QWidget* pParent, const char* szName) : + KProgressDialog(pParent, szName, sCaption, sText, true), + m_nIdleValue(-1) +{ + setAutoClose(false); + setAllowCancel(false); + + // Create the idle-progress timer + m_pIdleTimer = new QTimer(this); + + // Display a busy indicator by increasing the value of the idle counter + connect (m_pIdleTimer, SIGNAL(timeout()), this, SLOT(slotShowBusy())); +} + +/** + * Class destructor. + */ +ProgressDlg::~ProgressDlg() +{ +} + +/** + * Sets a new value to the progress bar. + * If the new value is non-zero, the progress bar is advanced. Otherwise, the + * idle timer is initiated to display a busy indicator. + * @param nValue The new value to set. + */ +void ProgressDlg::setValue(int nValue) +{ + KProgress* pProgress; + + pProgress = progressBar(); + + if (nValue != 0) { + // Do nothing if the value hasn't changed + if (nValue == pProgress->progress()) + return; + + // Handle first non-zero value + if (m_nIdleValue >= 0) { + m_pIdleTimer->stop(); + m_nIdleValue = -1; + pProgress->setPercentageVisible(true); + } + + // Set the new value + pProgress->setValue(nValue); + } + else if (m_nIdleValue == -1) { + // Handle first 0 value + pProgress->setValue(0); + pProgress->setPercentageVisible(false); + m_nIdleValue = 0; + m_pIdleTimer->start(200); + } +} + +void ProgressDlg::setIdle() +{ + m_nIdleValue = -1; + setValue(0); +} + +/** + * Increaes the value of the dummy counter by 1. + * This slot is called by the timeout() event of the idle timer. + */ +void ProgressDlg::slotShowBusy() +{ + // Increase the counter + m_nIdleValue += 5; + if (m_nIdleValue == 100) + m_nIdleValue = 0; + + // Set the value of the progress-bar + progressBar()->setValue(m_nIdleValue); +} + +#include "progressdlg.moc" diff --git a/src/progressdlg.h b/src/progressdlg.h new file mode 100644 index 0000000..d5f0e6b --- /dev/null +++ b/src/progressdlg.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PROGRESSDLG_H +#define PROGRESSDLG_H + +#include +#include +#include + +/** + * An improved progress dialog. + * This variation of the standard KDE progress dialog displays a busy + * indicator while waiting for the first value greater than 0. + * @author Elad Lahav + */ + +class ProgressDlg : public KProgressDialog +{ + Q_OBJECT + +public: + ProgressDlg(const QString&, const QString&, QWidget* pParent = 0, const + char* szName = 0); + ~ProgressDlg(); + + void setValue(int); + void setIdle(); + +private: + /** When the value is 0, this timer initiates value changes that cause + the progress-bar to move. */ + QTimer* m_pIdleTimer; + + /** A dummy value used to move the progress-bar while the value is 0. */ + int m_nIdleValue; + +private slots: + void slotShowBusy(); +}; + +#endif diff --git a/src/project.cpp b/src/project.cpp new file mode 100644 index 0000000..06e1332 --- /dev/null +++ b/src/project.cpp @@ -0,0 +1,442 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include "project.h" +#include "kscopeconfig.h" +#include "cscopefrontend.h" + +#define PROJECT_CONFIG_VER 2 + +inline void flListFromStringList(FileLocationList& fll, const QStringList& sl) +{ + QStringList::ConstIterator itr; + QString sPath; + uint nLine, nCol; + + // Transform the string into a list of file locations + for (itr = sl.begin(); itr != sl.end(); ++itr) { + sPath = (*itr).section(':', 0, 0); + nLine = (*itr).section(':', 1, 1).toUInt(); + nCol = (*itr).section(':', 2, 2).toUInt(); + fll.append(new FileLocation(sPath, nLine, nCol)); + } +} + +inline void stringListFromFlList(QStringList& sl, const FileLocationList& fll) +{ + FileLocationList* pList; + FileLocation* pLoc; + QString sLoc; + + // Nasty... + pList = (FileLocationList*)&fll; + sl.clear(); + + // Turn the object list into a string list, so that it can be written in + // the configuration file + for (pLoc = pList->first(); pLoc != NULL; pLoc = pList->next()) { + sLoc = ""; + QTextOStream(&sLoc) << pLoc->m_sPath << ":" << pLoc->m_nLine << ":" + << pLoc->m_nCol; + sl.append(sLoc); + } +} + +/** + */ +Project::Project() : ProjectBase(), + m_pConf(NULL) +{ +} + +/** + */ +Project::~Project() +{ + close(); +} + +/** + */ +bool Project::open(const QString& sPath) +{ + QString sConfFile; + Options opt; + + // Associate the object with the project directory + m_dir.setPath(sPath); + if (!m_dir.exists()) { + KMessageBox::error(0, i18n("Project directory does not exist")); + return false; + } + + // Initialise the file-list file object + m_fiFileList.setName(sPath + "/cscope.files"); + + // Open the configuration files + m_pConf = new KConfig(sPath + "/cscope.proj"); + + // Verify the configuration file's version is compatible + m_pConf->setGroup(""); + if (m_pConf->readUnsignedNumEntry("Version", 0) != PROJECT_CONFIG_VER) { + KMessageBox::error(0, i18n("Your project is not compatible with this " + "version of KScope.\nPlease re-create the project.")); + return false; + } + + // Get the project name + m_pConf->setGroup("Project"); + m_sName = m_pConf->readEntry("Name"); + if (m_sName == QString::null) { + KMessageBox::error(0, i18n("Cannot read project name")); + return false; + } + + // Get stored options + initOptions(); + + // Set default make values for new projects (overriden in loadSession(), + // which is not called for new projects) + m_sMakeRoot = getSourceRoot(); + m_sMakeCmd = "make"; + + return true; +} + +/** + */ +void Project::close() +{ + if (m_pConf) + delete m_pConf; + + m_fiFileList.close(); +} + +/** + * Returns a semi-colon separated list of the file types included in the + * current project. + */ +QString Project::getFileTypes() const +{ + QString sTypes; + + m_pConf->setGroup("Project"); + return m_pConf->readEntry("FileTypes"); +} + +/** + * Reads the project's options from the configuration file. + * @param opt A structure to fill with the read options + */ +void Project::getOptions(Options& opt) const +{ + // Get project properties + m_pConf->setGroup("Project"); + opt.sSrcRootPath = m_pConf->readEntry("RootPath", "/"); + opt.slFileTypes = m_pConf->readListEntry("FileTypes", ' '); + opt.bKernel = m_pConf->readBoolEntry("Kernel", DEF_IS_KERNEL); + opt.bInvIndex = m_pConf->readBoolEntry("InvIndex", DEF_INV_INDEX); + opt.bNoCompress = m_pConf->readBoolEntry("NoCompress", DEF_NO_COMPRESS); + opt.bSlowPathDef = m_pConf->readBoolEntry("SlowPathDef", DEF_SLOW_PATH); + opt.nAutoRebuildTime = m_pConf->readNumEntry("AutoRebuildTime"); + opt.nTabWidth = m_pConf->readUnsignedNumEntry("TabWidth"); + opt.sCtagsCmd = m_pConf->readEntry("CtagsCommand", DEF_CTAGS_COMMAND); + + // Get auto-completion options + m_pConf->setGroup("AutoCompletion"); + opt.bACEnabled = m_pConf->readBoolEntry("Enabled"); + opt.nACMinChars = m_pConf->readUnsignedNumEntry("MinChars", + DEF_AC_MIN_CHARS); + opt.nACDelay = m_pConf->readUnsignedNumEntry("Delay", DEF_AC_DELAY); + opt.nACMaxEntries = m_pConf->readUnsignedNumEntry("MaxEntries", + DEF_AC_MAX_ENTRIES); +} + +/** + * Sets project options. + * @param opt A structure containing the new parameters to set + */ +void Project::setOptions(const Options& opt) +{ + // Write the options to the configuration nfile + writeOptions(m_pConf, opt); + + // Update project parameters + initOptions(); +} + +/** + */ +void Project::loadSession(Session& sess) +{ + QStringList slEntry; + + m_pConf->setGroup("Session"); + + // Read the list of open file locations + slEntry = m_pConf->readListEntry("OpenFiles"); + flListFromStringList(sess.fllOpenFiles, slEntry); + + // Get the path of the last viewed file + sess.sLastFile = m_pConf->readEntry("LastOpenFile"); + + // Read the lists of locked query files and call-tree/graph files + sess.slQueryFiles = m_pConf->readListEntry("QueryFiles"); + sess.slCallTreeFiles = m_pConf->readListEntry("CallTreeFiles"); + + // Read the list of bookmarks + slEntry = m_pConf->readListEntry("Bookmarks"); + flListFromStringList(sess.fllBookmarks, slEntry); + + // Read make-related information + sess.sMakeCmd = m_pConf->readEntry("MakeCommand", "make"); + sess.sMakeRoot = m_pConf->readEntry("MakeRoot", getSourceRoot()); + + // Cache make values + m_sMakeCmd = sess.sMakeCmd; + m_sMakeRoot = sess.sMakeRoot; +} + +/** + * Saves session-related information in the project's configuration file. + * @param sess Session parameters + */ +void Project::storeSession(const Session& sess) +{ + QStringList slEntry; + + m_pConf->setGroup("Session"); + + // Write the list of open file locations + stringListFromFlList(slEntry, sess.fllOpenFiles); + m_pConf->writeEntry("OpenFiles", slEntry); + + // Write the path of the last viewed file + m_pConf->writeEntry("LastOpenFile", sess.sLastFile); + + // Write the lists of locked query files and call-tree/graph files + m_pConf->writeEntry("QueryFiles", sess.slQueryFiles); + m_pConf->writeEntry("CallTreeFiles", sess.slCallTreeFiles); + + // Write the list of bookmarks + stringListFromFlList(slEntry, sess.fllBookmarks); + m_pConf->writeEntry("Bookmarks", slEntry); + + // Write make-related information + // Be careful not to write empty strings, as they may occur if the make + // dialogue was not invoked during this session + if (!sess.sMakeCmd.isEmpty()) + m_pConf->writeEntry("MakeCommand", sess.sMakeCmd); + if (!sess.sMakeRoot.isEmpty()) + m_pConf->writeEntry("MakeRoot", sess.sMakeRoot); +} + +/** + * Fills a list object with all files in the project. + * List items are created by reading and parsing all file name entries from + * the project's 'cscope.files' file. + * Note that the file may contain option lines, beginning with a dash. These + * should be ignored. + * @param pList Pointer to the object to fill + */ +bool Project::loadFileList(FileListTarget* pList) +{ + QString sFilePath; + + // Open the 'cscope.files' file + if (!m_fiFileList.open(IO_ReadOnly)) + return false; + + // Read all file names from the file + QTextStream str(&m_fiFileList); + while ((sFilePath = str.readLine()) != QString::null) { + // Skip option lines + if (sFilePath.at(0) == '-') + continue; + + // Set the new list item + pList->addItem(sFilePath); + } + + m_fiFileList.close(); + return true; +} + +/** + * Writes all file entries in a list view widget to the project's + * 'cscope.files' file (replacing current file contents.) + * @param pList Pointer to the object from which to take the new entries + */ +bool Project::storeFileList(FileListSource* pList) +{ + QString sFilePath; + + // Open the 'cscope.files' file + if (!m_fiFileList.open(IO_WriteOnly | IO_Truncate)) + return false; + + QTextStream str(&m_fiFileList); + + // Write all file names + if (pList->firstItem(sFilePath)) { + do { + str << sFilePath << "\n"; + } while (pList->nextItem(sFilePath)); + } + + m_fiFileList.close(); + return true; +} + +/** + * Adds a single file to the file list. + * @param sPath The path of the file to add + * @return true if successful, false otherwise + */ +bool Project::addFile(const QString& sPath) +{ + // Open the 'cscope.files' file + if (!m_fiFileList.open(IO_WriteOnly | IO_Append)) + return false; + + // Write the file path + QTextStream str(&m_fiFileList); + str << sPath << "\n"; + + m_fiFileList.close(); + return true; +} + +/** + * Determines whether the project includes any files. + * Reads the 'cscope.files' file and looks for any file names in it. If none + * is present, then the project is considered empty. + * Note that the file may contain option lines, beginning with a dash. These + * should be ignored. + * @return true if no files are included in the project, false otherwise + */ +bool Project::isEmpty() +{ + QString sPath, sFileName; + bool bResult = true; + + // Open the 'cscope.files' file + if (!m_fiFileList.open(IO_ReadOnly)) + return true; + + // Find at least one file name entry in the file + QTextStream str(&m_fiFileList); + while ((sPath = str.readLine()) != QString::null) { + if (sPath.at(0) != '-') { + bResult = false; + break; + } + } + + m_fiFileList.close(); + return bResult; +} + +/** + * Copies the list of previously queried symbols to the target object. + * @param slSymHistory The list object to copy into + */ +void Project::getSymHistory(QStringList& slSymHistory) const +{ + slSymHistory = m_slSymHistory; +} + +/** + * Copies the list of previously queried symbols from the target object. + * @param slSymHistory The list object to copy from + */ +void Project::setSymHistory(QStringList& slSymHistory) +{ + m_slSymHistory = slSymHistory; +} + +void Project::getMakeParams(QString& sCmd, QString& sDir) const +{ + sCmd = m_sMakeCmd; + sDir = m_sMakeRoot; +} + +/** + * Creates a project by writing a configuration file inside the given + * directory. + * @param sName The project's name + * @param sPath The full path of the project's directory + * @param opt Project options + */ +bool Project::create(const QString& sName, const QString& sPath, + const Options& opt) +{ + // Prepare the project's files + KConfig conf(sPath + "/cscope.proj"); + + // Write the configuration file version + conf.setGroup(""); + conf.writeEntry("Version", PROJECT_CONFIG_VER); + + // Write project properties in the configuration file + conf.setGroup("Project"); + conf.writeEntry("Name", sName); + writeOptions(&conf, opt); + + // Flush the config file data, so the project is created even if KScope + // crashes... + conf.sync(); + + return true; +} + +void Project::writeOptions(KConfig* pConf, const Options& opt) +{ + pConf->setGroup("Project"); + pConf->writeEntry("RootPath", opt.sSrcRootPath); + pConf->writeEntry("FileTypes", opt.slFileTypes.join(" ")); + pConf->writeEntry("Kernel", opt.bKernel); + pConf->writeEntry("InvIndex", opt.bInvIndex); + pConf->writeEntry("NoCompress", opt.bNoCompress); + pConf->writeEntry("SlowPathDef", opt.bSlowPathDef); + pConf->writeEntry("AutoRebuildTime", opt.nAutoRebuildTime); + pConf->writeEntry("TabWidth", opt.nTabWidth); + pConf->writeEntry("CtagsCommand", opt.sCtagsCmd); + + // Set auto-completion options + pConf->setGroup("AutoCompletion"); + pConf->writeEntry("Enabled", opt.bACEnabled); + pConf->writeEntry("MinChars", opt.nACMinChars); + pConf->writeEntry("Delay", opt.nACDelay); + pConf->writeEntry("MaxEntries", opt.nACMaxEntries); +} diff --git a/src/project.h b/src/project.h new file mode 100644 index 0000000..a2679b2 --- /dev/null +++ b/src/project.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PROJECT_H +#define PROJECT_H + +#include + +/** + * @author Elad Lahav + */ +class Project : public ProjectBase +{ +public: + Project(); + virtual ~Project(); + + struct Session { + FileLocationList fllOpenFiles; + QString sLastFile; + QStringList slQueryFiles; + QStringList slCallTreeFiles; + FileLocationList fllBookmarks; + QString sMakeCmd; + QString sMakeRoot; + }; + + virtual bool open(const QString&); + virtual bool loadFileList(FileListTarget*); + virtual bool storeFileList(FileListSource*); + virtual bool addFile(const QString&); + virtual bool isEmpty(); + virtual void close(); + + virtual QString getFileTypes() const; + virtual void getOptions(Options&) const; + virtual void setOptions(const Options&); + virtual void loadSession(Session&); + virtual void storeSession(const Session&); + virtual void getSymHistory(QStringList&) const; + virtual void setSymHistory(QStringList&); + virtual void getMakeParams(QString&, QString&) const; + + /** + * Determines whether a project is based on a Cscope.out file, and is + * therefore considered as a temporary project. + * @return true if this is a temporary project, false otherwise + */ + virtual bool isTemporary() { return false; } + + static bool create(const QString&, const QString&, const Options&); + +private: + /** The configuration file ("cscope.proj") */ + KConfig* m_pConf; + + /** The file that holds the paths of all source files in this project + ("cscope.files") */ + QFile m_fiFileList; + + QString m_sMakeCmd; + + QString m_sMakeRoot; + + static void writeOptions(KConfig*, const Options&); +}; + +#endif diff --git a/src/projectbase.cpp b/src/projectbase.cpp new file mode 100644 index 0000000..f99c045 --- /dev/null +++ b/src/projectbase.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#include "projectbase.h" +#include "kscopeconfig.h" +#include "cscopefrontend.h" + +ProjectBase::ProjectBase() +{ +} + +ProjectBase::~ProjectBase() +{ +} + +bool ProjectBase::open(const QString& sPath) +{ + QFileInfo fi(sPath); + + // Make sure the file exists, and that is is a cross-reference file + if (!fi.exists() || !isCscopeOut(fi.absFilePath())) + return false; + + // Set the project's directory + m_dir = fi.dirPath(true); + + // Set the name of the project to be the full path of the file + m_sName = fi.absFilePath(); + + // Initialise project options (assume source root is the folder holding the + // cscope.out file) + getDefOptions(m_opt); + m_opt.sSrcRootPath = m_dir.absPath(); + + return true; +} + +/** + * Determines if the cscope.out file for this project exists. + * @return true if the database exists, false otherwise + */ +bool ProjectBase::dbExists() +{ + return m_dir.exists("cscope.out"); +} + +void ProjectBase::getOptions(Options& opt) const +{ + getDefOptions(opt); +} + +void ProjectBase::getMakeParams(QString& sCmd, QString& sDir) const +{ + sCmd = "make"; + sDir = getSourceRoot(); +} + +/** + * Fills a structure with default properties for a new project. + * Default properties are partly based on the system profile. + * @param opt The structure to fill + */ +void ProjectBase::getDefOptions(Options& opt) +{ + // Set default source path to file-system root + opt.sSrcRootPath = "/"; + + // Initialise MIME-type list + opt.slFileTypes.append("*.c"); + opt.slFileTypes.append("*.h"); + + // Set other options + opt.bKernel = DEF_IS_KERNEL; + opt.bInvIndex = DEF_INV_INDEX; + opt.bNoCompress = DEF_NO_COMPRESS; + opt.bSlowPathDef = DEF_SLOW_PATH; + opt.nACMinChars = DEF_AC_MIN_CHARS; + opt.nACDelay = DEF_AC_DELAY; + opt.nACMaxEntries = DEF_AC_MAX_ENTRIES; + opt.nTabWidth = DEF_TAB_WIDTH; + + // Set profile-dependant options + if (Config().getSysProfile() == KScopeConfig::Fast) { + opt.nAutoRebuildTime = 10; + opt.bACEnabled = true; + } + else { + opt.nAutoRebuildTime = -1; + opt.bACEnabled = false; + } +} + +void ProjectBase::initOptions() +{ + // Load the options + getOptions(m_opt); + + // Create the argument list for invoking Cscope + m_nArgs = 0; + if (m_opt.bKernel) + m_nArgs |= CscopeFrontend::Kernel; + if (m_opt.bInvIndex) + m_nArgs |= CscopeFrontend::InvIndex; + if (m_opt.bNoCompress) + m_nArgs |= CscopeFrontend::NoCompression; + if (m_opt.bSlowPathDef) + m_nArgs |= CscopeFrontend::SlowPathDef; +} + +/** + * Determines if the given file is a Cscope cross-reference database. + * @param sPath The full path of the file to check + * @return true if the given file is a cscope.out file, false otherwise + */ +bool ProjectBase::isCscopeOut(const QString& sPath) +{ + QFile file(sPath); + QString sLine; + int nVer; + char szDir[PATH_MAX]; + + // Try to open the file + if (!file.open(IO_ReadOnly)) + return false; + + // Check if the first line matches the expected format + sLine = QTextStream(&file).readLine(); + return sscanf(sLine.latin1(), "cscope %d %s", &nVer, szDir) == 2; +} + +/** + * Fills a list object with all files in the project. + * List items are created by reading and parsing all file name entries from + * the project's 'cscope.files' file. + * Note that the file may contain option lines, beginning with a dash. These + * should be ignored. + * @param pList Pointer to the object to fill + */ +bool ProjectBase::loadFileList(FileListTarget* pList) +{ + QString sFilePath; + QFile file; + + // Make sure the file exists + if (!m_dir.exists("cscope.files")) + return false; + + // Open the file + file.setName(m_dir.absPath() + "/cscope.files"); + if (!file.open(IO_ReadOnly)) + return false; + + // Read all file names from the file + QTextStream str(&file); + while ((sFilePath = str.readLine()) != QString::null) { + // Skip option lines + if (sFilePath.at(0) == '-') + continue; + + // Set the new list item + pList->addItem(sFilePath); + } + + file.close(); + return true; +} diff --git a/src/projectbase.h b/src/projectbase.h new file mode 100644 index 0000000..4170652 --- /dev/null +++ b/src/projectbase.h @@ -0,0 +1,281 @@ +/*************************************************************************** + * + * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PROJECTBASE_H +#define PROJECTBASE_H + +#include +#include +#include +#include + +#define DEF_IS_KERNEL false +#define DEF_INV_INDEX true +#define DEF_NO_COMPRESS false +#define DEF_SLOW_PATH false +#define DEF_AC_MIN_CHARS 3 +#define DEF_AC_DELAY 500 +#define DEF_AC_MAX_ENTRIES 100 +#define DEF_TAB_WIDTH 0 /* Use editor's default */ +#define DEF_CTAGS_COMMAND \ + "--regex-c=\"/^[ \\t]*([_a-zA-Z][_a-zA-Z0-9]*):/\\1/l,label/\" " \ + "--regex-c=\"/^[ \\t]*#[ \\t]*include[ \\t]*[\\\"<]" \ + "([_a-zA-Z0-9\\.\\/]*)[\\\">]/\\1/i,include/\" " \ + "--regex-c++=\"/^[ \\t]*#[ \\t]*include[ \\t]*[\\\"<]" \ + "([_a-zA-Z0-9\\.\\/]*)[\\\">]/\\1/i,include/\"" + +/** + * Abstract base class for classes that need the list of project files. + * Objects of classes derived from this one are used as a parameter to + * ProjectManager::fillList(), which reads all file entries in the project, + * and calls addItem() for each. + * Any class that wishes to retrieve the project's file list, should inherit + * from this class, and implement addItem(). + * @author Elad Lahav + */ + +class FileListTarget +{ +public: + /** + * Class constructor. + */ + FileListTarget() {} + + /** + * Class destructor. + */ + virtual ~FileListTarget() {} + + /** + * Appends a file to the list. + * @param sFilePath The full path of the file to add + */ + virtual void addItem(const QString& sFilePath) = 0; +}; + +/** + * Abstract base class for classes that need the list of project files. + * Objects of classes derived from this one are used as a parameter to + * ProjectManager::writeList(), which calls getFirstItem() and getNextItem(), + * and writes the returned values to the project's 'cscope.files' file. + * Any class that wishes to retrieve the project's file list, should inherit + * from this class, and implement firstItem() and nextItem(). + * @author Elad Lahav + */ + +class FileListSource +{ +public: + /** + * Class constructor. + */ + FileListSource() {} + + /** + * Class destructor. + */ + virtual ~FileListSource() {} + + /** + * Returns the first file in the list, and initiates a new iteration. + * @param sFilePath Holds the path of the first file, upon return + * @return true if there are more files, false otherwise + */ + virtual bool firstItem(QString& sFilePath) = 0; + + /** + * Returns the next file in the list. + * @param sFilePath Holds the path of the file, upon return + * @return true if there are more files, false otherwise + */ + virtual bool nextItem(QString& sFilePath) = 0; +}; + +/** + * Defines a cursor location inside a file. + * This structure is used to store project session information. + * @author Elad Lahav + */ +struct FileLocation +{ + /** + * Struct constructor. + * @param sPath The full path of the file + * @param nLine The line position of the cursor + * @param nCol The column position of the cursor + */ + FileLocation(QString sPath, uint nLine, uint nCol) : m_sPath(sPath), + m_nLine(nLine), m_nCol(nCol) {} + + /** The full path of the file. */ + QString m_sPath; + + /** The line position of the cursor. */ + uint m_nLine; + + /** The column position of the cursor. */ + uint m_nCol; +}; + +/** + * A list of file locations used for restoring a session. + */ +typedef QPtrList FileLocationList; + +class FileSemaphore; + +/** + * @author Elad Lahav + */ +class ProjectBase +{ +public: + ProjectBase(); + virtual ~ProjectBase(); + + /** + * Configurable project options. + */ + struct Options { + QString sSrcRootPath; + + /** A list of MIME-types that determines which files are included in + the project. */ + QStringList slFileTypes; + + /** true if the -k option for CScope should be used. */ + bool bKernel; + + /** true if Cscope should build an inverted index. */ + bool bInvIndex; + + /** true if the -c option for CScope should be used. */ + bool bNoCompress; + + /** true if the -D option for CScope should be used. */ + bool bSlowPathDef; + + /** The time, in milliseconds, after which the database should be + automatically rebuilt (-1 if this option is disabled). */ + int nAutoRebuildTime; + + /** true to use auto-completion. */ + bool bACEnabled; + + /** Minimum number of characters in a symbol for auto-completion. */ + uint nACMinChars; + + /** Time interval, in milliseconds, before auto-completion is + started. */ + uint nACDelay; + + /** Maximal number of entries for auto-completion. */ + uint nACMaxEntries; + + /** Per-project tab width (overrides editor settings). */ + uint nTabWidth; + + /** Ctags command line. */ + QString sCtagsCmd; + }; + + virtual bool open(const QString&); + virtual bool loadFileList(FileListTarget*); + virtual bool storeFileList(FileListSource*) { return false; } + virtual bool isEmpty() { return false; } + bool dbExists(); + virtual void close() {} + + virtual QString getFileTypes() const { return QString::null; } + virtual void getOptions(Options&) const; + virtual void setOptions(const Options&) {} + virtual void getSymHistory(QStringList&) const {} + virtual void setSymHistory(QStringList&) {} + virtual void getMakeParams(QString&, QString&) const; + + /** + * Determines whether a project is based on a Cscope.out file, and is + * therefore considered as a temporary project. + * @return true if this is a temporary project, false otherwise + */ + virtual bool isTemporary() { return true; } + + /** + * @return The name of the current project + */ + QString getName() const { return m_sName; } + + /** + * @return The full path of the project's directory + */ + QString getPath() const { return m_dir.absPath(); } + + /** + * @return Command-line arguments to pass to a Cscope object, based on + * project's options + */ + uint getArgs() const { return m_nArgs; } + + const QString& getSourceRoot() const { return m_opt.sSrcRootPath; } + + /** + * @return The time, in seconds, to wait before rebuilding the + * cross-refernce database. + */ + int getAutoRebuildTime() const { return m_opt.nAutoRebuildTime; } + + /** + * @return The tab width to use (0 to use the editor's default) + */ + uint getTabWidth() const { return m_opt.nTabWidth; } + + static void getDefOptions(Options&); + +protected: + /** The name of the project, as written in the configuration file */ + QString m_sName; + + /** The directory associated with the project */ + QDir m_dir; + + /** A cached version of the project's options. */ + Options m_opt; + + /** A list of Cscope command-line arguments based on the project's + options. */ + uint m_nArgs; + + /** A list of symbols previously queried. */ + QStringList m_slSymHistory; + + void initOptions(); + + static bool isCscopeOut(const QString&); +}; + +#endif diff --git a/src/projectfilesdlg.cpp b/src/projectfilesdlg.cpp new file mode 100644 index 0000000..de84417 --- /dev/null +++ b/src/projectfilesdlg.cpp @@ -0,0 +1,439 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "projectfilesdlg.h" +#include "dirscanner.h" +#include "scanprogressdlg.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pProjMgr Pointer the KScope's project manager object + * @param pParent The parent widget + * @param szName The widget's name + */ +ProjectFilesDlg::ProjectFilesDlg(Project* pProj, QWidget* pParent, + const char* szName) : + ProjectFilesLayout(pParent, szName), + m_pProj(pProj), + m_pScanDlg(NULL), + m_pItrItem(NULL), + m_pLastItem(NULL) +{ + // Create the scanner object + m_pScanner = new DirScanner(this, &m_dicFiles); + + // Initialise the list view + m_pFileList->setSelectionMode(QListView::Extended); + m_pFileList->addColumn("File Path"); + + // Sort only when asked to by the user + if (Config().getAutoSortFiles()) + m_pFileList->setSortColumn(0); + else + m_pFileList->setSortColumn(m_pFileList->columns() + 1); + + // Add file/directory/tree when the appropriate button is clicked + connect(m_pAddFilesButton, SIGNAL(clicked()), this, + SLOT(slotAddFiles())); + connect(m_pAddDirButton, SIGNAL(clicked()), this, SLOT(slotAddDir())); + connect(m_pAddTreeButton, SIGNAL(clicked()), this, SLOT(slotAddTree())); + + // Remove selected files/directory/tree when the appropriate button is + // clicked + connect(m_pRemSelButton, SIGNAL(clicked()), this, SLOT(slotRemSel())); + connect(m_pRemDirButton, SIGNAL(clicked()), this, SLOT(slotRemDir())); + connect(m_pRemTreeButton, SIGNAL(clicked()), this, SLOT(slotRemTree())); + + // Hide/show files according to filter + connect(m_pFilterButton, SIGNAL(clicked()), this, SLOT(slotFilter())); + connect(m_pShowAllButton, SIGNAL(clicked()), this, SLOT(slotShowAll())); + + // Close the dialog when OK/Cancel are clicked + connect(m_pOKButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + // Fill the list with the project's files + m_pFileList->setUpdatesEnabled(false); + m_pProj->loadFileList(this); + m_pFileList->setUpdatesEnabled(true); + m_pFileList->triggerUpdate(); +} + +/** + * Class destructor. + */ +ProjectFilesDlg::~ProjectFilesDlg() +{ + delete m_pScanner; +} + +/** + * Adds a single entry to the file list. + * Implements the addItem() virtual method of the FileListTarget base + * class. When a ProjectFilesDlg object is given as a parameter to + * ProjectManager::fillList(), this method is called for each file included + * in the project. A new list item is created, containing the file's path, + * and is added to the list. + * @param sFilePath The full path of a source file + */ +void ProjectFilesDlg::addItem(const QString& sFilePath) +{ + QListViewItem* pItem; + + pItem = new QListViewItem(m_pFileList, m_pLastItem); + pItem->setText(0, sFilePath); + m_pLastItem = pItem; + m_dicFiles.insert(sFilePath, pItem); +} + +/** + * Retrieves the first file path in the list. + * Imlpements the firstItem() virtual method of the FileListSource base + * class. + * @param sFilePath Contains the file path, upon successful return + * @return bool true if successful, false if the list is empty + */ +bool ProjectFilesDlg::firstItem(QString& sFilePath) +{ + m_pItrItem = m_pFileList->firstChild(); + return nextItem(sFilePath); +} + +/** + * Retrieves the next file path in the list. + * Imlpements the nextItem() virtual method of the FileListSource base + * class. The function requires that firstItem() will be called to begin an + * iteration through the file paths. + * @param sFilePath Contains the file path, upon successful return + * @return bool true if successful, false if no more items are + * available + */ +bool ProjectFilesDlg::nextItem(QString& sFilePath) +{ + if (m_pItrItem == NULL) + return false; + + sFilePath = m_pItrItem->text(0); + m_pItrItem = m_pItrItem->nextSibling(); + return true; +} + +/** + * Notifies the user on the progress of a directory scan (when adding a new + * directory), and, if finished, allows the user to add these files to the + * project. + * @param pEvent The event object + */ +void ProjectFilesDlg::customEvent(QCustomEvent* pEvent) +{ + DirScanEvent* pDSE; + QString sMsg; + + // Process only directory scan progress events + if (((uint)pEvent->type()) != DirScanEvent::EventId) + return; + + pDSE = (DirScanEvent*)pEvent; + + // Check if the scan has terminated + if (!pDSE->m_bFinished) { + // Create the scan progress dialog, if required + if (m_pScanDlg == NULL) { + m_pScanDlg = new ScanProgressDlg(this); + connect(m_pScanDlg, SIGNAL(cancelled()), this, + SLOT(slotCancelDirScan())); + } + + // Set progress indication + m_pScanDlg->addFiles(pDSE->m_nFiles); + return; + } + + // Destroy the scan progress dialog + delete m_pScanDlg; + m_pScanDlg = NULL; + + // Verify the thread has terminated + m_pScanner->wait(500); + if (!m_pScanner->finished()) + m_pScanner->terminate(); + + // Do nothing if the operation was cancelled + if (m_pScanner->wasCancelled()) + return; + + // Abort if no files were found + if (pDSE->m_nFiles == 0) { + KMessageBox::sorry(0, "No files were found"); + return; + } + + // Prompt the user for the files to add + sMsg.sprintf(i18n("Would you like to add %d files to your project?"), + pDSE->m_nFiles); + if (KMessageBox::questionYesNo(0, sMsg) == KMessageBox::No) + return; + + // Add the files to the list + const QStringList& slFiles = m_pScanner->getFiles(); + QStringList::const_iterator itr; + + for (itr = slFiles.begin(); itr != slFiles.end(); ++itr) + addItem(*itr); +} + +/** + * Removes a single item from the file list. + */ +void ProjectFilesDlg::removeItem(QListViewItem* pItem) +{ + m_dicFiles.remove(pItem->text(0)); + delete pItem; +} + +/** + * Adds a list of files to the project. + * Prompts the user for source files, and adds the selected files to the + * current project. + */ +void ProjectFilesDlg::slotAddFiles() +{ + QStringList slFiles; + QStringList::const_iterator itr; + + // Prompt the user + slFiles = KFileDialog::getOpenFileNames(m_pProj->getSourceRoot(), + m_pProj->getFileTypes()); + + // Add the selected files, skipping existing entries + for (itr = slFiles.begin(); itr != slFiles.end(); ++itr) { + if (m_dicFiles.find(*itr) == NULL) + addItem(*itr); + } +} + +/** + * Adds all source files in a given directory to the project. + * Prompts the user for a directory, and adds all files matching the + * project's pattern to the current project. + * Note that only source files in the selected directory are added, i.e., the + * search does not descend to sub-directories. + */ +void ProjectFilesDlg::slotAddDir() +{ + QString sDir; + QStringList slFiles; + QStringList::const_iterator itr; + + // Prompt the user for a directory + sDir = KFileDialog::getExistingDirectory(m_pProj->getSourceRoot()); + if (sDir.isEmpty()) + return; + + // Search for source files in this directory + m_pScanner->start(sDir, m_pProj->getFileTypes(), false); +} + +/** + * Adds all source files in a given file system tree to the project. + * Prompts the user for a directory, and adds all files matching the + * project's pattern to the current project. + * Note that source files are searched for in the given directory, as well as + * in any of its sub-directories. + */ +void ProjectFilesDlg::slotAddTree() +{ + QString sDir; + QStringList slFiles; + QStringList::const_iterator itr; + + // Prompt the user for a directory + sDir = KFileDialog::getExistingDirectory(m_pProj->getSourceRoot()); + if (sDir.isEmpty()) + return; + + // Search for source files in this directory + m_pScanner->start(sDir, m_pProj->getFileTypes(), true); +} + +/** + * Removes the selected files from the project. + */ +void ProjectFilesDlg::slotRemSel() +{ + QListViewItem* pItem, * pPrevItem; + + // Prompt the user before removing the files + if (KMessageBox::questionYesNo(0, i18n("Are you sure you want to remove " + "the selected files from the project?")) == KMessageBox::No) { + return; + } + + // Remove the selected files + pItem = m_pFileList->firstChild(); + while (pItem != NULL) { + pPrevItem = pItem; + pItem = pItem->nextSibling(); + + if (pPrevItem->isSelected()) + removeItem(pPrevItem); + } +} + +/** + * Removes all source files in a directory from the project. + */ +void ProjectFilesDlg::slotRemDir() +{ + QString sDir, sFilePath; + QListViewItem* pItem, * pPrevItem; + + // Prompt the user for a directory + sDir = KFileDialog::getExistingDirectory(m_pProj->getSourceRoot()); + if (sDir.isEmpty()) + return; + + // Confirm the directory removal + if (KMessageBox::questionYesNo(0, i18n("Are you sure you want to remove " + "the selected directory from the project?")) == KMessageBox::No) { + return; + } + + // Remove the files under the selected directory + pItem = m_pFileList->firstChild(); + while (pItem != NULL) { + pPrevItem = pItem; + pItem = pItem->nextSibling(); + + // Check if the file is under the selected directory + sFilePath = pPrevItem->text(0); + if (sFilePath.left(sFilePath.findRev('/') + 1) == sDir) + removeItem(pPrevItem); + } +} + +/** + * Removes all source files in a directory or any of its sub-directories from + * the project. + */ +void ProjectFilesDlg::slotRemTree() +{ + QString sDir, sFilePath; + QListViewItem* pItem, * pPrevItem; + + // Prompt the user for a directory + sDir = KFileDialog::getExistingDirectory(m_pProj->getSourceRoot()); + if (sDir.isEmpty()) + return; + + // Confirm the directory removal + if (KMessageBox::questionYesNo(0, i18n("Are you sure you want to remove " + "all files in the selected tree from the project?")) == + KMessageBox::No) { + return; + } + + // Remove the files under the selected directory + pItem = m_pFileList->firstChild(); + while (pItem != NULL) { + pPrevItem = pItem; + pItem = pItem->nextSibling(); + + // Check if the file is under the selected directory + sFilePath = pPrevItem->text(0); + if (sFilePath.startsWith(sDir)) + removeItem(pPrevItem); + } +} + +/** + * Filter files according to a pattern. + * Hides all entries in the file list, except for those that match a given + * pattern. + */ +void ProjectFilesDlg::slotFilter() +{ + QString sFilter; + QListViewItem* pItem; + + // Get the user's filter string + sFilter = m_pFilterEdit->text().stripWhiteSpace(); + if (sFilter.isEmpty()) + return; + + // Create the regular expression + QRegExp reFilter(sFilter); + reFilter.setWildcard(true); + + // Iterate over the list entries, and hide all items not matching the + // filter string + pItem = m_pFileList->firstChild(); + while (pItem != NULL) { + if (reFilter.search(pItem->text(0)) == -1) { + pItem->setVisible(false); + pItem->setSelectable(false); + } + + pItem = pItem->nextSibling(); + } +} + +/** + * Shows all entries in the file list, after a filter has been applied. + */ +void ProjectFilesDlg::slotShowAll() +{ + QListViewItem* pItem; + + // Iterate over the list entries, and make all items visible + pItem = m_pFileList->firstChild(); + while (pItem != NULL) { + pItem->setVisible(true); + pItem->setSelectable(true); + pItem = pItem->nextSibling(); + } +} + +/** + * Stops a directory scan process. + * This slot is called when the user clicks on the "Cancel" button in the + * scan progress dialog. + */ +void ProjectFilesDlg::slotCancelDirScan() +{ + m_pScanner->cancel(); +} + +#include "projectfilesdlg.moc" diff --git a/src/projectfilesdlg.h b/src/projectfilesdlg.h new file mode 100644 index 0000000..9c6d791 --- /dev/null +++ b/src/projectfilesdlg.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PROJECTFILESDLG_H +#define PROJECTFILESDLG_H + +#include +#include +#include +#include "project.h" + +class DirScanner; +class ScanProgressDlg; + +/** + * A dialog to manipulate the project's files. + * The dialog allows the user to add source files to the current project, or + * remove files from it. The main widget of the dialog is a list view, that + * displays all files currently in the project. When files are added or + * removed, this list view is updated. The project, however, is only modified + * if the user closes the dialog using the "OK" button. + * Since searches through a list view are very slow, the class also maintains + * a QDict object, that connects file names with their respective list items. + * This dictionary is used to ensure duplicated items are not added to the + * list. + * @author Elad Lahav + */ + +class ProjectFilesDlg : public ProjectFilesLayout, public FileListTarget, + public FileListSource +{ + Q_OBJECT + +public: + ProjectFilesDlg(Project*, QWidget* pParent = 0, const char* szName = 0); + ~ProjectFilesDlg(); + + virtual void addItem(const QString&); + virtual bool firstItem(QString&); + virtual bool nextItem(QString&); + +protected: + virtual void customEvent(QCustomEvent*); + +private: + /** The project to manipulate. */ + Project* m_pProj; + + /** Holds all file paths in a quickly searchable format (for duplicate + entries lookup). */ + QDict m_dicFiles; + + /** A thread object to a-synchronously scan directories for source files + to add to the project. */ + DirScanner* m_pScanner; + + /** Displays the progress of a directory scan operation. */ + ScanProgressDlg* m_pScanDlg; + + /** A file list item that serves as an iterator. */ + QListViewItem* m_pItrItem; + + /** The last item added. */ + QListViewItem* m_pLastItem; + + void removeItem(QListViewItem*); + +private slots: + void slotAddFiles(); + void slotAddDir(); + void slotAddTree(); + void slotRemSel(); + void slotRemDir(); + void slotRemTree(); + void slotFilter(); + void slotShowAll(); + void slotCancelDirScan(); +}; + +#endif diff --git a/src/projectfileslayout.ui b/src/projectfileslayout.ui new file mode 100644 index 0000000..a78af7e --- /dev/null +++ b/src/projectfileslayout.ui @@ -0,0 +1,201 @@ + +ProjectFilesLayout + + + ProjectFilesLayout + + + + 0 + 0 + 585 + 480 + + + + Project Files + + + + unnamed + + + + layout5 + + + + unnamed + + + + layout4 + + + + unnamed + + + + m_pFilterEdit + + + + + m_pFilterButton + + + Filter + + + + + m_pShowAllButton + + + Show All + + + + + + + m_pFileList + + + + + + + layout5 + + + + unnamed + + + + groupBox1 + + + Add + + + + unnamed + + + + m_pAddFilesButton + + + Files... + + + + + m_pAddDirButton + + + Directory... + + + + + m_pAddTreeButton + + + Tree... + + + + + + + groupBox2 + + + Remove + + + + unnamed + + + + m_pRemSelButton + + + Selected + + + + + m_pRemDirButton + + + Directory... + + + + + m_pRemTreeButton + + + Tree... + + + + + + + spacer3 + + + Vertical + + + Expanding + + + + 21 + 118 + + + + + + groupBox3 + + + + + + + unnamed + + + + m_pOKButton + + + OK + + + + + m_pCancelButton + + + Cancel + + + + + + + + + + diff --git a/src/projectmanager.cpp b/src/projectmanager.cpp new file mode 100644 index 0000000..998b4a5 --- /dev/null +++ b/src/projectmanager.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "projectmanager.h" +#include "project.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + */ +ProjectManager::ProjectManager() : m_pCurProj(NULL) +{ +} + +/** + * Class destructor. + */ +ProjectManager::~ProjectManager() +{ + close(); +} + +/** + * Creates a project's directory, and associates this directory with the + * current object. This directory is created under the given path, and using + * the project's name (which, thus, has to be a legal file name). + * Note: this function attempts to create a new directory, so the given path + * and name must not lead to an existing one. + * @param sName The project's name + * @param sPath The parent directory under which to create the + * project's directory + * @param opt A structure containing project options + * @return true if successful, false otherwise + */ +bool ProjectManager::create(const QString& sName, const QString& sPath, + const ProjectBase::Options& opt, QString& sProjDir) +{ + QDir dir(sPath); + QString sParentPath; + QString sDirName = sName; + QString sMsg; + + // Handle requests for a hidden .cscope directory + if (dir.dirName() == ".cscope") { + sParentPath = QDir::cleanDirPath(dir.absPath()); + sParentPath = sParentPath.section('/', 0, -2); + dir.cd(sParentPath); + sDirName = ".cscope"; + } + + // The parent directory must exist + if (!dir.exists()) { + sMsg = i18n("The requested parent directory (%1) does not exist"). + arg(sParentPath); + KMessageBox::error(0, sMsg); + return false; + } + + // Make sure the directory doesn't exist + if (dir.exists(sDirName)) { + sMsg = i18n("Cannot create a project inside an existing directory " + "(%1/%2)").arg(dir.canonicalPath()).arg(sDirName); + KMessageBox::error(0, sMsg); + return false; + } + + // Try to create the projcet's directory + if (!dir.mkdir(sDirName, false) || !dir.cd(sDirName, false)) { + sMsg = i18n("Failed to create the project directory (%1/%2)"). + arg(dir.canonicalPath()).arg(sDirName); + KMessageBox::error(0, sMsg); + return false; + } + + if (!Project::create(sName, dir.absPath(), opt)) + return false; + + sProjDir = dir.path(); + return true; +} + +/** + * Opens a project and makes it the current one. + * @param sPath The directory containing the project's files + * @return true if successful, false otherwise + */ +bool ProjectManager::open(const QString& sPath) +{ + Project* pProj; + + // Close the current project + close(); + + // Try to open the new project + pProj = new Project(); + if (!pProj->open(sPath)) { + delete pProj; + return false; + } + + // Add to the list of recently opened projects + Config().addRecentProject(sPath); + + // Project opened successfully + m_pCurProj = pProj; + return true; +} + +/** + * Opens a Cscope.out file as a temporary project. + * @param sFilePath The full path of the Cscope.out file + * @return true if successful, false otherwise + */ +bool ProjectManager::openCscopeOut(const QString& sFilePath) +{ + ProjectBase* pProj; + + // Close the current project + close(); + + // Try to open the new project + pProj = new ProjectBase(); + if (!pProj->open(sFilePath)) { + delete pProj; + return false; + } + + // Add to the list of recently opened projects + Config().addRecentProject(sFilePath); + + // Project opened successfully + m_pCurProj = pProj; + return true; +} + +/** + * Performs clean-up on the project's variables, and detaches the associated + * directory. + */ +void ProjectManager::close() +{ + if (m_pCurProj) { + delete m_pCurProj; + m_pCurProj = NULL; + } +} + +QString ProjectManager::getProjName() const +{ + if (!m_pCurProj) + return i18n("No Project"); + + return m_pCurProj->getName(); +} diff --git a/src/projectmanager.h b/src/projectmanager.h new file mode 100644 index 0000000..c78a2c9 --- /dev/null +++ b/src/projectmanager.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef PROJECTMANAGER_H +#define PROJECTMANAGER_H + +#include "projectbase.h" + +/** + * @author Elad Lahav + */ +class ProjectManager : public QObject +{ +public: + ProjectManager(); + virtual ~ProjectManager(); + + bool create(const QString&, const QString&, const ProjectBase::Options&, + QString&); + bool open(const QString&); + bool openCscopeOut(const QString&); + void close(); + QString getProjName() const; + + ProjectBase* curProject() const { return m_pCurProj; } + +private: + /** The current project (NULL if no project is open). */ + ProjectBase* m_pCurProj; +}; + +#endif diff --git a/src/query_locked.png b/src/query_locked.png new file mode 100644 index 0000000000000000000000000000000000000000..25db6b2d09bb5bda441e56e00d683d640c12b83d GIT binary patch literal 774 zcmV+h1Nr=kP)xL}i$ zAA_BpfhVC*`%}N)djkL@Ny!U>I9)28zE7ndi_Q6t<{+JZ*AWP`CKHK)m&3z-k$60e z?(Po6V&Qgot88xO6-AL9 zy}j2xZnyJhKF|Li85vt!SomfEfU^#ul=&i&;CMV932bcaXmfK*9~4D<1wdX|vAqz* z%Co`2{y-$sK3*=Ld;uT2TECl_NeYrAYnrBlQVLmC8hdMyZeQDI1&O+d zxCfUmI8#Hj(bUjDBXRaXbQx71cD3lb7yA|b1c(4&1AsTt=oshqCfh=x(YA1yJ1Gu5s49JIv*qxt8Uf0ieuxnX3Jve~N=erUh3j)fy9HgTo z>{`}2Km?#1AH&1*=iN-R;Tx2KR;!SB9y+Ce zQVF>P*#5kZ$z596S=g;4!{P^+X z>91eE7#JBD8RpKdWdH~u76vE)@)`d9`zOW2!#O`H%FRt(T@J|q4K(;40}~UI?2Q{w zE0!(Ww@9G!2QYmA0R%Sy=m4NX#-7APA2%5pVTR3{5B$Gy;r7)ZKYspGSC>`y z@GxgjNbs`g>svbU_iqM&kcA)s5I{^I0_ZG;4b( z4FCurumPD`hZ(j%Qr^e(=%N8AC`|a-ew#}?XVBz-$M6prh%wR|85Z4hV)*)-h2hov zKmVlIU;NA0y#h7>Ab`LI@Us1hPBXY|&cMw09T=Pp!0=)G@rRk^$3GshA{C*pUjrF0 zXbC*|#lZIcFLRF7{VYEAKO8`*H2?twHsCW0?;`z7CnhG=4-EhRGGGNtO#c`d{(NF! zU}a+b|5eNL@Pza3Kw)Np00JBE^22W?W{wNM(0mTGorwV_07-oVy70z(hL_J-!3qHa z2yDQ!SHBq;UIR^k{|A($&~zb1_%EO9gv*&9BvFhBr-4S4qn7jsHLxDE|d$_)B2ie+BxH`5(i(&;P(m00IbX!2dr$1#f_wKLHJ4WQJ(?15^MC zk3T@-7svo04N~{}AJ~BZ5d91Q0R&0PAl`pQh;6^28o(O=K{Y`Q1dD?r`Y$By0|7t) zferY_2&9fK$Nu~O xKSro#1}KKI|3M67ggB1%^>^lDAiV$q1^`WSZm7K{A*KKT002ovPDHLkV1mj`tF-_C literal 0 HcmV?d00001 diff --git a/src/querypage.cpp b/src/querypage.cpp new file mode 100644 index 0000000..502747b --- /dev/null +++ b/src/querypage.cpp @@ -0,0 +1,211 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "querypage.h" +#include "queryview.h" +#include "queryviewdriver.h" + +const char* QUERY_TYPES[][2] = { + { "References to ", "REF " }, + { "Definition of ", "DEF " }, + { "Functions called by ", "<-- " }, + { "Functions calling ", "-->" }, + { "Search for ", "TXT " }, + { "", "" }, + { "EGrep Search for ", "GRP " }, + { "Files named ", "FIL " }, + { "Files #including ", "INC " }, + { "Query", "Query" } +}; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +QueryPage::QueryPage(QWidget* pParent, const char * szName) : + QueryPageBase(pParent, szName), + m_nType(CscopeFrontend::None) +{ + m_pView = new QueryView(this); + m_pDriver = new QueryViewDriver(m_pView, this); + + connect(m_pView, SIGNAL(lineRequested(const QString&, uint)), this, + SIGNAL(lineRequested(const QString&, uint))); + + // Set colours and font + applyPrefs(); +} + +/** + * Class destructor. + */ +QueryPage::~QueryPage() +{ +} + +/** + * Runs a query, using the current page to display the results. + * @param nType The type of the query + * @param sText The text of the query + * @param bCase true for case-sensitive queries, false otherwise + */ +void QueryPage::query(uint nType, const QString& sText, bool bCase) +{ + m_nType = nType; + m_sText = sText; + m_bCase = bCase; + m_sName = getCaption(); + + m_pDriver->query(nType, sText, bCase); +} + +/** + * Re-runs the last query. + */ +void QueryPage::refresh() +{ + m_pView->clear(); + if (!m_sText.isEmpty()) + m_pDriver->query(m_nType, m_sText, m_bCase); +} + +/** + * Resets the query page by deleting all records. + */ +void QueryPage::clear() +{ + m_pView->clear(); + m_nType = CscopeFrontend::None; + m_sText = QString(); + m_sName = QString(); +} + +/** + * @return true if a query is currently running in this page, false otherwise + */ +bool QueryPage::isRunning() +{ + return m_pDriver->isRunning(); +} + +/** + * Constructs a caption for this page, based on the query's type and text. + * @param bBrief true to use a shortened version of the caption, false + * (default) for the full version + * @return The caption for this page + */ +QString QueryPage::getCaption(bool bBrief) const +{ + return QString(QUERY_TYPES[m_nType][bBrief ? 1 : 0] + m_sText); +} + +/** + * Creates a new query result item. + * @param sFile The file name + * @param sFunc The function defining the scope of the result + * @param sLine The line number + * @param sText The contents of the line + */ +void QueryPage::addRecord(const QString& sFile, const QString& sFunc, + const QString& sLine, const QString& sText) +{ + new QListViewItem(m_pView, sFile, sFunc, sLine, sText); +} + +/** + * Creates a unique file name for saving the contents of the query page. + * @param sProjPath The full path of the project directory + * @return The unique file name to use + */ +QString QueryPage::getFileName(const QString& sProjPath) const +{ + QString sFileName, sFileNameBase; + int i = 0; + + // Do nothing if not initialised + if (m_sName.isEmpty()) + return ""; + + // Create a unique file name + sFileNameBase = m_sName; + sFileNameBase.replace(' ', '_'); + do { + sFileName = sFileNameBase + QString::number(++i); + } while (QFile(sProjPath + "/" + sFileName).exists()); + + return sFileName; +} + +/** + * Reads query parameters from a file. + * This mehtod is used as part of the loading process. + * @param str A text stream set to the correct place in the file + * @return true if successful, false otherwise + */ +bool QueryPage::readHeader(QTextStream& str) +{ + QString sTemp; + + // Read the query name + m_sName = str.readLine(); + if (m_sName == QString::null || m_sName.isEmpty()) + return false; + + // Read the query's type + sTemp = str.readLine(); + if (sTemp == QString::null || sTemp.isEmpty()) + return false; + + // Convert the type string to an integer + m_nType = sTemp.toUInt(); + if (m_nType >= CscopeFrontend::None) { + m_nType = CscopeFrontend::None; + return false; + } + + // Read the query's text + m_sText = str.readLine(); + if (m_sText == QString::null || m_sText.isEmpty()) + return false; + + return true; +} + +/** + * Writes query parameters to a file. + * This mehtod is used as part of the storing process. + * @param str A text stream set to the correct place in the file + */ +void QueryPage::writeHeader(QTextStream& str) +{ + str << m_sName << "\n" << m_nType << "\n" << m_sText << "\n"; +} + +#include "querypage.moc" diff --git a/src/querypage.h b/src/querypage.h new file mode 100644 index 0000000..59d6ea2 --- /dev/null +++ b/src/querypage.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYPAGE_H +#define QUERYPAGE_H + +#include +#include +#include +#include "querypagebase.h" +#include "cscopefrontend.h" + +class QueryViewDriver; + +/** + * A QueryWidget page that runs and displays Cscope queries. + * The page uses a QueryViewDriver object to run queries, and an embedded + * QueryView widget for displaying query results. + * @author Elad Lahav + */ +class QueryPage : public QueryPageBase +{ + Q_OBJECT + +public: + QueryPage(QWidget* pParent = 0, const char* szName = 0); + ~QueryPage(); + + void query(uint, const QString&, bool); + void refresh(); + void clear(); + bool isRunning(); + + virtual QString getCaption(bool bBrief = false) const; + +protected: + virtual void addRecord(const QString&, const QString&, const QString&, + const QString&); + virtual QString getFileName(const QString&) const; + virtual bool readHeader(QTextStream&); + virtual void writeHeader(QTextStream&); + +private: + /** The type of query whose results are listed on this page. */ + uint m_nType; + + /** The text given as a parameter to the query. */ + QString m_sText; + + /** Whether the query is case-sensitive. */ + bool m_bCase; + + /** A formatted caption for this query, including the type of query and + its text. */ + QString m_sName; + +private: + /** Runs Cscope queries whose results are displayed in this page. */ + QueryViewDriver* m_pDriver; +}; + +#endif diff --git a/src/querypagebase.cpp b/src/querypagebase.cpp new file mode 100644 index 0000000..08cbe6d --- /dev/null +++ b/src/querypagebase.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "querypagebase.h" +#include "queryview.h" +#include "kscopeconfig.h" + +#define FILE_VERSION "VERSION=2" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +QueryPageBase::QueryPageBase(QWidget* pParent, const char* szName) : + QHBox(pParent, szName), + m_bLocked(false) +{ +} + +/** + * Class destructor. + */ +QueryPageBase::~QueryPageBase() +{ +} + +/** + * Sets the list's colours and font, according the user's preferences. + */ +void QueryPageBase::applyPrefs() +{ + // Apply colour settings + m_pView->setPaletteBackgroundColor(Config().getColor( + KScopeConfig::QueryWindowBack)); + m_pView->setPaletteForegroundColor(Config().getColor( + KScopeConfig::QueryWindowFore)); + m_pView->setFont(Config().getFont(KScopeConfig::QueryWindow)); +} + +/** + * Restores a locked query from the given query file. + * NOTE: The query file is deleted when loading is complete. + * @param sProjPath The full path of the project directory + * @param sFileName The name of the query file to load + * @return true if successful, false otherwise + */ +bool QueryPageBase::load(const QString& sProjPath, const QString& sFileName) +{ + QString sTemp, sFile, sFunc, sLine, sText; + int nState; + + // Try to open the query file for reading + QFile file(sProjPath + "/" + sFileName); + if (!file.open(IO_ReadOnly)) + return false; + + { + // Use a new scope for the QTextStream object, to ensure its + // destruction before the file is deleted + QTextStream str(&file); + + // Make sure the file's version is correct + sTemp = str.readLine(); + if (sTemp != FILE_VERSION) { + file.remove(); + return false; + } + + // Try to read the file header + if (!readHeader(str)) + return false; + + // Read query records + sTemp = str.readLine(); + nState = 0; + while (sTemp != QString::null) { + switch (nState) { + // File path + case 0: + sFile = sTemp; + break; + + // Function name + case 1: + sFunc = sTemp; + break; + + // Line number + case 2: + sLine = sTemp; + break; + + // Text string + case 3: + sText = sTemp; + addRecord(sFile, sFunc, sLine, sText); + break; + } + + nState = (nState + 1) % 4; + sTemp = str.readLine(); + } + } + + // Delete the query file + file.remove(); + + return true; +} + +/** + * Writes the contents of the page to a file. + * This method is called for pages that shoukld be stored before the owner + * project is closed (@see shouldSave()). + * @param sProjPath The full path of the project directory + * @param sFileName Holds the file name to which the page was saved, upon + * return + * @return true if successful, false otherwise + */ +bool QueryPageBase::save(const QString& sProjPath, QString& sFileName) +{ + QListViewItemIterator itr(m_pView); + + // Get the file name to use + sFileName = getFileName(sProjPath); + if (sFileName.isEmpty()) + return false; + + // Open the query file for writing + QFile file(sProjPath + "/" + sFileName); + if (!file.open(IO_WriteOnly)) + return false; + + QTextStream str(&file); + + // Write the version string + str << FILE_VERSION << "\n"; + + writeHeader(str); + + // Write all records + for(; itr.current(); ++itr) { + str << itr.current()->text(0) << "\n" + << itr.current()->text(1) << "\n" + << itr.current()->text(2) << "\n" + << itr.current()->text(3) << "\n"; + } + + return true; +} + +/** + * Selects the next record in the view. + */ +void QueryPageBase::selectNext() +{ + m_pView->selectNext(); +} + +/** + * Selects the previous record in the view. + */ +void QueryPageBase::selectPrev() +{ + m_pView->selectPrev(); +} + +#include "querypagebase.moc" diff --git a/src/querypagebase.h b/src/querypagebase.h new file mode 100644 index 0000000..8603874 --- /dev/null +++ b/src/querypagebase.h @@ -0,0 +1,148 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYPAGEBASE_H +#define QUERYPAGEBASE_H + +#include + +class QueryView; + +/** + * Defines a page in a QueryWidget's tab widget. + * This is a abstract base class for QueryPage and HistoryPage. It defines + * the common behaviour for all pages, which includes appearance, display + * of tab text, page locking, storage and retrieval of information to + * and from files and basic navigation. + * Each page embeds a list widget derived from QueryView. The actual type + * of widget is defined by the different page classes. + * @author Elad Lahav + */ +class QueryPageBase : public QHBox +{ +Q_OBJECT +public: + QueryPageBase(QWidget* pParent = 0, const char* szName = 0); + ~QueryPageBase(); + + void applyPrefs(); + bool load(const QString&, const QString&); + bool save(const QString&, QString&); + void selectNext(); + void selectPrev(); + + + /** + * Determines whether this page can be locked. + * Can be used by inheriting classes to define non-lockable pages. + * @return Always true + */ + virtual bool canLock() { return true; } + + /** + * Locks or unlocks this page. + * @param bLocked true to lock the page, false to unlock it. + */ + void setLocked(bool bLocked) { m_bLocked = bLocked; } + + /** + * Determines whether this page is locked. + * @return true if the page is locked, false otherwise + */ + bool isLocked() { return m_bLocked; } + + /** + * Determines whether this page should be saved when the project is closed. + * By default, pages are saved if and only if they are locked. + * @return true to save the page, false otherwise + */ + virtual bool shouldSave() const { return m_bLocked; }; + + /** + * Constructs a caption for this page. + * The caption appears in the page's tab button and as the page's + * tooltip. + * @param bBrief true to generate a brief caption, false otherwise + * @return The page's title + */ + virtual QString getCaption(bool bBrief = false) const = 0; + +signals: + /** + * Emitted when a record is selected in the view widget. + * @param sFile The "File" field of the selected record + * @param nLine The "Line" field of the selected record + */ + void lineRequested(const QString& sFile, uint nLine); + +protected: + /** The embedded list. */ + QueryView* m_pView; + + /** Indicates whether this page is locked. A locked page is never + overriden by new data, and is also saved to a disc file when the + session is closed. */ + bool m_bLocked; + + /** + * Creates a new list item and adds it to the embedded view. + * This method is used to add records read from a stored file. + * @param sFile The "File" field of the record + * @param sFunc The "Function" field of the record + * @param sLine The "Line" field of the record + * @param sText The "Text" field of the record + */ + virtual void addRecord(const QString& sFile, const QString& sFunc, + const QString& sLine, const QString& sText) = 0; + + /** + * Creates a file path to store this page. + * The path is composed of the project's path and a unique file name + * in that directory. + * @param sProjPath The project's directory + * @return The page's file path + */ + virtual QString getFileName(const QString& sProjPath) const = 0; + + /** + * Tries to read the file header of a stored page. + * The contents of the header differ among inheriting classes. + * @param str A text stream initialised to the open page file + * @return true if the header was read successfully and contains the + * expected information, false otherwise + */ + virtual bool readHeader(QTextStream& str) = 0; + + /** + * Writes a header to a page's file. + * The contents of the header differ among inheriting classes. + * @param str A text stream initialised to the open page file + */ + virtual void writeHeader(QTextStream& str) = 0; +}; + +#endif diff --git a/src/queryresultsmenu.cpp b/src/queryresultsmenu.cpp new file mode 100644 index 0000000..74bcdb4 --- /dev/null +++ b/src/queryresultsmenu.cpp @@ -0,0 +1,170 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "queryresultsmenu.h" + +/** + * Class constructor. + * @param pParent Parent widget + * @param szName Optional object name + */ +QueryResultsMenu::QueryResultsMenu(QWidget* pParent, const char* szName) : + QPopupMenu(pParent, szName), + m_pItem(NULL) +{ + // Create the menu + insertItem(i18n("&View Source"), this, SLOT(slotViewSource()), 0, + ViewSource); + insertItem(i18n("Find &Definition"), this, SLOT(slotFindDef()), 0, + FindDef); + insertSeparator(); + insertItem(i18n("&Copy"), this, SLOT(slotCopy()), 0, Copy); + insertSeparator(); + insertItem(i18n("&Filter..."), this, SLOT(slotFilter()), 0, Filter); + insertItem(i18n("&Show All"), this, SIGNAL(showAll()), 0, ShowAll); + insertSeparator(); + insertItem(i18n("&Remove Item"), this, SLOT(slotRemove()), 0, Remove); +} + +/** + * Class destructor. + */ +QueryResultsMenu::~QueryResultsMenu() +{ +} + +/** + * Displays the popup-menu at the requested coordinates. + * @param pItem The item on which the menu was requested + * @param ptPos The requested position for the menu + * @param nCol The column over which the menu was requested, -1 if no + * column is associated with the request + */ +void QueryResultsMenu::slotShow(QListViewItem* pItem, const QPoint& ptPos, + int nCol) +{ + // Save the requested item and column number to use in signals + m_pItem = pItem; + m_nCol = nCol; + + if (m_pItem == NULL) { + // No item selected, disable everything but the "Filter" and "Show All" + // items + setItemEnabled(ViewSource, false); + setItemEnabled(FindDef, false); + setItemEnabled(Copy, false); + setItemEnabled(Remove, false); + } + else { + // Item selected, enable record-specific actions + setItemEnabled(ViewSource, true); + setItemEnabled(Copy, true); + setItemEnabled(Remove, true); + + // The "Find Definition" item should only be enabled if the mouse + // was clicked over a valid function name + setItemEnabled(FindDef, (m_nCol == 0) && + (m_pItem->text(0) != "")); + + // Set menu contents according to the column number + switch (m_nCol) { + case 0: + changeItem(Copy, "&Copy Function"); + break; + + case 1: + changeItem(Copy, "&Copy File"); + break; + + case 2: + changeItem(Copy, "&Copy Line Number"); + break; + + case 3: + changeItem(Copy, "&Copy Text"); + break; + + default: + m_nCol = 0; + } + } + + // Show the menu + popup(ptPos); +} + +/** + * Emits the viewSource() signal. + * This slot is activated when the "View Source" item is selected. + */ +void QueryResultsMenu::slotViewSource() +{ + if (m_pItem != NULL) + emit viewSource(m_pItem); +} + +/** + * Emits the findDef() signal. + * This slot is activated when the "Find Definition" item is selected. + */ +void QueryResultsMenu::slotFindDef() +{ + if (m_pItem != NULL) + emit findDef(m_pItem->text(0)); +} + +/** + * Emits the copy() signal. + * This slot is activated when the "Copy [Column]" item is selected. + */ +void QueryResultsMenu::slotCopy() +{ + if (m_pItem != NULL) + emit copy(m_pItem, m_nCol); +} + +/** + * Emits the filter() signal. + * This slot is activated when the "Filter..." item is selected. + */ +void QueryResultsMenu::slotFilter() +{ + emit filter(m_nCol); +} + +/** + * Emits the remove() signal. + * This slot is activated when the "Remove" item is selected. + */ +void QueryResultsMenu::slotRemove() +{ + if (m_pItem != NULL) + emit remove(m_pItem); +} + +#include "queryresultsmenu.moc" diff --git a/src/queryresultsmenu.h b/src/queryresultsmenu.h new file mode 100644 index 0000000..099dd2e --- /dev/null +++ b/src/queryresultsmenu.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYRESULTSMENU_H +#define QUERYRESULTSMENU_H + +#include +#include +#include + +/** + * Provides a popup-menu for list views containing query results. + * The popup menu contains commands for copying field text out of items and + * for removing items. + * This class assumes a certain ordering of the list columns. If an owner + * object uses a different configuration, it needs to call setColumns() after + * constructing the object. + * @author Elad Lahav + */ +class QueryResultsMenu : public QPopupMenu +{ + Q_OBJECT + +public: + QueryResultsMenu(QWidget* pParent = 0, const char* szName = 0); + ~QueryResultsMenu(); + +public slots: + void slotShow(QListViewItem*, const QPoint&, int nCol); + +signals: + /** + * Indicates that the "View Source" menu item was selected. + * @param pItem The item for which the menu was displayed + */ + void viewSource(QListViewItem* pItem); + + /** + * Indicates that the "Find Definition" menu item was selected. + * @param sFunc The function to look for + */ + void findDef(const QString& sFunc); + + /** + * Indicates that the "Copy [Column]" menu item was selected. + * @param pItem The item for which the menu was displayed + * @param nCol The requested column + */ + void copy(QListViewItem* pItem, int nCol); + + /** + * Indicates that the "Filter..." menu item was selected. + * @param nCol The column in which to search + */ + void filter(int nCol); + + /** + * Indicates that the "Show All" menu item was selected. + */ + void showAll(); + + /** + * Indicates that the "Remove Item" menu item was selected. + * @param pItem The item for which the menu was displayed + */ + void remove(QListViewItem* pItem); + +private: + /** Menu item IDs. */ + enum { ViewSource, FindDef, Copy, Filter, ShowAll, Remove }; + + /** The item for which the popup menu is provided (cannot be NULL). */ + QListViewItem* m_pItem; + + /** The list column for which the query was invoked. */ + int m_nCol; + +private slots: + void slotViewSource(); + void slotFindDef(); + void slotCopy(); + void slotFilter(); + void slotRemove(); +}; + +#endif diff --git a/src/queryview.cpp b/src/queryview.cpp new file mode 100644 index 0000000..c56a2b0 --- /dev/null +++ b/src/queryview.cpp @@ -0,0 +1,444 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include "queryview.h" +#include "queryresultsmenu.h" +#include "queryviewdlg.h" +#include "cscopefrontend.h" +#include "searchresultsdlg.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The name of the widget + */ +QueryView::QueryView(QWidget* pParent, const char* szName) : + QListView(pParent, szName), + m_pLastItem(NULL) +{ + // Create the popup-menu + m_pQueryMenu = new QueryResultsMenu(this); + + // Initialise the list's columns + setAllColumnsShowFocus(true); + addColumn(i18n("Function")); + addColumn(i18n("File")); + addColumn(i18n("Line")); + addColumn(i18n("Text")); + setColumnAlignment(2, Qt::AlignRight); + + setShowSortIndicator(true); + + // A record is selected if it is either double-clicked, or the ENTER + // key is pressed while the record is highlighted + connect(this, SIGNAL(doubleClicked(QListViewItem*)), this, + SLOT(slotRecordSelected(QListViewItem*))); + connect(this, SIGNAL(returnPressed(QListViewItem*)), this, + SLOT(slotRecordSelected(QListViewItem*))); + + // Show the popup-menu when requested + connect(this, + SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)), + m_pQueryMenu, SLOT(slotShow(QListViewItem*, const QPoint&, int))); + + // Handle popup-menu commands + connect(m_pQueryMenu, SIGNAL(viewSource(QListViewItem*)), this, + SLOT(slotRecordSelected(QListViewItem*))); + connect(m_pQueryMenu, SIGNAL(findDef(const QString&)), this, + SLOT(slotFindDef(const QString&))); + connect(m_pQueryMenu, SIGNAL(copy(QListViewItem*, int)), this, + SLOT(slotCopy(QListViewItem*, int))); + connect(m_pQueryMenu, SIGNAL(filter(int)), this, SLOT(slotFilter(int))); + connect(m_pQueryMenu, SIGNAL(showAll()), this, + SLOT(slotShowAll())); + connect(m_pQueryMenu, SIGNAL(remove(QListViewItem*)), this, + SLOT(slotRemoveItem(QListViewItem*))); +} + +/** + * Class destructor. + */ +QueryView::~QueryView() +{ +} + +/** + * Creates a new list item showing a query result record. + * @param sFunc The name of the function + * @param sFile The file path + * @param sLine The line number in the above file + * @param sText The line's text + * @param pParent The parent item (ignored) + */ +void QueryView::addRecord(const QString& sFunc, const QString& sFile, + const QString& sLine, const QString& sText, QListViewItem* /* pParent */) +{ + QListViewItem* pItem; + + pItem = new QueryViewItem(this, m_pLastItem, 2); + pItem->setText(0, sFunc); + pItem->setText(1, sFile); + pItem->setText(2, sLine); + pItem->setText(3, sText); + + m_pLastItem = pItem; +} + +/** + * Selects an item. + * When an item is selected, it is highlighted and made visible. By + * definition, the lineRequested() signal is also emitted. + * This method is used for selecting records programmatically (@see + * selectNext() for example). It has nothing to do with user selection. + * @param pItem The list item to select + */ +void QueryView::select(QListViewItem* pItem) +{ + ensureItemVisible(pItem); + setSelected(pItem, true); + slotRecordSelected(pItem); +} + +/** + * Selects the next record in the list (if one exists). + * The function selects the next item as follows: + * - The first item in the list, if there is no current item + * - The current item, if it is not selected + * - The item immediately below the current item, otherwise + */ +void QueryView::selectNext() +{ + QListViewItem* pItem; + + // Do nothing if the list is empty + if (firstChild() == NULL) + return; + + // Find the next record + pItem = currentItem(); + if (pItem == NULL) { + pItem = firstChild(); + } + else if (pItem->isSelected()) { + pItem = pItem->itemBelow(); + if (pItem == NULL) + return; + } + + // Select the new item + select(pItem); +} + +/** + * Selects the previous record in the list (if one exists). + * The function selects the previous item as follows: + * - The first item in the list, if there is no current item + * - The current item, if it is not selected + * - The item immediately above the current item, otherwise + */ +void QueryView::selectPrev() +{ + QListViewItem* pItem; + + // Do nothing if the list is empty + if (firstChild() == NULL) + return; + + // Find the item immediately above this one + pItem = currentItem(); + if (pItem == NULL) { + pItem = firstChild(); + } + else if (pItem->isSelected()) { + pItem = pItem->itemAbove(); + if (pItem == NULL) + return; + } + + // Select the new item + select(pItem); +} + +/** + * Informs the view that query progress information has been received. + * The view emits the needToShow() signal telling its parent that the widget + * should become visible (if not already so). + */ +void QueryView::queryProgress() +{ + if (!isVisible()) + emit needToShow(); +} + +/** + * Called when a query using this view terminates. + * @param nRecords Number of records generated by the query + */ +void QueryView::queryFinished(uint nRecords, QListViewItem*) +{ + // Auto-select a single record (no need to emit the show() signal in + // that case) + if (nRecords == 1) { + emit select(firstChild()); + return; + } + + // Report a query that has returned an empty record set + if (nRecords == 0) + addRecord(i18n("No results"), "", "", "", NULL); + + // Data is available, instruct the owner object to show the view + emit needToShow(); +} + +/** + * Creates an iterator and initialises it to point to the first _visible_ + * item in the list. + * @return A new iterator initialised to the beginning of the list + */ +QueryView::Iterator QueryView::getIterator() +{ + QListViewItem* pItem; + + for (pItem = firstChild(); pItem != NULL && !pItem->isVisible(); + pItem = pItem->nextSibling()); + + return Iterator(pItem); +} + +/** + * Handles double-click events over the view. + * NOTE: We override this method since the QListView implementation opens + * expandable items. This is undesired for tree-like query views (such as the + * call tree. + * @param pEvent Event description object + */ +void QueryView::contentsMouseDoubleClickEvent(QMouseEvent* pEvent) +{ + QListViewItem* pItem; + + // Handle only left button double-clicks + if (pEvent == NULL || pEvent->button() != LeftButton) + return; + + // Find the clicked item + pItem = itemAt(contentsToViewport(pEvent->pos())); + if (pItem == NULL) + return; + + // Emit the doubleClicked() signal + emit doubleClicked(pItem); +} + +/** + * Emits the lineRequested() signal when a list item is selected. + * This slot is connected to the doubleClicked() and returnPressed() + * signals of the list view. + * @param pItem The selected item + */ +void QueryView::slotRecordSelected(QListViewItem* pItem) +{ + QString sFileName, sLine; + + // Get the file name and line number + sFileName = pItem->text(1); + sLine = pItem->text(2); + + // Do not process the "No results" item + if (!sLine.isEmpty()) + emit lineRequested(sFileName, sLine.toUInt()); +} + +/** + * Looks up the definition of a given function. + * Results are displayed in a popup window. + * This slot is connected to the findDef() signal emitted by the results menu. + * @param sFunc The function to look for + */ +void QueryView::slotFindDef(const QString& sFunc) +{ + QueryViewDlg* pDlg; + + // Create a query view dialogue + pDlg = new QueryViewDlg(QueryViewDlg::DestroyOnSelect, this); + + // Display a line when it is selected in the dialogue + connect(pDlg, SIGNAL(lineRequested(const QString&, uint)), this, + SIGNAL(lineRequested(const QString&, uint))); + + // Start the query + pDlg->query(CscopeFrontend::Definition, sFunc); +} + +/** + * Copies the text of the requested field (item+column) to the clipboard. + * This slot is connected to the copy() signal of the QueryResultsMenu object. + * @param pItem The item from which to copy + * @param nCol The index of the item field to copy + */ +void QueryView::slotCopy(QListViewItem* pItem, int nCol) +{ + QApplication::clipboard()->setText(pItem->text(nCol), + QClipboard::Clipboard); +} + +/** + * Hides all items in the page that do not meet the given search criteria. + * This slot is connected to the search() signal of the QueryResultsMenu + * object. + * The search is incremental: only visible items are checked, so that a new + * search goes over the results of the previous one. + * @param nCol The list column to search in + */ +void QueryView::slotFilter(int nCol) +{ + SearchResultsDlg dlg(this); + QRegExp re; + QListViewItem* pItem; + bool bNegate; + + // Prepare the dialogue + dlg.setColumn(nCol); + + // Show the dialogue + if (dlg.exec() != QDialog::Accepted) + return; + + // Get the selected regular expression + dlg.getPattern(re); + bNegate = dlg.isNegated(); + + // Disable visual updates while search is in progress + setUpdatesEnabled(false); + + // Iterate over all items in the list + pItem = firstChild(); + while (pItem != NULL) { + // Filter visible items only + if (pItem->isVisible() && + (re.search(pItem->text(nCol)) == -1) != bNegate) { + pItem->setVisible(false); + } + + pItem = pItem->nextSibling(); + } + + // Redraw the list + setUpdatesEnabled(true); + triggerUpdate(); +} + +/** + * Makes all list items visible. + * This slot is connected to the showAll() signal of the QueryResultsMenu + * object. + */ +void QueryView::slotShowAll() +{ + QListViewItem* pItem; + + // Iterate over all items in the list + pItem = firstChild(); + while (pItem != NULL) { + pItem->setVisible(true); + pItem = pItem->nextSibling(); + } +} + +/** + * Deletes the item on which a popup-menu has been invoked. + * This slot is connected to the remove() signal of the QueryResultsMenu + * object. + * @param pItem The item to remove + */ +void QueryView::slotRemoveItem(QListViewItem* pItem) +{ + delete pItem; +} + +/** + * Moves the iterator to the next _visible_ item in the list. + */ +void QueryView::Iterator::next() +{ + if (m_pItem == NULL) + return; + + do { + m_pItem = m_pItem->nextSibling(); + } while (m_pItem != NULL && !m_pItem->isVisible()); +} + +/** + * @return The function associated with the list item the iterator points to + */ +QString QueryView::Iterator::getFunc() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(0); +} + +/** + * @return The file associated with the list item the iterator points to + */ +QString QueryView::Iterator::getFile() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(1); +} + +/** + * @return The line number associated with the list item the iterator points + * to + */ +QString QueryView::Iterator::getLine() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(2); +} + +/** + * @return The text associated with the list item the iterator points to + */ +QString QueryView::Iterator::getText() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(3); +} + +#include "queryview.moc" diff --git a/src/queryview.h b/src/queryview.h new file mode 100644 index 0000000..c896d6b --- /dev/null +++ b/src/queryview.h @@ -0,0 +1,217 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYVIEW_H +#define QUERYVIEW_H + +#include +#include + +class QueryResultsMenu; + +/** + * Items in a query view. + * The sole purpose for creating a new class is to be able to sort query + * results numerically by line number. + * @author Elad Lahav + */ +class QueryViewItem : public QListViewItem +{ +public: + /** + * Class constructor. + * Used for list views. + * @param pView The view widget + * @param pAfter The item to preceed the new one + * @param nLineCol The index of the line column + */ + QueryViewItem(QListView* pView, QListViewItem* pAfter, + int nLineCol) : QListViewItem(pView, pAfter), m_nLineCol(nLineCol) + {} + + /** + * Class constructor. + * Used for tree views. + * @param pParent The parent item + * @param pAfter The item to preceed the new one + * @param nLineCol The index of the line column + */ + QueryViewItem(QListViewItem* pParent, QListViewItem* pAfter, + int nLineCol) : QListViewItem(pParent, pAfter), m_nLineCol(nLineCol) + {} + + /** + * Compares two items. + * If the given column holds line numbers, than the items are compared + * by their numeric values. Otherwise, a standard text comparison is + * performed. + * @param pItem The item to compare to + * @param nCol The column by which to compare + * @param bAscend Whether sorting in ascending or descending order + * @return 0 if the items are equal, 1 if the current item is greater, + * -1 if the current item is smaller + */ + virtual int compare(QListViewItem* pItem, int nCol, bool bAscend) const { + if (nCol == m_nLineCol) { + uint nLineCur, nLineOther; + int nResult; + + // Get the line numbers of each item + nLineCur = text(nCol).toUInt(); + nLineOther = pItem->text(nCol).toUInt(); + + // Compare the line numbers + nResult = nLineCur - nLineOther; + if (nResult == 0) + return 0; // Items are equal + else if (nResult > 0) + return 1; // The first item is greater + else + return -1; // The second item is greater + } + + return QListViewItem::compare(pItem, nCol, bAscend); + } + +private: + /** The index of the column holding the line numbers. */ + int m_nLineCol; +}; + +/** + * A list view widget for displaying locations in the source code. Each record + * (list item) represents a single line of code. + * The main purpose of this class is for showing query results (@see + * QueryViewDriver), but is can also serve as a base class for any widget + * which needs to refer to locations in the source code (@see + * HistoryView). + * The view has 4 columns, for showing the file path, function name, line + * number and line text of a code location. + * The widget owns a popup menu which allows users to copy information + * from records, filter records, and more. + * @author Elad Lahav + */ +class QueryView : public QListView +{ + Q_OBJECT + +public: + QueryView(QWidget* pParent = 0, const char* szName = 0); + ~QueryView(); + + virtual void addRecord(const QString&, const QString&, const QString&, + const QString&, QListViewItem* pParent = NULL); + virtual void select(QListViewItem*); + virtual void selectNext(); + virtual void selectPrev(); + virtual void queryProgress(); + virtual void queryFinished(uint, QListViewItem* pParent = NULL); + + /** + * Provides an iterator over the list of query results. + * @author Elad Lahav + */ + class Iterator + { + public: + /** + * Default constructor. + */ + Iterator() : m_pItem(NULL) {} + + /** + * Copy constructor. + * @param itr The copied object + */ + Iterator(const Iterator& itr) : m_pItem(itr.m_pItem) {} + + /** + * @return true if the iterator points _beyond_ the end of the list, + * false otherwise + */ + bool isEOF() { return m_pItem == NULL; } + + void next(); + + QString getFunc(); + QString getFile(); + QString getLine(); + QString getText(); + + private: + /** Points to the current list item. */ + QListViewItem* m_pItem; + + /** + * Private constructor used to return initialised iterators. + * This constructor can only be called from within QueryView. + * @param pItem The initial list item + */ + Iterator(QListViewItem* pItem) : m_pItem(pItem) {} + + friend class QueryView; + }; + + Iterator getIterator(); + +signals: + /** + * Notifies the owner widget that it needs to be visible since some + * information is available to display. + * This information may be an advancement of the progress bar, + * availability of query results, etc. + */ + void needToShow(); + + /** + * Emitted when a list record is selected. + * Selection is done by either double-clicking a query or by highlighting + * it and then pressing the ENTER key. + * @param sFile The "File" field of the selected record + * @param nLine The "Line" field of the selected record + */ + void lineRequested(const QString& sFile, uint nLine); + +protected: + /** A popup-menu for manipulating query result items. */ + QueryResultsMenu* m_pQueryMenu; + + /** A pointer to the last item (used for appending results). */ + QListViewItem* m_pLastItem; + + void contentsMouseDoubleClickEvent(QMouseEvent*); + +protected slots: + virtual void slotRecordSelected(QListViewItem*); + virtual void slotFindDef(const QString&); + virtual void slotCopy(QListViewItem*, int); + virtual void slotFilter(int); + virtual void slotShowAll(); + virtual void slotRemoveItem(QListViewItem*); +}; + +#endif diff --git a/src/queryviewdlg.cpp b/src/queryviewdlg.cpp new file mode 100644 index 0000000..93cd85e --- /dev/null +++ b/src/queryviewdlg.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include "queryviewdlg.h" +#include "queryviewdriver.h" + +/** + * Class constructor. + * @param nFlags Controls the behaviour of the diaogue + * @param pParent The parent widget + * @param szName The widget's name + */ +QueryViewDlg::QueryViewDlg(uint nFlags, QWidget* pParent, + const char* szName) : + QueryViewLayout(pParent, szName), + m_nFlags(nFlags) +{ + // Set the destructive flag, if required + if (nFlags & DestroyOnClose) + setWFlags(getWFlags() | WDestructiveClose); + + // Create a driver for running queries + m_pDriver = new QueryViewDriver(m_pView, this); + + // Show the dialogue when instructed by the driver + connect(m_pView, SIGNAL(needToShow()), this, SLOT(slotShow())); + + // Propagate the lineRequested() signal from the QueryView object + connect(m_pView, SIGNAL(lineRequested(const QString&, uint)), this, + SLOT(slotLineRequested(const QString&, uint))); + + // Make the dialogue modal + setModal(true); +} + +/** + * Class destructor. + */ +QueryViewDlg::~QueryViewDlg() +{ +} + +/** + * Starts a query. + * @param nType The type of the query + * @param sText The query's text + * @param bCase true for case-sensitive queries, false otherwise + */ +void QueryViewDlg::query(uint nType, const QString& sText, bool bCase) +{ + m_pDriver->query(nType, sText, bCase); +} + +/** + * Make the dialogue visible when instructed by the driver. + * This slot is connected to the show() signal emitted by the QueryViewDriver + * object. + */ +void QueryViewDlg::slotShow() +{ + show(); +} + +/** + * Propagates the lineRequested() signal from the view object. + * If the CloseOnSelect flag is set, the dialogue is closed. + * This slot is connected to the lineRequested() signal emitted by the + * QueryView widget. + */ +void QueryViewDlg::slotLineRequested(const QString& sFileName, uint nLine) +{ + emit lineRequested(sFileName, nLine); + + if (m_nFlags & CloseOnSelect) + close(); +} + +/** + * @return A QueryView iterator initialised to the beginning of the result + * list + */ +QueryView::Iterator QueryViewDlg::getIterator() +{ + return m_pView->getIterator(); +} + +#include "queryviewdlg.moc" diff --git a/src/queryviewdlg.h b/src/queryviewdlg.h new file mode 100644 index 0000000..fc1c2f7 --- /dev/null +++ b/src/queryviewdlg.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYVIEWDLG_H +#define QUERYVIEWDLG_H + +#include "queryviewlayout.h" +#include "queryview.h" + +class QueryViewDriver; + +/** + * A dialogue for running and displaying queries. + * The dialogue is built around a QueryView widget, and uses a QueryViewDriver + * object to run a query. The dialogue is used in different contexts, such + * as executing quick definitions, displaying multiple call nodes in a graph, + * etc. + * The dialogue is always modal, but should not be launched using exec(). + * Instead, it is created as a modeless, hidden, dialogue. It then becomes + * modal (and visible) only if and when information is available (@see + * QueryViewDriver::show()). + * @author Elad Lahav + */ +class QueryViewDlg : public QueryViewLayout +{ + Q_OBJECT + +public: + QueryViewDlg(uint nFlags = 0, QWidget* pParent = 0, + const char* szName = 0); + ~QueryViewDlg(); + + /** These flags control the behaviour of the dialogue. */ + enum { CloseOnSelect = 0x1, DestroyOnClose = 0x2, + DestroyOnSelect = CloseOnSelect | DestroyOnClose }; + + void query(uint, const QString&, bool bCase = true); + + QueryView::Iterator getIterator(); + +signals: + /** + * Propagates the lineRequested() signal of the embedded QueryView + * widget. + * @param sFile The "File" field of the selected record + * @param nLine The "Line" field of the selected record + */ + void lineRequested(const QString& sFile, uint nLine); + +private: + /** Flags the control the behaviour of the dialogue. */ + uint m_nFlags; + + /** Used for running Cscope queries and displaying their results in the + view. */ + QueryViewDriver* m_pDriver; + +private slots: + void slotShow(); + void slotLineRequested(const QString&, uint); +}; + +#endif + diff --git a/src/queryviewdriver.cpp b/src/queryviewdriver.cpp new file mode 100644 index 0000000..f04c44d --- /dev/null +++ b/src/queryviewdriver.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "queryviewdriver.h" +#include "queryview.h" + +/** + * Class constructor. + * Creates a driver that adds new records as root items in the given view. + * @param pView The view to which this driver should add records + * @param pParent The parent object of the driver + * @param szName The name of the object + */ +QueryViewDriver::QueryViewDriver(QueryView* pView, QObject* pParent, + const char* szName) : QObject(pParent, szName), + m_pView(pView), + m_pItem(NULL), + m_progress(pView), + m_bRunning(false) +{ + m_pCscope = new CscopeFrontend(); + + // Add records to the page when Cscope outputs them + connect(m_pCscope, SIGNAL(dataReady(FrontendToken*)), this, + SLOT(slotDataReady(FrontendToken*))); + + // Report progress information + connect(m_pCscope, SIGNAL(progress(int, int)), this, + SLOT(slotProgress(int, int))); + + // Perform tasks when the query process terminates + connect(m_pCscope, SIGNAL(finished(uint)), this, + SLOT(slotFinished(uint))); + + connect(m_pView, SIGNAL(destroyed()), this, SLOT(slotViewClosed())); +} + +/** + * Class destructor. + */ +QueryViewDriver::~QueryViewDriver() +{ + delete m_pCscope; +} + +/** + * Executes a query. + * @param nType The type of the query (@see CscopeFrontend) + * @param sText The query's text + * @param bCase true for case-sensitive queries, false otherwise + * @param pItem If non-null, represents an view item passed back to + * the view in a call to addRecord() + */ +void QueryViewDriver::query(uint nType, const QString& sText, bool bCase, + QListViewItem* pItem) +{ + m_pItem = pItem; + + // Make sure sorting is disabled while entries are added + m_pView->setSorting(100); + + // Execute the query + m_pCscope->query(nType, sText, bCase); + m_bRunning = true; + m_pView->setEnabled(false); + m_pView->setUpdatesEnabled(false); +} + +/** + * Adds a query entry to the view. + * Called by a CscopeFrontend object, when a new entry was received in its + * whole from the Cscope back-end process. + * @param pToken The first token in the entry + */ +void QueryViewDriver::slotDataReady(FrontendToken* pToken) +{ + QString sFile, sFunc, sLine, sText; + + // Get the file name + sFile = pToken->getData(); + pToken = pToken->getNext(); + + // Get the function name + sFunc = pToken->getData(); + pToken = pToken->getNext(); + + // Get the line number + sLine = pToken->getData(); + if (!sLine.toInt()) { + // Line number could not be 0! + // means that function name was empty + sLine = sFunc; + sFunc = ""; + } + else { + pToken = pToken->getNext(); + } + + // Get the line's text + sText = pToken->getData(); + pToken = pToken->getNext(); + + // Add a new item at the end of the list + m_pView->addRecord(sFunc, sFile, sLine, sText, m_pItem); +} + +/** + * Handles a finished query event, reported by the Cscope frontend object. + * If no resutls are available, a proper message is displayed. If only one + * record was generated by Cscope, it is automatically selected for viewing. + * @param nRecords The number of records the query has generated + */ +void QueryViewDriver::slotFinished(uint nRecords) +{ + // The query is no longer running + m_bRunning = false; + m_pView->setEnabled(true); + m_pView->setUpdatesEnabled(true); + m_pView->triggerUpdate(); + + // Destroy the progress bar + m_progress.finished(); + + // Let owner widget decide what to do based on the number of records + m_pView->queryFinished(nRecords, m_pItem); +} + +/** + * Displays search progress information. + * This slot is connected to the progress() signal emitted by a + * CscopeFrontend object. + * @param nFiles The number of files scanned + * @param nTotal The total number of files in the project + */ +void QueryViewDriver::slotProgress(int nFiles, int nTotal) +{ + // A progress report is available, instruct the owner object to show the + // view + if (nTotal > 1) + m_pView->queryProgress(); + + // Set the progress bar + m_progress.setProgress(nFiles, nTotal); +} + +/** + * Called when the owner view is destroyed. + */ +void QueryViewDriver::slotViewClosed() +{ + m_pView = NULL; + m_pCscope->kill(); +} + +#include "queryviewdriver.moc" diff --git a/src/queryviewdriver.h b/src/queryviewdriver.h new file mode 100644 index 0000000..77ff9ed --- /dev/null +++ b/src/queryviewdriver.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYVIEWDRIVER_H +#define QUERYVIEWDRIVER_H + +#include +#include +#include "cscopefrontend.h" + +class QueryView; + +/** + * Executes a Cscope query and displays the results in a QueryView widget. + * This class is used in conjunction with QueryView to create a query + * display object. The driver uses the view widget to display result records + * of an executed query. It also uses the view as a parent widget for the + * query progress bar. + * @author Elad Lahav + */ +class QueryViewDriver : public QObject +{ + Q_OBJECT + +public: + QueryViewDriver(QueryView*, QObject* pParent = 0, const char* szName = 0); + ~QueryViewDriver(); + + void query(uint, const QString&, bool bCase, QListViewItem* pItem = NULL); + + /** + * @return true if a query is currently running, false otherwise + */ + bool isRunning() { return m_bRunning; } + +private: + /** Cscope object for running queries. */ + CscopeFrontend* m_pCscope; + + /** The view to which this object adds result records. */ + QueryView* m_pView; + + /** QueryView item passed to addRecord(). */ + QListViewItem* m_pItem; + + /** Displays query progress information. */ + CscopeProgress m_progress; + + /** This flag is set to true when a query is executed, and back to false + when the the CscopeFrontend object emits the finished() signal. */ + bool m_bRunning; + +private slots: + void slotDataReady(FrontendToken*); + void slotFinished(uint); + void slotProgress(int, int); + void slotViewClosed(); +}; + +#endif diff --git a/src/queryviewlayout.ui b/src/queryviewlayout.ui new file mode 100644 index 0000000..ae097c5 --- /dev/null +++ b/src/queryviewlayout.ui @@ -0,0 +1,167 @@ + +QueryViewLayout + + + QueryViewLayout + + + + 0 + 0 + 654 + 499 + + + + Query Results + + + true + + + + unnamed + + + + m_pView + + + + + textLabel1 + + + + 5 + 0 + 0 + 0 + + + + Right-click inside the list for more options. + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + + + QueryView +
    queryview.h
    + + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
    +
    + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082 + + + + + buttonOk + clicked() + QueryViewLayout + accept() + + + buttonCancel + clicked() + QueryViewLayout + reject() + + + + + queryview.h + +
    diff --git a/src/querywidget.cpp b/src/querywidget.cpp new file mode 100644 index 0000000..113f216 --- /dev/null +++ b/src/querywidget.cpp @@ -0,0 +1,601 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "querywidget.h" +#include "kscopepixmaps.h" +#include "kscopeconfig.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +QueryWidget::QueryWidget(QWidget* pParent, const char* szName) : + QueryWidgetLayout(pParent, szName), + m_pPageMenu(NULL), + m_pLockAction(NULL), + m_pHistPage(NULL), + m_bHistEnabled(true), + m_nQueryPages(0) +{ + // Pages can be closed by clicking their tabs + m_pQueryTabs->setHoverCloseButton(true); + + // Change the lock action state according to the current page + connect(m_pQueryTabs, SIGNAL(currentChanged(QWidget*)), this, + SLOT(slotCurrentChanged(QWidget*))); + + // Close a query when its tab button is clicked + connect(m_pQueryTabs, SIGNAL(closeRequest(QWidget*)), this, + SLOT(slotClosePage(QWidget*))); + + // Show the menu when requested + connect(m_pQueryTabs, SIGNAL(contextMenu(const QPoint&)), this, + SLOT(slotContextMenu(const QPoint&))); + connect(m_pQueryTabs, SIGNAL(contextMenu(QWidget*, const QPoint&)), this, + SLOT(slotContextMenu(QWidget*, const QPoint&))); +} + +/** + * Class destructor. + */ +QueryWidget::~QueryWidget() +{ +} + +/** + * Runs a query in a query page. + * A query page is first selected, with a new one created if required. The + * method then creates a Cscope process and runs the query. + * @param nType The query's numeric type code + * @param sText The query's text, as entered by the user + * @param bCase true for case-sensitive queries, false otherwise + */ +void QueryWidget::initQuery(uint nType, const QString& sText, bool bCase) +{ + QueryPage* pPage; + + // Make sure we have a query page + findQueryPage(); + pPage = (QueryPage*)currentPage(); + + // Use the current page, or a new page if the current one is locked + if (pPage->isLocked()) { + addQueryPage(); + pPage = (QueryPage*)currentPage(); + } + + // Reset the page's results list + pPage->clear(); + pPage->query(nType, sText, bCase); + + // Set the page's tab text according to the new query + setPageCaption(pPage); +} + +/** + * Applies the user's colour and font preferences to all pages. + */ +void QueryWidget::applyPrefs() +{ + QueryPage* pPage; + int nPages, i; + + // Iterate query pages + nPages = m_pQueryTabs->count(); + for (i = 0; i < nPages; i++) { + pPage = (QueryPage*)m_pQueryTabs->page(i); + pPage->applyPrefs(); + setPageCaption(pPage); + } +} + +/** + * Loads all pages saved when the project was closed. + * @param sProjPath The full path of the project directory + * @param slFiles The list of query file names to load + */ +void QueryWidget::loadPages(const QString& sProjPath, + const QStringList& slFiles) +{ + QStringList::ConstIterator itr; + QueryPageBase* pPage; + QString sName; + + // Iterate through query files + for (itr = slFiles.begin(); itr != slFiles.end(); ++itr) { + // Set the target page, based on the file type (query or history) + if ((*itr).startsWith("History")) { + findHistoryPage(); + pPage = m_pHistPage; + } + else { + findQueryPage(); + pPage = (QueryPage*)currentPage(); + } + + // Load a query file to this page, and lock the page + if (pPage->load(sProjPath, *itr)) { + setPageCaption(pPage); + setPageLocked(pPage, true); + } + } +} + +/** + * Stores all pages marked for saving into files in the project directory. + * @param sProjPath The full path of the project directory + * @param slFiles Holds a list of query file names, upon return + */ +void QueryWidget::savePages(const QString& sProjPath, QStringList& slFiles) +{ + int nPageCount, i; + QueryPage* pPage; + QString sFileName; + + // Iterate pages + nPageCount = m_pQueryTabs->count(); + for (i = 0; i < nPageCount; i++) { + pPage = (QueryPage*)m_pQueryTabs->page(i); + if (pPage->shouldSave()) { + // Store this query page + if (pPage->save(sProjPath, sFileName) && !sFileName.isEmpty()) + slFiles.append(sFileName); + } + } +} + +/** + * Adds a new position record to the active history page. + * @param sFile The file path + * @param nLine The line number + * @param sText The contents of the line pointed to by the file path and + * line number + */ +void QueryWidget::addHistoryRecord(const QString& sFile, uint nLine, + const QString& sText) +{ + // Validate file name and line number + if (sFile.isEmpty() || nLine == 0) + return; + + // Do nothing if history logging is disabled + if (!m_bHistEnabled) + return; + + // Make sure there is an active history page + findHistoryPage(); + + // Add the position entry to the active page + m_pHistPage->addRecord(sFile, nLine, sText); +} + +/** + * Sets the tab caption and tool-tip for the given page. + * @param pPage The page whose tab needs to be changed + */ +void QueryWidget::setPageCaption(QueryPageBase* pPage) +{ + m_pQueryTabs->changeTab(pPage, + pPage->getCaption(Config().getUseBriefQueryCaptions())); + m_pQueryTabs->setTabToolTip(pPage, pPage->getCaption()); +} + +/** + * Creates a new query page, and adds it to the tab widget. + * The new page is set as the current one. + */ +void QueryWidget::addQueryPage() +{ + QueryPage* pPage; + QString sTitle; + + // Create the page + pPage = new QueryPage(this); + + // Add the page, and set it as the current one + m_pQueryTabs->insertTab(pPage, GET_PIXMAP(TabUnlocked), "Query", + m_nQueryPages++); + setCurrentPage(pPage); + + // Emit the lineRequested() signal when a query record is selected on + // this page + connect(pPage, SIGNAL(lineRequested(const QString&, uint)), this, + SLOT(slotRequestLine(const QString&, uint))); +} + +/** + * Creates a new query page, and emits signal about it. + */ +void QueryWidget::slotNewQueryPage() +{ + addQueryPage(); + emit newQuery(); +} + +/** + * Locks or unlocks a query. + * This slot is connected to the toggled() signal of the lock query button. + * @param bOn true if the new state of the button is "on", false if it is + * "off" + */ +void QueryWidget::slotLockCurrent(bool bOn) +{ + QueryPageBase* pPage; + + pPage = currentPage(); + + if (pPage != NULL) + setPageLocked(currentPage(), bOn); +} + +/** + * Locks or unlocks a query, by toggling the current state. + */ +void QueryWidget::slotLockCurrent() +{ + QueryPageBase* pPage; + + pPage = currentPage(); + if (pPage != NULL) + setPageLocked(pPage, !pPage->isLocked()); +} + +/** + * Reruns the query whose results are displayed in the current page. + */ +void QueryWidget::slotRefreshCurrent() +{ + QueryPage* pPage; + + // Make sure the current page is a valid, non-empty one + pPage = dynamic_cast(currentPage()); + if (pPage == NULL) + return; + + // Clear the current page contents + pPage->refresh(); +} + +/** + * Selects the next query result record in the current query page. + */ +void QueryWidget::slotNextResult() +{ + QueryPage* pPage; + + // Select the next record in the current page + pPage = dynamic_cast(currentPage()); + if (pPage != NULL) + pPage->selectNext(); +} + +/** + * Selects the next query result record in the current query page. + */ +void QueryWidget::slotPrevResult() +{ + QueryPage* pPage; + + // Select the next record in the current page + pPage = dynamic_cast(currentPage()); + if (pPage != NULL) + pPage->selectPrev(); +} + +/** + * Closes the current query page. + */ +void QueryWidget::slotCloseCurrent() +{ + QWidget* pPage; + + // Close the current page + pPage = currentPage(); + if (pPage != NULL) + slotClosePage(pPage); +} + +/** + * Closes all query pages. + */ +void QueryWidget::slotCloseAll() +{ + int nPageCount, i; + QueryPage* pPage; + + // Close all pages + nPageCount = m_pQueryTabs->count(); + for (i = 0; i < nPageCount; i++) { + pPage = (QueryPage*)m_pQueryTabs->page(0); + m_pQueryTabs->removePage(pPage); + delete pPage; + } + + m_pHistPage = NULL; +} + +/** + * Handles the "Go->Back" menu command. + * Moves to the previous position in the position history. + */ +void QueryWidget::slotHistoryPrev() +{ + if (m_pHistPage != NULL) { + m_bHistEnabled = false; + m_pHistPage->selectPrev(); + m_bHistEnabled = true; + } +} + +/** + * Handles the "Go->Forward" menu command. + * Moves to the next position in the position history. + */ +void QueryWidget::slotHistoryNext() +{ + if (m_pHistPage != NULL) { + m_bHistEnabled = false; + m_pHistPage->selectNext(); + m_bHistEnabled = true; + } +} + +/** + * Sets the active history page, if any, as the current page. + */ +void QueryWidget::selectActiveHistory() +{ + if (m_pHistPage) + setCurrentPage(m_pHistPage); +} + +/** + * Attaches the page operations menu to this widget. + * The page menu is a popup menu that handles such operations as opening a + * new page, closing a page, locking a page, etc. + * @param pMenu Pointer to the popup menu + * @param pAction Pointer to the "Lock/Unlock" toggle action + */ +void QueryWidget::setPageMenu(QPopupMenu* pMenu, KToggleAction* pAction) +{ + m_pPageMenu = pMenu; + m_pLockAction = pAction; +} + +/** + * Emits a signal indicating a certain source file and line number are + * requested. + * This slot is connected to the recordSelected() signal emitted by any of + * the query pages. The signal emitted by this slot is used to display an + * editor page at the requested line. + * @param sFileName The file's path + * @param nLine The requested line in the file + */ +void QueryWidget::slotRequestLine(const QString& sFileName, uint nLine) +{ + // Disable history if the request came from the active history page + if (currentPage() == m_pHistPage) + m_bHistEnabled = false; + + // Emit the signal + emit lineRequested(sFileName, nLine); + + // Re-enable history + if (currentPage() == m_pHistPage) + m_bHistEnabled = true; +} + +/** + * Update the lock button when the current query page changes. + * @param pWidget The new current page + */ +void QueryWidget::slotCurrentChanged(QWidget* pWidget) +{ + QueryPage* pPage; + + pPage = (QueryPage*)pWidget; + m_pLockAction->setChecked(pPage->isLocked()); +} + +/** + * Removes the given page from the tab widget. + * This slot is connected to the closeRequest() signal of the KTabBar object. + * @param pPage The page to close + */ +void QueryWidget::slotClosePage(QWidget* pPage) +{ + // Prompt the user before closing a locked query + if (((QueryPage*)pPage)->isLocked()) { + if (KMessageBox::questionYesNo(NULL, i18n("You about about to close" + " a locked page.\nAre you sure?")) == KMessageBox::No) { + return; + } + } + + // Check if the closed page is the active history page + if (pPage == m_pHistPage) + m_pHistPage = NULL; + // Update the number of open history pages + else if (dynamic_cast(pPage) == NULL) + m_nQueryPages--; + + // Remove the page and delete the object + m_pQueryTabs->removePage(pPage); + delete pPage; +} + +/** + * Displays a context menu for page operations. + * This slot is connected to the contextMenu() signal, emitted by + * m_pQueryTabs. + * NOTE: We assume that the first item in the menu is "New". + * @param pt The point over which the mouse was clicked in request for the + * context menu + */ +void QueryWidget::slotContextMenu(const QPoint& pt) +{ + uint i; + + // Disable everything but the "new" action (clicked outside any widget) + for (i = 1; i < m_pPageMenu->count(); i++) + m_pPageMenu->setItemEnabled(m_pPageMenu->idAt(i), false); + + // Show the menu + m_pPageMenu->popup(pt); +} + +/** + * Displays a context menu for page operations. + * This slot is connected to the contextMenu() signal, emitted by + * m_pQueryTabs. + * @param pWidget The page under the mouse + * @param pt The point over which the mouse was clicked in request for + * the context menu + */ +void QueryWidget::slotContextMenu(QWidget* pWidget, const QPoint& pt) +{ + uint i; + + // Operations are on the current page, so we must ensure the clicked + // tab becomes the current one + setCurrentPage(pWidget); + + // Enable all operations + for (i = 1; i < m_pPageMenu->count(); i++) + m_pPageMenu->setItemEnabled(m_pPageMenu->idAt(i), true); + + // Show the menu + m_pPageMenu->popup(pt); +} + +/** + * Locks/unlocks the give page. + * @param pPage The page to lock or unlock + * @param bLock true to lock the page, false to unlock it + */ +void QueryWidget::setPageLocked(QueryPageBase* pPage, bool bLock) +{ + if (!pPage->canLock()) + return; + + // Set the locking state of the current page + pPage->setLocked(bLock); + m_pQueryTabs->setTabIconSet(pPage, bLock ? GET_PIXMAP(TabLocked) : + GET_PIXMAP(TabUnlocked)); + + // There can only be one unlocked history page. Check if a non-active + // query page is being unlocked + if (isHistoryPage(pPage) && (pPage != m_pHistPage) && !bLock) { + // Lock the active history page (may be NULL) + if (m_pHistPage != NULL) + setPageLocked(m_pHistPage, true); + + // Set the unlock page as the new active history page + m_pHistPage = (HistoryPage*)pPage; + } +} + +/** + * Ensures the current page is a query page that is ready to accept new + * queries. + * The function first checks the current page. If it is an unlocked query + * page, then nothing needs to be done. Otherwise, it checks for the first + * unlocked query page by iterating over all pages in the tab widget. If this + * fails as well, a new query page is created. + */ +void QueryWidget::findQueryPage() +{ + QueryPage* pPage; + int nPages, i; + + // First check if the current page is an unlocked query page + pPage = dynamic_cast(currentPage()); + if (pPage != NULL) { + if (!pPage->isLocked() && !pPage->isRunning()) + return; + } + + // Look for the first unlocked query page + nPages = m_pQueryTabs->count(); + for (i = 0; i < nPages; i++) { + pPage = dynamic_cast(m_pQueryTabs->page(i)); + if (pPage != NULL) { + if (!pPage->isLocked() && !pPage->isRunning()) { + setCurrentPage(pPage); + return; + } + } + } + + // Couldn't find an unlocked query page, create a new one + addQueryPage(); +} + +/** + * Ensures an active history page exists. + * The active history page is the only unlocked history page. If one does not + * exist, it is created. + */ +void QueryWidget::findHistoryPage() +{ + HistoryPage* pPage; + int nPages, i; + QString sTitle; + + // First check if the active history page is unlocked + if (m_pHistPage != NULL && !m_pHistPage->isLocked()) + return; + + // Look for the first unlocked history page + nPages = m_pQueryTabs->count(); + for (i = 0; i < nPages; i++) { + pPage = dynamic_cast(m_pQueryTabs->page(i)); + if (pPage != NULL && !pPage->isLocked()) { + m_pHistPage = pPage; + return; + } + } + + // Couldn't find an unlocked query page, create a new one + m_pHistPage = new HistoryPage(this); + + // Add the page, and set it as the current one + m_pQueryTabs->insertTab(m_pHistPage, GET_PIXMAP(TabUnlocked), ""); + setPageCaption(m_pHistPage); + + // Emit the lineRequested() signal when a query record is selected on + // this page + connect(m_pHistPage, SIGNAL(lineRequested(const QString&, uint)), this, + SLOT(slotRequestLine(const QString&, uint))); +} + +#include "querywidget.moc" diff --git a/src/querywidget.h b/src/querywidget.h new file mode 100644 index 0000000..a798ec0 --- /dev/null +++ b/src/querywidget.h @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef QUERYWIDGET_H +#define QUERYWIDGET_H + +#include +#include +#include +#include "querywidgetlayout.h" +#include "tabwidget.h" +#include "querypage.h" +#include "historypage.h" +#include "projectmanager.h" + +/** + * A tabbed-window holding Cscope query results pages. + * @author Elad Lahav + */ + +class QueryWidget : public QueryWidgetLayout +{ + Q_OBJECT + +public: + QueryWidget(QWidget* pParent = 0, const char* szName = 0); + ~QueryWidget(); + + void addQueryPage(); + void initQuery(uint, const QString&, bool); + void applyPrefs(); + void loadPages(const QString&, const QStringList&); + void savePages(const QString&, QStringList&); + void addHistoryRecord(const QString&, uint, const QString&); + void selectActiveHistory(); + void setPageMenu(QPopupMenu*, KToggleAction*); + void getBookmarks(FileLocationList&); + + /** + * Enables/disables new history items. + * @param bEnabled true to enable new history items, false to + * disable + */ + void setHistoryEnabled(bool bEnabled) { m_bHistEnabled = bEnabled; } + +public slots: + void slotNewQueryPage(); + void slotLockCurrent(bool); + void slotLockCurrent(); + void slotRefreshCurrent(); + void slotNextResult(); + void slotPrevResult(); + void slotCloseCurrent(); + void slotCloseAll(); + void slotHistoryPrev(); + void slotHistoryNext(); + +signals: + /** + * Emitted when the a lineRequested() signal is received from any of the + * currently open query pages. + * @param sPath The full path of the requested source file + * @param nLine The requested line number + */ + void lineRequested(const QString& sPath, uint nLine); + + /** + * Emitted when new query page is requested by user + */ + void newQuery(); + +private: + /** A popup menu with query page commands (new query, lock/unlock, close + query, etc.). */ + QPopupMenu* m_pPageMenu; + + /** A toggle-like action for changing the locked state of a query. */ + KToggleAction* m_pLockAction; + + /** The active history page. */ + HistoryPage* m_pHistPage; + + /** Determines whether history items should be added to the active + history page. */ + bool m_bHistEnabled; + + /** The number of query pages currently open. */ + int m_nQueryPages; + + void setPageCaption(QueryPageBase*); + + /** + * @return The active page in the tab widget + */ + inline QueryPageBase* currentPage() { + return (QueryPageBase*)m_pQueryTabs->currentPage(); + } + + /** + * @param pWidget A query page to set as the current one + */ + inline void setCurrentPage(QWidget* pWidget) { + if (pWidget) + m_pQueryTabs->setCurrentPage(m_pQueryTabs->indexOf(pWidget)); + } + + /** + * Determines if a page is a history page. + * @param pPage The page to check + * @return true if the given page is a history page + */ + inline bool isHistoryPage(QWidget* pPage) { + return (dynamic_cast(pPage) != NULL); + } + + void setPageLocked(QueryPageBase*, bool); + void findQueryPage(); + void findHistoryPage(); + +private slots: + void slotRequestLine(const QString&, uint); + void slotCurrentChanged(QWidget*); + void slotClosePage(QWidget*); + void slotContextMenu(const QPoint&); + void slotContextMenu(QWidget*, const QPoint&); +}; + +#endif diff --git a/src/querywidgetlayout.ui b/src/querywidgetlayout.ui new file mode 100644 index 0000000..52e7fb3 --- /dev/null +++ b/src/querywidgetlayout.ui @@ -0,0 +1,62 @@ + +QueryWidgetLayout + + + QueryWidgetLayout + + + + 0 + 0 + 740 + 343 + + + + Form2 + + + + unnamed + + + 0 + + + 0 + + + + m_pQueryTabs + + + + + + + TabWidget +
    tabwidget.h
    + + -1 + -1 + + 1 + + 7 + 7 + 0 + 0 + + image0 +
    +
    + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000017c49444154388dad95db71c32010458f322e652966f3ef325031a68bf8df14c3f6e27c80c4338927e39df1182474b85c2ed2465f4fde53db76b4bcbf3e55af98414af79709c778b3815cfe9f8fc7576e39803b249afe1ff074e716c062bd76696716cd83a0519c2019dd444e66b8035ad12738a53ba274d0142146a6658a802a386d2ff6632e5d2fd5668c10430f3b56660621801a783fab9fc1add20255cdbf56d131698c45fd0ec49ef1d1f55c7df084fa19eab52a0d012c31d5a43859f554b5bf77dbcbbd62c1e17fb291322a86d367915ee90925a70707aeac70a578062faa854213b745ec7e061f2a0a6815b77dcf2a53d90b591ca2c96327d906b30c5505cae17192a118ec9ff5191508831d4b2b8e4d8b21abf23e5f1307b7db30d6b33cf6cb1cab56c5a1e4d53940eaf28f4a114c67bbbb77c5d926ab142939b5d967f5bdff63e2ceb79b08ecc332c5954db21a2971d9535c1fb331392718ca0691978cf16b9cda6169919c0efcce7ae980fca7b6a6fd56d5dbd07fdbc7f41bcb78aa0bdc5b1e190000000049454e44ae426082 + + + + + tabwidget.h + +
    diff --git a/src/scanprogressdlg.cpp b/src/scanprogressdlg.cpp new file mode 100644 index 0000000..e380c60 --- /dev/null +++ b/src/scanprogressdlg.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include "scanprogressdlg.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The widget's name + */ +ScanProgressDlg::ScanProgressDlg(QWidget* pParent, const char* szName) : + ScanProgressLayout(pParent, szName), + m_nFiles(0), + m_nCurFiles(0) +{ + show(); + + // Emit the cancelled() signal when the "Cancel" button is clicked + connect(m_pCancelButton, SIGNAL(clicked()), this, SIGNAL(cancelled())); +} + +/** + * Class destructor. + */ +ScanProgressDlg::~ScanProgressDlg() +{ +} + +/** + * Adds the given number of files to the total count of files already scanned. + * A visual indication of the progress is given in intervals of more than 100 + * files (to prevent too-frequent GUI updates.) + * @param nFiles The number of files scanned since the last call + */ +void ScanProgressDlg::addFiles(int nFiles) +{ + QString sText; + + // Do nothing if no files were scanned + if (nFiles <= 0) + return; + + // Update the total number of files scanned + m_nFiles += nFiles; + + // Update progress only if more than 100 files were scanned since the last + // update + if ((m_nFiles - m_nCurFiles) > 100) { + sText.sprintf(i18n("Scanned %d files..."), m_nFiles); + m_pText->setText(sText); + m_nCurFiles = m_nFiles; + } +} + +#include "scanprogressdlg.moc" diff --git a/src/scanprogressdlg.h b/src/scanprogressdlg.h new file mode 100644 index 0000000..84564de --- /dev/null +++ b/src/scanprogressdlg.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef SCANPROGRESSDLG_H +#define SCANPROGRESSDLG_H + +#include +#include + +/** + * Displays the progress of a file scan operation. + * This dialogue is displayed while a ProjectFilesDlg dialogue scans a + * directory tree for all files matching the patterns defined for the + * project's source files. + * @author Elad Lahav + */ + +class ScanProgressDlg : public ScanProgressLayout +{ + Q_OBJECT + +public: + ScanProgressDlg(QWidget* pParent = 0, const char* szName = 0); + ~ScanProgressDlg(); + + void addFiles(int); + +signals: + /** + * Indicates that the dialogue's "Cancel" button hsa been clicked by the + * user. + */ + void cancelled(); + +private: + /** The total number of files scanned thus far. */ + int m_nFiles; + + /** The number of files currently displayed in the progress report (which + may be smaller than m_nFiles since not every call to addFiles() updates + the progress display.)*/ + int m_nCurFiles; +}; + +#endif diff --git a/src/scanprogresslayout.ui b/src/scanprogresslayout.ui new file mode 100644 index 0000000..85482a8 --- /dev/null +++ b/src/scanprogresslayout.ui @@ -0,0 +1,115 @@ + +ScanProgressLayout + + + ScanProgressLayout + + + + 0 + 0 + 198 + 103 + + + + Scanning Directory + + + + unnamed + + + + layout4 + + + + unnamed + + + + m_pText + + + Scanned 0 files... + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + layout2 + + + + unnamed + + + + spacer2 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + m_pCancelButton + + + Cancel + + + true + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + + + + diff --git a/src/searchlist.cpp b/src/searchlist.cpp new file mode 100644 index 0000000..ccff869 --- /dev/null +++ b/src/searchlist.cpp @@ -0,0 +1,270 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include "searchlist.h" + +/** + * Intercepting additional key events of QLineEdit to browse the list + * @param pKey The pressed key event + */ +void SearchLineEdit::keyPressEvent(QKeyEvent* pKey) +{ + switch(pKey->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + emit keyPressed(pKey); + break; + + default: + QLineEdit::keyPressEvent(pKey); + break; + } +} + +/** + * Class constructor. + * @param pParent Owner list view widget + */ +ListToolTip::ListToolTip(SearchList* pParent) : + QToolTip(pParent->getList()->viewport()), + m_pList(pParent) +{ +} + +/** + * Displays a tool-tip according to the current location of the mouse + * pointer. + * @param pt The mouse pointer coordinates + */ +void ListToolTip::maybeTip(const QPoint& pt) +{ + QString str; + QListView* pList; + QListViewItem* pItem; + + // Get the item at the given point + pList = m_pList->getList(); + pItem = pList->itemAt(pt); + if (pItem == NULL) + return; + + // Get the tip string for this item + if (!m_pList->getTip(pItem, str)) + return; + + // Get the bounding rectangle of the item + const QRect rcItem = pList->itemRect(pItem); + if (!rcItem.isValid()) + return; + + // Get the header coordinates + const QRect rcHead = pList->header()->rect(); + if (!rcHead.isValid()) + return; + + // Calculate the tool-tip rectangle + QRect rcCell(rcHead.left(), rcItem.top(), rcItem.width(), rcItem.height()); + + // Display the tool-tip + tip(rcCell, str); +} + +/** + * Class constructor. + * @param nSearchCol The list column on which to perform string look-ups + * @param pParent The parent widget + * @param szName The widget's name + */ +SearchList::SearchList(int nSearchCol, QWidget* pParent, const char* szName) : + QVBox(pParent, szName), + m_nSearchCol(nSearchCol) +{ + // Create the child widgets + m_pEdit = new SearchLineEdit(this); + m_pList = new QListView(this); + + // Set up the tooltip generator + QToolTip::remove(m_pList); + m_pToolTip = new ListToolTip(this); + + connect(m_pEdit, SIGNAL(textChanged(const QString&)), this, + SLOT(slotFindItem(const QString&))); + connect(m_pList, SIGNAL(doubleClicked(QListViewItem*)), this, + SLOT(slotItemSelected(QListViewItem*))); + connect(m_pList, SIGNAL(returnPressed(QListViewItem*)), this, + SLOT(slotItemSelected(QListViewItem*))); + connect(m_pEdit, SIGNAL(returnPressed()), this, + SLOT(slotItemSelected())); + connect(m_pEdit, SIGNAL(keyPressed(QKeyEvent*)), this, + SLOT(slotKeyPressed(QKeyEvent*))); +} + +/** + * Class destructor. + */ +SearchList::~SearchList() +{ + delete m_pToolTip; +} + +/** + * Sets the keyboad focus to the search box. + */ +void SearchList::slotSetFocus() +{ + m_pEdit->setFocus(); +} + +/** + * Selects a list item whose string begins with the text entered in the edit + * widget. + * This slot is connected to the textChanged() signal of the line edit widget. + * @param sText The new text in the edit widget + */ +void SearchList::slotFindItem(const QString& sText) +{ + QListViewItem* pItem; + + // Try to find an item that contains this text + // Priority to exactly matched, + // then try to find line begins with the text, + // and if not found, then try to find the line contains the text + pItem = m_pList->findItem(sText, m_nSearchCol, + ExactMatch | BeginsWith | Contains); + + // Select this item + if (pItem != 0) { + m_pList->setSelected(pItem, true); + m_pList->ensureItemVisible(pItem); + } +} + +/** + * Lets inheriting classes process an item selection made through the list + * widget. + * This slot is connected to the doubleClicked() and returnPressed() + * signals of the list widget. + */ +void SearchList::slotItemSelected(QListViewItem* pItem) +{ + processItemSelected(pItem); + m_pEdit->setText(""); +} + +/** + * Lets inheriting classes process an item selection made through the edit + * widget. + * This slot is connected to the returnPressed() signal of the edit widget. + */ +void SearchList::slotItemSelected() +{ + QListViewItem* pItem; + + if ((pItem = m_pList->selectedItem()) != NULL) { + m_pEdit->setText(pItem->text(m_nSearchCol)); + processItemSelected(pItem); + } + + m_pEdit->setText(""); +} + +#define SEARCH_MATCH(pItem) \ + pItem->text(m_nSearchCol).startsWith(m_pEdit->text()) + +/** + * Sets a new current item based on key events in the edit box. + * This slot is connected to the keyPressed() signal of the edit widget. + * @param pKey The key evant passed by the edit box + */ +void SearchList::slotKeyPressed(QKeyEvent* pKey) +{ + QListViewItem* pItem, * pNewItem; + int nPageSize, nPos; + + // Select the current item, or the first one if there is no current item + pItem = m_pList->currentItem(); + + // Set a new current item based on the pressed key + switch (pKey->key()) { + case Qt::Key_Up: + if (pItem) { + for (pNewItem = pItem->itemAbove(); + pNewItem && !SEARCH_MATCH(pNewItem); + pNewItem = pNewItem->itemAbove()); + + if (pNewItem) + pItem = pNewItem; + } + break; + + case Qt::Key_Down: + if (pItem) { + for (pNewItem = pItem->itemBelow(); + pNewItem && !SEARCH_MATCH(pNewItem); + pNewItem = pNewItem->itemBelow()); + + if (pNewItem) + pItem = pNewItem; + } + break; + + case Qt::Key_PageUp: + nPageSize = m_pList->visibleHeight() / pItem->height(); + for (nPos = 0; + pItem && pItem->itemAbove() && (nPos < nPageSize); + nPos++) + pItem = pItem->itemAbove(); + break; + + case Qt::Key_PageDown: + nPageSize = m_pList->visibleHeight() / pItem->height(); + for (nPos = 0; + pItem && pItem->itemBelow() && (nPos < nPageSize); + nPos++) + pItem = pItem->itemBelow(); + break; + + default: + pKey->ignore(); + return; + } + + // Select the first item if no other item was selected + if (pItem == NULL) + pItem = m_pList->firstChild(); + + // Select the new item + if (pItem) { + m_pList->setSelected(pItem, true); + m_pList->ensureItemVisible(pItem); + } +} + +#include "searchlist.moc" diff --git a/src/searchlist.h b/src/searchlist.h new file mode 100644 index 0000000..ffa7ac8 --- /dev/null +++ b/src/searchlist.h @@ -0,0 +1,144 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef SEARCHLIST_H +#define SEARCHLIST_H + +#include +#include +#include +#include +#include + +class SearchList; + +/** + * Defines a line text edit for searchable list view. + * The widget is based on QLineEdit with additional key functions + * Supported key events (up and down) are emitted as signals + * @author Albert Yosher + */ +class SearchLineEdit : public QLineEdit +{ + Q_OBJECT +public: + SearchLineEdit(QWidget* pParent) : QLineEdit(pParent) {}; + ~SearchLineEdit() {}; + +signals: + /** + * Emitted when one of the up/down or page up/page down keys were pressed + * inside this edit widget. + * @param pEvent The event received for this key press + */ + void keyPressed(QKeyEvent* pEvent); + +private: + virtual void keyPressEvent(QKeyEvent*); +}; + +/** + * A tool-tip class for the search list. + * Enables sub-classes of the list to provide a customised tool-tip for each + * list item. + * @author Gabor Fekete + */ +class ListToolTip : public QToolTip +{ +public: + ListToolTip(SearchList* pParent); + +protected: + virtual void maybeTip(const QPoint& pt); + +private: + /** The owner widget. */ + SearchList* m_pList; +}; + + +/** + * Defines a searchable list view. + * The widget is composed of a list view, and an edit box used to enter + * search data. Whenever the text in the edit box changes, the list view is + * set to point to the first item that matches the new text. + * @author Elad Lahav + */ +class SearchList : public QVBox +{ + Q_OBJECT + +public: + SearchList(int nSearchCol, QWidget* pParent = 0, const char* szName = 0); + ~SearchList(); + + /** + * @return A pointer to the list part of the widget. + */ + QListView* getList() { return m_pList; } + + /** + * Constructs a tool-tip for the given item. + * @param pItem The item for which a tip is required + * @param sTip The constructed tip string (on return) + * @return True to display the tip, false otherwise + */ + virtual bool getTip(QListViewItem* pItem, QString& sTip) = 0; + +public slots: + void slotSetFocus(); + +protected: + /** The search edit-box. */ + QLineEdit* m_pEdit; + + /** The list part of the widget. */ + QListView* m_pList; + + /** + * Called whenever the user selects an item in the list by either double- + * clicking it, or by highlighting the item and pressing the ENTER key. + * @param pItem The selected list item + */ + virtual void processItemSelected(QListViewItem* pItem) = 0; + +protected slots: + void slotFindItem(const QString&); + void slotItemSelected(QListViewItem*); + void slotItemSelected(); + void slotKeyPressed(QKeyEvent*); + +private: + /** Specifies the search column, i.e., the list column whose strings are + compared with the text in the search edit-box. */ + int m_nSearchCol; + + /** A tool-tip for the list entries. */ + ListToolTip* m_pToolTip; +}; + +#endif diff --git a/src/searchresultsdlg.cpp b/src/searchresultsdlg.cpp new file mode 100644 index 0000000..bb63fa5 --- /dev/null +++ b/src/searchresultsdlg.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include "searchresultsdlg.h" + +int SearchResultsDlg::s_nType = PlainText; +bool SearchResultsDlg::s_bCaseSensitive = true; +bool SearchResultsDlg::s_bNegate = false; + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName Optional widget name + */ +SearchResultsDlg::SearchResultsDlg(QWidget* pParent, const char* szName) : + SearchResultsLayout(pParent, szName, true, 0) +{ + // Select the last selected type radio button + switch (s_nType) { + case PlainText: + m_pTextRadio->setChecked(true); + break; + + case RegExp: + m_pRegExpRadio->setChecked(true); + break; + + case SimpRegExp: + m_pSimpRegExpRadio->setChecked(true); + break; + } + + // Set the default value of the check-boxes + m_pCaseSenCheck->setChecked(s_bCaseSensitive); + m_pNegateCheck->setChecked(s_bNegate); + + // Terminate the dialogue when either the "OK" or "Cancel" buttons are + // clicked + connect(m_pOKButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); +} + +/** + * Class destructor. + */ +SearchResultsDlg::~SearchResultsDlg() +{ +} + +/** + * Determines the default column on which to search. + * The column's name appears in the column combo-box. + */ +void SearchResultsDlg::setColumn(int nCol) +{ + m_pColumnCB->setCurrentItem(nCol); +} + +/** + * @return The selected column on which to perform the search + */ +int SearchResultsDlg::getColumn() +{ + return m_pColumnCB->currentItem(); +} + +/** + * Creates a regular expression based on the given pattern and type of search. + * @param re A regular expression object to set + */ +void SearchResultsDlg::getPattern(QRegExp& re) +{ + QString sPattern; + + sPattern = m_pSearchEdit->text(); + + // Create the regular expression + switch (s_nType) { + case PlainText: + re.setPattern(QRegExp::escape(sPattern)); + re.setWildcard(false); + break; + + case RegExp: + re.setPattern(sPattern); + re.setWildcard(false); + break; + + case SimpRegExp: + re.setPattern(sPattern); + re.setWildcard(true); + break; + } + + // Set the case-(in)sensitive parameter + re.setCaseSensitive(s_bCaseSensitive); +} + +/** + * Reads user values from the widgets, and closes the dialogue. + * This slot is connected to the clicked() signal emitted by the "OK" button. + */ +void SearchResultsDlg::accept() +{ + QString sText; + + // Determine the selected type and store its value for the next invocation + if (m_pTextRadio->isChecked()) + s_nType = PlainText; + else if (m_pRegExpRadio->isChecked()) + s_nType = RegExp; + else if (m_pSimpRegExpRadio->isChecked()) + s_nType = SimpRegExp; + + // Determine search parameters + s_bCaseSensitive = m_pCaseSenCheck->isChecked(); + s_bNegate = m_pNegateCheck->isChecked(); + + // Remove white space from the search text + sText = m_pSearchEdit->text(); + sText.stripWhiteSpace(); + if (sText.isEmpty()) { + QDialog::reject(); + return; + } + + // Close the dialogue + QDialog::accept(); +} + +#include "searchresultsdlg.moc" + diff --git a/src/searchresultsdlg.h b/src/searchresultsdlg.h new file mode 100644 index 0000000..d636f8f --- /dev/null +++ b/src/searchresultsdlg.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef SEARCHRESULTSDLG_H +#define SEARCHRESULTSDLG_H + +#include +#include +#include "searchresultslayout.h" + +/** + * A dialogue for defining searches on query results. + * The dialogue is activated from the query results menu. + * @author Elad Lahav + */ +class SearchResultsDlg : public SearchResultsLayout +{ + Q_OBJECT + +public: + SearchResultsDlg(QWidget* pParent = 0, const char* szName = 0); + ~SearchResultsDlg(); + + void setColumn(int); + int getColumn(); + void getPattern(QRegExp&); + + /** + * @return true if the search pattern should be negated, false otherwise + */ + bool isNegated() { return m_pNegateCheck->isChecked(); } + +protected slots: + virtual void accept(); + +private: + /** Possible search types. */ + enum { PlainText = 0, RegExp, SimpRegExp }; + + /** Remembers the last search type. */ + static int s_nType; + + /** Remembers the last value of the Case Sensitive check-box. */ + static bool s_bCaseSensitive; + + /** Remembers the last value of the Negate Search check-box. */ + static bool s_bNegate; +}; + +#endif diff --git a/src/searchresultslayout.ui b/src/searchresultslayout.ui new file mode 100644 index 0000000..cdcde53 --- /dev/null +++ b/src/searchresultslayout.ui @@ -0,0 +1,214 @@ + +SearchResultsLayout + + + SearchResultsLayout + + + + 0 + 0 + 361 + 307 + + + + Filter Query Results + + + + unnamed + + + + layout2 + + + + unnamed + + + + textLabel2 + + + Search For: + + + + + m_pSearchEdit + + + + + + + layout4 + + + + unnamed + + + + textLabel1 + + + Search In: + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 171 + 20 + + + + + + + Function + + + + + File + + + + + Line + + + + + Text + + + + m_pColumnCB + + + + + + + buttonGroup1 + + + Search Type + + + + unnamed + + + + m_pTextRadio + + + Plain Text + + + + + m_pRegExpRadio + + + RegE&xp + + + + + m_pSimpRegExpRadio + + + Simplified RegExp + + + + + + + m_pCaseSenCheck + + + Case Sensitive + + + + + m_pNegateCheck + + + Negate Search + + + + + layout3 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Expanding + + + + 201 + 21 + + + + + + m_pOKButton + + + OK + + + + + m_pCancelButton + + + Cancel + + + + + + + + m_pSearchEdit + m_pColumnCB + m_pTextRadio + m_pRegExpRadio + m_pSimpRegExpRadio + m_pCaseSenCheck + m_pOKButton + m_pCancelButton + + + diff --git a/src/symbolcompletion.cpp b/src/symbolcompletion.cpp new file mode 100644 index 0000000..2ec8194 --- /dev/null +++ b/src/symbolcompletion.cpp @@ -0,0 +1,344 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "symbolcompletion.h" + +bool SymbolCompletion::s_bACEnabled; +uint SymbolCompletion::s_nACMinChars; +uint SymbolCompletion::s_nACDelay; +uint SymbolCompletion::s_nACMaxEntries; + +/** + * Class constructor. + * @param pEditor The editor object for which symbol completion is required + * @param pParent Parent object + * @param szName Optional object name + */ +SymbolCompletion::SymbolCompletion(SymbolCompletion::Interface* pEditor, + QObject* pParent, const char* szName) : + QObject(pParent, szName), + m_pEditor(pEditor), + m_pCCObject(NULL) +{ + // Initialise member objects + m_pCscope = new CscopeFrontend(); + m_pAutoCompTimer = new QTimer(this); + + // Add entries to the completion list when they are available + connect(m_pCscope, SIGNAL(dataReady(FrontendToken*)), this, + SLOT(slotAddEntry(FrontendToken*))); + + // Show the completion list when the query finishes + connect(m_pCscope, SIGNAL(finished(uint)), this, + SLOT(slotQueryFinished(uint))); + + // Initiate automatic symbol completion when timer expires + connect(m_pAutoCompTimer, SIGNAL(timeout()), this, + SLOT(slotAutoCompleteTimeout())); +} + +/** + * Class destructor. + */ +SymbolCompletion::~SymbolCompletion() +{ + delete m_pCscope; +} + +/** + * Stops a completion process. + * This includes killing a running query, and stoping the auto-completion + * timer. + */ +void SymbolCompletion::abort() +{ + if (m_pCscope->isRunning()) + m_pCscope->kill(); + + m_pAutoCompTimer->stop(); +} + +/** + * Configures auto-completion parameters. + * @param bEnabled true to enable auto-completion, false otherwise + * @param nMinChars Minimal number of characters a symbol needs to start + * auto-completion + * @param nDelay Auto-completion time interval (in milliseconds) + * @param nMaxEntries The maximal number of completion entries + */ +void SymbolCompletion::initAutoCompletion(bool bEnabled, uint nMinChars, + uint nDelay, uint nMaxEntries) +{ + s_bACEnabled = bEnabled; + s_nACMinChars = nMinChars; + s_nACDelay = nDelay; + s_nACMaxEntries = nMaxEntries; +} + +/** + * Starts a completion process immediately for the symbol currently under the + * cursor in the editor object. + * Symbol completion is only available if the cursor is positioned at the end + * of the symbol. + */ +void SymbolCompletion::slotComplete() +{ + QString sSymbol; + uint nPosInWord; + + // Read the symbol currently under the cursor + sSymbol = m_pEditor->getWordUnderCursor(&nPosInWord); + + // The completion was triggered by user + m_bAutoCompletion = false; + + // start completion process, prefix is only on the left from the cursor + complete(sSymbol.left(nPosInWord)); +} + +/** + * Initiates an auto-completion timer. + * When the timer times-out, is starts the symbol completion process. + */ +void SymbolCompletion::slotAutoComplete() +{ + if (s_bACEnabled) + m_pAutoCompTimer->start(s_nACDelay, true); +} + +/** + * Creates a list of possible completions to the symbol currently being + * edited. + * @param sPrefix The symbol to complete + * @param nMaxEntries The maximal number of entries to display + */ +void SymbolCompletion::complete(const QString& sPrefix, int nMaxEntries) +{ + // Create a regular expression to extract symbol names from the query + // results + m_reSymbol.setPattern(sPrefix + "[a-zA-Z0-9_]*"); + + // If the new prefix is itself a prefix of the old one, we only need to + // filter the current entries + if (!m_sPrefix.isEmpty() && sPrefix.startsWith(m_sPrefix)) { + filterEntries(); + m_sPrefix = sPrefix; + slotQueryFinished(0); + return; + } + + // Prepare member variables + m_sPrefix = sPrefix; + m_nMaxEntries = nMaxEntries; + m_elEntries.clear(); + + // Run the code-completion query + m_pCscope->query(CscopeFrontend::Definition, sPrefix + ".*"); +} + +/** + * Removes from the current completion list all symbols that do not match + * the current regular expression. + * This function is used to aviod requerying the database on certain + * situations. + */ +void SymbolCompletion::filterEntries() +{ + EntryList::Iterator itr; + + // Iterate over the list and check each entry against the current RE + for (itr = m_elEntries.begin(); itr != m_elEntries.end();) { + if (m_reSymbol.search((*itr).text) == -1) + itr = m_elEntries.erase(itr); + else + ++itr; + } +} + +/** + * Conevrts the completion list into a single-entry one, containing the given + * message. + * @param sMsg The text of the message to include in the list. + */ +void SymbolCompletion::makeErrMsg(const QString& sMsg) +{ + Entry entry; + + // Clear the current list + m_elEntries.clear(); + + // Create the message item and add it to the list + entry.text = sMsg; + entry.userdata = "NO_INSERT"; // The message should not be insertable + m_elEntries.append(entry); + + // Make sure a new completion request will start a new query + m_sPrefix = ""; +} + +/** + * Creates a new entry in the list when a query record is available. + * This slot is connected to the dataReady() signal of the CscopeFrontend + * object. + * @param pToken Points to the head of a record's linked-list + */ +void SymbolCompletion::slotAddEntry(FrontendToken* pToken) +{ + Entry entry; + QString sText; + + // Do not add entries beyond the requested limit + if (m_elEntries.count() > m_nMaxEntries) + return; + + // Get the line text + pToken = pToken->getNext()->getNext()->getNext(); + sText = pToken->getData(); + + // Find the symbol within the line + if (m_reSymbol.search(sText) == -1) + return; + + // Add the new entry to the completion list + entry.text = m_reSymbol.capturedTexts().first(); + entry.userdata = ""; + entry.comment = sText; + + m_elEntries.append(entry); +} + +/** + * Displays a code completion list, based on the results of the last query. + * @param nRecords (ingnored) + */ +void SymbolCompletion::slotQueryFinished(uint /* nRecords */) +{ + KTextEditor::CodeCompletionInterface* pCCI; + uint nEntryCount; + EntryList::Iterator itr; + QString sPrevText; + + // Get the number of entries + nEntryCount = m_elEntries.count(); + + // Do not show the box the only completion option is the prefix itself + if (m_bAutoCompletion && (nEntryCount == 1) && + (m_elEntries.first().text == m_sPrefix)) { + return; + } + + // Get a pointer to the CC interface + m_pCCObject = m_pEditor->getCCObject(); + pCCI = dynamic_cast(m_pCCObject); + if (!pCCI) + return; + + // Insert the correct part of the completed symbol, when chosen by the + // user + connect(m_pCCObject, + SIGNAL(filterInsertString(KTextEditor::CompletionEntry*, QString*)), + this, + SLOT(slotFilterInsert(KTextEditor::CompletionEntry*, QString*))); + + // Check the number of entries in the list + if (nEntryCount == 0) { + // No completion options, display an appropriate message + makeErrMsg(i18n("No matching completion found...")); + } + else if (nEntryCount > m_nMaxEntries) { + // The query has resulted in too many entries, display an + // appropriate message + makeErrMsg(i18n("Too many options...")); + } + else { + // Sort the entries + m_elEntries.sort(); + + // Make sure entries are unique + for (itr = m_elEntries.begin(); itr != m_elEntries.end();) { + if ((*itr).text == sPrevText) { + itr = m_elEntries.erase(itr); + } + else { + sPrevText = (*itr).text; + ++itr; + } + } + } + + // Display the completion list + pCCI->showCompletionBox(m_elEntries); +} + +/** + * Determines which part of the completion entry should be added to the code + * when that entry is selected. + * @param pEntry Points to the selected entry + * @param pTextToInsert Contains the string to insert, upon return + */ +void SymbolCompletion::slotFilterInsert(KTextEditor::CompletionEntry* pEntry, + QString* pTextToInsert) +{ + // Insert the completed entry, unless it contains an error message + if (pEntry->userdata.isEmpty()) + *pTextToInsert = pEntry->text.mid(m_sPrefix.length()); + else + *pTextToInsert = ""; + + // Disconnect the CC object signals + disconnect(m_pCCObject, 0, this, 0); + m_pCCObject = NULL; +} + +/** + * Checks if the current symbol is eligible for auto-completion, and if so, + * starts the completion process. + * Auto-completion is performed for symbols that have the required minimal + * number of entries, and the cursor is positioned at the end of the word. + * This slot is connected to the timeout() signal of the auto-completion + * timer. + */ +void SymbolCompletion::slotAutoCompleteTimeout() +{ + QString sPrefix; + uint nPosInWord, nLength; + + // Read the symbol currently under the cursor + sPrefix = m_pEditor->getWordUnderCursor(&nPosInWord); + nLength = sPrefix.length(); + + // Check conditions, and start the completion process + if ((nLength >= s_nACMinChars) && (nPosInWord == nLength)) { + // The completion was triggered by auto-completion + m_bAutoCompletion = true; + complete(sPrefix, s_nACMaxEntries); + } +} + +#include "symbolcompletion.moc" diff --git a/src/symbolcompletion.h b/src/symbolcompletion.h new file mode 100644 index 0000000..6fe57e2 --- /dev/null +++ b/src/symbolcompletion.h @@ -0,0 +1,195 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef SYMBOLCOMPLETION_H +#define SYMBOLCOMPLETION_H + +#include +#include +#include +#include +#include "cscopefrontend.h" + +/** + * This class executes symbol definition queries based on symbol prefixes. + * The results can then be displayed as symbol completion lists. + * @author Albert Yosher + */ +class SymbolCompletion : public QObject +{ + Q_OBJECT + +public: + /** + * A pure-virtual class that allows a SymbolCompletion object access to + * text-editing objects. + * Classes that wish to utilise SymbolCompletion need to inplement this + * interface. + * @author Albert Yosher + */ + struct Interface + { + /** + * Class destructor. + * NOTE: A virtual destructor is required by GCC 4.0 + */ + virtual ~Interface() {} + + /** + * Returns the word currently under the editing cursor. + * Symbol completion will be provided for this word only if the cursor + * is positioned at the end of this word. + * @param pPosInWord Set this value to the offset in the word on + * which the cursor is positioned + */ + virtual QString getWordUnderCursor(uint* pPosInWord) = 0; + + /** + * Returns a target object for displaying the completion list. + * @return A pointer to an object implementing + * KTextEditor::CodeCompletionInterface, or NULL if the + * implementation does not support this interface. + */ + virtual QObject* getCCObject() = 0; + }; + + SymbolCompletion(SymbolCompletion::Interface*, QObject* pParent = 0, + const char* szName = 0); + ~SymbolCompletion(); + + void abort(); + + static void initAutoCompletion(bool, uint, uint, uint); + +public slots: + void slotComplete(); + void slotAutoComplete(); + +private: + /** + * Symbol completion entry object, used in the completion list. + * Implements operators required for sorting the completion list. + * @author Albert Yosher + */ + class Entry : public KTextEditor::CompletionEntry + { + public: + /** + * Determines whether a given entry is smaller than this one. + * @param entry The entry to compare with + * @return true if the given entry is smaller, false otherwise + */ + bool operator < (const SymbolCompletion::Entry& entry) const { + return (text < entry.text); + } + + /** + * Determines whether a given entry is equal to this one. + * @param entry The entry to compare with + * @return true if the given entry equals this one, false otherwise + */ + bool operator == (const SymbolCompletion::Entry& entry) const { + return (text == entry.text); + } + }; + + /** + * A sortable version of the value list used by CodeCompletionInterface. + * @author Albert Yosher + */ + class EntryList : public QValueList + { + public: + /** + * Sorts completion list. + */ + void sort() { qHeapSort(*this); } + + /** + * Type casting support required for calling showCompletionBox(). + * @return A casted reference to this object + */ + operator QValueList() + { return *(QValueList*)this; } + }; + + /** Editor object for which symbol completion is provided. */ + Interface* m_pEditor; + + /** An object that supports KTextEditor::CodeCompletionInterface, as + supplied by the editor. */ + QObject* m_pCCObject; + + /** Cscope process used to run completion queries. */ + CscopeFrontend* m_pCscope; + + /** The prefix used for the current query. */ + QString m_sPrefix; + + /** A list of possible completions for the given prefix. */ + EntryList m_elEntries; + + /** The maximal number of completions to accept. */ + uint m_nMaxEntries; + + /** Regular expression for extracting a symbol out of Cscope's text field. + NOTE: This member is required due to a bug in Cscope that renders the + symbol field useless. */ + QRegExp m_reSymbol; + + /** Auto-completion timer. */ + QTimer* m_pAutoCompTimer; + + /** Auto-completion flag */ + bool m_bAutoCompletion; + + void complete(const QString&, int nMaxEntries = 1000); + void filterEntries(); + void makeErrMsg(const QString&); + + /** true if auto-completion is enabled, false otherwise. */ + static bool s_bACEnabled; + + /** The minimum number of characters a symbol must have for + auto-completion. */ + static uint s_nACMinChars; + + /** The interval between the time slotAutoComplete() is called and the + time the completion process begins (in milliseconds). */ + static uint s_nACDelay; + + /** The maximal number of entries for auto-completion. */ + static uint s_nACMaxEntries; + +private slots: + void slotAutoCompleteTimeout(); + void slotAddEntry(FrontendToken*); + void slotQueryFinished(uint); + void slotFilterInsert(KTextEditor::CompletionEntry*, QString*); +}; + +#endif diff --git a/src/symboldlg.cpp b/src/symboldlg.cpp new file mode 100644 index 0000000..3301678 --- /dev/null +++ b/src/symboldlg.cpp @@ -0,0 +1,334 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "symboldlg.h" +#include "cscopefrontend.h" +#include "kscopeconfig.h" + +QStringList SymbolDlg::s_slHistory; + +/** + * Class constructor. + * @param pParent Parent widget + * @param szName This widget's name + */ +SymbolDlg::SymbolDlg(QWidget* pParent, const char* szName) : + SymbolLayout(pParent, szName, true, 0), + m_progress(m_pHintList) +{ + // Create a persistent Cscope process + m_pCscope = new CscopeFrontend(); + + // Initialise the hint list (hidden by default) + m_pHintList->addColumn(i18n("Suggested Symbols")); + m_pHintList->hide(); + ((QWidget*)m_pHintGroup)->hide(); + m_pBeginWithRadio->toggle(); + adjustSize(); + + // Close the dialogue when either the "OK" or "Cancel" button are clicked + connect(m_pOKButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + // Run a symbol completion query when the "Hint" button is clicked + connect(m_pHintButton, SIGNAL(clicked()), this, SLOT(slotHintClicked())); + + // Add results to the hint list + connect(m_pCscope, SIGNAL(dataReady(FrontendToken*)), this, + SLOT(slotHintDataReady(FrontendToken*))); + + // Set hint button availability based on the type of query + connect(m_pTypeCombo, SIGNAL(activated(int)), this, + SLOT(slotTypeChanged(int))); + + // Selecting an item in the hint list sets it as the current text + connect(m_pHintList, SIGNAL(selectionChanged(QListViewItem*)), this, + SLOT(slotHintItemSelected(QListViewItem*))); + + // Double-clicking an item in the hint list accepts that item as the + // result of the query (i.e., the item is selcted and the dialogue is + // closed) + connect(m_pHintList, SIGNAL(doubleClicked(QListViewItem*)), this, + SLOT(accept())); + + // Refresh the hint list when the hint options change + connect(m_pBeginWithRadio, SIGNAL(toggled(bool)), this, + SLOT(slotHintOptionChanged(bool))); + connect(m_pContainRadio, SIGNAL(toggled(bool)), this, + SLOT(slotHintOptionChanged(bool))); + + // Show hint query progress information + connect(m_pCscope, SIGNAL(progress(int, int)), this, + SLOT(slotHintProgress(int, int))); + connect(m_pCscope, SIGNAL(finished(uint)), this, + SLOT(slotHintFinished(uint))); +} + +/** + * Class destructor. + */ +SymbolDlg::~SymbolDlg() +{ + delete m_pCscope; +} + +/** + * Displays the requested type of query in the type combo-box. + * @param nType The requested type + */ +void SymbolDlg::setType(uint nType) +{ + m_pTypeCombo->setCurrentItem(nType); + slotTypeChanged(nType); +} + +/** + * @param sSymbol The initial text of the combo-box + */ +void SymbolDlg::setSymbol(const QString& sSymbol) +{ + m_pSymbolHC->setCurrentText(sSymbol); +} + +/** + * @param slSymHistory A list of previously queried symbols + */ +void SymbolDlg::setHistory(QStringList& slSymHistory) +{ + m_pSymbolHC->setHistoryItems(slSymHistory); +} + +/** + * @return The current text of the symbol combo-box + */ +QString SymbolDlg::getSymbol() const +{ + QString sResult; + + sResult = m_pSymbolHC->currentText().stripWhiteSpace(); + if (m_pSubStringCheck->isChecked()) + sResult = ".*" + sResult + ".*"; + + return sResult; +} + +/** + * @return The type of query requested by the user + * @note The returned value does not conform to the type used for running + * Cscope queries. Use getQueryType() to translate between these + * values. + */ +uint SymbolDlg::getType() const +{ + return m_pTypeCombo->currentItem(); +} + +bool SymbolDlg::getCase() const +{ + return !m_pCaseCheck->isChecked(); +} + +/** + * A convinience static function for creating and showing SymbolDlg dialogue. + * @param pParent The parent widget + * @param nType The type of query requested by the user (may be + * changed in the dialogue) + * @param sSymbol The initial text of the combo-box + * @return The text entered by the user in the symbol combo-box, or an empty + * string if the dialogue was cancelled + */ +QString SymbolDlg::promptSymbol(QWidget* pParent, uint& nType, + const QString& sSymbol, bool& bCase) +{ + SymbolDlg dlg(pParent); + + // Initialise the dialogue + dlg.setType(nType); + dlg.setHistory(s_slHistory); + dlg.setSymbol(sSymbol); + + // Display the dialogue + if (dlg.exec() != QDialog::Accepted) + return ""; + + // Return the text entered by the user + nType = dlg.getType(); + bCase = dlg.getCase(); + dlg.m_pSymbolHC->addToHistory(dlg.getSymbol()); + s_slHistory = dlg.m_pSymbolHC->historyItems(); + return dlg.getSymbol(); +} + +/** + * Translates a symbol dialogue type into a Cscope query type. + * @param nType The type to translate + * @return A query type matching the symbol dialogue type + */ +uint SymbolDlg::getQueryType(uint nType) +{ + if (nType == CallTree) + return CscopeFrontend::None; + + if (nType <= Text) + return nType; + + return nType + 1; +} + +/** + * Runs a symbol definition query, looking for symbols starting with the + * currently entered text. + * If the hint list is not visible, it is shown first. + * This slot is connected to the clicked() signal of the "Hint" button. + */ +void SymbolDlg::slotHintClicked() +{ + QString sText, sRegExp; + + // Show the hint list if necessary + if (!m_pHintList->isVisible()) { + m_pHintList->show(); + ((QWidget*)m_pHintGroup)->show(); + adjustSize(); + } + + // Clear the previous contents + m_pHintList->clear(); + + // Get the currently entered text (must have at least one character) + sText = m_pSymbolHC->currentText().stripWhiteSpace(); + if (sText.isEmpty()) + return; + + // Create the regular expression + if (m_pBeginWithRadio->isOn()) + sRegExp = sText + "[a-zA-Z0-9_]*"; + else + sRegExp = "[a-zA-Z0-9_]*" + sText + "[a-zA-Z0-9_]*"; + + m_reHint.setPattern(sRegExp); + + // Run a Cscope symbol definition query using a regular expression + m_pCscope->query(CscopeFrontend::Definition, sRegExp); +} + +/** + * Called when a new record is ready to be added to the hint list. + * NOTE: Cscope 15.5 has a bug where the "function" field of the record + * displays the regular expression instead of the matched symbol name. For + * this reason, we need to extract the symbol from the "Text" field. + * @param pToken The head of the record's token list + */ +void SymbolDlg::slotHintDataReady(FrontendToken* pToken) +{ + QString sText; + + // Get the line text + pToken = pToken->getNext()->getNext()->getNext(); + sText = pToken->getData(); + + // Find the symbol within the line + if (m_reHint.search(sText) == -1) + return; + + // Find the symbol within the list, if found - do not add + if (m_pHintList->findItem(m_reHint.capturedTexts().first(), 0)) + return; + + // Add a list item + (void)new QListViewItem(m_pHintList, m_reHint.capturedTexts().first()); + +} + +/** + * Sets the text of a selected hint list item as the current text of the + * symbol combo-box. + * This slot is connected to the doubleClicked() signal of the hint list-view. + * @param pItem The clicked list item + */ +void SymbolDlg::slotHintItemSelected(QListViewItem* pItem) +{ + m_pSymbolHC->setCurrentText(pItem->text(0)); +} + +/** + * Refreshes the hint list based on the newly selected option. + * This slot is connected to the toggled() signal of the hint options radio + * buttons. + * NOTE: The list is only refreshed if the system profile is set to Fast. + * @param bOn true if the button was toggled on + */ +void SymbolDlg::slotHintOptionChanged(bool bOn) +{ + if (bOn && Config().getSysProfile() == KScopeConfig::Fast) + slotHintClicked(); +} + +/** + * Display a progress bar while the hint query is working. + * This slot is connected to the progress() signal emitted by the Cscope + * frontend object. + * @param nProgress Progress value + * @param nTotal The final expected value + */ +void SymbolDlg::slotHintProgress(int nProgress, int nTotal) +{ + m_progress.setProgress(nProgress, nTotal); +} + +/** + * Destroys all progress information widget when the query process terminates. + * This slot is connected to the finished() signal emitted by the Cscope + * process. + */ +void SymbolDlg::slotHintFinished(uint /* ignored */) +{ + m_progress.finished(); +} + +/** + * Enables/disables the hint button, based on the newly selected type. + * This slot is connected to the activated() signal of the type combo-box. + * @param nType The newly selected type + */ +void SymbolDlg::slotTypeChanged(int nType) +{ + if (nType == FileName || nType == Including) + m_pHintButton->setEnabled(false); + else + m_pHintButton->setEnabled(true); +} + +#include "symboldlg.moc" diff --git a/src/symboldlg.h b/src/symboldlg.h new file mode 100644 index 0000000..4360213 --- /dev/null +++ b/src/symboldlg.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef SYMBOLDLG_H +#define SYMBOLDLG_H + +#include +#include "symbollayout.h" +#include "cscopefrontend.h" + +/** + * A dialogue that prompts the user for the text of a query. + * When a query is requested, the user needs to fill in the required + * information (usually a symbol name). This dialogue allows the user to + * enter this information, as well as complete a symbol name, and use + * previously entered text. + * @author Elad Lahav + */ + +class SymbolDlg : public SymbolLayout +{ + Q_OBJECT + +public: + SymbolDlg(QWidget* pParent = 0, const char* szName = 0); + ~SymbolDlg(); + + enum { Reference = 0, Definition, Called, Calling, Text, Pattern, + FileName, Including, CallTree }; + + void setType(uint); + void setSymbol(const QString&); + void setHistory(QStringList&); + QString getSymbol() const; + uint getType() const; + bool getCase() const; + + static QString promptSymbol(QWidget*, uint&, const QString&, bool&); + static uint getQueryType(uint); + static void resetHistory() { s_slHistory.clear(); } + +private: + /** A cscope process used for symbol completion. */ + CscopeFrontend* m_pCscope; + + /** A regular expression for extracting the symbol name out of the text + token of a Cscope record. + @see note in slotHintDataReady(). */ + QRegExp m_reHint; + + /** Displays query progress information. */ + CscopeProgress m_progress; + + static QStringList s_slHistory; + +private slots: + void slotHintClicked(); + void slotHintDataReady(FrontendToken*); + void slotHintItemSelected(QListViewItem*); + void slotHintOptionChanged(bool); + void slotHintProgress(int, int); + void slotHintFinished(uint); + void slotTypeChanged(int); +}; + +#endif + diff --git a/src/symbollayout.ui b/src/symbollayout.ui new file mode 100644 index 0000000..09b2885 --- /dev/null +++ b/src/symbollayout.ui @@ -0,0 +1,297 @@ + +SymbolLayout + + + SymbolLayout + + + + 0 + 0 + 343 + 456 + + + + KScope Query + + + + unnamed + + + + layout15 + + + + unnamed + + + + layout14 + + + + unnamed + + + + textLabel1 + + + + 5 + 5 + 0 + 0 + + + + Type + + + + + textLabel2 + + + + 5 + 5 + 0 + 0 + + + + Symbol + + + + + + + layout13 + + + + unnamed + + + + + References to + + + + + Definition of + + + + + Functions called by + + + + + Functions calling + + + + + Find text + + + + + Find EGrep pattern + + + + + Find file + + + + + Files #including + + + + + Call graph for + + + + m_pTypeCombo + + + + 7 + 0 + 0 + 0 + + + + + + m_pSymbolHC + + + + 7 + 0 + 0 + 0 + + + + AtTop + + + false + + + + + + + + + m_pSubStringCheck + + + Search for &a Sub-String + + + Alt+A + + + + + m_pCaseCheck + + + Case Insensitive + + + + + line2 + + + HLine + + + Sunken + + + Horizontal + + + + + layout3 + + + + unnamed + + + + spacer2 + + + Horizontal + + + Expanding + + + + 71 + 21 + + + + + + m_pOKButton + + + OK + + + + + m_pHintButton + + + Hi&nt + + + + + m_pCancelButton + + + Cancel + + + + + + + m_pHintList + + + + + m_pHintGroup + + + Hint Options + + + + unnamed + + + + m_pBeginWithRadio + + + S&ymbols Beginning With... + + + + + m_pContainRadio + + + Sym&bols Containing... + + + + + + + + m_pSymbolHC + m_pTypeCombo + m_pSubStringCheck + m_pOKButton + m_pHintButton + m_pCancelButton + m_pHintList + m_pBeginWithRadio + m_pContainRadio + + + + kcombobox.h + klineedit.h + + diff --git a/src/tab_list.png b/src/tab_list.png new file mode 100644 index 0000000000000000000000000000000000000000..b0cb478a4d0043eb4796a2a59c1bfa90e89beb90 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn1|+R>-G2co&H|6fVg?3opai!dV|_~eM4;eF zPZ!4!i{7Yd|g;@lJxbG&v);%7k@hI7i8Lh%u>`d^6vA=>Vcu6 z3<@m|E^N!S6m~uGaFrLse0@H}h#tYm7J96)*BKj*N@yyz?^sn-tX?@!|NSPNxo?$i zymvA*EYb+LZW^R_&4M9%j?d*MR_E`!97%k=VCGE&p5?CL6IW{e+V|f#rOw3nbHo#U b@!xE}+Eb=-SNEg?J;mVZ>gTe~DWM4f%T{h^ literal 0 HcmV?d00001 diff --git a/src/tabwidget.cpp b/src/tabwidget.cpp new file mode 100644 index 0000000..2795a84 --- /dev/null +++ b/src/tabwidget.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include +#include +#include "tabwidget.h" +#include "kscopepixmaps.h" + +/** + * Class constructor. + * @param pParent A pointer to the parent widget + * @param szName Optional widget name + */ +TabWidget::TabWidget(QWidget* pParent, const char* szName) : + KTabWidget(pParent, szName) +{ + // Create a popup menu + m_pMenu = new QPopupMenu(this); + + // Set the current tab based on the menu selection + connect(m_pMenu, SIGNAL(activated(int)), this, SLOT(setCurrentPage(int))); + + // Create a button at the top-right corner of the tab widget + m_pButton = new QToolButton(this); + m_pButton->setIconSet(Pixmaps().getPixmap(KScopePixmaps::TabList)); + QToolTip::add(m_pButton, i18n("Shows a list of all open tabs")); + m_pButton->adjustSize(); + setCornerWidget(m_pButton, TopRight); + + // Show the popup-menu when the button is clicked + connect(m_pButton, SIGNAL(clicked()), this, SLOT(slotShowTabList())); +} + +/** + * Class destructor. + */ +TabWidget::~TabWidget() +{ +} + +/** + * Creates and displays a popup-menu containing all tab labels. + * This slot is connected to the clicked() signal emitted by the list button. + */ +void TabWidget::slotShowTabList() +{ + int i; + + // Delete the previous menu + m_pMenu->clear(); + + // Create and populate the menu + for (i = 0; i < count(); i++) + m_pMenu->insertItem(label(i), i); + + // Show the menu + m_pMenu->popup(mapToGlobal(m_pButton->pos())); +} + +#include "tabwidget.moc" diff --git a/src/tabwidget.h b/src/tabwidget.h new file mode 100644 index 0000000..74672ae --- /dev/null +++ b/src/tabwidget.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef TABWIDGET_H +#define TABWIDGET_H + + +#include +#include +#include + +/** + * An extension to the standard KDE tab widget that allows the user to select + * a tab from a list displayed as a popup menu. + * @author Elad Lahav + */ +class TabWidget : public KTabWidget +{ +Q_OBJECT +public: + TabWidget(QWidget* pParent = 0, const char* szName = 0); + ~TabWidget(); + +private: + /** The list button. */ + QToolButton* m_pButton; + + /** A popup-menu containing all tab labels. */ + QPopupMenu* m_pMenu; + +private slots: + void slotShowTabList(); +}; + +#endif diff --git a/src/treewidget.cpp b/src/treewidget.cpp new file mode 100644 index 0000000..b303194 --- /dev/null +++ b/src/treewidget.cpp @@ -0,0 +1,260 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#include "treewidget.h" +#include "queryviewdriver.h" + +/** + * Class constructor. + * @param pParent Parent widget + * @param szName The name of the widget + */ +TreeWidget::TreeWidget(QWidget* pParent, const char* szName) : + QueryView(pParent, szName), + m_nQueryType(CscopeFrontend::Called) +{ + setRootIsDecorated(true); + + // Create a driver object + m_pDriver = new QueryViewDriver(this, this); + + // Query a tree item when it is expanded for the first time + connect(this, SIGNAL(expanded(QListViewItem*)), this, + SLOT(slotQueryItem(QListViewItem*))); +} + +/** + * Class destructor. + */ +TreeWidget::~TreeWidget() +{ +} + +/** + * Determines the mode of the tree. + * @param mode The new mode (@see Mode) + */ +void TreeWidget::setMode(Mode mode) +{ + m_nQueryType = (mode == Called) ? CscopeFrontend::Called : + CscopeFrontend::Calling; +} + +/** + * Sets a new root item for the tree. + * @param sFunc The name of the function to serve as root + */ +void TreeWidget::setRoot(const QString& sFunc) +{ + QListViewItem* pRoot; + + // Remove the current root, if any + if ((pRoot = firstChild()) != NULL) + delete pRoot; + + // Create a new root item + pRoot = new QListViewItem(this, sFunc); + pRoot->setExpandable(true); +} + +/** + * Runs a query on the root item. + */ +void TreeWidget::queryRoot() +{ + QListViewItem* pRoot; + + if ((pRoot = firstChild()) != NULL) + slotQueryItem(pRoot); +} + +/** + * Stores the tree contents in the given file. + * @param pFile An open file to write to + */ +void TreeWidget::save(FILE* pFile) +{ + QTextStream str(pFile, IO_WriteOnly); + QListViewItem* pRoot; + Encoder enc; + + if (m_nQueryType == CscopeFrontend::Called) + str << "calltree {" << endl; + else + str << "callingtree {" << endl; + + // Write the tree to the file + pRoot = firstChild(); + str << pRoot->text(0) << endl; + str << '{' << endl; + saveItems(pRoot->firstChild(), str, enc); + str << '}' << endl; + str << '}' << endl; +} + +/** + * Recursively writes tree items to a file. + * Given an item, the method writes this item and all of its siblings. + * Child items are written recursively. + * @param pItem The first item to write + * @param str An initialised text stream to use for writing + * @param enc An encoder for free-text strings + */ +void TreeWidget::saveItems(QListViewItem* pItem, QTextStream& str, Encoder& enc) +{ + // Iterate over all items in this level + for (; pItem != NULL; pItem = pItem->nextSibling()) { + // Write function parameters + str << pItem->text(0) << " [ " + << "kscope_file=\"" << pItem->text(1) << "\", " + << "kscope_line=" << pItem->text(2) << ", " + << "kscope_text=\"" << enc.encode(pItem->text(3)) << "\"" + << "]" << endl; + + // Write child items + str << "{" << endl; + saveItems(pItem->firstChild(), str, enc); + str << "}" << endl; + } +} + +/** + * Creates a new tree item showing a query result record. + * @param sFunc The name of the function + * @param sFile The file path + * @param sLine The line number in the above file + * @param sText The line's text + * @param pParent The parent for the new item + */ +void TreeWidget::addRecord(const QString& sFunc, const QString& sFile, + const QString& sLine, const QString& sText, QListViewItem* pParent) +{ + QListViewItem* pItem; + + pItem = new QueryViewItem(pParent, m_pLastItem, 2); + pItem->setText(0, sFunc); + pItem->setText(1, sFile); + pItem->setText(2, sLine); + pItem->setText(3, sText); + + pItem->setExpandable(true); + m_pLastItem = pItem; +} + +/** + * Called when a query running on the tree terminates. + * If there were no results, the item becomes non-expandable. + * NOTE: On top of its current behaviour, this function is required in order to + * override the default behaviour, as specified by QueryView. + * @param nResults Number of results + * @param pParent The item for which the query was executed + */ +void TreeWidget::queryFinished(uint nResults, QListViewItem* pParent) +{ + if (nResults == 0) + pParent->setExpandable(false); + else + pParent->setOpen(true); +} + +/** + * Runs a query on the given item, unless it was queried before. + * This slot is connected to the expanded() signal of the list view. + * @param pItem The item to query + */ +void TreeWidget::slotQueryItem(QListViewItem* pItem) +{ + // Do nothing if the item was already queried + // An item has been queried if it has children or marked as non-expandable + if (pItem->firstChild() != NULL || !pItem->isExpandable()) + return; + + // Run the query + m_pDriver->query(m_nQueryType, pItem->text(0), true, pItem); +} + +/** + * Hides all descendant that do not meet the given search criteria. + * This slot is connected to the search() signal of the QueryResultsMenu + * object. + * The search is incremental: only visible items are checked, so that a new + * search goes over the results of the previous one. + * @param pParent The parent item whose child are searched + * @param re The pattern to search + * @param nCol The list column to search in + */ +void TreeWidget::slotSearch(QListViewItem* pParent, const QRegExp& re, + int nCol) +{ + QListViewItem* pItem; + + // Get the first child + if (pParent != NULL) + pItem = pParent->firstChild(); + else + pItem = firstChild(); + + // Iterate over all child items + while (pItem != NULL) { + // Filter visible items only + if (pItem->isVisible() && re.search(pItem->text(nCol)) == -1) + pItem->setVisible(false); + + // Search child items recursively + slotSearch(pItem, re, nCol); + + pItem = pItem->nextSibling(); + } +} + +/** + * Makes all descendants of the given item visible. + * This slot is connected to the showAll() signal of the QueryResultsMenu + * object. + */ +void TreeWidget::slotShowAll(QListViewItem* pParent) +{ + QListViewItem* pItem; + + // Get the first child + if (pParent != NULL) + pItem = pParent->firstChild(); + else + pItem = firstChild(); + + // Iterate over all child items + while (pItem != NULL) { + pItem->setVisible(true); + + // Show child items recursively + slotShowAll(pItem); + + pItem = pItem->nextSibling(); + } +} + +#include "treewidget.moc" diff --git a/src/treewidget.h b/src/treewidget.h new file mode 100644 index 0000000..57c2a98 --- /dev/null +++ b/src/treewidget.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ***************************************************************************/ + +#ifndef TREEWIDGET_H +#define TREEWIDGET_H + +#include "queryview.h" +#include "encoder.h" + +class QueryViewDriver; + +/** + * A tree-like widget displaying a hierarchical list of functions. + * The widget has two modes: called functions and calling functions. Depending + * on this mode, child items represent functions called by or calling their + * parent item. + * @author Elad Lahav + */ +class TreeWidget : public QueryView +{ + Q_OBJECT + +public: + TreeWidget(QWidget* pParent = 0, const char* szName = 0); + ~TreeWidget(); + + /** + * The type of tree to display. + */ + enum Mode { Called, Calling }; + + void setMode(Mode); + void setRoot(const QString&); + void queryRoot(); + void save(FILE*); + + virtual void addRecord(const QString&, const QString&, const QString&, + const QString&, QListViewItem*); + virtual void queryFinished(uint, QListViewItem*); + +protected slots: + virtual void slotSearch(QListViewItem*, const QRegExp&, int); + virtual void slotShowAll(QListViewItem*); + +private: + /** The CscopeFrontend query type to use (based on the current mode). */ + uint m_nQueryType; + + /** Runs queries and outputs the results as tree items. */ + QueryViewDriver* m_pDriver; + + void saveItems(QListViewItem*, QTextStream&, Encoder&); + +private slots: + void slotQueryItem(QListViewItem*); +}; + +#endif diff --git a/src/welcomedlg.ui b/src/welcomedlg.ui new file mode 100644 index 0000000..44c385c --- /dev/null +++ b/src/welcomedlg.ui @@ -0,0 +1,126 @@ + +WelcomeDlg + + + WelcomeDlg + + + + 0 + 0 + 519 + 386 + + + + Welcome + + + + unnamed + + + + m_pBrowser + + + + 255 + 255 + 255 + + + + <h1>Welcome to <font color="#c00000">KScope</font>!</h1> + +If this is the first time you are running Kscope, please follow these steps (click on the links for detailed instructions): +<p> +1. <a href="help:/kscope/configuration.html#config-progs">Configure</a> paths to the required back-end executables<br> +2. <a href="help:/kscope/projects.html#project-create">Create</a> a new project<br> +3. <a href="help:/kscope/projects.html#project-files">Populate</a> the project with source files<br> +4. <a href="help:/kscope/queries.html">Browse</a> the project and <a href="help:/kscope/editing.html">edit</a> files<br> + +</p> + +<p> +For more information, please take a look at KScope's <a href="help:/kscope">manual</a>, or visit the KScope <a href="http://kscope.sourceforge.net">website</a>. +</p> + +<p> +Enjoy! +</p> + +<p> +<font size="-1">This message will only appear once. Use the "<b>Help->Show Welcome Message...</b>" menu command to show it again at any time.</font> +</p> + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + layout1 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Expanding + + + + 381 + 21 + + + + + + m_pCloseButton + + + Close + + + true + + + + + + + + + + + m_pCloseButton + clicked() + WelcomeDlg + accept() + + + + + ktextbrowser.h + + diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..e69de29 diff --git a/subdirs b/subdirs new file mode 100644 index 0000000..0e67810 --- /dev/null +++ b/subdirs @@ -0,0 +1,3 @@ +doc +po +src diff --git a/templates/cpp b/templates/cpp new file mode 100644 index 0000000..adfe0fd --- /dev/null +++ b/templates/cpp @@ -0,0 +1,26 @@ +/*************************************************************************** + * + * Copyright (C) $YEAR$ $AUTHOR$ ($EMAIL$) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/ diff --git a/templates/h b/templates/h new file mode 100644 index 0000000..adfe0fd --- /dev/null +++ b/templates/h @@ -0,0 +1,26 @@ +/*************************************************************************** + * + * Copyright (C) $YEAR$ $AUTHOR$ ($EMAIL$) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + ***************************************************************************/