kio Library API Documentation

kdiroperator.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999,2000 Stephan Kulow <coolo@kde.org> 00003 1999,2000,2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <unistd.h> 00022 00023 #include <qdir.h> 00024 #include <qapplication.h> 00025 #include <qdialog.h> 00026 #include <qlabel.h> 00027 #include <qlayout.h> 00028 #include <qpushbutton.h> 00029 #include <qpopupmenu.h> 00030 #include <qregexp.h> 00031 #include <qtimer.h> 00032 #include <qvbox.h> 00033 00034 #include <kaction.h> 00035 #include <kapplication.h> 00036 #include <kdebug.h> 00037 #include <kdialog.h> 00038 #include <kdialogbase.h> 00039 #include <kdirlister.h> 00040 #include <kinputdialog.h> 00041 #include <klocale.h> 00042 #include <kmessagebox.h> 00043 #include <kpopupmenu.h> 00044 #include <kprogress.h> 00045 #include <kstdaction.h> 00046 #include <kio/job.h> 00047 #include <kio/jobclasses.h> 00048 #include <kio/netaccess.h> 00049 #include <kio/previewjob.h> 00050 #include <kpropertiesdialog.h> 00051 #include <kservicetypefactory.h> 00052 #include <kstdaccel.h> 00053 00054 #include "config-kfile.h" 00055 #include "kcombiview.h" 00056 #include "kdiroperator.h" 00057 #include "kfiledetailview.h" 00058 #include "kfileiconview.h" 00059 #include "kfilepreview.h" 00060 #include "kfileview.h" 00061 #include "kfileitem.h" 00062 #include "kfilemetapreview.h" 00063 00064 00065 template class QPtrStack<KURL>; 00066 template class QDict<KFileItem>; 00067 00068 00069 class KDirOperator::KDirOperatorPrivate 00070 { 00071 public: 00072 KDirOperatorPrivate() { 00073 onlyDoubleClickSelectsFiles = false; 00074 progressDelayTimer = 0L; 00075 dirHighlighting = false; 00076 config = 0L; 00077 dropOptions = 0; 00078 } 00079 00080 ~KDirOperatorPrivate() { 00081 delete progressDelayTimer; 00082 } 00083 00084 bool dirHighlighting; 00085 QString lastURL; // used for highlighting a directory on cdUp 00086 bool onlyDoubleClickSelectsFiles; 00087 QTimer *progressDelayTimer; 00088 KActionSeparator *viewActionSeparator; 00089 int dropOptions; 00090 00091 KConfig *config; 00092 QString configGroup; 00093 }; 00094 00095 KDirOperator::KDirOperator(const KURL& _url, 00096 QWidget *parent, const char* _name) 00097 : QWidget(parent, _name), 00098 dir(0), 00099 m_fileView(0), 00100 progress(0) 00101 { 00102 myPreview = 0L; 00103 myMode = KFile::File; 00104 m_viewKind = KFile::Simple; 00105 mySorting = static_cast<QDir::SortSpec>(QDir::Name | QDir::DirsFirst); 00106 d = new KDirOperatorPrivate; 00107 00108 if (_url.isEmpty()) { // no dir specified -> current dir 00109 QString strPath = QDir::currentDirPath(); 00110 strPath.append('/'); 00111 currUrl = KURL(); 00112 currUrl.setProtocol(QString::fromLatin1("file")); 00113 currUrl.setPath(strPath); 00114 } 00115 else { 00116 currUrl = _url; 00117 if ( currUrl.protocol().isEmpty() ) 00118 currUrl.setProtocol(QString::fromLatin1("file")); 00119 00120 currUrl.addPath("/"); // make sure we have a trailing slash! 00121 } 00122 00123 setDirLister( new KDirLister( true ) ); 00124 00125 connect(&myCompletion, SIGNAL(match(const QString&)), 00126 SLOT(slotCompletionMatch(const QString&))); 00127 00128 progress = new KProgress(this, "progress"); 00129 progress->adjustSize(); 00130 progress->move(2, height() - progress->height() -2); 00131 00132 d->progressDelayTimer = new QTimer( this, "progress delay timer" ); 00133 connect( d->progressDelayTimer, SIGNAL( timeout() ), 00134 SLOT( slotShowProgress() )); 00135 00136 myCompleteListDirty = false; 00137 00138 backStack.setAutoDelete( true ); 00139 forwardStack.setAutoDelete( true ); 00140 00141 // action stuff 00142 setupActions(); 00143 setupMenu(); 00144 00145 setFocusPolicy(QWidget::WheelFocus); 00146 } 00147 00148 KDirOperator::~KDirOperator() 00149 { 00150 resetCursor(); 00151 if ( m_fileView ) 00152 { 00153 if ( d->config ) 00154 m_fileView->writeConfig( d->config, d->configGroup ); 00155 00156 delete m_fileView; 00157 m_fileView = 0L; 00158 } 00159 00160 delete myPreview; 00161 delete dir; 00162 delete d; 00163 } 00164 00165 00166 void KDirOperator::setSorting( QDir::SortSpec spec ) 00167 { 00168 if ( m_fileView ) 00169 m_fileView->setSorting( spec ); 00170 mySorting = spec; 00171 updateSortActions(); 00172 } 00173 00174 void KDirOperator::resetCursor() 00175 { 00176 QApplication::restoreOverrideCursor(); 00177 progress->hide(); 00178 } 00179 00180 void KDirOperator::insertViewDependentActions() 00181 { 00182 // If we have a new view actionCollection(), insert its actions 00183 // into viewActionMenu. 00184 00185 if( !m_fileView ) 00186 return; 00187 00188 if ( (viewActionMenu->popupMenu()->count() == 0) || // Not yet initialized or... 00189 (viewActionCollection != m_fileView->actionCollection()) ) // ...changed since. 00190 { 00191 if (viewActionCollection) 00192 { 00193 disconnect( viewActionCollection, SIGNAL( inserted( KAction * )), 00194 this, SLOT( slotViewActionAdded( KAction * ))); 00195 disconnect( viewActionCollection, SIGNAL( removed( KAction * )), 00196 this, SLOT( slotViewActionRemoved( KAction * ))); 00197 } 00198 00199 viewActionMenu->popupMenu()->clear(); 00200 // viewActionMenu->insert( shortAction ); 00201 // viewActionMenu->insert( detailedAction ); 00202 // viewActionMenu->insert( actionSeparator ); 00203 viewActionMenu->insert( myActionCollection->action( "short view" ) ); 00204 viewActionMenu->insert( myActionCollection->action( "detailed view" ) ); 00205 viewActionMenu->insert( actionSeparator ); 00206 viewActionMenu->insert( showHiddenAction ); 00207 // viewActionMenu->insert( myActionCollection->action( "single" )); 00208 viewActionMenu->insert( separateDirsAction ); 00209 // Warning: adjust slotViewActionAdded() and slotViewActionRemoved() 00210 // when you add/remove actions here! 00211 00212 viewActionCollection = m_fileView->actionCollection(); 00213 if (!viewActionCollection) 00214 return; 00215 00216 if ( !viewActionCollection->isEmpty() ) 00217 { 00218 viewActionMenu->insert( d->viewActionSeparator ); 00219 00220 // first insert the normal actions, then the grouped ones 00221 QStringList groups = viewActionCollection->groups(); 00222 groups.prepend( QString::null ); // actions without group 00223 QStringList::ConstIterator git = groups.begin(); 00224 KActionPtrList list; 00225 KAction *sep = actionCollection()->action("separator"); 00226 for ( ; git != groups.end(); ++git ) 00227 { 00228 if ( git != groups.begin() ) 00229 viewActionMenu->insert( sep ); 00230 00231 list = viewActionCollection->actions( *git ); 00232 KActionPtrList::ConstIterator it = list.begin(); 00233 for ( ; it != list.end(); ++it ) 00234 viewActionMenu->insert( *it ); 00235 } 00236 } 00237 00238 connect( viewActionCollection, SIGNAL( inserted( KAction * )), 00239 SLOT( slotViewActionAdded( KAction * ))); 00240 connect( viewActionCollection, SIGNAL( removed( KAction * )), 00241 SLOT( slotViewActionRemoved( KAction * ))); 00242 } 00243 } 00244 00245 void KDirOperator::activatedMenu( const KFileItem *, const QPoint& pos ) 00246 { 00247 updateSelectionDependentActions(); 00248 00249 actionMenu->popup( pos ); 00250 } 00251 00252 void KDirOperator::updateSelectionDependentActions() 00253 { 00254 bool hasSelection = m_fileView && m_fileView->selectedItems() && 00255 !m_fileView->selectedItems()->isEmpty(); 00256 myActionCollection->action( "delete" )->setEnabled( hasSelection ); 00257 myActionCollection->action( "properties" )->setEnabled( hasSelection ); 00258 } 00259 00260 void KDirOperator::setPreviewWidget(const QWidget *w) 00261 { 00262 if(w != 0L) 00263 m_viewKind = (m_viewKind | KFile::PreviewContents); 00264 else 00265 m_viewKind = (m_viewKind & ~KFile::PreviewContents); 00266 00267 delete myPreview; 00268 myPreview = w; 00269 00270 KToggleAction *preview = static_cast<KToggleAction*>(myActionCollection->action("preview")); 00271 preview->setEnabled( w != 0L ); 00272 preview->setChecked( w != 0L ); 00273 setView( static_cast<KFile::FileView>(m_viewKind) ); 00274 } 00275 00276 int KDirOperator::numDirs() const 00277 { 00278 return m_fileView ? m_fileView->numDirs() : 0; 00279 } 00280 00281 int KDirOperator::numFiles() const 00282 { 00283 return m_fileView ? m_fileView->numFiles() : 0; 00284 } 00285 00286 void KDirOperator::slotDetailedView() 00287 { 00288 KFile::FileView view = static_cast<KFile::FileView>( (m_viewKind & ~KFile::Simple) | KFile::Detail ); 00289 setView( view ); 00290 } 00291 00292 void KDirOperator::slotSimpleView() 00293 { 00294 KFile::FileView view = static_cast<KFile::FileView>( (m_viewKind & ~KFile::Detail) | KFile::Simple ); 00295 setView( view ); 00296 } 00297 00298 void KDirOperator::slotToggleHidden( bool show ) 00299 { 00300 dir->setShowingDotFiles( show ); 00301 updateDir(); 00302 if ( m_fileView ) 00303 m_fileView->listingCompleted(); 00304 } 00305 00306 void KDirOperator::slotSeparateDirs() 00307 { 00308 if (separateDirsAction->isChecked()) 00309 { 00310 KFile::FileView view = static_cast<KFile::FileView>( m_viewKind | KFile::SeparateDirs ); 00311 setView( view ); 00312 } 00313 else 00314 { 00315 KFile::FileView view = static_cast<KFile::FileView>( m_viewKind & ~KFile::SeparateDirs ); 00316 setView( view ); 00317 } 00318 } 00319 00320 void KDirOperator::slotDefaultPreview() 00321 { 00322 m_viewKind = m_viewKind | KFile::PreviewContents; 00323 if ( !myPreview ) { 00324 myPreview = new KFileMetaPreview( this ); 00325 (static_cast<KToggleAction*>( myActionCollection->action("preview") ))->setChecked(true); 00326 } 00327 00328 setView( static_cast<KFile::FileView>(m_viewKind) ); 00329 } 00330 00331 void KDirOperator::slotSortByName() 00332 { 00333 int sorting = (m_fileView->sorting()) & ~QDir::SortByMask; 00334 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Name )); 00335 mySorting = m_fileView->sorting(); 00336 caseInsensitiveAction->setEnabled( true ); 00337 } 00338 00339 void KDirOperator::slotSortBySize() 00340 { 00341 int sorting = (m_fileView->sorting()) & ~QDir::SortByMask; 00342 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Size )); 00343 mySorting = m_fileView->sorting(); 00344 caseInsensitiveAction->setEnabled( false ); 00345 } 00346 00347 void KDirOperator::slotSortByDate() 00348 { 00349 int sorting = (m_fileView->sorting()) & ~QDir::SortByMask; 00350 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Time )); 00351 mySorting = m_fileView->sorting(); 00352 caseInsensitiveAction->setEnabled( false ); 00353 } 00354 00355 void KDirOperator::slotSortReversed() 00356 { 00357 if ( m_fileView ) 00358 m_fileView->sortReversed(); 00359 } 00360 00361 void KDirOperator::slotToggleDirsFirst() 00362 { 00363 QDir::SortSpec sorting = m_fileView->sorting(); 00364 if ( !KFile::isSortDirsFirst( sorting ) ) 00365 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::DirsFirst )); 00366 else 00367 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::DirsFirst)); 00368 mySorting = m_fileView->sorting(); 00369 } 00370 00371 void KDirOperator::slotToggleIgnoreCase() 00372 { 00373 QDir::SortSpec sorting = m_fileView->sorting(); 00374 if ( !KFile::isSortCaseInsensitive( sorting ) ) 00375 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::IgnoreCase )); 00376 else 00377 m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::IgnoreCase)); 00378 mySorting = m_fileView->sorting(); 00379 } 00380 00381 void KDirOperator::mkdir() 00382 { 00383 bool ok; 00384 QString where = url().isLocalFile() ? url().path(+1) : url().prettyURL(); 00385 QString dir = KInputDialog::getText( i18n( "New Folder" ), 00386 i18n( "Create new folder in:\n%1" ).arg( where ), 00387 i18n("New Folder"), &ok, this); 00388 if (ok) 00389 mkdir( dir, true ); 00390 } 00391 00392 bool KDirOperator::mkdir( const QString& directory, bool enterDirectory ) 00393 { 00394 // Creates "directory", relative to the current directory (currUrl). 00395 // The given path may contain any number directories, existant or not. 00396 // They will all be created, if possible. 00397 00398 bool writeOk = false; 00399 bool exists = false; 00400 KURL url( currUrl ); 00401 00402 QStringList dirs = QStringList::split( QDir::separator(), directory ); 00403 QStringList::ConstIterator it = dirs.begin(); 00404 00405 for ( ; it != dirs.end(); ++it ) 00406 { 00407 url.addPath( *it ); 00408 exists = KIO::NetAccess::exists( url, false, 0 ); 00409 writeOk = !exists && KIO::NetAccess::mkdir( url, topLevelWidget() ); 00410 } 00411 00412 if ( exists ) // url was already existant 00413 { 00414 QString which = url.isLocalFile() ? url.path() : url.prettyURL(); 00415 KMessageBox::sorry(viewWidget(), i18n("A file or folder named %1 already exists.").arg(which)); 00416 enterDirectory = false; 00417 } 00418 else if ( !writeOk ) { 00419 KMessageBox::sorry(viewWidget(), i18n("You don't have permission to " 00420 "create that folder." )); 00421 } 00422 else if ( enterDirectory ) { 00423 setURL( url, true ); 00424 } 00425 00426 return writeOk; 00427 } 00428 00429 KIO::DeleteJob * KDirOperator::del( const KFileItemList& items, 00430 bool ask, bool showProgress ) 00431 { 00432 return del( items, this, ask, showProgress ); 00433 } 00434 00435 KIO::DeleteJob * KDirOperator::del( const KFileItemList& items, 00436 QWidget *parent, 00437 bool ask, bool showProgress ) 00438 { 00439 if ( items.isEmpty() ) { 00440 KMessageBox::information( parent, 00441 i18n("You didn't select a file to delete."), 00442 i18n("Nothing to Delete") ); 00443 return 0L; 00444 } 00445 00446 KURL::List urls; 00447 QStringList files; 00448 KFileItemListIterator it( items ); 00449 00450 for ( ; it.current(); ++it ) { 00451 KURL url = (*it)->url(); 00452 urls.append( url ); 00453 if ( url.isLocalFile() ) 00454 files.append( url.path() ); 00455 else 00456 files.append( url.prettyURL() ); 00457 } 00458 00459 bool doIt = !ask; 00460 if ( ask ) { 00461 int ret; 00462 if ( items.count() == 1 ) { 00463 ret = KMessageBox::warningContinueCancel( parent, 00464 i18n( "<qt>Do you really want to delete\n <b>'%1'</b>?</qt>" ) 00465 .arg( files.first() ), 00466 i18n("Delete File"), 00467 KGuiItem(i18n("Delete"),"editdelete"), "AskForDelete" ); 00468 } 00469 else 00470 ret = KMessageBox::warningContinueCancelList( parent, 00471 i18n("translators: not called for n == 1", "Do you really want to delete these %n items?", items.count() ), 00472 files, 00473 i18n("Delete Files"), 00474 KGuiItem(i18n("Delete"), "editdelete"), "AskForDelete" ); 00475 doIt = (ret == KMessageBox::Continue); 00476 } 00477 00478 if ( doIt ) { 00479 KIO::DeleteJob *job = KIO::del( urls, false, showProgress ); 00480 job->setWindow (topLevelWidget()); 00481 job->setAutoErrorHandlingEnabled( true, parent ); 00482 return job; 00483 } 00484 00485 return 0L; 00486 } 00487 00488 void KDirOperator::deleteSelected() 00489 { 00490 if ( !m_fileView ) 00491 return; 00492 00493 const KFileItemList *list = m_fileView->selectedItems(); 00494 if ( list ) 00495 del( *list ); 00496 } 00497 00498 void KDirOperator::close() 00499 { 00500 resetCursor(); 00501 pendingMimeTypes.clear(); 00502 myCompletion.clear(); 00503 myDirCompletion.clear(); 00504 myCompleteListDirty = true; 00505 dir->stop(); 00506 } 00507 00508 void KDirOperator::checkPath(const QString &, bool /*takeFiles*/) // SLOT 00509 { 00510 #if 0 00511 // copy the argument in a temporary string 00512 QString text = _txt; 00513 // it's unlikely to happen, that at the beginning are spaces, but 00514 // for the end, it happens quite often, I guess. 00515 text = text.stripWhiteSpace(); 00516 // if the argument is no URL (the check is quite fragil) and it's 00517 // no absolute path, we add the current directory to get a correct url 00518 if (text.find(':') < 0 && text[0] != '/') 00519 text.insert(0, currUrl); 00520 00521 // in case we have a selection defined and someone patched the file- 00522 // name, we check, if the end of the new name is changed. 00523 if (!selection.isNull()) { 00524 int position = text.findRev('/'); 00525 ASSERT(position >= 0); // we already inserted the current dir in case 00526 QString filename = text.mid(position + 1, text.length()); 00527 if (filename != selection) 00528 selection = QString::null; 00529 } 00530 00531 KURL u(text); // I have to take care of entered URLs 00532 bool filenameEntered = false; 00533 00534 if (u.isLocalFile()) { 00535 // the empty path is kind of a hack 00536 KFileItem i("", u.path()); 00537 if (i.isDir()) 00538 setURL(text, true); 00539 else { 00540 if (takeFiles) 00541 if (acceptOnlyExisting && !i.isFile()) 00542 warning("you entered an invalid URL"); 00543 else 00544 filenameEntered = true; 00545 } 00546 } else 00547 setURL(text, true); 00548 00549 if (filenameEntered) { 00550 filename_ = u.url(); 00551 emit fileSelected(filename_); 00552 00553 QApplication::restoreOverrideCursor(); 00554 00555 accept(); 00556 } 00557 #endif 00558 kdDebug(kfile_area) << "TODO KDirOperator::checkPath()" << endl; 00559 } 00560 00561 void KDirOperator::setURL(const KURL& _newurl, bool clearforward) 00562 { 00563 KURL newurl; 00564 00565 if ( !_newurl.isValid() ) 00566 newurl.setPath( QDir::homeDirPath() ); 00567 else 00568 newurl = _newurl; 00569 00570 QString pathstr = newurl.path(+1); 00571 newurl.setPath(pathstr); 00572 00573 // already set 00574 if ( newurl.equals( currUrl, true ) ) 00575 return; 00576 00577 if ( !isReadable( newurl ) ) { 00578 // maybe newurl is a file? check its parent directory 00579 newurl.cd(QString::fromLatin1("..")); 00580 if ( !isReadable( newurl ) ) { 00581 resetCursor(); 00582 KMessageBox::error(viewWidget(), 00583 i18n("The specified folder does not exist " 00584 "or was not readable.")); 00585 return; 00586 } 00587 } 00588 00589 if (clearforward) { 00590 // autodelete should remove this one 00591 backStack.push(new KURL(currUrl)); 00592 forwardStack.clear(); 00593 } 00594 00595 d->lastURL = currUrl.url(-1); 00596 currUrl = newurl; 00597 00598 pathChanged(); 00599 emit urlEntered(newurl); 00600 00601 // enable/disable actions 00602 forwardAction->setEnabled( !forwardStack.isEmpty() ); 00603 backAction->setEnabled( !backStack.isEmpty() ); 00604 upAction->setEnabled( !isRoot() ); 00605 00606 dir->openURL( newurl ); 00607 } 00608 00609 void KDirOperator::updateDir() 00610 { 00611 dir->emitChanges(); 00612 if ( m_fileView ) 00613 m_fileView->listingCompleted(); 00614 } 00615 00616 void KDirOperator::rereadDir() 00617 { 00618 pathChanged(); 00619 dir->openURL( currUrl, false, true ); 00620 } 00621 00622 // Protected 00623 void KDirOperator::pathChanged() 00624 { 00625 if (!m_fileView) 00626 return; 00627 00628 pendingMimeTypes.clear(); 00629 m_fileView->clear(); 00630 myCompletion.clear(); 00631 myDirCompletion.clear(); 00632 00633 // it may be, that we weren't ready at this time 00634 QApplication::restoreOverrideCursor(); 00635 00636 // when KIO::Job emits finished, the slot will restore the cursor 00637 QApplication::setOverrideCursor( waitCursor ); 00638 00639 if ( !isReadable( currUrl )) { 00640 KMessageBox::error(viewWidget(), 00641 i18n("The specified folder does not exist " 00642 "or was not readable.")); 00643 if (backStack.isEmpty()) 00644 home(); 00645 else 00646 back(); 00647 } 00648 } 00649 00650 void KDirOperator::slotRedirected( const KURL& newURL ) 00651 { 00652 currUrl = newURL; 00653 pendingMimeTypes.clear(); 00654 myCompletion.clear(); 00655 myDirCompletion.clear(); 00656 myCompleteListDirty = true; 00657 emit urlEntered( newURL ); 00658 } 00659 00660 // Code pinched from kfm then hacked 00661 void KDirOperator::back() 00662 { 00663 if ( backStack.isEmpty() ) 00664 return; 00665 00666 forwardStack.push( new KURL(currUrl) ); 00667 00668 KURL *s = backStack.pop(); 00669 00670 setURL(*s, false); 00671 delete s; 00672 } 00673 00674 // Code pinched from kfm then hacked 00675 void KDirOperator::forward() 00676 { 00677 if ( forwardStack.isEmpty() ) 00678 return; 00679 00680 backStack.push(new KURL(currUrl)); 00681 00682 KURL *s = forwardStack.pop(); 00683 setURL(*s, false); 00684 delete s; 00685 } 00686 00687 KURL KDirOperator::url() const 00688 { 00689 return currUrl; 00690 } 00691 00692 void KDirOperator::cdUp() 00693 { 00694 KURL tmp( currUrl ); 00695 tmp.cd(QString::fromLatin1("..")); 00696 setURL(tmp, true); 00697 } 00698 00699 void KDirOperator::home() 00700 { 00701 setURL(QDir::homeDirPath(), true); 00702 } 00703 00704 void KDirOperator::clearFilter() 00705 { 00706 dir->setNameFilter( QString::null ); 00707 dir->clearMimeFilter(); 00708 checkPreviewSupport(); 00709 } 00710 00711 void KDirOperator::setNameFilter(const QString& filter) 00712 { 00713 dir->setNameFilter(filter); 00714 checkPreviewSupport(); 00715 } 00716 00717 void KDirOperator::setMimeFilter( const QStringList& mimetypes ) 00718 { 00719 dir->setMimeFilter( mimetypes ); 00720 checkPreviewSupport(); 00721 } 00722 00723 bool KDirOperator::checkPreviewSupport() 00724 { 00725 KToggleAction *previewAction = static_cast<KToggleAction*>( myActionCollection->action( "preview" )); 00726 00727 bool hasPreviewSupport = false; 00728 KConfig *kc = KGlobal::config(); 00729 KConfigGroupSaver cs( kc, ConfigGroup ); 00730 if ( kc->readBoolEntry( "Show Default Preview", true ) ) 00731 hasPreviewSupport = checkPreviewInternal(); 00732 00733 previewAction->setEnabled( hasPreviewSupport ); 00734 return hasPreviewSupport; 00735 } 00736 00737 bool KDirOperator::checkPreviewInternal() const 00738 { 00739 QStringList supported = KIO::PreviewJob::supportedMimeTypes(); 00740 // no preview support for directories? 00741 if ( dirOnlyMode() && supported.findIndex( "inode/directory" ) == -1 ) 00742 return false; 00743 00744 QStringList mimeTypes = dir->mimeFilters(); 00745 QStringList nameFilter = QStringList::split( " ", dir->nameFilter() ); 00746 00747 if ( mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty() ) 00748 return true; 00749 else { 00750 QRegExp r; 00751 r.setWildcard( true ); // the "mimetype" can be "image/*" 00752 00753 if ( !mimeTypes.isEmpty() ) { 00754 QStringList::Iterator it = supported.begin(); 00755 00756 for ( ; it != supported.end(); ++it ) { 00757 r.setPattern( *it ); 00758 00759 QStringList result = mimeTypes.grep( r ); 00760 if ( !result.isEmpty() ) { // matches! -> we want previews 00761 return true; 00762 } 00763 } 00764 } 00765 00766 if ( !nameFilter.isEmpty() ) { 00767 // find the mimetypes of all the filter-patterns and 00768 KServiceTypeFactory *fac = KServiceTypeFactory::self(); 00769 QStringList::Iterator it1 = nameFilter.begin(); 00770 for ( ; it1 != nameFilter.end(); ++it1 ) { 00771 if ( (*it1) == "*" ) { 00772 return true; 00773 } 00774 00775 KMimeType *mt = fac->findFromPattern( *it1 ); 00776 if ( !mt ) 00777 continue; 00778 QString mime = mt->name(); 00779 delete mt; 00780 00781 // the "mimetypes" we get from the PreviewJob can be "image/*" 00782 // so we need to check in wildcard mode 00783 QStringList::Iterator it2 = supported.begin(); 00784 for ( ; it2 != supported.end(); ++it2 ) { 00785 r.setPattern( *it2 ); 00786 if ( r.search( mime ) != -1 ) { 00787 return true; 00788 } 00789 } 00790 } 00791 } 00792 } 00793 00794 return false; 00795 } 00796 00797 KFileView* KDirOperator::createView( QWidget* parent, KFile::FileView view ) 00798 { 00799 KFileView* new_view = 0L; 00800 bool separateDirs = KFile::isSeparateDirs( view ); 00801 bool preview = ( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) ); 00802 00803 if ( separateDirs || preview ) { 00804 KCombiView *combi = 0L; 00805 if (separateDirs) 00806 { 00807 combi = new KCombiView( parent, "combi view" ); 00808 combi->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); 00809 } 00810 00811 KFileView* v = 0L; 00812 if ( KFile::isSimpleView( view ) ) 00813 v = createView( combi, KFile::Simple ); 00814 else 00815 v = createView( combi, KFile::Detail ); 00816 00817 v->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); 00818 00819 if (combi) 00820 combi->setRight( v ); 00821 00822 if (preview) 00823 { 00824 KFilePreview* pView = new KFilePreview( combi ? combi : v, parent, "preview" ); 00825 pView->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); 00826 new_view = pView; 00827 } 00828 else 00829 new_view = combi; 00830 } 00831 else if ( KFile::isDetailView( view ) && !preview ) { 00832 new_view = new KFileDetailView( parent, "detail view"); 00833 new_view->setViewName( i18n("Detailed View") ); 00834 } 00835 else /* if ( KFile::isSimpleView( view ) && !preview ) */ { 00836 KFileIconView *iconView = new KFileIconView( parent, "simple view"); 00837 new_view = iconView; 00838 new_view->setViewName( i18n("Short View") ); 00839 } 00840 00841 new_view->widget()->setAcceptDrops(acceptDrops()); 00842 return new_view; 00843 } 00844 00845 void KDirOperator::setAcceptDrops(bool b) 00846 { 00847 if (m_fileView) 00848 m_fileView->widget()->setAcceptDrops(b); 00849 QWidget::setAcceptDrops(b); 00850 } 00851 00852 void KDirOperator::setDropOptions(int options) 00853 { 00854 d->dropOptions = options; 00855 if (m_fileView) 00856 m_fileView->setDropOptions(options); 00857 } 00858 00859 void KDirOperator::setView( KFile::FileView view ) 00860 { 00861 bool separateDirs = KFile::isSeparateDirs( view ); 00862 bool preview=( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) ); 00863 00864 if (view == KFile::Default) { 00865 if ( KFile::isDetailView( (KFile::FileView) defaultView ) ) 00866 view = KFile::Detail; 00867 else 00868 view = KFile::Simple; 00869 00870 separateDirs = KFile::isSeparateDirs( static_cast<KFile::FileView>(defaultView) ); 00871 preview = ( KFile::isPreviewInfo( static_cast<KFile::FileView>(defaultView) ) || 00872 KFile::isPreviewContents( static_cast<KFile::FileView>(defaultView) ) ) 00873 && myActionCollection->action("preview")->isEnabled(); 00874 00875 if ( preview ) { // instantiates KFileMetaPreview and calls setView() 00876 m_viewKind = defaultView; 00877 slotDefaultPreview(); 00878 return; 00879 } 00880 else if ( !separateDirs ) 00881 separateDirsAction->setChecked(true); 00882 } 00883 00884 // if we don't have any files, we can't separate dirs from files :) 00885 if ( (mode() & KFile::File) == 0 && 00886 (mode() & KFile::Files) == 0 ) { 00887 separateDirs = false; 00888 separateDirsAction->setEnabled( false ); 00889 } 00890 00891 m_viewKind = static_cast<int>(view) | (separateDirs ? KFile::SeparateDirs : 0); 00892 view = static_cast<KFile::FileView>(m_viewKind); 00893 00894 KFileView *new_view = createView( this, view ); 00895 if ( preview ) { 00896 // we keep the preview-_widget_ around, but not the KFilePreview. 00897 // KFilePreview::setPreviewWidget handles the reparenting for us 00898 static_cast<KFilePreview*>(new_view)->setPreviewWidget(myPreview, url()); 00899 } 00900 00901 setView( new_view ); 00902 } 00903 00904 00905 void KDirOperator::connectView(KFileView *view) 00906 { 00907 // TODO: do a real timer and restart it after that 00908 pendingMimeTypes.clear(); 00909 bool listDir = true; 00910 00911 if ( dirOnlyMode() ) 00912 view->setViewMode(KFileView::Directories); 00913 else 00914 view->setViewMode(KFileView::All); 00915 00916 if ( myMode & KFile::Files ) 00917 view->setSelectionMode( KFile::Extended ); 00918 else 00919 view->setSelectionMode( KFile::Single ); 00920 00921 if (m_fileView) 00922 { 00923 if ( d->config ) // save and restore the views' configuration 00924 { 00925 m_fileView->writeConfig( d->config, d->configGroup ); 00926 view->readConfig( d->config, d->configGroup ); 00927 } 00928 00929 // transfer the state from old view to new view 00930 view->clear(); 00931 view->addItemList( *m_fileView->items() ); 00932 listDir = false; 00933 00934 if ( m_fileView->widget()->hasFocus() ) 00935 view->widget()->setFocus(); 00936 00937 KFileItem *oldCurrentItem = m_fileView->currentFileItem(); 00938 if ( oldCurrentItem ) { 00939 view->setCurrentItem( oldCurrentItem ); 00940 view->setSelected( oldCurrentItem, false ); 00941 view->ensureItemVisible( oldCurrentItem ); 00942 } 00943 00944 const KFileItemList *oldSelected = m_fileView->selectedItems(); 00945 if ( !oldSelected->isEmpty() ) { 00946 KFileItemListIterator it( *oldSelected ); 00947 for ( ; it.current(); ++it ) 00948 view->setSelected( it.current(), true ); 00949 } 00950 00951 m_fileView->widget()->hide(); 00952 delete m_fileView; 00953 } 00954 00955 else 00956 { 00957 if ( d->config ) 00958 view->readConfig( d->config, d->configGroup ); 00959 } 00960 00961 m_fileView = view; 00962 m_fileView->setDropOptions(d->dropOptions); 00963 viewActionCollection = 0L; 00964 KFileViewSignaler *sig = view->signaler(); 00965 00966 connect(sig, SIGNAL( activatedMenu(const KFileItem *, const QPoint& ) ), 00967 this, SLOT( activatedMenu(const KFileItem *, const QPoint& ))); 00968 connect(sig, SIGNAL( dirActivated(const KFileItem *) ), 00969 this, SLOT( selectDir(const KFileItem*) ) ); 00970 connect(sig, SIGNAL( fileSelected(const KFileItem *) ), 00971 this, SLOT( selectFile(const KFileItem*) ) ); 00972 connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ), 00973 this, SLOT( highlightFile(const KFileItem*) )); 00974 connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ), 00975 this, SLOT( slotViewSortingChanged( QDir::SortSpec ))); 00976 connect(sig, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&) ), 00977 this, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&)) ); 00978 00979 if ( reverseAction->isChecked() != m_fileView->isReversed() ) 00980 slotSortReversed(); 00981 00982 updateViewActions(); 00983 m_fileView->widget()->resize(size()); 00984 m_fileView->widget()->show(); 00985 00986 if ( listDir ) { 00987 QApplication::setOverrideCursor( waitCursor ); 00988 dir->openURL( currUrl ); 00989 } 00990 else 00991 view->listingCompleted(); 00992 } 00993 00994 KFile::Mode KDirOperator::mode() const 00995 { 00996 return myMode; 00997 } 00998 00999 void KDirOperator::setMode(KFile::Mode m) 01000 { 01001 if (myMode == m) 01002 return; 01003 01004 myMode = m; 01005 01006 dir->setDirOnlyMode( dirOnlyMode() ); 01007 01008 // reset the view with the different mode 01009 setView( static_cast<KFile::FileView>(m_viewKind) ); 01010 } 01011 01012 void KDirOperator::setView(KFileView *view) 01013 { 01014 if ( view == m_fileView ) { 01015 return; 01016 } 01017 01018 setFocusProxy(view->widget()); 01019 view->setSorting( mySorting ); 01020 view->setOnlyDoubleClickSelectsFiles( d->onlyDoubleClickSelectsFiles ); 01021 connectView(view); // also deletes the old view 01022 01023 emit viewChanged( view ); 01024 } 01025 01026 void KDirOperator::setDirLister( KDirLister *lister ) 01027 { 01028 if ( lister == dir ) // sanity check 01029 return; 01030 01031 delete dir; 01032 dir = lister; 01033 01034 dir->setAutoUpdate( true ); 01035 01036 QWidget* mainWidget = topLevelWidget(); 01037 dir->setMainWindow (mainWidget); 01038 kdDebug (kfile_area) << "mainWidget=" << mainWidget << endl; 01039 01040 connect( dir, SIGNAL( percent( int )), 01041 SLOT( slotProgress( int ) )); 01042 connect( dir, SIGNAL(started( const KURL& )), SLOT(slotStarted())); 01043 connect( dir, SIGNAL(newItems(const KFileItemList &)), 01044 SLOT(insertNewFiles(const KFileItemList &))); 01045 connect( dir, SIGNAL(completed()), SLOT(slotIOFinished())); 01046 connect( dir, SIGNAL(canceled()), SLOT(slotCanceled())); 01047 connect( dir, SIGNAL(deleteItem(KFileItem *)), 01048 SLOT(itemDeleted(KFileItem *))); 01049 connect( dir, SIGNAL(redirection( const KURL& )), 01050 SLOT( slotRedirected( const KURL& ))); 01051 connect( dir, SIGNAL( clear() ), SLOT( slotClearView() )); 01052 connect( dir, SIGNAL( refreshItems( const KFileItemList& ) ), 01053 SLOT( slotRefreshItems( const KFileItemList& ) ) ); 01054 } 01055 01056 void KDirOperator::insertNewFiles(const KFileItemList &newone) 01057 { 01058 if ( newone.isEmpty() || !m_fileView ) 01059 return; 01060 01061 myCompleteListDirty = true; 01062 m_fileView->addItemList( newone ); 01063 emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles()); 01064 01065 KFileItem *item; 01066 KFileItemListIterator it( newone ); 01067 01068 while ( (item = it.current()) ) { 01069 // highlight the dir we come from, if possible 01070 if ( d->dirHighlighting && item->isDir() && 01071 item->url().url(-1) == d->lastURL ) { 01072 m_fileView->setCurrentItem( item ); 01073 m_fileView->ensureItemVisible( item ); 01074 } 01075 01076 ++it; 01077 } 01078 01079 QTimer::singleShot(200, this, SLOT(resetCursor())); 01080 } 01081 01082 void KDirOperator::selectDir(const KFileItem *item) 01083 { 01084 setURL(item->url(), true); 01085 } 01086 01087 void KDirOperator::itemDeleted(KFileItem *item) 01088 { 01089 pendingMimeTypes.removeRef( item ); 01090 if ( m_fileView ) 01091 { 01092 m_fileView->removeItem( static_cast<KFileItem *>( item )); 01093 emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles()); 01094 } 01095 } 01096 01097 void KDirOperator::selectFile(const KFileItem *item) 01098 { 01099 QApplication::restoreOverrideCursor(); 01100 01101 emit fileSelected( item ); 01102 } 01103 01104 void KDirOperator::setCurrentItem( const QString& filename ) 01105 { 01106 if ( m_fileView ) { 01107 const KFileItem *item = 0L; 01108 01109 if ( !filename.isNull() ) 01110 item = static_cast<KFileItem *>(dir->findByName( filename )); 01111 01112 m_fileView->clearSelection(); 01113 if ( item ) { 01114 m_fileView->setCurrentItem( item ); 01115 m_fileView->setSelected( item, true ); 01116 m_fileView->ensureItemVisible( item ); 01117 } 01118 } 01119 } 01120 01121 QString KDirOperator::makeCompletion(const QString& string) 01122 { 01123 if ( string.isEmpty() ) { 01124 m_fileView->clearSelection(); 01125 return QString::null; 01126 } 01127 01128 prepareCompletionObjects(); 01129 return myCompletion.makeCompletion( string ); 01130 } 01131 01132 QString KDirOperator::makeDirCompletion(const QString& string) 01133 { 01134 if ( string.isEmpty() ) { 01135 m_fileView->clearSelection(); 01136 return QString::null; 01137 } 01138 01139 prepareCompletionObjects(); 01140 return myDirCompletion.makeCompletion( string ); 01141 } 01142 01143 void KDirOperator::prepareCompletionObjects() 01144 { 01145 if ( !m_fileView ) 01146 return; 01147 01148 if ( myCompleteListDirty ) { // create the list of all possible completions 01149 KFileItemListIterator it( *(m_fileView->items()) ); 01150 for( ; it.current(); ++it ) { 01151 KFileItem *item = it.current(); 01152 01153 myCompletion.addItem( item->name() ); 01154 if ( item->isDir() ) 01155 myDirCompletion.addItem( item->name() ); 01156 } 01157 myCompleteListDirty = false; 01158 } 01159 } 01160 01161 void KDirOperator::slotCompletionMatch(const QString& match) 01162 { 01163 setCurrentItem( match ); 01164 emit completion( match ); 01165 } 01166 01167 void KDirOperator::setupActions() 01168 { 01169 myActionCollection = new KActionCollection( this, "KDirOperator::myActionCollection" ); 01170 actionMenu = new KActionMenu( i18n("Menu"), myActionCollection, "popupMenu" ); 01171 upAction = KStdAction::up( this, SLOT( cdUp() ), myActionCollection, "up" ); 01172 upAction->setText( i18n("Parent Folder") ); 01173 backAction = KStdAction::back( this, SLOT( back() ), myActionCollection, "back" ); 01174 forwardAction = KStdAction::forward( this, SLOT(forward()), myActionCollection, "forward" ); 01175 homeAction = KStdAction::home( this, SLOT( home() ), myActionCollection, "home" ); 01176 homeAction->setText(i18n("Home Folder")); 01177 reloadAction = KStdAction::redisplay( this, SLOT(rereadDir()), myActionCollection, "reload" ); 01178 actionSeparator = new KActionSeparator( myActionCollection, "separator" ); 01179 d->viewActionSeparator = new KActionSeparator( myActionCollection, 01180 "viewActionSeparator" ); 01181 mkdirAction = new KAction( i18n("New Folder..."), 0, 01182 this, SLOT( mkdir() ), myActionCollection, "mkdir" ); 01183 new KAction( i18n( "Delete" ), "editdelete", Key_Delete, this, 01184 SLOT( deleteSelected() ), myActionCollection, "delete" ); 01185 mkdirAction->setIcon( QString::fromLatin1("folder_new") ); 01186 reloadAction->setText( i18n("Reload") ); 01187 reloadAction->setShortcut( KStdAccel::shortcut( KStdAccel::Reload )); 01188 01189 01190 // the sort menu actions 01191 sortActionMenu = new KActionMenu( i18n("Sorting"), myActionCollection, "sorting menu"); 01192 byNameAction = new KRadioAction( i18n("By Name"), 0, 01193 this, SLOT( slotSortByName() ), 01194 myActionCollection, "by name" ); 01195 byDateAction = new KRadioAction( i18n("By Date"), 0, 01196 this, SLOT( slotSortByDate() ), 01197 myActionCollection, "by date" ); 01198 bySizeAction = new KRadioAction( i18n("By Size"), 0, 01199 this, SLOT( slotSortBySize() ), 01200 myActionCollection, "by size" ); 01201 reverseAction = new KToggleAction( i18n("Reverse"), 0, 01202 this, SLOT( slotSortReversed() ), 01203 myActionCollection, "reversed" ); 01204 01205 QString sortGroup = QString::fromLatin1("sort"); 01206 byNameAction->setExclusiveGroup( sortGroup ); 01207 byDateAction->setExclusiveGroup( sortGroup ); 01208 bySizeAction->setExclusiveGroup( sortGroup ); 01209 01210 01211 dirsFirstAction = new KToggleAction( i18n("Folders First"), 0, 01212 myActionCollection, "dirs first"); 01213 caseInsensitiveAction = new KToggleAction(i18n("Case Insensitive"), 0, 01214 myActionCollection, "case insensitive" ); 01215 01216 connect( dirsFirstAction, SIGNAL( toggled( bool ) ), 01217 SLOT( slotToggleDirsFirst() )); 01218 connect( caseInsensitiveAction, SIGNAL( toggled( bool ) ), 01219 SLOT( slotToggleIgnoreCase() )); 01220 01221 01222 01223 // the view menu actions 01224 viewActionMenu = new KActionMenu( i18n("&View"), myActionCollection, "view menu" ); 01225 connect( viewActionMenu->popupMenu(), SIGNAL( aboutToShow() ), 01226 SLOT( insertViewDependentActions() )); 01227 01228 shortAction = new KRadioAction( i18n("Short View"), "view_multicolumn", 01229 KShortcut(), myActionCollection, "short view" ); 01230 detailedAction = new KRadioAction( i18n("Detailed View"), "view_detailed", 01231 KShortcut(), myActionCollection, "detailed view" ); 01232 01233 showHiddenAction = new KToggleAction( i18n("Show Hidden Files"), KShortcut(), 01234 myActionCollection, "show hidden" ); 01235 separateDirsAction = new KToggleAction( i18n("Separate Folders"), KShortcut(), 01236 this, 01237 SLOT(slotSeparateDirs()), 01238 myActionCollection, "separate dirs" ); 01239 KToggleAction *previewAction = new KToggleAction(i18n("Show Preview"), 01240 "thumbnail", KShortcut(), 01241 myActionCollection, 01242 "preview" ); 01243 connect( previewAction, SIGNAL( toggled( bool )), 01244 SLOT( togglePreview( bool ))); 01245 01246 01247 QString viewGroup = QString::fromLatin1("view"); 01248 shortAction->setExclusiveGroup( viewGroup ); 01249 detailedAction->setExclusiveGroup( viewGroup ); 01250 01251 connect( shortAction, SIGNAL( activated() ), 01252 SLOT( slotSimpleView() )); 01253 connect( detailedAction, SIGNAL( activated() ), 01254 SLOT( slotDetailedView() )); 01255 connect( showHiddenAction, SIGNAL( toggled( bool ) ), 01256 SLOT( slotToggleHidden( bool ) )); 01257 01258 new KAction( i18n("Properties..."), KShortcut(ALT+Key_Return), this, 01259 SLOT(slotProperties()), myActionCollection, "properties" ); 01260 } 01261 01262 void KDirOperator::setupMenu() 01263 { 01264 setupMenu(AllActions); 01265 } 01266 01267 void KDirOperator::setupMenu(int whichActions) 01268 { 01269 // first fill the submenus (sort and view) 01270 sortActionMenu->popupMenu()->clear(); 01271 sortActionMenu->insert( byNameAction ); 01272 sortActionMenu->insert( byDateAction ); 01273 sortActionMenu->insert( bySizeAction ); 01274 sortActionMenu->insert( actionSeparator ); 01275 sortActionMenu->insert( reverseAction ); 01276 sortActionMenu->insert( dirsFirstAction ); 01277 sortActionMenu->insert( caseInsensitiveAction ); 01278 01279 // now plug everything into the popupmenu 01280 actionMenu->popupMenu()->clear(); 01281 if (whichActions & NavActions) 01282 { 01283 actionMenu->insert( upAction ); 01284 actionMenu->insert( backAction ); 01285 actionMenu->insert( forwardAction ); 01286 actionMenu->insert( homeAction ); 01287 actionMenu->insert( actionSeparator ); 01288 } 01289 01290 if (whichActions & FileActions) 01291 { 01292 actionMenu->insert( mkdirAction ); 01293 actionMenu->insert( myActionCollection->action( "delete" ) ); 01294 actionMenu->insert( actionSeparator ); 01295 } 01296 01297 if (whichActions & SortActions) 01298 { 01299 actionMenu->insert( sortActionMenu ); 01300 actionMenu->insert( actionSeparator ); 01301 } 01302 01303 if (whichActions & ViewActions) 01304 { 01305 actionMenu->insert( viewActionMenu ); 01306 actionMenu->insert( actionSeparator ); 01307 } 01308 01309 if (whichActions & FileActions) 01310 { 01311 actionMenu->insert( myActionCollection->action( "properties" ) ); 01312 } 01313 } 01314 01315 void KDirOperator::updateSortActions() 01316 { 01317 if ( KFile::isSortByName( mySorting ) ) 01318 byNameAction->setChecked( true ); 01319 else if ( KFile::isSortByDate( mySorting ) ) 01320 byDateAction->setChecked( true ); 01321 else if ( KFile::isSortBySize( mySorting ) ) 01322 bySizeAction->setChecked( true ); 01323 01324 dirsFirstAction->setChecked( KFile::isSortDirsFirst( mySorting ) ); 01325 caseInsensitiveAction->setChecked( KFile::isSortCaseInsensitive(mySorting) ); 01326 caseInsensitiveAction->setEnabled( KFile::isSortByName( mySorting ) ); 01327 01328 if ( m_fileView ) 01329 reverseAction->setChecked( m_fileView->isReversed() ); 01330 } 01331 01332 void KDirOperator::updateViewActions() 01333 { 01334 KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind ); 01335 01336 separateDirsAction->setChecked( KFile::isSeparateDirs( fv ) && 01337 separateDirsAction->isEnabled() ); 01338 01339 shortAction->setChecked( KFile::isSimpleView( fv )); 01340 detailedAction->setChecked( KFile::isDetailView( fv )); 01341 } 01342 01343 void KDirOperator::readConfig( KConfig *kc, const QString& group ) 01344 { 01345 if ( !kc ) 01346 return; 01347 QString oldGroup = kc->group(); 01348 if ( !group.isEmpty() ) 01349 kc->setGroup( group ); 01350 01351 defaultView = 0; 01352 int sorting = 0; 01353 01354 QString viewStyle = kc->readEntry( QString::fromLatin1("View Style"), 01355 QString::fromLatin1("Simple") ); 01356 if ( viewStyle == QString::fromLatin1("Detail") ) 01357 defaultView |= KFile::Detail; 01358 else 01359 defaultView |= KFile::Simple; 01360 if ( kc->readBoolEntry( QString::fromLatin1("Separate Directories"), 01361 DefaultMixDirsAndFiles ) ) 01362 defaultView |= KFile::SeparateDirs; 01363 if ( kc->readBoolEntry(QString::fromLatin1("Show Preview"), false)) 01364 defaultView |= KFile::PreviewContents; 01365 01366 if ( kc->readBoolEntry( QString::fromLatin1("Sort case insensitively"), 01367 DefaultCaseInsensitive ) ) 01368 sorting |= QDir::IgnoreCase; 01369 if ( kc->readBoolEntry( QString::fromLatin1("Sort directories first"), 01370 DefaultDirsFirst ) ) 01371 sorting |= QDir::DirsFirst; 01372 01373 01374 QString name = QString::fromLatin1("Name"); 01375 QString sortBy = kc->readEntry( QString::fromLatin1("Sort by"), name ); 01376 if ( sortBy == name ) 01377 sorting |= QDir::Name; 01378 else if ( sortBy == QString::fromLatin1("Size") ) 01379 sorting |= QDir::Size; 01380 else if ( sortBy == QString::fromLatin1("Date") ) 01381 sorting |= QDir::Time; 01382 01383 mySorting = static_cast<QDir::SortSpec>( sorting ); 01384 setSorting( mySorting ); 01385 01386 01387 if ( kc->readBoolEntry( QString::fromLatin1("Show hidden files"), 01388 DefaultShowHidden ) ) { 01389 showHiddenAction->setChecked( true ); 01390 dir->setShowingDotFiles( true ); 01391 } 01392 if ( kc->readBoolEntry( QString::fromLatin1("Sort reversed"), 01393 DefaultSortReversed ) ) 01394 reverseAction->setChecked( true ); 01395 01396 kc->setGroup( oldGroup ); 01397 } 01398 01399 void KDirOperator::writeConfig( KConfig *kc, const QString& group ) 01400 { 01401 if ( !kc ) 01402 return; 01403 01404 const QString oldGroup = kc->group(); 01405 01406 if ( !group.isEmpty() ) 01407 kc->setGroup( group ); 01408 01409 QString sortBy = QString::fromLatin1("Name"); 01410 if ( KFile::isSortBySize( mySorting ) ) 01411 sortBy = QString::fromLatin1("Size"); 01412 else if ( KFile::isSortByDate( mySorting ) ) 01413 sortBy = QString::fromLatin1("Date"); 01414 kc->writeEntry( QString::fromLatin1("Sort by"), sortBy ); 01415 01416 kc->writeEntry( QString::fromLatin1("Sort reversed"), 01417 reverseAction->isChecked() ); 01418 kc->writeEntry( QString::fromLatin1("Sort case insensitively"), 01419 caseInsensitiveAction->isChecked() ); 01420 kc->writeEntry( QString::fromLatin1("Sort directories first"), 01421 dirsFirstAction->isChecked() ); 01422 01423 // don't save the separate dirs or preview when an application specific 01424 // preview is in use. 01425 bool appSpecificPreview = false; 01426 if ( myPreview ) { 01427 QWidget *preview = const_cast<QWidget*>( myPreview ); // grmbl 01428 KFileMetaPreview *tmp = dynamic_cast<KFileMetaPreview*>( preview ); 01429 appSpecificPreview = (tmp == 0L); 01430 } 01431 01432 if ( !appSpecificPreview ) { 01433 if ( separateDirsAction->isEnabled() ) 01434 kc->writeEntry( QString::fromLatin1("Separate Directories"), 01435 separateDirsAction->isChecked() ); 01436 01437 KToggleAction *previewAction = static_cast<KToggleAction*>(myActionCollection->action("preview")); 01438 if ( previewAction->isEnabled() ) { 01439 bool hasPreview = previewAction->isChecked(); 01440 kc->writeEntry( QString::fromLatin1("Show Preview"), hasPreview ); 01441 } 01442 } 01443 01444 kc->writeEntry( QString::fromLatin1("Show hidden files"), 01445 showHiddenAction->isChecked() ); 01446 01447 KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind ); 01448 QString style; 01449 if ( KFile::isDetailView( fv ) ) 01450 style = QString::fromLatin1("Detail"); 01451 else if ( KFile::isSimpleView( fv ) ) 01452 style = QString::fromLatin1("Simple"); 01453 kc->writeEntry( QString::fromLatin1("View Style"), style ); 01454 01455 kc->setGroup( oldGroup ); 01456 } 01457 01458 01459 void KDirOperator::resizeEvent( QResizeEvent * ) 01460 { 01461 if (m_fileView) 01462 m_fileView->widget()->resize( size() ); 01463 01464 if ( progress->parent() == this ) // might be reparented into a statusbar 01465 progress->move(2, height() - progress->height() -2); 01466 } 01467 01468 void KDirOperator::setOnlyDoubleClickSelectsFiles( bool enable ) 01469 { 01470 d->onlyDoubleClickSelectsFiles = enable; 01471 if ( m_fileView ) 01472 m_fileView->setOnlyDoubleClickSelectsFiles( enable ); 01473 } 01474 01475 bool KDirOperator::onlyDoubleClickSelectsFiles() const 01476 { 01477 return d->onlyDoubleClickSelectsFiles; 01478 } 01479 01480 void KDirOperator::slotStarted() 01481 { 01482 progress->setProgress( 0 ); 01483 // delay showing the progressbar for one second 01484 d->progressDelayTimer->start( 1000, true ); 01485 } 01486 01487 void KDirOperator::slotShowProgress() 01488 { 01489 progress->raise(); 01490 progress->show(); 01491 QApplication::flushX(); 01492 } 01493 01494 void KDirOperator::slotProgress( int percent ) 01495 { 01496 progress->setProgress( percent ); 01497 // we have to redraw this as fast as possible 01498 if ( progress->isVisible() ) 01499 QApplication::flushX(); 01500 } 01501 01502 01503 void KDirOperator::slotIOFinished() 01504 { 01505 d->progressDelayTimer->stop(); 01506 slotProgress( 100 ); 01507 progress->hide(); 01508 emit finishedLoading(); 01509 resetCursor(); 01510 01511 if ( m_fileView ) 01512 m_fileView->listingCompleted(); 01513 } 01514 01515 void KDirOperator::slotCanceled() 01516 { 01517 emit finishedLoading(); 01518 resetCursor(); 01519 01520 if ( m_fileView ) 01521 m_fileView->listingCompleted(); 01522 } 01523 01524 KProgress * KDirOperator::progressBar() const 01525 { 01526 return progress; 01527 } 01528 01529 void KDirOperator::clearHistory() 01530 { 01531 backStack.clear(); 01532 backAction->setEnabled( false ); 01533 forwardStack.clear(); 01534 forwardAction->setEnabled( false ); 01535 } 01536 01537 void KDirOperator::slotViewActionAdded( KAction *action ) 01538 { 01539 if ( viewActionMenu->popupMenu()->count() == 5 ) // need to add a separator 01540 viewActionMenu->insert( d->viewActionSeparator ); 01541 01542 viewActionMenu->insert( action ); 01543 } 01544 01545 void KDirOperator::slotViewActionRemoved( KAction *action ) 01546 { 01547 viewActionMenu->remove( action ); 01548 01549 if ( viewActionMenu->popupMenu()->count() == 6 ) // remove the separator 01550 viewActionMenu->remove( d->viewActionSeparator ); 01551 } 01552 01553 void KDirOperator::slotViewSortingChanged( QDir::SortSpec sort ) 01554 { 01555 mySorting = sort; 01556 updateSortActions(); 01557 } 01558 01559 void KDirOperator::setEnableDirHighlighting( bool enable ) 01560 { 01561 d->dirHighlighting = enable; 01562 } 01563 01564 bool KDirOperator::dirHighlighting() const 01565 { 01566 return d->dirHighlighting; 01567 } 01568 01569 void KDirOperator::slotProperties() 01570 { 01571 if ( m_fileView ) { 01572 const KFileItemList *list = m_fileView->selectedItems(); 01573 if ( !list->isEmpty() ) 01574 (void) new KPropertiesDialog( *list, this, "props dlg", true); 01575 } 01576 } 01577 01578 void KDirOperator::slotClearView() 01579 { 01580 if ( m_fileView ) 01581 m_fileView->clearView(); 01582 } 01583 01584 // ### temporary code 01585 #include <dirent.h> 01586 bool KDirOperator::isReadable( const KURL& url ) 01587 { 01588 if ( !url.isLocalFile() ) 01589 return true; // what else can we say? 01590 01591 struct stat buf; 01592 QString ts = url.path(+1); 01593 bool readable = ( ::stat( QFile::encodeName( ts ), &buf) == 0 ); 01594 if (readable) { // further checks 01595 DIR *test; 01596 test = opendir( QFile::encodeName( ts )); // we do it just to test here 01597 readable = (test != 0); 01598 if (test) 01599 closedir(test); 01600 } 01601 return readable; 01602 } 01603 01604 void KDirOperator::togglePreview( bool on ) 01605 { 01606 if ( on ) 01607 slotDefaultPreview(); 01608 else 01609 setView( (KFile::FileView) (m_viewKind & ~(KFile::PreviewContents|KFile::PreviewInfo)) ); 01610 } 01611 01612 void KDirOperator::slotRefreshItems( const KFileItemList& items ) 01613 { 01614 if ( !m_fileView ) 01615 return; 01616 01617 KFileItemListIterator it( items ); 01618 for ( ; it.current(); ++it ) 01619 m_fileView->updateView( it.current() ); 01620 } 01621 01622 void KDirOperator::setViewConfig( KConfig *config, const QString& group ) 01623 { 01624 d->config = config; 01625 d->configGroup = group; 01626 } 01627 01628 KConfig * KDirOperator::viewConfig() 01629 { 01630 return d->config; 01631 } 01632 01633 QString KDirOperator::viewConfigGroup() const 01634 { 01635 return d->configGroup; 01636 } 01637 01638 void KDirOperator::virtual_hook( int, void* ) 01639 { /*BASE::virtual_hook( id, data );*/ } 01640 01641 #include "kdiroperator.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:22:29 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003