summaryrefslogtreecommitdiffstats
path: root/kfind
diff options
context:
space:
mode:
Diffstat (limited to 'kfind')
-rw-r--r--kfind/AUTHORS18
-rw-r--r--kfind/ChangeLog141
-rw-r--r--kfind/Kfind.desktop79
-rw-r--r--kfind/Makefile.am36
-rw-r--r--kfind/README24
-rw-r--r--kfind/TODO13
-rw-r--r--kfind/findpart.desktop82
-rw-r--r--kfind/hi16-app-kfind.pngbin0 -> 996 bytes
-rw-r--r--kfind/hi22-app-kfind.pngbin0 -> 1417 bytes
-rw-r--r--kfind/hi32-app-kfind.pngbin0 -> 2247 bytes
-rw-r--r--kfind/hi48-app-kfind.pngbin0 -> 4298 bytes
-rw-r--r--kfind/hi64-app-kfind.pngbin0 -> 6131 bytes
-rw-r--r--kfind/kdatecombo.cpp131
-rw-r--r--kfind/kdatecombo.h49
-rw-r--r--kfind/kfind.cpp192
-rw-r--r--kfind/kfind.h64
-rw-r--r--kfind/kfinddlg.cpp293
-rw-r--r--kfind/kfinddlg.h69
-rw-r--r--kfind/kfindpart.cpp213
-rw-r--r--kfind/kfindpart.desktop87
-rw-r--r--kfind/kfindpart.h104
-rw-r--r--kfind/kfindpart.kdevprj178
-rw-r--r--kfind/kfindpart.kdevses20
-rw-r--r--kfind/kftabdlg.cpp871
-rw-r--r--kfind/kftabdlg.h136
-rw-r--r--kfind/kfwin.cpp434
-rw-r--r--kfind/kfwin.h75
-rw-r--r--kfind/kquery.cpp527
-rw-r--r--kfind/kquery.h102
-rw-r--r--kfind/main.cpp65
-rw-r--r--kfind/pics/Makefile.am2
-rw-r--r--kfind/pics/lo22-action-archive.pngbin0 -> 508 bytes
-rw-r--r--kfind/pics/lo22-action-delete.pngbin0 -> 473 bytes
-rw-r--r--kfind/pics/lo22-action-idea.pngbin0 -> 407 bytes
-rw-r--r--kfind/pics/lo22-action-info.pngbin0 -> 420 bytes
-rw-r--r--kfind/pics/lo22-action-openfile.pngbin0 -> 328 bytes
-rw-r--r--kfind/pics/lo22-action-save.pngbin0 -> 360 bytes
-rw-r--r--kfind/pics/lo22-action-search.pngbin0 -> 365 bytes
-rw-r--r--kfind/version.h3
39 files changed, 4008 insertions, 0 deletions
diff --git a/kfind/AUTHORS b/kfind/AUTHORS
new file mode 100644
index 000000000..cf0c32eb6
--- /dev/null
+++ b/kfind/AUTHORS
@@ -0,0 +1,18 @@
+kfind has been developed by :
+
+ Eric Coquelle <coquelle@caramail.com>
+ Beppe Grimaldi <grimalkin@ciaoweb.it>
+ Martin Hartig
+ Stephan Kulow <coolo@kde.org>
+ Mario Weilguni <mweilguni@sime.com>
+ Alex Zepeda <zipzippy@sonic.net>
+ Miroslav Fl�r <flidr@kky.zcu.cz>
+ Harri Porten <porten@kde.org>
+ Dima Rogozin <dima@mercury.co.il>
+ Carsten Pfeiffer <pfeiffer@kde.org>
+ Hans Petter Bieker <bieker@kde.org>
+ Waldo Bastian <bastian@kde.org>
+ Alexander Neundorf <neundorf@kde.org>
+ Albert R. Valiev <arkstone@mail.ru>
+ Clarence Dang <dang@kde.org>
+
diff --git a/kfind/ChangeLog b/kfind/ChangeLog
new file mode 100644
index 000000000..c13408a52
--- /dev/null
+++ b/kfind/ChangeLog
@@ -0,0 +1,141 @@
+Fri Jul 30 22:33:25 1999 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ * kfwin.cpp, kfwin.h: The listview items show a mini-pixmap, like those
+ in kfiledialog. For now, they're static icons (only folder and document
+ icons), maybe we can show the correct icons for the mimetypes, later.
+
+ Also introduced drag-support, you can drag files from the list.
+
+ * kftabdlg.cpp: accept Key_Enter to start the search, too.
+
+1999-06-13 Harri Porten <porten@kde.org>
+
+ * kftabdlg.cpp: introduced flexible geometry managment. Patch provided
+ by Dima Rogozin <dima@mercury.co.il>.
+
+1999-04-30 Harri Porten <porten@kde.org>
+
+ * kftabdlg.cpp: Default to '*' when no filenames are specified and
+ allow case insensitive text search. Patch provided by Dima Rogozin
+ <dima@mercury.co.il>.
+
+1999-04-06 Harri Porten <porten@kde.org>
+
+ * kfind.cpp: replaced simple delete and free() with delete [] iBuffer
+
+1998-12-07 Mario Weilguni <mweilguni@kde.org>
+
+ * made it work with Qt 2.0
+
+1998-12-07 Alex Zepeda <garbanzo@hooked.net>
+
+ * kfindtop.cpp: Commented out _height, as it's not used.
+
+1998-11-30 Miroslav Fldr <flidr@kky.zcu.cz>
+
+ * Dissabled multiple selection in view because it was not fully
+ handled
+ * Fixed problem in nameBox, dirBox combos which caused improper
+ find query generation (it is still neccesary to fix multiplication of
+ list entries)
+
+1998-10-23 Alex Zepeda <garbanzo@hooked.net>
+
+ * LICENSE: remove it, it's redundant.
+
+ * kfind/README: Tidy up, and mention inclusion in kdebase.
+
+ver. 0.4.1: Mario Weilguni <mweilguni@kde.org>
+ * temporary files are no longer needed
+ * found files are now shown while searching
+ * KDE compliant "Help" menu
+ * max-/min-size box is now disabled per default
+ * GUI is disabled while searching, makes it easier to see
+ progress
+ * kfind compiles now without warnings with -Wall
+ * result list is now scrollable without having the focus (only page
+ up and page down)
+ * moc files are now #included in moc.cpp instead of compiling
+ separate files. Speeds up compilation and makes binary smaller
+ * file patterns are remembered between sessions
+ * introduced new filetypes for searching: files, folders,
+ symlinks, special files, executables, suid executables
+ * better keyboard support
+
+ver. 0.4: Mario Weilguni <mweilguni@kde.org>
+ * introduced this ChangeLog
+ * kfind now uses KShellProcess instead of KProcess, makes
+ regular expression search possible with egrep/xargs
+ * kftabdlg.cpp: tab-dialog isn't closed anymore if Escape key
+ is pressed
+ * kfind can now search for contained text (with egrep)
+ * "Select All" and "Invert Selection" work now as expected
+ * "Copy" copies the currently selected items to the X11 selection
+ * "Unselect All" added for completeness
+
+ver. 0.3.4:
+
+ o removed some resizing problems
+ o kfinds icons now uses only 16 color
+ o mimetype browser removed from preferences
+ (something like that should be in kcc)
+ o kfind sets icon for kwmII
+
+ver. 0.3.3:
+
+ o uses KProcess
+ o supports other languages then english (at this time german and czech)
+
+ver. 0.3.2:
+
+ o uses KTopLevelWidget and KToolBar
+ o new documentations
+
+ver. 0.3.1:
+ o new documentation contributed by Mark Roberts
+
+ver. 0.3:
+ o entry Open in File menu or doubleclick on file executes default binding
+ o removed bug causing segfaults
+
+ver. 0.2.9:
+ o uses of autoconf
+ o you can specify searched directory as kfind argument
+ o added Icon entry in all provided filetypes (some were
+ missing this entry and kfm didn't liked it)
+
+ver. 0.2.8:
+ o kfind is now KDE AWARE application!!
+ o uses libkde0.7 (=> kmsgbox and ktabctl removed from kfind distribution)
+ o uses filetypes introduced by Torben Weis for kfm (kfind installs
+ some more filetypes)
+ o it is possible to store files in archives
+ o preferences dialog added
+ - it is possible to determine filename for results saving
+ - it is possible to browse available filetypes details
+ - it is possible to browse available archivers details
+ (in next version you will be able to change the details)
+ o calls kfm for properties dialog
+ o menu entry "remove" removed (kfm properties dialog does the job)
+ o removed some bugs
+
+ver. 0.2.6:
+ o reflects changes made by Martin Hartig (known as version 0.2.1)
+
+ver. 0.2.5:
+ o implemented dir selection box (it is actually a littlebit changed
+ and striped down version of QFileDialog)
+ o delete, rename, properties functions are implemented
+ o function "Open containing folder" implemented (it calls KFM)
+ o search results are now saved in file ~/.kfind-results.html
+ (I finally recognized this is better choice than plain text file)
+ o removed nasty bug causing segfaults when compiler optimization were
+ used
+ o improved Makefile
+
+ver. 0.2:
+ o all in kfind available options work now ;-))
+ o better calling of find. It's now separate process => interface isn't
+ blocked anymore during searching
+
+ver. 0.1: first official release
diff --git a/kfind/Kfind.desktop b/kfind/Kfind.desktop
new file mode 100644
index 000000000..96a8e3e5b
--- /dev/null
+++ b/kfind/Kfind.desktop
@@ -0,0 +1,79 @@
+[Desktop Entry]
+Exec=kfind %f
+Icon=kfind
+DocPath=kfind/index.html
+Path=
+Type=Application
+Terminal=false
+Name=Find Files/Folders
+Name[af]=Soek Lêers/Gidse
+Name[ar]=إبحث عن ملفات/مجلّدات
+Name[be]=Шукаць файлы/тэчкі
+Name[bg]=Търсене на файлове
+Name[bn]=ফাইল/ফোল্ডার অনুসন্ধান
+Name[br]=Klask restroù/renkelloù
+Name[bs]=Pronađi datoteke
+Name[ca]=Cerca fitxers i carpetes
+Name[cs]=Najít soubory/složky
+Name[csb]=Szëkba lopków/katalogów
+Name[da]=Find filer/mapper
+Name[de]=Dateien/Ordner suchen
+Name[el]=Αναζήτηση αρχείων/φακέλων
+Name[eo]=Trovu Dosierojn/Dosierujojn
+Name[es]=Buscar archivos/carpetas
+Name[et]=Failide/kataloogide otsimine
+Name[eu]=Bilatu fitxategiak/karpetak
+Name[fa]=یافتن پرونده‌ها/پوشه‌ها
+Name[fi]=Etsi tiedostoja ja kansioita
+Name[fr]=Recherche de fichiers/dossiers
+Name[fy]=Triemmen/mappen sykje
+Name[ga]=Aimsigh Comhaid/Comhadlanna
+Name[gl]=Buscar Ficheiros/Cartafoles
+Name[he]=חפש קבצים או תיקיות
+Name[hr]=Traži datoteke/mape
+Name[hu]=Fájlkereső
+Name[is]=Finna skrár/möppur
+Name[it]=Trova file/cartelle
+Name[ja]=ファイル/フォルダを検索
+Name[ka]=ფაილთა და საქაღალდეთა ძიება
+Name[kk]=Файлды не қапшықты табу
+Name[km]=រក​ឯកសារ/ថត
+Name[ko]=파일/폴더 찾기
+Name[lt]=Rasti bylas/aplankus
+Name[lv]=Meklēt Failus/Mapes
+Name[mk]=Пронајди датотеки/папки
+Name[ms]=Cari Fail/Folder
+Name[nb]=Finn filer/mapper
+Name[nds]=Dateien/Ornern söken
+Name[ne]=फाइल/फोल्डर फेला पार्नुहोस्
+Name[nl]=Bestanden/mappen zoeken
+Name[nn]=Finn filer/mapper
+Name[pa]=ਫਾਇਲ/ਫੋਲਡਰ ਖੋਜ
+Name[pl]=Wyszukiwanie plików/katalogów
+Name[pt]=Procurar Ficheiros/Pastas
+Name[pt_BR]=Procurar arquivos/pastas
+Name[ro]=Caută fișiere/foldere
+Name[ru]=Поиск файлов и папок
+Name[rw]=Gushaka Amadosiye/Ububiko
+Name[se]=Oza fiillaid dahje máhpaid
+Name[sk]=Hľadať súbory/priečinky
+Name[sl]=Najdi datoteke in mape
+Name[sr]=Тражење фајлова/фасцикли
+Name[sr@Latn]=Traženje fajlova/fascikli
+Name[sv]=Hitta filer eller kataloger
+Name[ta]=கோப்புகள்/அடைவுகளைக் கண்டுபிடி
+Name[te]=దస్త్రాలు/ఫొల్డర్లను వెతుకు
+Name[tg]=Ҷустуҷӯи файлҳо ва феҳрастҳо
+Name[th]=ค้นหาแฟ้ม/โฟลเดอร์
+Name[tr]=Dosya/Dizin Bul
+Name[tt]=Birem/Törgäk Ezläw
+Name[uk]=Пошук файлів та тек
+Name[uz]=Fayl/jildlarni qidirish
+Name[uz@cyrillic]=Файл/жилдларни қидириш
+Name[vi]=Tìm Tập tin/Thư mục
+Name[wa]=Trover des fitchîs/ridants
+Name[zh_CN]=查找文件/文件夹
+Name[zh_TW]=尋找檔案/資料夾
+X-KDE-StartupNotify=true
+OnlyShowIn=KDE;
+Categories=Qt;KDE;Core;
diff --git a/kfind/Makefile.am b/kfind/Makefile.am
new file mode 100644
index 000000000..a4f53b1b7
--- /dev/null
+++ b/kfind/Makefile.am
@@ -0,0 +1,36 @@
+#Global section
+METASOURCES = AUTO
+EXTRA_DIST = DESCRIPTION
+SUBDIRS = pics
+KDE_ICON = kfind
+# set the include path for X, qt and KDE
+INCLUDES= -I$(top_srcdir)/libkonq $(all_includes)
+
+noinst_LTLIBRARIES = libkfind_common.la
+libkfind_common_la_SOURCES = kftabdlg.cpp kfind.cpp kquery.cpp kdatecombo.cpp
+
+#This section is kfindpart
+kde_module_LTLIBRARIES = libkfindpart.la
+
+libkfindpart_la_SOURCES = kfindpart.cpp
+libkfindpart_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
+libkfindpart_la_LIBADD = libkfind_common.la $(LIB_KPARTS) $(top_builddir)/libkonq/libkonq.la
+
+noinst_HEADERS = kftabdlg.h kfind.h version.h kquery.h kdatecombo.h
+
+xdg_apps_DATA = Kfind.desktop
+
+kde_services_DATA = kfindpart.desktop
+kde_servicetypes_DATA = findpart.desktop
+
+messages:
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kfindpart.pot
+
+#And this is for kfind
+
+bin_PROGRAMS = kfind
+kfind_SOURCES = kfwin.cpp kfinddlg.cpp main.cpp
+kfind_LDADD = libkfind_common.la $(LIB_KPARTS)
+
+# the library search path.
+kfind_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/kfind/README b/kfind/README
new file mode 100644
index 000000000..7b6c24890
--- /dev/null
+++ b/kfind/README
@@ -0,0 +1,24 @@
+kfind
+=====
+
+Kfind is a graphical replacement for the utility `find' inspired by
+the find utility from NT.
+
+At this time it is fully functional. All options available in kfind
+are working. You can save the results, delete, change properties of
+found files/directories and ask konqueror to open the directory
+containing this file or execute default binding.
+
+THANKS
+------
+
+I want to thank Alexander Sanda <alex@darkstar.ping.at> for making
+KTabCtl which is used in Kfind and Torben Weis
+<weis@stud.uni-frankfurt.de> for his wonderful file manager konqueror.
+
+
+I hope you will find this program somehow useful and I would
+appreciate any suggestions and comments.
+
+ Miroslav Fldr
+ <flidr@kky.zcu.cz>
diff --git a/kfind/TODO b/kfind/TODO
new file mode 100644
index 000000000..0bf6ac832
--- /dev/null
+++ b/kfind/TODO
@@ -0,0 +1,13 @@
+TODO
+====
+
+ o support the more esoterical features of find
+
+DONE:
+
+ o drag found files to somewhere
+ o some layout managment
+ o context menus
+ o get preference dialog to work
+ o find pattern history
+ o support for finding files belonging to somebody
diff --git a/kfind/findpart.desktop b/kfind/findpart.desktop
new file mode 100644
index 000000000..9b33894e3
--- /dev/null
+++ b/kfind/findpart.desktop
@@ -0,0 +1,82 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=Konqueror/FindPart
+X-KDE-Derived=Browser/View
+Name=Find Part
+Name[af]=Soek Deel
+Name[ar]=ابحث عن جزء
+Name[az]=Parça tap
+Name[be]=Модуль пошуку
+Name[bg]=Търсене на модули
+Name[bn]=পার্ট অনুসন্ধান
+Name[br]=Kavout perzh
+Name[bs]=Nađi dio
+Name[ca]=Cerca la part
+Name[cs]=Najít soubor
+Name[csb]=Mòduł szëkbë
+Name[cy]=Canfod Rhan
+Name[da]=Find del
+Name[de]=Einbettungsfähiges Programm (Komponente) suchen
+Name[el]=Part Αναζήτηση
+Name[eo]=Trovokomponento
+Name[es]=Buscar parte
+Name[et]=Failide otsimise komponent
+Name[eu]=Bilatu partea
+Name[fa]=یافتن جزء
+Name[fi]=Etsi osa
+Name[fr]=Composant de recherche
+Name[fy]=In diel sykje
+Name[ga]=Aimsigh Páirt
+Name[gl]=Busca
+Name[he]=רכיב חיפוש
+Name[hi]=हिस्सा ढूंढें
+Name[hr]=Pronađi dio
+Name[hu]=Keresési objektum
+Name[id]=Cari bagian
+Name[is]=Finna hluti
+Name[it]=Trova parte
+Name[ja]=検索パート
+Name[ka]=ძიება შემადგენლობის მიხედვით
+Name[kk]=Мазмұнынан табу
+Name[km]=រក​ផ្នែក
+Name[ko]=찾기 부분
+Name[lo]=ຄັ້ນຫາບາງສ່ວນ
+Name[lt]=Surasti dalį
+Name[lv]=Meklēt Daļu
+Name[mk]=Пронајди дел
+Name[mn]=Хэсэг хайх
+Name[ms]=Cari Bahagian
+Name[mt]=Sib Parti
+Name[nb]=Finn del
+Name[nds]=Söök-Komponent
+Name[ne]=भाग फेला पार्नुहोस्
+Name[nl]=Gedeelte zoeken
+Name[nn]=Finn del
+Name[nso]=Hwetsa Seripa
+Name[pa]=ਹਿੱਸੇ ਖੋਜ
+Name[pl]=Moduł szukania
+Name[pt]=Componente de Pesquisa
+Name[pt_BR]=Componente de Busca
+Name[ro]=Componentă de căutare
+Name[ru]=Поиск по содержимому
+Name[rw]=Gushaka Igice
+Name[se]=Oza osiid
+Name[sk]=Nájsť Part
+Name[sl]=Najdi del
+Name[sr]=Део за тражење
+Name[sr@Latn]=Deo za traženje
+Name[sv]=Sökdel
+Name[ta]=பகுதி கண்டுபிடி
+Name[te]=వెతుకు భాగం
+Name[tg]=Қисматро пайдо кунед
+Name[th]=ค้นหาบางส่วน
+Name[tr]=Parça bul
+Name[tt]=Eçtälek Ezläw
+Name[uk]=Складова пошуку
+Name[ven]=Todani tshipida
+Name[vi]=Tìm từng phần
+Name[wa]=Trover des pårteyes
+Name[xh]=Fumana Indawana
+Name[zh_CN]=查找部件
+Name[zh_TW]=尋找組件
+Name[zu]=Thola Ingxenye
diff --git a/kfind/hi16-app-kfind.png b/kfind/hi16-app-kfind.png
new file mode 100644
index 000000000..f2b60daa7
--- /dev/null
+++ b/kfind/hi16-app-kfind.png
Binary files differ
diff --git a/kfind/hi22-app-kfind.png b/kfind/hi22-app-kfind.png
new file mode 100644
index 000000000..647dc2196
--- /dev/null
+++ b/kfind/hi22-app-kfind.png
Binary files differ
diff --git a/kfind/hi32-app-kfind.png b/kfind/hi32-app-kfind.png
new file mode 100644
index 000000000..171c2b1d2
--- /dev/null
+++ b/kfind/hi32-app-kfind.png
Binary files differ
diff --git a/kfind/hi48-app-kfind.png b/kfind/hi48-app-kfind.png
new file mode 100644
index 000000000..1d472379a
--- /dev/null
+++ b/kfind/hi48-app-kfind.png
Binary files differ
diff --git a/kfind/hi64-app-kfind.png b/kfind/hi64-app-kfind.png
new file mode 100644
index 000000000..fa5b5f0c4
--- /dev/null
+++ b/kfind/hi64-app-kfind.png
Binary files differ
diff --git a/kfind/kdatecombo.cpp b/kfind/kdatecombo.cpp
new file mode 100644
index 000000000..c5f9e4553
--- /dev/null
+++ b/kfind/kdatecombo.cpp
@@ -0,0 +1,131 @@
+/***********************************************************************
+ *
+ * kdatecombo.cpp
+ *
+ ***********************************************************************/
+
+#include <qtimer.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kdatepicker.h>
+#include <kdatetbl.h>
+#include <kdebug.h>
+
+#include "kdatecombo.h"
+
+#include "kdatecombo.moc"
+
+KDateCombo::KDateCombo(QWidget *parent, const char *name ) : QComboBox(FALSE, parent,name)
+{
+ QDate date = QDate::currentDate();
+ initObject(date, parent, name);
+}
+
+KDateCombo::KDateCombo(const QDate & date, QWidget *parent, const char *name) : QComboBox(FALSE, parent,name)
+{
+ initObject(date, parent, name);
+}
+
+void KDateCombo::initObject(const QDate & date, QWidget *, const char *)
+{
+ clearValidator();
+ popupFrame = new KPopupFrame(this, "popupFrame");
+ popupFrame->installEventFilter(this);
+ datePicker = new KDatePicker(popupFrame, date, "datePicker");
+ datePicker->setMinimumSize(datePicker->sizeHint());
+ datePicker->installEventFilter(this);
+ popupFrame->setMainWidget(datePicker);
+ setDate(date);
+
+ connect(datePicker, SIGNAL(dateSelected(QDate)), this, SLOT(dateEnteredEvent(QDate)));
+}
+
+KDateCombo::~KDateCombo()
+{
+ delete datePicker;
+ delete popupFrame;
+}
+
+QString KDateCombo::date2String(const QDate & date)
+{
+ return(KGlobal::locale()->formatDate(date, true));
+}
+
+QDate & KDateCombo::string2Date(const QString & str, QDate *qd)
+{
+ return *qd = KGlobal::locale()->readDate(str);
+}
+
+QDate & KDateCombo::getDate(QDate *currentDate)
+{
+ return string2Date(currentText(), currentDate);
+}
+
+bool KDateCombo::setDate(const QDate & newDate)
+{
+ if (newDate.isValid())
+ {
+ if (count())
+ clear();
+ insertItem(date2String(newDate));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void KDateCombo::dateEnteredEvent(QDate newDate)
+{
+ if (!newDate.isValid())
+ newDate = datePicker->date();
+ popupFrame->hide();
+ setDate(newDate);
+}
+
+void KDateCombo::mousePressEvent (QMouseEvent * e)
+{
+ if (e->button() & QMouseEvent::LeftButton)
+ {
+ if (rect().contains( e->pos()))
+ {
+ QDate tempDate;
+ getDate(& tempDate);
+ datePicker->setDate(tempDate);
+ popupFrame->popup(mapToGlobal(QPoint(0, height())));
+ //datePicker->setFocus();
+ }
+ }
+}
+
+bool KDateCombo::eventFilter (QObject*, QEvent* e)
+{
+ if ( e->type() == QEvent::MouseButtonPress )
+ {
+ QMouseEvent *me = (QMouseEvent *)e;
+ QPoint p = mapFromGlobal( me->globalPos() );
+ if (rect().contains( p ) )
+ {
+ QTimer::singleShot(10, this, SLOT(dateEnteredEvent()));
+ return true;
+ }
+ }
+ else if ( e->type() == QEvent::KeyRelease )
+ {
+ QKeyEvent *k = (QKeyEvent *)e;
+ //Press return == pick selected date and close the combo
+ if((k->key()==Qt::Key_Return)||(k->key()==Qt::Key_Enter))
+ {
+ dateEnteredEvent(datePicker->date());
+ return true;
+ }
+ else if (k->key()==Qt::Key_Escape)
+ {
+ popupFrame->hide();
+ return true;
+ }
+ else
+ return false;
+ }
+
+ return false;
+}
diff --git a/kfind/kdatecombo.h b/kfind/kdatecombo.h
new file mode 100644
index 000000000..12f66174a
--- /dev/null
+++ b/kfind/kdatecombo.h
@@ -0,0 +1,49 @@
+/***********************************************************************
+ *
+ * kdatecombo.h
+ *
+ ***********************************************************************/
+
+#ifndef KDATECOMBO_H
+#define KDATECOMBO_H
+
+#include <qwidget.h>
+#include <qcombobox.h>
+#include <qdatetime.h>
+
+/**
+ *@author Beppe Grimaldi
+ */
+
+class KDatePicker;
+class KPopupFrame;
+
+class KDateCombo : public QComboBox {
+ Q_OBJECT
+
+public:
+ KDateCombo(QWidget *parent=0, const char *name=0);
+ KDateCombo(const QDate & date, QWidget *parent=0, const char *name=0);
+ ~KDateCombo();
+
+ QDate & getDate(QDate *currentDate);
+ bool setDate(const QDate & newDate);
+
+private:
+ KPopupFrame * popupFrame;
+ KDatePicker * datePicker;
+
+ void initObject(const QDate & date, QWidget *parent, const char *name);
+
+ QString date2String(const QDate &);
+ QDate & string2Date(const QString &, QDate * );
+
+protected:
+ bool eventFilter (QObject*, QEvent*);
+ virtual void mousePressEvent (QMouseEvent * e);
+
+protected slots:
+ void dateEnteredEvent(QDate d=QDate());
+};
+
+#endif
diff --git a/kfind/kfind.cpp b/kfind/kfind.cpp
new file mode 100644
index 000000000..93c646a91
--- /dev/null
+++ b/kfind/kfind.cpp
@@ -0,0 +1,192 @@
+/***********************************************************************
+ *
+ * Kfind.cpp
+ *
+ * This is KFind, released under GPL
+ *
+ * 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.
+ *
+ * KFind (c) 1998-2003 The KDE Developers
+ Martin Hartig
+ Stephan Kulow <coolo@kde.org>
+ Mario Weilguni <mweilguni@sime.com>
+ Alex Zepeda <zipzippy@sonic.net>
+ Miroslav Fldr <flidr@kky.zcu.cz>
+ Harri Porten <porten@kde.org>
+ Dima Rogozin <dima@mercury.co.il>
+ Carsten Pfeiffer <pfeiffer@kde.org>
+ Hans Petter Bieker <bieker@kde.org>
+ Waldo Bastian <bastian@kde.org>
+ Beppe Grimaldi <grimalkin@ciaoweb.it>
+ Eric Coquelle <coquelle@caramail.com>
+
+ **********************************************************************/
+
+#include <kpushbutton.h>
+#include <qlayout.h>
+#include <qvbox.h>
+
+#include <kdialog.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kseparator.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <kstdguiitem.h>
+
+#include "kftabdlg.h"
+#include "kquery.h"
+
+#include "kfind.moc"
+
+Kfind::Kfind(QWidget *parent, const char *name)
+ : QWidget( parent, name )
+{
+ kdDebug() << "Kfind::Kfind " << this << endl;
+ QBoxLayout * mTopLayout = new QBoxLayout( this, QBoxLayout::LeftToRight,
+ KDialog::marginHint(), KDialog::spacingHint() );
+
+ // create tabwidget
+ tabWidget = new KfindTabWidget( this );
+ mTopLayout->addWidget(tabWidget);
+
+ /*
+ * This is ugly. Might be a KSeparator bug, but it makes a small black
+ * pixel for me which is visually distracting (GS).
+ // create separator
+ KSeparator * mActionSep = new KSeparator( this );
+ mActionSep->setFocusPolicy( QWidget::ClickFocus );
+ mActionSep->setOrientation( QFrame::VLine );
+ mTopLayout->addWidget(mActionSep);
+ */
+
+ // create button box
+ QVBox * mButtonBox = new QVBox( this );
+ QVBoxLayout *lay = (QVBoxLayout*)mButtonBox->layout();
+ lay->addStretch(1);
+ mTopLayout->addWidget(mButtonBox);
+
+ mSearch = new KPushButton( KGuiItem(i18n("&Find"), "find"), mButtonBox );
+ mButtonBox->setSpacing( (tabWidget->sizeHint().height()-4*mSearch->sizeHint().height()) / 4);
+ connect( mSearch, SIGNAL(clicked()), this, SLOT( startSearch() ) );
+ mStop = new KPushButton( KGuiItem(i18n("Stop"), "stop"), mButtonBox );
+ connect( mStop, SIGNAL(clicked()), this, SLOT( stopSearch() ) );
+ mSave = new KPushButton( KStdGuiItem::saveAs(), mButtonBox );
+ connect( mSave, SIGNAL(clicked()), this, SLOT( saveResults() ) );
+
+ KPushButton * mClose = new KPushButton( KStdGuiItem::close(), mButtonBox );
+ connect( mClose, SIGNAL(clicked()), this, SIGNAL( destroyMe() ) );
+
+ // react to search requests from widget
+ connect( tabWidget, SIGNAL(startSearch()), this, SLOT( startSearch() ) );
+
+ mSearch->setEnabled(true); // Enable "Search"
+ mStop->setEnabled(false); // Disable "Stop"
+ mSave->setEnabled(false); // Disable "Save..."
+
+ dirlister=new KDirLister();
+}
+
+Kfind::~Kfind()
+{
+ stopSearch();
+ dirlister->stop();
+ delete dirlister;
+ kdDebug() << "Kfind::~Kfind" << endl;
+}
+
+void Kfind::setURL( const KURL &url )
+{
+ tabWidget->setURL( url );
+}
+
+void Kfind::startSearch()
+{
+ tabWidget->setQuery(query);
+ emit started();
+
+ //emit resultSelected(false);
+ //emit haveResults(false);
+
+ mSearch->setEnabled(false); // Disable "Search"
+ mStop->setEnabled(true); // Enable "Stop"
+ mSave->setEnabled(false); // Disable "Save..."
+
+ tabWidget->beginSearch();
+
+ dirlister->openURL(KURL(tabWidget->dirBox->currentText().stripWhiteSpace()));
+
+ query->start();
+}
+
+void Kfind::stopSearch()
+{
+ // will call KFindPart::slotResult, which calls searchFinished here
+ query->kill();
+}
+
+/*
+void Kfind::newSearch()
+{
+ // WABA: Not used any longer?
+ stopSearch();
+
+ tabWidget->setDefaults();
+
+ emit haveResults(false);
+ emit resultSelected(false);
+
+ setFocus();
+}
+*/
+
+void Kfind::searchFinished()
+{
+ mSearch->setEnabled(true); // Enable "Search"
+ mStop->setEnabled(false); // Disable "Stop"
+ // ## TODO mSave->setEnabled(true); // Enable "Save..."
+
+ tabWidget->endSearch();
+ setFocus();
+}
+
+
+void Kfind::saveResults()
+{
+ // TODO
+}
+
+void Kfind::setFocus()
+{
+ tabWidget->setFocus();
+}
+
+void Kfind::saveState( QDataStream *stream )
+{
+ query->kill();
+ *stream << tabWidget->nameBox->currentText();
+ *stream << tabWidget->dirBox->currentText();
+ *stream << tabWidget->typeBox->currentItem();
+ *stream << tabWidget->textEdit->text();
+ *stream << (int)( tabWidget->subdirsCb->isChecked() ? 0 : 1 );
+}
+
+void Kfind::restoreState( QDataStream *stream )
+{
+ QString namesearched, dirsearched,containing;
+ int typeIdx;
+ int subdirs;
+ *stream >> namesearched;
+ *stream >> dirsearched;
+ *stream >> typeIdx;
+ *stream >> containing;
+ *stream >> subdirs;
+ tabWidget->nameBox->insertItem( namesearched, 0);
+ tabWidget->dirBox->insertItem ( dirsearched, 0);
+ tabWidget->typeBox->setCurrentItem(typeIdx);
+ tabWidget->textEdit->setText ( containing );
+ tabWidget->subdirsCb->setChecked( ( subdirs==0 ? true : false ));
+}
diff --git a/kfind/kfind.h b/kfind/kfind.h
new file mode 100644
index 000000000..9bc5d35e5
--- /dev/null
+++ b/kfind/kfind.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+ *
+ * Kfind.h
+ *
+ ***********************************************************************/
+
+#ifndef KFIND_H
+#define KFIND_H
+
+#include <qwidget.h>
+#include <kfileitem.h>
+#include <kdirlister.h>
+
+class QString;
+class KPushButton;
+
+class KQuery;
+class KURL;
+class KfindTabWidget;
+
+class Kfind: public QWidget
+{
+ Q_OBJECT
+
+public:
+ Kfind(QWidget * parent = 0, const char * name = 0);
+ ~Kfind();
+
+ void setURL( const KURL &url );
+
+ void setQuery(KQuery * q) { query = q; }
+ void searchFinished();
+
+ void saveState( QDataStream *stream );
+ void restoreState( QDataStream *stream );
+
+public slots:
+ void startSearch();
+ void stopSearch();
+ //void newSearch();
+ void saveResults();
+
+signals:
+ void haveResults(bool);
+ void resultSelected(bool);
+
+ void started();
+ void destroyMe();
+
+private:
+ void setFocus();
+ KfindTabWidget *tabWidget;
+ KPushButton *mSearch;
+ KPushButton *mStop;
+ KPushButton *mSave;
+ KQuery *query;
+
+public:
+ KDirLister *dirlister;
+};
+
+#endif
+
+
diff --git a/kfind/kfinddlg.cpp b/kfind/kfinddlg.cpp
new file mode 100644
index 000000000..4efafd2de
--- /dev/null
+++ b/kfind/kfinddlg.cpp
@@ -0,0 +1,293 @@
+/***********************************************************************
+ *
+ * Kfinddlg.cpp
+ *
+ **********************************************************************/
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#include <klocale.h>
+#include <kglobal.h>
+#include <kguiitem.h>
+#include <kstatusbar.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kaboutapplication.h>
+#include <kstandarddirs.h>
+
+#include "kftabdlg.h"
+#include "kquery.h"
+#include "kfwin.h"
+
+#include "kfinddlg.h"
+#include "kfinddlg.moc"
+
+KfindDlg::KfindDlg(const KURL & url, QWidget *parent, const char *name)
+ : KDialogBase( Plain, QString::null,
+ User1 | User2 | Apply | Close | Help, Apply,
+ parent, name, true, false,
+ KGuiItem(i18n("Stop"), "stop"),
+ KStdGuiItem::saveAs())
+{
+ QWidget::setCaption( i18n("Find Files/Folders" ) );
+ setButtonBoxOrientation(Vertical);
+
+ enableButton(Apply, true); // Enable "Find"
+ enableButton(User1, false); // Disable "Stop"
+ enableButton(User2, false); // Disable "Save As..."
+
+ setButtonApply(KGuiItem(i18n("&Find"), "find"));
+
+ isResultReported = false;
+
+ QFrame *frame = plainPage();
+
+ // create tabwidget
+ tabWidget = new KfindTabWidget( frame, "dialog");
+ tabWidget->setURL( url );
+
+ // prepare window for find results
+ win = new KfindWindow(frame,"window");
+
+ mStatusBar = new KStatusBar(frame);
+ mStatusBar->insertFixedItem(i18n("AMiddleLengthText..."), 0, true);
+ setStatusMsg(i18n("Ready."));
+ mStatusBar->setItemAlignment(0, AlignLeft | AlignVCenter);
+ mStatusBar->insertItem(QString::null, 1, 1, true);
+ mStatusBar->setItemAlignment(1, AlignLeft | AlignVCenter);
+
+ QVBoxLayout *vBox = new QVBoxLayout(frame);
+ vBox->addWidget(tabWidget, 0);
+ vBox->addWidget(win, 1);
+ vBox->addWidget(mStatusBar, 0);
+
+ connect(this, SIGNAL(applyClicked()),
+ this, SLOT(startSearch()));
+ connect(this, SIGNAL(user1Clicked()),
+ this, SLOT(stopSearch()));
+ connect(this, SIGNAL(user2Clicked()),
+ win, SLOT(saveResults()));
+
+ connect(win ,SIGNAL(resultSelected(bool)),
+ this,SIGNAL(resultSelected(bool)));
+
+ query = new KQuery(frame);
+ connect(query, SIGNAL(addFile(const KFileItem*,const QString&)),
+ SLOT(addFile(const KFileItem*,const QString&)));
+ connect(query, SIGNAL(result(int)), SLOT(slotResult(int)));
+
+ dirwatch=NULL;
+}
+
+KfindDlg::~KfindDlg()
+{
+ stopSearch();
+}
+
+void KfindDlg::closeEvent(QCloseEvent *)
+{
+ stopSearch();
+ slotClose();
+}
+
+void KfindDlg::setProgressMsg(const QString &msg)
+{
+ mStatusBar->changeItem(msg, 1);
+}
+
+void KfindDlg::setStatusMsg(const QString &msg)
+{
+ mStatusBar->changeItem(msg, 0);
+}
+
+
+void KfindDlg::startSearch()
+{
+ tabWidget->setQuery(query);
+
+ isResultReported = false;
+
+ // Reset count - use the same i18n as below
+ setProgressMsg(i18n("one file found", "%n files found", 0));
+
+ emit resultSelected(false);
+ emit haveResults(false);
+
+ enableButton(Apply, false); // Disable "Find"
+ enableButton(User1, true); // Enable "Stop"
+ enableButton(User2, false); // Disable "Save As..."
+
+ if(dirwatch!=NULL)
+ delete dirwatch;
+ dirwatch=new KDirWatch();
+ connect(dirwatch, SIGNAL(created(const QString&)), this, SLOT(slotNewItems(const QString&)));
+ connect(dirwatch, SIGNAL(deleted(const QString&)), this, SLOT(slotDeleteItem(const QString&)));
+ dirwatch->addDir(query->url().path(),true);
+
+#if 0
+ // waba: Watching for updates is disabled for now because even with FAM it causes too
+ // much problems. See BR68220, BR77854, BR77846, BR79512 and BR85802
+ // There are 3 problems:
+ // 1) addDir() keeps looping on recursive symlinks
+ // 2) addDir() scans all subdirectories, so it basically does the same as the process that
+ // is started by KQuery but in-process, undoing the advantages of using a seperate find process
+ // A solution could be to let KQuery emit all the directories it has searched in.
+ // Either way, putting dirwatchers on a whole file system is probably just too much.
+ // 3) FAM has a tendency to deadlock with so many files (See BR77854) This has hopefully
+ // been fixed in KDirWatch, but that has not yet been confirmed.
+
+ //Getting a list of all subdirs
+ if(tabWidget->isSearchRecursive() && (dirwatch->internalMethod() == KDirWatch::FAM))
+ {
+ QStringList subdirs=getAllSubdirs(query->url().path());
+ for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it)
+ dirwatch->addDir(*it,true);
+ }
+#endif
+
+ win->beginSearch(query->url());
+ tabWidget->beginSearch();
+
+ setStatusMsg(i18n("Searching..."));
+ query->start();
+}
+
+void KfindDlg::stopSearch()
+{
+ query->kill();
+}
+
+void KfindDlg::newSearch()
+{
+ // WABA: Not used any longer?
+ stopSearch();
+
+ tabWidget->setDefaults();
+
+ emit haveResults(false);
+ emit resultSelected(false);
+
+ setFocus();
+}
+
+void KfindDlg::slotResult(int errorCode)
+{
+ if (errorCode == 0)
+ setStatusMsg(i18n("Ready."));
+ else if (errorCode == KIO::ERR_USER_CANCELED)
+ setStatusMsg(i18n("Aborted."));
+ else if (errorCode == KIO::ERR_MALFORMED_URL)
+ {
+ setStatusMsg(i18n("Error."));
+ KMessageBox::sorry( this, i18n("Please specify an absolute path in the \"Look in\" box."));
+ }
+ else if (errorCode == KIO::ERR_DOES_NOT_EXIST)
+ {
+ setStatusMsg(i18n("Error."));
+ KMessageBox::sorry( this, i18n("Could not find the specified folder."));
+ }
+ else
+ {
+ kdDebug()<<"KIO error code: "<<errorCode<<endl;
+ setStatusMsg(i18n("Error."));
+ };
+
+ enableButton(Apply, true); // Enable "Find"
+ enableButton(User1, false); // Disable "Stop"
+ enableButton(User2, true); // Enable "Save As..."
+
+ win->endSearch();
+ tabWidget->endSearch();
+ setFocus();
+
+}
+
+void KfindDlg::addFile(const KFileItem* item, const QString& matchingLine)
+{
+ win->insertItem(*item,matchingLine);
+
+ if (!isResultReported)
+ {
+ emit haveResults(true);
+ isResultReported = true;
+ }
+
+ int count = win->childCount();
+ QString str = i18n("one file found", "%n files found", count);
+ setProgressMsg(str);
+}
+
+void KfindDlg::setFocus()
+{
+ tabWidget->setFocus();
+}
+
+void KfindDlg::copySelection()
+{
+ win->copySelection();
+}
+
+void KfindDlg::about ()
+{
+ KAboutApplication dlg(this, "about", true);
+ dlg.exec ();
+}
+
+void KfindDlg::slotDeleteItem(const QString& file)
+{
+ kdDebug()<<QString("Will remove one item: %1").arg(file)<<endl;
+ QListViewItem *iter;
+ QString iterwithpath;
+
+ iter=win->firstChild();
+ while( iter ) {
+ iterwithpath=query->url().path(+1)+iter->text(1)+iter->text(0);
+
+ if(iterwithpath==file)
+ {
+ win->takeItem(iter);
+ break;
+ }
+ iter = iter->nextSibling();
+ }
+}
+
+void KfindDlg::slotNewItems( const QString& file )
+{
+ kdDebug()<<QString("Will add this item")<<endl;
+ QStringList newfiles;
+ QListViewItem *checkiter;
+ QString checkiterwithpath;
+
+ if(file.find(query->url().path(+1))==0)
+ {
+ kdDebug()<<QString("Can be added, path OK")<<endl;
+ checkiter=win->firstChild();
+ while( checkiter ) {
+ checkiterwithpath=query->url().path(+1)+checkiter->text(1)+checkiter->text(0);
+ if(file==checkiterwithpath)
+ return;
+ checkiter = checkiter->nextSibling();
+ }
+ query->slotListEntries(QStringList(file));
+ }
+}
+
+QStringList KfindDlg::getAllSubdirs(QDir d)
+{
+ QStringList dirs;
+ QStringList subdirs;
+
+ d.setFilter( QDir::Dirs );
+ dirs = d.entryList();
+
+ for(QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it)
+ {
+ if((*it==".")||(*it==".."))
+ continue;
+ subdirs.append(d.path()+"/"+*it);
+ subdirs+=getAllSubdirs(d.path()+"/"+*it);
+ }
+ return subdirs;
+}
diff --git a/kfind/kfinddlg.h b/kfind/kfinddlg.h
new file mode 100644
index 000000000..dd1aa718c
--- /dev/null
+++ b/kfind/kfinddlg.h
@@ -0,0 +1,69 @@
+/***********************************************************************
+ *
+ * KfindDlg.h
+ *
+ ***********************************************************************/
+
+#ifndef KFINDDLG_H
+#define KFINDDLG_H
+
+#include <kdialogbase.h>
+#include <kdirlister.h>
+#include <kdirwatch.h>
+
+class QString;
+
+class KQuery;
+class KURL;
+class KFileItem;
+class KfindTabWidget;
+class KfindWindow;
+class KStatusBar;
+
+class KfindDlg: public KDialogBase
+{
+Q_OBJECT
+
+public:
+ KfindDlg(const KURL & url, QWidget * parent = 0, const char * name = 0);
+ ~KfindDlg();
+ void copySelection();
+
+ void setStatusMsg(const QString &);
+ void setProgressMsg(const QString &);
+
+private:
+ void closeEvent(QCloseEvent *);
+ /*Return a QStringList of all subdirs of d*/
+ QStringList getAllSubdirs(QDir d);
+
+public slots:
+ void startSearch();
+ void stopSearch();
+ void newSearch();
+ void addFile(const KFileItem* item, const QString& matchingLine);
+ void setFocus();
+ void slotResult(int);
+// void slotSearchDone();
+ void about ();
+ void slotDeleteItem(const QString&);
+ void slotNewItems( const QString& );
+
+signals:
+ void haveResults(bool);
+ void resultSelected(bool);
+
+private:
+ KfindTabWidget *tabWidget;
+ KfindWindow * win;
+
+ bool isResultReported;
+ KQuery *query;
+ KStatusBar *mStatusBar;
+ KDirLister *dirlister;
+ KDirWatch *dirwatch;
+};
+
+#endif
+
+
diff --git a/kfind/kfindpart.cpp b/kfind/kfindpart.cpp
new file mode 100644
index 000000000..4f5d8043f
--- /dev/null
+++ b/kfind/kfindpart.cpp
@@ -0,0 +1,213 @@
+/* This file is part of the KDE projects
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kfind.h"
+#include "kfindpart.h"
+#include "kquery.h"
+
+#include <kparts/genericfactory.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <qdir.h>
+#include <kinstance.h>
+
+class KonqDirPart;
+
+typedef KParts::GenericFactory<KFindPart> KFindFactory;
+K_EXPORT_COMPONENT_FACTORY( libkfindpart, KFindFactory )
+
+KFindPart::KFindPart( QWidget * parentWidget, const char *widgetName,
+ QObject *parent, const char *name ,
+ const QStringList & /*args*/ )
+ : KonqDirPart (parent, name )/*KParts::ReadOnlyPart*/
+{
+ setInstance( KFindFactory::instance() );
+
+ setBrowserExtension( new KonqDirPartBrowserExtension( this ) );
+
+ kdDebug() << "KFindPart::KFindPart " << this << endl;
+ m_kfindWidget = new Kfind( parentWidget, widgetName );
+ m_kfindWidget->setMaximumHeight(m_kfindWidget->minimumSizeHint().height());
+ const KFileItem *item = ((KonqDirPart*)parent)->currentItem();
+ kdDebug() << "Kfind: currentItem: " << ( item ? item->url().path().local8Bit() : QString("null") ) << endl;
+ QDir d;
+ if( item && d.exists( item->url().path() ))
+ m_kfindWidget->setURL( item->url() );
+
+ setWidget( m_kfindWidget );
+
+ connect( m_kfindWidget, SIGNAL(started()),
+ this, SLOT(slotStarted()) );
+ connect( m_kfindWidget, SIGNAL(destroyMe()),
+ this, SLOT(slotDestroyMe()) );
+ connect(m_kfindWidget->dirlister,SIGNAL(deleteItem(KFileItem*)), this, SLOT(removeFile(KFileItem*)));
+ connect(m_kfindWidget->dirlister,SIGNAL(newItems(const KFileItemList&)), this, SLOT(newFiles(const KFileItemList&)));
+ //setXMLFile( "kfind.rc" );
+ query = new KQuery(this);
+ connect(query, SIGNAL(addFile(const KFileItem *, const QString&)),
+ SLOT(addFile(const KFileItem *, const QString&)));
+ connect(query, SIGNAL(result(int)),
+ SLOT(slotResult(int)));
+
+ m_kfindWidget->setQuery(query);
+ m_bShowsResult = false;
+
+ m_lstFileItems.setAutoDelete( true );
+}
+
+KFindPart::~KFindPart()
+{
+}
+
+KAboutData *KFindPart::createAboutData()
+{
+ return new KAboutData( "kfindpart", I18N_NOOP( "Find Component" ), "1.0" );
+}
+
+bool KFindPart::doOpenURL( const KURL &url )
+{
+ m_kfindWidget->setURL( url );
+ return true;
+}
+
+void KFindPart::slotStarted()
+{
+ kdDebug() << "KFindPart::slotStarted" << endl;
+ m_bShowsResult = true;
+ m_lstFileItems.clear(); // clear our internal list
+ emit started();
+ emit clear();
+}
+
+void KFindPart::addFile(const KFileItem *item, const QString& /*matchingLine*/)
+{
+ // item is deleted by caller
+ // we need to clone it
+ KFileItem *clonedItem = new KFileItem(*item);
+ m_lstFileItems.append( clonedItem );
+
+ KFileItemList lstNewItems;
+ lstNewItems.append(clonedItem);
+ emit newItems(lstNewItems);
+
+ /*
+ win->insertItem(item);
+
+ if (!isResultReported)
+ {
+ emit haveResults(true);
+ isResultReported = true;
+ }
+
+ */
+}
+
+/* An item has been removed, so update konqueror's view */
+void KFindPart::removeFile(KFileItem *item)
+{
+ KFileItem *iter;
+ KFileItemList listiter;
+
+ emit started();
+ emit clear();
+
+ m_lstFileItems.remove( item ); //not working ?
+
+ for(iter=m_lstFileItems.first(); iter; iter=m_lstFileItems.next() ) {
+ if(iter->url()!=item->url())
+ listiter.append(iter);
+ }
+
+ emit newItems(listiter);
+ emit finished();
+}
+
+void KFindPart::newFiles(const KFileItemList&)
+{
+ if(m_bShowsResult)
+ return;
+ emit started();
+ emit clear();
+ if (m_lstFileItems.count())
+ emit newItems(m_lstFileItems);
+ emit finished();
+}
+
+void KFindPart::slotResult(int errorCode)
+{
+ if (errorCode == 0)
+ emit finished();
+ //setStatusMsg(i18n("Ready."));
+ else if (errorCode == KIO::ERR_USER_CANCELED)
+ emit canceled();
+ //setStatusMsg(i18n("Aborted."));
+ else
+ emit canceled(); // TODO ?
+ //setStatusMsg(i18n("Error."));
+ m_bShowsResult=false;
+ m_kfindWidget->searchFinished();
+}
+
+void KFindPart::slotDestroyMe()
+{
+ m_kfindWidget->stopSearch();
+ emit clear(); // this is necessary to clear the delayed-mimetypes items list
+ m_lstFileItems.clear(); // clear our internal list
+ emit findClosed();
+}
+
+void KFindPart::saveState( QDataStream& stream )
+{
+ KonqDirPart::saveState(stream);
+
+ m_kfindWidget->saveState( &stream );
+ //Now we'll save the search result
+ KFileItem *fileitem=m_lstFileItems.first();
+ stream << m_lstFileItems.count();
+ while(fileitem!=NULL)
+ {
+ stream << *fileitem;
+ fileitem=m_lstFileItems.next();
+ }
+}
+
+void KFindPart::restoreState( QDataStream& stream )
+{
+ KonqDirPart::restoreState(stream);
+ int nbitems;
+ KURL itemUrl;
+
+ m_kfindWidget->restoreState( &stream );
+
+ stream >> nbitems;
+ slotStarted();
+ for(int i=0;i<nbitems;i++)
+ {
+ KFileItem* item = new KFileItem( KFileItem::Unknown, KFileItem::Unknown, KURL() );
+ stream >> *item;
+ m_lstFileItems.append(item);
+ }
+ if (nbitems)
+ emit newItems(m_lstFileItems);
+
+ emit finished();
+}
+
+#include "kfindpart.moc"
diff --git a/kfind/kfindpart.desktop b/kfind/kfindpart.desktop
new file mode 100644
index 000000000..f388003f6
--- /dev/null
+++ b/kfind/kfindpart.desktop
@@ -0,0 +1,87 @@
+[Desktop Entry]
+Type=Service
+Name=Find Part
+Name[af]=Soek Deel
+Name[ar]=ابحث عن جزء
+Name[az]=Parça tap
+Name[be]=Модуль пошуку
+Name[bg]=Търсене на модули
+Name[bn]=পার্ট অনুসন্ধান
+Name[br]=Kavout perzh
+Name[bs]=Nađi dio
+Name[ca]=Cerca la part
+Name[cs]=Najít soubor
+Name[csb]=Mòduł szëkbë
+Name[cy]=Canfod Rhan
+Name[da]=Find del
+Name[de]=Einbettungsfähiges Programm (Komponente) suchen
+Name[el]=Part Αναζήτηση
+Name[eo]=Trovokomponento
+Name[es]=Buscar parte
+Name[et]=Failide otsimise komponent
+Name[eu]=Bilatu partea
+Name[fa]=یافتن جزء
+Name[fi]=Etsi osa
+Name[fr]=Composant de recherche
+Name[fy]=In diel sykje
+Name[ga]=Aimsigh Páirt
+Name[gl]=Busca
+Name[he]=רכיב חיפוש
+Name[hi]=हिस्सा ढूंढें
+Name[hr]=Pronađi dio
+Name[hu]=Keresési objektum
+Name[id]=Cari bagian
+Name[is]=Finna hluti
+Name[it]=Trova parte
+Name[ja]=検索パート
+Name[ka]=ძიება შემადგენლობის მიხედვით
+Name[kk]=Мазмұнынан табу
+Name[km]=រក​ផ្នែក
+Name[ko]=찾기 부분
+Name[lo]=ຄັ້ນຫາບາງສ່ວນ
+Name[lt]=Surasti dalį
+Name[lv]=Meklēt Daļu
+Name[mk]=Пронајди дел
+Name[mn]=Хэсэг хайх
+Name[ms]=Cari Bahagian
+Name[mt]=Sib Parti
+Name[nb]=Finn del
+Name[nds]=Söök-Komponent
+Name[ne]=भाग फेला पार्नुहोस्
+Name[nl]=Gedeelte zoeken
+Name[nn]=Finn del
+Name[nso]=Hwetsa Seripa
+Name[pa]=ਹਿੱਸੇ ਖੋਜ
+Name[pl]=Moduł szukania
+Name[pt]=Componente de Pesquisa
+Name[pt_BR]=Componente de Busca
+Name[ro]=Componentă de căutare
+Name[ru]=Поиск по содержимому
+Name[rw]=Gushaka Igice
+Name[se]=Oza osiid
+Name[sk]=Nájsť Part
+Name[sl]=Najdi del
+Name[sr]=Део за тражење
+Name[sr@Latn]=Deo za traženje
+Name[sv]=Sökdel
+Name[ta]=பகுதி கண்டுபிடி
+Name[te]=వెతుకు భాగం
+Name[tg]=Қисматро пайдо кунед
+Name[th]=ค้นหาบางส่วน
+Name[tr]=Parça bul
+Name[tt]=Eçtälek Ezläw
+Name[uk]=Складова пошуку
+Name[ven]=Todani tshipida
+Name[vi]=Tìm từng phần
+Name[wa]=Trover des pårteyes
+Name[xh]=Fumana Indawana
+Name[zh_CN]=查找部件
+Name[zh_TW]=尋找組件
+Name[zu]=Thola Ingxenye
+MimeType=
+ServiceTypes=Konqueror/FindPart
+X-KDE-Library=libkfindpart
+X-KDE-BrowserView-AllowAsDefault=true
+X-KDE-BrowserView-HideFromMenus=true
+X-KDE-BrowserView-PassiveMode=true
+InitialPreference=10
diff --git a/kfind/kfindpart.h b/kfind/kfindpart.h
new file mode 100644
index 000000000..29b133b99
--- /dev/null
+++ b/kfind/kfindpart.h
@@ -0,0 +1,104 @@
+/* This file is part of the KDE projects
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kfindpart__h
+#define kfindpart__h
+
+#include <kparts/browserextension.h>
+#include <kparts/part.h>
+#include <kfileitem.h>
+#include <kdebug.h>
+#include <qptrlist.h>
+#include <konq_dirpart.h>
+
+class KQuery;
+class KAboutData;
+//added
+class KonqPropsView;
+class KAction;
+class KToggleAction;
+class KActionMenu;
+class QIconViewItem;
+class IconViewBrowserExtension;
+//end added
+
+class KFindPart : public KonqDirPart//KParts::ReadOnlyPart
+{
+ friend class KFindPartBrowserExtension;
+ Q_OBJECT
+ Q_PROPERTY( bool showsResult READ showsResult )
+public:
+ KFindPart( QWidget * parentWidget, const char *widgetName,
+ QObject *parent, const char *name, const QStringList & /*args*/ );
+ virtual ~KFindPart();
+
+ static KAboutData *createAboutData();
+
+ virtual bool doOpenURL( const KURL &url );
+ virtual bool doCloseURL() { return true; }
+ virtual bool openFile() { return false; }
+
+ bool showsResult() const { return m_bShowsResult; }
+
+ virtual void saveState( QDataStream &stream );
+ virtual void restoreState( QDataStream &stream );
+
+ // "Cut" icons : disable those whose URL is in lst, enable the rest //added for konqdirpart
+ virtual void disableIcons( const KURL::List & ){};
+ virtual const KFileItem * currentItem(){return 0;};
+
+signals:
+ // Konqueror connects directly to those signals
+ void started(); // started a search
+ void clear(); // delete all items
+ void newItems(const KFileItemList&); // found this/these item(s)
+ void finished(); // finished searching
+ void canceled(); // the user canceled the search
+ void findClosed(); // close us
+ void deleteItem( KFileItem *item);
+
+protected slots:
+ void slotStarted();
+ void slotDestroyMe();
+ void addFile(const KFileItem *item, const QString& matchingLine);
+ /* An item has been removed, so update konqueror's view */
+ void removeFile(KFileItem *item);
+ void slotResult(int errorCode);
+ void newFiles(const KFileItemList&);
+ // slots connected to the directory lister //added for konqdirpart
+// virtual void slotStarted();
+ virtual void slotCanceled(){};
+ virtual void slotCompleted(){};
+ virtual void slotNewItems( const KFileItemList& ){};
+ virtual void slotDeleteItem( KFileItem * ){};
+ virtual void slotRefreshItems( const KFileItemList& ){};
+ virtual void slotClear(){};
+ virtual void slotRedirection( const KURL & ){};
+
+private:
+ Kfind * m_kfindWidget;
+ KQuery *query;
+ bool m_bShowsResult; // whether the dirpart shows the results of a search or not
+ /**
+ * The internal storage of file items
+ */
+ QPtrList<KFileItem> m_lstFileItems;
+};
+
+#endif
diff --git a/kfind/kfindpart.kdevprj b/kfind/kfindpart.kdevprj
new file mode 100644
index 000000000..d9fbfc7e2
--- /dev/null
+++ b/kfind/kfindpart.kdevprj
@@ -0,0 +1,178 @@
+[./AUTHORS]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./Makefile.am]
+files=./AUTHORS,./ChangeLog,./README,./TODO,./findpart.desktop,./kfind.cpp,./kfind.h,./kfindpart.cpp,./kfindpart.desktop,./kfindpart.h,./kftabdlg.cpp,./kftabdlg.h,./kquery.cpp,./kquery.h,./version.h,./kfindpart.kdevprj,
+sub_dirs=pics,
+type=normal
+
+[./README]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./TODO]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./findpart.desktop]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./kfind.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[./kfind.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[./kfindpart.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[./kfindpart.desktop]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./kfindpart.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[./kfindpart.kdevprj]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./kftabdlg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[./kftabdlg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[./kquery.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[./kquery.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[./version.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[Config for BinMakefileAm]
+addcxxflags=
+bin_program=kfindpart
+cxxflags=
+ldadd=
+ldflags=
+
+[General]
+AMChanged=false
+author=eric
+email=eric@darkstar.fr
+kdevprj_version=1.3
+lfv_open_groups=
+makefiles=./Makefile.am,pics/Makefile.am,
+project_name=kfindpart
+project_type=normal_empty
+sub_dir=
+version=
+version_control=CVS
+workspace=1
+
+[LFV Groups]
+Desktop=*.desktop,
+GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS,
+Headers=*.h,*.hxx,*.hpp,*.H,
+Others=*,
+Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l,
+Translations=*.ts,*.po,
+User Interface=*.ui,*.kdevdlg,*.rc,
+groups=Headers,Sources,GNU,Translations,User Interface,Desktop,Others
+
+[pics/Makefile.am]
+files=pics/lo22-action-archive.png,pics/lo22-action-delete.png,pics/lo22-action-idea.png,pics/lo22-action-info.png,pics/lo22-action-openfile.png,pics/lo22-action-save.png,pics/lo22-action-search.png,
+sub_dirs=
+type=normal
+
+[pics/lo22-action-archive.png]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[pics/lo22-action-delete.png]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[pics/lo22-action-idea.png]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[pics/lo22-action-info.png]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[pics/lo22-action-openfile.png]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[pics/lo22-action-save.png]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[pics/lo22-action-search.png]
+dist=true
+install=false
+install_location=
+type=DATA
diff --git a/kfind/kfindpart.kdevses b/kfind/kfindpart.kdevses
new file mode 100644
index 000000000..ad6d09112
--- /dev/null
+++ b/kfind/kfindpart.kdevses
@@ -0,0 +1,20 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE KDevPrjSession>
+<KDevPrjSession>
+ <Mainframe MaximizeMode="0" />
+ <DocsAndViews NumberOfDocuments="4" >
+ <Doc0 CursorPosLine="44" Type="KWriteDoc" NumberOfViews="1" CursorPosCol="0" FileName="/home/eric/kde/kdebase/kfind/kfind.cpp" >
+ <View0 Top="0" Width="754" Attach="1" Height="388" Left="0" Focus="0" Type="KWriteView" MinMaxMode="0" />
+ </Doc0>
+ <Doc1 CursorPosLine="20" Type="KWriteDoc" NumberOfViews="1" CursorPosCol="0" FileName="/home/eric/kde/kdebase/kfind/kfind.h" >
+ <View0 Top="0" Width="754" Attach="1" Height="388" Left="0" Focus="0" Type="KWriteView" MinMaxMode="0" />
+ </Doc1>
+ <Doc2 CursorPosLine="31" Type="KWriteDoc" NumberOfViews="1" CursorPosCol="0" FileName="/home/eric/kde/kdebase/kfind/kftabdlg.h" >
+ <View0 Top="0" Width="754" Attach="1" Height="388" Left="0" Focus="0" Type="KWriteView" MinMaxMode="0" />
+ </Doc2>
+ <Doc3 CursorPosLine="51" Type="KWriteDoc" NumberOfViews="1" CursorPosCol="0" FileName="/home/eric/kde/kdebase/kfind/kftabdlg.cpp" >
+ <View0 Top="0" Width="754" Attach="1" Height="388" Left="0" Focus="1" Type="KWriteView" MinMaxMode="0" />
+ </Doc3>
+ </DocsAndViews>
+ <LastCompileConfig>(Default)</LastCompileConfig>
+</KDevPrjSession>
diff --git a/kfind/kftabdlg.cpp b/kfind/kftabdlg.cpp
new file mode 100644
index 000000000..7f8f73f96
--- /dev/null
+++ b/kfind/kftabdlg.cpp
@@ -0,0 +1,871 @@
+/***********************************************************************
+ *
+ * kftabdlg.cpp
+ *
+ **********************************************************************/
+
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qcombobox.h>
+#include <qspinbox.h>
+#include <qpushbutton.h>
+#include <qapplication.h>
+
+#include <kcalendarsystem.h>
+#include <kglobal.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <kregexpeditorinterface.h>
+#include <kparts/componentfactory.h>
+#include <kstandarddirs.h>
+
+#include "kquery.h"
+#include "kftabdlg.h"
+
+// Static utility functions
+static void save_pattern(QComboBox *, const QString &, const QString &);
+
+#define SPECIAL_TYPES 7
+
+class KSortedMimeTypeList : public QPtrList<KMimeType>
+{
+public:
+ KSortedMimeTypeList() { };
+ int compareItems(QPtrCollection::Item s1, QPtrCollection::Item s2)
+ {
+ KMimeType *item1 = (KMimeType *) s1;
+ KMimeType *item2 = (KMimeType *) s2;
+ if (item1->comment() > item2->comment()) return 1;
+ if (item1->comment() == item2->comment()) return 0;
+ return -1;
+ }
+};
+
+KfindTabWidget::KfindTabWidget(QWidget *parent, const char *name)
+ : QTabWidget( parent, name ), regExpDialog(0)
+{
+ // This validator will be used for all numeric edit fields
+ //KDigitValidator *digitV = new KDigitValidator(this);
+
+ // ************ Page One ************
+
+ pages[0] = new QWidget( this, "page1" );
+
+ nameBox = new KComboBox(TRUE, pages[0], "combo1");
+ nameBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
+ QLabel * namedL = new QLabel(nameBox, i18n("&Named:"), pages[0], "named");
+ QToolTip::add( namedL, i18n("You can use wildcard matching and \";\" for separating multiple names") );
+ dirBox = new KComboBox(TRUE, pages[0], "combo2");
+ dirBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
+ QLabel * lookinL = new QLabel(dirBox, i18n("Look &in:"), pages[0], "named");
+ subdirsCb = new QCheckBox(i18n("Include &subfolders"), pages[0]);
+ caseSensCb = new QCheckBox(i18n("Case s&ensitive search"), pages[0]);
+ browseB = new QPushButton(i18n("&Browse..."), pages[0]);
+ useLocateCb = new QCheckBox(i18n("&Use files index"), pages[0]);
+
+ // Setup
+
+ subdirsCb->setChecked(true);
+ caseSensCb->setChecked(false);
+ useLocateCb->setChecked(false);
+ if(KStandardDirs::findExe("locate")==NULL)
+ useLocateCb->setEnabled(false);
+
+ nameBox->setDuplicatesEnabled(FALSE);
+ nameBox->setFocus();
+ dirBox->setDuplicatesEnabled(FALSE);
+
+ nameBox->setInsertionPolicy(QComboBox::AtTop);
+ dirBox->setInsertionPolicy(QComboBox::AtTop);
+
+ const QString nameWhatsThis
+ = i18n("<qt>Enter the filename you are looking for. <br>"
+ "Alternatives may be separated by a semicolon \";\".<br>"
+ "<br>"
+ "The filename may contain the following special characters:"
+ "<ul>"
+ "<li><b>?</b> matches any single character</li>"
+ "<li><b>*</b> matches zero or more of any characters</li>"
+ "<li><b>[...]</b> matches any of the characters in braces</li>"
+ "</ul>"
+ "<br>"
+ "Example searches:"
+ "<ul>"
+ "<li><b>*.kwd;*.txt</b> finds all files ending with .kwd or .txt</li>"
+ "<li><b>go[dt]</b> finds god and got</li>"
+ "<li><b>Hel?o</b> finds all files that start with \"Hel\" and end with \"o\", "
+ "having one character in between</li>"
+ "<li><b>My Document.kwd</b> finds a file of exactly that name</li>"
+ "</ul></qt>");
+ QWhatsThis::add(nameBox,nameWhatsThis);
+ QWhatsThis::add(namedL,nameWhatsThis);
+ const QString whatsfileindex
+ = i18n("<qt>This lets you use the files' index created by the <i>slocate</i> "
+ "package to speed-up the search; remember to update the index from time to time "
+ "(using <i>updatedb</i>)."
+ "</qt>");
+ QWhatsThis::add(useLocateCb,whatsfileindex);
+
+ // Layout
+
+ QGridLayout *grid = new QGridLayout( pages[0], 3, 2,
+ KDialog::marginHint(),
+ KDialog::spacingHint() );
+ QBoxLayout *subgrid = new QVBoxLayout( -1 , "subgrid" );
+ grid->addWidget( namedL, 0, 0 );
+ grid->addMultiCellWidget( nameBox, 0, 0, 1, 2 );
+ grid->addWidget( lookinL, 1, 0 );
+ grid->addWidget( dirBox, 1, 1 );
+ grid->addWidget( browseB, 1, 2);
+ grid->setColStretch(1,1);
+ grid->addMultiCellLayout( subgrid, 2, 2, 1, 2 );
+ subgrid->addWidget( subdirsCb );
+ subgrid->addWidget( caseSensCb);
+ subgrid->addWidget( useLocateCb );
+ subgrid->addStretch(1);
+
+ // Signals
+
+ connect( browseB, SIGNAL(clicked()),
+ this, SLOT(getDirectory()) );
+
+ connect( nameBox, SIGNAL(activated(int)),
+ this, SIGNAL(startSearch()));
+
+ // ************ Page Two
+
+ pages[1] = new QWidget( this, "page2" );
+
+ findCreated = new QCheckBox(i18n("Find all files created or &modified:"), pages[1]);
+ bg = new QButtonGroup();
+ rb[0] = new QRadioButton(i18n("&between"), pages[1] );
+ rb[1] = new QRadioButton(i18n("&during the previous"), pages[1] );
+ QLabel * andL = new QLabel(i18n("and"), pages[1], "and");
+ betweenType = new KComboBox(FALSE, pages[1], "comboBetweenType");
+ betweenType->insertItem(i18n("minute(s)"));
+ betweenType->insertItem(i18n("hour(s)"));
+ betweenType->insertItem(i18n("day(s)"));
+ betweenType->insertItem(i18n("month(s)"));
+ betweenType->insertItem(i18n("year(s)"));
+ betweenType->setCurrentItem(1);
+
+
+ QDate dt = KGlobal::locale()->calendar()->addYears(QDate::currentDate(), -1);
+
+ fromDate = new KDateCombo(dt, pages[1], "fromDate");
+ toDate = new KDateCombo(pages[1], "toDate");
+ timeBox = new QSpinBox(1, 60, 1, pages[1], "timeBox");
+
+ sizeBox =new KComboBox(FALSE, pages[1], "sizeBox");
+ QLabel * sizeL =new QLabel(sizeBox,i18n("File &size is:"), pages[1],"size");
+ sizeEdit=new QSpinBox(0, INT_MAX, 1, pages[1], "sizeEdit" );
+ sizeEdit->setValue(1);
+ sizeUnitBox =new KComboBox(FALSE, pages[1], "sizeUnitBox");
+
+ m_usernameBox = new KComboBox( true, pages[1], "m_combo1");
+ QLabel *usernameLabel= new QLabel(m_usernameBox,i18n("Files owned by &user:"),pages[1]);
+ m_groupBox = new KComboBox( true, pages[1], "m_combo2");
+ QLabel *groupLabel= new QLabel(m_groupBox,i18n("Owned by &group:"),pages[1]);
+
+ sizeBox ->insertItem( i18n("(none)") );
+ sizeBox ->insertItem( i18n("At Least") );
+ sizeBox ->insertItem( i18n("At Most") );
+ sizeBox ->insertItem( i18n("Equal To") );
+
+ sizeUnitBox ->insertItem( i18n("Bytes") );
+ sizeUnitBox ->insertItem( i18n("KB") );
+ sizeUnitBox ->insertItem( i18n("MB") );
+ sizeUnitBox ->insertItem( i18n("GB") );
+ sizeUnitBox ->setCurrentItem(1);
+
+ int tmp = sizeEdit->fontMetrics().width(" 000000000 ");
+ sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
+
+ m_usernameBox->setDuplicatesEnabled(FALSE);
+ m_groupBox->setDuplicatesEnabled(FALSE);
+ m_usernameBox->setInsertionPolicy(QComboBox::AtTop);
+ m_groupBox->setInsertionPolicy(QComboBox::AtTop);
+
+
+ // Setup
+ timeBox->setButtonSymbols(QSpinBox::PlusMinus);
+ rb[0]->setChecked(true);
+ bg->insert( rb[0] );
+ bg->insert( rb[1] );
+
+ // Layout
+
+ QGridLayout *grid1 = new QGridLayout( pages[1], 5, 6,
+ KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ grid1->addMultiCellWidget(findCreated, 0, 0, 0, 3 );
+ grid1->addColSpacing(0, KDialog::spacingHint());
+
+ grid1->addWidget(rb[0], 1, 1 );
+ grid1->addWidget(fromDate, 1, 2 );
+ grid1->addWidget(andL, 1, 3, AlignHCenter );
+ grid1->addWidget(toDate, 1, 4 );
+
+ grid1->addWidget(rb[1], 2, 1 );
+ grid1->addMultiCellWidget(timeBox, 2, 2, 2, 3);
+ grid1->addWidget(betweenType, 2, 4 );
+
+ grid1->addMultiCellWidget(sizeL,3,3,0,1);
+ grid1->addWidget(sizeBox,3,2);
+ grid1->addWidget(sizeEdit,3,3);
+ grid1->addWidget(sizeUnitBox,3,4);
+
+ grid1->addMultiCellWidget(usernameLabel,4,4,0,1);
+ grid1->addWidget(m_usernameBox,4,2);
+ grid1->addWidget(groupLabel,4,3);
+ grid1->addWidget(m_groupBox,4,4);
+
+ for (int c=1; c<=4; c++)
+ grid1->setColStretch(c,1);
+
+ grid1->setRowStretch(6,1);
+
+ // Connect
+ connect( findCreated, SIGNAL(toggled(bool)), SLOT(fixLayout()) );
+ connect( bg, SIGNAL(clicked(int)), this, SLOT(fixLayout()) );
+ connect( sizeBox, SIGNAL(highlighted(int)), this, SLOT(slotSizeBoxChanged(int)));
+
+
+ // ************ Page Three
+
+ pages[2] = new QWidget( this, "page3" );
+
+ typeBox =new KComboBox(FALSE, pages[2], "typeBox");
+ typeBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
+ QLabel * typeL =new QLabel(typeBox, i18n("File &type:"), pages[2], "type");
+ textEdit=new KLineEdit(pages[2], "textEdit" );
+ QLabel * textL =new QLabel(textEdit, i18n("C&ontaining text:"), pages[2], "text");
+
+ connect( textEdit, SIGNAL(returnPressed(const QString &)), SIGNAL( startSearch()));
+
+ const QString containingtext
+ = i18n("<qt>If specified, only files that contain this text"
+ " are found. Note that not all file types from the list"
+ " above are supported. Please refer to the documentation"
+ " for a list of supported file types."
+ "</qt>");
+ QToolTip::add(textEdit,containingtext);
+ QWhatsThis::add(textL,containingtext);
+
+ caseContextCb =new QCheckBox(i18n("Case s&ensitive"), pages[2]);
+ binaryContextCb =new QCheckBox(i18n("Include &binary files"), pages[2]);
+ regexpContentCb =new QCheckBox(i18n("Regular e&xpression"), pages[2]);
+
+ const QString binaryTooltip
+ = i18n("<qt>This lets you search in any type of file, "
+ "even those that usually do not contain text (for example "
+ "program files and images).</qt>");
+ QToolTip::add(binaryContextCb,binaryTooltip);
+
+ QPushButton* editRegExp = 0;
+ if ( !KTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() ) {
+ // The editor is available, so lets use it.
+ editRegExp = new QPushButton(i18n("&Edit..."), pages[2], "editRegExp");
+ }
+
+ metainfokeyEdit=new KLineEdit(pages[2], "textEdit" );
+ metainfoEdit=new KLineEdit(pages[2], "textEdit" );
+ QLabel * textMetaInfo = new QLabel(metainfoEdit, i18n("fo&r:"), pages[2], "text");
+ QLabel * textMetaKey = new QLabel(metainfokeyEdit, i18n("Search &metainfo sections:"), pages[2], "text");
+
+ // Setup
+ typeBox->insertItem(i18n("All Files & Folders"));
+ typeBox->insertItem(i18n("Files"));
+ typeBox->insertItem(i18n("Folders"));
+ typeBox->insertItem(i18n("Symbolic Links"));
+ typeBox->insertItem(i18n("Special Files (Sockets, Device Files, ...)"));
+ typeBox->insertItem(i18n("Executable Files"));
+ typeBox->insertItem(i18n("SUID Executable Files"));
+ typeBox->insertItem(i18n("All Images"));
+ typeBox->insertItem(i18n("All Video"));
+ typeBox->insertItem(i18n("All Sounds"));
+
+ initMimeTypes();
+ initSpecialMimeTypes();
+
+ for ( KMimeType::List::ConstIterator it = m_types.begin();
+ it != m_types.end(); ++it )
+ {
+ KMimeType::Ptr typ = *it;
+ typeBox->insertItem(typ->pixmap( KIcon::Small ), typ->comment());
+ }
+
+ if ( editRegExp ) {
+ // The editor was available, so lets use it.
+ connect( regexpContentCb, SIGNAL(toggled(bool) ), editRegExp, SLOT(setEnabled(bool)) );
+ editRegExp->setEnabled(false);
+ connect( editRegExp, SIGNAL(clicked()), this, SLOT( slotEditRegExp() ) );
+ }
+ else
+ regexpContentCb->hide();
+
+ // Layout
+ tmp = sizeEdit->fontMetrics().width(" 00000 ");
+ sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
+
+ QGridLayout *grid2 = new QGridLayout( pages[2], 5, 4,
+ KDialog::marginHint(),
+ KDialog::spacingHint() );
+ grid2->addWidget( typeL, 0, 0 );
+ grid2->addWidget( textL, 1, 0 );
+ grid2->addMultiCellWidget( typeBox, 0, 0, 1, 3 );
+ grid2->addMultiCellWidget( textEdit, 1, 1, 1, 3 );
+ grid2->addWidget( regexpContentCb, 2, 2);
+ grid2->addWidget( caseContextCb, 2, 1 );
+ grid2->addWidget( binaryContextCb, 3, 1);
+
+ grid2->addWidget( textMetaKey, 4, 0 );
+ grid2->addWidget( metainfokeyEdit, 4, 1 );
+ grid2->addWidget( textMetaInfo, 4, 2, AlignHCenter );
+ grid2->addWidget( metainfoEdit, 4, 3 );
+
+ metainfokeyEdit->setText("*");
+
+ if ( editRegExp ) {
+ // The editor was available, so lets use it.
+ grid2->addWidget( editRegExp, 2, 3 );
+ }
+
+ addTab( pages[0], i18n("Name/&Location") );
+ addTab( pages[2], i18n("C&ontents") );
+ addTab( pages[1], i18n("&Properties") );
+
+
+ // Setup
+ const QString whatsmetainfo
+ = i18n("<qt>Search within files' specific comments/metainfo<br>"
+ "These are some examples:<br>"
+ "<ul>"
+ "<li><b>Audio files (mp3...)</b> Search in id3 tag for a title, an album</li>"
+ "<li><b>Images (png...)</b> Search images with a special resolution, comment...</li>"
+ "</ul>"
+ "</qt>");
+ const QString whatsmetainfokey
+ = i18n("<qt>If specified, search only in this field<br>"
+ "<ul>"
+ "<li><b>Audio files (mp3...)</b> This can be Title, Album...</li>"
+ "<li><b>Images (png...)</b> Search only in Resolution, Bitdepth...</li>"
+ "</ul>"
+ "</qt>");
+ QWhatsThis::add(textMetaInfo,whatsmetainfo);
+ QToolTip::add(metainfoEdit,whatsmetainfo);
+ QWhatsThis::add(textMetaKey,whatsmetainfokey);
+ QToolTip::add(metainfokeyEdit,whatsmetainfokey);
+
+
+ fixLayout();
+ loadHistory();
+}
+
+KfindTabWidget::~KfindTabWidget()
+{
+ delete pages[0];
+ delete pages[1];
+ delete pages[2];
+}
+
+void KfindTabWidget::setURL( const KURL & url )
+{
+ KConfig *conf = KGlobal::config();
+ conf->setGroup("History");
+ m_url = url;
+ QStringList sl = conf->readPathListEntry("Directories");
+ dirBox->clear(); // make sure there is no old Stuff in there
+
+ if(!sl.isEmpty()) {
+ dirBox->insertStringList(sl);
+ // If the _searchPath already exists in the list we do not
+ // want to add it again
+ int indx = sl.findIndex(m_url.prettyURL());
+ if(indx == -1)
+ dirBox->insertItem(m_url.prettyURL(), 0); // make it the first one
+ else
+ dirBox->setCurrentItem(indx);
+ }
+ else {
+ QDir m_dir("/lib");
+ dirBox ->insertItem( m_url.prettyURL() );
+ dirBox ->insertItem( "file:" + QDir::homeDirPath() );
+ dirBox ->insertItem( "file:/" );
+ dirBox ->insertItem( "file:/usr" );
+ if (m_dir.exists())
+ dirBox ->insertItem( "file:/lib" );
+ dirBox ->insertItem( "file:/home" );
+ dirBox ->insertItem( "file:/etc" );
+ dirBox ->insertItem( "file:/var" );
+ dirBox ->insertItem( "file:/mnt" );
+ }
+}
+
+void KfindTabWidget::initMimeTypes()
+{
+ KMimeType::List tmp = KMimeType::allMimeTypes();
+ KSortedMimeTypeList sortedList;
+ for ( KMimeType::List::ConstIterator it = tmp.begin();
+ it != tmp.end(); ++it )
+ {
+ KMimeType * type = *it;
+ if ((!type->comment().isEmpty())
+ && (!type->name().startsWith("kdedevice/"))
+ && (!type->name().startsWith("all/")))
+ sortedList.append(type);
+ }
+ sortedList.sort();
+ for ( KMimeType *type = sortedList.first(); type; type = sortedList.next())
+ {
+ m_types.append(type);
+ }
+}
+
+void KfindTabWidget::initSpecialMimeTypes()
+{
+ KMimeType::List tmp = KMimeType::allMimeTypes();
+
+ for ( KMimeType::List::ConstIterator it = tmp.begin(); it != tmp.end(); ++it )
+ {
+ KMimeType * type = *it;
+
+ if(!type->comment().isEmpty()) {
+ if(type->name().startsWith("image/"))
+ m_ImageTypes.append(type->name());
+ else if(type->name().startsWith("video/"))
+ m_VideoTypes.append(type->name());
+ else if(type->name().startsWith("audio/"))
+ m_AudioTypes.append(type->name());
+ }
+ }
+}
+
+void KfindTabWidget::saveHistory()
+{
+ save_pattern(nameBox, "History", "Patterns");
+ save_pattern(dirBox, "History", "Directories");
+}
+
+void KfindTabWidget::loadHistory()
+{
+ // Load pattern history
+ KConfig *conf = KGlobal::config();
+ conf->setGroup("History");
+ QStringList sl = conf->readListEntry("Patterns");
+ if(!sl.isEmpty())
+ nameBox->insertStringList(sl);
+ else
+ nameBox->insertItem("*");
+
+ sl = conf->readPathListEntry("Directories");
+ if(!sl.isEmpty()) {
+ dirBox->insertStringList(sl);
+ // If the _searchPath already exists in the list we do not
+ // want to add it again
+ int indx = sl.findIndex(m_url.prettyURL());
+ if(indx == -1)
+ dirBox->insertItem(m_url.prettyURL(), 0); // make it the first one
+ else
+ dirBox->setCurrentItem(indx);
+ }
+ else {
+ QDir m_dir("/lib");
+ dirBox ->insertItem( m_url.prettyURL() );
+ dirBox ->insertItem( "file:" + QDir::homeDirPath() );
+ dirBox ->insertItem( "file:/" );
+ dirBox ->insertItem( "file:/usr" );
+ if (m_dir.exists())
+ dirBox ->insertItem( "file:/lib" );
+ dirBox ->insertItem( "file:/home" );
+ dirBox ->insertItem( "file:/etc" );
+ dirBox ->insertItem( "file:/var" );
+ dirBox ->insertItem( "file:/mnt" );
+ }
+}
+
+void KfindTabWidget::slotEditRegExp()
+{
+ if ( ! regExpDialog )
+ regExpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString::null, this );
+
+ KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( regExpDialog->qt_cast( "KRegExpEditorInterface" ) );
+ if ( !iface )
+ return;
+
+ iface->setRegExp( textEdit->text() );
+ bool ok = regExpDialog->exec();
+ if ( ok )
+ textEdit->setText( iface->regExp() );
+}
+
+void KfindTabWidget::setFocus()
+{
+ nameBox->setFocus();
+ nameBox->lineEdit()->selectAll();
+}
+
+void KfindTabWidget::slotSizeBoxChanged(int index)
+{
+ sizeEdit->setEnabled((bool)(index != 0));
+ sizeUnitBox->setEnabled((bool)(index != 0));
+}
+
+void KfindTabWidget::setDefaults()
+{
+ QDate dt = KGlobal::locale()->calendar()->addYears(QDate::currentDate(), -1);
+
+ fromDate ->setDate(dt);
+ toDate ->setDate(QDate::currentDate());
+
+ timeBox->setValue(1);
+ betweenType->setCurrentItem(1);
+
+ typeBox ->setCurrentItem(0);
+ sizeBox ->setCurrentItem(0);
+ sizeUnitBox ->setCurrentItem(1);
+ sizeEdit->setValue(1);
+}
+
+/*
+ Checks if dates are correct and popups a error box
+ if they are not.
+*/
+bool KfindTabWidget::isDateValid()
+{
+ // All files
+ if ( !findCreated->isChecked() ) return TRUE;
+
+ if (rb[1]->isChecked())
+ {
+ if (timeBox->value() > 0 ) return TRUE;
+
+ KMessageBox::sorry(this, i18n("Unable to search within a period which is less than a minute."));
+ return FALSE;
+ }
+
+ // If we can not parse either of the dates or
+ // "from" date is bigger than "to" date return FALSE.
+ QDate hi1, hi2;
+
+ QString str;
+ if ( ! fromDate->getDate(&hi1).isValid() ||
+ ! toDate->getDate(&hi2).isValid() )
+ str = i18n("The date is not valid.");
+ else if ( hi1 > hi2 )
+ str = i18n("Invalid date range.");
+ else if ( QDate::currentDate() < hi1 )
+ str = i18n("Unable to search dates in the future.");
+
+ if (!str.isNull()) {
+ KMessageBox::sorry(0, str);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void KfindTabWidget::setQuery(KQuery *query)
+{
+ KIO::filesize_t size;
+ KIO::filesize_t sizeunit;
+ bool itemAlreadyContained(false);
+ // only start if we have valid dates
+ if (!isDateValid()) return;
+
+ query->setPath(KURL(dirBox->currentText().stripWhiteSpace()));
+
+ for (int idx=0; idx<dirBox->count(); idx++)
+ if (dirBox->text(idx)==dirBox->currentText())
+ itemAlreadyContained=true;
+
+ if (!itemAlreadyContained)
+ dirBox->insertItem(dirBox->currentText().stripWhiteSpace(),0);
+
+ QString regex = nameBox->currentText().isEmpty() ? "*" : nameBox->currentText();
+ query->setRegExp(regex, caseSensCb->isChecked());
+ itemAlreadyContained=false;
+ for (int idx=0; idx<nameBox->count(); idx++)
+ if (nameBox->text(idx)==nameBox->currentText())
+ itemAlreadyContained=true;
+
+ if (!itemAlreadyContained)
+ nameBox->insertItem(nameBox->currentText(),0);
+
+ query->setRecursive(subdirsCb->isChecked());
+
+ switch (sizeUnitBox->currentItem())
+ {
+ case 0:
+ sizeunit = 1; //one byte
+ break;
+ case 2:
+ sizeunit = 1048576; //1M
+ break;
+ case 3:
+ sizeunit = 1073741824; //1GB
+ break;
+ case 1: //fall to default case
+ default:
+ sizeunit = 1024; //1k
+ break;
+ }
+ size = sizeEdit->value() * sizeunit;
+
+// TODO: troeder: do we need this check since it is very unlikely-
+// to exceed ULLONG_MAX with INT_MAX * 1024^3.-
+// Or is there an arch where this can happen?
+#if 0
+ if (size < 0) // overflow
+ if (KMessageBox::warningYesNo(this, i18n("Size is too big. Set maximum size value?"), i18n("Error"),i18n("Set"),i18n("Do Not Set"))
+ == KMessageBox::Yes)
+ {
+ sizeEdit->setValue(INT_MAX);
+ sizeUnitBox->setCurrentItem(0);
+ size = INT_MAX;
+ }
+ else
+ return;
+#endif
+
+ // set range mode and size value
+ query->setSizeRange(sizeBox->currentItem(),size,0);
+
+ // dates
+ QDateTime epoch;
+ epoch.setTime_t(0);
+
+ // Add date predicate
+ if (findCreated->isChecked()) { // Modified
+ if (rb[0]->isChecked()) { // Between dates
+ QDate q1, q2;
+ fromDate->getDate(&q1);
+ toDate->getDate(&q2);
+
+ // do not generate negative numbers .. find doesn't handle that
+ time_t time1 = epoch.secsTo(q1);
+ time_t time2 = epoch.secsTo(q2.addDays(1)) - 1; // Include the last day
+
+ query->setTimeRange(time1, time2);
+ }
+ else
+ {
+ time_t cur = time(NULL);
+ time_t minutes = cur;
+
+ switch (betweenType->currentItem())
+ {
+ case 0: // minutes
+ minutes = timeBox->value();
+ break;
+ case 1: // hours
+ minutes = 60 * timeBox->value();
+ break;
+ case 2: // days
+ minutes = 60 * 24 * timeBox->value();
+ break;
+ case 3: // months
+ minutes = 60 * 24 * (time_t)(timeBox->value() * 30.41667);
+ break;
+ case 4: // years
+ minutes = 12 * 60 * 24 * (time_t)(timeBox->value() * 30.41667);
+ break;
+ }
+
+ query->setTimeRange(cur - minutes * 60, 0);
+ }
+ }
+ else
+ query->setTimeRange(0, 0);
+
+ query->setUsername( m_usernameBox->currentText() );
+ query->setGroupname( m_groupBox->currentText() );
+
+ query->setFileType(typeBox->currentItem());
+
+ int id = typeBox->currentItem()-10;
+
+ if ((id >= -3) && (id < (int) m_types.count()))
+ {
+ switch(id)
+ {
+ case -3:
+ query->setMimeType( m_ImageTypes );
+ break;
+ case -2:
+ query->setMimeType( m_VideoTypes );
+ break;
+ case -1:
+ query->setMimeType( m_AudioTypes );
+ break;
+ default:
+ query->setMimeType( m_types[id]->name() );
+ }
+ }
+ else
+ {
+ query->setMimeType( QString::null );
+ }
+
+ //Metainfo
+ query->setMetaInfo(metainfoEdit->text(), metainfokeyEdit->text());
+
+ //Use locate to speed-up search ?
+ query->setUseFileIndex(useLocateCb->isChecked());
+
+ query->setContext(textEdit->text(), caseContextCb->isChecked(),
+ binaryContextCb->isChecked(), regexpContentCb->isChecked());
+}
+
+QString KfindTabWidget::date2String(const QDate & date) {
+ return(KGlobal::locale()->formatDate(date, true));
+}
+
+QDate &KfindTabWidget::string2Date(const QString & str, QDate *qd) {
+ return *qd = KGlobal::locale()->readDate(str);
+}
+
+void KfindTabWidget::getDirectory()
+{
+ QString result =
+ KFileDialog::getExistingDirectory( dirBox->text(dirBox->currentItem()).stripWhiteSpace(),
+ this );
+
+ if (!result.isEmpty())
+ {
+ for (int i = 0; i < dirBox->count(); i++)
+ if (result == dirBox->text(i)) {
+ dirBox->setCurrentItem(i);
+ return;
+ }
+ dirBox->insertItem(result, 0);
+ dirBox->setCurrentItem(0);
+ }
+}
+
+void KfindTabWidget::beginSearch()
+{
+/// dirlister->openURL(KURL(dirBox->currentText().stripWhiteSpace()));
+
+ saveHistory();
+ setEnabled( FALSE );
+}
+
+void KfindTabWidget::endSearch()
+{
+ setEnabled( TRUE );
+}
+
+/*
+ Disables/enables all edit fields depending on their
+ respective check buttons.
+*/
+void KfindTabWidget::fixLayout()
+{
+ int i;
+ // If "All files" is checked - disable all edits
+ // and second radio group on page two
+
+ if(! findCreated->isChecked()) {
+ fromDate->setEnabled(FALSE);
+ toDate->setEnabled(FALSE);
+ timeBox->setEnabled(FALSE);
+ for(i=0; i<2; i++)
+ rb[i]->setEnabled(FALSE);
+ betweenType->setEnabled(FALSE);
+ }
+ else {
+ for(i=0; i<2; i++)
+ rb[i]->setEnabled(TRUE);
+
+ fromDate->setEnabled(rb[0]->isChecked());
+ toDate->setEnabled(rb[0]->isChecked());
+ timeBox->setEnabled(rb[1]->isChecked());
+ betweenType->setEnabled(rb[1]->isChecked());
+ }
+
+ // Size box on page three
+ sizeEdit->setEnabled(sizeBox->currentItem() != 0);
+ sizeUnitBox->setEnabled(sizeBox->currentItem() != 0);
+}
+
+bool KfindTabWidget::isSearchRecursive()
+{
+ return subdirsCb->isChecked();
+}
+
+
+/**
+ Digit validator. Allows only digits to be typed.
+**/
+KDigitValidator::KDigitValidator( QWidget * parent, const char *name )
+ : QValidator( parent, name )
+{
+ r = new QRegExp("^[0-9]*$");
+}
+
+KDigitValidator::~KDigitValidator()
+{
+ delete r;
+}
+
+QValidator::State KDigitValidator::validate( QString & input, int & ) const
+{
+ if (r->search(input) < 0) {
+ // Beep on user if he enters non-digit
+ QApplication::beep();
+ return QValidator::Invalid;
+ }
+ else
+ return QValidator::Acceptable;
+}
+
+//*******************************************************
+// Static utility functions
+//*******************************************************
+static void save_pattern(QComboBox *obj,
+ const QString & group, const QString & entry)
+{
+ // QComboBox allows insertion of items more than specified by
+ // maxCount() (QT bug?). This API call will truncate list if needed.
+ obj->setMaxCount(15);
+
+ // make sure the current item is saved first so it will be the
+ // default when started next time
+ QStringList sl;
+ QString cur = obj->currentText();
+ sl.append(cur);
+ for (int i = 0; i < obj->count(); i++) {
+ if( cur != obj->text(i) ) {
+ sl.append(obj->text(i));
+ }
+ }
+
+ KConfig *conf = KGlobal::config();
+ conf->setGroup(group);
+ conf->writePathEntry(entry, sl);
+}
+
+QSize KfindTabWidget::sizeHint() const
+{
+ // #44662: avoid a huge default size when the comboboxes have very large items
+ // Like in minicli, we changed the combobox size policy so that they can resize down,
+ // and then we simply provide a reasonable size hint for the whole window, depending
+ // on the screen width.
+ QSize sz = QTabWidget::sizeHint();
+ KfindTabWidget* me = const_cast<KfindTabWidget*>( this );
+ const int screenWidth = qApp->desktop()->screenGeometry(me).width();
+ if ( sz.width() > screenWidth / 2 )
+ sz.setWidth( screenWidth / 2 );
+ return sz;
+}
+
+#include "kftabdlg.moc"
diff --git a/kfind/kftabdlg.h b/kfind/kftabdlg.h
new file mode 100644
index 000000000..3ead70c99
--- /dev/null
+++ b/kfind/kftabdlg.h
@@ -0,0 +1,136 @@
+/***********************************************************************
+ *
+ * kftabdlg.h
+ *
+ ***********************************************************************/
+
+#ifndef KFTABDLG_H
+#define KFTABDLG_H
+
+#include <qtabwidget.h>
+#include <qvalidator.h> // for KDigitValidator
+
+#include <kurl.h>
+#include <kmimetype.h>
+
+#include "kdatecombo.h"
+
+class QButtonGroup;
+class QPushButton;
+class QRadioButton;
+class QCheckBox;
+class QLineEdit;
+class QString;
+class QDate;
+class QRegExp;
+class QDialog;
+class QComboBox;
+class QSpinBox;
+
+class KfDirDialog;
+
+class KfindTabWidget: public QTabWidget
+{
+ Q_OBJECT
+
+public:
+ KfindTabWidget(QWidget * parent = 0, const char *name=0);
+ virtual ~KfindTabWidget();
+ void initMimeTypes();
+ void initSpecialMimeTypes();
+ void setQuery(class KQuery * query);
+ void setDefaults();
+
+ void beginSearch();
+ void endSearch();
+ void loadHistory();
+ void saveHistory();
+ bool isSearchRecursive();
+
+ void setURL( const KURL & url );
+
+ virtual QSize sizeHint() const;
+
+public slots:
+ void setFocus();
+
+private slots:
+ void getDirectory();
+ void fixLayout();
+ void slotSizeBoxChanged(int);
+ void slotEditRegExp();
+
+signals:
+ void startSearch();
+
+protected:
+public:
+ QComboBox *nameBox;
+ QComboBox *dirBox;
+ // for first page
+ QCheckBox *subdirsCb;
+ QCheckBox *useLocateCb;
+ // for third page
+ QComboBox *typeBox;
+ QLineEdit * textEdit;
+ QCheckBox *caseSensCb;
+ QComboBox *m_usernameBox;
+ QComboBox *m_groupBox;
+ //for fourth page
+ QLineEdit *metainfoEdit;
+ QLineEdit *metainfokeyEdit;
+
+private:
+ bool isDateValid();
+
+ QString date2String(const QDate &);
+ QDate &string2Date(const QString &, QDate * );
+
+ QWidget *pages[3];
+
+ //1st page
+ QPushButton *browseB;
+
+ KfDirDialog *dirselector;
+
+ //2nd page
+ QCheckBox *findCreated;
+ QComboBox *betweenType;
+ QButtonGroup *bg;
+ QRadioButton *rb[2];
+ KDateCombo * fromDate;
+ KDateCombo * toDate;
+ QSpinBox *timeBox;
+
+ //3rd page
+ QComboBox *sizeBox;
+ QComboBox *sizeUnitBox;
+ QSpinBox *sizeEdit;
+ QCheckBox *caseContextCb;
+ QCheckBox *binaryContextCb;
+ QCheckBox *regexpContentCb;
+ QDialog *regExpDialog;
+
+ KURL m_url;
+
+ KMimeType::List m_types;
+ QStringList m_ImageTypes;
+ QStringList m_VideoTypes;
+ QStringList m_AudioTypes;
+};
+
+class KDigitValidator : public QValidator
+{
+ Q_OBJECT
+
+public:
+ KDigitValidator(QWidget * parent, const char *name = 0 );
+ ~KDigitValidator();
+
+ QValidator::State validate(QString & input, int &) const;
+
+ private:
+ QRegExp *r;
+};
+
+#endif
diff --git a/kfind/kfwin.cpp b/kfind/kfwin.cpp
new file mode 100644
index 000000000..9eca22f19
--- /dev/null
+++ b/kfind/kfwin.cpp
@@ -0,0 +1,434 @@
+/***********************************************************************
+ *
+ * Kfwin.cpp
+ *
+ **********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <qtextstream.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qclipboard.h>
+#include <qpixmap.h>
+#include <qdragobject.h>
+
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <krun.h>
+#include <kprocess.h>
+#include <kpropertiesdialog.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <kmimetype.h>
+#include <kglobal.h>
+#include <kpopupmenu.h>
+#include <kio/netaccess.h>
+#include <kurldrag.h>
+#include <qptrlist.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+
+#include "kfwin.h"
+
+#include "kfwin.moc"
+
+template class QPtrList<KfFileLVI>;
+
+// Permission strings
+static const char* perm[4] = {
+ I18N_NOOP( "Read-write" ),
+ I18N_NOOP( "Read-only" ),
+ I18N_NOOP( "Write-only" ),
+ I18N_NOOP( "Inaccessible" ) };
+#define RW 0
+#define RO 1
+#define WO 2
+#define NA 3
+
+KfFileLVI::KfFileLVI(KfindWindow* lv, const KFileItem &item, const QString& matchingLine)
+ : QListViewItem(lv),
+ fileitem(item)
+{
+ fileInfo = new QFileInfo(item.url().path());
+
+ QString size = KGlobal::locale()->formatNumber(item.size(), 0);
+
+ QDateTime dt;
+ dt.setTime_t(item.time(KIO::UDS_MODIFICATION_TIME));
+ QString date = KGlobal::locale()->formatDateTime(dt);
+
+ int perm_index;
+ if(fileInfo->isReadable())
+ perm_index = fileInfo->isWritable() ? RW : RO;
+ else
+ perm_index = fileInfo->isWritable() ? WO : NA;
+
+ // Fill the item with data
+ setText(0, item.url().fileName(false));
+ setText(1, lv->reducedDir(item.url().directory(false)));
+ setText(2, size);
+ setText(3, date);
+ setText(4, i18n(perm[perm_index]));
+ setText(5, matchingLine);
+
+ // put the icon into the leftmost column
+ setPixmap(0, item.pixmap(16));
+}
+
+KfFileLVI::~KfFileLVI()
+{
+ delete fileInfo;
+}
+
+QString KfFileLVI::key(int column, bool) const
+{
+ switch (column) {
+ case 2:
+ // Returns size in bytes. Used for sorting
+ return QString().sprintf("%010d", fileInfo->size());
+ case 3:
+ // Returns time in secs from 1/1/1970. Used for sorting
+ return QString().sprintf("%010ld", fileitem.time(KIO::UDS_MODIFICATION_TIME));
+ }
+
+ return text(column);
+}
+
+KfindWindow::KfindWindow( QWidget *parent, const char *name )
+ : KListView( parent, name )
+,m_baseDir("")
+,m_menu(0)
+{
+ setSelectionMode( QListView::Extended );
+ setShowSortIndicator( TRUE );
+
+ addColumn(i18n("Name"));
+ addColumn(i18n("In Subfolder"));
+ addColumn(i18n("Size"));
+ setColumnAlignment(2, AlignRight);
+ addColumn(i18n("Modified"));
+ setColumnAlignment(3, AlignRight);
+ addColumn(i18n("Permissions"));
+ setColumnAlignment(4, AlignRight);
+
+ addColumn(i18n("First Matching Line"));
+ setColumnAlignment(5, AlignLeft);
+
+ // Disable autoresize for all columns
+ // Resizing is done by resetColumns() function
+ for (int i = 0; i < 6; i++)
+ setColumnWidthMode(i, Manual);
+
+ resetColumns(true);
+
+ connect( this, SIGNAL(selectionChanged()),
+ this, SLOT( selectionHasChanged() ));
+
+ connect(this, SIGNAL(contextMenu(KListView *, QListViewItem*,const QPoint&)),
+ this, SLOT(slotContextMenu(KListView *,QListViewItem*,const QPoint&)));
+
+ connect(this, SIGNAL(executed(QListViewItem*)),
+ this, SLOT(slotExecute(QListViewItem*)));
+ setDragEnabled(true);
+
+}
+
+
+QString KfindWindow::reducedDir(const QString& fullDir)
+{
+ if (fullDir.find(m_baseDir)==0)
+ {
+ QString tmp=fullDir.mid(m_baseDir.length());
+ return tmp;
+ };
+ return fullDir;
+}
+
+void KfindWindow::beginSearch(const KURL& baseUrl)
+{
+ kdDebug()<<QString("beginSearch in: %1").arg(baseUrl.path())<<endl;
+ m_baseDir=baseUrl.path(+1);
+ haveSelection = false;
+ clear();
+}
+
+void KfindWindow::endSearch()
+{
+}
+
+void KfindWindow::insertItem(const KFileItem &item, const QString& matchingLine)
+{
+ new KfFileLVI(this, item, matchingLine);
+}
+
+// copy to clipboard aka X11 selection
+void KfindWindow::copySelection()
+{
+ QDragObject *drag_obj = dragObject();
+
+ if (drag_obj)
+ {
+ QClipboard *cb = kapp->clipboard();
+ cb->setData(drag_obj);
+ }
+}
+
+void KfindWindow::saveResults()
+{
+ QListViewItem *item;
+
+ KFileDialog *dlg = new KFileDialog(QString::null, QString::null, this,
+ "filedialog", true);
+ dlg->setOperationMode (KFileDialog::Saving);
+
+ dlg->setCaption(i18n("Save Results As"));
+
+ QStringList list;
+
+ list << "text/plain" << "text/html";
+
+ dlg->setOperationMode(KFileDialog::Saving);
+
+ dlg->setMimeFilter(list, QString("text/plain"));
+
+ dlg->exec();
+
+ KURL u = dlg->selectedURL();
+ KMimeType::Ptr mimeType = dlg->currentFilterMimeType();
+ delete dlg;
+
+ if (!u.isValid() || !u.isLocalFile())
+ return;
+
+ QString filename = u.path();
+
+ QFile file(filename);
+
+ if ( !file.open(IO_WriteOnly) )
+ KMessageBox::error(parentWidget(),
+ i18n("Unable to save results."));
+ else {
+ QTextStream stream( &file );
+ stream.setEncoding( QTextStream::Locale );
+
+ if ( mimeType->name() == "text/html") {
+ stream << QString::fromLatin1("<HTML><HEAD>\n"
+ "<!DOCTYPE %1>\n"
+ "<TITLE>%2</TITLE></HEAD>\n"
+ "<BODY><H1>%3</H1>"
+ "<DL><p>\n")
+ .arg(i18n("KFind Results File"))
+ .arg(i18n("KFind Results File"))
+ .arg(i18n("KFind Results File"));
+
+ item = firstChild();
+ while(item != NULL)
+ {
+ QString path=((KfFileLVI*)item)->fileitem.url().url();
+ QString pretty=((KfFileLVI*)item)->fileitem.url().htmlURL();
+ stream << QString::fromLatin1("<DT><A HREF=\"") << path
+ << QString::fromLatin1("\">") << pretty
+ << QString::fromLatin1("</A>\n");
+
+ item = item->nextSibling();
+ }
+ stream << QString::fromLatin1("</DL><P></BODY></HTML>\n");
+ }
+ else {
+ item = firstChild();
+ while(item != NULL)
+ {
+ QString path=((KfFileLVI*)item)->fileitem.url().url();
+ stream << path << endl;
+ item = item->nextSibling();
+ }
+ }
+
+ file.close();
+ KMessageBox::information(parentWidget(),
+ i18n("Results were saved to file\n")+
+ filename);
+ }
+}
+
+// This function is called when selection is changed (both selected/deselected)
+// It notifies the parent about selection status and enables/disables menubar
+void KfindWindow::selectionHasChanged()
+{
+ emit resultSelected(true);
+
+ QListViewItem *item = firstChild();
+ while(item != 0L)
+ {
+ if(isSelected(item)) {
+ emit resultSelected( true );
+ haveSelection = true;
+ return;
+ }
+
+ item = item->nextSibling();
+ }
+
+ haveSelection = false;
+ emit resultSelected(false);
+}
+
+void KfindWindow::deleteFiles()
+{
+ QString tmp = i18n("Do you really want to delete the selected file?",
+ "Do you really want to delete the %n selected files?",selectedItems().count());
+ if (KMessageBox::warningContinueCancel(parentWidget(), tmp, "", KGuiItem( i18n("&Delete"), "editdelete")) == KMessageBox::Cancel)
+ return;
+
+ // Iterate on all selected elements
+ QPtrList<QListViewItem> selected = selectedItems();
+ for ( uint i = 0; i < selected.count(); i++ ) {
+ KfFileLVI *item = (KfFileLVI *) selected.at(i);
+ KFileItem file = item->fileitem;
+
+ KIO::NetAccess::del(file.url(), this);
+ }
+ selected.setAutoDelete(true);
+}
+
+void KfindWindow::fileProperties()
+{
+ // This dialog must be modal because it parent dialog is modal as well.
+ // Non-modal property dialog will hide behind the main window
+ (void) new KPropertiesDialog( &((KfFileLVI *)currentItem())->fileitem, this,
+ "propDialog", true);
+}
+
+void KfindWindow::openFolder()
+{
+ KFileItem fileitem = ((KfFileLVI *)currentItem())->fileitem;
+ KURL url = fileitem.url();
+ url.setFileName(QString::null);
+
+ (void) new KRun(url);
+}
+
+void KfindWindow::openBinding()
+{
+ ((KfFileLVI*)currentItem())->fileitem.run();
+}
+
+void KfindWindow::slotExecute(QListViewItem* item)
+{
+ if (item==0)
+ return;
+ ((KfFileLVI*)item)->fileitem.run();
+}
+
+// Resizes KListView to occupy all visible space
+void KfindWindow::resizeEvent(QResizeEvent *e)
+{
+ KListView::resizeEvent(e);
+ resetColumns(false);
+ clipper()->repaint();
+}
+
+QDragObject * KfindWindow::dragObject()
+{
+ KURL::List uris;
+ QPtrList<QListViewItem> selected = selectedItems();
+
+ // create a list of URIs from selection
+ for ( uint i = 0; i < selected.count(); i++ )
+ {
+ KfFileLVI *item = (KfFileLVI *) selected.at( i );
+ if (item)
+ {
+ uris.append( item->fileitem.url() );
+ }
+ }
+
+ if ( uris.count() <= 0 )
+ return 0;
+
+ QUriDrag *ud = new KURLDrag( uris, (QWidget *) this, "kfind uridrag" );
+
+ const QPixmap *pix = currentItem()->pixmap(0);
+ if ( pix && !pix->isNull() )
+ ud->setPixmap( *pix );
+
+ return ud;
+}
+
+void KfindWindow::resetColumns(bool init)
+{
+ QFontMetrics fm = fontMetrics();
+ if (init)
+ {
+ setColumnWidth(2, QMAX(fm.width(columnText(2)), fm.width("0000000")) + 15);
+ QString sampleDate =
+ KGlobal::locale()->formatDateTime(QDateTime::currentDateTime());
+ setColumnWidth(3, QMAX(fm.width(columnText(3)), fm.width(sampleDate)) + 15);
+ setColumnWidth(4, QMAX(fm.width(columnText(4)), fm.width(i18n(perm[RO]))) + 15);
+ setColumnWidth(5, QMAX(fm.width(columnText(5)), fm.width("some text")) + 15);
+ }
+
+ int free_space = visibleWidth() -
+ columnWidth(2) - columnWidth(3) - columnWidth(4) - columnWidth(5);
+
+// int name_w = QMIN((int)(free_space*0.5), 150);
+// int dir_w = free_space - name_w;
+ int name_w = QMAX((int)(free_space*0.5), fm.width("some long filename"));
+ int dir_w = name_w;
+
+ setColumnWidth(0, name_w);
+ setColumnWidth(1, dir_w);
+}
+
+void KfindWindow::slotContextMenu(KListView *,QListViewItem *item,const QPoint&p)
+{
+ if (!item) return;
+ int count = selectedItems().count();
+
+ if (count == 0)
+ {
+ return;
+ };
+
+ if (m_menu==0)
+ m_menu = new KPopupMenu(this);
+ else
+ m_menu->clear();
+
+ if (count == 1)
+ {
+ //menu = new KPopupMenu(item->text(0), this);
+ m_menu->insertTitle(item->text(0));
+ m_menu->insertItem(SmallIcon("fileopen"),i18n("Menu item", "Open"), this, SLOT(openBinding()));
+ m_menu->insertItem(SmallIcon("window_new"),i18n("Open Folder"), this, SLOT(openFolder()));
+ m_menu->insertSeparator();
+ m_menu->insertItem(SmallIcon("editcopy"),i18n("Copy"), this, SLOT(copySelection()));
+ m_menu->insertItem(SmallIcon("editdelete"),i18n("Delete"), this, SLOT(deleteFiles()));
+ m_menu->insertSeparator();
+ m_menu->insertItem(i18n("Open With..."), this, SLOT(slotOpenWith()));
+ m_menu->insertSeparator();
+ m_menu->insertItem(i18n("Properties"), this, SLOT(fileProperties()));
+ }
+ else
+ {
+ m_menu->insertTitle(i18n("Selected Files"));
+ m_menu->insertItem(SmallIcon("editcopy"),i18n("Copy"), this, SLOT(copySelection()));
+ m_menu->insertItem(SmallIcon("editdelete"),i18n("Delete"), this, SLOT(deleteFiles()));
+ }
+ m_menu->popup(p, 1);
+}
+
+void KfindWindow::slotOpenWith()
+{
+ KRun::displayOpenWithDialog( KURL::split(((KfFileLVI*)currentItem())->fileitem.url()) );
+}
diff --git a/kfind/kfwin.h b/kfind/kfwin.h
new file mode 100644
index 000000000..0d55c8f6a
--- /dev/null
+++ b/kfind/kfwin.h
@@ -0,0 +1,75 @@
+/***********************************************************************
+ *
+ * Kfwin.h
+ *
+ ***********************************************************************/
+
+#ifndef KFWIN_H
+#define KFWIN_H
+
+#include <klistview.h>
+#include <kfileitem.h>
+#include <kurl.h>
+
+class KfArchiver;
+class QPixmap;
+class QFileInfo;
+class KPopupMenu;
+class KfindWindow;
+
+class KfFileLVI : public QListViewItem
+{
+ public:
+ KfFileLVI(KfindWindow* lv, const KFileItem &item,const QString& matchingLine);
+ ~KfFileLVI();
+
+ QString key(int column, bool) const;
+
+ QFileInfo *fileInfo;
+ KFileItem fileitem;
+};
+
+class KfindWindow: public KListView
+{
+ Q_OBJECT
+public:
+ KfindWindow( QWidget * parent = 0, const char * name = 0 );
+
+ void beginSearch(const KURL& baseUrl);
+ void endSearch();
+
+ void insertItem(const KFileItem &item, const QString& matchingLine);
+
+ QString reducedDir(const QString& fullDir);
+
+public slots:
+ void copySelection();
+ void slotContextMenu(KListView *,QListViewItem *item,const QPoint&p);
+
+private slots:
+ void deleteFiles();
+ void fileProperties();
+ void openFolder();
+ void saveResults();
+ void openBinding();
+ void selectionHasChanged();
+ void slotExecute(QListViewItem*);
+ void slotOpenWith();
+
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+
+ virtual QDragObject *dragObject();
+
+signals:
+ void resultSelected(bool);
+
+private:
+ QString m_baseDir;
+ KPopupMenu *m_menu;
+ bool haveSelection;
+ bool m_pressed;
+ void resetColumns(bool init);
+};
+
+#endif
diff --git a/kfind/kquery.cpp b/kfind/kquery.cpp
new file mode 100644
index 000000000..5d5446fc6
--- /dev/null
+++ b/kfind/kquery.cpp
@@ -0,0 +1,527 @@
+#include <stdlib.h>
+
+#include <qfileinfo.h>
+#include <kdebug.h>
+#include <kfileitem.h>
+#include <kfilemetainfo.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kzip.h>
+
+#include "kquery.h"
+
+KQuery::KQuery(QObject *parent, const char * name)
+ : QObject(parent, name),
+ m_sizemode(0), m_sizeboundary1(0), m_sizeboundary2(0),
+ m_timeFrom(0), m_timeTo(0),
+ job(0), m_insideCheckEntries(false), m_result(0)
+{
+ m_regexps.setAutoDelete(true);
+ m_fileItems.setAutoDelete(true);
+ processLocate = new KProcess(this);
+ connect(processLocate,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(slotreceivedSdtout(KProcess*,char*,int)));
+ connect(processLocate,SIGNAL(receivedStderr(KProcess*, char*, int)),this,SLOT(slotreceivedSdterr(KProcess*,char*,int)));
+ connect(processLocate,SIGNAL(processExited(KProcess*)),this,SLOT(slotendProcessLocate(KProcess*)));
+
+ // Files with these mime types can be ignored, even if
+ // findFormatByFileContent() in some cases may claim that
+ // these are text files:
+ ignore_mimetypes.append("application/pdf");
+ ignore_mimetypes.append("application/postscript");
+
+ // PLEASE update the documentation when you add another
+ // file type here:
+ ooo_mimetypes.append("application/vnd.sun.xml.writer");
+ ooo_mimetypes.append("application/vnd.sun.xml.calc");
+ ooo_mimetypes.append("application/vnd.sun.xml.impress");
+ // OASIS mimetypes, used by OOo-2.x and KOffice >= 1.4
+ //ooo_mimetypes.append("application/vnd.oasis.opendocument.chart");
+ //ooo_mimetypes.append("application/vnd.oasis.opendocument.graphics");
+ //ooo_mimetypes.append("application/vnd.oasis.opendocument.graphics-template");
+ //ooo_mimetypes.append("application/vnd.oasis.opendocument.formula");
+ //ooo_mimetypes.append("application/vnd.oasis.opendocument.image");
+ ooo_mimetypes.append("application/vnd.oasis.opendocument.presentation-template");
+ ooo_mimetypes.append("application/vnd.oasis.opendocument.presentation");
+ ooo_mimetypes.append("application/vnd.oasis.opendocument.spreadsheet-template");
+ ooo_mimetypes.append("application/vnd.oasis.opendocument.spreadsheet");
+ ooo_mimetypes.append("application/vnd.oasis.opendocument.text-template");
+ ooo_mimetypes.append("application/vnd.oasis.opendocument.text");
+ // KOffice-1.3 mimetypes
+ koffice_mimetypes.append("application/x-kword");
+ koffice_mimetypes.append("application/x-kspread");
+ koffice_mimetypes.append("application/x-kpresenter");
+}
+
+KQuery::~KQuery()
+{
+}
+
+void KQuery::kill()
+{
+ if (job)
+ job->kill(false);
+ if (processLocate->isRunning())
+ processLocate->kill();
+ m_fileItems.clear();
+}
+
+void KQuery::start()
+{
+ m_fileItems.clear();
+ if(m_useLocate) //use "locate" instead of the internal search method
+ {
+ m_url.cleanPath();
+ processLocate->clearArguments();
+ *processLocate << "locate";
+ *processLocate << m_url.path(1).latin1();
+ bufferLocate=NULL;
+ bufferLocateLength=0;
+ processLocate->start(KProcess::NotifyOnExit,KProcess::AllOutput);
+ return;
+ }
+
+ if (m_recursive)
+ job = KIO::listRecursive( m_url, false );
+ else
+ job = KIO::listDir( m_url, false );
+
+ connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList &)),
+ SLOT(slotListEntries(KIO::Job *, const KIO::UDSEntryList &)));
+ connect(job, SIGNAL(result(KIO::Job *)), SLOT(slotResult(KIO::Job *)));
+ connect(job, SIGNAL(canceled(KIO::Job *)), SLOT(slotCanceled(KIO::Job *)));
+}
+
+void KQuery::slotResult( KIO::Job * _job )
+{
+ if (job != _job) return;
+ job = 0;
+
+ m_result=_job->error();
+ checkEntries();
+}
+
+void KQuery::slotCanceled( KIO::Job * _job )
+{
+ if (job != _job) return;
+ job = 0;
+
+ m_fileItems.clear();
+ m_result=KIO::ERR_USER_CANCELED;
+ checkEntries();
+}
+
+void KQuery::slotListEntries(KIO::Job*, const KIO::UDSEntryList& list)
+{
+ KFileItem * file = 0;
+ KIO::UDSEntryListConstIterator end = list.end();
+ for (KIO::UDSEntryListConstIterator it = list.begin(); it != end; ++it)
+ {
+ file = new KFileItem(*it, m_url, true, true);
+ m_fileItems.enqueue(file);
+ }
+ checkEntries();
+}
+
+void KQuery::checkEntries()
+{
+ if (m_insideCheckEntries)
+ return;
+ m_insideCheckEntries=true;
+ metaKeyRx=new QRegExp(m_metainfokey,true,true);
+ KFileItem * file = 0;
+ while ((file=m_fileItems.dequeue()))
+ {
+ processQuery(file);
+ delete file;
+ }
+ delete metaKeyRx;
+ m_insideCheckEntries=false;
+ if (job==0)
+ emit result(m_result);
+}
+
+/* List of files found using slocate */
+void KQuery::slotListEntries( QStringList list )
+{
+ KFileItem * file = 0;
+ metaKeyRx=new QRegExp(m_metainfokey,true,true);
+
+ QStringList::Iterator it = list.begin();
+ QStringList::Iterator end = list.end();
+
+ for (; it != end; ++it)
+ {
+ file = new KFileItem( KFileItem::Unknown, KFileItem::Unknown, KURL::fromPathOrURL(*it));
+ processQuery(file);
+ delete file;
+ }
+
+ delete metaKeyRx;
+}
+
+/* Check if file meets the find's requirements*/
+void KQuery::processQuery( KFileItem* file)
+{
+ QRegExp *filename_match;
+
+ if ( file->name() == "." || file->name() == ".." )
+ return;
+
+ bool matched=false;
+
+ for ( filename_match = m_regexps.first(); !matched && filename_match; filename_match = m_regexps.next() )
+ {
+ matched |= filename_match->isEmpty() ||
+ (filename_match->exactMatch( file->url().fileName( true ) ) );
+ }
+ if (!matched)
+ return;
+
+ switch( m_sizemode )
+ {
+ case 1: // "at least"
+ if ( file->size() < m_sizeboundary1 ) return;
+ break;
+ case 2: // "at most"
+ if ( file->size() > m_sizeboundary1 ) return;
+ break;
+ case 3: // "equal"
+ if ( file->size() != m_sizeboundary1 ) return;
+ break;
+ case 4: // "between"
+ if ( (file->size() < m_sizeboundary1) || (file->size() > m_sizeboundary2) ) return;
+ break;
+ case 0: // "none" -> fall to default
+ default:
+ break;
+ }
+
+ // make sure it's in the correct date range
+ // what about 0 times?
+ if ( m_timeFrom && m_timeFrom > file->time(KIO::UDS_MODIFICATION_TIME) )
+ return;
+ if ( m_timeTo && m_timeTo < file->time(KIO::UDS_MODIFICATION_TIME) )
+ return;
+
+ // username / group match
+ if ( (!m_username.isEmpty()) && (m_username != file->user()) )
+ return;
+ if ( (!m_groupname.isEmpty()) && (m_groupname != file->group()) )
+ return;
+
+ // file type
+ switch (m_filetype)
+ {
+ case 0:
+ break;
+ case 1: // plain file
+ if ( !S_ISREG( file->mode() ) )
+ return;
+ break;
+ case 2:
+ if ( !file->isDir() )
+ return;
+ break;
+ case 3:
+ if ( !file->isLink() )
+ return;
+ break;
+ case 4:
+ if ( !S_ISCHR ( file->mode() ) && !S_ISBLK ( file->mode() ) &&
+ !S_ISFIFO( file->mode() ) && !S_ISSOCK( file->mode() ) )
+ return;
+ break;
+ case 5: // binary
+ if ( (file->permissions() & 0111) != 0111 || file->isDir() )
+ return;
+ break;
+ case 6: // suid
+ if ( (file->permissions() & 04000) != 04000 ) // fixme
+ return;
+ break;
+ default:
+ if (!m_mimetype.isEmpty() && !m_mimetype.contains(file->mimetype()))
+ return;
+ }
+
+ // match datas in metainfo...
+ if ((!m_metainfo.isEmpty()) && (!m_metainfokey.isEmpty()))
+ {
+ bool foundmeta=false;
+ QString filename = file->url().path();
+
+ if(filename.startsWith("/dev/"))
+ return;
+
+ KFileMetaInfo metadatas(filename);
+ KFileMetaInfoItem metaitem;
+ QStringList metakeys;
+ QString strmetakeycontent;
+
+ if(metadatas.isEmpty())
+ return;
+
+ metakeys=metadatas.supportedKeys();
+ for ( QStringList::Iterator it = metakeys.begin(); it != metakeys.end(); ++it )
+ {
+ if (!metaKeyRx->exactMatch(*it))
+ continue;
+ metaitem=metadatas.item(*it);
+ strmetakeycontent=metaitem.string();
+ if(strmetakeycontent.find(m_metainfo)!=-1)
+ {
+ foundmeta=true;
+ break;
+ }
+ }
+ if (!foundmeta)
+ return;
+ }
+
+ // match contents...
+ QString matchingLine;
+ if (!m_context.isEmpty())
+ {
+
+ if( !m_search_binary && ignore_mimetypes.findIndex(file->mimetype()) != -1 ) {
+ kdDebug() << "ignoring, mime type is in exclusion list: " << file->url() << endl;
+ return;
+ }
+
+ bool found = false;
+ bool isZippedOfficeDocument=false;
+ int matchingLineNumber=0;
+
+ // FIXME: doesn't work with non local files
+
+ QString filename;
+ QTextStream* stream=0;
+ QFile qf;
+ QRegExp xmlTags;
+ QByteArray zippedXmlFileContent;
+
+ // KWord's and OpenOffice.org's files are zipped...
+ if( ooo_mimetypes.findIndex(file->mimetype()) != -1 ||
+ koffice_mimetypes.findIndex(file->mimetype()) != -1 )
+ {
+ KZip zipfile(file->url().path());
+ KZipFileEntry *zipfileEntry;
+
+ if(zipfile.open(IO_ReadOnly))
+ {
+ const KArchiveDirectory *zipfileContent = zipfile.directory();
+
+ if( koffice_mimetypes.findIndex(file->mimetype()) != -1 )
+ zipfileEntry = (KZipFileEntry*)zipfileContent->entry("maindoc.xml");
+ else
+ zipfileEntry = (KZipFileEntry*)zipfileContent->entry("content.xml"); //for OpenOffice.org
+
+ if(!zipfileEntry) {
+ kdWarning() << "Expected XML file not found in ZIP archive " << file->url() << endl;
+ return;
+ }
+
+ zippedXmlFileContent = zipfileEntry->data();
+ xmlTags.setPattern("<.*>");
+ xmlTags.setMinimal(true);
+ stream = new QTextStream(zippedXmlFileContent, IO_ReadOnly);
+ stream->setEncoding(QTextStream::UnicodeUTF8);
+ isZippedOfficeDocument = true;
+ } else {
+ kdWarning() << "Cannot open supposed ZIP file " << file->url() << endl;
+ }
+ } else if( !m_search_binary && !file->mimetype().startsWith("text/") &&
+ file->url().isLocalFile() ) {
+ KMimeType::Format f = KMimeType::findFormatByFileContent(file->url().path());
+ if ( !f.text ) {
+ kdDebug() << "ignoring, not a text file: " << file->url() << endl;
+ return;
+ }
+ }
+
+ if(!isZippedOfficeDocument) //any other file or non-compressed KWord
+ {
+ filename = file->url().path();
+ if(filename.startsWith("/dev/"))
+ return;
+ qf.setName(filename);
+ qf.open(IO_ReadOnly);
+ stream=new QTextStream(&qf);
+ stream->setEncoding(QTextStream::Locale);
+ }
+
+ while ( ! stream->atEnd() )
+ {
+ QString str = stream->readLine();
+ matchingLineNumber++;
+
+ if (str.isNull()) break;
+ if(isZippedOfficeDocument)
+ str.replace(xmlTags, "");
+
+ if (m_regexpForContent)
+ {
+ if (m_regexp.search(str)>=0)
+ {
+ matchingLine=QString::number(matchingLineNumber)+": "+str;
+ found = true;
+ break;
+ }
+ }
+ else
+ {
+ if (str.find(m_context, 0, m_casesensitive) != -1)
+ {
+ matchingLine=QString::number(matchingLineNumber)+": "+str;
+ found = true;
+ break;
+ }
+ }
+ kapp->processEvents();
+ }
+ delete stream;
+
+ if (!found)
+ return;
+ }
+ emit addFile(file,matchingLine);
+}
+
+void KQuery::setContext(const QString & context, bool casesensitive,
+ bool search_binary, bool useRegexp)
+{
+ m_context = context;
+ m_casesensitive = casesensitive;
+ m_search_binary = search_binary;
+ m_regexpForContent=useRegexp;
+ m_regexp.setWildcard(!m_regexpForContent);
+ m_regexp.setCaseSensitive(casesensitive);
+ if (m_regexpForContent)
+ m_regexp.setPattern(m_context);
+}
+
+void KQuery::setMetaInfo(const QString &metainfo, const QString &metainfokey)
+{
+ m_metainfo=metainfo;
+ m_metainfokey=metainfokey;
+}
+
+void KQuery::setMimeType(const QStringList &mimetype)
+{
+ m_mimetype = mimetype;
+}
+
+void KQuery::setFileType(int filetype)
+{
+ m_filetype = filetype;
+}
+
+void KQuery::setSizeRange(int mode, KIO::filesize_t value1, KIO::filesize_t value2)
+{
+ m_sizemode = mode;
+ m_sizeboundary1 = value1;
+ m_sizeboundary2 = value2;
+}
+
+void KQuery::setTimeRange(time_t from, time_t to)
+{
+ m_timeFrom = from;
+ m_timeTo = to;
+}
+
+void KQuery::setUsername(QString username)
+{
+ m_username = username;
+}
+
+void KQuery::setGroupname(QString groupname)
+{
+ m_groupname = groupname;
+}
+
+
+void KQuery::setRegExp(const QString &regexp, bool caseSensitive)
+{
+ QRegExp *regExp;
+ QRegExp sep(";");
+ QStringList strList=QStringList::split( sep, regexp, false);
+// QRegExp globChars ("[\\*\\?\\[\\]]", TRUE, FALSE);
+
+ m_regexps.clear();
+// m_regexpsContainsGlobs.clear();
+ for ( QStringList::ConstIterator it = strList.begin(); it != strList.end(); ++it ) {
+ regExp = new QRegExp((*it),caseSensitive,true);
+// m_regexpsContainsGlobs.append(regExp->pattern().contains(globChars));
+ m_regexps.append(regExp);
+ }
+}
+
+void KQuery::setRecursive(bool recursive)
+{
+ m_recursive = recursive;
+}
+
+void KQuery::setPath(const KURL &url)
+{
+ m_url = url;
+}
+
+void KQuery::setUseFileIndex(bool useLocate)
+{
+ m_useLocate=useLocate;
+}
+
+void KQuery::slotreceivedSdterr(KProcess* ,char* str,int)
+{
+ KMessageBox::error(NULL, QString(str), i18n("Error while using locate"));
+}
+
+void KQuery::slotreceivedSdtout(KProcess*,char* str,int l)
+{
+ int i;
+
+ bufferLocateLength+=l;
+ str[l]='\0';
+ bufferLocate=(char*)realloc(bufferLocate,sizeof(char)*(bufferLocateLength));
+ for (i=0;i<l;i++)
+ bufferLocate[bufferLocateLength-l+i]=str[i];
+}
+
+void KQuery::slotendProcessLocate(KProcess*)
+{
+ QString qstr;
+ QStringList strlist;
+ int i,j,k;
+
+ if((bufferLocateLength==0)||(bufferLocate==NULL))
+ {
+ emit result(0);
+ return;
+ }
+
+ i=0;
+ do
+ {
+ j=1;
+ while(bufferLocate[i]!='\n')
+ {
+ i++;
+ j++;
+ }
+ qstr="";
+ for(k=0;k<j-1;k++)
+ qstr.append(bufferLocate[k+i-j+1]);
+ strlist.append(qstr);
+ i++;
+
+ }while(i<bufferLocateLength);
+ bufferLocateLength=0;
+ free(bufferLocate);
+ bufferLocate=NULL;
+ slotListEntries(strlist );
+ emit result(0);
+}
+
+#include "kquery.moc"
diff --git a/kfind/kquery.h b/kfind/kquery.h
new file mode 100644
index 000000000..c7e81fcfe
--- /dev/null
+++ b/kfind/kquery.h
@@ -0,0 +1,102 @@
+#ifndef KQUERY_H
+#define KQUERY_H
+
+#include <time.h>
+
+#include <qobject.h>
+#include <qregexp.h>
+#include <qptrqueue.h>
+#include <qdir.h>
+#include <qstringlist.h>
+
+#include <kio/job.h>
+#include <kurl.h>
+#include <kprocess.h>
+
+class KFileItem;
+
+class KQuery : public QObject
+{
+ Q_OBJECT
+
+ public:
+ KQuery(QObject *parent = 0, const char * name = 0);
+ ~KQuery();
+
+ void setSizeRange( int mode, KIO::filesize_t value1, KIO::filesize_t value2 );
+ void setTimeRange( time_t from, time_t to );
+ void setRegExp( const QString &regexp, bool caseSensitive );
+ void setRecursive( bool recursive );
+ void setPath(const KURL & url );
+ void setFileType( int filetype );
+ void setMimeType( const QStringList & mimetype );
+ void setContext( const QString & context, bool casesensitive,
+ bool search_binary, bool useRegexp );
+ void setUsername( QString username );
+ void setGroupname( QString groupname );
+ void setMetaInfo(const QString &metainfo, const QString &metainfokey);
+ void setUseFileIndex(bool);
+
+ void start();
+ void kill();
+ const KURL& url() {return m_url;};
+
+ private:
+ /* Check if file meets the find's requirements*/
+ inline void processQuery(KFileItem*);
+
+ public slots:
+ /* List of files found using slocate */
+ void slotListEntries(QStringList);
+ protected slots:
+ /* List of files found using KIO */
+ void slotListEntries(KIO::Job *, const KIO::UDSEntryList &);
+ void slotResult(KIO::Job *);
+ void slotCanceled(KIO::Job *);
+ void slotreceivedSdtout(KProcess*,char*,int);
+ void slotreceivedSdterr(KProcess*,char*,int);
+ void slotendProcessLocate(KProcess*);
+
+ signals:
+ void addFile(const KFileItem *filename, const QString& matchingLine);
+ void result(int);
+
+ private:
+ void checkEntries();
+
+ int m_filetype;
+ int m_sizemode;
+ KIO::filesize_t m_sizeboundary1;
+ KIO::filesize_t m_sizeboundary2;
+ KURL m_url;
+ time_t m_timeFrom;
+ time_t m_timeTo;
+ QRegExp m_regexp;// regexp for file content
+ bool m_recursive;
+ QStringList m_mimetype;
+ QString m_context;
+ QString m_username;
+ QString m_groupname;
+ QString m_metainfo;
+ QString m_metainfokey;
+ bool m_casesensitive;
+ bool m_search_binary;
+ bool m_regexpForContent;
+ bool m_useLocate;
+ char* bufferLocate;
+ int bufferLocateLength;
+ QStringList locateList;
+ KProcess *processLocate;
+ QPtrList<QRegExp> m_regexps;// regexps for file name
+// QValueList<bool> m_regexpsContainsGlobs; // what should this be good for ? Alex
+ KIO::ListJob *job;
+ bool m_insideCheckEntries;
+ QPtrQueue<KFileItem> m_fileItems;
+ QRegExp* metaKeyRx;
+ int m_result;
+ QStringList ignore_mimetypes;
+ QStringList ooo_mimetypes; // OpenOffice.org mimetypes
+ QStringList koffice_mimetypes;
+};
+
+#endif
diff --git a/kfind/main.cpp b/kfind/main.cpp
new file mode 100644
index 000000000..a92f0ddcd
--- /dev/null
+++ b/kfind/main.cpp
@@ -0,0 +1,65 @@
+#include <qdir.h>
+#include <qfile.h>
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kopenwith.h>
+
+#include "kfinddlg.h"
+#include "version.h"
+
+static const char description[] =
+ I18N_NOOP("KDE file find utility");
+
+static KCmdLineOptions options[] =
+{
+ { "+[searchpath]", I18N_NOOP("Path(s) to search"), 0 },
+ KCmdLineLastOption
+};
+
+int main( int argc, char ** argv )
+{
+ KLocale::setMainCatalogue("kfindpart");
+ KAboutData aboutData( "kfind", I18N_NOOP("KFind"),
+ KFIND_VERSION, description, KAboutData::License_GPL,
+ I18N_NOOP("(c) 1998-2003, The KDE Developers"));
+
+ aboutData.addAuthor("Eric Coquelle", I18N_NOOP("Current Maintainer"), "coquelle@caramail.com");
+ aboutData.addAuthor("Mark W. Webb", I18N_NOOP("Developer"), "markwebb@adelphia.net");
+ aboutData.addAuthor("Beppe Grimaldi", I18N_NOOP("UI Design & more search options"), "grimalkin@ciaoweb.it");
+ aboutData.addAuthor("Martin Hartig");
+ aboutData.addAuthor("Stephan Kulow", 0, "coolo@kde.org");
+ aboutData.addAuthor("Mario Weilguni",0, "mweilguni@sime.com");
+ aboutData.addAuthor("Alex Zepeda",0, "zipzippy@sonic.net");
+ aboutData.addAuthor("Miroslav Fl�r",0, "flidr@kky.zcu.cz");
+ aboutData.addAuthor("Harri Porten",0, "porten@kde.org");
+ aboutData.addAuthor("Dima Rogozin",0, "dima@mercury.co.il");
+ aboutData.addAuthor("Carsten Pfeiffer",0, "pfeiffer@kde.org");
+ aboutData.addAuthor("Hans Petter Bieker", 0, "bieker@kde.org");
+ aboutData.addAuthor("Waldo Bastian", I18N_NOOP("UI Design"), "bastian@kde.org");
+ aboutData.addAuthor("Alexander Neundorf", 0, "neundorf@kde.org");
+ aboutData.addAuthor("Clarence Dang", 0, "dang@kde.org");
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication app;
+
+ KCmdLineArgs *args= KCmdLineArgs::parsedArgs();
+
+ KURL url;
+ if (args->count() > 0)
+ url = args->url(0);
+ if (url.isEmpty())
+ url = QDir::currentDirPath();
+ if (url.isEmpty())
+ url = QDir::homeDirPath();
+ args->clear();
+
+ KfindDlg kfinddlg(url, 0, "dialog");
+ return kfinddlg.exec();
+}
+
+
diff --git a/kfind/pics/Makefile.am b/kfind/pics/Makefile.am
new file mode 100644
index 000000000..0d31d2cf2
--- /dev/null
+++ b/kfind/pics/Makefile.am
@@ -0,0 +1,2 @@
+kfind_pics_datadir = $(kde_datadir)/kfindpart/icons
+kfind_pics_data_ICON = AUTO
diff --git a/kfind/pics/lo22-action-archive.png b/kfind/pics/lo22-action-archive.png
new file mode 100644
index 000000000..54e73c2f9
--- /dev/null
+++ b/kfind/pics/lo22-action-archive.png
Binary files differ
diff --git a/kfind/pics/lo22-action-delete.png b/kfind/pics/lo22-action-delete.png
new file mode 100644
index 000000000..1018d6e22
--- /dev/null
+++ b/kfind/pics/lo22-action-delete.png
Binary files differ
diff --git a/kfind/pics/lo22-action-idea.png b/kfind/pics/lo22-action-idea.png
new file mode 100644
index 000000000..e348d48b6
--- /dev/null
+++ b/kfind/pics/lo22-action-idea.png
Binary files differ
diff --git a/kfind/pics/lo22-action-info.png b/kfind/pics/lo22-action-info.png
new file mode 100644
index 000000000..41aec81ef
--- /dev/null
+++ b/kfind/pics/lo22-action-info.png
Binary files differ
diff --git a/kfind/pics/lo22-action-openfile.png b/kfind/pics/lo22-action-openfile.png
new file mode 100644
index 000000000..bdf6c55d9
--- /dev/null
+++ b/kfind/pics/lo22-action-openfile.png
Binary files differ
diff --git a/kfind/pics/lo22-action-save.png b/kfind/pics/lo22-action-save.png
new file mode 100644
index 000000000..4ae7ad4cd
--- /dev/null
+++ b/kfind/pics/lo22-action-save.png
Binary files differ
diff --git a/kfind/pics/lo22-action-search.png b/kfind/pics/lo22-action-search.png
new file mode 100644
index 000000000..2ed5031c4
--- /dev/null
+++ b/kfind/pics/lo22-action-search.png
Binary files differ
diff --git a/kfind/version.h b/kfind/version.h
new file mode 100644
index 000000000..24f2c33c1
--- /dev/null
+++ b/kfind/version.h
@@ -0,0 +1,3 @@
+#ifndef KFIND_VERSION
+#define KFIND_VERSION "2.0"
+#endif