summaryrefslogtreecommitdiffstats
path: root/krusader/Locate/locate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'krusader/Locate/locate.cpp')
-rwxr-xr-xkrusader/Locate/locate.cpp613
1 files changed, 613 insertions, 0 deletions
diff --git a/krusader/Locate/locate.cpp b/krusader/Locate/locate.cpp
new file mode 100755
index 0000000..c875de3
--- /dev/null
+++ b/krusader/Locate/locate.cpp
@@ -0,0 +1,613 @@
+/***************************************************************************
+ locate.cpp - description
+ -------------------
+ copyright : (C) 2004 by Csaba Karai
+ e-mail : krusader@users.sourceforge.net
+ web site : http://krusader.sourceforge.net
+ ---------------------------------------------------------------------------
+ Description
+ ***************************************************************************
+
+ A
+
+ db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b.
+ 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D
+ 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY'
+ 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b
+ 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88.
+ YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD
+
+ S o u r c e F i l e
+
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "locate.h"
+#include "../krusader.h"
+#include "../krusaderview.h"
+#include "../Panel/listpanel.h"
+#include "../Panel/panelfunc.h"
+#include "../defaults.h"
+#include "../krservices.h"
+#include "../VFS/vfs.h"
+#include "../VFS/virt_vfs.h"
+#include "../KViewer/krviewer.h"
+#include "../panelmanager.h"
+#include <klocale.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfontmetrics.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <qcursor.h>
+#include <qeventloop.h>
+#include <kfinddialog.h>
+#include <kinputdialog.h>
+#include <qregexp.h>
+#include <qdir.h>
+#include <qclipboard.h>
+#include <kurldrag.h>
+#include <../kicons.h>
+
+// these are the values that will exist in the menu
+#define VIEW_ID 90
+#define EDIT_ID 91
+#define FIND_ID 92
+#define FIND_NEXT_ID 93
+#define FIND_PREV_ID 94
+#define COPY_SELECTED_TO_CLIPBOARD 95
+//////////////////////////////////////////////////////////
+
+class LocateListView : public KListView
+{
+public:
+ LocateListView( QWidget * parent, const char * name = 0 ) : KListView( parent, name )
+ {
+ }
+
+ void startDrag()
+ {
+ KURL::List urls;
+
+ QListViewItem * item = firstChild();
+ while( item )
+ {
+ if( item->isSelected() )
+ urls.push_back( vfs::fromPathOrURL( item->text( 0 ) ) );
+
+ item = item->nextSibling();
+ }
+
+ if( urls.count() == 0 )
+ return;
+
+ KURLDrag *d = new KURLDrag(urls, this);
+ d->setPixmap( FL_LOADICON( "file" ), QPoint( -7, 0 ) );
+ d->dragCopy();
+ }
+};
+
+KProcess * LocateDlg::updateProcess = 0;
+LocateDlg * LocateDlg::LocateDialog = 0;
+
+LocateDlg::LocateDlg() : KDialogBase(0,0,false,"Locate", KDialogBase::User1 | KDialogBase::User2 | KDialogBase::User3 | KDialogBase::Close,
+ KDialogBase::User3, false, i18n("Stop"), i18n("Update DB"), i18n("Locate") ), isFeedToListBox( false )
+{
+ QWidget *widget=new QWidget(this, "locateMainWidget");
+ QGridLayout *grid = new QGridLayout( widget );
+ grid->setSpacing( 6 );
+ grid->setMargin( 11 );
+
+ setPlainCaption( i18n( "Krusader::Locate" ) );
+
+ QHBox *hbox = new QHBox( widget, "locateHBox" );
+ QLabel *label = new QLabel( i18n( "Search for:" ), hbox, "locateLabel" );
+ locateSearchFor = new KHistoryCombo( false, hbox, "locateSearchFor" );
+ label->setBuddy( locateSearchFor );
+ krConfig->setGroup("Locate");
+ QStringList list = krConfig->readListEntry("Search For");
+ locateSearchFor->setMaxCount(25); // remember 25 items
+ locateSearchFor->setHistoryItems(list);
+ locateSearchFor->setEditable( true );
+ locateSearchFor->setDuplicatesEnabled( false );
+ locateSearchFor->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
+ locateSearchFor->lineEdit()->setFocus();
+
+ grid->addWidget( hbox, 0, 0 );
+
+ QHBox *hbox2 = new QHBox( widget, "locateHBox" );
+ QSpacerItem* spacer = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ hbox2->layout()->addItem( spacer );
+ dontSearchInPath = new QCheckBox( i18n( "Don't search in path" ), hbox2, "dontSearchInPath" );
+ dontSearchInPath->setChecked( krConfig->readBoolEntry("Dont Search In Path") );
+ existingFiles = new QCheckBox( i18n( "Show only the existing files" ), hbox2, "existingFiles" );
+ existingFiles->setChecked( krConfig->readBoolEntry("Existing Files") );
+ caseSensitive = new QCheckBox( i18n( "Case Sensitive" ), hbox2, "caseSensitive" );
+ caseSensitive->setChecked( krConfig->readBoolEntry("Case Sensitive") );
+ grid->addWidget( hbox2, 1, 0 );
+
+ QFrame *line1 = new QFrame( widget, "locateLine1" );
+ line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ grid->addWidget( line1, 2, 0 );
+
+ resultList=new LocateListView( widget ); // create the main container
+
+ krConfig->setGroup("Look&Feel");
+ resultList->setFont(krConfig->readFontEntry("Filelist Font",_FilelistFont));
+
+ resultList->setAllColumnsShowFocus(true);
+ resultList->setVScrollBarMode(QScrollView::Auto);
+ resultList->setHScrollBarMode(QScrollView::Auto);
+ resultList->setShowSortIndicator(false);
+ resultList->setSorting(-1);
+ resultList->setSelectionMode( QListView::Extended );
+
+ resultList->addColumn( i18n("Results"), QFontMetrics(resultList->font()).width("W") * 60 );
+ resultList->setColumnWidthMode(0,QListView::Maximum);
+
+ connect( resultList,SIGNAL(rightButtonPressed(QListViewItem *, const QPoint &, int)),
+ this, SLOT(slotRightClick(QListViewItem *)));
+ connect( resultList,SIGNAL(doubleClicked(QListViewItem *)),
+ this, SLOT(slotDoubleClick(QListViewItem *)));
+ connect( resultList,SIGNAL(returnPressed(QListViewItem *)),
+ this, SLOT(slotDoubleClick(QListViewItem *)));
+
+ grid->addWidget( resultList, 3, 0 );
+
+ QFrame *line2 = new QFrame( widget, "locateLine2" );
+ line2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ grid->addWidget( line2, 4, 0 );
+
+ enableButton( KDialogBase::User1, false ); /* disable the stop button */
+
+ if( updateProcess )
+ {
+ if( updateProcess->isRunning() )
+ {
+ connect( updateProcess, SIGNAL(processExited(KProcess *)), this, SLOT(updateFinished()));
+ enableButton( KDialogBase::User2, false );
+ }
+ else
+ updateFinished();
+ }
+
+ setMainWidget(widget);
+ show();
+
+ LocateDialog = this;
+}
+
+void LocateDlg::slotUser1() /* The stop / feed to listbox button */
+{
+ if( isFeedToListBox )
+ feedToListBox();
+ else
+ stopping = true;
+}
+
+void LocateDlg::slotUser2() /* The Update DB button */
+{
+ if( !updateProcess )
+ {
+ krConfig->setGroup("Locate");
+
+ updateProcess = new KProcess();
+ *updateProcess << KrServices::fullPathName( "updatedb" );
+ *updateProcess << KrServices::separateArgs( krConfig->readEntry( "UpdateDB Arguments", "" ) );
+
+ connect( updateProcess, SIGNAL(processExited(KProcess *)), this, SLOT(updateFinished()));
+ updateProcess->start(KProcess::NotifyOnExit);
+ enableButton( KDialogBase::User2, false );
+ }
+}
+
+void LocateDlg::updateFinished()
+{
+ delete updateProcess;
+ updateProcess = 0;
+ enableButton( KDialogBase::User2, true );
+}
+
+void LocateDlg::slotUser3() /* The locate button */
+{
+ locateSearchFor->addToHistory(locateSearchFor->currentText());
+ QStringList list = locateSearchFor->historyItems();
+ krConfig->setGroup("Locate");
+ krConfig->writeEntry("Search For", list);
+ krConfig->writeEntry("Dont Search In Path", dontSearchPath = dontSearchInPath->isChecked() );
+ krConfig->writeEntry("Existing Files", onlyExist = existingFiles->isChecked() );
+ krConfig->writeEntry("Case Sensitive", isCs = caseSensitive->isChecked() );
+
+ if( !KrServices::cmdExist( "locate" ) )
+ {
+ KMessageBox::error(0,
+ i18n("Can't start 'locate'! Check the 'Dependencies' page in konfigurator."));
+ return;
+ }
+
+ resultList->clear();
+ lastItem = 0;
+ remaining = "";
+
+ enableButton( KDialogBase::User3, false ); /* disable the locate button */
+ enableButton( KDialogBase::User1, true ); /* enable the stop button */
+ setButtonText( KDialogBase::User1, i18n( "Stop" ) ); /* the button behaves as stop */
+ isFeedToListBox = false;
+ resultList->setFocus();
+
+ qApp->processEvents();
+
+ stopping = false;
+
+ KProcess locateProc;
+ connect( &locateProc, SIGNAL( receivedStdout(KProcess *, char *, int) ),
+ this, SLOT( processStdout(KProcess *, char *, int) ) );
+ connect( &locateProc, SIGNAL( receivedStderr(KProcess *, char *, int) ),
+ this, SLOT( processStderr(KProcess *, char *, int) ) );
+
+ locateProc << KrServices::fullPathName( "locate" );
+ if( !isCs )
+ locateProc << "-i";
+ locateProc << (pattern = locateSearchFor->currentText());
+
+ if( !pattern.startsWith( "*" ) )
+ pattern = "*" + pattern;
+ if( !pattern.endsWith( "*" ) )
+ pattern = pattern + "*";
+
+ collectedErr = "";
+ bool result = !locateProc.start( KProcess::Block, KProcess::AllOutput );
+ if( !collectedErr.isEmpty() && ( !locateProc.normalExit() || locateProc.exitStatus() ) )
+ {
+ KMessageBox::error( krApp, i18n( "Locate produced the following error message:\n\n" ) + collectedErr );
+ }else if ( result )
+ {
+ KMessageBox::error( krApp, i18n( "Error during the start of 'locate' process!" ) );
+ }
+ enableButton( KDialogBase::User3, true ); /* enable the locate button */
+
+ if( resultList->childCount() == 0 )
+ {
+ locateSearchFor->setFocus();
+ enableButton( KDialogBase::User1, false ); /* disable the stop button */
+ isFeedToListBox = false;
+ }else{
+ setButtonText( KDialogBase::User1, i18n("Feed to listbox") ); /* feed to listbox */
+ isFeedToListBox = true;
+ }
+}
+
+void LocateDlg::processStdout(KProcess *proc, char *buffer, int length)
+{
+ char *buf = new char[ length+1 ];
+ memcpy( buf, buffer, length );
+ buf[ length ] = 0;
+
+ remaining += QString::fromLocal8Bit( buf );
+ delete []buf;
+
+ QStringList list = QStringList::split("\n", remaining );
+ int items = list.size();
+
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if( --items == 0 && buffer[length-1] != '\n' )
+ remaining = *it;
+ else
+ {
+ if( dontSearchPath )
+ {
+ QRegExp regExp( pattern, isCs, true );
+ QString fileName = (*it).stripWhiteSpace();
+ if( fileName.endsWith( "/" ) && fileName != "/" )
+ fileName.truncate( fileName.length() -1 );
+ fileName = fileName.mid( fileName.findRev( '/' ) + 1 );
+
+ if( !regExp.exactMatch( fileName ) )
+ continue;
+ }
+ if( onlyExist )
+ {
+ KFileItem file(KFileItem::Unknown, KFileItem::Unknown, (*it).stripWhiteSpace() );
+ if( !file.isReadable() )
+ continue;
+ }
+
+ if( lastItem )
+ lastItem = new KListViewItem( resultList, lastItem, *it );
+ else
+ lastItem = new KListViewItem( resultList, *it );
+
+ lastItem->setDragEnabled( true );
+ }
+ }
+
+ if( stopping )
+ proc->kill( SIGKILL );
+
+ qApp->processEvents();
+}
+
+void LocateDlg::processStderr(KProcess *, char *buffer, int length)
+{
+ char *buf = new char[ length+1 ];
+ memcpy( buf, buffer, length );
+ buf[ length ] = 0;
+
+ collectedErr += QString::fromLocal8Bit( buf );
+ delete []buf;
+}
+
+void LocateDlg::slotRightClick(QListViewItem *item)
+{
+ if ( !item )
+ return;
+
+ // create the menu
+ KPopupMenu popup;
+ popup.insertTitle(i18n("Locate"));
+
+ popup.insertItem(i18n("View (F3)"), VIEW_ID);
+ popup.insertItem(i18n("Edit (F4)"), EDIT_ID);
+
+ popup.insertSeparator();
+
+ popup.insertItem(i18n("Find (Ctrl+F)"), FIND_ID);
+ popup.insertItem(i18n("Find next (Ctrl+N)"), FIND_NEXT_ID);
+ popup.insertItem(i18n("Find previous (Ctrl+P)"), FIND_PREV_ID);
+
+ popup.insertSeparator();
+
+ popup.insertItem(i18n("Copy selected to clipboard"), COPY_SELECTED_TO_CLIPBOARD);
+
+
+ int result=popup.exec(QCursor::pos());
+
+ // check out the user's option
+ switch (result)
+ {
+ case VIEW_ID:
+ case EDIT_ID:
+ case FIND_ID:
+ case FIND_NEXT_ID:
+ case FIND_PREV_ID:
+ case COPY_SELECTED_TO_CLIPBOARD:
+ operate( item, result );
+ break;
+ }
+}
+
+void LocateDlg::slotDoubleClick(QListViewItem *item)
+{
+ if ( !item )
+ return;
+
+ QString dirName = item->text(0);
+ QString fileName;
+
+ if( !QDir( dirName ).exists() )
+ {
+ fileName = dirName.mid( dirName.findRev( '/' ) + 1 );
+ dirName.truncate( dirName.findRev( '/' ) );
+ }
+
+ ACTIVE_FUNC->openUrl(vfs::fromPathOrURL( dirName ), fileName );
+ KDialogBase::accept();
+}
+
+void LocateDlg::keyPressEvent( QKeyEvent *e )
+{
+ if( Krusader::actCopy->shortcut().contains( KKey( e ) ) )
+ {
+ operate( 0, COPY_SELECTED_TO_CLIPBOARD );
+ e->accept();
+ return;
+ }
+
+ switch ( e->key() )
+ {
+ case Key_M :
+ if( e->state() == ControlButton )
+ {
+ resultList->setFocus();
+ e->accept();
+ }
+ break;
+ case Key_F3 :
+ if( resultList->currentItem() )
+ operate( resultList->currentItem(), VIEW_ID );
+ break;
+ case Key_F4 :
+ if( resultList->currentItem() )
+ operate( resultList->currentItem(), EDIT_ID );
+ break;
+ case Key_N :
+ if ( e->state() == ControlButton )
+ operate( resultList->currentItem(), FIND_NEXT_ID );
+ break;
+ case Key_P :
+ if ( e->state() == ControlButton )
+ operate( resultList->currentItem(), FIND_PREV_ID );
+ break;
+ case Key_F :
+ if ( e->state() == ControlButton )
+ operate( resultList->currentItem(), FIND_ID );
+ break;
+ }
+
+ QDialog::keyPressEvent( e );
+}
+
+void LocateDlg::operate( QListViewItem *item, int task )
+{
+ KURL name;
+ if( item != 0 )
+ name = vfs::fromPathOrURL( item->text( 0 ) );
+
+ switch ( task )
+ {
+ case VIEW_ID:
+ KrViewer::view( name, this ); // view the file
+ break;
+ case EDIT_ID:
+ KrViewer::edit( name, this ); // view the file
+ break;
+ case FIND_ID:
+ {
+ krConfig->setGroup("Locate");
+ long options = krConfig->readNumEntry("Find Options", 0);
+ QStringList list = krConfig->readListEntry("Find Patterns");
+
+ KFindDialog dlg( this, "locateFindDialog", options, list );
+ if ( dlg.exec() != QDialog::Accepted )
+ return;
+
+ if( list.first() != ( findPattern = dlg.pattern() ) )
+ list.push_front( dlg.pattern() );
+
+ krConfig->writeEntry( "Find Options", findOptions = dlg.options() );
+ krConfig->writeEntry( "Find Patterns", list );
+
+ if( !( findOptions & KFindDialog::FromCursor ) )
+ resultList->setCurrentItem( ( findOptions & KFindDialog::FindBackwards ) ?
+ resultList->lastItem() : resultList->firstChild() );
+
+ findCurrentItem = (KListViewItem *)resultList->currentItem();
+
+ if( find() && findCurrentItem )
+ resultList->setCurrentItem( findCurrentItem );
+ else
+ KMessageBox::information( 0, i18n( "Search string not found!" ) );
+
+ resultList->ensureItemVisible( resultList->currentItem() );
+ }
+ break;
+ case FIND_NEXT_ID:
+ case FIND_PREV_ID:
+ {
+ if( task == FIND_PREV_ID )
+ findOptions ^= KFindDialog::FindBackwards;
+
+ findCurrentItem = (KListViewItem *)resultList->currentItem();
+ nextLine();
+
+ if( find() && findCurrentItem )
+ resultList->setCurrentItem( findCurrentItem );
+ else
+ KMessageBox::information( 0, i18n( "Search string not found!" ) );
+
+ resultList->ensureItemVisible( resultList->currentItem() );
+
+ if( task == FIND_PREV_ID )
+ findOptions ^= KFindDialog::FindBackwards;
+ }
+ break;
+ case COPY_SELECTED_TO_CLIPBOARD:
+ {
+ KURL::List urls;
+
+ QListViewItem * item = resultList->firstChild();
+ while( item )
+ {
+ if( item->isSelected() )
+ urls.push_back( vfs::fromPathOrURL( item->text( 0 ) ) );
+
+ item = item->nextSibling();
+ }
+
+ if( urls.count() == 0 )
+ return;
+
+ KURLDrag *d = new KURLDrag(urls, this);
+ d->setPixmap( FL_LOADICON( "file" ), QPoint( -7, 0 ) );
+ QApplication::clipboard()->setData( d );
+ }
+ break;
+ }
+}
+
+void LocateDlg::nextLine()
+{
+ if( findOptions & KFindDialog::FindBackwards )
+ findCurrentItem = (KListViewItem *)findCurrentItem->itemAbove();
+ else
+ findCurrentItem = (KListViewItem *)findCurrentItem->itemBelow();
+}
+
+bool LocateDlg::find()
+{
+ while( findCurrentItem )
+ {
+ QString item = findCurrentItem->text( 0 );
+
+ if( findOptions & KFindDialog::RegularExpression )
+ {
+ if( item.contains( QRegExp( findPattern, findOptions & KFindDialog::CaseSensitive ) ) )
+ return true;
+ }
+ else
+ {
+ if( item.contains( findPattern, findOptions & KFindDialog::CaseSensitive ) )
+ return true;
+ }
+
+ nextLine();
+ }
+
+ return false;
+}
+
+void LocateDlg::feedToListBox()
+{
+ virt_vfs v(0,true);
+ v.vfs_refresh( KURL( "/" ) );
+
+ krConfig->setGroup( "Locate" );
+ int listBoxNum = krConfig->readNumEntry( "Feed To Listbox Counter", 1 );
+ QString queryName;
+ do {
+ queryName = i18n("Locate results")+QString( " %1" ).arg( listBoxNum++ );
+ }while( v.vfs_search( queryName ) != 0 );
+ krConfig->writeEntry( "Feed To Listbox Counter", listBoxNum );
+
+ krConfig->setGroup( "Advanced" );
+ if ( krConfig->readBoolEntry( "Confirm Feed to Listbox", _ConfirmFeedToListbox ) ) {
+ bool ok;
+ queryName = KInputDialog::getText(
+ i18n("Query name"), // Caption
+ i18n("Here you can name the file collection"), // Questiontext
+ queryName, // Default
+ &ok );
+ if ( ! ok)
+ return;
+ }
+
+ KURL::List urlList;
+ QListViewItem * item = resultList->firstChild();
+ while( item )
+ {
+ urlList.push_back( vfs::fromPathOrURL( item->text( 0 ) ) );
+ item = item->nextSibling();
+ }
+ KURL url = KURL::fromPathOrURL(QString("virt:/")+ queryName);
+ v.vfs_refresh( url );
+ v.vfs_addFiles( &urlList, KIO::CopyJob::Copy, 0 );
+ //ACTIVE_FUNC->openUrl(url);
+ ACTIVE_MNG->slotNewTab(url.prettyURL());
+ accept();
+}
+
+void LocateDlg::reset()
+{
+ locateSearchFor->lineEdit()->setFocus();
+ locateSearchFor->lineEdit()->selectAll();
+}
+
+#include "locate.moc"