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().prettyURL( +1, KURL::StripFileProtocol ); 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( KIO::encodeFileName( 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 do not 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 did not 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 KStdGuiItem::del(), "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 KURL u; 00702 u.setPath( QDir::homeDirPath() ); 00703 setURL(u, true); 00704 } 00705 00706 void KDirOperator::clearFilter() 00707 { 00708 dir->setNameFilter( QString::null ); 00709 dir->clearMimeFilter(); 00710 checkPreviewSupport(); 00711 } 00712 00713 void KDirOperator::setNameFilter(const QString& filter) 00714 { 00715 dir->setNameFilter(filter); 00716 checkPreviewSupport(); 00717 } 00718 00719 void KDirOperator::setMimeFilter( const QStringList& mimetypes ) 00720 { 00721 dir->setMimeFilter( mimetypes ); 00722 checkPreviewSupport(); 00723 } 00724 00725 bool KDirOperator::checkPreviewSupport() 00726 { 00727 KToggleAction *previewAction = static_cast<KToggleAction*>( myActionCollection->action( "preview" )); 00728 00729 bool hasPreviewSupport = false; 00730 KConfig *kc = KGlobal::config(); 00731 KConfigGroupSaver cs( kc, ConfigGroup ); 00732 if ( kc->readBoolEntry( "Show Default Preview", true ) ) 00733 hasPreviewSupport = checkPreviewInternal(); 00734 00735 previewAction->setEnabled( hasPreviewSupport ); 00736 return hasPreviewSupport; 00737 } 00738 00739 bool KDirOperator::checkPreviewInternal() const 00740 { 00741 QStringList supported = KIO::PreviewJob::supportedMimeTypes(); 00742 // no preview support for directories? 00743 if ( dirOnlyMode() && supported.findIndex( "inode/directory" ) == -1 ) 00744 return false; 00745 00746 QStringList mimeTypes = dir->mimeFilters(); 00747 QStringList nameFilter = QStringList::split( " ", dir->nameFilter() ); 00748 00749 if ( mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty() ) 00750 return true; 00751 else { 00752 QRegExp r; 00753 r.setWildcard( true ); // the "mimetype" can be "image/*" 00754 00755 if ( !mimeTypes.isEmpty() ) { 00756 QStringList::Iterator it = supported.begin(); 00757 00758 for ( ; it != supported.end(); ++it ) { 00759 r.setPattern( *it ); 00760 00761 QStringList result = mimeTypes.grep( r ); 00762 if ( !result.isEmpty() ) { // matches! -> we want previews 00763 return true; 00764 } 00765 } 00766 } 00767 00768 if ( !nameFilter.isEmpty() ) { 00769 // find the mimetypes of all the filter-patterns and 00770 KServiceTypeFactory *fac = KServiceTypeFactory::self(); 00771 QStringList::Iterator it1 = nameFilter.begin(); 00772 for ( ; it1 != nameFilter.end(); ++it1 ) { 00773 if ( (*it1) == "*" ) { 00774 return true; 00775 } 00776 00777 KMimeType *mt = fac->findFromPattern( *it1 ); 00778 if ( !mt ) 00779 continue; 00780 QString mime = mt->name(); 00781 delete mt; 00782 00783 // the "mimetypes" we get from the PreviewJob can be "image/*" 00784 // so we need to check in wildcard mode 00785 QStringList::Iterator it2 = supported.begin(); 00786 for ( ; it2 != supported.end(); ++it2 ) { 00787 r.setPattern( *it2 ); 00788 if ( r.search( mime ) != -1 ) { 00789 return true; 00790 } 00791 } 00792 } 00793 } 00794 } 00795 00796 return false; 00797 } 00798 00799 KFileView* KDirOperator::createView( QWidget* parent, KFile::FileView view ) 00800 { 00801 KFileView* new_view = 0L; 00802 bool separateDirs = KFile::isSeparateDirs( view ); 00803 bool preview = ( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) ); 00804 00805 if ( separateDirs || preview ) { 00806 KCombiView *combi = 0L; 00807 if (separateDirs) 00808 { 00809 combi = new KCombiView( parent, "combi view" ); 00810 combi->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); 00811 } 00812 00813 KFileView* v = 0L; 00814 if ( KFile::isSimpleView( view ) ) 00815 v = createView( combi, KFile::Simple ); 00816 else 00817 v = createView( combi, KFile::Detail ); 00818 00819 v->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); 00820 00821 if (combi) 00822 combi->setRight( v ); 00823 00824 if (preview) 00825 { 00826 KFilePreview* pView = new KFilePreview( combi ? combi : v, parent, "preview" ); 00827 pView->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); 00828 new_view = pView; 00829 } 00830 else 00831 new_view = combi; 00832 } 00833 else if ( KFile::isDetailView( view ) && !preview ) { 00834 new_view = new KFileDetailView( parent, "detail view"); 00835 new_view->setViewName( i18n("Detailed View") ); 00836 } 00837 else /* if ( KFile::isSimpleView( view ) && !preview ) */ { 00838 KFileIconView *iconView = new KFileIconView( parent, "simple view"); 00839 new_view = iconView; 00840 new_view->setViewName( i18n("Short View") ); 00841 } 00842 00843 new_view->widget()->setAcceptDrops(acceptDrops()); 00844 return new_view; 00845 } 00846 00847 void KDirOperator::setAcceptDrops(bool b) 00848 { 00849 if (m_fileView) 00850 m_fileView->widget()->setAcceptDrops(b); 00851 QWidget::setAcceptDrops(b); 00852 } 00853 00854 void KDirOperator::setDropOptions(int options) 00855 { 00856 d->dropOptions = options; 00857 if (m_fileView) 00858 m_fileView->setDropOptions(options); 00859 } 00860 00861 void KDirOperator::setView( KFile::FileView view ) 00862 { 00863 bool separateDirs = KFile::isSeparateDirs( view ); 00864 bool preview=( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) ); 00865 00866 if (view == KFile::Default) { 00867 if ( KFile::isDetailView( (KFile::FileView) defaultView ) ) 00868 view = KFile::Detail; 00869 else 00870 view = KFile::Simple; 00871 00872 separateDirs = KFile::isSeparateDirs( static_cast<KFile::FileView>(defaultView) ); 00873 preview = ( KFile::isPreviewInfo( static_cast<KFile::FileView>(defaultView) ) || 00874 KFile::isPreviewContents( static_cast<KFile::FileView>(defaultView) ) ) 00875 && myActionCollection->action("preview")->isEnabled(); 00876 00877 if ( preview ) { // instantiates KFileMetaPreview and calls setView() 00878 m_viewKind = defaultView; 00879 slotDefaultPreview(); 00880 return; 00881 } 00882 else if ( !separateDirs ) 00883 separateDirsAction->setChecked(true); 00884 } 00885 00886 // if we don't have any files, we can't separate dirs from files :) 00887 if ( (mode() & KFile::File) == 0 && 00888 (mode() & KFile::Files) == 0 ) { 00889 separateDirs = false; 00890 separateDirsAction->setEnabled( false ); 00891 } 00892 00893 m_viewKind = static_cast<int>(view) | (separateDirs ? KFile::SeparateDirs : 0); 00894 view = static_cast<KFile::FileView>(m_viewKind); 00895 00896 KFileView *new_view = createView( this, view ); 00897 if ( preview ) { 00898 // we keep the preview-_widget_ around, but not the KFilePreview. 00899 // KFilePreview::setPreviewWidget handles the reparenting for us 00900 static_cast<KFilePreview*>(new_view)->setPreviewWidget(myPreview, url()); 00901 } 00902 00903 setView( new_view ); 00904 } 00905 00906 00907 void KDirOperator::connectView(KFileView *view) 00908 { 00909 // TODO: do a real timer and restart it after that 00910 pendingMimeTypes.clear(); 00911 bool listDir = true; 00912 00913 if ( dirOnlyMode() ) 00914 view->setViewMode(KFileView::Directories); 00915 else 00916 view->setViewMode(KFileView::All); 00917 00918 if ( myMode & KFile::Files ) 00919 view->setSelectionMode( KFile::Extended ); 00920 else 00921 view->setSelectionMode( KFile::Single ); 00922 00923 if (m_fileView) 00924 { 00925 if ( d->config ) // save and restore the views' configuration 00926 { 00927 m_fileView->writeConfig( d->config, d->configGroup ); 00928 view->readConfig( d->config, d->configGroup ); 00929 } 00930 00931 // transfer the state from old view to new view 00932 view->clear(); 00933 view->addItemList( *m_fileView->items() ); 00934 listDir = false; 00935 00936 if ( m_fileView->widget()->hasFocus() ) 00937 view->widget()->setFocus(); 00938 00939 KFileItem *oldCurrentItem = m_fileView->currentFileItem(); 00940 if ( oldCurrentItem ) { 00941 view->setCurrentItem( oldCurrentItem ); 00942 view->setSelected( oldCurrentItem, false ); 00943 view->ensureItemVisible( oldCurrentItem ); 00944 } 00945 00946 const KFileItemList *oldSelected = m_fileView->selectedItems(); 00947 if ( !oldSelected->isEmpty() ) { 00948 KFileItemListIterator it( *oldSelected ); 00949 for ( ; it.current(); ++it ) 00950 view->setSelected( it.current(), true ); 00951 } 00952 00953 m_fileView->widget()->hide(); 00954 delete m_fileView; 00955 } 00956 00957 else 00958 { 00959 if ( d->config ) 00960 view->readConfig( d->config, d->configGroup ); 00961 } 00962 00963 m_fileView = view; 00964 m_fileView->setDropOptions(d->dropOptions); 00965 viewActionCollection = 0L; 00966 KFileViewSignaler *sig = view->signaler(); 00967 00968 connect(sig, SIGNAL( activatedMenu(const KFileItem *, const QPoint& ) ), 00969 this, SLOT( activatedMenu(const KFileItem *, const QPoint& ))); 00970 connect(sig, SIGNAL( dirActivated(const KFileItem *) ), 00971 this, SLOT( selectDir(const KFileItem*) ) ); 00972 connect(sig, SIGNAL( fileSelected(const KFileItem *) ), 00973 this, SLOT( selectFile(const KFileItem*) ) ); 00974 connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ), 00975 this, SLOT( highlightFile(const KFileItem*) )); 00976 connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ), 00977 this, SLOT( slotViewSortingChanged( QDir::SortSpec ))); 00978 connect(sig, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&) ), 00979 this, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&)) ); 00980 00981 if ( reverseAction->isChecked() != m_fileView->isReversed() ) 00982 slotSortReversed(); 00983 00984 updateViewActions(); 00985 m_fileView->widget()->resize(size()); 00986 m_fileView->widget()->show(); 00987 00988 if ( listDir ) { 00989 QApplication::setOverrideCursor( waitCursor ); 00990 dir->openURL( currUrl ); 00991 } 00992 else 00993 view->listingCompleted(); 00994 } 00995 00996 KFile::Mode KDirOperator::mode() const 00997 { 00998 return myMode; 00999 } 01000 01001 void KDirOperator::setMode(KFile::Mode m) 01002 { 01003 if (myMode == m) 01004 return; 01005 01006 myMode = m; 01007 01008 dir->setDirOnlyMode( dirOnlyMode() ); 01009 01010 // reset the view with the different mode 01011 setView( static_cast<KFile::FileView>(m_viewKind) ); 01012 } 01013 01014 void KDirOperator::setView(KFileView *view) 01015 { 01016 if ( view == m_fileView ) { 01017 return; 01018 } 01019 01020 setFocusProxy(view->widget()); 01021 view->setSorting( mySorting ); 01022 view->setOnlyDoubleClickSelectsFiles( d->onlyDoubleClickSelectsFiles ); 01023 connectView(view); // also deletes the old view 01024 01025 emit viewChanged( view ); 01026 } 01027 01028 void KDirOperator::setDirLister( KDirLister *lister ) 01029 { 01030 if ( lister == dir ) // sanity check 01031 return; 01032 01033 delete dir; 01034 dir = lister; 01035 01036 dir->setAutoUpdate( true ); 01037 01038 QWidget* mainWidget = topLevelWidget(); 01039 dir->setMainWindow (mainWidget); 01040 kdDebug (kfile_area) << "mainWidget=" << mainWidget << endl; 01041 01042 connect( dir, SIGNAL( percent( int )), 01043 SLOT( slotProgress( int ) )); 01044 connect( dir, SIGNAL(started( const KURL& )), SLOT(slotStarted())); 01045 connect( dir, SIGNAL(newItems(const KFileItemList &)), 01046 SLOT(insertNewFiles(const KFileItemList &))); 01047 connect( dir, SIGNAL(completed()), SLOT(slotIOFinished())); 01048 connect( dir, SIGNAL(canceled()), SLOT(slotCanceled())); 01049 connect( dir, SIGNAL(deleteItem(KFileItem *)), 01050 SLOT(itemDeleted(KFileItem *))); 01051 connect( dir, SIGNAL(redirection( const KURL& )), 01052 SLOT( slotRedirected( const KURL& ))); 01053 connect( dir, SIGNAL( clear() ), SLOT( slotClearView() )); 01054 connect( dir, SIGNAL( refreshItems( const KFileItemList& ) ), 01055 SLOT( slotRefreshItems( const KFileItemList& ) ) ); 01056 } 01057 01058 void KDirOperator::insertNewFiles(const KFileItemList &newone) 01059 { 01060 if ( newone.isEmpty() || !m_fileView ) 01061 return; 01062 01063 myCompleteListDirty = true; 01064 m_fileView->addItemList( newone ); 01065 emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles()); 01066 01067 KFileItem *item; 01068 KFileItemListIterator it( newone ); 01069 01070 while ( (item = it.current()) ) { 01071 // highlight the dir we come from, if possible 01072 if ( d->dirHighlighting && item->isDir() && 01073 item->url().url(-1) == d->lastURL ) { 01074 m_fileView->setCurrentItem( item ); 01075 m_fileView->ensureItemVisible( item ); 01076 } 01077 01078 ++it; 01079 } 01080 01081 QTimer::singleShot(200, this, SLOT(resetCursor())); 01082 } 01083 01084 void KDirOperator::selectDir(const KFileItem *item) 01085 { 01086 setURL(item->url(), true); 01087 } 01088 01089 void KDirOperator::itemDeleted(KFileItem *item) 01090 { 01091 pendingMimeTypes.removeRef( item ); 01092 if ( m_fileView ) 01093 { 01094 m_fileView->removeItem( static_cast<KFileItem *>( item )); 01095 emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles()); 01096 } 01097 } 01098 01099 void KDirOperator::selectFile(const KFileItem *item) 01100 { 01101 QApplication::restoreOverrideCursor(); 01102 01103 emit fileSelected( item ); 01104 } 01105 01106 void KDirOperator::setCurrentItem( const QString& filename ) 01107 { 01108 if ( m_fileView ) { 01109 const KFileItem *item = 0L; 01110 01111 if ( !filename.isNull() ) 01112 item = static_cast<KFileItem *>(dir->findByName( filename )); 01113 01114 m_fileView->clearSelection(); 01115 if ( item ) { 01116 m_fileView->setCurrentItem( item ); 01117 m_fileView->setSelected( item, true ); 01118 m_fileView->ensureItemVisible( item ); 01119 } 01120 } 01121 } 01122 01123 QString KDirOperator::makeCompletion(const QString& string) 01124 { 01125 if ( string.isEmpty() ) { 01126 m_fileView->clearSelection(); 01127 return QString::null; 01128 } 01129 01130 prepareCompletionObjects(); 01131 return myCompletion.makeCompletion( string ); 01132 } 01133 01134 QString KDirOperator::makeDirCompletion(const QString& string) 01135 { 01136 if ( string.isEmpty() ) { 01137 m_fileView->clearSelection(); 01138 return QString::null; 01139 } 01140 01141 prepareCompletionObjects(); 01142 return myDirCompletion.makeCompletion( string ); 01143 } 01144 01145 void KDirOperator::prepareCompletionObjects() 01146 { 01147 if ( !m_fileView ) 01148 return; 01149 01150 if ( myCompleteListDirty ) { // create the list of all possible completions 01151 KFileItemListIterator it( *(m_fileView->items()) ); 01152 for( ; it.current(); ++it ) { 01153 KFileItem *item = it.current(); 01154 01155 myCompletion.addItem( item->name() ); 01156 if ( item->isDir() ) 01157 myDirCompletion.addItem( item->name() ); 01158 } 01159 myCompleteListDirty = false; 01160 } 01161 } 01162 01163 void KDirOperator::slotCompletionMatch(const QString& match) 01164 { 01165 setCurrentItem( match ); 01166 emit completion( match ); 01167 } 01168 01169 void KDirOperator::setupActions() 01170 { 01171 myActionCollection = new KActionCollection( this, "KDirOperator::myActionCollection" ); 01172 actionMenu = new KActionMenu( i18n("Menu"), myActionCollection, "popupMenu" ); 01173 upAction = KStdAction::up( this, SLOT( cdUp() ), myActionCollection, "up" ); 01174 upAction->setText( i18n("Parent Folder") ); 01175 backAction = KStdAction::back( this, SLOT( back() ), myActionCollection, "back" ); 01176 forwardAction = KStdAction::forward( this, SLOT(forward()), myActionCollection, "forward" ); 01177 homeAction = KStdAction::home( this, SLOT( home() ), myActionCollection, "home" ); 01178 homeAction->setText(i18n("Home Folder")); 01179 reloadAction = KStdAction::redisplay( this, SLOT(rereadDir()), myActionCollection, "reload" ); 01180 actionSeparator = new KActionSeparator( myActionCollection, "separator" ); 01181 d->viewActionSeparator = new KActionSeparator( myActionCollection, 01182 "viewActionSeparator" ); 01183 mkdirAction = new KAction( i18n("New Folder..."), 0, 01184 this, SLOT( mkdir() ), myActionCollection, "mkdir" ); 01185 new KAction( i18n( "Delete" ), "editdelete", Key_Delete, this, 01186 SLOT( deleteSelected() ), myActionCollection, "delete" ); 01187 mkdirAction->setIcon( QString::fromLatin1("folder_new") ); 01188 reloadAction->setText( i18n("Reload") ); 01189 reloadAction->setShortcut( KStdAccel::shortcut( KStdAccel::Reload )); 01190 01191 01192 // the sort menu actions 01193 sortActionMenu = new KActionMenu( i18n("Sorting"), myActionCollection, "sorting menu"); 01194 byNameAction = new KRadioAction( i18n("By Name"), 0, 01195 this, SLOT( slotSortByName() ), 01196 myActionCollection, "by name" ); 01197 byDateAction = new KRadioAction( i18n("By Date"), 0, 01198 this, SLOT( slotSortByDate() ), 01199 myActionCollection, "by date" ); 01200 bySizeAction = new KRadioAction( i18n("By Size"), 0, 01201 this, SLOT( slotSortBySize() ), 01202 myActionCollection, "by size" ); 01203 reverseAction = new KToggleAction( i18n("Reverse"), 0, 01204 this, SLOT( slotSortReversed() ), 01205 myActionCollection, "reversed" ); 01206 01207 QString sortGroup = QString::fromLatin1("sort"); 01208 byNameAction->setExclusiveGroup( sortGroup ); 01209 byDateAction->setExclusiveGroup( sortGroup ); 01210 bySizeAction->setExclusiveGroup( sortGroup ); 01211 01212 01213 dirsFirstAction = new KToggleAction( i18n("Folders First"), 0, 01214 myActionCollection, "dirs first"); 01215 caseInsensitiveAction = new KToggleAction(i18n("Case Insensitive"), 0, 01216 myActionCollection, "case insensitive" ); 01217 01218 connect( dirsFirstAction, SIGNAL( toggled( bool ) ), 01219 SLOT( slotToggleDirsFirst() )); 01220 connect( caseInsensitiveAction, SIGNAL( toggled( bool ) ), 01221 SLOT( slotToggleIgnoreCase() )); 01222 01223 01224 01225 // the view menu actions 01226 viewActionMenu = new KActionMenu( i18n("&View"), myActionCollection, "view menu" ); 01227 connect( viewActionMenu->popupMenu(), SIGNAL( aboutToShow() ), 01228 SLOT( insertViewDependentActions() )); 01229 01230 shortAction = new KRadioAction( i18n("Short View"), "view_multicolumn", 01231 KShortcut(), myActionCollection, "short view" ); 01232 detailedAction = new KRadioAction( i18n("Detailed View"), "view_detailed", 01233 KShortcut(), myActionCollection, "detailed view" ); 01234 01235 showHiddenAction = new KToggleAction( i18n("Show Hidden Files"), KShortcut(), 01236 myActionCollection, "show hidden" ); 01237 // showHiddenAction->setCheckedState( i18n("Hide Hidden Files") ); 01238 separateDirsAction = new KToggleAction( i18n("Separate Folders"), KShortcut(), 01239 this, 01240 SLOT(slotSeparateDirs()), 01241 myActionCollection, "separate dirs" ); 01242 KToggleAction *previewAction = new KToggleAction(i18n("Show Preview"), 01243 "thumbnail", KShortcut(), 01244 myActionCollection, 01245 "preview" ); 01246 previewAction->setCheckedState(i18n("Hide Preview")); 01247 connect( previewAction, SIGNAL( toggled( bool )), 01248 SLOT( togglePreview( bool ))); 01249 01250 01251 QString viewGroup = QString::fromLatin1("view"); 01252 shortAction->setExclusiveGroup( viewGroup ); 01253 detailedAction->setExclusiveGroup( viewGroup ); 01254 01255 connect( shortAction, SIGNAL( activated() ), 01256 SLOT( slotSimpleView() )); 01257 connect( detailedAction, SIGNAL( activated() ), 01258 SLOT( slotDetailedView() )); 01259 connect( showHiddenAction, SIGNAL( toggled( bool ) ), 01260 SLOT( slotToggleHidden( bool ) )); 01261 01262 new KAction( i18n("Properties"), KShortcut(ALT+Key_Return), this, 01263 SLOT(slotProperties()), myActionCollection, "properties" ); 01264 } 01265 01266 void KDirOperator::setupMenu() 01267 { 01268 setupMenu(AllActions); 01269 } 01270 01271 void KDirOperator::setupMenu(int whichActions) 01272 { 01273 // first fill the submenus (sort and view) 01274 sortActionMenu->popupMenu()->clear(); 01275 sortActionMenu->insert( byNameAction ); 01276 sortActionMenu->insert( byDateAction ); 01277 sortActionMenu->insert( bySizeAction ); 01278 sortActionMenu->insert( actionSeparator ); 01279 sortActionMenu->insert( reverseAction ); 01280 sortActionMenu->insert( dirsFirstAction ); 01281 sortActionMenu->insert( caseInsensitiveAction ); 01282 01283 // now plug everything into the popupmenu 01284 actionMenu->popupMenu()->clear(); 01285 if (whichActions & NavActions) 01286 { 01287 actionMenu->insert( upAction ); 01288 actionMenu->insert( backAction ); 01289 actionMenu->insert( forwardAction ); 01290 actionMenu->insert( homeAction ); 01291 actionMenu->insert( actionSeparator ); 01292 } 01293 01294 if (whichActions & FileActions) 01295 { 01296 actionMenu->insert( mkdirAction ); 01297 actionMenu->insert( myActionCollection->action( "delete" ) ); 01298 actionMenu->insert( actionSeparator ); 01299 } 01300 01301 if (whichActions & SortActions) 01302 { 01303 actionMenu->insert( sortActionMenu ); 01304 actionMenu->insert( actionSeparator ); 01305 } 01306 01307 if (whichActions & ViewActions) 01308 { 01309 actionMenu->insert( viewActionMenu ); 01310 actionMenu->insert( actionSeparator ); 01311 } 01312 01313 if (whichActions & FileActions) 01314 { 01315 actionMenu->insert( myActionCollection->action( "properties" ) ); 01316 } 01317 } 01318 01319 void KDirOperator::updateSortActions() 01320 { 01321 if ( KFile::isSortByName( mySorting ) ) 01322 byNameAction->setChecked( true ); 01323 else if ( KFile::isSortByDate( mySorting ) ) 01324 byDateAction->setChecked( true ); 01325 else if ( KFile::isSortBySize( mySorting ) ) 01326 bySizeAction->setChecked( true ); 01327 01328 dirsFirstAction->setChecked( KFile::isSortDirsFirst( mySorting ) ); 01329 caseInsensitiveAction->setChecked( KFile::isSortCaseInsensitive(mySorting) ); 01330 caseInsensitiveAction->setEnabled( KFile::isSortByName( mySorting ) ); 01331 01332 if ( m_fileView ) 01333 reverseAction->setChecked( m_fileView->isReversed() ); 01334 } 01335 01336 void KDirOperator::updateViewActions() 01337 { 01338 KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind ); 01339 01340 separateDirsAction->setChecked( KFile::isSeparateDirs( fv ) && 01341 separateDirsAction->isEnabled() ); 01342 01343 shortAction->setChecked( KFile::isSimpleView( fv )); 01344 detailedAction->setChecked( KFile::isDetailView( fv )); 01345 } 01346 01347 void KDirOperator::readConfig( KConfig *kc, const QString& group ) 01348 { 01349 if ( !kc ) 01350 return; 01351 QString oldGroup = kc->group(); 01352 if ( !group.isEmpty() ) 01353 kc->setGroup( group ); 01354 01355 defaultView = 0; 01356 int sorting = 0; 01357 01358 QString viewStyle = kc->readEntry( QString::fromLatin1("View Style"), 01359 QString::fromLatin1("Simple") ); 01360 if ( viewStyle == QString::fromLatin1("Detail") ) 01361 defaultView |= KFile::Detail; 01362 else 01363 defaultView |= KFile::Simple; 01364 if ( kc->readBoolEntry( QString::fromLatin1("Separate Directories"), 01365 DefaultMixDirsAndFiles ) ) 01366 defaultView |= KFile::SeparateDirs; 01367 if ( kc->readBoolEntry(QString::fromLatin1("Show Preview"), false)) 01368 defaultView |= KFile::PreviewContents; 01369 01370 if ( kc->readBoolEntry( QString::fromLatin1("Sort case insensitively"), 01371 DefaultCaseInsensitive ) ) 01372 sorting |= QDir::IgnoreCase; 01373 if ( kc->readBoolEntry( QString::fromLatin1("Sort directories first"), 01374 DefaultDirsFirst ) ) 01375 sorting |= QDir::DirsFirst; 01376 01377 01378 QString name = QString::fromLatin1("Name"); 01379 QString sortBy = kc->readEntry( QString::fromLatin1("Sort by"), name ); 01380 if ( sortBy == name ) 01381 sorting |= QDir::Name; 01382 else if ( sortBy == QString::fromLatin1("Size") ) 01383 sorting |= QDir::Size; 01384 else if ( sortBy == QString::fromLatin1("Date") ) 01385 sorting |= QDir::Time; 01386 01387 mySorting = static_cast<QDir::SortSpec>( sorting ); 01388 setSorting( mySorting ); 01389 01390 01391 if ( kc->readBoolEntry( QString::fromLatin1("Show hidden files"), 01392 DefaultShowHidden ) ) { 01393 showHiddenAction->setChecked( true ); 01394 dir->setShowingDotFiles( true ); 01395 } 01396 if ( kc->readBoolEntry( QString::fromLatin1("Sort reversed"), 01397 DefaultSortReversed ) ) 01398 reverseAction->setChecked( true ); 01399 01400 kc->setGroup( oldGroup ); 01401 } 01402 01403 void KDirOperator::writeConfig( KConfig *kc, const QString& group ) 01404 { 01405 if ( !kc ) 01406 return; 01407 01408 const QString oldGroup = kc->group(); 01409 01410 if ( !group.isEmpty() ) 01411 kc->setGroup( group ); 01412 01413 QString sortBy = QString::fromLatin1("Name"); 01414 if ( KFile::isSortBySize( mySorting ) ) 01415 sortBy = QString::fromLatin1("Size"); 01416 else if ( KFile::isSortByDate( mySorting ) ) 01417 sortBy = QString::fromLatin1("Date"); 01418 kc->writeEntry( QString::fromLatin1("Sort by"), sortBy ); 01419 01420 kc->writeEntry( QString::fromLatin1("Sort reversed"), 01421 reverseAction->isChecked() ); 01422 kc->writeEntry( QString::fromLatin1("Sort case insensitively"), 01423 caseInsensitiveAction->isChecked() ); 01424 kc->writeEntry( QString::fromLatin1("Sort directories first"), 01425 dirsFirstAction->isChecked() ); 01426 01427 // don't save the separate dirs or preview when an application specific 01428 // preview is in use. 01429 bool appSpecificPreview = false; 01430 if ( myPreview ) { 01431 QWidget *preview = const_cast<QWidget*>( myPreview ); // grmbl 01432 KFileMetaPreview *tmp = dynamic_cast<KFileMetaPreview*>( preview ); 01433 appSpecificPreview = (tmp == 0L); 01434 } 01435 01436 if ( !appSpecificPreview ) { 01437 if ( separateDirsAction->isEnabled() ) 01438 kc->writeEntry( QString::fromLatin1("Separate Directories"), 01439 separateDirsAction->isChecked() ); 01440 01441 KToggleAction *previewAction = static_cast<KToggleAction*>(myActionCollection->action("preview")); 01442 if ( previewAction->isEnabled() ) { 01443 bool hasPreview = previewAction->isChecked(); 01444 kc->writeEntry( QString::fromLatin1("Show Preview"), hasPreview ); 01445 } 01446 } 01447 01448 kc->writeEntry( QString::fromLatin1("Show hidden files"), 01449 showHiddenAction->isChecked() ); 01450 01451 KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind ); 01452 QString style; 01453 if ( KFile::isDetailView( fv ) ) 01454 style = QString::fromLatin1("Detail"); 01455 else if ( KFile::isSimpleView( fv ) ) 01456 style = QString::fromLatin1("Simple"); 01457 kc->writeEntry( QString::fromLatin1("View Style"), style ); 01458 01459 kc->setGroup( oldGroup ); 01460 } 01461 01462 01463 void KDirOperator::resizeEvent( QResizeEvent * ) 01464 { 01465 if (m_fileView) 01466 m_fileView->widget()->resize( size() ); 01467 01468 if ( progress->parent() == this ) // might be reparented into a statusbar 01469 progress->move(2, height() - progress->height() -2); 01470 } 01471 01472 void KDirOperator::setOnlyDoubleClickSelectsFiles( bool enable ) 01473 { 01474 d->onlyDoubleClickSelectsFiles = enable; 01475 if ( m_fileView ) 01476 m_fileView->setOnlyDoubleClickSelectsFiles( enable ); 01477 } 01478 01479 bool KDirOperator::onlyDoubleClickSelectsFiles() const 01480 { 01481 return d->onlyDoubleClickSelectsFiles; 01482 } 01483 01484 void KDirOperator::slotStarted() 01485 { 01486 progress->setProgress( 0 ); 01487 // delay showing the progressbar for one second 01488 d->progressDelayTimer->start( 1000, true ); 01489 } 01490 01491 void KDirOperator::slotShowProgress() 01492 { 01493 progress->raise(); 01494 progress->show(); 01495 QApplication::flushX(); 01496 } 01497 01498 void KDirOperator::slotProgress( int percent ) 01499 { 01500 progress->setProgress( percent ); 01501 // we have to redraw this as fast as possible 01502 if ( progress->isVisible() ) 01503 QApplication::flushX(); 01504 } 01505 01506 01507 void KDirOperator::slotIOFinished() 01508 { 01509 d->progressDelayTimer->stop(); 01510 slotProgress( 100 ); 01511 progress->hide(); 01512 emit finishedLoading(); 01513 resetCursor(); 01514 01515 if ( m_fileView ) 01516 m_fileView->listingCompleted(); 01517 } 01518 01519 void KDirOperator::slotCanceled() 01520 { 01521 emit finishedLoading(); 01522 resetCursor(); 01523 01524 if ( m_fileView ) 01525 m_fileView->listingCompleted(); 01526 } 01527 01528 KProgress * KDirOperator::progressBar() const 01529 { 01530 return progress; 01531 } 01532 01533 void KDirOperator::clearHistory() 01534 { 01535 backStack.clear(); 01536 backAction->setEnabled( false ); 01537 forwardStack.clear(); 01538 forwardAction->setEnabled( false ); 01539 } 01540 01541 void KDirOperator::slotViewActionAdded( KAction *action ) 01542 { 01543 if ( viewActionMenu->popupMenu()->count() == 5 ) // need to add a separator 01544 viewActionMenu->insert( d->viewActionSeparator ); 01545 01546 viewActionMenu->insert( action ); 01547 } 01548 01549 void KDirOperator::slotViewActionRemoved( KAction *action ) 01550 { 01551 viewActionMenu->remove( action ); 01552 01553 if ( viewActionMenu->popupMenu()->count() == 6 ) // remove the separator 01554 viewActionMenu->remove( d->viewActionSeparator ); 01555 } 01556 01557 void KDirOperator::slotViewSortingChanged( QDir::SortSpec sort ) 01558 { 01559 mySorting = sort; 01560 updateSortActions(); 01561 } 01562 01563 void KDirOperator::setEnableDirHighlighting( bool enable ) 01564 { 01565 d->dirHighlighting = enable; 01566 } 01567 01568 bool KDirOperator::dirHighlighting() const 01569 { 01570 return d->dirHighlighting; 01571 } 01572 01573 void KDirOperator::slotProperties() 01574 { 01575 if ( m_fileView ) { 01576 const KFileItemList *list = m_fileView->selectedItems(); 01577 if ( !list->isEmpty() ) 01578 (void) new KPropertiesDialog( *list, this, "props dlg", true); 01579 } 01580 } 01581 01582 void KDirOperator::slotClearView() 01583 { 01584 if ( m_fileView ) 01585 m_fileView->clearView(); 01586 } 01587 01588 // ### temporary code 01589 #include <dirent.h> 01590 bool KDirOperator::isReadable( const KURL& url ) 01591 { 01592 if ( !url.isLocalFile() ) 01593 return true; // what else can we say? 01594 01595 struct stat buf; 01596 QString ts = url.path(+1); 01597 bool readable = ( ::stat( QFile::encodeName( ts ), &buf) == 0 ); 01598 if (readable) { // further checks 01599 DIR *test; 01600 test = opendir( QFile::encodeName( ts )); // we do it just to test here 01601 readable = (test != 0); 01602 if (test) 01603 closedir(test); 01604 } 01605 return readable; 01606 } 01607 01608 void KDirOperator::togglePreview( bool on ) 01609 { 01610 if ( on ) 01611 slotDefaultPreview(); 01612 else 01613 setView( (KFile::FileView) (m_viewKind & ~(KFile::PreviewContents|KFile::PreviewInfo)) ); 01614 } 01615 01616 void KDirOperator::slotRefreshItems( const KFileItemList& items ) 01617 { 01618 if ( !m_fileView ) 01619 return; 01620 01621 KFileItemListIterator it( items ); 01622 for ( ; it.current(); ++it ) 01623 m_fileView->updateView( it.current() ); 01624 } 01625 01626 void KDirOperator::setViewConfig( KConfig *config, const QString& group ) 01627 { 01628 d->config = config; 01629 d->configGroup = group; 01630 } 01631 01632 KConfig * KDirOperator::viewConfig() 01633 { 01634 return d->config; 01635 } 01636 01637 QString KDirOperator::viewConfigGroup() const 01638 { 01639 return d->configGroup; 01640 } 01641 01642 void KDirOperator::virtual_hook( int, void* ) 01643 { /*BASE::virtual_hook( id, data );*/ } 01644 01645 #include "kdiroperator.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:43:51 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003