summaryrefslogtreecommitdiffstats
path: root/src/app/Search
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/Search')
-rw-r--r--src/app/Search/Makefile.am9
-rw-r--r--src/app/Search/krsearchdialog.cpp628
-rw-r--r--src/app/Search/krsearchdialog.h184
-rw-r--r--src/app/Search/krsearchmod.cpp253
-rw-r--r--src/app/Search/krsearchmod.h86
5 files changed, 1160 insertions, 0 deletions
diff --git a/src/app/Search/Makefile.am b/src/app/Search/Makefile.am
new file mode 100644
index 0000000..e43b3de
--- /dev/null
+++ b/src/app/Search/Makefile.am
@@ -0,0 +1,9 @@
+noinst_LIBRARIES = libSearch.a
+
+INCLUDES = $(all_includes)
+
+libSearch_a_METASOURCES = AUTO
+
+libSearch_a_SOURCES = \
+ krsearchmod.cpp \
+ krsearchdialog.cpp
diff --git a/src/app/Search/krsearchdialog.cpp b/src/app/Search/krsearchdialog.cpp
new file mode 100644
index 0000000..af87f95
--- /dev/null
+++ b/src/app/Search/krsearchdialog.cpp
@@ -0,0 +1,628 @@
+/***************************************************************************
+ krsearchdialog.cpp
+ -------------------
+ copyright : (C) 2001 by Shie Erlich & Rafi Yanai
+ email : 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 "../krusader.h"
+#include "../defaults.h"
+#include "../panelmanager.h"
+#include "../VFS/vfs.h"
+#include "../krusaderview.h"
+#include "../Panel/listpanel.h"
+#include "../Panel/panelfunc.h"
+#include "../Dialogs/krdialogs.h"
+#include "../VFS/virt_vfs.h"
+#include "../KViewer/krviewer.h"
+#include "krsearchmod.h"
+#include "krsearchdialog.h"
+
+#include <kinputdialog.h>
+#include <tqregexp.h>
+#include <tqfontmetrics.h>
+#include <tdemessagebox.h>
+#include <tdepopupmenu.h>
+#include <tqcursor.h>
+#include <tqclipboard.h>
+#include <tqheader.h>
+#include <kurldrag.h>
+#include <../kicons.h>
+
+class SearchListView : public TQListView
+{
+public:
+ SearchListView( TQWidget * parent, const char * name ) : TQListView( parent, name )
+ {
+ }
+
+ void startDrag()
+ {
+ KURL::List urls;
+
+ TQListViewItem * item = firstChild();
+ while( item )
+ {
+ if( item->isSelected() )
+ {
+ TQString name = item->text(1);
+ name += (name.endsWith( "/" ) ? item->text(0) : "/" + item->text(0) );
+ urls.push_back( vfs::fromPathOrURL( name ) );
+ }
+ item = item->nextSibling();
+ }
+
+ if( urls.count() == 0 )
+ return;
+
+ KURLDrag *d = new KURLDrag(urls, this);
+ d->setPixmap( FL_LOADICON( "file" ), TQPoint( -7, 0 ) );
+ d->dragCopy();
+ }
+};
+
+
+
+KrSearchDialog *KrSearchDialog::SearchDialog = 0;
+
+TQString KrSearchDialog::lastSearchText = "*";
+int KrSearchDialog::lastSearchType = 0;
+bool KrSearchDialog::lastSearchForCase = false;
+bool KrSearchDialog::lastRemoteContentSearch = false;
+bool KrSearchDialog::lastContainsWholeWord = false;
+bool KrSearchDialog::lastContainsWithCase = true;
+bool KrSearchDialog::lastSearchInSubDirs = true;
+bool KrSearchDialog::lastSearchInArchives = false;
+bool KrSearchDialog::lastFollowSymLinks = false;
+
+// class starts here /////////////////////////////////////////
+KrSearchDialog::KrSearchDialog( TQString profile, TQWidget* parent, const char* name, bool modal, WFlags fl )
+ : TQDialog( parent, name, modal, fl ), query(0), searcher(0)
+{
+ setCaption( i18n( "Krusader::Search" ) );
+
+ TQGridLayout* searchBaseLayout = new TQGridLayout( this );
+ searchBaseLayout->setSpacing( 6 );
+ searchBaseLayout->setMargin( 11 );
+
+ // creating the dialog buttons ( Search, Stop, Close )
+
+ TQHBoxLayout* buttonsLayout = new TQHBoxLayout();
+ buttonsLayout->setSpacing( 6 );
+ buttonsLayout->setMargin( 0 );
+
+ profileManager = new ProfileManager( "SearcherProfile", this, "profileManager" );
+ buttonsLayout->addWidget( profileManager );
+
+ TQSpacerItem* spacer = new TQSpacerItem( 20, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
+ buttonsLayout->addItem( spacer );
+
+ mainFeedToListBoxBtn = new TQPushButton( this, "mainFeedToListBoxBtn" );
+ mainFeedToListBoxBtn->setText( i18n( "Feed to listbox" ) );
+ mainFeedToListBoxBtn->setEnabled(false);
+ buttonsLayout->addWidget( mainFeedToListBoxBtn );
+
+ mainSearchBtn = new TQPushButton( this, "mainSearchBtn" );
+ mainSearchBtn->setText( i18n( "Search" ) );
+ mainSearchBtn->setDefault(true);
+ buttonsLayout->addWidget( mainSearchBtn );
+
+ mainStopBtn = new TQPushButton( this, "mainStopBtn" );
+ mainStopBtn->setEnabled( false );
+ mainStopBtn->setText( i18n( "Stop" ) );
+ buttonsLayout->addWidget( mainStopBtn );
+
+ mainCloseBtn = new TQPushButton( this, "mainCloseBtn" );
+ mainCloseBtn->setText( i18n( "Close" ) );
+ buttonsLayout->addWidget( mainCloseBtn );
+
+ searchBaseLayout->addLayout( buttonsLayout, 1, 0 );
+
+ // creating the searcher tabs
+
+ searcherTabs = new TQTabWidget( this, "searcherTabs" );
+
+ filterTabs = FilterTabs::addTo( searcherTabs, FilterTabs::Default | FilterTabs::HasRemoteContentSearch );
+ generalFilter = (GeneralFilter *)filterTabs->get( "GeneralFilter" );
+
+ resultTab = new TQWidget( searcherTabs, "resultTab" );
+ resultLayout = new TQGridLayout( resultTab );
+ resultLayout->setSpacing( 6 );
+ resultLayout->setMargin( 11 );
+
+ // creating the result tab
+
+ TQHBoxLayout* resultLabelLayout = new TQHBoxLayout();
+ resultLabelLayout->setSpacing( 6 );
+ resultLabelLayout->setMargin( 0 );
+
+ foundLabel = new TQLabel( resultTab, "foundLabel" );
+ foundLabel->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)1, foundLabel->sizePolicy().hasHeightForWidth() ) );
+ foundLabel->setFrameShape( TQLabel::StyledPanel );
+ foundLabel->setFrameShadow( TQLabel::Sunken );
+ foundLabel->setText( i18n( "Found 0 matches." ) );
+ resultLabelLayout->addWidget( foundLabel );
+
+ searchingLabel = new KSqueezedTextLabel( resultTab, "searchingLabel" );
+ searchingLabel->setFrameShape( TQLabel::StyledPanel );
+ searchingLabel->setFrameShadow( TQLabel::Sunken );
+ searchingLabel->setText( "" );
+ resultLabelLayout->addWidget( searchingLabel );
+
+ resultLayout->addLayout( resultLabelLayout, 2, 0 );
+
+ // creating the result list view
+
+ resultsList = new SearchListView( resultTab, "resultsList" );
+ resultsList->addColumn( i18n( "Name" ) );
+ resultsList->addColumn( i18n( "Location" ) );
+ resultsList->addColumn( i18n( "Size" ) );
+ resultsList->addColumn( i18n( "Date" ) );
+ resultsList->addColumn( i18n( "Permissions" ) );
+
+ resultsList->setSorting(1); // sort by location
+ resultsList->setSelectionMode( TQListView::Extended );
+
+ // fix the results list
+ // => make the results font smaller
+ TQFont resultsFont( resultsList->font() );
+ resultsFont.setPointSize(resultsFont.pointSize()-1);
+ resultsList->setFont(resultsFont);
+
+ resultsList->setAllColumnsShowFocus(true);
+ for (int i=0; i<5; ++i) // don't let it resize automatically
+ resultsList->setColumnWidthMode(i, TQListView::Manual);
+
+ int i=TQFontMetrics(resultsList->font()).width("W");
+ int j=TQFontMetrics(resultsList->font()).width("0");
+ j=(i>j ? i : j);
+
+ resultsList->setColumnWidth(0, krConfig->readNumEntry("Name Width", j*14) );
+ resultsList->setColumnWidth(1, krConfig->readNumEntry("Path Width", j*25) );
+ resultsList->setColumnWidth(2, krConfig->readNumEntry("Size Width", j*6) );
+ resultsList->setColumnWidth(3, krConfig->readNumEntry("Date Width", j*7) );
+ resultsList->setColumnWidth(4, krConfig->readNumEntry("Perm Width", j*7) );
+ resultsList->setColumnAlignment( 2, AlignRight );
+
+ resultsList->header()->setStretchEnabled( true, 1 );
+
+ resultLayout->addWidget( resultsList, 0, 0 );
+
+ TQHBoxLayout* foundTextLayout = new TQHBoxLayout();
+ foundTextLayout->setSpacing( 6 );
+ foundTextLayout->setMargin( 0 );
+
+ TQLabel *l1 = new TQLabel(resultTab);
+ l1->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)1, l1->sizePolicy().hasHeightForWidth() ) );
+ l1->setFrameShape( TQLabel::StyledPanel );
+ l1->setFrameShadow( TQLabel::Sunken );
+ l1->setText(i18n("Text found:"));
+ foundTextLayout->addWidget( l1 );
+
+ foundTextLabel = new KrSqueezedTextLabel(resultTab);
+ foundTextLabel->setFrameShape( TQLabel::StyledPanel );
+ foundTextLabel->setFrameShadow( TQLabel::Sunken );
+ foundTextLabel->setText("");
+ foundTextLayout->addWidget( foundTextLabel );
+ resultLayout->addLayout(foundTextLayout, 1, 0);
+
+ searcherTabs->insertTab( resultTab, i18n( "&Results" ) );
+
+ searchBaseLayout->addWidget( searcherTabs, 0, 0 );
+
+ // signals and slots connections
+
+ connect( mainSearchBtn, TQ_SIGNAL( clicked() ), this, TQ_SLOT( startSearch() ) );
+ connect( mainStopBtn, TQ_SIGNAL( clicked() ), this, TQ_SLOT( stopSearch() ) );
+ connect( resultsList, TQ_SIGNAL( returnPressed(TQListViewItem*) ), this,
+ TQ_SLOT( resultDoubleClicked(TQListViewItem*) ) );
+ connect( resultsList, TQ_SIGNAL( doubleClicked(TQListViewItem*) ), this,
+ TQ_SLOT( resultDoubleClicked(TQListViewItem*) ) );
+ connect( resultsList, TQ_SIGNAL( currentChanged(TQListViewItem*) ), this,
+ TQ_SLOT( resultClicked(TQListViewItem*) ) );
+ connect( resultsList, TQ_SIGNAL( clicked(TQListViewItem*) ), this,
+ TQ_SLOT( resultClicked(TQListViewItem*) ) );
+ connect( resultsList, TQ_SIGNAL( rightButtonClicked(TQListViewItem*,const TQPoint&,int) ), this, TQ_SLOT( rightClickMenu(TQListViewItem*, const TQPoint&, int) ) );
+ connect( mainCloseBtn, TQ_SIGNAL( clicked() ), this, TQ_SLOT( closeDialog() ) );
+ connect( mainFeedToListBoxBtn, TQ_SIGNAL( clicked() ), this, TQ_SLOT( feedToListBox() ) );
+
+ connect( profileManager, TQ_SIGNAL( loadFromProfile( TQString ) ), filterTabs, TQ_SLOT( loadFromProfile( TQString ) ) );
+ connect( profileManager, TQ_SIGNAL( saveToProfile( TQString ) ), filterTabs, TQ_SLOT( saveToProfile( TQString ) ) );
+
+ // tab order
+
+ setTabOrder( mainSearchBtn, mainCloseBtn );
+ setTabOrder( mainCloseBtn, mainStopBtn );
+ setTabOrder( mainStopBtn, searcherTabs );
+ setTabOrder( searcherTabs, resultsList );
+
+ krConfig->setGroup( "Search" );
+ int sx = krConfig->readNumEntry( "Window Width", -1 );
+ int sy = krConfig->readNumEntry( "Window Height", -1 );
+
+ if( sx != -1 && sy != -1 )
+ resize( sx, sy );
+
+ if( krConfig->readBoolEntry( "Window Maximized", false ) )
+ showMaximized();
+ else
+ show();
+
+ generalFilter->searchFor->setFocus();
+
+ isSearching = closed = false;
+
+ // finaly, load a profile of apply defaults:
+
+ if ( profile.isEmpty() ) {
+ // load the last used values
+ generalFilter->searchFor->setEditText( lastSearchText );
+ generalFilter->searchFor->lineEdit()->selectAll();
+ generalFilter->ofType->setCurrentItem( lastSearchType );
+ generalFilter->searchForCase->setChecked( lastSearchForCase );
+ generalFilter->remoteContentSearch->setChecked( lastRemoteContentSearch );
+ generalFilter->containsWholeWord->setChecked( lastContainsWholeWord );
+ generalFilter->containsTextCase->setChecked( lastContainsWithCase );
+ generalFilter->searchInDirs->setChecked( lastSearchInSubDirs );
+ generalFilter->searchInArchives->setChecked( lastSearchInArchives );
+ generalFilter->followLinks->setChecked( lastFollowSymLinks );
+ // the path in the active panel should be the default search location
+ generalFilter->searchIn->lineEdit()->setText( ACTIVE_PANEL->virtualPath().prettyURL() );
+ }
+ else
+ profileManager->loadProfile( profile ); // important: call this _after_ you've connected profileManager ot the loadFromProfile!!
+}
+
+void KrSearchDialog::closeDialog( bool isAccept )
+{
+ // stop the search if it's on-going
+ if (searcher!=0) {
+ delete searcher;
+ searcher = 0;
+ }
+
+ // saving the searcher state
+
+ krConfig->setGroup( "Search" );
+
+ krConfig->writeEntry("Window Width", sizeX );
+ krConfig->writeEntry("Window Height", sizeY );
+ krConfig->writeEntry("Window Maximized", isMaximized() );
+
+ krConfig->writeEntry("Name Width", resultsList->columnWidth( 0 ) );
+ krConfig->writeEntry("Path Width", resultsList->columnWidth( 1 ) );
+ krConfig->writeEntry("Size Width", resultsList->columnWidth( 2 ) );
+ krConfig->writeEntry("Date Width", resultsList->columnWidth( 3 ) );
+ krConfig->writeEntry("Perm Width", resultsList->columnWidth( 4 ) );
+
+ lastSearchText = generalFilter->searchFor->currentText();
+ lastSearchType = generalFilter->ofType->currentItem();
+ lastSearchForCase = generalFilter->searchForCase->isChecked();
+ lastRemoteContentSearch = generalFilter->remoteContentSearch->isChecked();
+ lastContainsWholeWord = generalFilter->containsWholeWord->isChecked();
+ lastContainsWithCase = generalFilter->containsTextCase->isChecked();
+ lastSearchInSubDirs = generalFilter->searchInDirs->isChecked();
+ lastSearchInArchives = generalFilter->searchInArchives->isChecked();
+ lastFollowSymLinks = generalFilter->followLinks->isChecked();
+ hide();
+
+ SearchDialog = 0;
+ if( isAccept )
+ TQDialog::accept();
+ else
+ TQDialog::reject();
+
+ this->deleteLater();
+}
+
+void KrSearchDialog::reject() {
+ closeDialog( false );
+}
+
+void KrSearchDialog::resizeEvent( TQResizeEvent *e )
+{
+ if( !isMaximized() )
+ {
+ sizeX = e->size().width();
+ sizeY = e->size().height();
+ }
+}
+
+void KrSearchDialog::found(TQString what, TQString where, TDEIO::filesize_t size, time_t mtime, TQString perm, TQString foundText){
+ // convert the time_t to struct tm
+ struct tm* t=localtime((time_t *)&mtime);
+ TQDateTime tmp(TQDate(t->tm_year+1900, t->tm_mon+1, t->tm_mday), TQTime(t->tm_hour, t->tm_min));
+ ResultListViewItem *it =new ResultListViewItem(resultsList, what,
+ where.replace(TQRegExp("\\\\"),"#"), size, tmp, perm);
+ TQString totals = TQString(i18n("Found %1 matches.")).arg(resultsList->childCount());
+ foundLabel->setText(totals);
+
+ if (!foundText.isEmpty()) it->setFoundText(foundText);
+}
+
+bool KrSearchDialog::gui2query() {
+ // prepare the query ...
+ /////////////////// names, locations and greps
+ if (query!=0) { delete query; query = 0; }
+ query = new KRQuery();
+
+ return filterTabs->fillQuery( query );
+}
+
+void KrSearchDialog::startSearch() {
+
+ // prepare the query /////////////////////////////////////////////
+ if (!gui2query()) return;
+
+ // first, informative messages
+ if ( query->searchInArchives() ) {
+ KMessageBox::information(this, i18n("Since you chose to also search in archives, "
+ "note the following limitations:\n"
+ "You cannot search for text (grep) while doing"
+ " a search that includes archives."), 0, "searchInArchives");
+ }
+
+ // prepare the gui ///////////////////////////////////////////////
+ mainSearchBtn->setEnabled(false);
+ mainCloseBtn->setEnabled(false);
+ mainStopBtn->setEnabled(true);
+ mainFeedToListBoxBtn->setEnabled(false);
+ resultsList->clear();
+ searchingLabel->setText("");
+ foundLabel->setText(i18n("Found 0 matches."));
+ searcherTabs->setCurrentPage(2); // show the results page
+ foundTextLabel->setText("");
+ tqApp->processEvents();
+
+ // start the search.
+ if (searcher != 0) {
+ delete searcher;
+ searcher = 0;
+ }
+ searcher = new KRSearchMod(query);
+ connect(searcher, TQ_SIGNAL(searching(const TQString&)),
+ searchingLabel, TQ_SLOT(setText(const TQString&)));
+ connect(searcher, TQ_SIGNAL(found(TQString,TQString,TDEIO::filesize_t,time_t,TQString,TQString)),
+ this, TQ_SLOT(found(TQString,TQString,TDEIO::filesize_t,time_t,TQString,TQString)));
+ connect(searcher, TQ_SIGNAL(finished()), this, TQ_SLOT(stopSearch()));
+
+ isSearching = true;
+ searcher->start();
+ isSearching = false;
+ if( closed )
+ emit closeDialog();
+}
+
+void KrSearchDialog::stopSearch() {
+ if (searcher!=0) {
+ searcher->stop();
+ disconnect(searcher,0,0,0);
+ delete query;
+ query = 0;
+ }
+
+ // gui stuff
+ mainSearchBtn->setEnabled(true);
+ mainCloseBtn->setEnabled(true);
+ mainStopBtn->setEnabled(false);
+ if( resultsList->childCount() )
+ mainFeedToListBoxBtn->setEnabled( true );
+ searchingLabel->setText(i18n("Finished searching."));
+}
+
+void KrSearchDialog::resultDoubleClicked(TQListViewItem* i) {
+ ACTIVE_FUNC->openUrl(vfs::fromPathOrURL(i->text(1)),i->text(0));
+ showMinimized();
+}
+
+void KrSearchDialog::resultClicked(TQListViewItem* i) {
+ ResultListViewItem *it = dynamic_cast<ResultListViewItem*>(i);
+ if( it == 0 )
+ return;
+ if (!it->foundText().isEmpty()) {
+ // ugly hack: find the <b> and </b> in the text, then
+ // use it to set the are which we don't want squeezed
+ int idx = it->foundText().find("<b>")-4; // take "<qt>" into account
+ int length = it->foundText().find("</b>")-idx+4;
+ foundTextLabel->setText(it->foundText(), idx, length);
+ }
+}
+
+void KrSearchDialog::closeEvent(TQCloseEvent *e)
+{ /* if searching is in progress we must not close the window */
+ if( isSearching ) /* because tqApp->processEvents() is called by the searcher and */
+ { /* at window desruction, the searcher object will be deleted */
+ stopSearch(); /* instead we stop searching */
+ closed = true; /* and after stopping: startSearch can close the window */
+ e->ignore(); /* ignoring the close event */
+ }
+ else
+ TQDialog::closeEvent( e ); /* if no searching, let TQDialog handle the event */
+}
+
+void KrSearchDialog::keyPressEvent(TQKeyEvent *e)
+{
+ KKey pressedKey( e );
+
+ if( isSearching && e->key() == Key_Escape ) /* at searching we must not close the window */
+ {
+ stopSearch(); /* so we simply stop searching */
+ return;
+ }
+ if( resultsList->hasFocus() )
+ {
+ if( e->key() == Key_F4 )
+ {
+ if (!generalFilter->containsText->currentText().isEmpty() && TQApplication::clipboard()->text() != generalFilter->containsText->currentText())
+ TQApplication::clipboard()->setText(generalFilter->containsText->currentText());
+ editCurrent();
+ return;
+ }
+ else if( e->key() == Key_F3 )
+ {
+ if (!generalFilter->containsText->currentText().isEmpty() && TQApplication::clipboard()->text() != generalFilter->containsText->currentText())
+ TQApplication::clipboard()->setText(generalFilter->containsText->currentText());
+ viewCurrent();
+ return;
+ }
+ else if( Krusader::actCopy->shortcut().contains( pressedKey ) )
+ {
+ copyToClipBoard();
+ return;
+ }
+ }
+
+ TQDialog::keyPressEvent( e );
+}
+
+void KrSearchDialog::editCurrent()
+{
+ TQListViewItem *current = resultsList->currentItem();
+ if( current )
+ {
+ TQString name = current->text(1);
+ name += (name.endsWith( "/" ) ? current->text(0) : "/" + current->text(0) );
+ KURL url = vfs::fromPathOrURL( name );
+ KrViewer::edit( url, this );
+ }
+}
+
+void KrSearchDialog::viewCurrent()
+{
+ TQListViewItem *current = resultsList->currentItem();
+ if( current )
+ {
+ TQString name = current->text(1);
+ name += (name.endsWith( "/" ) ? current->text(0) : "/" + current->text(0) );
+ KURL url = vfs::fromPathOrURL( name );
+ KrViewer::view( url, this );
+ }
+}
+
+void KrSearchDialog::rightClickMenu(TQListViewItem *item, const TQPoint&, int)
+{
+ // these are the values that will exist in the menu
+ #define EDIT_FILE_ID 110
+ #define VIEW_FILE_ID 111
+ #define COPY_SELECTED_TO_CLIPBOARD 112
+ //////////////////////////////////////////////////////////
+ if (!item)
+ return;
+
+ // create the menu
+ TDEPopupMenu popup;
+ popup.insertTitle(i18n("Krusader Search"));
+
+ popup.insertItem(i18n("View File (F3)"), VIEW_FILE_ID);
+ popup.insertItem(i18n("Edit File (F4)"), EDIT_FILE_ID);
+ popup.insertItem(i18n("Copy selected to clipboard"),COPY_SELECTED_TO_CLIPBOARD);
+
+ int result=popup.exec(TQCursor::pos());
+
+ // check out the user's option
+ switch (result)
+ {
+ case VIEW_FILE_ID:
+ viewCurrent();
+ break;
+ case EDIT_FILE_ID:
+ editCurrent();
+ break;
+ case COPY_SELECTED_TO_CLIPBOARD:
+ copyToClipBoard();
+ break;
+ default: // the user clicked outside of the menu
+ break;
+ }
+}
+
+void KrSearchDialog::feedToListBox()
+{
+ virt_vfs v(0,true);
+ v.vfs_refresh( KURL( "/" ) );
+
+ krConfig->setGroup( "Search" );
+ int listBoxNum = krConfig->readNumEntry( "Feed To Listbox Counter", 1 );
+ TQString queryName;
+ do {
+ queryName = i18n("Search results")+TQString( " %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;
+ TQListViewItem * item = resultsList->firstChild();
+ while( item )
+ {
+ TQString name = item->text(1);
+ name += (name.endsWith( "/" ) ? item->text(0) : "/" + item->text(0) );
+ urlList.push_back( vfs::fromPathOrURL( name ) );
+ item = item->nextSibling();
+ }
+ KURL url = KURL::fromPathOrURL( TQString("virt:/") + queryName );
+ v.vfs_refresh( url );
+ v.vfs_addFiles( &urlList, TDEIO::CopyJob::Copy, 0 );
+ //ACTIVE_FUNC->openUrl(url);
+ ACTIVE_MNG->slotNewTab(url.prettyURL());
+ closeDialog();
+}
+
+void KrSearchDialog::copyToClipBoard()
+{
+ KURL::List urls;
+
+ TQListViewItem * item = resultsList->firstChild();
+ while( item )
+ {
+ if( item->isSelected() )
+ {
+ TQString name = item->text(1);
+ name += (name.endsWith( "/" ) ? item->text(0) : "/" + item->text(0) );
+ urls.push_back( vfs::fromPathOrURL( name ) );
+ }
+ item = item->nextSibling();
+ }
+
+ if( urls.count() == 0 )
+ return;
+
+ KURLDrag *d = new KURLDrag(urls, this);
+ d->setPixmap( FL_LOADICON( "file" ), TQPoint( -7, 0 ) );
+ TQApplication::clipboard()->setData( d );
+}
+
+#include "krsearchdialog.moc"
diff --git a/src/app/Search/krsearchdialog.h b/src/app/Search/krsearchdialog.h
new file mode 100644
index 0000000..273c95a
--- /dev/null
+++ b/src/app/Search/krsearchdialog.h
@@ -0,0 +1,184 @@
+/***************************************************************************
+ krsearchdialog.h
+ -------------------
+ copyright : (C) 2001 by Shie Erlich & Rafi Yanai
+ email : 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
+
+ H e a d e r 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. *
+ * *
+ ***************************************************************************/
+
+
+
+#ifndef KRSEARCHDIALOG_H
+#define KRSEARCHDIALOG_H
+
+#include "../Filter/filtertabs.h"
+#include "../Filter/generalfilter.h"
+#include "../VFS/krquery.h"
+#include "../VFS/krpermhandler.h"
+#include "krsearchmod.h"
+#include "../GUI/profilemanager.h"
+
+#include <tqwidget.h>
+#include <ksqueezedtextlabel.h>
+#include <tqstringlist.h>
+#include <sys/types.h>
+#include <time.h>
+#include <tqstring.h>
+#include <tqtabwidget.h>
+#include <tqlistview.h>
+#include <tqstringlist.h>
+#include <tdeglobal.h>
+#include <tdelocale.h>
+
+class KrSearchDialog : public TQDialog {
+ TQ_OBJECT
+
+public:
+ KrSearchDialog(TQString profile = 0, TQWidget* parent = 0, const char* name = 0, bool modal = false, WFlags fl = 0 );
+
+ void prepareGUI();
+
+ static KrSearchDialog *SearchDialog;
+
+public slots:
+ void startSearch();
+ void stopSearch();
+ void feedToListBox();
+ void copyToClipBoard();
+ void found(TQString what, TQString where, TDEIO::filesize_t size, time_t mtime, TQString perm, TQString foundText);
+ void closeDialog( bool isAccept = true );
+ void resultDoubleClicked(TQListViewItem*);
+ void resultClicked(TQListViewItem*);
+
+ virtual void keyPressEvent(TQKeyEvent *e);
+ virtual void closeEvent(TQCloseEvent *e);
+ virtual void rightClickMenu(TQListViewItem*, const TQPoint&, int);
+ virtual void resizeEvent( TQResizeEvent *e );
+
+protected slots:
+ void reject();
+
+private:
+ bool gui2query();
+ void editCurrent();
+ void viewCurrent();
+
+private:
+ ProfileManager *profileManager;
+
+ FilterTabs * filterTabs;
+ GeneralFilter * generalFilter;
+
+ TQPushButton* mainHelpBtn;
+ TQPushButton* mainSearchBtn;
+ TQPushButton* mainStopBtn;
+ TQPushButton* mainCloseBtn;
+ TQPushButton* mainFeedToListBoxBtn;
+
+ TQTabWidget* searcherTabs;
+ TQWidget* resultTab;
+ TQGridLayout* resultLayout;
+ TQLabel* foundLabel;
+ KrSqueezedTextLabel *foundTextLabel;
+ KSqueezedTextLabel *searchingLabel;
+
+ TQListView* resultsList;
+
+ KRQuery *query;
+ KRSearchMod *searcher;
+ TQStringList savedSearches;
+ bool isSearching;
+ bool closed;
+
+ static TQString lastSearchText;
+ static int lastSearchType;
+ static bool lastSearchForCase;
+ static bool lastRemoteContentSearch;
+ static bool lastContainsWholeWord;
+ static bool lastContainsWithCase;
+ static bool lastSearchInSubDirs;
+ static bool lastSearchInArchives;
+ static bool lastFollowSymLinks;
+
+ int sizeX;
+ int sizeY;
+};
+
+class ResultListViewItem : public TQListViewItem
+{
+public:
+ ResultListViewItem( TQListView *resultsList, TQString name, TQString where, TDEIO::filesize_t size,
+ TQDateTime date, TQString perm ) : TQListViewItem( resultsList, name, where,
+ KRpermHandler::parseSize(size),
+ TDEGlobal::locale()->formatDateTime( date ), perm )
+ {
+ fileSize = size;
+ fileDate = date;
+ setDragEnabled( true );
+ }
+
+ void setFoundText(TQString text) { _foundText=text; }
+ const TQString& foundText() const { return _foundText; }
+
+ virtual int compare(TQListViewItem *i,int col,bool ascending ) const
+ {
+ if( col == 2 ) {
+ ResultListViewItem *other = (ResultListViewItem *)i;
+ TDEIO::filesize_t otherSize = other->getSize();
+
+ if( fileSize == otherSize )
+ return 0;
+ if( fileSize > otherSize )
+ return 1;
+ return -1;
+ }
+ if( col == 3 ) {
+ ResultListViewItem *other = (ResultListViewItem *)i;
+ TQDateTime otherDate = other->getDate();
+
+ if( fileDate == otherDate )
+ return 0;
+ if( fileDate > otherDate )
+ return 1;
+ return -1;
+ }
+ return TQListViewItem::compare( i, col, ascending );
+ }
+
+ TDEIO::filesize_t getSize() {
+ return fileSize;
+ }
+
+ TQDateTime getDate() {
+ return fileDate;
+ }
+
+private:
+ TDEIO::filesize_t fileSize;
+ TQDateTime fileDate;
+ TQString _foundText;
+};
+
+#endif
diff --git a/src/app/Search/krsearchmod.cpp b/src/app/Search/krsearchmod.cpp
new file mode 100644
index 0000000..3198197
--- /dev/null
+++ b/src/app/Search/krsearchmod.cpp
@@ -0,0 +1,253 @@
+/***************************************************************************
+ krsearchmod.cpp
+ -------------------
+ copyright : (C) 2001 by Shie Erlich & Rafi Yanai
+ email : 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 "krsearchmod.h"
+#include "../VFS/krquery.h"
+#include "../krusader.h"
+#include "../resources.h"
+#include "../VFS/vfile.h"
+#include "../VFS/krpermhandler.h"
+#include "../VFS/krarchandler.h"
+
+#include <tdelocale.h>
+#include <tqdir.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <tqtextstream.h>
+#include <tqregexp.h>
+#include <klargefile.h>
+#include <kurlrequesterdlg.h>
+
+#include <kmimetype.h>
+
+#define EVENT_PROCESS_DELAY 250
+
+KRSearchMod::KRSearchMod( const KRQuery* q )
+{
+ stopSearch = false; /// ===> added
+ query = new KRQuery( *q );
+ connect( query, TQ_SIGNAL( status( const TQString & ) ),
+ this, TQ_SIGNAL( searching(const TQString&) ) );
+ connect( query, TQ_SIGNAL( processEvents( bool & ) ),
+ this, TQ_SLOT ( slotProcessEvents( bool & ) ) );
+
+ remote_vfs = 0;
+ virtual_vfs = 0;
+}
+
+KRSearchMod::~KRSearchMod()
+{
+ delete query;
+ if( remote_vfs )
+ delete remote_vfs;
+ if( virtual_vfs )
+ delete virtual_vfs;
+}
+
+void KRSearchMod::start()
+{
+ unScannedUrls.clear();
+ scannedUrls.clear();
+ timer.start();
+
+ KURL::List whereToSearch = query->searchInDirs();
+
+ // search every dir that needs to be searched
+ for ( unsigned int i = 0; i < whereToSearch.count(); ++i )
+ scanURL( whereToSearch [ i ] );
+
+ emit finished();
+}
+
+void KRSearchMod::stop()
+{
+ stopSearch = true;
+}
+
+void KRSearchMod::scanURL( KURL url )
+{
+ if( stopSearch ) return;
+
+ unScannedUrls.push( url );
+ while ( !unScannedUrls.isEmpty() )
+ {
+ KURL urlToCheck = unScannedUrls.pop();
+
+ if( stopSearch ) return;
+
+ if( query->isExcluded( urlToCheck ) ) {
+ if( !query->searchInDirs().contains( urlToCheck ) )
+ continue;
+ }
+
+ if( scannedUrls.contains( urlToCheck ) )
+ continue;
+ scannedUrls.push( urlToCheck );
+
+ emit searching( vfs::pathOrURL( urlToCheck ) );
+
+ if ( urlToCheck.isLocalFile() )
+ scanLocalDir( urlToCheck );
+ else
+ scanRemoteDir( urlToCheck );
+ }
+}
+
+void KRSearchMod::scanLocalDir( KURL urlToScan )
+{
+ TQString dir = urlToScan.path( 1 );
+
+ DIR* d = opendir( dir.local8Bit() );
+ if ( !d ) return ;
+
+ struct dirent* dirEnt;
+
+ while ( ( dirEnt = readdir( d ) ) != NULL )
+ {
+ TQString name = TQString::fromLocal8Bit( dirEnt->d_name );
+
+ // we dont scan the ".",".." enteries
+ if ( name == "." || name == ".." ) continue;
+
+ KDE_struct_stat stat_p;
+ KDE_lstat( ( dir + name ).local8Bit(), &stat_p );
+
+ KURL url = vfs::fromPathOrURL( dir + name );
+
+ TQString mime = TQString();
+ if ( query->searchInArchives() || !query->hasMimeType() )
+ mime = KMimeType::findByURL( url, stat_p.st_mode, true, false ) ->name();
+
+ // creating a vfile object for matching with krquery
+ vfile * vf = new vfile(name, (TDEIO::filesize_t)stat_p.st_size, KRpermHandler::mode2TQString(stat_p.st_mode),
+ stat_p.st_mtime, S_ISLNK(stat_p.st_mode), stat_p.st_uid, stat_p.st_gid,
+ mime, "", stat_p.st_mode);
+ vf->vfile_setUrl( url );
+
+ if ( query->isRecursive() )
+ {
+ if ( S_ISLNK( stat_p.st_mode ) && query->followLinks() )
+ unScannedUrls.push( vfs::fromPathOrURL( TQDir( dir + name ).canonicalPath() ) );
+ else if ( S_ISDIR( stat_p.st_mode ) )
+ unScannedUrls.push( url );
+ }
+ if ( query->searchInArchives() )
+ {
+ TQString type = mime.right( 4 );
+ if ( mime.contains( "-rar" ) ) type = "-rar";
+
+ if ( KRarcHandler::arcSupported( type ) )
+ {
+ KURL archiveURL = url;
+ bool encrypted;
+ TQString realType = KRarcHandler::getType( encrypted, url.path(), mime );
+
+ if( !encrypted ) {
+ if ( realType == "-tbz" || realType == "-tgz" || realType == "tarz" || realType == "-tar" )
+ archiveURL.setProtocol( "tar" );
+ else
+ archiveURL.setProtocol( "krarc" );
+
+ unScannedUrls.push( archiveURL );
+ }
+ }
+ }
+
+ if( query->match( vf ) )
+ {
+ // if we got here - we got a winner
+ results.append( dir + name );
+ emit found( name, dir, ( TDEIO::filesize_t ) stat_p.st_size, stat_p.st_mtime, KRpermHandler::mode2TQString( stat_p.st_mode ), query->foundText() );
+ }
+ delete vf;
+
+ if( timer.elapsed() >= EVENT_PROCESS_DELAY ) {
+ tqApp->processEvents();
+ timer.start();
+ if( stopSearch ) return;
+ }
+ }
+ // clean up
+ closedir( d );
+}
+
+void KRSearchMod::scanRemoteDir( KURL url )
+{
+ vfs * vfs_;
+
+
+ if( url.protocol() == "virt" )
+ {
+ if( virtual_vfs == 0 )
+ virtual_vfs = new virt_vfs( 0 );
+ vfs_ = virtual_vfs;
+ }
+ else
+ {
+ if( remote_vfs == 0 )
+ remote_vfs = new ftp_vfs( 0 );
+ vfs_ = remote_vfs;
+ }
+
+ if ( !vfs_->vfs_refresh( url ) ) return ;
+
+ for ( vfile * vf = vfs_->vfs_getFirstFile(); vf != 0 ; vf = vfs_->vfs_getNextFile() )
+ {
+ TQString name = vf->vfile_getName();
+ KURL fileURL = vfs_->vfs_getFile( name );
+
+ if ( query->isRecursive() && (( vf->vfile_isSymLink() && query->followLinks() ) || vf->vfile_isDir() ) )
+ unScannedUrls.push( fileURL );
+
+ if( query->match( vf ) )
+ {
+ // if we got here - we got a winner
+ results.append( vfs::pathOrURL( fileURL, -1 ) );
+
+ emit found( fileURL.fileName(), vfs::pathOrURL( fileURL.upURL(), -1 ), vf->vfile_getSize(), vf->vfile_getTime_t(), vf->vfile_getPerm(), query->foundText() );
+ }
+
+ if( timer.elapsed() >= EVENT_PROCESS_DELAY ) {
+ tqApp->processEvents();
+ timer.start();
+ if( stopSearch ) return;
+ }
+ }
+}
+
+void KRSearchMod::slotProcessEvents( bool & stopped ) {
+ tqApp->processEvents();
+ stopped = stopSearch;
+}
+
+#include "krsearchmod.moc"
diff --git a/src/app/Search/krsearchmod.h b/src/app/Search/krsearchmod.h
new file mode 100644
index 0000000..781d0e5
--- /dev/null
+++ b/src/app/Search/krsearchmod.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ krsearchmod.h
+ -------------------
+ copyright : (C) 2001 by Shie Erlich & Rafi Yanai
+ email : 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
+
+ H e a d e r 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. *
+ * *
+ ***************************************************************************/
+
+
+
+#ifndef KRSEARCHMOD_H
+#define KRSEARCHMOD_H
+
+#include <tqobject.h>
+#include <tqvaluestack.h>
+#include <tqstringlist.h>
+#include <tqdatetime.h>
+#include <time.h>
+#include <tdeio/global.h>
+#include <kurl.h>
+#include "../VFS/ftp_vfs.h"
+#include "../VFS/virt_vfs.h"
+
+
+class KRQuery;
+class ftp_vfs;
+
+class KRSearchMod : public TQObject {
+ TQ_OBJECT
+
+public:
+ KRSearchMod(const KRQuery *q);
+ ~KRSearchMod();
+
+ void scanURL( KURL url );
+ void start();
+ void stop();
+
+private:
+ void scanLocalDir( KURL url );
+ void scanRemoteDir( KURL url );
+
+signals:
+ void finished();
+ void searching(const TQString&);
+ void found(TQString what, TQString where, TDEIO::filesize_t size, time_t mtime, TQString perm, TQString textFound);
+
+private slots:
+ void slotProcessEvents( bool & stopped );
+
+private:
+ bool stopSearch;
+ TQValueStack<KURL> scannedUrls;
+ TQValueStack<KURL> unScannedUrls;
+ KRQuery *query;
+ TQStringList results;
+
+ ftp_vfs *remote_vfs;
+ virt_vfs *virtual_vfs;
+
+ TQTime timer;
+};
+
+#endif