/*************************************************************************** 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 TDEListView { public: LocateListView( TQWidget * parent, const char * name = 0 ) : TDEListView( parent, name ) { } void startDrag() { KURL::List urls; TQListViewItem * 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" ), TQPoint( -7, 0 ) ); d->dragCopy(); } }; TDEProcess * 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 ) { TQWidget *widget=new TQWidget(this, "locateMainWidget"); TQGridLayout *grid = new TQGridLayout( widget ); grid->setSpacing( 6 ); grid->setMargin( 11 ); setPlainCaption( i18n( "Krusader::Locate" ) ); TQHBox *hbox = new TQHBox( widget, "locateHBox" ); TQLabel *label = new TQLabel( i18n( "Search for:" ), hbox, "locateLabel" ); locateSearchFor = new KHistoryCombo( false, hbox, "locateSearchFor" ); label->setBuddy( locateSearchFor ); krConfig->setGroup("Locate"); TQStringList list = krConfig->readListEntry("Search For"); locateSearchFor->setMaxCount(25); // remember 25 items locateSearchFor->setHistoryItems(list); locateSearchFor->setEditable( true ); locateSearchFor->setDuplicatesEnabled( false ); locateSearchFor->setSizePolicy(TQSizePolicy::Expanding,TQSizePolicy::Fixed); locateSearchFor->lineEdit()->setFocus(); grid->addWidget( hbox, 0, 0 ); TQHBox *hbox2 = new TQHBox( widget, "locateHBox" ); TQSpacerItem* spacer = new TQSpacerItem( 40, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); hbox2->layout()->addItem( spacer ); dontSearchInPath = new TQCheckBox( i18n( "Don't search in path" ), hbox2, "dontSearchInPath" ); dontSearchInPath->setChecked( krConfig->readBoolEntry("Dont Search In Path") ); existingFiles = new TQCheckBox( i18n( "Show only the existing files" ), hbox2, "existingFiles" ); existingFiles->setChecked( krConfig->readBoolEntry("Existing Files") ); caseSensitive = new TQCheckBox( i18n( "Case Sensitive" ), hbox2, "caseSensitive" ); caseSensitive->setChecked( krConfig->readBoolEntry("Case Sensitive") ); grid->addWidget( hbox2, 1, 0 ); TQFrame *line1 = new TQFrame( widget, "locateLine1" ); line1->setFrameStyle( TQFrame::HLine | TQFrame::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(TQScrollView::Auto); resultList->setHScrollBarMode(TQScrollView::Auto); resultList->setShowSortIndicator(false); resultList->setSorting(-1); resultList->setSelectionMode( TQListView::Extended ); resultList->addColumn( i18n("Results"), TQFontMetrics(resultList->font()).width("W") * 60 ); resultList->setColumnWidthMode(0,TQListView::Maximum); connect( resultList,TQT_SIGNAL(rightButtonPressed(TQListViewItem *, const TQPoint &, int)), this, TQT_SLOT(slotRightClick(TQListViewItem *))); connect( resultList,TQT_SIGNAL(doubleClicked(TQListViewItem *)), this, TQT_SLOT(slotDoubleClick(TQListViewItem *))); connect( resultList,TQT_SIGNAL(returnPressed(TQListViewItem *)), this, TQT_SLOT(slotDoubleClick(TQListViewItem *))); grid->addWidget( resultList, 3, 0 ); TQFrame *line2 = new TQFrame( widget, "locateLine2" ); line2->setFrameStyle( TQFrame::HLine | TQFrame::Sunken ); grid->addWidget( line2, 4, 0 ); enableButton( KDialogBase::User1, false ); /* disable the stop button */ if( updateProcess ) { if( updateProcess->isRunning() ) { connect( updateProcess, TQT_SIGNAL(processExited(TDEProcess *)), this, TQT_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 TDEProcess(); *updateProcess << KrServices::fullPathName( "updatedb" ); *updateProcess << KrServices::separateArgs( krConfig->readEntry( "UpdateDB Arguments", "" ) ); connect( updateProcess, TQT_SIGNAL(processExited(TDEProcess *)), this, TQT_SLOT(updateFinished())); updateProcess->start(TDEProcess::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()); TQStringList 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(); tqApp->processEvents(); stopping = false; TDEProcess locateProc; connect( &locateProc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int) ), this, TQT_SLOT( processStdout(TDEProcess *, char *, int) ) ); connect( &locateProc, TQT_SIGNAL( receivedStderr(TDEProcess *, char *, int) ), this, TQT_SLOT( processStderr(TDEProcess *, 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( TDEProcess::Block, TDEProcess::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(TDEProcess *proc, char *buffer, int length) { char *buf = new char[ length+1 ]; memcpy( buf, buffer, length ); buf[ length ] = 0; remaining += TQString::fromLocal8Bit( buf ); delete []buf; TQStringList list = TQStringList::split("\n", remaining ); int items = list.size(); for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) { if( --items == 0 && buffer[length-1] != '\n' ) remaining = *it; else { if( dontSearchPath ) { TQRegExp regExp( pattern, isCs, true ); TQString 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 TDEListViewItem( resultList, lastItem, *it ); else lastItem = new TDEListViewItem( resultList, *it ); lastItem->setDragEnabled( true ); } } if( stopping ) proc->kill( SIGKILL ); tqApp->processEvents(); } void LocateDlg::processStderr(TDEProcess *, char *buffer, int length) { char *buf = new char[ length+1 ]; memcpy( buf, buffer, length ); buf[ length ] = 0; collectedErr += TQString::fromLocal8Bit( buf ); delete []buf; } void LocateDlg::slotRightClick(TQListViewItem *item) { if ( !item ) return; // create the menu TDEPopupMenu 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(TQCursor::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(TQListViewItem *item) { if ( !item ) return; TQString dirName = item->text(0); TQString fileName; if( !TQDir( dirName ).exists() ) { fileName = dirName.mid( dirName.findRev( '/' ) + 1 ); dirName.truncate( dirName.findRev( '/' ) ); } ACTIVE_FUNC->openUrl(vfs::fromPathOrURL( dirName ), fileName ); KDialogBase::accept(); } void LocateDlg::keyPressEvent( TQKeyEvent *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; } TQDialog::keyPressEvent( e ); } void LocateDlg::operate( TQListViewItem *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); TQStringList list = krConfig->readListEntry("Find Patterns"); KFindDialog dlg( this, "locateFindDialog", options, list ); if ( dlg.exec() != TQDialog::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 = (TDEListViewItem *)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 = (TDEListViewItem *)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; TQListViewItem * 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" ), TQPoint( -7, 0 ) ); TQApplication::clipboard()->setData( d ); } break; } } void LocateDlg::nextLine() { if( findOptions & KFindDialog::FindBackwards ) findCurrentItem = (TDEListViewItem *)findCurrentItem->itemAbove(); else findCurrentItem = (TDEListViewItem *)findCurrentItem->itemBelow(); } bool LocateDlg::find() { while( findCurrentItem ) { TQString item = findCurrentItem->text( 0 ); if( findOptions & KFindDialog::RegularExpression ) { if( item.contains( TQRegExp( 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 ); TQString queryName; do { queryName = i18n("Locate 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 = resultList->firstChild(); while( item ) { urlList.push_back( vfs::fromPathOrURL( item->text( 0 ) ) ); 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()); accept(); } void LocateDlg::reset() { locateSearchFor->lineEdit()->setFocus(); locateSearchFor->lineEdit()->selectAll(); } #include "locate.moc"