From b6e09a3a8ea5f1338d089a29eb6e08f00f03f1aa Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 10 Feb 2010 01:15:27 +0000 Subject: [PATCH] Added abandoned KDE3 version of kdirstat git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kdirstat@1088039 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- AUTHORS | 1 + COPYING | 280 + COPYING.LIB | 482 + CREDITS | 18 + ChangeLog | 684 ++ INSTALL | 167 + Makefile.am | 48 + Makefile.cvs | 14 + Makefile.dist | 14 + README | 20 + TODO | 52 + acinclude.m4 | 11360 +++++++++++++++++++++++ aclocal.m4 | 1045 +++ build-howto.html | 191 + config.h.in | 243 + configure.files | 2 + configure.in | 109 + configure.in.in | 6 + doc/Makefile.am | 2 + doc/en/Makefile.am | 11 + doc/en/feedback-mail.png | Bin 0 -> 14538 bytes doc/en/index.docbook | 1954 ++++ doc/en/kdirstat-config-cleanups.png | Bin 0 -> 14165 bytes doc/en/kdirstat-config-tree-colors.png | Bin 0 -> 11280 bytes doc/en/kdirstat-main.png | Bin 0 -> 39583 bytes kdirstat.kdevprj | 153 + kdirstat.lsm | 14 + kdirstat.spec | 70 + kdirstat/Makefile.am | 98 + kdirstat/fix_move_to_trash_bin.pl | 9 + kdirstat/hi16-app-kdirstat.png | Bin 0 -> 303 bytes kdirstat/hi32-app-kdirstat.png | Bin 0 -> 538 bytes kdirstat/kactivitytracker.cpp | 93 + kdirstat/kactivitytracker.h | 109 + kdirstat/kcleanup.cpp | 432 + kdirstat/kcleanup.h | 360 + kdirstat/kcleanupcollection.cpp | 283 + kdirstat/kcleanupcollection.h | 225 + kdirstat/kdirsaver.cpp | 71 + kdirstat/kdirsaver.h | 75 + kdirstat/kdirstat.desktop | 20 + kdirstat/kdirstat.upd | 6 + kdirstat/kdirstat_part.rc | 14 + kdirstat/kdirstatapp.cpp | 847 ++ kdirstat/kdirstatapp.h | 421 + kdirstat/kdirstatfeedback.cpp | 184 + kdirstat/kdirstatmain.cpp | 115 + kdirstat/kdirstatsettings.cpp | 1056 +++ kdirstat/kdirstatsettings.h | 744 ++ kdirstat/kdirstatui.rc | 189 + kdirstat/kdirtree.cpp | 1636 ++++ kdirstat/kdirtree.h | 1437 +++ kdirstat/kdirtreeiterators.cpp | 417 + kdirstat/kdirtreeiterators.h | 386 + kdirstat/kdirtreeview.cpp | 1956 ++++ kdirstat/kdirtreeview.h | 889 ++ kdirstat/kfeedback.cpp | 503 + kdirstat/kfeedback.h | 460 + kdirstat/kpacman.cpp | 311 + kdirstat/kpacman.h | 265 + kdirstat/kstdcleanup.cpp | 150 + kdirstat/kstdcleanup.h | 65 + kdirstat/ktreemaptile.cpp | 608 ++ kdirstat/ktreemaptile.h | 323 + kdirstat/ktreemapview.cpp | 745 ++ kdirstat/ktreemapview.h | 446 + kdirstat/lo16-app-kdirstat.png | Bin 0 -> 303 bytes kdirstat/lo32-app-kdirstat.png | Bin 0 -> 538 bytes kdirstat/pics/Makefile.am | 2 + kdirstat/pics/hi16-action-symlink.png | Bin 0 -> 433 bytes kdirstat/pics/hi16-action-symlink.xcf | Bin 0 -> 1863 bytes kdirstat/pics/hi32-action-symlink.png | Bin 0 -> 1140 bytes kdirstat/pics/hi48-action-symlink.png | Bin 0 -> 1745 bytes kdirstat/pics/hi48-action-symlink.xcf | Bin 0 -> 3926 bytes kdirstat/pics/lo16-action-symlink.png | Bin 0 -> 239 bytes po/Makefile.am | 6 + po/de.po | 963 ++ po/fr.po | 726 ++ po/hu.po | 733 ++ po/it.po | 960 ++ po/ja.po | 973 ++ stamp-h.in | 1 + subdirs | 3 + 83 files changed, 37255 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 CREDITS create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.cvs create mode 100644 Makefile.dist create mode 100644 README create mode 100644 TODO create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100644 build-howto.html 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/feedback-mail.png create mode 100644 doc/en/index.docbook create mode 100644 doc/en/kdirstat-config-cleanups.png create mode 100644 doc/en/kdirstat-config-tree-colors.png create mode 100644 doc/en/kdirstat-main.png create mode 100644 kdirstat.kdevprj create mode 100644 kdirstat.lsm create mode 100644 kdirstat.spec create mode 100644 kdirstat/Makefile.am create mode 100755 kdirstat/fix_move_to_trash_bin.pl create mode 100644 kdirstat/hi16-app-kdirstat.png create mode 100644 kdirstat/hi32-app-kdirstat.png create mode 100644 kdirstat/kactivitytracker.cpp create mode 100644 kdirstat/kactivitytracker.h create mode 100644 kdirstat/kcleanup.cpp create mode 100644 kdirstat/kcleanup.h create mode 100644 kdirstat/kcleanupcollection.cpp create mode 100644 kdirstat/kcleanupcollection.h create mode 100644 kdirstat/kdirsaver.cpp create mode 100644 kdirstat/kdirsaver.h create mode 100644 kdirstat/kdirstat.desktop create mode 100644 kdirstat/kdirstat.upd create mode 100644 kdirstat/kdirstat_part.rc create mode 100644 kdirstat/kdirstatapp.cpp create mode 100644 kdirstat/kdirstatapp.h create mode 100644 kdirstat/kdirstatfeedback.cpp create mode 100644 kdirstat/kdirstatmain.cpp create mode 100644 kdirstat/kdirstatsettings.cpp create mode 100644 kdirstat/kdirstatsettings.h create mode 100644 kdirstat/kdirstatui.rc create mode 100644 kdirstat/kdirtree.cpp create mode 100644 kdirstat/kdirtree.h create mode 100644 kdirstat/kdirtreeiterators.cpp create mode 100644 kdirstat/kdirtreeiterators.h create mode 100644 kdirstat/kdirtreeview.cpp create mode 100644 kdirstat/kdirtreeview.h create mode 100644 kdirstat/kfeedback.cpp create mode 100644 kdirstat/kfeedback.h create mode 100644 kdirstat/kpacman.cpp create mode 100644 kdirstat/kpacman.h create mode 100644 kdirstat/kstdcleanup.cpp create mode 100644 kdirstat/kstdcleanup.h create mode 100644 kdirstat/ktreemaptile.cpp create mode 100644 kdirstat/ktreemaptile.h create mode 100644 kdirstat/ktreemapview.cpp create mode 100644 kdirstat/ktreemapview.h create mode 100644 kdirstat/lo16-app-kdirstat.png create mode 100644 kdirstat/lo32-app-kdirstat.png create mode 100644 kdirstat/pics/Makefile.am create mode 100644 kdirstat/pics/hi16-action-symlink.png create mode 100644 kdirstat/pics/hi16-action-symlink.xcf create mode 100644 kdirstat/pics/hi32-action-symlink.png create mode 100644 kdirstat/pics/hi48-action-symlink.png create mode 100644 kdirstat/pics/hi48-action-symlink.xcf create mode 100644 kdirstat/pics/lo16-action-symlink.png create mode 100644 po/Makefile.am create mode 100644 po/de.po create mode 100644 po/fr.po create mode 100644 po/hu.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100644 stamp-h.in create mode 100644 subdirs diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..3bbdb0b --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Stefan Hundhammer diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..c7aea18 --- /dev/null +++ b/COPYING @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..778d0bb --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/CREDITS b/CREDITS new file mode 100644 index 0000000..36c3e9c --- /dev/null +++ b/CREDITS @@ -0,0 +1,18 @@ +We would like to thank the following people: + +- Alexander Rawass for implementing the + first version of treemaps for KDirStat (this version has been completely + replaced beginning May 2002). + +- Ben Shneiderman for his ingenious idea of treemaps as an alternative and + truly intuitive way of visualizing trees. + +- All the people at the TU Eindhoven who worked on SequoiaView that gave us the + inspiration for including treemaps in KDirStat and numerous papers describing + the algorithms behind it. + +- Harald Fernengel (harry1701@users.sourceforge.net) for continued support for + integrating KDirStat with new Qt versions. + +- Toyohiro Asukai for Asian support patches. + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..6040b43 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,684 @@ +2005-01-07 Stefan Hundhammer + + * Improved handling of sparse files: + Now adding up only allocated size + + * Improved handling of regular files with multiple links: + Now adding up size / no_links per occurence. + This is much closer to what "du" reports. + + * Extended "own size" column context menu to show sparse files + and regular files with multiple links + + * Reordered "own size" column context menu for consistency: xxx MB (yyy Bytes) + + * Removed currently read path from status line while reading: + Much less flicker, no more constant window resizing, improved performance + + * Added explanations for sparse files and multiple links to online help + + * Bumped version to 2.4.4 + + +2004-12-06 Stefan Hundhammer + + * Added "Open with" cleanup upon request by Jarl Friis + + * Bumped version to 2.4.3 + +2004-11-23 Stefan Hundhammer + + * Migration to KIO slave trash:/ for "move to trash" cleanup + (querying KDE version >= 3.4 at runtime) + + * Added configuration update for safer transition from old-style + fixed "*/Trash" paths to "%t" placeholder + + * Fixed lots of KDE libs "deprecated" warnings + + * Reimported admin/ subdir from a recent KDE version (3.3.0) + + * Bumped version to 2.4.2 + + +2004-03-30 Stefan Hundhammer + + * Fixed KPacMan rendering in toolbar (thanks to Coolo) + + +2004-03-01 Stefan Hundhammer + + * Updated German translation + + +2003-11-13 Stefan Hundhammer + + * Added Italian translation by Giuliano Colla + + +2003-10-29 Stefan Hundhammer + + * Applied i18n patch by Toyohiro Asukai + + * Updated Japanese translation by Toyohiro Asukai + + +2003-10-20 Stefan Hundhammer + + * Fixed some SuSE-internal Autobuild complaints + + * Fixed treemap context menu popup location + + * Bumped version to 2.4.1 + + +2003-09-15 Stefan Hundhammer + + * Added Hungarian translation contributed by + Marcel Hilzinger + +2003-08-26 Stefan Hundhammer + + * Bumped version to 2.4.0 + + * Fixed crash on program end while reading directories + + * Fixed crash on open dir while still reading another directory + + * Added "stop reading" action + + * Added German translation contributed by + Christoph Eckert + + +2003-05-25 Stefan Hundhammer + + * Bumped version to 2.3.7 + + * Performance boost: Directory reading is now 16-20 times faster + because much fewer KDirTreeViewItems are cloned during reading + + * Using QListViewItem::compare() instead of QListViewItem::key() + for better performance: less string operations / numeric formatting + + +2003-04-28 Stefan Hundhammer + + * Added French translation by Michel Grentzinger + + * Don't add up special files (char/block devices, sockets, FIFOs) + + +2003-02-03 Stefan Hundhammer + + * Bumped version to 2.3.6 + + * Fixed crash on startup when no config file present + + +2003-02-02 Stefan Hundhammer + + * Fixed crash in treemap when deleting subtree with cleanup + + * Improved treemap action enabled/disabled state update + + +2003-01-30 Stefan Hundhammer + + * Bumped version to 2.3.5 + + * Colorize treemap tiles (by fixed rules, not customizable yet) + + * Added new '%t' cleanup placeholder for the KDE trash directory + + * Read jobs are now displayed in the percentage bar column + + +2003-01-28 Stefan Hundhammer + + * User cleanups now have an applicaton-wide keyboard shortcut + (Ctrl-0, Ctrl-1, Ctrl-2, ...) + + * Prevent some treemap segfaults when re-reading directories + + +2003-01-14 Stefan Hundhammer + + * Synchronize treemap selection with dir tree after treemap rebuild + +2003-01-08 Stefan Hundhammer + + * Changed activity point handling: The user was prompted far to + early to send feedback mail. + + * Changed treemap double click handling: + Now double clicking the middle button zooms out, + double clicking the right button does nothing + (it pops up the context menu before receiving the second click + anyway) + + * Changed help file accordingly + + +2003-01-07 Stefan Hundhammer + + * Bumped version to 2.3.4 + + * Updated admin subdir to latest KDE autoconf / automake stuff + + * Gcc 3.x fixes + + +2003-01-06 Stefan Hundhammer + + * Tweaked treemap cushion ridges: + Squarified layout row now gets its own ridge, + no more double /triple ridges for directories + + * Changed treemap cushion light source direction from bottom right + to top left + + * Moved min/max/default for treemap settings to central header file + + * Changed max/default treemap setting values + + * Reduced settings dialogs outer borders: + No more accumulated borders + + +2003-01-04 Stefan Hundhammer + + * Added "general" settings page; now user configurable: + - cross file system boundaries + - use local dir read methods + - PacMan animation in toolbar + - PacMan animation ("PacMan armada") in dir tree + + * Added "treemap" settings page: now user configurable: + - plain vs. cushion treemap + - squarified vs. simple treemap + - ambient light + - height scale factor + - force grid + - draw lines upon low contrast + - plain (non-cushioned) treemap colors + - highlight rectangle color + - minimum tile size + - auto-resize treemap + + * Added "open URL" in "file" menu for easier access to remote URLs + + * Bumped version to 2.3.3 + +2003-01-01 Stefan Hundhammer + + * Added treemap actions + * Added treemap menu + * Added treemap context menu + * Improved treemap integration into main application + * Added online help for treemaps + + +2002-12-31 Stefan Hundhammer + + * Lots of small fiddling with treemaps + + +2002-12-28 Stefan Hundhammer + + * Implemented cushion treemaps + + * Bumped version to 2.3.2-devel + + * Changed treemap selection mechanism: + Now using a transparent separate rectangle so even the outline + of entire directories can clearly be seen. + +2002-12-27 Stefan Hundhammer + + * Added treemap mouse operations: + - select item in tree view (single click left) + - zoom in (double-click left) + - zoom out (double-click right) + - rebuild treemap in visible area (double-click middle) + + * Added visible selection in treemap + + * Select treemap tile when tree item is selected + + +2002-12-26 Stefan Hundhammer + + * Implemented squarified treemaps. + Now there are no longer lots of elongated, thin rectangles that + are hard to compare against each other and hard to point at. + + +2002-12-23 Stefan Hundhammer + + * Changed treemap handling completely: Now using QCanvas. + + * Bumped version to 2.3.1-devel + +2002-05-12 Stefan Hundhammer + + * Initial version of new treemaps + + * Communication between treemap view and tree view + + * Bumped version to 2.3.0-devel + +2002-05-10 Stefan Hundhammer + + * Removed support for old treemaps + + * Updated build-howto.html + +2002-05-09 Stefan Hundhammer + + * Bumped version to 2.2.0 + The KDE3 port proved stable enough to warrant a new stable + version. + +2002-04-23 Stefan Hundhammer + + * Bumped version to 2.1.1-beta + + * Added Japanese translation by + Toyohiro Asukai + + * Applied another Asian lang support patch by + Toyohiro Asukai : + QString::sprintf() -> QString::arg() + +2002-04-22 Stefan Hundhammer + + * Applied Asian language support patch by + Toyohiro Asukai : + Somme missing QString::fromLocal8Bit() issues + +2002-04-18 Stefan Hundhammer + + * KDE-3 migration: + - Replaced admin/ subdirectory completely + * Bumped version to 2.1.0-beta + +2002-03-01 Stefan Hundhammer + + * Bumped version to 2.0.1 + * Added large file (>2GB) support + +2002-02-24 Stefan Hundhammer + + * Bumped version to 2.0.0 - the real release version + * Completed help texts + * Added "Help" button to feedback dialog + * Added "Help" button to settings dialog + * Drastically reduced logging to stdout + +2002-02-11 Stefan Hundhammer + + * Prevent crash: Disable cleanups that modify the subtree while it + is still being read + +2002-02-10 Stefan Hundhammer + + * Fixed double slashes in URLs when opening with file selection box + * Bumped version to 1.8.7-rc2 + +2002-02-09 Stefan Hundhammer + + * Fixed huge numbers overflow in details context popup + * Fixed huge numbers sorting + * Added new action "continue reading at mount point". + This is essentially the same as "refreshing selected branch", + but it's more intuitive to use. + +2002-02-02 Stefan Hundhammer + + * Initial help documentation + * Bumped version to 1.8.6-rc1 + This is the first release candidate. + The final version will be released as 2.0 + +2002-01-27 Stefan Hundhammer + + * Fixed update bug upon "refresh branch" and executing cleanups + * Embed cleanup %p / %n parameters in double quotes + * Added keyboard accelerators for standard cleanups + * (Partial) fix for PacMan animation display error on some KDE themes + * Bumped version to 1.8.5-beta + +2002-01-19 Stefan Hundhammer + + * Added feedback mail facility + * Bumped version to 1.8.4-beta + +2002-01-10 Stefan Hundhammer + + * Fixed repaint error in percentage bar column when scrolling + * Fixed repaint error when resizing percentage bar column + +2002-01-04 Stefan Hundhammer + + * Bumped version to 1.8.3-beta + The new KDirStat is now as complete as the old one ever was! + + * Added simple 'mail to owner' report + * Implemented cleanup configuration + * Added 'ask for confirmation' flag to cleanups + * Added 'works for local files only' flag to cleanups + * Fixed URL handling: Always strip off trailing slash + * Fixed app icon + * Fixed .desktop file - KDirStat is now in 'Utilities' + +2002-01-03 Stefan Hundhammer + + * Implemented save/read configuration + * Updated TODO list - gosh, was this thing outdated! + * kdDebug() operator << for KCleanup + * kdDebug() operator << for KDirTreeViewItem + + +2002-01-02 Stefan Hundhammer + + * Implemented 'settings' dialog + * Implemented 'tree colors' settings + + +2002-01-01 Stefan Hundhammer + + * Implemented / completed KCleanupCollection + * Fixed some core dumps (oops) + + +2001-12-31 Stefan Hundhammer + + * kdDebug() operator<< for KFileInfo + + +2001-12-30 Stefan Hundhammer + + * Bumped version to 1.8.2-beta + * Cleanups are back! + + +2001-12-26 Stefan Hundhammer + + * Mount point remains marked as mount point even after + "refresh selected branch" + + * KFileInfo / KDirInfo now have direct access to their + KDirTree (i.e. they now have their own pointer) + => transparent access from outside easier + + +2001-12-08 Stefan Hundhammer + + * Tree colors are back again + + * Transparently handle selections in the KDirTree; + all kinds of views should benefit from that. + + +2001-11-25 Stefan Hundhammer + + * Bumped version to 1.8.0-beta + + * Added "Refresh selected" to main + context menu + + * Implemented refreshing a single branch + + * Many internal changes to enable deleting subtrees + (this is a requirement for cleanups) + + * Internal cleanup: Got rid of that statRoot() mess, + clean ??::stat() implementation for all directory readers + + +2001-11-18 Stefan Hundhammer + + * Bumped version to 1.7.11-devel + + * Improved mount point handling: + * Different icon, + * New read status KDirOnRequestOnly + * Prepared for explicit reading of mounted file systems + + * Created infrastructure for context menu in tree view + + * Simple context menu (cleanup actions will follow) + + +2001-11-17 Stefan Hundhammer + + * Moved treemap sources to separate subdirectory to prevent that + too-clever admin/am_edit script from breaking things: It always + uses all available sources rather than just those in + Makefile.am. + + * Changed default from --enable-treemaps to --disable-treemaps + since treemaps don't compile and link for more than 6 weeks now. + + * Updated build-howto.html + + +2001-10-22 Harald Fernengel (harry1701@users.sourceforge.net) + + * make it work with Qt 3 / KDE 3 + +2001-09-26 Alexander Rawass + + * committed Makefile.am from kdirstat-1-7-10-devel + +2001-09-26 Alexander Rawass + + * debugging output in kparts + +2001-09-25 Alexander Rawass + + * added files kdirstat_{part,factory}.{cpp,h,rc} + * trying to make a kpart of kdirstat + * libtool does not work for me yet + +2001-08-20 Alexander Rawass + + * modified configure.in.in to test for libqtreemap + test may not work on some/most systems + +2001-08-18 Alexander Rawass + + * V1.7.8-devel + * added kdirstat.spec (to build rpms) + * released kdirstat-1.7.8-1.i386.rpm + +2001-08-17 Alexander Rawass + + * removed files q*{cpp,h} from cvs + * removed doc/treemaps from cvs + * modified configure.in and kdirstat/Makefile.am + * QTreeMap is now in it's own cvs qtreemap.sourceforge.net + +2001-08-11 Alexander Rawass + + * QTreeMap can write data files for 'HypView', + a hyperbolic tree browser + +2001-08-09 Alexander Rawass + + * changed all size-functions from int to asize/float + * qxmltreemap: if a node has got an empty attribute 'size', + the size is calculated recursively + + * new files & classes + qlistviewtreemapwindow.cpp + qlistviewtreemapwindow.h + qlistviewtreemaparea.cpp + qlistviewtreemap.h + qxmltreemapviewer.cpp + + * files q*treemap* are built as a library libqtreemap + * new qxmltreemapviewer binary: + stand-alone QT/Xml Treemap Viewer + * QTreeMap/QListViewTreeMapArea works fine with KProf + +2001-08-09 Stefan Hundhammer + + * Added "credits" section in about box + +2001-08-08 Stefan Hundhammer + + * Implemented iterator classes: KFileInfoIterator and + KFileInfoSortedIterator + * Added CREDITS file + +2001-08-06 Stefan Hundhammer + + * Fixed segfaults due to bad dot entry cleanup (huh? ;-) ) that + had caused core dumps after finishing reading small trees + +2001-08-05 Alexander Rawass + + * compiler warnings removed + * using List of Objects (instead List of KDirInfo) + * Bug: regexps not working in xml-window + selection not working in xml-window + * removed dependencies to KDirStat from QTreeMap + +2001-07-29 Alexander Rawass + + * load XML working (with memory hole) + +2001-07-28 Alexander Rawass + + * new sort of treemap/drawing mode: piemap + added file qtreemaparea_piemap.cpp + will not get checked in until legal problems solved + * checkmarks work also for paintmode + + * new options for piemap mode + * bitmap can be saved to a file + * tree can be saved as xml file + + * new files & classes + qxmltreemapwindow.cpp + qxmltreemapwindow.h + qxmltreemaparea.cpp + qxmltreemap.h + (don't work yet) + + * new defines for compilation: + HAVE_PIEMAP if you have the piemap source + EXPERIMENTAL if you want to see more options + +2001-07-17 Alexander Rawass + + * user can use keywords instead of numbers for options + * checkmarks start working + * yet only with drawmode + +2001-07-16 Alexander Rawass + + * user can now use regexps or wildcards in config + * regexps are now compiled only once at startup + * wildcards are working correctly + * regexps need 3 /// backslashes in kdirstatrc + * Feature: the color list is parsed in alphabetic sort + +2001-07-14 Alexander Rawass + + * KDirTreeMapWindow reads out configuration with KConfig + * Bug: regexps are not working correctly + +2001-07-13 Alexander Rawass + + * user can click on rectangles and select/deselect them + * those rectangles are stored in a list and appear + at the bottom of the right-button popupmenu + +2001-07-12 Alexander Rawass + + * user can search for regexp, matches get highlighted + * current_dir_display working again + +2001-07-11 Alexander Rawass + + * new shading: image (sensible only with squarify) + displays pictures, can be used as picture browser + * removed most warnings + +2001-07-11 Alexander Rawass + + * various bugs fixed in squarified treemaps: + correct end of recursion + using floats rather than ints to prevent miscalc. + should work now???? + * new hierarchical shadings + + +2001-07-10 Alexander Rawass + + * implemented squarified treemaps (experimental, buggy) + * new file added: qtreemaparea_squarify.cpp + * Bug: when zooming in too much, the paintarea takes up too much + memory -> X swaps till death + +2001-07-05 Alexander Rawass + + * more options and exp. shadings + * experimental dynamic shading (not working) + * user can watch treemap build up + * paintEntry moved to qtreemaparea_paint.cpp + * drawTreeMap,drawDuTree,CTM moved to qtreemaparea_recursion.cpp + * renamed some of the shadings and + * wrote some Documentation how to use Shadings and Options + + +2001-07-03 Alexander Rawass + + * QTreeMapWindow is now an abstract class + * KDirTreeMapWindow implements makeTreeMapWidget() + * experimental hierach. cushion + * new menu options (experimental & debugging) + * new way to make a border (border_step) + * CTM (Cushion Treemap) test routine added (not working yet) + * new Bug: I'm getting warnings about wrong RGB parameters, + even in flat mode + + +2001-07-01 Alexander Rawass + + * QTreeMapArea is now a general abstract class to display hierarchies of any kind (not connected to KDirStat anymore) + * KDirTreeMapArea is the implementation for KDirStat + * new Bug: signals/slot not working correctly + * Bug fixed: crashed when telling kdirstat to display a directory which does not exist + + +2001-06-29 Stefan Hundhammer + + * Moved CVS to SourceForge + +2001-06-24 Alexander Rawass + + * V1.7.6-Devel + * Removed Zoom Bug + * Removed DM_FILES Bug + * Faster shading (dirs are always drawn flat) + * New directory coloring (shades of grey) + * Options for start direction, border width, draw text + * Removed most compiler warnings + +2001-06-18 Stefan Hundhammer + + * V1.7.3-Devel + * Applied first treemap patch from + Alexander Rawass + * Added Alexander Rawass to authors list + * Improved treemap repaint behaviour (not perfect yet) + +2001-06-17 Stefan Hundhammer + + * V1.7.2-Alpha + * Implemented support for all of KDE's IO protocols (ftp, smb, ...) + * Fixed PacMan warnings on premature exit + 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..6c7afac --- /dev/null +++ b/Makefile.am @@ -0,0 +1,48 @@ +# Toplevel Makefile.am for KDirStat +# +# Originally generated by KDevelop, modified by sh@suse.de +# + +SUBDIRS = kdirstat po doc + +EXTRA_DIST = \ + AUTHORS \ + COPYING \ + COPYING.LIB \ + CREDITS \ + ChangeLog \ + INSTALL \ + README \ + TODO \ + admin \ + build-howto.html \ + kdirstat.kdevprj \ + kdirstat.lsm + + +# This is not a GNU package. You can remove this line +# if have all needed files a GNU package needs. +AUTOMAKE_OPTIONS = foreign + +CLEANFILES = $(wildcard autom4te.cache/*) + +$(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 + + +dist-hook: + cd $(top_distdir) && perl admin/am_edit -padmin + cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs + diff --git a/Makefile.cvs b/Makefile.cvs new file mode 100644 index 0000000..be59a86 --- /dev/null +++ b/Makefile.cvs @@ -0,0 +1,14 @@ +all: + @echo "This Makefile is only for the CVS repository" + @echo "This will be deleted before making the distribution" + @echo "" + @if test ! -d admin; then \ + echo "Please recheckout this module!" ;\ + echo "for cvs: use checkout once and after that update again" ;\ + echo "for cvsup: checkout kde-common from cvsup and" ;\ + echo " link kde-common/admin to ./admin" ;\ + exit 1 ;\ + fi + $(MAKE) -f admin/Makefile.common cvs + +.SILENT: diff --git a/Makefile.dist b/Makefile.dist new file mode 100644 index 0000000..be59a86 --- /dev/null +++ b/Makefile.dist @@ -0,0 +1,14 @@ +all: + @echo "This Makefile is only for the CVS repository" + @echo "This will be deleted before making the distribution" + @echo "" + @if test ! -d admin; then \ + echo "Please recheckout this module!" ;\ + echo "for cvs: use checkout once and after that update again" ;\ + echo "for cvsup: checkout kde-common from cvsup and" ;\ + echo " link kde-common/admin to ./admin" ;\ + exit 1 ;\ + fi + $(MAKE) -f admin/Makefile.common cvs + +.SILENT: diff --git a/README b/README new file mode 100644 index 0000000..193f6cc --- /dev/null +++ b/README @@ -0,0 +1,20 @@ +This is a graphical "du" (disk usage) display. + +What you see here is a 90% rewrite - GUI, engine, everything. The one thing it +can do a whole lot better than the old version is stay on one file system - the +single most most requested feature. Plus, it's way faster for large directory +trees - scanning an entire Linux file system no longer takes 30+ +minutes. Rather, it's about 2-3 minutes: The old version seemed to have +problems with system buffer thrashing due to too many directories open for +reading at one time - the new version uses an internal queue and keeps only one +directory open. + +For more details, see the KDirStat home page at + + http://kdirstat.sourceforge.net/ + + + +Stefan Hundhammer +2002-05-10 + diff --git a/TODO b/TODO new file mode 100644 index 0000000..3dde3dd --- /dev/null +++ b/TODO @@ -0,0 +1,52 @@ + TODO list for KDirStat + ======================== + Updated: 2005-01-07 + +- help text for "treemap" settings + +- help text for "general" settings + +- update screen shots in online help (no treemaps yet) + +- make KDirStat a KPart + + + +Maybe: +====== + +- German help file + +- Animation other than pacman (optional?) + +- configure mail report texts (the user gets an editor in the mailer anyway) + +- 'kdf' like 'disk free' display for file system of current tree - pie, bar graph? + Steal that thing from the SuSE YaST2 package manager UI I wrote? + (which, in turn, I stole in large parts from KDirStat) + +- Filter on tree view: by user, by mtime, by size + +- Select items in the tree view as "special interest" for further processing in mail reports + +- Manually mark dir subtrees as "static" - e.g., for system directories that + almost never change anyway; scan them just once and save their sizes to file; + only rescan those subtrees on explicit user request + +- Automagically mark such subtrees by mtime and/or a hardwired list + + + + +Postponed until further notice: +=============================== + +- write scanned trees to cache file for later reuse; + use this cache file first and then begin scanning the dir tree. + + Since the Linux 2.4 kernel is great at caching directory entries, + this isn't really necessary for Linux - and I am a Linux guy... + ;-) + + + diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..38bdc44 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,11360 @@ +## -*- 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(, [${x_direct_test_function}()], +[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 + if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then + kde32ornewer= + else + if test "$kde_qtver" = "3" && test "$kde_qtsubver" -le 1; then + kde32ornewer= + 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 + KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin], [XMLLINT=""]) + + if test -n "$MEINPROC" && test ! "$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") + + # 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 + +# 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 +) + +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" + +# 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 + +if test -z "$LIBQT"; then +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" +else + kde_int_qt="$LIBQT" + kde_lib_qt_set=yes +fi + +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 + if test -z "$LIBQT"; then + LIBQT="-l$qtlib-mt" + kde_int_qt="-l$qtlib-mt" + else + LIBQT="$qtlib-mt" + kde_int_qt="$qtlib-mt" + fi + 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="$all_libraries $QT_LDFLAGS" +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.]) +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) +]) + +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="$all_libraries $KDE_LDFLAGS" +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 + AC_SUBST(LIB_KDECORE, "-lkdecore") + AC_SUBST(LIB_KDEUI, "-lkdeui") + AC_SUBST(LIB_KIO, "-lkio") + 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") +# 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_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( +[/* Override any gcc2 internal prototype to avoid an error. */ +struct jpeg_decompress_struct; +typedef struct jpeg_decompress_struct * j_decompress_ptr; +typedef int size_t; +#ifdef __cplusplus +extern "C" { +#endif + void jpeg_CreateDecompress(j_decompress_ptr cinfo, + int version, size_t structsize); +#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. */ +], + [jpeg_CreateDecompress(0L, 0, 0);], + 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([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 +]) + +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 similiar]), + [ + 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 + + 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 -Wwrite-strings $CXXFLAGS" + case $host in + *-*-linux-gnu) + CFLAGS="-ansi -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"]) + KDE_CHECK_COMPILER_FLAG(Wnon-virtual-dtor,[CXXFLAGS="-Wnon-virtual-dtor $CXXFLAGS"]) + fi + fi + + if test "$GXX" = "yes" && test "$kde_use_strict_options" = "yes"; then + CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS" + fi + + 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" + fi + 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= ) + + AC_ARG_ENABLE(pch, + AC_HELP_STRING([--enable-pch], + [enables precompiled header support (currently only KCC) [default=no]]), + [ + kde_use_pch=$enableval + ],[kde_use_pch=no]) + + 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_SUBST(NOOPT_CXXFLAGS) + AC_SUBST(NOOPT_CFLAGS) + AC_SUBST(ENABLE_PERMISSIVE_FLAG) + + KDE_CHECK_FINAL + KDE_CHECK_CLOSURE + KDE_CHECK_NMCHECK + + ifdef([AM_DEPENDENCIES], AC_REQUIRE([KDE_ADD_DEPENDENCIES]), []) +]) + +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) + +# 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 \$(kde_libraries)" + + 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 -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", [ + LDFLAGS="$ac_save_ldflags" + CFLAGS="$ac_save_cflags" + LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries -lX11 -lXext $LIBSOCKET" + LIBS="$LIBS -lXdpms" + 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="-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 ]) + AH_TEMPLATE(HAVE_DPMSINFO_PROTO, + [Define if you have the DPMSInfo prototype in ]) + AC_CHECK_DECL(DPMSInfo, + AC_DEFINE(HAVE_DPMSINFO_PROTO),, + [#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" + LDFLAGS="$LDFLAGS $GL_LDFLAGS $X_LDFLAGS $all_libraries -lMesaGL -lMesaGLU" + test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LDFLAGS="$LDFLAGS -lX11" + LDFLAGS="$LDFLAGS $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="mesa", ac_cv_have_gl="no") + if test "x$ac_cv_have_gl" = "xno"; then + LDFLAGS="$ac_save_ldflags $X_LDFLAGS $GL_LDFLAGS $all_libraries -lGLU -lGL" + test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LDFLAGS="$LDFLAGS -lX11" + LDFLAGS="$LDFLAGS $LIB_XEXT -lm $LIBSOCKET" + CXXFLAGS="$ac_save_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") + fi + AC_LANG_RESTORE + LDFLAGS="$ac_save_ldflags" + CXXFLAGS="$ac_save_cxxflags" + ])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 + if test "$ac_cv_have_gl" = "mesa"; then + GLLIB='-lMesaGLU -lMesaGL $(LIB_X11)' + else + GLLIB='-lGLU -lGL $(LIB_X11)' + fi + else + if test "$ac_cv_have_gl" = "mesa"; then + GLLIB="$GL_LDFLAGS -lMesaGLU -lMesaGL "'$(LIB_X11)' + else + GLLIB="$GL_LDFLAGS -lGLU -lGL "'$(LIB_X11)' + fi + 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], +[ + 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 + + 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.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 similiar to libstd++-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" + +if test ! -s $srcdir/subdirs; then + dnl Note: Makefile.common creates subdirs, so this is just a fallback + TOPSUBDIRS="" + 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], +[ + AC_LANG_SAVE + kde_safe_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $all_includes" + AC_LANG_CPLUSPLUS + AC_CHECK_HEADER([$1], [$2], [$3], [$4]) + CPPFLAGS=$kde_safe_cppflags + AC_LANG_RESTORE +]) + +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,/$,,'` + kde_libs_htmldir=$prefix/share/doc/HTML/ + exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + 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 + +]) +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# 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 And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +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_F77])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([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(AR, ar, false) +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 + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([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. +compiler=$CC +])# _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_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _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], +[_LT_AC_SHELL_INIT([ +# 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) +])])# _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 + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + 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 + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # 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.o`" in + *32-bit*) + LINUX_64_MODE="32" + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + LINUX_64_MODE="64" + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + 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 + ;; +AC_PROVIDE_IFELSE([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) + ;; + ]) +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_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && 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 + $2=yes + fi + fi + $rm conftest* +]) + +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" + printf "$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 $build_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; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + *) + # 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 + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + 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 + printf "$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 . + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && 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 + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + 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)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; 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 +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +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= +shrext=".so" +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}${shared_ext}$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}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + 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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + 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}${shared_ext}$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}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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 + shrext=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-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 + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $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 + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +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}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$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}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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 + case "$host_cpu" in + ia64*) + shrext='.so' + 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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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 + ;; + hppa*64*) + shrext='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext='.sl' + 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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # 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 ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + 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}" + hardcode_into_libs=yes + ;; + +# 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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + 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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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}${shared_ext}$versuffix ${libname}${shared_ext}$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' + shrext=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $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}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + 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}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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}${shared_ext}$versuffix ${libname}${shared_ext}$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}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=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${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$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 @<:@automatic@:>@])], + [tagnames="$withval"]) + +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) + if test -n "$CXX" && test "X$CXX" != "Xno"; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + 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. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + 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_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +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 pathname 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([LT_AC_PROG_SED])dnl +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 $CC]) + 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 pathname 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. + case `"$lt_cv_path_LD" -v 2>&1 &1 /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 + case "$host_cpu" in + ia64*) + 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 + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + 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 + ;; + esac + ;; + +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* | 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]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + 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 + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + 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 pathname 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 + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + 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 + ;; + esac + esac + 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* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, 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, lt_dlinit, + [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 + + +# 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_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# 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_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# -------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}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;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_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 " | grep "[[ ]]$]_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_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +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 + ;; + darwin* | rhapsody*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + test -z ${LD_TWOLEVEL_NAMESPACE} && _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + esac + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + else + _LT_AC_TAGVAR(ld_shlibs, $1)=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_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_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)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# 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;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# 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 +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_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 + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _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" | \ + grep '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 -nostdlib $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 | grep "\-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 + ;; + + 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)=no + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + darwin* | rhapsody*) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + test -z ${LD_TWOLEVEL_NAMESPACE} && _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + esac + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + 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*) + ;; + hpux9*) + _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' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _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) + _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' + # 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 + _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' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + *) + _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' + ;; + esac + fi + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _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' + ;; + 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) | grep "\-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_cpu" in + ia64*|hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _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' + ;; + 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 $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$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)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.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$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; 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*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _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 + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + 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)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.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 | grep "\-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)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.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 "%s %s\\n" -exported_symbol "\$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 | grep "\-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 | grep "\-[[LR]]"`; 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 | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_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 $compiler_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 | grep \"\-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 $compiler_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 $compiler_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 | grep \"\-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 + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## 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_POSTDEP_PREDEP($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_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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. + +# A sed program that does not truncate output. +SED=$lt_SED + +# 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 disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $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) + +# An ERE matcher. +EGREP=$lt_EGREP + +# 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 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" + +# Shared library suffix (normally ".so"). +shrext='$shrext' + +# 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 used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# 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) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $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${shared_ext} 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) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $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 + ;; + 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], [], + [_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]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_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. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGISTW]]' ;; +esac + +# 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 grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' 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* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # 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 and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _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" + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + 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* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + 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 and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _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 + ;; + + 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,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # 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*) + case $CC in + icc* | ecc*) + _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' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + 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*) + _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' + ;; + + 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)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -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)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -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 | grep '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 + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _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(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $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_flag_spec_ld, $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(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _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 extended regexp 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 | grep ': 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)=no + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + 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 $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' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep '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 | grep ': 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 | grep ': 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' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep '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 + 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 | grep '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)=no + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext=".dll" + # 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"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + if test "$GXX" = yes ; then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + test -z ${LD_TWOLEVEL_NAMESPACE} && _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + esac + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + 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*) + if test "$GCC" = yes; then + _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' + else + _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' + fi + _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 + + # 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' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _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 + + # 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(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # 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 + ;; + esac + fi + ;; + + 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' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + 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 $compiler_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 $compiler_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 "%s %s\\n" -exported_symbol "\$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) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _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 + ;; + esac + 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? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _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* + printf "$lt_simple_compile_test_code" > 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 + ;; +esac +])# 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_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && break + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_MSG_RESULT([$SED]) +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..264f8fa --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1045 @@ +# generated automatically by aclocal 1.9.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# 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. + +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + +# 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. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.1])]) + +# AM_AUX_DIR_EXPAND + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# 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 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 6 + +# 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]) +AC_SUBST([$1_FALSE]) +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])]) + +# serial 7 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + + +# 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], 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/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]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +#serial 2 + +# _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. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /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"]) +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 7 + +# 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 -*- + +# 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. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 11 + +# 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.58])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 +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +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 + 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 +]) +]) + + +# 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_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 1 + +# 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])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 2 + +# 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 +]) + +# -*- Autoconf -*- + + +# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 3 + +# 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 +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 +]) + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. + +# Copyright (C) 2003, 2004 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 2 + +# _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. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 3 + +# 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)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# 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="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 Free Software Foundation, Inc. + +# 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# serial 1 + + +# _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/build-howto.html b/build-howto.html new file mode 100644 index 0000000..ea247f4 --- /dev/null +++ b/build-howto.html @@ -0,0 +1,191 @@ + + + + + Building KDirStat for KDE 3.x + + + + + + + + + + +
+ Last modified: 23 Nov 2004 + + Contact: Stefan Hundhammer +
+ + +

Building KDirStat for KDE 3.x

+ + + + + + +

Note:

+If you are using the +latest +SuSE Linux +, you may not have to build it at all. +There usually is an RPM package you can use at the +download area. +See also the KDirStat home page. +
+ +
    +
  • +Get the latest sources - either the +tarball from the download area +or via +anonymous CVS from SourceForge. +


    +
  • + +
  • +Make sure you have a development system up and running. + +

    +You'll need at least: + +

      +
    • A C++ compiler +
    • Header files for the system libs +
    • X11 development environment (libs and header files) +
    • Qt 3.0 (or later) development environment +
    • KDE 3.x development environment +
    + +

    +- maybe more. If you are unsure and you are running SuSE Linux, it might be +a good idea to install the development system selection. +

    + +

    +Please understand that I cannot and will not fix everybody's broken development +systems any more - this had taken me quite some time with KDirStat 0.8x. Please +make sure you can compile simple KDE programs like kless or +kexample before contacting me about build problems. +

    +
  • +
    + +
  • Unpack the sources: +
    +
    +
    +    tar xjvf kdirstat-2.4.2.tar.bz2
    +
    +
    +

    +(or whatever version you downloaded) +

    +


    +
  • + +
  • +Go to this directory: +
    +
    +
    +    cd kdirstat-2.4.2
    +
    +
    +
  • + +
  • +Make sure I didn't accidentially include a config.cache file in the +tarball - remove it to make sure. This is a neverending cause of trouble. +
    +
    +
    +    rm -f config.cache
    +
    +
    +
  • + + +
  • +Let the configure script figure out where everything required is on +your system. +

    +Watch out for error messages and fix them before reporting +errors! +

    + +

    On SuSE Linux systems, KDE 3.x is installed to /opt/kde3 which is a +good idea if you want to keep some KDE 1.x/2.x programs around. So use that +/opt/kde3 prefix for KDirStat, too - otherwise it will be installed to +/opt/kde and clutter up a working KDE 1.x/2.x environment. +
    +

    +
    +    ./configure --prefix=/opt/kde3
    +
    +
    +

    +If you don't care about that or if you set up KDE 3.x in /opt/kde +anyway, simply type +

    +
    +
    +    ./configure
    +
    +
    +
  • + +
  • +Compile everything: +
    +
    +
    +    make
    +
    +
    +

    +Again, watch out for error messages. +

    +

    +
    +

    +
  • + +
  • +If everything worked out allright, become root and install the program +and everything it needs: +
    +
    +
    +    su
    +    make install
    +
    +
    +

    +Don't do this if the previous step reported errors! +

    +
  • + +
+ +

+That's it. +

+ + + + + + + + + + + + + + + diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..1a7d2f2 --- /dev/null +++ b/config.h.in @@ -0,0 +1,243 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* 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 if you have long long as datatype */ +#undef HAVE_LONG_LONG + +/* 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 + +/* 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 a `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of a `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of a `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of a `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of a `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of a `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 + +/* + * 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 + + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + + +#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 + + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + + +/* + * 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..2f1bf62 --- /dev/null +++ b/configure.in @@ -0,0 +1,109 @@ +dnl ======================================================= +dnl FILE: ./admin/configure.in.min +dnl ======================================================= + +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., 51 Franklin Street, Fifth Floor, +dnl Boston, MA 02110-1301, 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(kdirstat, 2.4.4) 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 + +dnl KDE_USE_QT +AC_PATH_KDE +dnl ======================================================= +dnl FILE: configure.in.in +dnl ======================================================= + +#MIN_CONFIG + +dnl PACKAGE set before + +AC_SYS_LARGEFILE +KDE_CHECK_LONG_LONG +KDE_CREATE_SUBDIRSLIST +AC_CONFIG_FILES([ Makefile ]) +AC_CONFIG_FILES([ doc/Makefile ]) +AC_CONFIG_FILES([ doc/en/Makefile ]) +AC_CONFIG_FILES([ kdirstat/Makefile ]) +AC_CONFIG_FILES([ kdirstat/pics/Makefile ]) +AC_CONFIG_FILES([ po/Makefile ]) +AC_OUTPUT +# Check if KDE_SET_PREFIX was called, and --prefix was passed to configure +if test -n "$kde_libs_prefix" -a -n "$given_prefix"; then + # And if so, warn when they don't match + if test "$kde_libs_prefix" != "$given_prefix"; then + # And if kde doesn't know about the prefix yet + echo ":"`kde-config --path exe`":" | grep ":$given_prefix/bin/:" 2>&1 >/dev/null + if test $? -ne 0; then + echo "" + echo "Warning: you chose to install this package in $given_prefix," + echo "but KDE was found in $kde_libs_prefix." + echo "For this to work, you will need to tell KDE about the new prefix, by ensuring" + echo "that KDEDIRS contains it, e.g. export KDEDIRS=$given_prefix:$kde_libs_prefix" + echo "Then restart KDE." + echo "" + fi + fi +fi + +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..ffca859 --- /dev/null +++ b/configure.in.in @@ -0,0 +1,6 @@ +#MIN_CONFIG + +AM_INIT_AUTOMAKE(kdirstat,2.4.4) + +AC_SYS_LARGEFILE +KDE_CHECK_LONG_LONG diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..8eb3435 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = en + diff --git a/doc/en/Makefile.am b/doc/en/Makefile.am new file mode 100644 index 0000000..bcc478a --- /dev/null +++ b/doc/en/Makefile.am @@ -0,0 +1,11 @@ + +EXTRA_DIST = \ + index.docbook \ + kdirstat-main.png \ + kdirstat-config-cleanups.png \ + kdirstat-config-tree-colors.png \ + feedback-mail.png + +KDE_LANG = en +KDE_DOCS = kdirstat + diff --git a/doc/en/feedback-mail.png b/doc/en/feedback-mail.png new file mode 100644 index 0000000000000000000000000000000000000000..977910dd8937c45cff8aa1ce18af37feaf5ec1bf GIT binary patch literal 14538 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 literal 0 HcmV?d00001 diff --git a/doc/en/index.docbook b/doc/en/index.docbook new file mode 100644 index 0000000..6076630 --- /dev/null +++ b/doc/en/index.docbook @@ -0,0 +1,1954 @@ + +KDirStat'> + + + + + + +]> + + + + + + + + + + + + + +The KDirStat Handbook + + + +Stefan +Hundhammer + +
sh@suse.de
+
+
+
+ + + + +1999-2005 +Stefan Hundhammer + + + +&FDLNotice; + + + +02/02/2002 +0.1.01 + + + + + + +&kdirstat; is a graphical disk usage utility, very much like the Unix "du" command, +plus some cleanup facilities to reclaim disk space. + + + + + + +KDE +kdeutils +utilities +file system +disk usage +cleanup + + +
+ + + + + + + +Overview + + + + +&kapp; is a graphical disk usage utility. It shows you where all your disk +space has gone and tries to help clean it up. + + + + +Screen Shot + + + + +The &kapp; main window + + + + + + Main window screenshot + + + + + + + + + + +Features + + +Display Features + + + +Graphical and numeric display of used disk space + + + +Treemap display of used disk space + + + +Files kept apart from directories in separate <Files> items to prevent +cluttering the display + + + + +All numbers displayed human readable - e.g., 34.4 MB instead of 36116381 Bytes + + + + +Reasonable handling of sparse files - only blocks that are actually allocated +are added up to the total sums. + + + + +Reasonable handling of (regular) files with multiple hard links - their size is +divided by their number of hard links, thus evenly distributing their size over +the directories they are linked to -- and, more importantly, not adding the same +file up several times. + + + + +Different colors in the directory tree display to keep the different tree +levels visually apart + + + + +Display of latest change time within an entire directory tree - you can easily +see what object was changed last and when. + + + + + + +Directory Reading + + + + +Stays on one file system by default - reads mounted file systems only on +request. + + +You don't care about a mounted /usr file system if the root file +system is full and you need to find out why in a hurry, nor do you want to scan +everybody's home directory on the NFS server when your local disk is full. + + + + + +Network transparency: Scan FTP or Samba directories - or whatever else +protocols KDE support. + + + +PacMan animation while directories are being read. +OK, this is not exactly essential, but it's fun. + + + + + + + +Cleaning up + + + +Predefined cleanup actions: Easily delete a file or a directory tree, move it +to the KDE trash bin, compress it to a .tar.bz2 archive or simply open a shell +or a Konqueror window there. + + + + +User-defined cleanup actions: Add your own cleanup commands or edit the +existing ones. + + + +"Send mail to owner" report facility: Send a mail requesting the owner +of a large directory tree to please clean up unused files. + + + + + + + +Misc + + + +Feedback mail facility: Rate the program and tell the authors your opinion +about it. + + + + + + + + + +More Sceen Shots + + +Configuring cleanup actions + + +Configuring cleanup actions + + + + + + Configure cleanup actions window screenshot + + + + + + + +Configuring tree colors + + +Configuring tree colors + + + + + + Configure tree colors window screenshot + + + + + + +Feedback mail + + +Feedback mail + + + + + + Feedback mail window screenshot + + + + + + + + + + + + + +Basic Usage + + +Invoke &kdirstat; + + +Start &kdirstat; from the KDE menu, right-click a directory in a +Konqueror window or type +kdirstat or +kdirstat <directory-name> in a shell +window or at KDE's Run command prompt +(Alt-F2). + + + + +Select a Directory + + +&kdirstat; will prompt for a directory if you didn't specify one when starting +it. You can specify local directories as well as URLs of remote locations - +kdirstat /usr/lib works as well as +kdirstat ftp:/ftp.myserver.org/pub. + + +In any case, &kdirstat; will start reading that directory. That might take a +while, but you can work with the program during all that time. + + + + +Find out what Uses up all the Disk Space + + +Look at the "Subtree Total" column or wait until a subtree is finished reading +and look at the graphical percentage bar display to find out what directory +subtee takes up how much disk space. Use the open / close icons (plus and minus +signs or small arrows, depending on how you set up your KDE) or double-click an +item to open or close it. + + +Notice how files at any directory level are kept apart from subdirectories - +there is a separate <Files> entry for them. This way, you can easily tell +how much disk space the files are using up in relation to the subdirectories +and their respective files. + + + + +Do Something about it + + +Once you found out where all your disk space goes, do something about it - this +is probably why you are using this program in the first place. You have several +options: + + + + + +Go to a computer hardware store and buy a new hard disk. +This is probably not what you want. ;-) + + + + +Tell the owner of that file or directory to please clean up. +You can use &kdirstat; for that: Mark that file or directory (i.e., left-click +on it) and select Send Mail to Owner +from the context menu (right-click), from the tool bar (the envelope icon) or +from the Report menu. + + +A precomposed message will open in your +favourite mail client. +You can edit that text before actually sending it. The recipient of +the mail is the user who owns the file or directory you marked - but of course +you can edit that, too in the mail client. + + +The mail will contain those items that are currently displayed open from the +marked item on. If you want to include more items, open the respective +directories; if you want less, close them. Of course you can always delete +lines in the mail client if you find them irrelevant - there is no use +complaining about some 367 byte files along with others that take several +megabytes. + + + + + + +Invoke a "cleanup" action. There are several predefined ones, and you can +define your own. Use the context menu, the tool bar or the Clean +Up menu to find out which are available. + + +For some cleanup actions you will have to wait until the directory +tree is completely read until you can activate them. If a cleanup action +doesn't get enabled even then, the type of item you selected is inappropriate +for that kind of action: Some actions can only performed on directories, while +others can only be performed on files. Only very few actions work for +<Files> pseudo entries since they don't have a real counterpart in the +file system. + + + + + + + + + + +Treemaps + + + +Quick Introduction to Treemaps + + + +What is it? + + +The shaded rectangles you can see in the lower half of the &kdirstat; main +window are called a "treemap". This is just another way of displaying items in +a tree that each have a numerical value, such as a file size. + + + +Each rectangle corresponds to a file or directory on your hard disk. The larger +the rectangle (or, rather, the larger its area), the larger the file. + + + + + + + +How to Use Treemaps + + +Look at the largest rectangles. Click on one, and it is selected - both in +the treemap view and above in the tree view (the list above). You can now see +what file or directory that is - both in the tree view above and in the status +line below. + + + +Find the largest rectangles, identify them, ant decide what to do with them: +Keep them, delete them, whatever. Use the cleanup actions like in the tree +view. The right mouse button opens a context menu that contains cleanup actions. + + + +The shading gives hints about which files belong together in directories. The +bright spots indicate about where the center of parent directories is. + + + + + + + +Pros and Cons of Treemaps + + +Treemaps are good for finding single large files, possibly very deeply nested +in the directory hierarchy. They don't help very much if lots of small files +clutter up a directory - use the tree view (the list) above the treemap for +that. + + + +The treemap by itself view doesn't give away very much information other than +relative file sizes. It can tell you where large files are, even if they are +very deeply hidden in subdirectories. You always see all files at once, not +only the relative sizes of subdirectories against each other like in the tree +view. Click on a file to see more details in the tree view above. + + + +Bottom line: Both the treemap and the tree view have their strenghs and +weaknesses. Use a combination of both to make best use of either's benefits. + + + + + + + +How to Get Rid of it + + +If you need the screen space for the tree view (the list) or if you find it +takes too long to update the tree view each time you delete a file, you can +drag the splitter between the tree view and the treemap all the way down. The +treemap doesn't get rebuilt below a certain minimum size, thus it doesn't eat +performance any more. Alternatively, uncheck "show treemap" in the "treemap" +menu or simply hit F9. + + + + + + + + +Treemap Related Actions + + + +Mouse Actions in the Treemap + + + + +A single click with the left mouse button selects the clicked file or directory +both in the treemap and in the tree view. + + + +A single click with the middle mouse button selects the parent of the clicked +file or directory. + + + +A single click with the right mouse button opens the context menu. + + + +A double click with the left mouse button zooms the treemap in at the clicked +file or directory: The treemap is redisplayed with the near-topmost ancestor of +the clicked file or directory as the root. + + + +A double click with the middle mouse button zooms out after zooming in. + + +If the treemap is not zoomed in at all, it is simply rebuilt to fit into the +available screen space without the need for scrollbars. This is mainly useful +if automatic treemap resizing (the default) is switched off. + + + +Dragging the splitter above the treemap not only resizes the treemap subwindow, +it also rebuilds the treemap and makes it fit into the available space. + + + +You can drag the splitter all the way down to deactivate the treemap +alltogether. Below a minimum size the treemap will not be updated any more, so +it doesn't cost any performance. + + + + + + + + +Treemap Menu Actions + + +Most treemap mouse actions have counterparts in the "treemap" menu. + + + +In addition to that, "show treemap" in the "treemap" menu toggles display of +the treemap subwindow. If disabled, the treemap is really inactive and doesn't +cost any performance. + + + + + + + +More Information about Treemaps + + +How a Simple Treemap is Constructed + + +In its most basic form, construction of a treemap is very easy: + + + +First, you need a tree where each node has an associated value. Directory trees +with their accumulated file sizes are a very natural example. However, the tree +needs to be complete with all accumulated values before anything can be done - +that's why &kdirstat; doesn't display a treemap while directories are being +read. + + + +Decide upon an direcion in which to split the available area initially. Since +normally the treemap subwindow is wider than it is high, we first split +horizontally. + + + +Split the area so each toplevel directory gets an area proportional to its +accumulated size (i.e., its own size plus the size of all its children, +grandchildren etc.). + + + +For each rectangle thus constructed, repeat the process for each directory +level, but change direction for each level. For example, the second level will +be split vertically, the third again horizontally etc. + + + +This basic algorithm as well as the idea of treemaps at all was introduced by +Ben Shneiderman quite some years ago. + + + + + + + +Squarified Treemaps + + +One major drawback of the simple treemap algorithm is that it usually results +in lots of very thin, elongated rectangles that are hard to point at with the +mouse and hard to compare visually against each other. This is why &kdirstat; +uses "squarified" treemaps as described by Mark Bruls, Kees Huizing, and Jarke +J. van Wijk of the Technical University of Eindhoven in the Netherlands. The +basic idea is to improve the aspect ratio of the resulting rectangles, thus to +make them more "square-like". Even though this doesn't always work out +perfectly, it usually improves things a lot: There are normally very few (if +any) thin, elongated rectangles in such a squarified treemap. + + + + + + +The Shading: Cushioned Treemaps + + +Squarifying a treemap comes at a cost: It makes the structure of the underlying +tree even less obvious for the user. Where simple treemaps change direction for +each level of subdivision, sqarified treemaps change direction within each +level. The result are clusters of more or less square-like rectangles. The only +hint about the tree structure that is given is that larger rectangles are near +the left and at the top of each level. + + + +Thus, &kdirstat; uses a technique described by Jarke J. van Wijk and Huub van +de Wetering of the TU Eindhoven, NL: "Cushioned" treemaps. This is the 3D-like +shading you can see in &kdirstat;'s treemaps: It gives each rectangle within +the treemap (each "tile") a cushion-like impression. This is not just for +pretty looks, its main purpose is to group files optically together. + + + + + + +&kdirstat;'s own Treemap Improvements + + +The squarification algorithm requires items to be sorted by size. A Linux/Unix +directory tree, however, usually has lots of items; a full-blown Linux +installation can easily consist of 150,000+ (!) files and directories. The best +sort algorithms (heap sort, quick sort) still have a cost in the order of +n*ln(n), i.e. they are proportional to the product of the number of items times +their logarithm. + + + +Likewise, the cushion shading algorithm requires relatively expensive +floating-point arithmetics for each individual pixel of each treemap tile (even +though, by the way, it is very efficient for a 3D-shading algorithm - no +expensive sinus/cosinus etc. calculation required). + + + +On the other hand, most items in large directory trees are so tiny they cannot +be seen at all. &kdirstat; simply omits everything that will result in treemap +tiles less than a predefined (3*3 pixels) size - they are pretty useless for +the purposes of &kdirstat;'s users anyway. Those tiny thingies may end up in +some featureless grey space in the treemap display. + + + +So don't wonder if you click on some grey pixels and &kdirstat; insists they +belong to a rather high-level directory: &kdirstat; simply means to tell you +that those pixels correspond to some small stuff in that directory. Use the +tree view (the list) above the treemap for more detailed information. + + + + + +Credits and Further Reading about Treemaps + + + + +SequoiaView gave the inspiration for treemaps within &kdirstat;. SequoiaView is +a MS Windows (that's the bad part) program created at the TU Eindhoven, NL. It +introduced cushion treemaps and later squarified cushion treemaps. Its purpose +is very close to &kdirstat;'s. If you are looking for a &kdirstat;-like program +on that "other" ;-) platform, go for SequoiaView: + + +http://www.win.tue.nl/sequoiaview +. + + + +Needless to say, &kdirstat; users should easily be able to simply mount their +MS Windows partitions and use &kdirstat; to clean up those as well. The only +acceptable excuse ;-) for not doing this might be NTFS partitions (no reliable +write access from Linux to those yet) or single-OS MS Windows machines. + + + +Ben Shneiderman invented treemaps - a truly intuitive way of visualizing +numerical contents of a tree. For more information, see + + +http://www.cs.umd.edu/hcil/treemaps/ +. + + + +Jarke J. van Wijk and Huub van de Wetering from the TU Eindhoven, NL wrote a +paper called "Cushion Treemaps: Visualization of Hierarchical Information". It +is available in PDF format at + + +http://www.win.tue.nl/~vanwijk/ +. + + + +Mark Bruls, Kees Huizing and Jarke J. van Wijk from the TU Eindhoven wrote a +paper called "Squarified Treemaps". It is also available in PDF format at + +http://www.win.tue.nl/~vanwijk/ +. + + + +Alexander Rawass had written a previous implementation of treemaps for +&kdirstat;. Even that part has been completely replaced for various reasons +(performance, integration into the &kdirstat; main application, memory +consumption, stability, user interface conformance, lack of maintenance), it +had proven that treemaps are a useful addition for a program like &kdirstat;. + + + +Frederic Vernier and Laurence Nigay from the University of Grenoble, France +wrote a paper called "Modifiable Treemaps Containing Variable-Shaped Units" +(URL unknown, sorry). They also wrote a MS Windows programm called "parent" +that uses a mixture of treemaps and file lists within individual treemap +tiles. + +Personally, I don't like that approach very much - I find that display very +cluttered and confusing (that is why I didn't adopt anything like that for +&kdirstat;). But this is just my personal opinion that others may or may not +share. + + + + + + + + + + + +Predefined Cleanup Actions + + +&kdirstat; comes with a number of predefined cleanup actions. You can configure +them all to your personal preference, and you can add your own. Here is what +the predefined cleanup actions do: + + + +Open in Konqueror + + +This opens the selected item in a Konqueror window. + + +You can use Konqueror to delete it (but then, you can also do that more easily +from within &kdirstat;), you can move it to another place or you can examine it +more closely. + + +If the selected item is a known MIME type, this will open the appropriate +application. For example, if you invoke +Open in Konqueror on a PNG image, Konqueror will +immediately start an image viewer and display that image. + + +This is the Swiss army knife of cleanup actions: You can do a lot of different +things with it. Thus, &kdirstat; cannot know if and when it makes sense to +re-read that directory - you will have to do that manually: +Select Refresh selected from the context menu +(right-click) or from the File menu. + + + + + +Open in Terminal + + +This opens a terminal window in the directory of the selected item. + + + +Use this to issue a few shell commands in that directory, then simply close +that shell window. You can easily open a new one in a different directory if +you need one, so you might want not to bother to repeatedly type +cd with lenghty paths - simply close that shell and open +a new one at the new location (type Ctrl-T. + + +As with the Open in Konqueror cleanup action described +above, you must manually re-read the directory's contents if you make +changes. Otherwise they will not be reflected in &kdirstat;'s display. + + + + + +Compress + + +This compresses the selected directory to a .tar.bz2 archive. + + + +For example, a subdirectory +/work/home/kilroy/loveletters will become a compressed +archive /work/home/kilroy/loveletters.tar.bz2. +The directory is removed once the compressed archive is successfully created +(but of course not if that failed). + + +Any existing archive of the same name will silently be overwritten. + + +Remember that Konqueror and related utilities can use that kind of archive +transparently; there is no need to unpack it if you want to read a file in that +archive. Simply click into the archive in Konqueror. + + + +If you prefer .tgz archives to .tar.bz2, change the command line in the +cleanup settings. With .tar.bz2, +this is + + + +cd ..; tar cjvf %n.tar.bz2 %n && rm -rf %n + + + +For .tgz archives, change this to + + + +cd ..; tar czvf %n.tgz %n && rm -rf %n + + + +But you might think twice before doing that: "bzip2" (for .tar.bz2) compresses +a lot more efficient than ordinary "gzip" (for .tgz or .tar.gz), and most +systems support that just as well. It's just a matter of getting used to typing +tar cjvf rather than tar czvf for +creating an archive or tar xjvf rather than tar +xzvf for unpacking it. + + + + + + +make clean + + +This issues a make clean command in the selected +directory. + + +This is useful if you build software from source frequently. After successfully +installing the software (make install), there is no +need to keep the built binaries around in the source directory any longer. On +the other hand, people frequently forget to clean up those directories, so you +can do that from within &kdirstat; with a few mouse clicks. + + + + + +Delete Trash Files + + +This deletes files that are usually superfluous, such as editor backup files or +core dumps in the selected directory and in any of its subdirectories. + + +By default, the following types of files are deleted: + + +Object files left over from compiling software: *.o +Editor backup files: *~ *.bak *.auto +Core dump files: core + + + +Of course, you can configure this +to suit your personal preferences. + + + + + + +Delete (to Trash Bin) + + +This invokes the KDE standard "delete" operation, i.e. the selected file or +directory is moved to the KDE trash bin. + + +Even though this doesn't help to reclaim disk space right away, it is a safe +method of deleting. Use this action for anything you want to get rid of and +then review your actions by looking into the KDE trash bin. If you are really +sure, select Empty Trash Bin there. Until that point, +you can always move those items back to where they came from. + + +You might consider not using this cleanup action if you are cleaning up a +directory on a different file system than your home directory: In that case +that "moving to trash" involves copying the items (and then deleting them at +the original location) which might take a while. + + +Notice that when moving an item to trash is not successful, &kdirstat; will +still falsely display that item as deleted even though it's still there. Use +Refresh selected from the context menu to update the +display manually. Read here why. + + + + + +Delete (no way to undelete!) + + +This is a real delete, not simply moving something to the trash bin. It's +quicker, and disk space is reclaimed immediately, but there is no way to +recover if you made a mistake. You will be prompted for confirmation when you +invoke this. + + +You can change the configuration to not prompt for +confirmation, but don't blame me if anything goes wrong after you did that. + + +As with Delete (to Trash Bin), you will need to manually +re-read a directory if this went wrong (usually due to insufficient permissions) +- &kdirstat;'s display is out of sync with the hard disk if that happens. +Read here why. + + + + + + + +Configuring Cleanup Actions + + + +Select Configure &kdirstat;... from the +Settings menu and switch to the +Cleanups page: + + + + +Configuring cleanup actions + + + + + + Configure cleanup actions window screenshot + + + + + + +Reference + + +Select the cleanup action you want to configure from the list at the left +side. You might need to check Enabled before you can +make any changes. + + + +Enter a title in the Title field. You should mark one of +the characters in the title with an ampersand ('&') to provide a keyboard +shortcut in the menus. + + + +Enter a shell command in the Command line field. The +command will be invoked with /bin/sh, so you can use +everything the default shell provides - including pipelines, logical 'and' or +'or' ('&&' or '||', respectively) or multiple commands separated by +semicolons. Use '%p' for the full path (or URL) of the currently selected file +or directory or '%n' for the name without path. '%t' will be expanded to the +full path name of the KDE trash directory (usually ${HOME}/Desktop/Trash, but +since this tends to change between different KDE versions it is safer to use +'%t'). + + +&kdirstat; +will always change directory to the selected item, so there is no need to +manually add a cd command to the command line. + + +Commands are started in the background if possible, so don't add an extra +ampersand '&'. + + + +Check Recurse into subdirectories if the command should +be called for each subdirectory of the selected directory. Whether or not this +is useful depends on the kind of command you entered: A make +clean command usually takes care of that internally, while it's a +lot easier to use rm -f *.bak and let &kdirstat; handle +subdirectories rather than using a more complex find ... | xargs +... command. + + + +Check Ask for confirmation if you want to prompt the +user for confirmation every time he invokes that cleanup action (but not for +each recursive subdirectory!). But beware: Having to confirm a lot of such +prompts tends to make users unattentive. They begin to blindly confirm +everything out of habit. Thus, use confirmations only when really necessary. + + + +Check the category of objects this cleanup action works for. Not all commands +make sense for both files and directories. <Files> pseudo entries are a +very special case: They don't have a real counterpart on the hard disk. You can +safely check the <Files> category for actions that require changing +directory to somewhere and then execute a command there, but there is no use +trying to delete such a <Files> entry. + + + +Choose between On local machine only ('file:/' protocol) +and Network transparent (ftp, smb, tar, ...). +Most commands run locally only. There are only a few exceptions: For example, +you can open a remote location in many KDE applications, e.g., Konqueror. + + + +Select a Refresh Policy to tell &kdirstat; how to update +its display after the cleanup action has been invoked: + + + + + + +No refresh: Don't refresh the display. Either the +cleanup action doesn't change the directory tree anyway or it is unknown when +or how - or you don't care. + + +Cleanup actions with this refresh policy are the only ones that can be invoked +while the respective directory subtree is being read. All others can only be +started once reading is finished. + + + + + +Refresh this entry: Refresh the directory branch the +cleanup action was selected with. This is the most useful refresh policy for +cleanup actions that delete a number of items from a directory tree, for +example Delete Trash Files. + + +If this refresh policy is selected, the command is not started in the +background: &kdirstat; has to wait for it to finish so the directory display +can be refreshed at the proper time. + + + + + +Refresh this entry's parent: Similar to +Refresh this entry, but one level higher up. Useful for +cleanup actions that delete the selected item but create a new one on the same +level, for example the Compress standard cleanup: The +original directory is deleted, but a .tar.bz2 file is created instead. + + +If this refresh policy is selected, the command is not started in the +background: &kdirstat; has to wait for it to finish so the directory display +can be refreshed at the proper time. + + + + + +Asume entry has been deleted: Don't really re-read +anything from disk, but assume the cleanup action deletes the selected +item, thus simply remove that item from the directory tree's representation in +&kdirstat;'s internal data structures. + + +This is much faster than any real refresh, but it might cause the internal data +structures to get out of sync with the hard disk if the cleanup action fails and +doesn't really delete the selected item. In this case, the user will have to +manually re-read that directory branch. + + + + + + + + +Examples + + +Open in Emacs + + +This is a trivial example that shows you how to add a new cleanup action that +opens a file in Emacs (or any other editor of your choice). + + + +Select one of the unused user-defined cleanup actions from the list. Make sure +Enabled is checked. + + + +Enter Open in &Emacs in the +Title field. Notice the '&': This marks the letter +'E' as this cleanup action's keyboard shortcut. + + + +Enter emacs %p in the Command +line field. + + + +Leave both Recurse into subdirectories and +Ask for confirmation unchecked. + + + +Make sure only Files is checked in the Works +for... section and Directories and +<Files> pseudo entries are unchecked. If you like +Emacs' "dired" mode very much, you can also leave +Directories checked, but it definitely doesn't make any +sense trying to open an editor with a <Files> entry. + + + +Leave On local machine only selected. If you feel like +experimenting a lot, you can try setting up Emacs so it fetches files from +remote locations, but even then most likely only the 'ftp' protocol will work. + + + +Leave the Refresh Policy at +No refresh. This ensures Emacs is started +in the background and you can continue working with &kdirstat; while Emacs +runs. It wouldn't make too much sense to change the command line to +emacs %p & and change the refresh policy to, say, +Refresh this entry: The refresh would take place +immediately after Emacs starts, and this is probably not what you want. + + + + + + +Compress + + +This example explains the predefined Compress cleanup +action in more detail. Remember, this cleanup action makes a compressed +.tar.bz2 archive from a directory. + + + +The Command line for this cleanup action is: + + + + +cd ..; tar cjvf %n.tar.bz2 %n && rm -rf %n + + + + +cd .. changes directory one level up. We don't +want to do something in the selected directory, but one level higher. + + + +The semicolon ; tells the shell to execute one more +command - unconditionally, no matter if the previous command succeeded or +failed. + + + +tar cjvf %n.tar.bz2 %n && +is where the compressed .tar.bz2 archive is created. "c" is the tar command for +"create", "j" means "use bzip2 compression", "v" is "verbose" (even though this +is strictly spoken unnecessary here), "f" means use the next argument as the +target file name rather than some default tape device (which nowadays nobody +uses any more anyway). "%n.tar.bz2" will be expanded to the name of the +selected directory without path plus "tar.bz2", "%n" will be expanded to +the name without anything else. For a directory +/usr/lib/something all this will result in a command + + +tar cjvf something.tar.bz2 something + + + +&& makes the shell execute the rest only if the +previous command (the tar command) is executed +successfully. This is used here to make sure the directory only is deleted if +we really have a .tar.bz2 archive with the same contents so we can easily +restore it when necessary. This is crucial in case there insufficient disk +space to create the archive or should we have insufficient permissions to +create the archive. + + + +rm -rf %n recursively deletes the directory +without asking or complaining. + + + +Works for... is enabled for directories only. Note it +wouldn't be a good idea to enable it for <Files> entries, too: The user +would rightfully expect the .tar.bz2 archive to contain the contents of the +<Files> entry only, i.e. only the files on that directory level. The +command would, however, pack the entire directory tree from the parent level on +into the .tar.bz2 file. + + + +The Refresh Policy is set to +Refresh this entry's parent since not only the selected +item is changed, but its parent also: It loses one child (the directory) but +gets another one (the .tar.bz2 archive). + + + +Please note that Recurse into subdirectories is not +checked here: the tar command and rm +-rf take care of any subdirectories. + + + + + + + + + + + +Feedback Mail + + +Description + + +Send Feedback Mail... from the +Help menu opens this dialog: + + + + +Feedback mail + + + + + + Feedback mail window screenshot + + + + + + +You answer the questions (at least those marked as required) and add your personal +comments (in English, if you can, or in the special case of &kdirstat; +alternatively in German). + + + +Upon clicking on the Mail this... button, your +mail client opens with a +precomposed mail. +You can review that mail to make sure it doesn't contain anything you +don't like. When you are convinced the mail is okay and doesn't contain +anything you don't like, send it. + + + +With your opinion and your personal comments, you can make a contribution to +the Open Source movement - even if you are not a developer, even if you don't +have a clue how to improve or change the software. Your opinion is important, +even if you decide you don't like the program and send the mail off with "this +program is crap" checked. + + + +Open Source softare lives and breathes with user feedback. If you miss a +feature, tell us about it. If you consider an existing feature confusing, tell +us about it. If you find an application overloaded with features so you can't +find the ones you really need, tell us about it. + + + +On the other hand, if you like the program the way it is and you wouldn't like +to see it changed in any way, tell us about that, too. If you simply want to +thank those who go through the trouble writing all that software, do it. Your +input is appreciated, be it positive or negative. + + + +There is nothing more frustrating for an Open Source software author than that +lingering uncertainty if there is anybody out there who actually uses his +program. He may not get any response from users - does that mean nobody +uses the software, or does it mean it simply runs so good nobody has reason to +complain? You can contribute by telling him he is doing all right and he should +keep up the good work. + + + +In the opposite case, why not tell the author of a particular annoying program +just how annoying it is? This may shake him sober and make him reconsider his +work. + + + +Open Source is one of the world's greatest democracies. Make your vote! + + + + + + + +Privacy + + +Your mail sent with Send Feedback Mail... is sent to the +authors of this program, to nobody else. No company or government institution +will get your mail address or any personal data. You might have noticed no +personal data are requested in the feedback form. In particular, you will never +receive spam e-mail of any kind because of sending feedback mail. + + + +We, the authors of this program, loathe spam probably even more than the +average KDE user since we get so much of it - spam robots tend to extract +e-mail addresses from source code and from web pages, so you can be sure we do +our best to make life as hard as we can on the spammers and certainly not help +them in any way. + + + +The purpose of all this feedback mail is to gather information about average +user satisfaction, about average opinions about an application's feature set, +an application's stability and learning curve. It's all about averages, thus no +specific user's data will ever be made available to the public - only +statistical averages over a large number of users, if at all. + + + + + +Feedback Mail Example + + +A typical feedback mail looks about like that: + + + + +[kde-feedback] KDirStat-2.4.4 user feedback + +<comment> +This is where the personal comments go. +You may enter virtually any number of lines. +</comment> + +general_opinion="5/8_nice_try" + +features_liked="stay_on_one_filesys" +features_liked="feedback" +features_liked="pacman" + +stability="5/5_keeps_crashing" +learning_curve="5/5_still_no_clue" +recommend="yes" + + + + + +Notice it's all plain ASCII. There is no attachment, no hidden header fields, +no information about your machine or yourself - only what you would send to +anybody else when you send a mail. + + + +By the way, this is also why we kept the format that simple. Many developers +today prefer XML for all kinds of data, but the end user (you) should be able +to read and understand what you send - just so you can make sure you don't send +any information you'd rather keep to yourself. + + + + + + + + +Developer's Guide to KDirStat + + +Most of what you can see of &kdirstat; is one separate KDE widget that can be +used in other applications, too. Those parts of &kdirstat; are even licensed +under the LGPL, so you are even allowed to use it in commercial applications. + + + +The &kdirstat; sources are extensively documented. Read the documentation in +the header files for more details or use "kdoc" to generate HTML documentation +from them. + + + + + + +Questions and Answers + + +&reporting.bugs; + + + + + + + +Can I use &kdirstat; to sum up a directory on an FTP server? + + + + +Yes. Simply specify the URL at the command line or even in &kdirstat;'s +directory selection box: +kdirstat ftp:/ftp.myserver.org/pub (command line) or +ftp:/ftp.myserver.org/pub (directory selection box). + + +&kdirstat; supports all protocols that KDE supports. You can even use the "tar" +protocol (does it make any sense to do that? You decide). The only restriction +is that the protocol needs to support the "list directory" service - which not +all protocols do. + + +If you are unsure about the syntax to use, try it in Konqueror first and look +at Konqueror's URL line. For example, to figure out how to specify a "tar" URL, +click into a "tar" archive in Konqueror and look at the resulting URL to get an +idea of what it looks like. + + + + + + + + +How do I get the exact byte size of an entry rather than Megabytes or +Kilobytes? + + + + +Right-click the number in the list. + + + + + + + + +Why does the "du" command sometimes report different +sizes than &kdirstat;? + + + + +There are different kinds of sizes reported by different kinds of system calls +or KDE services: The byte size and the block size. + + +The byte size is the exact number of bytes of a file or directory. This is what +&kdirstat; uses. + + +The block size is the number of disk blocks allocated by a file or +directory. Most "du" commands use that. +Depending on the type of file system, parts of the last block of a +file or directory may be unused, yet reserved for it anyway. If such a file system +uses 1024 byte blocks, a file will at least need those 1024 bytes, no matter if +it is 1024, 200 or even just one byte large. That depends on the file system type +and sometimes even on how this is set up - i.e., this is highly system +specific. + + +&kdirstat; uses the byte size since this the only size that is reliably +returned by all kinds of system calls and KDE services alike. It only really +makes a difference in very pathological situations anyway, for example if you +have subdirectories with a large number of tiny files. + + + + + + + + +What does this display mean: + +6.3 MB (allocated: 1.3 MB) + + + + + + +This is a so-called "sparse file" (also known as "file with holes"). +This means that the file really is 6.3 MB large, but only 1.3 MB of that are +actually allocated - the rest are just zeroes. + + +This is typical for core dumps (memory images of crashed programs written to a +file named core or core.*) +or binary database files: The kernel writes those files in a way so only real +data content is allocated on disk and not the large amount of zeroes. + + +Technically, a sparse file is created with the regular open() system call to +open the file for writing, then using lseek() to extend the file size beyond +its previous size and then writing at least one byte. The area between the old +and the new file size becomes a "hole" in the file - it is not actually +allocated on the disk. Upon reading this area, a value of zero is returned for +each byte read. When bytes are written to that area, file system blocks are +actually allocated, possibly creating two smaller holes before and after the +area written to. + + +Please note that most file utilities do not deal graciously with sparse +files. Those that support them at all normally need special command line +arguments. Otherwise they tend to simply reading all bytes (including all the +zeroes from the holes) and writing them to a new location - which of course +means that the resulting file is no longer sparse, but really occupies all the +space its size indicates. This may mean that you can blow up the above 6.3 MB +core dump file from 1.3 MB disk usage (and 5 MB zeroes in holes) to really +6.3 MB disk usage. + + +GNU file system utilities like +tar and rsync at least support +command line options to prevent that. +GNU cp is a notable exception - it has a heuristic that +seems to work very well. +GUI driven file managers on the other hand tend to simply ignore this - even +the most modern and cool looking ones. + + +If in doubt, check your favourite file tools. Produce a core dump - they are +normally sparse files. The more memory a program uses, the more likely it is to +have large sections of zeroes in its memory image. Try this (in a shell): + + + +Enable core dumps - they are usually disabled in most Linux distributions: + + +ulmit -c 128000 + + +This sets the limit of core dump files to 128000 blocks (512 bytes each), i.e., +to 64 MB. This should be sufficient. + + + +Start a program with considerable memory consumption - in the background: + + +xmms & + + + +Make the program dump core: + + +kill -ABRT %xmms + + +This sends the ABORT signal to this process, terminating it with a core dump. + + + +Look at the core dump: + + +kdirstat . + + +or, for a neutral third-party program (from the Linux coreutils package): + + +/usr/bin/stat core* + + +(You need to multiply the "blocks" output with 512 to find out allocated disk space) + + + +Copy that core dump (e.g. to another directory) and look at it again. You will +be surprised how "heavy" all those zeroes suddenly have become. Try that with +several copy utilities (/bin/cp, file managers of your +choice). Remember to always use the sparse original, not any blown-up copies! + + +Moving files should always be safe (unless a file manager is really, really +stupid), but copying can easily blow up sparse files to huge assemblies of +meaningless zeroes. + + + + + +Agreed, sparse files are rather uncommon these days, so this is usually not a +problem. Just remember &kdirstat; knows how to deal with them. ;-) + + +Please note that this special handling is only in effect if &kdirstat;'s +optimized read methods for local files are used (you can turn this on and off +in the Settings -> General dialog) - KDE's KIO +methods do not return this kind of information. + + + + + + + + +What does this display mean: + +878.5 KB / 21 Links + + + + + +This means that this file has a number of hard links. &kdirstat; uses only the +respective portion of its size for its statistics - in the above case, 878.5 KB +/ 21 = 41.8 KB. When another link to this file is processed, the next 875.5/21 +KB are added to the total - and so on. + + +The rationale is that is makes no sense to count such a file 21 times with its +full size - this would greatly distort the statistics. For example, look at +/usr/lib/locale on a (SuSE) Linux system - many files +there have multiple hard links to save disk space. The total sum of that +directory on a SuSE Linux 9.2-i386 system is 40.5 MB -- as opposed to 205.6 MB +that the added-up output of /bin/ls -lR would suggest +(or &kdirstat; with use optimized local read methods +turned off in the Settings -> General dialog) +- sometimes, as in this example, this really makes a difference! + + +Technical background: In Unix/Linux file systems, files primarily have a +numeric ID, their "i-number", the index of the corresponding "i-node", the file +system's administrative information. Each directory entry of a file really is +no more than a link to that i-node. You can have the very same file under +several distinct names this way - even in different directories. The only +limitation is that this is restricted to one file system (i.e. to one disk +partition) because those i-numbers are unique only per file system. + + +Hard links can also introduce a whole new dimenstion of problems with +applications that create backup copies of working files - they usually only +rename the original file to a backup name and write their content to a new +file. Editors usually work that way. This however means that any additional +hard links to that file now point to the outdated backup copy - which is +normally not what is desired. Only very few applications handle this +reasonably. So the bottom line is: Use hard links only if you know very well +what you are doing. + + +All this is probably why symbolic links have become so much more popular in recent +years: They can also point to different file systems, even (via NFS) to +different hosts in the network. On the downside, symlinks can also be stale - +pointing into nothingness. This cannot happen with hard links: A file is only +really deleted when the last of its links is deleted (this includes open +i-nodes in memory - i.e., processes still having an open file handle to that +i-node). + + +Directories rely completely on hard links (this is also why &kdirstat; does not +attempt to try anything smart with multiple-hard-link directories - it would +make no sense): The ".." entries in each directory pointing to its parent is +nothing else than another hard link to that parent (named ".."), and "." is +nothing else than a hard link to itself. This is also why even a completely +empty directory has a link count of 2 - one for "." in its own directory, one +for its name in its parent directory. + + +Like sparse files above, regular files with multiple hard links are pretty +uncommon these days - but they are still used, and sometimes they can make a +difference, and this is why &kdirstat; has special handling for them. + + +Please note that this special handling is only in effect if &kdirstat;'s +optimized read methods for local files are used (you can turn this on and off +in the Settings -> General dialog) - KDE's KIO +methods do not return this kind of information. + + + + + + + + +I don't want to use KMail every time I send a mail with &kdirstat;. +How do I tell &kdirstat; to use a different mail client? + + + + +Start kcontrol or select +Preferences in the KDE menu, then select +Network -> Email and enter +your favourite mail client in the Preferred Email client +field. + + + + + + + + +How do I get rid of those many percentage bar colors? I want them all displayed +in the same color. + + + + +Select Configure &kdirstat;... from the +Settings menu, switch to the Tree +colors page and drag the slider all the way up. + + + + + + + + + + + + + + +Credits and License + + +&kapp; + + +Program copyright 1999-2002 Stefan Hundhammer sh@suse.de + + + +Contributors: + + + Alexander Rawawss alexannika@users.sourceforge.net + Initial treemaps (those who currently don't work any more) + + + + + + +Documentation copyright 2002 Stefan Hundhammer sh@suse.de + + + + +&underFDL; + + +&underGPL; + + + + + +Installation + + +How to obtain KDirStat + + +&kdirstat; is part of the KDE project +http://www.kde.org. + +&kdirstat; can be found on the &kdirstat; home page at +http://kdirstat.sourceforge.net/ +or at the mirror site at +http://www.suse.de/~sh/kdirstat/ +. + + + +Requirements + + + +Linux or any other Unix-type operating system. +As stupid as this sounds: There were quite some people complaining that +they couldn't get &kdirstat; installed on their Win9x system. Many people seem +to believe that if it has windows, it has to run on MS Windows... + + + +KDE 3.x + + + + +All required libraries as well as &kdirstat; itself can be found on +The &kdirstat; home page. + + + + + +Compilation and Installation + + +See file "build-howto.html" in the distribution tarball. + + + + + + + +&documentation.index; +
+ + diff --git a/doc/en/kdirstat-config-cleanups.png b/doc/en/kdirstat-config-cleanups.png new file mode 100644 index 0000000000000000000000000000000000000000..1c13b8a838ec0af3bd61e67988f8d7a1bdb62ac8 GIT binary patch literal 14165 zcmbWeWmsI@vMs!j0F49!1lOR!Jvf9UcyK4Uy9RDw=)o;?J(l=r;?mDWk@#D zveFK~|Mi+=HFWZrqsSxqP_|ce;DbT&08+%KIB5i_HuMn|^wr40H$*hc$Q<;BwpwAW z3S6`5(zM3ZMv^XGl!Xq;wRi8|yQ|*|HK#}Hm8jlMXc|ljEx3Y`foVzFDJLym!;^n3wYrziY^D$`<=@@K`xjF61VvAm^ z#wsrOEcz_}3HkEMJ@nUtGR23zKQnqEu+@T<1_?B3n5o&-Dr$d-#_V5{GwYKeySOHixOxyS_7;SI(p{J5V}r5iWZb zCCuM%+Y*$kpfeNSmN=mShAfTe`ZK(x+SA2c?5SRLDzNxFUW}CYXs-e+tncdj{-eD?sXHl8t4WWi<;wuEz>ul&2 zP%G86+PnZ)LfTYXOYh8Uzv=wj395yGfX7)}Y(;ZfBz6 zF$OjJQo69`c$Dw)pn;yp8bgiUoCaC__FhOQxJ;IXDTBTT!?mk1wO2wZgRpX)9fmj5 z(2GdsgtM!;bjvJMi-_YAZX-tQDdU4D)V_*=;7-WkC1{ka^z5I~JhsNFwy3 zhkn?dQ0W2?@9l&!r~aU$dGqOWLcWWSbB>okLcFzen^u%Sm?nm!mo81(J(wemZ$6un>1kO9|D zv!cZLHRB7>8UBccguL^Jl9X%0TI*Rb0MXbI$_h z_gwWWN?mNe)itpbPpEb3ldG1kywm8_6i#rA<8qqgs~f#pPiekt>_@Ckc(Tm2JFG6z zxEI~H>cNa>@kIjdhwo`%>&$m0fdmcHoeH;HwgR5A^ueLh-#BIm!he5A`1FgoUPJa=-BlPDIO#%iaZ$Z>a2oIMDQoXR0Y^Nyi7mD#+~fS^-*wHR@EB?l8a+^LvuI+WdS=J4b& z^Hm623BK*YRr`#*pTM!5$8|~CLCz`n>BKXGMY@-P$f1~!G%48quHSX-IU@T=Nn`dq zxu1Gy)E)Z|uKp>pi4}^oj9r|XgtK@#BVRJk&?%!)i_)4ODGc`i7T7<|>=E=@)3fv3;#&U%WQdji zg<5kbNxMFz73d*y7vFFyo3D<)?IHsHqSH+_8-+pCo%vqUK&>Spkr)Lu2z~Prh2VNEYbsjt5mU^mR9Zha;JMm zG8a#T*zp5GUWM0PmFQ$FEtvWD;;i9ji(L%rHV@hjM$PywElu6sIb78kJCgaWU*4iV zUVaMXzO0sOq5SmJ&+&$M1Em%K@G^}(i2bMzPyvn?j@`w_1n)FaO!@ZScI zND>XT_k5i-g}GE^jw;CHRC1?hd;TF4smP2~pah(we3u#JGZZ87(TcEWuO!?S3-L4w zuO$f`EJ#RBQgzJ2vlP4>IRL79cZh_>=&x!&MV1uV;L0#gVO zKUu~-Io)tHCrwqA@!_mmn5?m|BtR5rKUu=v5uHtBk=0e+$CE-CQn$1)N9`e|4Uhu> z>eo66RO|yQ`~22p+N9swHF$XxGaTJuB4<7FWC;G>z14O}L&s&xGW6Z@iZSxDB+U&o zGH7>oQ@jO3Hi=%R{Rym($NrL2fdH(>W1~~oK%A~RObXn5-P~F|&9nW>J}qp9Y?Ehj z4-2`!SKk}J#1CWFEl3Kb0fsL#aK1Bs=KjTAt%eV)awzbAhip$&y@u>dGb7`YzI+kM#pU9dU;Xgq8Tyi|^;C{y*9k^1+=61V4j6?q7~0Z^TN?e0{d} zMB=yG_FErPu6LGX{y!XNq+UP?4V)lP-!)z+JU9>SlFj{vVjR~`WcF>s$cFb!Bg*RrKH-W*|*W$zTFstSj*nqX{uIdk~e zFm^N)=dVjbOe@0zkPaH1-}UW1kZxaR>+&!B+$&#@21tpeAoH%RgRaZivr2XG4~vLK zy>L5UG*l}Jk4ErhSaX3~CARFjto3EHT~2%-{*q7jDpGZ{v`U4`P}jSOsXKov>1;C$ zpNJ)zKvt3Jo=-A@0t_II;3r(&6uSJ}NN*6202gTo8%Uu+4Ia#OEypJ;dyMk+WD&!& zUu^5|yf<4_1Y|#)yO)vNWjKGr5r4Zm4KbMg_6YsUpQiwAog^f#!`&M~r>Z^ubE=eu z-`kIBIa&D}A^J{Suai`B?+hB_@VVe{9M44qh%uUX`sy`A>s%EL{qyUdhkm^d*#`!% zh_wH7h+ciQhB9@E`3PX@_3BpEtFM#P_@%p6N>_A80anECeUP(>WZQY`i8oD5~uFrFIjCPnI(QQ`pvB1&)} zC2O}E5MAYGIWZ{{Khnrpd}wK5)r<4&>{+tv6z(GzPChi}wDA^ee$ zR0)&ZTEoXcOouz!rY_fkd!gUP3^}5FO2;9ta}orpotPZ~2$q*`gnrEegM*0oFHn~8 z=#CzgPjO{CDwY{CuOu4eo;q=ti+xsPuZ;|3aC6loXI=M?lS*!>8AAp$Tu}W(qivRZ z_B_6PS4!C8;!GI~`*J>m?iryvit{NNGjXeE{DN5{l8+?yG0+m#E98VPeu*jcM^00J zsatOL4bxbKMFK?E<7N}g67dV~B)kceURA_1#XW}CV*f!}kE+}lI=4d{c!=j3&CwJ& z$I*T=Ihbq`SMsaJ?Bv^X$ca*CyYsQD0+~j2Q2o+kp`TCD7dbQ!2IyVoKU7}ntm^1b z62{V&dXhE!1YJ={r6VzyWUXIZM zZb^VEK+ZoR%H)wr2UR!TQBGsq&Cd`r#dS^D;EgZOY#^HB525o(tOv^m!ok1p_FX3C zy`JVJ5-(Dg*QY+-;Hvo5QbZDeIsb1->6|ZV$;G~|G(sAX%34nEIEa1F$ccpTDDb9z zY)VL@oX`6Mwol^qTMK41$@`H$K3mZVgo)!I!dzFoH*4i zm6+n{t#c$FI@uhUf4oF9#n^heI~7TibarcTmRa6d7Vr4jHO$Aa@CX^^rPZxq_Cklb zdn!OucJ^|p;xGg^nGnv2*hkGOQcQ=ur^?4BZ~Fr!DFE5D4L&@fD`bQrbH90fEJA)sA^=oM;`n|>kc z;~;ebIun-2kugJ#%zBgCGE1JYnhA}^9^tav1Z8wdWLZ9`X`-)gs!k}qwAbd+J>_aC zJ%S$1XLw-6L997RopHb!KIpoJsaN{ns%1T%lO1=k&?~wMU(btUg z>!IiX5nNZ_*fzwWtUrZDuU(rR=Zm|F4JwCVO%P`5F)CONp|o_DcnS>4y(>IxIG`o4 zkFU*(No+!rmm*6V35jtHl7fmx`ZnGw4dkn)eI&;!j0yHq{IF^Jvjy97M%$el%8s>^J?U& zPB7xd_4fx*TitNfCnc7BQshsi6eBAmOYSBj(AMO~O9p}9q=Wr_7Nds~Vj<`~ZlOM} z)0T(C;pPa53TrXrZ(?X+Y@rk9f}eK}!OaaNEe;NhJcvO8L_`PB(i?qZ_K)aY!wu8z zGq#Vh@q1BqELtOf{!wUu3s3kh_xa9TL!JX3kUZ9@kpI2tPI<98zkiE~+eksHxtvc% z+SMNhw`9#MKU2aKPBkV=(;oS-wdaDH)ml(#|E7&wCA91bkRf%o2$}dSuAerjNC(uwP7FRDu`-U(6)a|AOS{&isbWjHQSu#5fuOEU7(zMlG zj55~9K#!~#8}*$^)82?|m=)P8yIiZ(76~3aDS(4aP)Gmlz4z^7Lg)O?#h-%A03s@4 zy+GJ*i3_)GUityK`WQ<<1t$>+W_409TFu}NT*xT(W#*hE$75cNlvmjDVLQ~W&m#Gz zk6!5eEtNRT)E)XZMyC*=^0ef0KI880usE{<;1p;4h;V!l^*vJ5{4C?sQ?J$PM#Z`T zPDzwt-(Ubv6Bia?6-mQ@~T4+NcxJn%E32x3y6?0T?EZBln#2 z$VAEXP0T}l#D+kHarHeA-Y~azMEMNloTeRGc6(DO0S^95T5VRIw=#>7PpEY3qrgEGYA$Y=xiO0RU@~En1p+&X%>~RF zqKc83W#HbOP{=b;Kz(GXXN!f2pZmHSn+_NcTwB9wLSD$+M)ij!cH;;RmT%ipeh9Jg z1Bmcl2qp4}yT+r8Fhzs_c_axqPo6sx0F1^seO*f7nc5dU3L5?qxg|FUt56^%`C7rr zLu9=z%AHwcXNU=i)8`UMNHq&sa0R$0CL;RV8%EOjcVwei&F~YLYl(W~4?zrTWtzjs zOo+xI3sAuy4HtQ?Y{xC15bcg|J_hD0$-8{z$Psmw-9Y?qmGM@OiVU9{r*AL~@5@;(q;UJA|{b}Z!CaXd+<#WzJy zE~)NjCqHfAS*cKs)n-}aVwjB2hX4L)9W-)rNFQ`ME;1;~UBNY|j3^%2WAI*!N_8Tx zNiu`*OYyUiY}KEmqTe3k7JetJ|ORvk~RX+Mfyrr(Q zB@V_dg^w4q6Hh55YSlx>r04Ng570STxo;+EppVr!ex!Idw8A}Kf0uKhF*W}f7{@7; zrhc(Ck?;zv0^xx^hc9ik7ySF)n`EII%n6=OFQP75o$*FIKR4k&z8SqkLUrGtwIb91 zyA1a|o^)u}0jnUt51Z3X=kxclg+g&Ou0P)5Q~V^p+x$5bhbTKD42UG&(NA5|jQV#g zBVLH&xVO3!NcyGK7$N} zS}DWOB;eyTO4m50S>1Ex97YGIG0Ig))ULntiM5!r+|tN-h$F~n$Ae!gF8Hj?sT+S5B>)fhz|2&g z8GHn_*|buv2E~{;9=%m%Z={w~jzgh{`Tz<%Ah#7+PhzcDPKSOUo8B)F$VgnTao2M* zirr^p@C$?pcswZWs)p=Psf`C%!!Wvze=OPud zcjf08MhM!)@;$9>5lYP9DyrO+4W!G>`3&aF^&}~DD&YB_FRdxo`fbF^B`GqIRU>PN zrXu9J9u^xD#7$u6e++zN{P~j0<1;#a=o3vYBX^Tu&aRCLDPDm&UTb(M{Cz(gg>}RG z-0g=_RVMZIw(4U3fGK^E%2Wai6{T&iL-fCj@#K ze&j}OZjKH60p}`gqcZksloRAazT)r%%yC?oi0F7Jrt~hHmuSjv#TMTTVxA<0w}YY+ zs2L17EL_=X_0PC$V6&4qoWrgcr?#=9mQrpCQu)y>KSp?LxApe3-*YJbA?cxPdyttB zxvEG{I>7)r_d7he{E{361!X@IHnCvL$*) zFYIOWB7aKrcU{(^VR{)wu@S(5+*OqslpUYfJC9_34JBQX)XyLj%@@O?rQPr=4@p)+V+ZQC1ggp#68a8rFHt!>+r+qEO4L2Gd zL=6@Syf8ZYz#nk$?dP}_EP2-{?^4WEwcg=jR-KY zW{_%jP`x%Kxz#_5!4pgO`D1RsjVeE6}{e?k+HQ5+U>$J5;Bh0MC4l% zb3}|6=E|vr>z>+qxCX6#BuI#`=y1K)k&){~Z3V2OxPIFb_+NHM}v9f-{;)?VLy7JfxGvexUa#S&4hq$RPcIImP_&=^9I~LkybX$~+ zjZ2pqPLWQsRDHQB_igxI|4^cT3QH2^OgtlgOw16mOsH()+;$n~xlD5g{UVi&U#6YI zjP<4N&qN+aF8+z!hr*6;q*l%7A~<2%8NT5Nd{qFEU_j46(v?#EdYzfKB0DJK1cYWC zXuUiq=IlqRab(3BJW}JU)kC7kwOZwCJz_DFA$6RBvv>Y zXUr*;iSQHI|0^ZvY;vpLdFz_CS1 z<)f{gYO??bz#k1QQ&n#=Z}3}yjF($L#lQ_9{unG6XY`oD;G9FLJ^fmFvnZb4lPL1x zVuR9yTh1_*<|bODbNRU{MIBJH%a`xA`NTe&f#1^j5-lxiJ+Yv~vGqfMY`d}jhtuc9 zEL?V=5x>v!4_FC6gkWol@anbx_?!vaitHkeV+2xIV01FVI^H`(*TGG^$eG(RUuyQT zBeRqFt4>(urxNYHp5_OG_(MBOgpXr>R zr&Di9-iQYVOq>6@yod;1Qx_a|>Yg&QX{T&?#|cxGU{#E5xF+2Zl^C*%Ko&9r#Bn6x zAM6}I6HA$VV|;As_N^k#D%&Sdsn=1M0KmkPfDdS*kpun!bXbOcQOl@AWCtV&|&{|}ath7kULV+g<-P&dVj z=<2WCJX+o#b#iNf{9-eFrKjHB$hvhf`lGxB*5vg;jVMD7+~*a2DjLr)ZmDtap_Zt! zqQ9W0T+?wDFH8I9&F9LWdeI`FI*X|I$Dr{dVn6Dz*m=P1Lv#n>#uL6oTIevuDk5nX zoiL0rpNC~VSTnt?C$Q;1D3<|$2v7ZunC(Rp7m5m)nE(sb3lYTlu z_e|H_#7>QN@&4l)mM9!|)!s+^tmP*aRKd0hwmc*?5qu0S|Ne69z4($x6~H;-jG5H( zJAys$B~iLG4FXF4h2*~hol8nqz;v!9fw(XS!z*^o;TQ@~Rbo(EVQQ!d;WY&TuS9%e zPL?z^mxKZL__dRGDl1AL5f3dBZ&E`R`)J|ZR}&5bj+_Ya)a{vlgc!WLSiuYgDvs;a6$!PjkW z>9Z=_V>ti?ypnS5>FaMef}-F-9LnDa>div!+TrgmF#+n9NbI$t#WFqI0OblP-S`m? z=%V{=BFHC)0pPy#yW?wpGG9h($p~3no3S*jgQtteOIoX>g0$xwxH> zm$GX^v-LP7@EgRPnuQ-B!&bwt^He6Z`B+Nfwbh0p4JgB+ z8Qie7HHj=|1Jr6cw_FOPsdVr5alU+!eYFUC3qLmx&Ng<2j=HxC%ai0sW)_nZWLe#% zY*96Kjyj}S2EWtU@O{hmeI<)s!2EuUjqKRSCIx9 zK~xwryzzwzi5>L{eqrBVN3c6iCT5HV?-esf3P)pM-sJeUzU=$ieW}K(&j6j;biM}r35%^$3=b3WVcTTJs1>}iNE9v~dUbR-GTRx=-z(5)_Qfh_ zn3(>3x)g>|9bz#Ct#@E6+tXN8E3KUBL*7|IpFWRrq=%T_VR>qz(r6x6$}=#mYNg^` zboORxWG#BxE0DyH1uQyF+QEW!Y_1s%6)>@Q;FFlhWPm*OyS59W*&A#?9_4>LuLqaw z0XR({nKZb(j{y0^Ly-if{;}1)WNr`G*|bn*&CCZfU>yoNf_Y_9lSyQ>73w1wW7}gx z_(CVNwc`?`hr~d>>HH$D@lpZiMF8E#>FKPgo(dlC666~jEf0qKM z+IA#F*yzyeAsGW?To#ol8DwnJcW@ z7zQiM@ZuN6|CLQAm&m;G48H;#wErWrUKxALaLQ^`9tLBS-SDL1`SHX&E`-PUw{8t5 zhrj4a{hg;#bb7>l3K#9rCtA$1=Aerg(YGG#B3%$Zb`3Kf7>VzqE&eW-iegZ=+4bU= zaML?{E@~G+{%Rd{(~6BjZpFDpW)4sogU5n5@`X?@e7G!NelefFk$)1GV*i!>R0Az@ zqeouI4qq)~)j&On%}~t2eogJU-3h@|lQFF%Ww%zg|4&J+_?}(d4_8IM8U_KUmW! zJNM|cs!-uGu|@%tDU1nsvVh^MX?EhTo*ojck58FYA@C%HSa0MZ%lY*b)2txH$xwTb z0Vxf__Cks}aDt(m1v`+_rSnhWn%>#4Q#65NWlbN(qsG607hV>X&794CkusarRw92Y z(X)&Y8}=-?Ts1Fx7<Z;(7cM}TioAsvUu(B$6S`d z4mu{LY`so{7+ib7`OFE+;ttGEb`GD;9Bk^gAzp>{Kr7keO4W!&Z(9mFr3E7eA?eDb zgWnZwc(R&;&l<1V@UCVG2L7HC|Jw%ciFcBQKv}ByZ-OyA(z2%0xY$UCixXCr(fC8N ztsF%90%);xPWw|C8NFs!f-Da2E13LszUrvQxYSaZj&+1XxOvr76jW0|6m~ePds_R7 zBW%qKj<+$I{LSyGBj#piI)qQ(t0?+;kYc(P*Qn&nJierOa9V*=HT3CRbn4V3FvdH5 za-LziC9irt3UeqBfbk|b&Duy`2>KYy+~JH9s@GN$f}W{cR`&B)x!OonPq;;Df{9@- z2q*8GNX1(Hoas=3MI=~6mmbAUFHi1*qs9s9Rt7J1wPcy>(Bn48tT2cK!wYu@WP=VZ zjH*H_jqGId(sWB31}9g(V$v@2GJ6>(PZhj0n}swy@$42Y@FiaCP=4UdHbbkIv)ngn zN^}a``kw3M(PbNrCj&-V#RJg}STcH%m4;@s`Oh*`DbV3OLz?KMNk$KMu!&CsCx1)f zEGzi7Vo~syv?g5swKbpUprg$N&jrinDy3iRBp@jA6WXGXFPW}B<1*6(R)>q|<7gZ> z|41yp0tkacsx{ooSK}LZtAt|LPLEaRZ0vK5zBN081iag( zy+Z9ghH=X`V#nJQ%$t3YwDOfNKNQ(E+AcDp%o-<2LL(7vxS zfEn~so7TvleMUj}*3w{Ouc%%sw%+K7Arbi>g&I4x>ke_vf)Rt7|4WeQA)9Sm(?cUx zdsY-r?GSjv>!M*3P*jYBmO_UyzdzR z1Y)s*qR>BTQLr-o7d801L+0Nq)4xvf|GR|51)J{YaGYMmH*8$OrQ!rB!{!_^V2Q?t z5c9)pYUm$LES8UL9(tnw|GHxSFB)k6cczzyiztA66xh6V2A=g3g77c@9Tk+t!Cp&H zff}o&=8(GCUA%pTTjnnZNdNj5(6=-m9B=4L=b(eOL2GN@LFl&rCEkA&FZK6GjFHsXtRuAv}H>&>FL1(gv2>Co(q|-vq(2FYog6ZDf9qUSz>G zK(sDm7j`=3ozwUE1JP4qUuG$_(DxbS6Iv|ji~m~P4^%CTY4E|gJ_g_yU z9VT+P>`mGd|MeBRa;3$uTBRr4Y|n*%(ZMgdN}P9I1ynr1>X3V(vuxi0Ryynrc}X$3 z=jsE%HlAtR+U5R2O91LPa)Wguh+-C>i~}oSZBQwQ#HTTa_|?e98OE16gthi!KE}O0 zm~vf&0e>8?Iz~Z!A#tKHaqTS5^M( zJAuqW^0NC}_ zN2jR?-vr1ECJ8jab`hpAwrw8VbyQHs=zx>87q!9!a#}i+v&{|6S>;HIKWsZ@Vwr%R zh}Tj3b>25h*@QI!!;XmhCvqZH5&?xZD-(yTKPMP_pK{{!KoB9K0adyaGLKZdK*NXD zN!&`WDFtF*;tcK>WPJkgJ+ka8A4Jyy)GI!)qcRxrf8W*izYEI$4k0mIXGgk(3iRXP zHv!0F2k5|~VTL$ROM?gTuo;2kA&4Q;-@$JTT>U?`+MNay7+iPzZM8fG=S)LSc#tAo zO~CHa6NMnT2NBAC2NdEKj9C9S-FpSTo*rQ1964AXxb4qw4&*(`9Rv#)pOoPzuRfqR^Fs_c_?7`(IVl*obuWVG~?OA7T7iQZ1 z!HnYlO&uXqr)7Xu`-U9GFe2}}wj<|}wr|hH|2ake3hw7MZ?`bSe@sy&j+LM^&~%>- z);;O$tl}8s$^6Og_cH&o=XLtp<){BQMvpRm z&X_Gy`z$}y6YQRgjBVe&-rjT4{ajlwl3M?L8U=;DvjT9Q0l(S8wmv+K`QR?|#>1oQ zT0gzIP08Dm!TP}$G66ah&;JBeO%U~tyMh2l3ys3=nD^ZfIU`)^RJ9PT`}s1ow^o3q zfK~>hhuv}QT)384Pou=QGKO!1;??9?!Qs0$XJuNCnZlFQ_bCoB?AQ4NJQ4I&OsW_} zj~-}c?IORy3_IK*{P=yY*;C0GGFA?|7{7w?kY~58>u>MxPF1_1XT$}CSUR7ObrrbS|YZ z^Er@R#tCTJ)oJI%HTI21x=F4Od=gun(idjpPDn^#)_tYO&d$DVmNFx-VQN?VmUMFa z%0TqkkIznvee9tFSnCiqSgX6LOveWa1kU_Jn)i1f(vq%f1vBk9d5StU`_A!de$757 z9z&wdOW(i+Z<(T4r~f7GatlL|pROU(Dcr3!@pwX!uR@xXhT3NA5e(@wmZrhPes@B) z+s3)-2j9k_fdfqu=0WSjxT9NWyT$JITK#4Cl(w9-d-onQ1Lf4BJqUw2-VcCkQ-x=> z8=CzvY0vTehuxBZtf7Iu6f-VUyZRRQB~)ym?K7eMy4xYIu*Em$v{ncknzIQJms}u_ zPJ+~PVUVyvn>9cM%ePJN&mA@DZ5S@1rhJ|v%S@7pJ}-Qghz@zk-D%tHy({=j5>mJ6 z^z|QD3Nl{xdr?=#euClVAGo(+TaP_Jo~qI*bghv`PRDZ%*@j-XlZ|WZD?m$R*We)p zwf41zK(N$ps-B4MOf!bTtSjAsBw5eJBc12JS@p_Hsbe(qI zQ+uQu+mF&;#L$_mQBS_tR43RDu=0;^~N~b%5$G3Qkd8ix*G%Th|IpTN1Pr z5()Aj9GQ2f&~ykySrMW@IMh*1~)t1!Av3>AkqAxoaXE5;h~M5&6P_q$fRzus)j3S zaGT$!$(pf26hbl$xt!ev?G7&u?sS^;ygIulHt3E|6>o0X{cgK14N9AqSCYaY!xfL( z#OyXAr-rKHTrYj>-zD5}PsL4(8LgmFz^_u1+^(~8w(}Con(n^9UNJ=8=aZ6>jAfj~ zZ(!)f+{`__IO*&oT>7l&J&->;v>C=1r{O!1*4NIf?{!P42(sIRx5~Apo3||u6m+Q{ zu15H-uAA=cl)U){ZG!|s1<@HU+w zmpXP~01c+UvKft8)GT@}p4A84UorbR?fabP@qzp|dAL+jl<}+Fht=yvd)tnrjcZIS zG_Zx-?#kt_HobrQ2162r+UA$m*$GLuNcN?Ptc9$NJ-e|J*(Z%H60%cBWM8vnCtG&OzLO=g zC0U2x8R_%x^ZtEa-~Y~>=bYy}bMEW8uIs+<6Rdhqj+llR0DyA}@-p`U0D1-hAj?Eh z@XUt5g_i)p1SrVd(s-P-I^h^f-|9WQ>Fx(1A^M(T7s1Z&{?1cUo4uJYNA?$QylsK6gd~OAXM+kuH41G;SY+ei%>7Xc z5pOs?XRF9Dm|fxiOf5`)Mn>erDr1R|P`N;rkiDCQh3nMLQ@juMlhq^c2a}0YoonCo z$pCt|lqq)k zN`mk*-YR*yvD3;`SPvy(pp05HeEey%ApTI%gUk3Wn*_5=Bz727q~k*T3WQN26x^{%w@J{0la(drBS#L?cgpH=BZ$*K)LdU03qP&NGO|(TNysi8ZhgBMqBuOKouW=l=04TB7e!4PtN zsdO;eD#9dJ`yg$~Om^zX5qh;7mzkSXrmEvaZl?U`u!-!{3peb^t&^GWk%)0%c~0=_ z6(2u?Ud_Hh^sMB-RdNQY!4)i%f@#%Zk-@sj%JUzjgX&*@?7Wnb%z0X zGVqOA$Z0S#YeNc$9InSYy=Ilmb>-`5ve{Ar-uXu}TLI9)&gHD3?rK)07~*!SWt~Pb z_nv~Po#_To|K0te+SDtOyBlePojpD)!Gw%HKgU!^_6kZ5t2`u_o3dCV&i&L!rsZ06 z>vns#BfG^A;{z+N6yXw^gbGgD1#VP?%)pKLg)Y+VjJ>ovsVkV>O;W?*;$Sxgu2@6U zFt)FKa%U>VLZuV}h_O?&BED|<nc(&1tL86J-qsz5{KFiKSnP-DLj=9jt}`=+EOyY1F3SW) zNIH29BkVZa>`BUSaU~6-;`3wfhfX7b$z)&pw*RX{byvIYUw0yjnC%Q-5H1_Ddv_eV z7jWO}yol1DTSZhiobDleTgjM>*&>Uk%BQ4T?`Y5%s6j!>5G9vTV1ON|DWe%q3ngRx{CYo}%zplBb;On`4;Nc7*+bVY$kTLI zwW~sdTX6+~}Ptal#38X00 z4Z5!Q?${@HzP-5U#(P}ldthoVOE9k!#ui7CeE4?$``l%@uyGw<$ zFH4@U+$-xh?74re)Baf%4iUabi*6)GG9`QIKXn?PB8ZrMuELp{4rJ{$iI|)0X|75z z*ZwNCZ!>|_e3YBC=jLb6QDDLBb{X)NRHxrYi2tFcSEEJvGk54|H)0K?V!{LP-8o0j zMG!GhUh{CuSm^o{b#DEUo`veVWz{=7bH)p3hc)KC$%9<^ z0y|Xq0~tM>IP*hj)F{y9o~J??E_r1GjXQ;vec$sz-zA^prMfSYC z6jn1jGp0(hv{4fIRXP5~KH!xp!fKjuq!5I!8`)KE-K1$D)!&pD91s5)Rb-IpK8R$5 zo(0tG<@xZ?f()6)GVG5{;bvC+6QZN49fL{PozxE_Cyx@I!cemnY`TVtJGmdM1Ly&n ztyVbks7veF=4MJR{ENCM)Zmpe8YmIVvyUC_cgsB04Z;N;i?7`@)RA72j{hU=`)6~X+t*XZ)5`%-0CR&)nt)iyvcB3`v9R3Syh1@WDH^@-ynIn0 zPRB}qx0oy>x+9X_dFPUxCe4cSSH6&E0`N?FK?Ln39dZ(brK3@9CG*w`z=S7;jL^Tr z<(CfkP_0%K>dQyJv&$pO4{xFJ*Uz`-a+D-;OoyfU!O|8!`pLA4H@7}37mrlt15&Ex zh$2`&fx4TSBZDH(y&`Jf<{3P>L{(5eV>Es6-3-{sD>H!+v;r*SPv-FQq|jwK+^ov- zRips@p#Qa0I4I1N`b01QjU>YXg*%MR>&Q9z0z%wjO5(W&yD0fVOY1;#Jh46jpj)+v zS5BdV8DU}71L1;P>6cvhoU+H{BSFhOK0T* z7tUky3DCiO)M0uFyPX7ks9<6Y=DGvF05BECAoVTsZWt-0)OPUC8SU4Hhl`RWUh~N2 zQfDp*@NkBj^w2npuWVpoB{c^~N&K}w=Dgpzho)d+4Yjr9hJk-*!!Mk#tkjg-g#xH2 zK{O7-@4x`jXSj2M;8A6kseD^!VDz)~&S`_A<`y)`0~jPqV5yACPsU{m#HevxgWs0XfB z1=Mq#_|x!#OqOi+^dl3Phd5v2diBkklq4GGK|d21V0}^Z<$Ygy%RZmCPQttp>E~~( z?;myx7q7i>oU%7r(C|#>PkVwq4;NO%je6ro1MpXZ8oa4zE?YcO^LGJksWe}H?loJt zrsIjbjd3!IDJzR#AAl^CWhPvFk%m9wnltYwvlFY``5=Tf;~NAR~($44MW!Lw0y?1em5^ZukUpmXR>AJ_$f>>}V|cB^w6I zhx*6^y`cd-mJlF_kr@Jnv-}r*U7zEiHZO%1K7=nf{R0TFghgwt%F}@eLfAdp`~3Am=8sBe4i>`{29Lmxh5@7^g<~I8idcxEN)j1Fu^gH zjf%UpXn8VtWA%iWl0pwiSl=b%Vg*R*0xSdu- zE{77b6iY(U0kQ+o8!jVNG=U@wWT|@bn>u4$E{}j4oZ!`S9Jk6QtUoaIVdp8Fi7!`P zw6MDa@Atw3&V^(XWYWO-^Q<>Pl36Kn7wK||jpEj(e>TE9U5#(#gwJ?ssUk)8ar}c% zi}xg`ve|)zq0KEgUw-C35x{;4e6jf$;@>aU5PI@rL#(y<(F%9uiLUPEl|!WEYocsIG5HJ&PzIW@5&SpW@J48XkdTo)qeeI=ol$8Yt?phHct zz>K>OsdV!>+-}0r4a7Z%>-LY1)SSXpQ+d@@D}C* zN5_CyFAK5iRL!h;Z;d*;dYYz$WKTg-q&4aW19&{O=Nua7SfZ|#j1Ar-(WeJKyxA}H zpkr$*)8(dOt*omqO0tb@x)BJGegdvX^EM*GnA=Au+|v6d@4NW5$l2mw-Fyc$bz8Ca z_*pRY!v?uCqCA#;cjM!`PeJhP(P1@y6H~SiA-W9rMzs+Hzuzbb0yq(D;^Kg^1z>wi zekozPeCtfF0S2?CqZh|`RxT9Z-&4(DXLV7mw}+$8TQ2!g0_a_wY58xNxF`^& zig}PHy#=BGxBGviAWrxc1x6&K<8CTToB;XTX(+x@$2IG{-f>7xtE=T2`lxZ_$mK&R zIUHc3Y~HM|@pauIw7ce3#fN|<<(^<9<=|8u{LT&)99wrF7!JNuDQTm_fh&4QilC+f zU+hXLt3o8J!m;}C6@^GWALlH^84SMg%$c+GtW2!+uyQNB+0BBZ`MSc4I&4W@fet@2 z)O0^;%iDr3w4L?lSPNWYN-JK;UN@?rq&@5U z6~#Fn=(IvGqqd7!7;)1$3pt?K=2R1AskUr0f<&|K2^(4IvCYQ>fKtp4BdlWrA$9m_YCTnm~Lk(dXS zLrU`Km(x|kkfn22BVih^`A^L%-Ynj`(O0JSniD&;^ELGdaIt}N^1+B;4vkolcBSRf zLm}!gge(C9n((XMdk2#bB`YW#BAM2K0!=Kt+a}a(OrgI` zij2i^t;D;YBvKs+0@^tJIa?Y-1S5J%%LiOwVP!gN*MCMPC>+g)gH= z?Hpxfah((YK)#tQhsB9SaoBVMiOP6&vh?zAtt!EOJL-%gn_b#`xqo8|%mA{7vZMs& z3z9nD?jp4?aJWg7G^Pa~i8Q$GO9F|Wa(pY4Vg2A&mnNzHcKfzrm0(|cXVwl@pd-wT zxKWx8bT38^Ww&)Rk9GWPvJM2)vK0a0=9y}IX`%}w_6_T-8Y=|d;{_fuu_aOhrSGfX2rY$~4GO-34ag1% zK%vi;%crr`_#@U9qYqJU<~jzX8_Z8|muH`^oCN#>PG&pJl?LOb=oua4QlG|8EAL3adH1Z7*`OXGqED&z0q8A8dJ z!RQ8A^V|f2!_gT8bu+?faSZ+qi$BUpR&~mWDQb|q6`;&TeF>}>KD_lm@m6&`hhpL* zt42y_gM*9Zn)DJ95TpgE^$nC6lDFuyqQ&H6tg^oN8*K9i)NCo2e_JEffg^9vd&we< zg-{H>3x2E?LH1?Vl*<(mJXLyT2z`U?D0-O)wnSvNa8^T`pOuTdATAh$(O=H!miS=g z-82jd6)#9#d@&PMu9*DB01%jEQWMGXa0H!%&;4YITF{bji*8$Fh(}+Z!(@x7r7D4F zt6vP++~dYq`36W)5`iP{Vq3j4)hg&ZX3d@}4}8x?M)6T(QzicIe6u*#@qjGucCGE^Sb;rRt=3o>}`!w`}!P&Hk+ z(Fvyx46;hO(TeBNb2s%G00e>T`2U-5qPB+*uQfh|bCQMp!I{yUQxgv8gg#o)O1Wd) z({hTlfd`-_eE5ws_Kv@B#zdv9-TW3TP<*H$#A83l3~6hAHOglN+OG6@3IWG5DSe#l zI%@x~}wfgY3T6qYPsPGrla9A>CT1JdamkG2?Z++5jaEWySdvsX2dP zQPgH9pC0GX4#O_jT-WR8dhi@h0RBtsZbMahxslGniVYb8n=-&PsVYLdI?yt@OF4wMx%rn3aVa8YRPoI5#aj#j;H zMFf-PS&Kz0+?EHp{HCB(M1J9bO>qUE6exH@P;%ST98X%So{^Po@c)9>M%aTqYLb_# zPr7OTWc{P2V4m=d7=xbz8z-R*YkV!zQ-lu$$!=WB;!^|?N-8}hTqwv&u?N4BB%LLV z2*AZSzp305H3AdJt{LmGAUbA<<@uejx4z;=Dx9yd{BIhAv=qnK(6H%MJQmToOZMV_ z)0jieziA9|PAOCkYS;)Xe_#F3=Ngo=Zcg6bcA(hCS(9{Pl+A7ZU82Z#t*`k=k+Q_S zFBG1DT)Y~TiRD1+i!ax$?ItrJ@qXMzi}N?eTz2>^4*Hjs$viA98Cu~+&z5!7eC5Lr zB205^S0lm90M!!@V=$=|Na5^OLSN0c_m90Kmn~a%vue$@C|=!lYuj6WF6L9%W&9{G zRXD5WeeLibqSRoy1G{hNE&|Fk=!ZR?b_+K5602jMo( zMJ`d0qK4=5lQD+dhy|Ve?_YGuCk*pn4=~2?lzbk;YXNhFa{P!OaBYIDrZiexsp2u$ z-s7DeltID3OmT1=%yDO_3g|c5zmp<+_M2qBjdC#e7gGN1<{pSmtC*kJ|7BZ_$%f7L zfw?2_H8@*}DDEUea84G`Qzd-F!pTGs(B7m>^AtRG@Bp7D#ZQZg74QM+iZmdtw^Tau zk0IOOndYUV?)bluWyxq>>Pq`k6;kmZWQl`ECjx27X2&z8X{_RM%3J;_Aa8M(ogho~ z-QUOxakSF>5)ux)rxr4jt^t=D;+S~z^n~-Bntu`4Y1$~QgZh-A*61G+3ziPj|F;`E zT>6h2%c8qmxH5tvsV6X zVKwdV5X7fYc<&uG?;tRjRF!ZXIoIQYQ&BJ|H(%9Cv4aLolqs9E=qQ|N=kh15u@h_# zy>>2>qCfm9opL8Bwig24{F}5!k1B=Q&F_t5tQ=&taH}(_2-o5VX*IgTR;dO8m)zjl z+wFR5u`BHzBgyfgTkMm=Gtq~J&Jiw!W{SpfT*)TwJ8*{;W4m0IPs$ZI;xhXp_>m$= zMx!cK?VbkXo7V7@^@`XkR7`d0YTbgjg$ziGoSqd-%JlkAxu7`2R@bbl+^FSEeR89Q_M6 zY??A=N30J43k(0VI04|7Ak!LIHGqcy6enoUd{oQKl$HmWn&RAY{H2V0lui-$ND)NX zaN!BU*hl|TMu4{B{W9hKtv>+V8l-Ji>k;w7qu7bDd){kh^z{;28_#YZ!*8AJuBbb@l!yTiIdtP?%s9p55NS3ZrbS=c0sfV}5K7cL@0cgW?CLJQ`YmU z|9-q6Kl+c!e{rVbA(d)KrbjM0OSbLWZ-+0sJt)%}oAbo4;~5ajmW>@f8N1Gkt88@K zs}Te%T+0uzsh;sX*PMKrdnFW7M+OD z1^_aWf9m3cdsf2$K+=i(7T`}o>|x6VfH!U!Ndt13OS_S<=nXd}7w%E(Q4=pcm_i9=`|BK6j!`bC*ZiGBAO|@fWc>#QAU4^=C2w48#ZN?_) zzBQHC0n(uc7tzage>Zval7-I|Bg#nKwxeb4W_?7fG>8Godi`4N&F@`X)6 zQTmR?*gLQ|UYs8DJoj%W)`4?kvfaV~4UlQlR`@g7Qt##8cHi`m-3QLiRbw8i*)sml zDko^?YC~E&MaGh2=FpveMy>}yA6Pk0Rn-`4#UV|$V7vhHH_|F8!P1;Z!-Z$o2alzA zZg(Whkt-QjE?LGYjjxR1W^T-CHDNJ;9f zJ~+uFUkc;OYe28;0Lh)}C&7YSp9Tw##DoL&1(^#IY1GURG_Rgk$|DeD%jKsI>`fks zx7&FM;6)+mRT{;rt1bipPy|Zpzxsn$&FLVPfuG_B+CduQ;HM5d-$hTP9})l(8m`I? zqzJOl#8euq>@EDxBiW=u7PE{$saj0`?e78ZkLj9N(BE5Lva6paWrj$1I3(Wm1s8=3 zNEA6x|5qOQ9~MJv|D%*|DXZL8!LLZb)=Hy|Z>5v~8%7xC#?>G1wU;hGTJBMH=adt~ z?yK`7GRtpk04%X!_5Ih8O>B&IXF0j*9=)6gD$&Y7Q)qnjz;!(mbYbUx%tz9dM}AtE zAGOPDQ!W$B1LB}&f=!Qd_2VM^fp0MqYs%|mHA=5RovCeIUeE=b6oFKTBWOgG`B$VS?| ziX|Hu+r;_(=bSqv+Vg+>KKJA35aSD^XxHFuU44CU9#A?5Cw{IStaT-wKur#J|C`Z0 z1KgmAe7J2nGNvp4A6j$&iM>Z>e1-*dX0q=pGbis2goj&6cLh4Jg!i83(;?4e`#OI^ z*H*ydR)>M=r)nf5C~zdN?6vq9B@S~my?rJvfTCk&d|*c)Q@mH!Am0-Uz#+qLDo>ID)Xn7MaSOYndfOi}Vs(#8VyyT< z-s3L(gG6TV3Z4;A^F0@-?6c>QT6e)&&xf6xm&x*mV()HK5(1XI|M1@*&Kvb;=`%^j zKE&Gw0Q_=UdDX>R03d1~67B#tY0Q@)08tp&FZ*}H;7{B8q=H5==EvP@E4DMq zSV?^DlUP@fy|At{*v9-V*vmO8U(S4t_)s$pohSpl)KfnDIjN|=a9k%K4LapehVK5B zZ;h)j-`x(@-jvWEfljn6c2F9T$kQp2JuKF}9SqLyRcixj<>qUtiPhFFh|N>}ep*uI zE-50YeBKkwT~A4UnKd_$jbgcyx<2_V2Wo*}L1Zwl-Is(DJ zx%u*R#LzM>4 zj%e9x3<-_D^(FjC%CU9p#leT6?kW4~_#rKA50bCmO{H5k-Yuh!8oGx!LO6MN5@^@vL?$XD%jpUSK+t0dYj`~o}FKQI;Gr!ij+pE-By1MD|{a(+i!TicGjRNjKT zyl(~E+C8wvM^&p8wpzT$&pVDiTWw36_8I~iDONU_UgjAOXy?^Fk*aZE*}7bM^f)hg zzr3=g@&iYCOttnr7SrWs+x6`;^b1d?JB)GCo3FsZo7;RganaYPYb5kD>W1Oc51(zJ zmEB0rXw1-E?G1WWyMv9uMjx-z+=+ecMG+|j)Wc2fi5w@?Cr`~um5N>c#ZsrP!ba3!3B5 zeIc#SQ+*Y;CzUJ=Re9~d>*}v_q>iiTXpb}O^L5Y6C&bBSUBqUA({x&NHPN8vtw>A_ zDxBBHn;97elZ$H&OUOzKo!67%b<9dCe90@be`Z{B*ld;aCnJ?S%=F@r5_BInvfT=E zidXkOXFXI;$)`l-FEv@+)Y-AJZz*p3Bt%LwVedVsIDdO*_mSC z7mDcA%70DX-7lo*bALH4YSYNvqpDVPJGdh$RkC4OmudYSx06rxU{hzw-J{`-Jo)1+ z;?)`*-^TdTi#NP=%K|0w;~amEzNn48s;J_=DmT@Ud(YR^*7mM>W)8o})$;q>VY&Vn z>kP3EqVvnpuOr>FWh7?ot7?9wt>;x^owpr44hRPp+4{FtyyjPv4Ij9Bf+r+2Go+ij zRS)~ijvjZ(l!UX_^`sA_A9rpeI+Gn12n~9FJ|OQ}RWHcsF{qu(mumA|9?x1#$hvLC zHfXSkeWOt7TSYACU35e+T)P_6ncWrDqVeEcjNv2HOf#w)yg}G)`2)L9bH&Q?Bx&_G zwZ@UyI`#C!LhKYARj}*R_jXh&qJ-CXanX0j_s47R0}J1s23?=3NkJ_QGZLFU&2mbE z!j>Ah;~DV2{*4~f@qtI{gp(Q9QeTVg*$j)~PeC`@TNgb$?2lIhhIIVv_H}%#o9mXC z>UM@DBNiO%FxLzJP~3FBwTTgl3vDv5E}DD#BD~_I;2(B`ScQcD)|7-SMF&t*2Ag10 z&;AwiAt|&Lay;Ab`y;)z&cH1i0L(N{FXa&a81Um&nQw}E zK7wEKAP}IEb5#WFaQxM+^gsmRI!-Qv0Py5o?GID1DG9vUJcgJNf6J$)SQZ06^#v4U L@5$sNjQsu|cF+!2 literal 0 HcmV?d00001 diff --git a/doc/en/kdirstat-main.png b/doc/en/kdirstat-main.png new file mode 100644 index 0000000000000000000000000000000000000000..e1fdcb6a67cd58add595d217754337d02834ee20 GIT binary patch literal 39583 zcma&N1ymecyDi#CaCdh?V6?(PH#?hXkMEJ1=>2=4Cg!QF!dcWwMO+55le%6sR% zF^V2kcdc4gpUh9zT#+hD(g*|y00014Rz^Y%0D#g503eRwAi>`>AfllF0Av7J2~iEN zjN|q|8$#XG&vcJJnufOD6C{&e+>Ah4aJHaR&ecTBQBT zy~2WcT>u!CAP6LroMK4ouPJI=!Z)(Uc}=k@AJnp7fLI8j6Ub_*N~bhc?X4fKgxs?r z9&c&X2qgeGQ2!apAsYncWp5hMI!?`8fbq%+pKKt&pG!sm&MwjD0{#5}&1nVYkCs`? zGbM&!jMweFFxG{Lq}M%^?PTib=%8MWl^ON+_m&C}0Fg?jX$HY9l$vSF|J>UohZfQf zdcFJlBk^?T5}%ljJyeiRE(=nx#?R0*1%)n+DWKnv#yk9+Gv!oS1}uaRA3g}u8yC7? zPT(Q{sv673Sfm1HDWcP+Rd2{+GHPrPrs=J;GIT{xU6zzX-=rxsBU-E>G-NO@ZBg= z@>`<{Pyq^peZZLenuI5A zYiG&Pe9c*-CH0Iy@UQp*P>R@-dJb&$p#3qSN=q1wkP*6AvoR*b`R@T_CV+pn8N3T$w1CcJqziVM z#fM%Loz27S-6Vh~W4I-l*bDbpzrt4fVo_#+ zMutTgN|lS@1pY;lUuUVl{51h~F|ELYS(}mtpqi^p_CN;^@jgdax=4~!w@d=fq?iE` z>%&CRX?~7Q)M2N_ooprEhl4r!=h+7x3A(=JWi$HSL{mS###k0ZV4{#ux!lqyoz_DM zeBYOOtmH(6^fF3@;vbdKM$58D{}J<~1_ZK3a-#Cm&@{Osf%_LzA3AyB3&X>qSP&EY zy^5Z65$K_YzILF%J&Zqq2sY^cT8v>Gf?lY{-`_XUJq&*hb8sn1#KK*{!o8+n3<9vc zvdm%ntX(TpYk>3h#Kf4@Kk_!o4SgO>m6PFr%J=Y?uy5w_x8PNV$-!lA)wpw;+ znT2${$QwNMsfTInhZS$=>4vEp*>4sE_y%Y>YSs(H(Yk|h%A3pfys<73HRUj3AUHn=% zX;-SmoO%eEqb`*xPuZNPKwQa8{05BiI3hI$)7IZ#dam&w^Ad*;XRK$XIgL5-$|z@H zZ*NXiA;GV%ex^K?^d(j(xS^rzu;1el?|G_57l|5gq*#KxUZ*#Yk%N17P{o?R{3FSK z0idSHSbr@hnR=rxwGI!C2iC=z(~7l)@zw`$F`kku=AO4_959m(zf zT_%{owmTnf*_Hf#qdL3?U2`a;vog)*wPoC`qNWlZTlWD(1not~btj9zlOa`e+dE)2 z-+$tFe6rR0W^#oZP4ct#QyFXO53L=n@FCA=^)2qkv#NMw4FziNIc<5(n}kCbMZ_fJ zj^z;@rO%W}W$I$h9y6u6j@&WlYSKm2DG_1y5r>I62lgv1wq{>ovsz={3^Km{(-@8X zFB0zD!>(P@)0T@u{6CN2e}LhPtnmh4YhBVi^+#fa$I6K610V;sii%6D9!fF3Yeo?S z)F)JbL3^ZIlF{v013#rzzl&Z$xlvOICC69ABge(^Lzz8Ajh{)Y9?);vDC2dwhvR;A z)~59{Hyt3W7BZn25xb<@bh$X%U94a$z%xteGMFPoWRG~LjB4B#ug_KuZ%ANFpXCYW z|D&Dn7M%CxqcLG}5u%Qb&0_iT0Jj*s-WTku%71Kx-iA?Z7&xVwWSOHxb^w`f-ioB2 zmYeJVoMfpfvxtVCFLC6I;?Nk#<9WoNOH4DfcSzx@&dr)X+17)NVFO<-r>9$Lx+aa2 zppAW`!i~XDN0;jeOg{|%CiRb$LLc43O1HEjwO?(vG}-dYEb`S#wkT&yTW&TD3x>*3 z3Gd&JQKf_6GQAZvqdvr}&Gj|Omahz!qa5N)+FMeu{%l+XswI?F)X?r8!JU*?1OKrp zf%@fs$D`gB_zoZV=7&LiMJan;P1SmouXEFOg|(ENbSWw~QFsUrCa⁡aWW>u%>Uk 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 +Maintained-by: Stefan Hundhammer +Primary-site: http://kdirstat.sourceforge.net/ +Home-page: http://kdirstat.sourceforge.net/ +Original-site: http://kdirstat.sourceforge.net/ +Platforms: Linux and other Unices +Copying-policy: GNU Public License +End diff --git a/kdirstat.spec b/kdirstat.spec new file mode 100644 index 0000000..3b04c79 --- /dev/null +++ b/kdirstat.spec @@ -0,0 +1,70 @@ +# +# spec file for package kdirstat (Version 2.4.4) +# +# Copyright (c) 2005 SUSE LINUX Products GmbH, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://www.suse.de/feedback/ +# + +# norootforbuild +# neededforbuild kde3-devel-packages + +BuildRequires: aaa_base acl attr bash bind-utils bison bzip2 coreutils cpio cpp cracklib cvs cyrus-sasl db devs diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv klogd less libacl libattr libgcc libnscd libselinux libstdc++ libxcrypt libzio m4 make man mktemp module-init-tools ncurses ncurses-devel net-tools netcfg openldap2-client openssl pam pam-modules patch permissions popt procinfo procps psmisc pwdutils rcs readline sed strace syslogd sysvinit tar tcpd texinfo timezone unzip util-linux vim zlib zlib-devel arts arts-devel autoconf automake binutils expat fam fam-devel fontconfig fontconfig-devel freeglut freeglut-devel freetype2 freetype2-devel gcc gcc-c++ gdbm gettext glib2 glib2-devel gnome-filesystem jack jack-devel kdelibs3 kdelibs3-devel kdelibs3-doc libart_lgpl libart_lgpl-devel libgcrypt libgcrypt-devel libgpg-error libgpg-error-devel libidn libidn-devel libjpeg libjpeg-devel liblcms liblcms-devel libmng libmng-devel libpng libpng-devel libstdc++-devel libtiff libtiff-devel libtool libxml2 libxml2-devel libxslt libxslt-devel openssl-devel pcre pcre-devel perl python qt3 qt3-devel rpm unsermake update-desktop-files xorg-x11-Mesa xorg-x11-Mesa-devel xorg-x11-devel xorg-x11-libs + +Name: kdirstat +URL: http://kdirstat.sourceforge.net +License: GPL +Group: Productivity/File utilities +Summary: Graphical Directory Statistics for Used Disk Space +Version: 2.4.4 +Release: 0 +BuildRoot: %{_tmppath}/%{name}-%{version}-build +Source0: kdirstat-%{version}.tar.bz2 + +%description +KDirStat (KDE Directory Statistics) is a utility program that sums up +disk usage for directory trees - very much like the Unix 'du' command. +It can also help you clean up used space. + + + +Authors: +-------- + Stefan Hundhammer + +%prep +%setup -q +. /etc/opt/kde3/common_options +update_admin --no-unsermake + +%build +. /etc/opt/kde3/common_options +./configure $configkde --disable-final +make + +%install +. /etc/opt/kde3/common_options +make DESTDIR=$RPM_BUILD_ROOT $INSTALL_TARGET +%suse_update_desktop_file %name Filesystem +%find_lang %name + +%files -f %name.lang +%defattr(-,root,root) +%doc COPYING AUTHORS ChangeLog TODO README +/opt/kde3/bin/kdirstat +/opt/kde3/share/apps/kdirstat +/opt/kde3/share/appl*/*/kdirstat* +/opt/kde3/share/doc/HTML/*/kdirstat/ +%dir /opt/kde3/share/icons/hicolor/16x16 +%dir /opt/kde3/share/icons/hicolor/16x16/apps +%dir /opt/kde3/share/icons/hicolor/32x32 +%dir /opt/kde3/share/icons/hicolor/32x32/apps +%dir /opt/kde3/share/icons/locolor/16x16/apps +%dir /opt/kde3/share/icons/locolor/32x32/apps +/opt/kde3/share/icons/??color/??x??/*/kdirstat* +%dir /opt/kde3/share/apps/kconf_update +/opt/kde3/share/apps/kconf_update/kdirstat.upd +/opt/kde3/share/apps/kconf_update/fix_move_to_trash_bin.pl + diff --git a/kdirstat/Makefile.am b/kdirstat/Makefile.am new file mode 100644 index 0000000..8ae3a22 --- /dev/null +++ b/kdirstat/Makefile.am @@ -0,0 +1,98 @@ + +# Makefile.am for kdirstat/kdirstat +# +# Initially generated by KDevelop, cleaned up by + +SUBDIRS = pics + +bin_PROGRAMS = kdirstat + + +kdirstat_SOURCES = \ + kdirstatmain.cpp \ + kdirstatapp.cpp \ + kdirstatfeedback.cpp \ + kfeedback.cpp \ + kdirtreeview.cpp \ + kdirtreeiterators.cpp \ + kdirtree.cpp \ + ktreemapview.cpp \ + ktreemaptile.cpp \ + kcleanup.cpp \ + kstdcleanup.cpp \ + kcleanupcollection.cpp \ + kdirstatsettings.cpp \ + kdirsaver.cpp \ + kactivitytracker.cpp \ + kpacman.cpp + + +noinst_HEADERS = \ + kdirstatapp.h \ + kfeedback.h \ + kdirtreeview.h \ + kdirtreeiterators.h \ + kdirtree.h \ + ktreemapview.h \ + ktreemaptile.h \ + kcleanup.h \ + kstdcleanup.h \ + kcleanupcollection.h \ + kdirstatsettings.h \ + kdirsaver.h \ + kactivitytracker.h \ + kpacman.h + + +EXTRA_DIST = \ + kdirstatui.rc \ + kdirstat.desktop \ + lo32-app-kdirstat.png \ + lo16-app-kdirstat.png \ + hi32-app-kdirstat.png \ + hi16-app-kdirstat.png + + +updatedir = $(kde_datadir)/kconf_update +update_DATA = kdirstat.upd +update_SCRIPTS = fix_move_to_trash_bin.pl + + +kdirstat_LDADD = $(LIB_KFILE) + +KDE_ICON = kdirstat + +applnkdir = $(kde_appsdir)/Utilities +applnk_DATA = kdirstat.desktop + +####### kdevelop will overwrite this part!!! (end)############ +# this 10 paths are KDE specific. Use them: +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_appsdir Where your application file (.kdelnk) should go to. +# kde_icondir Where your icon should go to. +# kde_minidir Where your mini icon should go to. +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to.(contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to. +# kde_mimedir Where mimetypes should go to. +# kde_toolbardir Where general toolbar icons should go to. +# kde_wallpaperdir Where general wallpapers should go to. + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + +METASOURCES = AUTO + +# the library search path. +kdirstat_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +rcdir = $(kde_datadir)/kdirstat +rc_DATA = kdirstatui.rc + +messages: rc.cpp + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/kdirstat.pot; \ + fi + diff --git a/kdirstat/fix_move_to_trash_bin.pl b/kdirstat/fix_move_to_trash_bin.pl new file mode 100755 index 0000000..6a42af8 --- /dev/null +++ b/kdirstat/fix_move_to_trash_bin.pl @@ -0,0 +1,9 @@ +#!/usr/bin/perl +# +# Replace ~/KDesktop/Trash to %t +# +while( <> ) +{ + s:~?\S*/\S*Trash\S*:%t: if ( /^\s*command\s*=\s*kfmclient\s+move/ ); + print $_; +} diff --git a/kdirstat/hi16-app-kdirstat.png b/kdirstat/hi16-app-kdirstat.png new file mode 100644 index 0000000000000000000000000000000000000000..4bd140e8c5b9a60cc6080c3a88cd16429d392a25 GIT binary patch literal 303 zcmV+~0nq-5P)HUU5LRwba1Z{rjnR+B2_jTx&CdwKV`;mx_R80yCTK;RIVx zC{OgA8QgB4n>`WP2Q1UPf|x@UdKy85gfi;et~1 zIf4rc-{Yka0$B(ou;ra$BrxcGyAnSZNE17Kk$6p#QU_zclDXhrJr(3F!MSn&_iGMZ z2_4MvTShT6vr@_yVbJ=(}JP zyOc6|{#5ahHjZa!F^aoHT<1$;xBFAtL`Un2mgV4F>v@P2=T=Emkm5MBKUKVZHb7Bq zXZL++r=K(hAt$9Cd{o65GIIWuk`k!v%c2C9C<(wm#ikrCal8ru-h;|dBzpo&6Uhz` zOXL**vx&SM;E_a85+ApH4 cDa;xE2cxNpXzC!vS^xk507*qoM6N<$f=gKCH~;_u literal 0 HcmV?d00001 diff --git a/kdirstat/kactivitytracker.cpp b/kdirstat/kactivitytracker.cpp new file mode 100644 index 0000000..a7a1826 --- /dev/null +++ b/kdirstat/kactivitytracker.cpp @@ -0,0 +1,93 @@ + +/* + * File name: kactivitytracker.cpp + * Summary: Utility object to track user activity + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#include +#include +#include +#include "kactivitytracker.h" + + +KActivityTracker::KActivityTracker( QObject * parent, + const QString & id, + long initialThreshold ) + : QObject( parent ) +{ + _id = id; + + KConfig * config = kapp->config(); + config->setGroup( _id ); + _sum = config->readNumEntry( "activityPoints", 0 ); + _lastSignal = config->readNumEntry( "lastSignal" , 0 ); + _threshold = config->readNumEntry( "threshold", initialThreshold ); +} + + +KActivityTracker::~KActivityTracker() +{ + // NOP +} + + +void +KActivityTracker::setThreshold( long threshold ) +{ + _threshold = threshold; + + KConfig * config = kapp->config(); + config->setGroup( _id ); + config->writeEntry( "threshold", _threshold ); + + checkThreshold(); +} + + +void +KActivityTracker::trackActivity( int points ) +{ + _sum += points; + + if ( _sum < 0 ) // handle long int overflow + _sum = 0; + +#if 0 + kdDebug() << "Adding " << points << " activity points." + << " Total: " << _sum << " threshold: " << _threshold + << endl; +#endif + + KConfig * config = kapp->config(); + config->setGroup( _id ); + config->writeEntry( "activityPoints", _sum ); + + checkThreshold(); +} + + +void +KActivityTracker::checkThreshold() +{ + if ( _sum > _threshold && _lastSignal < _threshold ) + { + // kdDebug() << "Activity threshold reached for " << _id << endl; + + _lastSignal = _sum; + KConfig * config = kapp->config(); + config->setGroup( _id ); + config->writeEntry( "lastSignal", _lastSignal ); + + emit thresholdReached(); + } +} + + + + +// EOF diff --git a/kdirstat/kactivitytracker.h b/kdirstat/kactivitytracker.h new file mode 100644 index 0000000..081d1d8 --- /dev/null +++ b/kdirstat/kactivitytracker.h @@ -0,0 +1,109 @@ +/* + * File name: kactivitytracker.h + * Summary: Utility object to track user activity + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KActivityTracker_h +#define KActivityTracker_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + + +/** + * Helper class to track user activity of any kind: When the user uses an + * application's actions (menu items etc.), those actions notify this object of + * that fact. Each action has an amount of "activity points" assigned + * (i.e. what this action is "worth"). Those points are summed up here, and + * when a certain number of points is reached, a signal is triggered. This + * signal can be used for example to ask the user if he wouldn't like to rate + * this program - or register it if this is a shareware program. + * + * @short User activity tracker + **/ +class KActivityTracker: public QObject +{ + Q_OBJECT +public: + /** + * Constructor. The ID is a name for the KConfig object to look in for + * accumulated activity points so far. 'initialThreshold' is only used if + * the application's @ref KConfig object doesn't contain a corresponding + * entry yet. + **/ + KActivityTracker( QObject * parent, + const QString & id, + long initialThreshold ); + + /** + * Destructor. + **/ + virtual ~KActivityTracker(); + + /** + * Returns the number of activity points accumulated so far. + **/ + long sum() const { return _sum; } + + /** + * Sets the activity threshold, i.e. when a signal will be sent. + **/ + void setThreshold( long threshold ); + + /** + * Returns the current threshold. + **/ + long threshold() const { return _threshold; } + + /** + * Check the sum of activity points accumulated so far against the current + * threshold and emit a signal if appropriate. + **/ + void checkThreshold(); + + +public slots: + + /** + * Track an activity, i.e. add the specified amount of activity points to + * the accumulated sum. + **/ + void trackActivity( int points ); + + /** + * Set the threshold to its double value. + **/ + void doubleThreshold() { setThreshold( 2 * threshold() ); } + + +signals: + + /** + * Emitted when the activity threshold is reached. + * + * You might want to set the threshold to a new value when this signal is + * emitted. You can simply connect it to @ref doubleThreshold(). + **/ + void thresholdReached( void ); + + +protected: + + long _sum; + long _threshold; + long _lastSignal; + QString _id; +}; + +#endif // KActivityTracker_h + + +// EOF diff --git a/kdirstat/kcleanup.cpp b/kdirstat/kcleanup.cpp new file mode 100644 index 0000000..01251a2 --- /dev/null +++ b/kdirstat/kcleanup.cpp @@ -0,0 +1,432 @@ +/* + * File name: kcleanup.cpp + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2004-11-23 + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "kcleanup.h" +#include "kdirsaver.h" + +#define VERBOSE_RUN_COMMAND 1 +#define SIMULATE_COMMAND 0 + +using namespace KDirStat; + + +KCleanup::KCleanup( QString id, + QString command, + QString title, + KActionCollection * parent ) + + : KAction( title, + 0, // accel + parent, + id ) + + , _id ( id ) + , _command ( command ) + , _title ( title ) +{ + _selection = 0; + _enabled = true; + _worksForDir = true; + _worksForFile = false; + _worksForDotEntry = false; + _worksLocalOnly = true; + _recurse = false; + _askForConfirmation = false; + _refreshPolicy = noRefresh; + + KAction::setEnabled( false ); +} + + +KCleanup::KCleanup( const KCleanup &src ) + : KAction() +{ + copy( src ); +} + + +KCleanup & +KCleanup::operator= ( const KCleanup &src ) +{ + copy( src ); + + return *this; +} + + +void +KCleanup::copy( const KCleanup &src ) +{ + setTitle( src.title() ); + _selection = src.selection(); + _id = src.id(); + _command = src.command(); + _enabled = src.enabled(); + _worksForDir = src.worksForDir(); + _worksForFile = src.worksForFile(); + _worksForDotEntry = src.worksForDotEntry(); + _worksLocalOnly = src.worksLocalOnly(); + _recurse = src.recurse(); + _askForConfirmation = src.askForConfirmation(); + _refreshPolicy = src.refreshPolicy(); +} + + +void +KCleanup::setTitle( const QString &title ) +{ + _title = title; + KAction::setText( _title ); +} + + +bool +KCleanup::worksFor( KFileInfo *item ) const +{ + if ( ! _enabled || ! item ) + return false; + + if ( worksLocalOnly() && ! item->tree()->isFileProtocol() ) + return false; + + if ( item->isDotEntry() ) return worksForDotEntry(); + if ( item->isDir() ) return worksForDir(); + + return worksForFile(); +} + + +void +KCleanup::selectionChanged( KFileInfo *selection ) +{ + bool enabled = false; + _selection = selection; + + if ( selection ) + { + enabled = worksFor( selection ); + + if ( ! selection->isFinished() ) + { + // This subtree isn't finished reading yet + + switch ( _refreshPolicy ) + { + // Refresh policies that would cause this subtree to be deleted + case refreshThis: + case refreshParent: + case assumeDeleted: + + // Prevent premature deletion of this tree - this would + // cause a core dump for sure. + enabled = false; + break; + + default: + break; + } + + } + } + + KAction::setEnabled( enabled ); +} + + +void +KCleanup::executeWithSelection() +{ + if ( _selection ) + execute( _selection ); +} + + +bool +KCleanup::confirmation( KFileInfo * item ) +{ + QString msg; + + if ( item->isDir() || item->isDotEntry() ) + { + msg = i18n( "%1\nin directory %2" ).arg( cleanTitle() ).arg( item->url() ); + } + else + { + msg = i18n( "%1\nfor file %2" ).arg( cleanTitle() ).arg( item->url() ); + } + + if ( KMessageBox::warningContinueCancel( 0, // parentWidget + msg, // message + i18n( "Please Confirm" ), // caption + i18n( "Confirm" ) // confirmButtonLabel + ) == KMessageBox::Continue ) + return true; + else + return false; +} + + +void +KCleanup::execute( KFileInfo *item ) +{ + if ( worksFor( item ) ) + { + if ( _askForConfirmation && ! confirmation( item ) ) + return; + + KDirTree * tree = item->tree(); + + executeRecursive( item ); + + switch ( _refreshPolicy ) + { + case noRefresh: + // Do nothing. + break; + + + case refreshThis: + tree->refresh( item ); + break; + + + case refreshParent: + tree->refresh( item->parent() ); + break; + + + case assumeDeleted: + + // Assume the cleanup action has deleted the item. + // Modify the KDirTree accordingly. + + tree->deleteSubtree( item ); + + // Don't try to figure out a reasonable next selection - the + // views have to do that while handling the subtree + // deletion. Only the views have any knowledge about a + // reasonable strategy for choosing a next selection. Unlike + // the view items, the KFileInfo items don't have an order that + // makes any sense to the user. + + break; + } + } + + emit executed(); +} + + +void +KCleanup::executeRecursive( KFileInfo *item ) +{ + if ( worksFor( item ) ) + { + if ( _recurse ) + { + // Recurse into all subdirectories. + + KFileInfo * subdir = item->firstChild(); + + while ( subdir ) + { + if ( subdir->isDir() ) + { + /** + * Recursively execute in this subdirectory, but only if it + * really is a directory: File children might have been + * reparented to the directory (normally, they reside in + * the dot entry) if there are no real subdirectories on + * this directory level. + **/ + executeRecursive( subdir ); + } + subdir = subdir->next(); + } + } + + + // Perform cleanup for this directory. + + runCommand( item, _command ); + } +} + + +const QString +KCleanup::itemDir( const KFileInfo *item ) const +{ + QString dir = item->url(); + + if ( ! item->isDir() && ! item->isDotEntry() ) + { + dir.replace ( QRegExp ( "/[^/]*$" ), "" ); + } + + return dir; +} + + +QString +KCleanup::cleanTitle() const +{ + // Use the cleanup action's title, if possible. + + QString title = _title; + + if ( title.isEmpty() ) + { + title = _id; + } + + // Get rid of any "&" characters in the text that denote keyboard + // shortcuts in menus. + title.replace( QRegExp( "&" ), "" ); + + return title; +} + + +QString +KCleanup::expandVariables( const KFileInfo * item, + const QString & unexpanded ) const +{ + QString expanded = unexpanded; + + expanded.replace( QRegExp( "%p" ), + "\"" + QString::fromLocal8Bit( item->url() ) + "\"" ); + expanded.replace( QRegExp( "%n" ), + "\"" + QString::fromLocal8Bit( item->name() ) + "\"" ); + + if ( KDE::versionMajor() >= 3 && KDE::versionMinor() >= 4 ) + expanded.replace( QRegExp( "%t" ), "trash:/" ); + else + expanded.replace( QRegExp( "%t" ), KGlobalSettings::trashPath() ); + + return expanded; +} + +#include +void +KCleanup::runCommand ( const KFileInfo * item, + const QString & command ) const +{ + KProcess proc; + KDirSaver dir( itemDir( item ) ); + QString cmd( expandVariables( item, command )); + +#if VERBOSE_RUN_COMMAND + printf( "\ncd " ); + fflush( stdout ); + system( "pwd" ); + QTextCodec * codec = QTextCodec::codecForLocale(); + printf( "%s\n", (const char *) codec->fromUnicode( cmd ) ); + fflush( stdout ); +#endif + +#if ! SIMULATE_COMMAND + proc << "sh"; + proc << "-c"; + proc << cmd; + + switch ( _refreshPolicy ) + { + case noRefresh: + case assumeDeleted: + + // In either case it is no use waiting for the command to + // finish, so we are starting the command as a pure + // background process. + + proc.start( KProcess::DontCare ); + break; + + + case refreshThis: + case refreshParent: + + // If a display refresh is due after the command, we need to + // wait for the command to be finished in order to avoid + // performing the update prematurely, so we are starting this + // process in blocking mode. + + QApplication::setOverrideCursor( waitCursor ); + proc.start( KProcess::Block ); + QApplication::restoreOverrideCursor(); + break; + } + +#endif +} + + +void +KCleanup::readConfig() +{ + KConfig *config = kapp->config(); + KConfigGroupSaver saver( config, _id ); + + bool valid = config->readBoolEntry( "valid", false ); + + // If the config section requested exists, it should contain a + // "valid" field with a true value. If not, there is no such + // section within the config file. In this case, just leave this + // cleanup action undisturbed - we'd rather have a good default + // value (as provided - hopefully - by our application upon + // startup) than a generic empty cleanup action. + + if ( valid ) + { + _command = config->readEntry ( "command" ); + _enabled = config->readBoolEntry ( "enabled" ); + _worksForDir = config->readBoolEntry ( "worksForDir" ); + _worksForFile = config->readBoolEntry ( "worksForFile" ); + _worksForDotEntry = config->readBoolEntry ( "worksForDotEntry" ); + _worksLocalOnly = config->readBoolEntry ( "worksLocalOnly" ); + _recurse = config->readBoolEntry ( "recurse" , false ); + _askForConfirmation = config->readBoolEntry ( "askForConfirmation" , false ); + _refreshPolicy = (KCleanup::RefreshPolicy) config->readNumEntry( "refreshPolicy" ); + setTitle( config->readEntry( "title" ) ); + } +} + + +void +KCleanup::saveConfig() const +{ + KConfig *config = kapp->config(); + KConfigGroupSaver saver( config, _id ); + + config->writeEntry( "valid", true ); + config->writeEntry( "command", _command ); + config->writeEntry( "title", _title ); + config->writeEntry( "enabled", _enabled ); + config->writeEntry( "worksForDir", _worksForDir ); + config->writeEntry( "worksForFile", _worksForFile ); + config->writeEntry( "worksForDotEntry", _worksForDotEntry ); + config->writeEntry( "worksLocalOnly", _worksLocalOnly ); + config->writeEntry( "recurse", _recurse ); + config->writeEntry( "askForConfirmation", _askForConfirmation ); + config->writeEntry( "refreshPolicy", (int) _refreshPolicy ); +} + + +// EOF diff --git a/kdirstat/kcleanup.h b/kdirstat/kcleanup.h new file mode 100644 index 0000000..0cb7f13 --- /dev/null +++ b/kdirstat/kcleanup.h @@ -0,0 +1,360 @@ +/* + * File name: kcleanup.h + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KCleanup_h +#define KCleanup_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include +#include +#include +#include +#include +#include "kdirtree.h" + + +namespace KDirStat +{ + /** + * Cleanup action to be performed for @ref KDirTree items. + * + * @short KDirStat cleanup action + **/ + + class KCleanup: public KAction + { + Q_OBJECT + + public: + + enum RefreshPolicy { noRefresh, refreshThis, refreshParent, assumeDeleted }; + + /** + * Constructor. + * + * 'id' is the name of this cleanup action as used in the XML UI file + * and config files, 'title' is the human readable menu title. + * 'command' is the shell command to execute. + * + * Most applications will want to pass KMainWindow::actionCollection() + * for 'parent' so the menus and toolbars can be created using the XML + * UI description ('kdirstatui.rc' for KDirStat). + **/ + KCleanup( QString id = "", + QString command = "", + QString title = "", + KActionCollection * parent = 0 ); + + /** + * Copy Constructor. + * + * Notice that this is a not quite complete copy constructor: Since + * there is no KAction copy constructor, the inherited KAction members + * will be constructed with the KAction default constructor. Thus, an + * object created with this copy constructor can rely only on its + * KCleanup members. This is intended for save/restore operations only, + * not for general use. In particular, DO NOT connect an object thus + * constructed with signals. The results will be undefined (at best). + **/ + KCleanup( const KCleanup &src ); + + /** + * Assignment operator. + * + * This will not modify the KAction members, just the KCleanup + * members. Just like the copy constructor, this is intended for + * save/restore operations, not for general use. + **/ + KCleanup & operator= ( const KCleanup &src ); + + /** + * Return the ID (name) of this cleanup action as used for setup files + * and the XML UI description. This ID should be unique within the + * application. + **/ + const QString & id() const { return _id; } + + /** + * Return the command line that will be executed upon calling @ref + * KCleanup::execute(). This command line may contain %p for the + * complete path of the directory or file concerned or %n for the pure + * file or directory name without path. + **/ + const QString & command() const { return _command; } + + /** + * Return the user title of this command as displayed in menus. + * This may include '&' characters for keyboard shortcuts. + * See also @ref cleanTitle() . + **/ + const QString & title() const { return _title; } + + /** + * Returns the cleanup action's title without '&' keyboard shortcuts. + * Uses the ID as fallback if the name is empty. + **/ + QString cleanTitle() const; + + /** + * Return whether or not this cleanup action is generally enabled. + **/ + bool enabled() const { return _enabled; } + + /** + * Return this cleanup's internally stored @ref KDirTree + * selection. Important only for copy constructor etc. + **/ + KFileInfo * selection() const { return _selection; } + + /** + * Return whether or not this cleanup action works for this particular + * KFileInfo. Checks all the other conditions (enabled(), + * worksForDir(), worksForFile(), ...) accordingly. + **/ + bool worksFor( KFileInfo *item ) const; + + /** + * Return whether or not this cleanup action works for directories, + * i.e. whether or not @ref KCleanup::execute() will be successful if + * the object passed is a directory. + **/ + bool worksForDir() const { return _worksForDir; } + + /** + * Return whether or not this cleanup action works for plain files. + **/ + bool worksForFile() const { return _worksForFile; } + + /** + * Return whether or not this cleanup action works for KDirStat's + * special 'Dot Entry' items, i.e. the pseudo nodes created in most + * directories that hold the plain files. + **/ + bool worksForDotEntry() const { return _worksForDotEntry; } + + /** + * Return whether or not this cleanup action works for simple local + * files and directories only ('file:/' protocol) or network + * transparent, i.e. all protocols KDE supports ('ftp', 'smb' - but + * even 'tar', even though it is - strictly spoken - local). + **/ + bool worksLocalOnly() const { return _worksLocalOnly; } + + /** + * Return whether or not the cleanup action should be performed + * recursively in subdirectories of the initial KFileInfo. + **/ + bool recurse() const { return _recurse; } + + /** + * Return whether or not this cleanup should ask the user for + * confirmation when it is executed. + * + * The default is 'false'. Use with caution - not only can this become + * very annoying, people also tend to automatically click on 'OK' when + * too many confirmation dialogs pop up! + **/ + bool askForConfirmation() const { return _askForConfirmation; } + + /** + * Return the refresh policy of this cleanup action - i.e. the action + * to perform after each call to KCleanup::execute(). This is supposed + * to bring the corresponding KDirTree back into sync after the cleanup + * action - the underlying file tree might have changed due to that + * cleanup action. + * + * noRefresh: Don't refresh anything. Assume nothing has changed. + * This is the default. + * + * refreshThis: Refresh the KDirTree from the item on that was passed + * to KCleanup::execute(). + * + * refreshParent: Refresh the KDirTree from the parent of the item on + * that was passed to KCleanup::execute(). If there is no such parent, + * refresh the entire tree. + * + * assumeDeleted: Do not actually refresh the KDirTree. Instead, + * blindly assume the cleanup action has deleted the item that was + * passed to KCleanup::execute() and delete the corresponding subtree + * in the KDirTree accordingly. This will work well for most deleting + * actions as long as they can be performed without problems. If there + * are any problems, however, the KDirTree might easily run out of sync + * with the directory tree: The KDirTree will show the subtree as + * deleted (i.e. it will not show it any more), but it still exists on + * disk. This is the tradeoff to a very quick response. On the other + * hand, the user can easily at any time hit one of the explicit + * refresh buttons and everything will be back into sync again. + **/ + enum RefreshPolicy refreshPolicy() const { return _refreshPolicy; } + + + void setTitle ( const QString &title ); + void setId ( const QString &id ) { _id = id; } + void setCommand ( const QString &command) { _command = command; } + void setEnabled ( bool enabled ) { _enabled = enabled; } + void setWorksForDir ( bool canDo ) { _worksForDir = canDo; } + void setWorksForFile ( bool canDo ) { _worksForFile = canDo; } + void setWorksForDotEntry ( bool canDo ) { _worksForDotEntry = canDo; } + void setWorksLocalOnly ( bool canDo ) { _worksLocalOnly = canDo; } + void setRecurse ( bool recurse ) { _recurse = recurse; } + void setAskForConfirmation ( bool ask ) { _askForConfirmation = ask; } + void setRefreshPolicy ( enum RefreshPolicy refreshPolicy ) { _refreshPolicy = refreshPolicy; } + + + public slots: + + /** + * The heart of the matter: Perform the cleanup with the KFileInfo + * specified. + **/ + void execute( KFileInfo *item ); + + /** + * Perform the cleanup with the current KDirTree selection if there is + * any. + **/ + void executeWithSelection(); + + /** + * Set enabled/disabled status according to 'selection' and internally + * store 'selection' - this will also be used upon calling + * @ref executeWithSelection() . '0' means "nothing selected". + **/ + void selectionChanged( KFileInfo *selection ); + + /** + * Read configuration. + **/ + void readConfig(); + + /** + * Save configuration. + **/ + void saveConfig() const; + + + signals: + + /** + * Emitted after the action is executed. + * + * Please note that there intentionally is no reference as to which + * object the action was executed upon since this object very likely + * doesn't exist any more. + **/ + void executed(); + + + protected slots: + + /** + * Inherited from @ref KAction : Perform the action. + * In this case, execute the cleanup with the current selection. + **/ + virtual void slotActivated() { executeWithSelection(); } + + + protected: + + /** + * Recursively perform the cleanup. + **/ + void executeRecursive( KFileInfo *item ); + + /** + * Ask user for confirmation to execute this cleanup action for + * 'item'. Returns 'true' if user accepts, 'false' otherwise. + **/ + bool confirmation( KFileInfo *item ); + + /** + * Retrieve the directory part of a KFileInfo's path. + **/ + const QString itemDir( const KFileInfo *item ) const; + + /** + * Expand some variables in string 'unexpanded' to information from + * within 'item'. Multiple expansion is performed as needed, i.e. the + * string may contain more than one variable to expand. The resulting + * string is returned. + * + * %p expands to item->path(), i.e. the item's full path name. + * + * /usr/local/bin for that directory + * /usr/local/bin/doit for a file within it + * + * %n expands to item->name(), i.e. the last component of the pathname. + * The examples above would expand to: + * + * bin + * doit + * + * For commands that are to be executed from within the 'Clean up' + * menu, you might specify something like: + * + * "kfmclient openURL %p" + * "tar czvf %{name}.tgz && rm -rf %{name}" + **/ + QString expandVariables ( const KFileInfo * item, + const QString & unexpanded ) const; + + /** + * Run a command with 'item' as base to expand variables. + **/ + void runCommand ( const KFileInfo * item, + const QString & command ) const; + + /** + * Internal implementation of the copy constructor and assignment + * operator: Copy all data members from 'src'. + **/ + void copy ( const KCleanup &src ); + + + // + // Data members + // + + KFileInfo * _selection; + QString _id; + QString _command; + QString _title; + bool _enabled; + bool _worksForDir; + bool _worksForFile; + bool _worksForDotEntry; + bool _worksLocalOnly; + bool _recurse; + bool _askForConfirmation; + enum RefreshPolicy _refreshPolicy; + }; + + + inline kdbgstream & operator<< ( kdbgstream & stream, const KCleanup * cleanup ) + { + if ( cleanup ) + stream << cleanup->id(); + else + stream << ""; + + return stream; + } +} // namespace KDirStat + + +#endif // ifndef KCleanup_h + + +// EOF diff --git a/kdirstat/kcleanupcollection.cpp b/kdirstat/kcleanupcollection.cpp new file mode 100644 index 0000000..fffa9b4 --- /dev/null +++ b/kdirstat/kcleanupcollection.cpp @@ -0,0 +1,283 @@ +/* + * File name: kcleanupcollection.cpp + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2004-11-23 + */ + + +#include +#include "kcleanup.h" +#include "kstdcleanup.h" +#include "kcleanupcollection.h" + + +using namespace KDirStat; + + +KCleanupCollection::KCleanupCollection( KActionCollection * actionCollection ) + : QObject() + , _actionCollection( actionCollection ) +{ + /** + * All cleanups beloningt to this collection are stored in two separate Qt + * collections, a QList and a QDict. Make _one_ of them manage the cleanup + * objects, i.e. have them clear the KCleanup objects upon deleting. The + * QList is the master collection, the QDict the slave. + **/ + + _cleanupList.setAutoDelete( true ); + _cleanupDict.setAutoDelete( false ); + + _nextUserCleanupNo = 0; +} + + +KCleanupCollection::KCleanupCollection( const KCleanupCollection &src ) + : QObject() +{ + deepCopy( src ); + + // Keep consistent with the KCleanup copy constructor: It explicitly uses a + // zero KActionCollecton to make sure no duplicates of cleanups get into + // the action collection. + _actionCollection = 0; +} + + +KCleanupCollection::~KCleanupCollection() +{ + // No need to delete the cleanups: _cleanupList takes care of that + // (autoDelete!). +} + + +KCleanupCollection & +KCleanupCollection::operator= ( const KCleanupCollection &src ) +{ + if ( size() != src.size() ) + { + /** + * If the sizes are different, we really need to make a deep copy - + * i.e. discard all the existing cleanups in this collection and create + * new ones with the KCleanup copy constructor. + **/ + + // kdDebug() << k_funcinfo << "Sizes different - deep copy" << endl; + + deepCopy( src ); + } + else + { + /** + * If the sizes are the same, we'd rather just use the KCleanup + * assignment operator to individually assign each cleanup in the + * source collection to the corresponding one in this collection. + * + * The background of this seemingly awkward solution are (again) the + * limitations of the KCleanup copy constructor: It doesn't make a + * truly identical copy of the entire KCleanup object. Rather, it + * copies only the KCleanup members and leaves most of the KAction + * members (the parent class) untouched. + * + * The behaviour implemented here comes handy in the most common + * situation where this assignment operator is used: + * + * KCleanupCollection tmpCollection( origCollection ); + * ... + * ... // let use change settings in settings dialog + * ... + * origCollection = tmpCollection; + * + * 'tmpCollection' here is an incomplete copy of 'origCollection' - + * which represents what the user really can see in the menus, i.e. all + * the KAction stuff in there really needs to work. + * + * During changing preferences in the 'settings' dialog, the user only + * changes 'tmpCollection' - if he chooses to abandon his changes + * (e.g., he clicks on the 'cancel' button), no harm is done - + * 'tmpCollection' is simply not copied back to + * 'origCollection'. Anyway, since 'tmpCollection' is merely a + * container for the true KCleanup members, the KAction members don't + * matter here: There is no representation of 'tmpCollection' in any + * menu or tool bar. + * + * As soon as the user clicks on 'apply' or 'ok' in the 'settings' + * dialog, however, 'tmpCollection' is copied back to 'origCollection' + * - that is, its KCleanup members. Most of the KAction members (other + * than 'text()' which is explicitly copied back) remain untouched, + * thus maintaining consistency with the user interface is guaranteed. + **/ + + // kdDebug() << k_funcinfo << "Same sizes - individual assignment" << endl; + + KCleanupList srcList = src.cleanupList(); + KCleanupListIterator srcIt( srcList ); + KCleanupListIterator destIt( _cleanupList ); + + while ( *srcIt && *destIt ) + { + // kdDebug() << "Assigning " << *srcIt << endl; + **destIt = **srcIt; + ++srcIt; + ++destIt; + } + } + + // Intentionally leaving '_actionCollection' untouched! + + return *this; +} + + +void +KCleanupCollection::deepCopy( const KCleanupCollection &src ) +{ + // Copy simple values + _nextUserCleanupNo = src.nextUserCleanupNo(); + + // Just to make sure - clear the internal collections + _cleanupList.clear(); + _cleanupDict.clear(); + + + // Make a deep copy of all the cleanups in the source collection + + KCleanupList srcList = src.cleanupList(); + KCleanupListIterator it( srcList ); + + while ( *it ) + { + // kdDebug() << k_funcinfo << "Creating new " << *it << endl; + + add( new KCleanup( **it ) ); + ++it; + } +} + + +void +KCleanupCollection::add( KCleanup *newCleanup ) +{ + CHECK_PTR( newCleanup ); + + if ( _cleanupDict[ newCleanup->id() ] ) // Already there? + { + // Delete any old instance in the list. + // + // The instance in the dict will be deleted automatically by inserting + // the new one. + + _cleanupList.first(); // Moves _cleanupList.current() to beginning + + while ( _cleanupList.current() ) + { + if ( _cleanupList.current()->id() == newCleanup->id() ) + { + // Found a cleanup with the same ID - + // remove the current list item, delete it (autoDelete!) and + // move _cleanupList.current() to the next item. + + _cleanupList.remove(); + } + else + _cleanupList.next(); + } + } + + _cleanupList.append( newCleanup ); + _cleanupDict.insert( newCleanup->id(), newCleanup ); + + connect( this, SIGNAL( selectionChanged( KFileInfo * ) ), + newCleanup, SLOT ( selectionChanged( KFileInfo * ) ) ); + + connect( this, SIGNAL( readConfig() ), + newCleanup, SLOT ( readConfig() ) ); + + connect( this, SIGNAL( saveConfig() ), + newCleanup, SLOT ( saveConfig() ) ); + + connect( newCleanup, SIGNAL( executed() ), + this, SLOT ( cleanupExecuted() ) ); +} + + +void +KCleanupCollection::addStdCleanups() +{ + add( KStdCleanup::openInKonqueror ( _actionCollection ) ); + add( KStdCleanup::openInTerminal ( _actionCollection ) ); + add( KStdCleanup::compressSubtree ( _actionCollection ) ); + add( KStdCleanup::makeClean ( _actionCollection ) ); + add( KStdCleanup::deleteTrash ( _actionCollection ) ); + add( KStdCleanup::moveToTrashBin ( _actionCollection ) ); + add( KStdCleanup::hardDelete ( _actionCollection ) ); +} + + +void +KCleanupCollection::addUserCleanups( int number ) +{ + for ( int i=0; i < number; i++ ) + { + QString id; + id.sprintf( "cleanup_user_defined_%d", _nextUserCleanupNo ); + QString title; + + if ( _nextUserCleanupNo <= 9 ) + // Provide a keyboard shortcut for cleanup #0..#9 + title=i18n( "User Defined Cleanup #&%1" ).arg(_nextUserCleanupNo); + else + // No keyboard shortcuts for cleanups #10.. - they would be duplicates + title=i18n( "User Defined Cleanup #%1" ).arg(_nextUserCleanupNo); + + _nextUserCleanupNo++; + + KCleanup *cleanup = new KCleanup( id, "", title, _actionCollection ); + CHECK_PTR( cleanup ); + cleanup->setEnabled( false ); + + if ( i <= 9 ) + { + // Provide an application-wide keyboard accelerator for cleanup #0..#9 + cleanup->setShortcut( Qt::CTRL + Qt::Key_0 + i ); + } + + add( cleanup ); + } +} + + +KCleanup * +KCleanupCollection::cleanup( const QString & id ) +{ + return _cleanupDict[ id ]; +} + + +void +KCleanupCollection::clear() +{ + _cleanupList.clear(); + _cleanupDict.clear(); + _nextUserCleanupNo = 0; +} + + +void +KCleanupCollection::slotReadConfig() +{ + emit readConfig(); +} + + +void +KCleanupCollection::cleanupExecuted() +{ + emit userActivity( 10 ); +} + + +// EOF diff --git a/kdirstat/kcleanupcollection.h b/kdirstat/kcleanupcollection.h new file mode 100644 index 0000000..74f0900 --- /dev/null +++ b/kdirstat/kcleanupcollection.h @@ -0,0 +1,225 @@ +/* + * File name: kcleanupcollection.h + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KCleanupCollection_h +#define KCleanupCollection_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "kcleanup.h" + +// Forward declarations +class KActionCollection; + + +namespace KDirStat +{ + typedef QDict KCleanupDict; + typedef QDictIterator KCleanupDictIterator; + + typedef QPtrList KCleanupList; + typedef QPtrListIterator KCleanupListIterator; + + + /** + * Set of @ref KCleanup actions to be performed for @ref KDirTree items, + * consisting of a number of predefined and a number of user-defined + * cleanups. The prime purpose of this is to make save/restore operations + * with a number of cleanups easier. Thus, it provides a copy constructor, + * an assignment operator and various methods to directly access individual + * cleanups. + * + * @short KDirStat cleanup action collection + **/ + + class KCleanupCollection: public QObject + { + Q_OBJECT + + public: + + /** + * Constructor. + * + * Most applications will want to pass KMainWindow::actionCollection() + * for 'actionCollection' so the menus and toolbars can be created + * using the XML UI description ('kdirstatui.rc' for KDirStat). + * + * All @ref KCleanup actions ever added to this collection will get + * this as their parent. + **/ + KCleanupCollection( KActionCollection * actionCollection = 0 ); + + /** + * Copy Constructor. + * + * Makes a deep copy of this collection with 'actionCollection' set to + * 0 for all copied cleanups. Please note that since there is no + * complete copy constructor for @ref KCleanup, all restrictions to the + * @ref KCleanup copy constructor apply to the KCleanupCollection, too: + * This copy constructor is intended for save/restore operations only, + * not for general use. In particular, DO NOT connect an object thus + * constructed with signals. The results will be undefined (at best). + **/ + KCleanupCollection( const KCleanupCollection &src ); + + /** + * Assignment operator. + * + * This operator has the same restrictions as the copy constructor: + * Just like the copy constructor, this is intended for save/restore + * operations, not for general use. + * + * For details, see the extensive comments in the source file. + **/ + KCleanupCollection & operator= ( const KCleanupCollection &src ); + + /** + * Destructor + **/ + virtual ~KCleanupCollection(); + + /** + * Add the standard cleanups to this collection. + **/ + void addStdCleanups(); + + /** + * Add 'number' user-defined cleanups to this collection. + **/ + void addUserCleanups( int number ); + + /** + * Add one single cleanup to this collection. The collection assumes + * ownerwhip of this cleanup - don't delete it! + **/ + void add( KCleanup *cleanup ); + + /** + * Retrieve a cleanup by its ID (internal name). + * Returns 0 if there is no such cleanup. + **/ + KCleanup * cleanup( const QString & id ); + + /** + * An alias to @ref cleanup() for convenience: Thus, you can use + * collection[ "cleanup_id" ] to access any particular cleanup. + **/ + KCleanup * operator[] ( const QString & id ) + { return cleanup( id ); } + + /** + * Remove all cleanups from this collection. + **/ + void clear(); + + /** + * Return (a shallow copy of) the internal cleanup list. + * + * Use this and a KCleanupListIterator to iterate over all cleanups in + * this collection. Remember to keep the list until you no longer need + * the iterator! + * + * KCleanupCollection *coll = ... + * KCleanupList cleanup_list = coll->cleanupList(); + * KCleanupListIterator it( cleanup_list ); + * + * while ( *it ) + * { + * kdDebug() << "Found cleanup " << *it << endl; + * ++it; + * } + **/ + KCleanupList cleanupList() const { return _cleanupList; } + + /** + * Return the number of cleanup actions in this collection. + **/ + int size() const { return _cleanupList.count(); } + + /** + * For internal use only: Returns the number to be assigned to the next + * user cleanup that may be added. + **/ + int nextUserCleanupNo() const { return _nextUserCleanupNo; } + + public slots: + + /** + * Emit the readConfig() signal for all cleanups. + **/ + void slotReadConfig(); + + + signals: + + /** + * Emitted when the currently selected item changes. + * 'item' may be 0 when the selection is cleared. + * + * Connect a view's selectionChanged() signal to this + * selectionChanged() signal to have the cleanup collection pass this + * signal to its cleanups. + **/ + void selectionChanged( KFileInfo *item ); + + /** + * Read collection for all cleanups. + **/ + void readConfig(); + + /** + * Save configuration for all cleanups. + **/ + void saveConfig(); + + /** + * Emitted at user activity, i.e. when the user executes a cleanup. + * This is intended for use together with a @ref KActivityTracker. + **/ + void userActivity( int points ); + + + protected slots: + + /** + * Connected to each cleanup's @ref executed() signal to track user + * activity. + **/ + void cleanupExecuted(); + + + protected: + + /** + * Internal implementation of copy constructor and assignment operator: + * Make a deep copy of the collection. + **/ + void deepCopy( const KCleanupCollection &src ); + + + // Data members + + KActionCollection * _actionCollection; + int _nextUserCleanupNo; + KCleanupList _cleanupList; + KCleanupDict _cleanupDict; + }; +} // namespace KDirStat + + +#endif // ifndef KCleanupCollection_h + + +// EOF diff --git a/kdirstat/kdirsaver.cpp b/kdirstat/kdirsaver.cpp new file mode 100644 index 0000000..2be9074 --- /dev/null +++ b/kdirstat/kdirsaver.cpp @@ -0,0 +1,71 @@ +/* + * File name: kdirsaver.cpp + * Summary: Utility object to save current working directory + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#include +#include +#include "kdirsaver.h" + + +KDirSaver::KDirSaver( const QString & newPath ) +{ + /* + * No need to actually save the current working directory: This object + * includes a QDir whose default constructor constructs a directory object + * that contains the current working directory. Just what is needed here. + */ + + cd( newPath ); +} + + +KDirSaver::KDirSaver( const KURL & url ) +{ + if ( url.isLocalFile() ) + { + cd( url.path() ); + } + else + { + kdError() << k_funcinfo << "Can't change dir to remote location " << url.url() << endl; + } +} + + +KDirSaver::~KDirSaver() +{ + restore(); +} + + +void +KDirSaver::cd( const QString & newPath ) +{ + if ( ! newPath.isEmpty() ) + { + chdir( newPath ); + } +} + + +QString +KDirSaver::currentDirPath() const +{ + return QDir::currentDirPath(); +} + + +void +KDirSaver::restore() +{ + chdir( oldWorkingDir.path() ); +} + + +// EOF diff --git a/kdirstat/kdirsaver.h b/kdirstat/kdirsaver.h new file mode 100644 index 0000000..4fbe6e2 --- /dev/null +++ b/kdirstat/kdirsaver.h @@ -0,0 +1,75 @@ +/* + * File name: kdirsaver.h + * Summary: Utility object to save current working directory + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KDirSaver_h +#define KDirSaver_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + + +/** + * Helper class to change directories without losing the current context. + * Will change back to the old working directory when destroyed. + * + * @short Directory changer with automatic restore + **/ +class KDirSaver +{ +public: + /** + * Constructor. Will save the current working directory and change to the + * path supplied. The old working directory will be restored when this + * object is destroyed. + **/ + KDirSaver( const QString & newPath = "" ); + + /** + * Constructor from a KURL. Will issue error messages on stdout for + * non-local objects. + **/ + KDirSaver( const KURL & url ); + + /** + * Destructor. Restores the original working directory. + **/ + virtual ~KDirSaver(); + + /** + * Change directory. Unlike @ref QDir::cd(), this method really performs a + * system chdir() so subsequent system calls will have the directory + * specified as the new current working directory. + **/ + void cd( const QString & newPath ); + + /** + * Obtain the current working directory's absolute path. + * This is useful for resolving/simplifying relative paths. + **/ + QString currentDirPath() const; + + /** + * (Prematurely) restore the working directory. Unnecessary when this + * object will be destroyed anyway since the destructor does exactly that. + **/ + void restore(); + +protected: + QDir oldWorkingDir; +}; + +#endif // KDirSaver_h + + +// EOF diff --git a/kdirstat/kdirstat.desktop b/kdirstat/kdirstat.desktop new file mode 100644 index 0000000..77f815a --- /dev/null +++ b/kdirstat/kdirstat.desktop @@ -0,0 +1,20 @@ +# KDE Config File +[Desktop Entry] +Type=Application +Exec=kdirstat -caption "%c" %i %m +Icon=kdirstat.png +MiniIcon=kdirstat.png +DocPath=kdirstat/index.html +Encoding=UTF-8 +Comment=Directory statistics and disk usage +Comment[de]=Verzeichnisstatistik und Platzverbrauch +Comment[hu]=Könyvtárstatisztikák és szabad hely +Terminal=0 +Name=KDirStat - Directory Statistics +Name[de]=KDirStat - Verzeichnisstatistik +Name[hu]=KDirStat könyvtárstatisztika + +MimeType=inode/directory + + + diff --git a/kdirstat/kdirstat.upd b/kdirstat/kdirstat.upd new file mode 100644 index 0000000..13520f1 --- /dev/null +++ b/kdirstat/kdirstat.upd @@ -0,0 +1,6 @@ +# Update for KDirStat configuration +Id=kdirstat_2004_11_24_11_36 +File=kdirstatrc +Group=cleanup_move_to_trash_bin +Options=overwrite +Script=fix_move_to_trash_bin.pl,perl diff --git a/kdirstat/kdirstat_part.rc b/kdirstat/kdirstat_part.rc new file mode 100644 index 0000000..fce2dcc --- /dev/null +++ b/kdirstat/kdirstat_part.rc @@ -0,0 +1,14 @@ + + + + + + &Edit + + + + + + + + diff --git a/kdirstat/kdirstatapp.cpp b/kdirstat/kdirstatapp.cpp new file mode 100644 index 0000000..22726e9 --- /dev/null +++ b/kdirstat/kdirstatapp.cpp @@ -0,0 +1,847 @@ +/* + * File name: kdirstatapp.cpp + * Summary: The KDirStat application - menu bar, tool bar, ... + * License: GPL - See file COPYING for details. + * + * Author: Stefan Hundhammer + * Parts auto-generated by KDevelop + * + * Updated: 2004-12-06 + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kdirstatapp.h" +#include "kcleanupcollection.h" +#include "kdirtree.h" +#include "kpacman.h" +#include "ktreemapview.h" +#include "ktreemaptile.h" +#include "kcleanupcollection.h" +#include "kactivitytracker.h" +#include "kdirtreeview.h" +#include "kdirstatsettings.h" + + +#define USER_CLEANUPS 10 // Number of user cleanup actions + +#define ID_STATUS_MSG 1 +#define ID_PACMAN 42 +#define PACMAN_WIDTH 350 +#define PACMAN_INTERVAL 75 // millisec + +#define INITIAL_FEEDBACK_REMINDER 2000L +#define FEEDBACK_REMINDER_INTERVAL 1000L + + +using namespace KDirStat; + + +KDirStatApp::KDirStatApp( QWidget* , const char* name ) + : KMainWindow( 0, name ) +{ + // Simple inits + + _activityTracker = 0; // Might or might not be needed + + + // Those will be created delayed, only when needed + + _settingsDialog = 0; + _feedbackDialog = 0; + _treemapView = 0; + _pacMan = 0; + _pacManDelimiter = 0; + + + // Set up internal (mainWin -> mainWin) connections + + connect( this, SIGNAL( readConfig ( void ) ), + this, SLOT ( readMainWinConfig( void ) ) ); + + connect( this, SIGNAL( saveConfig ( void ) ), + this, SLOT ( saveMainWinConfig( void ) ) ); + + + // Create main window + + _splitter = new QSplitter( QSplitter::Vertical, this ); + setCentralWidget( _splitter ); + + _treeView = new KDirTreeView( _splitter ); + + connect( _treeView, SIGNAL( progressInfo( const QString & ) ), + this, SLOT ( statusMsg ( const QString & ) ) ); + + connect( _treeView, SIGNAL( selectionChanged( KFileInfo * ) ), + this, SLOT ( selectionChanged( KFileInfo * ) ) ); + + connect( _treeView, SIGNAL( contextMenu( KDirTreeViewItem *, const QPoint & ) ), + this, SLOT ( contextMenu( KDirTreeViewItem *, const QPoint & ) ) ); + + connect( this, SIGNAL( readConfig() ), _treeView, SLOT ( readConfig() ) ); + connect( this, SIGNAL( saveConfig() ), _treeView, SLOT ( saveConfig() ) ); + + connect( _treeView, SIGNAL( finished() ), this, SLOT( createTreemapView() ) ); + connect( _treeView, SIGNAL( aborted() ), this, SLOT( createTreemapView() ) ); + connect( _treeView, SIGNAL( startingReading() ), this, SLOT( deleteTreemapView() ) ); + + connect( _treeView, SIGNAL( startingReading() ), this, SLOT( updateActions() ) ); + connect( _treeView, SIGNAL( finished() ), this, SLOT( updateActions() ) ); + connect( _treeView, SIGNAL( aborted() ), this, SLOT( updateActions() ) ); + + // Call inits to invoke all other construction parts + + initStatusBar(); + initActions(); + initCleanups(); + createGUI(); + initActivityTracker(); + + _treeViewContextMenu = (QPopupMenu *) factory()->container( "treeViewContextMenu", this ); + _treemapContextMenu = (QPopupMenu *) factory()->container( "treemapContextMenu", this ); + + readMainWinConfig(); + + + // Disable certain actions at startup + + _editCopy->setEnabled( false ); + _reportMailToOwner->setEnabled( false ); + _fileRefreshAll->setEnabled( false ); + _fileRefreshSelected->setEnabled( false ); + updateActions(); +} + + +KDirStatApp::~KDirStatApp() +{ + delete _cleanupCollection; +} + + + +void +KDirStatApp::initActions() +{ + _fileAskOpenDir = KStdAction::open ( this, SLOT( fileAskOpenDir() ), actionCollection() ); + + _fileAskOpenUrl = new KAction( i18n( "Open &URL..." ), "konqueror", 0, + this, SLOT( fileAskOpenUrl() ), + actionCollection(), "file_open_url" ); + + _fileOpenRecent = KStdAction::openRecent ( this, SLOT( fileOpenRecent( const KURL& ) ), actionCollection() ); + _fileCloseDir = KStdAction::close ( this, SLOT( fileCloseDir() ), actionCollection() ); + + _fileRefreshAll = new KAction( i18n( "Refresh &All" ), "reload", 0, + this, SLOT( refreshAll() ), + actionCollection(), "file_refresh_all" ); + + _fileRefreshSelected = new KAction( i18n( "Refresh &Selected" ), 0, + this, SLOT( refreshSelected() ), + actionCollection(), "file_refresh_selected" ); + + _fileContinueReadingAtMountPoint = new KAction( i18n( "Continue Reading at &Mount Point" ), "hdd_mount", 0, + this, SLOT( refreshSelected() ), actionCollection(), + "file_continue_reading_at_mount_point" ); + + _fileStopReading = new KAction( i18n( "Stop Rea&ding" ), "stop", 0, + this, SLOT( stopReading() ), actionCollection(), + "file_stop_reading" ); + + _fileQuit = KStdAction::quit ( kapp, SLOT( quit() ), actionCollection() ); + _editCopy = KStdAction::copy ( this, SLOT( editCopy() ), actionCollection() ); + _showToolBar = KStdAction::showToolbar ( this, SLOT( toggleToolBar() ), actionCollection() ); + _showStatusBar = KStdAction::showStatusbar ( this, SLOT( toggleStatusBar() ), actionCollection() ); + + _cleanupOpenWith = new KAction( i18n( "Open With" ), 0, + this, SLOT( cleanupOpenWith() ), + actionCollection(), "cleanup_open_with" ); + + _treemapZoomIn = new KAction( i18n( "Zoom in" ), "viewmag+", Key_Plus, + this, SLOT( treemapZoomIn() ), + actionCollection(), "treemap_zoom_in" ); + + _treemapZoomOut = new KAction( i18n( "Zoom out" ), "viewmag-", Key_Minus, + this, SLOT( treemapZoomOut() ), + actionCollection(), "treemap_zoom_out" ); + + _treemapSelectParent= new KAction( i18n( "Select Parent" ), "up", Key_Asterisk, + this, SLOT( treemapSelectParent() ), + actionCollection(), "treemap_select_parent" ); + + _treemapRebuild = new KAction( i18n( "Rebuild Treemap" ), 0, + this, SLOT( treemapRebuild() ), + actionCollection(), "treemap_rebuild" ); + + _showTreemapView = new KToggleAction( i18n( "Show Treemap" ), Key_F9, + this, SLOT( toggleTreemapView() ), + actionCollection(), "options_show_treemap" ); + + new KAction( i18n( "Help about Treemaps" ), "help", 0, + this, SLOT( treemapHelp() ), + actionCollection(), "treemap_help" ); + + KAction * pref = KStdAction::preferences( this, SLOT( preferences() ), actionCollection() ); + + _reportMailToOwner = new KAction( i18n( "Send &Mail to Owner" ), "mail_generic", 0, + _treeView, SLOT( sendMailToOwner() ), + actionCollection(), "report_mail_to_owner" ); + + _helpSendFeedbackMail = new KAction( i18n( "Send &Feedback Mail..." ), 0, + this, SLOT( sendFeedbackMail() ), + actionCollection(), "help_send_feedback_mail" ); + + + _fileAskOpenDir->setStatusText ( i18n( "Opens a directory" ) ); + _fileAskOpenUrl->setStatusText ( i18n( "Opens a (possibly remote) directory" ) ); + _fileOpenRecent->setStatusText ( i18n( "Opens a recently used directory" ) ); + _fileCloseDir->setStatusText ( i18n( "Closes the current directory" ) ); + _fileRefreshAll->setStatusText ( i18n( "Re-reads the entire directory tree" ) ); + _fileRefreshSelected->setStatusText ( i18n( "Re-reads the selected subtree" ) ); + _fileContinueReadingAtMountPoint->setStatusText( i18n( "Scan mounted file systems" ) ); + _fileStopReading->setStatusText ( i18n( "Stops directory reading" ) ); + _fileQuit->setStatusText ( i18n( "Quits the application" ) ); + _editCopy->setStatusText ( i18n( "Copies the URL of the selected item to the clipboard" ) ); + _showToolBar->setStatusText ( i18n( "Enables/disables the toolbar" ) ); + _showStatusBar->setStatusText ( i18n( "Enables/disables the statusbar" ) ); + _cleanupOpenWith->setStatusText ( i18n( "Open file or directory with arbitrary application" ) ); + _showTreemapView->setStatusText ( i18n( "Enables/disables the treemap view" ) ); + _treemapZoomIn->setStatusText ( i18n( "Zoom treemap in" ) ); + _treemapZoomOut->setStatusText ( i18n( "Zoom treemap out" ) ); + _treemapSelectParent->setStatusText ( i18n( "Select parent" ) ); + _treemapRebuild->setStatusText ( i18n( "Rebuild treemap to fit into available space" ) ); + pref->setStatusText ( i18n( "Opens the preferences dialog" ) ); + _reportMailToOwner->setStatusText ( i18n( "Sends a mail to the owner of the selected subtree" ) ); +} + + +void +KDirStatApp::initCleanups() +{ + _cleanupCollection = new KCleanupCollection( actionCollection() ); + CHECK_PTR( _cleanupCollection ); + _cleanupCollection->addStdCleanups(); + _cleanupCollection->addUserCleanups( USER_CLEANUPS ); + _cleanupCollection->slotReadConfig(); + + connect( _treeView, SIGNAL( selectionChanged( KFileInfo * ) ), + _cleanupCollection, SIGNAL( selectionChanged( KFileInfo * ) ) ); + + connect( this, SIGNAL( readConfig( void ) ), + _cleanupCollection, SIGNAL( readConfig( void ) ) ); + + connect( this, SIGNAL( saveConfig( void ) ), + _cleanupCollection, SIGNAL( saveConfig( void ) ) ); +} + + +void +KDirStatApp::revertCleanupsToDefaults() +{ + KCleanupCollection defaultCollection; + defaultCollection.addStdCleanups(); + defaultCollection.addUserCleanups( USER_CLEANUPS ); + *_cleanupCollection = defaultCollection; +} + + +void +KDirStatApp::initPacMan( bool enablePacMan ) +{ + if ( enablePacMan ) + { + if ( ! _pacMan ) + { + _pacMan = new KPacMan( toolBar(), 16, false, "kde toolbar widget" ); + _pacMan->setInterval( PACMAN_INTERVAL ); // millisec + int id = ID_PACMAN; + toolBar()->insertWidget( id, PACMAN_WIDTH, _pacMan ); + toolBar()->setItemAutoSized( id, false ); + + _pacManDelimiter = new QWidget( toolBar() ); + toolBar()->insertWidget( ++id, 1, _pacManDelimiter ); + + connect( _treeView, SIGNAL( startingReading() ), _pacMan, SLOT( start() ) ); + connect( _treeView, SIGNAL( finished() ), _pacMan, SLOT( stop () ) ); + connect( _treeView, SIGNAL( aborted() ), _pacMan, SLOT( stop () ) ); + } + } + else + { + if ( _pacMan ) + { + delete _pacMan; + _pacMan = 0; + } + + if ( _pacManDelimiter ) + { + delete _pacManDelimiter; + _pacManDelimiter = 0; + } + } +} + + +void +KDirStatApp::initStatusBar() +{ + statusBar()->insertItem( i18n( "Ready." ), ID_STATUS_MSG ); +} + + +void +KDirStatApp::initActivityTracker() +{ + if ( ! doFeedbackReminder() ) + return; + + _activityTracker = new KActivityTracker( this, "Feedback", + INITIAL_FEEDBACK_REMINDER ); + + connect( _activityTracker, SIGNAL( thresholdReached() ), + this, SLOT ( askForFeedback() ) ); + + connect( _treeView, SIGNAL( userActivity( int ) ), + _activityTracker, SLOT ( trackActivity( int ) ) ); + + connect( _cleanupCollection, SIGNAL( userActivity( int ) ), + _activityTracker, SLOT ( trackActivity( int ) ) ); +} + + +void +KDirStatApp::openURL( const KURL& url ) +{ + statusMsg( i18n( "Opening directory..." ) ); + + _treeView->openURL( url ); + _fileOpenRecent->addURL( url ); + _fileRefreshAll->setEnabled( true ); + setCaption( url.fileName(), false ); + + statusMsg( i18n( "Ready." ) ); +} + + +void KDirStatApp::readMainWinConfig() +{ + + KConfig * config = kapp->config(); + config->setGroup( "General Options" ); + + // Status settings of the various bars and views + + _showToolBar->setChecked( config->readBoolEntry( "Show Toolbar", true ) ); + toggleToolBar(); + + _showStatusBar->setChecked( config->readBoolEntry( "Show Statusbar", true ) ); + toggleStatusBar(); + + _showTreemapView->setChecked( config->readBoolEntry( "Show Treemap", true ) ); + toggleTreemapView(); + + + // Position settings of the various bars + + KToolBar::BarPosition toolBarPos; + toolBarPos = ( KToolBar::BarPosition ) config->readNumEntry( "ToolBarPos", KToolBar::Top ); + toolBar( "mainToolBar" )->setBarPos( toolBarPos ); + + _treemapViewHeight = config->readNumEntry( "TreemapViewHeight", 250 ); + + // initialize the recent file list + _fileOpenRecent->loadEntries( config,"Recent Files" ); + + QSize size = config->readSizeEntry( "Geometry" ); + + if( ! size.isEmpty() ) + resize( size ); + + config->setGroup( "Animation" ); + initPacMan( config->readBoolEntry( "ToolbarPacMan", true ) ); + _treeView->enablePacManAnimation( config->readBoolEntry( "DirTreePacMan", false ) ); +} + + +void +KDirStatApp::saveMainWinConfig() +{ + KConfig * config = kapp->config(); + + config->setGroup( "General Options" ); + + config->writeEntry( "Geometry", size() ); + config->writeEntry( "Show Toolbar", _showToolBar->isChecked() ); + config->writeEntry( "Show Statusbar", _showStatusBar->isChecked() ); + config->writeEntry( "Show Treemap", _showTreemapView->isChecked() ); + config->writeEntry( "ToolBarPos", (int) toolBar( "mainToolBar" )->barPos() ); + + if ( _treemapView ) + config->writeEntry( "TreemapViewHeight", _treemapView->height() ); + + _fileOpenRecent->saveEntries( config,"Recent Files" ); +} + + +void +KDirStatApp::saveProperties( KConfig *config ) +{ + (void) config; + // TODO +} + + +void +KDirStatApp::readProperties( KConfig *config ) +{ + (void) config; + // TODO +} + + +bool +KDirStatApp::queryClose() +{ + return true; +} + +bool +KDirStatApp::queryExit() +{ + emit saveConfig(); + + return true; +} + + +//============================================================================ +// Slots +//============================================================================ + + +void +KDirStatApp::fileAskOpenDir() +{ + statusMsg( i18n( "Opening directory..." ) ); + + KURL url = KFileDialog::getExistingDirectory( QString::null, this, i18n( "Open Directory..." ) ); + + if( ! url.isEmpty() ) + openURL( fixedUrl( url.url() ) ); + + statusMsg( i18n( "Ready." ) ); +} + + +void +KDirStatApp::fileAskOpenUrl() +{ + statusMsg( i18n( "Opening URL..." ) ); + + KURL url = KURLRequesterDlg::getURL( QString::null, // startDir + this, i18n( "Open URL..." ) ); + + if( ! url.isEmpty() ) + openURL( fixedUrl( url.url() ) ); + + statusMsg( i18n( "Ready." ) ); +} + + +void +KDirStatApp::fileOpenRecent( const KURL& url ) +{ + statusMsg( i18n( "Opening directory..." ) ); + + if( ! url.isEmpty() ) + openURL( fixedUrl( url.url() ) ); + + statusMsg( i18n( "Ready." ) ); +} + + +void +KDirStatApp::fileCloseDir() +{ + statusMsg( i18n( "Closing directory..." ) ); + + _treeView->clear(); + _fileRefreshAll->setEnabled( false ); + close(); + + statusMsg( i18n( "Ready." ) ); +} + + +void +KDirStatApp::refreshAll() +{ + statusMsg( i18n( "Refreshing directory tree..." ) ); + _treeView->refreshAll(); + statusMsg( i18n( "Ready." ) ); +} + + +void +KDirStatApp::refreshSelected() +{ + if ( ! _treeView->selection() ) + return; + + statusMsg( i18n( "Refreshing selected subtree..." ) ); + _treeView->refreshSelected(); + statusMsg( i18n( "Ready." ) ); +} + + +void +KDirStatApp::stopReading() +{ + _treeView->abortReading(); +} + + +void +KDirStatApp::editCopy() +{ + if ( _treeView->selection() ) + kapp->clipboard()->setText( QString::fromLocal8Bit(_treeView->selection()->orig()->url()) ); + +#if 0 +#warning debug + if ( _activityTracker ) + _activityTracker->trackActivity( 800 ); +#endif +} + + +void +KDirStatApp::cleanupOpenWith() +{ + if ( ! _treeView->selection() ) + return; + + KFileInfo * sel = _treeView->selection()->orig(); + + if ( sel->isDotEntry() ) + return; + + KURL::List urlList( KURL( sel->url() ) ); + KRun::displayOpenWithDialog( urlList, false ); +} + + +void +KDirStatApp::selectionChanged( KFileInfo *selection ) +{ + if ( selection ) + { + _editCopy->setEnabled( true ); + _reportMailToOwner->setEnabled( true ); + _fileRefreshSelected->setEnabled( ! selection->isDotEntry() ); + _cleanupOpenWith->setEnabled( ! selection->isDotEntry() ); + + if ( selection->isMountPoint() && + selection->readState() == KDirOnRequestOnly ) + { + _fileContinueReadingAtMountPoint->setEnabled( true ); + } + else + _fileContinueReadingAtMountPoint->setEnabled( false ); + + statusMsg( QString::fromLocal8Bit(selection->url()) ); + } + else + { + _editCopy->setEnabled( false ); + _reportMailToOwner->setEnabled( false ); + _fileRefreshSelected->setEnabled( false ); + _fileContinueReadingAtMountPoint->setEnabled( false ); + _cleanupOpenWith->setEnabled( false ); + statusMsg( "" ); + } + + updateActions(); +} + + +void +KDirStatApp::updateActions() +{ + _treemapZoomIn->setEnabled ( _treemapView && _treemapView->canZoomIn() ); + _treemapZoomOut->setEnabled( _treemapView && _treemapView->canZoomOut() ); + _treemapRebuild->setEnabled( _treemapView && _treemapView->rootTile() ); + _treemapSelectParent->setEnabled( _treemapView && _treemapView->canSelectParent() ); + + if ( _treeView->tree() && _treeView->tree()->isBusy() ) + _fileStopReading->setEnabled( true ); + else + _fileStopReading->setEnabled( false ); +} + + +void +KDirStatApp::treemapZoomIn() +{ + if ( _treemapView ) + { + _treemapView->zoomIn(); + updateActions(); + } +} + + +void +KDirStatApp::treemapZoomOut() +{ + if ( _treemapView ) + { + _treemapView->zoomOut(); + updateActions(); + } +} + + +void +KDirStatApp::treemapSelectParent() +{ + if ( _treemapView ) + { + _treemapView->selectParent(); + updateActions(); + } +} + + +void +KDirStatApp::treemapRebuild() +{ + if ( _treemapView ) + { + _treemapView->rebuildTreemap(); + updateActions(); + } +} + + +void +KDirStatApp::treemapHelp() +{ + kapp->invokeHelp( "treemap_intro" ); +} + + +void +KDirStatApp::toggleToolBar() +{ + if ( _showToolBar->isChecked() ) toolBar( "mainToolBar" )->show(); + else toolBar( "mainToolBar" )->hide(); +} + + +void +KDirStatApp::toggleStatusBar() +{ + if ( _showStatusBar->isChecked() ) statusBar()->show(); + else statusBar()->hide(); +} + + +void +KDirStatApp::toggleTreemapView() +{ + if ( _showTreemapView->isChecked() ) + { + if ( ! _treemapView ) + createTreemapView(); + } + else + { + if ( _treemapView ) + deleteTreemapView(); + } +} + + +void +KDirStatApp::preferences() +{ + if ( ! _settingsDialog ) + { + _settingsDialog = new KDirStat::KSettingsDialog( this ); + CHECK_PTR( _settingsDialog ); + } + + if ( ! _settingsDialog->isVisible() ) + _settingsDialog->show(); +} + + +void +KDirStatApp::askForFeedback() +{ + if ( ! doFeedbackReminder() ) + return; + + KConfig * config = kapp->config(); + + switch ( KMessageBox::warningYesNoCancel( this, + i18n( "Now that you know this program for some time,\n" + "wouldn't you like to tell the authors your opinion about it?\n" + "\n" + "Open Source software depends on user feedback.\n" + "Your opinion can help us make the software better." ), + i18n( "Please tell us your opinion!" ), // caption + i18n( "Open &Feedback Form..." ), // yesButton + i18n( "&No, and don't ask again!" ) // noButton + ) + ) + { + case KMessageBox::Yes: + sendFeedbackMail(); + break; + + case KMessageBox::No: // ...and don't ask again + config->setGroup( "Feedback" ); + config->writeEntry( "dontAsk", true ); + config->sync(); // make sure this doesn't get lost even if the app is killed or crashes + break; + + case KMessageBox::Cancel: + break; + } + + config->setGroup( "Feedback" ); + int remindersCount = config->readNumEntry ( "remindersCount", 0 ); + config->writeEntry( "remindersCount", ++remindersCount ); + + if ( _activityTracker ) + { + _activityTracker->setThreshold( _activityTracker->threshold() + + FEEDBACK_REMINDER_INTERVAL ); + } +} + + +void +KDirStatApp::feedbackMailSent() +{ + KConfig * config = kapp->config(); + config->setGroup( "Feedback" ); + config->writeEntry( "mailSent", true ); + config->sync(); +} + + +bool +KDirStatApp::doFeedbackReminder() +{ + KConfig * config = kapp->config(); + config->setGroup( "Feedback" ); + + bool mailSent = config->readBoolEntry( "mailSent", false ); + bool dontAsk = config->readBoolEntry( "dontAsk", false ); + int remindersCount = config->readNumEntry ( "remindersCount", 0 ); + + return !mailSent && !dontAsk && remindersCount < 5; +} + + +void +KDirStatApp::statusMsg( const QString &text ) +{ + // Change status message permanently + + statusBar()->clear(); + statusBar()->changeItem( text, ID_STATUS_MSG ); +} + + +void +KDirStatApp::contextMenu( KDirTreeViewItem * item, const QPoint &pos ) +{ + NOT_USED( item ); + + if ( _treeViewContextMenu ) + _treeViewContextMenu->popup( pos ); +} + + +void +KDirStatApp::contextMenu( KTreemapTile * tile, const QPoint &pos ) +{ + NOT_USED( tile ); + + if ( _treemapContextMenu ) + _treemapContextMenu->popup( pos ); +} + + +void +KDirStatApp::createTreemapView() +{ + if ( ! _showTreemapView->isChecked() || ! _treeView->tree() ) + return; + + if ( _treemapView ) + delete _treemapView; + + _treemapView = new KTreemapView( _treeView->tree(), _splitter, + QSize( _splitter->width(), _treemapViewHeight ) ); + CHECK_PTR( _treemapView ); + + connect( _treemapView, SIGNAL( contextMenu( KTreemapTile *, const QPoint & ) ), + this, SLOT ( contextMenu( KTreemapTile *, const QPoint & ) ) ); + + connect( _treemapView, SIGNAL( treemapChanged() ), + this, SLOT ( updateActions() ) ); + + connect( _treemapView, SIGNAL( selectionChanged( KFileInfo * ) ), + this, SLOT ( selectionChanged( KFileInfo * ) ) ); + + if ( _activityTracker ) + { + connect( _treemapView, SIGNAL( userActivity ( int ) ), + _activityTracker, SLOT ( trackActivity( int ) ) ); + } + + _treemapView->show(); // QSplitter needs explicit show() for new children + updateActions(); +} + + +void +KDirStatApp::deleteTreemapView() +{ + if ( _treemapView ) + { + _treemapViewHeight = _treemapView->height(); + delete _treemapView; + } + + _treemapView = 0; + updateActions(); +} + + + +// EOF diff --git a/kdirstat/kdirstatapp.h b/kdirstat/kdirstatapp.h new file mode 100644 index 0000000..0f8b875 --- /dev/null +++ b/kdirstat/kdirstatapp.h @@ -0,0 +1,421 @@ +/* + * File name: kdirstatapp.h + * Summary: The KDirStat application - menu bar, tool bar, ... + * License: GPL - See file COPYING for details. + * + * Author: Stefan Hundhammer + * Parts auto-generated by KDevelop + * + * Updated: 2004-12-06 + */ + + +#ifndef KDirStatApp_h +#define KDirStatApp_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "kdirtree.h" + + +// Forward declarations +class QPopupMenu; +class QSplitter; + +class KAction; +class KActivityTracker; +class KFeedbackDialog; +class KFeedbackDialog; +class KFeedbackQuestion; +class KPacMan; +class KPacMan; +class KRecentFilesAction; +class KToggleAction; + +namespace KDirStat +{ + class KCleanupCollection; + class KDirTreeView; + class KDirTreeViewItem; + class KFileInfo; + class KSettingsDialog; + class KTreemapView; + class KTreemapTile; +} + +using namespace KDirStat; + + +/** + * The base class for KDirStat application windows. It sets up the main window + * and reads the config file as well as providing a menubar, toolbar and + * statusbar. An instance of KDirStatView creates your center view, which is + * connected to the window's Doc object. KDirStatApp reimplements the methods + * that KMainWindow provides for main window handling and supports full + * session management as well as using KActions. + * + * @see KMainWindow + * @see KApplication + * @see KConfig + * + * @author Source Framework Automatically Generated by KDevelop, + * (c) The KDevelop Team. + * + * @version KDevelop version 1.2 code generation + **/ +class KDirStatApp : public KMainWindow +{ + Q_OBJECT + +public: + + /** + * Construtor of KDirStatApp, calls all init functions to create the + * application. + **/ + KDirStatApp( QWidget* parent=0, const char* name=0 ); + + /** + * Destructor. + **/ + virtual ~KDirStatApp(); + + /** + * Open an URL specified by command line argument. + **/ + void openURL( const KURL & url ); + + /** + * Return the main window's @ref KDirTreeView. + **/ + KDirTreeView * treeView() const { return _treeView; } + + /** + * Returns the main window's @ref KTreemapView or 0 if there is none. + * + * Caution: Do not try to cache this value. The treemap view is destroyed + * and re-created frequently! + **/ + KTreemapView * treemapView() const { return _treemapView; } + + +public slots: + + /** + * Open a directory tree. + **/ + void fileAskOpenDir(); + + /** + * Open a (possibly remote) directory tree. + **/ + void fileAskOpenUrl(); + + /** + * Refresh the entire directory tree, i.e. re-read everything from disk. + **/ + void refreshAll(); + + /** + * Refresh the selected subtree, i.e. re-read it from disk. + **/ + void refreshSelected(); + + /** + * Refresh the entire directory tree, i.e. re-read everything from disk. + **/ + void stopReading(); + + /** + * Open a directory tree from the "recent" menu. + **/ + void fileOpenRecent( const KURL& url ); + + /** + * asks for saving if the file is modified, then closes the current file + * and window + **/ + void fileCloseDir(); + + /** + * put the marked text/object into the clipboard + **/ + void editCopy(); + + /** + * Notification that the view's selection has changed. + * Enable/disable user actions as appropriate. + **/ + void selectionChanged( KFileInfo *selection ); + + /** + * Ask user what application to open a file or directory with + **/ + void cleanupOpenWith(); + + /** + * Toggle tool bar + **/ + void toggleToolBar(); + + /** + * Toggle status bar + **/ + void toggleStatusBar(); + + /** + * Toggle treemap view + **/ + void toggleTreemapView(); + + /** + * Zoom in the treemap at the currently selected tile. + **/ + void treemapZoomIn(); + + /** + * Zoom out the treemap after zooming in. + **/ + void treemapZoomOut(); + + /** + * Select the parent of the currently selected treemap tile. + **/ + void treemapSelectParent(); + + /** + * Rebuild the treemap. + **/ + void treemapRebuild(); + + /** + * Invoke online help about treemaps. + **/ + void treemapHelp(); + + /** + * Open settings dialog + **/ + void preferences(); + + /** + * Changes the statusbar contents for the standard label permanently, used + * to indicate current actions. + * + * @param text the text that is displayed in the statusbar + **/ + void statusMsg( const QString &text ); + + /** + * Opens a context menu for tree view items. + **/ + void contextMenu( KDirTreeViewItem * item, const QPoint &pos ); + + /** + * Opens a context menu for treemap tiles. + **/ + void contextMenu( KTreemapTile * tile, const QPoint &pos ); + + /** + * Create a treemap view. This makes only sense after a directory tree is + * completely read. + **/ + void createTreemapView(); + + /** + * Delete an existing treemap view if there is one. + **/ + void deleteTreemapView(); + + /** + * Sends a user feedback mail. + **/ + void sendFeedbackMail(); + + /** + * Read configuration for the main window. + **/ + void readMainWinConfig(); + + /** + * Save the main window's configuration. + **/ + void saveMainWinConfig(); + + /** + * Revert all cleanups to default values. + **/ + void revertCleanupsToDefaults(); + + /** + * For the settings dialog only: Return the internal cleanup collection. + **/ + KCleanupCollection * cleanupCollection() { return _cleanupCollection; } + + /** + * Initialize @ref KPacMan animation in the tool bar. + **/ + void initPacMan( bool enablePacMan = true ); + + /** + * Returns true if the pacman animation in the tool bar is enabled, false + * otherwise. + **/ + bool pacManEnabled() const { return _pacMan != 0; } + + /** + * Ask user if he wouldn't like to rate this program. + **/ + void askForFeedback(); + + /** + * Notification that a feedback mail has been sent, thus don't remind + * the user any more. + **/ + void feedbackMailSent(); + + /** + * Update enabled/disabled state of the user actions. + **/ + void updateActions(); + + +signals: + + /** + * Emitted when the configuration is to be read - other than at program + * startup / object creation where each object is responsible for reading + * its configuraton at an appropriate time. + **/ + void readConfig(); + + /** + * Emitted when the configuration is to be saved. + **/ + void saveConfig(); + + +protected: + + /** + * Initialize the KActions of the application. + **/ + void initActions(); + + /** + * Initialize @ref KCleanup actions. + **/ + void initCleanups(); + + /** + * Set up status bar for the main window by initializing a status label. + **/ + void initStatusBar(); + + /** + * Set up the activity tracker. + **/ + void initActivityTracker(); + + /** + * Called when a main window is to be closed. + * + * Returns "true" when closing this window is OK, "false" to abort closing. + **/ + virtual bool queryClose(); + + /** + * Called when the application is to be shut down alltogether, i.e. when + * all windows are to be closed. + * + * Returns "true" when exiting is OK, "false" otherwise. + **/ + virtual bool queryExit(); + + /** + * Save the window properties for each open window during session end to + * the session config file, including saving the currently opened file by a + * temporary filename provided by KApplication. + * + * @see KTMainWindow#saveProperties + **/ + virtual void saveProperties( KConfig * config ); + + /** + * Reads session config file and restore application state including the + * last opened files and documents by reading the temporary files saved by + * saveProperties(). + * + * @see KTMainWindow#readProperties + **/ + virtual void readProperties( KConfig * config ); + + + /** + * Add a list of features of this program to a feedback question + **/ + void addFeatureList( KFeedbackQuestion * question ); + + /** + * Check if the user should be reminded to submit feedback. + **/ + bool doFeedbackReminder(); + + + // + // Data members + // + + // Widgets + + QSplitter * _splitter; + KDirTreeView * _treeView; + KTreemapView * _treemapView; + KPacMan * _pacMan; + QWidget * _pacManDelimiter; + QPopupMenu * _treeViewContextMenu; + QPopupMenu * _treemapContextMenu; + KDirStat::KSettingsDialog * _settingsDialog; + KFeedbackDialog * _feedbackDialog; + KActivityTracker * _activityTracker; + + + // Actions + + KAction * _fileAskOpenDir; + KAction * _fileAskOpenUrl; + KRecentFilesAction * _fileOpenRecent; + KAction * _fileCloseDir; + KAction * _fileRefreshAll; + KAction * _fileRefreshSelected; + KAction * _fileContinueReadingAtMountPoint; + KAction * _fileStopReading; + KAction * _fileQuit; + KAction * _editCopy; + KAction * _cleanupOpenWith; + KAction * _treemapZoomIn; + KAction * _treemapZoomOut; + KAction * _treemapSelectParent; + KAction * _treemapRebuild; + + KAction * _reportMailToOwner; + KAction * _helpSendFeedbackMail; + KToggleAction * _showToolBar; + KToggleAction * _showStatusBar; + KToggleAction * _showTreemapView; + + KCleanupCollection * _cleanupCollection; + + + // Misc + + int _treemapViewHeight; +}; + + +#endif // KDirStatApp_h diff --git a/kdirstat/kdirstatfeedback.cpp b/kdirstat/kdirstatfeedback.cpp new file mode 100644 index 0000000..0483499 --- /dev/null +++ b/kdirstat/kdirstatfeedback.cpp @@ -0,0 +1,184 @@ +/* + * File name: kdirstatfeedback.cpp + * Summary: User feedback questions for KDirStat + * License: GPL - See file COPYING for details. + * + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#include + +#include "kdirstatapp.h" +#include "kfeedback.h" + + + +void +KDirStatApp::sendFeedbackMail() +{ + if ( ! _feedbackDialog ) + { + _feedbackDialog = new KFeedbackDialog( "sh@suse.de", "feedback_mail" ); + CHECK_PTR( _feedbackDialog ); + + connect( _feedbackDialog->form(), SIGNAL( mailSent() ), + this, SLOT( feedbackMailSent() ) ); + + KFeedbackQuestionList * list = _feedbackDialog->form()->questionList(); + + KFeedbackQuestion * question = + list->addQuestion( i18n( "What is your general opinion about this program?" ), "general_opinion", true, true ); + + question->addAnswer( i18n( "It's one of my favourites" ), "1/8_favourite" ); + question->addAnswer( i18n( "I like it" ), "2/8_like_it" ); + question->addAnswer( i18n( "It's sometimes useful" ), "3/8_sometimes_useful" ); + question->addAnswer( i18n( "It's average" ), "4/8_average" ); + question->addAnswer( i18n( "Nice try, but this could be done better" ), "5/8_nice_try" ); + question->addAnswer( i18n( "It's poor" ), "6/8_poor" ); + question->addAnswer( i18n( "It's useless" ), "7/8_useless" ); + question->addAnswer( i18n( "It's crap" ), "8/8_crap" ); + + question = list->addQuestion( i18n( "Which features of this program do you like?" ), "features_liked", false ); + addFeatureList( question ); + + question = list->addQuestion( i18n( "Which features don't you like?" ), "features_not_liked", false ); + addFeatureList( question ); + + question = list->addQuestion( i18n( "Which features do you never use?" ), "features_never_used", false ); + addFeatureList( question ); + + question = list->addQuestion( i18n( "What is your favourite feature?" ), "favourite_feature", true ); + addFeatureList( question ); + + question = list->addQuestion( i18n( "Are there features you are missing?" ), "features_missing", true ); + question->addAnswer( i18n( "Yes, a lot! (please add comment below)" ), "1/4_lots" ); + question->addAnswer( i18n( "Some (please add comment below)" ), "2/4_some" ); + question->addAnswer( i18n( "None" ), "3/4_none" ); + question->addAnswer( i18n( "It has too many features already!" ), "4/4_too_many_already" ); + + question = list->addQuestion( i18n( "How do you rate the stability of this program?" ), "stability", true, true ); + question->addAnswer( i18n( "Rock solid" ), "1/5_rock_solid" ); + question->addAnswer( i18n( "Good" ), "2/5_good" ); + question->addAnswer( i18n( "Average" ), "3/5_average" ); + question->addAnswer( i18n( "Poor" ), "4/5_poor" ); + question->addAnswer( i18n( "It keeps crashing all the time" ), "5/5_keeps_crashing" ); + + question = list->addQuestion( i18n( "How do you rate the performance of this program?" ), "performance", true ); + question->addAnswer( i18n( "Great" ), "1/5_great" ); + question->addAnswer( i18n( "Good" ), "2/5_good" ); + question->addAnswer( i18n( "Average" ), "3/5_average" ); + question->addAnswer( i18n( "Poor" ), "4/5_poor" ); + question->addAnswer( i18n( "It's so slow it drives me nuts" ), "5/5_drives_me_nuts" ); + + question = list->addQuestion( i18n( "What is your experience with computers in general?" ), "computer_experience", true ); + question->addAnswer( i18n( "Expert" ), "1/5_expert" ); + question->addAnswer( i18n( "Fair" ), "2/5_fair" ); + question->addAnswer( i18n( "Average" ), "3/5_average" ); + question->addAnswer( i18n( "Learning" ), "4/5_learning" ); + question->addAnswer( i18n( "Newbie" ), "5/5_newbie" ); + + question = list->addQuestion( i18n( "What is your experience with Unix/Linux systems?" ), "unix_experience", true ); + question->addAnswer( i18n( "Expert" ), "1/5_expert" ); + question->addAnswer( i18n( "Fair" ), "2/5_fair" ); + question->addAnswer( i18n( "Average" ), "3/5_average" ); + question->addAnswer( i18n( "Learning" ), "4/5_learning" ); + question->addAnswer( i18n( "Newbie" ), "5/5_newbie" ); + + question = list->addQuestion( i18n( "Did you have trouble figuring out how to work with this program in general?" ), + "learning_curve", true, true ); + question->addAnswer( i18n( "No problem" ), "1/5_no_problem" ); + question->addAnswer( i18n( "Some" ), "2/5_some_problems" ); + question->addAnswer( i18n( "I'm still learning" ), "3/5_still_learing" ); + question->addAnswer( i18n( "I didn't have a clue what to do at first" ), "4/5_no_clue_at_first" ); + question->addAnswer( i18n( "I still don't have a clue what to do" ), "5/5_still_no_clue" ); + + question = list->addQuestion( i18n( "Where do you use this program most?" ), "usage_where", true ); + question->addAnswer( i18n( "At work" ), "at_work" ); + question->addAnswer( i18n( "At home" ), "at_home" ); + question->addAnswer( i18n( "At university / school" ), "university" ); + + question = list->addQuestion( i18n( "What is your primary role there?" ), "primary_role", true ); + question->addAnswer( i18n( "Home user" ), "home_user" ); + question->addAnswer( i18n( "Student" ), "student" ); + question->addAnswer( i18n( "Educational (teacher / professor)" ), "educational" ); + question->addAnswer( i18n( "Non-computer related work" ), "non_computer" ); + question->addAnswer( i18n( "Developer" ), "developer" ); + question->addAnswer( i18n( "System administrator" ), "sysadmin" ); + + question = list->addQuestion( i18n( "Do you have any other roles there?" ), "other_roles", false ); + question->addAnswer( i18n( "Home user" ), "home_user" ); + question->addAnswer( i18n( "Student" ), "student" ); + question->addAnswer( i18n( "Educational (teacher / professor)" ), "educational" ); + question->addAnswer( i18n( "Non-computer related work" ), "non_computer" ); + question->addAnswer( i18n( "Developer" ), "developer" ); + question->addAnswer( i18n( "System administrator" ), "sysadmin" ); + + question = list->addQuestion( i18n( "How did you get to know this program?" ), "first_contact", true ); + question->addAnswer( i18n( "In a menu on my machine" ), "menu" ); + question->addAnswer( i18n( "Somebody told me about it" ), "told" ); + question->addAnswer( i18n( "On the internet" ), "internet" ); + question->addAnswer( i18n( "Printed magazine / book" ), "print_media" ); + question->addAnswer( i18n( "Other (please add comment below)" ), "other" ); + + list->addYesNoQuestion( i18n( "Did you ever get a KDirStat mail report telling you to clean up disk space?" ), + "got_mail_report" ); + + question = list->addQuestion( i18n( "Could you figure yet out how to work with the treemaps?" ), "learning_treemaps", true ); + question->addAnswer( i18n( "I became an expert at it" ), "1/5_expert" ); + question->addAnswer( i18n( "I got a fairly good idea of it" ), "2/5_ok" ); + question->addAnswer( i18n( "I'm still learning" ), "3/5_still_learing" ); + question->addAnswer( i18n( "I still don't have a clue what to do" ), "4/5_no_clue" ); + question->addAnswer( i18n( "Treemaps? Huh? What the hell is that?" ), "5/5_say_what" ); + + question = list->addQuestion( i18n( "What do you think about the treemaps?" ), "treemaps", false ); + question->addAnswer( i18n( "They are useless" ), "useless" ); + question->addAnswer( i18n( "The display is confusing" ), "display_confusing" ); + question->addAnswer( i18n( "They look ugly" ), "look_ugly" ); + question->addAnswer( i18n( "They look nice" ), "look_nice" ); + question->addAnswer( i18n( "They help finding large files" ), "good_for_large_files" ); + question->addAnswer( i18n( "I could do with the treemap view alone" ), "treemaps_alone" ); + question->addAnswer( i18n( "The combination of tree view and treemaps is great" ), "like_combined_views"); + question->addAnswer( i18n( "I want more info inside the treemap view" ), "more_info" ); + question->addAnswer( i18n( "Leave the treemaps as they are right now" ), "leave_like_this" ); + + list->addYesNoQuestion( i18n( "Would you recommend this program to a friend?" ), "recommend", true ); + } + + if ( ! _feedbackDialog->isVisible() ) + _feedbackDialog->show(); +} + + +void +KDirStatApp::addFeatureList( KFeedbackQuestion * question ) +{ + question->addAnswer( i18n( "The directory tree display in general" ), "tree_view" ); + question->addAnswer( i18n( "Percentage bars as graphical display of relative sizes" ), "percentage_bars" ); + question->addAnswer( i18n( "Files apart from directories in a separate item"), "files_item" ); + + question->addAnswer( i18n( "Treemaps in general" ), "treemaps" ); + question->addAnswer( i18n( "The cushioned treemap rendering" ), "treemap_cushions" ); + + question->addAnswer( i18n( "Cleanup actions in general" ), "cleanups_general" ); + question->addAnswer( i18n( "Predefined cleanup actions" ), "predefined_cleanups" ); + question->addAnswer( i18n( "User defined cleanup actions" ), "user_cleanups" ); + question->addAnswer( i18n( "Cleanup action configuration" ), "cleanup_config" ); + + question->addAnswer( i18n( "Different colors in percentage bars" ), "tree_colors" ); + question->addAnswer( i18n( "Tree color configuration" ), "tree_color_config" ); + question->addAnswer( i18n( "Staying on one file system" ), "stay_on_one_filesys" ); + question->addAnswer( i18n( "The \"mail to owner\" facility" ), "mail_to_owner" ); + question->addAnswer( i18n( "This \"feedback mail\" facility" ), "feedback" ); + + question->addAnswer( i18n( "Human readable sizes (kB, MB, ...)" ), "human_readable_sizes" ); + question->addAnswer( i18n( "All the numbers in the tree display" ), "numeric_display" ); + question->addAnswer( i18n( "Last change time of an entire directory tree" ), "last_change_time" ); + question->addAnswer( i18n( "The PacMan animation" ), "pacman" ); +} + + + +// EOF diff --git a/kdirstat/kdirstatmain.cpp b/kdirstat/kdirstatmain.cpp new file mode 100644 index 0000000..dd957db --- /dev/null +++ b/kdirstat/kdirstatmain.cpp @@ -0,0 +1,115 @@ +/* + * File name: kdirstatmain.cpp + * Summary: Main program for KDirStat + * License: GPL - See file COPYING for details. + * + * Author: Stefan Hundhammer + * Parts auto-generated by KDevelop + * + * Updated: 2003-01-07 + */ + + +#include +#include +#include + +#include "kdirstatapp.h" + + +static const char *description = + I18N_NOOP("KDirStat - Directory statistics.\n" + "\n" + "Shows where all your disk space has gone\n" + "and helps you clean it up." + "\n" + "\n" + "\n" + "If you have any comments or if you would simply like to tell your opinion\n" + "about this program, please use \"Send Feedback Mail\" from the \"Help\" menu.\n" + "\n" + "Any feedback (even negative!) is appreciated." + ); + + +static KCmdLineOptions options[] = +{ + { "+[Dir/URL]", I18N_NOOP("Directory or URL to open"), 0 }, + { 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + + KAboutData aboutData( "kdirstat", I18N_NOOP("KDirStat"), + VERSION, description, KAboutData::License_GPL, + "(c) 1999-2003 Stefan Hundhammer", 0, 0, + "sh@suse.de" ); + + aboutData.addAuthor( "Stefan Hundhammer", + I18N_NOOP("\n" + "If you have any comments or if you would simply like to tell\n" + "your opinion about this program, please use \n" + "\"Send Feedback Mail\" from the \"Help\" menu.\n" + "\n" + "Any feedback (even negative!) is appreciated." ), + "sh@suse.de", "http://kdirstat.sourceforge.net/" ); + + + aboutData.addCredit( I18N_NOOP( "All the people who worked on SequoiaView" ), + I18N_NOOP( "for showing just how useful treemaps really can be.\n" ), + 0, // e-mail + "http://www.win.tue.nl/sequoiaview" ); + + aboutData.addCredit( I18N_NOOP( "Jarke J. van Wijk, Huub van de Wetering, and Mark Bruls" ), + I18N_NOOP( "for their papers about treemaps.\n" ), + "vanwijk@win.tue.nl", + "http://www.win.tue.nl/~vanwijk/" ); + + aboutData.addCredit( "Ben Shneiderman", + I18N_NOOP( "for his ingenious idea of treemaps -\n" + "a truly intuitive way of visualizing tree contents.\n" ), + "", // E-Mail + "http://www.cs.umd.edu/hcil/treemaps/" ); + + aboutData.addCredit( "All the users who gave feedback of any kind", + I18N_NOOP( "for showing that all the work involved with such a project\n" + "is really appreciated out there.\n" ) ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + + KApplication app; + + if ( app.isRestored() ) + { + RESTORE(KDirStatApp); + } + else + { + KDirStatApp *kdirstat = new KDirStatApp(); + kdirstat->show(); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if ( args->count() ) + { + // Process command line arguments as URLs or paths to scan + + KURL url = fixedUrl( args->arg( 0 ) ); + // kdDebug() << "Opening " << url.url() << endl; + kdirstat->openURL( url ); + } + else + { + kdirstat->fileAskOpenDir(); + } + + args->clear(); + } + + // kdDebug() << "Entering main loop" << endl; + + return app.exec(); +} + diff --git a/kdirstat/kdirstatsettings.cpp b/kdirstat/kdirstatsettings.cpp new file mode 100644 index 0000000..c647178 --- /dev/null +++ b/kdirstat/kdirstatsettings.cpp @@ -0,0 +1,1056 @@ +/* + * File name: kdirstatsettings.cpp + * Summary: Settings dialog for KDirStat + * License: GPL - See file COPYING for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-30 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kdirtreeview.h" +#include "ktreemapview.h" +#include "kdirstatsettings.h" + + +using namespace KDirStat; + + +KSettingsDialog::KSettingsDialog( KDirStatApp *mainWin ) + : KDialogBase( Tabbed, // dialogFace + i18n( "Settings" ), // caption + Ok | Apply | Default | Cancel | Help, // buttonMask + Ok, // defaultButton + 0, // parent + 0, // name + false ) // modal + , _mainWin( mainWin ) +{ + /** + * This may seem like overkill, but I didn't find any other way to get + * geometry management right with KDialogBase, yet maintain a modular and + * object-oriented design: + * + * Each individual settings page is added with 'addVBoxPage()' to get some + * initial geometry management. Only then can some generic widget be added + * into this - and I WANT my settings pages to be generic widgets. I want + * them to be self-sufficient - no monolithic mess of widget creation in my + * code, intermixed with all kinds of layout objects. + * + * The ordinary KDialogBase::addPage() just creates a QFrame which is too + * dumb for any kind of geometry management - it cannot even handle one + * single child right. So, let's have KDialogBase create something more + * intelligent: A QVBox (which is derived from QFrame anyway). This QVBox + * gets only one child - the KSettingsPage. This KSettingsPage handles its + * own layout. + **/ + + QWidget * page; + + page = addVBoxPage( i18n( "&Cleanups" ) ); + _cleanupsPageIndex = pageIndex( page ); + new KCleanupPage( this, page, _mainWin ); + + page = addVBoxPage( i18n( "&Tree Colors" ) ); + _treeColorsPageIndex = pageIndex( page ); + new KTreeColorsPage( this, page, _mainWin ); + + page = addVBoxPage( i18n( "Tree&map" ) ); + _treemapPageIndex = pageIndex( page ); + new KTreemapPage( this, page, _mainWin ); + + page = addVBoxPage( i18n( "&General" ) ); + _generalSettingsPageIndex = pageIndex( page ); + new KGeneralSettingsPage( this, page, _mainWin ); + + // resize( sizeHint() ); +} + + +KSettingsDialog::~KSettingsDialog() +{ + // NOP +} + + +void +KSettingsDialog::show() +{ + emit aboutToShow(); + KDialogBase::show(); +} + + +void +KSettingsDialog::slotDefault() +{ + if ( KMessageBox::warningContinueCancel( this, + i18n( "Really revert all settings to their default values?\n" + "You will lose all changes you ever made!" ), + i18n( "Please Confirm" ), // caption + i18n( "&Really Revert to Defaults" ) // continueButton + ) == KMessageBox::Continue ) + { + emit defaultClicked(); + emit applyClicked(); + } +} + + +void +KSettingsDialog::slotHelp() +{ + QString helpTopic = ""; + + if ( activePageIndex() == _cleanupsPageIndex ) helpTopic = "configuring_cleanups"; + else if ( activePageIndex() == _treeColorsPageIndex ) helpTopic = "tree_colors"; + else if ( activePageIndex() == _treemapPageIndex ) helpTopic = "treemap_settings"; + else if ( activePageIndex() == _generalSettingsPageIndex) helpTopic = "general_settings"; + + // kdDebug() << "Help topic: " << helpTopic << endl; + kapp->invokeHelp( helpTopic ); +} + + +/*--------------------------------------------------------------------------*/ + + +KSettingsPage::KSettingsPage( KSettingsDialog * dialog, + QWidget * parent ) + : QWidget( parent ) +{ + connect( dialog, SIGNAL( aboutToShow ( void ) ), + this, SLOT ( setup ( void ) ) ); + + connect( dialog, SIGNAL( okClicked ( void ) ), + this, SLOT ( apply ( void ) ) ); + + connect( dialog, SIGNAL( applyClicked ( void ) ), + this, SLOT ( apply ( void ) ) ); + + connect( dialog, SIGNAL( defaultClicked ( void ) ), + this, SLOT ( revertToDefaults( void ) ) ); +} + + +KSettingsPage::~KSettingsPage() +{ + // NOP +} + + +/*--------------------------------------------------------------------------*/ + + +KTreeColorsPage::KTreeColorsPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ) + : KSettingsPage( dialog, parent ) + , _mainWin( mainWin ) + , _treeView( mainWin->treeView() ) + , _maxButtons( KDirStatSettingsMaxColorButton ) +{ + // Outer layout box + + QHBoxLayout * outerBox = new QHBoxLayout( this, + 0, // border + dialog->spacingHint() ); + + + // Inner layout box with a column of color buttons + + QGridLayout *grid = new QGridLayout( _maxButtons, // rows + _maxButtons + 1, // cols + dialog->spacingHint() ); + outerBox->addLayout( grid, 1 ); + grid->setColStretch( 0, 0 ); // label column - dont' stretch + + for ( int i=1; i < _maxButtons; i++ ) + { + grid->setColStretch( i, 1 ); // all other columns stretch as you like + } + + for ( int i=0; i < _maxButtons; i++ ) + { + QString labelText; + + labelText=i18n( "Tree Level %1" ).arg(i+1); + _colorLabel[i] = new QLabel( labelText, this ); + grid->addWidget( _colorLabel [i], i, 0 ); + + _colorButton[i] = new KColorButton( this ); + _colorButton[i]->setMinimumSize( QSize( 80, 10 ) ); + grid->addMultiCellWidget( _colorButton [i], i, i, i+1, _maxButtons ); + grid->setRowStretch( i, 1 ); + } + + + // Vertical slider + + _slider = new QSlider( 1, // minValue + _maxButtons, // maxValue + 1, // pageStep + 1, // value + QSlider::Vertical, + this ); + outerBox->addWidget( _slider, 0 ); + outerBox->activate(); + + connect( _slider, SIGNAL( valueChanged( int ) ), + this, SLOT ( enableColors( int ) ) ); +} + + +KTreeColorsPage::~KTreeColorsPage() +{ + // NOP +} + + +void +KTreeColorsPage::apply() +{ + _treeView->setUsedFillColors( _slider->value() ); + + for ( int i=0; i < _maxButtons; i++ ) + { + _treeView->setFillColor( i, _colorButton [i]->color() ); + } + + _treeView->triggerUpdate(); +} + + +void +KTreeColorsPage::revertToDefaults() +{ + _treeView->setDefaultFillColors(); + setup(); +} + + +void +KTreeColorsPage::setup() +{ + for ( int i=0; i < _maxButtons; i++ ) + { + _colorButton [i]->setColor( _treeView->rawFillColor(i) ); + } + + _slider->setValue( _treeView->usedFillColors() ); + enableColors( _treeView->usedFillColors() ); +} + + +void +KTreeColorsPage::enableColors( int maxColors ) +{ + for ( int i=0; i < _maxButtons; i++ ) + { + _colorButton [i]->setEnabled( i < maxColors ); + _colorLabel [i]->setEnabled( i < maxColors ); + } +} + + +/*--------------------------------------------------------------------------*/ + + + +KCleanupPage::KCleanupPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ) + : KSettingsPage( dialog, parent ) + , _mainWin( mainWin ) + , _currentCleanup( 0 ) +{ + // Copy the main window's cleanup collection. + + _workCleanupCollection = *mainWin->cleanupCollection(); + + // Create layout and widgets. + + QHBoxLayout * layout = new QHBoxLayout( this, + 0, // border + dialog->spacingHint() ); // spacing + _listBox = new KCleanupListBox( this ); + _props = new KCleanupPropertiesPage( this, mainWin ); + + + // Connect list box signals to reflect changes in the list + // selection in the cleanup properties page - whenever the user + // clicks on a different cleanup in the list, the properties page + // will display that cleanup's values. + + connect( _listBox, SIGNAL( selectCleanup( KCleanup * ) ), + this, SLOT ( changeCleanup( KCleanup * ) ) ); + + + // Fill list box so it can determine a reasonable startup geometry - that + // doesn't work if it happens only later. + + setup(); + + // Now that _listBox will (hopefully) have determined a reasonable + // default geometry, add the widgets to the layout. + + layout->addWidget( _listBox, 0 ); + layout->addWidget( _props , 1 ); + layout->activate(); +} + + +KCleanupPage::~KCleanupPage() +{ + // NOP +} + + +void +KCleanupPage::changeCleanup( KCleanup * newCleanup ) +{ + if ( _currentCleanup && newCleanup != _currentCleanup ) + { + storeProps( _currentCleanup ); + } + + _currentCleanup = newCleanup; + _props->setFields( _currentCleanup ); +} + + +void +KCleanupPage::apply() +{ + exportCleanups(); +} + + +void +KCleanupPage::revertToDefaults() +{ + _mainWin->revertCleanupsToDefaults(); + setup(); +} + + +void +KCleanupPage::setup() +{ + importCleanups(); + + // Fill the list box. + + _listBox->clear(); + KCleanupList cleanupList = _workCleanupCollection.cleanupList(); + KCleanupListIterator it( cleanupList ); + + while ( *it ) + { + _listBox->insert( *it ); + ++it; + } + + + // (Re-) Initialize list box. + + // _listBox->resize( _listBox->sizeHint() ); + _listBox->setSelected( 0, true ); +} + + +void +KCleanupPage::importCleanups() +{ + // Copy the main window's cleanup collecton to _workCleanupCollection. + + _workCleanupCollection = * _mainWin->cleanupCollection(); + + + // Pointers to the old collection contents are now invalid! + + _currentCleanup = 0; +} + + +void +KCleanupPage::exportCleanups() +{ + // Retrieve any pending changes from the properties page and store + // them in the current cleanup. + + storeProps( _currentCleanup ); + + + // Copy the _workCleanupCollection to the main window's cleanup + // collection. + + * _mainWin->cleanupCollection() = _workCleanupCollection; +} + + +void +KCleanupPage::storeProps( KCleanup * cleanup ) +{ + if ( cleanup ) + { + // Retrieve the current fields contents and store them in the current + // cleanup. + + *cleanup = _props->fields(); + + // Update the list box accordingly - the cleanup's title may have + // changed, too! + + _listBox->updateTitle( cleanup ); + } +} + +/*--------------------------------------------------------------------------*/ + + +KCleanupListBox::KCleanupListBox( QWidget *parent ) + : QListBox( parent ) +{ + _selection = 0; + + connect( this, + SIGNAL( selectionChanged( QListBoxItem *) ), + SLOT ( selectCleanup ( QListBoxItem *) ) ); +} + + +QSize +KCleanupListBox::sizeHint() const +{ + // FIXME: Is this still needed with Qt 2.x? + + if ( count() < 1 ) + { + // As long as the list is empty, sizeHint() would default to + // (0,0) which is ALWAYS just a pain in the ass. We'd rather + // have an absolutely random value than this. + return QSize( 100, 100 ); + } + else + { + // Calculate the list contents and take 3D frames (2*2 pixels) + // into account. + return QSize ( maxItemWidth() + 5, + count() * itemHeight( 0 ) + 4 ); + } +} + + +void +KCleanupListBox::insert( KCleanup * cleanup ) +{ + // Create a new listbox item - this will insert itself (!) automatically. + // It took me half an afternoon to figure _this_ out. Not too intuitive + // when there is an insertItem() method, too, eh? + + new KCleanupListBoxItem( this, cleanup ); +} + + +void +KCleanupListBox::selectCleanup( QListBoxItem * listBoxItem ) +{ + KCleanupListBoxItem * item = (KCleanupListBoxItem *) listBoxItem; + + _selection = item->cleanup(); + emit selectCleanup( _selection ); +} + + +void +KCleanupListBox::updateTitle( KCleanup * cleanup ) +{ + KCleanupListBoxItem * item = (KCleanupListBoxItem *) firstItem(); + + while ( item ) + { + if ( ! cleanup || item->cleanup() == cleanup ) + item->updateTitle(); + + item = (KCleanupListBoxItem *) item->next(); + } +} + + +/*--------------------------------------------------------------------------*/ + + +KCleanupListBoxItem::KCleanupListBoxItem( KCleanupListBox * listBox, + KCleanup * cleanup ) + : QListBoxText( listBox ) + , _cleanup( cleanup ) +{ + CHECK_PTR( cleanup ); + setText( cleanup->cleanTitle() ); +} + + +void +KCleanupListBoxItem::updateTitle() +{ + setText( _cleanup->cleanTitle() ); +} + + +/*--------------------------------------------------------------------------*/ + + +KCleanupPropertiesPage::KCleanupPropertiesPage( QWidget * parent, + KDirStatApp * mainWin ) + : QWidget( parent ) + , _mainWin( mainWin ) +{ + QVBoxLayout *outerBox = new QVBoxLayout( this, 0, 0 ); // border, spacing + + // The topmost check box: "Enabled". + + _enabled = new QCheckBox( i18n( "&Enabled" ), this ); + outerBox->addWidget( _enabled, 0 ); + outerBox->addSpacing( 7 ); + outerBox->addStretch(); + + connect( _enabled, SIGNAL( toggled ( bool ) ), + this, SLOT ( enableFields( bool ) ) ); + + + // All other widgets of this page are grouped together in a + // separate subwidget so they can all be enabled / disabled + // together. + _fields = new QWidget( this ); + outerBox->addWidget( _fields, 1 ); + + QVBoxLayout *fieldsBox = new QVBoxLayout( _fields ); + + + // Grid layout for the edit fields, their labels, some + // explanatory text and the "recurse?" check box. + + QGridLayout *grid = new QGridLayout( 7, // rows + 2, // cols + 4 ); // spacing + fieldsBox->addLayout( grid, 0 ); + fieldsBox->addStretch(); + fieldsBox->addSpacing( 5 ); + + grid->setColStretch( 0, 0 ); // column for field labels - dont' stretch + grid->setColStretch( 1, 1 ); // column for edit fields - stretch as you like + + + // Edit fields for cleanup action title and command line. + + QLabel *label; + _title = new QLineEdit( _fields ); grid->addWidget( _title, 0, 1 ); + _command = new QLineEdit( _fields ); grid->addWidget( _command, 1, 1 ); + label = new QLabel( _title, i18n( "&Title:" ), _fields ); grid->addWidget( label, 0, 0 ); + label = new QLabel( _command, i18n( "&Command Line:" ), _fields ); grid->addWidget( label, 1, 0 ); + + label = new QLabel( i18n( "%p Full Path" ), _fields ); + grid->addWidget( label, 2, 1 ); + + label = new QLabel( i18n( "%n File / Directory Name Without Path" ), _fields ); + grid->addWidget( label, 3, 1 ); + + label = new QLabel( i18n( "%t KDE Trash Directory" ), _fields ); + grid->addWidget( label, 4, 1 ); + + + // "Recurse into subdirs" check box + + _recurse = new QCheckBox( i18n( "&Recurse into Subdirectories" ), _fields ); + grid->addWidget( _recurse, 5, 1 ); + + // "Ask for confirmation" check box + + _askForConfirmation = new QCheckBox( i18n( "&Ask for Confirmation" ), _fields ); + grid->addWidget( _askForConfirmation, 6, 1 ); + + + // The "Works for..." check boxes, grouped together in a button group. + + QButtonGroup *worksFor = new QButtonGroup( i18n( "Works for..." ), _fields ); + QVBoxLayout *worksForBox = new QVBoxLayout( worksFor, 15, 2 ); + fieldsBox->addWidget( worksFor, 0 ); + fieldsBox->addSpacing( 5 ); + fieldsBox->addStretch(); + + _worksForDir = new QCheckBox( i18n( "&Directories" ), worksFor ); + _worksForFile = new QCheckBox( i18n( "&Files" ), worksFor ); + _worksForDotEntry = new QCheckBox( i18n( " P&seudo Entries"), worksFor ); + + worksForBox->addWidget( _worksForDir , 1 ); + worksForBox->addWidget( _worksForFile , 1 ); + worksForBox->addWidget( _worksForDotEntry , 1 ); + + worksForBox->addSpacing( 5 ); + _worksForProtocols = new QComboBox( false, worksFor ); + worksForBox->addWidget( _worksForProtocols, 1 ); + + _worksForProtocols->insertItem( i18n( "On Local Machine Only ('file:/' Protocol)" ) ); + _worksForProtocols->insertItem( i18n( "Network Transparent (ftp, smb, tar, ...)" ) ); + + + // Grid layout for combo boxes at the bottom + + grid = new QGridLayout( 1, // rows + 2, // cols + 4 ); // spacing + + fieldsBox->addLayout( grid, 0 ); + fieldsBox->addSpacing( 5 ); + fieldsBox->addStretch(); + int row = 0; + + + // The "Refresh policy" combo box + + _refreshPolicy = new QComboBox( false, _fields ); + grid->addWidget( _refreshPolicy, row, 1 ); + + label = new QLabel( _refreshPolicy, i18n( "Refresh &Policy:" ), _fields ); + grid->addWidget( label, row++, 0 ); + + + // Caution: The order of those entries must match the order of + // 'enum RefreshPolicy' in 'kcleanup.h'! + // + // I don't like this one bit. The ComboBox should provide something better + // than mere numeric IDs. One of these days I'm going to rewrite this + // thing! + + _refreshPolicy->insertItem( i18n( "No Refresh" ) ); + _refreshPolicy->insertItem( i18n( "Refresh This Entry" ) ); + _refreshPolicy->insertItem( i18n( "Refresh This Entry's Parent" ) ); + _refreshPolicy->insertItem( i18n( "Assume Entry Has Been Deleted" ) ); + + + outerBox->activate(); + setMinimumSize( sizeHint() ); +} + + +void +KCleanupPropertiesPage::enableFields( bool active ) +{ + _fields->setEnabled( active ); +} + + +void +KCleanupPropertiesPage::setFields( const KCleanup * cleanup ) +{ + _id = cleanup->id(); + _enabled->setChecked ( cleanup->enabled() ); + _title->setText ( cleanup->title() ); + _command->setText ( cleanup->command() ); + _recurse->setChecked ( cleanup->recurse() ); + _askForConfirmation->setChecked ( cleanup->askForConfirmation() ); + _worksForDir->setChecked ( cleanup->worksForDir() ); + _worksForFile->setChecked ( cleanup->worksForFile() ); + _worksForDotEntry->setChecked ( cleanup->worksForDotEntry() ); + _worksForProtocols->setCurrentItem ( cleanup->worksLocalOnly() ? 0 : 1 ); + _refreshPolicy->setCurrentItem ( cleanup->refreshPolicy() ); + + enableFields( cleanup->enabled() ); +} + + +KCleanup +KCleanupPropertiesPage::fields() const +{ + KCleanup cleanup( _id ); + + cleanup.setEnabled ( _enabled->isChecked() ); + cleanup.setTitle ( _title->text() ); + cleanup.setCommand ( _command->text() ); + cleanup.setRecurse ( _recurse->isChecked() ); + cleanup.setAskForConfirmation ( _askForConfirmation->isChecked() ); + cleanup.setWorksForDir ( _worksForDir->isChecked() ); + cleanup.setWorksForFile ( _worksForFile->isChecked() ); + cleanup.setWorksLocalOnly ( _worksForProtocols->currentItem() == 0 ? true : false ); + cleanup.setWorksForDotEntry ( _worksForDotEntry->isChecked() ); + cleanup.setRefreshPolicy ( (KCleanup::RefreshPolicy) _refreshPolicy->currentItem() ); + + return cleanup; +} + + +/*--------------------------------------------------------------------------*/ + + +KGeneralSettingsPage::KGeneralSettingsPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ) + : KSettingsPage( dialog, parent ) + , _mainWin( mainWin ) + , _treeView( mainWin->treeView() ) +{ + + // Create layout and widgets. + + QVBoxLayout * layout = new QVBoxLayout( this, 5, // border + dialog->spacingHint() ); // spacing + + QVGroupBox * gbox = new QVGroupBox( i18n( "Directory Reading" ), this ); + layout->addWidget( gbox ); + + _crossFileSystems = new QCheckBox( i18n( "Cross &File System Boundaries" ), gbox ); + _enableLocalDirReader = new QCheckBox( i18n( "Use Optimized &Local Directory Read Methods" ), gbox ); + + connect( _enableLocalDirReader, SIGNAL( stateChanged( int ) ), + this, SLOT ( checkEnabledState() ) ); + + layout->addSpacing( 10 ); + + gbox = new QVGroupBox( i18n( "Animation" ), this ); + layout->addWidget( gbox ); + + _enableToolBarAnimation = new QCheckBox( i18n( "P@cM@n Animation in Tool &Bar" ), gbox ); + _enableTreeViewAnimation = new QCheckBox( i18n( "P@cM@n Animation in Directory &Tree" ), gbox ); +} + + +KGeneralSettingsPage::~KGeneralSettingsPage() +{ + // NOP +} + + +void +KGeneralSettingsPage::apply() +{ + KConfig * config = kapp->config(); + + config->setGroup( "Directory Reading" ); + config->writeEntry( "CrossFileSystems", _crossFileSystems->isChecked() ); + config->writeEntry( "EnableLocalDirReader", _enableLocalDirReader->isChecked() ); + + config->setGroup( "Animation" ); + config->writeEntry( "ToolbarPacMan", _enableToolBarAnimation->isChecked() ); + config->writeEntry( "DirTreePacMan", _enableTreeViewAnimation->isChecked() ); + + _mainWin->initPacMan( _enableToolBarAnimation->isChecked() ); + _treeView->enablePacManAnimation( _enableTreeViewAnimation->isChecked() ); +} + + +void +KGeneralSettingsPage::revertToDefaults() +{ + _crossFileSystems->setChecked( false ); + _enableLocalDirReader->setChecked( true ); + + _enableToolBarAnimation->setChecked( true ); + _enableTreeViewAnimation->setChecked( false ); +} + + +void +KGeneralSettingsPage::setup() +{ + KConfig * config = kapp->config(); + config->setGroup( "Directory Reading" ); + + _crossFileSystems->setChecked ( config->readBoolEntry( "CrossFileSystems" , false) ); + _enableLocalDirReader->setChecked ( config->readBoolEntry( "EnableLocalDirReader" , true ) ); + + _enableToolBarAnimation->setChecked ( _mainWin->pacManEnabled() ); + _enableTreeViewAnimation->setChecked( _treeView->doPacManAnimation() ); + + checkEnabledState(); +} + + +void +KGeneralSettingsPage::checkEnabledState() +{ + _crossFileSystems->setEnabled( _enableLocalDirReader->isChecked() ); +} + + +/*--------------------------------------------------------------------------*/ + + +KTreemapPage::KTreemapPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ) + : KSettingsPage( dialog, parent ) + , _mainWin( mainWin ) +{ + // kdDebug() << k_funcinfo << endl; + + QVBoxLayout * layout = new QVBoxLayout( this, 0, 0 ); // parent, border, spacing + + QVBox * vbox = new QVBox( this ); + vbox->setSpacing( dialog->spacingHint() ); + layout->addWidget( vbox ); + + _squarify = new QCheckBox( i18n( "S&quarify Treemap" ), vbox ); + _doCushionShading = new QCheckBox( i18n( "Use C&ushion Shading" ), vbox ); + + + // Cushion parameters + + QVGroupBox * gbox = new QVGroupBox( i18n( "Cushion Parameters" ), vbox ); + _cushionParams = gbox; + gbox->addSpace( 7 ); + gbox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); + + QLabel * label = new QLabel( i18n( "Ambient &Light" ), gbox ); + QHBox * hbox = new QHBox( gbox ); + _ambientLight = new QSlider ( MinAmbientLight, MaxAmbientLight, 10, // min, max, pageStep + DefaultAmbientLight, Horizontal, hbox ); + _ambientLightSB = new QSpinBox( MinAmbientLight, MaxAmbientLight, 1, // min, max, step + hbox ); + _ambientLightSB->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); + label->setBuddy( _ambientLightSB ); + + gbox->addSpace( 7 ); + label = new QLabel( i18n( "&Height Scale" ), gbox ); + hbox = new QHBox( gbox ); + _heightScalePercent = new QSlider( MinHeightScalePercent, MaxHeightScalePercent, 10, // min, max, pageStep + DefaultHeightScalePercent, Horizontal, hbox ); + _heightScalePercentSB = new QSpinBox( MinHeightScalePercent, MaxHeightScalePercent, 1, // min, max, step + hbox ); + _heightScalePercentSB->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); + label->setBuddy( _heightScalePercentSB ); + + gbox->addSpace( 10 ); + _ensureContrast = new QCheckBox( i18n( "Draw Lines if Lo&w Contrast" ), gbox ); + + + hbox = new QHBox( gbox ); + _forceCushionGrid = new QCheckBox( i18n( "Always Draw &Grid" ), hbox ); + addHStretch( hbox ); + + _cushionGridColorL = new QLabel( " " + i18n( "Gr&id Color: " ), hbox ); + _cushionGridColor = new KColorButton( hbox ); + _cushionGridColorL->setBuddy( _cushionGridColor ); + _cushionGridColorL->setAlignment( AlignRight | AlignVCenter ); + + // addVStretch( vbox ); + + + // Plain treemaps parameters + + _plainTileParams = new QHGroupBox( i18n( "Colors for Plain Treemaps" ), vbox ); + + _plainTileParams->addSpace( 7 ); + label = new QLabel( i18n( "&Files: " ), _plainTileParams ); + _fileFillColor = new KColorButton( _plainTileParams ); + label->setBuddy( _fileFillColor ); + label->setAlignment( AlignRight | AlignVCenter ); + + label = new QLabel( " " + i18n( "&Directories: " ), _plainTileParams ); + _dirFillColor = new KColorButton( _plainTileParams ); + label->setBuddy( _dirFillColor ); + label->setAlignment( AlignRight | AlignVCenter ); + + label = new QLabel( i18n( "Gr&id: " ), _plainTileParams ); + _outlineColor = new KColorButton( _plainTileParams ); + label->setBuddy( _outlineColor ); + label->setAlignment( AlignRight | AlignVCenter ); + + + // Misc + + QWidget * gridBox = new QWidget( vbox ); + QGridLayout * grid = new QGridLayout( gridBox, 2, 3, dialog->spacingHint() ); // rows, cols, spacing + grid->setColStretch( 0, 0 ); // (col, stretch) don't stretch this column + grid->setColStretch( 1, 0 ); // don't stretch + grid->setColStretch( 2, 1 ); // stretch this as you like + + label = new QLabel( i18n( "Hi&ghlight R&ectangle: " ), gridBox ); + _highlightColor = new KColorButton( gridBox ); + label->setBuddy( _highlightColor ); + + grid->addWidget( label, 0, 0 ); + grid->addWidget( _highlightColor, 0, 1 ); + + + label = new QLabel( i18n( "Minim&um Treemap Tile Size: " ), gridBox ); + _minTileSize = new QSpinBox( 0, 30, 1, gridBox ); // min, max, step, parent + label->setBuddy( _minTileSize ); + + grid->addWidget( label, 1, 0 ); + grid->addWidget( _minTileSize, 1, 1 ); + + _autoResize = new QCheckBox( i18n( "Auto-&Resize Treemap" ), vbox ); + + + // Connections + + + connect( _ambientLight, SIGNAL( valueChanged(int) ), + _ambientLightSB, SLOT ( setValue (int) ) ); + + connect( _ambientLightSB, SIGNAL( valueChanged(int) ), + _ambientLight, SLOT ( setValue (int) ) ); + + + connect( _heightScalePercent, SIGNAL( valueChanged(int) ), + _heightScalePercentSB, SLOT ( setValue (int) ) ); + + connect( _heightScalePercentSB, SIGNAL( valueChanged(int) ), + _heightScalePercent, SLOT ( setValue (int) ) ); + + + connect( _doCushionShading, SIGNAL( stateChanged( int ) ), this, SLOT( checkEnabledState() ) ); + connect( _forceCushionGrid, SIGNAL( stateChanged( int ) ), this, SLOT( checkEnabledState() ) ); + + checkEnabledState(); +} + + +KTreemapPage::~KTreemapPage() +{ + // NOP +} + + +void +KTreemapPage::apply() +{ + KConfig * config = kapp->config(); + + config->setGroup( "Treemaps" ); + + config->writeEntry( "Squarify", _squarify->isChecked() ); + config->writeEntry( "CushionShading", _doCushionShading->isChecked() ); + config->writeEntry( "AmbientLight", _ambientLight->value() ); + config->writeEntry( "HeightScaleFactor", _heightScalePercent->value() / 100.0 ); + config->writeEntry( "EnsureContrast", _ensureContrast->isChecked() ); + config->writeEntry( "ForceCushionGrid", _forceCushionGrid->isChecked() ); + config->writeEntry( "MinTileSize", _minTileSize->value() ); + config->writeEntry( "AutoResize", _autoResize->isChecked() ); + config->writeEntry( "CushionGridColor", _cushionGridColor->color() ); + config->writeEntry( "OutlineColor", _outlineColor->color() ); + config->writeEntry( "FileFillColor", _fileFillColor->color() ); + config->writeEntry( "DirFillColor", _dirFillColor->color() ); + config->writeEntry( "HighlightColor", _highlightColor->color() ); + + if ( treemapView() ) + { + treemapView()->readConfig(); + treemapView()->rebuildTreemap(); + } +} + + +void +KTreemapPage::revertToDefaults() +{ + _squarify->setChecked( true ); + _doCushionShading->setChecked( true ); + + _ambientLight->setValue( DefaultAmbientLight ); + _heightScalePercent->setValue( DefaultHeightScalePercent ); + _ensureContrast->setChecked( true ); + _forceCushionGrid->setChecked( false ); + _minTileSize->setValue( DefaultMinTileSize ); + _autoResize->setChecked( true ); + + _cushionGridColor->setColor ( QColor( 0x80, 0x80, 0x80 ) ); + _outlineColor->setColor ( black ); + _fileFillColor->setColor ( QColor( 0xde, 0x8d, 0x53 ) ); + _dirFillColor->setColor ( QColor( 0x10, 0x7d, 0xb4 ) ); + _highlightColor->setColor ( red ); +} + + +void +KTreemapPage::setup() +{ + KConfig * config = kapp->config(); + config->setGroup( "Treemaps" ); + + _squarify->setChecked ( config->readBoolEntry( "Squarify" , true ) ); + _doCushionShading->setChecked ( config->readBoolEntry( "CushionShading" , true ) ); + + _ambientLight->setValue ( config->readNumEntry( "AmbientLight" , DefaultAmbientLight ) ); + _heightScalePercent->setValue( (int) ( 100 * config->readDoubleNumEntry ( "HeightScaleFactor", DefaultHeightScaleFactor ) ) ); + _ensureContrast->setChecked ( config->readBoolEntry( "EnsureContrast" , true ) ); + _forceCushionGrid->setChecked ( config->readBoolEntry( "ForceCushionGrid" , false ) ); + _minTileSize->setValue ( config->readNumEntry ( "MinTileSize" , DefaultMinTileSize ) ); + _autoResize->setChecked ( config->readBoolEntry( "AutoResize" , true ) ); + + _cushionGridColor->setColor ( readColorEntry( config, "CushionGridColor" , QColor( 0x80, 0x80, 0x80 ) ) ); + _outlineColor->setColor ( readColorEntry( config, "OutlineColor" , black ) ); + _fileFillColor->setColor ( readColorEntry( config, "FileFillColor" , QColor( 0xde, 0x8d, 0x53 ) ) ); + _dirFillColor->setColor ( readColorEntry( config, "DirFillColor" , QColor( 0x10, 0x7d, 0xb4 ) ) ); + _highlightColor->setColor ( readColorEntry( config, "HighlightColor" , red ) ); + + _ambientLightSB->setValue( _ambientLight->value() ); + _heightScalePercentSB->setValue( _heightScalePercent->value() ); + + checkEnabledState(); +} + + +void +KTreemapPage::checkEnabledState() +{ + _cushionParams->setEnabled( _doCushionShading->isChecked() ); + _plainTileParams->setEnabled( ! _doCushionShading->isChecked() ); + + if ( _doCushionShading->isChecked() ) + { + _cushionGridColor->setEnabled ( _forceCushionGrid->isChecked() ); + _cushionGridColorL->setEnabled( _forceCushionGrid->isChecked() ); + _ensureContrast->setEnabled ( ! _forceCushionGrid->isChecked() ); + } +} + + +QColor +KTreemapPage::readColorEntry( KConfig * config, const char * entryName, QColor defaultColor ) +{ + return config->readColorEntry( entryName, &defaultColor ); +} + + + +void +addHStretch( QWidget * parent ) +{ + QWidget * stretch = new QWidget( parent ); + stretch->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, // hor + QSizePolicy::Minimum, // vert + 1, // hstretch + 0 ) ); // vstretch +} + + +void +addVStretch( QWidget * parent ) +{ + QWidget * stretch = new QWidget( parent ); + stretch->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, // hor + QSizePolicy::Expanding, // vert + 0, // hstretch + 1 ) ); // vstretch +} + + +// EOF diff --git a/kdirstat/kdirstatsettings.h b/kdirstat/kdirstatsettings.h new file mode 100644 index 0000000..0091f09 --- /dev/null +++ b/kdirstat/kdirstatsettings.h @@ -0,0 +1,744 @@ +/* + * File name: kdirstatsettings.h + * Summary: Settings dialog for KDirStat + * License: GPL - See file COPYING for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KDirStatSettings_h +#define KDirStatSettings_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "kcleanup.h" +#include "kcleanupcollection.h" +#include "kdirstatapp.h" + + +class QCheckBox; +class QComboBox; +class QHGroupBox; +class QLabel; +class QLineEdit; +class QRadioButton; +class QSlider; +class QSpinBox; +class QVGroupBox; +class QWidget; + +class KColorButton; + + +#define KDirStatSettingsMaxColorButton 12 + + +namespace KDirStat +{ + class KCleanupListBox; + class KCleanupPropertiesPage; + class KDirTreeView; + class KTreemapView; + + + /** + * Settings dialog for KDirStat + * + * @short Settings dialog for KDirStat + **/ + class KSettingsDialog: public KDialogBase + { + Q_OBJECT + + public: + + /** + * Constructor. + * + * Notice there is no parent widget passed but the application's main + * window so its functions can be accessed. The parent of this widget + * is always 0 since this is a dialog. + **/ + + KSettingsDialog( KDirStatApp * mainWin ); + + /** + * Destructor. + **/ + virtual ~KSettingsDialog(); + + + /** + * Overwritten from @ref QDialog() to get any chance to set up the + * dialog contents when the dialog gets shown - every time, not just at + * program startup when the settings dialog is created (!). + * + * QTabDialog used to have 'aboutToShow()' for a good reason, but the + * creators of @ref KDialogBase in their infinite wisdom chose not to + * include anything similar. How is that supposed to work, anyway? + * Everything I saw in any other KDE sources looked to me like ugly + * hacks to work around this. Am I really supposed to destroy my + * settings dialog and create a new one every time it pops up? This can + * certainly not be the way to go. + * + * This overwritten show() method sends that @ref aboutToShow() signal + * before calling the parent class show() method. + **/ + virtual void show(); + + + public slots: + + /** + * Reimplemented from @ref KDialogBase to ask for confirmation. + * Emits signal @ref defaultClicked() when the user confirms. + **/ + virtual void slotDefault(); + + /** + * Reimplemented from @ref KDialogBase to set the appropriate help + * topic prior to invoking online help. + **/ + virtual void slotHelp(); + + + signals: + + /** + * Emitted when (you might have guessed it) the dialog is about to be + * shown. Connect this to slots that fill the individual dialog pages' + * widgets contents (input fields etc.) + **/ + void aboutToShow(); + + protected: + + KDirStatApp * _mainWin; + int _cleanupsPageIndex; + int _treeColorsPageIndex; + int _treemapPageIndex; + int _generalSettingsPageIndex; + + }; // class KSettingsDialog + + + + /** + * Abstract base class for all settings pages. Contains stubs for methods + * that all settings pages have in common: setup(), apply(), + * revertToDefaults(). + * + * Note: This class contains pure virtuals - it cannot be + * instantiated. Rather, derive your own classes from this one. + **/ + class KSettingsPage: public QWidget + { + Q_OBJECT + + public: + + /** + * Constructor. + * + * Sets up standard connections to the methods defined in this class, + * e.g., apply(), setup(), revertToDefaults(). + **/ + KSettingsPage( KSettingsDialog * dialog, + QWidget * parent ); + + /** + * Destructor. + **/ + virtual ~KSettingsPage(); + + + public slots: + + /** + * Apply the changes. + * + * Derived classes need to reimplement this method. + **/ + virtual void apply() = 0; + + /** + * Revert all values to their defaults. + * + * Derived classes need to reimplement this method. + **/ + virtual void revertToDefaults() = 0; + + /** + * Set up all fields prior to displaying the dialog. + * + * Derived classes need to reimplement this method. + **/ + virtual void setup() = 0; + + + public: + + /** + * Returns the page index of this page. + * This seems to be the only way to find out which settings page is in + * the foreground for a @ref KDialogBase page. + **/ + int pageIndex() { return _pageIndex; } + + protected: + + int _pageIndex; + + }; // class KSettingsPage + + + + /** + * Settings tab page for the tree colors. + * + * Uses a vertical slider on the left side and a column of color + * selection buttons on the right side. The slider enables/disables + * the color buttons from top to bottom (at least one button is always + * enabled). Each button represents the percentage fill color of one + * directory level within the tree. When the tree widget runs out of + * colors (i.e. there are more directory levels than different + * colors), it will wrap around to the first color. + * + * @short settings page for tree colors + * @author Stefan Hundhammer + **/ + class KTreeColorsPage: public KSettingsPage + { + Q_OBJECT + + public: + + /** + * Constructor + **/ + KTreeColorsPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ); + + /** + * Destructor + **/ + virtual ~KTreeColorsPage(); + + + public slots: + + /** + * Apply the changes. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void apply(); + + /** + * Revert all values to their defaults. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void revertToDefaults(); + + /** + * Set up all fields prior to displaying the dialog. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void setup(); + + + protected slots: + + /** + * Enable all colors up to color no. 'maxColors'. + **/ + void enableColors( int maxColors ); + + + protected: + + + KDirStatApp * _mainWin; + KDirTreeView * _treeView; + QSlider * _slider; + KColorButton * _colorButton [ KDirStatSettingsMaxColorButton ]; + QLabel * _colorLabel [ KDirStatSettingsMaxColorButton ]; + + int _maxButtons; + + }; // class KTreeColorsPage + + + + /** + * Settings tab page for cleanup actions. + * + * Uses a KCleanupListBox for selection of one cleanup action and a + * KCleanupPropertiesPage for editing this cleanup action's + * properties. This class handles just the switching between the individual + * cleanups. It copies the cleanup actions inserted and works with the + * copies only until it is requested to save the changes or revert all + * values to their defaults. + * + * @short settings page for cleanup actions + **/ + class KCleanupPage: public KSettingsPage + { + Q_OBJECT + + public: + + /** + * Constructor + **/ + KCleanupPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ); + + /** + * Destructor + **/ + virtual ~KCleanupPage(); + + /** + * Insert an entry for a cleanup action. This is the original value + * that will be changed only when receiving the apply() or + * defaultValues() signals. + **/ + void insert( KCleanup *cleanup ); + + /** + * Import all cleanup actions from the originals (from the main + * window) to internal working copies. + **/ + void importCleanups(); + + /** + * Copy the internal working copies of the cleanup actions back to + * the main window's originals. Take care of pending changes within + * the current properties page's fields prior to that. + **/ + void exportCleanups(); + + + public slots: + + /** + * Apply the changes. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void apply(); + + /** + * Revert all values to their defaults. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void revertToDefaults(); + + /** + * Set up all fields prior to displaying the dialog. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void setup(); + + /** + * Switch back and forth between all the cleanup actions very much + * like in a tab dialog: Exchange field contents of the cleanup + * properties page with the cleanup specified. Store the old + * properties page contents in the working copies of the cleanups. + **/ + void changeCleanup( KCleanup * cleanup ); + + + protected: + + /** + * Retrieve any pending changes from the properties page and store + * them in the cleanup specified. + **/ + void storeProps( KCleanup * cleanup ); + + + // + // Data members + // + + KCleanupListBox * _listBox; + KCleanupPropertiesPage * _props; + KDirStatApp * _mainWin; + + KCleanupCollection _workCleanupCollection; + KCleanup * _currentCleanup; + + }; // class KCleanupPage + + + + /** + * List box for cleanup actions. + * + * This is meant as a substitute for a tabbed dialog inside the tabbed + * dialog which would be much too wide and possibly confusing. Plus, this + * list box is supposed to take care of its own geometry - the normal + * dumbass list box obviously cannot do that. It just uses some random + * geometry, relying on scroll bars for everything else. But in this + * special case we want all items to be visible at all times without scroll + * bars. + * + * @short cleanup list box + **/ + class KCleanupListBox: public QListBox + { + Q_OBJECT + + public: + + /** + * Constructor. + **/ + KCleanupListBox( QWidget * parent = 0 ); + + /** + * Destructor. + **/ + virtual ~KCleanupListBox() {}; + + /** + * Reimplemented so we can make sure all items are visible at all times + * without scrolling. In fact, we never want to see a scroll bar with + * this kind of list box. + **/ + virtual QSize sizeHint() const; + + /** + * Insert an entry for a cleanup action into the list box. Uses the + * cleanup action's internally stored title for display. + **/ + void insert( KCleanup * cleanup ); + + /** + * Returns the currently selected cleanup of 0 if nothing is selected. + **/ + KCleanup * selection() { return _selection; } + + /** + * Update the list item's text that corresponds to 'cleanup' - the user + * may have entered a new cleanup name. '0' means "check all items". + **/ + void updateTitle( KCleanup * cleanup = 0 ); + + + signals: + + /** + * Emitted when the user selects a list item, i.e. a cleanup action. + **/ + void selectCleanup( KCleanup * cleanup ); + + + protected slots: + + /** + * Select an item. + **/ + void selectCleanup( QListBoxItem * item ); + + + protected: + + KCleanup * _selection; + + }; // class KCleanupListBox + + + + /** + * List box item for a KCleanupListBox. + **/ + class KCleanupListBoxItem: public QListBoxText + { + public: + + /** + * Constructor. + **/ + KCleanupListBoxItem( KCleanupListBox * listBox, + KCleanup * cleanup ); + + /** + * Returns the corresponding cleanup. + **/ + KCleanup * cleanup() { return _cleanup; } + + /** + * Update the list box display with the cleanup's name which may have + * changed - the user may have entered a new one. + **/ + void updateTitle(); + + + protected: + + + // Data members + + KCleanup * _cleanup; + + }; // class KCleanupListBoxItem + + + + /** + * Properties page for one cleanup action. + **/ + class KCleanupPropertiesPage: public QWidget + { + Q_OBJECT + + public: + + /** + * Constructor + **/ + KCleanupPropertiesPage( QWidget * parent, + KDirStatApp * mainWin ); + + /** + * Retrieve the page's fields' values and store them in the cleanup + * action. + **/ + KCleanup fields( void ) const; + + + public slots: + + /** + * Set the page's fields' values with the cleanup action's + * contents. + **/ + void setFields( const KCleanup * cleanup ); + + /** + * Enable / disable all of the properties page's fields except the + * 'enabled' check box. + **/ + void enableFields( bool active ); + + + protected: + + QString _id; + QCheckBox * _enabled; + QWidget * _fields; + QLineEdit * _title; + QLineEdit * _command; + QCheckBox * _recurse; + QCheckBox * _askForConfirmation; + QCheckBox * _worksForDir; + QCheckBox * _worksForFile; + QCheckBox * _worksForDotEntry; + QComboBox * _worksForProtocols; + QComboBox * _refreshPolicy; + + KDirStatApp * _mainWin; + + }; // class KCleanupPropertiesPage + + + + /** + * Settings tab page for general/misc settings. + **/ + class KGeneralSettingsPage: public KSettingsPage + { + Q_OBJECT + + public: + + /** + * Constructor + **/ + KGeneralSettingsPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ); + + /** + * Destructor + **/ + virtual ~KGeneralSettingsPage(); + + + public slots: + + /** + * Apply the changes. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void apply(); + + /** + * Revert all values to their defaults. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void revertToDefaults(); + + /** + * Set up all fields prior to displaying the dialog. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void setup(); + + /** + * Check the enabled state of all widgets depending on the value of + * other widgets. + **/ + void checkEnabledState(); + + + protected: + + // Data members + + KDirStatApp * _mainWin; + KDirTreeView * _treeView; + + QCheckBox * _crossFileSystems; + QCheckBox * _enableLocalDirReader; + + QCheckBox * _enableToolBarAnimation; + QCheckBox * _enableTreeViewAnimation; + + }; // class KGeneralSettingsPage + + + + /** + * Settings tab page for treemap settings. + **/ + class KTreemapPage: public KSettingsPage + { + Q_OBJECT + + public: + + /** + * Constructor + **/ + KTreemapPage( KSettingsDialog * dialog, + QWidget * parent, + KDirStatApp * mainWin ); + + /** + * Destructor + **/ + virtual ~KTreemapPage(); + + + public slots: + + /** + * Apply the changes. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void apply(); + + /** + * Revert all values to their defaults. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void revertToDefaults(); + + /** + * Set up all fields prior to displaying the dialog. + * + * Inherited from @ref KSettingsPage. + **/ + virtual void setup(); + + /** + * Check the enabled state of all widgets depending on the value of + * other widgets. + **/ + void checkEnabledState(); + + + protected: + + /** + * Returns the main window's current treemap view or 0 if there is + * none. Don't cache this value, it changes frequently! + **/ + KTreemapView * treemapView() const { return _mainWin->treemapView(); } + + /** + * Convenience method to read a color from 'config'. + **/ + QColor readColorEntry( KConfig * config, + const char * entryName, + QColor defaultColor ); + + // Data members + + KDirStatApp * _mainWin; + + + // Widgets + + QCheckBox * _squarify; + QCheckBox * _doCushionShading; + QVGroupBox * _cushionParams; + QSlider * _ambientLight; + QSpinBox * _ambientLightSB; + QSlider * _heightScalePercent; + QSpinBox * _heightScalePercentSB; + QCheckBox * _ensureContrast; + QCheckBox * _forceCushionGrid; + KColorButton * _cushionGridColor; + QLabel * _cushionGridColorL; + QHGroupBox * _plainTileParams; + KColorButton * _fileFillColor; + KColorButton * _dirFillColor; + KColorButton * _outlineColor; + KColorButton * _highlightColor; + QSpinBox * _minTileSize; + QCheckBox * _autoResize; + + }; // class KTreemapPage + +} // namespace KDirStat + + +/** + * Add a horizontal stretch widget to take all excess space. + **/ +void addHStretch( QWidget * parent ); + +/** + * Add a vertical stretch widget to take all excess space. + **/ +void addVStretch( QWidget * parent ); + + + +#endif // ifndef KDirStatSettings_h + + +// EOF diff --git a/kdirstat/kdirstatui.rc b/kdirstat/kdirstatui.rc new file mode 100644 index 0000000..7234719 --- /dev/null +++ b/kdirstat/kdirstatui.rc @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + &File + + + + + + + + + + + + + Clean &Up + + + + + + + + + + + + + + + + + + + + + + + + &Treemap + + + + + + + + + + + + &Settings + + + + + + + &Report + + + + + &Help + + + + + + + + + + + + + + Main Toolbar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kdirstat/kdirtree.cpp b/kdirstat/kdirtree.cpp new file mode 100644 index 0000000..7bf972a --- /dev/null +++ b/kdirstat/kdirtree.cpp @@ -0,0 +1,1636 @@ +/* + * File name: kdirtree.cpp + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2005-01-07 + */ + + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include "kdirtree.h" +#include "kdirtreeiterators.h" +#include "kdirtreeview.h" +#include "kdirsaver.h" +#include "kio/job.h" +#include "kio/netaccess.h" + +#define HAVE_STUPID_COMPILER 0 + + +using namespace KDirStat; + + +KFileInfo::KFileInfo( KDirTree * tree, + KDirInfo * parent, + const char * name ) + : _parent( parent ) + , _next( 0 ) + , _tree( tree ) +{ + _isLocalFile = true; + _isSparseFile = false; + _name = name ? name : ""; + _device = 0; + _mode = 0; + _links = 0; + _size = 0; + _blocks = 0; + _mtime = 0; +} + + +KFileInfo::KFileInfo( const QString & filenameWithoutPath, + struct stat * statInfo, + KDirTree * tree, + KDirInfo * parent ) + : _parent( parent ) + , _next( 0 ) + , _tree( tree ) +{ + CHECK_PTR( statInfo ); + + _isLocalFile = true; + _name = filenameWithoutPath; + + _device = statInfo->st_dev; + _mode = statInfo->st_mode; + _links = statInfo->st_nlink; + _mtime = statInfo->st_mtime; + + if ( isSpecial() ) + { + _size = 0; + _blocks = 0; + _isSparseFile = false; + } + else + { + _size = statInfo->st_size; + _blocks = statInfo->st_blocks; + _isSparseFile = isFile() && ( allocatedSize() < _size ); + + if ( _isSparseFile ) + { + kdDebug() << "Found sparse file: " << this + << " Byte size: " << formatSize( byteSize() ) + << " Allocated: " << formatSize( allocatedSize() ) + << endl; + } + +#if 0 + if ( isFile() && _links > 1 ) + { + kdDebug() << _links << " hard links: " << this << endl; + } +#endif + } + +#if 0 +#warning Debug mode: Huge sizes + _size <<= 10; +#endif +} + + +KFileInfo::KFileInfo( const KFileItem * fileItem, + KDirTree * tree, + KDirInfo * parent ) + : _parent( parent ) + , _next( 0 ) + , _tree( tree ) +{ + CHECK_PTR( fileItem ); + + _isLocalFile = fileItem->isLocalFile(); + _name = parent ? fileItem->name() : fileItem->url().url(); + _device = 0; + _mode = fileItem->mode(); + _links = 1; + + + if ( isSpecial() ) + { + _size = 0; + _blocks = 0; + _isSparseFile = false; + } + else + { + _size = fileItem->size(); + + // Since KFileItem does not return any information about allocated disk + // blocks, calculate that information artificially so callers don't + // need to bother with special cases depending on how this object was + // constructed. + + _blocks = _size / blockSize(); + + if ( ( _size % blockSize() ) > 0 ) + _blocks++; + + // There is no way to find out via KFileInfo if this is a sparse file. + _isSparseFile = false; + } + + _mtime = fileItem->time( KIO::UDS_MODIFICATION_TIME ); +} + + +KFileInfo::~KFileInfo() +{ + // NOP + + + /** + * The destructor should also take care about unlinking this object from + * its parent's children list, but regrettably that just doesn't work: At + * this point (within the destructor) parts of the object are already + * destroyed, e.g., the virtual table - virtual methods don't work any + * more. Thus, somebody from outside must call deletingChild() just prior + * to the actual "delete". + * + * This sucks, but it's the C++ standard. + **/ +} + + +KFileSize +KFileInfo::allocatedSize() const +{ + return blocks() * blockSize(); +} + + +KFileSize +KFileInfo::size() const +{ + KFileSize sz = _isSparseFile ? allocatedSize() : _size; + + if ( _links > 1 ) + sz /= _links; + + return sz; +} + + +QString +KFileInfo::url() const +{ + if ( _parent ) + { + QString parentUrl = _parent->url(); + + if ( isDotEntry() ) // don't append "/." for dot entries + return parentUrl; + + if ( parentUrl == "/" ) // avoid duplicating slashes + return parentUrl + _name; + else + return parentUrl + "/" + _name; + } + else + return _name; +} + + +QString +KFileInfo::debugUrl() const +{ + return url() + ( isDotEntry() ? "/" : "" ); +} + + +QString +KFileInfo::urlPart( int targetLevel ) const +{ + int level = treeLevel(); // Cache this - it's expensive! + + if ( level < targetLevel ) + { + kdError() << k_funcinfo << "URL level " << targetLevel + << " requested, this is level " << level << endl; + return ""; + } + + const KFileInfo *item = this; + + while ( level > targetLevel ) + { + level--; + item = item->parent(); + } + + return item->name(); +} + + +int +KFileInfo::treeLevel() const +{ + int level = 0; + KFileInfo * parent = _parent; + + while ( parent ) + { + level++; + parent = parent->parent(); + } + + return level; + + + if ( _parent ) + return _parent->treeLevel() + 1; + else + return 0; +} + + +bool +KFileInfo::hasChildren() const +{ + return firstChild() || dotEntry(); +} + + +bool +KFileInfo::isInSubtree( const KFileInfo *subtree ) const +{ + const KFileInfo * ancestor = this; + + while ( ancestor ) + { + if ( ancestor == subtree ) + return true; + + ancestor = ancestor->parent(); + } + + return false; +} + + +KFileInfo * +KFileInfo::locate( QString url, bool findDotEntries ) +{ + if ( ! url.startsWith( _name ) ) + return 0; + else // URL starts with this node's name + { + url.remove( 0, _name.length() ); // Remove leading name of this node + + if ( url.length() == 0 ) // Nothing left? + return this; // Hey! That's us! + + if ( url.startsWith( "/" ) ) // If the next thing a path delimiter, + url.remove( 0, 1 ); // remove that leading delimiter. + else // No path delimiter at the beginning + { + if ( _name.right(1) != "/" && // and this is not the root directory + ! isDotEntry() ) // or a dot entry: + return 0; // This can't be any of our children. + } + + + // Search all children + + KFileInfo *child = firstChild(); + + while ( child ) + { + KFileInfo *foundChild = child->locate( url, findDotEntries ); + + if ( foundChild ) + return foundChild; + else + child = child->next(); + } + + + // Special case: The dot entry is requested. + + if ( findDotEntries && dotEntry() && url == "" ) + return dotEntry(); + + // Search the dot entry if there is one - but only if there is no more + // path delimiter left in the URL. The dot entry contains files only, + // and their names may not contain the path delimiter, nor can they + // have children. This check is not strictly necessary, but it may + // speed up things a bit if we don't search the non-directory children + // if the rest of the URL consists of several pathname components. + + if ( dotEntry() && + url.find ( "/" ) < 0 ) // No (more) "/" in this URL + { + return dotEntry()->locate( url, findDotEntries ); + } + } + + return 0; +} + + + + + + +KDirInfo::KDirInfo( KDirTree * tree, + KDirInfo * parent, + bool asDotEntry ) + : KFileInfo( tree, parent ) +{ + init(); + + if ( asDotEntry ) + { + _isDotEntry = true; + _dotEntry = 0; + _name = "."; + } + else + { + _isDotEntry = false; + _dotEntry = new KDirInfo( tree, this, true ); + } +} + + +KDirInfo::KDirInfo( const QString & filenameWithoutPath, + struct stat * statInfo, + KDirTree * tree, + KDirInfo * parent ) + : KFileInfo( filenameWithoutPath, + statInfo, + tree, + parent ) +{ + init(); + _dotEntry = new KDirInfo( tree, this, true ); +} + + +KDirInfo::KDirInfo( const KFileItem * fileItem, + KDirTree * tree, + KDirInfo * parent ) + : KFileInfo( fileItem, + tree, + parent ) +{ + init(); + _dotEntry = new KDirInfo( tree, this, true ); +} + + +void +KDirInfo::init() +{ + _isDotEntry = false; + _pendingReadJobs = 0; + _dotEntry = 0; + _firstChild = 0; + _totalSize = _size; + _totalBlocks = _blocks; + _totalItems = 0; + _totalSubDirs = 0; + _totalFiles = 0; + _latestMtime = _mtime; + _isMountPoint = false; + _summaryDirty = false; + _beingDestroyed = false; + _readState = KDirQueued; +} + + +KDirInfo::~KDirInfo() +{ + _beingDestroyed = true; + KFileInfo *child = _firstChild; + + + // Recursively delete all children. + + while ( child ) + { + KFileInfo * nextChild = child->next(); + delete child; + child = nextChild; + } + + + // Delete the dot entry. + + if ( _dotEntry ) + { + delete _dotEntry; + } +} + + +void +KDirInfo::recalc() +{ + // kdDebug() << k_funcinfo << this << endl; + + _totalSize = _size; + _totalBlocks = _blocks; + _totalItems = 0; + _totalSubDirs = 0; + _totalFiles = 0; + _latestMtime = _mtime; + + KFileInfoIterator it( this, KDotEntryAsSubDir ); + + while ( *it ) + { + _totalSize += (*it)->totalSize(); + _totalBlocks += (*it)->totalBlocks(); + _totalItems += (*it)->totalItems() + 1; + _totalSubDirs += (*it)->totalSubDirs(); + _totalFiles += (*it)->totalFiles(); + + if ( (*it)->isDir() ) + _totalSubDirs++; + + if ( (*it)->isFile() ) + _totalFiles++; + + time_t childLatestMtime = (*it)->latestMtime(); + + if ( childLatestMtime > _latestMtime ) + _latestMtime = childLatestMtime; + + ++it; + } + + _summaryDirty = false; +} + + +void +KDirInfo::setMountPoint( bool isMountPoint ) +{ + _isMountPoint = isMountPoint; +} + + +KFileSize +KDirInfo::totalSize() +{ + if ( _summaryDirty ) + recalc(); + + return _totalSize; +} + + +KFileSize +KDirInfo::totalBlocks() +{ + if ( _summaryDirty ) + recalc(); + + return _totalBlocks; +} + + +int +KDirInfo::totalItems() +{ + if ( _summaryDirty ) + recalc(); + + return _totalItems; +} + + +int +KDirInfo::totalSubDirs() +{ + if ( _summaryDirty ) + recalc(); + + return _totalSubDirs; +} + + +int +KDirInfo::totalFiles() +{ + if ( _summaryDirty ) + recalc(); + + return _totalFiles; +} + + +time_t +KDirInfo::latestMtime() +{ + if ( _summaryDirty ) + recalc(); + + return _latestMtime; +} + + +bool +KDirInfo::isFinished() +{ + return ! isBusy(); +} + + +void KDirInfo::setReadState( KDirReadState newReadState ) +{ + // "aborted" has higher priority than "finished" + + if ( _readState == KDirAborted && newReadState == KDirFinished ) + return; + + _readState = newReadState; +} + + +bool +KDirInfo::isBusy() +{ + if ( _pendingReadJobs > 0 && _readState != KDirAborted ) + return true; + + if ( readState() == KDirReading || + readState() == KDirQueued ) + return true; + + return false; +} + + +void +KDirInfo::insertChild( KFileInfo *newChild ) +{ + CHECK_PTR( newChild ); + + if ( newChild->isDir() || _dotEntry == 0 || _isDotEntry ) + { + /** + * Only directories are stored directly in pure directory nodes - + * unless something went terribly wrong, e.g. there is no dot entry to use. + * If this is a dot entry, store everything it gets directly within it. + * + * In any of those cases, insert the new child in the children list. + * + * We don't bother with this list's order - it's explicitly declared to + * be unordered, so be warned! We simply insert this new child at the + * list head since this operation can be performed in constant time + * without the need for any additional lastChild etc. pointers or - + * even worse - seeking the correct place for insertion first. This is + * none of our business; the corresponding "view" object for this tree + * will take care of such niceties. + **/ + newChild->setNext( _firstChild ); + _firstChild = newChild; + newChild->setParent( this ); // make sure the parent pointer is correct + + childAdded( newChild ); // update summaries + } + else + { + /* + * If the child is not a directory, don't store it directly here - use + * this entry's dot entry instead. + */ + _dotEntry->insertChild( newChild ); + } +} + + +void +KDirInfo::childAdded( KFileInfo *newChild ) +{ + if ( ! _summaryDirty ) + { + _totalSize += newChild->size(); + _totalBlocks += newChild->blocks(); + _totalItems++; + + if ( newChild->isDir() ) + _totalSubDirs++; + + if ( newChild->isFile() ) + _totalFiles++; + + if ( newChild->mtime() > _latestMtime ) + _latestMtime = newChild->mtime(); + } + else + { + // NOP + + /* + * Don't bother updating the summary fields if the summary is dirty + * (i.e. outdated) anyway: As soon as anybody wants to know some exact + * value a complete recalculation of the entire subtree will be + * triggered. On the other hand, if nobody wants to know (which is very + * likely) we can save this effort. + */ + } + + if ( _parent ) + _parent->childAdded( newChild ); +} + + +void +KDirInfo::deletingChild( KFileInfo *deletedChild ) +{ + /** + * When children are deleted, things go downhill: Marking the summary + * fields as dirty (i.e. outdated) is the only thing that can be done here. + * + * The accumulated sizes could be updated (by subtracting this deleted + * child's values from them), but the latest mtime definitely has to be + * recalculated: The child now being deleted might just be the one with the + * latest mtime, and figuring out the second-latest cannot easily be + * done. So we merely mark the summary as dirty and wait until a recalc() + * will be triggered from outside - which might as well never happen when + * nobody wants to know some summary field anyway. + **/ + + _summaryDirty = true; + + if ( _parent ) + _parent->deletingChild( deletedChild ); + + if ( ! _beingDestroyed && deletedChild->parent() == this ) + { + /** + * Unlink the child from the children's list - but only if this doesn't + * happen recursively in the destructor of this object: No use + * bothering about the validity of the children's list if this will all + * be history anyway in a moment. + **/ + + unlinkChild( deletedChild ); + } +} + + +void +KDirInfo::unlinkChild( KFileInfo *deletedChild ) +{ + if ( deletedChild->parent() != this ) + { + kdError() << deletedChild << " is not a child of " << this + << " - cannot unlink from children list!" << endl; + return; + } + + if ( deletedChild == _firstChild ) + { + // kdDebug() << "Unlinking first child " << deletedChild << endl; + _firstChild = deletedChild->next(); + return; + } + + KFileInfo *child = firstChild(); + + while ( child ) + { + if ( child->next() == deletedChild ) + { + // kdDebug() << "Unlinking " << deletedChild << endl; + child->setNext( deletedChild->next() ); + + return; + } + + child = child->next(); + } + + kdError() << "Couldn't unlink " << deletedChild << " from " + << this << " children list" << endl; +} + + +void +KDirInfo::readJobAdded() +{ + _pendingReadJobs++; + + if ( _parent ) + _parent->readJobAdded(); +} + + +void +KDirInfo::readJobFinished() +{ + _pendingReadJobs--; + + if ( _parent ) + _parent->readJobFinished(); +} + + +void +KDirInfo::readJobAborted() +{ + _readState = KDirAborted; + + if ( _parent ) + _parent->readJobAborted(); +} + + +void +KDirInfo::finalizeLocal() +{ + cleanupDotEntries(); +} + + +KDirReadState +KDirInfo::readState() const +{ + if ( _isDotEntry && _parent ) + return _parent->readState(); + else + return _readState; +} + + +void +KDirInfo::cleanupDotEntries() +{ + if ( ! _dotEntry || _isDotEntry ) + return; + + // Reparent dot entry children if there are no subdirectories on this level + + if ( ! _firstChild ) + { + // kdDebug() << "Removing solo dot entry " << this << " " << endl; + + KFileInfo *child = _dotEntry->firstChild(); + _firstChild = child; // Move the entire children chain here. + _dotEntry->setFirstChild( 0 ); // _dotEntry will be deleted below. + + while ( child ) + { + child->setParent( this ); + child = child->next(); + } + } + + + // Delete dot entries without any children + + if ( ! _dotEntry->firstChild() ) + { + // kdDebug() << "Removing empty dot entry " << this << endl; + delete _dotEntry; + _dotEntry = 0; + } +} + + + + + + +KDirReadJob::KDirReadJob( KDirTree * tree, + KDirInfo * dir ) + : _tree( tree ) + , _dir( dir ) +{ + _dir->readJobAdded(); +} + + +KDirReadJob::~KDirReadJob() +{ + _dir->readJobFinished(); +} + + +void +KDirReadJob::childAdded( KFileInfo *newChild ) +{ + _tree->childAddedNotify( newChild ); +} + + +void +KDirReadJob::deletingChild( KFileInfo *deletedChild ) +{ + _tree->deletingChildNotify( deletedChild ); +} + + + + + + +KLocalDirReadJob::KLocalDirReadJob( KDirTree * tree, + KDirInfo * dir ) + : KDirReadJob( tree, dir ) + , _diskDir( 0 ) +{ +} + + +KLocalDirReadJob::~KLocalDirReadJob() +{ +} + + +void +KLocalDirReadJob::startReading() +{ + struct dirent * entry; + struct stat statInfo; + QString dirName = _dir->url(); + + if ( ( _diskDir = opendir( dirName ) ) ) + { + _tree->sendProgressInfo( dirName ); + _dir->setReadState( KDirReading ); + + while ( ( entry = readdir( _diskDir ) ) ) + { + QString entryName = entry->d_name; + + if ( entryName != "." && + entryName != ".." ) + { + QString fullName = dirName + "/" + entryName; + + if ( lstat( fullName, &statInfo ) == 0 ) // lstat() OK + { + if ( S_ISDIR( statInfo.st_mode ) ) // directory child? + { + KDirInfo *subDir = new KDirInfo( entryName, &statInfo, _tree, _dir ); + _dir->insertChild( subDir ); + childAdded( subDir ); + + if ( subDir->dotEntry() ) + childAdded( subDir->dotEntry() ); + + if ( _dir->device() == subDir->device() ) // normal case + { + _tree->addJob( new KLocalDirReadJob( _tree, subDir ) ); + } + else // The subdirectory we just found is a mount point. + { + // kdDebug() << "Found mount point " << subDir << endl; + subDir->setMountPoint(); + + if ( _tree->crossFileSystems() ) + { + _tree->addJob( new KLocalDirReadJob( _tree, subDir ) ); + } + else + { + subDir->setReadState( KDirOnRequestOnly ); + _tree->sendFinalizeLocal( subDir ); + subDir->finalizeLocal(); + } + } + } + else // non-directory child + { + KFileInfo *child = new KFileInfo( entryName, &statInfo, _tree, _dir ); + _dir->insertChild( child ); + childAdded( child ); + } + } + else // lstat() error + { + // kdWarning() << "lstat(" << fullName << ") failed: " << strerror( errno ) << endl; + + /* + * Not much we can do when lstat() didn't work; let's at + * least create an (almost empty) entry as a placeholder. + */ + KDirInfo *child = new KDirInfo( _tree, _dir, entry->d_name ); + child->setReadState( KDirError ); + _dir->insertChild( child ); + childAdded( child ); + } + } + } + + closedir( _diskDir ); + // kdDebug() << "Finished reading " << _dir << endl; + _dir->setReadState( KDirFinished ); + _tree->sendFinalizeLocal( _dir ); + _dir->finalizeLocal(); + } + else + { + _dir->setReadState( KDirError ); + _tree->sendFinalizeLocal( _dir ); + _dir->finalizeLocal(); + // kdWarning() << k_funcinfo << "opendir(" << dirName << ") failed" << endl; + // opendir() doesn't set 'errno' according to POSIX :-( + } + + _tree->jobFinishedNotify( this ); + // Don't add anything after _tree->jobFinishedNotify() + // since this deletes this job! +} + + + +KFileInfo * +KLocalDirReadJob::stat( const KURL & url, + KDirTree * tree, + KDirInfo * parent ) +{ + struct stat statInfo; + + if ( lstat( url.path(), &statInfo ) == 0 ) // lstat() OK + { + QString name = parent ? url.filename() : url.path(); + + if ( S_ISDIR( statInfo.st_mode ) ) // directory? + { + KDirInfo * dir = new KDirInfo( name, &statInfo, tree, parent ); + + if ( dir && parent && dir->device() != parent->device() ) + dir->setMountPoint(); + + return dir; + } + else // no directory + return new KFileInfo( name, &statInfo, tree, parent ); + } + else // lstat() failed + return 0; +} + + + + + + +KAnyDirReadJob::KAnyDirReadJob( KDirTree * tree, + KDirInfo * dir ) + : QObject() + , KDirReadJob( tree, dir ) +{ + _job = 0; +} + + +KAnyDirReadJob::~KAnyDirReadJob() +{ +#if 0 + if ( _job ) + _job->kill( true ); // quietly +#endif +} + + +void +KAnyDirReadJob::startReading() +{ + KURL url( _dir->url() ); + + if ( ! url.isValid() ) + { + kdWarning() << k_funcinfo << "URL malformed: " << _dir->url() << endl; + } + + _job = KIO::listDir( url, + false ); // showProgressInfo + + connect( _job, SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList& ) ), + this, SLOT ( entries( KIO::Job *, const KIO::UDSEntryList& ) ) ); + + connect( _job, SIGNAL( result ( KIO::Job * ) ), + this, SLOT ( finished( KIO::Job * ) ) ); + + connect( _job, SIGNAL( canceled( KIO::Job * ) ), + this, SLOT ( finished( KIO::Job * ) ) ); +} + + +void +KAnyDirReadJob::entries ( KIO::Job * job, + const KIO::UDSEntryList & entryList ) +{ + NOT_USED( job ); + KURL url( _dir->url() ); // Cache this - it's expensive! + + if ( ! url.isValid() ) + { + kdWarning() << k_funcinfo << "URL malformed: " << _dir->url() << endl; + } + + KIO::UDSEntryListConstIterator it = entryList.begin(); + + while ( it != entryList.end() ) + { + KFileItem entry( *it, + url, + true, // determineMimeTypeOnDemand + true ); // URL is parent directory + + if ( entry.name() != "." && + entry.name() != ".." ) + { + // kdDebug() << "Found " << entry.url().url() << endl; + + if ( entry.isDir() && // Directory child + ! entry.isLink() ) // and not a symlink? + { + KDirInfo *subDir = new KDirInfo( &entry, _tree, _dir ); + _dir->insertChild( subDir ); + childAdded( subDir ); + + if ( subDir->dotEntry() ) + childAdded( subDir->dotEntry() ); + + _tree->addJob( new KAnyDirReadJob( _tree, subDir ) ); + } + else // non-directory child + { + KFileInfo *child = new KFileInfo( &entry, _tree, _dir ); + _dir->insertChild( child ); + childAdded( child ); + } + } + + ++it; + } +} + + +void +KAnyDirReadJob::finished( KIO::Job * job ) +{ + if ( job->error() ) + _dir->setReadState( KDirError ); + else + _dir->setReadState( KDirFinished ); + + _tree->sendFinalizeLocal( _dir ); + _dir->finalizeLocal(); + _job = 0; // The job deletes itself after this signal! + + _tree->jobFinishedNotify( this ); + // Don't add anything after _tree->jobFinishedNotify() + // since this deletes this job! +} + + + +KFileInfo * +KAnyDirReadJob::stat( const KURL & url, + KDirTree * tree, + KDirInfo * parent ) +{ + KIO::UDSEntry uds_entry; + + if ( KIO::NetAccess::stat( url, uds_entry, qApp->mainWidget() ) ) // remote stat() OK? + { + KFileItem entry( uds_entry, url, + true, // determine MIME type on demand + false ); // URL specifies parent directory + + return entry.isDir() ? new KDirInfo ( &entry, tree, parent ) : new KFileInfo( &entry, tree, parent ); + } + else // remote stat() failed + return 0; + + +#if HAVE_STUPID_COMPILER + /** + * This is stupid, but GCC 2.95.3 claims that "control reaches end of + * non-void function" without this - so let him have this stupid "return". + * + * Sigh. + **/ + return 0; +#endif +} + + +QString +KAnyDirReadJob::owner( KURL url ) +{ + KIO::UDSEntry uds_entry; + + if ( KIO::NetAccess::stat( url, uds_entry, qApp->mainWidget() ) ) // remote stat() OK? + { + KFileItem entry( uds_entry, url, + true, // determine MIME type on demand + false ); // URL specifies parent directory + + return entry.user(); + } + + return QString(); +} + + + + + + +KDirTree::KDirTree() + : QObject() +{ + _root = 0; + _selection = 0; + _isFileProtocol = false; + _isBusy = false; + _readMethod = KDirReadUnknown; + _jobQueue.setAutoDelete( true ); // Delete queued jobs automatically when destroyed + readConfig(); +} + + +KDirTree::~KDirTree() +{ + selectItem( 0 ); + + // Jobs still in the job queue are automatically deleted along with the + // queue since autoDelete is set. + // + // However, the queue needs to be cleared first before the entire tree is + // deleted, otherwise the dir pointers in each read job becomes invalid too + // early. + + _jobQueue.clear(); + + if ( _root ) + delete _root; +} + + +void +KDirTree::readConfig() +{ + KConfig * config = kapp->config(); + config->setGroup( "Directory Reading" ); + + _crossFileSystems = config->readBoolEntry( "CrossFileSystems", false ); + _enableLocalDirReader = config->readBoolEntry( "EnableLocalDirReader", true ); +} + + +void +KDirTree::startReading( const KURL & url ) +{ + // kdDebug() << k_funcinfo << " " << url.url() << endl; + +#if 0 + kdDebug() << "url: " << url.url() << endl; + kdDebug() << "path: " << url.path() << endl; + kdDebug() << "filename: " << url.filename() << endl; + kdDebug() << "protocol: " << url.protocol() << endl; + kdDebug() << "isValid: " << url.isValid() << endl; + kdDebug() << "isMalformed: " << url.isMalformed() << endl; + kdDebug() << "isLocalFile: " << url.isLocalFile() << endl; +#endif + + _isBusy = true; + emit startingReading(); + + if ( _root ) + { + // Clean up leftover stuff + + selectItem( 0 ); + emit deletingChild( _root ); + + // kdDebug() << "Deleting root prior to reading" << endl; + delete _root; + _root = 0; + emit childDeleted(); + } + + readConfig(); + _isFileProtocol = url.isLocalFile(); + + if ( _isFileProtocol && _enableLocalDirReader ) + { + // kdDebug() << "Using local directory reader for " << url.url() << endl; + _readMethod = KDirReadLocal; + _root = KLocalDirReadJob::stat( url, this ); + } + else + { + // kdDebug() << "Using KIO methods for " << url.url() << endl; + KURL cleanUrl( url ); + cleanUrl.cleanPath(); // Resolve relative paths, get rid of multiple '/' + _readMethod = KDirReadKIO; + _root = KAnyDirReadJob::stat( cleanUrl, this ); + } + + if ( _root ) + { + childAddedNotify( _root ); + + if ( _root->isDir() ) + { + KDirInfo *dir = (KDirInfo *) _root; + + if ( _readMethod == KDirReadLocal ) + addJob( new KLocalDirReadJob( this, dir ) ); + else + addJob( new KAnyDirReadJob( this, dir ) ); + } + else + { + _isBusy = false; + emit finished(); + } + } + else // stat() failed + { + // kdWarning() << "stat(" << url.url() << ") failed" << endl; + _isBusy = false; + emit finished(); + emit finalizeLocal( 0 ); + } + + if ( ! _jobQueue.isEmpty() ) + QTimer::singleShot( 0, this, SLOT( timeSlicedRead() ) ); +} + + +void +KDirTree::refresh( KFileInfo *subtree ) +{ + if ( ! _root ) + return; + + if ( ! subtree || ! subtree->parent() ) // Refresh all (from root) + { + startReading( fixedUrl( _root->url() ) ); + } + else // Refresh subtree + { + // Save some values from the old subtree. + + KURL url = subtree->url(); + KDirInfo * parent = subtree->parent(); + + + // Select nothing if the current selection is to be deleted + + if ( _selection && _selection->isInSubtree( subtree ) ) + selectItem( 0 ); + + // Get rid of the old subtree. + + emit deletingChild( subtree ); + + // kdDebug() << "Deleting subtree " << subtree << endl; + + /** + * This may sound stupid, but the parent must be told to unlink its + * child from the children list. The child cannot simply do this by + * itself in its destructor since at this point important parts of the + * object may already be destroyed, e.g., the virtual table - + * i.e. virtual methods won't work any more. + * + * I just found that out the hard way by several hours of debugging. ;-} + **/ + parent->deletingChild( subtree ); + delete subtree; + emit childDeleted(); + + + // Create new subtree root. + + subtree = ( _readMethod == KDirReadLocal ) ? + KLocalDirReadJob::stat( url, this, parent ) : KAnyDirReadJob::stat( url, this, parent ); + + // kdDebug() << "New subtree: " << subtree << endl; + + if ( subtree ) + { + // Insert new subtree root into the tree hierarchy. + + parent->insertChild( subtree ); + childAddedNotify( subtree ); + + if ( subtree->isDir() ) + { + // Prepare reading this subtree's contents. + + KDirInfo *dir = (KDirInfo *) subtree; + + if ( _readMethod == KDirReadLocal ) + addJob( new KLocalDirReadJob( this, dir ) ); + else + addJob( new KAnyDirReadJob( this, dir ) ); + } + else + { + _isBusy = false; + emit finished(); + } + + + // Trigger reading as soon as the event loop continues. + + if ( ! _jobQueue.isEmpty() ) + QTimer::singleShot( 0, this, SLOT( timeSlicedRead() ) ); + } + } +} + + + +void +KDirTree::timeSlicedRead() +{ + if ( ! _jobQueue.isEmpty() ) + _jobQueue.head()->startReading(); +} + + + +void +KDirTree::abortReading() +{ + if ( _jobQueue.isEmpty() ) + return; + + while ( ! _jobQueue.isEmpty() ) + { + _jobQueue.head()->dir()->readJobAborted(); + _jobQueue.dequeue(); + } + + _isBusy = false; + emit aborted(); +} + + + +void +KDirTree::jobFinishedNotify( KDirReadJob *job ) +{ + // Get rid of the old (finished) job. + + _jobQueue.dequeue(); + delete job; + + + // Look for a new job. + + if ( _jobQueue.isEmpty() ) // No new job available - we're done. + { + _isBusy = false; + emit finished(); + } + else // There is a new job + { + // Set up zero-duration timer for the new job. + + QTimer::singleShot( 0, this, SLOT( timeSlicedRead() ) ); + } +} + + +void +KDirTree::childAddedNotify( KFileInfo *newChild ) +{ + emit childAdded( newChild ); + + if ( newChild->dotEntry() ) + emit childAdded( newChild->dotEntry() ); +} + + +void +KDirTree::deletingChildNotify( KFileInfo *deletedChild ) +{ + emit deletingChild( deletedChild ); + + // Only now check for selection and root: Give connected objects + // (i.e. views) a chance to change either while handling the signal. + + if ( _selection && _selection->isInSubtree( deletedChild ) ) + selectItem( 0 ); + + if ( deletedChild == _root ) + _root = 0; +} + + +void +KDirTree::childDeletedNotify() +{ + emit childDeleted(); +} + + +void +KDirTree::deleteSubtree( KFileInfo *subtree ) +{ + // kdDebug() << "Deleting subtree " << subtree << endl; + KDirInfo *parent = subtree->parent(); + + if ( parent ) + { + // Give the parent of the child to be deleted a chance to unlink the + // child from its children list and take care of internal summary + // fields + parent->deletingChild( subtree ); + } + + // Send notification to anybody interested (e.g., to attached views) + deletingChildNotify( subtree ); + + if ( parent ) + { + if ( parent->isDotEntry() && ! parent->hasChildren() ) + // This was the last child of a dot entry + { + // Get rid of that now empty and useless dot entry + + if ( parent->parent() ) + { + if ( parent->parent()->isFinished() ) + { + // kdDebug() << "Removing empty dot entry " << parent << endl; + + deletingChildNotify( parent ); + parent->parent()->setDotEntry( 0 ); + + delete parent; + } + } + else // no parent - this should never happen (?) + { + kdError() << "Internal error: Killing dot entry without parent " << parent << endl; + + // Better leave that dot entry alone - we shouldn't have come + // here in the first place. Who knows what will happen if this + // thing is deleted now?! + // + // Intentionally NOT calling: + // delete parent; + } + } + } + + delete subtree; + + emit childDeleted(); +} + + +void +KDirTree::addJob( KDirReadJob * job ) +{ + CHECK_PTR( job ); + _jobQueue.enqueue( job ); +} + + +void +KDirTree::sendProgressInfo( const QString &infoLine ) +{ + emit progressInfo( infoLine ); +} + + +void +KDirTree::sendFinalizeLocal( KDirInfo *dir ) +{ + emit finalizeLocal( dir ); +} + + +void +KDirTree::selectItem( KFileInfo *newSelection ) +{ + if ( newSelection == _selection ) + return; + +#if 0 + if ( newSelection ) + kdDebug() << k_funcinfo << " selecting " << newSelection << endl; + else + kdDebug() << k_funcinfo << " selecting nothing" << endl; +#endif + + _selection = newSelection; + emit selectionChanged( _selection ); +} + + + + + + +KURL +KDirStat::fixedUrl( const QString & dirtyUrl ) +{ + KURL url = dirtyUrl; + + if ( ! url.isValid() ) // Maybe it's just a path spec? + { + url = KURL(); // Start over with an empty, but valid URL + url.setPath( dirtyUrl ); // and use just the path part. + } + else + { + url.cleanPath(); // Resolve relative paths, get rid of multiple slashes. + } + + + // Strip off the rightmost slash - some kioslaves (e.g. 'tar') can't handle that. + + QString path = url.path(); + + if ( path.length() > 1 && path.right(1) == "/" ) + { + path = path.left( path.length()-1 ); + url.setPath( path ); + } + + if ( url.isLocalFile() ) + { + // Make a relative path an absolute path + + KDirSaver dir( url.path() ); + url.setPath( dir.currentDirPath() ); + } + + return url; +} + + + + + + +QString +KDirStat::formatSize( KFileSize lSize ) +{ + QString sizeString; + double size; + QString unit; + + if ( lSize < 1024 ) + { + sizeString.setNum( (long) lSize ); + + unit = i18n( "Bytes" ); + } + else + { + size = lSize / 1024.0; // kB + + if ( size < 1024.0 ) + { + sizeString.sprintf( "%.1f", size ); + unit = i18n( "kB" ); + } + else + { + size /= 1024.0; // MB + + if ( size < 1024.0 ) + { + sizeString.sprintf( "%.1f", size ); + unit = i18n ( "MB" ); + } + else + { + size /= 1024.0; // GB - we won't go any further... + + sizeString.sprintf( "%.2f", size ); + unit = i18n ( "GB" ); + } + } + } + + if ( ! unit.isEmpty() ) + { + sizeString += " " + unit; + } + + return sizeString; +} + + + +// EOF diff --git a/kdirstat/kdirtree.h b/kdirstat/kdirtree.h new file mode 100644 index 0000000..d4155a9 --- /dev/null +++ b/kdirstat/kdirtree.h @@ -0,0 +1,1437 @@ +/* + * File name: kdirtree.h + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2005-01-07 + */ + + +#ifndef KDirTree_h +#define KDirTree_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifndef NOT_USED +# define NOT_USED(PARAM) ( (void) (PARAM) ) +#endif + +// Open a new name space since KDE's name space is pretty much cluttered +// already - all names that would even remotely match are already used up, +// yet the resprective classes don't quite fit the purposes required here. + +namespace KDirStat +{ + // With today's hard disks, the 2 GB we could sum up with 'long' (or 4 GB + // with 'unsigned long') are definitely not enough. So we have to go for + // something larger: + typedef long long KFileSize; + + // Taken from Linux (the Alpha definition - 64 Bit long!). + // This is how much bytes this program can handle. +#define KFileSizeMax 9223372036854775807LL + + // Forward declarations + class KDirInfo; + class KDirTree; + class KDirReadJob; + class KDirTreeView; + + + /** + * Status of a directory read job. + **/ + typedef enum + { + KDirQueued, // Waiting in the directory read queue + KDirReading, // Reading in progress + KDirFinished, // Reading finished and OK + KDirOnRequestOnly, // Will be read upon explicit request only (mount points) + KDirAborted, // Reading aborted upon user request + KDirError // Error while reading + } KDirReadState; + + + /** + * Directory read methods. + **/ + typedef enum + { + KDirReadUnknown, // Unknown (yet) + KDirReadLocal, // Use opendir() and lstat() + KDirReadKIO // Use KDE 2.x's KIO network transparent methods + } KDirReadMethod; + + + + /** + * The most basic building block of a @ref KDirTree: + * + * Information about one single directory entry. This is the type of info + * typically obtained by stat() / lstat() or similar calls. Most of this + * can also be obtained by @ref KIO::KDirListJob, but not all: The device + * this file resides on is something none of KIO's many classes will tell + * (since of course this only makes sense for local files) - yet this had + * been _the_ single most requested feature of KDirStat <1.0: Stay on one + * filesystem. To facilitate this, information about the device is + * required, thus we'll do lstat() sys calls ourselves for local + * files. This is what the classes in this file are all about. + * + * This class is tuned for size rather than speed: A typical Linux system + * easily has 150,000+ file system objects, and at least one entry of this + * sort is required for each of them. + * + * This class provides stubs for children management, yet those stubs all + * are default implementations that don't really deal with children. + * Derived classes need to take care of that. + * + * @short Basic file information (like obtained by the lstat() sys call) + **/ + class KFileInfo + { + public: + /** + * Default constructor. + **/ + KFileInfo( KDirTree * tree, + KDirInfo * parent = 0, + const char * name = 0 ); + + /** + * Constructor from a stat buffer (i.e. based on an lstat() call). + **/ + KFileInfo( const QString & filenameWithoutPath, + struct stat * statInfo, + KDirTree * tree, + KDirInfo * parent = 0 ); + + /** + * Constructor from a KFileItem, i.e. from a @ref KIO::StatJob + **/ + KFileInfo( const KFileItem * fileItem, + KDirTree * tree, + KDirInfo * parent = 0 ); + + /** + * Destructor. + * + * Don't forget to call @ref KFileInfo::unlinkChild() when deleting + * objects of this class! + **/ + virtual ~KFileInfo(); + + /** + * Returns whether or not this is a local file (protocol "file:"). + * It might as well be a remote file ("ftp:", "smb:" etc.). + **/ + bool isLocalFile() const { return _isLocalFile; } + + /** + * Returns the file or directory name without path, i.e. only the last + * path name component (i.e. "printcap" rather than "/etc/printcap"). + * + * If a directory scan doesn't begin at the root directory and this is + * the top entry of this directory scan it will also contain the base + * path and maybe the protocol (for remote files), + * i.e. "/usr/share/man" rather than just "man" if a scan was requested + * for "/usr/share/man". Notice, however, that the entry for + * "/usr/share/man/man1" will only return "man1" in this example. + **/ + QString name() const { return _name; } + + /** + * Returns the full URL of this object with full path and protocol + * (unless the protocol is "file:"). + * + * This is a (somewhat) expensive operation since it will recurse up + * to the top of the tree. + **/ + QString url() const; + + /** + * Very much like @ref KFileInfo::url(), but with "/" appended + * if this is a dot entry. Useful for debugging. + * Notice: You can simply use the @ref kdbgstream operator<< to + * output exactly this: + * + * kdDebug() << "Found fileInfo " << info << endl; + **/ + QString debugUrl() const; + + /** + * Returns part no. "level" of this object's URL, i.e. traverses up the + * tree until this tree level is reached and returns this predecessor's + * @ref name() . This is useful for tree searches in symmetrical trees + * to find an item's counterpart in the other tree. + **/ + QString urlPart( int level ) const; + + /** + * Returns the major and minor device numbers of the device this file + * resides on or 0 if this is a remote file. + **/ + dev_t device() const { return _device; } + + /** + * The file permissions and object type as returned by lstat(). + * You might want to use the repective convenience methods instead: + * @ref isDir(), @ref isFile(), ... + **/ + mode_t mode() const { return _mode; } + + /** + * The number of hard links to this file. Relevant for size summaries + * to avoid counting one file several times. + **/ + nlink_t links() const { return _links; } + + /** + * The file size in bytes. This does not take unused space in the last + * disk block (cluster) into account, yet it is the only size all kinds + * of info functions can obtain. This is also what most file system + * utilities (like "ls -l") display. + **/ + KFileSize byteSize() const { return _size; } + + /** + * The number of bytes actually allocated on the file system. Usually + * this will be more than @ref byteSize() since the last few bytes of a + * file usually consume an additional cluster on the file system. + * + * In the case of sparse files, however, this might as well be + * considerably less than @ref byteSize() - this means that this file + * has "holes", i.e. large portions filled with zeros. This is typical + * for large core dumps for example. The only way to create such a file + * is to lseek() far ahead of the previous file size and then writing + * data. Most file system utilities will however disregard the fact + * that files are sparse files and simply allocate the holes as well, + * thus greatly increasing the disk space consumption of such a + * file. Only some few file system utilities like "cp", "rsync", "tar" + * have options to handle this more graciously - but usually only when + * specifically requested. See the respective man pages. + **/ + KFileSize allocatedSize() const; + + /** + * The file size, taking into account multiple links for plain files or + * the true allocated size for sparse files. For plain files with + * multiple links this will be size/no_links, for sparse files it is + * the number of bytes actually allocated. + **/ + KFileSize size() const; + + /** + * The file size in 512 byte blocks. + **/ + KFileSize blocks() const { return _blocks; } + + /** + * The size of one single block that @ref blocks() returns. + * Notice: This is _not_ the blocksize that lstat() returns! + **/ + KFileSize blockSize() const { return 512L; } + + /** + * The modification time of the file (not the inode). + **/ + time_t mtime() const { return _mtime; } + + /** + * Returns the total size in bytes of this subtree. + * Derived classes that have children should overwrite this. + **/ + virtual KFileSize totalSize() { return size(); } + + /** + * Returns the total size in blocks of this subtree. + * Derived classes that have children should overwrite this. + **/ + virtual KFileSize totalBlocks() { return _blocks; } + + /** + * Returns the total number of children in this subtree, excluding this item. + * Derived classes that have children should overwrite this. + **/ + virtual int totalItems() { return 0; } + + /** + * Returns the total number of subdirectories in this subtree, + * excluding this item. Dot entries and "." or ".." are not counted. + * Derived classes that have children should overwrite this. + **/ + virtual int totalSubDirs() { return 0; } + + /** + * Returns the total number of plain file children in this subtree, + * excluding this item. + * Derived classes that have children should overwrite this. + **/ + virtual int totalFiles() { return 0; } + + /** + * Returns the latest modification time of this subtree. + * Derived classes that have children should overwrite this. + **/ + virtual time_t latestMtime() { return _mtime; } + + /** + * Returns whether or not this is a mount point. + * Derived classes may want to overwrite this. + **/ + virtual bool isMountPoint() { return false; } + + /** + * Sets the mount point state, i.e. whether or not this is a mount + * point. + * + * This default implementation silently ignores the value passed and + * does nothing. Derived classes may want to overwrite this. + **/ + virtual void setMountPoint( bool isMountPoint = true ) + { ((void) isMountPoint); return; } + + /** + * Returns true if this subtree is finished reading. + * + * This default implementation always returns 'true'; + * derived classes should overwrite this. + **/ + virtual bool isFinished() { return true; } + + /** + * Returns true if this subtree is busy, i.e. it is not finished + * reading yet. + * + * This default implementation always returns 'false'; + * derived classes should overwrite this. + **/ + virtual bool isBusy() { return false; } + + /** + * Returns the number of pending read jobs in this subtree. When this + * number reaches zero, the entire subtree is done. + * Derived classes that have children should overwrite this. + **/ + virtual int pendingReadJobs() { return 0; } + + + // + // Tree management + // + + /** + * Returns a pointer to the @ref KDirTree this entry belongs to. + **/ + KDirTree * tree() const { return _tree; } + + /** + * Returns a pointer to this entry's parent entry or 0 if there is + * none. + **/ + KDirInfo * parent() const { return _parent; } + + /** + * Set the "parent" pointer. + **/ + void setParent( KDirInfo *newParent ) { _parent = newParent; } + + /** + * Returns a pointer to the next entry on the same level + * or 0 if there is none. + **/ + KFileInfo * next() const { return _next; } + + /** + * Set the "next" pointer. + **/ + void setNext( KFileInfo *newNext ) { _next = newNext; } + + /** + * Returns the first child of this item or 0 if there is none. + * Use the child's next() method to get the next child. + * + * This default implementation always returns 0. + **/ + virtual KFileInfo * firstChild() const { return 0; } + + /** + * Set this entry's first child. + * Use this method only if you know exactly what you are doing. + * + * This default implementation does nothing. + * Derived classes might want to overwrite this. + **/ + virtual void setFirstChild( KFileInfo *newFirstChild ) + { NOT_USED( newFirstChild ); } + + /** + * Returns true if this entry has any children. + **/ + virtual bool hasChildren() const; + + /** + * Returns true if this entry is in subtree 'subtree', i.e. if this is + * a child or grandchild etc. of 'subtree'. + **/ + bool isInSubtree( const KFileInfo *subtree ) const; + + /** + * Locate a child somewhere in this subtree whose URL (i.e. complete + * path) matches the URL passed. Returns 0 if there is no such child. + * + * Notice: This is a very expensive operation since the entire subtree + * is searched recursively. + * + * Derived classes might or might not wish to overwrite this method; + * it's only advisable to do so if a derived class comes up with a + * different method than brute-force search all children. + * + * 'findDotEntries' specifies if locating "dot entries" (".../") + * is desired. + **/ + virtual KFileInfo * locate( QString url, bool findDotEntries = false ); + + /** + * Insert a child into the children list. + * + * The order of children in this list is absolutely undefined; + * don't rely on any implementation-specific order. + * + * This default implementation does nothing. + **/ + virtual void insertChild( KFileInfo *newChild ) { NOT_USED( newChild ); } + + /** + * Return the "Dot Entry" for this node if there is one (or 0 + * otherwise): This is a pseudo entry that directory nodes use to store + * non-directory children separately from directories. This way the end + * user can easily tell which summary fields belong to the directory + * itself and which are the accumulated values of the entire subtree. + * + * This default implementation always returns 0. + **/ + virtual KFileInfo *dotEntry() const { return 0; } + + /** + * Set a "Dot Entry". This makes sense for directories only. + * + * This default implementation does nothing. + **/ + virtual void setDotEntry( KFileInfo *newDotEntry ) { NOT_USED( newDotEntry ); } + + /** + * Returns true if this is a "Dot Entry". + * See @ref dotEntry() for details. + * + * This default implementation always returns false. + **/ + virtual bool isDotEntry() const { return false; } + + /** + * Returns the tree level (depth) of this item. + * The topmost level is 0. + * + * This is a (somewhat) expensive operation since it will recurse up + * to the top of the tree. + **/ + int treeLevel() const; + + /** + * Notification that a child has been added somewhere in the subtree. + * + * This default implementation does nothing. + **/ + virtual void childAdded( KFileInfo *newChild ) { NOT_USED( newChild ); } + + /** + * Remove a child from the children list. + * + * IMPORTANT: This MUST be called just prior to deleting an object of + * this class. Regrettably, this cannot simply be moved to the + * destructor: Important parts of the object might already be destroyed + * (e.g., the virtual table - no more virtual methods). + * + * This default implementation does nothing. + * Derived classes that can handle children should overwrite this. + **/ + virtual void unlinkChild( KFileInfo *deletedChild ) { NOT_USED( deletedChild ); } + + /** + * Notification that a child is about to be deleted somewhere in the + * subtree. + **/ + virtual void deletingChild( KFileInfo *deletedChild ) { NOT_USED( deletedChild ); } + + /** + * Get the current state of the directory reading process: + * + * This default implementation always returns KDirFinished. + * Derived classes should overwrite this. + **/ + virtual KDirReadState readState() const { return KDirFinished; } + + /** + * Returns true if this is a @ref KDirInfo object. + * + * Don't confuse this with @ref isDir() which tells whether or not this + * is a disk directory! Both should return the same, but you'll never + * know - better be safe than sorry! + * + * This default implementation always returns 'false'. Derived classes + * (in particular, those derived from @ref KDirInfo) should overwrite this. + **/ + virtual bool isDirInfo() const { return false; } + + /** + * Returns true if this is a sparse file, i.e. if this file has + * actually fewer disk blocks allocated than its byte size would call + * for. + * + * This is a cheap operation since it relies on a cached flag that is + * calculated in the constructor rather than doing repeated + * calculations and comparisons. + * + * Please not that @ref size() already takes this into account. + **/ + bool isSparseFile() const { return _isSparseFile; } + + + // + // File type / mode convenience methods. + // These are simply shortcuts to the respective macros from + // . + // + + /** + * Returns true if this is a directory. + **/ + bool isDir() const { return S_ISDIR( _mode ) ? true : false; } + + /** + * Returns true if this is a regular file. + **/ + bool isFile() const { return S_ISREG( _mode ) ? true : false; } + + /** + * Returns true if this is a symbolic link. + **/ + bool isSymLink() const { return S_ISLNK( _mode ) ? true : false; } + + + /** + * Returns true if this is a (block or character) device. + **/ + bool isDevice() const { return ( S_ISBLK ( _mode ) || + S_ISCHR ( _mode ) ) ? true : false; } + + /** + * Returns true if this is a block device. + **/ + bool isBlockDevice() const { return S_ISBLK ( _mode ) ? true : false; } + + /** + * Returns true if this is a block device. + **/ + bool isCharDevice() const { return S_ISCHR ( _mode ) ? true : false; } + + /** + * Returns true if this is a "special" file, i.e. a (block or character) + * device, a FIFO (named pipe) or a socket. + **/ + bool isSpecial() const { return ( S_ISBLK ( _mode ) || + S_ISCHR ( _mode ) || + S_ISFIFO( _mode ) || + S_ISSOCK( _mode ) ) ? true : false; } + + protected: + + // Data members. + // + // Keep this short in order to use as little memory as possible - + // there will be a _lot_ of entries of this kind! + + QString _name; // the file name (without path!) + bool _isLocalFile :1; // flag: local or remote file? + bool _isSparseFile :1; // (cache) flag: sparse file (file with "holes")? + dev_t _device; // device this object resides on + mode_t _mode; // file permissions + object type + nlink_t _links; // number of links + KFileSize _size; // size in bytes + KFileSize _blocks; // 512 bytes blocks + time_t _mtime; // modification time + + KDirInfo * _parent; // pointer to the parent entry + KFileInfo * _next; // pointer to the next entry + KDirTree * _tree; // pointer to the parent tree + }; // class KFileInfo + + + /** + * A more specialized version of @ref KFileInfo: This class can actually + * manage children. The base class (@ref KFileInfo) has only stubs for the + * respective methods to integrate seamlessly with the abstraction of a + * file / directory tree; this class fills those stubs with life. + * + * @short directory item within a @ref KDirTree. + **/ + class KDirInfo: public KFileInfo + { + public: + /** + * Default constructor. + * + * If "asDotEntry" is set, this will be used as the parent's + * "dot entry", i.e. the pseudo directory that holds all the parent's + * non-directory children. This is the only way to create a "dot + * entry"! + **/ + KDirInfo( KDirTree * tree, + KDirInfo * parent = 0, + bool asDotEntry = false ); + + /** + * Constructor from a stat buffer (i.e. based on an lstat() call). + **/ + KDirInfo( const QString & filenameWithoutPath, + struct stat * statInfo, + KDirTree * tree, + KDirInfo * parent = 0 ); + + /** + * Constructor from a KFileItem, i.e. from a @ref KIO::StatJob + **/ + KDirInfo( const KFileItem * fileItem, + KDirTree * tree, + KDirInfo * parent = 0 ); + + /** + * Destructor. + **/ + virtual ~KDirInfo(); + + + /** + * Returns the total size in bytes of this subtree. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual KFileSize totalSize(); + + /** + * Returns the total size in blocks of this subtree. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual KFileSize totalBlocks(); + + /** + * Returns the total number of children in this subtree, excluding this item. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual int totalItems(); + + /** + * Returns the total number of subdirectories in this subtree, + * excluding this item. Dot entries and "." or ".." are not counted. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual int totalSubDirs(); + + /** + * Returns the total number of plain file children in this subtree, + * excluding this item. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual int totalFiles(); + + /** + * Returns the latest modification time of this subtree. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual time_t latestMtime(); + + /** + * Returns whether or not this is a mount point. + * + * This will return 'false' only if this information can be obtained at + * all, i.e. if local directory reading methods are used. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual bool isMountPoint() { return _isMountPoint; } + + /** + * Sets the mount point state, i.e. whether or not this is a mount + * point. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual void setMountPoint( bool isMountPoint = true ); + + /** + * Returns true if this subtree is finished reading. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual bool isFinished(); + + /** + * Returns true if this subtree is busy, i.e. it is not finished + * reading yet. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual bool isBusy(); + + /** + * Returns the number of pending read jobs in this subtree. When this + * number reaches zero, the entire subtree is done. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual int pendingReadJobs() { return _pendingReadJobs; } + + /** + * Returns the first child of this item or 0 if there is none. + * Use the child's next() method to get the next child. + **/ + virtual KFileInfo * firstChild() const { return _firstChild; } + + /** + * Set this entry's first child. + * Use this method only if you know exactly what you are doing. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual void setFirstChild( KFileInfo *newfirstChild ) + { _firstChild = newfirstChild; } + + /** + * Insert a child into the children list. + * + * The order of children in this list is absolutely undefined; + * don't rely on any implementation-specific order. + **/ + virtual void insertChild( KFileInfo *newChild ); + + /** + * Get the "Dot Entry" for this node if there is one (or 0 otherwise): + * This is a pseudo entry that directory nodes use to store + * non-directory children separately from directories. This way the end + * user can easily tell which summary fields belong to the directory + * itself and which are the accumulated values of the entire subtree. + **/ + virtual KFileInfo * dotEntry() const { return _dotEntry; } + + /** + * Set a "Dot Entry". This makes sense for directories only. + **/ + virtual void setDotEntry( KFileInfo *newDotEntry ) { _dotEntry = newDotEntry; } + + /** + * Returns true if this is a "Dot Entry". See @ref dotEntry() for + * details. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual bool isDotEntry() const { return _isDotEntry; } + + /** + * Notification that a child has been added somewhere in the subtree. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual void childAdded( KFileInfo *newChild ); + + /** + * Remove a child from the children list. + * + * IMPORTANT: This MUST be called just prior to deleting an object of + * this class. Regrettably, this cannot simply be moved to the + * destructor: Important parts of the object might already be destroyed + * (e.g., the virtual table - no more virtual methods). + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual void unlinkChild( KFileInfo *deletedChild ); + + /** + * Notification that a child is about to be deleted somewhere in the + * subtree. + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual void deletingChild( KFileInfo *deletedChild ); + + /** + * Notification of a new directory read job somewhere in the subtree. + **/ + void readJobAdded(); + + /** + * Notification of a finished directory read job somewhere in the + * subtree. + **/ + void readJobFinished(); + + /** + * Notification of an aborted directory read job somewhere in the + * subtree. + **/ + void readJobAborted(); + + /** + * Finalize this directory level after reading it is completed. + * This does _not_ mean reading reading all subdirectories is completed + * as well! + * + * Clean up unneeded dot entries. + **/ + virtual void finalizeLocal(); + + /** + * Get the current state of the directory reading process: + * + * KDirQueued waiting in the directory read queue + * KDirReading reading in progress + * KDirFinished reading finished and OK + * KDirAborted reading aborted upon user request + * KDirError error while reading + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual KDirReadState readState() const; + + /** + * Set the state of the directory reading process. + * See @ref readState() for details. + **/ + void setReadState( KDirReadState newReadState ); + + /** + * Returns true if this is a @ref KDirInfo object. + * + * Don't confuse this with @ref isDir() which tells whether or not this + * is a disk directory! Both should return the same, but you'll never + * know - better be safe than sorry! + * + * Reimplemented - inherited from @ref KFileInfo. + **/ + virtual bool isDirInfo() const { return true; } + + + protected: + + /** + * Recursively recalculate the summary fields when they are dirty. + * + * This is a _very_ expensive operation since the entire subtree may + * recursively be traversed. + **/ + void recalc(); + + /** + * Clean up unneeded / undesired dot entries: + * Delete dot entries that don't have any children, + * reparent dot entry children to the "real" (parent) directory if + * there are not subdirectory siblings at the level of the dot entry. + **/ + void cleanupDotEntries(); + + + bool _isDotEntry; // Flag: is this entry a "dot entry"? + bool _isMountPoint; // Flag: is this a mount point? + int _pendingReadJobs; // number of open directories in this subtree + + // Children management + + KFileInfo * _firstChild; // pointer to the first child + KFileInfo * _dotEntry; // pseudo entry to hold non-dir children + + // Some cached values + + KFileSize _totalSize; + KFileSize _totalBlocks; + int _totalItems; + int _totalSubDirs; + int _totalFiles; + time_t _latestMtime; + + bool _summaryDirty; // dirty flag for the cached values + bool _beingDestroyed; + KDirReadState _readState; + + + private: + + void init(); + + }; // class KDirInfo + + + /** + * A directory read job that can be queued. This is mainly to prevent + * buffer thrashing because of too many directories opened at the same time + * because of simultaneous reads or even system resource consumption + * (directory handles in this case). + * + * Objects of this kind are transient by nature: They live only as long as + * the job is queued or executed. When it's done, the data is contained in + * the corresponding @ref KDirInfo subtree of the corresponding @ref + * KDirTree. + * + * For each entry automatically a @ref KFileInfo or @ref KDirInfo will be + * created and added to the parent @ref KDirInfo. For each directory a new + * @ref KDirReadJob will be created and added to the @ref KDirTree 's job + * queue. + * + * Notice: This class contains pure virtuals - you cannot use it + * directly. Derive your own class from it or use one of + * @ref KLocalDirReadJob or @ref KAnyDirReadJob. + * + * @short Abstract base class for directory reading. + **/ + class KDirReadJob + { + public: + /** + * Constructor. + **/ + KDirReadJob( KDirTree *tree, KDirInfo *dir ); + + /** + * Destructor. + **/ + virtual ~KDirReadJob(); + + /** + * Start reading the directory. Prior to this nothing happens. + * + * Please notice there is no corresponding abortReading() call: + * Simply delete the reader if the user requests to abort reading. + * + * Derived classes need to implement this method. + **/ + virtual void startReading() = 0; + + /** + * Returns the corresponding @ref KDirInfo item. + **/ + virtual KDirInfo * dir() { return _dir; } + + + protected: + + /** + * Notification that a new child has been added. + * + * Derived classes are required to call this whenever a new child is + * added so this notification can be passed up to the @ref KDirTree + * which in turn emits a corresponding signal. + **/ + void childAdded( KFileInfo *newChild ); + + /** + * Notification that a child is about to be deleted. + * + * Derived classes are required to call this just before a child is + * deleted so this notification can be passed up to the @ref KDirTree + * which in turn emits a corresponding signal. + * + * Derived classes are not required to handle child deletion at all, + * but if they do, calling this method is required. + **/ + void deletingChild( KFileInfo *deletedChild ); + + + KDirTree * _tree; + KDirInfo * _dir; + }; + + + /** + * Impementation of the abstract @ref KDirReadJob class that reads a local + * directory. + * + * This will use lstat() system calls rather than KDE's network transparent + * directory services since lstat() unlike the KDE services can obtain + * information about the device (i.e. file system) a file or directory + * resides on. This is important if you wish to limit directory scans to + * one file system - which is most desirable when that one file system runs + * out of space. + * + * @short Directory reader that reads one local directory. + **/ + class KLocalDirReadJob: public KDirReadJob + { + public: + /** + * Constructor. + **/ + KLocalDirReadJob( KDirTree * tree, KDirInfo * dir ); + + /** + * Destructor. + **/ + virtual ~KLocalDirReadJob(); + + /** + * Start reading the directory. Prior to this nothing happens. + * + * Inherited and reimplemented from @ref KDirReadJob. + **/ + virtual void startReading(); + + /** + * Obtain information about the URL specified and create a new @ref + * KFileInfo or a @ref KDirInfo (whatever is appropriate) from that + * information. Use @ref KFileInfo::isDirInfo() to find out which. + * Returns 0 if such information cannot be obtained (i.e. the + * appropriate stat() call fails). + **/ + static KFileInfo * stat( const KURL & url, + KDirTree * tree, + KDirInfo * parent = 0 ); + + protected: + DIR * _diskDir; + }; + + + /** + * Generic impementation of the abstract @ref KDirReadJob class, using + * KDE's network transparent IO methods. + * + * This is much more generic than @ref KLocalDirReadJob since it supports + * protocols like 'ftp', 'http', 'smb', 'tar' etc., too. Its only drawback + * is that is cannot be prevented from crossing file system boundaries - + * which makes it pretty useless for figuring out the cause of a 'file + * system full' error. + * + * @short Generic directory reader that reads one directory, remote or local. + **/ + class KAnyDirReadJob: public QObject, public KDirReadJob + { + Q_OBJECT + + public: + /** + * Constructor. + **/ + KAnyDirReadJob( KDirTree * tree, KDirInfo * dir ); + + /** + * Destructor. + **/ + virtual ~KAnyDirReadJob(); + + /** + * Start reading the directory. Prior to this nothing happens. + * + * Inherited and reimplemented from @ref KDirReadJob. + **/ + virtual void startReading(); + + /** + * Obtain information about the URL specified and create a new @ref + * KFileInfo or a @ref KDirInfo (whatever is appropriate) from that + * information. Use @ref KFileInfo::isDirInfo() to find out which. + * Returns 0 if such information cannot be obtained (i.e. the + * appropriate stat() call fails). + **/ + static KFileInfo * stat( const KURL & url, + KDirTree * tree, + KDirInfo * parent = 0 ); + + /** + * Obtain the owner of the URL specified. + * + * This is a moderately expensive operation since it involves a network + * transparent stat() call. + **/ + static QString owner( KURL url ); + + + protected slots: + /** + * Receive directory entries from a KIO job. + **/ + void entries( KIO::Job * job, + const KIO::UDSEntryList & entryList ); + + /** + * KIO job is finished. + **/ + void finished( KIO::Job * job ); + + protected: + + KIO::ListJob * _job; + }; + + + + /** + * This class provides some infrastructure as well as global data for a + * directory tree. It acts as the glue that holds things together: The root + * item from which to descend into the subtree, the read queue and some + * global policies (like whether or not to cross file systems while reading + * directories). + * + * @short Directory tree global data and infrastructure + **/ + class KDirTree: public QObject + { + Q_OBJECT + + public: + /** + * Constructor. + * + * Remember to call @ref startReading() after the constructor and + * setting up connections. + **/ + KDirTree(); + + /** + * Destructor. + **/ + virtual ~KDirTree(); + + + public slots: + + /** + * Actually start reading. + * + * It's not very pretty this is required as an extra method, but this + * cannot simply be done in the constructor: We need to give the caller + * a chance to set up Qt signal connections, and for this the + * constructor must return before any signals are sent, i.e. before + * anything is read. + **/ + void startReading( const KURL & url ); + + /** + * Forcefully stop a running read process. + **/ + void abortReading(); + + /** + * Refresh a subtree, i.e. read its contents from disk again. + * + * The old subtree will be deleted and rebuilt from scratch, i.e. all + * pointers to elements within this subtree will become invalid (a + * @ref subtreeDeleted() signal will be emitted to notify about that + * fact). + * + * When 0 is passed, the entire tree will be refreshed, i.e. from the + * root element on. + **/ + void refresh( KFileInfo *subtree = 0 ); + + /** + * Select some other item in this tree. Triggers the @ref + * selectionChanged() signal - even to the sender of this signal, + * i.e. take care not to cause endless signal ping-pong! + * + * Select nothing if '0' is passed. + **/ + void selectItem( KFileInfo *newSelection ); + + /** + * Delete a subtree. + **/ + void deleteSubtree( KFileInfo *subtree ); + + + public: + + /** + * Returns the root item of this tree. + * + * Currently, there can only be one single root item for each tree. + */ + KFileInfo * root() const { return _root; } + + /** + * Locate a child somewhere in the tree whose URL (i.e. complete path) + * matches the URL passed. Returns 0 if there is no such child. + * + * Notice: This is a very expensive operation since the entire tree is + * searched recursively. + * + * 'findDotEntries' specifies if locating "dot entries" (".../") + * is desired. + * + * This is just a convenience method that maps to + * KDirTree::root()->locate( url, findDotEntries ) + **/ + KFileInfo * locate( QString url, bool findDotEntries = false ) + { return _root ? _root->locate( url, findDotEntries ) : 0; } + + /** + * Notification of a finished directory read job. + * All read jobs are required to call this upon (successful or + * unsuccessful) completion. + **/ + void jobFinishedNotify( KDirReadJob *job ); + + /** + * Add a new directory read job to the queue. + **/ + void addJob( KDirReadJob * job ); + + /** + * Obtain the directory read method for this tree: + * KDirReadLocal use opendir() and lstat() + * KDirReadKDirLister use KDE 2.x's KDirLister + **/ + KDirReadMethod readMethod() const { return _readMethod; } + + /** + * Should directory scans cross file systems? + * + * Notice: This can only be avoided with local directories where the + * device number a file resides on can be obtained. + * Remember, that's what this KDirStat business is all about. ;-) + **/ + bool crossFileSystems() const { return _crossFileSystems; } + + /** + * Set or unset the "cross file systems" flag. + **/ + void setCrossFileSystems( bool doCross ) { _crossFileSystems = doCross; } + + /** + * Return the tree's current selection. + * + * Even though the KDirTree by itself doesn't have a visual + * representation, it supports the concept of one single selected + * item. Views can use this to transparently keep track of this single + * selected item, notifying the KDirTree and thus other views with @ref + * KDirTree::selectItem() . Attached views should connect to the @ref + * selectionChanged() signal to be notified when the selection changes. + * + * NOTE: This method returns 0 if nothing is selected. + **/ + KFileInfo * selection() const { return _selection; } + + /** + * Notification that a child has been added. + * + * Directory read jobs are required to call this for each child added + * so the tree can emit the corresponding @ref childAdded() signal. + **/ + virtual void childAddedNotify( KFileInfo *newChild ); + + /** + * Notification that a child is about to be deleted. + * + * Directory read jobs are required to call this for each deleted child + * so the tree can emit the corresponding @ref deletingChild() signal. + **/ + virtual void deletingChildNotify( KFileInfo *deletedChild ); + + /** + * Notification that one or more children have been deleted. + * + * Directory read jobs are required to call this when one or more + * children are deleted so the tree can emit the corresponding @ref + * deletingChild() signal. For multiple deletions (e.g. entire + * subtrees) this should only happen once at the end. + **/ + virtual void childDeletedNotify(); + + /** + * Send a @ref progressInfo() signal to keep the user entertained while + * directories are being read. + **/ + void sendProgressInfo( const QString &infoLine ); + + /** + * Send a @ref finalizeLocal() signal to give views a chance to + * finalize the display of this directory level - e.g. clean up dot + * entries, set the final "expandable" state etc. + **/ + void sendFinalizeLocal( KDirInfo *dir ); + + /** + * Returns 'true' if this tree uses the 'file:/' protocol (regardless + * of local or network transparent directory reader). + **/ + bool isFileProtocol() { return _isFileProtocol; } + + /** + * Returns 'true' if directory reading is in progress in this tree. + **/ + bool isBusy() { return _isBusy; } + + + signals: + + /** + * Emitted when a child has been added. + **/ + void childAdded( KFileInfo *newChild ); + + /** + * Emitted when a child is about to be deleted. + **/ + void deletingChild( KFileInfo *deletedChild ); + + /** + * Emitted after a child is deleted. If you are interested which child + * it was, better use the @ref deletingChild() signal. + * @ref childDeleted() is only useful to rebuild a view etc. completely. + * If possible, this signal is sent only once for multiple deletions - + * e.g., when entire subtrees are deleted. + **/ + void childDeleted(); + + /** + * Emitted when reading is started. + **/ + void startingReading(); + + /** + * Emitted when reading this directory tree is finished. + **/ + void finished(); + + /** + * Emitted when reading this directory tree has been aborted. + **/ + void aborted(); + + /** + * Emitted when reading a directory is finished. + * This does _not_ mean reading all subdirectories is finished, too - + * only this directory level is complete! + * + * WARNING: 'dir' may be 0 if the the tree's root could not be read. + * + * Use this signal to do similar cleanups like + * @ref KDirInfo::finalizeLocal(), e.g. cleaning up unused / undesired + * dot entries like in @ref KDirInfo::cleanupDotEntries(). + **/ + void finalizeLocal( KDirInfo *dir ); + + /** + * Emitted when the current selection has changed, i.e. whenever some + * attached view triggers the @ref selectItem() slot or when the + * current selection is deleted. + * + * NOTE: 'newSelection' may be 0 if nothing is selected. + **/ + void selectionChanged( KFileInfo *newSelection ); + + /** + * Single line progress information, emitted when the read status + * changes - typically when a new directory is being read. Connect to a + * status bar etc. to keep the user entertained. + **/ + void progressInfo( const QString &infoLine ); + + + protected slots: + + /** + * Time-sliced work procedure to be performed while the application is + * in the main loop: Read some directory entries, but relinquish + * control back to the application so it can maintain some + * responsiveness. This method uses single-shot timers of minimal + * duration to activate itself as soon as there are no more user events + * to process. Call this only once directly after inserting a read job + * into the job queue. + **/ + void timeSlicedRead(); + + /** + * Read some parameters from the global @ref KConfig object. + **/ + void readConfig(); + + + protected: + + KFileInfo * _root; + KFileInfo * _selection; + QPtrQueue _jobQueue; + KDirReadMethod _readMethod; + bool _crossFileSystems; + bool _enableLocalDirReader; + bool _isFileProtocol; + bool _isBusy; + }; + + + //---------------------------------------------------------------------- + // Static Functions + //---------------------------------------------------------------------- + + /** + * Make a valid, fixed and cleaned URL from a (possibly dirty) URL or maybe + * a path. + **/ + KURL fixedUrl( const QString & dirtyUrl ); + + + /** + * Format a file / subtree size human readable, i.e. in "GB" / "MB" + * etc. rather than huge numbers of digits. + * + * Note: For kdDebug() etc., operator<< is overwritten to do exactly that: + * + * kdDebug() << "Size: " << x->totalSize() << endl; + **/ + QString formatSize ( KFileSize lSize ); + + + /** + * Print the debugUrl() of a @ref KFileInfo in a debug stream. + **/ + inline kdbgstream & operator<< ( kdbgstream & stream, const KFileInfo * info ) + { + if ( info ) + stream << info->debugUrl(); + else + stream << ""; + + return stream; + } + + + /** + * Human-readable output of a file size in a debug stream. + **/ + inline kdbgstream & operator<< ( kdbgstream & stream, KFileSize lSize ) + { + stream << formatSize( lSize ); + + return stream; + } + +} // namespace KDirStat + + +#endif // ifndef KDirTree_h + + +// EOF diff --git a/kdirstat/kdirtreeiterators.cpp b/kdirstat/kdirtreeiterators.cpp new file mode 100644 index 0000000..6f42798 --- /dev/null +++ b/kdirstat/kdirtreeiterators.cpp @@ -0,0 +1,417 @@ +/* + * File name: kdirtreeiterators.h + * Summary: Support classes for KDirStat - KDirTree iterator classes + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#include "kdirtreeiterators.h" +#include "kdirtree.h" + + +using namespace KDirStat; + + +KFileInfoIterator::KFileInfoIterator( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy ) +{ + init( parent, + dotEntryPolicy, + true ); // callNext +} + + +KFileInfoIterator::KFileInfoIterator( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy, + bool callNext ) +{ + init( parent, dotEntryPolicy, callNext ); +} + + +void +KFileInfoIterator::init( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy, + bool callNext ) +{ + _parent = parent; + _policy = dotEntryPolicy; + _current = 0; + + _directChildrenProcessed = false; + _dotEntryProcessed = false; + _dotEntryChildrenProcessed = false; + + if ( callNext ) + next(); +} + + +KFileInfoIterator::~KFileInfoIterator() +{ + // NOP +} + + +void KFileInfoIterator::next() +{ + if ( ! _directChildrenProcessed ) + { + // Process direct children + + _current = _current ? _current->next() : _parent->firstChild(); + + if ( ! _current ) + { + _directChildrenProcessed = true; + next(); + } + else + { + // kdDebug() << k_funcinfo << " direct child " << _current << endl; + } + } + else // _directChildrenProcessed + { + if ( ! _dotEntryProcessed ) + { + // Process dot entry + + _current = _policy == KDotEntryAsSubDir ? _parent->dotEntry() : 0; + _dotEntryProcessed = true; + + if ( ! _current ) + { + next(); + } + else + { + // kdDebug() << k_funcinfo << " dot entry " << _current << endl; + } + } + else // Dot entry already processed or processing it not desired + { + if ( ! _dotEntryChildrenProcessed ) + { + if ( _policy == KDotEntryTransparent ) + { + // Process dot entry children + + _current = _current ? + _current->next() : + ( _parent->dotEntry() ? _parent->dotEntry()->firstChild() : 0 ); + + if ( ! _current ) + { + _dotEntryChildrenProcessed = true; + } + else + { + // kdDebug() << k_funcinfo << " dot entry child " << _current << endl; + } + } + else // _policy != KDotEntryTransparent + { + _current = 0; + _dotEntryChildrenProcessed = true; + } + } + } + } +} + + +int +KFileInfoIterator::count() +{ + int cnt = 0; + + // Count direct children + + KFileInfo *child = _parent->firstChild(); + + while ( child ) + { + cnt++; + child = child->next(); + } + + + // Handle the dot entry + + switch ( _policy ) + { + case KDotEntryTransparent: // Count the dot entry's children as well. + if ( _parent->dotEntry() ) + { + child = _parent->dotEntry()->firstChild(); + + while ( child ) + { + cnt++; + child = child->next(); + } + } + break; + + case KDotEntryAsSubDir: // The dot entry counts as one item. + if ( _parent->dotEntry() ) + cnt++; + break; + + case KDotEntryIgnore: // We're done. + break; + } + + return cnt; +} + + + + + + +KFileInfoSortedIterator::KFileInfoSortedIterator( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy, + KFileInfoSortOrder sortOrder, + bool ascending ) + : KFileInfoIterator( parent, dotEntryPolicy, false ) +{ + _sortOrder = sortOrder; + _ascending = ascending; + _initComplete = false; + _childrenList = 0; + _current = 0; +} + + +void +KFileInfoSortedIterator::delayedInit() +{ + _childrenList = new KFileInfoList( _sortOrder, _ascending ); + CHECK_PTR( _childrenList ); + + if ( _sortOrder == KSortByName ) + { + makeDefaultOrderChildrenList(); + } + else + { + makeChildrenList(); + } + + _current = _childrenList->first(); + _initComplete = true; +} + + +KFileInfoSortedIterator::~KFileInfoSortedIterator() +{ + if ( _childrenList ) + delete _childrenList; +} + + +void KFileInfoSortedIterator::makeDefaultOrderChildrenList() +{ + // Fill children list with direct children + + KFileInfo *child = _parent->firstChild(); + + while ( child ) + { + _childrenList->append( child ); + child = child->next(); + } + + _childrenList->sort(); + + if ( _policy == KDotEntryAsSubDir && _parent->dotEntry() ) + { + // Append dot entry to the children list + + _childrenList->append( _parent->dotEntry() ); + } + + + // Append the dot entry's children to the children list + + if ( _policy == KDotEntryTransparent && _parent->dotEntry() ) + { + // Create a temporary list for the dot entry children + + KFileInfoList dotEntryChildrenList( _sortOrder, _ascending ); + child = _parent->dotEntry()->firstChild(); + + while ( child ) + { + dotEntryChildrenList.append( child ); + child = child->next(); + } + + dotEntryChildrenList.sort(); + + + // Now append all of this dot entry children list to the children list + + child = dotEntryChildrenList.first(); + + while ( child ) + { + _childrenList->append( child ); + child = dotEntryChildrenList.next(); + } + } +} + + +void +KFileInfoSortedIterator::makeChildrenList() +{ + KFileInfoIterator it( _parent, _policy ); + + while ( *it ) + { + _childrenList->append( *it ); + ++it; + } + + _childrenList->sort(); +} + + +KFileInfo * +KFileInfoSortedIterator::current() +{ + if ( ! _initComplete ) + delayedInit(); + + return _current; +} + + +void KFileInfoSortedIterator::next() +{ + if ( ! _initComplete ) + delayedInit(); + + _current = _childrenList->next(); +} + + +bool +KFileInfoSortedIterator::finished() +{ + if ( ! _initComplete ) + delayedInit(); + + return _current == 0; +} + + + + + + +KFileInfoSortedBySizeIterator::KFileInfoSortedBySizeIterator( KFileInfo * parent, + KFileSize minSize, + KDotEntryPolicy dotEntryPolicy, + bool ascending ) + : KFileInfoSortedIterator( parent, dotEntryPolicy, KSortByTotalSize, ascending ) + , _minSize( minSize ) +{ +} + + +void +KFileInfoSortedBySizeIterator::makeChildrenList() +{ + KFileInfoIterator it( _parent, _policy ); + + while ( *it ) + { + if ( (*it)->totalSize() >= _minSize ) + _childrenList->append( *it ); + + ++it; + } + + _childrenList->sort(); +} + + + + + + +KFileInfoList::KFileInfoList( KFileInfoSortOrder sortOrder, bool ascending ) + : QPtrList() +{ + _sortOrder = sortOrder; + _ascending = ascending; +} + + +KFileInfoList::~KFileInfoList() +{ + // NOP +} + + + +KFileSize +KFileInfoList::sumTotalSizes() +{ + KFileSize sum = 0; + KFileInfoListIterator it( *this ); + + while ( *it ) + { + sum += (*it)->totalSize(); + ++it; + } + + return sum; +} + + + +int +KFileInfoList::compareItems( QCollection::Item it1, QCollection::Item it2 ) +{ + if ( it1 == it2 ) + return 0; + + KFileInfo *file1 = (KFileInfo *) it1; + KFileInfo *file2 = (KFileInfo *) it2; + + int result = 0; + + switch ( _sortOrder ) + { + case KUnsorted: + return 1; + + case KSortByName: + result = QString::compare( file1->name(), file2->name() ); + break; + + case KSortByTotalSize: + result = compare( file1->totalSize(), file2->totalSize() ); + break; + + case KSortByLatestMtime: + result = compare( file1->latestMtime(), file2->latestMtime() ); + break; + } + + return _ascending ? result : -result; +} + + + + +// EOF diff --git a/kdirstat/kdirtreeiterators.h b/kdirstat/kdirtreeiterators.h new file mode 100644 index 0000000..c3e2569 --- /dev/null +++ b/kdirstat/kdirtreeiterators.h @@ -0,0 +1,386 @@ +/* + * File name: kdirtreeiterators.h + * Summary: Support classes for KDirStat - KDirTree iterators + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KDirTreeIterators_h +#define KDirTreeIterators_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "kdirtree.h" + + +namespace KDirStat +{ + /** + * Policies how to treat a "dot entry" for iterator objects. + * See @ref KFileInfoIterator for details. + **/ + typedef enum + { + KDotEntryTransparent, // Flatten hierarchy - move dot entry children up + KDotEntryAsSubDir, // Treat dot entry as ordinary subdirectory + KDotEntryIgnore // Ignore dot entry and its children completely + } KDotEntryPolicy; + + + typedef enum + { + KUnsorted, + KSortByName, + KSortByTotalSize, + KSortByLatestMtime + } KFileInfoSortOrder; + + + // Forward declarations + class KFileInfoList; + + + /** + * Iterator class for children of a @ref KFileInfo object. For optimum + * performance, this iterator class does NOT return children in any + * specific sort order. If you need that, use @ref KFileInfoSortedIterator + * instead. + * + * Sample usage: + * + * KFileInfoIterator it( node, KDotEntryTransparent ); + * + * while ( *it ) + * { + * kdDebug() << *it << ":\t" << (*it)->totalSize() ) << endl; + * ++it; + * } + * + * This will output the URL (path+name) and the total size of each (direct) + * subdirectory child and each (direct) file child of 'node'. + * Notice: This does not recurse into subdirectories! + * + * @short (unsorted) iterator for @ref KFileInfo children. + **/ + class KFileInfoIterator + { + public: + /** + * Constructor: Initialize an iterator object to iterate over the + * children of 'parent' (unsorted!), depending on 'dotEntryPolicy': + * + * KDotEntryTransparent (default): + * + * Treat the dot entry as if it wasn't there - pretend to move all its + * children up to the real parent. This makes a directory look very + * much like the directory on disk, without the dot entry. 'current()' + * or 'operator*()' will never return the dot entry, but all of its + * children. Subdirectories will be processed before any file children. + * + * KDotEntryIsSubDir: + * + * Treat the dot entry just like any other subdirectory. Don't iterate + * over its children, too (unlike KDotEntryTransparent above). + * 'current()' or 'operator*()' will return the dot entry, but none of + * its children (unless, of course, you create an iterator with the dot + * entry as the parent). + * + * KDotEntryIgnore: + * + * Ignore the dot entry and its children completely. Useful if children + * other than subdirectories are not interesting anyway. 'current()' + * or 'operator*()' will never return the dot entry nor any of its + * children. + * + **/ + KFileInfoIterator( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy = KDotEntryTransparent ); + + protected: + /** + * Alternate constructor to be called from derived classes: Those can + * choose not to call next() in the constructor. + **/ + KFileInfoIterator ( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy, + bool callNext ); + + private: + /** + * Internal initialization called from any constructor. + **/ + void init ( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy, + bool callNext ); + + public: + + /** + * Destructor. + **/ + virtual ~KFileInfoIterator(); + + /** + * Return the current child object or 0 if there is no more. + * Same as @ref operator*() . + **/ + virtual KFileInfo * current() { return _current; } + + /** + * Return the current child object or 0 if there is no more. + * Same as @ref current(). + **/ + KFileInfo * operator*() { return current(); } + + /** + * Advance to the next child. Same as @ref operator++(). + **/ + virtual void next(); + + /** + * Advance to the next child. Same as @ref next(). + **/ + void operator++() { next(); } + + /** + * Returns 'true' if this iterator is finished and 'false' if not. + **/ + virtual bool finished() { return _current == 0; } + + /** + * Check whether or not the current child is a directory, i.e. can be + * cast to @ref KDirInfo * . + **/ + bool currentIsDir() { return _current && _current->isDirInfo(); } + + /** + * Return the current child object cast to @ref KDirInfo * or 0 if + * there either is no more or it isn't a directory. Check with @ref + * currentIsDir() before using this! + **/ + KDirInfo * currentDir() { return currentIsDir() ? (KDirInfo *) _current : 0; } + + /** + * Return the number of items that will be processed. + * This is an expensive operation. + **/ + int count(); + + + protected: + + KFileInfo * _parent; + KDotEntryPolicy _policy; + KFileInfo * _current; + bool _directChildrenProcessed; + bool _dotEntryProcessed; + bool _dotEntryChildrenProcessed; + + }; // class KFileInfoIterator + + + + /** + * Iterator class for children of a @ref KFileInfo object. This iterator + * returns children sorted by name: Subdirectories first, then the dot + * entry (if desired - depending on policy), then file children (if + * desired). Note: If you don't need the sorting feature, you might want to + * use @ref KFileItemIterator instead which has better performance. + * + * @short sorted iterator for @ref KFileInfo children. + **/ + class KFileInfoSortedIterator: public KFileInfoIterator + { + public: + /** + * Constructor. Specify the sorting order with 'sortOrder' and 'ascending'. + * See @ref KFileInfoIterator for more details. + **/ + KFileInfoSortedIterator( KFileInfo * parent, + KDotEntryPolicy dotEntryPolicy = KDotEntryTransparent, + KFileInfoSortOrder sortOrder = KSortByName, + bool ascending = true ); + /** + * Destructor. + **/ + virtual ~KFileInfoSortedIterator(); + + /** + * Return the current child object or 0 if there is no more. + * + * Inherited from @ref KFileInfoIterator. + * Overwritten to overcome some shortcomings of C++: + * Virtual methods cannot be used in the constructor. + **/ + virtual KFileInfo * current(); + + /** + * Advance to the next child. Same as @ref operator++(). + * Sort by name, sub directories first, then the dot entry (if + * desired), then files (if desired). + * + * Inherited from @ref KFileInfoIterator. + **/ + virtual void next(); + + /** + * Returns 'true' if this iterator is finished and 'false' if not. + * + * Inherited from @ref KFileInfoIterator. + **/ + virtual bool finished(); + + + protected: + + /** + * Delayed initialization for class parts that rely on availability of + * virtual methods. This is a kludge to overcome a major shortcoming of + * C++: Virtual methods are not available in the constructor yet. + * This is a neverending cause of trouble. + **/ + void delayedInit(); + + /** + * Make a 'default order' children list: + * First all subdirectories sorted by name, + * then the dot entry (depending on policy), + * then the dot entry's children (depending on policy). + **/ + virtual void makeDefaultOrderChildrenList(); + + /** + * Make a sorted children list according to the current sort + * criteria - unless KSortByName is requested, in which case + * makeDefaultOrderChildrenList() above is used. + **/ + virtual void makeChildrenList(); + + + // Data members + + KFileInfoList * _childrenList; + KFileInfoSortOrder _sortOrder; + bool _ascending; + bool _initComplete; + + }; // class KFileInfoSortedIterator + + + + /** + * Specialized KFileInfo iterator that sorts by (total) size, yet + * disregards children below a minimum size. This can considerably improve + * performance if the number of children that need to be sorted decreases + * dramatically. + * + * For example, treemaps can only display a limited portion of large + * directory trees since the number of available pixels is very + * limited. Thus, files (or directories) below a certain size usually don't + * get a individual visual representation anyway, so they may as well be + * omitted right away - no need for expensive list sorting operations. + **/ + class KFileInfoSortedBySizeIterator: public KFileInfoSortedIterator + { + public: + + /** + * Constructor. Children below 'minSize' will be ignored by this iterator. + **/ + KFileInfoSortedBySizeIterator( KFileInfo * parent, + KFileSize minSize = 0, + KDotEntryPolicy dotEntryPolicy = KDotEntryTransparent, + bool ascending = false ); + + /** + * Destructor. + **/ + virtual ~KFileInfoSortedBySizeIterator() {}; + + + protected: + + /** + * Create the (sorted) children list. Disregard children below minSize. + * Reimplemented from KFileInfoSortedIterator. + **/ + virtual void makeChildrenList(); + + + // Data members + + KFileSize _minSize; + + }; // class KFileInfoSortedBySizeIterator + + + + /** + * Internal helper class for sorting iterators. + **/ + class KFileInfoList: public QPtrList + { + public: + + /** + * Constructor. + **/ + KFileInfoList( KFileInfoSortOrder sortOrder = KSortByName, + bool ascending = true ); + + /** + * Destructor. + **/ + virtual ~KFileInfoList(); + + /** + * Returns the sum of all the total sizes in the list. + **/ + KFileSize sumTotalSizes(); + + + protected: + /** + * Comparison function. This is why this class is needed at all. + **/ + virtual int compareItems( QCollection::Item it1, QCollection::Item it2 ); + + KFileInfoSortOrder _sortOrder; + bool _ascending; + }; + + + typedef QPtrListIterator KFileInfoListIterator; + + + + //---------------------------------------------------------------------- + // Static Functions + //---------------------------------------------------------------------- + + /** + * Generic comparison function as expected by all kinds of sorting etc. + * algorithms. Requires operator<() and operator==() to be defined for this + * class. + **/ + template + inline int compare( T val1, T val2 ) + { + if ( val1 < val2 ) return -1; + else if ( val1 == val2 ) return 0; + else return 1; + } + +} // namespace KDirStat + + +#endif // ifndef KDirTreeIterators_h + + +// EOF diff --git a/kdirstat/kdirtreeview.cpp b/kdirstat/kdirtreeview.cpp new file mode 100644 index 0000000..3283efe --- /dev/null +++ b/kdirstat/kdirtreeview.cpp @@ -0,0 +1,1956 @@ +/* + * File name: kdirtreeview.cpp + * Summary: High level classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2005-01-07 + */ + + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "kdirtreeview.h" +#include "kdirtreeiterators.h" +#include "kpacman.h" + +#define SEPARATE_READ_JOBS_COL 0 +#define VERBOSE_PROGRESS_INFO 0 + +using namespace KDirStat; + + +KDirTreeView::KDirTreeView( QWidget * parent ) + : KDirTreeViewParentClass( parent ) +{ + _tree = 0; + _updateTimer = 0; + _selection = 0; + _openLevel = 1; + _doLazyClone = true; + _doPacManAnimation = false; + _updateInterval = 333; // millisec + _sortCol = -1; + + for ( int i=0; i < DEBUG_COUNTERS; i++ ) + _debugCount[i] = 0; + + setDebugFunc( 1, "KDirTreeViewItem::init()" ); + setDebugFunc( 2, "KDirTreeViewItem::updateSummary()" ); + setDebugFunc( 3, "KDirTreeViewItem::deferredClone()" ); + setDebugFunc( 4, "KDirTreeViewItem::compare()" ); + setDebugFunc( 5, "KDirTreeViewItem::paintCell()" ); + +#if SEPARATE_READ_JOBS_COL + _readJobsCol = -1; +#endif + setRootIsDecorated( false ); + + int numCol = 0; + addColumn( i18n( "Name" ) ); _nameCol = numCol; + _iconCol = numCol++; + addColumn( i18n( "Subtree Percentage" ) ); _percentBarCol = numCol++; + addColumn( i18n( "Percentage" ) ); _percentNumCol = numCol++; + addColumn( i18n( "Subtree Total" ) ); _totalSizeCol = numCol++; + _workingStatusCol = _totalSizeCol; + addColumn( i18n( "Own Size" ) ); _ownSizeCol = numCol++; + addColumn( i18n( "Items" ) ); _totalItemsCol = numCol++; + addColumn( i18n( "Files" ) ); _totalFilesCol = numCol++; + addColumn( i18n( "Subdirs" ) ); _totalSubDirsCol = numCol++; + addColumn( i18n( "Last Change" ) ); _latestMtimeCol = numCol++; + +#if ! SEPARATE_READ_JOBS_COL + _readJobsCol = _percentBarCol; +#endif + + setColumnAlignment ( _totalSizeCol, AlignRight ); + setColumnAlignment ( _percentNumCol, AlignRight ); + setColumnAlignment ( _ownSizeCol, AlignRight ); + setColumnAlignment ( _totalItemsCol, AlignRight ); + setColumnAlignment ( _totalFilesCol, AlignRight ); + setColumnAlignment ( _totalSubDirsCol, AlignRight ); + setColumnAlignment ( _readJobsCol, AlignRight ); + + + setSorting( _totalSizeCol ); + + +#define loadIcon(ICON) KGlobal::iconLoader()->loadIcon( (ICON), KIcon::Small ) + + _openDirIcon = loadIcon( "folder_open" ); + _closedDirIcon = loadIcon( "folder" ); + _openDotEntryIcon = loadIcon( "folder_orange_open"); + _closedDotEntryIcon = loadIcon( "folder_orange" ); + _unreadableDirIcon = loadIcon( "folder_locked" ); + _mountPointIcon = loadIcon( "hdd_mount" ); + _fileIcon = loadIcon( "mime_empty" ); + _symLinkIcon = loadIcon( "symlink" ); // The KDE standard link icon is ugly! + _blockDevIcon = loadIcon( "blockdevice" ); + _charDevIcon = loadIcon( "chardevice" ); + _fifoIcon = loadIcon( "socket" ); + _stopIcon = loadIcon( "stop" ); + _readyIcon = QPixmap(); + +#undef loadIcon + + setDefaultFillColors(); + readConfig(); + ensureContrast(); + + + connect( kapp, SIGNAL( kdisplayPaletteChanged() ), + this, SLOT ( paletteChanged() ) ); + + connect( this, SIGNAL( selectionChanged ( QListViewItem * ) ), + this, SLOT ( selectItem ( QListViewItem * ) ) ); + + connect( this, SIGNAL( rightButtonPressed ( QListViewItem *, const QPoint &, int ) ), + this, SLOT ( popupContextMenu ( QListViewItem *, const QPoint &, int ) ) ); + + connect( header(), SIGNAL( sizeChange ( int, int, int ) ), + this, SLOT ( columnResized( int, int, int ) ) ); + + _contextInfo = new QPopupMenu; + _idContextInfo = _contextInfo->insertItem ( "dummy" ); +} + + +KDirTreeView::~KDirTreeView() +{ + if ( _tree ) + delete _tree; + + /* + * Don't delete _updateTimer here, it's already automatically deleted by Qt! + * (Since it's derived from QObject and has a QObject parent). + */ +} + + +void +KDirTreeView::setDebugFunc( int i, const QString & functionName ) +{ + if ( i > 0 && i < DEBUG_COUNTERS ) + _debugFunc[i] = functionName; +} + + +void +KDirTreeView::incDebugCount( int i ) +{ + if ( i > 0 && i < DEBUG_COUNTERS ) + _debugCount[i]++; +} + + +void +KDirTreeView::busyDisplay() +{ +#if SEPARATE_READ_JOBS_COL + if ( _readJobsCol < 0 ) + { + _readJobsCol = header()->count(); + addColumn( i18n( "Read Jobs" ) ); + setColumnAlignment( _readJobsCol, AlignRight ); + } +#else + _readJobsCol = _percentBarCol; +#endif +} + + +void +KDirTreeView::idleDisplay() +{ +#if SEPARATE_READ_JOBS_COL + if ( _readJobsCol >= 0 ) + { + removeColumn( _readJobsCol ); + } +#else + if ( _sortCol == _readJobsCol && _sortCol >= 0 ) + { + // A pathological case: The user requested sorting by read jobs, and + // now that everything is read, the items are still in that sort order. + // Not only is that sort order now useless (since all read jobs are + // done), it is contrary to the (now changed) semantics of this + // column. Calling QListView::sort() might do the trick, but we can + // never know just how clever that QListView widget tries to be and + // maybe avoid another sorting by the same column - so let's use the + // easy way out and sort by another column that has the same sorting + // semantics like the percentage bar column (that had doubled as the + // read job column while reading) now has. + + setSorting( _percentNumCol ); + } +#endif + + _readJobsCol = -1; +} + + +void +KDirTreeView::openURL( KURL url ) +{ + // Clean up any old leftovers + + clear(); + _currentDir = ""; + + if ( _tree ) + delete _tree; + + + // Create new (empty) dir tree + + _tree = new KDirTree(); + + + // Connect signals + + connect( _tree, SIGNAL( progressInfo ( const QString & ) ), + this, SLOT ( sendProgressInfo( const QString & ) ) ); + + connect( _tree, SIGNAL( childAdded( KFileInfo * ) ), + this, SLOT ( addChild ( KFileInfo * ) ) ); + + connect( _tree, SIGNAL( deletingChild( KFileInfo * ) ), + this, SLOT ( deleteChild ( KFileInfo * ) ) ); + + connect( _tree, SIGNAL( startingReading() ), + this, SLOT ( prepareReading() ) ); + + connect( _tree, SIGNAL( finished() ), + this, SLOT ( slotFinished() ) ); + + connect( _tree, SIGNAL( aborted() ), + this, SLOT ( slotAborted() ) ); + + connect( _tree, SIGNAL( finalizeLocal( KDirInfo * ) ), + this, SLOT ( finalizeLocal( KDirInfo * ) ) ); + + connect( this, SIGNAL( selectionChanged( KFileInfo * ) ), + _tree, SLOT ( selectItem ( KFileInfo * ) ) ); + + connect( _tree, SIGNAL( selectionChanged( KFileInfo * ) ), + this, SLOT ( selectItem ( KFileInfo * ) ) ); + + // Implicitly calling prepareReading() via the tree's startingReading() signal + _tree->startReading( url ); + + logActivity( 30 ); +} + + +void +KDirTreeView::prepareReading() +{ + + // Prepare cyclic update + + if ( _updateTimer ) + delete _updateTimer; + + _updateTimer = new QTimer( this ); + + if ( _updateTimer ) + { + _updateTimer->changeInterval( _updateInterval ); + connect( _updateTimer, SIGNAL( timeout() ), + this, SLOT ( updateSummary() ) ); + + connect( _updateTimer, SIGNAL( timeout() ), + this, SLOT ( sendProgressInfo() ) ); + } + + + // Change display to busy state + + setSorting( _totalSizeCol ); + busyDisplay(); + emit startingReading(); + + + // Actually do something + + _stopWatch.start(); +} + + +void +KDirTreeView::refreshAll() +{ + if ( _tree && _tree->root() ) + { + clear(); + // Implicitly calling prepareReading() via the tree's startingReading() signal + _tree->refresh( 0 ); + } +} + + +void +KDirTreeView::refreshSelected() +{ + if ( _tree && _tree->root() && _selection ) + { + // Implicitly calling prepareReading() via the tree's startingReading() signal + _tree->refresh( _selection->orig() ); + } + + logActivity( 10 ); +} + + +void +KDirTreeView::abortReading() +{ + if ( _tree ) + _tree->abortReading(); +} + + +void +KDirTreeView::clear() +{ + clearSelection(); + KDirTreeViewParentClass::clear(); + + for ( int i=0; i < DEBUG_COUNTERS; i++ ) + _debugCount[i] = 0; +} + + +void +KDirTreeView::addChild( KFileInfo *newChild ) +{ + if ( newChild->parent() ) + { + KDirTreeViewItem *cloneParent = locate( newChild->parent(), + _doLazyClone, // lazy + true ); // doClone + + if ( cloneParent ) + { + if ( isOpen( cloneParent ) || ! _doLazyClone ) + { + // kdDebug() << "Immediately cloning " << newChild << endl; + new KDirTreeViewItem( this, cloneParent, newChild ); + } + } + else // Error + { + if ( ! _doLazyClone ) + { + kdError() << k_funcinfo << "Can't find parent view item for " + << newChild << endl; + } + } + } + else // No parent - top level item + { + // kdDebug() << "Immediately top level cloning " << newChild << endl; + new KDirTreeViewItem( this, newChild ); + } +} + + +void +KDirTreeView::deleteChild( KFileInfo *child ) +{ + KDirTreeViewItem *clone = locate( child, + false, // lazy + false ); // doClone + KDirTreeViewItem *nextSelection = 0; + + if ( clone ) + { + if ( clone == _selection ) + { + /** + * The selected item is about to be deleted. Select some other item + * so there is still something selected: Preferably the next item + * or the parent if there is no next. This cannot be done from + * outside because the order of items is not known to the outside; + * it might appear very random if the next item in the KFileInfo + * list would be selected. The order of that list is definitely + * different than the order of this view - which is what the user + * sees. So let's give the user a reasonable next selection so he + * can continue working without having to explicitly select another + * item. + * + * This is very useful if the user just activated a cleanup action + * that deleted an item: It makes sense to implicitly select the + * next item so he can clean up many items in a row. + **/ + + nextSelection = clone->next() ? clone->next() : clone->parent(); + // kdDebug() << k_funcinfo << " Next selection: " << nextSelection << endl; + } + + KDirTreeViewItem *parent = clone->parent(); + delete clone; + + while ( parent ) + { + parent->updateSummary(); + parent = parent->parent(); + } + + if ( nextSelection ) + selectItem( nextSelection ); + } +} + + +void +KDirTreeView::updateSummary() +{ + KDirTreeViewItem *child = firstChild(); + + while ( child ) + { + child->updateSummary(); + child = child->next(); + } +} + + +void +KDirTreeView::slotFinished() +{ + emit progressInfo( i18n( "Finished. Elapsed time: %1" ) + .arg( formatTime( _stopWatch.elapsed(), true ) ) ); + + if ( _updateTimer ) + { + delete _updateTimer; + _updateTimer = 0; + } + + idleDisplay(); + updateSummary(); + logActivity( 30 ); + +#if 0 + for ( int i=0; i < DEBUG_COUNTERS; i++ ) + { + kdDebug() << "Debug counter #" << i << ": " << _debugCount[i] + << "\t" << _debugFunc[i] + << endl; + } + kdDebug() << endl; +#endif + + emit finished(); +} + + +void +KDirTreeView::slotAborted() +{ + emit progressInfo( i18n( "Aborted. Elapsed time: %1" ) + .arg( formatTime( _stopWatch.elapsed(), true ) ) ); + + if ( _updateTimer ) + { + delete _updateTimer; + _updateTimer = 0; + } + + idleDisplay(); + updateSummary(); + + emit aborted(); +} + + +void +KDirTreeView::finalizeLocal( KDirInfo *dir ) +{ + if ( dir ) + { + KDirTreeViewItem *clone = locate( dir, + false, // lazy + false ); // doClone + if ( clone ) + clone->finalizeLocal(); + } +} + + +void +KDirTreeView::sendProgressInfo( const QString & newCurrentDir ) +{ + _currentDir = newCurrentDir; + +#if VERBOSE_PROGRESS_INFO + emit progressInfo( i18n( "Elapsed time: %1 reading directory %2" ) + .arg( formatTime( _stopWatch.elapsed() ) ) + .arg( _currentDir ) ); +#else + emit progressInfo( i18n( "Elapsed time: %1" ) + .arg( formatTime( _stopWatch.elapsed() ) ) ); +#endif +} + + +#if QT_VERSION < 300 +void +KDirTreeView::sendProgressInfo() +{ + sendProgressInfo( _currentDir ); +} +#endif + + +KDirTreeViewItem * +KDirTreeView::locate( KFileInfo *wanted, bool lazy, bool doClone ) +{ + KDirTreeViewItem *child = firstChild(); + + while ( child ) + { + KDirTreeViewItem *wantedChild = child->locate( wanted, lazy, doClone, 0 ); + + if ( wantedChild ) + return wantedChild; + else + child = child->next(); + } + + return 0; +} + + + +int +KDirTreeView::openCount() +{ + int count = 0; + KDirTreeViewItem *child = firstChild(); + + while ( child ) + { + count += child->openCount(); + child = child->next(); + } + + return count; +} + + +void +KDirTreeView::selectItem( QListViewItem *listViewItem ) +{ + _selection = dynamic_cast( listViewItem ); + + if ( _selection ) + { + // kdDebug() << k_funcinfo << " Selecting item " << _selection << endl; + setSelected( _selection, true ); + } + else + { + // kdDebug() << k_funcinfo << " Clearing selection" << endl; + clearSelection(); + } + + + emit selectionChanged( _selection ); + emit selectionChanged( _selection ? _selection->orig() : (KFileInfo *) 0 ); +} + + +void +KDirTreeView::selectItem( KFileInfo *newSelection ) +{ + // Short-circuit for the most common case: The signal has been triggered by + // this view, and the KDirTree has sent it right back. + + if ( _selection && _selection->orig() == newSelection ) + return; + + if ( ! newSelection ) + clearSelection(); + else + { + _selection = locate( newSelection, + false, // lazy + true ); // doClone + if ( _selection ) + { + closeAllExcept( _selection ); + _selection->setOpen( false ); + ensureItemVisible( _selection ); + emit selectionChanged( _selection ); + setSelected( _selection, true ); + } + else + kdError() << "Couldn't clone item " << newSelection << endl; + } +} + + +void +KDirTreeView::clearSelection() +{ + // kdDebug() << k_funcinfo << endl; + _selection = 0; + QListView::clearSelection(); + + emit selectionChanged( (KDirTreeViewItem *) 0 ); + emit selectionChanged( (KFileInfo *) 0 ); +} + + +void +KDirTreeView::closeAllExcept( KDirTreeViewItem *except ) +{ + if ( ! except ) + { + kdError() << k_funcinfo << ": NULL pointer passed" << endl; + return; + } + + except->closeAllExceptThis(); +} + + +const QColor & +KDirTreeView::fillColor( int level ) const +{ + if ( level < 0 ) + { + level = 0; + kdWarning() << k_funcinfo << "Invalid argument: " << level << endl; + } + + return _fillColor [ level % _usedFillColors ]; +} + + +const QColor & +KDirTreeView::rawFillColor( int level ) const +{ + if ( level < 0 || level > KDirTreeViewMaxFillColor ) + { + level = 0; + kdWarning() << k_funcinfo << "Invalid argument: " << level << endl; + } + + return _fillColor [ level % KDirTreeViewMaxFillColor ]; +} + + +void +KDirTreeView::setFillColor( int level, + const QColor & color ) +{ + if ( level >= 0 && level < KDirTreeViewMaxFillColor ) + _fillColor[ level ] = color; +} + + + +void +KDirTreeView::setUsedFillColors( int usedFillColors ) +{ + if ( usedFillColors < 1 ) + { + kdWarning() << k_funcinfo << "Invalid argument: "<< usedFillColors << endl; + usedFillColors = 1; + } + else if ( usedFillColors >= KDirTreeViewMaxFillColor ) + { + kdWarning() << k_funcinfo << "Invalid argument: "<< usedFillColors + << " (max: " << KDirTreeViewMaxFillColor-1 << ")" << endl; + usedFillColors = KDirTreeViewMaxFillColor-1; + } + + _usedFillColors = usedFillColors; +} + + +void +KDirTreeView::setDefaultFillColors() +{ + int i; + + for ( i=0; i < KDirTreeViewMaxFillColor; i++ ) + { + _fillColor[i] = blue; + } + + i = 0; + _usedFillColors = 4; + + setFillColor ( i++, QColor ( 0, 0, 255 ) ); + setFillColor ( i++, QColor ( 128, 0, 128 ) ); + setFillColor ( i++, QColor ( 231, 147, 43 ) ); + setFillColor ( i++, QColor ( 4, 113, 0 ) ); + setFillColor ( i++, QColor ( 176, 0, 0 ) ); + setFillColor ( i++, QColor ( 204, 187, 0 ) ); + setFillColor ( i++, QColor ( 162, 98, 30 ) ); + setFillColor ( i++, QColor ( 0, 148, 146 ) ); + setFillColor ( i++, QColor ( 217, 94, 0 ) ); + setFillColor ( i++, QColor ( 0, 194, 65 ) ); + setFillColor ( i++, QColor ( 194, 108, 187 ) ); + setFillColor ( i++, QColor ( 0, 179, 255 ) ); +} + + +void +KDirTreeView::setTreeBackground( const QColor &color ) +{ + _treeBackground = color; + _percentageBarBackground = _treeBackground.dark( 115 ); + + QPalette pal = kapp->palette(); + pal.setBrush( QColorGroup::Base, _treeBackground ); + setPalette( pal ); +} + + +void +KDirTreeView::ensureContrast() +{ + if ( colorGroup().base() == white || + colorGroup().base() == black ) + { + setTreeBackground( colorGroup().midlight() ); + } + else + { + setTreeBackground( colorGroup().base() ); + } +} + + +void +KDirTreeView::paletteChanged() +{ + setTreeBackground( KGlobalSettings::baseColor() ); + ensureContrast(); +} + + +void +KDirTreeView::popupContextMenu( QListViewItem * listViewItem, + const QPoint & pos, + int column ) +{ + KDirTreeViewItem *item = (KDirTreeViewItem *) listViewItem; + + if ( ! item ) + return; + + if ( column == _nameCol || + column == _percentBarCol || + column == _percentNumCol ) + { + // Make the item the context menu is popping up over the current + // selection - all user operations refer to the current selection. + // Just right-clicking on an item does not make it the current + // item! + selectItem( item ); + + // Let somebody from outside pop up the context menu, if so desired. + emit contextMenu( item, pos ); + } + + + // If the column is one with a large size in kB/MB/GB, open a + // info popup with the exact number. + + if ( column == _ownSizeCol && ! item->orig()->isDotEntry() ) + { + KFileInfo * orig = item->orig(); + + if ( orig->isSparseFile() || ( orig->links() > 1 && orig->isFile() ) ) + { + QString text; + + if ( orig->isSparseFile() ) + { + text = i18n( "Sparse file: %1 (%2 Bytes) -- allocated: %3 (%4 Bytes)" ) + .arg( formatSize( orig->byteSize() ) ) + .arg( formatSizeLong( orig->byteSize() ) ) + .arg( formatSize( orig->allocatedSize() ) ) + .arg( formatSizeLong( orig->allocatedSize() ) ); + } + else + { + text = i18n( "%1 (%2 Bytes) with %3 hard links => effective size: %4 (%5 Bytes)" ) + .arg( formatSize( orig->byteSize() ) ) + .arg( formatSizeLong( orig->byteSize() ) ) + .arg( orig->links() ) + .arg( formatSize( orig->size() ) ) + .arg( formatSizeLong( orig->size() ) ); + } + + popupContextInfo( pos, text ); + } + else + { + popupContextSizeInfo( pos, orig->size() ); + } + } + + if ( column == _totalSizeCol && + ( item->orig()->isDir() || item->orig()->isDotEntry() ) ) + { + popupContextSizeInfo( pos, item->orig()->totalSize() ); + } + + + // Show alternate time / date format in time / date related columns. + + if ( column == _latestMtimeCol ) + { + popupContextInfo( pos, formatTimeDate( item->orig()->latestMtime() ) ); + } + + logActivity( 3 ); +} + + +void +KDirTreeView::popupContextSizeInfo( const QPoint & pos, + KFileSize size ) +{ + QString info; + + if ( size < 1024 ) + { + info = formatSizeLong( size ) + " " + i18n( "Bytes" ); + } + else + { + info = i18n( "%1 (%2 Bytes)" ) + .arg( formatSize( size ) ) + .arg( formatSizeLong( size ) ); + } + + popupContextInfo( pos, info ); +} + + +void +KDirTreeView::popupContextInfo( const QPoint & pos, + const QString & info ) +{ + _contextInfo->changeItem( info, _idContextInfo ); + _contextInfo->popup( pos ); +} + + +void +KDirTreeView::readConfig() +{ + KConfig *config = kapp->config(); + KConfigGroupSaver saver( config, "Tree Colors" ); + _usedFillColors = config->readNumEntry( "usedFillColors", -1 ); + + if ( _usedFillColors < 0 ) + { + /* + * No 'usedFillColors' in the config file? Better forget that + * file and use default values. Otherwise, all colors would very + * likely become blue - the default color. + */ + setDefaultFillColors(); + } + else + { + // Read the rest of the 'Tree Colors' section + + QColor defaultColor( blue ); + + for ( int i=0; i < KDirTreeViewMaxFillColor; i++ ) + { + QString name; + name.sprintf( "fillColor_%02d", i ); + _fillColor [i] = config->readColorEntry( name, &defaultColor ); + } + } + + if ( isVisible() ) + triggerUpdate(); +} + + +void +KDirTreeView::saveConfig() const +{ + KConfig *config = kapp->config(); + KConfigGroupSaver saver( config, "Tree Colors" ); + + config->writeEntry( "usedFillColors", _usedFillColors ); + + for ( int i=0; i < KDirTreeViewMaxFillColor; i++ ) + { + QString name; + name.sprintf( "fillColor_%02d", i ); + config->writeEntry ( name, _fillColor [i] ); + } +} + + +void +KDirTreeView::setSorting( int column, bool increasing ) +{ + _sortCol = column; + QListView::setSorting( column, increasing ); +} + + +void +KDirTreeView::logActivity( int points ) +{ + emit userActivity( points ); +} + + +void +KDirTreeView::columnResized( int column, int oldSize, int newSize ) +{ + NOT_USED( oldSize ); + NOT_USED( newSize ); + + if ( column == _percentBarCol ) + triggerUpdate(); +} + +void +KDirTreeView::sendMailToOwner() +{ + if ( ! _selection ) + { + kdError() << k_funcinfo << "Nothing selected!" << endl; + return; + } + + QString owner = KAnyDirReadJob::owner( fixedUrl( _selection->orig()->url() ) ); + QString subject = i18n( "Disk Usage" ); + QString body = + i18n("Please check your disk usage and clean up if you can. Thank you." ) + + "\n\n" + + _selection->asciiDump() + + "\n\n" + + i18n( "Disk usage report generated by KDirStat" ) + + "\nhttp://kdirstat.sourceforge.net/"; + + // kdDebug() << "owner: " << owner << endl; + // kdDebug() << "subject: " << subject << endl; + // kdDebug() << "body:\n" << body << endl; + + KURL mail; + mail.setProtocol( "mailto" ); + mail.setPath( owner ); + mail.setQuery( "?subject=" + KURL::encode_string( subject ) + + "&body=" + KURL::encode_string( body ) ); + + // TODO: Check for maximum command line length. + // + // The hard part with this is how to get this from all that 'autoconf' + // stuff into 'config.h' or some other include file without hardcoding + // anything - this is too system dependent. + + kapp->invokeMailer( mail ); + logActivity( 10 ); +} + + + + + + +KDirTreeViewItem::KDirTreeViewItem( KDirTreeView * view, + KFileInfo * orig ) + : QListViewItem( view ) +{ + init( view, 0, orig ); +} + + +KDirTreeViewItem::KDirTreeViewItem( KDirTreeView * view, + KDirTreeViewItem * parent, + KFileInfo * orig ) + : QListViewItem( parent ) +{ + CHECK_PTR( parent ); + init( view, parent, orig ); +} + + +void +KDirTreeViewItem::init( KDirTreeView * view, + KDirTreeViewItem * parent, + KFileInfo * orig ) +{ + _view = view; + _parent = parent; + _orig = orig; + _percent = 0.0; + _pacMan = 0; + _openCount = 0; + + // _view->incDebugCount(1); + // kdDebug() << "new KDirTreeViewItem for " << orig << endl; + + if ( _orig->isDotEntry() ) + { + setText( view->nameCol(), i18n( "" ) ); + QListViewItem::setOpen ( false ); + } + else + { + setText( view->nameCol(), QString::fromLocal8Bit(_orig->name()) ); + + if ( ! _orig->isDevice() ) + { + QString text; + + if ( _orig->isFile() && ( _orig->links() > 1 ) ) // Regular file with multiple links + { + if ( _orig->isSparseFile() ) + { + text = i18n( "%1 / %2 Links (allocated: %3)" ) + .arg( formatSize( _orig->byteSize() ) ) + .arg( formatSize( _orig->links() ) ) + .arg( formatSize( _orig->allocatedSize() ) ); + } + else + { + text = i18n( "%1 / %2 Links" ) + .arg( formatSize( _orig->byteSize() ) ) + .arg( _orig->links() ); + } + } + else // No multiple links or no regular file + { + if ( _orig->isSparseFile() ) + { + text = i18n( "%1 (allocated: %2)" ) + .arg( formatSize( _orig->byteSize() ) ) + .arg( formatSize( _orig->allocatedSize() ) ); + } + else + { + text = formatSize( _orig->size() ); + } + } + + setText( view->ownSizeCol(), text ); + } + + QListViewItem::setOpen ( _orig->treeLevel() < _view->openLevel() ); + /* + * Don't use KDirTreeViewItem::setOpen() here since this might call + * KDirTreeViewItem::deferredClone() which would confuse bookkeeping + * with addChild() signals that might arrive, too - resulting in double + * dot entries. + */ + } + + if ( _view->doLazyClone() && + ( _orig->isDir() || _orig->isDotEntry() ) ) + { + /* + * Determine whether or not this item can be opened. + * + * Normally, Qt handles this very well, but when lazy cloning is in + * effect, Qt cannot know whether or not there are children - they may + * only be in the original tree until the user tries to open this + * item. So let's assume there may be children as long as the directory + * is still being read. + */ + + if ( _orig->readState() == KDirQueued || + _orig->readState() == KDirReading ) + { + setExpandable( true ); + } + else // KDirFinished, KDirError, KDirAborted + { + setExpandable( _orig->hasChildren() ); + } + } + + if ( ! parent || parent->isOpen() ) + { + setIcon(); + } + + _openCount = isOpen() ? 1 : 0; +} + + +KDirTreeViewItem::~KDirTreeViewItem() +{ + if ( _pacMan ) + delete _pacMan; + + if ( this == _view->selection() ) + _view->clearSelection(); +} + + +void +KDirTreeViewItem::setIcon() +{ + QPixmap icon; + + if ( _orig->isDotEntry() ) + { + icon = isOpen() ? _view->openDotEntryIcon() : _view->closedDotEntryIcon(); + } + else if ( _orig->isDir() ) + { + if ( _orig->readState() == KDirAborted ) icon = _view->stopIcon(); + else if ( _orig->readState() == KDirError ) + { + icon = _view->unreadableDirIcon(); + setExpandable( false ); + } + else + { + if ( _orig->isMountPoint() ) + { + icon = _view->mountPointIcon(); + } + else + { + icon = isOpen() ? _view->openDirIcon() : _view->closedDirIcon(); + } + } + } + else if ( _orig->isFile() ) icon = _view->fileIcon(); + else if ( _orig->isSymLink() ) icon = _view->symLinkIcon(); + else if ( _orig->isBlockDevice() ) icon = _view->blockDevIcon(); + else if ( _orig->isCharDevice() ) icon = _view->charDevIcon(); + else if ( _orig->isSpecial() ) icon = _view->fifoIcon(); + + setPixmap( _view->iconCol(), icon ); +} + + +void +KDirTreeViewItem::updateSummary() +{ + // _view->incDebugCount(2); + + // Update this item + + setIcon(); + setText( _view->latestMtimeCol(), " " + localeTimeDate( _orig->latestMtime() ) ); + + if ( _orig->isDir() || _orig->isDotEntry() ) + { + QString prefix = " "; + + if ( _orig->readState() == KDirAborted ) + prefix = " >"; + + setText( _view->totalSizeCol(), prefix + formatSize( _orig->totalSize() ) ); + setText( _view->totalItemsCol(), prefix + formatCount( _orig->totalItems() ) ); + setText( _view->totalFilesCol(), prefix + formatCount( _orig->totalFiles() ) ); + + if ( _view->readJobsCol() >= 0 ) + { +#if SEPARATE_READ_JOBS_COL + setText( _view->readJobsCol(), " " + formatCount( _orig->pendingReadJobs(), true ) ); +#else + int jobs = _orig->pendingReadJobs(); + QString text = ""; + + if ( jobs > 0 ) + text = i18n( "[%1 Read Jobs]" ).arg( formatCount( _orig->pendingReadJobs(), true ) ); + setText( _view->readJobsCol(), text ); +#endif + } + } + + if ( _orig->isDir() ) + { + setText( _view->totalSubDirsCol(), " " + formatCount( _orig->totalSubDirs() ) ); + } + + + // Calculate and display percentage + + if ( _orig->parent() && // only if there is a parent as calculation base + _orig->parent()->pendingReadJobs() < 1 && // not before subtree is finished reading + _orig->parent()->totalSize() > 0 ) // avoid division by zero + { + _percent = ( 100.0 * _orig->totalSize() ) / (float) _orig->parent()->totalSize(); + setText( _view->percentNumCol(), formatPercent ( _percent ) ); + } + else + { + _percent = 0.0; + setText( _view->percentNumCol(), "" ); + } + + if ( _view->doPacManAnimation() && _orig->isBusy() ) + { + if ( ! _pacMan ) + _pacMan = new KPacManAnimation( _view, height()-4, true ); + + repaint(); + } + + + if ( ! isOpen() ) // Lazy update: Nobody can see the children + return; // -> don't update them. + + + // Update all children + + KDirTreeViewItem *child = firstChild(); + + while ( child ) + { + child->updateSummary(); + child = child->next(); + } +} + + +KDirTreeViewItem * +KDirTreeViewItem::locate( KFileInfo * wanted, + bool lazy, + bool doClone, + int level ) +{ + if ( lazy && ! isOpen() ) + { + /* + * In "lazy" mode, we don't bother searching all the children of this + * item if they are not visible (i.e. the branch is open) anyway. In + * this case, cloning that branch is deferred until the branch is + * actually opened - which in most cases will never happen anyway (most + * users don't manually open each and every subtree). If and when it + * happens, we'll probably be fast enough bringing the view tree in + * sync with the original tree since opening a branch requires manual + * interaction which is a whole lot slower than copying a couple of + * objects. + * + * Note that this mode is _independent_ of lazy cloning in general: The + * caller explicitly specifies if he wants to locate an item at all + * cost, even if that means deferred cloning children whose creation + * has been delayed until now. + */ + + // kdDebug() << "Too lazy to search for " << wanted << " from " << this << endl; + return 0; + } + + if ( _orig == wanted ) + { + return this; + } + + if ( level < 0 ) + level = _orig->treeLevel(); + + if ( wanted->urlPart( level ) == _orig->name() ) + { + // Search all children + + KDirTreeViewItem *child = firstChild(); + + if ( ! child && _orig->hasChildren() && doClone ) + { + // kdDebug() << "Deferred cloning " << this << " for children search of " << wanted << endl; + deferredClone(); + child = firstChild(); + } + + while ( child ) + { + KDirTreeViewItem *foundChild = child->locate( wanted, lazy, doClone, level+1 ); + + if ( foundChild ) + return foundChild; + else + child = child->next(); + } + } + + return 0; +} + + +void +KDirTreeViewItem::deferredClone() +{ + // _view->incDebugCount(3); + + if ( ! _orig->hasChildren() ) + { + // kdDebug() << k_funcinfo << "Oops, no children - sorry for bothering you!" << endl; + setExpandable( false ); + + return; + } + + + // Clone all normal children + + int level = _orig->treeLevel(); + bool startingClean = ! firstChild(); + KFileInfo *origChild = _orig->firstChild(); + + while ( origChild ) + { + if ( startingClean || + ! locate( origChild, + false, // lazy + true, // doClone + level ) ) + { + // kdDebug() << "Deferred cloning " << origChild << endl; + new KDirTreeViewItem( _view, this, origChild ); + } + + origChild = origChild->next(); + } + + + // Clone the dot entry + + if ( _orig->dotEntry() && + ( startingClean || + ! locate( _orig->dotEntry(), + false, // lazy + true, // doClone + level ) + ) + ) + { + // kdDebug() << "Deferred cloning dot entry for " << _orig << endl; + new KDirTreeViewItem( _view, this, _orig->dotEntry() ); + } +} + + +void +KDirTreeViewItem::finalizeLocal() +{ + // kdDebug() << k_funcinfo << _orig << endl; + cleanupDotEntries(); + + if ( _orig->totalItems() == 0 ) + // _orig->hasChildren() would give a wrong answer here since it counts + // the dot entry, too - which might be removed a moment later. + { + setExpandable( false ); + } +} + + +void +KDirTreeViewItem::cleanupDotEntries() +{ + if ( ! _orig->dotEntry() ) + return; + + KDirTreeViewItem *dotEntry = findDotEntry(); + + if ( ! dotEntry ) + return; + + + // Reparent dot entry children if there are no subdirectories on this level + + if ( ! _orig->firstChild() ) + { + // kdDebug() << "Removing solo dot entry clone " << _orig << endl; + KDirTreeViewItem *child = dotEntry->firstChild(); + + while ( child ) + { + KDirTreeViewItem *nextChild = child->next(); + + + // Reparent this child + + // kdDebug() << "Reparenting clone " << child << endl; + dotEntry->removeItem( child ); + insertItem( child ); + + child = nextChild; + } + + /* + * Immediately delete the (now emptied) dot entry. The algorithm for + * the original tree doesn't quite fit here - there, the dot entry is + * actually deleted in the step below. But the 'no children' check for + * this fails here since the original dot entry still _has_ its + * children - they will be deleted only after all clones have been + * processed. + * + * This had been the cause for a core that took me quite some time to + * track down. + */ + delete dotEntry; + dotEntry = 0; + } + + + // Delete dot entries without any children + + if ( ! _orig->dotEntry()->firstChild() && dotEntry ) + { + // kdDebug() << "Removing empty dot entry clone " << _orig << endl; + delete dotEntry; + } +} + + +KDirTreeViewItem * +KDirTreeViewItem::findDotEntry() const +{ + KDirTreeViewItem *child = firstChild(); + + while ( child ) + { + if ( child->orig()->isDotEntry() ) + return child; + + child = child->next(); + } + + return 0; +} + + +void +KDirTreeViewItem::setOpen( bool open ) +{ + if ( open && _view->doLazyClone() ) + { + // kdDebug() << "Opening " << this << endl; + deferredClone(); + } + + if ( isOpen() != open ) + { + openNotify( open ); + } + + QListViewItem::setOpen( open ); + setIcon(); + + if ( open ) + updateSummary(); + + // kdDebug() << _openCount << " open in " << this << endl; + + // _view->logActivity( 1 ); +} + + +void +KDirTreeViewItem::openNotify( bool open ) +{ + if ( open ) + _openCount++; + else + _openCount--; + + if ( _parent ) + _parent->openNotify( open ); +} + + +void +KDirTreeViewItem::openSubtree() +{ + if ( parent() ) + parent()->setOpen( true ); + + setOpen( true ); +} + + +void +KDirTreeViewItem::closeSubtree() +{ + setOpen( false ); + + if ( _openCount > 0 ) + { + KDirTreeViewItem * child = firstChild(); + + while ( child ) + { + child->closeSubtree(); + child = child->next(); + } + } + + _openCount = 0; // just to be sure +} + + +void +KDirTreeViewItem::closeAllExceptThis() +{ + KDirTreeViewItem *sibling = _parent ? + _parent->firstChild() : _view->firstChild(); + + while ( sibling ) + { + if ( sibling != this ) + sibling->closeSubtree(); // Recurse down + + sibling = sibling->next(); + } + + setOpen( true ); + + if ( _parent ) + _parent->closeAllExceptThis(); // Recurse up +} + + +QString +KDirTreeViewItem::asciiDump() +{ + QString dump; + + dump.sprintf( "%10s %s\n", + (const char *) formatSize( _orig->totalSize() ), + (const char *) _orig->debugUrl() ); + + if ( isOpen() ) + { + KDirTreeViewItem *child = firstChild(); + + while ( child ) + { + dump += child->asciiDump(); + child = child->next(); + } + } + + return dump; +} + + +/** + * Comparison function used for sorting the list. + * Returns: + * -1 if this < other + * 0 if this == other + * +1 if this > other + **/ +int +KDirTreeViewItem::compare( QListViewItem * otherListViewItem, + int column, + bool ascending ) const +{ + // _view->incDebugCount(4); + KDirTreeViewItem * other = dynamic_cast (otherListViewItem); + + if ( other ) + { + KFileInfo * otherOrig = other->orig(); + +#if ! SEPARATE_READ_JOBS_COL + if ( column == _view->readJobsCol() ) return - compare( _orig->pendingReadJobs(), otherOrig->pendingReadJobs() ); + else +#endif + if ( column == _view->totalSizeCol() || + column == _view->percentNumCol() || + column == _view->percentBarCol() ) return - compare( _orig->totalSize(), otherOrig->totalSize() ); + + else if ( column == _view->ownSizeCol() ) return - compare( _orig->size(), otherOrig->size() ); + else if ( column == _view->totalItemsCol() ) return - compare( _orig->totalItems(), otherOrig->totalItems() ); + else if ( column == _view->totalFilesCol() ) return - compare( _orig->totalFiles(), otherOrig->totalFiles() ); + else if ( column == _view->totalSubDirsCol() ) return - compare( _orig->totalSubDirs(), otherOrig->totalSubDirs() ); + else if ( column == _view->latestMtimeCol() ) return - compare( _orig->latestMtime(), otherOrig->latestMtime() ); + else + { + if ( _orig->isDotEntry() ) // make sure dot entries are last in the list + return 1; + + if ( otherOrig->isDotEntry() ) + return -1; + } + } + + return QListViewItem::compare( otherListViewItem, column, ascending ); +} + + +void +KDirTreeViewItem::paintCell( QPainter * painter, + const QColorGroup & colorGroup, + int column, + int width, + int alignment ) +{ + // _view->incDebugCount(5); + + if ( column == _view->percentBarCol() ) + { + painter->setBackgroundColor( colorGroup.base() ); + + if ( _percent > 0.0 ) + { + if ( _pacMan ) + { + delete _pacMan; + _pacMan = 0; + } + + int level = _orig->treeLevel(); + paintPercentageBar ( _percent, + painter, + _view->treeStepSize() * ( level-1 ), + width, + _view->fillColor( level-1 ), + _view->percentageBarBackground() ); + } + else + { + if ( _pacMan && _orig->isBusy() ) + { + // kdDebug() << "Animating PacMan for " << _orig << endl; + // painter->setBackgroundColor( _view->treeBackground() ); + _pacMan->animate( painter, QRect( 0, 0, width, height() ) ); + } + else + { + if ( _view->percentBarCol() == _view->readJobsCol() + && ! _pacMan ) + { + QListViewItem::paintCell( painter, + colorGroup, + column, + width, + alignment ); + } + else + { + painter->eraseRect( 0, 0, width, height() ); + } + } + } + } + else + { + /* + * Call the parent's paintCell() method. We don't want to do + * all the hassle of drawing strings and pixmaps, regarding + * alignments etc. + */ + QListViewItem::paintCell( painter, + colorGroup, + column, + width, + alignment ); + } +} + + +void +KDirTreeViewItem::paintPercentageBar( float percent, + QPainter * painter, + int indent, + int width, + const QColor & fillColor, + const QColor & barBackground ) +{ + int penWidth = 2; + int extraMargin = 3; + int x = _view->itemMargin(); + int y = extraMargin; + int w = width - 2 * _view->itemMargin(); + int h = height() - 2 * extraMargin; + int fillWidth; + + painter->eraseRect( 0, 0, width, height() ); + w -= indent; + x += indent; + + if ( w > 0 ) + { + QPen pen( painter->pen() ); + pen.setWidth( 0 ); + painter->setPen( pen ); + painter->setBrush( NoBrush ); + fillWidth = (int) ( ( w - 2 * penWidth ) * percent / 100.0); + + + // Fill bar background. + + painter->fillRect( x + penWidth, y + penWidth, + w - 2 * penWidth + 1, h - 2 * penWidth + 1, + barBackground ); + /* + * Notice: The Xlib XDrawRectangle() function always fills one + * pixel less than specified. Altough this is very likely just a + * plain old bug, it is documented that way. Obviously, Qt just + * maps the fillRect() call directly to XDrawRectangle() so they + * inherited that bug (although the Qt doc stays silent about + * it). So it is really necessary to compensate for that missing + * pixel in each dimension. + * + * If you don't believe it, see for yourself. + * Hint: Try the xmag program to zoom into the drawn pixels. + **/ + + // Fill the desired percentage. + + painter->fillRect( x + penWidth, y + penWidth, + fillWidth+1, h - 2 * penWidth+1, + fillColor ); + + + // Draw 3D shadows. + + pen.setColor( contrastingColor ( Qt::black, + painter->backgroundColor() ) ); + painter->setPen( pen ); + painter->drawLine( x, y, x+w, y ); + painter->drawLine( x, y, x, y+h ); + + pen.setColor( contrastingColor( barBackground.dark(), + painter->backgroundColor() ) ); + painter->setPen( pen ); + painter->drawLine( x+1, y+1, x+w-1, y+1 ); + painter->drawLine( x+1, y+1, x+1, y+h-1 ); + + pen.setColor( contrastingColor( barBackground.light(), + painter->backgroundColor() ) ); + painter->setPen( pen ); + painter->drawLine( x+1, y+h, x+w, y+h ); + painter->drawLine( x+w, y, x+w, y+h ); + + pen.setColor( contrastingColor( Qt::white, + painter->backgroundColor() ) ); + painter->setPen( pen ); + painter->drawLine( x+2, y+h-1, x+w-1, y+h-1 ); + painter->drawLine( x+w-1, y+1, x+w-1, y+h-1 ); + } +} + + + + + + + + +QString +KDirStat::formatSizeLong( KFileSize size ) +{ + QString sizeText; + int count = 0; + + while ( size > 0 ) + { + sizeText = ( ( size % 10 ) + '0' ) + sizeText; + size /= 10; + + if ( ++count == 3 && size > 0 ) + { + sizeText = KGlobal::locale()->thousandsSeparator() + sizeText; + count = 0; + } + } + + return sizeText; +} + + +QString +KDirStat::hexKey( KFileSize size ) +{ + /** + * This is optimized for performance, not for aesthetics. + * And every now and then the old C hacker breaks through in most of us... + * ;-) + **/ + + static const char hexDigits[] = "0123456789ABCDEF"; + char key[ sizeof( KFileSize ) * 2 + 1 ]; // 2 hex digits per byte required + char *cptr = key + sizeof( key ) - 1; // now points to last char of key + + memset( key, '0', sizeof( key ) - 1 ); // fill with zeroes + *cptr-- = 0; // terminate string + + while ( size > 0 ) + { + *cptr-- = hexDigits[ size & 0xF ]; // same as size % 16 + size >>= 4; // same as size /= 16 + } + + return QString( key ); +} + + +QString +KDirStat::formatTime( long millisec, bool showMilliSeconds ) +{ + QString formattedTime; + int hours; + int min; + int sec; + + hours = millisec / 3600000L; // 60*60*1000 + millisec %= 3600000L; + + min = millisec / 60000L; // 60*1000 + millisec %= 60000L; + + sec = millisec / 1000L; + millisec %= 1000L; + + if ( showMilliSeconds ) + { + formattedTime.sprintf ( "%02d:%02d:%02d.%03ld", + hours, min, sec, millisec ); + } + else + { + formattedTime.sprintf ( "%02d:%02d:%02d", hours, min, sec ); + } + + return formattedTime; +} + + +QString +KDirStat::formatCount( int count, bool suppressZero ) +{ + if ( suppressZero && count == 0 ) + return ""; + + QString countString; + countString.setNum( count ); + + return countString; +} + + +QString +KDirStat::formatPercent( float percent ) +{ + QString percentString; + + percentString.sprintf( "%.1f%%", percent ); + + return percentString; +} + + +QString +KDirStat::formatTimeDate( time_t rawTime ) +{ + QString timeDateString; + struct tm *t = localtime( &rawTime ); + + /* + * Format this as "yyyy-mm-dd hh:mm:ss". + * + * This format may not be POSIX'ly correct, but it is the ONLY of all those + * brain-dead formats today's computer users are confronted with that makes + * any sense to the average human. + * + * Agreed, it takes some getting used to, too, but once you got that far, + * you won't want to miss it. + * + * Who the hell came up with those weird formats like described in the + * ctime() man page? Don't those people ever actually use that? + * + * What sense makes a format like "Wed Jun 30 21:49:08 1993" ? + * The weekday (of all things!) first, then a partial month name, then the + * day of month, then the time and then - at the very end - the year. + * IMHO this is maximum brain-dead. Not only can't you do any kind of + * decent sorting or automatic processing with that disinformation + * hodge-podge, your brain runs in circles trying to make sense of it. + * + * I could put up with crap like that if the Americans and Brits like it + * that way, but unfortunately I as a German am confronted with that + * bullshit, too, on a daily basis - either because some localization stuff + * didn't work out right (again) or because some jerk decided to emulate + * this stuff in the German translation, too. I am sick and tired with + * that, and since this is MY program I am going to use a format that makes + * sense to ME. + * + * No, no exceptions for Americans or Brits. I had to put up with their + * crap long enough, now it's time for them to put up with mine. + * Payback time - though luck, folks. + * ;-) + * + * Stefan Hundhammer 2001-05-28 + * (in quite some fit of frustration) + */ + timeDateString.sprintf( "%4d-%02d-%02d %02d:%02d:%02d", + t->tm_year + 1900, + t->tm_mon + 1, // another brain-dead common pitfall - 0..11 + t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec ); + + return timeDateString; +} + + +QString +KDirStat::localeTimeDate( time_t rawTime ) +{ + QDateTime timeDate; + timeDate.setTime_t( rawTime ); + QString timeDateString = + KGlobal::locale()->formatDate( timeDate.date(), true ) + " " + // short format + KGlobal::locale()->formatTime( timeDate.time(), true ); // include seconds + + return timeDateString; +} + + +QColor +KDirStat::contrastingColor( const QColor &desiredColor, + const QColor &contrastColor ) +{ + if ( desiredColor != contrastColor ) + { + return desiredColor; + } + + if ( contrastColor != contrastColor.light() ) + { + // try a little lighter + return contrastColor.light(); + } + else + { + // try a little darker + return contrastColor.dark(); + } +} + + + + + +// EOF diff --git a/kdirstat/kdirtreeview.h b/kdirstat/kdirtreeview.h new file mode 100644 index 0000000..baeae6b --- /dev/null +++ b/kdirstat/kdirtreeview.h @@ -0,0 +1,889 @@ +/* + * File name: kdirtreeview.h + * Summary: High level classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-08-26 + */ + + +#ifndef KDirTreeView_h +#define KDirTreeView_h + + +// Alternative parent class for KDirTreeView. +// +// If you change this, don't forget to change the KDirTreeView class +// declaration also. Unfortunately there this 'define' can't be used - +// it seems to confuse the 'moc' preprocessor. + +#define USE_KLISTVIEW 0 +#define DEBUG_COUNTERS 10 + + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include +#include +#include +#include +#include "kdirtree.h" + + +// Forward declarations +class QWidget; +class QTimer; +class QPopupMenu; +class KPacManAnimation; + + +// Open a new name space since KDE's name space is pretty much cluttered +// already - all names that would even remotely match are already used up, +// yet the resprective classes don't quite fit the purposes required here. + +namespace KDirStat +{ +#define KDirTreeViewMaxFillColor 16 + + +#if USE_KLISTVIEW +# define KDirTreeViewParentClass KListView +#else +# define KDirTreeViewParentClass QListView +#endif + + class KDirTreeViewItem; + + + class KDirTreeView: public QListView + // Using + // class KDirTreeView: public KDirTreeViewParentClass + // or some other 'ifdef' ... construct seems to confuse "moc". + { + Q_OBJECT + + public: + /** + * Default constructor. + **/ + KDirTreeView( QWidget * parent = 0 ); + + /** + * Destructor. + **/ + virtual ~KDirTreeView(); + + /** + * Locate the counterpart to an original tree item "wanted" somewhere + * within this view tree. Returns 0 on failure. + * If "lazy" is set, only the open part of the tree is searched. + * "doClone" specifies whether or not to (deferred) clone nodes that + * are not cloned yet. This is only used if "lazy" is false. + **/ + KDirTreeViewItem * locate( KFileInfo * wanted, + bool lazy = true, + bool doClone = true ); + + /** + * Get the first child of this view or 0 if there is none. + * Use the child's next() method to get the next child. + * Reimplemented from @ref QListView. + **/ + KDirTreeViewItem * firstChild() const + { return (KDirTreeViewItem *) KDirTreeViewParentClass::firstChild(); } + + /** + * Return the currently selected item or 0, if none is selected. + **/ + KDirTreeViewItem * selection() const { return _selection; } + + /** + * Returns the default level until which items are opened by default + * (unless they are dot entries). + **/ + int openLevel() const { return _openLevel; } + + /** + * Returns true if the view tree is to be cloned lazily, i.e. only + * those view tree branches that are really visible are synced with the + * original tree. + **/ + bool doLazyClone() const { return _doLazyClone; } + + /** + * Enable / disable PacMan animation in this tree view during directory + * reading. This is disabled by default since it eats quite some + * performance. + **/ + void enablePacManAnimation( bool enable ) { _doPacManAnimation = enable; } + /** + * Returns true if the PacMan animation is to be used during directory + * reading. + **/ + bool doPacManAnimation() const { return _doPacManAnimation; } + + /** + * Returns the number of open items in the entire tree. + **/ + int openCount(); + + /** + * Return the percentage bar fill color for the specified directory + * level (0..MaxInt). Wraps around every usedFillColors() colors. + **/ + const QColor & fillColor( int level ) const; + + /** + * Very much like @ref fillColor(), but doesn't wrap around at @ref + * usedFillColors(), but at KDirTreeViewMaxFillColor. + **/ + const QColor & rawFillColor( int level ) const; + + /** + * Set the fill color of percentage bars of the specified directory + * level (0..KDirTreeViewMaxFillColor-1). + * + * Calling repaint() after setting all desired colors is the + * caller's responsibility. + **/ + void setFillColor( int level, const QColor &color ); + + /** + * Set all tree colors to default values. + **/ + void setDefaultFillColors(); + + /** + * Set the number of used percentage bar fill colors + * (1..KDirTreeViewMaxFillColor). + **/ + void setUsedFillColors( int usedFillColors ); + + /** + * Returns the number of used percentage bar fill colors. + **/ + int usedFillColors() const { return _usedFillColors; } + + /** + * Set the tree background color. + * + * Calling repaint() after setting all desired colors is the + * caller's responsibility. + **/ + void setTreeBackground( const QColor &color ); + + /** + * Returns the tree background color. + **/ + const QColor & treeBackground() const { return _treeBackground; } + + /** + * Returns the background color for percentage bars. + **/ + const QColor & percentageBarBackground() const { return _percentageBarBackground; } + + /** + * (Try to) ensure good contrast between the tree background and the + * percentage bars' 3D edges - prevent ugly 3D effects which will + * inevitably be the case for a white background (which unfortunately + * is very common): The percentage bars use white and black for 3D + * borders - like any other widget. But other widgets normally can + * assume their parent widget uses some more neutral color so white and + * black will result in at least some minimal contrast. + * + * This function automagically sets a reasonable default background + * color for the tree display: If the current color scheme's document + * background color (as used for input fields, lists etc.) is white or + * black, use the palette midlight color (the same color as "normal" + * widgets like push buttons etc., but brighter). For all other colors + * than white, the document background color (the palette base color) + * is used. + **/ + void ensureContrast(); + + /** + * Set the sort column. + * + * Reimplemented from QListView so we can keep track of the sort column. + **/ + virtual void setSorting( int column, bool increasing = TRUE ); + + /** + * Returns the internal @ref KDirTree this view works on. + * Handle with caution: This might be short-lived information. + * The view might choose to create a new tree shortly after returning + * this, so don't store this pointer internally. + **/ + KDirTree *tree() { return _tree; } + + int nameCol() const { return _nameCol; } + int iconCol() const { return _iconCol; } + int percentBarCol() const { return _percentBarCol; } + int percentNumCol() const { return _percentNumCol; } + int totalSizeCol() const { return _totalSizeCol; } + int workingStatusCol() const { return _workingStatusCol; } + int ownSizeCol() const { return _ownSizeCol; } + int totalItemsCol() const { return _totalItemsCol; } + int totalFilesCol() const { return _totalFilesCol; } + int totalSubDirsCol() const { return _totalSubDirsCol; } + int latestMtimeCol() const { return _latestMtimeCol; } + int readJobsCol() const { return _readJobsCol; } + int sortCol() const { return _sortCol; } + + QPixmap openDirIcon() const { return _openDirIcon; } + QPixmap closedDirIcon() const { return _closedDirIcon; } + QPixmap openDotEntryIcon() const { return _openDotEntryIcon; } + QPixmap closedDotEntryIcon() const { return _closedDotEntryIcon; } + QPixmap unreadableDirIcon() const { return _unreadableDirIcon; } + QPixmap mountPointIcon() const { return _mountPointIcon; } + QPixmap fileIcon() const { return _fileIcon; } + QPixmap symLinkIcon() const { return _symLinkIcon; } + QPixmap blockDevIcon() const { return _blockDevIcon; } + QPixmap charDevIcon() const { return _charDevIcon; } + QPixmap fifoIcon() const { return _fifoIcon; } + QPixmap stopIcon() const { return _stopIcon; } + QPixmap workingIcon() const { return _workingIcon; } + QPixmap readyIcon() const { return _readyIcon; } + + + /** + * Set function name of debug function #i + **/ + void setDebugFunc( int i, const QString & functionName ); + + /** + * Increase debug counter #i + **/ + void incDebugCount( int i ); + + + public slots: + + /** + * Open a directory URL. Assume "file:" protocol unless otherwise specified. + **/ + void openURL( KURL url ); + + /** + * Refresh (i.e. re-read from disk) the entire tree. + **/ + void refreshAll(); + + /** + * Refresh (i.e. re-read from disk) the selected subtree. + **/ + void refreshSelected(); + + /** + * Forcefully stop a running read process. + **/ + void abortReading(); + + /** + * Clear this view's contents. + **/ + void clear(); + + /** + * Select a (QListViewItem) item. Triggers selectionChanged() signals. + **/ + void selectItem( QListViewItem *item ); + + /** + * Select an item. Triggers selectionChanged() signals. + * Overloaded for convenience. + **/ + void selectItem( KDirTreeViewItem *item ) { selectItem( (QListViewItem *) item ); } + + /** + * Select a KDirTree item. Used for connecting the @ref + * KDirTree::selectionChanged() signal. + **/ + void selectItem( KFileInfo *item ); + + /** + * Clear the current selection. Triggers selectionChanged() signals. + **/ + void clearSelection(); + + /** + * Close all tree branches except the one specified. + **/ + void closeAllExcept( KDirTreeViewItem *except ); + + /** + * Send a standardized mail to the owner of the selected branch. + * The user will get a mailer window where he can edit that mail all he + * likes before deciding to send or discard it. + * + * The mail includes all currently open branches from the selected + * branch on. + **/ + void sendMailToOwner(); + + /** + * Notification of a change in the KDE palette, i.e. the user selected + * and applied different colors in the KDE control center. + **/ + void paletteChanged(); + + /** + * Read configuration and initialize variables accordingly. + * Will be called automatically in the constructor. + **/ + void readConfig(); + + /** + * Save configuraton. + **/ + void saveConfig() const; + + /** + * Emit a @ref userActivity() signal worth 'points' activity points. + **/ + void logActivity( int points ); + + /** + * Returns the minimum recommended size for this widget. + * Reimplemented from QWidget. + **/ + virtual QSize minimumSizeHint() const { return QSize( 0, 0 ); } + + + protected slots: + + /** + * Add a child as a clone of original tree item "newChild" to this view + * tree. + **/ + void addChild ( KFileInfo *newChild ); + + /** + * Delete a cloned child. + **/ + void deleteChild ( KFileInfo *newChild ); + + /** + * Recursively update the visual representation of the summary fields. + * This update is as lazy as possible for optimum performance since it + * is called very frequently as a cyclic update. + **/ + void updateSummary(); + + /** + * Signal end of all read jobs, finalize display and terminate pending + * cyclic visual update. + **/ + void slotFinished(); + + /** + * Signal abortion of all read jobs, finalize display and terminate pending + * cyclic visual update. + **/ + void slotAborted(); + + /** + * Signal end of one read job at this level and finalize display of + * this level. + **/ + void finalizeLocal( KDirInfo *dir ); + + /** + * Display progress information in the status bar. Automatically adds + * the elapsed time of a directory scan. + **/ + void sendProgressInfo( const QString & currentDir = "" ); + + +#if QT_VERSION < 300 + /** + * "moc" doesnt't seem to handle default arguments well, so this is an + * overloaded slot that uses the internally stored current directory. + **/ + void sendProgressInfo(); +#endif + + /** + * Set up everything prior to reading: Cyclic update timer, display + * busy state, default sorting, stopwatch. + **/ + void prepareReading(); + + /** + * Change the tree display to "busy" state, i.e. add a column to + * display the number of pending read jobs for each level. + **/ + void busyDisplay(); + + /** + * Change the tree display back to "idle" state, i.e. remove columns + * that are useful only while directories are being read, like the + * pending read jobs column. + **/ + void idleDisplay(); + + /** + * Pop up context menu (i.e. emit the contextMenu() signal) or open a + * small info popup with exact information, depending on 'column'. + **/ + void popupContextMenu ( QListViewItem * listViewItem, + const QPoint & pos, + int column ); + + /** + * Pop up info window with exact byte size. + **/ + void popupContextSizeInfo ( const QPoint & pos, + KFileSize size ); + + /** + * Pop up info window with arbitrary one-line text. + **/ + void popupContextInfo ( const QPoint & pos, + const QString & info ); + + + protected slots: + + /** + * Notification that a column has just been resized, thus may need + * repaining. + **/ + void columnResized( int column, int oldSize, int newSize ); + + + signals: + + /** + * Single line progress information, emitted when the read status + * changes - typically when a new directory is being read. Connect to a + * status bar etc. to keep the user busy. + **/ + void progressInfo( const QString &infoLine ); + + /** + * Emitted when reading is started. + **/ + void startingReading(); + + /** + * Emitted when reading this tree is finished. + **/ + void finished(); + + /** + * Emitted when reading this tree has been aborted. + **/ + void aborted(); + + /** + * Emitted when the currently selected item changes. + * Caution: 'item' may be 0 when the selection is cleared. + **/ + void selectionChanged( KDirTreeViewItem *item ); + + /** + * Emitted when the currently selected item changes. + * Caution: 'item' may be 0 when the selection is cleared. + **/ + void selectionChanged( KFileInfo *item ); + + /** + * Emitted when a context menu for this item should be opened. + * (usually on right click). 'pos' contains the click's mouse + * coordinates. + * + * NOTE: + * + * This is _not_ the same as @ref QListView::rightButtonClicked(): + * The context menu may not open on a right click on every column, + * usually only in the nameCol(). + **/ + void contextMenu( KDirTreeViewItem *item, const QPoint &pos ); + + /** + * Emitted at user activity. Some interactive actions are assigned an + * amount of "activity points" that can be used to judge whether or not + * the user is actually using this program or if it's just idly sitting + * around on the desktop. This is intended for use together with a @ref + * KActivityTracker. + **/ + void userActivity( int points ); + + + protected: + + KDirTree * _tree; + QTimer * _updateTimer; + QTime _stopWatch; + QString _currentDir; + KDirTreeViewItem * _selection; + QPopupMenu * _contextInfo; + int _idContextInfo; + + int _openLevel; + bool _doLazyClone; + bool _doPacManAnimation; + int _updateInterval; // millisec + int _usedFillColors; + QColor _fillColor [ KDirTreeViewMaxFillColor ]; + QColor _treeBackground; + QColor _percentageBarBackground; + + + // The various columns in which to display information + + int _nameCol; + int _iconCol; + int _percentNumCol; + int _percentBarCol; + int _totalSizeCol; + int _workingStatusCol; + int _ownSizeCol; + int _totalItemsCol; + int _totalFilesCol; + int _totalSubDirsCol; + int _latestMtimeCol; + int _readJobsCol; + int _sortCol; + + int _debugCount[ DEBUG_COUNTERS ]; + QString _debugFunc [ DEBUG_COUNTERS ]; + + + // The various icons + + QPixmap _openDirIcon; + QPixmap _closedDirIcon; + QPixmap _openDotEntryIcon; + QPixmap _closedDotEntryIcon; + QPixmap _unreadableDirIcon; + QPixmap _mountPointIcon; + QPixmap _fileIcon; + QPixmap _symLinkIcon; + QPixmap _blockDevIcon; + QPixmap _charDevIcon; + QPixmap _fifoIcon; + QPixmap _stopIcon; + QPixmap _workingIcon; + QPixmap _readyIcon; + }; + + + + class KDirTreeViewItem: public QListViewItem + { + public: + /** + * Constructor for the root item. + **/ + KDirTreeViewItem ( KDirTreeView * view, + KFileInfo * orig ); + + /** + * Constructor for all other items. + **/ + KDirTreeViewItem ( KDirTreeView * view, + KDirTreeViewItem * parent, + KFileInfo * orig ); + + /** + * Destructor. + **/ + virtual ~KDirTreeViewItem(); + + /** + * Locate the counterpart to an original tree item "wanted" somewhere + * within this view tree. Returns 0 on failure. + * + * When "lazy" is set, only the open part of the tree is searched. + * "doClone" specifies whether or not to (deferred) clone nodes that + * are not cloned yet. This is only used if "lazy" is false. + * "Level" is just a hint for the current tree level for better + * performance. It will be calculated automatically if omitted. + **/ + KDirTreeViewItem * locate( KFileInfo * wanted, + bool lazy = true, + bool doClone = true, + int level = -1 ); + + /** + * Recursively update the visual representation of the summary fields. + * This update is as lazy as possible for optimum performance. + **/ + void updateSummary(); + + /** + * Bring (the top level of) this branch of the view tree in sync with + * the original tree. Does _not_ recurse into subdirectories - only + * this level of this branch is processed. Called when lazy tree + * cloning is in effect and this branch is about to be opened. + **/ + void deferredClone(); + + + /** + * Finalize this level - clean up unneeded / undesired dot entries. + **/ + void finalizeLocal(); + + /** + * Returns the corresponding view. + **/ + KDirTreeView * view() { return _view; } + + + /** + * Returns the parent view item or 0 if this is the root. + **/ + KDirTreeViewItem * parent() { return _parent; } + + /** + * Returns the corresponding original item of the "real" (vs. view) + * tree where all the important information resides. + **/ + KFileInfo * orig() { return _orig; } + + /** + * Returns the first child of this item or 0 if there is none. + * Use the child's next() method to get the next child. + * Reimplemented from @ref QListViewItem. + **/ + KDirTreeViewItem * firstChild() const + { return (KDirTreeViewItem *) QListViewItem::firstChild(); } + + /** + * Returns the next sibling of this item or 0 if there is none. + * (Kind of) reimplemented from @ref QListViewItem. + **/ + KDirTreeViewItem * next() const + { return (KDirTreeViewItem *) QListViewItem::nextSibling(); } + + /** + * Comparison function used for sorting the list. + * + * Using this function is much more efficient than overwriting + * QListViewItem::key() which operates on QStrings. + * + * Returns: + * -1 if this < other + * 0 if this == other + * +1 if this > other + * + * Reimplemented from QListViewItem + **/ + virtual int compare( QListViewItem * other, + int col, + bool ascending ) const; + + /** + * Perform any necessary pending updates when a branch is opened. + * Reimplemented from @ref QListViewItem. + **/ + virtual void setOpen( bool open ); + + /** + * Notification that a branch in this subtree has been opened or close + * somewhere. Don't call this if the state hasn't really changed! + **/ + void openNotify( bool open ); + + /** + * Recursively open this subtree and all its ancestors up to the root. + **/ + void openSubtree(); + + /** + * Recursively close all tree branches from here on downwards. + **/ + void closeSubtree(); + + /** + * Close all tree branches except this one from the root on. + **/ + void closeAllExceptThis(); + + /** + * Returns the number of open items in this subtree. + **/ + int openCount() const { return _openCount; } + + /** + * Recursively return an ASCII representation of all open items from + * here on. + **/ + QString asciiDump(); + + + protected: + + /** + * Set the appropriate icon depending on this item's type and open / + * closed state. + **/ + void setIcon(); + + /** + * Remove dot entry if it doesn't have any children. + * Reparent all of the dot entry's children if there are no + * subdirectories on this level. + **/ + void cleanupDotEntries(); + + /** + * Find this entry's dot entry (clone). + * + * This doesn't create one if deferred cloning is in effect (which is + * not a drawback since cloning directory nodes create a dot entry + * clone along with the directory clone). + * + * Returns 0 if there is no dot entry clone. + **/ + KDirTreeViewItem * findDotEntry() const; + + + /** + * Paint method. Reimplemented from @ref QListViewItem so different + * colors can be used - and of course for painting percentage bars. + * + * Reimplemented from @ref QListViewItem. + **/ + virtual void paintCell ( QPainter * painter, + const QColorGroup & colorGroup, + int column, + int width, + int alignment ); + + /** + * Paint a percentage bar into a @ref QListViewItem cell. + * 'width' is the width of the entire cell. + * 'indent' is the number of pixels to indent the bar. + **/ + void paintPercentageBar ( float percent, + QPainter * painter, + int indent, + int width, + const QColor & fillColor, + const QColor & barBackground ); + + /** + * Generic comparison function. + **/ + template inline + int compare( T a, T b ) const + { + if ( a < b ) return -1; + if ( a > b ) return 1; + return 0; + } + + private: + + /** + * Initializations common to all constructors. + **/ + void init ( KDirTreeView * view, + KDirTreeViewItem * parent, + KFileInfo * orig ); + + protected: + + // Data members + + KDirTreeView * _view; + KDirTreeViewItem * _parent; + KFileInfo * _orig; + KPacManAnimation * _pacMan; + float _percent; + int _openCount; + + }; + + + inline kdbgstream & operator<< ( kdbgstream & stream, KDirTreeViewItem * item ) + { + if ( item ) + { + if ( item->orig() ) + { + stream << item->orig()->debugUrl(); + } + else + { + stream << " " << endl; + } + } + else + stream << ""; + + return stream; + } + + + + //---------------------------------------------------------------------- + // Static Functions + //---------------------------------------------------------------------- + + /** + * Format a file size with all digits, yet human readable using the current + * locale's thousand separator, i.e. 12,345,678 rather than 12345678 + **/ + QString formatSizeLong( KFileSize size ); + + /** + * Format a file size for use within a QListView::key() function: + * Right-justify and fill with leading zeroes. + **/ + QString hexKey( KFileSize size ); + + /** + * Format a millisecond granularity time human readable. + * Milliseconds will only be inluded if 'showMilliSeconds' is true. + **/ + QString formatTime ( long millisec, + bool showMilliSeconds = false ); + + /** + * Format counters of any kind. + * + * Returns an empty string if 'suppressZero' is 'true' and the value of + * 'count' is 0. + **/ + QString formatCount( int count, bool suppressZero = false ); + + /** + * Format percentages. + **/ + QString formatPercent( float percent ); + + /** + * Format time and date human-readable as "yyyy-mm-dd hh:mm:ss" + * - unlike that ctime() crap that is really useless. + * See the source for more about why this format. + **/ + QString formatTimeDate( time_t rawTime ); + + /** + * Format time and date according to the current locale for those who + * really must have that brain-dead ctime() format. + **/ + QString localeTimeDate( time_t rawTime ); + + /** + * Return a color that contrasts to 'contrastColor'. + **/ + QColor contrastingColor ( const QColor &desiredColor, + const QColor &contrastColor ); + +} // namespace KDirStat + + +#endif // ifndef KDirTreeView_h + + +// EOF diff --git a/kdirstat/kfeedback.cpp b/kdirstat/kfeedback.cpp new file mode 100644 index 0000000..9730d89 --- /dev/null +++ b/kdirstat/kfeedback.cpp @@ -0,0 +1,503 @@ + +/* + * File name: kfeedback.cpp + * Summary: User feedback form + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2004-11-23 + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "kfeedback.h" + + +KFeedbackDialog::KFeedbackDialog( const QString & feedbackMailAddress, + const QString & helpTopic ) + : KDialogBase( Plain, // dialogFace + i18n( "Feedback" ), // caption + Apply | Cancel + | ( helpTopic.isEmpty() ? 0 : (int) Help ), // buttonMask + Apply ) // defaultButton +{ + QVBoxLayout * layout = new QVBoxLayout( plainPage(), 0, spacingHint() ); + setButtonApply( KGuiItem( i18n( "&Mail this..." ) ) ); + + if ( ! helpTopic.isEmpty() ) + setHelp( helpTopic ); + + _form = new KFeedbackForm( feedbackMailAddress, plainPage() ); + CHECK_PTR( _form ); + + layout->addWidget( _form ); + checkSendButton(); + + connect( this, SIGNAL( applyClicked() ), + _form, SLOT ( sendMail() ) ); + + connect( _form, SIGNAL( mailSent() ), + this, SLOT ( hide() ) ); + + connect( _form, SIGNAL( mailSent() ), + this, SIGNAL( mailSent() ) ); + + connect( _form, SIGNAL( checkComplete() ), + this, SLOT ( checkSendButton() ) ); +} + + +KFeedbackDialog::~KFeedbackDialog() +{ + // NOP +} + + +void +KFeedbackDialog::checkSendButton() +{ + enableButtonApply( _form->readyToSend() ); +} + + + + + +KFeedbackForm::KFeedbackForm( const QString & feedbackMailAddress, + QWidget * parent ) + : QVBox( parent ) + , _feedbackMailAddress( feedbackMailAddress ) +{ + // + // Explanation above the question list + // + + QLabel * label = new QLabel( i18n( "

Please tell us your opinion about this program.

" + "

You will be able to review everything in your mailer " + "before any mail is sent.
" + "Nothing will be sent behind your back.

" + ), this ); + // + // Question list + // + + _questionList = new KFeedbackQuestionList( this ); + CHECK_PTR( _questionList ); + + connect( _questionList, SIGNAL( checkComplete() ), + this, SLOT ( slotCheckComplete() ) ); + + + // + // Explanation below the question list + // + + QHBox * hbox = new QHBox( this ); + CHECK_PTR( hbox ); + + QSizePolicy pol( QSizePolicy::Fixed, QSizePolicy::Fixed ); // hor / vert + + label = new QLabel( i18n( "Questions marked with " ), hbox ); + CHECK_PTR( label ); + label->setSizePolicy( pol ); + + label = new QLabel( hbox ); + CHECK_PTR( label ); + label->setPixmap( KGlobal::iconLoader()->loadIcon( "edit", KIcon::Small ) ); + label->setSizePolicy( pol ); + + label = new QLabel( i18n( " must be answered before a mail can be sent.") , hbox ); + CHECK_PTR( label ); + label->setSizePolicy( pol ); + + new QWidget( hbox ); // Fill any leftover space to the right. + + + // + // Free-text comment field + // + + label = new QLabel( "\n" + i18n( "&Additional Comments:" ), this ); CHECK_PTR( label ); + _comment = new QMultiLineEdit( this ); CHECK_PTR( _comment ); + + label->setBuddy( _comment ); +#if (QT_VERSION < 300) + _comment->setFixedVisibleLines( 5 ); +#endif + _comment->setWordWrap( QMultiLineEdit::FixedColumnWidth ); + _comment->setWrapColumnOrWidth( 70 ); +} + + +KFeedbackForm::~KFeedbackForm() +{ + // NOP +} + + +void +KFeedbackForm::sendMail() +{ + // + // Build mail subject + // + + QString subject; + + const KAboutData * aboutData = KGlobal::instance()->aboutData(); + + if ( aboutData ) + subject = aboutData->programName() + "-" + aboutData->version(); + else + subject = kapp->name(); + + subject = "[kde-feedback] " + subject + " user feedback"; + + + // + // Build mail body + // + + QString body = subject + "\n\n" + + formatComment() + + _questionList->result(); + + + // + // Build "mailto:" URL from all this + // + + KURL mail; + mail.setProtocol( "mailto" ); + mail.setPath( _feedbackMailAddress ); + mail.setQuery( "?subject=" + KURL::encode_string( subject ) + + "&body=" + KURL::encode_string( body ) ); + + // TODO: Check for maximum command line length. + // + // The hard part with this is how to get this from all that 'autoconf' + // stuff into 'config.h' or some other include file without hardcoding + // anything - this is too system dependent. + + + // + // Actually send mail + // + + kapp->invokeMailer( mail ); + + emit mailSent(); +} + + +void +KFeedbackForm::slotCheckComplete() +{ + emit checkComplete(); +} + + +QString +KFeedbackForm::formatComment() +{ + QString result = _comment->text(); + + if ( ! result.isEmpty() ) + { + result = "\n" + result + "\n\n\n"; + } + + return result; +} + + +bool +KFeedbackForm::readyToSend() +{ + return _questionList->isComplete(); +} + + + + + + +KFeedbackQuestionList::KFeedbackQuestionList( QWidget *parent ) + : QListView( parent ) +{ + addColumn( "" ); + header()->hide(); +} + + +KFeedbackQuestionList::~KFeedbackQuestionList() +{ + // NOP +} + + +bool +KFeedbackQuestionList::isComplete() +{ + KFeedbackQuestion * question = firstQuestion(); + + while ( question ) + { + if ( question->isRequired() && ! question->isAnswered() ) + return false; + + question = question->nextQuestion(); + } + + return true; +} + + +QString +KFeedbackQuestionList::result() +{ + QString res; + KFeedbackQuestion * question = firstQuestion(); + + while ( question ) + { + res += question->result(); + + question = question->nextQuestion(); + } + + return res; +} + + +KFeedbackQuestion * +KFeedbackQuestionList::addQuestion( const QString & text, + const QString & id, + bool exclusiveAnswer, + bool required ) +{ + KFeedbackQuestion * question = new KFeedbackQuestion( this, text, id, + exclusiveAnswer, + required ); + CHECK_PTR( question ); + + return question; +} + + +void +KFeedbackQuestionList::addYesNoQuestion( const QString & text, + const QString & id, + bool required ) +{ + + KFeedbackQuestion * question = new KFeedbackQuestion( this, text, id, + true, // exclusive + required ); + CHECK_PTR( question ); + question->addAnswer( i18n( "yes" ), "yes" ); + question->addAnswer( i18n( "no" ), "no" ); +} + + +void +KFeedbackQuestionList::questionAnswered() +{ + emit checkComplete(); +} + +void +KFeedbackQuestionList::questionAdded( KFeedbackQuestion * question) +{ + if ( question->isRequired() ) + emit checkComplete(); +} + + + + + +static int nextNo = 0; + +KFeedbackQuestion::KFeedbackQuestion( KFeedbackQuestionList * parent, + const QString & text, + const QString & id, + bool exclusiveAnswer, + bool required, + bool open ) + : QCheckListItem( parent, text ) + , _id( id ) + , _exclusiveAnswer( exclusiveAnswer ) + , _required( required ) +{ + if ( required ) + { + setPixmap( 0, KGlobal::iconLoader()->loadIcon( "edit", KIcon::Small ) ); + } + + setOpen( open ); + _no = nextNo++; + + parent->questionAdded( this ); +} + + +void +KFeedbackQuestion::addAnswer( const QString & text, + const QString & id ) +{ + new KFeedbackAnswer( this, text, id, _exclusiveAnswer ); +} + + +bool +KFeedbackQuestion::isAnswered() +{ + if ( ! _exclusiveAnswer ) + { + /** + * If any number of answers is permitted for this question, this + * question is always considered to be answered. + **/ + + return true; + } + + + /** + * If this question requires an exclusive answer, exactly one of them + * should be checked. We don't need to bother about more than one being + * checked here - QListView does that for us. + **/ + + KFeedbackAnswer *answer = firstAnswer(); + + while ( answer ) + { + if ( answer->isChecked() ) + return true; + + answer = answer->nextAnswer(); + } + + return false; +} + + +QString +KFeedbackQuestion::result() +{ + QString res; + int answers = 0; + + KFeedbackAnswer *answer = firstAnswer(); + + while ( answer ) + { + if ( answer->isChecked() ) + { + res += _id + "=\"" + answer->id() + "\"\n"; + answers++; + } + + answer = answer->nextAnswer(); + } + + if ( answers > 1 ) + { + res = "\n" + res + "\n"; + } + + return res; +} + + +QString +KFeedbackQuestion::text() +{ + return QCheckListItem::text(0); +} + + +QString +KFeedbackQuestion::key( int, bool ) const +{ + QString no; + no.sprintf( "%08d", _no ); + + return no; +} + + +KFeedbackQuestionList * +KFeedbackQuestion::questionList() const +{ + return dynamic_cast( listView() ); +} + + + + + + + +KFeedbackAnswer::KFeedbackAnswer( KFeedbackQuestion * parent, + const QString & text, + const QString & id, + bool exclusive ) + : QCheckListItem( parent, + text, + exclusive + ? QCheckListItem::RadioButton + : QCheckListItem::CheckBox ) + , _id( id ) +{ + _no = nextNo++; +} + + +QString +KFeedbackAnswer::text() +{ + return QCheckListItem::text(0); +} + + +QString +KFeedbackAnswer::key( int, bool ) const +{ + QString no; + no.sprintf( "%08d", _no ); + + return no; +} + + +void +KFeedbackAnswer::stateChange( bool newState ) +{ + if ( newState && question()->isRequired() ) + { + KFeedbackQuestionList * list = question()->questionList(); + + if ( list ) + list->questionAnswered(); + } +} + + + +// EOF diff --git a/kdirstat/kfeedback.h b/kdirstat/kfeedback.h new file mode 100644 index 0000000..3d1978b --- /dev/null +++ b/kdirstat/kfeedback.h @@ -0,0 +1,460 @@ +/* + * File name: kfeedback.h + * Summary: User feedback form and mailing utilities + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KFeedback_h +#define KFeedback_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + + +#ifndef NOT_USED +# define NOT_USED(PARAM) ( (void) (PARAM) ) +#endif + + +class KFeedbackForm; +class KFeedbackQuestionList; +class KFeedbackQuestion; +class KFeedbackAnswer; +class QMultiLineEdit; + + +/** + * Dialog containing a @ref KFeedbackForm and all the infrastructure for + * sending a mail etc. + **/ +class KFeedbackDialog: public KDialogBase +{ + Q_OBJECT + +public: + + /** + * Constructor. + **/ + KFeedbackDialog( const QString & feedbackMailAddress, + const QString & helpTopic = QString::null ); + + + /** + * Destructor. + **/ + virtual ~KFeedbackDialog(); + + + /** + * Returns the internal @KFeedbackForm + **/ + KFeedbackForm *form() { return _form; } + + +public slots: + + /** + * Check if sufficient information is available to send a mail now and + * enable / disable the "send mail" button accordingly. + **/ + void checkSendButton(); + + +signals: + /** + * Emitted when the user has sent the feedback mail - i.e. when he clicked + * on the "Send mail" button and the mail has successfully been forwarded + * to the mailer. He can still choose not to send the mail from within the + * mailer, though. + **/ + void mailSent(); + + +protected: + + KFeedbackForm * _form; +}; + + +/** + * User feedback form: + * + * User is asked a list of questions, the answers of which will be sent via + * mail back to a feedback mail address. + **/ +class KFeedbackForm: public QVBox +{ + Q_OBJECT + +public: + /** + * Constructor. + **/ + KFeedbackForm( const QString & feedbackMailAddress, + QWidget * parent ); + + /** + * Destructor. + **/ + virtual ~KFeedbackForm(); + + +public slots: + + /** + * Compose a mail from the user's answers and send it to the feedback mail + * address passed to the constructor. + * + * This method will check with @ref readyToSend() if the mail can be sent + * with the questions answered until now and prompt the user to answer more + * questions if not. + * + * Connect the @ref mailSent() signal if you are interested when exactly + * all this was successful. + **/ + virtual void sendMail(); + + +public: + + /** + * Checks if the mail is ready to send, i.e. if all required fields are + * filled. + **/ + virtual bool readyToSend(); + + /** + * Returns the @ref KFeedbackQuestionList . + **/ + KFeedbackQuestionList * questionList() { return _questionList; } + + +signals: + /** + * Emitted when the user has sent the feedback mail - i.e. when he clicked + * on the "Send mail" button and the mail has successfully been forwarded + * to the mailer. He can still choose not to send the mail from within the + * mailer, though. + **/ + void mailSent(); + + /** + * Emitted when it is time to check for completeness of all information in + * this form: Either when a new question is added or when a question is + * answered. + **/ + void checkComplete(); + + +protected slots: + /** + * Check for completeness of this form. + **/ + void slotCheckComplete(); + + +protected: + + /** + * Format the "personal comments" field for sending mail. + **/ + QString formatComment(); + + + QString _feedbackMailAddress; + KFeedbackQuestionList * _questionList; + QMultiLineEdit * _comment; +}; + + + +/** + * List of feedback questions presented in a @ref QListView widget. + **/ +class KFeedbackQuestionList: public QListView +{ + Q_OBJECT + +public: + + /** + * Constructor. + **/ + KFeedbackQuestionList( QWidget *parent ); + + /** + * Destructor. + **/ + virtual ~KFeedbackQuestionList(); + + /** + * Returns whether or not this question list is answered satisfactorily, + * i.e. if all questions marked as "required" are answered. + **/ + virtual bool isComplete(); + + /** + * The result of all answered questions in ASCII. + **/ + QString result(); + + /** + * Add a yes/no question to the list. + * + * 'text' is the text the user will see (in his native language). + * + * 'id' is what will be sent with the feedback mail, thus it should be + * unique within the application, yet human readable (preferably English) + * and not contain any weird characters that might confuse scripts that are + * later used to automatically parse those mails. + * Examples: "would_recommend_to_a_friend" + * + * Set 'required' to 'true' if answering this question is required to + * successfully complete this form. + * + * Returns a pointer to this question so you can add answers. + **/ + + KFeedbackQuestion * addQuestion( const QString & text, + const QString & id, + bool exclusiveAnswer = true, + bool required = false ); + + /** + * Add a yes/no question to the list. + **/ + void addYesNoQuestion( const QString & text, + const QString & id, + bool required = false ); + + /** + * Returns the first question of that list. + * Use @ref KFeedbackQuestion::next() to get the next one. + **/ + KFeedbackQuestion * firstQuestion() const + { return (KFeedbackQuestion *) QListView::firstChild(); } + + /** + * Notify the list that another question has been answered. + * Emits the @ref checkComplete() signal when all required questions are + * answered. + **/ + void questionAnswered(); + + /** + * Notify the list that another question has been added. + * Emits the @ref checkComplete() signal when a required question is + * added. + **/ + void questionAdded( KFeedbackQuestion * question ); + +signals: + /** + * Emitted when all required questions are answered. + **/ + void checkComplete(); +}; + + +/** + * A user feedback question to be inserted into a @ref KFeedbackQuestionList. + **/ +class KFeedbackQuestion: public QCheckListItem +{ +public: + + /** + * Constructor. + * + * The parent @ref KFeedbackQuestionList assumes ownership of this object, + * so don't delete it unless you want to delete it from the question list + * as well. + * + * 'text' is the text the user will see (in his native language). + * + * 'id' is what will be sent with the feedback mail, thus it should be + * unique within the application, yet human readable (preferably English) + * and not contain any weird characters that might confuse scripts that are + * later used to automatically parse those mails. + * Examples: "features_not_liked", "stability" + * + * Set 'required' to 'true' if answering this question is required to + * successfully complete this form. + * + * Set 'exclusiveAnswer' to 'true' if only one of all answers may be + * checked at any one time, to 'false' if multiple answers are allowed. + **/ + KFeedbackQuestion( KFeedbackQuestionList * parent, + const QString & text, + const QString & id, + bool exclusiveAnswer = true, + bool required = false, + bool open = true ); + + /** + * Add an answer to this question. Again, 'text' is what the user will see + * (translated to his native language), 'id' is what you will get back with + * the mail. The answer IDs need only be unique for that question; answers + * to other questions may have the same ID. + **/ + void addAnswer( const QString & text, + const QString & id ); + + /** + * Returns if answering this question is required. + **/ + bool isRequired() { return _required; } + + /** + * Returns if this question is answered satisfactorily. + **/ + bool isAnswered(); + + /** + * The result of this question in ASCII, e.g. + * recommend="yes" + * or + * features_i_like="builtin_tetris" + * features_i_like="pink_elephant" + * features_i_like="studlycapslyfier" + **/ + QString result(); + + /** + * Return this question's ID. + **/ + QString id() { return _id; } + + /** + * Return this question's text. + **/ + QString text(); + + /** + * Returns whether or not this question requires an exclusive answer. + **/ + bool exclusiveAnswer() { return _exclusiveAnswer; } + + + /** + * Returns the sort key. + * + * Reimplemented from @ref QListViewItem to maintain insertion order. + **/ + virtual QString key( int column, bool ascending ) const; + + /** + * Returns the next question or 0 if there is no more. + **/ + KFeedbackQuestion * nextQuestion() const + { return (KFeedbackQuestion *) QListViewItem::nextSibling(); } + + /** + * Returns the first possible answer to this question. + * Use @ref KFeedbackAnswer::nextAnswer() to get the next one. + **/ + KFeedbackAnswer * firstAnswer() const + { return (KFeedbackAnswer *) QListViewItem::firstChild(); } + + /** + * Returns the @ref KFeedbackQuestionList this question belongs to or 0 if + * the parent is no @ref KFeedbackQuestionList. + **/ + KFeedbackQuestionList * questionList() const; + + +protected: + + QString _id; + bool _exclusiveAnswer; + bool _required; + int _no; +}; + + +class KFeedbackAnswer: public QCheckListItem +{ +public: + /** + * Constructor. + * + * 'exclusive' tells the type of answer: One of many allowed or any number + * of many. + **/ + KFeedbackAnswer( KFeedbackQuestion * parent, + const QString & text, + const QString & id, + bool exclusive = true ); + + /** + * Return this answer's ID. + **/ + QString id() { return _id; } + + /** + * Return this answer's text. + **/ + QString text(); + + /** + * Returns whether or not this is an exclusive answer. + **/ + bool isExclusive() { return _exclusive; } + + /** + * Returns whether or not this answer is checked. + **/ + bool isChecked() { return QCheckListItem::isOn(); } + + /** + * Returns the next possible answer or 0 if there is no more. + **/ + KFeedbackAnswer * nextAnswer() const + { return (KFeedbackAnswer *) QListViewItem::nextSibling(); } + + /** + * Returns the question to this answer. + **/ + KFeedbackQuestion * question() const + { return (KFeedbackQuestion *) QListViewItem::parent(); } + + /** + * Returns the sort key. + * + * Reimplemented from @ref QListViewItem to maintain insertion order. + **/ + virtual QString key( int column, bool ascending ) const; + + + /** + * On/off change. + * + * Reimplemented from @ref QCheckListItem to monitor answering required + * questions. This method notifies the @ref KFeedbackQuestionList whenever + * a required question is being answered. + **/ + virtual void stateChange( bool newState ); + +protected: + + QString _id; + bool _exclusive; + int _no; +}; + + + +#endif // KFeedback_h + + +// EOF diff --git a/kdirstat/kpacman.cpp b/kdirstat/kpacman.cpp new file mode 100644 index 0000000..55a61d4 --- /dev/null +++ b/kdirstat/kpacman.cpp @@ -0,0 +1,311 @@ + +/* + * File name: kpacman.cpp + * Summary: PacMan animation + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2004-03-29 + */ + + +#include +#include +#include +#include +#include + +#include "kpacman.h" + + +KPacManAnimation::KPacManAnimation( QWidget * widget, + int size, + bool randomStart ) +{ + _widget = widget; + _size = size; + _randomStart = randomStart; + _brush = QBrush( Qt::yellow ); + _pos = 0; + _speed = 4; + _interval = 100; + + _minMouth = 10; + _maxMouth = 70; + _mouthInc = ( _maxMouth - _minMouth ) / 3; + _mouth = _minMouth; + _pacManRect = QRect( 0, 0, 0, 0 ); + + restart(); +} + + +KPacManAnimation::~KPacManAnimation() +{ +} + + +void +KPacManAnimation::restart() +{ + _justStarted = true; + + if ( _randomStart ) + { + _goingRight = ( rand() > ( RAND_MAX / 2 ) ); + + // Initial _pos is set in animate() since the width (upon which it + // depends) is still unknown here. + } + else + { + _goingRight = true; + _pos = 0; + } + + // Care for initial display + _time = _time.addMSecs( _interval + 1 ); +} + + +void +KPacManAnimation::animate( QPainter * painter, + QRect rect ) +{ + if ( _time.elapsed() < _interval ) + return; + + _time.restart(); + + + // Make PacMan fit into height + + int size = _size <= rect.height() ? _size : rect.height(); + + if ( rect.width() < size ) // No space to animate in? + return; // -> forget it! + + + if ( _justStarted ) + { + _justStarted = false; + + if ( _pacManRect.width() > 0 ) + painter->eraseRect( _pacManRect ); + + if ( _randomStart ) + { + // Set random initial position + // - this depends on the width which is unknown in the constructor. + + _pos = (int) ( (rect.width() - size ) * ( (double) rand() / RAND_MAX) ); + } + } + else // ! _justStarted + { + // Erase last PacMan + + if ( ! _goingRight ) + _pacManRect.setX( _pacManRect.x() + _pacManRect.width() - _speed ); + + _pacManRect.setWidth( _speed ); + painter->eraseRect( _pacManRect ); + } + + + if ( _pos + size > rect.width() ) // Right edge reached? + { + // Notice: This can also happen when the rectangle is resized - i.e. it + // really makes sense to do that right here rather than at the end of + // this function! + + // Turn left + + _pos = rect.width() - size; + _goingRight = false; + _mouth = _minMouth; + } + else if ( _pos < 0 ) // Left edge reached? + { + // Turn right + + _pos = 0; + _goingRight = true; + _mouth = _minMouth; + } + + + // Draw PacMan (double-buffered) + + _pacManRect = QRect( 0, 0, size, size ); + QPixmap pixmap( size, size ); + pixmap.fill( painter->backgroundColor() ); + QPainter p( &pixmap, _widget ); + p.setBrush( _brush ); + + if ( _goingRight ) + { + p.drawPie( _pacManRect, + _mouth * 16, // arc (1/16 degrees) + ( 360 - 2 * _mouth ) * 16 ); // arc lenght (1/16 degrees) + } + else + { + p.drawPie( _pacManRect, + ( 180 + _mouth ) * 16, // arc (1/16 degrees) + ( 360 - 2 * _mouth ) * 16 ); // arc lenght (1/16 degrees) + } + + _pacManRect = QRect( rect.x() + _pos, // x + ( rect.height() - size ) / 2, // y + size, size ); // width, height + + // Transfer pixmap into widget + +#if 0 + QPoint offset = painter->worldMatrix().map( _pacManRect.topLeft() ); + // kdDebug() << "bitBlt() to " << offset.x() << ", " << offset.y() << endl; + bitBlt( _widget, offset, &pixmap ); +#endif + + painter->drawPixmap( _pacManRect.topLeft(), pixmap ); + + + // Animate mouth for next turn + + _mouth += _mouthInc; + + if ( _mouth >= _maxMouth ) // max open reached + { + _mouth = _maxMouth; + _mouthInc = -_mouthInc; // reverse direction + } + else if ( _mouth <= _minMouth ) // min open reached + { + _mouth = _minMouth; + _mouthInc = -_mouthInc; // reverse direction + } + + + // Advance position for next turn + + if ( _goingRight ) + _pos += _speed; + else + _pos -= _speed; +} + + + + + + +KPacMan::KPacMan( QWidget * parent, + int pacManSize, + bool randomStart, + const char * widgetName ) + : QWidget( parent, widgetName ) +{ + _pacManSize = pacManSize; + _pacMan = new KPacManAnimation( this, _pacManSize, randomStart ); + _timer = 0; + _interval = 100; // millisec + _active = false; + _painter = new QPainter( this ); + _margin = 1; +} + + +KPacMan::~KPacMan() +{ + if ( _painter ) + delete _painter; + + if ( _pacMan ) + delete _pacMan; +} + + +void +KPacMan::start() +{ + if ( ! _timer ) + { + _timer = new QTimer( this ); + } + + _pacMan->restart(); + + if ( _timer ) + { + _active = true; + _timer->start( _interval ); + connect( _timer, SIGNAL( timeout() ), + this, SLOT ( animate() ) ); + } +} + + +void +KPacMan::stop() +{ + _active = false; + + if ( _timer ) + _timer->stop(); + + repaint(); +} + + +void +KPacMan::animate() +{ + repaint( false ); +} + + +void +KPacMan::setInterval( int intervalMilliSec ) +{ + _interval = intervalMilliSec; + _pacMan->setInterval( _interval ); + + if ( _timer ) + _timer->changeInterval( _interval ); +} + + +void +KPacMan::paintEvent( QPaintEvent *ev ) +{ + QWidget::paintEvent( ev ); + + if ( _active ) + { + _pacMan->animate( _painter, QRect( _margin, 0, width() - _margin, height() ) ); + } +} + + +void +KPacMan::mouseReleaseEvent ( QMouseEvent *ev ) +{ + if ( _active ) + { + if ( _pacMan->lastPacMan().contains( ev->pos() ) ) + stop(); + } +} + + +QSize +KPacMan::sizeHint() const +{ + return QSize( 16 * _pacManSize, // width - admittedly somewhat random + _pacManSize + 2 * _margin ); // height +} + + + +// EOF diff --git a/kdirstat/kpacman.h b/kdirstat/kpacman.h new file mode 100644 index 0000000..02d4ce1 --- /dev/null +++ b/kdirstat/kpacman.h @@ -0,0 +1,265 @@ +/* + * File name: kpacman.h + * Summary: PacMan animation inside widgets + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2004-03-29 + */ + + +#ifndef KPacMan_h +#define KPacMan_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + + +#ifndef NOT_USED +# define NOT_USED(PARAM) ( (void) (PARAM) ) +#endif + +class QTimer; + + +/** + * Helper class to display a PacMan animation inside a widget. + * Note that this is not a widget itself, it needs to be placed inside a widget + * - which fact makes it suitable for use inside non-widget objects such as + * @ref QListViewItem. + * + * If you are looking for a widget that can do all that self-contained, see + * @ref KPacMan. + * + * @short PacMan animation + **/ +class KPacManAnimation +{ +public: + /** + * Constructor. + * + * Create a PacMan sprite in 'widget' of 'size' pixels diameter. Start at + * a random position and move in random direction if 'randomStart' is true. + **/ + KPacManAnimation( QWidget * widget, + int size, + bool randomStart ); + + /** + * Destructor. + **/ + virtual ~KPacManAnimation(); + + /** + * Animate PacMan inside this rectangle. + * Call this frequently enough (e.g. by a timer) to get fluid motion. + * Set up the painter prior to calling this; the entire rectangle will be + * cleared with the current brush, and PacMan's outline will be drawn with + * the current pen. + * + * PacMan moves from the left side of this rectangle to the right, turning + * around when it (he?) reaches the right edge. It (he?) is centered + * vertically. + * + * My, what is the sex of that thing? ;-) + **/ + void animate( QPainter * painter, + QRect rect ); + + /** + * Restart - reset to initial position and direction. + **/ + void restart(); + + /** + * Return the rectangle where the last PacMan was painted. + **/ + QRect lastPacMan() { return _pacManRect; } + + /** + * Set the animation interval in milliseconds. + **/ + void setInterval( int intervalMilliSec ) { _interval = intervalMilliSec; } + int interval() const { return _interval; } + + /** + * Number of pixels to move for each phase. + **/ + int speed() const { return _speed; } + void setSpeed( int speed ) { _speed = speed; } + + /** + * Brush to draw PacMan's inside. Bright yellow by default. + **/ + QBrush brush() const { return _brush; } + void setBrush( const QBrush & brush ) { _brush = brush; } + + /** + * Number of degrees PacMan's mouth opens or closes for each animation. + **/ + int mouthOpenInc() const { return _mouthInc; } + void setMouthOpenInc( int deg ) { _mouthInc = deg; } + + /** + * Minimum angle in degrees that PacMan's mouth opens. + **/ + int minMouthOpenAngle() const { return _minMouth; } + void setMinMouthOpenAngle( int deg ) { _minMouth = deg; } + + /** + * Maximum angle in degrees that PacMan's mouth opens. + **/ + int maxMouthOpenAngle() const { return _maxMouth; } + void setMaxMouthOpenAngle( int deg ) { _maxMouth = deg; } + +protected: + + QWidget * _widget; + QBrush _brush; + QTime _time; + QRect _pacManRect; + int _size; + bool _randomStart; + int _speed; + + int _minMouth; + int _maxMouth; + int _mouthInc; + int _interval; // milliseconds + + + // Current values + + int _pos; + int _mouth; + bool _justStarted; + bool _goingRight; +}; + + + +/** + * Widget that displays a PacMan animation. + * + * @short PacMan widget + **/ +class KPacMan: public QWidget +{ + Q_OBJECT + +public: + + /** + * Constructor. + * + * @param pacManSize size of the PacMan sprite + * @param randomStart random start position and direction if true + **/ + KPacMan( QWidget * parent = 0, + int pacManSize = 16, + bool randomStart = false, + const char * widgetName = 0 ); + + /** + * Destructor. + **/ + virtual ~KPacMan(); + + /** + * Access to the internal @ref PacManAnimation to avoid duplicating all its + * methods. + **/ + KPacManAnimation * pacMan() { return _pacMan; } + + /** + * Access to the internal @ref QPainter to avoid duplicating all its + * methods. Change this painter in order to change the visual appearance of + * the PacMan sprite. + **/ + QPainter * painter() { return _painter; } + + /** + * Returns the animation interval in milliseconds. + **/ + int interval() const { return _interval; } + + /** + * Set the animation interval in milliseconds. + **/ + void setInterval( int intervalMilliSec ); + + /** + * Return the (left and right) margin. + **/ + int margin() { return _margin; } + + /** + * Set the (left and right) margin - a place PacMan never goes. + **/ + void setMargin( int margin ) { _margin = margin; } + + /** + * Returns the widget's preferred size. + * + * Reimplemented from @ref QWidget. + **/ + virtual QSize sizeHint() const; + + +public slots: + + /** + * Start the animation. + **/ + void start(); + + /** + * Stop the animation and clear the widget. + **/ + void stop(); + + /** + * Do one animation. Triggered by timer. + **/ + void animate(); + + +protected: + + /** + * Actually do the painting. + * + * Reimplemented from @ref QWidget. + **/ + virtual void paintEvent( QPaintEvent *ev ); + + /** + * Stop animation on mouse click. + * + * Reimplemented from @ref QWidget. + **/ + virtual void mouseReleaseEvent ( QMouseEvent *ev ); + + +protected: + + KPacManAnimation * _pacMan; + QPainter * _painter; + QTimer * _timer; + int _interval; // millisec + bool _active; + int _margin; + int _pacManSize; +}; + +#endif // KPacMan_h + + +// EOF diff --git a/kdirstat/kstdcleanup.cpp b/kdirstat/kstdcleanup.cpp new file mode 100644 index 0000000..8626dfc --- /dev/null +++ b/kdirstat/kstdcleanup.cpp @@ -0,0 +1,150 @@ +/* + * File name: kstdcleanup.cpp + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2004-11-23 + */ + + +#include +#include "kcleanup.h" +#include "kstdcleanup.h" + +using namespace KDirStat; + + +KCleanup * +KStdCleanup::openInKonqueror( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_open_in_konqueror", + "kfmclient openURL %p", + i18n( "Open in &Konqueror" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( true ); + cleanup->setWorksForDotEntry( true ); + cleanup->setWorksLocalOnly ( false ); + cleanup->setRefreshPolicy( KCleanup::noRefresh ); + cleanup->setIcon( "konqueror.png" ); + cleanup->setShortcut( Qt::CTRL + Qt::Key_K ); + + return cleanup; +} + + +KCleanup * +KStdCleanup::openInTerminal( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_open_in_terminal", + "konsole", + i18n( "Open in &Terminal" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( true ); + cleanup->setWorksForDotEntry( true ); + cleanup->setRefreshPolicy( KCleanup::noRefresh ); + cleanup->setIcon( "konsole.png" ); + cleanup->setShortcut( Qt::CTRL + Qt::Key_T ); + + return cleanup; +} + + +KCleanup * +KStdCleanup::compressSubtree( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_compress_subtree", + "cd ..; tar cjvf %n.tar.bz2 %n && rm -rf %n", + i18n( "&Compress" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( false ); + cleanup->setWorksForDotEntry( false ); + cleanup->setRefreshPolicy( KCleanup::refreshParent ); + cleanup->setIcon( "ark.png" ); + + return cleanup; +} + + +KCleanup * +KStdCleanup::makeClean( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_make_clean", + "make clean", + i18n( "&make clean" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( false ); + cleanup->setWorksForDotEntry( true ); + cleanup->setRefreshPolicy( KCleanup::refreshThis ); + + return cleanup; +} + + +KCleanup * +KStdCleanup::deleteTrash( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_delete_trash", + "rm -f *.o *~ *.bak *.auto core", + i18n( "Delete T&rash Files" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( false ); + cleanup->setWorksForDotEntry( true ); + cleanup->setRefreshPolicy( KCleanup::refreshThis ); + cleanup->setRecurse( true ); + + return cleanup; +} + + +KCleanup * +KStdCleanup::moveToTrashBin( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_move_to_trash_bin", + "kfmclient move %p %t", + i18n( "Delete (to Trash &Bin)" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( true ); + cleanup->setWorksForDotEntry( false ); + cleanup->setRefreshPolicy( KCleanup::assumeDeleted ); + cleanup->setIcon( "edittrash.png" ); + cleanup->setShortcut( Qt::CTRL + Qt::Key_X ); + + return cleanup; +} + + +KCleanup * +KStdCleanup::hardDelete( KActionCollection *parent ) +{ + KCleanup *cleanup = new KCleanup( "cleanup_hard_delete", + "rm -rf %p", + i18n( "&Delete (no way to undelete!)" ), + parent ); + CHECK_PTR( cleanup ); + cleanup->setWorksForDir ( true ); + cleanup->setWorksForFile ( true ); + cleanup->setWorksForDotEntry( false ); + cleanup->setAskForConfirmation( true ); + cleanup->setRefreshPolicy( KCleanup::assumeDeleted ); + cleanup->setIcon( "editdelete.png" ); + cleanup->setShortcut( Qt::CTRL + Qt::Key_Delete ); + + return cleanup; +} + + + +// EOF diff --git a/kdirstat/kstdcleanup.h b/kdirstat/kstdcleanup.h new file mode 100644 index 0000000..110cd2b --- /dev/null +++ b/kdirstat/kstdcleanup.h @@ -0,0 +1,65 @@ +/* + * File name: kstdcleanup.h + * Summary: Support classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KStdCleanup_h +#define KStdCleanup_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + +// Forward declarations +class KActionCollection; +class KDirStat::KCleanup; + + +namespace KDirStat +{ + /** + * Predefined standard @ref KCleanup actions to be performed on + * @ref KDirTree items. + * + * This class is not meant to be ever instantiated - use the static methods + * only. + * + * For details about what each individual method does, refer to the help + * file. Use the old (KDirStat 0.86) help file in case the current help + * file isn't available yet. + * + * @short KDirStat standard cleanup actions + **/ + + class KStdCleanup + { + public: + static KCleanup *openInKonqueror ( KActionCollection *parent = 0 ); + static KCleanup *openInTerminal ( KActionCollection *parent = 0 ); + static KCleanup *compressSubtree ( KActionCollection *parent = 0 ); + static KCleanup *makeClean ( KActionCollection *parent = 0 ); + static KCleanup *deleteTrash ( KActionCollection *parent = 0 ); + static KCleanup *moveToTrashBin ( KActionCollection *parent = 0 ); + static KCleanup *hardDelete ( KActionCollection *parent = 0 ); + + private: + /** + * Prevent instances of this class - private constructor / destructor. + **/ + KStdCleanup() {} + ~KStdCleanup() {} + }; + +} // namespace KDirStat + + +#endif // ifndef KStdCleanup_h + + +// EOF diff --git a/kdirstat/ktreemaptile.cpp b/kdirstat/ktreemaptile.cpp new file mode 100644 index 0000000..c55b38c --- /dev/null +++ b/kdirstat/ktreemaptile.cpp @@ -0,0 +1,608 @@ +/* + * File name: ktreemaptile.cpp + * Summary: High level classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-30 + */ + + +#include +#include + +#include +#include +#include +#include +#include + +#include "ktreemaptile.h" +#include "ktreemapview.h" +#include "kdirtreeiterators.h" +#include "kdirtreeview.h" + + +using namespace KDirStat; +using std::max; +using std::min; + + +KTreemapTile::KTreemapTile( KTreemapView * parentView, + KTreemapTile * parentTile, + KFileInfo * orig, + const QRect & rect, + KOrientation orientation ) + : QCanvasRectangle( rect, parentView->canvas() ) + , _parentView( parentView ) + , _parentTile( parentTile ) + , _orig( orig ) +{ + init(); + + if ( parentTile ) + _cushionSurface = parentTile->cushionSurface(); + + createChildren( rect, orientation ); +} + + +KTreemapTile::KTreemapTile( KTreemapView * parentView, + KTreemapTile * parentTile, + KFileInfo * orig, + const QRect & rect, + const KCushionSurface & cushionSurface, + KOrientation orientation ) + : QCanvasRectangle( rect, parentView->canvas() ) + , _parentView( parentView ) + , _parentTile( parentTile ) + , _orig( orig ) + , _cushionSurface( cushionSurface ) +{ + init(); + + // Intentionally not copying the parent's cushion surface! + + createChildren( rect, orientation ); +} + + +KTreemapTile::~KTreemapTile() +{ + // NOP +} + + +void +KTreemapTile::init() +{ + // Set up height (z coordinate) - one level higher than the parent so this + // will be closer to the foreground. + // + // Note that this must happen before any children are created. + // I found that out the hard way. ;-) + + setZ( _parentTile ? ( _parentTile->z() + 1.0 ) : 0.0 ); + + setBrush( QColor( 0x60, 0x60, 0x60 ) ); + setPen( NoPen ); + + show(); // QCanvasItems are invisible by default! + + // kdDebug() << "Creating treemap tile for " << orig << " " << rect << " size " << orig->totalSize() << endl; +} + + +void +KTreemapTile::createChildren( const QRect & rect, + KOrientation orientation ) +{ + if ( _orig->totalSize() == 0 ) // Prevent division by zero + return; + + if ( _parentView->squarify() ) + createSquarifiedChildren( rect ); + else + createChildrenSimple( rect, orientation ); +} + + +void +KTreemapTile::createChildrenSimple( const QRect & rect, + KOrientation orientation ) +{ + + KOrientation dir = orientation; + KOrientation childDir = orientation; + + if ( dir == KTreemapAuto ) + dir = rect.width() > rect.height() ? KTreemapHorizontal : KTreemapVertical; + + if ( orientation == KTreemapHorizontal ) childDir = KTreemapVertical; + if ( orientation == KTreemapVertical ) childDir = KTreemapHorizontal; + + int offset = 0; + int size = dir == KTreemapHorizontal ? rect.width() : rect.height(); + int count = 0; + double scale = (double) size / (double) _orig->totalSize(); + + _cushionSurface.addRidge( childDir, _cushionSurface.height(), rect ); + + KFileInfoSortedBySizeIterator it( _orig, + (KFileSize) ( _parentView->minTileSize() / scale ), + KDotEntryAsSubDir ); + + while ( *it ) + { + int childSize = 0; + + childSize = (int) ( scale * (*it)->totalSize() ); + + if ( childSize >= _parentView->minTileSize() ) + { + QRect childRect; + + if ( dir == KTreemapHorizontal ) + childRect = QRect( rect.x() + offset, rect.y(), childSize, rect.height() ); + else + childRect = QRect( rect.x(), rect.y() + offset, rect.width(), childSize ); + + KTreemapTile * tile = new KTreemapTile( _parentView, this, *it, childRect, childDir ); + CHECK_PTR( tile ); + + tile->cushionSurface().addRidge( dir, + _cushionSurface.height() * _parentView->heightScaleFactor(), + childRect ); + + offset += childSize; + } + + ++count; + ++it; + } +} + + +void +KTreemapTile::createSquarifiedChildren( const QRect & rect ) +{ + if ( _orig->totalSize() == 0 ) + { + kdError() << k_funcinfo << "Zero totalSize()" << endl; + return; + } + + double scale = rect.width() * (double) rect.height() / _orig->totalSize(); + KFileSize minSize = (KFileSize) ( _parentView->minTileSize() / scale ); + +#if 0 + if ( _orig->hasChildren() ) + { + _cushionSurface.addRidge( KTreemapHorizontal, _cushionSurface.height(), rect ); + _cushionSurface.addRidge( KTreemapVertical, _cushionSurface.height(), rect ); + } +#endif + + KFileInfoSortedBySizeIterator it( _orig, minSize, KDotEntryAsSubDir ); + QRect childrenRect = rect; + + while ( *it ) + { + KFileInfoList row = squarify( childrenRect, scale, it ); + childrenRect = layoutRow( childrenRect, scale, row ); + } +} + + +KFileInfoList +KTreemapTile::squarify( const QRect & rect, + double scale, + KFileInfoSortedBySizeIterator & it ) +{ + // kdDebug() << "squarify() " << _orig << " " << rect << endl; + + KFileInfoList row; + int length = max( rect.width(), rect.height() ); + + if ( length == 0 ) // Sanity check + { + kdWarning() << k_funcinfo << "Zero length" << endl; + + if ( *it ) // Prevent endless loop in case of error: + ++it; // Advance iterator. + + return row; + } + + + bool improvingAspectRatio = true; + double lastWorstAspectRatio = -1.0; + double sum = 0; + + // This is a bit ugly, but doing all calculations in the 'size' dimension + // is more efficient here since that requires only one scaling before + // doing all other calculations in the loop. + const double scaledLengthSquare = length * (double) length / scale; + + while ( *it && improvingAspectRatio ) + { + sum += (*it)->totalSize(); + + if ( ! row.isEmpty() && sum != 0 && (*it)->totalSize() != 0 ) + { + double sumSquare = sum * sum; + double worstAspectRatio = max( scaledLengthSquare * row.first()->totalSize() / sumSquare, + sumSquare / ( scaledLengthSquare * (*it)->totalSize() ) ); + + if ( lastWorstAspectRatio >= 0.0 && + worstAspectRatio > lastWorstAspectRatio ) + { + improvingAspectRatio = false; + } + + lastWorstAspectRatio = worstAspectRatio; + } + + if ( improvingAspectRatio ) + { + // kdDebug() << "Adding " << *it << " size " << (*it)->totalSize() << endl; + row.append( *it ); + ++it; + } + else + { + // kdDebug() << "Getting worse after adding " << *it << " size " << (*it)->totalSize() << endl; + } + } + + return row; +} + + + +QRect +KTreemapTile::layoutRow( const QRect & rect, + double scale, + KFileInfoList & row ) +{ + if ( row.isEmpty() ) + return rect; + + // Determine the direction in which to subdivide. + // We always use the longer side of the rectangle. + KOrientation dir = rect.width() > rect.height() ? KTreemapHorizontal : KTreemapVertical; + + // This row's primary length is the longer one. + int primary = max( rect.width(), rect.height() ); + + // This row's secondary length is determined by the area (the number of + // pixels) to be allocated for all of the row's items. + KFileSize sum = row.sumTotalSizes(); + int secondary = (int) ( sum * scale / primary ); + + if ( sum == 0 ) // Prevent division by zero. + return rect; + + if ( secondary < _parentView->minTileSize() ) // We don't want tiles that small. + return rect; + + + // Set up a cushion surface for this layout row: + // Add another ridge perpendicular to the row's direction + // that optically groups this row's tiles together. + + KCushionSurface rowCushionSurface = _cushionSurface; + + rowCushionSurface.addRidge( dir == KTreemapHorizontal ? KTreemapVertical : KTreemapHorizontal, + _cushionSurface.height() * _parentView->heightScaleFactor(), + rect ); + + int offset = 0; + int remaining = primary; + KFileInfoListIterator it( row ); + + while ( *it ) + { + int childSize = (int) ( (*it)->totalSize() / (double) sum * primary + 0.5 ); + + if ( childSize > remaining ) // Prevent overflow because of accumulated rounding errors + childSize = remaining; + + remaining -= childSize; + + if ( childSize >= _parentView->minTileSize() ) + { + QRect childRect; + + if ( dir == KTreemapHorizontal ) + childRect = QRect( rect.x() + offset, rect.y(), childSize, secondary ); + else + childRect = QRect( rect.x(), rect.y() + offset, secondary, childSize ); + + KTreemapTile * tile = new KTreemapTile( _parentView, this, *it, childRect, rowCushionSurface ); + CHECK_PTR( tile ); + + tile->cushionSurface().addRidge( dir, + rowCushionSurface.height() * _parentView->heightScaleFactor(), + childRect ); + offset += childSize; + } + + ++it; + } + + + // Subtract the layouted area from the rectangle. + + QRect newRect; + + if ( dir == KTreemapHorizontal ) + newRect = QRect( rect.x(), rect.y() + secondary, rect.width(), rect.height() - secondary ); + else + newRect = QRect( rect.x() + secondary, rect.y(), rect.width() - secondary, rect.height() ); + + // kdDebug() << "Left over:" << " " << newRect << " " << _orig << endl; + + return newRect; +} + + +void +KTreemapTile::drawShape( QPainter & painter ) +{ + // kdDebug() << k_funcinfo << endl; + + QSize size = rect().size(); + + if ( size.height() < 1 || size.width() < 1 ) + return; + + + if ( _parentView->doCushionShading() ) + { + if ( _orig->isDir() || _orig->isDotEntry() ) + { + QCanvasRectangle::drawShape( painter ); + } + else + { + if ( _cushion.isNull() ) + _cushion = renderCushion(); + + QRect rect = QCanvasRectangle::rect(); + + if ( ! _cushion.isNull() ) + painter.drawPixmap( rect, _cushion ); + + if ( _parentView->forceCushionGrid() ) + { + // Draw a clearly visible boundary + + painter.setPen( QPen( _parentView->cushionGridColor(), 1 ) ); + + if ( rect.x() > 0 ) + painter.drawLine( rect.topLeft(), rect.bottomLeft() + QPoint( 0, 1 ) ); + + if ( rect.y() > 0 ) + painter.drawLine( rect.topLeft(), rect.topRight() + QPoint( 1, 0 ) ); + } + } + } + else // No cushion shading, use plain tiles + { + painter.setPen( QPen( _parentView->outlineColor(), 1 ) ); + + if ( _orig->isDir() || _orig->isDotEntry() ) + painter.setBrush( _parentView->dirFillColor() ); + else + { + painter.setBrush( _parentView->tileColor( _orig ) ); +#if 0 + painter.setBrush( _parentView->fileFillColor() ); +#endif + } + + QCanvasRectangle::drawShape( painter ); + } +} + + +QPixmap +KTreemapTile::renderCushion() +{ + QRect rect = QCanvasRectangle::rect(); + + if ( rect.width() < 1 || rect.height() < 1 ) + return QPixmap(); + + // kdDebug() << k_funcinfo << endl; + + double nx; + double ny; + double cosa; + int x, y; + int red, green, blue; + + + // Cache some values. They are used for each loop iteration, so let's try + // to keep multiple indirect references down. + + int ambientLight = parentView()->ambientLight(); + double lightX = parentView()->lightX(); + double lightY = parentView()->lightY(); + double lightZ = parentView()->lightZ(); + + double xx2 = cushionSurface().xx2(); + double xx1 = cushionSurface().xx1(); + double yy2 = cushionSurface().yy2(); + double yy1 = cushionSurface().yy1(); + + int x0 = rect.x(); + int y0 = rect.y(); + + QColor color = parentView()->tileColor( _orig ); + int maxRed = max( 0, color.red() - ambientLight ); + int maxGreen = max( 0, color.green() - ambientLight ); + int maxBlue = max( 0, color.blue() - ambientLight ); + + QImage image( rect.width(), rect.height(), 32 ); + + for ( y = 0; y < rect.height(); y++ ) + { + for ( x = 0; x < rect.width(); x++ ) + { + nx = 2.0 * xx2 * (x+x0) + xx1; + ny = 2.0 * yy2 * (y+y0) + yy1; + cosa = ( nx * lightX + ny * lightY + lightZ ) / sqrt( nx*nx + ny*ny + 1.0 ); + + red = (int) ( maxRed * cosa + 0.5 ); + green = (int) ( maxGreen * cosa + 0.5 ); + blue = (int) ( maxBlue * cosa + 0.5 ); + + if ( red < 0 ) red = 0; + if ( green < 0 ) green = 0; + if ( blue < 0 ) blue = 0; + + red += ambientLight; + green += ambientLight; + blue += ambientLight; + + image.setPixel( x, y, qRgb( red, green, blue) ); + } + } + + if ( _parentView->ensureContrast() ) + ensureContrast( image ); + + return QPixmap( image ); +} + + +void +KTreemapTile::ensureContrast( QImage & image ) +{ + if ( image.width() > 5 ) + { + // Check contrast along the right image boundary: + // + // Compare samples from the outmost boundary to samples a few pixels to + // the inside and count identical pixel values. A number of identical + // pixels are tolerated, but not too many. + + int x1 = image.width() - 6; + int x2 = image.width() - 1; + int interval = max( image.height() / 10, 5 ); + int sameColorCount = 0; + + + // Take samples + + for ( int y = interval; y < image.height(); y+= interval ) + { + if ( image.pixel( x1, y ) == image.pixel( x2, y ) ) + sameColorCount++; + } + + if ( sameColorCount * 10 > image.height() ) + { + // Add a line at the right boundary + + QRgb val = contrastingColor( image.pixel( x2, image.height() / 2 ) ); + + for ( int y = 0; y < image.height(); y++ ) + image.setPixel( x2, y, val ); + } + } + + + if ( image.height() > 5 ) + { + // Check contrast along the bottom boundary + + int y1 = image.height() - 6; + int y2 = image.height() - 1; + int interval = max( image.width() / 10, 5 ); + int sameColorCount = 0; + + for ( int x = interval; x < image.width(); x += interval ) + { + if ( image.pixel( x, y1 ) == image.pixel( x, y2 ) ) + sameColorCount++; + } + + if ( sameColorCount * 10 > image.height() ) + { + // Add a grey line at the bottom boundary + + QRgb val = contrastingColor( image.pixel( image.width() / 2, y2 ) ); + + for ( int x = 0; x < image.width(); x++ ) + image.setPixel( x, y2, val ); + } + } +} + + +QRgb +KTreemapTile::contrastingColor( QRgb col ) +{ + if ( qGray( col ) < 128 ) + return qRgb( qRed( col ) * 2, qGreen( col ) * 2, qBlue( col ) * 2 ); + else + return qRgb( qRed( col ) / 2, qGreen( col ) / 2, qBlue( col ) / 2 ); +} + + + + +KCushionSurface::KCushionSurface() +{ + _xx2 = 0.0; + _xx1 = 0.0; + _yy2 = 0.0; + _yy1 = 0.0; + _height = CushionHeight; +} + + +void +KCushionSurface::addRidge( KOrientation dim, double height, const QRect & rect ) +{ + _height = height; + + if ( dim == KTreemapHorizontal ) + { + _xx2 = squareRidge( _xx2, _height, rect.left(), rect.right() ); + _xx1 = linearRidge( _xx1, _height, rect.left(), rect.right() ); + } + else + { + _yy2 = squareRidge( _yy2, _height, rect.top(), rect.bottom() ); + _yy1 = linearRidge( _yy1, _height, rect.top(), rect.bottom() ); + } +} + + +double +KCushionSurface::squareRidge( double squareCoefficient, double height, int x1, int x2 ) +{ + if ( x2 != x1 ) // Avoid division by zero + squareCoefficient -= 4.0 * height / ( x2 - x1 ); + + return squareCoefficient; +} + + +double +KCushionSurface::linearRidge( double linearCoefficient, double height, int x1, int x2 ) +{ + if ( x2 != x1 ) // Avoid division by zero + linearCoefficient += 4.0 * height * ( x2 + x1 ) / ( x2 - x1 ); + + return linearCoefficient; +} + + + + +// EOF diff --git a/kdirstat/ktreemaptile.h b/kdirstat/ktreemaptile.h new file mode 100644 index 0000000..93b1ce3 --- /dev/null +++ b/kdirstat/ktreemaptile.h @@ -0,0 +1,323 @@ +/* + * File name: ktreemaptile.h + * Summary: High level classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-01-07 + */ + + +#ifndef KTreemapTile_h +#define KTreemapTile_h + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "kdirtreeiterators.h" + + +namespace KDirStat +{ + class KFileInfo; + class KTreemapView; + + enum KOrientation + { + KTreemapHorizontal, + KTreemapVertical, + KTreemapAuto + }; + + + /** + * Helper class for cushioned treemaps: This class holds the polynome + * parameters for the cushion surface. The height of each point of such a + * surface is defined as: + * + * z(x, y) = a*x^2 + b*y^2 + c*x + d*y + * or + * z(x, y) = xx2*x^2 + yy2*y^2 + xx1*x + yy1*y + * + * to better keep track of which coefficient belongs where. + **/ + class KCushionSurface + { + public: + /** + * Constructor. All polynome coefficients are set to 0. + **/ + KCushionSurface(); + + /** + * Adds a ridge of the specified height in dimension 'dim' within + * rectangle 'rect' to this surface. It's real voodo magic. + * + * Just kidding - read the paper about "cushion treemaps" by Jarke + * J. van Wiik and Huub van de Wetering from the TU Eindhoven, NL for + * more details. + * + * If you don't want to get all that involved: The coefficients are + * changed in some way. + **/ + void addRidge( KOrientation dim, double height, const QRect & rect ); + + /** + * Set the cushion's height. + **/ + void setHeight( double newHeight ) { _height = newHeight; } + + /** + * Returns the cushion's height. + **/ + double height() const { return _height; } + + /** + * Returns the polynomal coefficient of the second order for X direction. + **/ + double xx2() const { return _xx2; } + + /** + * Returns the polynomal coefficient of the first order for X direction. + **/ + double xx1() const { return _xx1; } + + /** + * Returns the polynomal coefficient of the second order for Y direction. + **/ + double yy2() const { return _yy2; } + + /** + * Returns the polynomal coefficient of the first order for Y direction. + **/ + double yy1() const { return _yy1; } + + + protected: + + /** + * Calculate a new square polynomal coefficient for adding a ridge of + * specified height between x1 and x2. + **/ + double squareRidge( double squareCoefficient, double height, int x1, int x2 ); + + /** + * Calculate a new linear polynomal coefficient for adding a ridge of + * specified height between x1 and x2. + **/ + double linearRidge( double linearCoefficient, double height, int x1, int x2 ); + + + // Data members + + double _xx2, _xx1; + double _yy2, _yy1; + double _height; + + }; // class KCushionSurface + + + + /** + * This is the basic building block of a treemap view: One single tile of a + * treemap. If it corresponds to a leaf in the tree, it will be visible as + * one tile (one rectangle) of the treemap. If it has children, it will be + * subdivided again. + * + * @short Basic building block of a treemap + **/ + class KTreemapTile: public QCanvasRectangle + { + public: + + /** + * Constructor: Create a treemap tile from 'fileinfo' that fits into a + * rectangle 'rect' inside 'parent'. + * + * 'orientation' is the direction for further subdivision. 'Auto' + * selects the wider direction inside 'rect'. + **/ + KTreemapTile( KTreemapView * parentView, + KTreemapTile * parentTile, + KFileInfo * orig, + const QRect & rect, + KOrientation orientation = KTreemapAuto ); + + protected: + + /** + * Alternate constructor: Like the above, but explicitly specify a + * cushion surface rather than using the parent's. + **/ + KTreemapTile( KTreemapView * parentView, + KTreemapTile * parentTile, + KFileInfo * orig, + const QRect & rect, + const KCushionSurface & cushionSurface, + KOrientation orientation = KTreemapAuto ); + + public: + /** + * Destructor. + **/ + virtual ~KTreemapTile(); + + + /** + * Returns the original @ref KFileInfo item that corresponds to this + * treemap tile. + **/ + KFileInfo * orig() const { return _orig; } + + /** + * Returns the parent @ref KTreemapView. + **/ + KTreemapView * parentView() const { return _parentView; } + + /** + * Returns the parent @ref KTreemapTile or 0 if there is none. + **/ + KTreemapTile * parentTile() const { return _parentTile; } + + /** + * Returns this tile's cushion surface parameters. + **/ + KCushionSurface & cushionSurface() { return _cushionSurface; } + + + protected: + + /** + * Create children (sub-tiles) of this tile. + **/ + void createChildren ( const QRect & rect, + KOrientation orientation ); + + /** + * Create children (sub-tiles) using the simple treemap algorithm: + * Alternate between horizontal and vertical subdivision in each + * level. Each child will get the entire height or width, respectively, + * of the specified rectangle. This algorithm is very fast, but often + * results in very thin, elongated tiles. + **/ + void createChildrenSimple( const QRect & rect, + KOrientation orientation ); + + /** + * Create children using the "squarified treemaps" algorithm as + * described by Mark Bruls, Kees Huizing, and Jarke J. van Wijk of the + * TU Eindhoven, NL. + * + * This algorithm is not quite so simple and involves more expensive + * operations, e.g., sorting the children of each node by size first, + * try some variations of the layout and maybe backtrack to the + * previous attempt. But it results in tiles that are much more + * square-like, i.e. have more reasonable width-to-height ratios. It is + * very much less likely to get thin, elongated tiles that are hard to + * point at and even harder to compare visually against each other. + * + * This implementation includes some improvements to that basic + * algorithm. For example, children below a certain size are + * disregarded completely since they will not get an adequate visual + * representation anyway (it would be way too small). They are + * summarized in some kind of 'misc stuff' area in the parent treemap + * tile - in fact, part of the parent directory's tile can be "seen + * through". + * + * In short, a lot of small children that don't have any useful effect + * for the user in finding wasted disk space are omitted from handling + * and, most important, don't need to be sorted by size (which has a + * cost of O(n*ln(n)) in the best case, so reducing n helps a lot). + **/ + void createSquarifiedChildren( const QRect & rect ); + + /** + * Squarify as many children as possible: Try to squeeze members + * referred to by 'it' into 'rect' until the aspect ratio doesn't get + * better any more. Returns a list of children that should be laid out + * in 'rect'. Moves 'it' until there is no more improvement or 'it' + * runs out of items. + * + * 'scale' is the scaling factor between file sizes and pixels. + **/ + KFileInfoList squarify( const QRect & rect, + double scale, + KFileInfoSortedBySizeIterator & it ); + + /** + * Lay out all members of 'row' within 'rect' along its longer side. + * Returns the new rectangle with the layouted area subtracted. + **/ + QRect layoutRow( const QRect & rect, + double scale, + KFileInfoList & row ); + + /** + * Draw the tile. + * + * Reimplemented from QCanvasRectangle. + **/ + virtual void drawShape( QPainter & painter ); + + /** + * Render a cushion as described in "cushioned treemaps" by Jarke + * J. van Wijk and Huub van de Wetering of the TU Eindhoven, NL. + **/ + QPixmap renderCushion(); + + /** + * Check if the contrast of the specified image is sufficient to + * visually distinguish an outline at the right and bottom borders + * and add a grey line there, if necessary. + **/ + void ensureContrast( QImage & image ); + + /** + * Returns a color that gives a reasonable contrast to 'col': Lighter + * if 'col' is dark, darker if 'col' is light. + **/ + QRgb contrastingColor( QRgb col ); + + private: + + /** + * Initialization common to all constructors. + **/ + void init(); + + + protected: + + // Data members + + KTreemapView * _parentView; + KTreemapTile * _parentTile; + KFileInfo * _orig; + KCushionSurface _cushionSurface; + QPixmap _cushion; + + }; // class KTreemapTile + +} // namespace KDirStat + + + +inline kdbgstream & operator<< ( kdbgstream & stream, const QRect & rect ) +{ + stream << "(" + << rect.width() << "x" << rect.height() + << "+" << rect.x() << "+" << rect.y() + << ")"; + + return stream; +} + + +#endif // ifndef KTreemapTile_h + + +// EOF diff --git a/kdirstat/ktreemapview.cpp b/kdirstat/ktreemapview.cpp new file mode 100644 index 0000000..2a8bf20 --- /dev/null +++ b/kdirstat/ktreemapview.cpp @@ -0,0 +1,745 @@ +/* + * File name: ktreemapview.cpp + * Summary: High level classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-10-20 + */ + + +#include + +#include +#include + +#include +#include +#include +#include + +#include "kdirtree.h" +#include "ktreemapview.h" +#include "ktreemaptile.h" + + +using namespace KDirStat; + +#define UpdateMinSize 20 + + + +KTreemapView::KTreemapView( KDirTree * tree, QWidget * parent, const QSize & initialSize ) + : QCanvasView( parent ) + , _tree( tree ) + , _rootTile( 0 ) + , _selectedTile( 0 ) + , _selectionRect( 0 ) +{ + // kdDebug() << k_funcinfo << endl; + + readConfig(); + + // Default values for light sources taken from Wiik / Wetering's paper + // about "cushion treemaps". + + _lightX = 0.09759; + _lightY = 0.19518; + _lightZ = 0.9759; + + if ( _autoResize ) + { + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOff ); + } + + if ( initialSize.isValid() ) + resize( initialSize ); + + if ( tree && tree->root() ) + { + if ( ! _rootTile ) + { + // The treemap might already be created indirectly by + // rebuildTreemap() called from resizeEvent() triggered by resize() + // above. If this is so, don't do it again. + + rebuildTreemap( tree->root() ); + } + } + + connect( this, SIGNAL( selectionChanged( KFileInfo * ) ), + tree, SLOT ( selectItem ( KFileInfo * ) ) ); + + connect( tree, SIGNAL( selectionChanged( KFileInfo * ) ), + this, SLOT ( selectTile ( KFileInfo * ) ) ); + + connect( tree, SIGNAL( deletingChild ( KFileInfo * ) ), + this, SLOT ( deleteNotify ( KFileInfo * ) ) ); + + connect( tree, SIGNAL( childDeleted() ), + this, SLOT ( rebuildTreemap() ) ); +} + + +KTreemapView::~KTreemapView() +{ +} + + +void +KTreemapView::clear() +{ + if ( canvas() ) + deleteAllItems( canvas() ); + + _selectedTile = 0; + _selectionRect = 0; + _rootTile = 0; +} + + +void +KTreemapView::deleteAllItems( QCanvas * canvas ) +{ + if ( ! canvas ) + return; + + QCanvasItemList all = canvas->allItems(); + + for ( QCanvasItemList::Iterator it = all.begin(); it != all.end(); ++it ) + delete *it; +} + + +void +KTreemapView::readConfig() +{ + KConfig * config = kapp->config(); + config->setGroup( "Treemaps" ); + + _ambientLight = config->readNumEntry( "AmbientLight" , DefaultAmbientLight ); + + _heightScaleFactor = config->readDoubleNumEntry( "HeightScaleFactor" , DefaultHeightScaleFactor ); + _autoResize = config->readBoolEntry( "AutoResize" , true ); + _squarify = config->readBoolEntry( "Squarify" , true ); + _doCushionShading = config->readBoolEntry( "CushionShading" , true ); + _ensureContrast = config->readBoolEntry( "EnsureContrast" , true ); + _forceCushionGrid = config->readBoolEntry( "ForceCushionGrid" , false ); + _minTileSize = config->readNumEntry ( "MinTileSize" , DefaultMinTileSize ); + + _highlightColor = readColorEntry( config, "HighlightColor" , red ); + _cushionGridColor = readColorEntry( config, "CushionGridColor" , QColor( 0x80, 0x80, 0x80 ) ); + _outlineColor = readColorEntry( config, "OutlineColor" , black ); + _fileFillColor = readColorEntry( config, "FileFillColor" , QColor( 0xde, 0x8d, 0x53 ) ); + _dirFillColor = readColorEntry( config, "DirFillColor" , QColor( 0x10, 0x7d, 0xb4 ) ); + + if ( _autoResize ) + { + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOff ); + } + else + { + setHScrollBarMode( QScrollView::Auto ); + setVScrollBarMode( QScrollView::Auto ); + } +} + + +QColor +KTreemapView::readColorEntry( KConfig * config, const char * entryName, QColor defaultColor ) +{ + return config->readColorEntry( entryName, &defaultColor ); +} + + +KTreemapTile * +KTreemapView::tileAt( QPoint pos ) +{ + KTreemapTile * tile = 0; + + QCanvasItemList coll = canvas()->collisions( pos ); + QCanvasItemList::Iterator it = coll.begin(); + + while ( it != coll.end() && tile == 0 ) + { + tile = dynamic_cast (*it); + ++it; + } + + return tile; +} + + +void +KTreemapView::contentsMousePressEvent( QMouseEvent * event ) +{ + // kdDebug() << k_funcinfo << endl; + + KTreemapTile * tile = tileAt( event->pos() ); + + switch ( event->button() ) + { + case LeftButton: + selectTile( tile ); + emit userActivity( 1 ); + break; + + case MidButton: + // Select clicked tile's parent, if available + + if ( _selectedTile && + _selectedTile->rect().contains( event->pos() ) ) + { + if ( _selectedTile->parentTile() ) + tile = _selectedTile->parentTile(); + } + + // Intentionally handling the middle button like the left button if + // the user clicked outside the (old) selected tile: Simply select + // the clicked tile. This makes using this middle mouse button + // intuitive: It can be used very much like the left mouse button, + // but it has added functionality. Plus, it cycles back to the + // clicked tile if the user has already clicked all the way up the + // hierarchy (i.e. the topmost directory is highlighted). + + selectTile( tile ); + emit userActivity( 1 ); + break; + + case RightButton: + + if ( tile ) + { + if ( _selectedTile && + _selectedTile->rect().contains( event->pos() ) ) + { + // If a directory (non-leaf tile) is already selected, + // don't override this by + + emit contextMenu( _selectedTile, event->globalPos() ); + } + else + { + selectTile( tile ); + emit contextMenu( tile, event->globalPos() ); + } + + emit userActivity( 3 ); + } + break; + + default: + // event->button() is an enum, so g++ complains + // if there are unhandled cases. + break; + } +} + + +void +KTreemapView::contentsMouseDoubleClickEvent( QMouseEvent * event ) +{ + // kdDebug() << k_funcinfo << endl; + + KTreemapTile * tile = tileAt( event->pos() ); + + switch ( event->button() ) + { + case LeftButton: + if ( tile ) + { + selectTile( tile ); + zoomIn(); + emit userActivity( 5 ); + } + break; + + case MidButton: + zoomOut(); + emit userActivity( 5 ); + break; + + case RightButton: + // Double-clicking the right mouse button is pretty useless - the + // first click opens the context menu: Single clicks are always + // delivered first. Even if that would be caught by using timers, + // it would still be very awkward to use: Click too slow, and + // you'll get the context menu rather than what you really wanted - + // then you'd have to get rid of the context menu first. + break; + + default: + // Prevent compiler complaints about missing enum values in switch + break; + } +} + + +void +KTreemapView::zoomIn() +{ + if ( ! _selectedTile || ! _rootTile ) + return; + + KTreemapTile * newRootTile = _selectedTile; + + while ( newRootTile->parentTile() != _rootTile && + newRootTile->parentTile() ) // This should never happen, but who knows? + { + newRootTile = newRootTile->parentTile(); + } + + if ( newRootTile ) + { + KFileInfo * newRoot = newRootTile->orig(); + + if ( newRoot->isDir() || newRoot->isDotEntry() ) + rebuildTreemap( newRoot ); + } +} + + +void +KTreemapView::zoomOut() +{ + if ( _rootTile ) + { + KFileInfo * root = _rootTile->orig(); + + if ( root->parent() ) + root = root->parent(); + + rebuildTreemap( root ); + } +} + + +void +KTreemapView::selectParent() +{ + if ( _selectedTile && _selectedTile->parentTile() ) + selectTile( _selectedTile->parentTile() ); +} + + +bool +KTreemapView::canZoomIn() const +{ + if ( ! _selectedTile || ! _rootTile ) + return false; + + if ( _selectedTile == _rootTile ) + return false; + + KTreemapTile * newRootTile = _selectedTile; + + while ( newRootTile->parentTile() != _rootTile && + newRootTile->parentTile() ) // This should never happen, but who knows? + { + newRootTile = newRootTile->parentTile(); + } + + if ( newRootTile ) + { + KFileInfo * newRoot = newRootTile->orig(); + + if ( newRoot->isDir() || newRoot->isDotEntry() ) + return true; + } + + return false; +} + + +bool +KTreemapView::canZoomOut() const +{ + if ( ! _rootTile || ! _tree->root() ) + return false; + + return _rootTile->orig() != _tree->root(); +} + + +bool +KTreemapView::canSelectParent() const +{ + return _selectedTile && _selectedTile->parentTile(); +} + + +void +KTreemapView::rebuildTreemap() +{ + KFileInfo * root = 0; + + if ( ! _savedRootUrl.isEmpty() ) + { + // kdDebug() << "Restoring old treemap with root " << _savedRootUrl << endl; + + root = _tree->locate( _savedRootUrl, true ); // node, findDotEntries + } + + if ( ! root ) + root = _rootTile ? _rootTile->orig() : _tree->root(); + + rebuildTreemap( root, canvas()->size() ); + _savedRootUrl = ""; +} + + +void +KTreemapView::rebuildTreemap( KFileInfo * newRoot, + const QSize & newSz ) +{ + // kdDebug() << k_funcinfo << endl; + + QSize newSize = newSz; + + if ( newSz.isEmpty() ) + newSize = visibleSize(); + + + // Delete all old stuff. + clear(); + + // Re-create a new canvas + + if ( ! canvas() ) + { + QCanvas * canv = new QCanvas( this ); + CHECK_PTR( canv ); + setCanvas( canv ); + } + + canvas()->resize( newSize.width(), newSize.height() ); + + if ( newSize.width() >= UpdateMinSize && newSize.height() >= UpdateMinSize ) + { + // The treemap contents is displayed if larger than a certain minimum + // visible size. This is an easy way for the user to avoid + // time-consuming delays when deleting a lot of files: Simply make the + // treemap (sub-) window very small. + + // Fill the new canvas + + if ( newRoot ) + { + _rootTile = new KTreemapTile( this, // parentView + 0, // parentTile + newRoot, // orig + QRect( QPoint( 0, 0), newSize ), + KTreemapAuto ); + } + + + // Synchronize selection with the tree + + if ( _tree->selection() ) + selectTile( _tree->selection() ); + } + else + { + // kdDebug() << "Too small - suppressing treemap contents" << endl; + } + + emit treemapChanged(); +} + + +void +KTreemapView::deleteNotify( KFileInfo * ) +{ + if ( _rootTile ) + { + if ( _rootTile->orig() != _tree->root() ) + { + // If the user zoomed the treemap in, save the root's URL so the + // current state can be restored upon the next rebuildTreemap() + // call (which is triggered by the childDeleted() signal that the + // tree emits after deleting is done). + // + // Intentionally using debugUrl() here rather than just url() so + // the correct zoom can be restored even when a dot entry is the + // current treemap root. + + _savedRootUrl = _rootTile->orig()->debugUrl(); + } + else + { + // A shortcut for the most common case: No zoom. Simply use the + // tree's root for the next treemap rebuild. + + _savedRootUrl = ""; + } + } + else + { + // Intentionally leaving _savedRootUrl alone: Otherwise multiple + // deleteNotify() calls might cause a previously saved _savedRootUrl to + // be unnecessarily deleted, thus the treemap couldn't be restored as + // it was. + } + + clear(); +} + + +void +KTreemapView::resizeEvent( QResizeEvent * event ) +{ + QCanvasView::resizeEvent( event ); + + if ( _autoResize ) + { + bool tooSmall = + event->size().width() < UpdateMinSize || + event->size().height() < UpdateMinSize; + + if ( tooSmall && _rootTile ) + { + // kdDebug() << "Suppressing treemap contents" << endl; + rebuildTreemap( _rootTile->orig() ); + } + else if ( ! tooSmall && ! _rootTile ) + { + if ( _tree->root() ) + { + // kdDebug() << "Redisplaying suppressed treemap contents" << endl; + rebuildTreemap( _tree->root() ); + } + } + else if ( _rootTile ) + { + // kdDebug() << "Auto-resizing treemap" << endl; + rebuildTreemap( _rootTile->orig() ); + } + } +} + + +void +KTreemapView::selectTile( KTreemapTile * tile ) +{ + // kdDebug() << k_funcinfo << endl; + + KTreemapTile * oldSelection = _selectedTile; + _selectedTile = tile; + + + // Handle selection (highlight) rectangle + + if ( _selectedTile ) + { + if ( ! _selectionRect ) + _selectionRect = new KTreemapSelectionRect( canvas(), _highlightColor ); + } + + if ( _selectionRect ) + _selectionRect->highlight( _selectedTile ); + + canvas()->update(); + + if ( oldSelection != _selectedTile ) + { + emit selectionChanged( _selectedTile ? _selectedTile->orig() : 0 ); + } +} + + +void +KTreemapView::selectTile( KFileInfo * node ) +{ + selectTile( findTile( node ) ); +} + + + +KTreemapTile * +KTreemapView::findTile( KFileInfo * node ) +{ + if ( ! node ) + return 0; + + QCanvasItemList itemList = canvas()->allItems(); + QCanvasItemList::Iterator it = itemList.begin(); + + while ( it != itemList.end() ) + { + KTreemapTile * tile = dynamic_cast (*it); + + if ( tile && tile->orig() == node ) + return tile; + + ++it; + } + + return 0; +} + + +QSize +KTreemapView::visibleSize() +{ + ScrollBarMode oldHMode = hScrollBarMode(); + ScrollBarMode oldVMode = vScrollBarMode(); + + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOff ); + + QSize size = QSize( QCanvasView::visibleWidth(), + QCanvasView::visibleHeight() ); + + setHScrollBarMode( oldHMode ); + setVScrollBarMode( oldVMode ); + + return size; +} + + +QColor +KTreemapView::tileColor( KFileInfo * file ) +{ + if ( file ) + { + if ( file->isFile() ) + { + // Find the filename extension: Everything after the first '.' + QString ext = file->name().section( '.', 1 ); + + while ( ! ext.isEmpty() ) + { + QString lowerExt = ext.lower(); + + // Try case sensitive comparisions first + + if ( ext == "~" ) return Qt::red; + if ( ext == "bak" ) return Qt::red; + + if ( ext == "c" ) return Qt::blue; + if ( ext == "cpp" ) return Qt::blue; + if ( ext == "cc" ) return Qt::blue; + if ( ext == "h" ) return Qt::blue; + if ( ext == "hpp" ) return Qt::blue; + if ( ext == "el" ) return Qt::blue; + + if ( ext == "o" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "lo" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "Po" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "al" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "moc.cpp" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "moc.cc" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "elc" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "la" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "a" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( ext == "rpm" ) return QColor( 0xff, 0xa0, 0x00 ); + + if ( lowerExt == "tar.bz2" ) return Qt::green; + if ( lowerExt == "tar.gz" ) return Qt::green; + if ( lowerExt == "tgz" ) return Qt::green; + if ( lowerExt == "bz2" ) return Qt::green; + if ( lowerExt == "bz" ) return Qt::green; + if ( lowerExt == "gz" ) return Qt::green; + + if ( lowerExt == "html" ) return Qt::blue; + if ( lowerExt == "htm" ) return Qt::blue; + if ( lowerExt == "txt" ) return Qt::blue; + if ( lowerExt == "doc" ) return Qt::blue; + + if ( lowerExt == "png" ) return Qt::cyan; + if ( lowerExt == "jpg" ) return Qt::cyan; + if ( lowerExt == "jpeg" ) return Qt::cyan; + if ( lowerExt == "gif" ) return Qt::cyan; + if ( lowerExt == "tif" ) return Qt::cyan; + if ( lowerExt == "tiff" ) return Qt::cyan; + if ( lowerExt == "bmp" ) return Qt::cyan; + if ( lowerExt == "xpm" ) return Qt::cyan; + if ( lowerExt == "tga" ) return Qt::cyan; + + if ( lowerExt == "wav" ) return Qt::yellow; + if ( lowerExt == "mp3" ) return Qt::yellow; + + if ( lowerExt == "avi" ) return QColor( 0xa0, 0xff, 0x00 ); + if ( lowerExt == "mov" ) return QColor( 0xa0, 0xff, 0x00 ); + if ( lowerExt == "mpg" ) return QColor( 0xa0, 0xff, 0x00 ); + if ( lowerExt == "mpeg" ) return QColor( 0xa0, 0xff, 0x00 ); + + if ( lowerExt == "pdf" ) return Qt::blue; + if ( lowerExt == "ps" ) return Qt::cyan; + + + // Some DOS/Windows types + + if ( lowerExt == "exe" ) return Qt::magenta; + if ( lowerExt == "com" ) return Qt::magenta; + if ( lowerExt == "dll" ) return QColor( 0xff, 0xa0, 0x00 ); + if ( lowerExt == "zip" ) return Qt::green; + if ( lowerExt == "arj" ) return Qt::green; + + + // No match so far? Try the next extension. Some files might have + // more than one, e.g., "tar.bz2" - if there is no match for + // "tar.bz2", there might be one for just "bz2". + + ext = ext.section( '.', 1 ); + } + + // Shared libs + if ( QRegExp( "lib.*\\.so.*" ).exactMatch( file->name() ) ) + return QColor( 0xff, 0xa0, 0x00 ); + + // Very special, but common: Core dumps + if ( file->name() == "core" ) return Qt::red; + + // Special case: Executables + if ( ( file->mode() & S_IXUSR ) == S_IXUSR ) return Qt::magenta; + } + else // Directories + { + // TO DO + return Qt::blue; + } + } + + return Qt::white; +} + + + + + + +KTreemapSelectionRect::KTreemapSelectionRect( QCanvas * canvas, const QColor & color ) + : QCanvasRectangle( canvas ) +{ + setPen( QPen( color, 2 ) ); + setZ( 1e10 ); // Higher than everything else +} + + + +void +KTreemapSelectionRect::highlight( KTreemapTile * tile ) +{ + if ( tile ) + { + QRect tileRect = tile->rect(); + + move( tileRect.x(), tileRect.y() ); + setSize( tileRect.width(), tileRect.height() ); + + if ( ! isVisible() ) + show(); + } + else + { + if ( isVisible() ) + hide(); + } +} + + + +// EOF diff --git a/kdirstat/ktreemapview.h b/kdirstat/ktreemapview.h new file mode 100644 index 0000000..86edd97 --- /dev/null +++ b/kdirstat/ktreemapview.h @@ -0,0 +1,446 @@ +/* + * File name: ktreemapview.h + * Summary: High level classes for KDirStat + * License: LGPL - See file COPYING.LIB for details. + * Author: Stefan Hundhammer + * + * Updated: 2003-02-02 + */ + + +#ifndef KTreemapView_h +#define KTreemapView_h + +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#define MinAmbientLight 0 +#define MaxAmbientLight 200 +#define DefaultAmbientLight 40 + +#define MinHeightScalePercent 10 +#define MaxHeightScalePercent 200 +#define DefaultHeightScalePercent 100 +#define DefaultHeightScaleFactor ( DefaultHeightScalePercent / 100.0 ) + +#define DefaultMinTileSize 3 +#define CushionHeight 1.0 + + +class QMouseEvent; +class KConfig; + +namespace KDirStat +{ + class KTreemapTile; + class KTreemapSelectionRect; + class KDirTree; + class KFileInfo; + + class KTreemapView: public QCanvasView + { + Q_OBJECT + + public: + /** + * Constructor. + **/ + KTreemapView( KDirTree * tree, + QWidget * parent = 0, + const QSize & initialSize = QSize() ); + + /** + * Destructor. + **/ + virtual ~KTreemapView(); + + /** + * Returns the (topmost) treemap tile at the specified position + * or 0 if there is none. + **/ + KTreemapTile * tileAt( QPoint pos ); + + /** + * Returns the minimum recommended size for this widget. + * Reimplemented from QWidget. + **/ + virtual QSize minimumSizeHint() const { return QSize( 0, 0 ); } + + /** + * Returns this treemap view's currently selected treemap tile or 0 if + * there is none. + **/ + KTreemapTile * selectedTile() const { return _selectedTile; } + + + /** + * Returns this treemap view's root treemap tile or 0 if there is none. + **/ + KTreemapTile * rootTile() const { return _rootTile; } + + /** + * Returns this treemap view's @ref KDirTree. + **/ + KDirTree * tree() const { return _tree; } + + /** + * Search the treemap for a tile that corresponds to the specified + * KFileInfo node. Returns 0 if there is none. + * + * Notice: This is an expensive operation since all treemap tiles need + * to be searched. + **/ + KTreemapTile * findTile( KFileInfo * node ); + + /** + * Returns a suitable color for 'file' based on a set of internal rules + * (according to filename extension, MIME type or permissions). + **/ + QColor tileColor( KFileInfo * file ); + + + public slots: + + /** + * Make a treemap tile this treemap's selected tile. + * 'tile' may be 0. In this case, only the previous selection is + * deselected. + **/ + void selectTile( KTreemapTile * tile ); + + /** + * Search the treemap for a tile with the specified KFileInfo node and + * select that tile if it is found. If nothing is found or if 'node' is + * 0, the previously selected tile is deselected. + **/ + void selectTile( KFileInfo * node ); + + /** + * Zoom in one level towards the currently selected treemap tile: + * The entire treemap will be rebuilt with the near-topmost ancestor of + * the selected tile as the new root. + **/ + void zoomIn(); + + /** + * Zoom out one level: The parent (if there is any) KFileInfo node of + * the current treemap root becomes the new root. This usually works + * only after zoomIn(). + **/ + void zoomOut(); + + /** + * Select the parent of the currently selected tile (if possible). + * + * This is very much the same as clicking with the middle mouse button, + * but not quite: The middle mouse button cycles back to the tile + * clicked at if there is no more parent. This method does not (because + * there is no known mouse position). + **/ + void selectParent(); + + /** + * Completely rebuild the entire treemap from the internal tree's root + * on. + **/ + void rebuildTreemap(); + + /** + * Clear the treemap contents. + **/ + void clear(); + + /** + * Delete all items of a QCanvas. + * + * Strangely enough, QCanvas itself does not provide such a function. + **/ + static void deleteAllItems( QCanvas * canvas ); + + /** + * Notification that a dir tree node has been deleted. + **/ + void deleteNotify( KFileInfo * node ); + + /** + * Read some parameters from the global @ref KConfig object. + **/ + void readConfig(); + + public: + + /** + * Rebuild the treemap with 'newRoot' as the new root and the specified + * size. If 'newSize' is (0, 0), visibleSize() is used. + **/ + void rebuildTreemap( KFileInfo * newRoot, + const QSize & newSize = QSize() ); + + /** + * Returns the visible size of the viewport presuming no scrollbars are + * needed - which makes a lot more sense than fiddling with scrollbars + * since treemaps can be scaled to make scrollbars unnecessary. + **/ + QSize visibleSize(); + + /** + * Returns the visible width of the viewport presuming no scrollbars + * are needed. + * + * This uses visibleSize() which is a somewhat expensive operation, so + * if you need both visibleWidth() and visibleHeight(), better call + * visibleSize() once and access its width() and height() methods. + **/ + int visibleWidth() { return visibleSize().width(); } + + /** + * Returns the visible height of the viewport presuming no scrollbars + * are needed. + * + * This uses visibleSize() which is a somewhat expensive operation, so + * if you need both visibleWidth() and visibleHeight(), better call + * visibleSize() once and access its width() and height() methods. + **/ + int visibleHeight() { return visibleSize().height(); } + + /** + * Returns true if it is possible to zoom in with the currently + * selected tile, false if not. + **/ + bool canZoomIn() const; + + /** + * Returns true if it is possible to zoom out with the currently + * selected tile, false if not. + **/ + bool canZoomOut() const; + + /** + * Returns true if it is possible to select the parent of the currently + * selected tile, false if not. + **/ + bool canSelectParent() const; + + /** + * Returns 'true' if the treemap is automatically resized to fit into + * the available space, 'false' if not. + **/ + bool autoResize() const { return _autoResize; } + + /** + * Returns 'true' if treemap tiles are to be squarified upon creation, + * 'false' if not. + **/ + bool squarify() const { return _squarify; } + + /** + * Returns 'true' if cushion shading is to be used, 'false' if not. + **/ + bool doCushionShading() const { return _doCushionShading; } + + /** + * Returns 'true' if cushion shaded treemap tiles are to be separated + * by a grid, 'false' if not. + **/ + bool forceCushionGrid() const { return _forceCushionGrid; } + + /** + * Returns 'true' if tile boundary lines should be drawn for cushion + * treemaps, 'false' if not. + **/ + bool ensureContrast() const { return _ensureContrast; } + + /** + * Returns the minimum tile size in pixels. No treemap tiles less than + * this in width or height are desired. + **/ + int minTileSize() const { return _minTileSize; } + + /** + * Returns the cushion grid color. + **/ + const QColor & cushionGridColor() const { return _cushionGridColor; } + + /** + * Returns the outline color to use if cushion shading is not used. + **/ + const QColor & outlineColor() const { return _outlineColor; } + + /** + * Returns the fill color for non-directory treemap tiles when cushion + * shading is not used. + **/ + const QColor & fileFillColor() const { return _fileFillColor; } + + /** + * Returns the fill color for directory (or "dotentry") treemap tiles + * when cushion shading is not used. + **/ + const QColor & dirFillColor() const { return _dirFillColor; } + + /** + * Returns the intensity of ambient light for cushion shading + * [0..255] + **/ + int ambientLight() const { return _ambientLight; } + + /** + * Returns the X coordinate of a directed light source for cushion + * shading. + **/ + + double lightX() const { return _lightX; } + + /** + * Returns the Y coordinate of a directed light source for cushion + * shading. + **/ + double lightY() const { return _lightY; } + + /** + * Returns the Z coordinate of a directed light source for cushion + * shading. + **/ + double lightZ() const { return _lightZ; } + + /** + * Returns cushion ridge height degradation factor (0 .. 1.0) for each + * level of subdivision. + **/ + double heightScaleFactor() const { return _heightScaleFactor; } + + + signals: + + /** + * Emitted when the currently selected item changes. + * Caution: 'item' may be 0 when the selection is cleared. + **/ + void selectionChanged( KFileInfo * item ); + + /** + * Emitted when the treemap changes, e.g. is rebuilt, zoomed in, or + * zoomed out. + **/ + void treemapChanged(); + + /** + * Emitted when a context menu for this tile should be opened. + * (usually on right click). 'pos' contains the click's mouse + * coordinates. + **/ + void contextMenu( KTreemapTile * tile, const QPoint & pos ); + + /** + * Emitted at user activity. Some interactive actions are assigned an + * amount of "activity points" that can be used to judge whether or not + * the user is actually using this program or if it's just idly sitting + * around on the desktop. This is intended for use together with a @ref + * KActivityTracker. + **/ + void userActivity( int points ); + + + protected: + + /** + * Catch mouse click - emits a selectionChanged() signal. + **/ + virtual void contentsMousePressEvent( QMouseEvent * event ); + + /** + * Catch mouse double click: + * Left button double-click zooms in, + * right button double-click zooms out, + * middle button double-click rebuilds treemap. + **/ + virtual void contentsMouseDoubleClickEvent( QMouseEvent * event ); + + /** + * Resize the treemap view. Suppress the treemap contents if the size + * falls below a minimum size, redisplay it if it grows above that + * minimum size. + * + * Reimplemented from QFrame. + **/ + virtual void resizeEvent( QResizeEvent * event ); + + /** + * Convenience method to read a color from 'config'. + **/ + QColor readColorEntry( KConfig * config, + const char * entryName, + QColor defaultColor ); + + // Data members + + KDirTree * _tree; + KTreemapTile * _rootTile; + KTreemapTile * _selectedTile; + KTreemapSelectionRect * _selectionRect; + QString _savedRootUrl; + + bool _autoResize; + bool _squarify; + bool _doCushionShading; + bool _forceCushionGrid; + bool _ensureContrast; + int _minTileSize; + + QColor _highlightColor; + QColor _cushionGridColor; + QColor _outlineColor; + QColor _fileFillColor; + QColor _dirFillColor; + + int _ambientLight; + + double _lightX; + double _lightY; + double _lightZ; + + double _heightScaleFactor; + + }; // class KTreemapView + + + + /** + * Transparent rectangle to make a treemap tile clearly visible as + * "selected". Leaf tiles could do that on their own, but higher-level + * tiles (corresponding to directories) are obscured for the most part, so + * only a small portion (if any) of their highlighted outline could be + * visible. This selection rectangle simply draws a two-pixel red outline + * on top (i.e., great z-height) of everything else. The rectangle is + * transparent, so the treemap tile contents remain visible. + **/ + class KTreemapSelectionRect: public QCanvasRectangle + { + public: + + /** + * Constructor. + **/ + KTreemapSelectionRect( QCanvas * canvas, const QColor & color ); + + /** + * Highlight the specified treemap tile: Resize this selection + * rectangle to match this tile and move it to this tile's + * position. Show the selection rectangle if it is currently + * invisible. + **/ + void highlight( KTreemapTile * tile ); + + }; // class KTreemapSelectionRect + +} // namespace KDirStat + + +#endif // ifndef KTreemapView_h + + +// EOF diff --git a/kdirstat/lo16-app-kdirstat.png b/kdirstat/lo16-app-kdirstat.png new file mode 100644 index 0000000000000000000000000000000000000000..4bd140e8c5b9a60cc6080c3a88cd16429d392a25 GIT binary patch literal 303 zcmV+~0nq-5P)HUU5LRwba1Z{rjnR+B2_jTx&CdwKV`;mx_R80yCTK;RIVx zC{OgA8QgB4n>`WP2Q1UPf|x@UdKy85gfi;et~1 zIf4rc-{Yka0$B(ou;ra$BrxcGyAnSZNE17Kk$6p#QU_zclDXhrJr(3F!MSn&_iGMZ z2_4MvTShT6vr@_yVbJ=(}JP zyOc6|{#5ahHjZa!F^aoHT<1$;xBFAtL`Un2mgV4F>v@P2=T=Emkm5MBKUKVZHb7Bq zXZL++r=K(hAt$9Cd{o65GIIWuk`k!v%c2C9C<(wm#ikrCal8ru-h;|dBzpo&6Uhz` zOXL**vx&SM;E_a85+ApH4 cDa;xE2cxNpXzC!vS^xk507*qoM6N<$f=gKCH~;_u literal 0 HcmV?d00001 diff --git a/kdirstat/pics/Makefile.am b/kdirstat/pics/Makefile.am new file mode 100644 index 0000000..8ae12f6 --- /dev/null +++ b/kdirstat/pics/Makefile.am @@ -0,0 +1,2 @@ +iconsdir = $(kde_datadir)/kdirstat/icons +icons_ICON = AUTO diff --git a/kdirstat/pics/hi16-action-symlink.png b/kdirstat/pics/hi16-action-symlink.png new file mode 100644 index 0000000000000000000000000000000000000000..95ea7d91c436bc055f137af5d2c614416869422a GIT binary patch literal 433 zcmV;i0Z#sjP)c86G!;no)(US8h!`|E-K56iN404bNtKfbR_4w1=tGW(%aDqWeT zNe~39b38oZ;zhWA6*evfJkeSUK%>zRKpe-BTCH|isZ{oC+qSdW>`}~40T6_Mz^)1B z0WsNiT>z9)0B6&-xm+$k91c$=0{gdcunG6?i>w6z-}jG!8zZUl1+6`b#Ue^6BTnHs z4()cEZnt|^C={$#tMxP(47QRAT6>9dOa^dW*QnR)Z%V0kzyN4AoB4D)eF{tqXk%W~ zUaz+eJjC}*Ci5IcQIdG&x2~N|=P`B%==b~MFbu~F3(R6P8l|Er@_~=Pa=)Qkt*$LC bvNS#c1{!zl7uHUd00000NkvXXu0mjfIb5&$ literal 0 HcmV?d00001 diff --git a/kdirstat/pics/hi16-action-symlink.xcf b/kdirstat/pics/hi16-action-symlink.xcf new file mode 100644 index 0000000000000000000000000000000000000000..c269214845a0ce708c50b9194d66b39f470dbdb8 GIT binary patch literal 1863 zcmeH|O-xfk5P)a0QB(wX?zS()x-I>>B zt8JIDtD(u*WNotmN_0?(V^A5xAr4iu<}?5)%3Rbi)GE|@s9C6DGlt4&=&;!=?GCho zHpUm(E%gpdqj9g*(PFG_u^3CF@=AIdk4hoPOOZYR0oNjSDhoI(`H)}4`rXZzHhLI= zO1n9#CdlNW4Khv;8N#{{)`zed!coW+i$sO0Mx}Rk~&AXplAEy?IXN)s=KZ8=w-y|kse2r>vkY)SZsWZ1_YSp zIC#?QT*n#`7#4tRyLa6C;GVGIrExrU_vufZdj=Px!5LS9=lo~1ucz_|?uOP0AAffs z7M}_5mBW$?kDi>!6lkLgrZ|KrElSZcWQ;2Z*Zv@p=$ByuU6FE!a+Os!S*&uEQ5BH< zt7=OKyq-p3B*;ppSZ%_CpVx$EWNW~8#=Huv-`ig}KOSdanIQ}>(|xLYkr16Jd%;pOMwG{+W-jUcXI1%a=4bi%sVBalhPpsUXAJhp7Mn literal 0 HcmV?d00001 diff --git a/kdirstat/pics/hi32-action-symlink.png b/kdirstat/pics/hi32-action-symlink.png new file mode 100644 index 0000000000000000000000000000000000000000..1f3248a53d251ba2068641d751e3f25e63c69382 GIT binary patch literal 1140 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 literal 0 HcmV?d00001 diff --git a/kdirstat/pics/hi48-action-symlink.xcf b/kdirstat/pics/hi48-action-symlink.xcf new file mode 100644 index 0000000000000000000000000000000000000000..e944b60faec4c264522616b995ee1c11a43439c4 GIT binary patch literal 3926 zcmeHKX>3$g6h80GOsD%I44r9N2D(f;v@=72(w4S#ipU2&7K@til)cAD^4{liVpd*An+bMHCt z<-U9GtEyhO#Q6H0N@Hd90tZmD1&nbVnIzGr4_RpOCIB{SeaX~h#bi1%D_K+(4V5`( z@xq0UMK#2MJN6s9)KOOBs4%`(T{G7>W3IzEe&W;;_Vy#=Avh|YZbfwG##~!cSyo}p zQn;*Kl^9S3{6@apO9AYc2m#2w@EOv{M@_Q#V7V7QM=`rOgksKhW4RZmM-7ZG*?X|u z3-kCl1LO2ye=ff++n3OL;wR-?JvdnR*Z*@Mrj*9?<6vDbx=Q0@1jU?Fuxvj7P_$dY zfs6D9y;>hY^ok(WMwpG?Z^-0jRgMMh3?bv%kSsKSIU+28=?39JI3fr~2H~h6978x1 zsnMOAmdyYBJrgHE@hBJhy#Vg2kYeSJdTa6_=1x^MxHslS$K-EU zT8&y#yScw#$Pd-h@NODDGTP1&o5I6FrBFBVsFdmD%VM=!GR&z%CUfrVGt$%3Ov!^MU*(E- zl$cVde%Mp-cPDq&e)Kt4+JXu3meSd$pYV>f1|Ad)F^t#T9?=`sTM=zg#@L z?ahiKoUy6-hr8};myXprD_>z=-}F`Mji1gRtbLbHy80u72D3+WeQMlyUA`?^MsLDxEd4{5n^B zv}XF$s=eJ6YtRH?m_n8e5t#HCOAh!=ph2gqktbExtW&;=l1fLl@?CVTI{(`D!Knl7 zao>lb%L$;N?^|hImD2a2Y3{9QE;Dz^Yfv;?Kr?#It~Bn%G<17gR`gdLM-z7VE^aqy zV)rsU{)PdhB`uhOkJ_788bBU!0#otPg=Knx{?4N=$@So<>!7Q-eobxdxI?C8Nz(|?m z<#^fP>7Qx}0U3mT7gcm;tBxvvb%)D!V*jrCV~2JgUy;In4adpZ(XmP=NlAw>6vf7Y zihK(DVdrw%cHU<3ltB@Xk?3x%(?Q<`)S@`!SDR3ep5;1qeUNqv4d`8!xGzXLf(a=0 zHwP(u=$#6eGKhW)4nk=FJ#~PuW1l~Pem&zRf81t_M=#(23`5cAmv*qb!H*9x-lkWo zJ;ZpkAMa8oW|(ZI>_N7)%&|FkduCB)tVI7PLca)Q6m9n~5nwJ z327$PEUpft1Glg~U^$cihJ59u`sOI&BNm5}C{!h^+UN`|tb$c5?Vz3tq_?95pA|LS z*#O?Mw&C5vP)GnV($LM*Aq9Lk4(&l!)|Bp+Ze*kV*r$RB@MUta;xIGH;1ESKGqSK| zVwA>6(NY)g4+JF+swN9;WKg|r!D^&r@3_cMCsO3N?K_qa@{jjU zpIg@JoRTv!|Jl9YV*ePr9CFzhx&%Z8CI%Mw2p-teD$o?k@cYKEBCnUe$!UQnRwT?z z=2u_Jk~U4U>aAZ$!dh33hj9;;eR~QSIx?89)U3Z0Wh@o1sQu%IboSaubA+GIG1wfV j-Y{qL%}n, 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: de\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2004-03-01 14:25+0100\n" +"PO-Revision-Date: 2004-03-01 13:47:00+0100\n" +"Last-Translator: Stefan Hundhammer \n" +"Language-Team: Deutsch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: kcleanupcollection.cpp:231 +msgid "User Defined Cleanup #&%1" +msgstr "Benutzerdefinierte Aufräumaktion Nr. &%1" + +#: kcleanupcollection.cpp:234 +msgid "User Defined Cleanup #%1" +msgstr "Benutzerdefinierte Aufräumaktion #%1" + +#: kcleanup.cpp:169 +msgid "" +"%1\n" +"in directory %2" +msgstr "" +"%1\n" +"im Verzeichnis %2" + +#: kcleanup.cpp:173 +msgid "" +"%1\n" +"for file %2" +msgstr "" +"%1\n" +"für die Datei %2" + +#: kcleanup.cpp:178 kdirstatsettings.cpp:106 +msgid "Please Confirm" +msgstr "Bitte bestätigen" + +#: kcleanup.cpp:179 +msgid "Confirm" +msgstr "Bestätigen" + +#: kdirstatapp.cpp:145 +msgid "Open &URL..." +msgstr "&URL öffnen..." + +#: kdirstatapp.cpp:152 +msgid "Refresh &All" +msgstr "Alles &aktualisieren" + +#: kdirstatapp.cpp:156 +msgid "Refresh &Selected" +msgstr "Ausgewähltes Verzeichnis &neu einlesen" + +#: kdirstatapp.cpp:160 +msgid "Continue Reading at &Mount Point" +msgstr "Am &Mountpunkt weiterlesen" + +#: kdirstatapp.cpp:164 +msgid "Stop Rea&ding" +msgstr "Lesen Ab&brechen" + +#: kdirstatapp.cpp:173 +msgid "Zoom in" +msgstr "Vergrößern" + +#: kdirstatapp.cpp:177 +msgid "Zoom out" +msgstr "Verkleinern" + +#: kdirstatapp.cpp:181 +msgid "Select Parent" +msgstr "Nach oben" + +#: kdirstatapp.cpp:185 +msgid "Rebuild Treemap" +msgstr "Treemap neu aufbauen" + +#: kdirstatapp.cpp:189 +msgid "Show Treemap" +msgstr "Treemap anzeigen" + +#: kdirstatapp.cpp:193 +msgid "Help about Treemaps" +msgstr "Hilfe zu Treemaps" + +#: kdirstatapp.cpp:199 +msgid "Send &Mail to Owner" +msgstr "&Mail an Besitzer senden" + +#: kdirstatapp.cpp:203 +msgid "Send &Feedback Mail..." +msgstr "&Feedback-Mail versenden" + +#: kdirstatapp.cpp:208 +msgid "Opens a directory" +msgstr "Öffnet ein Verzeichnis" + +#: kdirstatapp.cpp:209 +msgid "Opens a (possibly remote) directory" +msgstr "Öffnet ein Verzeichnis (auch über Netzwerk)" + +#: kdirstatapp.cpp:210 +msgid "Opens a recently used directory" +msgstr "Öffnet ein kürzlich verwendetes Verzeichnis" + +#: kdirstatapp.cpp:211 +msgid "Closes the current directory" +msgstr "Schließt das aktuelle Verzeichnis" + +#: kdirstatapp.cpp:212 +msgid "Re-reads the entire directory tree" +msgstr "Liest den gesamten Verzeichnisbaum neu ein" + +#: kdirstatapp.cpp:213 +msgid "Re-reads the selected subtree" +msgstr "Liest den ausgewählten Teilbaum neu ein" + +#: kdirstatapp.cpp:214 +msgid "Scan mounted file systems" +msgstr "Gemountete Dateisysteme einlesen" + +#: kdirstatapp.cpp:215 +msgid "Stops directory reading" +msgstr "Lesen anhalten" + +#: kdirstatapp.cpp:216 +msgid "Quits the application" +msgstr "Beendet das Programm" + +#: kdirstatapp.cpp:217 +msgid "Copies the URL of the selected item to the clipboard" +msgstr "Kopiert die URL des ausgewählten Eintrags in die Zwischenablage" + +#: kdirstatapp.cpp:218 +msgid "Enables/disables the toolbar" +msgstr "Werkzeugleiste ein- und ausschalten" + +#: kdirstatapp.cpp:219 +msgid "Enables/disables the statusbar" +msgstr "Statusleiste ein- und ausschalten" + +#: kdirstatapp.cpp:220 +msgid "Enables/disables the treemap view" +msgstr "Werkzeugleiste ein- und ausschalten" + +#: kdirstatapp.cpp:221 +msgid "Zoom treemap in" +msgstr "Treemap vergrößern" + +#: kdirstatapp.cpp:222 +msgid "Zoom treemap out" +msgstr "Treemap verkleinern" + +#: kdirstatapp.cpp:223 +msgid "Select parent" +msgstr "Nach oben" + +#: kdirstatapp.cpp:224 +msgid "Rebuild treemap to fit into available space" +msgstr "Treemap in verfügbaren Platz einpassen" + +#: kdirstatapp.cpp:225 +msgid "Opens the preferences dialog" +msgstr "Öffnet den Einstellungsdialog" + +#: kdirstatapp.cpp:226 +msgid "Sends a mail to the owner of the selected subtree" +msgstr "Sendet eine Mail an den Besitzer des ausgewählten Teilbaumes" + +#: kdirstatapp.cpp:301 kdirstatapp.cpp:335 kdirstatapp.cpp:445 +#: kdirstatapp.cpp:460 kdirstatapp.cpp:472 kdirstatapp.cpp:485 +#: kdirstatapp.cpp:494 kdirstatapp.cpp:506 +msgid "Ready." +msgstr "Fertig." + +#: kdirstatapp.cpp:328 kdirstatapp.cpp:438 kdirstatapp.cpp:467 +msgid "Opening directory..." +msgstr "Verzeichnis öffnen..." + +#: kdirstatapp.cpp:440 +msgid "Open Directory..." +msgstr "Verzeichnis öffnen..." + +#: kdirstatapp.cpp:452 +msgid "Opening URL..." +msgstr "URL wird geöffnet..." + +#: kdirstatapp.cpp:455 +msgid "Open URL..." +msgstr "URL öffnen" + +#: kdirstatapp.cpp:479 +msgid "Closing directory..." +msgstr "Verzeichnis schließen..." + +#: kdirstatapp.cpp:492 +msgid "Refreshing directory tree..." +msgstr "Verzeichnisbaum neu einlesen..." + +#: kdirstatapp.cpp:504 +msgid "Refreshing selected subtree..." +msgstr "Ausgewählten Teilbaum neu einlesen..." + +#: kdirstatapp.cpp:684 +msgid "" +"Now that you know this program for some time,\n" +"wouldn't you like to tell the authors your opinion about it?\n" +"\n" +"Open Source software depends on user feedback.\n" +"Your opinion can help us make the software better." +msgstr "" +"Möchten Sie nicht vielleicht jetzt, da Sie dieses\n" +"Programm einigermaßen kennengelernt haben, den\n" +"Autoren Ihre Meinung darüber mitteilen?\n" +"\n" +"Open-Source-Software lebt davon, daß die Anwender mitmachen.\n" +"Ihre Meinung kann entscheidend dazu beitragen, die Software\n" +"besser zu machen." + +#: kdirstatapp.cpp:689 +msgid "Please tell us your opinion!" +msgstr "Bitte lassen Sie uns Ihre Meinung wissen!" + +#: kdirstatapp.cpp:690 +msgid "Open &Feedback Form..." +msgstr "&Feedback-Formular öffnen..." + +#: kdirstatapp.cpp:691 +msgid "&No, and don't ask again!" +msgstr "&Nein, und bitte nicht mehr nachfragen." + +#: kdirstatfeedback.cpp:33 +msgid "What is your general opinion about this program?" +msgstr "Wie finden Sie dieses Programm?" + +#: kdirstatfeedback.cpp:35 +msgid "It's one of my favourites" +msgstr "Es ist eines meiner Lieblingsprogramme" + +#: kdirstatfeedback.cpp:36 +msgid "I like it" +msgstr "Es gefällt mir" + +#: kdirstatfeedback.cpp:37 +msgid "It's sometimes useful" +msgstr "Ganz nett" + +#: kdirstatfeedback.cpp:38 +msgid "It's average" +msgstr "Es geht so" + +#: kdirstatfeedback.cpp:39 +msgid "Nice try, but this could be done better" +msgstr "Netter Versuch, aber stark verbesserungsbedürftig" + +#: kdirstatfeedback.cpp:40 +msgid "It's poor" +msgstr "Armselig" + +#: kdirstatfeedback.cpp:41 +msgid "It's useless" +msgstr "Nutzlos" + +#: kdirstatfeedback.cpp:42 +msgid "It's crap" +msgstr "So ein Mist!" + +#: kdirstatfeedback.cpp:44 +msgid "Which features of this program do you like?" +msgstr "Welche Eigenschaften dieses Programmes gefallen Ihnen?" + +#: kdirstatfeedback.cpp:47 +msgid "Which features don't you like?" +msgstr "Welche Eigenschaften gefallen Ihnen nicht?" + +#: kdirstatfeedback.cpp:50 +msgid "Which features do you never use?" +msgstr "Welche Funktionen benutzen Sie überhaupt nicht?" + +#: kdirstatfeedback.cpp:53 +msgid "What is your favourite feature?" +msgstr "Welche Funktion finden Sie besonders gut?" + +#: kdirstatfeedback.cpp:56 +msgid "Are there features you are missing?" +msgstr "Vermissen Sie irgendwelche Funktionen?" + +#: kdirstatfeedback.cpp:57 +msgid "Yes, a lot! (please add comment below)" +msgstr "Ja, eine ganze Menge! (Bitte im Kommentarfeld unten präzisieren)" + +#: kdirstatfeedback.cpp:58 +msgid "Some (please add comment below)" +msgstr "Sonstige (bitte unten Kommentar angeben)" + +#: kdirstatfeedback.cpp:59 +msgid "None" +msgstr "Keine" + +#: kdirstatfeedback.cpp:60 +msgid "It has too many features already!" +msgstr "Es ist jetzt schon überladen!" + +#: kdirstatfeedback.cpp:62 +msgid "How do you rate the stability of this program?" +msgstr "Wie beurteilen Sie die Stabilität dieses Programms?" + +#: kdirstatfeedback.cpp:63 +msgid "Rock solid" +msgstr "Bombenstabil" + +#: kdirstatfeedback.cpp:64 kdirstatfeedback.cpp:71 +msgid "Good" +msgstr "Gut" + +#: kdirstatfeedback.cpp:65 kdirstatfeedback.cpp:72 kdirstatfeedback.cpp:79 +#: kdirstatfeedback.cpp:86 +msgid "Average" +msgstr "Durchschnittlich" + +#: kdirstatfeedback.cpp:66 kdirstatfeedback.cpp:73 +msgid "Poor" +msgstr "Bescheiden" + +#: kdirstatfeedback.cpp:67 +msgid "It keeps crashing all the time" +msgstr "Es stürzt dauernd ab" + +#: kdirstatfeedback.cpp:69 +msgid "How do you rate the performance of this program?" +msgstr "Wie beurteilen Sie die Geschwindigkeit dieses Programms?" + +#: kdirstatfeedback.cpp:70 +msgid "Great" +msgstr "Hervorragend" + +#: kdirstatfeedback.cpp:74 +msgid "It's so slow it drives me nuts" +msgstr "Es ist so langsam, daß es mich wahnsinnig macht" + +#: kdirstatfeedback.cpp:76 +msgid "What is your experience with computers in general?" +msgstr "Wie beurteilen Sie Ihre Computerkenntnisse allgemein?" + +#: kdirstatfeedback.cpp:77 kdirstatfeedback.cpp:84 +msgid "Expert" +msgstr "Experte" + +#: kdirstatfeedback.cpp:78 kdirstatfeedback.cpp:85 +msgid "Fair" +msgstr "Einigermaßen gut" + +#: kdirstatfeedback.cpp:80 kdirstatfeedback.cpp:87 +msgid "Learning" +msgstr "Normaler Anwender" + +#: kdirstatfeedback.cpp:81 kdirstatfeedback.cpp:88 +msgid "Newbie" +msgstr "Einsteiger" + +#: kdirstatfeedback.cpp:83 +msgid "What is your experience with Unix/Linux systems?" +msgstr "Wie beurteilen Sie Ihre Linux- bzw. Unixkenntnisse?" + +#: kdirstatfeedback.cpp:90 +msgid "" +"Did you have trouble figuring out how to work with this program in general?" +msgstr "Fiel es Ihnen der Umgang mit diesem Programm am Anfang schwer?" + +#: kdirstatfeedback.cpp:92 +msgid "No problem" +msgstr "Kein Problem" + +#: kdirstatfeedback.cpp:93 +msgid "Some" +msgstr "Ein bißchen" + +#: kdirstatfeedback.cpp:94 kdirstatfeedback.cpp:132 +msgid "I'm still learning" +msgstr "Ich bin noch dabei, es herauszufinden" + +#: kdirstatfeedback.cpp:95 +msgid "I didn't have a clue what to do at first" +msgstr "Ich hatte anfangs überhaupt keine Ahnung" + +#: kdirstatfeedback.cpp:96 kdirstatfeedback.cpp:133 +msgid "I still don't have a clue what to do" +msgstr "Ich habe immer noch keine Ahnung" + +#: kdirstatfeedback.cpp:98 +msgid "Where do you use this program most?" +msgstr "Wo setzen Sie dieses Programm am meisten ein?" + +#: kdirstatfeedback.cpp:99 +msgid "At work" +msgstr "In der Arbeit" + +#: kdirstatfeedback.cpp:100 +msgid "At home" +msgstr "Zu Hause" + +#: kdirstatfeedback.cpp:101 +msgid "At university / school" +msgstr "In der Uni bzw. Schule" + +#: kdirstatfeedback.cpp:103 +msgid "What is your primary role there?" +msgstr "Was ist dort Ihre Hauptfunktion?" + +#: kdirstatfeedback.cpp:104 kdirstatfeedback.cpp:112 +msgid "Home user" +msgstr "Privatanwender" + +#: kdirstatfeedback.cpp:105 kdirstatfeedback.cpp:113 +msgid "Student" +msgstr "Student / Schüler" + +#: kdirstatfeedback.cpp:106 kdirstatfeedback.cpp:114 +msgid "Educational (teacher / professor)" +msgstr "Ausbilder (Lehrer, Dozent)" + +#: kdirstatfeedback.cpp:107 kdirstatfeedback.cpp:115 +msgid "Non-computer related work" +msgstr "Nichts computerbezogenes" + +#: kdirstatfeedback.cpp:108 kdirstatfeedback.cpp:116 +msgid "Developer" +msgstr "Entwickler" + +#: kdirstatfeedback.cpp:109 kdirstatfeedback.cpp:117 +msgid "System administrator" +msgstr "Systemverwalter" + +#: kdirstatfeedback.cpp:111 +msgid "Do you have any other roles there?" +msgstr "Haben Sie dort weitere Funktionen?" + +#: kdirstatfeedback.cpp:119 +msgid "How did you get to know this program?" +msgstr "Wie sind Sie auf dieses Programm gestoßen?" + +#: kdirstatfeedback.cpp:120 +msgid "In a menu on my machine" +msgstr "In einem Menü auf meinem Computer" + +#: kdirstatfeedback.cpp:121 +msgid "Somebody told me about it" +msgstr "Jemand hat mir davon erzählt" + +#: kdirstatfeedback.cpp:122 +msgid "On the internet" +msgstr "Im Internet" + +#: kdirstatfeedback.cpp:123 +msgid "Printed magazine / book" +msgstr "Zeitschrift / Buch" + +#: kdirstatfeedback.cpp:124 +msgid "Other (please add comment below)" +msgstr "Sonstige (bitte Kommentar unten)" + +#: kdirstatfeedback.cpp:126 +msgid "" +"Did you ever get a KDirStat mail report telling you to clean up disk space?" +msgstr "Haben Sie schon einmal eine KDirStat-Mail erhalten, in der sie aufgefordert wurden, Plattenplatz aufzuräumen?" + +#: kdirstatfeedback.cpp:129 +msgid "Could you figure yet out how to work with the treemaps?" +msgstr "Haben Sie schon herausbekommen, wie man mit Treemaps umgeht?" + +#: kdirstatfeedback.cpp:130 +msgid "I became an expert at it" +msgstr "Ich bin darin zum Experten geworden" + +#: kdirstatfeedback.cpp:131 +msgid "I got a fairly good idea of it" +msgstr "Ich kenne mich so einigermaßen damit aus" + +#: kdirstatfeedback.cpp:134 +msgid "Treemaps? Huh? What the hell is that?" +msgstr "Treemaps? Was ist das denn?" + +#: kdirstatfeedback.cpp:136 +msgid "What do you think about the treemaps?" +msgstr "Was halten Sie von den Treemaps?" + +#: kdirstatfeedback.cpp:137 +msgid "They are useless" +msgstr "Sie sind nutzlos" + +#: kdirstatfeedback.cpp:138 +msgid "The display is confusing" +msgstr "Die Darstellung ist verwirrend" + +#: kdirstatfeedback.cpp:139 +msgid "They look ugly" +msgstr "Sieht häßlich aus" + +#: kdirstatfeedback.cpp:140 +msgid "They look nice" +msgstr "Sieht gut aus" + +#: kdirstatfeedback.cpp:141 +msgid "They help finding large files" +msgstr "Hilft, große Dateien zu finden" + +#: kdirstatfeedback.cpp:142 +msgid "I could do with the treemap view alone" +msgstr "Mir würde die Treemap-Ansicht alleine völlig ausreichen" + +#: kdirstatfeedback.cpp:143 +msgid "The combination of tree view and treemaps is great" +msgstr "Die Kombination von Baumansicht und Treemap ist sehr gut" + +#: kdirstatfeedback.cpp:144 +msgid "I want more info inside the treemap view" +msgstr "Ich möchte mehr Informationen innerhalb der Treemap-Ansicht" + +#: kdirstatfeedback.cpp:145 +msgid "Leave the treemaps as they are right now" +msgstr "Die Treemaps sollten genauso bleiben, wie sie jetzt sind" + +#: kdirstatfeedback.cpp:147 +msgid "Would you recommend this program to a friend?" +msgstr "Würden Sie dieses Programm an Freunde weiterempfehlen?" + +#: kdirstatfeedback.cpp:158 +msgid "The directory tree display in general" +msgstr "Die Anzeige des Verzeichnis generell" + +#: kdirstatfeedback.cpp:159 +msgid "Percentage bars as graphical display of relative sizes" +msgstr "Prozentbalken als grafische Darstellung der relativen Größe" + +#: kdirstatfeedback.cpp:160 +msgid "Files apart from directories in a separate item" +msgstr "Dateien getrennt von Verzeichnissen als separaten -Eintrag" + +#: kdirstatfeedback.cpp:162 +msgid "Treemaps in general" +msgstr "Treemaps allgemein" + +#: kdirstatfeedback.cpp:163 +msgid "The cushioned treemap rendering" +msgstr "Die Kissendarstellung der Treemaps" + +#: kdirstatfeedback.cpp:165 +msgid "Cleanup actions in general" +msgstr "Aufräumaktionen allgemein" + +#: kdirstatfeedback.cpp:166 +msgid "Predefined cleanup actions" +msgstr "Vordefinierte Aufräumaktionen" + +#: kdirstatfeedback.cpp:167 +msgid "User defined cleanup actions" +msgstr "Benutzerdefinierte Aufräumaktionen" + +#: kdirstatfeedback.cpp:168 +msgid "Cleanup action configuration" +msgstr "Konfiguration der Aufräumaktionen" + +#: kdirstatfeedback.cpp:170 +msgid "Different colors in percentage bars" +msgstr "Unterschiedliche Farben der Prozentbalken" + +#: kdirstatfeedback.cpp:171 +msgid "Tree color configuration" +msgstr "Farbzuweisung für die Baumanzeige" + +#: kdirstatfeedback.cpp:172 +msgid "Staying on one file system" +msgstr "Innerhalb eines Dateisystemes bleiben" + +#: kdirstatfeedback.cpp:173 +msgid "The \"mail to owner\" facility" +msgstr "Die Funktion \"Mail an Besitzer\"" + +#: kdirstatfeedback.cpp:174 +msgid "This \"feedback mail\" facility" +msgstr "Diese Funktion \"Feedback-Mail\" hier" + +#: kdirstatfeedback.cpp:176 +msgid "Human readable sizes (kB, MB, ...)" +msgstr "Für Menschen lesbare Größenangaben (KB, MB, ...)" + +#: kdirstatfeedback.cpp:177 +msgid "All the numbers in the tree display" +msgstr "Die ganzen Zahlen in der Baumanzeige" + +#: kdirstatfeedback.cpp:178 +msgid "Last change time of an entire directory tree" +msgstr "Die letzte Änderungszeit eines gesamten Verzeichnisbaums" + +#: kdirstatfeedback.cpp:179 +msgid "The PacMan animation" +msgstr "Die PacMan-Animation" + +#: kdirstatsettings.cpp:37 +msgid "Settings" +msgstr "Einstellungen" + +#: kdirstatsettings.cpp:66 +msgid "&Cleanups" +msgstr "&Aufräumen" + +#: kdirstatsettings.cpp:70 +msgid "&Tree Colors" +msgstr "&Verzeichnisfarben" + +#: kdirstatsettings.cpp:74 +msgid "Tree&map" +msgstr "&Treemap" + +#: kdirstatsettings.cpp:78 +msgid "&General" +msgstr "Allge&mein" + +#: kdirstatsettings.cpp:104 +msgid "" +"Really revert all settings to their default values?\n" +"You will lose all changes you ever made!" +msgstr "" +"Wirklich alle Einstellungen auf Voreinstellungen zurücksetzen?\n" +"Alle eigenen Einstellungen gehen dabei verloren!" + +#: kdirstatsettings.cpp:107 +msgid "&Really Revert to Defaults" +msgstr "Wirklich auf Standardwerte zu&rücksetzen" + +#: kdirstatsettings.cpp:193 +msgid "Tree Level %1" +msgstr "Baumebene %1" + +#: kdirstatsettings.cpp:529 +msgid "&Enabled" +msgstr "&Aktiv" + +#: kdirstatsettings.cpp:566 +msgid "&Title:" +msgstr "&Titel:" + +#: kdirstatsettings.cpp:567 +msgid "&Command Line:" +msgstr "&Kommandozeile:" + +#: kdirstatsettings.cpp:569 +#, c-format +msgid "%p Full Path" +msgstr "%p Vollständiger Pfad" + +#: kdirstatsettings.cpp:572 +#, c-format +msgid "%n File / Directory Name Without Path" +msgstr "%n Datei- bzw. Verzeichnisname ohne Pfad" + +#: kdirstatsettings.cpp:575 +msgid "%t KDE Trash Directory" +msgstr "%t KDE-Mülleimer-Verzeichnis" + +#: kdirstatsettings.cpp:581 +msgid "&Recurse into Subdirectories" +msgstr "Unte&rverzeichnisse durchlaufen" + +#: kdirstatsettings.cpp:586 +msgid "&Ask for Confirmation" +msgstr "&Nachfragen" + +#: kdirstatsettings.cpp:592 +msgid "Works for..." +msgstr "Anwendbar auf..." + +#: kdirstatsettings.cpp:598 +msgid "&Directories" +msgstr "&Verzeichnisse" + +#: kdirstatsettings.cpp:599 +msgid "&Files" +msgstr "&Dateien" + +#: kdirstatsettings.cpp:600 +msgid " P&seudo Entries" +msgstr "-P&seudo-Einträge" + +#: kdirstatsettings.cpp:610 +msgid "On Local Machine Only ('file:/' Protocol)" +msgstr "Nur lokal ('file:/' -Protokoll)" + +#: kdirstatsettings.cpp:611 +msgid "Network Transparent (ftp, smb, tar, ...)" +msgstr "Netzwerktransparent (ftp, smb, tar, ...)" + +#: kdirstatsettings.cpp:631 +msgid "Refresh &Policy:" +msgstr "A&ktualisierung:" + +#: kdirstatsettings.cpp:642 +msgid "No Refresh" +msgstr "Nicht aktualisieren" + +#: kdirstatsettings.cpp:643 +msgid "Refresh This Entry" +msgstr "Diesen Eintrag aktualisieren" + +#: kdirstatsettings.cpp:644 +msgid "Refresh This Entry's Parent" +msgstr "Übergeordneten Eintrag aktualisieren" + +#: kdirstatsettings.cpp:645 +msgid "Assume Entry Has Been Deleted" +msgstr "Annehmen, der Eintrag sei gelöscht" + +#: kdirstatsettings.cpp:715 +msgid "Directory Reading" +msgstr "Verzeichnisse lesen" + +#: kdirstatsettings.cpp:718 +msgid "Cross &File System Boundaries" +msgstr "Über Dateisystemgrenzen &hinweg lesen" + +#: kdirstatsettings.cpp:719 +msgid "Use Optimized &Local Directory Read Methods" +msgstr "Für lokale Verzeichnisse &optimierte Lesemethoden verwenden" + +#: kdirstatsettings.cpp:726 +msgid "Animation" +msgstr "Animation" + +#: kdirstatsettings.cpp:729 +msgid "P@cM@n Animation in Tool &Bar" +msgstr "P@cM@n-Animation in der &Werkzeugleiste" + +#: kdirstatsettings.cpp:730 +msgid "P@cM@n Animation in Directory &Tree" +msgstr "P@cM@n-Animation im Verzeichnis&baum" + +#: kdirstatsettings.cpp:809 +msgid "S&quarify Treemap" +msgstr "Treemap &Quadrat-optimieren" + +#: kdirstatsettings.cpp:810 +msgid "Use C&ushion Shading" +msgstr "&Kissendarstellung" + +#: kdirstatsettings.cpp:815 +msgid "Cushion Parameters" +msgstr "Kissen-Parameter" + +#: kdirstatsettings.cpp:820 +msgid "Ambient &Light" +msgstr "&Umgebungslicht" + +#: kdirstatsettings.cpp:830 +msgid "&Height Scale" +msgstr "&Höhenskala" + +#: kdirstatsettings.cpp:840 +msgid "Draw Lines if Lo&w Contrast" +msgstr "&Linien bei geringem Kontrast" + +#: kdirstatsettings.cpp:844 +msgid "Always Draw &Grid" +msgstr "Immer &Gitter anzeigen" + +#: kdirstatsettings.cpp:847 +msgid "Gr&id Color: " +msgstr "G&itterfarbe:" + +#: kdirstatsettings.cpp:857 +msgid "Colors for Plain Treemaps" +msgstr "Farben für einfache Treemaps" + +#: kdirstatsettings.cpp:860 +msgid "&Files: " +msgstr "&Dateien:" + +#: kdirstatsettings.cpp:865 +msgid "&Directories: " +msgstr "&Verzeichnisse:" + +#: kdirstatsettings.cpp:870 +msgid "Gr&id: " +msgstr "G&itter:" + +#: kdirstatsettings.cpp:884 +msgid "Hi&ghlight R&ectangle: " +msgstr "Markierungs&rahmen:" + +#: kdirstatsettings.cpp:892 +msgid "Minim&um Treemap Tile Size: " +msgstr "Mi&nimale Kachelgröße:" + +#: kdirstatsettings.cpp:899 +msgid "Auto-&Resize Treemap" +msgstr "Treemap automatisch &einpassen" + +#: kdirtree.cpp:1548 kdirtreeview.cpp:800 +msgid "Bytes" +msgstr "Bytes" + +#: kdirtree.cpp:1557 +msgid "kB" +msgstr "KB" + +#: kdirtree.cpp:1566 +msgid "MB" +msgstr "MB" + +#: kdirtree.cpp:1573 +msgid "GB" +msgstr "GB" + +#: kdirtreeview.cpp:62 +msgid "Name" +msgstr "Name" + +#: kdirtreeview.cpp:64 +msgid "Subtree Percentage" +msgstr "Teilbaum Prozent" + +#: kdirtreeview.cpp:65 +msgid "Percentage" +msgstr "Prozent" + +#: kdirtreeview.cpp:66 +msgid "Subtree Total" +msgstr "Teilbaum gesamt" + +#: kdirtreeview.cpp:68 +msgid "Own Size" +msgstr "Eigene Größe" + +#: kdirtreeview.cpp:69 +msgid "Items" +msgstr "Einträge" + +#: kdirtreeview.cpp:70 +msgid "Files" +msgstr "Dateien" + +#: kdirtreeview.cpp:71 +msgid "Subdirs" +msgstr "Unterverz." + +#: kdirtreeview.cpp:72 +msgid "Last Change" +msgstr "Geändert am" + +#: kdirtreeview.cpp:165 +msgid "Read Jobs" +msgstr "Gelesene" + +#: kdirtreeview.cpp:434 +msgid "Finished. Elapsed time: %1" +msgstr "Fertig. Gesamtdauer : %1" + +#: kdirtreeview.cpp:464 +msgid "Aborted. Elapsed time: %1" +msgstr "Benutzerabbruch. Gesamtdauer : %1" + +#: kdirtreeview.cpp:499 +msgid "Elapsed time: %1 reading directory %2" +msgstr "Zeit bisher: %1 Lese Verzeichnis %2" + +#: kdirtreeview.cpp:907 +msgid "Disk Usage" +msgstr "Platzbedarf" + +#: kdirtreeview.cpp:909 +msgid "Please check your disk usage and clean up if you can. Thank you." +msgstr "Bitte überprüfen Sie den verbrauchten Plattenplatz und räumen Sie nach Möglichkeit auf. Danke." + +#: kdirtreeview.cpp:913 +msgid "Disk usage report generated by KDirStat" +msgstr "Report über Plattenplatzverbrauch - generiert von KDirStat" + +#: kdirtreeview.cpp:976 +msgid "" +msgstr "" + +#: kdirtreeview.cpp:1109 +msgid "[%1 Read Jobs]" +msgstr "[%1 Lesejobs]" + +#: kfeedback.cpp:32 +msgid "Feedback" +msgstr "Feedback" + +#: kfeedback.cpp:38 +msgid "&Mail this..." +msgstr "&Mail versenden..." + +#: kfeedback.cpp:88 +msgid "" +"

Please tell us your opinion about this program.

You will be " +"able to review everything in your mailer before any mail is sent.
Nothing " +"will be sent behind your back.

" +msgstr "" +"

Bitte teilen Sie uns Ihre Meinung zu diesem Programm mit.

\n" +"

Sie können alles noch einmal in ihrem Mail-Programm überprüfen, \n" +"bevor tatsächlich eine Mail verschickt wird.
\n" +"Es wird garantiert nichts hinter Ihrem Rücken versendet.

" + +#: kfeedback.cpp:113 +msgid "Questions marked with " +msgstr "Fragen, die mit " + +#: kfeedback.cpp:122 +msgid " must be answered before a mail can be sent." +msgstr " gekennzeichnet sind, müssen beantwortet werden, um eine Mail zu senden." + +#: kfeedback.cpp:133 +msgid "&Additional Comments:" +msgstr "Zusätzliche &Anmerkungen:" + +#: kfeedback.cpp:311 +msgid "yes" +msgstr "Ja" + +#: kfeedback.cpp:312 +msgid "no" +msgstr "Nein" + +#: kstdcleanup.cpp:23 +msgid "Open in &Konqueror" +msgstr "In &Konqueror öffnen" + +#: kstdcleanup.cpp:43 +msgid "Open in &Terminal" +msgstr "In &Terminal öffnen" + +#: kstdcleanup.cpp:62 +msgid "&Compress" +msgstr "&Komprimieren" + +#: kstdcleanup.cpp:80 +msgid "&make clean" +msgstr "&make clean" + +#: kstdcleanup.cpp:97 +msgid "Delete T&rash Files" +msgstr "Müll-Da&teien löschen" + +#: kstdcleanup.cpp:115 +msgid "Delete (to Trash &Bin)" +msgstr "In den Mülleimer verschie&ben" + +#: kstdcleanup.cpp:134 +msgid "&Delete (no way to undelete!)" +msgstr "Lö&schen (Endgültig!)" + +#~ msgid "Clean &Up" +#~ msgstr "A&ufräumen" + +#~ msgid "&Report" +#~ msgstr "&Report" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..a898f70 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,726 @@ +# translation of fr.po to français +# Copyright (C) 2003 Free Software Foundation, Inc. +# Michel Grentzinger , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: kdirstat 2.3.6\n" +"POT-Creation-Date: 2002-04-19 13:38+0900\n" +"PO-Revision-Date: 2003-04-25 21:45GMT\n" +"Last-Translator: Michel Grentzinger \n" +"Language-Team: French \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.1\n" + +#: kcleanup.cpp:171 +msgid "" +"%1\n" +"in directory %2" +msgstr "" +"%1\n" +"dans le répertoire %2" + +#: kcleanup.cpp:175 +msgid "" +"%1\n" +"for file %2" +msgstr "" +"%1\n" +"pour le fichier %2" + +#: kcleanup.cpp:180 kdirstatsettings.cpp:100 +msgid "Please confirm" +msgstr "Veuillez confirmer" + +#: kcleanup.cpp:181 +msgid "Confirm" +msgstr "Confirmation" + +#: kdirstatapp.cpp:126 +msgid "Refresh &All" +msgstr "Rafraîchir &tout" + +#: kdirstatapp.cpp:130 +msgid "Refresh &Selected" +msgstr "Rafraîchir la &sélection" + +#: kdirstatapp.cpp:134 +msgid "Continue Reading at &Mount Point" +msgstr "Continuer la lecture au point de &montage" + +#: kdirstatapp.cpp:144 +msgid "Send &Mail to Owner" +msgstr "Envoyer un &courriel au propriétaire" + +#: kdirstatapp.cpp:148 +msgid "Send &Feedback Mail..." +msgstr "Envoyer une &remarque par courriel ..." + +#: kdirstatapp.cpp:153 +msgid "Opens a directory" +msgstr "Ouvre un répertoire" + +#: kdirstatapp.cpp:154 +msgid "Opens a recently used directory" +msgstr "Ouvre un répertoire récemment utilisé" + +#: kdirstatapp.cpp:155 +msgid "Closes the current directory" +msgstr "Ferme le répertoire courant" + +#: kdirstatapp.cpp:156 +msgid "Re-reads the entire directory tree" +msgstr "Relire l'arborescence complète du répertoire" + +#: kdirstatapp.cpp:157 +msgid "Re-reads the selected subtree" +msgstr "Relire la sous-arborescence sélectionnée" + +#: kdirstatapp.cpp:158 +msgid "Scan mounted file systems" +msgstr "Examiner les systèmes de fichier montés" + +#: kdirstatapp.cpp:159 +msgid "Quits the application" +msgstr "Quitte l'application" + +#: kdirstatapp.cpp:160 +msgid "Copies the URL of the selected item to the clipboard" +msgstr "Copie l'URL de l'entrée sélectionnée vers le presse-papier" + +#: kdirstatapp.cpp:161 +msgid "Enables/disables the toolbar" +msgstr "Active/désactive la barre d'outils" + +#: kdirstatapp.cpp:162 +msgid "Enables/disables the statusbar" +msgstr "Active/désactive la barre d'état" + +#: kdirstatapp.cpp:163 +msgid "Opens the preferences dialog" +msgstr "Ouvre les préférences" + +#: kdirstatapp.cpp:164 +msgid "Sends a mail to the owner of the selected subtree" +msgstr "Envoie un courriel au propriétaire du sous-arbre sélectionné" + +#: kdirstatapp.cpp:216 kdirstatapp.cpp:250 kdirstatapp.cpp:349 +#: kdirstatapp.cpp:361 kdirstatapp.cpp:374 kdirstatapp.cpp:383 +#: kdirstatapp.cpp:395 +msgid "Ready." +msgstr "Prêt." + +#: kdirstatapp.cpp:243 kdirstatapp.cpp:342 kdirstatapp.cpp:356 +msgid "Opening directory..." +msgstr "Ouverture d'un répertoire..." + +#: kdirstatapp.cpp:344 +msgid "Open Directory..." +msgstr "Ouvrir un répertoire..." + +#: kdirstatapp.cpp:368 +msgid "Closing directory..." +msgstr "Fermeture du répertoire..." + +#: kdirstatapp.cpp:381 +msgid "Refreshing directory tree..." +msgstr "Rafraîchissement de l'arborescence du répertoire..." + +#: kdirstatapp.cpp:393 +msgid "Refreshing selected subtree..." +msgstr "Rafraîchissement du sous-arbre sélectionné..." + +#: kdirstatapp.cpp:482 +msgid "" +"Now that you know this program for some time,\n" +"wouldn't you like to tell the authors your opinion about it?\n" +"\n" +"Open Source software depends on user feedback.\n" +"Your opinion can help us make the software better." +msgstr "" +"Maintenant que vous connaissez ce programme depuis un moment,\n" +"n'aimeriez-vous pas indiquer aux auteurs l'opinion que vous en avez ?\n" +"\n" +"Le logiciel Open Source dépend de l'avis des utilisateurs.\n" +"Vos remarques peuvent nous aider à améliorer le programme." + +#: kdirstatapp.cpp:487 +msgid "Please tell us your opinion!" +msgstr "Veuillez nous indiquer votre opinion !" + +#: kdirstatapp.cpp:488 +msgid "Open &Feedback Form..." +msgstr "Ouvrir le &formulaire de remarques..." + +#: kdirstatapp.cpp:489 +msgid "&No, and don't ask again!" +msgstr "&Non, et ne plus me demander !" + +#: kdirtreeview.cpp:59 +msgid "Name" +msgstr "Nom" + +#: kdirtreeview.cpp:61 +msgid "Subtree Percentage" +msgstr "Pourcentage du sous-arbre" + +#: kdirtreeview.cpp:62 +msgid "Percentage" +msgstr "Pourcentage" + +#: kdirtreeview.cpp:63 +msgid "Subtree Total" +msgstr "Total du sous-arbre" + +#: kdirtreeview.cpp:65 +msgid "Own Size" +msgstr "Taille propre" + +#: kdirtreeview.cpp:66 +msgid "Items" +msgstr "Entrées" + +#: kdirtreeview.cpp:67 +msgid "Files" +msgstr "Fichiers" + +#: kdirtreeview.cpp:68 +msgid "Subdirs" +msgstr "Sous-répertoires" + +#: kdirtreeview.cpp:69 +msgid "Last Change" +msgstr "Modifié" + +#: kdirtreeview.cpp:156 +msgid "Read Jobs" +msgstr "Lectures à faire" + +#: kdirtreeview.cpp:405 +#, c-format +msgid "Finished. Elapsed time: %1" +msgstr "Terminé. Temps écoulé : %1" + +#: kdirtreeview.cpp:440 +msgid "Elapsed time: %1 reading directory %2" +msgstr "Temps écoulé: %1 lecture du répertoire %2 " + +#: kdirtreeview.cpp:704 kdirtreeview.cpp:1451 +msgid "Bytes" +msgstr "Octets" + +#: kdirtreeview.cpp:803 +msgid "Disk usage" +msgstr "Utilisation du disque" + +#: kdirtreeview.cpp:805 +msgid "Please check your disk usage and clean up if you can. Thank you." +msgstr "Veuillez vérifier l'utilisation de votre disque et nettoyez-le si vous pouvez. Merci." + +#: kdirtreeview.cpp:809 +msgid "Disk usage report generated by KDirStat" +msgstr "Rapport de l'utilisation du disque généré par KDirStat" + +#: kdirtreeview.cpp:868 +msgid "" +msgstr "" + +#: kdirtreeview.cpp:1460 +msgid "kB" +msgstr "Ko" + +#: kdirtreeview.cpp:1469 +msgid "MB" +msgstr "Mo" + +#: kdirtreeview.cpp:1476 +msgid "GB" +msgstr "Go" + +#: kstdcleanup.cpp:26 +msgid "Open in &Konqueror" +msgstr "Ouvrir dans &Konqueror" + +#: kstdcleanup.cpp:46 +msgid "Open in &Terminal" +msgstr "Ouvrir dans un &Terminal" + +#: kstdcleanup.cpp:65 +msgid "&Compress" +msgstr "&Compresser" + +#: kstdcleanup.cpp:83 +msgid "&make clean" +msgstr "&make clean" + +#: kstdcleanup.cpp:100 +msgid "Delete T&rash Files" +msgstr "Supp&rimer les fichiers détruits" + +#: kstdcleanup.cpp:118 +msgid "Delete (to Trash &Bin)" +msgstr "Supprimer (vers la cor&beille)" + +#: kstdcleanup.cpp:137 +msgid "&Delete (no way to undelete!)" +msgstr "&Supprimer (aucune façon de restaurer !)" + +#: kcleanupcollection.cpp:234 +#, c-format +msgid "User Defined Cleanup #&%1" +msgstr "Nettoyage défini par l'utilisateur #&%1" + +#: kcleanupcollection.cpp:237 +#, c-format +msgid "User Defined Cleanup #%1" +msgstr "Nettoyage défini par l'utilisateur #%1" + +#: kdirstatsettings.cpp:39 +msgid "Settings" +msgstr "Paramètres" + +#: kdirstatsettings.cpp:68 +msgid "&Cleanups" +msgstr "&Nettoyages" + +#: kdirstatsettings.cpp:72 +msgid "&Tree Colors" +msgstr "&Couleurs de l'arborescence" + +#: kdirstatsettings.cpp:98 +msgid "" +"Really revert all settings to their default values?\n" +"You will lose all changes you ever made!" +msgstr "" +"Revenir vraiment aux valeurs par défaut pour tous les paramètres ?\n" +"Vous perdrez tous les changements déjà effectués !\"" + +#: kdirstatsettings.cpp:101 +msgid "&Really revert to defaults" +msgstr "&Revenir vraiment aux valeurs par défaut" + +#: kdirstatsettings.cpp:185 +#, c-format +msgid "Tree level %1" +msgstr "Niveau de l'arborescence %1" + +#: kdirstatsettings.cpp:527 +msgid "&Enabled" +msgstr "&Activé" + +#: kdirstatsettings.cpp:564 +msgid "&Title:" +msgstr "&Titre : " + +#: kdirstatsettings.cpp:565 +msgid "&Command line:" +msgstr "Ligne de &commande : " + +#: kdirstatsettings.cpp:567 +#, c-format +msgid "%p full path" +msgstr "%p chemin complet" + +#: kdirstatsettings.cpp:570 +#, c-format +msgid "%n file / directory name without path" +msgstr "%n nom de fichier / répertoire sans chemin" + +#: kdirstatsettings.cpp:576 +msgid "&Recurse into subdirectories" +msgstr "&Traiter récursivement les sous-répertoires" + +#: kdirstatsettings.cpp:581 +msgid "&Ask for confirmation" +msgstr "&Demander une confirmation" + +#: kdirstatsettings.cpp:587 +msgid "Works for..." +msgstr "Fonctionne avec les..." + +#: kdirstatsettings.cpp:593 +msgid "&Directories" +msgstr "&Répertoires" + +#: kdirstatsettings.cpp:594 +msgid "&Files" +msgstr "&Fichiers" + +#: kdirstatsettings.cpp:595 +msgid " p&seudo entries" +msgstr "&Pseudos-entrées " + +#: kdirstatsettings.cpp:605 +msgid "On local machine only ('file:/' protocol)" +msgstr "Uniquement sur la machine locale (protocole 'file:/')" + +#: kdirstatsettings.cpp:606 +msgid "Network transparent (ftp, smb, tar, ...)" +msgstr "A travers le réseau (ftp, smb, tar, ...)" + +#: kdirstatsettings.cpp:626 +msgid "Refresh &Policy:" +msgstr "Règl&es de rafraîchissement : " + +#: kdirstatsettings.cpp:637 +msgid "No refresh" +msgstr "Pas de rafraîchissement" + +#: kdirstatsettings.cpp:638 +msgid "Refresh this entry" +msgstr "Rafraîchir cette entrée" + +#: kdirstatsettings.cpp:639 +msgid "Refresh this entry's parent" +msgstr "Rafraîchir le parent de cette entrée" + +#: kdirstatsettings.cpp:640 +msgid "Assume entry has been deleted" +msgstr "S'assurer que l'entrée a été supprimée" + +#: kdirstatfeedback.cpp:36 +msgid "What is your general opinion about this program?" +msgstr "Quelle est votre impression générale sur ce programme ?" + +#: kdirstatfeedback.cpp:38 +msgid "It's one of my favourites" +msgstr "C'est l'un de mes préféré" + +#: kdirstatfeedback.cpp:39 +msgid "I like it" +msgstr "Je l'adore" + +#: kdirstatfeedback.cpp:40 +msgid "It's sometimes useful" +msgstr "Il est parfois utile" + +#: kdirstatfeedback.cpp:41 +msgid "It's average" +msgstr "Il est moyen" + +#: kdirstatfeedback.cpp:42 +msgid "Nice try, but this could be done better" +msgstr "Satisfaisant, mais celà pourrait être meilleur" + +#: kdirstatfeedback.cpp:43 +msgid "It's poor" +msgstr "Il est médiocre" + +#: kdirstatfeedback.cpp:44 +msgid "It's useless" +msgstr "Il est inutile" + +#: kdirstatfeedback.cpp:45 +msgid "It's crap" +msgstr "C'est de la merde" + +#: kdirstatfeedback.cpp:47 +msgid "Which features of this program do you like?" +msgstr "Quelles fonctionnalités de ce programme aimez-vous ?" + +#: kdirstatfeedback.cpp:50 +msgid "Which features don't you like?" +msgstr "Quelles fonctionnalités n'aimez-vous pas ?" + +#: kdirstatfeedback.cpp:53 +msgid "Which features do you never use?" +msgstr "Quelles fonctionnalités n'utilisez-vous jamais ?" + +#: kdirstatfeedback.cpp:56 +msgid "What is your favourite feature?" +msgstr "Quelle est votre fonctionnalité préférée ?" + +#: kdirstatfeedback.cpp:59 +msgid "Are there features you are missing?" +msgstr "Voyez-vous des fonctionnalités manquantes ?" + +#: kdirstatfeedback.cpp:60 +msgid "Yes, a lot! (please add comment below)" +msgstr "Oui, beaucoup ! (veuillez ajouter vos commentaires ci-dessous)" + +#: kdirstatfeedback.cpp:62 +msgid "None" +msgstr "Aucune" + +#: kdirstatfeedback.cpp:63 +msgid "It has too many features already!" +msgstr "Il y a déjà trop de fonctionnalités !" + +#: kdirstatfeedback.cpp:65 +msgid "How do you rate the stability of this program?" +msgstr "Comment évaluez-vous la stabilité de ce programme ?" + +#: kdirstatfeedback.cpp:66 +msgid "Rock solid" +msgstr "Solide comme un roc" + +#: kdirstatfeedback.cpp:67 kdirstatfeedback.cpp:74 +msgid "Good" +msgstr "Bonne" + +#: kdirstatfeedback.cpp:68 kdirstatfeedback.cpp:75 kdirstatfeedback.cpp:82 +#: kdirstatfeedback.cpp:89 +msgid "Average" +msgstr "Moyenne" + +#: kdirstatfeedback.cpp:69 kdirstatfeedback.cpp:76 +msgid "Poor" +msgstr "Médiocre" + +#: kdirstatfeedback.cpp:70 +msgid "It keeps crashing all the time" +msgstr "Il n'arrête pas de planter" + +#: kdirstatfeedback.cpp:72 +msgid "How do you rate the performance of this program?" +msgstr "Comment évaluez-vous la performance de ce programme ?" + +#: kdirstatfeedback.cpp:73 +msgid "Great" +msgstr "Excellente" + +#: kdirstatfeedback.cpp:77 +msgid "It's so slow it drives me nuts" +msgstr "Il est tellement lent qu'il me rend fou" + +#: kdirstatfeedback.cpp:79 +msgid "What is your experience with computers in general?" +msgstr "Quelle est votre expérience informatique globalement ?" + +#: kdirstatfeedback.cpp:80 kdirstatfeedback.cpp:87 +msgid "Expert" +msgstr "Expert" + +#: kdirstatfeedback.cpp:81 kdirstatfeedback.cpp:88 +msgid "Fair" +msgstr "Correct" + +#: kdirstatfeedback.cpp:83 kdirstatfeedback.cpp:90 +msgid "Learning" +msgstr "Apprenti" + +#: kdirstatfeedback.cpp:84 kdirstatfeedback.cpp:91 +msgid "Newbie" +msgstr "Débutant" + +#: kdirstatfeedback.cpp:86 +msgid "What is your experience with Unix/Linux systems?" +msgstr "Quelle est votre expérience avec les systèmes Unix/Linux ?" + +#: kdirstatfeedback.cpp:93 +msgid "Did you have trouble figuring out how to work with this program?" +msgstr "Avez-vous eu du mal à savoir comment travailler avec ce programme ?" + +#: kdirstatfeedback.cpp:95 +msgid "No problem" +msgstr "Aucun problème" + +#: kdirstatfeedback.cpp:96 +msgid "Some" +msgstr "Un peu" + +#: kdirstatfeedback.cpp:97 +msgid "I'm still learning" +msgstr "Je suis encore en train d'apprendre" + +#: kdirstatfeedback.cpp:98 +msgid "I didn't have a clue what to do at first" +msgstr "Je n'avais pas la moindre idée de ce qu'il fallait faire au début" + +#: kdirstatfeedback.cpp:99 +msgid "I still don't have a clue what to do" +msgstr "Je n'ai toujours pas la moindre idée de ce qu'il faut faire" + +#: kdirstatfeedback.cpp:101 +msgid "Where do you use this program most?" +msgstr "Où utilisez-vous ce programme le plus souvent ?" + +#: kdirstatfeedback.cpp:102 +msgid "At work" +msgstr "Au travail" + +#: kdirstatfeedback.cpp:103 +msgid "At home" +msgstr "A la maison" + +#: kdirstatfeedback.cpp:104 +msgid "At university / school" +msgstr "A l'université / à l'école" + +#: kdirstatfeedback.cpp:106 +msgid "What is your primary role there?" +msgstr "Quelle est votre fonction la-bàs ?" + +#: kdirstatfeedback.cpp:107 kdirstatfeedback.cpp:115 +msgid "Home user" +msgstr "Utilisateur personnel" + +#: kdirstatfeedback.cpp:108 kdirstatfeedback.cpp:116 +msgid "Student" +msgstr "Etudiant" + +#: kdirstatfeedback.cpp:109 kdirstatfeedback.cpp:117 +msgid "Educational (teacher / professor)" +msgstr "Education (enseignant / professeur)" + +#: kdirstatfeedback.cpp:110 kdirstatfeedback.cpp:118 +msgid "Non-computer related work" +msgstr "Travail non lié à l'informatique" + +#: kdirstatfeedback.cpp:111 kdirstatfeedback.cpp:119 +msgid "Developer" +msgstr "Développeur" + +#: kdirstatfeedback.cpp:112 kdirstatfeedback.cpp:120 +msgid "System administrator" +msgstr "Administrateur système" + +#: kdirstatfeedback.cpp:114 +msgid "Do you have any other roles there?" +msgstr "Avez-vous d'autres fonctions la-bàs ?" + +#: kdirstatfeedback.cpp:122 +msgid "How did you get to know this program?" +msgstr "Comment avez-vous connu ce programme ?" + +#: kdirstatfeedback.cpp:123 +msgid "In a menu on my machine" +msgstr "Dans un menu de ma machine" + +#: kdirstatfeedback.cpp:124 +msgid "Somebody told me about it" +msgstr "Quelqu'un m'en a parlé" + +#: kdirstatfeedback.cpp:125 +msgid "On the internet" +msgstr "Sur internet" + +#: kdirstatfeedback.cpp:126 +msgid "Printed magazine / book" +msgstr "Magazine imprimé / livre" + +#: kdirstatfeedback.cpp:127 +msgid "Other (please add comment below)" +msgstr "Autre (veuillez ajoutez vos commentaires ci-dessous)" + +#: kdirstatfeedback.cpp:129 +msgid "Did you ever get a KDirStat mail report telling you to clean up disk space?" +msgstr "Avez-vous déjà recu un courriel de KDirStat vous indiquant de libérer de l'espace disque ?" + +#: kdirstatfeedback.cpp:132 +msgid "Would you recommend this program to a friend?" +msgstr "Conseillerez-vous ce programme à un ami ?" + +#: kdirstatfeedback.cpp:143 +msgid "The directory tree display in general" +msgstr "L'affichage de l'arborescence des répertoires en général" + +#: kdirstatfeedback.cpp:144 +msgid "Percentage bars as graphical display of relative sizes" +msgstr "L'affichage en barres graphiques du pourcentage des tailles relatives" + +#: kdirstatfeedback.cpp:145 +msgid "Files apart from directories in a separate item" +msgstr "L'ensemble des fichiers d'un répertoire dans une entrée séparée" + +#: kdirstatfeedback.cpp:147 +msgid "Cleanup actions in general" +msgstr "Les actions de nettoyage en général" + +#: kdirstatfeedback.cpp:148 +msgid "Predefined cleanup actions" +msgstr "Les actions de nettoyage prédéfinies" + +#: kdirstatfeedback.cpp:149 +msgid "User defined cleanup actions" +msgstr "Les actions de nettoyage prédéfinies par l'utilisateur" + +#: kdirstatfeedback.cpp:150 +msgid "Cleanup action configuration" +msgstr "La configuration des actions de nettoyage" + +#: kdirstatfeedback.cpp:152 +msgid "Different colors in percentage bars" +msgstr "Les couleurs différentes dans les barres de pourcentage" + +#: kdirstatfeedback.cpp:153 +msgid "Tree color configuration" +msgstr "La configuration des couleurs de l'arborescence" + +#: kdirstatfeedback.cpp:154 +msgid "Staying on one file system" +msgstr "Le fait de rester sur un système de fichier" + +#: kdirstatfeedback.cpp:155 +msgid "The \"mail to owner\" facility" +msgstr "La fonction \"envoyer un courriel au propriétaire\"" + +#: kdirstatfeedback.cpp:156 +msgid "This \"feedback mail\" facility" +msgstr "La fonction \"envoyer une remarque par courriel\"" + +#: kdirstatfeedback.cpp:158 +msgid "Human readable sizes (kB, MB, ...)" +msgstr "Les tailles lisibles facilement (Ko, Mo, ...)" + +#: kdirstatfeedback.cpp:159 +msgid "All the numbers in the tree display" +msgstr "Tous les chiffres dans l'affichage de l'arborescence" + +#: kdirstatfeedback.cpp:160 +msgid "Last change time of an entire directory tree" +msgstr "Heure de la dernière modification de l'arborescence entière d'un répertoire" + +#: kdirstatfeedback.cpp:161 +msgid "The PacMan animation" +msgstr "L'animation PacMan" + +#: kfeedback.cpp:35 +msgid "Feedback" +msgstr "Les remarques aux auteurs" + +#: kfeedback.cpp:41 +msgid "&Mail this..." +msgstr "&Envoyer ceci..." + +#: kfeedback.cpp:91 +msgid "" +"

Please tell us your opinion about this program.

You will be " +"able to review everything in your mailer before any mail is sent.
Nothing " +"will be sent behind your back.

" +msgstr "

Veuillez nous indiquer votre opinion à propos de ce programme.

Vous pourrez revoir toute chose dans votre client de courrier avant que le courriel ne soit envoyé
Rien ne sera envoyé à votre insu.

" + +#: kfeedback.cpp:116 +msgid "Questions marked with " +msgstr "Les questions marquées par un " + +#: kfeedback.cpp:125 +msgid " must be answered before a mail can be sent." +msgstr "doivent être remplies avant qu'un courriel ne puisse être envoyé." + +#: kfeedback.cpp:136 +msgid "&Additional comments:" +msgstr "Rem&arques supplémentaires" + +#: kfeedback.cpp:314 +msgid "yes" +msgstr "oui" + +#: kfeedback.cpp:315 +msgid "no" +msgstr "non" + +#: kdirstatui.rc:32 +msgid "Clean &Up" +msgstr "&Nettoyage" + +#: kdirstatui.rc:60 +msgid "&Report" +msgstr "&Rapport" + +#~ #: kdirstatfeedback.cpp:61 +#~ msgid "Some (please add comment below)" +#~ msgstr "Quelques-unes (veuillez ajouter vos commentaires ci-dessous)" + diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..998ecd7 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,733 @@ +# translation of hu.po to Hungarian +# translation of fr.po to hungarian +# translation of fr.po to français +# Copyright (C) 2003 Free Software Foundation, Inc. +# Michel Grentzinger , 2003 +# Marcel Hilzinger , 2003 +# Peter Breuer , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: hu\n" +"POT-Creation-Date: 2002-04-19 13:38+0900\n" +"PO-Revision-Date: 2003-09-05 15:43+0200\n" +"Last-Translator: Peter Breuer \n" +"Language-Team: Hungarian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.1\n" + +#: kcleanup.cpp:171 +msgid "" +"%1\n" +"in directory %2" +msgstr "" +"%1\n" +"ebben a könyvtárban: %2" + +#: kcleanup.cpp:175 +msgid "" +"%1\n" +"for file %2" +msgstr "" +"%1\n" +"ehhez a fájlhoz: %2" + +#: kcleanup.cpp:180 kdirstatsettings.cpp:100 +msgid "Please confirm" +msgstr "Kérem, erősítse meg" + +#: kcleanup.cpp:181 +msgid "Confirm" +msgstr "Megerősítés" + +#: kdirstatapp.cpp:126 +msgid "Refresh &All" +msgstr "Összes &frissítése" + +#: kdirstatapp.cpp:130 +msgid "Refresh &Selected" +msgstr "&Kiválasztottak frissítése" + +#: kdirstatapp.cpp:134 +msgid "Continue Reading at &Mount Point" +msgstr "Az olvasás folytatása a &csatolási ponttól" + +#: kdirstatapp.cpp:144 +msgid "Send &Mail to Owner" +msgstr "&Levélküldés a tulajdonosnak" + +#: kdirstatapp.cpp:148 +msgid "Send &Feedback Mail..." +msgstr "&Válaszlevél küldése..." + +#: kdirstatapp.cpp:153 +msgid "Opens a directory" +msgstr "Könyvtár megnyitása" + +#: kdirstatapp.cpp:154 +msgid "Opens a recently used directory" +msgstr "A legutóbb használt könyvtár megnyitása" + +#: kdirstatapp.cpp:155 +msgid "Closes the current directory" +msgstr "A jelenlegi könyvtár bezárása" + +#: kdirstatapp.cpp:156 +msgid "Re-reads the entire directory tree" +msgstr "A teljes könyvtárfa újraolvasása" + +#: kdirstatapp.cpp:157 +msgid "Re-reads the selected subtree" +msgstr "A kiválasztott alkönyvtárfa újraolvasása" + +#: kdirstatapp.cpp:158 +msgid "Scan mounted file systems" +msgstr "Csatolt fájlrendszerek ellenőrzése" + +#: kdirstatapp.cpp:159 +msgid "Quits the application" +msgstr "Kilépés az alkalmazásból" + +#: kdirstatapp.cpp:160 +msgid "Copies the URL of the selected item to the clipboard" +msgstr "A kiválasztott elem URL címének vágólapra másolása" + +#: kdirstatapp.cpp:161 +msgid "Enables/disables the toolbar" +msgstr "Az eszköztár ki/bekapcsolása" + +#: kdirstatapp.cpp:162 +msgid "Enables/disables the statusbar" +msgstr "Az állapotsor ki/bekapcsolása" + +#: kdirstatapp.cpp:163 +msgid "Opens the preferences dialog" +msgstr "A beállítási párbeszédablak megnyitása" + +#: kdirstatapp.cpp:164 +msgid "Sends a mail to the owner of the selected subtree" +msgstr "Levélküldés a kiválasztott alkönyvtárak tulajdonosának" + +#: kdirstatapp.cpp:216 kdirstatapp.cpp:250 kdirstatapp.cpp:349 +#: kdirstatapp.cpp:361 kdirstatapp.cpp:374 kdirstatapp.cpp:383 +#: kdirstatapp.cpp:395 +msgid "Ready." +msgstr "Kész." + +#: kdirstatapp.cpp:243 kdirstatapp.cpp:342 kdirstatapp.cpp:356 +msgid "Opening directory..." +msgstr "Könyvtár megnyitása..." + +#: kdirstatapp.cpp:344 +msgid "Open Directory..." +msgstr "Könyvtár megnyitása..." + +#: kdirstatapp.cpp:368 +msgid "Closing directory..." +msgstr "Könyvtár bezárása..." + +#: kdirstatapp.cpp:381 +msgid "Refreshing directory tree..." +msgstr "A könyvtárfa frissítése..." + +#: kdirstatapp.cpp:393 +msgid "Refreshing selected subtree..." +msgstr "A kiválasztott könyvtárfa frissítése..." + +#: kdirstatapp.cpp:482 +msgid "" +"Now that you know this program for some time,\n" +"wouldn't you like to tell the authors your opinion about it?\n" +"\n" +"Open Source software depends on user feedback.\n" +"Your opinion can help us make the software better." +msgstr "" +"Ha gyakran használja a programot,\n" +"megosztaná velünk tapasztalatait?\n" +"\n" +"A nyílt forráskódú szoftver minősége a felhasználói visszajelzésektől függ.\n" +"A megjegyzései segíthetnek jobbá tenni a szoftvert." + +#: kdirstatapp.cpp:487 +msgid "Please tell us your opinion!" +msgstr "Kérjük tudassa velünk véleményét!" + +#: kdirstatapp.cpp:488 +msgid "Open &Feedback Form..." +msgstr "Vála&sz űrlap megnyitása..." + +#: kdirstatapp.cpp:489 +msgid "&No, and don't ask again!" +msgstr "&Nem és ne is kérdezzen újból!" + +#: kdirtreeview.cpp:59 +msgid "Name" +msgstr "Név" + +#: kdirtreeview.cpp:61 +msgid "Subtree Percentage" +msgstr "Alkönyvtárfa százalékban" + +#: kdirtreeview.cpp:62 +msgid "Percentage" +msgstr "Százalék" + +#: kdirtreeview.cpp:63 +msgid "Subtree Total" +msgstr "Alkönyvtárfa összesen" + +#: kdirtreeview.cpp:65 +msgid "Own Size" +msgstr "Egyéni méret" + +#: kdirtreeview.cpp:66 +msgid "Items" +msgstr "Elemek" + +#: kdirtreeview.cpp:67 +msgid "Files" +msgstr "Fájlok" + +#: kdirtreeview.cpp:68 +msgid "Subdirs" +msgstr "Alkönyvtárak" + +#: kdirtreeview.cpp:69 +msgid "Last Change" +msgstr "Utolsó módosítás" + +#: kdirtreeview.cpp:156 +msgid "Read Jobs" +msgstr "Beolvasott feladatok" + +#: kdirtreeview.cpp:405 +#, c-format +msgid "Finished. Elapsed time: %1" +msgstr "Végrehajtva. Eltelt idő : %1" + +#: kdirtreeview.cpp:440 +msgid "Elapsed time: %1 reading directory %2" +msgstr "Eltelt idő: %1 %2 könyvtár olvasása " + +#: kdirtreeview.cpp:704 kdirtreeview.cpp:1451 +msgid "Bytes" +msgstr "bájt(ok)" + +#: kdirtreeview.cpp:803 +msgid "Disk usage" +msgstr "Lemezhasználat" + +#: kdirtreeview.cpp:805 +msgid "Please check your disk usage and clean up if you can. Thank you." +msgstr "Kérem ellenőrizze a lemez kihasználtságát és tisztítsa meg a felesleges fájloktól, ha akarja. Köszönöm." + +#: kdirtreeview.cpp:809 +msgid "Disk usage report generated by KDirStat" +msgstr "Lemezhasználat jelentés a KDirStat programtól" + +#: kdirtreeview.cpp:868 +msgid "" +msgstr "" + +#: kdirtreeview.cpp:1460 +msgid "kB" +msgstr "KB" + +#: kdirtreeview.cpp:1469 +msgid "MB" +msgstr "MB" + +#: kdirtreeview.cpp:1476 +msgid "GB" +msgstr "GB" + +#: kstdcleanup.cpp:26 +msgid "Open in &Konqueror" +msgstr "Megnyitás &Konquerorban" + +#: kstdcleanup.cpp:46 +msgid "Open in &Terminal" +msgstr "Megnyitás &terminálban" + +#: kstdcleanup.cpp:65 +msgid "&Compress" +msgstr "&Tömörítés" + +#: kstdcleanup.cpp:83 +msgid "&make clean" +msgstr "&Tisztítás" + +#: kstdcleanup.cpp:100 +msgid "Delete T&rash Files" +msgstr "KDirStat &szemétkosár ürítése" + +#: kstdcleanup.cpp:118 +msgid "Delete (to Trash &Bin)" +msgstr "Kidobás a KDirStat &szemétkosárba)" + +#: kstdcleanup.cpp:137 +msgid "&Delete (no way to undelete!)" +msgstr "&Törlés (nem lehet visszavonni!)" + +#: kcleanupcollection.cpp:234 +#, c-format +msgid "User Defined Cleanup #&%1" +msgstr "Felhasználó által megadott tisztítás: #&%1" + +#: kcleanupcollection.cpp:237 +#, c-format +msgid "User Defined Cleanup #%1" +msgstr "Felhasználó által megadott tisztítás: #%1" + +#: kdirstatsettings.cpp:39 +msgid "Settings" +msgstr "Beállítások" + +#: kdirstatsettings.cpp:68 +msgid "&Cleanups" +msgstr "&Tisztítások" + +#: kdirstatsettings.cpp:72 +msgid "&Tree Colors" +msgstr "&Könyvtárfa színek" + +#: kdirstatsettings.cpp:98 +msgid "" +"Really revert all settings to their default values?\n" +"You will lose all changes you ever made!" +msgstr "" +"Valóban vissza szeretné állítani az összes értéket az alapértelmezett értékre?\n" +"Minden beállítást el fog veszteni!" + +#: kdirstatsettings.cpp:101 +msgid "&Really revert to defaults" +msgstr "&Alapértelmezett értékek visszaállítása" + +#: kdirstatsettings.cpp:185 +#, c-format +msgid "Tree level %1" +msgstr "Könyvtárszint %1" + +#: kdirstatsettings.cpp:527 +msgid "&Enabled" +msgstr "&Aktív" + +#: kdirstatsettings.cpp:564 +msgid "&Title:" +msgstr "&Cím : " + +#: kdirstatsettings.cpp:565 +msgid "&Command line:" +msgstr "&Parancssor: " + +#: kdirstatsettings.cpp:567 +#, c-format +msgid "%p full path" +msgstr "%p teljes útvonal" + +#: kdirstatsettings.cpp:570 +#, c-format +msgid "%n file / directory name without path" +msgstr "%n fájl / könyvtárnév útvonal nélkül" + +#: kdirstatsettings.cpp:576 +msgid "&Recurse into subdirectories" +msgstr "&Belépés az alkönyvtárakba is" + +#: kdirstatsettings.cpp:581 +msgid "&Ask for confirmation" +msgstr "&Kérdezzen rá a jóváhagyáshoz" + +#: kdirstatsettings.cpp:587 +msgid "Works for..." +msgstr "Működik az alábbinál..." + +#: kdirstatsettings.cpp:593 +msgid "&Directories" +msgstr "&Könyvtárak" + +#: kdirstatsettings.cpp:594 +msgid "&Files" +msgstr "&Fájlok" + +#: kdirstatsettings.cpp:595 +msgid " p&seudo entries" +msgstr " &Pszeudo-bejegyzések" + +#: kdirstatsettings.cpp:605 +msgid "On local machine only ('file:/' protocol)" +msgstr "Csak a helyi gépen ('file:/' protokoll)" + +#: kdirstatsettings.cpp:606 +msgid "Network transparent (ftp, smb, tar, ...)" +msgstr "Transzparens hálózat (ftp, smb, tar, ...)" + +#: kdirstatsettings.cpp:626 +msgid "Refresh &Policy:" +msgstr "Frissítési &Szabályok: " + +#: kdirstatsettings.cpp:637 +msgid "No refresh" +msgstr "Nincs frissítés" + +#: kdirstatsettings.cpp:638 +msgid "Refresh this entry" +msgstr "Frissítse ezt a bejegyzést" + +#: kdirstatsettings.cpp:639 +msgid "Refresh this entry's parent" +msgstr "Frissítse a bejegyzés szülőjét" + +#: kdirstatsettings.cpp:640 +msgid "Assume entry has been deleted" +msgstr "Feltételezett törölt bejegyzés" + +#: kdirstatfeedback.cpp:36 +msgid "What is your general opinion about this program?" +msgstr "Mik az általános észrevételei a programmal kapcsolatban?" + +#: kdirstatfeedback.cpp:38 +msgid "It's one of my favourites" +msgstr "Egyike a kedvenceimnek" + +#: kdirstatfeedback.cpp:39 +msgid "I like it" +msgstr "Kedvelem" + +#: kdirstatfeedback.cpp:40 +msgid "It's sometimes useful" +msgstr "Néha hasznos" + +#: kdirstatfeedback.cpp:41 +msgid "It's average" +msgstr "Közepes" + +#: kdirstatfeedback.cpp:42 +msgid "Nice try, but this could be done better" +msgstr "Szép próbálkozás, de lehetne jobb is" + +#: kdirstatfeedback.cpp:43 +msgid "It's poor" +msgstr "Szegényes" + +#: kdirstatfeedback.cpp:44 +msgid "It's useless" +msgstr "Használhatatlan" + +#: kdirstatfeedback.cpp:45 +msgid "It's crap" +msgstr "Rossz" + +#: kdirstatfeedback.cpp:47 +msgid "Which features of this program do you like?" +msgstr "Mely tulajdonságokat kedvel a programban?" + +#: kdirstatfeedback.cpp:50 +msgid "Which features don't you like?" +msgstr "Mely tulajdonságokat nem kedvel a programban?" + +#: kdirstatfeedback.cpp:53 +msgid "Which features do you never use?" +msgstr "Mely tulajdonságokat nem használ a programban?" + +#: kdirstatfeedback.cpp:56 +msgid "What is your favourite feature?" +msgstr "Melyek a kedvenc tulajdonságai?" + +#: kdirstatfeedback.cpp:59 +msgid "Are there features you are missing?" +msgstr "Mik a hiányos vagy hiányzó tulajdonságok?" + +#: kdirstatfeedback.cpp:60 +msgid "Yes, a lot! (please add comment below)" +msgstr "Igen, nagyon! (kérjük töltse ki a megjegyzés rovatot is)" + +#: kdirstatfeedback.cpp:62 +msgid "None" +msgstr "Semmi" + +#: kdirstatfeedback.cpp:63 +msgid "It has too many features already!" +msgstr "Túl sok tulajdonsága van már most is!" + +#: kdirstatfeedback.cpp:65 +msgid "How do you rate the stability of this program?" +msgstr "Hogyan osztályozná a program stabilitását? " + +#: kdirstatfeedback.cpp:66 +msgid "Rock solid" +msgstr "Sziklaszilárd" + +#: kdirstatfeedback.cpp:67 kdirstatfeedback.cpp:74 +msgid "Good" +msgstr "Jó" + +#: kdirstatfeedback.cpp:68 kdirstatfeedback.cpp:75 kdirstatfeedback.cpp:82 +#: kdirstatfeedback.cpp:89 +msgid "Average" +msgstr "Közepes" + +#: kdirstatfeedback.cpp:69 kdirstatfeedback.cpp:76 +msgid "Poor" +msgstr "Szegényes" + +#: kdirstatfeedback.cpp:70 +msgid "It keeps crashing all the time" +msgstr "Mindig lefagy" + +#: kdirstatfeedback.cpp:72 +msgid "How do you rate the performance of this program?" +msgstr "Hogyan osztályozza a program teljesítményét?" + +#: kdirstatfeedback.cpp:73 +msgid "Great" +msgstr "Kitűnő" + +#: kdirstatfeedback.cpp:77 +msgid "It's so slow it drives me nuts" +msgstr "Túl lassú" + +#: kdirstatfeedback.cpp:79 +msgid "What is your experience with computers in general?" +msgstr "Mi a gyakorlata általában a számítógépekkel?" + +#: kdirstatfeedback.cpp:80 kdirstatfeedback.cpp:87 +msgid "Expert" +msgstr "Szakértő" + +#: kdirstatfeedback.cpp:81 kdirstatfeedback.cpp:88 +msgid "Fair" +msgstr "Megfelelő" + +#: kdirstatfeedback.cpp:83 kdirstatfeedback.cpp:90 +msgid "Learning" +msgstr "Tanuló" + +#: kdirstatfeedback.cpp:84 kdirstatfeedback.cpp:91 +msgid "Newbie" +msgstr "Újonc" + +#: kdirstatfeedback.cpp:86 +msgid "What is your experience with Unix/Linux systems?" +msgstr "Mi a gyakorlata Unix/Linux rendszerek terén?" + +#: kdirstatfeedback.cpp:93 +msgid "Did you have trouble figuring out how to work with this program?" +msgstr "Vázolná nekünk, hogyan dolgozik a programmal?" + +#: kdirstatfeedback.cpp:95 +msgid "No problem" +msgstr "Nincs probléma" + +#: kdirstatfeedback.cpp:96 +msgid "Some" +msgstr "Néha" + +#: kdirstatfeedback.cpp:97 +msgid "I'm still learning" +msgstr "Jelenleg még tanulok" + +#: kdirstatfeedback.cpp:98 +msgid "I didn't have a clue what to do at first" +msgstr "Nincs ötletem mit tegyek elsőként" + +#: kdirstatfeedback.cpp:99 +msgid "I still don't have a clue what to do" +msgstr "Nincs továbbra sem ötletem, mit tehetnék" + +#: kdirstatfeedback.cpp:101 +msgid "Where do you use this program most?" +msgstr "Hol használja legtöbbet a programot?" + +#: kdirstatfeedback.cpp:102 +msgid "At work" +msgstr "Munkahelyen" + +#: kdirstatfeedback.cpp:103 +msgid "At home" +msgstr "Otthon" + +#: kdirstatfeedback.cpp:104 +msgid "At university / school" +msgstr "Iskolában" + +#: kdirstatfeedback.cpp:106 +msgid "What is your primary role there?" +msgstr "Mi az elsődleges célja?" + +#: kdirstatfeedback.cpp:107 kdirstatfeedback.cpp:115 +msgid "Home user" +msgstr "Otthoni felhasználó" + +#: kdirstatfeedback.cpp:108 kdirstatfeedback.cpp:116 +msgid "Student" +msgstr "Diák" + +#: kdirstatfeedback.cpp:109 kdirstatfeedback.cpp:117 +msgid "Educational (teacher / professor)" +msgstr "Oktató (tanársegéd / tanár)" + +#: kdirstatfeedback.cpp:110 kdirstatfeedback.cpp:118 +msgid "Non-computer related work" +msgstr "Nem számítógépes munka" + +#: kdirstatfeedback.cpp:111 kdirstatfeedback.cpp:119 +msgid "Developer" +msgstr "Fejlesztő" + +#: kdirstatfeedback.cpp:112 kdirstatfeedback.cpp:120 +msgid "System administrator" +msgstr "Rendszeradminisztrátor" + +#: kdirstatfeedback.cpp:114 +msgid "Do you have any other roles there?" +msgstr "Vannak egyéb feladatai itt?" + +#: kdirstatfeedback.cpp:122 +msgid "How did you get to know this program?" +msgstr "Hol találta meg a programot?" + +#: kdirstatfeedback.cpp:123 +msgid "In a menu on my machine" +msgstr "A gépemen található menüből" + +#: kdirstatfeedback.cpp:124 +msgid "Somebody told me about it" +msgstr "Valaki mesélt róla" + +#: kdirstatfeedback.cpp:125 +msgid "On the internet" +msgstr "Az interneten" + +#: kdirstatfeedback.cpp:126 +msgid "Printed magazine / book" +msgstr "Nyomtatott újságban / könyvben" + +#: kdirstatfeedback.cpp:127 +msgid "Other (please add comment below)" +msgstr "Egyéb (Kérjük részletezze alább)" + +#: kdirstatfeedback.cpp:129 +msgid "Did you ever get a KDirStat mail report telling you to clean up disk space?" +msgstr "Kapott már valaha KDirStat levél jelentést a lemezhely tisztításáról?" + +#: kdirstatfeedback.cpp:132 +msgid "Would you recommend this program to a friend?" +msgstr "Ajánlaná a programot egy barátjának?" + +#: kdirstatfeedback.cpp:143 +msgid "The directory tree display in general" +msgstr "Az általános könyvtárfa megjelenítés" + +#: kdirstatfeedback.cpp:144 +msgid "Percentage bars as graphical display of relative sizes" +msgstr "A százalékjelzők grafikusak relatív méretezéssel" + +#: kdirstatfeedback.cpp:145 +msgid "Files apart from directories in a separate item" +msgstr "A könyvtárakban eltérő fájlok, külön bejegyzéssel " + +#: kdirstatfeedback.cpp:147 +msgid "Cleanup actions in general" +msgstr "Általános akciók törlése" + +#: kdirstatfeedback.cpp:148 +msgid "Predefined cleanup actions" +msgstr "Előre megadott akciók törlése" + +#: kdirstatfeedback.cpp:149 +msgid "User defined cleanup actions" +msgstr "Felhasználó által megadott akciók törlése" + +#: kdirstatfeedback.cpp:150 +msgid "Cleanup action configuration" +msgstr "Az akció beállítások törlése" + +#: kdirstatfeedback.cpp:152 +msgid "Different colors in percentage bars" +msgstr "Eltérő színek a százalékjelzőkben" + +#: kdirstatfeedback.cpp:153 +msgid "Tree color configuration" +msgstr "Könyvtárfa színek beállítása" + +#: kdirstatfeedback.cpp:154 +msgid "Staying on one file system" +msgstr "Maradjon egyetlen fájlrendszeren" + +#: kdirstatfeedback.cpp:155 +msgid "The \"mail to owner\" facility" +msgstr "A \"levél a felhasználónak\" lehetőség" + +#: kdirstatfeedback.cpp:156 +msgid "This \"feedback mail\" facility" +msgstr "A \"válaszlevél\" lehetőség" + +#: kdirstatfeedback.cpp:158 +msgid "Human readable sizes (kB, MB, ...)" +msgstr "Emberi mértékegységű méretek (KB, MB, ...)" + +#: kdirstatfeedback.cpp:159 +msgid "All the numbers in the tree display" +msgstr "Az összes szám a könyvtárfa nézetben" + +#: kdirstatfeedback.cpp:160 +msgid "Last change time of an entire directory tree" +msgstr "A teljes könyvtárba utolsó módosításának ideje" + +#: kdirstatfeedback.cpp:161 +msgid "The PacMan animation" +msgstr "A PacMan animáció" + +#: kfeedback.cpp:35 +msgid "Feedback" +msgstr "Visszajelzés" + +#: kfeedback.cpp:41 +msgid "&Mail this..." +msgstr "&Levél küldése..." + +#: kfeedback.cpp:91 +msgid "" +"

Please tell us your opinion about this program.

You will be " +"able to review everything in your mailer before any mail is sent.
Nothing " +"will be sent behind your back.

" +msgstr "" +"

Kérjük ossza meg velünk a programmal kapcsolatos észrevételeit.

" +"

Minden küldendő adatot lehetősége lesz mégegyszer átolvasni a levelezőprogramjában." +"
Semmit sem küldünk az Ön háta mögött.

" + +#: kfeedback.cpp:116 +msgid "Questions marked with " +msgstr "A csillaggal jelölt kérdéseket " + +#: kfeedback.cpp:125 +msgid " must be answered before a mail can be sent." +msgstr " meg kell válaszolni mielőtt a levél küldésre kerülne." + +#: kfeedback.cpp:136 +msgid "&Additional comments:" +msgstr "További &megjegyzések:" + +#: kfeedback.cpp:314 +msgid "yes" +msgstr "igen" + +#: kfeedback.cpp:315 +msgid "no" +msgstr "nem" + +#: kdirstatui.rc:32 +msgid "Clean &Up" +msgstr "&Tisztítás" + +#: kdirstatui.rc:60 +msgid "&Report" +msgstr "&Jelentés" + +#~ #: kdirstatfeedback.cpp:61 +#~ msgid "Some (please add comment below)" +#~ msgstr "Quelques-unes (veuillez ajouter vos commentaires ci-dessous)" + diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..6fed6b0 --- /dev/null +++ b/po/it.po @@ -0,0 +1,960 @@ +# translation of it.po to Italiano +# Copyright (C) 2003 Free Software Foundation, Inc. +# Giuliano Colla , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: it\n" +"POT-Creation-Date: 2003-11-11 10:55+0100\n" +"PO-Revision-Date: 2003-11-12 19:25+0100\n" +"Last-Translator: Giuliano Colla \n" +"Language-Team: Italiano\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0\n" + +#: kcleanupcollection.cpp:231 +msgid "User Defined Cleanup #&%1" +msgstr "Pulizia personalizzata N. &%1" + +#: kcleanupcollection.cpp:234 +msgid "User Defined Cleanup #%1" +msgstr "Pulizia personalizzata N. %1" + +#: kcleanup.cpp:169 +msgid "" +"%1\n" +"in directory %2" +msgstr "" +"%1\n" +"nella directory %2" + +#: kcleanup.cpp:173 +msgid "" +"%1\n" +"for file %2" +msgstr "" +"%1\n" +"per il file %2" + +#: kcleanup.cpp:178 kdirstatsettings.cpp:106 +msgid "Please Confirm" +msgstr "Confermare" + +#: kcleanup.cpp:179 +msgid "Confirm" +msgstr "Conferma" + +#: kdirstatapp.cpp:145 +msgid "Open &URL..." +msgstr "Apri &URL..." + +#: kdirstatapp.cpp:152 +msgid "Refresh &All" +msgstr "&Aggiornare tutto" + +#: kdirstatapp.cpp:156 +msgid "Refresh &Selected" +msgstr "Aggiornare &Selezione" + +#: kdirstatapp.cpp:160 +msgid "Continue Reading at &Mount Point" +msgstr "Continua Lettura al punto di &Mount" + +#: kdirstatapp.cpp:164 +msgid "Stop Rea&ding" +msgstr "&Ferma Lettura" + +#: kdirstatapp.cpp:173 +msgid "Zoom in" +msgstr "Ingrandisci" + +#: kdirstatapp.cpp:177 +msgid "Zoom out" +msgstr "Rimpicciolisci" + +#: kdirstatapp.cpp:181 +msgid "Select Parent" +msgstr "Seleziona Padre" + +#: kdirstatapp.cpp:185 +msgid "Rebuild Treemap" +msgstr "Ricostruisci la Treemap" + +#: kdirstatapp.cpp:189 +msgid "Show Treemap" +msgstr "Mostra la Treemap" + +#: kdirstatapp.cpp:193 +msgid "Help about Treemaps" +msgstr "Aiuto sulle Treemap" + +#: kdirstatapp.cpp:199 +msgid "Send &Mail to Owner" +msgstr "Invia una e-&Mail al Proprietario" + +#: kdirstatapp.cpp:203 +msgid "Send &Feedback Mail..." +msgstr "Invia una E-mail di &Commento" + +#: kdirstatapp.cpp:208 +msgid "Opens a directory" +msgstr "Apre una Directory" + +#: kdirstatapp.cpp:209 +msgid "Opens a (possibly remote) directory" +msgstr "Apre una Directory (anche remota)" + +#: kdirstatapp.cpp:210 +msgid "Opens a recently used directory" +msgstr "Apre una Directory usata recentemente" + +#: kdirstatapp.cpp:211 +msgid "Closes the current directory" +msgstr "Chiude la Directory corrente" + +#: kdirstatapp.cpp:212 +msgid "Re-reads the entire directory tree" +msgstr "Ricarica l'intero albero di Directory" + +#: kdirstatapp.cpp:213 +msgid "Re-reads the selected subtree" +msgstr "Ricarica il sottoalbero selezionato" + +#: kdirstatapp.cpp:214 +msgid "Scan mounted file systems" +msgstr "Ricerca i filesystem montati" + +#: kdirstatapp.cpp:215 +msgid "Stops directory reading" +msgstr "Ferma la lettura della Directory" + +#: kdirstatapp.cpp:216 +msgid "Quits the application" +msgstr "Uscita dal programma" + +#: kdirstatapp.cpp:217 +msgid "Copies the URL of the selected item to the clipboard" +msgstr "Copia l'URL selezionato negli appunti" + +#: kdirstatapp.cpp:218 +msgid "Enables/disables the toolbar" +msgstr "Abilita/disabilita la barra degli strumenti" + +#: kdirstatapp.cpp:219 +msgid "Enables/disables the statusbar" +msgstr "Abilita/disabilita la barra di stato" + +#: kdirstatapp.cpp:220 +msgid "Enables/disables the treemap view" +msgstr "Abilita/disabilita la vista della Treemap" + +#: kdirstatapp.cpp:221 +msgid "Zoom treemap in" +msgstr "Ingrandisci la Treemap" + +#: kdirstatapp.cpp:222 +msgid "Zoom treemap out" +msgstr "Rimpicciolisci la Treemap" + +#: kdirstatapp.cpp:223 +msgid "Select parent" +msgstr "Seleziona Padre" + +#: kdirstatapp.cpp:224 +msgid "Rebuild treemap to fit into available space" +msgstr "Riadatta la Treemap allo spazio disponibile" + +#: kdirstatapp.cpp:225 +msgid "Opens the preferences dialog" +msgstr "Apre il dialogo delle preferenze" + +#: kdirstatapp.cpp:226 +msgid "Sends a mail to the owner of the selected subtree" +msgstr "Invia una e-mail al proprietario del sottoalbero selezionato" + +#: kdirstatapp.cpp:301 kdirstatapp.cpp:335 kdirstatapp.cpp:445 +#: kdirstatapp.cpp:460 kdirstatapp.cpp:472 kdirstatapp.cpp:485 +#: kdirstatapp.cpp:494 kdirstatapp.cpp:506 +msgid "Ready." +msgstr "Pronto." + +#: kdirstatapp.cpp:328 kdirstatapp.cpp:438 kdirstatapp.cpp:467 +msgid "Opening directory..." +msgstr "Apertura directory..." + +#: kdirstatapp.cpp:440 +msgid "Open Directory..." +msgstr "Apre Directory..." + +#: kdirstatapp.cpp:452 +msgid "Opening URL..." +msgstr "Apertura URL..." + +#: kdirstatapp.cpp:455 +msgid "Open URL..." +msgstr "Apri URL..." + +#: kdirstatapp.cpp:479 +msgid "Closing directory..." +msgstr "Chiusura Directory..." + +#: kdirstatapp.cpp:492 +msgid "Refreshing directory tree..." +msgstr "Aggiornamento albero..." + +#: kdirstatapp.cpp:504 +msgid "Refreshing selected subtree..." +msgstr "Aggiornamento sottoalbero scelto..." + +#: kdirstatapp.cpp:684 +msgid "" +"Now that you know this program for some time,\n" +"wouldn't you like to tell the authors your opinion about it?\n" +"\n" +"Open Source software depends on user feedback.\n" +"Your opinion can help us make the software better." +msgstr "" +"Ora che ha usato il programma per qualche tempo,\n" +"non vorrebbe dire agli autori la sua opinione in proposito?\n" +"\n" +"Il software Open Source si affida al parere degli utenti.\n" +"I suoi commenti ci possono aiutare a migliorarlo." + +#: kdirstatapp.cpp:689 +msgid "Please tell us your opinion!" +msgstr "Vi preghiamo di darci il vostro parere! " + +#: kdirstatapp.cpp:690 +msgid "Open &Feedback Form..." +msgstr "Apri il &Questionario ..." + +#: kdirstatapp.cpp:691 +msgid "&No, and don't ask again!" +msgstr "&No,e non chiedermelo più." + +#: kdirstatfeedback.cpp:33 +msgid "What is your general opinion about this program?" +msgstr "Quale è la sua opinione in generale su questo programma?" + +#: kdirstatfeedback.cpp:35 +msgid "It's one of my favourites" +msgstr "E' uno dei miei preferiti" + +#: kdirstatfeedback.cpp:36 +msgid "I like it" +msgstr "Mi piace" + +#: kdirstatfeedback.cpp:37 +msgid "It's sometimes useful" +msgstr "Qualche volta è utile" + +#: kdirstatfeedback.cpp:38 +msgid "It's average" +msgstr "E' nella media" + +#: kdirstatfeedback.cpp:39 +msgid "Nice try, but this could be done better" +msgstr "Buon tentativo, ma si poteva fare di meglio" + +#: kdirstatfeedback.cpp:40 +msgid "It's poor" +msgstr "E' molto modesto" + +#: kdirstatfeedback.cpp:41 +msgid "It's useless" +msgstr "E' inutile" + +#: kdirstatfeedback.cpp:42 +msgid "It's crap" +msgstr "Fa schifo!" + +#: kdirstatfeedback.cpp:44 +msgid "Which features of this program do you like?" +msgstr "Quali caratteristiche di questo programma le piacciono?" + +#: kdirstatfeedback.cpp:47 +msgid "Which features don't you like?" +msgstr "Quali caratteristiche non le piacciono?" + +#: kdirstatfeedback.cpp:50 +msgid "Which features do you never use?" +msgstr "Quali funzioni non usa mai?" + +#: kdirstatfeedback.cpp:53 +msgid "What is your favourite feature?" +msgstr "Quali funzioni predilige?" + +#: kdirstatfeedback.cpp:56 +msgid "Are there features you are missing?" +msgstr "Ci sono funzioni di cui sente la mancanza?" + +#: kdirstatfeedback.cpp:57 +msgid "Yes, a lot! (please add comment below)" +msgstr "Sì, molte! (Per piacere, aggiunga qui sotto le sue richieste)" + +#: kdirstatfeedback.cpp:58 +msgid "Some (please add comment below)" +msgstr "Alcune (Per piacere, aggiunga qui sotto le sue richieste)" + +#: kdirstatfeedback.cpp:59 +msgid "None" +msgstr "Nessuna" + +#: kdirstatfeedback.cpp:60 +msgid "It has too many features already!" +msgstr "Ha già anche troppe funzioni!" + +#: kdirstatfeedback.cpp:62 +msgid "How do you rate the stability of this program?" +msgstr "Come classifica la stabilità di questo programma?" + +#: kdirstatfeedback.cpp:63 +msgid "Rock solid" +msgstr "Come una roccia!" + +#: kdirstatfeedback.cpp:64 kdirstatfeedback.cpp:71 +msgid "Good" +msgstr "Buona" + +#: kdirstatfeedback.cpp:65 kdirstatfeedback.cpp:72 kdirstatfeedback.cpp:79 +#: kdirstatfeedback.cpp:86 +msgid "Average" +msgstr "Media" + +#: kdirstatfeedback.cpp:66 kdirstatfeedback.cpp:73 +msgid "Poor" +msgstr "Modesta" + +#: kdirstatfeedback.cpp:67 +msgid "It keeps crashing all the time" +msgstr "Si pianta di continuo" + +#: kdirstatfeedback.cpp:69 +msgid "How do you rate the performance of this program?" +msgstr "Come classifica le prestazioni di questo programma?" + +#: kdirstatfeedback.cpp:70 +msgid "Great" +msgstr "Notevoli" + +#: kdirstatfeedback.cpp:74 +msgid "It's so slow it drives me nuts" +msgstr "E' così lento che mi fa impazzire" + +#: kdirstatfeedback.cpp:76 +msgid "What is your experience with computers in general?" +msgstr "Quale è la sua esperienza con i computers in generale?" + +#: kdirstatfeedback.cpp:77 kdirstatfeedback.cpp:84 +msgid "Expert" +msgstr "Esperto" + +#: kdirstatfeedback.cpp:78 kdirstatfeedback.cpp:85 +msgid "Fair" +msgstr "Abbastanza buona" + +#: kdirstatfeedback.cpp:80 kdirstatfeedback.cpp:87 +msgid "Learning" +msgstr "Sto imparando" + +#: kdirstatfeedback.cpp:81 kdirstatfeedback.cpp:88 +msgid "Newbie" +msgstr "Alle prime armi" + +#: kdirstatfeedback.cpp:83 +msgid "What is your experience with Unix/Linux systems?" +msgstr "Quale è la sua esperienza sui sitemi Unix/Linux?" + +#: kdirstatfeedback.cpp:90 +msgid "Did you have trouble figuring out how to work with this program in general?" +msgstr "Ha avuto problemi a capire come funziona questo programma in generale?" + +#: kdirstatfeedback.cpp:92 +msgid "No problem" +msgstr "Nessun problema" + +#: kdirstatfeedback.cpp:93 +msgid "Some" +msgstr "Qualche problema" + +#: kdirstatfeedback.cpp:94 kdirstatfeedback.cpp:132 +msgid "I'm still learning" +msgstr "Sto ancora imparando" + +#: kdirstatfeedback.cpp:95 +msgid "I didn't have a clue what to do at first" +msgstr "Non avevo un'idea di come fare" + +#: kdirstatfeedback.cpp:96 kdirstatfeedback.cpp:133 +msgid "I still don't have a clue what to do" +msgstr "Non ho ancora un'idea di come fare" + +#: kdirstatfeedback.cpp:98 +msgid "Where do you use this program most?" +msgstr "Dove usa questo programma prevalentemente?" + +#: kdirstatfeedback.cpp:99 +msgid "At work" +msgstr "Al lavoro" + +#: kdirstatfeedback.cpp:100 +msgid "At home" +msgstr "A casa" + +#: kdirstatfeedback.cpp:101 +msgid "At university / school" +msgstr "A scuola / all'Università" + +#: kdirstatfeedback.cpp:103 +msgid "What is your primary role there?" +msgstr "Quale è il suo ruolo in quel luogo?" + +#: kdirstatfeedback.cpp:104 kdirstatfeedback.cpp:112 +msgid "Home user" +msgstr "Utente privato" + +#: kdirstatfeedback.cpp:105 kdirstatfeedback.cpp:113 +msgid "Student" +msgstr "Studente" + +#: kdirstatfeedback.cpp:106 kdirstatfeedback.cpp:114 +msgid "Educational (teacher / professor)" +msgstr "Insegnante" + +#: kdirstatfeedback.cpp:107 kdirstatfeedback.cpp:115 +msgid "Non-computer related work" +msgstr "Lavoro non informatico" + +#: kdirstatfeedback.cpp:108 kdirstatfeedback.cpp:116 +msgid "Developer" +msgstr "Sviluppatore" + +#: kdirstatfeedback.cpp:109 kdirstatfeedback.cpp:117 +msgid "System administrator" +msgstr "Amministratore di sistema" + +#: kdirstatfeedback.cpp:111 +msgid "Do you have any other roles there?" +msgstr "Ricopre altri ruoli?" + +#: kdirstatfeedback.cpp:119 +msgid "How did you get to know this program?" +msgstr "Come è venuto a conoscenza di questo programma?" + +#: kdirstatfeedback.cpp:120 +msgid "In a menu on my machine" +msgstr "In un menu del mio computer" + +#: kdirstatfeedback.cpp:121 +msgid "Somebody told me about it" +msgstr "Qualcuno me ne ha parlato" + +#: kdirstatfeedback.cpp:122 +msgid "On the internet" +msgstr "Su Internet" + +#: kdirstatfeedback.cpp:123 +msgid "Printed magazine / book" +msgstr "Da riviste / libri" + +#: kdirstatfeedback.cpp:124 +msgid "Other (please add comment below)" +msgstr "Altro (si prega specificare sotto)" + +#: kdirstatfeedback.cpp:126 +msgid "Did you ever get a KDirStat mail report telling you to clean up disk space?" +msgstr "Ha mai ricevuto un report da KDirStat che suggeriva di liberare spazio sul disco?" + +#: kdirstatfeedback.cpp:129 +msgid "Could you figure yet out how to work with the treemaps?" +msgstr "E' già riuscito a orientarsi nell'uso delle Treemap?" + +#: kdirstatfeedback.cpp:130 +msgid "I became an expert at it" +msgstr "Sono diventato un esperto!" + +#: kdirstatfeedback.cpp:131 +msgid "I got a fairly good idea of it" +msgstr "Ne ho già un'idea abbastanza chiara" + +#: kdirstatfeedback.cpp:134 +msgid "Treemaps? Huh? What the hell is that?" +msgstr "Le Treemap? Che cosa diavolo sono?" + +#: kdirstatfeedback.cpp:136 +msgid "What do you think about the treemaps?" +msgstr "Che cosa pensa delle Treemap?" + +#: kdirstatfeedback.cpp:137 +msgid "They are useless" +msgstr "Sono inutili" + +#: kdirstatfeedback.cpp:138 +msgid "The display is confusing" +msgstr "La visualizzazione disorienta" + +#: kdirstatfeedback.cpp:139 +msgid "They look ugly" +msgstr "Sono brutte" + +#: kdirstatfeedback.cpp:140 +msgid "They look nice" +msgstr "Sono belle" + +#: kdirstatfeedback.cpp:141 +msgid "They help finding large files" +msgstr "Aiutano a trovare i file più lunghi" + +#: kdirstatfeedback.cpp:142 +msgid "I could do with the treemap view alone" +msgstr "Potrei lavorare solo con la vista a Treemap" + +#: kdirstatfeedback.cpp:143 +msgid "The combination of tree view and treemaps is great" +msgstr "La combinazione delle due viste, a albero e a Treemap, è una grande idea" + +#: kdirstatfeedback.cpp:144 +msgid "I want more info inside the treemap view" +msgstr "Vorrei più informazioni nella vista a Treemap" + +#: kdirstatfeedback.cpp:145 +msgid "Leave the treemaps as they are right now" +msgstr "Le Treemap mi vanno bene così come sono" + +#: kdirstatfeedback.cpp:147 +msgid "Would you recommend this program to a friend?" +msgstr "Consiglierebbe questo programma a un amico?" + +#: kdirstatfeedback.cpp:158 +msgid "The directory tree display in general" +msgstr "La presentazione in generale dell'albero delle directory" + +#: kdirstatfeedback.cpp:159 +msgid "Percentage bars as graphical display of relative sizes" +msgstr "Le barre come rappresentazione grafica delle dimensioni relative" + +#: kdirstatfeedback.cpp:160 +msgid "Files apart from directories in a separate item" +msgstr "I files distinti dalle directory in un oggetto a parte" + +#: kdirstatfeedback.cpp:162 +msgid "Treemaps in general" +msgstr "Le Treemap in generale" + +#: kdirstatfeedback.cpp:163 +msgid "The cushioned treemap rendering" +msgstr "La presentazione \"a cuscino\" delle Treemap" + +#: kdirstatfeedback.cpp:165 +msgid "Cleanup actions in general" +msgstr "Le funzioni di pulizia in generale" + +#: kdirstatfeedback.cpp:166 +msgid "Predefined cleanup actions" +msgstr "Le funzioni di pulizia predefinite" + +#: kdirstatfeedback.cpp:167 +msgid "User defined cleanup actions" +msgstr "Le funzioni di pulizia personalizzate" + +#: kdirstatfeedback.cpp:168 +msgid "Cleanup action configuration" +msgstr "La configurabilità delle funzioni di pulizia" + +#: kdirstatfeedback.cpp:170 +msgid "Different colors in percentage bars" +msgstr "I colori differenziati nelle barre" + +#: kdirstatfeedback.cpp:171 +msgid "Tree color configuration" +msgstr "La presentazione a colori dell'albero" + +#: kdirstatfeedback.cpp:172 +msgid "Staying on one file system" +msgstr "Il rimanere all'interno di un solo filesystem" + +#: kdirstatfeedback.cpp:173 +msgid "The \"mail to owner\" facility" +msgstr "La funzione \"Invia una e-mail al proprietario\"" + +#: kdirstatfeedback.cpp:174 +msgid "This \"feedback mail\" facility" +msgstr "Questa posibilità di inviare commenti" + +#: kdirstatfeedback.cpp:176 +msgid "Human readable sizes (kB, MB, ...)" +msgstr "Dimensioni in valori comprensibili (KB, MB, ...)" + +#: kdirstatfeedback.cpp:177 +msgid "All the numbers in the tree display" +msgstr "Tutti i numeri nella presentazione ad albero" + +#: kdirstatfeedback.cpp:178 +msgid "Last change time of an entire directory tree" +msgstr "La data dell'ultimo cambiamento di un intero albero di directory" + +#: kdirstatfeedback.cpp:179 +msgid "The PacMan animation" +msgstr "L'animazione PacMan" + +#: kdirstatsettings.cpp:37 +msgid "Settings" +msgstr "Impostazioni" + +#: kdirstatsettings.cpp:66 +msgid "&Cleanups" +msgstr "&Pulizia" + +#: kdirstatsettings.cpp:70 +msgid "&Tree Colors" +msgstr "&Colori" + +#: kdirstatsettings.cpp:74 +msgid "Tree&map" +msgstr "&Treemap" + +#: kdirstatsettings.cpp:78 +msgid "&General" +msgstr "&Generali" + +#: kdirstatsettings.cpp:104 +msgid "" +"Really revert all settings to their default values?\n" +"You will lose all changes you ever made!" +msgstr "" +"Ripristinare tutte le impostazioni ai valori originali?\n" +"Tutte le modifiche che avete fatto andranno perse!" + +#: kdirstatsettings.cpp:107 +msgid "&Really Revert to Defaults" +msgstr "&Ripristina le impostazioni originali" + +#: kdirstatsettings.cpp:193 +msgid "Tree Level %1" +msgstr "Livello %1" + +#: kdirstatsettings.cpp:529 +msgid "&Enabled" +msgstr "&Abilitato" + +#: kdirstatsettings.cpp:566 +msgid "&Title:" +msgstr "&Titolo:" + +#: kdirstatsettings.cpp:567 +msgid "&Command Line:" +msgstr "Riga di &Comando:" + +#: kdirstatsettings.cpp:569 +#, c-format +msgid "%p Full Path" +msgstr "%p Percorso completo" + +#: kdirstatsettings.cpp:572 +#, c-format +msgid "%n File / Directory Name Without Path" +msgstr "%n File / Directory senza percorso" + +#: kdirstatsettings.cpp:575 +msgid "%t KDE Trash Directory" +msgstr "%t Directory Cestino di KDE" + +#: kdirstatsettings.cpp:581 +msgid "&Recurse into Subdirectories" +msgstr "&Recursione nelle sotto-directory" + +#: kdirstatsettings.cpp:586 +msgid "&Ask for Confirmation" +msgstr "Dom&anda Conferma" + +#: kdirstatsettings.cpp:592 +msgid "Works for..." +msgstr "Applica a..." + +#: kdirstatsettings.cpp:598 +msgid "&Directories" +msgstr "&Directory" + +#: kdirstatsettings.cpp:599 +msgid "&Files" +msgstr "&Files" + +#: kdirstatsettings.cpp:600 +msgid " P&seudo Entries" +msgstr "-P&seudo-voci" + +#: kdirstatsettings.cpp:610 +msgid "On Local Machine Only ('file:/' Protocol)" +msgstr "Solo computer locale (protocollo 'file./')" + +#: kdirstatsettings.cpp:611 +msgid "Network Transparent (ftp, smb, tar, ...)" +msgstr "Trasparente alla rete (ftp, smb, tar, ...)" + +#: kdirstatsettings.cpp:631 +msgid "Refresh &Policy:" +msgstr "&Politica di agiornamento:" + +#: kdirstatsettings.cpp:642 +msgid "No Refresh" +msgstr "Non aggiornare" + +#: kdirstatsettings.cpp:643 +msgid "Refresh This Entry" +msgstr "Aggiorna questa voce" + +#: kdirstatsettings.cpp:644 +msgid "Refresh This Entry's Parent" +msgstr "Aggiorna il Padre di questa voce" + +#: kdirstatsettings.cpp:645 +msgid "Assume Entry Has Been Deleted" +msgstr "Considera la voce come cancellata" + +#: kdirstatsettings.cpp:715 +msgid "Directory Reading" +msgstr "Lettura directory" + +#: kdirstatsettings.cpp:718 +msgid "Cross &File System Boundaries" +msgstr "Attraversa i confini tra &Filesystem" + +#: kdirstatsettings.cpp:719 +msgid "Use Optimized &Local Directory Read Methods" +msgstr "Usa lettura ottimizzata delle directory &locali" + +#: kdirstatsettings.cpp:726 +msgid "Animation" +msgstr "Animazione" + +#: kdirstatsettings.cpp:729 +msgid "P@cM@n Animation in Tool &Bar" +msgstr "Animazione P@cM@n nella &Barra Strumenti" + +#: kdirstatsettings.cpp:730 +msgid "P@cM@n Animation in Directory &Tree" +msgstr "Animazione P@cM@n nell'albero delle &Directory" + +#: kdirstatsettings.cpp:809 +msgid "S&quarify Treemap" +msgstr "Treemap S&quadrata" + +#: kdirstatsettings.cpp:810 +msgid "Use C&ushion Shading" +msgstr "Sfumatura a C&uscino" + +#: kdirstatsettings.cpp:815 +msgid "Cushion Parameters" +msgstr "Parametri Cuscino" + +#: kdirstatsettings.cpp:820 +msgid "Ambient &Light" +msgstr "&Luce Ambiente" + +#: kdirstatsettings.cpp:830 +msgid "&Height Scale" +msgstr "&Scala in altezza" + +#: kdirstatsettings.cpp:840 +msgid "Draw Lines if Lo&w Contrast" +msgstr "Con &Basso Contrasto traccia Linee" + +#: kdirstatsettings.cpp:844 +msgid "Always Draw &Grid" +msgstr "Disegna sempre &Griglia" + +#: kdirstatsettings.cpp:847 +msgid "Gr&id Color: " +msgstr "Colore Gr&iglia" + +#: kdirstatsettings.cpp:857 +msgid "Colors for Plain Treemaps" +msgstr "Colori delle Treemap semplici" + +#: kdirstatsettings.cpp:860 +msgid "&Files: " +msgstr "&Files: " + +#: kdirstatsettings.cpp:865 +msgid "&Directories: " +msgstr "&Directory: " + +#: kdirstatsettings.cpp:870 +msgid "Gr&id: " +msgstr "Gr&iglia: " + +#: kdirstatsettings.cpp:884 +msgid "Hi&ghlight R&ectangle: " +msgstr "Evidenzia R&ettangolo; " + +#: kdirstatsettings.cpp:892 +msgid "Minim&um Treemap Tile Size: " +msgstr "Dimensione &Minima Piastrelle Treemap" + +#: kdirstatsettings.cpp:899 +msgid "Auto-&Resize Treemap" +msgstr "Auto-&Ridimensiona Treemap" + +#: kdirtree.cpp:1548 kdirtreeview.cpp:800 +msgid "Bytes" +msgstr "Bytes" + +#: kdirtree.cpp:1557 +msgid "kB" +msgstr "KB" + +#: kdirtree.cpp:1566 +msgid "MB" +msgstr "MB" + +#: kdirtree.cpp:1573 +msgid "GB" +msgstr "GB" + +#: kdirtreeview.cpp:62 +msgid "Name" +msgstr "Nome" + +#: kdirtreeview.cpp:64 +msgid "Subtree Percentage" +msgstr "% Sottoalbero" + +#: kdirtreeview.cpp:65 +msgid "Percentage" +msgstr "Percentuale" + +#: kdirtreeview.cpp:66 +msgid "Subtree Total" +msgstr "Totale Sottoalbero" + +#: kdirtreeview.cpp:68 +msgid "Own Size" +msgstr "Dimens. Propria" + +#: kdirtreeview.cpp:69 +msgid "Items" +msgstr "Oggetti" + +#: kdirtreeview.cpp:70 +msgid "Files" +msgstr "File" + +#: kdirtreeview.cpp:71 +msgid "Subdirs" +msgstr "Sottodir." + +#: kdirtreeview.cpp:72 +msgid "Last Change" +msgstr "Ultima Modifica" + +#: kdirtreeview.cpp:165 +msgid "Read Jobs" +msgstr "Letture in corso" + +#: kdirtreeview.cpp:434 +msgid "Finished. Elapsed time: %1" +msgstr "Pronto. Tempo trascorso: %1" + +#: kdirtreeview.cpp:464 +msgid "Aborted. Elapsed time: %1" +msgstr "Annullato. Tempo trascorso: %1" + +#: kdirtreeview.cpp:499 +msgid "Elapsed time: %1 reading directory %2" +msgstr "Tempo trascorso: %1 Lettura directory %2" + +#: kdirtreeview.cpp:907 +msgid "Disk Usage" +msgstr "Utilizzo disco" + +#: kdirtreeview.cpp:909 +msgid "Please check your disk usage and clean up if you can. Thank you." +msgstr "Controllare l'occupazione del disco e ripulire, se possibile. Grazie." + +#: kdirtreeview.cpp:913 +msgid "Disk usage report generated by KDirStat" +msgstr "Rapporto sull'uso del disco generato da KDirStat" + +#: kdirtreeview.cpp:976 +msgid "" +msgstr "" + +#: kdirtreeview.cpp:1109 +msgid "[%1 Read Jobs]" +msgstr "[%1 Letture in corso]" + +#: kfeedback.cpp:32 +msgid "Feedback" +msgstr "Commenti" + +#: kfeedback.cpp:38 +msgid "&Mail this..." +msgstr "&Invia questo..." + +#: kfeedback.cpp:88 +msgid "" +"

Please tell us your opinion about this program.

You will be " +"able to review everything in your mailer before any mail is sent.
Nothing " +"will be sent behind your back.

" +msgstr "" +"

Ci mandi la sua opinione su questo programma

Potrà " +"rivedere tutto nel suo programma di posta prima della spedizione.
Nulla " +"sarà spedito a sua insaputa.

" + +#: kfeedback.cpp:113 +msgid "Questions marked with " +msgstr "E' necessario rispondere alle domande contrassegnate da " + +#: kfeedback.cpp:122 +msgid " must be answered before a mail can be sent." +msgstr " perché l'e-mail possa essere spedita." + +#: kfeedback.cpp:133 +msgid "&Additional Comments:" +msgstr "Commenti &Aggiuntivi" + +#: kfeedback.cpp:311 +msgid "yes" +msgstr "sì" + +#: kfeedback.cpp:312 +msgid "no" +msgstr "no" + +#: kstdcleanup.cpp:23 +msgid "Open in &Konqueror" +msgstr "Apri in &Konqueror" + +#: kstdcleanup.cpp:43 +msgid "Open in &Terminal" +msgstr "Apri in un &Terminale" + +#: kstdcleanup.cpp:62 +msgid "&Compress" +msgstr "&Comprimi" + +#: kstdcleanup.cpp:80 +msgid "&make clean" +msgstr "&make clean" + +#: kstdcleanup.cpp:97 +msgid "Delete T&rash Files" +msgstr "Elimina Files da Cestina&re" + +#: kstdcleanup.cpp:115 +msgid "Delete (to Trash &Bin)" +msgstr "Elimina (al Cesti&no)" + +#: kstdcleanup.cpp:134 +msgid "&Delete (no way to undelete!)" +msgstr "Elimina (&Definitivamente)" + +#: required for version 2.3.7 +msgid "Clean &Up" +msgstr "&Pulizia" + +msgid "&Report" +msgstr "&Rapporto" + diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..0c4e0eb --- /dev/null +++ b/po/ja.po @@ -0,0 +1,973 @@ +# translation of ja.po to +# translation of ja.po to +# translation of ja.po to +# translation of ja.po to +# Copyright (C) 2003 Free Software Foundation, Inc. +# Toyohiro Asukai , 2003 +#, no-wrap +msgid "" +msgstr "" +"Project-Id-Version: ja\n" +"POT-Creation-Date: 2003-10-27 14:56+0900\n" +"PO-Revision-Date: 2003-10-29 17:08+0900\n" +"Last-Translator: Toyohiro Asukai \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 3.1.2\n" + +#: kstdcleanup.cpp:23 +msgid "Open in &Konqueror" +msgstr "Konquerorで開く(&K)" + +#: kstdcleanup.cpp:43 +msgid "Open in &Terminal" +msgstr "ターミナルで開く(&T)" + +#: kstdcleanup.cpp:62 +msgid "&Compress" +msgstr "圧縮(&C)" + +#: kstdcleanup.cpp:80 +msgid "&make clean" +msgstr "&make clean" + +#: kstdcleanup.cpp:97 +msgid "Delete T&rash Files" +msgstr "ゴミ箱を空に(&r)" + +#: kstdcleanup.cpp:115 +msgid "Delete (to Trash &Bin)" +msgstr "ゴミ箱へ(&B)" + +#: kstdcleanup.cpp:134 +msgid "&Delete (no way to undelete!)" +msgstr "削除(復元できない)(&D)" + +#: kcleanup.cpp:169 +msgid "" +"%1\n" +"in directory %2" +msgstr "" +"%1\n" +"ディレクトリー %2" + +#: kcleanup.cpp:173 +msgid "" +"%1\n" +"for file %2" +msgstr "" +"%1\n" +"ファイル %2" + +#: kcleanup.cpp:178 kdirstatsettings.cpp:106 +msgid "Please Confirm" +msgstr "確認してください" + +#: kcleanup.cpp:179 +msgid "Confirm" +msgstr "確認" + +#: kfeedback.cpp:32 +msgid "Feedback" +msgstr "フィードバック" + +#: kfeedback.cpp:38 +msgid "&Mail this..." +msgstr "これをメール(&M)..." + +#: kfeedback.cpp:88 +msgid "" +"

Please tell us your opinion about this program.

You will be " +"able to review everything in your mailer before any mail is sent.
Nothing " +"will be sent behind your back.

" +msgstr "" +"

我々にこのプログラムに関するあなたの意見を聞かせてください

" +"メールを送信する前に、あなたのメーラーですべてをチェックすることができます
" +"何も、あなたに黙って送信されません

" + +#: kfeedback.cpp:113 +msgid "Questions marked with " +msgstr "質問で、次の印" + +#: kfeedback.cpp:122 +msgid " must be answered before a mail can be sent." +msgstr "は、メールを送信する前に、答えていなければいけません" + +#: kfeedback.cpp:133 +msgid "&Additional Comments:" +msgstr "追加コメント(&A):" + +#: kfeedback.cpp:311 +msgid "yes" +msgstr "はい" + +#: kfeedback.cpp:312 +msgid "no" +msgstr "いいえ" + +#: kdirtreeview.cpp:62 +msgid "Name" +msgstr "名前" + +#: kdirtreeview.cpp:64 +msgid "Subtree Percentage" +msgstr "サブツリー・バーセンテージ" + +#: kdirtreeview.cpp:65 +msgid "Percentage" +msgstr "パーセンテージ" + +#: kdirtreeview.cpp:66 +msgid "Subtree Total" +msgstr "サブツリー合計" + +#: kdirtreeview.cpp:68 +msgid "Own Size" +msgstr "サイズ" + +#: kdirtreeview.cpp:69 +msgid "Items" +msgstr "アイテム数" + +#: kdirtreeview.cpp:70 +msgid "Files" +msgstr "ファイル数" + +#: kdirtreeview.cpp:71 +msgid "Subdirs" +msgstr "サブディレクトリ数" + +#: kdirtreeview.cpp:72 +msgid "Last Change" +msgstr "最終更新日" + +#: kdirtreeview.cpp:165 +msgid "Read Jobs" +msgstr "読取りジョブ" + +#: kdirtreeview.cpp:434 +#, c-format +msgid "Finished. Elapsed time: %1" +msgstr "終了. 経過時間 : %1" + +#: kdirtreeview.cpp:464 +#, c-format +msgid "Aborted. Elapsed time: %1" +msgstr "中断. 経過時間 : %1" + +#: kdirtreeview.cpp:499 +msgid "Elapsed time: %1 reading directory %2" +msgstr "経過時間: %1 ディレクトリ読込み中 %2" + +#: kdirtree.cpp:1548 kdirtreeview.cpp:800 +msgid "Bytes" +msgstr "バイト" + +#: kdirtreeview.cpp:907 +msgid "Disk Usage" +msgstr "ディスク使用状況" + +#: kdirtreeview.cpp:909 +msgid "Please check your disk usage and clean up if you can. Thank you." +msgstr "ディスク使用状況を確認してください、もし可能なら不要ファイルを削除してください" + +#: kdirtreeview.cpp:913 +msgid "Disk usage report generated by KDirStat" +msgstr "KDirStatによってディスク使用状況レポートを作成しました" + +#: kdirtreeview.cpp:976 +msgid "" +msgstr "<ファイル>" + +#: kdirtreeview.cpp:1109 +msgid "[%1 Read Jobs]" +msgstr "[%1 読込みジョブ]" + +#: kdirstatfeedback.cpp:33 +msgid "What is your general opinion about this program?" +msgstr "このプログラムに関するあなたの一般的な意見は、何ですか?" + +#: kdirstatfeedback.cpp:35 +msgid "It's one of my favourites" +msgstr "私のお気に入りの1つです" + +#: kdirstatfeedback.cpp:36 +msgid "I like it" +msgstr "好きです" + +#: kdirstatfeedback.cpp:37 +msgid "It's sometimes useful" +msgstr "時々役に立ちます" + +#: kdirstatfeedback.cpp:38 +msgid "It's average" +msgstr "普通です" + +#: kdirstatfeedback.cpp:39 +msgid "Nice try, but this could be done better" +msgstr "素晴らしいです、しかしより良くすることができます" + +#: kdirstatfeedback.cpp:40 +msgid "It's poor" +msgstr "貧弱です" + +#: kdirstatfeedback.cpp:41 +msgid "It's useless" +msgstr "役に立ちません" + +#: kdirstatfeedback.cpp:42 +msgid "It's crap" +msgstr "ナンセンスです" + +#: kdirstatfeedback.cpp:44 +msgid "Which features of this program do you like?" +msgstr "あなたは、このプログラムのどの機能が好きか?" + +#: kdirstatfeedback.cpp:47 +msgid "Which features don't you like?" +msgstr "あなたは、どの機能が嫌いですか?" + +#: kdirstatfeedback.cpp:50 +msgid "Which features do you never use?" +msgstr "あなたは、どの機能を使用しませんか?" + +#: kdirstatfeedback.cpp:53 +msgid "What is your favourite feature?" +msgstr "あなたの大好きな機能は、何ですか?" + +#: kdirstatfeedback.cpp:56 +msgid "Are there features you are missing?" +msgstr "あなたが見逃している機能が、ありますか?" + +#: kdirstatfeedback.cpp:57 +msgid "Yes, a lot! (please add comment below)" +msgstr "はい,たくさん!(コメントを下で記述)" + +#: kdirstatfeedback.cpp:58 +msgid "Some (please add comment below)" +msgstr "いくつか(コメントを下で記述)" + +#: kdirstatfeedback.cpp:59 +msgid "None" +msgstr "なし" + +#: kdirstatfeedback.cpp:60 +msgid "It has too many features already!" +msgstr "すでにあまりに多くの機能を持つ!" + +#: kdirstatfeedback.cpp:62 +msgid "How do you rate the stability of this program?" +msgstr "どのように、あなたはこのプログラムの安定度の評価を得ますか?" + +#: kdirstatfeedback.cpp:63 +msgid "Rock solid" +msgstr "信頼できる" + +#: kdirstatfeedback.cpp:64 kdirstatfeedback.cpp:71 +msgid "Good" +msgstr "良い" + +#: kdirstatfeedback.cpp:65 kdirstatfeedback.cpp:72 kdirstatfeedback.cpp:79 +#: kdirstatfeedback.cpp:86 +msgid "Average" +msgstr "普通" + +#: kdirstatfeedback.cpp:66 kdirstatfeedback.cpp:73 +msgid "Poor" +msgstr "貧弱" + +#: kdirstatfeedback.cpp:67 +msgid "It keeps crashing all the time" +msgstr "ずっと、クラッシュし続ける" + +#: kdirstatfeedback.cpp:69 +msgid "How do you rate the performance of this program?" +msgstr "どのように、このプログラムのパフォーマンスの評価を得ますか?" + +#: kdirstatfeedback.cpp:70 +msgid "Great" +msgstr "とても良い" + +#: kdirstatfeedback.cpp:74 +msgid "It's so slow it drives me nuts" +msgstr "とても遅い" + +#: kdirstatfeedback.cpp:76 +msgid "What is your experience with computers in general?" +msgstr "コンピュータによるあなたの経験は?" + +#: kdirstatfeedback.cpp:77 kdirstatfeedback.cpp:84 +msgid "Expert" +msgstr "専門家" + +#: kdirstatfeedback.cpp:78 kdirstatfeedback.cpp:85 +msgid "Fair" +msgstr "一応(そこそこ)" + +#: kdirstatfeedback.cpp:80 kdirstatfeedback.cpp:87 +msgid "Learning" +msgstr "学習中" + +#: kdirstatfeedback.cpp:81 kdirstatfeedback.cpp:88 +msgid "Newbie" +msgstr "初心者" + +#: kdirstatfeedback.cpp:83 +msgid "What is your experience with Unix/Linux systems?" +msgstr "Unix/Linuxシステムによるあなたの経験は?" + +#: kdirstatfeedback.cpp:90 +msgid "Did you have trouble figuring out how to work with this program in general?" +msgstr "どのようにこのプログラムの動作を理解するのに苦労したか?" + +#: kdirstatfeedback.cpp:92 +msgid "No problem" +msgstr "苦労しない" + +#: kdirstatfeedback.cpp:93 +msgid "Some" +msgstr "時々" + +#: kdirstatfeedback.cpp:94 kdirstatfeedback.cpp:132 +msgid "I'm still learning" +msgstr "まだ、学習中" + +#: kdirstatfeedback.cpp:95 +msgid "I didn't have a clue what to do at first" +msgstr "何を最初にすればいいか手がかりがなかった" + +#: kdirstatfeedback.cpp:96 kdirstatfeedback.cpp:133 +msgid "I still don't have a clue what to do" +msgstr "まだ何をしたら良いか解らない" + +#: kdirstatfeedback.cpp:98 +msgid "Where do you use this program most?" +msgstr "どこで、あなたは最もこのプログラムを使うか?" + +#: kdirstatfeedback.cpp:99 +msgid "At work" +msgstr "仕事で" + +#: kdirstatfeedback.cpp:100 +msgid "At home" +msgstr "自宅で" + +#: kdirstatfeedback.cpp:101 +msgid "At university / school" +msgstr "大学/学校で" + +#: kdirstatfeedback.cpp:103 +msgid "What is your primary role there?" +msgstr "あなたの主な役割は?" + +#: kdirstatfeedback.cpp:104 kdirstatfeedback.cpp:112 +msgid "Home user" +msgstr "自宅ユーザ" + +#: kdirstatfeedback.cpp:105 kdirstatfeedback.cpp:113 +msgid "Student" +msgstr "学生" + +#: kdirstatfeedback.cpp:106 kdirstatfeedback.cpp:114 +msgid "Educational (teacher / professor)" +msgstr "教育者(先生/教授)" + +#: kdirstatfeedback.cpp:107 kdirstatfeedback.cpp:115 +msgid "Non-computer related work" +msgstr "非コンピュータ関連した仕事" + +#: kdirstatfeedback.cpp:108 kdirstatfeedback.cpp:116 +msgid "Developer" +msgstr "開発者" + +#: kdirstatfeedback.cpp:109 kdirstatfeedback.cpp:117 +msgid "System administrator" +msgstr "システム管理者" + +#: kdirstatfeedback.cpp:111 +msgid "Do you have any other roles there?" +msgstr "あなたは、他の役割を持っていますか?" + +#: kdirstatfeedback.cpp:119 +msgid "How did you get to know this program?" +msgstr "どのように、あなたはこのプログラムを知りましたか?" + +#: kdirstatfeedback.cpp:120 +msgid "In a menu on my machine" +msgstr "私のマシンのメニューで" + +#: kdirstatfeedback.cpp:121 +msgid "Somebody told me about it" +msgstr "誰かが、私に教えた" + +#: kdirstatfeedback.cpp:122 +msgid "On the internet" +msgstr "インターネットの上で" + +#: kdirstatfeedback.cpp:123 +msgid "Printed magazine / book" +msgstr "書籍 マガジン/本" + +#: kdirstatfeedback.cpp:124 +msgid "Other (please add comment below)" +msgstr "その他 (コメントを下で記述)" + +#: kdirstatfeedback.cpp:126 +msgid "Did you ever get a KDirStat mail report telling you to clean up disk space?" +msgstr "ディスクスペースをきれいにするようにKDirStatメール・レポートを得ましたか?" + +#: kdirstatfeedback.cpp:129 +msgid "Could you figure yet out how to work with the treemaps?" +msgstr "Could you figure yet out how to work with the treemaps?" + +#: kdirstatfeedback.cpp:130 +msgid "I became an expert at it" +msgstr "私はエキスパートになりました" + +#: kdirstatfeedback.cpp:131 +msgid "I got a fairly good idea of it" +msgstr "私は、かなりよい考えを思いつきました。" + +#: kdirstatfeedback.cpp:134 +msgid "Treemaps? Huh? What the hell is that?" +msgstr "ツリーマップ?へえー? 一体全体、それは何ですか" + +#: kdirstatfeedback.cpp:136 +msgid "What do you think about the treemaps?" +msgstr "ツリーマップについての貴方の考えは?" + +#: kdirstatfeedback.cpp:137 +msgid "They are useless" +msgstr "役立ちません" + +#: kdirstatfeedback.cpp:138 +msgid "The display is confusing" +msgstr "表示は混同しています" + +#: kdirstatfeedback.cpp:139 +msgid "They look ugly" +msgstr "醜く見えます" + +#: kdirstatfeedback.cpp:140 +msgid "They look nice" +msgstr "よく見えます" + +#: kdirstatfeedback.cpp:141 +msgid "They help finding large files" +msgstr "大きなファイルを見つけることを支援します" + +#: kdirstatfeedback.cpp:142 +msgid "I could do with the treemap view alone" +msgstr "私は、ツリーマップ表示を単独で必要とします。" + +#: kdirstatfeedback.cpp:143 +msgid "The combination of tree view and treemaps is great" +msgstr "ツリー表示およびツリーマップのコンビネーションは良いです" + +#: kdirstatfeedback.cpp:144 +msgid "I want more info inside the treemap view" +msgstr "私は、ツリーマップ表示の内部のより多くの情報を望みます。" + +#: kdirstatfeedback.cpp:145 +msgid "Leave the treemaps as they are right now" +msgstr "それらが今ちょうどあるように、ツリーマップを残します" + +#: kdirstatfeedback.cpp:147 +msgid "Would you recommend this program to a friend?" +msgstr "あなたは、このプログラムを友人に推薦しますか?" + +#: kdirstatfeedback.cpp:158 +msgid "The directory tree display in general" +msgstr "ディレクトリーツリーを表示する" + +#: kdirstatfeedback.cpp:159 +msgid "Percentage bars as graphical display of relative sizes" +msgstr "関連するサイズのグラフィックディスプレイとしてのパーセンテージ・バー" + +#: kdirstatfeedback.cpp:160 +msgid "Files apart from directories in a separate item" +msgstr "別々の<ファイル>項目でのディレクトリーからは、別ファイルとして" + +#: kdirstatfeedback.cpp:162 +msgid "Treemaps in general" +msgstr "ツリーマップ(一般)" + +#: kdirstatfeedback.cpp:163 +msgid "The cushioned treemap rendering" +msgstr "ツリーマップレンダー" + +#: kdirstatfeedback.cpp:165 +msgid "Cleanup actions in general" +msgstr "クリーンアップ動作" + +#: kdirstatfeedback.cpp:166 +msgid "Predefined cleanup actions" +msgstr "定義されたクリーンアップ動作" + +#: kdirstatfeedback.cpp:167 +msgid "User defined cleanup actions" +msgstr "ユーザー定義した、クリーンアップ動作" + +#: kdirstatfeedback.cpp:168 +msgid "Cleanup action configuration" +msgstr "クリーンアップ動作設定" + +#: kdirstatfeedback.cpp:170 +msgid "Different colors in percentage bars" +msgstr "パーセンテージ・バーでの異なる色" + +#: kdirstatfeedback.cpp:171 +msgid "Tree color configuration" +msgstr "ツリーカラー構成" + +#: kdirstatfeedback.cpp:172 +msgid "Staying on one file system" +msgstr "1つのファイルシステム上に" + +#: kdirstatfeedback.cpp:173 +msgid "The \"mail to owner\" facility" +msgstr "\"オーナーへのメール\" 機能" + +#: kdirstatfeedback.cpp:174 +msgid "This \"feedback mail\" facility" +msgstr "\"フィードバックメール\" 機能" + +#: kdirstatfeedback.cpp:176 +msgid "Human readable sizes (kB, MB, ...)" +msgstr "判読可能なサイズ(kB(MB)...)" + +#: kdirstatfeedback.cpp:177 +msgid "All the numbers in the tree display" +msgstr "ツリー表示での全ての数" + +#: kdirstatfeedback.cpp:178 +msgid "Last change time of an entire directory tree" +msgstr "ディレクトリーツリーの最後の変更時間" + +#: kdirstatfeedback.cpp:179 +msgid "The PacMan animation" +msgstr "パックマン・アニメーション" + +#: kdirstatsettings.cpp:37 +msgid "Settings" +msgstr "設定" + +#: kdirstatsettings.cpp:66 +msgid "&Cleanups" +msgstr "クリーンアップ(&C)" + +#: kdirstatsettings.cpp:70 +msgid "&Tree Colors" +msgstr "ツリー色(&T)" + +#: kdirstatsettings.cpp:74 +msgid "Tree&map" +msgstr "ツリーマップ(&m)" + +#: kdirstatsettings.cpp:78 +msgid "&General" +msgstr "一般(&G)" + +#: kdirstatsettings.cpp:104 +msgid "" +"Really revert all settings to their default values?\n" +"You will lose all changes you ever made!" +msgstr "" +"本当に、全ての設定値をデフォルト値に戻しますか?\n" +"貴方は、これまでに作った全ての変更を失います!" + +#: kdirstatsettings.cpp:107 +msgid "&Really Revert to Defaults" +msgstr "本当に、デフォルト値に戻します。(&R)" + +#: kdirstatsettings.cpp:193 +#, c-format +msgid "Tree Level %1" +msgstr "ツリーレベル %1" + +#: kdirstatsettings.cpp:529 +msgid "&Enabled" +msgstr "有効(&E)" + +#: kdirstatsettings.cpp:566 +msgid "&Title:" +msgstr "タイトル(&T):" + +#: kdirstatsettings.cpp:567 +msgid "&Command Line:" +msgstr "コマンドライン(&C):" + +#: kdirstatsettings.cpp:569 +#, c-format +msgid "%p Full Path" +msgstr "%p フルパス" + +#: kdirstatsettings.cpp:572 +#, c-format +msgid "%n File / Directory Name Without Path" +msgstr "%n パスのない、ファイル/ディレクトリ名" + +#: kdirstatsettings.cpp:575 +msgid "%t KDE Trash Directory" +msgstr "%t KDE ゴミ箱のディレクトリー" + +#: kdirstatsettings.cpp:581 +msgid "&Recurse into Subdirectories" +msgstr "サブディレクトリへの再帰(&R)" + +#: kdirstatsettings.cpp:586 +msgid "&Ask for Confirmation" +msgstr "確認を求める(&A)" + +#: kdirstatsettings.cpp:592 +msgid "Works for..." +msgstr "動作..." + +#: kdirstatsettings.cpp:598 +msgid "&Directories" +msgstr "ディレクトリ(&D)" + +#: kdirstatsettings.cpp:599 +msgid "&Files" +msgstr "ファイル(&F)" + +#: kdirstatsettings.cpp:600 +msgid " P&seudo Entries" +msgstr "<ファイル> 疑似エントリー(&s)" + +#: kdirstatsettings.cpp:610 +msgid "On Local Machine Only ('file:/' Protocol)" +msgstr "ローカルマシン上のみ ('file:/' protocol)" + +#: kdirstatsettings.cpp:611 +msgid "Network Transparent (ftp, smb, tar, ...)" +msgstr "ネットワークトランスペアレント(ftp, smb, tar, ...)" + +#: kdirstatsettings.cpp:631 +msgid "Refresh &Policy:" +msgstr "リフレッシュのポリシー(&P):" + +#: kdirstatsettings.cpp:642 +msgid "No Refresh" +msgstr "リフレッシュなし" + +#: kdirstatsettings.cpp:643 +msgid "Refresh This Entry" +msgstr "このエントリをリフレッシュ" + +#: kdirstatsettings.cpp:644 +msgid "Refresh This Entry's Parent" +msgstr "エントリーの親をリフレッシュ" + +#: kdirstatsettings.cpp:645 +msgid "Assume Entry Has Been Deleted" +msgstr "エントリーが削除されたと仮定" + +#: kdirstatsettings.cpp:715 +msgid "Directory Reading" +msgstr "ディレクトリーの読込み" + +#: kdirstatsettings.cpp:718 +msgid "Cross &File System Boundaries" +msgstr "クロス・ファイル・システム境界(&F)" + +#: kdirstatsettings.cpp:719 +msgid "Use Optimized &Local Directory Read Methods" +msgstr "ローカルディレクトリーを最適化(&L)" + +#: kdirstatsettings.cpp:726 +msgid "Animation" +msgstr "アニメーション" + +#: kdirstatsettings.cpp:729 +msgid "P@cM@n Animation in Tool &Bar" +msgstr "パックマンアニメーションツールバー(&B)" + +#: kdirstatsettings.cpp:730 +msgid "P@cM@n Animation in Directory &Tree" +msgstr "ディレクトリーツリー内のパックマンアニメーション(&T)" + +#: kdirstatsettings.cpp:809 +msgid "S&quarify Treemap" +msgstr "四角のツリーマップ(&q)" + +#: kdirstatsettings.cpp:810 +msgid "Use C&ushion Shading" +msgstr "濃淡な図形(&u)" + +#: kdirstatsettings.cpp:815 +msgid "Cushion Parameters" +msgstr "パラメータ" + +#: kdirstatsettings.cpp:820 +msgid "Ambient &Light" +msgstr "アンビアント・ライト(&L)" + +#: kdirstatsettings.cpp:830 +msgid "&Height Scale" +msgstr "高さ(&H)" + +#: kdirstatsettings.cpp:840 +msgid "Draw Lines if Lo&w Contrast" +msgstr "低いコントラスト時の描画ライン(&w)" + +#: kdirstatsettings.cpp:844 +msgid "Always Draw &Grid" +msgstr "グリッド表示(&G)" + +#: kdirstatsettings.cpp:847 +msgid "Gr&id Color: " +msgstr "グリッド色(&i): " + +#: kdirstatsettings.cpp:857 +msgid "Colors for Plain Treemaps" +msgstr "簡易・ツリーマップ時の色" + +#: kdirstatsettings.cpp:860 +msgid "&Files: " +msgstr "ファイル(&F): " + +#: kdirstatsettings.cpp:865 +msgid "&Directories: " +msgstr "ディレクトリ(&D): " + +#: kdirstatsettings.cpp:870 +msgid "Gr&id: " +msgstr "グリッド(&i): " + +#: kdirstatsettings.cpp:884 +msgid "Hi&ghlight R&ectangle: " +msgstr "ハイライト(&g)・長方形(&e): " + +#: kdirstatsettings.cpp:892 +msgid "Minim&um Treemap Tile Size: " +msgstr "最小のツリーマップ・タイル・サイズ(&u): " + +#: kdirstatsettings.cpp:899 +msgid "Auto-&Resize Treemap" +msgstr "自動リサイズ・ツリーマップ(&R)" + +#: kdirtree.cpp:1557 +msgid "kB" +msgstr "kB" + +#: kdirtree.cpp:1566 +msgid "MB" +msgstr "MB" + +#: kdirtree.cpp:1573 +msgid "GB" +msgstr "GB" + +#: kdirstatapp.cpp:145 +msgid "Open &URL..." +msgstr "URLを開く(&U)..." + +#: kdirstatapp.cpp:152 +msgid "Refresh &All" +msgstr "全てリフレッシュ(&A)" + +#: kdirstatapp.cpp:156 +msgid "Refresh &Selected" +msgstr "選択した項目のリフレッシュ(&S)" + +#: kdirstatapp.cpp:160 +msgid "Continue Reading at &Mount Point" +msgstr "マウント・ポイントで読み続ける(&M)" + +#: kdirstatapp.cpp:164 +msgid "Stop Rea&ding" +msgstr "読込み中止(&d)" + +#: kdirstatapp.cpp:173 +msgid "Zoom in" +msgstr "ズームイン" + +#: kdirstatapp.cpp:177 +msgid "Zoom out" +msgstr "ズームアウト" + +#: kdirstatapp.cpp:181 +msgid "Select Parent" +msgstr "親を選択" + +#: kdirstatapp.cpp:185 +msgid "Rebuild Treemap" +msgstr "ツリーマップの再構築" + +#: kdirstatapp.cpp:189 +msgid "Show Treemap" +msgstr "ツリーマップ表示" + +#: kdirstatapp.cpp:193 +msgid "Help about Treemaps" +msgstr "ツリーマップのヘルプ" + +#: kdirstatapp.cpp:199 +msgid "Send &Mail to Owner" +msgstr "オーナーにメイル送信(&M)" + +#: kdirstatapp.cpp:203 +msgid "Send &Feedback Mail..." +msgstr "フィードバックメール送信(&F)..." + +#: kdirstatapp.cpp:208 +msgid "Opens a directory" +msgstr "ディレクトリを開きます" + +#: kdirstatapp.cpp:209 +msgid "Opens a (possibly remote) directory" +msgstr "(恐らく遠隔)ディレクトリーを開きます" + +#: kdirstatapp.cpp:210 +msgid "Opens a recently used directory" +msgstr "最近用いられているディレクトリーを開きます" + +#: kdirstatapp.cpp:211 +msgid "Closes the current directory" +msgstr "カレント・ディレクトリを閉じます" + +#: kdirstatapp.cpp:212 +msgid "Re-reads the entire directory tree" +msgstr "再度ディレクトリー全体を読みます" + +#: kdirstatapp.cpp:213 +msgid "Re-reads the selected subtree" +msgstr "選択されたサブツリーを再度読みます" + +#: kdirstatapp.cpp:214 +msgid "Scan mounted file systems" +msgstr "マウントしたファイル・システムをスキャンします" + +#: kdirstatapp.cpp:215 +msgid "Stops directory reading" +msgstr "ディレクトリーの読込みを中止" + +#: kdirstatapp.cpp:216 +msgid "Quits the application" +msgstr "アプリケーションを中止します" + +#: kdirstatapp.cpp:217 +msgid "Copies the URL of the selected item to the clipboard" +msgstr "選択されたアイテムのURLをクリップボードにコピーします" + +#: kdirstatapp.cpp:218 +msgid "Enables/disables the toolbar" +msgstr "ツールバーを表示/非表示" + +#: kdirstatapp.cpp:219 +msgid "Enables/disables the statusbar" +msgstr "ステータスバーを表示/非表示" + +#: kdirstatapp.cpp:220 +msgid "Enables/disables the treemap view" +msgstr "ツリーマップを表示/非表示" + +#: kdirstatapp.cpp:221 +msgid "Zoom treemap in" +msgstr "ツリーマップズームイン" + +#: kdirstatapp.cpp:222 +msgid "Zoom treemap out" +msgstr "ツリーマップズームアウト" + +#: kdirstatapp.cpp:223 +msgid "Select parent" +msgstr "親を選択" + +#: kdirstatapp.cpp:224 +msgid "Rebuild treemap to fit into available space" +msgstr "利用可能なスペースに入れるべきツリーマップを再構築" + +#: kdirstatapp.cpp:225 +msgid "Opens the preferences dialog" +msgstr "プレファレンス・ダイアログを開く" + +#: kdirstatapp.cpp:226 +msgid "Sends a mail to the owner of the selected subtree" +msgstr "選択されたサブツリーの所有者へメールを送信" + +#: kdirstatapp.cpp:301 kdirstatapp.cpp:335 kdirstatapp.cpp:445 +#: kdirstatapp.cpp:460 kdirstatapp.cpp:472 kdirstatapp.cpp:485 +#: kdirstatapp.cpp:494 kdirstatapp.cpp:506 +msgid "Ready." +msgstr "準備ができています" + +#: kdirstatapp.cpp:328 kdirstatapp.cpp:438 kdirstatapp.cpp:467 +msgid "Opening directory..." +msgstr "ディレクトリーを開いてます..." + +#: kdirstatapp.cpp:440 +msgid "Open Directory..." +msgstr "ディレクトリー開きます" + +#: kdirstatapp.cpp:452 +msgid "Opening URL..." +msgstr "URLを開いています..." + +#: kdirstatapp.cpp:455 +msgid "Open URL..." +msgstr "URL開きます..." + +#: kdirstatapp.cpp:479 +msgid "Closing directory..." +msgstr "ディレクトリーを閉じています..." + +#: kdirstatapp.cpp:492 +msgid "Refreshing directory tree..." +msgstr "ディレクトリーツリーのリフレッシュ中..." + +#: kdirstatapp.cpp:504 +msgid "Refreshing selected subtree..." +msgstr "選択されたサブツリーのリフレッシュ中..." + +#: kdirstatapp.cpp:684 +msgid "" +"Now that you know this program for some time,\n" +"wouldn't you like to tell the authors your opinion about it?\n" +"\n" +"Open Source software depends on user feedback.\n" +"Your opinion can help us make the software better." +msgstr "" +"このプログラムを知っているので\n" +"著者にあなたの見解を伝えることはいかがではないでしょうか?\n" +"\n" +"Open Source ソフトウェアはユーザ・フィードバックに依存します。\n" +"あなたの意見は、私たちがソフトウェアをよりよくするのを助けることができます。" + +#: kdirstatapp.cpp:689 +msgid "Please tell us your opinion!" +msgstr "私たちにあなたの意見を伝えてください!" + +#: kdirstatapp.cpp:690 +msgid "Open &Feedback Form..." +msgstr "フィードバックフォームを開く(&F)..." + +#: kdirstatapp.cpp:691 +msgid "&No, and don't ask again!" +msgstr "いいえ、再び尋ねないでください!(&N)" + +#: kcleanupcollection.cpp:231 +#, c-format +msgid "User Defined Cleanup #&%1" +msgstr "ユーザ・クリーンアップを定義しました #&%1" + +#: kcleanupcollection.cpp:234 +#, c-format +msgid "User Defined Cleanup #%1" +msgstr "ユーザ・クリーンアップを定義しました #%1" + +#: kdirstatui.rc:34 +msgid "Clean &Up" +msgstr "クリーンアップ(&U)" + +#: kdirstatui.rc:75 +msgid "&Treemap" +msgstr "ツリーマップ(&T)" + +#: kdirstatui.rc:75 +msgid "&Report" +msgstr "レポート(&R)" + diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/subdirs b/subdirs new file mode 100644 index 0000000..66d938a --- /dev/null +++ b/subdirs @@ -0,0 +1,3 @@ +doc +kdirstat +po