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