dolphin/kfind/kfinddlg.cpp
Anselmo Melo 58988f4cef Set focus on "named" field when kfind starts instead of the "Find" button.
By setting the initial focus on "named" field, the user does not need to select
it before introducing the search string and, as pointed by the bug reporter,
the default action is "Find", so an 'Enter pressed' triggers the search independently
of the focused widget.

BUG:239026


svn path=/trunk/KDE/kdebase/apps/; revision=1131315
2010-05-28 02:31:58 +00:00

300 lines
8 KiB
C++

/*******************************************************************
* kfinddlg.cpp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************/
#include "kfinddlg.h"
#include "kfinddlg.moc"
#include <QtGui/QLayout>
#include <QtGui/QPushButton>
#include <klocale.h>
#include <kglobal.h>
#include <kguiitem.h>
#include <kstatusbar.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kaboutapplicationdialog.h>
#include <kstandarddirs.h>
#include "kftabdlg.h"
#include "kquery.h"
#include "kfindtreeview.h"
KfindDlg::KfindDlg(const KUrl & url, QWidget *parent)
: KDialog( parent )
{
setButtons( User1 | User2 | User3 | Close | Help );
setHelp( QString(), "kfind" );
setDefaultButton( User3 );
setModal( true );
setButtonGuiItem( User3, KStandardGuiItem::find());
setButtonGuiItem( User2, KStandardGuiItem::stop() );
setButtonGuiItem( User1, KStandardGuiItem::saveAs() );
QWidget::setWindowTitle( i18n("Find Files/Folders" ) );
setButtonsOrientation(Qt::Vertical);
enableButton(User3, true); // Enable "Find"
enableButton(User2, false); // Disable "Stop"
enableButton(User1, false); // Disable "Save As..."
isResultReported = false;
QFrame *frame = new QFrame;
setMainWidget( frame );
// create tabwidget
tabWidget = new KfindTabWidget( frame );
tabWidget->setURL( url );
tabWidget->setFocus();
// prepare window for find results
win = new KFindTreeView(frame, this);
mStatusBar = new KStatusBar(frame);
mStatusBar->insertItem("AMiddleLengthText...", 0);
setStatusMsg( i18nc("the application is currently idle, there is no active search", "Idle.") );
mStatusBar->setItemAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
mStatusBar->insertPermanentItem(QString(), 1, 1);
mStatusBar->setItemAlignment(1, Qt::AlignRight | Qt::AlignVCenter);
QVBoxLayout *vBox = new QVBoxLayout(frame);
vBox->addWidget(tabWidget, 0);
vBox->addWidget(win, 1);
vBox->addWidget(mStatusBar, 0);
connect(this, SIGNAL(user3Clicked()),
this, SLOT(startSearch()));
connect(this, SIGNAL(user2Clicked()),
this, SLOT(stopSearch()));
connect(this, SIGNAL(user1Clicked()),
win, SLOT(saveResults()));
connect( this, SIGNAL(closeClicked()), this, SLOT(finishAndClose()) );
connect(win ,SIGNAL(resultSelected(bool)),
this,SIGNAL(resultSelected(bool)));
query = new KQuery(frame);
connect(query, SIGNAL(result(int)), SLOT(slotResult(int)));
connect(query, SIGNAL(foundFileList(QList< QPair<KFileItem,QString> >)), SLOT(addFiles(QList< QPair<KFileItem,QString> >)));
dirwatch=NULL;
}
KfindDlg::~KfindDlg()
{
stopSearch();
if (dirwatch)
delete dirwatch;
}
void KfindDlg::finishAndClose()
{
//Stop the current search and closes the dialog
stopSearch();
close();
}
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(i18np("one file found", "%1 files found", 0));
emit resultSelected(false);
emit haveResults(false);
enableButton(User3, false); // Disable "Find"
enableButton(User2, true); // Enable "Stop"
enableButton(User1, 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(), KDirWatch::WatchFiles);
#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 separate 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))
{
const QStringList subdirs=getAllSubdirs(query->url().path());
for(QStringList::const_iterator it = subdirs.constBegin(); it != subdirs.constEnd(); ++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( i18nc("the application is currently idle, there is no active search", "Idle.") );
else if (errorCode == KIO::ERR_USER_CANCELED)
setStatusMsg(i18n("Canceled."));
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
{
kDebug()<<"KIO error code: "<<errorCode;
setStatusMsg(i18n("Error."));
};
enableButton(User3, true); // Enable "Find"
enableButton(User2, false); // Disable "Stop"
enableButton(User1, true); // Enable "Save As..."
win->endSearch();
tabWidget->endSearch();
setFocus();
}
void KfindDlg::addFiles( const QList< QPair<KFileItem,QString> > & pairs)
{
win->insertItems( pairs );
if (!isResultReported)
{
emit haveResults(true);
isResultReported = true;
}
QString str = i18np("one file found", "%1 files found", win->itemCount());
setProgressMsg( str );
}
void KfindDlg::setFocus()
{
tabWidget->setFocus();
}
void KfindDlg::copySelection()
{
win->copySelection();
}
void KfindDlg::about ()
{
KAboutApplicationDialog dlg(0, this);
dlg.exec ();
}
void KfindDlg::slotDeleteItem(const QString& file)
{
kDebug()<<QString("Will remove one item: %1").arg(file);
KUrl url;
url.setPath( file );
win->removeItem( url );
QString str = i18np("one file found", "%1 files found", win->itemCount());
setProgressMsg( str );
}
void KfindDlg::slotNewItems( const QString& file )
{
kDebug()<<QString("Will add this item") << file;
if( file.indexOf(query->url().path(KUrl::AddTrailingSlash))==0 )
{
KUrl url;
url.setPath ( file );
if ( !win->isInserted( url ) )
query->slotListEntries( QStringList() << file );
}
}
QStringList KfindDlg::getAllSubdirs(QDir d)
{
QStringList dirs;
QStringList subdirs;
d.setFilter( QDir::Dirs );
dirs = d.entryList();
for(QStringList::const_iterator it = dirs.constBegin(); it != dirs.constEnd(); ++it)
{
if((*it==".")||(*it==".."))
continue;
subdirs.append(d.path()+'/'+*it);
subdirs+=getAllSubdirs(d.path()+'/'+*it);
}
return subdirs;
}