diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-08-28 22:44:34 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-08-31 23:25:26 +0900 |
commit | 086012dcad8a976a0dabbb7cbc20c9cb612cdfa9 (patch) | |
tree | 56c9bfcfd7cd13b17707dc8862f26932e9814973 /src/app/Search | |
parent | 409e7f624d202c7f96b4d0ab2da1834135169f8b (diff) | |
download | krusader-master.tar.gz krusader-master.zip |
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'src/app/Search')
-rw-r--r-- | src/app/Search/Makefile.am | 9 | ||||
-rw-r--r-- | src/app/Search/krsearchdialog.cpp | 628 | ||||
-rw-r--r-- | src/app/Search/krsearchdialog.h | 184 | ||||
-rw-r--r-- | src/app/Search/krsearchmod.cpp | 253 | ||||
-rw-r--r-- | src/app/Search/krsearchmod.h | 86 |
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 |