Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / kfind / kfinddlg.cpp
blob6af328f00e46ec7348da449f540ec01566b9c599
1 /***********************************************************************
3 * Kfinddlg.cpp
5 **********************************************************************/
6 #include "kfinddlg.h"
7 #include "kfinddlg.moc"
9 #include <QtGui/QLayout>
10 #include <QtGui/QPushButton>
12 #include <klocale.h>
13 #include <kglobal.h>
14 #include <kguiitem.h>
15 #include <kstatusbar.h>
16 #include <kmessagebox.h>
17 #include <kdebug.h>
18 #include <kaboutapplicationdialog.h>
19 #include <kstandarddirs.h>
21 #include "kftabdlg.h"
22 #include "kquery.h"
23 #include "kfwin.h"
25 KfindDlg::KfindDlg(const KUrl & url, QWidget *parent)
26 : KDialog( parent )
28 setButtons( User1 | User2 | User3 | Close | Help );
29 setHelp( QString(), "kfind" );
30 setDefaultButton( User3 );
31 setModal( true );
33 setButtonGuiItem( User3, KStandardGuiItem::find());
34 setButtonGuiItem( User2, KStandardGuiItem::stop() );
35 setButtonGuiItem( User1, KStandardGuiItem::saveAs() );
37 QWidget::setWindowTitle( i18n("Find Files/Folders" ) );
38 setButtonsOrientation(Qt::Vertical);
40 enableButton(User3, true); // Enable "Find"
41 enableButton(User2, false); // Disable "Stop"
42 enableButton(User1, false); // Disable "Save As..."
44 isResultReported = false;
46 QFrame *frame = new QFrame;
47 setMainWidget( frame );
49 // create tabwidget
50 tabWidget = new KfindTabWidget( frame );
51 tabWidget->setURL( url );
53 // prepare window for find results
54 win = new KfindWindow(frame );
56 mStatusBar = new KStatusBar(frame);
57 mStatusBar->insertFixedItem("AMiddleLengthText...", 0);
58 setStatusMsg(i18n("Ready."));
59 mStatusBar->setItemAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
60 mStatusBar->insertPermanentItem(QString(), 1, 1);
61 mStatusBar->setItemAlignment(1, Qt::AlignLeft | Qt::AlignVCenter);
63 QVBoxLayout *vBox = new QVBoxLayout(frame);
64 vBox->addWidget(tabWidget, 0);
65 vBox->addWidget(win, 1);
66 vBox->addWidget(mStatusBar, 0);
68 connect(this, SIGNAL(user3Clicked()),
69 this, SLOT(startSearch()));
70 connect(this, SIGNAL(user2Clicked()),
71 this, SLOT(stopSearch()));
72 connect(this, SIGNAL(user1Clicked()),
73 win, SLOT(saveResults()));
75 connect(win ,SIGNAL(resultSelected(bool)),
76 this,SIGNAL(resultSelected(bool)));
78 query = new KQuery(frame);
79 connect(query, SIGNAL(addFile(const KFileItem&,const QString&)),
80 SLOT(addFile(const KFileItem&,const QString&)));
81 connect(query, SIGNAL(result(int)), SLOT(slotResult(int)));
83 dirwatch=NULL;
86 KfindDlg::~KfindDlg()
88 stopSearch();
91 void KfindDlg::closeEvent(QCloseEvent *)
93 slotButtonClicked(KDialog::Close);
96 void KfindDlg::setProgressMsg(const QString &msg)
98 mStatusBar->changeItem(msg, 1);
101 void KfindDlg::setStatusMsg(const QString &msg)
103 mStatusBar->changeItem(msg, 0);
107 void KfindDlg::startSearch()
109 tabWidget->setQuery(query);
111 isResultReported = false;
113 // Reset count - use the same i18n as below
114 setProgressMsg(i18np("one file found", "%1 files found", 0));
116 emit resultSelected(false);
117 emit haveResults(false);
119 enableButton(User3, false); // Disable "Find"
120 enableButton(User2, true); // Enable "Stop"
121 enableButton(User1, false); // Disable "Save As..."
123 if(dirwatch!=NULL)
124 delete dirwatch;
125 dirwatch=new KDirWatch();
126 connect(dirwatch, SIGNAL(created(const QString&)), this, SLOT(slotNewItems(const QString&)));
127 connect(dirwatch, SIGNAL(deleted(const QString&)), this, SLOT(slotDeleteItem(const QString&)));
128 dirwatch->addDir(query->url().path(), KDirWatch::WatchFiles);
130 #if 0
131 // waba: Watching for updates is disabled for now because even with FAM it causes too
132 // much problems. See BR68220, BR77854, BR77846, BR79512 and BR85802
133 // There are 3 problems:
134 // 1) addDir() keeps looping on recursive symlinks
135 // 2) addDir() scans all subdirectories, so it basically does the same as the process that
136 // is started by KQuery but in-process, undoing the advantages of using a separate find process
137 // A solution could be to let KQuery emit all the directories it has searched in.
138 // Either way, putting dirwatchers on a whole file system is probably just too much.
139 // 3) FAM has a tendency to deadlock with so many files (See BR77854) This has hopefully
140 // been fixed in KDirWatch, but that has not yet been confirmed.
142 //Getting a list of all subdirs
143 if(tabWidget->isSearchRecursive() && (dirwatch->internalMethod() == KDirWatch::FAM))
145 const QStringList subdirs=getAllSubdirs(query->url().path());
146 for(QStringList::const_iterator it = subdirs.constBegin(); it != subdirs.constEnd(); ++it)
147 dirwatch->addDir(*it,true);
149 #endif
151 win->beginSearch(query->url());
152 tabWidget->beginSearch();
154 setStatusMsg(i18n("Searching..."));
155 query->start();
158 void KfindDlg::stopSearch()
160 query->kill();
163 void KfindDlg::newSearch()
165 // WABA: Not used any longer?
166 stopSearch();
168 tabWidget->setDefaults();
170 emit haveResults(false);
171 emit resultSelected(false);
173 setFocus();
176 void KfindDlg::slotResult(int errorCode)
178 if (errorCode == 0)
179 setStatusMsg(i18n("Ready."));
180 else if (errorCode == KIO::ERR_USER_CANCELED)
181 setStatusMsg(i18n("Aborted."));
182 else if (errorCode == KIO::ERR_MALFORMED_URL)
184 setStatusMsg(i18n("Error."));
185 KMessageBox::sorry( this, i18n("Please specify an absolute path in the \"Look in\" box."));
187 else if (errorCode == KIO::ERR_DOES_NOT_EXIST)
189 setStatusMsg(i18n("Error."));
190 KMessageBox::sorry( this, i18n("Could not find the specified folder."));
192 else
194 kDebug()<<"KIO error code: "<<errorCode;
195 setStatusMsg(i18n("Error."));
198 enableButton(User3, true); // Enable "Find"
199 enableButton(User2, false); // Disable "Stop"
200 enableButton(User1, true); // Enable "Save As..."
202 win->endSearch();
203 tabWidget->endSearch();
204 setFocus();
208 void KfindDlg::addFile(const KFileItem &item, const QString& matchingLine)
210 win->insertItem(item,matchingLine);
212 if (!isResultReported)
214 emit haveResults(true);
215 isResultReported = true;
218 int count = win->childCount();
219 QString str = i18np("one file found", "%1 files found", count);
220 setProgressMsg(str);
223 void KfindDlg::setFocus()
225 tabWidget->setFocus();
228 void KfindDlg::copySelection()
230 win->copySelection();
233 void KfindDlg::about ()
235 KAboutApplicationDialog dlg(0, this);
236 dlg.exec ();
239 void KfindDlg::slotDeleteItem(const QString& file)
241 kDebug()<<QString("Will remove one item: %1").arg(file);
242 Q3ListViewItem *iter;
243 QString iterwithpath;
245 iter=win->firstChild();
246 while( iter ) {
247 iterwithpath=query->url().path(KUrl::AddTrailingSlash)+iter->text(1)+iter->text(0);
249 if(iterwithpath==file)
251 win->takeItem(iter);
252 break;
254 iter = iter->nextSibling();
258 void KfindDlg::slotNewItems( const QString& file )
260 kDebug()<<QString("Will add this item");
261 QStringList newfiles;
262 Q3ListViewItem *checkiter;
263 QString checkiterwithpath;
265 if(file.indexOf(query->url().path(KUrl::AddTrailingSlash))==0)
267 kDebug()<<QString("Can be added, path OK");
268 checkiter=win->firstChild();
269 while( checkiter ) {
270 checkiterwithpath=query->url().path(KUrl::AddTrailingSlash)+checkiter->text(1)+checkiter->text(0);
271 if(file==checkiterwithpath)
272 return;
273 checkiter = checkiter->nextSibling();
275 query->slotListEntries(QStringList(file));
279 QStringList KfindDlg::getAllSubdirs(QDir d)
281 QStringList dirs;
282 QStringList subdirs;
284 d.setFilter( QDir::Dirs );
285 dirs = d.entryList();
287 for(QStringList::const_iterator it = dirs.constBegin(); it != dirs.constEnd(); ++it)
289 if((*it==".")||(*it==".."))
290 continue;
291 subdirs.append(d.path()+'/'+*it);
292 subdirs+=getAllSubdirs(d.path()+'/'+*it);
294 return subdirs;