commit b6e09a3a8ea5f1338d089a29eb6e08f00f03f1aa Author: tpearson Date: Wed Feb 10 01:15:27 2010 +0000 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 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 0000000..977910d Binary files /dev/null and b/doc/en/feedback-mail.png differ 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 0000000..1c13b8a Binary files /dev/null and b/doc/en/kdirstat-config-cleanups.png differ diff --git a/doc/en/kdirstat-config-tree-colors.png b/doc/en/kdirstat-config-tree-colors.png new file mode 100644 index 0000000..40ac045 Binary files /dev/null and b/doc/en/kdirstat-config-tree-colors.png differ diff --git a/doc/en/kdirstat-main.png b/doc/en/kdirstat-main.png new file mode 100644 index 0000000..e1fdcb6 Binary files /dev/null and b/doc/en/kdirstat-main.png differ diff --git a/kdirstat.kdevprj b/kdirstat.kdevprj new file mode 100644 index 0000000..e627d2c --- /dev/null +++ b/kdirstat.kdevprj @@ -0,0 +1,153 @@ +[AUTHORS] +dist=true +install=false +install_location= +type=DATA +[COPYING] +dist=true +install=false +install_location= +type=DATA +[ChangeLog] +dist=true +install=false +install_location= +type=DATA +[Config for BinMakefileAm] +bin_program=kdirstat +cxxflags=-O0 -g3 -Wall +ldadd=$(LIB_KFILE) -lkdeui -lkdecore $(LIB_QT) +ldflags= +[General] +AMChanged=false +author=Stefan Hundhammer +configure_args=--with-qt-dir=/usr/lib/qt2 --prefix=/opt/kde2 +email=sh@suse.de +kdevprj_version=1.3 +lfv_open_groups= +makefiles=Makefile.am,kdirstat/Makefile.am,doc/Makefile.am,doc/en/Makefile.am,po/Makefile.am +project_name=KDirStat +project_type=normal_kde2 +sgml_file=/work/home/sh/kde2/kdirstat/doc/en/index.docbook +sub_dir=kdirstat/ +version=1.1 +version_control=None +workspace=1 +[INSTALL] +dist=true +install=false +install_location= +type=DATA +[LFV Groups] +GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS +Headers=*.h,*.hh,*.hxx,*.hpp,*.H +Others=* +Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l +Translations=*.po +B_KFILEUser Interface=*.kdevdlg,*.ui,*.rc +groups=Headers,Sources,User Interface,Translations,GNU,Others +[Makefile.am] +files=kdirstat.kdevprj,AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,kdirstat.lsm +sub_dirs=kdirstat,po,doc +type=normal +[README] +dist=true +install=false +install_location= +type=DATA +[TODO] +dist=true +install=false +install_location= +type=DATA +[Workspace_1] +browser_file=file:/opt/kde2/share/doc/HTML/default/kdevelop/kde_libref/index.html +cpp_file=/work/home/sh/kde2/kdirstat/kdirstat/kdirstat.cpp +header_file=/work/home/sh/kde2/kdirstat/AUTHORS +openfiles=Untitled.h,Untitled.cpp,/work/home/sh/kde2/kdirstat/kdirstat/kdirstat.h,/work/home/sh/kde2/kdirstat/COPYING,/work/home/sh/kde2/kdirstat/COPYING.LIB,/work/home/sh/kde2/kdirstat/AUTHORS,/work/home/sh/kde2/kdirstat/kdirstat/kdirstat.cpp,/work/home/sh/kde2/kdirstat/kdirstat/kdirtree.cpp +show_outputview=true +show_treeview=true +[doc/Makefile.am] +sub_dirs=en +type=normal +[doc/en/Makefile.am] +files=doc/en/index.docbook +sub_dirs= +type=normal +[doc/en/index.docbook] +dist=true +install=false +install_location=$$(kde_icondir)/locolor/16x16/apps/kdirstat.png +type=DATA +[kdirstat.kdevprj] +dist=true +install=false +install_location= +type=DATA +[kdirstat.lsm] +dist=true +install=false +install_location= +type=DATA +[kdirstat/Makefile.am] +files=kdirstat/main.cpp,kdirstat/kdirstat.cpp,kdirstat/kdirstat.h,kdirstat/kdirstatdoc.cpp,kdirstat/kdirstatdoc.h,kdirstat/kdirstatview.cpp,kdirstat/kdirstatview.h,kdirstat/kdirstatui.rc,kdirstat/kdirstat.desktop,kdirstat/lo32-app-kdirstat.png,kdirstat/lo16-app-kdirstat.png +sub_dirs= +type=prog_main +[kdirstat/kdirstat.cpp] +dist=true +install=false +install_location= +type=SOURCE +[kdirstat/kdirstat.desktop] +dist=true +install=true +install_location=$$(kde_appsdir)/Applications/kdirstat.desktop +type=DATA +[kdirstat/kdirstat.h] +dist=true +install=false +install_location= +type=HEADER +[kdirstat/kdirstatdoc.cpp] +dist=true +install=false +install_location= +type=SOURCE +[kdirstat/kdirstatdoc.h] +dist=true +install=false +install_location= +type=HEADER +[kdirstat/kdirstatui.rc] +dist=true +install=false +install_location= +type=DATA +[kdirstat/kdirstatview.cpp] +dist=true +install=false +install_location= +type=SOURCE +[kdirstat/kdirstatview.h] +dist=true +install=false +install_location= +type=HEADER +[kdirstat/lo16-app-kdirstat.png] +dist=true +install=true +install_location=$$(kde_icondir)/locolor/16x16/apps/kdirstat.png +type=DATA +[kdirstat/lo32-app-kdirstat.png] +dist=true +install=true +install_location=$$(kde_icondir)/locolor/32x32/apps/kdirstat.png +type=DATA +[kdirstat/main.cpp] +dist=true +install=false +install_location= +type=SOURCE +[po/Makefile.am] +sub_dirs= +type=po diff --git a/kdirstat.lsm b/kdirstat.lsm new file mode 100644 index 0000000..abc1000 --- /dev/null +++ b/kdirstat.lsm @@ -0,0 +1,14 @@ +Begin3 +Title: KDirStat +Version: 1.8.6-rc1 +Entered-date: 2001-06-29 +Description: Grapical 'du' (disk usage) utility for KDE 2.x +Keywords: disk usage, file system, cleanup +Author: Stefan Hundhammer +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 0000000..4bd140e Binary files /dev/null and b/kdirstat/hi16-app-kdirstat.png differ diff --git a/kdirstat/hi32-app-kdirstat.png b/kdirstat/hi32-app-kdirstat.png new file mode 100644 index 0000000..d6c8d99 Binary files /dev/null and b/kdirstat/hi32-app-kdirstat.png differ 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 0000000..4bd140e Binary files /dev/null and b/kdirstat/lo16-app-kdirstat.png differ diff --git a/kdirstat/lo32-app-kdirstat.png b/kdirstat/lo32-app-kdirstat.png new file mode 100644 index 0000000..d6c8d99 Binary files /dev/null and b/kdirstat/lo32-app-kdirstat.png differ 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 0000000..95ea7d9 Binary files /dev/null and b/kdirstat/pics/hi16-action-symlink.png differ diff --git a/kdirstat/pics/hi16-action-symlink.xcf b/kdirstat/pics/hi16-action-symlink.xcf new file mode 100644 index 0000000..c269214 Binary files /dev/null and b/kdirstat/pics/hi16-action-symlink.xcf differ diff --git a/kdirstat/pics/hi32-action-symlink.png b/kdirstat/pics/hi32-action-symlink.png new file mode 100644 index 0000000..1f3248a Binary files /dev/null and b/kdirstat/pics/hi32-action-symlink.png differ diff --git a/kdirstat/pics/hi48-action-symlink.png b/kdirstat/pics/hi48-action-symlink.png new file mode 100644 index 0000000..911bff4 Binary files /dev/null and b/kdirstat/pics/hi48-action-symlink.png differ diff --git a/kdirstat/pics/hi48-action-symlink.xcf b/kdirstat/pics/hi48-action-symlink.xcf new file mode 100644 index 0000000..e944b60 Binary files /dev/null and b/kdirstat/pics/hi48-action-symlink.xcf differ diff --git a/kdirstat/pics/lo16-action-symlink.png b/kdirstat/pics/lo16-action-symlink.png new file mode 100644 index 0000000..ade0d48 Binary files /dev/null and b/kdirstat/pics/lo16-action-symlink.png differ diff --git a/po/Makefile.am b/po/Makefile.am new file mode 100644 index 0000000..50aeed8 --- /dev/null +++ b/po/Makefile.am @@ -0,0 +1,6 @@ +####### kdevelop will overwrite this part!!! (begin)########## + + +####### kdevelop will overwrite this part!!! (end)############ +POFILES = AUTO + diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..c1f1929 --- /dev/null +++ b/po/de.po @@ -0,0 +1,963 @@ +# translation of de.po to Deutsch +# Copyright (C) 2003 Free Software Foundation, Inc. +# Christoph Eckert , 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