00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "kfilewidget.h"
00028
00029 #include "kfileplacesview.h"
00030 #include "kfileplacesmodel.h"
00031 #include "kfilebookmarkhandler_p.h"
00032 #include "kurlcombobox.h"
00033 #include "kurlnavigator.h"
00034 #include "kfilepreviewgenerator.h"
00035 #include <config-kfile.h>
00036
00037 #include <kactioncollection.h>
00038 #include <kdiroperator.h>
00039 #include <kdirselectdialog.h>
00040 #include <kfilefiltercombo.h>
00041 #include <kimagefilepreview.h>
00042 #include <kmenu.h>
00043 #include <kmimetype.h>
00044 #include <kpushbutton.h>
00045 #include <krecentdocument.h>
00046 #include <ktoolbar.h>
00047 #include <kurlcompletion.h>
00048 #include <kuser.h>
00049 #include <kprotocolmanager.h>
00050 #include <kio/job.h>
00051 #include <kio/jobuidelegate.h>
00052 #include <kio/netaccess.h>
00053 #include <kio/scheduler.h>
00054 #include <krecentdirs.h>
00055 #include <kdebug.h>
00056 #include <kio/kfileitemdelegate.h>
00057
00058 #include <QtGui/QCheckBox>
00059 #include <QtGui/QDockWidget>
00060 #include <QtGui/QLayout>
00061 #include <QtGui/QLabel>
00062 #include <QtGui/QLineEdit>
00063 #include <QtGui/QSplitter>
00064 #include <QtGui/QAbstractProxyModel>
00065 #include <QtCore/QFSFileEngine>
00066 #include <kshell.h>
00067 #include <kmessagebox.h>
00068 #include <kauthorized.h>
00069
00070 class KFileWidgetPrivate
00071 {
00072 public:
00073 KFileWidgetPrivate(KFileWidget *widget)
00074 : q(widget),
00075 boxLayout(0),
00076 placesDock(0),
00077 placesView(0),
00078 placesViewSplitter(0),
00079 placesViewWidth(-1),
00080 labeledCustomWidget(0),
00081 bottomCustomWidget(0),
00082 autoSelectExtCheckBox(0),
00083 operationMode(KFileWidget::Opening),
00084 bookmarkHandler(0),
00085 toolbar(0),
00086 locationEdit(0),
00087 ops(0),
00088 filterWidget(0),
00089 autoSelectExtChecked(false),
00090 keepLocation(false),
00091 hasView(false),
00092 hasDefaultFilter(false),
00093 inAccept(false),
00094 dummyAdded(false),
00095 confirmOverwrite(false),
00096 differentHierarchyLevelItemsEntered(false),
00097 previewGenerator(0),
00098 iconSizeSlider(0)
00099 {
00100 }
00101
00102 ~KFileWidgetPrivate()
00103 {
00104 delete bookmarkHandler;
00105 delete ops;
00106 }
00107
00108 void updateLocationWhatsThis();
00109 void updateAutoSelectExtension();
00110 void initSpeedbar();
00111 void initGUI();
00112 void readConfig(KConfigGroup &configGroup);
00113 void writeConfig(KConfigGroup &configGroup);
00114 void setNonExtSelection();
00115 void setLocationText(const KUrl&);
00116 void setLocationText(const KUrl::List&);
00117 void appendExtension(KUrl &url);
00118 void updateLocationEditExtension(const QString &);
00119 void updateFilter();
00120 KUrl::List& parseSelectedUrls();
00127 KUrl::List tokenize(const QString& line) const;
00131 void readRecentFiles(KConfigGroup &cg);
00135 void saveRecentFiles(KConfigGroup &cg);
00140 void multiSelectionChanged();
00141
00145 KUrl getCompleteUrl(const QString&) const;
00146
00151 void setDummyHistoryEntry(const QString& text, const QPixmap& icon = QPixmap(),
00152 bool usePreviousPixmapIfNull = true);
00153
00157 void removeDummyHistoryEntry();
00158
00165 bool toOverwrite(const KUrl&);
00166
00167
00168 void _k_slotLocationChanged( const QString& );
00169 void _k_urlEntered( const KUrl& );
00170 void _k_enterUrl( const KUrl& );
00171 void _k_enterUrl( const QString& );
00172 void _k_locationAccepted( const QString& );
00173 void _k_slotFilterChanged();
00174 void _k_fileHighlighted( const KFileItem& );
00175 void _k_fileSelected( const KFileItem& );
00176 void _k_slotLoadingFinished();
00177 void _k_fileCompletion( const QString& );
00178 void _k_toggleSpeedbar( bool );
00179 void _k_toggleBookmarks( bool );
00180 void _k_slotAutoSelectExtClicked();
00181 void _k_placesViewSplitterMoved(int, int);
00182 void _k_activateUrlNavigator();
00183 void _k_zoomOutIconsSize();
00184 void _k_zoomInIconsSize();
00185
00186 void addToRecentDocuments();
00187
00188 QString locationEditCurrentText() const;
00189
00195 static KUrl mostLocalUrl(const KUrl &url);
00196
00197 KFileWidget* q;
00198
00199
00200 KUrl url;
00201
00202
00203 QString filenames;
00204
00205
00206
00207 QBoxLayout *boxLayout;
00208 QGridLayout *lafBox;
00209 QVBoxLayout *vbox;
00210
00211 QLabel *locationLabel;
00212 QWidget *opsWidget;
00213 QWidget *pathSpacer;
00214
00215 QLabel *filterLabel;
00216 KUrlNavigator *urlNavigator;
00217 KPushButton *okButton, *cancelButton;
00218 QDockWidget *placesDock;
00219 KFilePlacesView *placesView;
00220 QSplitter *placesViewSplitter;
00221
00222
00223
00224 int placesViewWidth;
00225
00226 QWidget *labeledCustomWidget;
00227 QWidget *bottomCustomWidget;
00228
00229
00230 QCheckBox *autoSelectExtCheckBox;
00231 QString extension;
00232
00233 QList<KIO::StatJob*> statJobs;
00234
00235 KUrl::List urlList;
00236
00237 KFileWidget::OperationMode operationMode;
00238
00239
00240 QString fileClass;
00241
00242 KFileBookmarkHandler *bookmarkHandler;
00243
00244 KActionMenu* bookmarkButton;
00245
00246 KToolBar *toolbar;
00247 KUrlComboBox *locationEdit;
00248 KDirOperator *ops;
00249 KFileFilterCombo *filterWidget;
00250
00251 KFilePlacesModel *model;
00252
00253
00254 bool autoSelectExtChecked : 1;
00255
00256
00257
00258 bool keepLocation : 1;
00259
00260
00261
00262 bool hasView : 1;
00263
00264 bool hasDefaultFilter : 1;
00265 bool autoDirectoryFollowing : 1;
00266 bool inAccept : 1;
00267 bool dummyAdded : 1;
00268
00269 bool confirmOverwrite : 1;
00270 bool differentHierarchyLevelItemsEntered;
00271
00272 KFilePreviewGenerator *previewGenerator;
00273 QSlider *iconSizeSlider;
00274 };
00275
00276 K_GLOBAL_STATIC(KUrl, lastDirectory)
00277
00278 static const char autocompletionWhatsThisText[] = I18N_NOOP("<qt>While typing in the text area, you may be presented "
00279 "with possible matches. "
00280 "This feature can be controlled by clicking with the right mouse button "
00281 "and selecting a preferred mode from the <b>Text Completion</b> menu.") "</qt>";
00282
00283
00284 static bool containsProtocolSection( const QString& string )
00285 {
00286 int len = string.length();
00287 static const char prot[] = ":/";
00288 for (int i=0; i < len;) {
00289 i = string.indexOf( QLatin1String(prot), i );
00290 if (i == -1)
00291 return false;
00292 int j=i-1;
00293 for (; j >= 0; j--) {
00294 const QChar& ch( string[j] );
00295 if (ch.toAscii() == 0 || !ch.isLetter())
00296 break;
00297 if (ch.isSpace() && (i-j-1) >= 2)
00298 return true;
00299 }
00300 if (j < 0 && i >= 2)
00301 return true;
00302 i += 3;
00303 }
00304 return false;
00305 }
00306
00307 KFileWidget::KFileWidget( const KUrl& _startDir, QWidget *parent )
00308 : QWidget(parent), KAbstractFileWidget(), d(new KFileWidgetPrivate(this))
00309 {
00310 KUrl startDir(_startDir);
00311 QString filename;
00312
00313 d->okButton = new KPushButton(KStandardGuiItem::ok(), this);
00314 d->okButton->setDefault(true);
00315 d->cancelButton = new KPushButton(KStandardGuiItem::cancel(), this);
00316
00317 d->okButton->hide();
00318 d->cancelButton->hide();
00319
00320 d->opsWidget = new QWidget(this);
00321 QVBoxLayout *opsWidgetLayout = new QVBoxLayout(d->opsWidget);
00322 opsWidgetLayout->setMargin(0);
00323
00324 d->toolbar = new KToolBar(d->opsWidget, true);
00325 d->toolbar->setObjectName("KFileWidget::toolbar");
00326 d->toolbar->setMovable(false);
00327 opsWidgetLayout->addWidget(d->toolbar);
00328
00329 d->model = new KFilePlacesModel(this);
00330 d->urlNavigator = new KUrlNavigator(d->model, startDir, d->opsWidget);
00331 d->urlNavigator->setPlacesSelectorVisible(false);
00332 opsWidgetLayout->addWidget(d->urlNavigator);
00333
00334 KUrl u;
00335 KUrlComboBox *pathCombo = d->urlNavigator->editor();
00336 #ifdef Q_WS_WIN
00337 foreach( const QFileInfo &drive,QFSFileEngine::drives() )
00338 {
00339 u.setPath( drive.filePath() );
00340 pathCombo->addDefaultUrl(u,
00341 KIO::pixmapForUrl( u, 0, KIconLoader::Small ),
00342 i18n("Drive: %1", u.toLocalFile()));
00343 }
00344 #else
00345 u.setPath(QDir::rootPath());
00346 pathCombo->addDefaultUrl(u,
00347 KIO::pixmapForUrl(u, 0, KIconLoader::Small),
00348 u.toLocalFile());
00349 #endif
00350
00351 u.setPath(QDir::homePath());
00352 pathCombo->addDefaultUrl(u, KIO::pixmapForUrl(u, 0, KIconLoader::Small),
00353 u.path(KUrl::AddTrailingSlash));
00354
00355 KUrl docPath;
00356 docPath.setPath( KGlobalSettings::documentPath() );
00357 if ( (u.path(KUrl::AddTrailingSlash) != docPath.path(KUrl::AddTrailingSlash)) &&
00358 QDir(docPath.path(KUrl::AddTrailingSlash)).exists() )
00359 {
00360 pathCombo->addDefaultUrl( docPath,
00361 KIO::pixmapForUrl( docPath, 0, KIconLoader::Small ),
00362 docPath.path(KUrl::AddTrailingSlash));
00363 }
00364
00365 u.setPath( KGlobalSettings::desktopPath() );
00366 pathCombo->addDefaultUrl(u,
00367 KIO::pixmapForUrl(u, 0, KIconLoader::Small),
00368 u.path(KUrl::AddTrailingSlash));
00369
00370 KIO::StatJob *statJob = KIO::stat(startDir, KIO::HideProgressInfo);
00371 bool res = KIO::NetAccess::synchronousRun(statJob, 0);
00372 if (res) {
00373 if (!statJob->statResult().isDir()) {
00374 startDir.adjustPath(KUrl::RemoveTrailingSlash);
00375 filename = startDir.fileName();
00376 startDir.setFileName(QString());
00377 }
00378 }
00379
00380 d->url = getStartUrl( startDir, d->fileClass );
00381
00382 d->ops = new KDirOperator(d->url, d->opsWidget);
00383 d->ops->setObjectName( "KFileWidget::ops" );
00384 opsWidgetLayout->addWidget(d->ops);
00385 connect(d->ops, SIGNAL(urlEntered(const KUrl&)),
00386 SLOT(_k_urlEntered(const KUrl&)));
00387 connect(d->ops, SIGNAL(fileHighlighted(const KFileItem &)),
00388 SLOT(_k_fileHighlighted(const KFileItem &)));
00389 connect(d->ops, SIGNAL(fileSelected(const KFileItem &)),
00390 SLOT(_k_fileSelected(const KFileItem &)));
00391 connect(d->ops, SIGNAL(finishedLoading()),
00392 SLOT(_k_slotLoadingFinished()));
00393
00394 d->ops->setupMenu(KDirOperator::SortActions |
00395 KDirOperator::FileActions |
00396 KDirOperator::ViewActions);
00397 KActionCollection *coll = d->ops->actionCollection();
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 coll->action( "up" )->setWhatsThis(i18n("<qt>Click this button to enter the parent folder.<br /><br />"
00408 "For instance, if the current location is file:/home/%1 clicking this "
00409 "button will take you to file:/home.</qt>", KUser().loginName() ));
00410
00411 coll->action( "back" )->setWhatsThis(i18n("Click this button to move backwards one step in the browsing history."));
00412 coll->action( "forward" )->setWhatsThis(i18n("Click this button to move forward one step in the browsing history."));
00413
00414 coll->action( "reload" )->setWhatsThis(i18n("Click this button to reload the contents of the current location."));
00415 coll->action( "mkdir" )->setShortcut( QKeySequence(Qt::Key_F10) );
00416 coll->action( "mkdir" )->setWhatsThis(i18n("Click this button to create a new folder."));
00417
00418 KAction *goToNavigatorAction = coll->addAction( "gotonavigator", this, SLOT( _k_activateUrlNavigator() ) );
00419 goToNavigatorAction->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_L) );
00420
00421 KToggleAction *showSidebarAction =
00422 new KToggleAction(i18n("Show Places Navigation Panel"), this);
00423 coll->addAction("toggleSpeedbar", showSidebarAction);
00424 showSidebarAction->setShortcut( QKeySequence(Qt::Key_F9) );
00425 connect( showSidebarAction, SIGNAL( toggled( bool ) ),
00426 SLOT( _k_toggleSpeedbar( bool )) );
00427
00428 KToggleAction *showBookmarksAction =
00429 new KToggleAction(i18n("Show Bookmarks"), this);
00430 coll->addAction("toggleBookmarks", showBookmarksAction);
00431 connect( showBookmarksAction, SIGNAL( toggled( bool ) ),
00432 SLOT( _k_toggleBookmarks( bool )) );
00433
00434 KActionMenu *menu = new KActionMenu( KIcon("configure"), i18n("Options"), this);
00435 coll->addAction("extra menu", menu);
00436 menu->setWhatsThis(i18n("<qt>This is the preferences menu for the file dialog. "
00437 "Various options can be accessed from this menu including: <ul>"
00438 "<li>how files are sorted in the list</li>"
00439 "<li>types of view, including icon and list</li>"
00440 "<li>showing of hidden files</li>"
00441 "<li>the Places navigation panel</li>"
00442 "<li>file previews</li>"
00443 "<li>separating folders from files</li></ul></qt>"));
00444 menu->addAction(coll->action("sorting menu"));
00445 menu->addAction(coll->action("view menu"));
00446 menu->addSeparator();
00447 menu->addAction(coll->action("decoration menu"));
00448 menu->addSeparator();
00449 coll->action( "show hidden" )->setShortcut( QKeySequence(Qt::Key_F8) );
00450 menu->addAction( coll->action( "show hidden" ));
00451 menu->addAction( showSidebarAction );
00452 menu->addAction( showBookmarksAction );
00453 coll->action( "inline preview" )->setShortcut( QKeySequence(Qt::Key_F11) );
00454 menu->addAction( coll->action( "preview" ));
00455
00456 menu->setDelayed( false );
00457 connect( menu->menu(), SIGNAL( aboutToShow() ),
00458 d->ops, SLOT( updateSelectionDependentActions() ));
00459
00460 d->iconSizeSlider = new QSlider(this);
00461 d->iconSizeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
00462 d->iconSizeSlider->setOrientation(Qt::Horizontal);
00463 d->iconSizeSlider->setMinimum(0);
00464 d->iconSizeSlider->setMaximum(100);
00465 connect(d->iconSizeSlider, SIGNAL(valueChanged(int)),
00466 d->ops, SLOT(setIconsZoom(int)));
00467 connect(d->ops, SIGNAL(currentIconSizeChanged(int)),
00468 d->iconSizeSlider, SLOT(setValue(int)));
00469
00470 KAction *furtherAction = new KAction(KIcon("zoom-out"), i18n("Zoom out"), this);
00471 connect(furtherAction, SIGNAL(triggered()), SLOT(_k_zoomOutIconsSize()));
00472 KAction *closerAction = new KAction(KIcon("zoom-in"), i18n("Zoom in"), this);
00473 connect(closerAction, SIGNAL(triggered()), SLOT(_k_zoomInIconsSize()));
00474
00475 QWidget *midSpacer = new QWidget(this);
00476 midSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00477
00478 QAction *separator = new QAction(this);
00479 separator->setSeparator(true);
00480
00481 QAction *separator2 = new QAction(this);
00482 separator2->setSeparator(true);
00483
00484 QAction *separator3 = new QAction(this);
00485 separator3->setSeparator(true);
00486
00487 d->toolbar->addAction(coll->action("back" ));
00488 d->toolbar->addAction(coll->action("forward"));
00489 d->toolbar->addAction(coll->action("up"));
00490 d->toolbar->addAction(coll->action("reload"));
00491 d->toolbar->addAction(separator);
00492 d->toolbar->addAction(coll->action("short view"));
00493 d->toolbar->addAction(coll->action("detailed view"));
00494 d->toolbar->addAction(separator2);
00495 d->toolbar->addAction(coll->action("inline preview"));
00496 d->toolbar->addWidget(midSpacer);
00497 d->toolbar->addAction(furtherAction);
00498 d->toolbar->addWidget(d->iconSizeSlider);
00499 d->toolbar->addAction(closerAction);
00500 d->toolbar->addAction(separator3);
00501 d->toolbar->addAction(coll->action("mkdir"));
00502 d->toolbar->addAction(menu);
00503
00504 d->toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
00505 d->toolbar->setMovable(false);
00506
00507 KUrlCompletion *pathCompletionObj = new KUrlCompletion( KUrlCompletion::DirCompletion );
00508 pathCombo->setCompletionObject( pathCompletionObj );
00509 pathCombo->setAutoDeleteCompletionObject( true );
00510
00511 connect( d->urlNavigator, SIGNAL( urlChanged( const KUrl& )),
00512 this, SLOT( _k_enterUrl( const KUrl& ) ));
00513 connect( d->urlNavigator, SIGNAL( returnPressed() ),
00514 d->ops, SLOT( setFocus() ));
00515
00516 QString whatsThisText;
00517
00518
00519 d->locationLabel = new QLabel(i18n("&Name:"), this);
00520 d->locationEdit = new KUrlComboBox(KUrlComboBox::Files, true, this);
00521
00522
00523
00524 d->locationEdit->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
00525 connect( d->locationEdit, SIGNAL( editTextChanged( const QString& ) ),
00526 SLOT( _k_slotLocationChanged( const QString& )) );
00527
00528 d->updateLocationWhatsThis();
00529 d->locationLabel->setBuddy(d->locationEdit);
00530
00531 KUrlCompletion *fileCompletionObj = new KUrlCompletion( KUrlCompletion::FileCompletion );
00532 d->locationEdit->setCompletionObject( fileCompletionObj );
00533 d->locationEdit->setAutoDeleteCompletionObject( true );
00534 connect( fileCompletionObj, SIGNAL( match( const QString& ) ),
00535 SLOT( _k_fileCompletion( const QString& )) );
00536
00537 connect(d->locationEdit, SIGNAL( returnPressed( const QString& )),
00538 this, SLOT( _k_locationAccepted( const QString& ) ));
00539
00540
00541 whatsThisText = i18n("<qt>This is the filter to apply to the file list. "
00542 "File names that do not match the filter will not be shown.<p>"
00543 "You may select from one of the preset filters in the "
00544 "drop down menu, or you may enter a custom filter "
00545 "directly into the text area.</p><p>"
00546 "Wildcards such as * and ? are allowed.</p></qt>");
00547 d->filterLabel = new QLabel(i18n("&Filter:"), this);
00548 d->filterLabel->setWhatsThis(whatsThisText);
00549 d->filterWidget = new KFileFilterCombo(this);
00550
00551
00552
00553 d->filterWidget->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
00554 d->filterWidget->setWhatsThis(whatsThisText);
00555 d->filterLabel->setBuddy(d->filterWidget);
00556 connect(d->filterWidget, SIGNAL(filterChanged()), SLOT(_k_slotFilterChanged()));
00557
00558
00559
00560 d->autoSelectExtCheckBox = new QCheckBox (this);
00561 d->autoSelectExtCheckBox->setStyleSheet(QString("QCheckBox { padding-top: %1px; }").arg(KDialog::spacingHint()));
00562 connect(d->autoSelectExtCheckBox, SIGNAL(clicked()), SLOT(_k_slotAutoSelectExtClicked()));
00563
00564 d->initGUI();
00565
00566
00567 KSharedConfig::Ptr config = KGlobal::config();
00568 KConfigGroup viewConfigGroup(config, ConfigGroup);
00569 d->readConfig(viewConfigGroup);
00570
00571 coll->action("inline preview")->setChecked(d->ops->isInlinePreviewShown());
00572 d->iconSizeSlider->setValue(d->ops->iconsZoom());
00573
00574 KFilePreviewGenerator *pg = d->ops->previewGenerator();
00575 if (pg) {
00576 coll->action("inline preview")->setChecked(pg->isPreviewShown());
00577 }
00578
00579
00580 if (!filename.isEmpty()) {
00581 d->locationEdit->lineEdit()->setText(filename);
00582 }
00583
00584 d->locationEdit->setFocus();
00585 }
00586
00587 KFileWidget::~KFileWidget()
00588 {
00589 KSharedConfig::Ptr config = KGlobal::config();
00590 config->sync();
00591
00592 delete d;
00593 }
00594
00595 void KFileWidget::setLocationLabel(const QString& text)
00596 {
00597 d->locationLabel->setText(text);
00598 }
00599
00600 void KFileWidget::setFilter(const QString& filter)
00601 {
00602 int pos = filter.indexOf('/');
00603
00604
00605
00606
00607 if (pos > 0 && filter[pos - 1] != '\\') {
00608 QStringList filters = filter.split(" ", QString::SkipEmptyParts);
00609 setMimeFilter( filters );
00610 return;
00611 }
00612
00613
00614
00615
00616 QString copy (filter);
00617 for (pos = 0; (pos = copy.indexOf("\\/", pos)) != -1; ++pos)
00618 copy.remove(pos, 1);
00619
00620 d->ops->clearFilter();
00621 d->filterWidget->setFilter(copy);
00622 d->ops->setNameFilter(d->filterWidget->currentFilter());
00623 d->hasDefaultFilter = false;
00624 d->filterWidget->setEditable( true );
00625
00626 d->updateAutoSelectExtension ();
00627 }
00628
00629 QString KFileWidget::currentFilter() const
00630 {
00631 return d->filterWidget->currentFilter();
00632 }
00633
00634 void KFileWidget::setMimeFilter( const QStringList& mimeTypes,
00635 const QString& defaultType )
00636 {
00637 d->filterWidget->setMimeFilter( mimeTypes, defaultType );
00638
00639 QStringList types = d->filterWidget->currentFilter().split(" ",QString::SkipEmptyParts);
00640 types.append( QLatin1String( "inode/directory" ));
00641 d->ops->clearFilter();
00642 d->ops->setMimeFilter( types );
00643 d->hasDefaultFilter = !defaultType.isEmpty();
00644 d->filterWidget->setEditable( !d->hasDefaultFilter ||
00645 d->operationMode != Saving );
00646
00647 d->updateAutoSelectExtension ();
00648 }
00649
00650 void KFileWidget::clearFilter()
00651 {
00652 d->filterWidget->setFilter( QString() );
00653 d->ops->clearFilter();
00654 d->hasDefaultFilter = false;
00655 d->filterWidget->setEditable( true );
00656
00657 d->updateAutoSelectExtension ();
00658 }
00659
00660 QString KFileWidget::currentMimeFilter() const
00661 {
00662 int i = d->filterWidget->currentIndex();
00663 if (d->filterWidget->showsAllTypes() && i == 0)
00664 return QString();
00665
00666 return d->filterWidget->filters()[i];
00667 }
00668
00669 KMimeType::Ptr KFileWidget::currentFilterMimeType()
00670 {
00671 return KMimeType::mimeType( currentMimeFilter() );
00672 }
00673
00674 void KFileWidget::setPreviewWidget(KPreviewWidgetBase *w) {
00675 d->ops->setPreviewWidget(w);
00676 d->ops->clearHistory();
00677 d->hasView = true;
00678 }
00679
00680 KUrl KFileWidgetPrivate::getCompleteUrl(const QString &_url) const
00681 {
00682
00683
00684 QString url = KShell::tildeExpand(_url);
00685 KUrl u;
00686
00687 if ( KUrl::isRelativeUrl(url) )
00688 {
00689 if (!url.isEmpty() && !QDir::isRelativePath(url) )
00690 u.setPath( url );
00691 else
00692 {
00693 u = ops->url();
00694
00695 u.addPath( url );
00696
00697 u.cleanPath();
00698
00699 }
00700 }
00701 else
00702 u = url;
00703
00704
00705
00706 return u;
00707 }
00708
00709
00710 void KFileWidget::slotOk()
00711 {
00712
00713
00714 const KFileItemList items = d->ops->selectedItems();
00715 const QString locationEditCurrentText(KShell::tildeExpand(d->locationEditCurrentText()));
00716 KUrl::List locationEditCurrentTextList(d->tokenize(locationEditCurrentText));
00717 KFile::Modes mode = d->ops->mode();
00718
00719
00720 if (!locationEditCurrentTextList.count()) {
00721 return;
00722 }
00723
00724
00725 Q_ASSERT((mode & KFile::File) || (mode & KFile::Directory) || (mode & KFile::Files));
00726
00727
00728
00729 if (locationEditCurrentTextList.count() > 1) {
00730 if (mode & KFile::File) {
00731 KMessageBox::sorry(this,
00732 i18n("You can only select one file"),
00733 i18n("More than one file provided"));
00734 return;
00735 }
00736
00757 if (!d->differentHierarchyLevelItemsEntered) {
00758 KUrl::List urlList;
00759 int start = 0;
00760 KUrl topMostUrl;
00761 KIO::StatJob *statJob;
00762 bool res = false;
00763
00764
00765
00766
00767
00768 while (!res && start < locationEditCurrentTextList.count()) {
00769 topMostUrl = locationEditCurrentTextList.at(start);
00770 statJob = KIO::stat(topMostUrl, KIO::HideProgressInfo);
00771 res = KIO::NetAccess::synchronousRun(statJob, 0);
00772 start++;
00773 }
00774
00775
00776
00777 if (!statJob->statResult().isDir()) {
00778 topMostUrl.setFileName(QString());
00779 }
00780
00781
00782
00783 for (int i = start; i < locationEditCurrentTextList.count(); ++i) {
00784 KUrl currUrl = locationEditCurrentTextList.at(i);
00785 KIO::StatJob *statJob = KIO::stat(currUrl, KIO::HideProgressInfo);
00786 bool res = KIO::NetAccess::synchronousRun(statJob, 0);
00787 if (res) {
00788
00789 if (!statJob->statResult().isDir()) {
00790 currUrl.setFileName(QString());
00791 }
00792
00793
00794 while (!topMostUrl.isParentOf(currUrl)) {
00795 topMostUrl = topMostUrl.upUrl();
00796 }
00797 }
00798 }
00799
00800
00801 for (int i = 0; i < locationEditCurrentTextList.count(); ++i) {
00802 locationEditCurrentTextList[i] = KUrl::relativeUrl(topMostUrl, locationEditCurrentTextList[i]);
00803 }
00804
00805 d->ops->setUrl(topMostUrl, true);
00806 const bool signalsBlocked = d->locationEdit->lineEdit()->blockSignals(true);
00807 QStringList stringList;
00808 foreach (const KUrl &url, locationEditCurrentTextList) {
00809 stringList << url.prettyUrl();
00810 }
00811 d->locationEdit->lineEdit()->setText(QString("\"%1\"").arg(stringList.join("\" \"")));
00812 d->locationEdit->lineEdit()->blockSignals(signalsBlocked);
00813
00814 d->differentHierarchyLevelItemsEntered = true;
00815 slotOk();
00816 return;
00817 }
00821 } else if (locationEditCurrentTextList.count()) {
00822
00823
00824 if (!(mode & KFile::Directory) && (!KUrl::isRelativeUrl(locationEditCurrentText) ||
00825 QDir::isAbsolutePath(locationEditCurrentText))) {
00826 KUrl _url(locationEditCurrentText);
00827 KUrl url(_url.path(KUrl::RemoveTrailingSlash));
00828 url.setFileName(QString());
00829 d->ops->setUrl(url, true);
00830 const bool signalsBlocked = d->locationEdit->lineEdit()->blockSignals(true);
00831 d->locationEdit->lineEdit()->setText(_url.fileName());
00832 d->locationEdit->lineEdit()->blockSignals(signalsBlocked);
00833 slotOk();
00834 return;
00835 }
00836 }
00837
00838
00839 d->differentHierarchyLevelItemsEntered = false;
00840
00841
00842 if ((mode & KFile::LocalOnly) && !d->mostLocalUrl(d->url).isLocalFile()) {
00843 KMessageBox::sorry(this,
00844 i18n("You can only select local files"),
00845 i18n("Remote files not accepted"));
00846 return;
00847 }
00848
00849
00850
00851
00852 bool directoryMode = (mode & KFile::Directory);
00853 bool onlyDirectoryMode = directoryMode && !(mode & KFile::File) && !(mode & KFile::Files);
00854 foreach (const KUrl &url, locationEditCurrentTextList) {
00855 d->url = url;
00856 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
00857 bool res = KIO::NetAccess::synchronousRun(statJob, 0);
00858
00859 if (!KAuthorized::authorizeUrlAction("open", KUrl(), url)) {
00860 QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, d->url.prettyUrl());
00861 KMessageBox::error(this, msg);
00862 return;
00863 }
00864
00865 if ((d->operationMode == Saving) && d->confirmOverwrite && !d->toOverwrite(url)) {
00866 return;
00867 }
00868
00869
00870 if (res && !directoryMode && statJob->