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 <config-kfile.h>
00035
00036 #include <kactioncollection.h>
00037 #include <kdiroperator.h>
00038 #include <kdirselectdialog.h>
00039 #include <kfilefiltercombo.h>
00040 #include <kimagefilepreview.h>
00041 #include <kmenu.h>
00042 #include <kmimetype.h>
00043 #include <kpushbutton.h>
00044 #include <krecentdocument.h>
00045 #include <ktoolbar.h>
00046 #include <kurlcompletion.h>
00047 #include <kuser.h>
00048 #include <kprotocolmanager.h>
00049 #include <kio/job.h>
00050 #include <kio/jobuidelegate.h>
00051 #include <kio/netaccess.h>
00052 #include <kio/scheduler.h>
00053 #include <krecentdirs.h>
00054 #include <kdebug.h>
00055
00056 #include <QtGui/QCheckBox>
00057 #include <QtGui/QLayout>
00058 #include <QtGui/QLabel>
00059 #include <QtGui/QLineEdit>
00060 #include <QtGui/QSplitter>
00061 #include <QtCore/QFSFileEngine>
00062 #include <kshell.h>
00063 #include <kmessagebox.h>
00064 #include <kauthorized.h>
00065
00066 class KFileWidgetPrivate
00067 {
00068 public:
00069 KFileWidgetPrivate( KFileWidget* q )
00070 : boxLayout(0),
00071 labeledCustomWidget(0),
00072 bottomCustomWidget(0),
00073 speedBarWidth(-1),
00074 inAccept(false),
00075 dummyAdded(false),
00076 q(q)
00077 {
00078 }
00079 void updateLocationWhatsThis();
00080 void updateAutoSelectExtension();
00081 void initSpeedbar();
00082 void initGUI();
00083 void readConfig(const KConfigGroup &configGroup);
00084 void writeConfig(KConfigGroup &configGroup);
00085 void setNonExtSelection();
00086 void setLocationText(const KUrl&);
00087 void setLocationText(const KUrl::List&);
00088 void appendExtension(KUrl &url);
00089 void updateLocationEditExtension(const QString &);
00090 void updateFilter();
00091 void updateSplitterSize();
00092 KUrl::List& parseSelectedUrls();
00099 KUrl::List tokenize(const QString& line) const;
00103 void readRecentFiles( KConfig * );
00107 void saveRecentFiles( KConfig * );
00112 void multiSelectionChanged();
00113
00117 KUrl getCompleteUrl(const QString&) const;
00118
00123 void setDummyHistoryEntry(const QString& text, const QPixmap& icon = QPixmap(),
00124 bool usePreviousPixmapIfNull = true);
00125
00129 void removeDummyHistoryEntry();
00130
00131
00132 void _k_slotLocationChanged( const QString& );
00133 void _k_urlEntered( const KUrl& );
00134 void _k_enterUrl( const KUrl& );
00135 void _k_enterUrl( const QString& );
00136 void _k_locationAccepted( const QString& );
00137 void _k_locationActivated( const QString& );
00138 void _k_slotFilterChanged();
00139 void _k_fileHighlighted( const KFileItem& );
00140 void _k_fileSelected( const KFileItem& );
00141 void _k_slotStatResult( KJob* );
00142 void _k_slotLoadingFinished();
00143 void _k_fileCompletion( const QString& );
00144 void _k_toggleSpeedbar( bool );
00145 void _k_toggleBookmarks( bool );
00146 void _k_slotAutoSelectExtClicked();
00147 void _k_placesViewSplitterMoved();
00148
00149 void addToRecentDocuments();
00150
00151 QString locationEditCurrentText() const;
00152
00153
00154 KUrl url;
00155
00156
00157 QString filenames;
00158
00159
00160 QString selection;
00161
00162
00163
00164 QBoxLayout *boxLayout;
00165 QGridLayout *lafBox;
00166 QVBoxLayout *vbox;
00167
00168 QLabel *locationLabel;
00169
00170
00171 QLabel *filterLabel;
00172 KUrlNavigator *urlNavigator;
00173 KPushButton *okButton, *cancelButton;
00174 KFilePlacesView *placesView;
00175 QSplitter *placesViewSplitter;
00176 QWidget *labeledCustomWidget;
00177 QWidget *bottomCustomWidget;
00178
00179
00180 QCheckBox *autoSelectExtCheckBox;
00181 bool autoSelectExtChecked;
00182 QString extension;
00183
00184 QList<KIO::StatJob*> statJobs;
00185
00186 KUrl::List urlList;
00187
00188 QStringList mimetypes;
00189
00190
00191
00192
00193 int speedBarWidth;
00194
00195
00196
00197 bool keepLocation;
00198
00199
00200
00201 bool hasView;
00202
00203 bool hasDefaultFilter;
00204 bool autoDirectoryFollowing;
00205 bool inAccept;
00206 bool dummyAdded;
00207
00208
00209 KFileWidget::OperationMode operationMode;
00210
00211
00212 QString fileClass;
00213
00214 KFileBookmarkHandler *bookmarkHandler;
00215
00216 KActionMenu* bookmarkButton;
00217 KConfigGroup *viewConfigGroup;
00218
00219 KToolBar *toolbar;
00220 KUrlComboBox *locationEdit;
00221 KDirOperator *ops;
00222 KFileFilterCombo *filterWidget;
00223 KFileWidget* q;
00224
00225 KFilePlacesModel *model;
00226 };
00227
00228 K_GLOBAL_STATIC(KUrl, lastDirectory)
00229
00230 static const char autocompletionWhatsThisText[] = I18N_NOOP("<qt>While typing in the text area, you may be presented "
00231 "with possible matches. "
00232 "This feature can be controlled by clicking with the right mouse button "
00233 "and selecting a preferred mode from the <b>Text Completion</b> menu.") "</qt>";
00234
00235
00236 static bool containsProtocolSection( const QString& string )
00237 {
00238 int len = string.length();
00239 static const char prot[] = ":/";
00240 for (int i=0; i < len;) {
00241 i = string.indexOf( QLatin1String(prot), i );
00242 if (i == -1)
00243 return false;
00244 int j=i-1;
00245 for (; j >= 0; j--) {
00246 const QChar& ch( string[j] );
00247 if (ch.toAscii() == 0 || !ch.isLetter())
00248 break;
00249 if (ch.isSpace() && (i-j-1) >= 2)
00250 return true;
00251 }
00252 if (j < 0 && i >= 2)
00253 return true;
00254 i += 3;
00255 }
00256 return false;
00257 }
00258
00259 KFileWidget::KFileWidget( const KUrl& startDir, QWidget *parent )
00260 : QWidget(parent), KAbstractFileWidget(), d(new KFileWidgetPrivate(this))
00261 {
00262
00263 d->keepLocation = false;
00264 d->operationMode = Opening;
00265 d->bookmarkHandler = 0;
00266 d->hasDefaultFilter = false;
00267 d->hasView = false;
00268
00269 d->okButton = new KPushButton(KStandardGuiItem::ok(), this);
00270 d->okButton->setDefault( true );
00271 d->cancelButton = new KPushButton(KStandardGuiItem::cancel(), this);
00272
00273 d->okButton->hide();
00274 d->cancelButton->hide();
00275
00276 d->autoSelectExtCheckBox = 0;
00277 d->autoSelectExtChecked = false;
00278 d->placesView = 0;
00279
00280 d->toolbar = new KToolBar(this, true);
00281 d->toolbar->setObjectName("KFileWidget::toolbar");
00282 d->toolbar->setMovable(false);
00283
00284 d->model = new KFilePlacesModel(this);
00285 d->urlNavigator = new KUrlNavigator(d->model, startDir, d->toolbar);
00286 d->urlNavigator->setPlacesSelectorVisible(false);
00287
00288 KUrl u;
00289 KUrlComboBox *pathCombo = d->urlNavigator->editor();
00290 #ifdef Q_WS_WIN
00291 foreach( const QFileInfo &drive,QFSFileEngine::drives() )
00292 {
00293 u.setPath( drive.filePath() );
00294 pathCombo->addDefaultUrl(u,
00295 KIO::pixmapForUrl( u, 0, KIconLoader::Small ),
00296 i18n("Drive: %1", u.toLocalFile()));
00297 }
00298 #else
00299 u.setPath(QDir::rootPath());
00300 pathCombo->addDefaultUrl(u,
00301 KIO::pixmapForUrl(u, 0, KIconLoader::Small),
00302 u.toLocalFile());
00303 #endif
00304
00305 u.setPath(QDir::homePath());
00306 pathCombo->addDefaultUrl(u, KIO::pixmapForUrl(u, 0, KIconLoader::Small),
00307 u.path(KUrl::AddTrailingSlash));
00308
00309 KUrl docPath;
00310 docPath.setPath( KGlobalSettings::documentPath() );
00311 if ( (u.path(KUrl::AddTrailingSlash) != docPath.path(KUrl::AddTrailingSlash)) &&
00312 QDir(docPath.path(KUrl::AddTrailingSlash)).exists() )
00313 {
00314 pathCombo->addDefaultUrl( docPath,
00315 KIO::pixmapForUrl( docPath, 0, KIconLoader::Small ),
00316 docPath.path(KUrl::AddTrailingSlash));
00317 }
00318
00319 u.setPath( KGlobalSettings::desktopPath() );
00320 pathCombo->addDefaultUrl(u,
00321 KIO::pixmapForUrl(u, 0, KIconLoader::Small),
00322 u.path(KUrl::AddTrailingSlash));
00323
00324 d->url = getStartUrl( startDir, d->fileClass );
00325 d->selection = d->url.url();
00326
00327
00328 if ( d->url.isLocalFile() )
00329 {
00330 if ( !QFile::exists( d->url.toLocalFile() ) )
00331 {
00332 d->url = d->url.upUrl();
00333 QDir dir( d->url.toLocalFile() );
00334 while ( !dir.exists() )
00335 {
00336 d->url = d->url.upUrl();
00337 dir.setPath( d->url.toLocalFile() );
00338 }
00339 }
00340 }
00341
00342 d->ops = new KDirOperator(d->url, this );
00343 d->ops->setObjectName( "KFileWidget::ops" );
00344 d->ops->setOnlyDoubleClickSelectsFiles( true );
00345 connect(d->ops, SIGNAL(urlEntered(const KUrl&)),
00346 SLOT(_k_urlEntered(const KUrl&)));
00347 connect(d->ops, SIGNAL(fileHighlighted(const KFileItem &)),
00348 SLOT(_k_fileHighlighted(const KFileItem &)));
00349 connect(d->ops, SIGNAL(fileSelected(const KFileItem &)),
00350 SLOT(_k_fileSelected(const KFileItem &)));
00351 connect(d->ops, SIGNAL(finishedLoading()),
00352 SLOT(_k_slotLoadingFinished()));
00353
00354 d->ops->setupMenu(KDirOperator::SortActions |
00355 KDirOperator::FileActions |
00356 KDirOperator::ViewActions);
00357 KActionCollection *coll = d->ops->actionCollection();
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 d->toolbar->addAction( coll->action( "up" ) );
00368 coll->action( "up" )->setWhatsThis(i18n("<qt>Click this button to enter the parent folder.<br /><br />"
00369 "For instance, if the current location is file:/home/%1 clicking this "
00370 "button will take you to file:/home.</qt>", KUser().loginName() ));
00371
00372 d->toolbar->addAction( coll->action( "back" ) );
00373 coll->action( "back" )->setWhatsThis(i18n("Click this button to move backwards one step in the browsing history."));
00374 d->toolbar->addAction( coll->action( "forward" ) );
00375 coll->action( "forward" )->setWhatsThis(i18n("Click this button to move forward one step in the browsing history."));
00376
00377 d->toolbar->addAction( coll->action( "reload" ) );
00378 coll->action( "reload" )->setWhatsThis(i18n("Click this button to reload the contents of the current location."));
00379 coll->action( "mkdir" )->setShortcut( QKeySequence(Qt::Key_F10) );
00380 d->toolbar->addAction( coll->action( "mkdir" ) );
00381 coll->action( "mkdir" )->setWhatsThis(i18n("Click this button to create a new folder."));
00382
00383 KToggleAction *showSidebarAction =
00384 new KToggleAction(i18n("Show Places Navigation Panel"), this);
00385 coll->addAction("toggleSpeedbar", showSidebarAction);
00386 showSidebarAction->setShortcut( QKeySequence(Qt::Key_F9) );
00387 connect( showSidebarAction, SIGNAL( toggled( bool ) ),
00388 SLOT( _k_toggleSpeedbar( bool )) );
00389
00390 KToggleAction *showBookmarksAction =
00391 new KToggleAction(i18n("Show Bookmarks"), this);
00392 coll->addAction("toggleBookmarks", showBookmarksAction);
00393 connect( showBookmarksAction, SIGNAL( toggled( bool ) ),
00394 SLOT( _k_toggleBookmarks( bool )) );
00395
00396 KActionMenu *menu = new KActionMenu( KIcon("configure"), i18n("Options"), this);
00397 coll->addAction("extra menu", menu);
00398 menu->setWhatsThis(i18n("<qt>This is the preferences menu for the file dialog. "
00399 "Various options can be accessed from this menu including: <ul>"
00400 "<li>how files are sorted in the list</li>"
00401 "<li>types of view, including icon and list</li>"
00402 "<li>showing of hidden files</li>"
00403 "<li>the Places navigation panel</li>"
00404 "<li>file previews</li>"
00405 "<li>separating folders from files</li></ul></qt>"));
00406 menu->addAction( coll->action( "sorting menu" ));
00407 menu->addSeparator();
00408 coll->action( "short view" )->setShortcut( QKeySequence(Qt::Key_F6) );
00409 menu->addAction( coll->action( "short view" ));
00410 coll->action( "detailed view" )->setShortcut( QKeySequence(Qt::Key_F7) );
00411 menu->addAction( coll->action( "detailed view" ));
00412 menu->addSeparator();
00413 coll->action( "show hidden" )->setShortcut( QKeySequence(Qt::Key_F8) );
00414 menu->addAction( coll->action( "show hidden" ));
00415 menu->addAction( showSidebarAction );
00416 menu->addAction( showBookmarksAction );
00417 coll->action( "preview" )->setShortcut( QKeySequence(Qt::Key_F11) );
00418 menu->addAction( coll->action( "preview" ));
00419
00420 menu->setDelayed( false );
00421 connect( menu->menu(), SIGNAL( aboutToShow() ),
00422 d->ops, SLOT( updateSelectionDependentActions() ));
00423 d->toolbar->addAction( menu );
00424
00425 d->toolbar->addWidget(d->urlNavigator);
00426
00427
00428
00429 d->toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
00430 d->toolbar->setMovable(false);
00431
00432 KUrlCompletion *pathCompletionObj = new KUrlCompletion( KUrlCompletion::DirCompletion );
00433 pathCombo->setCompletionObject( pathCompletionObj );
00434 pathCombo->setAutoDeleteCompletionObject( true );
00435
00436 connect( d->urlNavigator, SIGNAL( urlChanged( const KUrl& )),
00437 this, SLOT( _k_enterUrl( const KUrl& ) ));
00438
00439 QString whatsThisText;
00440
00441
00442 d->locationLabel = new QLabel(i18n("&Location:"), this);
00443 d->locationEdit = new KUrlComboBox(KUrlComboBox::Files, true, this);
00444
00445
00446
00447 d->locationEdit->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
00448 connect( d->locationEdit, SIGNAL( editTextChanged( const QString& ) ),
00449 SLOT( _k_slotLocationChanged( const QString& )) );
00450
00451 d->updateLocationWhatsThis();
00452 d->locationLabel->setBuddy(d->locationEdit);
00453
00454 KUrlCompletion *fileCompletionObj = new KUrlCompletion( KUrlCompletion::FileCompletion );
00455 QString dir = d->url.url(KUrl::AddTrailingSlash);
00456
00457 d->urlNavigator->setUrl( dir );
00458
00459 fileCompletionObj->setDir( dir );
00460 d->locationEdit->setCompletionObject( fileCompletionObj );
00461 d->locationEdit->setAutoDeleteCompletionObject( true );
00462 connect( fileCompletionObj, SIGNAL( match( const QString& ) ),
00463 SLOT( _k_fileCompletion( const QString& )) );
00464
00465 connect(d->locationEdit, SIGNAL( returnPressed( const QString& )),
00466 this, SLOT( _k_locationAccepted( const QString& ) ));
00467 connect(d->locationEdit, SIGNAL( activated( const QString& )),
00468 this, SLOT( _k_locationActivated( const QString& ) ));
00469
00470
00471 whatsThisText = i18n("<qt>This is the filter to apply to the file list. "
00472 "File names that do not match the filter will not be shown.<p>"
00473 "You may select from one of the preset filters in the "
00474 "drop down menu, or you may enter a custom filter "
00475 "directly into the text area.</p><p>"
00476 "Wildcards such as * and ? are allowed.</p></qt>");
00477 d->filterLabel = new QLabel(i18n("&Filter:"), this);
00478 d->filterLabel->setWhatsThis(whatsThisText);
00479 d->filterWidget = new KFileFilterCombo(this);
00480
00481
00482
00483 d->filterWidget->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
00484 d->filterWidget->setWhatsThis(whatsThisText);
00485 d->filterLabel->setBuddy(d->filterWidget);
00486 connect(d->filterWidget, SIGNAL(filterChanged()), SLOT(_k_slotFilterChanged()));
00487
00488
00489
00490 d->autoSelectExtCheckBox = new QCheckBox (this);
00491 d->autoSelectExtCheckBox->setStyleSheet(QString("QCheckBox { padding-top: %1px; }").arg(KDialog::spacingHint()));
00492 connect(d->autoSelectExtCheckBox, SIGNAL(clicked()), SLOT(_k_slotAutoSelectExtClicked()));
00493
00494 d->initGUI();
00495
00496 KSharedConfig::Ptr config = KGlobal::config();
00497 d->readRecentFiles(config.data());
00498
00499 d->viewConfigGroup=new KConfigGroup(config,ConfigGroup);
00500 d->ops->setViewConfig(*d->viewConfigGroup);
00501 d->readConfig(* d->viewConfigGroup);
00502 setSelection(d->selection);
00503 d->locationEdit->setFocus();
00504 }
00505
00506 KFileWidget::~KFileWidget()
00507 {
00508 KSharedConfig::Ptr config = KGlobal::config();
00509
00510 config->sync();
00511
00512 delete d->bookmarkHandler;
00513 delete d->ops;
00514 delete d->viewConfigGroup;
00515 delete d;
00516 }
00517
00518 void KFileWidget::setLocationLabel(const QString& text)
00519 {
00520 d->locationLabel->setText(text);
00521 }
00522
00523 void KFileWidget::setFilter(const QString& filter)
00524 {
00525 int pos = filter.indexOf('/');
00526
00527
00528
00529
00530 if (pos > 0 && filter[pos - 1] != '\\') {
00531 QStringList filters = filter.split(" ", QString::SkipEmptyParts);
00532 setMimeFilter( filters );
00533 return;
00534 }
00535
00536
00537
00538
00539 QString copy (filter);
00540 for (pos = 0; (pos = copy.indexOf("\\/", pos)) != -1; ++pos)
00541 copy.remove(pos, 1);
00542
00543 d->ops->clearFilter();
00544 d->filterWidget->setFilter(copy);
00545 d->ops->setNameFilter(d->filterWidget->currentFilter());
00546 d->hasDefaultFilter = false;
00547 d->filterWidget->setEditable( true );
00548
00549 d->updateAutoSelectExtension ();
00550 }
00551
00552 QString KFileWidget::currentFilter() const
00553 {
00554 return d->filterWidget->currentFilter();
00555 }
00556
00557 void KFileWidget::setMimeFilter( const QStringList& mimeTypes,
00558 const QString& defaultType )
00559 {
00560 d->mimetypes = mimeTypes;
00561 d->filterWidget->setMimeFilter( mimeTypes, defaultType );
00562
00563 QStringList types = d->filterWidget->currentFilter().split(" ",QString::SkipEmptyParts);
00564 types.append( QLatin1String( "inode/directory" ));
00565 d->ops->clearFilter();
00566 d->ops->setMimeFilter( types );
00567 d->hasDefaultFilter = !defaultType.isEmpty();
00568 d->filterWidget->setEditable( !d->hasDefaultFilter ||
00569 d->operationMode != Saving );
00570
00571 d->updateAutoSelectExtension ();
00572 }
00573
00574 void KFileWidget::clearFilter()
00575 {
00576 d->mimetypes.clear();
00577 d->filterWidget->setFilter( QString() );
00578 d->ops->clearFilter();
00579 d->hasDefaultFilter = false;
00580 d->filterWidget->setEditable( true );
00581
00582 d->updateAutoSelectExtension ();
00583 }
00584
00585 QString KFileWidget::currentMimeFilter() const
00586 {
00587 int i = d->filterWidget->currentIndex();
00588 if (d->filterWidget->showsAllTypes())
00589 i--;
00590
00591 if ((i >= 0) && (i < (int) d->mimetypes.count()))
00592 return d->mimetypes[i];
00593 return QString();
00594 }
00595
00596 KMimeType::Ptr KFileWidget::currentFilterMimeType()
00597 {
00598 return KMimeType::mimeType( currentMimeFilter() );
00599 }
00600
00601 void KFileWidget::setPreviewWidget(KPreviewWidgetBase *w) {
00602 d->ops->setPreviewWidget(w);
00603 d->ops->clearHistory();
00604 d->hasView = true;
00605 }
00606
00607 KUrl KFileWidgetPrivate::getCompleteUrl(const QString &_url) const
00608 {
00609 QString url = KShell::tildeExpand(_url);
00610 KUrl u;
00611
00612 if ( KUrl::isRelativeUrl(url) )
00613 {
00614 if (!url.isEmpty() && !QDir::isRelativePath(url) )
00615 u.setPath( url );
00616 else
00617 {
00618 u = ops->url();
00619 u.addPath( url );
00620 u.cleanPath();
00621 }
00622 }
00623 else
00624 u = url;
00625
00626 return u;
00627 }
00628
00629
00630 void KFileWidget::slotOk()
00631 {
00632 kDebug(kfile_area) << "slotOk\n";
00633
00634
00635
00636 const KFileItemList items = d->ops->selectedItems();
00637
00638 const QString locationEditCurrentText( d->locationEditCurrentText() );
00639
00640 if ( (mode() & KFile::Directory) != KFile::Directory ) {
00641 if ( locationEditCurrentText.isEmpty() ) {
00642
00643
00644 if (items.isEmpty())
00645 return;
00646
00647
00648
00649 bool multi = (mode() & KFile::Files) != 0;
00650 QString endQuote = QLatin1String("\" ");
00651 QString name;
00652 KUrl::List urlList;
00653 foreach (const KFileItem &fileItem, items) {
00654 name = fileItem.name();
00655 if ( multi ) {
00656 name.prepend( QLatin1Char( '"' ) );
00657 name.append( endQuote );
00658 }
00659
00660 urlList << fileItem.url();
00661 }
00662 d->setLocationText( urlList );
00663 return;
00664 }
00665 }
00666
00667 bool dirOnly = d->ops->dirOnlyMode();
00668
00669
00670 if ( !d->locationEdit->lineEdit()->isModified() &&
00671 !(items.isEmpty() && !dirOnly) ) {
00672
00673 d->urlList.clear();
00674 d->filenames.clear();
00675
00676 if ( dirOnly ) {
00677 d->url = d->ops->url();
00678 }
00679 else {
00680 if ( !(mode() & KFile::Files) ) {
00681 d->url = items.first().url();
00682 }
00683
00684 else {
00685 d->url = d->ops->url();
00686 KUrl::List urlList;
00687 foreach (const KFileItem &item, items) {
00688 urlList.append(item.url());
00689 }
00690 d->urlList = urlList;
00691 }
00692 }
00693
00694 KUrl url = KIO::NetAccess::mostLocalUrl(d->url,topLevelWidget());
00695 if ( ( (mode() & KFile::LocalOnly) == KFile::LocalOnly ) &&
00696 !url.isLocalFile() )
00697 {
00698
00699 KMessageBox::sorry( this,
00700 i18n("You can only select local files."),
00701 i18n("Remote Files Not Accepted") );
00702 return;
00703 }
00704
00705 d->url = url;
00706 emit accepted();
00707 return;
00708 }
00709
00710 KUrl selectedUrl;
00711
00712 if ( (mode() & KFile::Files) == KFile::Files ) {
00713 if ( locationEditCurrentText.contains( '/' ) ) {
00714
00715 KUrl u( d->ops->url(), KShell::tildeExpand( locationEditCurrentText ));
00716 if ( u.isValid() )
00717 selectedUrl = u;
00718 else
00719 selectedUrl = d->ops->url();
00720 }
00721 else
00722 selectedUrl = d->ops->url();
00723 }
00724
00725 else {
00726 selectedUrl = d->getCompleteUrl( locationEditCurrentText );
00727
00728
00729 d->appendExtension (selectedUrl);
00730 }
00731
00732 if ( !selectedUrl.isValid() ) {
00733 KMessageBox::sorry( this, i18n("%1\ndoes not appear to be a valid URL.\n", d->url.url()), i18n("Invalid URL") );
00734 return;
00735 }
00736
00737 KUrl url = KIO::NetAccess::mostLocalUrl(selectedUrl,topLevelWidget());
00738 if ( ( (mode() & KFile::LocalOnly) == KFile::LocalOnly ) &&
00739 !url.isLocalFile() )
00740 {
00741 KMessageBox::sorry( this,
00742 i18n("You can only select local files."),
00743 i18n("Remote Files Not Accepted") );
00744 return;
00745 }
00746
00747 d->url = url;
00748
00749
00750
00751 if ( (mode() & KFile::Directory) == KFile::Directory ) {
00752 kDebug(kfile_area) << "Directory";
00753 bool done = true;
00754 if ( d->url.isLocalFile() ) {
00755 if ( locationEditCurrentText.isEmpty() ) {
00756 QFileInfo info( d->url.toLocalFile() );
00757 if ( info.isDir() ) {
00758 d->filenames.clear();
00759 d->urlList.clear();
00760 d->urlList.append( d->url );
00761 emit accepted();
00762 }
00763 else if (!info.exists() && (mode() & KFile::File) != KFile::File) {
00764
00765 if ( d->ops->mkdir( d->url.url(), true ))
00766 return;
00767 else
00768 emit accepted();
00769 }
00770 else {
00771
00772 if ( (mode() & KFile::File) == KFile::File ||
00773 (mode() & KFile::Files) == KFile::Files )
00774 done = false;
00775 }
00776 }
00777 else
00778 {
00779 if ( mode() & KFile::ExistingOnly )
00780 {
00781 if ( d->ops->dirOnlyMode() )
00782 {
00783 KUrl fullURL(d->url, locationEditCurrentText);
00784 if ( QFile::exists( fullURL.toLocalFile() ) )
00785 {
00786 d->url = fullURL;
00787 d->filenames.clear();
00788 d->urlList.clear();
00789 emit accepted();
00790 return;
00791 }
00792 else
00793 return;
00794 }
00795 }
00796
00797 d->filenames = locationEditCurrentText;
00798 emit accepted();
00799 }
00800
00801 }
00802 else {
00803
00804 d->filenames.clear();
00805 d->urlList.clear();
00806 d->urlList.append( d->url );
00807
00808 if ( mode() & KFile::ExistingOnly )
00809 done = false;
00810 else
00811 emit accepted();
00812 }
00813
00814 if ( done )
00815 return;
00816 }
00817 else {
00818 KUrl::List urls = d->tokenize( locationEditCurrentText );
00819 if ( urls.count()==1 && urls.first().isLocalFile() ) {
00820 QFileInfo info( urls.first().toLocalFile() );
00821 if ( info.isDir() && this->selectedUrl().isValid() && !this->selectedUrl().equals( urls.first(), KUrl::CompareWithoutTrailingSlash ) ) {
00822 setSelection( info.absolutePath() );
00823 slotOk();
00824 return;
00825 }
00826 }
00827 }
00828
00829 if (!KAuthorized::authorizeUrlAction("open", KUrl(), d->url))
00830 {
00831 QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, d->url.prettyUrl());
00832 KMessageBox::error( this, msg);
00833 return;
00834 }
00835
00836 KIO::StatJob *job = 0L;
00837 d->statJobs.clear();
00838 d->filenames = KShell::tildeExpand( locationEditCurrentText );
00839
00840 if ( (mode() & KFile::Files) == KFile::Files &&
00841 !locationEditCurrentText.contains( '/' ) ) {
00842 kDebug(kfile_area) << "Files\n";
00843 KUrl::List list = d->parseSelectedUrls();
00844 for ( KUrl::List::ConstIterator it = list.begin();
00845 it != list.end(); ++it )
00846 {
00847 if (!KAuthorized::authorizeUrlAction("open", KUrl(), *it))
00848 {
00849 QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, (*it).prettyUrl());
00850 KMessageBox::error( this, msg);
00851 return;
00852 }
00853 }
00854 for ( KUrl::List::ConstIterator it = list.begin();
00855 it != list.end(); ++it )
00856 {
00857 KIO::JobFlags flags = !(*it).isLocalFile() ? KIO::DefaultFlags : KIO::HideProgressInfo;
00858 job = KIO::stat( *it, flags );
00859 job->ui()->setWindow (topLevelWidget());
00860 KIO::Scheduler::scheduleJob( job );
00861 d->statJobs.append( job );
00862 connect( job, SIGNAL( result(KJob *) ),
00863 SLOT( _k_slotStatResult( KJob *) ));
00864 }
00865 return;
00866 }
00867
00868 KIO::JobFlags flags = !d->url.isLocalFile() ? KIO::DefaultFlags : KIO::HideProgressInfo;
00869 job = KIO::stat(d->url,flags);
00870 job->ui()->setWindow (topLevelWidget());
00871 d->statJobs.append( job );
00872 connect(job, SIGNAL(result(KJob*)), SLOT(_k_slotStatResult(KJob*)));
00873 }
00874
00875
00876
00877
00878 void KFileWidgetPrivate::_k_slotStatResult(KJob* job)
00879 {
00880 kDebug(kfile_area) << "slotStatResult";
00881 KIO::StatJob *sJob = static_cast<KIO::StatJob *>( job );
00882
00883 if ( !statJobs.removeAll( sJob ) ) {
00884 return;
00885 }
00886
00887 int count = statJobs.count();
00888
00889
00890
00891 if (sJob->error() && count == 0 && !ops->dirOnlyMode())
00892 {
00893 emit q->accepted();
00894 return;
00895 }
00896
00897 KIO::UDSEntry t = sJob->statResult();
00898 if (t.isDir())
00899 {
00900 if ( ops->dirOnlyMode() )
00901 {
00902 filenames.clear();
00903 urlList.clear();
00904 emit q->accepted();
00905 }
00906 else
00907 {
00908 if ( count == 0 ) {
00909 locationEdit->clearEditText();
00910 locationEdit->lineEdit()->setModified( false );
00911 q->setUrl( sJob->url() );
00912 }
00913 }
00914 statJobs.clear();
00915 return;
00916 }
00917 else if ( ops->dirOnlyMode() )
00918 {
00919 return;
00920 }
00921
00922 kDebug(kfile_area) << "filename " << sJob->url().url();
00923
00924 if ( count == 0 )
00925 emit q->accepted();
00926 }
00927
00928 void KFileWidget::accept()
00929 {
00930 d->inAccept = true;
00931
00932 *lastDirectory = d->ops->url();
00933 if (!d->fileClass.isEmpty())
00934 KRecentDirs::add(d->fileClass, d->ops->url().url());
00935
00936
00937 d->locationEdit->setItemText( 0, QString() );
00938
00939 KUrl::List list = selectedUrls();
00940 QList<KUrl>::const_iterator it = list.begin();
00941 int atmost = d->locationEdit->maxItems();
00942 for ( ; it != list.end() && atmost > 0; ++it ) {
00943 const KUrl& url = *it;
00944
00945
00946
00947 QString file = url.isLocalFile() ? url.path(KUrl::RemoveTrailingSlash) : url.prettyUrl(KUrl::RemoveTrailingSlash);
00948
00949
00950 for ( int i = 1; i < d->locationEdit->count(); i++ ) {
00951 if ( d->locationEdit->itemText( i ) == file ) {
00952 d->locationEdit->removeItem( i-- );
00953 break;
00954 }
00955 }
00956
00957
00958
00959 d->locationEdit->insertItem( 1,file);
00960 atmost--;
00961 }
00962
00963 KSharedConfig::Ptr config = KGlobal::config();
00964 config->setForceGlobal( true );
00965 KConfigGroup grp(config,ConfigGroup);
00966 d->writeConfig(grp);
00967 config->setForceGlobal( false );
00968
00969 d->saveRecentFiles(config.data());
00970 config->sync();
00971
00972 d->addToRecentDocuments();
00973
00974 if ( (mode() & KFile::Files) != KFile::Files )
00975 emit fileSelected(d->url.url());
00976
00977 d->ops->close();
00978 }
00979
00980
00981 void KFileWidgetPrivate::_k_fileHighlighted(const KFileItem &i)
00982 {
00983 const bool modified = locationEdit->lineEdit()->isModified();
00984 locationEdit->lineEdit()->setModified( false );
00985
00986 if ( ( !i.isNull() && i.isDir() ) ||
00987 ( locationEdit->hasFocus() && !locationEdit->currentText().isEmpty() ) )
00988 return;
00989
00990 if ( (ops->mode() & KFile::Files) != KFile::Files ) {
00991 if ( i.isNull() ) {
00992 if ( !modified ) {
00993 setLocationText( KUrl() );
00994 }
00995 return;
00996 }
00997
00998 url = i.url();
00999
01000 if ( !locationEdit->hasFocus() ) {
01001 setLocationText( url );
01002 }
01003 emit q->fileHighlighted(url.url());
01004 }
01005
01006 else {
01007 multiSelectionChanged();
01008 emit q->selectionChanged();
01009 }
01010
01011 locationEdit->lineEdit()->selectAll();
01012 }
01013
01014 void KFileWidgetPrivate::_k_fileSelected(const KFileItem &i)
01015 {
01016 if (!i.isNull() && i.isDir())
01017 return;
01018
01019 if ( (ops->mode() & KFile::Files) != KFile::Files ) {
01020 if ( i.isNull() ) {
01021 setLocationText( KUrl() );
01022 return;
01023 }
01024
01025 setLocationText( i.url() );
01026 }
01027 else {
01028 multiSelectionChanged();
01029 emit q->selectionChanged();
01030 }
01031 q->slotOk();
01032 }
01033
01034
01035
01036
01037 void KFileWidgetPrivate::multiSelectionChanged()
01038 {
01039 if ( locationEdit->hasFocus() && !locationEdit->currentText().isEmpty() )
01040 return;
01041
01042 const KFileItemList list = ops->selectedItems();
01043
01044 if ( list.isEmpty() ) {
01045 setLocationText( KUrl() );
01046 return;
01047 }
01048
01049 static const QString &begin = KGlobal::staticQString(" \"");
01050 KUrl::List urlList;
01051 foreach (const KFileItem &fileItem, list) {
01052 urlList << fileItem.url();
01053 }
01054
01055 setLocationText( urlList );
01056 }
01057
01058 void KFileWidgetPrivate::setDummyHistoryEntry( const QString& text, const QPixmap& icon,
01059 bool usePreviousPixmapIfNull )
01060 {
01061
01062
01063
01064 QObject::disconnect( locationEdit, SIGNAL( editTextChanged( const QString& ) ),
01065 q, SLOT( _k_slotLocationChanged( const QString& ) ) );
01066
01067 bool dummyExists = dummyAdded;
01068
01069 int cursorPosition = locationEdit->lineEdit()->cursorPosition();
01070
01071 if ( dummyAdded ) {
01072 if ( !icon.isNull() ) {
01073 locationEdit->setItemIcon( 0, icon );
01074 locationEdit->setItemText( 0, text );
01075 } else {
01076 if ( !usePreviousPixmapIfNull ) {
01077 locationEdit->setItemIcon( 0, QPixmap() );
01078 }
01079 locationEdit->setItemText( 0, text );
01080 }
01081 } else {
01082 if ( !text.isEmpty() ) {
01083 if ( !icon.isNull() ) {
01084 locationEdit->insertItem( 0, icon, text );
01085 } else {
01086 if ( !usePreviousPixmapIfNull ) {
01087 locationEdit->insertItem( 0, QPixmap(), text );
01088 } else {
01089 locationEdit->insertItem( 0, text );
01090 }
01091 }
01092 dummyAdded = true;
01093 dummyExists = true;
01094 }
01095 }
01096
01097 if ( dummyExists && !text.isEmpty() ) {
01098 locationEdit->setCurrentIndex( 0 );
01099 }
01100
01101 locationEdit->lineEdit()->setCursorPosition( cursorPosition );
01102
01103 QObject::connect( locationEdit, SIGNAL( editTextChanged ( const QString& ) ),
01104 q, SLOT( _k_slotLocationChanged( const QString& )) );
01105 }
01106
01107 void KFileWidgetPrivate::removeDummyHistoryEntry()
01108 {
01109 if ( !dummyAdded || locationEdit->lineEdit()->isModified() ) {
01110 return;
01111 }
01112
01113
01114
01115
01116 QObject::disconnect( locationEdit, SIGNAL( editTextChanged( const QString& ) ),
01117 q, SLOT( _k_slotLocationChanged( const QString& ) ) );
01118
01119 locationEdit->removeItem( 0 );
01120 locationEdit->setCurrentIndex( -1 );
01121 dummyAdded = false;
01122
01123 QObject::connect( locationEdit, SIGNAL( editTextChanged ( const QString& ) ),
01124 q, SLOT( _k_slotLocationChanged( const QString& )) );
01125 }
01126
01127 void KFileWidgetPrivate::setLocationText( const KUrl& url )
01128 {
01129 if ( !url.isEmpty() ) {
01130 QPixmap mimeTypeIcon = KIconLoader::global()->loadMimeTypeIcon( KMimeType::iconNameForUrl( url ), KIconLoader::Small );
01131 setDummyHistoryEntry( url.fileName(), mimeTypeIcon );
01132 } else {
01133 removeDummyHistoryEntry();
01134 }
01135
01136
01137 if ( operationMode == KFileWidget::Saving && !locationEdit->isVisible())
01138 setNonExtSelection();
01139 }
01140
01141 void KFileWidgetPrivate::setLocationText( const KUrl::List& urlList )
01142 {
01143 if ( urlList.count() > 1 ) {
01144 QString urls;
01145 foreach (const KUrl &url, urlList) {
01146 urls += QString( "\"%1\"" ).arg( url.fileName() ) + ' ';
01147 }
01148 urls = urls.left( urls.size() - 1 );
01149
01150 setDummyHistoryEntry( urls, QPixmap(), false );
01151 } else if ( urlList.count() ) {
01152 const QPixmap mimeTypeIcon = KIconLoader::global()->loadMimeTypeIcon( KMimeType::iconNameForUrl( urlList[0] ), KIconLoader::Small );
01153 setDummyHistoryEntry( urlList[0].fileName(), mimeTypeIcon );
01154 } else {
01155 removeDummyHistoryEntry();
01156 }
01157
01158
01159 if ( operationMode == KFileWidget::Saving && !locationEdit->isVisible())
01160 setNonExtSelection();
01161 }
01162
01163 void KFileWidgetPrivate::updateLocationWhatsThis()
01164 {
01165 QString whatsThisText;
01166 if (operationMode == KFileWidget::Saving)
01167 {
01168 whatsThisText = "<qt>" + i18n("This is the name to save the file as.") +
01169 i18n (autocompletionWhatsThisText);
01170 }
01171 else if (ops->mode() & KFile::Files)
01172 {
01173 whatsThisText = "<qt>" + i18n("This is the list of files to open. More than "
01174 "one file can be specified by listing several "
01175 "files, separated by spaces.") +
01176 i18n (autocompletionWhatsThisText);
01177 }
01178 else
01179 {
01180 whatsThisText = "<qt>" + i18n("This is the name of the file to open.") +
01181 i18n (autocompletionWhatsThisText);
01182 }
01183
01184 locationLabel->setWhatsThis(whatsThisText);
01185 locationEdit->setWhatsThis(whatsThisText);
01186 }
01187
01188 void KFileWidgetPrivate::initSpeedbar()
01189 {
01190 placesView = new KFilePlacesView( q );
01191 placesView->setModel(model);
01192 placesView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
01193
01194 placesView->setObjectName( QLatin1String( "url bar" ) );
01195 QObject::connect( placesView, SIGNAL( urlChanged( const KUrl& )),
01196 q, SLOT( _k_enterUrl( const KUrl& )) );
01197
01198
01199
01200
01201
01202 placesView->setUrl( url );
01203
01204 placesViewSplitter->insertWidget( 0, placesView );
01205 }
01206
01207 void KFileWidgetPrivate::initGUI()
01208 {
01209 delete boxLayout;
01210
01211 boxLayout = new QVBoxLayout( q);
01212 boxLayout->setMargin(0);
01213 boxLayout->setSpacing(0);
01214 boxLayout->addWidget(toolbar, 0, Qt::AlignTop);
01215
01216 placesViewSplitter = new QSplitter(q);
01217 placesViewSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
01218 placesViewSplitter->setChildrenCollapsible(false);
01219 boxLayout->addWidget(placesViewSplitter);
01220
01221 QObject::connect(placesViewSplitter, SIGNAL(splitterMoved(int,int)), q, SLOT(_k_placesViewSplitterMoved()));
01222
01223 vbox = new QVBoxLayout();
01224 vbox->setMargin(0);
01225 QWidget *vboxWidget = new QWidget();
01226 vboxWidget->setLayout(vbox);
01227 placesViewSplitter->insertWidget(0, vboxWidget);
01228
01229 vbox->addWidget(ops, 4);
01230 vbox->addSpacing(KDialog::spacingHint());
01231
01232 lafBox = new QGridLayout();
01233
01234 lafBox->setSpacing(KDialog::spacingHint());
01235 lafBox->addWidget(locationLabel, 0, 0, Qt::AlignVCenter);
01236 lafBox->addWidget(locationEdit, 0, 1, Qt::AlignVCenter);
01237 lafBox->addWidget(okButton, 0, 2, Qt::AlignVCenter);
01238
01239 lafBox->addWidget(filterLabel, 1, 0, Qt::AlignVCenter);
01240 lafBox->addWidget(filterWidget, 1, 1, Qt::AlignVCenter);
01241 lafBox->addWidget(cancelButton, 1, 2, Qt::AlignVCenter);
01242
01243 lafBox->setColumnStretch(1, 4);
01244
01245 vbox->addLayout(lafBox);
01246
01247
01248 vbox->addWidget(autoSelectExtCheckBox);
01249
01250 q->setTabOrder(ops, autoSelectExtCheckBox);
01251 q->setTabOrder(autoSelectExtCheckBox, locationEdit);
01252 q->setTabOrder(locationEdit, filterWidget);
01253 q->setTabOrder(filterWidget, okButton);
01254 q->setTabOrder(okButton, cancelButton);
01255 q->setTabOrder(cancelButton, urlNavigator);
01256 q->setTabOrder(urlNavigator, ops);
01257 q->setTabOrder(cancelButton, urlNavigator);
01258 q->setTabOrder(urlNavigator, ops);
01259 }
01260
01261 void KFileWidgetPrivate::_k_slotFilterChanged()
01262 {
01263 QString filter = filterWidget->currentFilter();
01264 ops->clearFilter();
01265
01266 if ( filter.indexOf( '/' ) > -1 ) {
01267 QStringList types = filter.split(" ",QString::SkipEmptyParts);
01268 types.prepend( "inode/directory" );
01269 ops->setMimeFilter( types );
01270 }
01271 else
01272 ops->setNameFilter( filter );
01273
01274 ops->updateDir();
01275
01276 updateAutoSelectExtension();
01277
01278 emit q->filterChanged( filter );
01279 }
01280
01281
01282 void KFileWidget::setUrl(const KUrl& url, bool clearforward)
01283 {
01284 d->selection.clear();
01285 d->ops->setUrl( url, clearforward);
01286 }
01287
01288
01289 void KFileWidgetPrivate::_k_urlEntered(const KUrl& url)
01290 {
01291 QString filename = locationEditCurrentText();
01292 selection.clear();
01293
01294 KUrlComboBox* pathCombo = urlNavigator->editor();
01295 if ( pathCombo->count() != 0 ) {
01296 pathCombo->setUrl( url );
01297 }
01298
01299 bool blocked = locationEdit->blockSignals( true );
01300 if ( keepLocation ) {
01301 locationEdit->changeUrl( 0, KIcon( KMimeType::iconNameForUrl( filename ) ), filename );
01302 locationEdit->lineEdit()->setModified( true );
01303 }
01304
01305 locationEdit->blockSignals( blocked );
01306
01307 urlNavigator->setUrl( url );
01308
01309 QString dir = url.url(KUrl::AddTrailingSlash);
01310
01311 KUrlCompletion *completion = dynamic_cast<KUrlCompletion*>( locationEdit->completionObject() );
01312 if( completion )
01313 completion->setDir( dir );
01314
01315 if ( placesView )
01316 placesView->setUrl( url );
01317 }
01318
01319 void KFileWidgetPrivate::_k_locationAccepted( const QString& url )
01320 {
01321 ops->setCurrentItem( url );
01322 q->slotOk();
01323 }
01324
01325 void KFileWidgetPrivate::_k_locationActivated( const QString& url )
01326 {
01327
01328
01329 q->setUrl( url );
01330 }
01331
01332 void KFileWidgetPrivate::_k_enterUrl( const KUrl& url )
01333 {
01334 KUrl fixedUrl( url );
01335
01336
01337 fixedUrl.adjustPath( KUrl::AddTrailingSlash );
01338 q->setUrl( fixedUrl );
01339 }
01340
01341 void KFileWidgetPrivate::_k_enterUrl( const QString& url )
01342 {
01343 _k_enterUrl( KUrl( KUrlCompletion::replacedPath( url, true, true )) );
01344 }
01345
01346
01347 void KFileWidget::setSelection(const QString& url)
01348 {
01349 kDebug(kfile_area) << "setSelection " << url;
01350
01351 if (url.isEmpty()) {
01352 d->selection.clear();
01353 return;
01354 }
01355
01356 KUrl u = d->getCompleteUrl(url);
01357 if (!u.isValid()) {
01358 kWarning() << url << " is not a correct argument for setSelection!";
01359 return;
01360 }
01361
01362
01363 if (!KProtocolManager::supportsListing(u))
01364 return;
01365
01366
01367
01368
01369 KIO::UDSEntry entry;
01370 bool res = KIO::NetAccess::stat(u, entry, this);
01371 KFileItem i(entry, u);
01372
01373 kDebug(kfile_area) << "KFileItem " << u.path() << " " << i.isDir() << " " << u.isLocalFile() << " " << QFile::exists( u.path() );
01374 if ( res && i.isDir() && u.isLocalFile() && QFile::exists( u.path() ) ) {
01375
01376
01377
01378
01379 setUrl(u, true);
01380 }
01381 else if ( res ) {
01382 QString filename = u.url();
01383 int sep = filename.lastIndexOf('/');
01384 if (sep >= 0) {
01385 KUrl dir(u);
01386 dir.setQuery( QString() );
01387 dir.setFileName( QString() );
01388 setUrl(dir, true );
01389
01390
01391
01392 filename = u.fileName();
01393 kDebug(kfile_area) << "filename " << filename;
01394 d->selection = filename;
01395 d->setLocationText( u );
01396
01397
01398
01399
01400
01401
01402
01403
01404 d->locationEdit->lineEdit()->setModified( true );
01405 }
01406
01407 d->url = d->ops->url();
01408 d->url.addPath(filename);
01409 }
01410 else {
01411 d->setLocationText(url);
01412 d->locationEdit->lineEdit()->setModified( true );
01413 }
01414 }
01415
01416 void KFileWidgetPrivate::_k_slotLoadingFinished()
01417 {
01418 if ( !selection.isEmpty() )
01419 ops->setCurrentItem( selection );
01420 }
01421
01422 void KFileWidgetPrivate::_k_fileCompletion( const QString& match )
01423 {
01424 if ( match.isEmpty() && ops->view() ) {
01425 ops->view()->clearSelection();
01426 } else {
01427 ops->setCurrentItem( match );
01428 setDummyHistoryEntry( locationEdit->currentText(), KIconLoader::global()->loadMimeTypeIcon( KMimeType::iconNameForUrl( match ), KIconLoader::Small ), !locationEdit->currentText().isEmpty() );
01429 locationEdit->setCompletedText( match );
01430 }
01431 }
01432
01433 void KFileWidgetPrivate::_k_slotLocationChanged( const QString& text )
01434 {
01435 locationEdit->lineEdit()->setModified( true );
01436
01437 if ( text.isEmpty() && ops->view() )
01438 ops->view()->clearSelection();
01439
01440 if ( text.isEmpty() ) {
01441 removeDummyHistoryEntry();
01442 } else {
01443 setDummyHistoryEntry( text );
01444 }
01445
01446 ops->setCurrentItem( text );
01447
01448 updateFilter();
01449 }
01450
01451 KUrl KFileWidget::selectedUrl() const
01452 {
01453 if ( d->inAccept )
01454 return d->url;
01455 else
01456 return KUrl();
01457 }
01458
01459 KUrl::List KFileWidget::selectedUrls() const
01460 {
01461 KUrl::List list;
01462 if ( d->inAccept ) {
01463 if ( (d->ops->mode() & KFile::Files) == KFile::Files )
01464 list = d->parseSelectedUrls();
01465 else
01466 list.append( d->url );
01467 }
01468 return list;
01469 }
01470
01471
01472 KUrl::List& KFileWidgetPrivate::parseSelectedUrls()
01473 {
01474 if ( filenames.isEmpty() ) {
01475 return urlList;
01476 }
01477
01478 urlList.clear();
01479 if ( filenames.contains( '/' )) {
01480 KUrl u;
01481 if ( containsProtocolSection( filenames ) )
01482 u = filenames;
01483 else
01484 u.setPath( filenames );
01485
01486 if ( u.isValid() )
01487 urlList.append( u );
01488 else
01489 KMessageBox::error( q,
01490 i18n("The chosen filenames do not\n"
01491 "appear to be valid."),
01492 i18n("Invalid Filenames") );
01493 }
01494
01495 else
01496 urlList = tokenize( filenames );
01497
01498 filenames.clear();
01499
01500 return urlList;
01501 }
01502
01503
01504
01505 KUrl::List KFileWidgetPrivate::tokenize( const QString& line ) const
01506 {
01507 KUrl::List urls;
01508 KUrl u( ops->url() );
01509 QString name;
01510
01511 const int count = line.count( QLatin1Char( '"' ) );
01512 if ( count == 0 ) {
01513 u.setFileName( line );
01514 if ( u.isValid() )
01515 urls.append( u );
01516
01517 return urls;
01518 }
01519
01520 if ( (count % 2) == 1 ) {
01521 KMessageBox::sorry(q, i18n("The requested filenames\n"
01522 "%1\n"
01523 "do not appear to be valid;\n"
01524 "make sure every filename is enclosed in double quotes.", line),
01525 i18n("Filename Error"));
01526 return urls;
01527 }
01528
01529 int start = 0;
01530 int index1 = -1, index2 = -1;
01531 while ( true ) {
01532 index1 = line.indexOf( '"', start );
01533 index2 = line.indexOf( '"', index1 + 1 );
01534
01535 if ( index1 < 0 )
01536 break;
01537
01538
01539 name = line.mid( index1 + 1, index2 - index1 - 1 );
01540 u.setFileName( name );
01541 if ( u.isValid() )
01542 urls.append( u );
01543
01544 start = index2 + 1;
01545 }
01546 return urls;
01547 }
01548
01549
01550 QString KFileWidget::selectedFile() const
01551 {
01552 if ( d->inAccept ) {
01553 const KUrl url = KIO::NetAccess::mostLocalUrl(d->url,topLevelWidget());
01554 if (url.isLocalFile())
01555 return url.path();
01556 else {
01557 KMessageBox::sorry( const_cast<KFileWidget*>(this),
01558 i18n("You can only select local files."),
01559 i18n("Remote Files Not Accepted") );
01560 }
01561 }
01562 return QString();
01563 }
01564
01565 QStringList KFileWidget::selectedFiles() const
01566 {
01567 QStringList list;
01568
01569 if ( d->inAccept ) {
01570 if ( (d->ops->mode() & KFile::Files) == KFile::Files ) {
01571 KUrl::List urls = d->parseSelectedUrls();
01572 QList<KUrl>::const_iterator it = urls.begin();
01573 while ( it != urls.end() ) {
01574 KUrl url = KIO::NetAccess::mostLocalUrl(*it,topLevelWidget());
01575 if ( url.isLocalFile() )
01576 list.append( url.path() );
01577 ++it;
01578 }
01579 }
01580
01581 else {
01582 if ( d->url.isLocalFile() )
01583 list.append( d->url.path() );
01584 }
01585 }
01586
01587 return list;
01588 }
01589
01590 KUrl KFileWidget::baseUrl() const
01591 {
01592 return d->ops->url();
01593 }
01594
01595 void KFileWidget::resizeEvent(QResizeEvent* event)
01596 {
01597 d->updateSplitterSize();
01598
01599 QWidget::resizeEvent(event);
01600 }
01601
01602 void KFileWidget::showEvent(QShowEvent* event)
01603 {
01604 if ( !d->hasView ) {
01605 d->ops->setView(KFile::Default);
01606 d->ops->view()->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) );
01607 d->hasView = true;
01608 }
01609 d->ops->clearHistory();
01610
01611 QWidget::showEvent(event);
01612 }
01613
01614 void KFileWidget::setMode( KFile::Modes m )
01615 {
01616 d->ops->setMode(m);
01617 if ( d->ops->dirOnlyMode() ) {
01618 d->filterWidget->setDefaultFilter( i18n("*|All Folders") );
01619 }
01620 else {
01621 d->filterWidget->setDefaultFilter( i18n("*|All Files") );
01622 }
01623
01624 d->updateAutoSelectExtension();
01625 }
01626
01627 KFile::Modes KFileWidget::mode() const
01628 {
01629 return d->ops->mode();
01630 }
01631
01632
01633 void KFileWidgetPrivate::readConfig( const KConfigGroup &configGroup)
01634 {
01635 ops->readConfig(configGroup);
01636
01637 KUrlComboBox *combo = urlNavigator->editor();
01638 combo->setUrls( configGroup.readPathEntry( RecentURLs, QStringList() ), KUrlComboBox::RemoveTop );
01639 combo->setMaxItems( configGroup.readEntry( RecentURLsNumber,
01640 DefaultRecentURLsNumber ) );
01641 combo->setUrl( ops->url() );
01642 autoDirectoryFollowing = configGroup.readEntry( AutoDirectoryFollowing,
01643 DefaultDirectoryFollowing );
01644
01645 KGlobalSettings::Completion cm = (KGlobalSettings::Completion)
01646 configGroup.readEntry( PathComboCompletionMode,
01647 static_cast<int>( KGlobalSettings::completionMode() ) );
01648 if ( cm != KGlobalSettings::completionMode() )
01649 combo->setCompletionMode( cm );
01650
01651 cm = (KGlobalSettings::Completion)
01652 configGroup.readEntry( LocationComboCompletionMode,
01653 static_cast<int>( KGlobalSettings::completionMode() ) );
01654 if ( cm != KGlobalSettings::completionMode() )
01655 locationEdit->setCompletionMode( cm );
01656
01657
01658 _k_toggleSpeedbar( configGroup.readEntry( ShowSpeedbar, true ) );
01659
01660
01661 _k_toggleBookmarks( configGroup.readEntry(ShowBookmarks, false) );
01662
01663
01664 autoSelectExtChecked = configGroup.readEntry (AutoSelectExtChecked, DefaultAutoSelectExtChecked);
01665 updateAutoSelectExtension();
01666
01667
01668 urlNavigator->setUrlEditable( !configGroup.readEntry(BreadcrumbNavigation, true) );
01669
01670 int w1 = q->minimumSize().width();
01671 int w2 = toolbar->sizeHint().width();
01672 if (w1 < w2)
01673 q->setMinimumWidth(w2);
01674 }
01675
01676 void KFileWidgetPrivate::writeConfig(KConfigGroup &configGroup)
01677 {
01678 KUrlComboBox *pathCombo = urlNavigator->editor();
01679 configGroup.writePathEntry( RecentURLs, pathCombo->urls() );
01680
01681 configGroup.writeEntry( PathComboCompletionMode, static_cast<int>(pathCombo->completionMode()) );
01682 configGroup.writeEntry( LocationComboCompletionMode, static_cast<int>(locationEdit->completionMode()) );
01683
01684 const bool showSpeedbar = placesView && !placesView->isHidden();
01685 configGroup.writeEntry( ShowSpeedbar, showSpeedbar );
01686 if (showSpeedbar) {
01687 const QList<int> sizes = placesViewSplitter->sizes();
01688 Q_ASSERT( sizes.count() > 0 );
01689 configGroup.writeEntry( SpeedbarWidth, sizes[0] );
01690 }
01691
01692 configGroup.writeEntry( ShowBookmarks, bookmarkHandler != 0 );
01693 configGroup.writeEntry( AutoSelectExtChecked, autoSelectExtChecked );
01694 configGroup.writeEntry( BreadcrumbNavigation, !urlNavigator->isUrlEditable() );
01695
01696 ops->writeConfig(configGroup);
01697 }
01698
01699
01700 void KFileWidgetPrivate::readRecentFiles( KConfig *kc )
01701 {
01702 KConfigGroup cg( kc, ConfigGroup );
01703
01704 locationEdit->setMaxItems( cg.readEntry( RecentFilesNumber,
01705 DefaultRecentURLsNumber ) );
01706 locationEdit->setUrls( cg.readPathEntry( RecentFiles, QStringList() ),
01707 KUrlComboBox::RemoveBottom );
01708 locationEdit->setCurrentIndex( -1 );
01709 }
01710
01711 void KFileWidgetPrivate::saveRecentFiles( KConfig *kc )
01712 {
01713 KConfigGroup cg(kc, ConfigGroup );
01714 cg.writePathEntry( RecentFiles, locationEdit->urls() );
01715 }
01716
01717 KPushButton * KFileWidget::okButton() const
01718 {
01719 return d->okButton;
01720 }
01721
01722 KPushButton * KFileWidget::cancelButton() const
01723 {
01724 return d->cancelButton;
01725 }
01726
01727
01728 void KFileWidget::slotCancel()
01729 {
01730 d->ops->close();
01731
01732 KSharedConfig::Ptr config = KGlobal::config();
01733 config->setForceGlobal( true );
01734 KConfigGroup grp(config,ConfigGroup);
01735 d->writeConfig(grp);
01736 config->setForceGlobal( false );
01737 }
01738
01739 void KFileWidget::setKeepLocation( bool keep )
01740 {
01741 d->keepLocation = keep;
01742 }
01743
01744 bool KFileWidget::keepsLocation() const
01745 {
01746 return d->keepLocation;
01747 }
01748
01749 void KFileWidget::setOperationMode( OperationMode mode )
01750 {
01751 d->operationMode = mode;
01752 d->keepLocation = (mode == Saving);
01753 d->filterWidget->setEditable( !d->hasDefaultFilter || mode != Saving );
01754 if ( mode == Opening )
01755
01756 d->okButton->setGuiItem( KGuiItem( i18n( "&Open" ), "document-open") );
01757 else if ( mode == Saving ) {
01758 d->okButton->setGuiItem( KStandardGuiItem::save() );
01759 d->setNonExtSelection();
01760 }
01761 else
01762 d->okButton->setGuiItem( KStandardGuiItem::ok() );
01763 d->updateLocationWhatsThis();
01764 d->updateAutoSelectExtension();
01765 }
01766
01767 KFileWidget::OperationMode KFileWidget::operationMode() const
01768 {
01769 return d->operationMode;
01770 }
01771
01772 void KFileWidgetPrivate::_k_slotAutoSelectExtClicked()
01773 {
01774 kDebug (kfile_area) << "slotAutoSelectExtClicked(): "
01775 << autoSelectExtCheckBox->isChecked() << endl;
01776
01777
01778 autoSelectExtChecked = autoSelectExtCheckBox->isChecked();
01779
01780
01781 updateLocationEditExtension (extension );
01782 }
01783
01784 void KFileWidgetPrivate::_k_placesViewSplitterMoved()
01785 {
01786 const QList<int> sizes = placesViewSplitter->sizes();
01787 speedBarWidth = sizes[0];
01788 }
01789
01790 static QString getExtensionFromPatternList(const QStringList &patternList)
01791 {
01792 QString ret;
01793 kDebug (kfile_area) << "\tgetExtension " << patternList;
01794
01795 QStringList::ConstIterator patternListEnd = patternList.end();
01796 for (QStringList::ConstIterator it = patternList.begin();
01797 it != patternListEnd;
01798 ++it)
01799 {
01800 kDebug (kfile_area) << "\t\ttry: \'" << (*it) << "\'";
01801
01802
01803
01804
01805
01806
01807
01808
01809 if ((*it).startsWith ("*.") &&
01810 (*it).length() > 2 &&
01811 (*it).indexOf('*', 2) < 0 && (*it).indexOf ('?', 2) < 0)
01812 {
01813 ret = (*it).mid (1);
01814 break;
01815 }
01816 }
01817
01818 return ret;
01819 }
01820
01821 static QString stripUndisplayable (const QString &string)
01822 {
01823 QString ret = string;
01824
01825 ret.remove (':');
01826 ret.remove ('&');
01827
01828 return ret;
01829 }
01830
01831
01832
01833
01834
01835
01836
01837 void KFileWidgetPrivate::updateAutoSelectExtension()
01838 {
01839 if (!autoSelectExtCheckBox) return;
01840
01841
01842
01843
01844
01845
01846
01847
01848 kDebug (kfile_area) << "Figure out an extension: ";
01849 QString lastExtension = extension;
01850 extension.clear();
01851
01852
01853 if ((operationMode == KFileWidget::Saving) && (ops->mode() & KFile::File))
01854 {
01855
01856
01857
01858
01859 QString filter = filterWidget->currentFilter();
01860 if (!filter.isEmpty())
01861 {
01862
01863 if (filter.indexOf ('/') < 0)
01864 {
01865 extension = getExtensionFromPatternList (filter.split(" ",QString::SkipEmptyParts)).toLower();
01866 kDebug (kfile_area) << "\tsetFilter-style: pattern ext=\'"
01867 << extension << "\'" << endl;
01868 }
01869
01870 else
01871 {
01872 KMimeType::Ptr mime = KMimeType::mimeType (filter);
01873
01874 if (mime)
01875 {
01876
01877 QString nativeExtension = mime->property ("X-KDE-NativeExtension").toString();
01878 if (!nativeExtension.isEmpty() && nativeExtension.at (0) == '.')
01879 {
01880 extension = nativeExtension.toLower();
01881 kDebug (kfile_area) << "\tsetMimeFilter-style: native ext=\'"
01882 << extension << "\'" << endl;
01883 }
01884
01885
01886 if (extension.isEmpty())
01887 {
01888 extension = getExtensionFromPatternList (mime->patterns()).toLower();
01889 kDebug (kfile_area) << "\tsetMimeFilter-style: pattern ext=\'"
01890 << extension << "\'" << endl;
01891 }
01892 }
01893 }
01894 }
01895
01896
01897
01898
01899
01900
01901 QString whatsThisExtension;
01902 if (!extension.isEmpty())
01903 {
01904
01905 autoSelectExtCheckBox->setText (i18n ("Automatically select filename e&xtension (%1)", extension));
01906 whatsThisExtension = i18n ("the extension <b>%1</b>", extension);
01907
01908 autoSelectExtCheckBox->setEnabled (true);
01909 autoSelectExtCheckBox->setChecked (autoSelectExtChecked);
01910 }
01911 else
01912 {
01913
01914 autoSelectExtCheckBox->setText (i18n ("Automatically select filename e&xtension"));
01915 whatsThisExtension = i18n ("a suitable extension");
01916
01917 autoSelectExtCheckBox->setChecked (false);
01918 autoSelectExtCheckBox->setEnabled (false);
01919 }
01920
01921 const QString locationLabelText = stripUndisplayable (locationLabel->text());
01922 const QString filterLabelText = stripUndisplayable (filterLabel->text());
01923 autoSelectExtCheckBox->setWhatsThis( "<qt>" +
01924 i18n (
01925 "This option enables some convenient features for "
01926 "saving files with extensions:<br />"
01927 "<ol>"
01928 "<li>Any extension specified in the <b>%1</b> text "
01929 "area will be updated if you change the file type "
01930 "to save in.<br />"
01931 "<br /></li>"
01932 "<li>If no extension is specified in the <b>%2</b> "
01933 "text area when you click "
01934 "<b>Save</b>, %3 will be added to the end of the "
01935 "filename (if the filename does not already exist). "
01936 "This extension is based on the file type that you "
01937 "have chosen to save in.<br />"
01938 "<br />"
01939 "If you do not want KDE to supply an extension for the "
01940 "filename, you can either turn this option off or you "
01941 "can suppress it by adding a period (.) to the end of "
01942 "the filename (the period will be automatically "
01943 "removed)."
01944 "</li>"
01945 "</ol>"
01946 "If unsure, keep this option enabled as it makes your "
01947 "files more manageable."
01948 ,
01949 locationLabelText,
01950 locationLabelText,
01951 whatsThisExtension)
01952 + "</qt>"
01953 );
01954
01955 autoSelectExtCheckBox->show();
01956
01957
01958
01959 updateLocationEditExtension (lastExtension);
01960 }
01961
01962 else
01963 {
01964 autoSelectExtCheckBox->setChecked (false);
01965 autoSelectExtCheckBox->hide();
01966 }
01967 }
01968
01969
01970
01971
01972 void KFileWidgetPrivate::updateLocationEditExtension (const QString &lastExtension)
01973 {
01974 if (!autoSelectExtCheckBox->isChecked() || extension.isEmpty())
01975 return;
01976
01977 QString urlStr = locationEditCurrentText();
01978 if (urlStr.isEmpty())
01979 return;
01980
01981 KUrl url = getCompleteUrl(urlStr);
01982 kDebug (kfile_area) << "updateLocationEditExtension (" << url << ")";
01983
01984 const int fileNameOffset = urlStr.lastIndexOf ('/') + 1;
01985 QString fileName = urlStr.mid (fileNameOffset);
01986
01987 const int dot = fileName.lastIndexOf ('.');
01988 const int len = fileName.length();
01989 if (dot > 0 &&
01990
01991 dot != len - 1
01992 )
01993 {
01994
01995 KIO::UDSEntry t;
01996 if (KIO::NetAccess::stat (url, t, q->topLevelWidget()))
01997 {
01998 kDebug (kfile_area) << "\tfile exists";
01999
02000 if (t.isDir())
02001 {
02002 kDebug (kfile_area) << "\tisDir - won't alter extension";
02003 return;
02004 }
02005
02006
02007 }
02008
02009
02010
02011
02012
02013
02014
02015 if (lastExtension.length() && fileName.endsWith (lastExtension))
02016 fileName.truncate (len - lastExtension.length());
02017 else if (extension.length() && fileName.endsWith (extension))
02018 fileName.truncate (len - extension.length());
02019
02020 else
02021 fileName.truncate (dot);
02022
02023
02024 const QString newText = urlStr.left (fileNameOffset) + fileName + extension;
02025 if ( newText != locationEditCurrentText() )
02026 {
02027 locationEdit->setItemText(locationEdit->currentIndex(),urlStr.left (fileNameOffset) + fileName + extension);
02028 locationEdit->lineEdit()->setModified (true);
02029 }
02030 }
02031 }
02032
02033
02034
02035 void KFileWidgetPrivate::updateFilter()
02036 {
02037 if ((operationMode == KFileWidget::Saving) && (ops->mode() & KFile::File) ) {
02038 const QString urlStr = locationEditCurrentText();
02039 if (urlStr.isEmpty())
02040 return;
02041
02042 KMimeType::Ptr mime = KMimeType::findByPath(urlStr, 0, true);
02043 if (mime && mime->name() != KMimeType::defaultMimeType()) {
02044 if (filterWidget->currentFilter() != mime->name() &&
02045 filterWidget->filters().indexOf(mime->name()) != -1)
02046 filterWidget->setCurrentFilter(mime->name());
02047 }
02048 }
02049 }
02050
02051
02052
02053
02054
02055 void KFileWidgetPrivate::updateSplitterSize()
02056 {
02057 QList<int> sizes = placesViewSplitter->sizes();
02058 if (sizes.count() == 2) {
02059
02060 KConfigGroup configGroup( KGlobal::config(), ConfigGroup );
02061 const int speedbarWidth = speedBarWidth == -1 ? configGroup.readEntry( SpeedbarWidth, placesView->sizeHintForColumn(0) )
02062 : speedBarWidth;
02063 const int availableWidth = q->width();
02064 sizes[0] = speedbarWidth + 1;
02065 sizes[1] = availableWidth - speedbarWidth - 1;
02066 placesViewSplitter->setSizes( sizes );
02067 }
02068 }
02069
02070
02071 void KFileWidgetPrivate::appendExtension (KUrl &url)
02072 {
02073 if (!autoSelectExtCheckBox->isChecked() || extension.isEmpty())
02074 return;
02075
02076 QString fileName = url.fileName();
02077 if (fileName.isEmpty())
02078 return;
02079
02080 kDebug (kfile_area) << "appendExtension(" << url << ")";
02081
02082 const int len = fileName.length();
02083 const int dot = fileName.lastIndexOf ('.');
02084
02085 const bool suppressExtension = (dot == len - 1);
02086 const bool unspecifiedExtension = (dot <= 0);
02087
02088
02089 if (!(suppressExtension || unspecifiedExtension))
02090 return;
02091
02092
02093 KIO::UDSEntry t;
02094 if (KIO::NetAccess::stat (url, t, q->topLevelWidget()))
02095 {
02096 kDebug (kfile_area) << "\tfile exists - won't append extension";
02097 return;
02098 }
02099
02100
02101 if (suppressExtension)
02102 {
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113 kDebug (kfile_area) << "\tstrip trailing dot";
02114 url.setFileName (fileName.left (len - 1));
02115 }
02116
02117 else if (unspecifiedExtension)
02118 {
02119 kDebug (kfile_area) << "\tappending extension \'" << extension << "\'...";
02120 url.setFileName (fileName + extension);
02121 kDebug (kfile_area) << "\tsaving as \'" << url << "\'";
02122 }
02123 }
02124
02125
02126
02127 void KFileWidgetPrivate::addToRecentDocuments()
02128 {
02129 int m = ops->mode();
02130 int atmost = KRecentDocument::maximumItems();
02131
02132
02133 if ( m & KFile::LocalOnly ) {
02134 const QStringList files = q->selectedFiles();
02135 QStringList::ConstIterator it = files.begin();
02136 for ( ; it != files.end() && atmost > 0; ++it ) {
02137 KRecentDocument::add( *it );
02138 atmost--;
02139 }
02140 }
02141
02142 else {
02143 KUrl::List urls = q->selectedUrls();
02144 KUrl::List::ConstIterator it = urls.begin();
02145 for ( ; it != urls.end() && atmost > 0; ++it ) {
02146 if ( (*it).isValid() ) {
02147 KRecentDocument::add( *it );
02148 atmost--;
02149 }
02150 }
02151 }
02152 }
02153
02154 KUrlComboBox* KFileWidget::locationEdit() const
02155 {
02156 return d->locationEdit;
02157 }
02158
02159 KFileFilterCombo* KFileWidget::filterWidget() const
02160 {
02161 return d->filterWidget;
02162 }
02163
02164 KActionCollection * KFileWidget::actionCollection() const
02165 {
02166 return d->ops->actionCollection();
02167 }
02168
02169 void KFileWidgetPrivate::_k_toggleSpeedbar( bool show )
02170 {
02171 if ( show )
02172 {
02173 if ( !placesView )
02174 initSpeedbar();
02175
02176 placesView->show();
02177
02178
02179 KUrl homeURL;
02180 homeURL.setPath( QDir::homePath() );
02181 KFilePlacesModel *model = static_cast<KFilePlacesModel*>(placesView->model());
02182 for ( int rowIndex = 0 ; rowIndex < placesView->model()->rowCount() ; rowIndex++ )
02183 {
02184 QModelIndex index = model->index(rowIndex, 0);
02185 KUrl url = model->url(index);
02186
02187 if ( homeURL.equals( url, KUrl::CompareWithoutTrailingSlash ) ) {
02188 toolbar->removeAction( ops->actionCollection()->action( "home" ) );
02189 break;
02190 }
02191 }
02192 }
02193 else
02194 {
02195 if (placesView)
02196 placesView->hide();
02197
02198 QAction* homeAction = ops->actionCollection()->action( "home" );
02199 QAction* reloadAction = ops->actionCollection()->action( "reload" );
02200 if ( !toolbar->actions().contains(homeAction) )
02201 toolbar->insertAction( reloadAction, homeAction );
02202 }
02203
02204 static_cast<KToggleAction *>(q->actionCollection()->action("toggleSpeedbar"))->setChecked( show );
02205 }
02206
02207 void KFileWidgetPrivate::_k_toggleBookmarks(bool show)
02208 {
02209 if (show)
02210 {
02211 if (bookmarkHandler)
02212 {
02213 return;
02214 }
02215
02216 bookmarkHandler = new KFileBookmarkHandler( q );
02217 q->connect( bookmarkHandler, SIGNAL( openUrl( const QString& )),
02218 SLOT( _k_enterUrl( const QString& )));
02219
02220 bookmarkButton = new KActionMenu(KIcon("bookmarks"),i18n("Bookmarks"), q);
02221 bookmarkButton->setDelayed(false);
02222 q->actionCollection()->addAction("bookmark", bookmarkButton);
02223 bookmarkButton->setMenu(bookmarkHandler->menu());
02224 bookmarkButton->setWhatsThis(i18n("<qt>This button allows you to bookmark specific locations. "
02225 "Click on this button to open the bookmark menu where you may add, "
02226 "edit or select a bookmark.<br /><br />"
02227 "These bookmarks are specific to the file dialog, but otherwise operate "
02228 "like bookmarks elsewhere in KDE.</qt>"));
02229 toolbar->addAction(bookmarkButton);
02230 }
02231 else if (bookmarkHandler)
02232 {
02233 delete bookmarkHandler;
02234 bookmarkHandler = 0;
02235 delete bookmarkButton;
02236 bookmarkButton = 0;
02237 }
02238
02239 static_cast<KToggleAction *>(q->actionCollection()->action("toggleBookmarks"))->setChecked( show );
02240 }
02241
02242
02243 KUrl KFileWidget::getStartUrl( const KUrl& startDir,
02244 QString& recentDirClass )
02245 {
02246 recentDirClass.clear();
02247 KUrl ret;
02248
02249 bool useDefaultStartDir = startDir.isEmpty();
02250 if ( !useDefaultStartDir )
02251 {
02252 if (startDir.protocol() == "kfiledialog")
02253 {
02254 if ( startDir.query() == "?global" )
02255 recentDirClass = QString( "::%1" ).arg( startDir.path().mid( 1 ) );
02256 else
02257 recentDirClass = QString( ":%1" ).arg( startDir.path().mid( 1 ) );
02258
02259 ret = KUrl( KRecentDirs::dir(recentDirClass) );
02260 }
02261 else
02262 {
02263 ret = startDir;
02264
02265 if ( !KProtocolManager::supportsListing( ret ) )
02266 useDefaultStartDir = true;
02267 }
02268 }
02269
02270 if ( useDefaultStartDir )
02271 {
02272 if (lastDirectory->isEmpty()) {
02273 lastDirectory->setPath(KGlobalSettings::documentPath());
02274 KUrl home;
02275 home.setPath( QDir::homePath() );
02276
02277
02278
02279
02280 if ( lastDirectory->path(KUrl::AddTrailingSlash) == home.path(KUrl::AddTrailingSlash) ||
02281 QDir::currentPath() != QDir::homePath() ||
02282 !QDir(lastDirectory->path(KUrl::AddTrailingSlash)).exists() )
02283 lastDirectory->setPath(QDir::currentPath());
02284 }
02285 ret = *lastDirectory;
02286 }
02287
02288 return ret;
02289 }
02290
02291 void KFileWidget::setStartDir( const KUrl& directory )
02292 {
02293 if ( directory.isValid() )
02294 *lastDirectory = directory;
02295 }
02296
02297 void KFileWidgetPrivate::setNonExtSelection()
02298 {
02299
02300 QString filename = locationEditCurrentText();
02301 QString extension = KMimeType::extractKnownExtension( filename );
02302
02303 if ( !extension.isEmpty() )
02304 locationEdit->lineEdit()->setSelection( 0, filename.length() - extension.length() - 1 );
02305 else
02306 {
02307 int lastDot = filename.lastIndexOf( '.' );
02308 if ( lastDot > 0 )
02309 locationEdit->lineEdit()->setSelection( 0, lastDot );
02310 }
02311 }
02312
02313 KToolBar * KFileWidget::toolBar() const
02314 {
02315 return d->toolbar;
02316 }
02317
02318 void KFileWidget::setCustomWidget(QWidget* widget)
02319 {
02320 delete d->bottomCustomWidget;
02321 d->bottomCustomWidget = widget;
02322
02323
02324
02325
02326 d->bottomCustomWidget->setParent( this );
02327
02328 d->vbox->addWidget( d->bottomCustomWidget );
02329
02330
02331
02332
02333
02334
02335
02336 setTabOrder(d->cancelButton, d->bottomCustomWidget);
02337 setTabOrder(d->bottomCustomWidget, d->urlNavigator);
02338 }
02339
02340 void KFileWidget::setCustomWidget(const QString& text, QWidget* widget)
02341 {
02342 delete d->labeledCustomWidget;
02343 d->labeledCustomWidget = widget;
02344
02345 QLabel* label = new QLabel(text, this);
02346 d->lafBox->addWidget(label, 2, 0, Qt::AlignVCenter);
02347 d->lafBox->addWidget(widget, 2, 1, Qt::AlignVCenter);
02348 }
02349
02350 void KFileWidget::virtual_hook( int id, void* data )
02351 {
02352 Q_UNUSED(id);
02353 Q_UNUSED(data);
02354 }
02355
02356 QString KFileWidgetPrivate::locationEditCurrentText() const
02357 {
02358 return QDir::fromNativeSeparators(locationEdit->currentText().trimmed());
02359 }
02360
02361 #include "kfilewidget.moc"