summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS3
-rw-r--r--COPYING340
-rw-r--r--ChangeLog180
-rw-r--r--INSTALL55
-rw-r--r--SConstruct82
-rw-r--r--TODO14
-rw-r--r--VERSION1
-rw-r--r--admin/detect_uds_hidden.diff29
-rw-r--r--admin/generic.py635
-rw-r--r--admin/kde.py839
-rw-r--r--debian/changelog189
-rw-r--r--debian/compat1
-rw-r--r--debian/control18
-rw-r--r--debian/copyright29
-rwxr-xr-xdebian/rules37
-rw-r--r--doc/en/index.docbook185
-rw-r--r--doc/en/screenshot.pngbin0 -> 26739 bytes
-rw-r--r--po/de.po244
-rw-r--r--po/fr.po244
-rw-r--r--po/kio_locate.pot241
-rwxr-xr-xpo/messages.sh69
-rw-r--r--src/SConscript40
-rw-r--r--src/kio_locate.cpp1035
-rw-r--r--src/kio_locate.h273
-rw-r--r--src/kio_locate.kcfg62
-rw-r--r--src/klocateconfig.kcfgc6
-rw-r--r--src/klocateconfigfilterwidget.ui105
-rw-r--r--src/klocateconfiglocatewidget.ui211
-rw-r--r--src/klocateconfigwidget.ui391
-rw-r--r--src/locate.desktop8
-rw-r--r--src/locate.protocol18
-rw-r--r--src/locater.cpp131
-rw-r--r--src/locater.h103
-rw-r--r--src/locater.protocol15
-rw-r--r--src/pattern.cpp124
-rw-r--r--src/pattern.h114
-rw-r--r--src/rlocate.protocol18
-rw-r--r--templates/cpp22
-rw-r--r--templates/h22
39 files changed, 6133 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..034349c
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Tobi Vollebregt <tobivollebregt@gmail.com>
+Armin Straub <linux@arminstraub.de>
+Michael Schuerig <schuerig@acm.org>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..c13faf0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..8ee97d8
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,180 @@
+kio-locate (0.4.5) 2006-02-05 -- Armin Straub
+
+ * Search hits with non-ascii characters in the file name always showed up
+ with invalid size/owner/group information (fixed by Johan Billing).
+ * kio-locate should now compile with gcc-4.1_beta (fixed by Jan Jitse
+ Venselaar).
+ * Updated to bksys 1.5.1.
+
+
+kio-locate (0.4.4) 2005-10-19 -- Armin Straub
+
+ + Warn if locate (or whatever is selected) is not installed (suggested
+ by Axel K. Braun).
+ * Use slocate and rlocate as default when available (suggested by Nicolas
+ Degand).
+ * Closed a bug preventing the display of items having the same prefix
+ (reported by Takis).
+
+
+kio-locate (0.4.3) 2005-09-15 -- Armin Straub
+
+ * Made the config dialogs more verbose.
+ * Replaced the previous screenshot (105K) with a similar one (27K)
+ significantly reducing the package size.
+ + Added a (crude?) German translation.
+
+
+kio-locate (0.4.2tvo0.2) 2005-08-21 -- Tobi Vollebregt
+
+ * Hit counting is now recursive.
+ * Fixed a packaging bug which caused the helpfiles to be inaccessable
+ if installed using the .deb file.
+ * Updated to the newest version of bksys.
+
+
+kio-locate (0.4.2tvo0.1) 2005-07-14 -- Tobi Vollebregt
+
+ + Directory collapsing if pattern matches the directory part of a path.
+ + Entries for searching within directories and entries for plain
+ browsing of the directories.
+ + Added full wildcard support in all patterns (after discussion this seemed
+ to be more appropriate than full regexp support for `locate:').
+ + Added full regexp support in the filtering patterns with the `rlocate:'
+ protocol.
+ + A case sensitivity setting in the config page.
+ + A `config succesfully updated' or `config unchanged' message is
+ displayed after closing the config dialog.
+ + Different icons for normal and collapsed directories.
+ + Configurable RegExp filtering, using a white list and a black list.
+ * Fixed searches within a directory other than root (/).
+ * Reduced flickering when listing results.
+ * Number of hits displayed in front of a directory, is now exactly
+ the number of entries you'll see after you click that entry.
+ * `locater:help' now actually works.
+ * Updated to the newest version of bksys.
+
+
+kio-locate (0.4.2) 2005-05-22 -- Armin Straub
+
+ * Removed stupid bug inverting case sensitivity.
+
+
+kio-locate (0.4.1) 2005-05-21 -- Armin Straub
+
+ + Added a config page for settings related to locate (the real
+ one :-)). You can e.g. choose slocate or other replacements now.
+ * For compatibility -i is used instead of --ignore-case when calling
+ locate.
+ * Case Sensitivity is now chosen for every part of the search
+ pattern on its own.
+
+
+kio-locate (0.4.0) 2005-04-10 -- Armin Straub
+
+ + Using scons and bksys instead of autotools and the like. This
+ saves both - a lot of space (around 500kb) and lots of time
+ when developing (thanks to Nagy Thomas for his help).
+ Read INSTALL for a quick guide.
+ + Added the possibility to configure some aspects of kio-locate
+ by envoking locater:config. (More to come...)
+ * Use the locater protocol which uses standard Urls for more
+ complex tasks and keep the locate protocol for simple queries.
+ * Don't use ilocate and clocate anymore. (Check the settings for
+ configuring kio-locate's case sensitivity.)
+ * Some minor enhancements and some new bugs :-)
+
+
+kio-locate (0.3.4) 2005-01-22 -- Armin Straub
+
+ * Removed yet another bug preventing kio-locate from compiling when using
+ KDE 3.2 (thanks to Sergio Cambra).
+
+
+kio-locate (0.3.3) 2005-01-21 -- Armin Straub
+
+ * Removed small bug preventing kio-locate from compiling on some systems
+ (thanks to Francesco di Cugno who also provided a package for Slackware).
+
+
+kio-locate (0.3.2) 2005-01-17 -- Armin Straub
+
+ + Several hits in one directory are now grouped together. For code and
+ ideas lots of thanks to Fred Schaettgen.
+ * The search process should be a bit faster as only those files are
+ checked for existence that are displayed (thanks to Fred Schaettgen).
+
+
+kio-locate (0.3.1) 2004-12-10 -- Armin Straub
+
+ * The locate protocol no more does only case sensitive searches, but
+ searches case insensitive by default and switches to case sensitivity if
+ the search string contains upper case characters.
+ + Added the protocol clocate for case sensitive searches.
+ + Added a locate search to konquerors list of web shortcuts. This enables
+ you to select locate as the default search engine in konqueror. (Whenever
+ you enter a nonsense url then, konqueror will use locate to search for
+ this "nonsense".)
+
+
+kio-locate (0.3.0) 2004-11-01 -- Armin Straub
+
+ * Filtering by regular expressions is now possible:
+ You can use "locate:pattern [!]regexp ..." now. pattern uses standard locate
+ syntax followed by regexps that may be preceded by ! meaning that they
+ shouldn't match.
+
+
+kio-locate (0.2.4) 2004-10-26 -- Armin Straub
+
+ * Removed bugs in kio-locate.spec used to generate rpm's (thanks to Sami
+ Vento).
+
+
+kio-locate (0.2.3) 2004-10-25 -- Armin Straub
+
+ * Taking current locale into account, so kio-locate won't change non-latin1
+ encoded file names (thanks to Jakub Stachowski).
+ + Added kio-locate.spec so that you can build rpms by just typing
+ rpmbuild -ta --target=i686 kio-locate_$VERSION.tar.gz (thanks to Sami
+ Vento).
+
+
+kio-locate (0.2.2) 2004-10-24 -- Armin Straub
+
+ + Added the protocol ilocate for case insensitive searches.
+ + Interpret ~/ and ~user/ in a search (expand just as the shell normally
+ does).
+ + Detection of konquerors autocompletion.
+
+
+kio-locate (0.2.1) 2004-10-22 -- Armin Straub
+
+ + Added french translation (thanks to Laurent Rathle).
+ * Included stdlib.h correctly (previously preventing kio-locate to compile on
+ some machines).
+
+
+kio-locate (0.2.0) 2004-10-15 -- Armin Straub
+
+ * Complete rewrite.
+ * Works with KDE 3.3.
+ + Displays detailed information in Konqueror (not just filenames).
+ + Enabled patterns like the ones used for locate.
+
+
+kio-locate (0.1.1-1) -- Michael Schuerig
+
+ * Corrected URL prefix ("file:" instead of "file:/").
+ * Update admin dir.
+
+
+kio-locate (0.1-2) -- Michael Schuerig
+
+ * Rebuild for KDE 3.1.
+
+
+kio-locate (0.1-1) -- Michael Schuerig
+
+ * Initial Release.
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..5053a25
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,55 @@
+QUICKSTART
+
+kio-locate uses scons for configuring and building. In general
+it should suffice to execute (if you have scons installed):
+
+$ scons configure
+$ scons
+$ sudo scons install
+
+If you don't have scons installed, you can use the stripped
+down version shipping with kio-locate. This can be found in the
+file scons-mini.tar.bz2 and has to be unpacked.
+
+$ tar xjf scons-mini.tar.bz2
+$ python scons.py configure
+$ python scons.py
+$ sudo python scons.py install
+
+As you can see the command "python scons.py" replaces executing
+"scons" if you don't have that installed. In the following you
+have to bear this in mind.
+
+
+SPECIAL CONFIGURING
+
+On some systems, it might be necessary to configure the project
+using scons configure qtincludes=path1 kdeincludes=path2
+like this:
+$ scons configure qtincludes=/usr/include/qt3/include \
+> kdeincludes=/usr/lib/kde3/include
+When in doubt, use scons --help or scons -h to display the options.
+
+As when using ./configure you can specify using prefix=... where to
+install the package.
+$ scons configure prefix=/usr
+
+To enable debug mode you can use:
+$ scons configure debug=1
+
+To clean the project:
+$ scons -c
+
+And to uninstall kio-locate:
+$ scons -c install
+
+
+NOTE THIS
+
+This is just a very overview about what you can do.
+
+If you encounter problems, please post them (or better their solutions)
+to me, so that I can include them into this guide.
+
+Armin Straub
+linux@arminstraub.de
diff --git a/SConstruct b/SConstruct
new file mode 100644
index 0000000..dd1e218
--- /dev/null
+++ b/SConstruct
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+# kio-locate
+#
+# Copyright (C) 2005 by Tobi Vollebregt
+# tobivollebregt@gmail.com
+#
+# Thanks to Google's Summer Of Code Program!
+#
+# Copyright (C) 2005 by Armin Straub
+# linux@arminstraub.de
+#
+# Adapted from the example shipping with bksys.
+# Thomas Nagy, 2004, 2005
+# Thanks for this great tool!
+
+"""
+help -> scons -h
+compile -> scons
+clean -> scons -c
+install -> scons install
+uninstall -> scons -c install
+configure -> scons configure prefix=/tmp/ita debug=full extraincludes=/usr/local/include:/tmp/include prefix=/usr/local
+
+Run from a subdirectory -> scons -u
+The variables are saved automatically after the first run (look at cache/kde.cache.py, ..)
+"""
+
+###################################################################
+# LOAD THE ENVIRONMENT AND SET UP THE TOOLS
+###################################################################
+
+## Load the builders in config
+env = Environment( tools=['default', 'generic', 'kde'], toolpath=['./admin'])
+
+# Set the build directory so we can do "rm -rf build" to clean up.
+BuildDir('build/src', 'src')
+
+env.KDEuse("environ")
+#env.KDEuse("environ rpath lang_qt thread nohelp")
+
+# Add -DHAVE_UDS_HIDDEN if we detected the UDS_HIDDEN patch.
+if '1' in env['HAVE_UDS_HIDDEN']:
+ env.Append(CPPFLAGS = ['-DHAVE_UDS_HIDDEN'])
+
+###################################################################
+# SCRIPTS FOR BUILDING THE TARGETS
+###################################################################
+
+## target processing is done in the subdirectories
+env.subdirs('build/src')
+
+############################
+## Process the documentation
+############################
+
+## Use a distinct environment
+myenv=env.Copy()
+
+## Define this to enable docbook file dependency tracking
+#myenv['i_am_a_documentation_writer']=1
+
+# This shouldn't be needed, but it works around a (possible) bug in bksys 1.5.2.rc1.
+# myenv['_BUILDDIR_']='build'
+
+## Use docfolder for each documentation directory
+## The parameters of docfolder are: documentation dir, language code, app name
+myenv.docfolder('doc/en/', 'en', 'kio-locate/')
+#myenv.docfolder('doc/fr/', 'fr', 'kio-locate/')
+
+############################
+## Process the translations
+############################
+
+## They are usually located in the po/ directory
+## We use myenv here because it has the _BUILDDIR_ workaround. See above.
+myenv.KDElang('po/', 'kio-locate')
+
+###################################################################
+# CONVENIENCE FUNCTIONS TO EMULATE 'make dist' and 'make distclean'
+###################################################################
+
+env.dist('kio-locate')
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..75b6edb
--- /dev/null
+++ b/TODO
@@ -0,0 +1,14 @@
+Short Term
+
+Mid Term
++ Add kio-locate to kde-extragear.
++ Translations needed. Contact Håvard Dahle for Norwegian translation.
++ Support searches on remote servers via ssh. A possible search could
+ then look like "locate://username@server:port pattern". (Suggested
+ by Ferdinand Gassauer)
+
+Ideas
++ Some kind of first start screen?
++ Check out beagle-query which was said to behave similar
+ to command line locate. (Benjamin Kudria)
++ Use other backends like kat?
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..0bfccb0
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.4.5
diff --git a/admin/detect_uds_hidden.diff b/admin/detect_uds_hidden.diff
new file mode 100644
index 0000000..254de80
--- /dev/null
+++ b/admin/detect_uds_hidden.diff
@@ -0,0 +1,29 @@
+Only in kio-locate/admin/: .arch-ids
+diff -ur bksys-1.5.1.pre4/admin/kde.py kio-locate/admin/kde.py
+--- bksys-1.5.1.pre4/admin/kde.py 2005-08-16 23:16:32.000000000 +0200
++++ kio-locate/admin/kde.py 2005-08-17 12:27:49.000000000 +0200
+@@ -242,6 +242,15 @@
+ qtlibs=qtdir+"/lib"+libsuffix
+ env['QTLIBPATH']=qtlibs
+
++ ## check if KDE has the UDS_HIDDEN patch
++ print "Checking KDE for UDS_HIDDEN : ",
++ if 'UDS_HIDDEN' in os.popen('cat ' + env['KDEINCLUDEPATH'] + '/kio/global.h').read():
++ env['HAVE_UDS_HIDDEN']='1'
++ p('GREEN', 'yes')
++ else:
++ env['HAVE_UDS_HIDDEN']='0'
++ p('YELLOW', 'no')
++
+ def generate(env):
+ """"Set up the qt and kde environment and builders - the moc part is difficult to understand """
+
+@@ -304,7 +313,7 @@
+ ('KDELOCALE', ''), ('KDEDOC', ''), ('KDEKCFG', ''),
+ ('KDEXDG', ''), ('KDEXDGDIR', ''), ('KDEMENU', ''),
+ ('KDEMIME', ''), ('KDEICONS', ''), ('KDESERV', ''),
+- ('KDESERVTYPES', ''), ('KDEAPPS', ''),
++ ('KDESERVTYPES', ''), ('KDEAPPS', ''), ('HAVE_UDS_HIDDEN', ''),
+ )
+ opts.Update(env)
+
diff --git a/admin/generic.py b/admin/generic.py
new file mode 100644
index 0000000..0837fb9
--- /dev/null
+++ b/admin/generic.py
@@ -0,0 +1,635 @@
+## Thomas Nagy, 2005
+""" Run scons -h to display the associated help, or look below """
+
+import os, re, types, sys, string, shutil, stat, glob
+import SCons.Defaults
+import SCons.Tool
+import SCons.Util
+from SCons.Script.SConscript import SConsEnvironment
+from SCons.Options import Options, PathOption
+
+def getreldir(lenv):
+ cwd=os.getcwd()
+ root=SCons.Node.FS.default_fs.Dir('#').abspath
+ return cwd.replace(root,'').lstrip('/')
+
+def dist(env, appname, version=None):
+ ### To make a tarball of your masterpiece, use 'scons dist'
+ import os
+ if 'dist' in sys.argv:
+ if not version: VERSION=os.popen("cat VERSION").read().rstrip()
+ else: VERSION=version
+ FOLDER = appname+'-'+VERSION
+ TMPFOLD = ".tmp"+FOLDER
+ ARCHIVE = FOLDER+'.tar.bz2'
+
+ ## check if the temporary directory already exists
+ os.popen('rm -rf %s %s %s' % (FOLDER, TMPFOLD, ARCHIVE) )
+
+ ## create a temporary directory
+ startdir = os.getcwd()
+
+ os.popen("mkdir -p "+TMPFOLD)
+ os.popen("cp -R * "+TMPFOLD)
+ os.popen("mv "+TMPFOLD+" "+FOLDER)
+
+ ## remove scons-local if it is unpacked
+ os.popen("rm -rf "+FOLDER+"/scons "+FOLDER+"/sconsign "+FOLDER+"/scons-local-0.96.1")
+
+ ## remove our object files first
+ os.popen("find "+FOLDER+" -name \"cache\" | xargs rm -rf")
+ os.popen("find "+FOLDER+" -name \"build\" | xargs rm -rf")
+ os.popen("find "+FOLDER+" -name \"*.pyc\" | xargs rm -f")
+
+ ## CVS cleanup
+ os.popen("find "+FOLDER+" -name \"CVS\" | xargs rm -rf")
+ os.popen("find "+FOLDER+" -name \".cvsignore\" | xargs rm -rf")
+
+ ## Subversion cleanup
+ os.popen("find %s -name .svn -type d | xargs rm -rf" % FOLDER)
+
+ ## GNU Arch cleanup
+ os.popen("find "+FOLDER+" -name \"{arch}\" | xargs rm -rf")
+ os.popen("find "+FOLDER+" -name \".arch-i*\" | xargs rm -rf")
+
+ ## Create the tarball (coloured output)
+ print "\033[92m"+"Writing archive "+ARCHIVE+"\033[0m"
+ os.popen("tar cjf "+ARCHIVE+" "+FOLDER)
+
+ ## Remove the temporary directory
+ os.popen('rm -rf '+FOLDER)
+ env.Exit(0)
+
+ if 'distclean' in sys.argv:
+ ## Remove the cache directory
+ import os, shutil
+ if os.path.isdir(env['CACHEDIR']): shutil.rmtree(env['CACHEDIR'])
+ os.popen("find . -name \"*.pyc\" | xargs rm -rf")
+ env.Exit(0)
+
+colors= {
+'BOLD' :"\033[1m",
+'RED' :"\033[91m",
+'GREEN' :"\033[92m",
+'YELLOW':"\033[1m", #"\033[93m" # unreadable on white backgrounds
+'CYAN' :"\033[96m",
+'NORMAL':"\033[0m",
+}
+
+def pprint(env, col, str, label=''):
+ if env.has_key('NOCOLORS'):
+ print "%s %s" % (str, label)
+ return
+ try: mycol=colors[col]
+ except: mycol=''
+ print "%s%s%s %s" % (mycol, str, colors['NORMAL'], label)
+
+class genobj:
+ def __init__(self, val, env):
+ if not val in "program shlib kioslave staticlib".split():
+ print "unknown genobj given: "+val
+ env.Exit(1)
+
+ self.type = val
+ self.orenv = env
+ self.env = None
+ self.executed = 0
+
+ self.target=''
+ self.src=None
+
+ self.cxxflags=''
+ self.cflags=''
+ self.includes=''
+
+ self.linkflags=''
+ self.libpaths=''
+ self.libs=''
+
+ # vars used by shlibs
+ self.vnum=''
+ self.libprefix=''
+
+ # a directory where to install the targets (optional)
+ self.instdir=''
+
+ # change the working directory before reading the targets
+ self.chdir=''
+
+ # unix permissions
+ self.perms=''
+
+ # these members are private
+ self.chdir_lock=None
+ self.dirprefix='./'
+ self.old_os_dir=''
+ self.old_fs_dir=''
+ self.p_local_shlibs=[]
+ self.p_local_staticlibs=[]
+ self.p_global_shlibs=[]
+
+ self.p_localsource=None
+ self.p_localtarget=None
+
+ # work directory
+ self.workdir_lock=None
+ self.orig_fs_dir=SCons.Node.FS.default_fs.getcwd()
+ self.not_orig_fs_dir=''
+ self.not_orig_os_dir=''
+
+ if not env.has_key('USE_THE_FORCE_LUKE'): env['USE_THE_FORCE_LUKE']=[self]
+ else: env['USE_THE_FORCE_LUKE'].append(self)
+
+ def joinpath(self, val):
+ dir=self.dirprefix
+
+ thing=self.orenv.make_list(val)
+ files=[]
+ bdir="./"
+ if self.orenv.has_key('_BUILDDIR_'): bdir=self.orenv['_BUILDDIR_']
+
+ for v in thing:
+ files.append( self.orenv.join(bdir, dir, v) )
+
+ #for f in files: print f
+ #print "\n"
+ return files
+
+ # a list of paths, with absolute and relative ones
+ def fixpath(self, val):
+ dir=self.dirprefix
+
+ thing=self.orenv.make_list(val)
+ ret=[]
+ bdir="./"
+ if self.orenv.has_key('_BUILDDIR_'): bdir=self.orenv['_BUILDDIR_']
+ for v in thing:
+ if v[:2] == "./" or v[:3] == "../":
+ ret.append( self.orenv.join(bdir, dir, v) )
+ elif v[:1] == "#" or v[:1] == "/":
+ ret.append( v )
+ else:
+ ret.append( self.orenv.join(bdir, dir, v) )
+ return ret
+
+ def lockworkdir(self):
+ if self.workdir_lock: return
+ self.workdir_lock=1
+ self.not_orig_fs_dir=SCons.Node.FS.default_fs.getcwd()
+ self.not_orig_os_dir=os.getcwd()
+ SCons.Node.FS.default_fs.chdir( self.orig_fs_dir, change_os_dir=1)
+
+ def unlockworkdir(self):
+ if not self.workdir_lock: return
+ SCons.Node.FS.default_fs.chdir( self.not_orig_fs_dir, change_os_dir=0)
+ os.chdir(self.not_orig_os_dir)
+ self.workdir_lock=None
+
+ def lockchdir(self):
+ if not self.chdir: return
+ if self.chdir_lock: return
+ self.chdir_lock=1
+ SConfFS=SCons.Node.FS.default_fs
+ self.old_fs_dir=SConfFS.getcwd()
+ self.old_os_dir=os.getcwd()
+ SConfFS.chdir( SConfFS.Dir('#/'+self.chdir), change_os_dir=1)
+
+ def unlockchdir(self):
+ if not self.chdir: return
+ if not self.chdir_lock: return
+ SCons.Node.FS.default_fs.chdir(self.old_fs_dir, change_os_dir=0)
+ os.chdir(self.old_os_dir)
+ self.chdir_lock=None
+
+ def execute(self):
+ if self.executed: return
+
+ self.lockchdir()
+
+ if self.orenv.has_key('DUMPCONFIG'):
+ print self.xml()
+ self.unlockchdir()
+ self.executed=1
+ return
+
+ self.env = self.orenv.Copy()
+
+ if not self.p_localtarget: self.p_localtarget = self.joinpath(self.target)
+ if not self.p_localsource: self.p_localsource = self.joinpath(self.src)
+
+ if (not self.src or len(self.src) == 0) and not self.p_localsource:
+ self.env.pprint('RED',"no source file given to object - self.src")
+ self.env.Exit(1)
+ if not self.target:
+ self.env.pprint('RED',"no target given to object - self.target")
+ self.env.Exit(1)
+ if not self.env.has_key('nosmart_includes'): self.env.AppendUnique(CPPPATH=['./'])
+ if self.type == "kioslave": self.libprefix=''
+
+ if len(self.includes)>0: self.env.AppendUnique(CPPPATH=self.fixpath(self.includes))
+ if len(self.cxxflags)>0: self.env.AppendUnique(CXXFLAGS=self.env.make_list(self.cxxflags))
+ if len(self.cflags)>0: self.env.AppendUnique(CCFLAGS=self.env.make_list(self.cflags))
+
+ llist=self.env.make_list(self.libs)
+ lext=['.so', '.la']
+ sext='.a'.split()
+ for l in llist:
+ sal=SCons.Util.splitext(l)
+ if len(sal)>1:
+ if sal[1] in lext: self.p_local_shlibs.append(self.fixpath(sal[0]+'.so')[0])
+ elif sal[1] in sext: self.p_local_staticlibs.append(sal[0]+'.a')
+ else: self.p_global_shlibs.append(l)
+
+ if len(self.p_global_shlibs)>0: self.env.AppendUnique(LIBS=self.p_global_shlibs)
+ if len(self.libpaths)>0: self.env.PrependUnique(LIBPATH=self.fixpath(self.libpaths))
+ if len(self.linkflags)>0: self.env.PrependUnique(LINKFLAGS=self.env.make_list(self.linkflags))
+ if len(self.p_local_shlibs)>0:
+ self.env.link_local_shlib(self.p_local_shlibs)
+ if len(self.p_local_staticlibs)>0:
+ self.env.link_local_staticlib(self.p_local_staticlibs)
+
+ # the target to return - no more self.env modification is allowed after this part
+ ret=None
+ if self.type=='shlib' or self.type=='kioslave':
+ ret=self.env.bksys_shlib(self.p_localtarget, self.p_localsource, self.instdir,
+ self.libprefix, self.vnum)
+ elif self.type=='program':
+ ret=self.env.Program(self.p_localtarget, self.p_localsource)
+ if not self.env.has_key('NOAUTOINSTALL'):
+ ins=self.env.bksys_install(self.instdir, ret)
+ if self.perms: self.env.AddPostAction(ins, self.env.Chmod(ins, self.perms))
+ elif self.type=='staticlib':
+ ret=self.env.StaticLibrary(self.p_localtarget, self.p_localsource)
+
+ # we link the program against a shared library made locally, add the dependency
+ if len(self.p_local_shlibs)>0:
+ if ret: self.env.Depends( ret, self.p_local_shlibs )
+ if len(self.p_local_staticlibs)>0:
+ if ret: self.env.Depends( ret, self.p_local_staticlibs )
+
+ self.unlockchdir()
+ self.executed=1
+
+## Copy function that honors symlinks
+def copy_bksys(dest, source, env):
+ if os.path.islink(source):
+ #print "symlinking "+source+" "+dest
+ if os.path.islink(dest):
+ os.unlink(dest)
+ os.symlink(os.readlink(source), dest)
+ else:
+ shutil.copy2(source, dest)
+ st=os.stat(source)
+ os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+ return 0
+
+## Return a list of things
+def make_list(env, s):
+ if type(s) is types.ListType: return s
+ else:
+ try: return s.split()
+ except AttributeError: return s
+
+def join(lenv, s1, s2, s3=None, s4=None):
+ if s4 and s3: return lenv.join(s1, s2, lenv.join(s3, s4))
+ if s3 and s2: return lenv.join(s1, lenv.join(s2, s3))
+ elif not s2: return s1
+ # having s1, s2
+ #print "path1 is "+s1+" path2 is "+s2+" "+os.path.join(s1,string.lstrip(s2,'/'))
+ if not s1: s1="/"
+ return os.path.join(s1,string.lstrip(s2,'/'))
+
+def exists(env):
+ return true
+
+def generate(env):
+ ## Bksys requires scons 0.96
+ env.EnsureSConsVersion(0, 96)
+
+ SConsEnvironment.pprint = pprint
+ SConsEnvironment.make_list = make_list
+ SConsEnvironment.join = join
+ SConsEnvironment.dist = dist
+ SConsEnvironment.getreldir = getreldir
+
+ env['HELP']=0
+ if '--help' in sys.argv or '-h' in sys.argv or 'help' in sys.argv: env['HELP']=1
+ if env['HELP']:
+ p=env.pprint
+ p('BOLD','*** Instructions ***')
+ p('BOLD','--------------------')
+ p('BOLD','* scons ','to compile')
+ p('BOLD','* scons -j4 ','to compile with several instances')
+ p('BOLD','* scons install ','to compile and install')
+ p('BOLD','* scons -c install','to uninstall')
+ p('BOLD','\n*** Generic options ***')
+ p('BOLD','--------------------')
+ p('BOLD','* debug ','debug=1 (-g) or debug=full (-g3, slower) else use environment CXXFLAGS, or -O2 by default')
+ p('BOLD','* prefix ','the installation path')
+ p('BOLD','* extraincludes','a list of paths separated by ":"')
+ p('BOLD','* scons configure debug=full prefix=/usr/local extraincludes=/tmp/include:/usr/local')
+ p('BOLD','* scons install prefix=/opt/local DESTDIR=/tmp/blah\n')
+ return
+
+ ## Global cache directory
+ # Put all project files in it so a rm -rf cache will clean up the config
+ if not env.has_key('CACHEDIR'): env['CACHEDIR'] = env.join(os.getcwd(),'/cache/')
+ if not os.path.isdir(env['CACHEDIR']): os.mkdir(env['CACHEDIR'])
+
+ ## SCons cache directory
+ # This avoids recompiling the same files over and over again:
+ # very handy when working with cvs
+ if os.getuid() != 0: env.CacheDir(os.getcwd()+'/cache/objects')
+
+ # Avoid spreading .sconsign files everywhere - keep this line
+ env.SConsignFile(env['CACHEDIR']+'/scons_signatures')
+
+ def makeHashTable(args):
+ table = { }
+ for arg in args:
+ if len(arg) > 1:
+ lst=arg.split('=')
+ if len(lst) < 2: continue
+ key=lst[0]
+ value=lst[1]
+ if len(key) > 0 and len(value) >0: table[key] = value
+ return table
+
+ env['ARGS']=makeHashTable(sys.argv)
+
+ SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod, lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
+
+ ## Special trick for installing rpms ...
+ env['DESTDIR']=''
+ if 'install' in sys.argv:
+ dd=''
+ if os.environ.has_key('DESTDIR'): dd=os.environ['DESTDIR']
+ if not dd:
+ if env['ARGS'] and env['ARGS'].has_key('DESTDIR'): dd=env['ARGS']['DESTDIR']
+ if dd:
+ env['DESTDIR']=dd
+ env.pprint('CYAN','** Enabling DESTDIR for the project ** ',env['DESTDIR'])
+
+ ## install symlinks for shared libraries properly
+ env['INSTALL'] = copy_bksys
+
+ ## Use the same extension .o for all object files
+ env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
+
+ ## no colors
+ if os.environ.has_key('NOCOLORS'): env['NOCOLORS']=1
+
+ ## load the options
+ cachefile=env['CACHEDIR']+'generic.cache.py'
+ opts = Options(cachefile)
+ opts.AddOptions(
+ ( 'GENCCFLAGS', 'C flags' ),
+ ( 'GENCXXFLAGS', 'debug level for the project : full or just anything' ),
+ ( 'GENLINKFLAGS', 'additional link flags' ),
+ ( 'PREFIX', 'prefix for installation' ),
+ ( 'EXTRAINCLUDES', 'extra include paths for the project' ),
+ ( 'ISCONFIGURED', 'is the project configured' ),
+ )
+ opts.Update(env)
+
+ # Use this to avoid an error message 'how to make target configure ?'
+ env.Alias('configure', None)
+
+ # Check if the following command line arguments have been given
+ # and set a flag in the environment to show whether or not it was
+ # given.
+ if 'install' in sys.argv: env['_INSTALL']=1
+ else: env['_INSTALL']=0
+ if 'configure' in sys.argv: env['_CONFIGURE']=1
+ else: env['_CONFIGURE']=0
+
+ # Configure the environment if needed
+ if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('ISCONFIGURED')):
+ # be paranoid, unset existing variables
+ for var in ['GENCXXFLAGS', 'GENCCFLAGS', 'GENLINKFLAGS', 'PREFIX', 'EXTRAINCLUDES', 'ISCONFIGURED', 'EXTRAINCLUDES']:
+ if env.has_key(var): env.__delitem__(var)
+
+ if env['ARGS'].get('debug', None):
+ debuglevel = env['ARGS'].get('debug', None)
+ env.pprint('CYAN','** Enabling debug for the project **')
+ if (debuglevel == "full"): env['GENCXXFLAGS'] = ['-DDEBUG', '-g3', '-Wall']
+ else: env['GENCXXFLAGS'] = ['-DDEBUG', '-g', '-Wall']
+ else:
+ if os.environ.has_key('CXXFLAGS'):
+ # user-defined flags (gentooers will be elighted)
+ env['GENCXXFLAGS'] = SCons.Util.CLVar( os.environ['CXXFLAGS'] )
+ env.Append( GENCXXFLAGS = ['-DNDEBUG', '-DNO_DEBUG'] )
+ else:
+ env.Append(GENCXXFLAGS = ['-O2', '-DNDEBUG', '-DNO_DEBUG'])
+
+ if os.environ.has_key('CFLAGS'): env['GENCCFLAGS'] = SCons.Util.CLVar( os.environ['CFLAGS'] )
+
+ ## FreeBSD settings (contributed by will at freebsd dot org)
+ if os.uname()[0] == "FreeBSD":
+ if os.environ.has_key('PTHREAD_LIBS'):
+ env.AppendUnique( GENLINKFLAGS = SCons.Util.CLVar( os.environ['PTHREAD_LIBS'] ) )
+ else:
+ syspf = os.popen('/sbin/sysctl kern.osreldate')
+ osreldate = int(syspf.read().split()[1])
+ syspf.close()
+ if osreldate < 500016:
+ env.AppendUnique( GENLINKFLAGS = ['-pthread'])
+ env.AppendUnique( GENCXXFLAGS = ['-D_THREAD_SAFE'])
+ elif osreldate < 502102:
+ env.AppendUnique( GENLINKFLAGS = ['-lc_r'])
+ env.AppendUnique( GENCXXFLAGS = ['-D_THREAD_SAFE'])
+ else:
+ env.AppendUnique( GENLINKFLAGS = ['-pthread'])
+
+ # User-specified prefix
+ if env['ARGS'].has_key('prefix'):
+ env['PREFIX'] = os.path.abspath( env['ARGS'].get('prefix', '') )
+ env.pprint('CYAN','** installation prefix for the project set to:',env['PREFIX'])
+
+ # User-specified include paths
+ env['EXTRAINCLUDES'] = env['ARGS'].get('extraincludes', None)
+ if env['EXTRAINCLUDES']:
+ env.pprint('CYAN','** extra include paths for the project set to:',env['EXTRAINCLUDES'])
+
+ env['ISCONFIGURED']=1
+
+ # And finally save the options in the cache
+ opts.Save(cachefile, env)
+
+ def bksys_install(lenv, subdir, files, destfile=None, perms=None):
+ """ Install files on 'scons install' """
+ if not env['_INSTALL']: return
+ basedir = env['DESTDIR']
+ install_list=None
+ if not destfile: install_list = env.Install(lenv.join(basedir,subdir), lenv.make_list(files))
+ elif subdir: install_list = env.InstallAs(lenv.join(basedir,subdir,destfile), lenv.make_list(files))
+ else: install_list = env.InstallAs(lenv.join(basedir,destfile), lenv.make_list(files))
+ if perms and install_list: lenv.AddPostAction(install_list, lenv.Chmod(install_list, perms))
+ env.Alias('install', install_list)
+ return install_list
+
+ def build_la_file(target, source, env):
+ """ Writes a .la file, used by libtool """
+ dest=open(target[0].path, 'w')
+ sname=source[0].name
+ dest.write("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by bksys)\n#\n#\n")
+ if len(env['BKSYS_VNUM'])>0:
+ vnum=env['BKSYS_VNUM']
+ nums=vnum.split('.')
+ src=source[0].name
+ name = src.split('so.')[0] + 'so'
+ strn = src+" "+name+"."+str(nums[0])+" "+name
+ dest.write("dlname='%s'\n" % (name+'.'+str(nums[0])) )
+ dest.write("library_names='%s'\n" % (strn) )
+ else:
+ dest.write("dlname='%s'\n" % sname)
+ dest.write("library_names='%s %s %s'\n" % (sname, sname, sname) )
+ dest.write("old_library=''\ndependency_libs=''\ncurrent=0\n")
+ dest.write("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n")
+ dest.write("dlopen=''\ndlpreopen=''\n")
+ dest.write("libdir='%s'" % env['BKSYS_DESTDIR'])
+ dest.close()
+ return 0
+
+ def string_la_file(target, source, env):
+ print "building '%s' from '%s'" % (target[0].name, source[0].name)
+ la_file = env.Action(build_la_file, string_la_file, 'BKSYS_VNUM', 'BKSYS_DESTDIR')
+ env['BUILDERS']['LaFile'] = env.Builder(action=la_file,suffix='.la',src_suffix=env['SHLIBSUFFIX'])
+
+ ## Function for building shared libraries
+ def bksys_shlib(lenv, ntarget, source, libdir, libprefix='lib', vnum='', noinst=None):
+ """ Install a shared library.
+
+ Installs a shared library, with or without a version number, and create a
+ .la file for use by libtool.
+
+ If library version numbering is to be used, the version number
+ should be passed as a period-delimited version number (e.g.
+ vnum = '1.2.3'). This causes the library to be installed
+ with its full version number, and with symlinks pointing to it.
+
+ For example, for libfoo version 1.2.3, install the file
+ libfoo.so.1.2.3, and create symlinks libfoo.so and
+ libfoo.so.1 that point to it.
+ """
+ # parameter can be a list
+ if type(ntarget) is types.ListType: target=ntarget[0]
+ else: target=ntarget
+
+ thisenv = lenv.Copy() # copying an existing environment is cheap
+ thisenv['BKSYS_DESTDIR']=libdir
+ thisenv['BKSYS_VNUM']=vnum
+ thisenv['SHLIBPREFIX']=libprefix
+
+ if len(vnum)>0:
+ thisenv['SHLIBSUFFIX']='.so.'+vnum
+ thisenv.Depends(target, thisenv.Value(vnum))
+ num=vnum.split('.')[0]
+ lst=target.split('/')
+ tname=lst[len(lst)-1]
+ libname=tname.split('.')[0]
+ thisenv.AppendUnique(LINKFLAGS = ["-Wl,--soname=%s.so.%s" % (libname, num)] )
+
+ # Fix against a scons bug - shared libs and ordinal out of range(128)
+ if type(source) is types.ListType:
+ src2=[]
+ for i in source: src2.append( str(i) )
+ source=src2
+
+ library_list = thisenv.SharedLibrary(target, source)
+ lafile_list = thisenv.LaFile(target, library_list)
+
+ ## Install the libraries automatically
+ if not thisenv.has_key('NOAUTOINSTALL') and not noinst:
+ thisenv.bksys_install(libdir, library_list)
+ thisenv.bksys_install(libdir, lafile_list)
+
+ ## Handle the versioning
+ if len(vnum)>0:
+ nums=vnum.split('.')
+ symlinkcom = ('cd $TARGET.dir && rm -f $TARGET.name && ln -s $SOURCE.name $TARGET.name')
+ tg = target+'.so.'+vnum
+ nm1 = target+'.so'
+ nm2 = target+'.so.'+nums[0]
+ thisenv.Command(nm1, tg, symlinkcom)
+ thisenv.Command(nm2, tg, symlinkcom)
+ thisenv.bksys_install(libdir, nm1)
+ thisenv.bksys_install(libdir, nm2)
+ return library_list
+
+ # Declare scons scripts to process
+ def subdirs(lenv, folderlist):
+ flist=lenv.make_list(folderlist)
+ for i in flist:
+ lenv.SConscript(lenv.join(i, 'SConscript'))
+ # take all objects - warn those who are not already executed
+ if lenv.has_key('USE_THE_FORCE_LUKE'):
+ for ke in lenv['USE_THE_FORCE_LUKE']:
+ if ke.executed: continue
+ #lenv.pprint('GREEN',"you forgot to execute object "+ke.target)
+ ke.lockworkdir()
+ ke.execute()
+ ke.unlockworkdir()
+
+ def link_local_shlib(lenv, str):
+ """ Links against a shared library made in the project """
+ lst = lenv.make_list(str)
+ for file in lst:
+ import re
+ reg=re.compile("(.*)/lib(.*).(la|so)$")
+ result=reg.match(file)
+ if not result:
+ reg = re.compile("(.*)/lib(.*).(la|so)\.(.)")
+ result=reg.match(file)
+ if not result:
+ print "Unknown la file given "+file
+ continue
+ dir = result.group(1)
+ link = result.group(2)
+ else:
+ dir = result.group(1)
+ link = result.group(2)
+
+ lenv.AppendUnique(LIBS = [link])
+ lenv.PrependUnique(LIBPATH = [dir])
+
+ def link_local_staticlib(lenv, str):
+ """ Links against a shared library made in the project """
+ lst = lenv.make_list(str)
+ for file in lst:
+ import re
+ reg = re.compile("(.*)/(lib.*.a)")
+ result = reg.match(file)
+ if not result:
+ print "Unknown archive file given "+file
+ continue
+ f=SCons.Node.FS.default_fs.File(file)
+ lenv.Append(LINKFLAGS=[f.path])
+
+ def set_build_dir(lenv, dirs, buildto):
+ lenv.SetOption('duplicate', 'soft-copy')
+ lenv['_BUILDDIR_']=buildto
+ ldirs=lenv.make_list(dirs)
+ for dir in ldirs:
+ lenv.BuildDir(buildto+os.path.sep+dir, dir)
+
+ #valid_targets = "program shlib kioslave staticlib".split()
+ SConsEnvironment.bksys_install = bksys_install
+ SConsEnvironment.bksys_shlib = bksys_shlib
+ SConsEnvironment.subdirs = subdirs
+ SConsEnvironment.link_local_shlib = link_local_shlib
+ SConsEnvironment.link_local_staticlib = link_local_staticlib
+ SConsEnvironment.genobj=genobj
+ SConsEnvironment.set_build_dir=set_build_dir
+
+ if env.has_key('GENCXXFLAGS'): env.AppendUnique( CPPFLAGS = env['GENCXXFLAGS'] )
+ if env.has_key('GENCCFLAGS'): env.AppendUnique( CCFLAGS = env['GENCCFLAGS'] )
+ if env.has_key('GENLINKFLAGS'): env.AppendUnique( LINKFLAGS = env['GENLINKFLAGS'] )
+
+ if env.has_key('EXTRAINCLUDES'):
+ if env['EXTRAINCLUDES']:
+ incpaths = []
+ for dir in str(env['EXTRAINCLUDES']).split(':'): incpaths.append( dir )
+ env.Append(CPPPATH = incpaths)
+
+ env.Export('env')
diff --git a/admin/kde.py b/admin/kde.py
new file mode 100644
index 0000000..43927f2
--- /dev/null
+++ b/admin/kde.py
@@ -0,0 +1,839 @@
+# Thomas Nagy, 2005 <tnagy2^8@yahoo.fr>
+""" Run scons -h to display the associated help, or look below """
+
+import os, re, types
+from SCons.Script.SConscript import SConsEnvironment
+
+# Returns the name of the shared object (i.e. libkdeui.so.4)
+# referenced by a libtool archive (like libkdeui.la)
+def getSOfromLA(lafile):
+ contents = open(lafile, 'r').read()
+ match = re.search("^dlname='([^']*)'$", contents, re.M)
+ if match: return match.group(1)
+ return None
+
+# A helper, needed .. everywhere
+def KDEuse(lenv, flags):
+ if lenv['HELP']: lenv.Exit(0)
+
+ _flags=lenv.make_list(flags)
+ if 'environ' in _flags:
+ ## The scons developers advise against using this but it is mostly innocuous :)
+ lenv.AppendUnique( ENV = os.environ )
+ if not 'lang_qt' in _flags:
+ ## Use this define if you are using the kde translation scheme (.po files)
+ lenv.Append( CPPFLAGS = '-DQT_NO_TRANSLATION' )
+ if 'rpath' in _flags:
+ ## Use this to set rpath - this may cause trouble if folders are moved (chrpath)
+ kdelibpaths=[]
+ if lenv['KDELIBPATH'] == lenv['KDELIB']: kdelibpaths = [lenv['KDELIB']]
+ else: kdelibpaths = [lenv['KDELIBPATH'], lenv['KDELIB']]
+ lenv.Append( RPATH = [lenv['QTLIBPATH'], lenv['KDEMODULE']]+kdelibpaths )
+ if 'thread' in _flags:
+ ## Uncomment the following if you need threading support
+ lenv.KDEaddflags_cxx( ['-DQT_THREAD_SUPPORT', '-D_REENTRANT'] )
+ if 'fastmoc' in _flags:
+ lenv['BKSYS_FASTMOC']=1
+ if not 'nohelp' in _flags:
+ if lenv['_CONFIGURE'] or lenv['HELP']: lenv.Exit(0)
+ if not 'nosmart' or not lenv.has_key('nosmart_includes'):
+ lenv.AppendUnique(CPPPATH=['#/'])
+ lst=[]
+ if lenv.has_key('USE_THE_FORCE_LUKE'):
+ lst=lenv['USE_THE_FORCE_LUKE']
+ lenv.__delitem__('USE_THE_FORCE_LUKE')
+ for v in lst: v.execute()
+ else: lenv['nosmart_includes']=1
+
+ ## To use kdDebug(intvalue)<<"some trace"<<endl; you need to define -DDEBUG
+ ## it is done in admin/generic.py automatically when you do scons configure debug=1
+
+def exists(env):
+ return True
+
+def detect_kde(env):
+ """ Detect the qt and kde environment using kde-config mostly """
+ def getpath(varname):
+ if not env.has_key('ARGS'): return None
+ v=env['ARGS'].get(varname, None)
+ if v: v=os.path.abspath(v)
+ return v
+
+ def getstr(varname):
+ if env.has_key('ARGS'): return env['ARGS'].get(varname, '')
+ return ''
+
+ prefix = getpath('prefix')
+ execprefix = getpath('execprefix')
+ datadir = getpath('datadir')
+ libdir = getpath('libdir')
+
+ kdedir = getstr('kdedir')
+ kdeincludes = getpath('kdeincludes')
+ kdelibs = getpath('kdelibs')
+
+ qtdir = getstr('qtdir')
+ qtincludes = getpath('qtincludes')
+ qtlibs = getpath('qtlibs')
+ libsuffix = getstr('libsuffix')
+
+ p=env.pprint
+
+ if libdir: libdir = libdir+libsuffix
+
+ ## Detect the kde libraries
+ print "Checking for kde-config : ",
+ str="which kde-config 2>/dev/null"
+ if kdedir: str="which %s 2>/dev/null" % (kdedir+'/bin/kde-config')
+ kde_config = os.popen(str).read().strip()
+ if len(kde_config):
+ p('GREEN', 'kde-config was found as '+kde_config)
+ else:
+ if kdedir: p('RED','kde-config was NOT found in the folder given '+kdedir)
+ else: p('RED','kde-config was NOT found in your PATH')
+ print "Make sure kde is installed properly"
+ print "(missing package kdebase-devel?)"
+ env.Exit(1)
+ if kdedir: env['KDEDIR']=kdedir
+ else: env['KDEDIR'] = os.popen(kde_config+' -prefix').read().strip()
+
+ print "Checking for kde version : ",
+ kde_version = os.popen(kde_config+" --version|grep KDE").read().strip().split()[1]
+ if int(kde_version[0]) != 3 or int(kde_version[2]) < 2:
+ p('RED', kde_version)
+ p('RED',"Your kde version can be too old")
+ p('RED',"Please make sure kde is at least 3.2")
+ else:
+ p('GREEN',kde_version)
+
+ ## Detect the qt library
+ print "Checking for the qt library : ",
+ if not qtdir: qtdir = os.getenv("QTDIR")
+ if qtdir:
+ p('GREEN',"qt is in "+qtdir)
+ else:
+ try:
+ tmplibdir = os.popen(kde_config+' --expandvars --install lib').read().strip()
+ libkdeuiSO = env.join(tmplibdir, getSOfromLA(env.join(tmplibdir,'/libkdeui.la')) )
+ m = re.search('(.*)/lib/libqt.*', os.popen('ldd ' + libkdeuiSO + ' | grep libqt').read().strip().split()[2])
+ except: m=None
+ if m:
+ qtdir = m.group(1)
+ p('YELLOW',"qt was found as "+m.group(1))
+ else:
+ p('RED','qt was not found')
+ p('RED','Please set QTDIR first (/usr/lib/qt3?) or try scons -h for more options')
+ env.Exit(1)
+ env['QTDIR'] = qtdir.strip()
+
+ ## Find the necessary programs uic and moc
+ print "Checking for uic : ",
+ uic = qtdir + "/bin/uic"
+ if os.path.isfile(uic):
+ p('GREEN',"uic was found as "+uic)
+ else:
+ uic = os.popen("which uic 2>/dev/null").read().strip()
+ if len(uic):
+ p('YELLOW',"uic was found as "+uic)
+ else:
+ uic = os.popen("which uic 2>/dev/null").read().strip()
+ if len(uic):
+ p('YELLOW',"uic was found as "+uic)
+ else:
+ p('RED',"uic was not found - set QTDIR put it in your PATH ?")
+ env.Exit(1)
+ env['QT_UIC'] = uic
+
+ print "Checking for moc : ",
+ moc = qtdir + "/bin/moc"
+ if os.path.isfile(moc):
+ p('GREEN',"moc was found as "+moc)
+ else:
+ moc = os.popen("which moc 2>/dev/null").read().strip()
+ if len(moc):
+ p('YELLOW',"moc was found as "+moc)
+ elif os.path.isfile("/usr/share/qt3/bin/moc"):
+ moc = "/usr/share/qt3/bin/moc"
+ p('YELLOW',"moc was found as "+moc)
+ else:
+ p('RED',"moc was not found - set QTDIR or put it in your PATH ?")
+ env.Exit(1)
+ env['QT_MOC'] = moc
+
+ ## check for the qt and kde includes
+ print "Checking for the qt includes : ",
+ if qtincludes and os.path.isfile(qtincludes + "/qlayout.h"):
+ # The user told where to look for and it looks valid
+ p('GREEN',"ok "+qtincludes)
+ else:
+ if os.path.isfile(qtdir + "/include/qlayout.h"):
+ # Automatic detection
+ p('GREEN',"ok "+qtdir+"/include/")
+ qtincludes = qtdir + "/include/"
+ elif os.path.isfile("/usr/include/qt3/qlayout.h"):
+ # Debian probably
+ p('YELLOW','the qt headers were found in /usr/include/qt3/')
+ qtincludes = "/usr/include/qt3"
+ else:
+ p('RED',"the qt headers were not found")
+ env.Exit(1)
+
+ print "Checking for the kde includes : ",
+ kdeprefix = os.popen(kde_config+" --prefix").read().strip()
+ if not kdeincludes:
+ kdeincludes = kdeprefix+"/include/"
+ if os.path.isfile(kdeincludes + "/klineedit.h"):
+ p('GREEN',"ok "+kdeincludes)
+ else:
+ if os.path.isfile(kdeprefix+"/include/kde/klineedit.h"):
+ # Debian, Fedora probably
+ p('YELLOW',"the kde headers were found in %s/include/kde/"%kdeprefix)
+ kdeincludes = kdeprefix + "/include/kde/"
+ else:
+ p('RED',"The kde includes were NOT found")
+ env.Exit(1)
+
+ # kde-config options
+ kdec_opts = {'KDEBIN' : 'exe', 'KDEAPPS' : 'apps',
+ 'KDEDATA' : 'data', 'KDEICONS' : 'icon',
+ 'KDEMODULE' : 'module', 'KDELOCALE' : 'locale',
+ 'KDEKCFG' : 'kcfg', 'KDEDOC' : 'html',
+ 'KDEMENU' : 'apps', 'KDEXDG' : 'xdgdata-apps',
+ 'KDEMIME' : 'mime', 'KDEXDGDIR' : 'xdgdata-dirs',
+ 'KDESERV' : 'services','KDESERVTYPES' : 'servicetypes',
+ 'KDEINCLUDE': 'include' }
+
+ if prefix:
+ ## use the user-specified prefix
+ if not execprefix: execprefix=prefix
+ if not datadir: datadir=env.join(prefix,'share')
+ if not libdir: libdir=env.join(execprefix, "lib"+libsuffix)
+
+ subst_vars = lambda x: x.replace('${exec_prefix}', execprefix)\
+ .replace('${datadir}', datadir)\
+ .replace('${libdir}', libdir)\
+ .replace('${prefix}', prefix)
+ debian_fix = lambda x: x.replace('/usr/share', '${datadir}')
+ env['PREFIX'] = prefix
+ env['KDELIB'] = libdir
+ for (var, option) in kdec_opts.items():
+ dir = os.popen(kde_config+' --install ' + option).read().strip()
+ if var == 'KDEDOC': dir = debian_fix(dir)
+ env[var] = subst_vars(dir)
+
+ else:
+ env['PREFIX'] = os.popen(kde_config+' --expandvars --prefix').read().strip()
+ env['KDELIB'] = os.popen(kde_config+' --expandvars --install lib').read().strip()
+ for (var, option) in kdec_opts.items():
+ dir = os.popen(kde_config+' --expandvars --install ' + option).read().strip()
+ env[var] = dir
+
+ env['QTPLUGINS']=os.popen(kde_config+' --expandvars --install qtplugins').read().strip()
+
+ ## kde libs and includes
+ env['KDEINCLUDEPATH']=kdeincludes
+ if not kdelibs:
+ kdelibs=os.popen(kde_config+' --expandvars --install lib').read().strip()
+ env['KDELIBPATH']=kdelibs
+
+ ## qt libs and includes
+ env['QTINCLUDEPATH']=qtincludes
+ if not qtlibs:
+ qtlibs=qtdir+"/lib"+libsuffix
+ env['QTLIBPATH']=qtlibs
+
+ ## check if KDE has the UDS_HIDDEN patch
+ print "Checking KDE for UDS_HIDDEN : ",
+ if 'UDS_HIDDEN' in os.popen('cat ' + env['KDEINCLUDEPATH'] + '/kio/global.h').read():
+ env['HAVE_UDS_HIDDEN']='1'
+ p('GREEN', 'yes')
+ else:
+ env['HAVE_UDS_HIDDEN']='0'
+ p('YELLOW', 'no')
+
+def generate(env):
+ """"Set up the qt and kde environment and builders - the moc part is difficult to understand """
+
+ # attach this function immediately
+ SConsEnvironment.KDEuse=KDEuse
+
+ if env['HELP']:
+ p=env.pprint
+ p('BOLD','*** KDE options ***')
+ p('BOLD','--------------------')
+ p('BOLD','* prefix ','base install path, ie: /usr/local')
+ p('BOLD','* execprefix ','install path for binaries, ie: /usr/bin')
+ p('BOLD','* datadir ','install path for the data, ie: /usr/local/share')
+ p('BOLD','* libdir ','install path for the libs, ie: /usr/lib')
+
+ p('BOLD','* qtdir ','base of the kde libraries')
+ p('BOLD','* kdedir ','base of the qt libraries')
+
+ p('BOLD','* libsuffix ','suffix of libraries on amd64, ie: 64, 32')
+ p('BOLD','* kdeincludes','kde includes path (/usr/include/kde on debian, ..)')
+ p('BOLD','* qtincludes ','qt includes path (/usr/include/qt on debian, ..)')
+ p('BOLD','* kdelibs ','kde libraries path, for linking the programs')
+ p('BOLD','* qtlibs ','qt libraries path, for linking the program')
+
+ p('BOLD','* scons configure libdir=/usr/local/lib qtincludes=/usr/include/qt\n')
+ return
+
+ import SCons.Defaults
+ import SCons.Tool
+ import SCons.Util
+ import SCons.Node
+
+ CLVar = SCons.Util.CLVar
+ splitext = SCons.Util.splitext
+ Builder = SCons.Builder.Builder
+
+ # Detect the environment - replaces ./configure implicitely and store the options into a cache
+ from SCons.Options import Options
+ cachefile=env['CACHEDIR']+'kde.cache.py'
+ opts = Options(cachefile)
+ opts.AddOptions(
+ ('PREFIX', 'root of the program installation'),
+
+ ('QTDIR', ''),
+ ('QTLIBPATH', 'path to the qt libraries'),
+ ('QTINCLUDEPATH', 'path to the qt includes'),
+ ('QT_UIC', 'uic command'),
+ ('QT_MOC', 'moc command'),
+ ('QTPLUGINS', 'uic executable command'),
+
+ ('KDEDIR', ''),
+ ('KDELIBPATH', 'path to the installed kde libs'),
+ ('KDEINCLUDEPATH', 'path to the installed kde includes'),
+
+ ('KDEBIN', 'inst path of the kde binaries'),
+ ('KDEINCLUDE', 'inst path of the kde include files'),
+ ('KDELIB', 'inst path of the kde libraries'),
+ ('KDEMODULE', 'inst path of the parts and libs'),
+ ('KDEDATA', 'inst path of the application data'),
+ ('KDELOCALE', ''), ('KDEDOC', ''), ('KDEKCFG', ''),
+ ('KDEXDG', ''), ('KDEXDGDIR', ''), ('KDEMENU', ''),
+ ('KDEMIME', ''), ('KDEICONS', ''), ('KDESERV', ''),
+ ('KDESERVTYPES', ''), ('KDEAPPS', ''), ('HAVE_UDS_HIDDEN', ''),
+ )
+ opts.Update(env)
+
+ def getInstDirForResType(lenv,restype):
+ if len(restype) == 0 or not lenv.has_key(restype):
+ lenv.pprint('RED',"unknown resource type "+restype)
+ lenv.Exit(1)
+ else: instdir = lenv[restype]
+
+ if env['ARGS'] and env['ARGS'].has_key('prefix'):
+ instdir = instdir.replace(lenv['PREFIX'], env['ARGS']['prefix'])
+ return instdir
+
+ # reconfigure when things are missing
+ if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('QTDIR') or not env.has_key('KDEDIR')):
+ detect_kde(env)
+ opts.Save(cachefile, env)
+
+ ## set default variables, one can override them in sconscript files
+ env.Append(CXXFLAGS = ['-I'+env['KDEINCLUDEPATH'], '-I'+env['QTINCLUDEPATH'] ],
+ LIBPATH = [env['KDELIBPATH'], env['QTLIBPATH'] ])
+
+ env['QT_AUTOSCAN'] = 1
+ env['QT_DEBUG'] = 0
+
+ env['MEINPROC'] = 'meinproc'
+ env['MSGFMT'] = 'msgfmt'
+
+ ## ui file processing
+ def uic_processing(target, source, env):
+ inc_kde ='#include <klocale.h>\n#include <kdialog.h>\n'
+ inc_moc ='#include "%s"\n' % target[2].name
+ comp_h ='$QT_UIC -L $QTPLUGINS -nounload -o %s %s' % (target[0].path, source[0].path)
+ comp_c ='$QT_UIC -L $QTPLUGINS -nounload -tr tr2i18n -impl %s %s' % (target[0].path, source[0].path)
+ comp_moc ='$QT_MOC -o %s %s' % (target[2].path, target[0].path)
+ if env.Execute(comp_h): return ret
+ dest = open( target[1].path, "w" )
+ dest.write(inc_kde)
+ dest.close()
+ if env.Execute( comp_c+" >> "+target[1].path ): return ret
+ dest = open( target[1].path, "a" )
+ dest.write(inc_moc)
+ dest.close()
+ ret = env.Execute( comp_moc )
+ return ret
+ def uicEmitter(target, source, env):
+ adjustixes = SCons.Util.adjustixes
+ bs = SCons.Util.splitext(str(source[0].name))[0]
+ bs = env.join(str(target[0].get_dir()),bs)
+ target.append(bs+'.cpp')
+ target.append(bs+'.moc')
+ return target, source
+ env['BUILDERS']['Uic']=Builder(action=uic_processing,emitter=uicEmitter,suffix='.h',src_suffix='.ui')
+
+ def kcfg_buildit(target, source, env):
+ comp='kconfig_compiler -d%s %s %s' % (str(source[0].get_dir()), source[1].path, source[0].path)
+ return env.Execute(comp)
+ def kcfg_stringit(target, source, env):
+ print "processing %s to get %s and %s" % (source[0].name, target[0].name, target[1].name)
+ def kcfgEmitter(target, source, env):
+ adjustixes = SCons.Util.adjustixes
+ file=str(source[0].srcnode().name)
+ bs = SCons.Util.splitext(str(source[0].name))[0]
+ bs = env.join(str(target[0].get_dir()),bs)
+ # .h file is already there
+ target.append( bs+'.cpp' )
+
+ content=source[0].srcnode().get_contents()
+ #print content
+
+ kcfgfilename=""
+ kcfgFileDeclRx = re.compile("[fF]ile\s*=\s*(.+)\s*")
+ match = kcfgFileDeclRx.search(content)
+ if match: kcfgfilename = match.group(1)
+
+ if not kcfgfilename:
+ env.pprint('RED','invalid kcfgc file '+source[0].srcnode().abspath)
+ env.Exit(1)
+ source.append( env.join( str(source[0].get_dir()), kcfgfilename) )
+ return target, source
+
+ env['BUILDERS']['Kcfg']=Builder(action=env.Action(kcfg_buildit, kcfg_stringit),
+ emitter=kcfgEmitter, suffix='.h', src_suffix='.kcfgc')
+
+ ## MOC processing
+ env['BUILDERS']['Moc']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='.moc',src_suffix='.h')
+ env['BUILDERS']['Moccpp']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='_moc.cpp',src_suffix='.h')
+
+ ## KIDL file
+ env['BUILDERS']['Kidl']=Builder(action= 'dcopidl $SOURCE > $TARGET || (rm -f $TARGET ; false)',
+ suffix='.kidl', src_suffix='.h')
+ ## DCOP
+ env['BUILDERS']['Dcop']=Builder(action='dcopidl2cpp --c++-suffix cpp --no-signals --no-stub $SOURCE',
+ suffix='_skel.cpp', src_suffix='.kidl')
+ ## STUB
+ env['BUILDERS']['Stub']=Builder(action= 'dcopidl2cpp --c++-suffix cpp --no-signals --no-skel $SOURCE',
+ suffix='_stub.cpp', src_suffix='.kidl')
+ ## DOCUMENTATION
+ env['BUILDERS']['Meinproc']=Builder(action='cd $TARGET.dir && $MEINPROC --check --cache $TARGET.name $SOURCE.name',suffix='.cache.bz2')
+ ## TRANSLATIONS
+ env['BUILDERS']['Transfiles']=Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
+
+ ## Handy helpers for building kde programs
+ ## You should not have to modify them ..
+
+ ui_ext = [".ui"]
+ kcfg_ext = ['.kcfgc']
+ header_ext = [".h", ".hxx", ".hpp", ".hh"]
+ cpp_ext = [".cpp", ".cxx", ".cc"]
+ skel_ext = [".skel", ".SKEL"]
+ stub_ext = [".stub", ".STUB"]
+
+ def KDEfiles(lenv, target, source):
+ """ Returns a list of files for scons (handles kde tricks like .skel)
+ It also makes custom checks against double includes like : ['file.ui', 'file.cpp']
+ (file.cpp is already included because of file.ui) """
+
+ q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
+ def scan_moc(cppfile):
+ addfile=None
+
+ # try to find the header
+ orifile=cppfile.srcnode().name
+ bs=SCons.Util.splitext(orifile)[0]
+
+ h_file=''
+ dir=cppfile.dir
+ for n_h_ext in header_ext:
+ afile=dir.File(bs+n_h_ext)
+ if afile.rexists():
+ #h_ext=n_h_ext
+ h_file=afile
+ break
+ # We have the header corresponding to the cpp file
+ if h_file:
+ h_contents = h_file.get_contents()
+ if q_object_search.search(h_contents):
+ # we know now there is Q_OBJECT macro
+ reg = '\n\s*#include\s*("|<)'+str(bs)+'.moc("|>)'
+ meta_object_search = re.compile(reg)
+ #cpp_contents = open(file_cpp, 'rb').read()
+ cpp_contents=cppfile.get_contents()
+ if meta_object_search.search(cpp_contents):
+ lenv.Moc(h_file)
+ else:
+ lenv.Moccpp(h_file)
+ addfile=bs+'_moc.cpp'
+ print "WARNING: moc.cpp for "+h_file.name+" consider using #include <file.moc> instead"
+ return addfile
+
+ src=[]
+ ui_files=[]
+ kcfg_files=[]
+ other_files=[]
+ kidl=[]
+
+ source_=lenv.make_list(source)
+
+ # For each file, check wether it is a dcop file or not, and create the complete list of sources
+ for file in source_:
+ sfile=SCons.Node.FS.default_fs.File(str(file)) # why str(file) ? because ordinal not in range issues
+ bs = SCons.Util.splitext(file)[0]
+ ext = SCons.Util.splitext(file)[1]
+ if ext in skel_ext:
+ if not bs in kidl:
+ kidl.append(bs)
+ lenv.Dcop(bs+'.kidl')
+ src.append(bs+'_skel.cpp')
+ elif ext in stub_ext:
+ if not bs in kidl:
+ kidl.append(bs)
+ lenv.Stub(bs+'.kidl')
+ src.append(bs+'_stub.cpp')
+ elif ext == ".moch":
+ lenv.Moccpp(bs+'.h')
+ src.append(bs+'_moc.cpp')
+ elif ext in cpp_ext:
+ src.append(file)
+ if not env.has_key('NOMOCFILE'):
+ ret = scan_moc(sfile)
+ if ret: src.append( ret )
+ elif ext in ui_ext:
+ lenv.Uic(file)
+ src.append(bs+'.cpp')
+ elif ext in kcfg_ext:
+ name=SCons.Util.splitext(sfile.name)[0]
+ hfile=lenv.Kcfg(file)
+ cppkcfgfile=sfile.dir.File(bs+'.cpp')
+ src.append(bs+'.cpp')
+ else:
+ src.append(file)
+
+ for base in kidl: lenv.Kidl(base+'.h')
+
+ # Now check against typical newbie errors
+ for file in ui_files:
+ for ofile in other_files:
+ if ofile == file:
+ env.pprint('RED',"WARNING: You have included %s.ui and another file of the same prefix"%file)
+ print "Files generated by uic (file.h, file.cpp must not be included"
+ for file in kcfg_files:
+ for ofile in other_files:
+ if ofile == file:
+ env.pprint('RED',"WARNING: You have included %s.kcfg and another file of the same prefix"%file)
+ print "Files generated by kconfig_compiler (settings.h, settings.cpp) must not be included"
+ return src
+
+
+ """ In the future, these functions will contain the code that will dump the
+ configuration for re-use from an IDE """
+ def KDEinstall(lenv, restype, subdir, files, perms=None):
+ if env.has_key('DUMPCONFIG'):
+ print "<install type=\"%s\" subdir=\"%s\">" % (restype, subdir)
+ for i in lenv.make_list(files): print " <file name=\"%s\"/>" % (lenv.join(lenv.getreldir(),i))
+ print "</install>"
+ return
+
+ if not env['_INSTALL']: return None
+ dir = getInstDirForResType(lenv, restype)
+
+ p=None
+ if not perms:
+ if restype=='KDEBIN': p=0755
+ else: p=perms
+ install_list = lenv.bksys_install(lenv.join(dir, subdir), files, perms=p)
+ return install_list
+
+ def KDEinstallas(lenv, restype, destfile, file):
+ if not env['_INSTALL']: return
+ dir = getInstDirForResType(lenv, restype)
+ install_list = lenv.InstallAs(lenv.join(dir, destfile), file)
+ env.Alias('install', install_list)
+ return install_list
+
+ def KDEprogram(lenv, target, source,
+ includes='', localshlibs='', globallibs='', globalcxxflags=''):
+ """ Makes a kde program
+ The program is installed except if one sets env['NOAUTOINSTALL'] """
+ src = KDEfiles(lenv, target, source)
+ program_list = lenv.Program(target, src)
+
+ # we link the program against a shared library done locally, add the dependency
+ if not lenv.has_key('nosmart_includes'):
+ lenv.AppendUnique(CPPPATH=['./'])
+ if len(localshlibs)>0:
+ lst=lenv.make_list(localshlibs)
+ lenv.link_local_shlib(lst)
+ lenv.Depends( program_list, lst )
+
+ if len(includes)>0: lenv.KDEaddpaths_includes(includes)
+ if len(globallibs)>0: lenv.KDEaddlibs(globallibs)
+ if len(globalcxxflags)>0: lenv.KDEaddflags_cxx(globalcxxflags)
+
+ if not lenv.has_key('NOAUTOINSTALL'):
+ KDEinstall(lenv, 'KDEBIN', '', target)
+ return program_list
+
+ def KDEshlib(lenv, target, source, kdelib=0, libprefix='lib',
+ includes='', localshlibs='', globallibs='', globalcxxflags='', vnum=''):
+ """ Makes a shared library for kde (.la file for klibloader)
+ The library is installed except if one sets env['NOAUTOINSTALL'] """
+ src = KDEfiles(lenv, target, source)
+
+ if not lenv.has_key('nosmart_includes'):
+ lenv.AppendUnique(CPPPATH=['./'])
+ # we link the program against a shared library done locally, add the dependency
+ lst=[]
+ if len(localshlibs)>0:
+ lst=lenv.make_list(localshlibs)
+ lenv.link_local_shlib(lst)
+ if len(includes)>0: lenv.KDEaddpaths_includes(includes)
+ if len(globallibs)>0: lenv.KDEaddlibs(globallibs)
+ if len(globalcxxflags)>0: lenv.KDEaddflags_cxx(globalcxxflags)
+
+ restype='KDEMODULE'
+ if kdelib==1: restype='KDELIB'
+
+ library_list = lenv.bksys_shlib(target, src, getInstDirForResType(lenv, restype), libprefix, vnum)
+ if len(lst)>0: lenv.Depends( library_list, lst )
+
+ return library_list
+
+ def KDEstaticlib(lenv, target, source):
+ """ Makes a static library for kde - in practice you should not use static libraries
+ 1. they take more memory than shared ones
+ 2. makefile.am needed it because of limitations
+ (cannot handle sources in separate folders - takes extra processing) """
+ if not lenv.has_key('nosmart_includes'): lenv.AppendUnique(CPPPATH=['./'])
+ src=KDEfiles(lenv, target, source)
+ return lenv.StaticLibrary(target, src)
+ # do not install static libraries by default
+
+ def KDEaddflags_cxx(lenv, fl):
+ """ Compilation flags for C++ programs """
+ lenv.AppendUnique(CXXFLAGS = lenv.make_list(fl))
+
+ def KDEaddflags_c(lenv, fl):
+ """ Compilation flags for C programs """
+ lenv.AppendUnique(CFLAGS = lenv.make_list(fl))
+
+ def KDEaddflags_link(lenv, fl):
+ """ Add link flags - Use this if KDEaddlibs below is not enough """
+ lenv.PrependUnique(LINKFLAGS = lenv.make_list(fl))
+
+ def KDEaddlibs(lenv, libs):
+ """ Helper function """
+ lenv.AppendUnique(LIBS = lenv.make_list(libs))
+
+ def KDEaddpaths_includes(lenv, paths):
+ """ Add new include paths """
+ lenv.AppendUnique(CPPPATH = lenv.make_list(paths))
+
+ def KDEaddpaths_libs(lenv, paths):
+ """ Add paths to libraries """
+ lenv.PrependUnique(LIBPATH = lenv.make_list(paths))
+
+ def KDElang(lenv, folder, appname):
+ """ Process translations (.po files) in a po/ dir """
+ import glob
+ dir=SCons.Node.FS.default_fs.Dir(folder).srcnode()
+ fld=dir.srcnode()
+ tmptransfiles = glob.glob(str(fld)+'/*.po')
+
+ transfiles=[]
+ if lenv.has_key('_BUILDDIR_'):
+ bdir=lenv['_BUILDDIR_']
+ for dir in lenv.make_list(tmptransfiles):
+ transfiles.append( lenv.join(bdir, dir) )
+ else: tmptransfiles=transfiles
+
+ languages=None
+ if lenv['ARGS'] and lenv['ARGS'].has_key('languages'):
+ languages=lenv.make_list(lenv['ARGS']['languages'])
+ mydir=SCons.Node.FS.default_fs.Dir('.')
+ for f in transfiles:
+ fname=f.replace(mydir.abspath, '')
+ file=SCons.Node.FS.default_fs.File(fname)
+ country = SCons.Util.splitext(file.name)[0]
+ if not languages or country in languages:
+ result = lenv.Transfiles(file)
+ dir=lenv.join( getInstDirForResType(lenv, 'KDELOCALE'), country)
+ lenv.bksys_install(lenv.join(dir, 'LC_MESSAGES'), result, destfile=appname+'.mo')
+
+ def KDEicon(lenv, icname='*', path='./', restype='KDEICONS', subdir=''):
+ """Contributed by: "Andrey Golovizin" <grooz()gorodok()net>
+ modified by "Martin Ellis" <m.a.ellis()ncl()ac()uk>
+
+ Installs icons with filenames such as cr22-action-frame.png into
+ KDE icon hierachy with names like icons/crystalsvg/22x22/actions/frame.png.
+
+ Global KDE icons can be installed simply using env.KDEicon('name').
+ The second parameter, path, is optional, and specifies the icons
+ location in the source, relative to the SConscript file.
+
+ To install icons that need to go under an applications directory (to
+ avoid name conflicts, for example), use e.g.
+ env.KDEicon('name', './', 'KDEDATA', 'appname/icons')"""
+
+ if env.has_key('DUMPCONFIG'):
+ print "<icondirent subdir=\"%s\" />" % (lenv.join(lenv.getreldir(),path,subdir))
+ return
+
+ type_dic = { 'action':'actions', 'app':'apps', 'device':'devices',
+ 'filesys':'filesystems', 'mime':'mimetypes' }
+ dir_dic = {
+ 'los' :'locolor/16x16', 'lom' :'locolor/32x32',
+ 'him' :'hicolor/32x32', 'hil' :'hicolor/48x48',
+ 'lo16' :'locolor/16x16', 'lo22' :'locolor/22x22', 'lo32' :'locolor/32x32',
+ 'hi16' :'hicolor/16x16', 'hi22' :'hicolor/22x22', 'hi32' :'hicolor/32x32',
+ 'hi48' :'hicolor/48x48', 'hi64' :'hicolor/64x64', 'hi128':'hicolor/128x128',
+ 'hisc' :'hicolor/scalable',
+ 'cr16' :'crystalsvg/16x16', 'cr22' :'crystalsvg/22x22', 'cr32' :'crystalsvg/32x32',
+ 'cr48' :'crystalsvg/48x48', 'cr64' :'crystalsvg/64x64', 'cr128':'crystalsvg/128x128',
+ 'crsc' :'crystalsvg/scalable'
+ }
+
+ iconfiles = []
+ dir=SCons.Node.FS.default_fs.Dir(path).srcnode()
+ mydir=SCons.Node.FS.default_fs.Dir('.')
+ import glob
+ for ext in ['png', 'xpm', 'mng', 'svg', 'svgz']:
+ files = glob.glob(str(dir)+'/'+'*-*-%s.%s' % (icname, ext))
+ for file in files:
+ iconfiles.append( file.replace(mydir.abspath, '') )
+ for iconfile in iconfiles:
+ lst = iconfile.split('/')
+ filename = lst[ len(lst) - 1 ]
+ tmp = filename.split('-')
+ if len(tmp)!=3:
+ env.pprint('RED','WARNING: icon filename has unknown format: '+iconfile)
+ continue
+ [icon_dir, icon_type, icon_filename]=tmp
+ try:
+ basedir=getInstDirForResType(lenv, restype)
+ destdir = '%s/%s/%s/%s/' % (basedir, subdir, dir_dic[icon_dir], type_dic[icon_type])
+ except KeyError:
+ env.pprint('RED','WARNING: unknown icon type: '+iconfile)
+ continue
+ lenv.bksys_install(destdir, iconfile, icon_filename)
+
+ ## This function uses env imported above - WARNING ugly code, i will have to rewrite (ITA)
+ def docfolder(lenv, folder, lang, destination=""):
+ # folder is the folder to process
+ # lang is the language
+ # destination is the subdirectory in KDEDOC
+ import glob
+ docfiles=[]
+ dir=SCons.Node.FS.default_fs.Dir(folder).srcnode()
+ mydir=SCons.Node.FS.default_fs.Dir('.')
+ dirpath=mydir.srcnode().abspath
+ docg = glob.glob(str(dir)+"/???*.*") # file files that are at least 4 chars wide :)
+ for file in docg:
+ f = file.replace(dirpath, '')
+ docfiles.append(f)
+
+ # warn about errors
+ #if len(lang) != 2:
+ # print "error, lang must be a two-letter string, like 'en'"
+
+ # when the destination is not given, use the folder
+ if len(destination) == 0: destination=folder
+ docbook_list = []
+
+ bdir='.'
+ if lenv.has_key('_BUILDDIR_'): bdir = lenv['_BUILDDIR_']
+ for file in docfiles:
+ # do not process folders
+ #if not os.path.isfile( lenv.join('.', file) ): continue
+
+ # using nodefile forces to symlink in builddir
+ nodefile=SCons.Node.FS.default_fs.File( lenv.join(mydir.abspath, file) )
+
+ # do not process the cache file
+ if file == 'index.cache.bz2': continue
+ # ignore invalid files (TODO??)
+ if len( SCons.Util.splitext( file ) ) <= 1: continue
+ ext = SCons.Util.splitext( file )[1]
+
+ # install picture files
+ if ext in ['.jpeg', '.jpg', '.png']: lenv.KDEinstall('KDEDOC', lenv.join(lang,destination), nodefile.srcnode())
+ # docbook files are processed by meinproc
+ if ext != '.docbook': continue
+
+ docbook_list.append( nodefile )
+ lenv.KDEinstall('KDEDOC', lenv.join(lang,destination), nodefile.srcnode())
+
+ # Now process the index.docbook files ..
+ if len(docbook_list) == 0: return
+ # TODO
+ #if not os.path.isfile( folder+'/index.docbook' ):
+ # print "Error, index.docbook was not found in "+folder+'/index.docbook'
+ # return
+ ## Define this to 1 if you are writing documentation else to 0 :)
+ #if lenv.has_key('i_am_a_documentation_writer'):
+ for file in docbook_list:
+ lenv.Depends( folder+'index.cache.bz2', nodefile )
+
+ if lenv.has_key('_BUILDDIR_'): folder=lenv.join(lenv['_BUILDDIR_'], folder)
+
+ lenv.Meinproc( lenv.join(folder,'index.cache.bz2'), lenv.join(folder,'index.docbook') )
+ lenv.KDEinstall( 'KDEDOC', lenv.join(lang,destination), lenv.join(folder,'index.cache.bz2') )
+
+ if env['_INSTALL']:
+ dir=lenv.join(lenv.getInstDirForResType('KDEDOC'), lang, destination)
+ comp='mkdir -p %s && cd %s && rm -f common && ln -s ../common common' % (dir, dir)
+ lenv.Execute(comp)
+
+ #valid_targets = "program shlib kioslave staticlib".split()
+ import generic
+ class kobject(generic.genobj):
+ def __init__(self, val, senv=None):
+ if senv: generic.genobj.__init__(self, val, senv)
+ else: generic.genobj.__init__(self, val, env)
+ self.iskdelib=0
+ def it_is_a_kdelib(self): self.iskdelib=1
+ def execute(self):
+ if self.executed: return
+ self.lockchdir()
+ if self.orenv.has_key('DUMPCONFIG'):
+ print self.xml()
+ self.unlockchdir()
+ self.executed=1
+ return
+ if (self.type=='shlib' or self.type=='kioslave'):
+ install_dir = 'KDEMODULE'
+ if self.iskdelib==1: install_dir = 'KDELIB'
+ self.instdir=getInstDirForResType(self.orenv, install_dir)
+ elif self.type=='program':
+ self.instdir=getInstDirForResType(self.orenv, 'KDEBIN')
+ self.perms=0755
+
+ self.p_localsource=KDEfiles(env, self.joinpath(self.target), self.joinpath(self.source))
+ generic.genobj.execute(self)
+ self.unlockchdir()
+
+ def xml(self):
+ chdirto=self.orenv.join(self.orenv.getreldir(),self.chdir)
+ ret= '<compile type="%s" chdir="%s" target="%s" cxxflags="%s" cflags="%s" includes="%s" linkflags="%s" libpaths="%s" libs="%s" vnum="%s" iskdelib="%s" libprefix="%s">\n' % (self.type, chdirto, self.target, self.cxxflags, self.cflags, self.includes, self.linkflags, self.libpaths, self.libs, self.vnum, self.iskdelib, self.libprefix)
+ if self.source:
+ for i in self.orenv.make_list(self.source): ret+=' <source file="%s"/>\n' % i
+ ret += "</compile>"
+ return ret
+
+ # Attach the functions to the environment so that SConscripts can use them
+ SConsEnvironment.KDEprogram = KDEprogram
+ SConsEnvironment.KDEshlib = KDEshlib
+ SConsEnvironment.KDEstaticlib = KDEstaticlib
+ SConsEnvironment.KDEinstall = KDEinstall
+ SConsEnvironment.KDEinstallas = KDEinstallas
+ SConsEnvironment.KDElang = KDElang
+ SConsEnvironment.KDEicon = KDEicon
+
+ SConsEnvironment.KDEaddflags_cxx = KDEaddflags_cxx
+ SConsEnvironment.KDEaddflags_c = KDEaddflags_c
+ SConsEnvironment.KDEaddflags_link = KDEaddflags_link
+ SConsEnvironment.KDEaddlibs = KDEaddlibs
+ SConsEnvironment.KDEaddpaths_includes = KDEaddpaths_includes
+ SConsEnvironment.KDEaddpaths_libs = KDEaddpaths_libs
+
+ SConsEnvironment.docfolder = docfolder
+ SConsEnvironment.getInstDirForResType = getInstDirForResType
+ SConsEnvironment.kobject = kobject
+
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..1d71935
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,189 @@
+kio-locate-kde3 (0.4.5-1ubuntu4) karmic; urgency=low
+
+ * Karmic rebuild
+
+ -- Timothy Pearson <kb9vqf@pearsoncomputing.net> Thu, 02 July 2009 16:08:00 -0600
+
+kio-locate-kde3 (0.4.5-1ubuntu2) intrepid; urgency=low
+
+ * Moved KDE3 to /opt/kde3
+ * Integrated properly with KDE4.2+
+
+ -- Timothy Pearson <kb9vqf@pearsoncomputing.net> Thu, 05 March 2009 29:52:00 -0600
+
+kio-locate-kde3 (0.4.5-1ubuntu1) intrepid; urgency=low
+
+ * Added -kde3 suffix
+
+ -- Timothy Pearson <kb9vqf@pearsoncomputing.net> Thu, 04 Dec 2008 00:35:00 -0600
+
+kio-locate (0.4.5-0ubuntu3) hardy; urgency=low
+
+ * Rebuild with recent g++ compiler version.
+
+ -- Matthias Klose <doko@ubuntu.com> Thu, 03 Apr 2008 11:24:38 +0000
+
+kio-locate (0.4.5-0ubuntu2) feisty; urgency=low
+
+ * debian/control: Update maintainer fields according to debian-
+ maintainer-field spec.
+
+ -- Martin Pitt <martin.pitt@ubuntu.com> Mon, 26 Feb 2007 08:49:35 +0000
+
+kio-locate (0.4.5-0ubuntu1) edgy; urgency=low
+
+ * Sync with upstream.
+ * Added an entry in debian/rules to work arround a build issue.
+ * Switched to debhelper 5
+
+ -- Anthony Mercatante <tonio@ubuntu.com> Sun, 24 Jul 2006 23:30:58 +0200
+
+kio-locate (0.4.5-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Sun, 05 Feb 2006 17:02:09 +0100
+
+kio-locate (0.4.4-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Wed, 19 Oct 2005 18:01:59 +0200
+
+kio-locate (0.4.3-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Thu, 15 Sep 2005 09:12:38 +0200
+
+kio-locate (0.4.2tvo0.2) breezy; urgency=low
+
+ * New release of kio-locate.
+
+ -- Tobi Vollebregt <tobivollebregt@gmail.com> Sun, 21 Aug 2005 14:31:16 +0200
+
+kio-locate (0.4.2tvo0.1) breezy; urgency=low
+
+ * New release of kio-locate.
+ * Minor changes for ubuntu.
+ * Add bzip2 and python to build-deps.
+ * Fix the clean rule.
+
+ -- Tobi Vollebregt <tobivollebregt@gmail.com> Thu, 14 Jul 2005 23:14:16 +0200
+
+kio-locate (0.4.2-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Sun, 22 May 2005 09:55:57 +0200
+
+kio-locate (0.4.1-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Sat, 21 May 2005 16:21:19 +0200
+
+kio-locate (0.4.0-1) unstable; urgency=low
+
+ * New release of kio-locate.
+ * Adapted to the usage of scons.
+
+ -- Armin Straub <linux@arminstraub.de> Sun, 10 Apr 2005 13:12:28 +0200
+
+kio-locate (0.3.4-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Sat, 22 Jan 2005 16:13:54 +0100
+
+kio-locate (0.3.3-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Fri, 21 Jan 2005 10:23:13 +0100
+
+kio-locate (0.3.2-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Mon, 17 Jan 2005 16:38:47 +0100
+
+kio-locate (0.3.1-1) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Fri, 10 Dec 2004 10:24:34 +0100
+
+kio-locate (0.3.0) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Mon, 01 Nov 2004 08:41:55 +0100
+
+kio-locate (0.2.4-2) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * Reupload with orig.tar.gz named correctly.
+
+ -- Christoffer Sawicki <qerub@home.se> Sat, 30 Oct 2004 19:33:56 +0200
+
+kio-locate (0.2.4-1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * This is a non-native package and should be treated as such.
+ * Switched to CDBS.
+
+ -- Christoffer Sawicki <qerub@home.se> Sat, 30 Oct 2004 19:03:23 +0200
+
+kio-locate (0.2.4) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Tue, 26 Oct 2004 18:08:05 +0200
+
+kio-locate (0.2.3) unstable; urgency=low
+
+ * New release of kio-locate.
+
+ -- Armin Straub <linux@arminstraub.de> Mon, 25 Oct 2004 19:49:52 +0200
+
+kio-locate (0.2.2) unstable; urgency=low
+
+ * New release of kio-locate.
+ * Adjusted the control file to the new release.
+
+ -- Armin Straub <linux@arminstraub.de> Sun, 24 Oct 2004 13:29:05 +0200
+
+kio-locate (0.2.1) unstable; urgency=low
+
+ * New release of kio-locate.
+ * Using kde as the section instead of utils.
+
+ -- Armin Straub <linux@arminstraub.de> Fri, 22 Oct 2004 10:31:37 +0200
+
+kio-locate (0.2.0) unstable; urgency=low
+
+ * Complete rewrite.
+ * Works with KDE 3.3.
+
+ -- Armin Straub <linux@arminstraub.de> Fri, 15 Oct 2004 08:20:36 +0200
+
+kio-locate (0.1.1-1) unstable; urgency=low
+
+ * Corrected URL prefix ("file:" instead of "file:/").
+ * Update admin dir.
+
+ -- Michael Schuerig <michael@schuerig.de> Sun, 7 Mar 2004 13:10:35 +0100
+
+kio-locate (0.1-2) unstable; urgency=low
+
+ * Rebuild for KDE 3.1.
+
+ -- Michael Schuerig <schuerig@acm.org> Mon, 24 Feb 2003 09:07:34 +0100
+
+kio-locate (0.1-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Michael Schuerig <schuerig@acm.org> Sat, 14 Dec 2002 01:24:28 +0100
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7ed6ff8
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..31f8fb3
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,18 @@
+Source: kio-locate-kde3
+Section: kde
+Priority: optional
+Maintainer: Timothy Pearson <kb9vqf@pearsoncomputing.net>
+XSBC-Original-Maintainer: Tobi Vollebregt <tobivollebregt@gmail.com>
+Build-Depends: cdbs, debhelper (>= 5), kdelibs4-kde3-dev, bzip2, python (>= 2.3), scons
+Standards-Version: 3.7.2
+
+Package: kio-locate-kde3
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: kio-slave for the locate command [KDE3]
+ Adds support for the "locate:" and "locater:"
+ protocols to Konqueror and other KDE applications.
+ .
+ This enables you to perform locate searches as you
+ would in a terminal. The result is displayed just
+ as a directory.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..17e1fdc
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,29 @@
+This package was debianized by Tobi Vollebregt <tobivollebregt@gmail.com> on
+Thu, 14 Jul 2005 22:47:39 +0200
+
+It was downloaded from http://arminstraub.de
+
+Copyright:
+ Copyright (C) 2004 by Tobi Vollebregt
+ tobivollebregt@gmail.com
+
+ Copyright (C) 2004 by Armin Straub
+ linux@arminstraub.de
+
+ This program was initially written by Michael Schuerig.
+ Although I have completely rewritten it, most ideas are adopted
+ from his original work.
+
+ Copyright (C) 2002 by Michael Schuerig
+ michael@schuerig.de
+
+Upstream Authors:
+ Tobi Vollebregt <tobivollebregt@gmail.com>
+ Armin Straub <linux@arminstraub.de>
+ Michael Schuerig <schuerig@acm.org>
+
+License:
+ You are free to distribute this software under the terms of
+ the GNU General Public License.
+ On Debian systems, the complete text of the GNU General Public
+ License can be found in the file `/usr/share/common-licenses/GPL'.
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..b0cae30
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,37 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+
+DEB_CONFIGURE_INCLUDEDIR := /opt/kde3/include/kde
+DEB_CONFIGURE_MANDIR := /opt/kde3/share/man
+DEB_CONFIGURE_PREFIX := /opt/kde3
+DEB_CONFIGURE_INFODIR := /opt/kde3/share/info
+
+cdbs_configure_flags := --with-qt-dir=/usr/share/qt3 --disable-rpath --with-xinerama $(cdbs_kde_enable_final) $(cdbs_kde_enable_debug)
+
+DEB_COMPRESS_EXCLUDE=.docbook
+DEB_SCONS_PREFIX=/opt/kde3
+
+CONFIG_STATUS=$(DEB_BUILDDIR)/config.status
+SCONS_CMD=/usr/bin/scons
+
+common-configure-arch common-configure-indep:: common-configure-impl
+common-configure-impl:: $(CONFIG_STATUS)
+$(CONFIG_STATUS):
+ env PATH=/opt/kde3/bin:$(PATH) $(SCONS_CMD) configure prefix=$(DEB_DESTDIR)$(DEB_SCONS_PREFIX)
+ touch $(CONFIG_STATUS)
+
+common-build-arch common-build-indep:: common-build-impl
+common-build-impl::
+ env PATH=/opt/kde3/bin:$(PATH) $(SCONS_CMD)
+ rm -f doc/en/index.cache.bz2
+
+common-install-arch common-install-indep:: common-install-impl
+common-install-impl::
+ env PATH=/opt/kde3/bin:$(PATH) $(SCONS_CMD) install
+
+clean::
+ rm -rf build cache scons-mini
+ rm -f admin/*.pyc $(CONFIG_STATUS)
+
+DEB_INSTALL_DOCS_kio-locate-kde3 := -XREADME -XNEWS -XTODO -XAUTHORS
diff --git a/doc/en/index.docbook b/doc/en/index.docbook
new file mode 100644
index 0000000..bde0bc6
--- /dev/null
+++ b/doc/en/index.docbook
@@ -0,0 +1,185 @@
+<?xml version="1.0" ?>
+<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.1.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
+ <!ENTITY app "kio-locate">
+ <!ENTITY app_date "2005-09-15"> <!-- (YYYY-MM-DD) -->
+ <!ENTITY app_version "0.4.3"> <!-- (V.MM.LL) -->
+ <!ENTITY kio-locate "<application>&app;</application>">
+ <!ENTITY kappname "<application>&app; &app_version;</application>"><!-- Do *not* replace kappname-->
+
+ <!ENTITY my_email "tobivollebregt@gmail.com">
+
+ <!ENTITY package "kde-module"><!-- kdebase, kdeadmin, etc -->
+ <!ENTITY % addindex "IGNORE">
+ <!ENTITY % English "INCLUDE"><!-- change language only here -->
+
+
+ <!-- Do not define any other entities; instead, use the entities
+ from kde-genent.entities and $LANG/user.entities. -->
+]>
+
+
+<book lang="&language;">
+
+
+<bookinfo>
+<title>&kappname; Handbook</title>
+
+<authorgroup>
+<author>
+<firstname>Tobi</firstname>
+<othername></othername>
+<surname>Vollebregt</surname>
+<affiliation>
+<address><email>&my_email;</email></address>
+</affiliation>
+</author>
+<author>
+<firstname>Armin</firstname>
+<othername></othername>
+<surname>Straub</surname>
+<affiliation>
+<address><email>linux@arminstraub.de</email></address>
+</affiliation>
+</author>
+<author>
+<firstname>Michael</firstname>
+<othername></othername>
+<surname>Schuerig</surname>
+<affiliation>
+<address><email>michael@schuerig.de</email></address>
+</affiliation>
+</author>
+</authorgroup>
+
+<copyright>
+<year>2005</year>
+<holder>Tobi Vollebregt</holder>
+</copyright>
+<copyright>
+<year>2005</year>
+<holder>Armin Straub</holder>
+</copyright>
+<copyright>
+<year>2002</year>
+<holder>Michael Schuerig</holder>
+</copyright>
+<legalnotice>&FDLNotice;</legalnotice>
+
+<date>&app_date;</date>
+<releaseinfo>&app_version;</releaseinfo>
+
+<abstract>
+<para>
+&kio-locate; is a KDE I/O Slave for the locate command.
+</para>
+</abstract>
+
+<keywordset>
+<keyword>KDE</keyword>
+<keyword>kio-locate</keyword>
+<keyword>kio_locate</keyword>
+<keyword>kiolocate</keyword>
+<keyword>locate</keyword>
+<keyword>slocate</keyword>
+<keyword>kio-slave</keyword>
+<keyword>kio_slave</keyword>
+<keyword>kioslave</keyword>
+<keyword>search</keyword>
+</keywordset>
+
+</bookinfo>
+
+
+
+<chapter id="introduction">
+<title>Introduction</title>
+
+<!-- The introduction chapter contains a brief introduction for the
+application that explains what it does and where to report
+problems. Basically a long version of the abstract. Don't include a
+revision history. (see installation appendix comment) -->
+
+<para>
+&kio-locate; is a KDE I/O Slave for the locate command.
+</para>
+<para>
+ This means that you can use &kio-locate; by simply typing in konquerors address box. You can e.g. type <command>locate:index.html</command> to find all files that contain "index.html" in their name.
+</para>
+<para>
+There's even more: You can use &kio-locate; in all KDE applications that accept URLs.
+</para>
+<para>
+To find out more about &kio-locate; and to look for new versions, you should take a look at <ulink url="http://arminstraub.de">arminstraub.de</ulink>.
+</para>
+</chapter>
+
+
+<chapter id="using-kio-locate">
+<title>How to use this?</title>
+
+<para>
+ You can use &kio-locate; mostly as you use locate. Instead of typing <command>locate pattern</command> at a command prompt, you start the search with &kio-locate; directly in konqueror. You just enter <command>locate:pattern</command> as the address.
+</para>
+<para>
+ By default, a search <command>locate:pattern</command> is case insensitive if the pattern is lowercase. If the pattern is mixed- or uppercase the search is case sensitive. This default behaviour can be overridden.
+</para>
+<para>
+ <emphasis>Hint:</emphasis> Type <command>locater:config</command> in the konqueror address bar to show the configuration dialog. Likewise, <command>locater:help</command> shows this help document.
+</para>
+
+<sect1 id="kio-locate-patterns">
+<title>How to write patterns</title>
+
+<para>
+<itemizedlist>
+ <listitem><para>Regular wildcard characters may be used in the patterns passed to &kio-locate;: A star (*) matches any string with nonzero length, a question mark (?) matches a single character, and a character list ([abc-z]) matches the characters in the list. A character list can be inverted by putting a caret after the first square bracket ([^abc-z]).</para></listitem>
+ <listitem><para>Every plus (+) in a search is used just as a star (*) is. Instead of <command>locate:*.html</command> you may also type <command>locate:+.html</command>. This is because you can't use the star in konqueror. In other apps both ways are supported.</para></listitem>
+ <listitem><para>Should you need to use a plus in your search you have to escape it with a backslash. Instead of <command>locate:g++</command> you have to use <command>locate:g\+\+</command>.</para></listitem>
+ <listitem><para>Furthermore you can't use a slash as the last character of your query. O.k. you can, but KDE will ignore it. In such a case you can quote your pattern: Write <command>locate:"servicemenus/"</command> rather than <command>locate:servicemenus/</command>.</para></listitem>
+ <listitem><para>A search as e.g. <command>locate:~/*.doc</command> works as you might expect. This means that <command>~/</command> and <command>~user/</command> are expanded correctly at the beginning of the pattern.</para></listitem>
+ <listitem><para>You may add a filtering pattern after the first pattern, e.g. <command>locate:fish home</command> results in all files whose path contains fish AND home.</para></listitem>
+ <listitem><para>A filtering pattern may be inverted by prefixing it with an exclamation mark. E.g. <command>locate:fish !home</command> results in all files whose path contains fish AND NOT home.</para></listitem>
+ <listitem><para>Any number of filtering patterns may be used.</para></listitem>
+ <listitem><para>With <command>locate:</command> wildcard matching is performed with all patterns. If you're a regular expression guru, you might want to use <command>rlocate:</command>, which enables regexp matching for all filtering patterns (that is: all patterns except the first one).</para></listitem>
+</itemizedlist>
+</para>
+
+</sect1>
+
+<sect1 id="kio-locate-screenshot">
+<title>Take a look at &kio-locate;</title>
+
+<para>
+<screenshot>
+ <screeninfo>Here's a screenshot of &kio-locate;</screeninfo>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="screenshot.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Screenshot</phrase>
+ </textobject>
+ </mediaobject>
+</screenshot>
+</para>
+
+</sect1>
+
+</chapter>
+
+<chapter id="license">
+
+<title>License</title>
+
+&underFDL; <!-- FDL: do not remove -->
+&underGPL; <!-- GPL License -->
+
+<para>
+Also, I'd like to thank Google for their <ulink url="http://code.google.com/summerofcode.html">Summer Of Code Program</ulink> and Jonathan Riddell for being my mentor!
+</para>
+
+</chapter>
+
+&documentation.index;
+</book>
+
diff --git a/doc/en/screenshot.png b/doc/en/screenshot.png
new file mode 100644
index 0000000..efd4129
--- /dev/null
+++ b/doc/en/screenshot.png
Binary files differ
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..2714455
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,244 @@
+# kio-locate: KDE I/O Slave for the locate command
+#
+# Copyright (C) 2004 by Armin Straub
+# linux@arminstraub.de
+#
+# This file is distributed under the same license as kio-locate.
+msgid ""
+msgstr ""
+"Project-Id-Version: kio-locate\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-09-15 10:08+0200\n"
+"PO-Revision-Date: 2004-09-29 12:59+0200\n"
+"Last-Translator: Armin Straub <linux@arminstraub.de>\n"
+"Language-Team: German <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.3.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/kio_locate.cpp:499
+msgid "Locating %1 ..."
+msgstr "Suche %1 ..."
+
+#: ../src/kio_locate.cpp:614
+msgid "Finished."
+msgstr "Suche abgeschlossen."
+
+#: ../src/kio_locate.cpp:752
+msgid "Configure - kio-locate"
+msgstr "Einstellungen - kio-locate"
+
+#: ../src/kio_locate.cpp:755
+msgid "General"
+msgstr "Allgemeines"
+
+#: ../src/kio_locate.cpp:756
+msgid "Filters"
+msgstr "Filter"
+
+#: ../src/kio_locate.cpp:757
+msgid "Locate"
+msgstr "Locate"
+
+#: ../src/kio_locate.cpp:778
+msgid "Configuration succesfully updated."
+msgstr "Einstellungen wurden übernommen."
+
+#: ../src/kio_locate.cpp:780
+msgid "Configuration unchanged."
+msgstr "Einstellungen unverändert."
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:78
+msgid "KLocateConfigFilterWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:79
+msgid "Filter Settings"
+msgstr "Filter Einstellungen"
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:80
+msgid ""
+"A path must match at least one of the regular expressions in the White List "
+"and it must not match any of the expressions in the Black List for being "
+"displayed as a hit."
+msgstr "Damit ein Pfad als Treffer angezeigt wird, muss er mit mindestens einem regulären Ausdruck aus der White List übereinstimmen und darf mit keinem Eintrag aus der Black List übereinstimmen."
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:81
+msgid "&White List"
+msgstr "&White List"
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:82
+msgid "A path must match at least one of these regular expressions."
+msgstr "Pfade müssen mit mindestens einer dieser regulären Ausdrücke übereinstimmen."
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:83
+msgid ""
+"<i>Hint:</i> E.g. replacing the default '.' entry by '^/home/user/' will "
+"only allow hits in the home directory of user."
+msgstr "<i>Tipp:</i> Sie können z.B. den standardmäßigen Eintrag '.' durch '^/home/user/' ersetzen, um nur noch Treffer im Heimatverzeichnis von user anzuzeigen."
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:84
+msgid "&Black List"
+msgstr "&Black List"
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:85
+msgid "A path may not match any of these regular expressions."
+msgstr "Pfade dürfen mit keiner dieser regulären Ausdrücke übereinstimmen."
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:86
+msgid ""
+"<i>Hint:</i> Adding e.g. '/\\.' will no longer display hidden files (this "
+"will be unnecessary in some next version of kde though)."
+msgstr "<i>Tipp:</i> Fügen Sie z.B. '/\\.' hinzu, um versteckte Dateien bei der Suche zu ignorieren (in einer der nächsten KDE Versionen wird das unnötig sein)."
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:111
+msgid "KLocateConfigLocateWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:112
+msgid "Locate Settings"
+msgstr "Einstellungen für Locate"
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:113
+msgid ""
+"<p>kio-locate does not handle the settings of locate, because this setup "
+"varies among different distributions. There are even distributions that use "
+"replacements like slocate.</p>\n"
+"<p>To configure locate you should take a look at the manpage of locate. "
+"Since most distributions use cron for updating locate's database, it may "
+"also be useful to take a look at the manpage of crontab.</p>"
+msgstr "<p>Sie können die Einstellungen von locate nicht mit kio-locate vornehmen, da es dabei große Unterschiede zwischen verschiedenen Distributionen gibt. Einige verwenden sogar ganz andere Ersatzprogramme.</p>\n"
+"<p>Für die Einstellungen von locate lohnt es sich einen Blick in die Manpage zu locate zu werfen. Da die meisten Distributionen cron zur Aktualisierung der Datenbank für locate verwenden, kann es sich auch lohnen die Manpage zu crontab zu lesen.</p>"
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:115
+msgid "Locate Binary"
+msgstr "Locate Backend"
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:116
+msgid ""
+"Use these settings only if you really know what you do. Otherwise the "
+"default should be ok."
+msgstr "Verwenden Sie die folgenden Einstellung nur wenn Sie genau wissen, was Sie tun. Ansonsten sollten die Vorgaben genügen."
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:117
+msgid "Locate &binary:"
+msgstr "&Pfad zu locate:"
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:118
+msgid ""
+"<i>Hint:</i> You may for example choose to use slocate instead of plain old "
+"locate."
+msgstr "<i>Tipp:</i> Sie könnten hier z.B. slocate anstelle von locate verwenden."
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:119
+msgid "Additional &arguments:"
+msgstr "Zusätzliche &Argumente:"
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:120
+msgid ""
+"<i>Hint:</i> Do not use -r or -i here. The first will confuse kio-locate, "
+"and the latter can be changed through the \"Case sensitivity\" option."
+msgstr "<i>Tipp:</i> Verwenden Sie nicht -r oder -i. Ersteres verwirrt kio-locate und letzteres kann durch die Option \"Groß- und Kleinschreibung\" eingestellt werden."
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:870
+msgid "KLocateConfigWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:871
+msgid "General Settings"
+msgstr "Allgemeine Einstellungen"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:872
+msgid "Case se&nsitivity:"
+msgstr "&Groß- und Kleinschreibung"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:874
+msgid "Auto"
+msgstr "Auto"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:875
+msgid "Sensitive"
+msgstr "Verwenden"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:876
+msgid "Insensitive"
+msgstr "Ignorieren"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:877
+msgid ""
+"<i>Hint:</i> With \"Auto\" case sensitivity a pattern will be case "
+"insensitive if it is lowercase and case sensitive if it is mixed- or "
+"uppercase."
+msgstr "<i>Tipp:</i> Wenn Sie \"Auto\" auswählen wird eine Suche Groß- und Kleinschreibung nur dann unterscheiden, falls Sie nicht durchgehend klein geschrieben ist."
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:878
+msgid "Collapsing Search Results"
+msgstr "Verzeichnisse zusammenfassen"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:879
+msgid "&Collapse a directory with more hits:"
+msgstr "Verzeichnisse mit mehr Treffern &zusammenfassen."
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:880
+msgid "Collapse a directory with more hits."
+msgstr "Verzeichnisse mit mehr Treffern zusammenfassen."
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:881
+msgid "Text of a collapsed &directory:"
+msgstr "Anzeige einer &Verzeichnissuche:"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:882
+msgid ""
+"<i>Hint:</i> %1 is substituted by the number of hits and %2 by the name of "
+"the directory."
+msgstr "<i>Tipp:</i> %1 wird durch die Anzahl der Treffer und %2 durch den Verzeichnisnamen ersetzt."
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:883
+msgid "&Icon of a collapsed directory:"
+msgstr "&Icon für Verzeichnissuchen:"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:885
+msgid "Blue"
+msgstr "Blau"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:886
+msgid "Green"
+msgstr "Grün"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:887
+msgid "Grey"
+msgstr "Grau"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:888
+msgid "Orange"
+msgstr "Orange"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:889
+msgid "Red"
+msgstr "Rot"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:890
+msgid "Violet"
+msgstr "Violett"
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:891
+msgid "Yellow"
+msgstr "Gelb"
+
+#: ../src/tmphack/klocateconfig.cpp:35
+msgid "(%1 Hits) %2"
+msgstr "(%1 Treffer) %2"
+
+#: ../src/_translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+
+#: ../src/_translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..54def3e
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,244 @@
+# translation of kio_locate.po to French
+# kio-locate: KDE I/O Slave for the locate command
+#
+# Copyright (C) 2004 by Armin Straub
+# linux@arminstraub.de
+#
+# This file is distributed under the same license as kio-locate.
+# Laurent Rathle <lrathle@kde-france.org>, 2004.
+msgid ""
+msgstr ""
+"Project-Id-Version: kio_locate\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-09-15 10:08+0200\n"
+"PO-Revision-Date: 2004-10-21 16:52+0200\n"
+"Last-Translator: Laurent Rathle <lrathle@kde-france.org>\n"
+"Language-Team: French <kde-francophone@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.9\n"
+
+#: ../src/kio_locate.cpp:499
+msgid "Locating %1 ..."
+msgstr "Recherche de %1 en cours ..."
+
+#: ../src/kio_locate.cpp:614
+msgid "Finished."
+msgstr "Terminé."
+
+#: ../src/kio_locate.cpp:752
+msgid "Configure - kio-locate"
+msgstr ""
+
+#: ../src/kio_locate.cpp:755
+msgid "General"
+msgstr ""
+
+#: ../src/kio_locate.cpp:756
+msgid "Filters"
+msgstr ""
+
+#: ../src/kio_locate.cpp:757
+msgid "Locate"
+msgstr ""
+
+#: ../src/kio_locate.cpp:778
+msgid "Configuration succesfully updated."
+msgstr ""
+
+#: ../src/kio_locate.cpp:780
+msgid "Configuration unchanged."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:78
+msgid "KLocateConfigFilterWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:79
+msgid "Filter Settings"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:80
+msgid ""
+"A path must match at least one of the regular expressions in the White List "
+"and it must not match any of the expressions in the Black List for being "
+"displayed as a hit."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:81
+msgid "&White List"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:82
+msgid "A path must match at least one of these regular expressions."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:83
+msgid ""
+"<i>Hint:</i> E.g. replacing the default '.' entry by '^/home/user/' will "
+"only allow hits in the home directory of user."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:84
+msgid "&Black List"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:85
+msgid "A path may not match any of these regular expressions."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:86
+msgid ""
+"<i>Hint:</i> Adding e.g. '/\\.' will no longer display hidden files (this "
+"will be unnecessary in some next version of kde though)."
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:111
+msgid "KLocateConfigLocateWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:112
+msgid "Locate Settings"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:113
+msgid ""
+"<p>kio-locate does not handle the settings of locate, because this setup "
+"varies among different distributions. There are even distributions that use "
+"replacements like slocate.</p>\n"
+"<p>To configure locate you should take a look at the manpage of locate. "
+"Since most distributions use cron for updating locate's database, it may "
+"also be useful to take a look at the manpage of crontab.</p>"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:115
+msgid "Locate Binary"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:116
+msgid ""
+"Use these settings only if you really know what you do. Otherwise the "
+"default should be ok."
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:117
+msgid "Locate &binary:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:118
+msgid ""
+"<i>Hint:</i> You may for example choose to use slocate instead of plain old "
+"locate."
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:119
+msgid "Additional &arguments:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:120
+msgid ""
+"<i>Hint:</i> Do not use -r or -i here. The first will confuse kio-locate, "
+"and the latter can be changed through the \"Case sensitivity\" option."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:870
+msgid "KLocateConfigWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:871
+msgid "General Settings"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:872
+msgid "Case se&nsitivity:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:874
+msgid "Auto"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:875
+msgid "Sensitive"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:876
+msgid "Insensitive"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:877
+msgid ""
+"<i>Hint:</i> With \"Auto\" case sensitivity a pattern will be case "
+"insensitive if it is lowercase and case sensitive if it is mixed- or "
+"uppercase."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:878
+msgid "Collapsing Search Results"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:879
+msgid "&Collapse a directory with more hits:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:880
+msgid "Collapse a directory with more hits."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:881
+msgid "Text of a collapsed &directory:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:882
+msgid ""
+"<i>Hint:</i> %1 is substituted by the number of hits and %2 by the name of "
+"the directory."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:883
+msgid "&Icon of a collapsed directory:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:885
+msgid "Blue"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:886
+msgid "Green"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:887
+msgid "Grey"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:888
+msgid "Orange"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:889
+msgid "Red"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:890
+msgid "Violet"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:891
+msgid "Yellow"
+msgstr ""
+
+#: ../src/tmphack/klocateconfig.cpp:35
+msgid "(%1 Hits) %2"
+msgstr ""
+
+#: ../src/_translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+
+#: ../src/_translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
diff --git a/po/kio_locate.pot b/po/kio_locate.pot
new file mode 100644
index 0000000..b52727a
--- /dev/null
+++ b/po/kio_locate.pot
@@ -0,0 +1,241 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-09-15 10:08+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/kio_locate.cpp:499
+msgid "Locating %1 ..."
+msgstr ""
+
+#: ../src/kio_locate.cpp:614
+msgid "Finished."
+msgstr ""
+
+#: ../src/kio_locate.cpp:752
+msgid "Configure - kio-locate"
+msgstr ""
+
+#: ../src/kio_locate.cpp:755
+msgid "General"
+msgstr ""
+
+#: ../src/kio_locate.cpp:756
+msgid "Filters"
+msgstr ""
+
+#: ../src/kio_locate.cpp:757
+msgid "Locate"
+msgstr ""
+
+#: ../src/kio_locate.cpp:778
+msgid "Configuration succesfully updated."
+msgstr ""
+
+#: ../src/kio_locate.cpp:780
+msgid "Configuration unchanged."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:78
+msgid "KLocateConfigFilterWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:79
+msgid "Filter Settings"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:80
+msgid ""
+"A path must match at least one of the regular expressions in the White List "
+"and it must not match any of the expressions in the Black List for being "
+"displayed as a hit."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:81
+msgid "&White List"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:82
+msgid "A path must match at least one of these regular expressions."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:83
+msgid ""
+"<i>Hint:</i> E.g. replacing the default '.' entry by '^/home/user/' will "
+"only allow hits in the home directory of user."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:84
+msgid "&Black List"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:85
+msgid "A path may not match any of these regular expressions."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigfilterwidget.ui.cpp:86
+msgid ""
+"<i>Hint:</i> Adding e.g. '/\\.' will no longer display hidden files (this "
+"will be unnecessary in some next version of kde though)."
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:111
+msgid "KLocateConfigLocateWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:112
+msgid "Locate Settings"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:113
+msgid ""
+"<p>kio-locate does not handle the settings of locate, because this setup "
+"varies among different distributions. There are even distributions that use "
+"replacements like slocate.</p>\n"
+"<p>To configure locate you should take a look at the manpage of locate. "
+"Since most distributions use cron for updating locate's database, it may "
+"also be useful to take a look at the manpage of crontab.</p>"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:115
+msgid "Locate Binary"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:116
+msgid ""
+"Use these settings only if you really know what you do. Otherwise the "
+"default should be ok."
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:117
+msgid "Locate &binary:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:118
+msgid ""
+"<i>Hint:</i> You may for example choose to use slocate instead of plain old "
+"locate."
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:119
+msgid "Additional &arguments:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfiglocatewidget.ui.cpp:120
+msgid ""
+"<i>Hint:</i> Do not use -r or -i here. The first will confuse kio-locate, "
+"and the latter can be changed through the \"Case sensitivity\" option."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:870
+msgid "KLocateConfigWidget"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:871
+msgid "General Settings"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:872
+msgid "Case se&nsitivity:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:874
+msgid "Auto"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:875
+msgid "Sensitive"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:876
+msgid "Insensitive"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:877
+msgid ""
+"<i>Hint:</i> With \"Auto\" case sensitivity a pattern will be case "
+"insensitive if it is lowercase and case sensitive if it is mixed- or "
+"uppercase."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:878
+msgid "Collapsing Search Results"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:879
+msgid "&Collapse a directory with more hits:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:880
+msgid "Collapse a directory with more hits."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:881
+msgid "Text of a collapsed &directory:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:882
+msgid ""
+"<i>Hint:</i> %1 is substituted by the number of hits and %2 by the name of "
+"the directory."
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:883
+msgid "&Icon of a collapsed directory:"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:885
+msgid "Blue"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:886
+msgid "Green"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:887
+msgid "Grey"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:888
+msgid "Orange"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:889
+msgid "Red"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:890
+msgid "Violet"
+msgstr ""
+
+#: ../src/tmphack/klocateconfigwidget.ui.cpp:891
+msgid "Yellow"
+msgstr ""
+
+#: ../src/tmphack/klocateconfig.cpp:35
+msgid "(%1 Hits) %2"
+msgstr ""
+
+#: ../src/_translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+
+#: ../src/_translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
diff --git a/po/messages.sh b/po/messages.sh
new file mode 100755
index 0000000..818688c
--- /dev/null
+++ b/po/messages.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+# Modified by Tobi Vollebregt for use with kio-locate.
+
+# Inspired by Makefile.common from coolo
+# this script is used to update the .po files
+
+# To update the translations, you will need a specific gettext
+# patched for kde and a lot of patience, tenacity, luck, time ..
+
+
+# I guess one should only update the .po files when all .cpp files
+# are generated (after a make or scons)
+
+# If you have a better way to do this, do not keep that info
+# for yourself and help me to improve this script, thanks
+# (tnagyemail-mail tat yahoo d0tt fr)
+#
+
+SRCDIR=../src
+TIPSDIR=$SRCDIR/appdata
+
+KDEDIR=`kde-config --prefix`
+EXTRACTRC=extractrc
+KDEPOT=`kde-config --prefix`/include/kde/kde.pot
+XGETTEXT="xgettext -C -ki18n -ktr2i18n -kI18N_NOOP -ktranslate -kaliasLocale -x $KDEPOT "
+
+## check that kde.pot is available
+if ! test -e $KDEPOT; then
+ echo "$KDEPOT does not exist, there may be something wrong with your installation!"
+ XGETTEXT="xgettext -C -ki18n -ktr2i18n -kI18N_NOOP -ktranslate -kaliasLocale "
+fi
+
+## extract the strings
+echo "extracting the strings"
+
+echo -e 'i18n("_: NAME OF TRANSLATORS\\n"\n"Your names")\ni18n("_: EMAIL OF TRANSLATORS\\n"\n"Your emails")' > $SRCDIR/_translatorinfo.cpp
+
+## bad hack to get strings from *.ui files
+# Armin Straub <linux@arminstraub.de>
+UIC="uic -tr i18n"
+TMPHACK="$SRCDIR/tmphack"
+mkdir $TMPHACK || exit 1
+for F in "$SRCDIR/"*.ui; do
+ echo ".. preparing $F"
+ FN=$TMPHACK/$(basename "$F")
+ $UIC "$F" > "$FN.h" && $UIC -impl "$FN.h" "$F" > "$FN.cpp"
+done
+kconfig_compiler -d $TMPHACK $SRCDIR/*.kcfg $SRCDIR/*.kcfgc
+## bad hack to get strings from *.ui files
+
+$XGETTEXT `find $SRCDIR -name "*.cpp"` -o kio_locate.pot
+
+## bad hack to get strings from *.ui files
+rm -rf "$TMPHACK"
+## bad hack to get strings from *.ui files
+
+# remove the intermediate files
+rm -f $SRCDIR/_translatorinfo.cpp
+
+## now merge the .po files ..
+echo "merging the .po files"
+
+for i in `ls *.po`; do
+ msgmerge $i kio_locate.pot -o $i || exit 1
+done
+
+## finished
+echo "Done"
diff --git a/src/SConscript b/src/SConscript
new file mode 100644
index 0000000..141cd59
--- /dev/null
+++ b/src/SConscript
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# kio-locate
+#
+# Copyright (C) 2005 by Tobi Vollebregt
+# tobivollebregt@gmail.com
+#
+# Thanks to Google's Summer Of Code Program!
+#
+# Copyright (C) 2005 by Armin Straub
+# linux@arminstraub.de
+#
+# Adapted from the example shipping with bksys.
+# Thomas Nagy, 2004, 2005
+# Thanks for this great tool!
+
+Import('env')
+
+# The kioslave library is kio_test5.so and not libkio_test5.so (empty string)
+obj=env.kobject('kioslave')
+obj.target='kio_locate'
+obj.source="""
+ klocateconfig.kcfgc
+ klocateconfigwidget.ui
+ klocateconfigfilterwidget.ui
+ klocateconfiglocatewidget.ui
+ kio_locate.cpp
+ locater.cpp
+ pattern.cpp
+"""
+obj.libs='qt-mt kio'
+obj.linkflags='-module -avoid-version' # add more link flags
+obj.execute()
+
+# Install the protocol files
+env.KDEinstall('KDESERV', '', 'locate.protocol')
+env.KDEinstall('KDESERV', '', 'locater.protocol')
+env.KDEinstall('KDESERV', '', 'rlocate.protocol')
+
+# Install the searchprovider file
+env.KDEinstall('KDESERV', '/searchproviders', 'locate.desktop')
diff --git a/src/kio_locate.cpp b/src/kio_locate.cpp
new file mode 100644
index 0000000..9beee51
--- /dev/null
+++ b/src/kio_locate.cpp
@@ -0,0 +1,1035 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Thanks to Google's Summer Of Code Program! *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <algorithm>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <kapplication.h>
+#include <kconfigdialog.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kuser.h>
+#include <qfile.h>
+
+#include "kio_locate.h"
+#include "klocateconfig.h"
+#include "klocateconfigwidget.h"
+#include "klocateconfigfilterwidget.h"
+#include "klocateconfiglocatewidget.h"
+
+using namespace KIO;
+
+
+static const QString queryQuery = "q";
+static const QString queryDirectory = "directory";
+static const QString queryCase = "case";
+static const QString queryRegExp = "regexp";
+
+static const QString iconToStringTable[] = {
+ "folder", "folder_green", "folder_grey", "folder_orange",
+ "folder_red", "folder_violet", "folder_yellow"
+};
+
+
+/////////////////////////////////////////////////////////////////////
+// HELPERS
+
+/**
+ * Determines if a string contains unescaped wildcard characters.
+ * Currently, wildcard characters are: * + ? [ ]
+ * For older versions of Konqueror: + behaves identical to *
+ * @param s the string to inspect
+ */
+static bool hasWildcards(const QString& s)
+{
+ for (unsigned int i = 0; i < s.length(); ++i) {
+ if ((s[i] == '*' || s[i] == '+' || s[i] == '?' || s[i] == '[' || s[i] == ']') && (i < 1 || s[i-1] != '\\'))
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Converts a string containing shell wildcard characters (globbing characters)
+ * to a regular expression. This function takes care of escaped wildcards and
+ * any regexp special characters which happen to be in the string.
+ * @param s the string to convert
+ * @return the converted string
+ */
+static QString convertWildcardsToRegExp(QString s)
+{
+ bool in_set = false;
+
+ // No support for regexp searches.
+ // (Konqueror makes passing chars like "/" almost impossible anyway.)
+ // Note that this converts actual wildcards to escaped wildcards (\wildcard),
+ // and escaped wildcards to 'triple'-escaped wildcards (\\\wildcard).
+ s = QRegExp::escape(s);
+
+ // Walk through the string, converting \wildcard to regexp and
+ // \\\wildcard back to \wildcard.
+ for (unsigned i = 1; i < s.length(); ++i) {
+ //DEBUGSTR << s.left(i+1) << endl;
+ if (i < 3 || s[i-3] != '\\' || s[i-2] != '\\') {
+ // If it was an unescaped character (now possibly escaped once)
+ if (s[i-1] == '\\') {
+ // If it actually was escaped once
+ if (!in_set) {
+ // If it's NOT inside a character set, we need to convert *?[
+ if (s[i] == '*' || s[i] == '+') {
+ s = s.left(i-1) + "[^/]*" + s.mid(i+1);
+ i += 3; // 3 == strlen("[^/]*")-strlen("\\*")
+ } else if (s[i] == '?') {
+ s = s.left(i-1) + "[^/]" + s.mid(i+1);
+ i += 2; // 2 == strlen("[^/]")-strlen("\\*")
+ } else if (s[i] == '[') {
+ s = s.left(i-1) + s.mid(i);
+ --i;
+ in_set = true;
+ }
+ } else {
+ // If it's inside a character set, we need to convert ]^
+ // and to unescape everything else.
+ if (s[i] == ']') {
+ s = s.left(i-1) + s.mid(i);
+ --i;
+ in_set = false;
+ } else if (s[i] == '^' && i >= 2 && s[i-2] == '[') {
+ s = s.left(i-1) + s.mid(i);
+ --i;
+ } else {
+ s = s.left(i-1) + s.mid(i);
+ }
+ }
+ }
+ } else {
+ // If it's an escaped character, remove the extra escape characters.
+ s = s.left(i-3) + s.mid(i-1);
+ i -= 2; // 2 == strlen("\\\\")-strlen("")
+ }
+ }
+ return s;
+}
+
+
+/**
+ * Determines if path includes a trailing slash.
+ * @param path the path to inspect
+ */
+static bool hasTrailingSlash(const QString& path)
+{
+ int n = path.length();
+ return ((n > 0) && (path[n-1] == '/'));
+}
+
+
+/**
+ * Strips a trailing slash / from a path.
+ * @param path the path to strip the slash off
+ */
+static QString stripTrailingSlash(const QString& path)
+{
+ int n = path.length();
+ if ((n > 0) && (path[n-1] == '/')) {
+ return path.left(n-1);
+ }
+ return path;
+}
+
+
+/**
+ * Add a trailing slash / to a path if there is none yet.
+ * @param path the path to append the slash to
+ */
+static QString addTrailingSlash(const QString& path)
+{
+ int n = path.length();
+ if ((n > 0) && (path[n-1] == '/')) {
+ return path;
+ }
+ return path + '/';
+}
+
+
+static void addAtom(UDSEntry& entry, unsigned int uds, const QString& s)
+{
+ UDSAtom a;
+ a.m_uds = uds;
+ a.m_str = s;
+ entry.append(a);
+}
+
+
+static void addAtom(UDSEntry& entry, unsigned int uds, long l)
+{
+ UDSAtom a;
+ a.m_uds = uds;
+ a.m_long = l;
+ entry.append(a);
+}
+
+
+static const UDSEntry pathToUDSEntry(const QString& path, const QString& display,
+ const QString& url = QString::null, const QString& icon = QString::null)
+{
+ UDSEntry entry;
+ addAtom(entry, KIO::UDS_NAME, display);
+
+ if (!path.isEmpty()) {
+ struct stat info;
+ lstat(path.local8Bit(), &info);
+
+ addAtom(entry, KIO::UDS_SIZE, info.st_size);
+ addAtom(entry, KIO::UDS_ACCESS, info.st_mode);
+ addAtom(entry, KIO::UDS_MODIFICATION_TIME, info.st_mtime);
+ addAtom(entry, KIO::UDS_ACCESS_TIME, info.st_atime);
+ addAtom(entry, KIO::UDS_CREATION_TIME, info.st_ctime);
+
+ struct passwd * user = getpwuid(info.st_uid);
+ struct group * group = getgrgid(info.st_gid);
+ addAtom(entry, KIO::UDS_USER, ((user != NULL) ? user->pw_name : "???" ));
+ addAtom(entry, KIO::UDS_GROUP, ((group != NULL) ? group->gr_name : "???" ));
+
+ if (url.isEmpty()) {
+ // List an existing file.
+ addAtom(entry, KIO::UDS_URL, "file:" + path);
+
+ mode_t type = info.st_mode;
+ if (S_ISLNK(type)) {
+ QString slink = QString::null;
+ char buff[1000];
+ int n = readlink(path, buff, 1000);
+ if (n != -1) {
+ buff[n] = 0;
+ slink = buff;
+ }
+ addAtom(entry, KIO::UDS_LINK_DEST, slink);
+ } else {
+ type &= S_IFMT;
+ }
+ addAtom(entry, KIO::UDS_FILE_TYPE, type);
+
+#ifdef HAVE_UDS_HIDDEN
+ if (path.contains("/.")) {
+ addAtom(entry, KIO::UDS_HIDDEN, 1);
+ }
+#endif
+ } else {
+ // List a locate link.
+ addAtom(entry, KIO::UDS_URL, url);
+ addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
+ }
+ } else {
+ addAtom(entry, KIO::UDS_URL, url);
+ }
+
+ if (!icon.isEmpty()) {
+ addAtom(entry, KIO::UDS_ICON_NAME, icon);
+ }
+
+ return entry;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// INITIALIZATION
+
+LocateProtocol::LocateProtocol(const QCString &pool_socket, const QCString &app_socket)
+ : SlaveBase("kio_locate", pool_socket, app_socket)
+{
+ DEBUGSTR << "LocateProtocol::LocateProtocol()" << endl;
+
+ connect(&m_locater, SIGNAL(found(const QStringList&)),
+ this, SLOT(processLocateOutput(const QStringList&)));
+ connect(&m_locater, SIGNAL(finished()),
+ this, SLOT(locateFinished()));
+
+ m_baseDir = NULL;
+ m_curDir = NULL;
+}
+
+
+LocateProtocol::~LocateProtocol()
+{
+ DEBUGSTR << "LocateProtocol::~LocateProtocol()" << endl;
+
+ delete m_baseDir;
+}
+
+
+const LocateRegExp& LocateProtocol::getRegExp() const
+{
+ return m_locateRegExp;
+}
+
+
+int LocateProtocol::getCollapseDirectoryThreshold() const
+{
+ return m_config.m_collapseDirectoryThreshold;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// KIO STUFF
+
+void LocateProtocol::setUrl(const KURL& url)
+{
+ if (url.protocol() != "locater") {
+ QString pattern = KURL::decode_string(url.url());
+ pattern = pattern.mid(url.protocol().length() + 1);
+
+ KURL newUrl;
+ newUrl.setProtocol("locater");
+
+ if (pattern.isEmpty() || pattern == "/") {
+ // Give help.
+ newUrl.setPath("help");
+ } else if (hasTrailingSlash(pattern)) {
+ // Detect auto-completion from within konqueror and "stop"
+ // this search.
+ newUrl.setPath("autosearch");
+ newUrl.addQueryItem(queryQuery, pattern);
+ } else if (url.protocol() == "rlocate") {
+ // Standard regexp search.
+ newUrl.setPath("search");
+ newUrl.addQueryItem(queryQuery, pattern);
+ newUrl.addQueryItem(queryRegExp, "1");
+ } else {
+ // Standard wildcard search.
+ newUrl.setPath("search");
+ newUrl.addQueryItem(queryQuery, pattern);
+ }
+ m_url = newUrl;
+
+ DEBUGSTR << "Redirect: " << m_url << endl;
+ } else {
+ m_url = url;
+ }
+ // Perhaps this will be unneccessary most times, but who knows...
+ updateConfig();
+}
+
+void LocateProtocol::get(const KURL& url)
+{
+ DEBUGSTR << "LocateProtocol::get(" << url << ")" << endl;
+
+ setUrl(url);
+
+ if (isSearchRequest()) {
+ if (m_locater.binaryExists()) {
+ error(KIO::ERR_IS_DIRECTORY, QString::null);
+ } else {
+ QString html = i18n("<h1>\"%1\" could not be started.</h1><p>Please note that kio-locate can't be used on its own. You need an additional program for doing searches. Typically this is the command line tool <i>locate</i> that can be found in many distributions by default. You can check if the correct tool is used by looking at the <a href=\"locater:config\">setting</a> \"Locate Binary\".<p>Besides the mentioned tool <i>locate</i>, kio-locate can use any tool that uses the same syntax. In particular, it was reported to work with <i>slocate</i> and <i>rlocate</i>.").arg(m_locater.binary());
+ outputHtml(html);
+ }
+ } else if (isConfigRequest()) {
+ configRequest();
+ } else if (isHelpRequest()) {
+ helpRequest();
+ } else {
+ // What's this?
+ error(KIO::ERR_DOES_NOT_EXIST, QString::null);
+ }
+}
+
+
+void LocateProtocol::stat(const KURL& url)
+{
+ DEBUGSTR << "LocateProtocol::stat(" << url << ")" << endl ;
+
+ setUrl(url);
+
+ if (isSearchRequest() || isConfigRequest() || isHelpRequest()) {
+ bool isDir = isSearchRequest() && m_locater.binaryExists();
+ /// \todo Is UDS_NAME used for anything in stat? If so we should
+ /// at least strip of the protocol part.
+ UDSEntry entry;
+ addAtom(entry, KIO::UDS_NAME, url.decode_string(url.url()));
+ addAtom(entry, KIO::UDS_FILE_TYPE, isDir ? S_IFDIR : S_IFREG);
+ statEntry(entry);
+ finished();
+ /// \todo Somehow locate: and locate:/ is thought to be a directory
+ /// by konqueror anyway. How to change this?
+ } else {
+ // What's this?
+ error(KIO::ERR_DOES_NOT_EXIST, QString::null);
+ }
+}
+
+
+void LocateProtocol::listDir(const KURL& url)
+{
+ DEBUGSTR << "LocateProtocol::listDir(" << url << ")" << endl ;
+
+ setUrl(url);
+
+ if (isSearchRequest()) {
+ searchRequest();
+ } else if (isConfigRequest() || isHelpRequest()) {
+ error(KIO::ERR_IS_FILE, QString::null);
+ } else {
+ // What's this?
+ error(KIO::ERR_DOES_NOT_EXIST, QString::null);
+ }
+}
+
+
+void LocateProtocol::mimetype(const KURL& url)
+{
+ DEBUGSTR << "LocateProtocol::mimetype(" << url << ")" << endl ;
+
+ setUrl(url);
+
+ if (isSearchRequest()) {
+ if (m_locater.binaryExists()) {
+ mimeType("inode/directory");
+ } else {
+ mimeType("text/html");
+ }
+ } else if (isConfigRequest() || isHelpRequest()) {
+ mimeType("text/html");
+ }
+ finished();
+}
+
+
+void LocateProtocol::outputHtml(const QString& body)
+{
+ mimeType("text/html");
+
+ QString theData = "<html><body>" + body + "</body></html>";
+ data(theData.local8Bit());
+ finished();
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// SEARCHING
+
+bool LocateProtocol::isSearchRequest()
+{
+ return m_url.path() == "search";
+}
+
+
+void LocateProtocol::searchRequest()
+{
+ // Reset old values.
+ m_caseSensitivity = caseAuto;
+ m_useRegExp = false;
+ m_locatePattern = QString::null;
+ m_locateDirectory = QString::null;
+ m_regExps.clear();
+ m_pendingPath = QString::null;
+
+ delete m_baseDir;
+ m_baseDir = NULL;
+ m_curDir = NULL;
+
+ updateConfig();
+
+ QString query = m_url.queryItem(queryQuery);
+ m_locateDirectory = addTrailingSlash(m_url.queryItem(queryDirectory));
+
+ QString caseSensitivity = m_url.queryItem(queryCase);
+ if (caseSensitivity == "sensitive") {
+ m_caseSensitivity = caseSensitive;
+ } else if (caseSensitivity == "insensitive") {
+ m_caseSensitivity = caseInsensitive;
+ }
+
+ QString useRegExp = m_url.queryItem(queryRegExp);
+ if (!useRegExp.isEmpty() && useRegExp != "0") {
+ m_useRegExp = true;
+ }
+
+ // Split query into components. The first component is the query
+ // for locate. The others are filtering regular expressions. They are
+ // delimited by (not escaped) whitespace.
+ // If the last component starts with two backslahes \\, then the search
+ // is only to be done within the directory following them.
+ query = query.simplifyWhiteSpace();
+ int s = 0;
+ int n = query.length();
+ bool regexp;
+ QString display;
+ for (int i = 0; i <= n; i++) {
+ if ((i == n) || ((query[i] == ' ') && (i > 0)
+ && (query[i-1] != '\\') && (i-s > 0))) {
+ QString temp = query.mid(s, i-s);
+ QString part = partToPattern(temp, s==0);
+ if (s == 0) {
+ // We don't want to show the escaped regexpified string to
+ // the user, so we store the string we get in for later display.
+ display = temp;
+ // This is the same check as in partToPattern.
+ // ie. regexp is used if locate pattern contains wildcards,
+ // or regexp searching was enabled.
+ regexp = hasWildcards(temp);
+ m_locatePattern = part;
+ } else {
+ // For each regular expression determine if it should be
+ // case sensitive.
+ m_regExps += LocateRegExp(part, !isCaseSensitive(part));
+ }
+ s = i+1;
+ }
+ }
+
+ DEBUGSTR << "Pattern: " << m_locatePattern << endl;
+ DEBUGSTR << "Directory: " << m_locateDirectory << endl;
+
+ // We set up the regexp used to see whether the match was in the
+ // directory part or the filename part of a path.
+ m_locateRegExp = LocateRegExp(convertWildcardsToRegExp(m_locatePattern), !isCaseSensitive(m_locatePattern));
+
+ // Now perform the search...
+ infoMessage(i18n("Locating %1 ...").arg(display));
+
+ bool started = m_locater.locate(m_locatePattern, !isCaseSensitive(m_locatePattern), regexp);
+
+ if (!started) {
+ DEBUGSTR << "Locate could not be found." << endl;
+ finished();
+ }
+}
+
+
+bool LocateProtocol::isCaseSensitive(const QString& text)
+{
+ if (m_caseSensitivity == caseSensitive) {
+ return true;
+ } else if (m_caseSensitivity == caseInsensitive) {
+ return false;
+ } else if (m_config.m_caseSensitivity == caseSensitive) {
+ return true;
+ } else if (m_config.m_caseSensitivity == caseInsensitive) {
+ return false;
+ } else {
+ return text != text.lower();
+ }
+}
+
+
+void LocateProtocol::addHit(const QString& path, int subItems)
+{
+ // DEBUGSTR << "LocateProtocol::addHit( " << path << ", " << subItems << " )" << endl;
+ if (QFile::exists(path)) {
+ if (subItems > 0) {
+ m_entries += pathToUDSEntry(path, pathToDisplay(path, subItems), makeLocaterUrl(path), iconToStringTable[m_config.m_collapsedIcon]);
+ } else {
+ m_entries += pathToUDSEntry(path, pathToDisplay(path));
+ }
+ }
+}
+
+
+void LocateProtocol::addPreviousLocateOutput()
+{
+ if (m_baseDir == NULL) {
+ return;
+ }
+ // m_baseDir->debugTrace();
+ if (m_locateDirectory == "/") {
+ // Allow toplevel directories to collapse (e.g. when locating "/usr/").
+ m_baseDir->prepareListing(this, 0);
+ } else {
+ m_baseDir->prepareListing(this, m_locateDirectory.length());
+ }
+ m_baseDir->listItems(this);
+ delete m_baseDir;
+ m_baseDir = NULL;
+ m_curDir = NULL;
+
+ listEntries(m_entries);
+ m_entries.clear();
+}
+
+
+void LocateProtocol::processPath(const QString &path, const QString &nextPath)
+{
+ if (!nextPath) {
+ // We need to know the next path, so we remember this path for later processing.
+ m_pendingPath = path;
+ } else if (!nextPath.startsWith(path + '/')) {
+ if (isMatching(path)) {
+ if ((m_baseDir != NULL) && !path.startsWith(m_baseDir->m_path)) {
+ addPreviousLocateOutput();
+ }
+ // Add path to current directory.
+ if (m_baseDir == NULL) {
+ int p = path.find('/', 1);
+ QString base = path;
+ if (p >= 0) {
+ base = path.left(p+1);
+ }
+ m_baseDir = new LocateDirectory(NULL, base);
+ m_curDir = m_baseDir;
+ }
+ m_curDir = m_curDir->addPath(path);
+ }
+ }
+}
+
+
+void LocateProtocol::processLocateOutput(const QStringList& items)
+{
+ // I don't know if this really necessary, but if we were signaled, we'll
+ // better stop.
+ if (wasKilled()) {
+ m_locater.stop();
+ return;
+ }
+ // Go through what we have found.
+ QStringList::ConstIterator it = items.begin();
+ if (m_pendingPath) {
+ processPath(m_pendingPath, *it);
+ m_pendingPath = QString::null;
+ }
+ for (; it != items.end();) {
+ QString path = *it;
+ ++it;
+ processPath(path, it != items.end() ? *it : QString::null);
+ }
+}
+
+
+void LocateProtocol::locateFinished()
+{
+ // Add any pending items.
+ if (m_pendingPath) {
+ processPath(m_pendingPath, "");
+ m_pendingPath = QString::null;
+ }
+ addPreviousLocateOutput();
+
+ DEBUGSTR << "LocateProtocol::locateFinished" << endl;
+ infoMessage(i18n("Finished."));
+ finished();
+}
+
+
+QString LocateProtocol::partToPattern(const QString& part, bool forLocate)
+{
+ DEBUGSTR << "BEG part: " << part << endl;
+ QString pattern = part;
+ // Unescape whitespace.
+ pattern.replace("\\ ", " ");
+ // Unquote quoted pattern.
+ int n = pattern.length(), index;
+ if ((n > 1) && (pattern[0] == '"') && (pattern[n-1] == '"')) {
+ pattern = pattern.mid(1, n-2);
+ }
+
+ // We can't do regular expression matching on the locate pattern,
+ // the regular expression format used by locate is incompatible
+ // with the format used by QRegExp.
+ if (!m_useRegExp || forLocate) {
+ // Escape regexp characters for filtering pattern, and for locate,
+ // but the latter only if it is actually necessary to pass a regexp to locate.
+ // (ie. the pattern contains wildcards.)
+ if (!forLocate || hasWildcards(pattern)) {
+ pattern = convertWildcardsToRegExp(pattern);
+ } else {
+ // Special case for locate pattern without wildcards:
+ // Unescape all escaped wildcards.
+ pattern.replace("\\*", "*");
+ pattern.replace("\\+", "+");
+ pattern.replace("\\?", "?");
+ pattern.replace("\\[", "[");
+ pattern.replace("\\]", "]");
+ }
+ }
+
+ // Special treatment for the pattern used for locate:
+ if (forLocate) {
+ // Replace ~/ and ~user/ at the beginning (as the shell does)
+ if ((pattern.length() > 0) && (pattern[0] == '~')) {
+ index = pattern.find('/');
+ if (index >= 0) {
+ QString name = pattern.mid(1, index-1);
+ QString homeDir;
+ if (name.isEmpty()) {
+ homeDir = KUser(KUser::UseRealUserID).homeDir();
+ } else {
+ homeDir = KUser(name).homeDir();
+ }
+ if (!homeDir.isEmpty()) {
+ pattern.replace(0, index, homeDir);
+ }
+ }
+ }
+ pattern.replace("\\~", "~");
+ }
+ DEBUGSTR << "END part: " << pattern << endl;
+ return pattern;
+}
+
+
+bool LocateProtocol::isMatching(const QString& path)
+{
+ // The file has to belong to our directory.
+ if (!path.startsWith(m_locateDirectory)) {
+ return false;
+ }
+ // And it has to match at least one regular expression in the whitelist.
+ if (!m_config.m_whiteList.isMatchingOne(path)) {
+ return false;
+ }
+ // And it may not match any regular expression in the blacklist.
+ if (m_config.m_blackList.isMatchingOne(path)) {
+ return false;
+ }
+ // And it has to match against all regular expressions specified in the URL.
+ if (!m_regExps.isMatchingAll(path)) {
+ return false;
+ }
+ // And it must not solely match m_locateDirectory.
+ return m_locateRegExp.isMatching(path.mid(m_locateDirectory.length()));
+}
+
+
+QString LocateProtocol::pathToDisplay(const QString& path, int subItems)
+{
+ // Split off the directory part. If it is not just the minimal '/'.
+ QString display = path;
+ if ((m_locateDirectory != "/") && display.startsWith(m_locateDirectory)) {
+ display = display.mid(m_locateDirectory.length());
+ }
+ if (subItems > 0) {
+ // Can't use m_collapsedDisplay.arg(subItems).arg(display); here
+ // because user might forget to type %1 or %2, or type it twice.
+ // In both cases the result of arg() is undefined.
+ QString output = m_config.m_collapsedDisplay, temp;
+ temp.setNum(subItems);
+ output.replace("%1", temp);
+ output.replace("%2", display);
+ display = output;
+ }
+ return display;
+}
+
+
+QString LocateProtocol::makeLocaterUrl(const QString& directory)
+{
+ KURL url(m_url);
+ url.removeQueryItem(queryDirectory);
+ url.addQueryItem(queryDirectory, directory);
+ return url.url();
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// CONFIG
+
+bool LocateProtocol::isConfigRequest()
+{
+ return m_url.path() == "config";
+}
+
+
+void LocateProtocol::configRequest()
+{
+ // This flag is used to show either a "succesful" or an "unchanged" message
+ // in configFinished().
+ m_configUpdated = false;
+
+ // Don't show it twice. During my tests I never got there however.
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialog *dialog = new KConfigDialog(0, "settings", KLocateConfig::self(),
+ KDialogBase::IconList,
+ KDialogBase::Default|KDialogBase::Ok|KDialogBase::Cancel|KDialogBase::Help,
+ KDialogBase::Ok, true);
+ dialog->setCaption(i18n("Configure - kio-locate"));
+ dialog->setIcon(SmallIcon("find"));
+
+ dialog->addPage(new KLocateConfigWidget(), i18n("General"), "package_settings");
+ dialog->addPage(new KLocateConfigFilterWidget(), i18n("Filters"), "filter");
+ dialog->addPage(new KLocateConfigLocateWidget(), i18n("Locate"), "find");
+
+ // React on user's actions.
+ connect(dialog, SIGNAL(settingsChanged()), this, SLOT(updateConfig()));
+ connect(dialog, SIGNAL(finished()), this, SLOT(configFinished()));
+
+ dialog->show();
+ qApp->enter_loop();
+ delete dialog;
+}
+
+
+void LocateProtocol::configFinished()
+{
+ DEBUGSTR << "LocateProtocol::configFinished" << endl;
+
+ qApp->exit_loop();
+
+ QString html;
+ if (m_configUpdated) {
+ html = i18n("Configuration succesfully updated.");
+ } else {
+ html = i18n("Configuration unchanged.");
+ }
+ outputHtml("<h1>" + html + "</h1>");
+}
+
+
+void LocateProtocol::updateConfig()
+{
+ // It's not needed to update the config if it's still up to date.
+ DEBUGSTR << "LocateProtocol::updateConfig" << endl;
+
+ KLocateConfig::self()->readConfig();
+ m_config.m_caseSensitivity = (LocateCaseSensitivity) KLocateConfig::caseSensitivity();
+ m_config.m_collapseDirectoryThreshold = KLocateConfig::collapseDirectoryThreshold();
+ m_config.m_collapsedDisplay = KLocateConfig::collapsedDisplay();
+ m_config.m_collapsedIcon = (LocateCollapsedIcon) KLocateConfig::collapsedIcon();
+ m_config.m_whiteList = KLocateConfig::whiteList();
+ m_config.m_blackList = KLocateConfig::blackList();
+
+ m_locater.setupLocate(KLocateConfig::locateBinary(),
+ KLocateConfig::locateAdditionalArguments());
+
+ m_configUpdated = true;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// HELP
+
+bool LocateProtocol::isHelpRequest()
+{
+ return m_url.path() == "help";
+}
+
+
+void LocateProtocol::helpRequest()
+{
+ // Redirect the user to our help documents.
+ redirection("help:/kio-locate/");
+ finished();
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// SEARCH STRUCTURES
+
+LocateDirectory::LocateDirectory(LocateDirectory *parent, const QString& path)
+{
+ m_parent = parent;
+ m_path = path;
+ m_childs.setAutoDelete(true);
+ m_itemsCount = 0;
+}
+
+
+LocateDirectory *LocateDirectory::addPath(const QString& path)
+{
+ if (path.startsWith(m_path)) {
+ QString relPath = path.mid(m_path.length());
+ int p = relPath.findRev('/');
+ if (p >= 0) {
+ LocateDirectory *child = getSubDirectory(relPath.left(p));
+ child->addItem(relPath.mid(p+1));
+ return child;
+ }
+ addItem(relPath);
+ return this;
+ }
+ if (m_parent != NULL) {
+ return m_parent->addPath(path);
+ }
+ // This should not happen
+ return this;
+}
+
+
+LocateDirectory *LocateDirectory::getSubDirectory(const QString& relPath)
+{
+ QString base = relPath;
+ int p = relPath.find('/');
+ if (p >= 0) {
+ base = relPath.left(p);
+ }
+ LocateDirectory *child = m_childs.find(base);
+ if (child == NULL) {
+ child = new LocateDirectory(this, addTrailingSlash(m_path + base));
+ m_childs.insert(base, child);
+ }
+ if (p >= 0) {
+ return child->getSubDirectory(relPath.mid(p+1));
+ }
+ return child;
+}
+
+
+void LocateDirectory::addItem(const QString& path)
+{
+ m_items += LocateItem(m_path + path, 0);
+ m_itemsCount++;
+}
+
+
+int LocateDirectory::countMatchingItems(const LocateProtocol* protocol, int skip)
+{
+ int count = 0;
+ LocateItems::ConstIterator item = m_items.begin();
+ for (; item != m_items.end(); ++item) {
+ if ((*item).m_subItems) {
+ count += (*item).m_subItems;
+ } else if (protocol->getRegExp().isMatching((*item).m_path.mid(skip))) {
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+void LocateDirectory::prepareListing(const LocateProtocol* protocol, int skip)
+{
+ int n = m_path.length(), newSkip = n;
+ if (skip > newSkip) newSkip = skip;
+
+ // Recursively walk through all childs.
+ LocateDirectoriesIterator child(m_childs);
+ for (; child.current(); ++child) {
+ child.current()->prepareListing(protocol, newSkip);
+ }
+
+ // Set m_fullCount to the total number of childs matching the pattern.
+ m_fullCount = countMatchingItems(protocol, newSkip);
+
+ // Collapse if directory part matches.
+ LocateDirectory* parent = m_parent;
+ if (parent == NULL) {
+ parent = this;
+ }
+ if (n > skip && protocol->getRegExp().isMatching(m_path.mid(skip))) {
+ // Directory part matches.
+ m_childs.clear();
+ m_items.clear();
+ m_itemsCount = 0;
+ parent->m_items += LocateItem(m_path, m_fullCount);
+ ++parent->m_itemsCount;
+ if (m_fullCount != 0) {
+ parent->m_items += LocateItem(m_path, 0);
+ ++parent->m_itemsCount;
+ }
+ }
+
+ // Collapse if we got too many hits.
+ int maxHits = protocol->getCollapseDirectoryThreshold();
+ if (n > skip && maxHits != 0 && m_itemsCount > maxHits) {
+ if (m_parent != NULL) {
+ m_parent->m_items += LocateItem(m_path, m_fullCount);
+ ++m_parent->m_itemsCount;
+ } else {
+ m_items.clear();
+ m_items += LocateItem(m_path, m_fullCount);
+ ++m_itemsCount;
+ }
+ } else {
+ // Propagate items to parent.
+ // (only root LocateDirectory runs listItems)
+ if (m_parent != NULL) {
+ m_parent->m_items += m_items;
+ m_parent->m_itemsCount += m_itemsCount;
+ }
+ }
+}
+
+
+void LocateDirectory::listItems(LocateProtocol *protocol)
+{
+ LocateItems::ConstIterator item = m_items.begin();
+ for (; item != m_items.end(); ++item) {
+ protocol->addHit(stripTrailingSlash((*item).m_path), (*item).m_subItems);
+ }
+}
+
+
+void LocateDirectory::debugTrace(int level)
+{
+ QString ws;
+ ws.fill(' ', level);
+ DEBUGSTR << ws << m_path << endl;
+ LocateItems::ConstIterator item = m_items.begin();
+ for (; item != m_items.end(); ++item) {
+ DEBUGSTR << ws << "+ " << (*item).m_path << endl;
+ }
+ LocateDirectoriesIterator child(m_childs);
+ for (; child.current(); ++child) {
+ child.current()->debugTrace(level+2);
+ }
+}
+
+
+LocateItem::LocateItem()
+{
+}
+
+
+LocateItem::LocateItem(const QString& path, int subItems)
+{
+ m_path = path;
+ m_subItems = subItems;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// INVOKATION
+
+extern "C"
+{
+ int kdemain(int argc, char **argv)
+ {
+ // We use KApplication instead of KInstance here, because we use a
+ // config dialog and such gui stuff.
+ KApplication app(argc, argv, "kio_locate", false, true);
+
+ DEBUGSTR << "*** Starting kio_locate " << endl;
+
+ if (argc != 4) {
+ DEBUGSTR << "Usage: kio_locate protocol domain-socket1 domain-socket2" << endl;
+ exit(-1);
+ }
+
+ LocateProtocol slave(argv[2], argv[3]);
+ slave.dispatchLoop();
+
+ DEBUGSTR << "*** kio_locate Done" << endl;
+ return 0;
+ }
+}
+
+
+#include "kio_locate.moc"
diff --git a/src/kio_locate.h b/src/kio_locate.h
new file mode 100644
index 0000000..d5df32c
--- /dev/null
+++ b/src/kio_locate.h
@@ -0,0 +1,273 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Thanks to Google's Summer Of Code Program! *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+/**
+ * \mainpage KDE I/O Slave for the locate command
+ *
+ * \section intro_sec What is kio-locate?
+ * kio-locate is a KDE I/O Slave for the locate command.
+ * <p>This means that you can use kio-locate by simply typing in konquerors
+ * address box. You can e.g. type "locate:index.html" to find all files that
+ * contain "index.html" in their name.
+ * <p>There's even more: You can use kio-locate in all KDE applications, that
+ * accept URLs.
+ * <p>To find out more about kio-locate and to look for new versions, you
+ * should take a look at
+ * <a href="http://arminstraub.de/browse.php?page=programs_kiolocate">
+ * arminstraub.de</a>.
+ *
+ *
+ * \todo Implement locater:help.
+ *
+ * \todo If a directory matches then don't add its childs.\ At least make
+ * this configurable.
+ *
+ * \todo Use different icons for collapsed directories and make this
+ * configurable.
+ *
+ * \todo After updating the settings show a success html message instead
+ * of a blank page.
+ *
+ * \todo Check if locate's databases are outdated and warn about that.
+ *
+ * \todo Provide a means of updating the locate database (configurable
+ * of course).
+ */
+
+#ifndef _kio_locate_H_
+#define _kio_locate_H_
+
+#include <qcstring.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qdict.h>
+#include <qvaluelist.h>
+
+#include <kio/global.h>
+#include <kio/slavebase.h>
+
+#include "locater.h"
+#include "pattern.h"
+
+class QCString;
+
+class KURL;
+
+
+class LocateItem;
+class LocateDirectory;
+
+typedef QValueList<LocateItem> LocateItems;
+typedef QDict<LocateDirectory> LocateDirectories;
+typedef QDictIterator<LocateDirectory> LocateDirectoriesIterator;
+
+enum LocateCaseSensitivity { caseAuto, caseSensitive, caseInsensitive };
+enum LocateCollapsedIcon { iconBlue, iconGreen, iconGrey, iconOrange, iconRed, iconViolet, iconYellow };
+
+
+/**
+ * Implementation of the kioslave for the locate protocol.
+ *
+ * Enables you to enter "locate:pattern" wherever an URL can be used
+ * in KDE.
+ */
+class LocateProtocol : public QObject, public KIO::SlaveBase
+{
+ Q_OBJECT
+ public:
+ /**
+ * Constructor
+ */
+ LocateProtocol(const QCString &pool_socket, const QCString &app_socket);
+
+ virtual ~LocateProtocol();
+
+ /**
+ * Returns the mimetype "inode/directory".
+ * @param url the url to work on
+ */
+ virtual void mimetype(const KURL& url);
+
+ /**
+ * Raises an error so that eyerone notes we are dealing with
+ * directories only.
+ * @param url the url to work on
+ */
+ virtual void get(const KURL& url);
+
+ /**
+ * Marks the url as a directory.
+ * @param url the url to work on
+ */
+ virtual void stat(const KURL& url);
+
+ /**
+ * Searches for the pattern specified in the url.
+ * Every file found is listed.
+ * @param url the url to work on
+ */
+ virtual void listDir(const KURL& url);
+
+ /**
+ * Actually report a hit.
+ * If subItems > 0 then this hit is a "directory subsearch".
+ * @param path the path of the hit
+ * @param subItems the number of hits beneath this one
+ * (or 0 for a regular hit)
+ */
+ virtual void addHit(const QString& path, int subItems = 0);
+
+ const LocateRegExp& getRegExp() const;
+ int getCollapseDirectoryThreshold() const;
+
+ private slots:
+ void processLocateOutput(const QStringList& items);
+ void locateFinished();
+ void configFinished();
+ void updateConfig();
+
+ private:
+ Locater m_locater;
+ KURL m_url;
+
+ QString m_locatePattern;
+ LocateRegExp m_locateRegExp; // Equals m_locatePattern, but regexp.
+ QString m_locateDirectory; // Includes a trailing slash.
+ LocateRegExpList m_regExps; // List of extra filtering regexps.
+
+ LocateCaseSensitivity m_caseSensitivity; // For current search.
+ bool m_useRegExp;
+
+ // Options
+ struct
+ {
+ LocateCaseSensitivity m_caseSensitivity; // Default case sensitivity.
+ int m_collapseDirectoryThreshold; // Maximum number of hits in a directory
+ // before a directory search is created
+ QString m_collapsedDisplay; // Format string used for collapsed directories.
+ LocateCollapsedIcon m_collapsedIcon; // Icon used for collapsed directories.
+ LocateRegExpList m_whiteList; // Path must match at least one regexp in this list.
+ LocateRegExpList m_blackList; // Path may not match any regexp in this list.
+ } m_config;
+
+ bool m_configUpdated; // Used in config methods to check if config was cancelled or okay'ed.
+ QString m_pendingPath; // Must be processed as soon as new output becomes available.
+
+ LocateDirectory *m_baseDir; // The toplevel directory, e.g. "/usr/".
+ LocateDirectory *m_curDir; // The current directory (while locating).
+
+ KIO::UDSEntryList m_entries; // Used to cache a lot of hits and list them all at once.
+
+ QString partToPattern(const QString& part, bool forLocate);
+ bool isMatching(const QString& file);
+ QString pathToDisplay(const QString& path, int subItems = 0);
+ void addPreviousLocateOutput();
+ void processPath(const QString &path, const QString &nextPath);
+
+ bool isSearchRequest();
+ bool isConfigRequest();
+ bool isHelpRequest();
+
+ void searchRequest();
+ void configRequest();
+ void helpRequest();
+
+ bool isCaseSensitive(const QString& text);
+
+ /**
+ * Composes a locater:... url for the current search parameters
+ * bound to a given directory.
+ * @param directory the directory in which we should be searched
+ * @return the url that envokes the specified search
+ */
+ QString makeLocaterUrl(const QString& dir);
+
+ /**
+ * This function has to check whether we are accessed via the standard
+ * locater protocol. If this is not the case we have to redirect
+ * this access to an access via the locater protocol.
+ * There are other ways, that I have tried to achieve this:
+ * - Use a search provider. This works perfectly for konqueror but
+ * not for any other KDE application.
+ * - Really use redirection. But this turned out not to be a good
+ * solution. Seemed not to work from OpenDialogs ...
+ * - So no we just internally redirect... Works, isn't it?
+ */
+ void setUrl(const KURL& url);
+
+ void outputHtml(const QString& body);
+};
+
+
+/**
+ * Internally used class to represent a hit as kio-locate will
+ * report.
+ *
+ * This may either be a path as given by locate or a directory
+ * search (if the number of subItems is set to a positive number).
+ */
+class LocateItem
+{
+ public:
+ LocateItem();
+ LocateItem(const QString& path, int subItems);
+
+ public:
+ QString m_path;
+ int m_subItems;
+};
+
+
+/**
+ * Internally used class to represent a directory while kio-locate
+ * gathers data from locate.
+ *
+ * Each directory has a list of files found in just that directory
+ * and a list of all subdirectories.
+ */
+class LocateDirectory
+{
+ public:
+ LocateDirectory(LocateDirectory *parent, const QString& path);
+
+ LocateDirectory *addPath(const QString& path);
+ void prepareListing(const LocateProtocol* protocol, int skip);
+ void listItems(LocateProtocol *protocol);
+ void debugTrace(int level = 0);
+
+ public:
+ QString m_path; // Including trailing slash.
+ LocateDirectory *m_parent;
+ LocateDirectories m_childs;
+ LocateItems m_items;
+ int m_itemsCount;
+ int m_fullCount;
+
+ LocateDirectory *getSubDirectory(const QString& relPath);
+ void addItem(const QString& path);
+ int countMatchingItems(const LocateProtocol *protocol, int skip);
+};
+
+#endif
diff --git a/src/kio_locate.kcfg b/src/kio_locate.kcfg
new file mode 100644
index 0000000..e0fdddc
--- /dev/null
+++ b/src/kio_locate.kcfg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+
+ <kcfgfile name="kio_locaterc"/>
+ <include>klocale.h</include>
+ <group name="General">
+ <entry name="caseSensitivity" type="Int">
+ <label>Case sensitivity</label>
+ <whatsthis>0 for automatic case sensitivity determination (lowercase pattern -> case insensitive, upper- or mixedcase pattern -> case sensitive), 1 for case sensitive and 2 for case insensitive.</whatsthis>
+ <default>0</default>
+ </entry>
+
+ <entry name="collapseDirectoryThreshold" type="Int">
+ <label>Collapse directory</label>
+ <whatsthis>Collapse a directory with more hits.</whatsthis>
+ <default>5</default>
+ </entry>
+
+ <entry name="collapsedDisplay" type="String">
+ <label>How to display a collapsed directory entry</label>
+ <whatsthis>Hint: %1 is substituted by the number of hits, %2 by the name of the directory.</whatsthis>
+ <default code="true">i18n("(%1 Hits) %2")</default>
+ </entry>
+
+ <entry name="collapsedIcon" type="Int">
+ <label>Icon to use for a collapsed directory entry</label>
+ <whatsthis>0-Blue, 1-Green, 2-Grey, 3-Orange, 4-Red, 5-Violet, 6-Yellow</whatsthis>
+ <default>1</default>
+ </entry>
+ </group>
+
+ <group name="Filtering">
+ <entry name="whiteList" type="StringList">
+ <label>White list</label>
+ <whatsthis>A path must match at least one of these regular expressions.</whatsthis>
+ <default>.</default>
+ </entry>
+
+ <entry name="blackList" type="StringList">
+ <label>Black list</label>
+ <whatsthis>A path may not match any of these regular expressions.</whatsthis>
+ <default></default>
+ </entry>
+ </group>
+
+ <group name="Locate">
+ <entry name="locateBinary" type="String">
+ <label>Locate Binary</label>
+ <default></default>
+ </entry>
+
+ <entry name="locateAdditionalArguments" type="String">
+ <label>Additional Arguments for locate</label>
+ <whatsthis>Do not use -r or -i here. The first will confuse kio-locate, while the latter can be changed through the caseSensitivity option.</whatsthis>
+ <default></default>
+ </entry>
+ </group>
+
+</kcfg>
diff --git a/src/klocateconfig.kcfgc b/src/klocateconfig.kcfgc
new file mode 100644
index 0000000..453e65f
--- /dev/null
+++ b/src/klocateconfig.kcfgc
@@ -0,0 +1,6 @@
+# Code generation options for kconfig_compiler
+File=kio_locate.kcfg
+ClassName=KLocateConfig
+Singleton=true
+Mutators=true
+# will create the necessary code for setting those variables
diff --git a/src/klocateconfigfilterwidget.ui b/src/klocateconfigfilterwidget.ui
new file mode 100644
index 0000000..523e5c9
--- /dev/null
+++ b/src/klocateconfigfilterwidget.ui
@@ -0,0 +1,105 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KLocateConfigFilterWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KLocateConfigFilterWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>497</width>
+ <height>347</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>KLocateConfigFilterWidget</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="title">
+ <string>Filter Settings</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>A path must match at least one of the regular expressions in the White List and it must not match any of the expressions in the Black List for being displayed as a hit.</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ <widget class="KEditListBox" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_whiteList</cstring>
+ </property>
+ <property name="title">
+ <string>&amp;White List</string>
+ </property>
+ <property name="buttons">
+ <set>Remove|Add</set>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>A path must match at least one of these regular expressions.</string>
+ </property>
+ </widget>
+ <widget class="KEditListBox" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_blackList</cstring>
+ </property>
+ <property name="title">
+ <string>&amp;Black List</string>
+ </property>
+ <property name="buttons">
+ <set>Remove|Add</set>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>A path may not match any of these regular expressions.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Hint:&lt;/i&gt; E.g. replacing the default '.' entry by '^/home/user/' will only allow hits in the home directory of user.</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Hint:&lt;/i&gt; Adding e.g. '/\.' will no longer display hidden files (this will be unnecessary in some next version of kde though).</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>keditlistbox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>keditlistbox.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/klocateconfiglocatewidget.ui b/src/klocateconfiglocatewidget.ui
new file mode 100644
index 0000000..e1fb7a8
--- /dev/null
+++ b/src/klocateconfiglocatewidget.ui
@@ -0,0 +1,211 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KLocateConfigLocateWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KLocateConfigLocateWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>567</width>
+ <height>385</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>KLocateConfigLocateWidget</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Locate Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;kio-locate does not handle the settings of locate, because this setup varies among different distributions. There are even distributions that use replacements like slocate.&lt;/p&gt;
+&lt;p&gt;To configure locate you should take a look at the manpage of locate. Since most distributions use cron for updating locate's database, it may also be useful to take a look at the manpage of crontab.&lt;/p&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Locate Binary</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Use these settings only if you really know what you do. Otherwise the default should be ok.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>Locate &amp;binary:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_locateBinary</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>kcfg_locateBinary</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Hint:&lt;/i&gt; If you don't specify a value here (which is the default), kio-locate will automatically pick slocate, rlocate or locate (in that order).</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout12</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Additional &amp;arguments:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_locateAdditionalArguments</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>kcfg_locateAdditionalArguments</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Hint:&lt;/i&gt; Do not use -r or -i here. The first will confuse kio-locate, and the latter can be changed through the "Case sensitivity" option.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/klocateconfigwidget.ui b/src/klocateconfigwidget.ui
new file mode 100644
index 0000000..2e1d946
--- /dev/null
+++ b/src/klocateconfigwidget.ui
@@ -0,0 +1,391 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KLocateConfigWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KLocateConfigWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>442</width>
+ <height>298</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>KLocateConfigWidget</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>General Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Case se&amp;nsitivity:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_caseSensitivity</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>284</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>Auto</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Sensitive</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Insensitive</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_caseSensitivity</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Hint:&lt;/i&gt; With "Auto" case sensitivity a pattern will be case insensitive if it is lowercase and case sensitive if it is mixed- or uppercase.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Collapsing Search Results</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Collapse a directory with more hits:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_collapseDirectoryThreshold</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>141</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>kcfg_collapseDirectoryThreshold</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Collapse a directory with more hits.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Text of a collapsed &amp;directory:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_collapsedDisplay</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>100</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>kcfg_collapsedDisplay</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Hint:&lt;/i&gt; %1 is substituted by the number of hits and %2 by the name of the directory.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Icon of a collapsed directory:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_collapsedIcon</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>161</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>Blue</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Green</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Grey</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image2</pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Orange</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image3</pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Red</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image4</pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Violet</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yellow</string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image6</pixmap>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_collapsedIcon</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<images>
+ <image name="image0">
+ <data format="PNG" length="1136">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000043749444154388d9d946f88545518c67f3b7347cea551eec49833667507ffac635acdd29a2e19ecc6464ebb8a9b164cf9410721dc224a0824a2c22ff9519420c824d3faa0ad41ba94e55ad6ba90b42bacb962e68cecb273d91d766eeb65ee69f6b8b70f77d6dd30f0cff3e570e03dbff739cf793941ee459aa1c756b66f7c66f3be4fae3b2ae4483922c20fcd5565ab3455527397c0a06136d4a79ab7b6373436ac935a7c4ed7b727fa13517dbcb7af3797fff1bdd741fe0da0dd29d358b07a49726dfb6be9d674464423f37216c8d112ab5735d4f65c90976c5588a361a0b8152cc231216289650076beef024a56442c154f36665e6d6a79715b6a4562d1804d4d61c8459f009b083d97dc9adca0bc219461a019f7a3ac6bd3604d04cca733f54d9bb26fb4ad493d9f77e4e4e12f3a3eb70bb96be90dd9cdabeb137512b4812117a120a2e9f48d42ce0284ae19213b2e893b68910560f5f96021428ddbf66dcf6ec9bc935eaecf270475e824cdecdbaec2d335820316946c97b8d0b95884fc28146c1080841aa119115b163c114e98d2190020105b9a5e98dd9279f395943e5f84fc4824908812888409e62c1f100febe41cb05d4081d0fc3a14e01212447484590bcc0208d84ee11fa4bc3195b3acaeaeaa1e522e86809c33b5afd629bfa16b038a00a02396d582300002a9b5ed2df1a8884e41c5cdd1829c0d86d0b16515a2a69b0a40daa0cb6a13618410e642118e99008148d4a84dc674c3e56666b82ef45d011c10c23f28673845f95024b8d20520b95806b6b6c617602c5b0910bc2ea5b362cdba171e9b17bacf01064bd03f04f130cc9e03c50a941c9093201d70ca20c7fda6b20cb36729d6d7db649b25894708f6ffe54c58574e7f17b0ce779debfca1e78c3b0185eb902b42caf4937215c86ae852829ca8aed51ba44c971d1b6c32cd121176d101636efc71446c71102555a9a2d1d4bcbe5569687a002211702a604bffdac5aa3bbbecbbd627e1e514bcb4c661494c838a2437a4f8f8eb9ec2b99f3b0fcb627f9706605de8faa9e374eff9ec86ba551725c4abce50d3f0a92949c6a06d05240cffbf29146d3a7f2954f61fe9ecce9f3fbc17277f0a18d70064313fda79ace3ab7463dd4a1401b73aa733472b22a029054d26800b4ad077c962ff91de42c7b1cf0e4aebec0194fd273009109c9a2ecb1ab412cb9f6b8e3f38f7819a80ff58b68452191206ac5f020d0f0301508ee2cbef072a1feeed3873fa9bddefabb173079994c380c7ff29d9b2e3ada3bddec4f1cb9e776ac4f38e5ef5bc3f46bcffe8eae5b2b775e7f121c36cfb0844addfea361286392fb3bbfbd743bf79deef639e37569906962b9e77b46b58a65a769d246cae0366df163853b127331bb7ef1f1e1f1e9b860e8f78debb7bba078da56dbbd0c4a23b72798b34a19b9b3e3d70e88c4f3e7e7658366ede7792b0d90a84ef1e3843229a7a34bdb3bb6fc79eeeabb127321fdcbbcb5bd135c4524f09c37c96bbcdb2aa7f01e2660a8dfb27078d0000000049454e44ae426082</data>
+ </image>
+ <image name="image1">
+ <data format="PNG" length="1276">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000004c349444154388d955451681c55143dbb99a46fcaa6ddd5adce486a76a5d5cc62c4867eb8512909feb816d12952bbb18211a9b445a8890af6332a141205493e84b622a42dd5742b9444a19248216d699b9d62da8e92a52f1fa5b392907936e3ce257dcdf8319bb4552bf5c1e5f26698f3ce3be7ce89044180ffbb5cd7ad2d5c2c6c1a991ad94b826accf566a7e33a8d669b6965d299390088fc4fe0c8b035dc34668fedf075ff7591140ff349fe872ef4a2231dad15adeff7bed7fb230028f705771328968a0d23d3236f8a98e8749bddc76cb223b806a4f5f46a0ebed62a597354a2b5beeb434da87703bbaecb0a970acdae70eb3a9ee928ea6b749fcff0f8a10b874c2ef9cec4bac4d336d935eeac0b1d3a100346c5288410b544544ba04749125454817ddf8f162e155a2c61edd634ed259bd9caee93bb8f18f5c60562b495a5d8262858519c2d42870e2da6c1220b5c700000632c4992161de9343a65a72eb126b1a038334eddc0c5811d4c631f6637661bb8e4d0a50e8ad3bbae741755a6466dcf8e400046ccc0b49c06270e971c000081c0185b09895502a2c1be66afce346766a2a7a74f1bf164bc7bc3ba0d0db6b421204020e8313d4231aae11e8fa4a141d334d88a054772f8d207c042b660204111c6980a059a35693d020051e18905482c966539145a86cd973e20012619e2c9046c69812481aaef212964ec12e00150b002313cc0057f1c3781a8edd9cfa931b59e2d3150c2ae2a2a8808baa2c381b36c3053aa872b0c980720aa7b861a30acb666ad8dceac13897297b7a51a520f3ab2aa599589239c906d9ca12ccbcb4c97bb209020806e0f6d2e65322d9e7eb6f86b714d8d99376fd5c66a5f5457a9cc931ebc450fceac0363a501f5a108a6a253f0681e80844712524a78c2839c97900b125804b43a0d3b1a3f82a96f4504caaac9d2f973d1dc93b95376c99e606010520002c837986049064771966f40145ed9f7fcdbd3a030b42773e835fa914be6a02a71e8313d7ea664bd1c6d4db5cef933fe10f3d82d48201bcf42650990224092b0a4fd9261aa12ca65d41bd8bbfe13f434f7221dcb000a603b7670ecec619b5bf659052ab0a579cb0fa3a5d1dfb4262dc33d1e8ed0125349a1399240007c0998c93c3ae21d482b69f84410d2c7a1f387ff1c192b145a74a36ff8cbe15f1400c83665a7477f1a3d9e90890c971c04111a5235c647380569a6239fec442b6b0d0ff708f62c0f064ef4d9e529fe45f7abbb8eeedabe6b1e6ad54f5555a1433fea949c37a0a15110c155dc2a631f2a54b4c75ad1117f1b716880049cd9320ae78f7907be3b38d4a21b9ff77f367429b321b31c95cbb1e9ceb891ee13ddfb5a9e6ff9c0555c08cd01f7a6919629e4625bd05edf0ef8a11456a918f41defbb629fb1faba5eeb1aca6fcbcfabf5ea9d7976771e0f5bc34d63e5b1efb575f127ca49078692418e99d06bf5f06f9cf771f0e783dec091812183197d3d7b7a2e679a33ff1ee841102c57a55241d7375d7b769edab9307e633cb8735dbd7e7531bf2f3f696c36deeaffaabf3ea804777dfbf7fac783f1e278b26da0ede4e095c1200882a0b25009064f0fde30b61b07cc77cccce5e2e5ff04bc27701004e829f4bc607e6bfe3e717d62b173a0d332361bdbf71fd81fabdca8dc17e83d81e7e6e66a739fe63e4e6d4b7d9d7d25fbd4c4b989fb065caabf0002b81688eda386d60000000049454e44ae426082</data>
+ </image>
+ <image name="image2">
+ <data format="PNG" length="1233">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000049849444154388d95945d68145714c7ffbb199b3b4ddacea2a13b6583b9904067a9d40d15dc102a2b163158b0115f126cadd052941644fbd04a2b69f0a5d207212d48fd409a4ac192521b93076b22a19b209a2cc4246b35cda446338b59666ee93073dc0cb97dd8754df1033d70b8dc0f7efccfc73d2129259ed59c05273c7069a03193c97ceae41dab7d677b07b91435d61ad3baae2f0240e899c08bc0d8c4d8ea81c181f7225a6497d160f0befebe5b8e702e0b57e84d6f347db8f793bd5900509e963995995a353832b843abd63e6a5ad7f41a0284cd9b26781dafc52cbcd99bb3ae75db8a017818ec2c384af67a963bc209373537fd158944026bceaa1ebb3ab625b790db9b58934842c173d66d0be413a00056ce0a99b3e692239c15e6ac19f3fff5a1bea096c03e30757dca18b932f201e77c1b1185cffc70e604636c9c29ec5dcef9665ecfabccdb26c82d02110056ce020303632c4a01fd635a26475014a95896a50c5c18d8a9ebfa672d6fb7d40308810033677e0942a045b54a2144283b9d45a43a0230402c0858c202001008ac9abd44010570c1b3b3d9cac648e3bdb0396dc6f55afd50727db201400841f1318f72458fe94ce4458888c0631c080022020504555101000c0ce45285c634d511ce6a2b674500204c444b4c6121222a2a0896ad2550341a857005fcc0072d16effdc00700e4f2390857000a98aaa8af64ae64560340d89ab3d631c6aa98c28000600a2b2509705c078c95cec1ca0a0140850ae10a38c201168148754481821a73da7cddf77d84852b36f33abe5290281705281646b802da2aad1cfef2482c61c1110eee470a86502ad5f262ce111bb213d9ca8ab61d6d4b4a95b2a546aba90c0a01c82358390bdaf31a6a63b5081542208f80254078024121c082bd00f2a8d8214b80b652c3c60dad48ac7b136e3e5f3577d7bca02492894be675f32a8ff18d44042b6f81d77330858188cab9242a2a15ae28e75e652af8ab71341a49a094b2688cd70e0ef66c52e246dcce64323f0b2136f8e457e8511d5af523c207408b0406062770108d71180d06788c830820f2317c6d24e8ebefb92cf2d67818000c6ef48d4d8cfda956ab705ce7e1eeb8df0541b1a88944021b532d88d71b0000211cfc78f6e4c2c953df7e63aca96b3f7feefc4505008cb5c6dfe62f660f02c4414518032baf22100000ad46038fc511d1b4e2087009996b53c18953dffd81c0ffbaf3ab8317b7bfb3bd509e15aaaa8237f09fcc69b39d698c97bf6d49315318a27551e8515eee1c73d644cfd99e5c4fff99ef53a9d4b103fb0edce19c3f183c52caa21764a8fb74f7e1d1e15139393e29ed795b4e4e4dca991b33d2b33d29a5949e27a5677bb2f7dcc542ebd6d6df5b36b5bcd5dbd3bb4216e4034ec9ffb7191d1ead3f7eecf8447a382de76fcd4bdbb6a52cc8b2cdcfdbb2b3e3c89de4fae4a1ce8e4eddb6ed87808f047b9e87aea35d7bba4f77dfb3efda72b98d0e8fde6bdbd1d6dfbab535951e4a2b8f033e122ca5c4cc8d19ede017077f4b0fa5a59452dab62dbb8e76dd4a36a73eefece87cd9befb78954f044b29d17baeb7f9c8e12373e9a134ed7e7ff7afaddb5a9bd343e98aa7013e112c3d59b1e7e33dbb126b13fbf7efdbffd42a97fb7fa1807393b78b271b0000000049454e44ae426082</data>
+ </image>
+ <image name="image3">
+ <data format="PNG" length="1135">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000043649444154388d9d946f8814651cc73fbbfbdcf14ccdc5acac3a2b1beca679adfd6305cd3b5438c3b235ad4c0bb67ca18b905e1275d09b080b09ea45ef34903249bc8490eb4597889282751d78b527dec549c2edc9c5ee72b7dc4e3aec3cade34e2f66cf5b4af0cff7e5cceff9f079bebf6142dc470c89d6bdc1dc7aa067ed21575d6f51557beae1889c5fb2dccaec4ce01e81a1cec78c153b37a5ba3b3b3a3747a57ae8c79fcf8e6846e25a6e3497fff0c8c4dbcae56f0071b7d08eb8b1b47b5bf2ad74573a13d6e542ac3c155bd1d9d1d1ae8a83978bba154560703bb0a94b9930e53280e1096b54b9d4523119cdbc907cf3d5f5e95d89787209e5b180532e82ae1116164e7930a054fea66148c390cc2b29aede024b4130b32abe22fbcababda9355b3628ab54effbfef037f9b27535fb727a7b22d9b11ca584531e0329d1f430d8c360e7d10442e946346a2a3b6c102b590c0308296939b0bd6b4f6647f67ded89f42214684a91dd9d780f1c0fb410e5311cb782664441e5c11a03b708484005649b0c83e52522323e36a10008a697988b333bb2ef681d6f2cc2958d5214e88920221cc2ca832ee7a06a76f1d29f13804e4bb84d6a719376a0152058b4ad7f94e226371af3aef20fb90eb8e008401a60e7c19d7ddf34271d10041168cb12b44b810110ec5e9f7a5146a2915ba6a2c9c4cea3490394d578eeccad5b4a900aa406280c5db6c4e32c3623320e103422e1762d9634709d86a9f26d4bc33e44cc3e6b36058402094ee39c12c96034b933b62cc64a809052d7edcd6b9edcd8623ef520351bac49981a01230ac1365065a855a00ed46d102e888adfa4ab705bdbb0f48d283d0b3211b24b2337ce5d2c9d0a9e1d2d0d0d9e3b791ed701bb08561ecc5453cf0d432cbf22ac5be68e91c28af4a08c0c0e06a0118d194f9b068f86948b2b6a155e7a7edd265c21686d817ad8b77315e0825b86ba82bae5d7130cc0a2d7b1e7bd86786029ca05b77c85c1335f144ffe30d43b32aece86002ab69a5ebb34dc156d5f196366125ae743adecc3ab65dfb45e8120a027e0912c15a313826d58d5698aa3a76b7dbd9f9c3fd83bb46ff0b23aead6991600136535ddd77ff2f8f235e99540d0dfbef46f2e00a54046c14c82b90e07897415a5d230b933878b5f1fef3bfaeb4575c4525cc1df06a1d9ffc4e454a9f45c2ab17efe82e8020834be04cb378d2420be11a29d7ebd35c5d86fdfd6fabefcf8fc6787ceed1bfad33daa5c0a80c7edd2b32df9ae973b71c3cbf57bdea59f3c2f77c2f30a7f78cda94e8d7bfd8776feb56595f1a914b4fb37bc43e211b970e060e617efc231cf1bffddf3aad53962adea157227d4fedda9d37193cd40db1d81cdc9ac36b716bedb73cd9b29cc41670ade40ef07935b5619fba564c95d59fe3752a27db52b7e64e6c231cff33caf70a95f1dd8db753a1e6113a0df33b039a9987c7ce0f3f4f0c0e19ef1cc6af32329eed3f27fd682402ac633f1887c967bedb2917f01b258f688d5631b0b0000000049454e44ae426082</data>
+ </image>
+ <image name="image4">
+ <data format="PNG" length="1154">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000044949444154388d9d945d6c145514803fb677e50e5dc8349466568ab4b1a05b6a4c1112b6d2041a6a604c7dd8a431a962848607bb068dc89b890fbe49786b8da8c410a02406d104e98326954068496abb468b8b8add461a7702851dcbd8b92cb71d1f66a5e527043cc97db973f39d6fce393965fc8fb060f16b96f5eafbebd67fe44ebad3b78aea9fb8904b2667f5df00f6161bf1284009d1a494cf776e48bed9d2dab4d58472c775a25d954d337d3f0e9ccf4eaabd4011c14383176c96b2e195864497dd66b7c72db9d41fcfe3b88a96c6647d6e70f062dc532b24980aaea0ef025b8245b531d6282d67b29e1a058ab582951d4f275e4fb5d93bea1b122bfd892cf9d13c0889a514ce5026e28fe76e298d2961b1822bb78d25947554cb64676b7277635be716f7724e9f387cf050c1534e6a5b6a7b7d73d333f86ea4707104b4812980892ceaaa8b19938f2929aba452d74c8de5c21f681012a2dd9b6adeeae87a77afb1295505607805d289c43b68054246fc6c063559400ac0c9423e8f522005b882052a2697a254b1425033ae398780484b254f76ec4a7719ede92a04a054782ae3116266c4ff3d0b425281c2b894c1700b61238544010a40ca4552c8f25a580d44d010f13545a599c1f74103da075d827b2e0a3050e0e400f051a5022ad090f714521a65866089855c05942320926eb052152b6aabd0255b4d78f0f12fe7a8302bc02b8430ad3090a5ef90572a34064cd334e252d65bb01c0d1115ab78829ac412941bbed00adc3c7e6610a4846829218000ff5698dcf114aa2421854436b788c4f6f4aab8e0390494e179532f3cbbda36ea1a634ce5612c0397734457ad275a1e85ab79987241dd04cf0bf34e2bf4ac44690d562d46dbcb2c7eb183e8f215d11b438353ee12f96da4df513f0c9cfcf2349e1bd6512bd89c829811764687a6281f7c50f3ec65b38ddcbd07d96a83340088c7ccb5264675c4859bbd6733c7b9f48b8f06ac44f848c81028e695a2340d325e8bdcb10763479a8aba46d0a07e1e09063e7cefd7bed1cce72e5c13000313eee98193bdc34ded1d1b7172509df86f904ad052c30c09eb9b60db4ea88c8386c2449edc5727bc13c77a4ef53b4e8f0343b640098071cdb5beeffa8f35b5a63670a320d085d058cf1bad9a04246d58d7021848e5933f3f383bf8c9fedf8e9eee3f90d1ea0b057920b863571cbde87c9d3adbdf9968a85d6b4cba730b44c839e0b238f8809367e0d3835edfe183a77a27c67b5c189afb45ee5d6d5d75567afac0be62d07724087e3a1704678e07c1d858101483308a41f0d799e1d9cfb6a6b24929df061e0716dc85c1de62df796109967dd3bef9fbe943dd41f0e78520989e0e6ec7f5ebc1f0feeea99dd535bd16348785bf7fd85bed7b2f5395e64b1776a5dc606c6c8e39323c73a4bd63b451cab404eb7e960f3426d458f881657e7cfdc0be20989a0e2ef4744f75d5d51c3621093cf620e0038d016ae0a9e31b1bcf1f69b7479231f906a1e543c77d8de7c1d798d0082c7c142884c6ff02ebb2fb9af346c6500000000049454e44ae426082</data>
+ </image>
+ <image name="image5">
+ <data format="PNG" length="1194">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000047149444154388d95945f6c145514c6bf9d4ef50e4ee3dcb8c4dd80a6230bba95865283ba4422d4c43f0d3eb8ca832598501e88c43e348d4f0d26c0830f92a8498d12f1c18855b4f4c1204d508201bb25c0ee9a005d024d072d74d652772e769c7b7427bd3eec6e5b2328dce4e46672cffd9def7e2773224a29dce9f23c5997f9bef0547ea4d04da1184a6f4a1d1482ee4dad5ffdb3d16000002277042e03991f7389fc49775bacd1de623f602f19fc7af02c63ec5a3e9f973dbbdbb7af5db7f67700d06f97397acebd3f7fb2f02a63b1eda90d6d2b4086e65c76904cac5d55186326f9e257d7712dacc34dc065d43957bd072591168f3187733eeb4eb866eeacbb515ca73792cda9c701d4bb1302e41781d0865b949a3b21ca9ecf1af23f15a22fbf865fe6c1656074cc5de65ca56d71d37ac5b94a91e343b98f98695c62b0b6dacbede79a1af922a7e8417a048416880c8869c0d08d3aa018856efde1095a0a200700ba9c91dac8a9621a3a7bab35613f4a80c6a31c6ed47a1b21422bc619094446afb830740b0087108010f30f650d8c23842a9c739779d73df0c51c5ae162d186ce76af5e196fa6101a420021108ff1fa788c1b621a11411eb819879c31403e4021c0163848c0dd8c714682ad708b6e1d0068c2f766990e8da89224c3f95d8600851e2c93c3131520550b5335cf151e1022029d2d229f2f77ae38160068de345a98c9cc5a75439fdfc9072cc6502b8a054a990e78be84573de326bf0bbafd9098201b0034c7719f8d47f99285971102eeb4048512d00d100154ae3ebb7aee0809e11388082803d6621969db105b9a3955780252424b26e3836ed1fb8db1ca051902ae9060a6016655a00801563f6f81ebcbb95ca633c46d42fb464436bcc4eb31836772e70bf76876829f72aeb823355f852f61371a60acd2959a972401518552081011b809b43e29d0f682048f130c93010d6c4dffc7834d5a53d29e21290e912fcb140276ac0a0de7bbef51054a04305466819d00da5e24a45200332bf999a1bc2c9cc9ff009da67400482eb7becb9d772eb4ae6c6af17c893833e6947a0450cd7b006012a966829d2040af14731da1063f3b72b97031f3deb6eecdfd9d5b3b6e54c02df635e772fe900ce52a222352535a83a3dab8584c22d90c700b40c8e0098191a1d1e0d017fddfd8cdd6defdfd7b73ada956052c986eb991d187c5b4719845638978d4802700e1035ef50fb39702762300784008142ebaeaf30f8f8c1d3f73e4dd9e3737f7776ce9b8511b990000a554250285039f0cefce664ab3d9d381ca9e56ead851a5b219a54a534a29a5541028559a0ad4c0be63417b4be7c1f6f5e9c7864f0c6b738c05f18f8f6ce6c2b2031f0c9fcb9e085436a7d4e4b852ea2f35b7262f9554efeb7d63a947dabbf6ecdcc34ba5d2bf803705074180fdef1fde31f0e9853f6b2a95aac0878f8e07e9f53bbe4a3fdfb1e6562a6f09564a617c749cf7760d7c9bcd4c2aa5942a4d06b37dbb06c6522de9ae3dbbdee1a5a95babfc4fb0520a07f61d7eba6fe7b1c9e1a3e341e7a6de2f6f57e5ff824b5381dedbddd7996a4977f574f7dc77bb2a17c6df8cbd46ed068731d30000000049454e44ae426082</data>
+ </image>
+ <image name="image6">
+ <data format="PNG" length="1211">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000048249444154388d95944f6c54551487bf695ff53e9cea0c69c94c6cb02fb4d84682b601a30425d3c4a8c0c63646a9ff426b62005920246aaa0b52c584d2850b1660d005200b086cccc0a653443b1a10c604e96b80f40db6ce1b6bed7bb193be0b73e5ba98a1b4091238c9c9c9bdb9f73b27e777cf0d69adb96f0b82d0f0a96f9ff42fa6b67b8aacf5f2963e5379b5b1156dd74cd35400a1fb0217c11d49d7c98ba9b7a976375acfc41bd2075357e5a47916e5c6bda6ee773bbab68c0218f7caf41c67a17df24087552b375989c872c2540623195a9aad25b26057b8e7ec69fbeaf0a3c01dc0c5a032c866164b4988bae66c341abde98d390bfc5f922fa29cf75b5e88ac3663de038c3b042311ccb0807006dfb19529657550c8d605d30166b5590617c11b492d259bee8ed6d02efd8cb607c57e8475296e78efc45646d7994d224c3e03bf4540c430635990c320cc9010625144492dff722c29c1ac0623980e2afd9ff7be2ef07ba2abad26a24e284a8c96a6ec2e0a6ed16c889b4827c4af1284053117940d05ff9692448578385014a3ca5bea8cdb46b4b65519fe48ea0921646ff439cb82f46c574cabbe0a64156336e463506f020e4817a40443800c4a8727658529446544e597f879f711e0ef0a6fd2d7200cb0a128e7b85f8a79010d71306c501ec87266e5956256c2a40443565882c5f6b9c13a800a39966915029322a54ad49c98f7c1b0c0704b6b55a62a0998909730564e2444c8aaa656f8de72800a0ace5ab3deaca160972e48bf14b32e8cc7202640e54105b7e10a18f74a5059eeb521427259bbe9e5f36b5cc7312adf7bad3d1479c878a92a9c7f901bd3505090ad02e369585a050b1c9005b8a9402a985130aec0036e144019040b1ab9d2b883f1c73af1738ee94979ca88af5c3b98bf78fc82158badc17760b2191a2c88b8805f6a0b4041420198e476e54604b7ae0d37de8d4f0414881acb4a1d3d9ca88837ac9a747d8ee15bff520062cd10714a5005204a82493147b800a2ad388d9fe1357f82147104e06406d58593c7cf66b2cee50a4c88b7ac4dba23f92b080b7c67be805296804a9645130475dd380dbd04b1b6524edf257da4ffcfe4377bfacc952d6f1e4ea64f1b00d653cf8e0e1f499d882beb630a0ea848a9d232a8f4b404849b09eadec0375a1040e04bdc4cba983cd8ff435e89dd9dbbf6a43a5ee928defe2b4c13bfda3ae25cb5375811ea29081065a8f4c088424d1b41b813a9040270b30e3f1dfdda4d9e3cfc959568dfb767db8e9c6559b30336fb6d069e17b28f7efe456ba3f8908807f5f9f284b540b81d8c560205c800fbc764f1f8fefed3b62f77777dd0fbfdbaf5eb8a5431dfb4d6b33e9a1e78fcd2decdf6cc991ead27bab4fee790d67a4adfb2a9df73fad8ceed639d2bea7bb66fea8ae54673f3eecff5f91b33330c7dd9b3357760f3753d715ecfb55c7ae07aefab8964d7fab56b86524386be7167e09dc15a93bb7c69e1775b13c9a93387b4d65acf4ce4f4407fcfb5aed5cd1ff5edec5d3435317557e0ff82b5d60ceceb7dfefca7ed7f8ca68e057d1b1227bad627560d9d19aabc17e05dc133135395bd6f2536b62f8b6cebd9b6f99eab9cebff01a7a517d9791775a00000000049454e44ae426082</data>
+ </image>
+</images>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/locate.desktop b/src/locate.desktop
new file mode 100644
index 0000000..20bfdb7
--- /dev/null
+++ b/src/locate.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+Name=locate - Search for local files
+ServiceTypes=SearchProvider
+Keys=locate
+Query=locate:\\{@}
+Charset=utf8
diff --git a/src/locate.protocol b/src/locate.protocol
new file mode 100644
index 0000000..61e4810
--- /dev/null
+++ b/src/locate.protocol
@@ -0,0 +1,18 @@
+[Protocol]
+exec=kio_locate
+protocol=locate
+input=none
+output=filesystem
+listing=Name,Type,Size,Date,AccessDate,Access,Owner,Group,Link
+reading=true
+Icon=find
+Description=KDE I/O Slave for the locate command
+
+# Using this will e.g. display previews etc.
+Class=:local
+
+# No special parsing needed. locate does not use URL syntax.
+URIMode=rawuri
+
+# Our very sophisticated documentation
+DocPath=kio-locate/index.html
diff --git a/src/locater.cpp b/src/locater.cpp
new file mode 100644
index 0000000..4072209
--- /dev/null
+++ b/src/locater.cpp
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Thanks to Google's Summer Of Code Program! *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qtextcodec.h>
+
+#include <kdebug.h>
+#include <kstandarddirs.h>
+
+#include "locater.h"
+
+
+Locater::Locater(QObject *parent, const char *name)
+ : QObject(parent, name), m_process(QTextCodec::codecForLocale())
+{
+ DEBUGSTR << "Locater::Locater" << endl;
+
+ connect(&m_process, SIGNAL(processExited(KProcess*)),
+ this, SLOT(finished(KProcess*)));
+ connect(&m_process, SIGNAL(readReady(KProcIO*)),
+ this, SLOT(gotOutput(KProcIO*)));
+
+ setupLocate();
+}
+
+
+Locater::~Locater()
+{
+ DEBUGSTR << "Locater::~Locater" << endl;
+}
+
+
+void Locater::setupLocate(const QString& binary, const QString& additionalArguments)
+{
+ DEBUGSTR << "Locater::setupLocate(" << binary << ", " << additionalArguments << ")" << endl;
+
+ // Automatically choose the correct binary if not specified.
+ if (binary.isEmpty()) {
+ if (KStandardDirs::findExe("slocate")) {
+ m_binary = "slocate";
+ } else if (KStandardDirs::findExe("rlocate")) {
+ m_binary = "rlocate";
+ } else {
+ m_binary = "locate";
+ }
+ DEBUGSTR << "Using binary:" << m_binary << endl;
+ } else {
+ m_binary = binary;
+ }
+ m_additionalArguments = additionalArguments;
+ m_binaryExists = KStandardDirs::findExe(m_binary) != QString::null;
+}
+
+
+bool Locater::locate(const QString& pattern, bool ignoreCase, bool regExp)
+{
+ DEBUGSTR << "Locater::locate(" << pattern << "," << ignoreCase << "," << regExp << ")" << endl;
+
+ m_process.resetAll();
+ m_process << m_binary;
+ if (!m_additionalArguments.isEmpty()) {
+ m_process << m_additionalArguments;
+ }
+ if (ignoreCase) {
+ // m_process << "--ignore-case";
+ m_process << "-i";
+ }
+ if (regExp) {
+ m_process << "-r";
+ }
+ m_process << pattern;
+
+ return m_process.start(KProcess::Block, false);
+}
+
+void Locater::stop()
+{
+ DEBUGSTR << "Locater::stop()" << endl;
+
+ m_process.kill();
+ emit finished();
+}
+
+
+void Locater::gotOutput(KProcIO* /*proc*/)
+{
+ //DEBUGSTR << "Locater::gotOutput" << endl;
+
+ QStringList items;
+ QString line;
+
+ while (m_process.readln(line) != -1) {
+ //DEBUGSTR << "OUTPUT>> '" << line << "'" << endl;
+
+ items << line;
+ }
+
+ emit found(items);
+}
+
+
+void Locater::finished(KProcess* /*proc*/)
+{
+ DEBUGSTR << "Locater::finished" << endl;
+
+ emit finished();
+}
+
+
+#include "locater.moc"
diff --git a/src/locater.h b/src/locater.h
new file mode 100644
index 0000000..e083d2a
--- /dev/null
+++ b/src/locater.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Thanks to Google's Summer Of Code Program! *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef LOCATER_H
+#define LOCATER_H
+
+#include <qobject.h>
+#include <qstringlist.h>
+
+#include <kprocio.h>
+
+
+#define DEBUGSTR kdDebug(7199)
+
+
+/**
+ * Interface to the locate command.
+ *
+ * Usage is very simple:
+ * - Calling locate searches for the given pattern.
+ * - You can then collect the found files by connecting to the signal
+ * found.
+ * - When finished the signal finished is emitted.
+ */
+class Locater : public QObject
+{
+ Q_OBJECT
+ public:
+ /**
+ * Constructor
+ */
+ Locater(QObject *parent = 0, const char *name = 0);
+
+ virtual ~Locater();
+
+ /**
+ * Starts the search.
+ * @param pattern the pattern to search for
+ * @param ignoreCase whether to ignore case or not
+ * @param regExp whether to treat pattern as a regular expression or not
+ * @return true if locate could be started
+ */
+ bool locate(const QString& pattern, bool ignoreCase = false, bool regExp = false);
+
+ /**
+ * Set parameters for using locate.
+ * @param binary the binary to use (default: automatically chosen from
+ * slocate, rlocate and locate)
+ * @param additionalArguments additional arguments to use
+ */
+ void setupLocate(const QString& binary = "", const QString& additionalArguments = "");
+
+ void stop();
+
+ QString binary() { return m_binary; }
+ bool binaryExists() { return m_binaryExists; }
+
+ signals:
+ /**
+ * Emitted whenever some new files are found.
+ * @param items a list of the new filenames
+ */
+ void found(const QStringList& items);
+
+ /**
+ * Emitted when the search is finished.
+ */
+ void finished();
+
+ private slots:
+ void gotOutput(KProcIO* proc);
+ void finished(KProcess* proc);
+
+ private:
+ KProcIO m_process;
+ QString m_binary;
+ QString m_additionalArguments;
+ bool m_binaryExists;
+};
+
+#endif
diff --git a/src/locater.protocol b/src/locater.protocol
new file mode 100644
index 0000000..b40c6a2
--- /dev/null
+++ b/src/locater.protocol
@@ -0,0 +1,15 @@
+[Protocol]
+exec=kio_locate
+protocol=locater
+input=none
+output=filesystem
+listing=Name,Type,Size,Date,AccessDate,Access,Owner,Group,Link
+reading=true
+Icon=find
+Description=KDE I/O Slave for the locate command
+
+# Using this will e.g. display previews etc.
+Class=:local
+
+# Our very sophisticated documentation
+DocPath=kio-locate/index.html
diff --git a/src/pattern.cpp b/src/pattern.cpp
new file mode 100644
index 0000000..14c74e3
--- /dev/null
+++ b/src/pattern.cpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Thanks to Google's Summer Of Code Program! *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <kdebug.h>
+
+#include "pattern.h"
+
+
+LocateRegExp::LocateRegExp(const QString& pattern, bool ignoreCase)
+{
+ m_ignoreCase = ignoreCase;
+ setPattern(pattern);
+}
+
+
+LocateRegExp::LocateRegExp()
+{
+}
+
+
+LocateRegExp::~LocateRegExp()
+{
+}
+
+
+bool LocateRegExp::isMatching(const QString& file) const
+{
+ bool matching = m_regExp.search(file) >= 0;
+ if (m_negated) {
+ matching = !matching;
+ }
+ return matching;
+}
+
+
+int LocateRegExp::getMatchPosition() const
+{
+ // Why is QRegExp::pos() non const?
+ return const_cast<LocateRegExp*>(this)->m_regExp.pos();
+}
+
+
+int LocateRegExp::getMatchedLength() const
+{
+ return m_regExp.matchedLength();
+}
+
+
+void LocateRegExp::setPattern(const QString& pattern)
+{
+ m_negated = false;
+ m_pattern = pattern;
+ if ((m_pattern.length() > 0) && (m_pattern[0] == '!')) {
+ m_negated = true;
+ m_pattern = m_pattern.mid(1, m_pattern.length()-1);
+ }
+ m_regExp = QRegExp(m_pattern, !m_ignoreCase);
+}
+
+
+QString LocateRegExp::getPattern() const
+{
+ return m_pattern;
+}
+
+
+LocateRegExpList::~LocateRegExpList()
+{
+}
+
+
+LocateRegExpList& LocateRegExpList::operator = (const QStringList& list)
+{
+ clear();
+ QStringList::ConstIterator it = list.begin();
+ for (; it != list.end(); ++it) {
+ append(LocateRegExp((*it), (*it) == (*it).lower()));
+ }
+ return *this;
+}
+
+
+bool LocateRegExpList::isMatchingOne(const QString& file) const
+{
+ bool matches = false;
+ LocateRegExpList::ConstIterator it = begin();
+ for (; !matches && (it != end()); ++it) {
+ matches = (*it).isMatching(file);
+ }
+ return matches;
+}
+
+
+bool LocateRegExpList::isMatchingAll(const QString& file) const
+{
+ bool matches = true;
+ LocateRegExpList::ConstIterator it = begin();
+ for (; matches && (it != end()); ++it) {
+ matches = (*it).isMatching(file);
+ }
+ return matches;
+}
diff --git a/src/pattern.h b/src/pattern.h
new file mode 100644
index 0000000..8e17a69
--- /dev/null
+++ b/src/pattern.h
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Thanks to Google's Summer Of Code Program! *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef PATTERN_H
+#define PATTERN_H
+
+#include <qregexp.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+/**
+ * Regular Expression adapted to the needs of kio-locate.
+ */
+class LocateRegExp
+{
+public:
+ /**
+ * Constructor
+ * @param pattern the pattern to start with
+ * @param ignoreCase specifies, if the search should be case sensitive
+ */
+ LocateRegExp(const QString& pattern, bool ignoreCase = false);
+ LocateRegExp();
+
+ virtual ~LocateRegExp();
+
+ /**
+ * Determines whether a file name is matching this regular expression.
+ * @param file the filename to match
+ */
+ virtual bool isMatching(const QString& file) const;
+
+ /**
+ * @return The position of the last match.
+ */
+ virtual int getMatchPosition() const;
+
+ /**
+ * @return The length of the last match.
+ */
+ virtual int getMatchedLength() const;
+
+ /**
+ * Set the pattern.
+ * @param pattern the pattern to search for. It may be prepended by an
+ * exclamation mark, to invert its meaning.
+ */
+ virtual void setPattern(const QString& pattern);
+
+ /**
+ * Get the pattern.
+ * @return search pattern
+ */
+ virtual QString getPattern() const;
+
+ private:
+ bool m_negated;
+ bool m_ignoreCase;
+ QRegExp m_regExp;
+ QString m_pattern;
+};
+
+/**
+ * List of regular expressions
+ */
+class LocateRegExpList: public QValueList<LocateRegExp>
+{
+ public:
+ virtual ~LocateRegExpList();
+
+ /**
+ * Converts a stringlist into a regexplist.
+ * @param list the stringlist to convert
+ */
+ LocateRegExpList& operator = (const QStringList& list);
+
+ /**
+ * Determines whether a file name is matching at least one regular
+ * expression in the list.
+ * @param file the filename to match
+ */
+ virtual bool isMatchingOne(const QString& file) const;
+
+ /**
+ * Determines whether a file name is matching all regular expressions
+ * in the list.
+ * @param file the filename to match
+ */
+ virtual bool isMatchingAll(const QString& file) const;
+};
+
+#endif
diff --git a/src/rlocate.protocol b/src/rlocate.protocol
new file mode 100644
index 0000000..a994b32
--- /dev/null
+++ b/src/rlocate.protocol
@@ -0,0 +1,18 @@
+[Protocol]
+exec=kio_locate
+protocol=rlocate
+input=none
+output=filesystem
+listing=Name,Type,Size,Date,AccessDate,Access,Owner,Group,Link
+reading=true
+Icon=find
+Description=KDE I/O Slave for the locate command
+
+# Using this will e.g. display previews etc.
+Class=:local
+
+# No special parsing needed. locate does not use URL syntax.
+URIMode=rawuri
+
+# Our very sophisticated documentation
+DocPath=kio-locate/index.html
diff --git a/templates/cpp b/templates/cpp
new file mode 100644
index 0000000..7db1f84
--- /dev/null
+++ b/templates/cpp
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
diff --git a/templates/h b/templates/h
new file mode 100644
index 0000000..7db1f84
--- /dev/null
+++ b/templates/h
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * kio-locate: KDE I/O Slave for the locate command *
+ * *
+ * Copyright (C) 2005 by Tobi Vollebregt *
+ * tobivollebregt@gmail.com *
+ * *
+ * Copyright (C) 2004 by Armin Straub *
+ * linux@arminstraub.de *
+ * *
+ * This program was initially written by Michael Schuerig. *
+ * Although I have completely rewritten it, most ideas are adopted *
+ * from his original work. *
+ * *
+ * Copyright (C) 2002 by Michael Schuerig *
+ * michael@schuerig.de *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/