• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KFile

  • kfile
kfilewidget.cpp
Go to the documentation of this file.
1// -*- c++ -*-
2/* This file is part of the KDE libraries
3 Copyright (C) 1997, 1998 Richard Moore <rich@kde.org>
4 1998 Stephan Kulow <coolo@kde.org>
5 1998 Daniel Grana <grana@ie.iwi.unibe.ch>
6 1999,2000,2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org>
7 2003 Clarence Dang <dang@kde.org>
8 2007 David Faure <faure@kde.org>
9 2008 Rafael Fernández López <ereslibre@kde.org>
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License as published by the Free Software Foundation; either
14 version 2 of the License, or (at your option) any later version.
15
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Library General Public License for more details.
20
21 You should have received a copy of the GNU Library General Public License
22 along with this library; see the file COPYING.LIB. If not, write to
23 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 Boston, MA 02110-1301, USA.
25*/
26
27#include "kfilewidget.h"
28
29#include "kfileplacesview.h"
30#include "kfileplacesmodel.h"
31#include "kfilebookmarkhandler_p.h"
32#include "kurlcombobox.h"
33#include "kurlnavigator.h"
34#include "kfilepreviewgenerator.h"
35#include <config-kfile.h>
36
37#include <kactioncollection.h>
38#include <kdiroperator.h>
39#include <kdirselectdialog.h>
40#include <kfilefiltercombo.h>
41#include <kimagefilepreview.h>
42#include <kmenu.h>
43#include <kmimetype.h>
44#include <kpushbutton.h>
45#include <krecentdocument.h>
46#include <ktoolbar.h>
47#include <kurlcompletion.h>
48#include <kuser.h>
49#include <kprotocolmanager.h>
50#include <kio/job.h>
51#include <kio/jobuidelegate.h>
52#include <kio/netaccess.h>
53#include <kio/scheduler.h>
54#include <krecentdirs.h>
55#include <kdebug.h>
56#include <kio/kfileitemdelegate.h>
57#include <kde_file.h>
58
59#include <QtGui/QCheckBox>
60#include <QtGui/QDockWidget>
61#include <QtGui/QLayout>
62#include <QtGui/QLabel>
63#include <QtGui/QLineEdit>
64#include <QtGui/QSplitter>
65#include <QtGui/QAbstractProxyModel>
66#include <QtGui/QHelpEvent>
67#include <QtGui/QApplication>
68#include <QtCore/QFSFileEngine>
69#include <kshell.h>
70#include <kmessagebox.h>
71#include <kauthorized.h>
72
73class KFileWidgetPrivate
74{
75public:
76 KFileWidgetPrivate(KFileWidget *widget)
77 : q(widget),
78 boxLayout(0),
79 placesDock(0),
80 placesView(0),
81 placesViewSplitter(0),
82 placesViewWidth(-1),
83 labeledCustomWidget(0),
84 bottomCustomWidget(0),
85 autoSelectExtCheckBox(0),
86 operationMode(KFileWidget::Opening),
87 bookmarkHandler(0),
88 toolbar(0),
89 locationEdit(0),
90 ops(0),
91 filterWidget(0),
92 autoSelectExtChecked(false),
93 keepLocation(false),
94 hasView(false),
95 hasDefaultFilter(false),
96 inAccept(false),
97 dummyAdded(false),
98 confirmOverwrite(false),
99 differentHierarchyLevelItemsEntered(false),
100 previewGenerator(0),
101 iconSizeSlider(0)
102 {
103 }
104
105 ~KFileWidgetPrivate()
106 {
107 delete bookmarkHandler; // Should be deleted before ops!
108 delete ops;
109 }
110
111 void updateLocationWhatsThis();
112 void updateAutoSelectExtension();
113 void initSpeedbar();
114 void initGUI();
115 void readViewConfig();
116 void writeViewConfig();
117 void setNonExtSelection();
118 void setLocationText(const KUrl&);
119 void setLocationText(const KUrl::List&);
120 void appendExtension(KUrl &url);
121 void updateLocationEditExtension(const QString &);
122 void updateFilter();
123 KUrl::List& parseSelectedUrls();
130 KUrl::List tokenize(const QString& line) const;
134 void readRecentFiles();
138 void saveRecentFiles();
143 void multiSelectionChanged();
144
148 KUrl getCompleteUrl(const QString&) const;
149
154 void setDummyHistoryEntry(const QString& text, const QPixmap& icon = QPixmap(),
155 bool usePreviousPixmapIfNull = true);
156
160 void removeDummyHistoryEntry();
161
168 bool toOverwrite(const KUrl&);
169
170 // private slots
171 void _k_slotLocationChanged( const QString& );
172 void _k_urlEntered( const KUrl& );
173 void _k_enterUrl( const KUrl& );
174 void _k_enterUrl( const QString& );
175 void _k_locationAccepted( const QString& );
176 void _k_slotFilterChanged();
177 void _k_fileHighlighted( const KFileItem& );
178 void _k_fileSelected( const KFileItem& );
179 void _k_slotLoadingFinished();
180 void _k_fileCompletion( const QString& );
181 void _k_toggleSpeedbar( bool );
182 void _k_toggleBookmarks( bool );
183 void _k_slotAutoSelectExtClicked();
184 void _k_placesViewSplitterMoved(int, int);
185 void _k_activateUrlNavigator();
186 void _k_zoomOutIconsSize();
187 void _k_zoomInIconsSize();
188 void _k_slotIconSizeSliderMoved(int);
189 void _k_slotIconSizeChanged(int);
190
191 void addToRecentDocuments();
192
193 QString locationEditCurrentText() const;
194
200 KUrl mostLocalUrl(const KUrl &url);
201
202 void setInlinePreviewShown(bool show);
203
204 KFileWidget* q;
205
206 // the last selected url
207 KUrl url;
208
209 // the selected filenames in multiselection mode -- FIXME
210 QString filenames;
211
212 // now following all kind of widgets, that I need to rebuild
213 // the geometry management
214 QBoxLayout *boxLayout;
215 QGridLayout *lafBox;
216 QVBoxLayout *vbox;
217
218 QLabel *locationLabel;
219 QWidget *opsWidget;
220 QWidget *pathSpacer;
221
222 QLabel *filterLabel;
223 KUrlNavigator *urlNavigator;
224 KPushButton *okButton, *cancelButton;
225 QDockWidget *placesDock;
226 KFilePlacesView *placesView;
227 QSplitter *placesViewSplitter;
228 // caches the places view width. This value will be updated when the splitter
229 // is moved. This allows us to properly set a value when the dialog itself
230 // is resized
231 int placesViewWidth;
232
233 QWidget *labeledCustomWidget;
234 QWidget *bottomCustomWidget;
235
236 // Automatically Select Extension stuff
237 QCheckBox *autoSelectExtCheckBox;
238 QString extension; // current extension for this filter
239
240 QList<KIO::StatJob*> statJobs;
241
242 KUrl::List urlList; //the list of selected urls
243
244 KFileWidget::OperationMode operationMode;
245
246 // The file class used for KRecentDirs
247 QString fileClass;
248
249 KFileBookmarkHandler *bookmarkHandler;
250
251 KActionMenu* bookmarkButton;
252
253 KToolBar *toolbar;
254 KUrlComboBox *locationEdit;
255 KDirOperator *ops;
256 KFileFilterCombo *filterWidget;
257 QTimer filterDelayTimer;
258
259 KFilePlacesModel *model;
260
261 // whether or not the _user_ has checked the above box
262 bool autoSelectExtChecked : 1;
263
264 // indicates if the location edit should be kept or cleared when changing
265 // directories
266 bool keepLocation : 1;
267
268 // the KDirOperators view is set in KFileWidget::show(), so to avoid
269 // setting it again and again, we have this nice little boolean :)
270 bool hasView : 1;
271
272 bool hasDefaultFilter : 1; // necessary for the operationMode
273 bool autoDirectoryFollowing : 1;
274 bool inAccept : 1; // true between beginning and end of accept()
275 bool dummyAdded : 1; // if the dummy item has been added. This prevents the combo from having a
276 // blank item added when loaded
277 bool confirmOverwrite : 1;
278 bool differentHierarchyLevelItemsEntered;
279
280 KFilePreviewGenerator *previewGenerator;
281 QSlider *iconSizeSlider;
282
283 // The group which stores app-specific settings. These settings are recent
284 // files and urls. Visual settings (view mode, sorting criteria...) are not
285 // app-specific and are stored in kdeglobals
286 KConfigGroup configGroup; };
287
288K_GLOBAL_STATIC(KUrl, lastDirectory) // to set the start path
289
290static const char autocompletionWhatsThisText[] = I18N_NOOP("<qt>While typing in the text area, you may be presented "
291 "with possible matches. "
292 "This feature can be controlled by clicking with the right mouse button "
293 "and selecting a preferred mode from the <b>Text Completion</b> menu.</qt>");
294
295// returns true if the string contains "<a>:/" sequence, where <a> is at least 2 alpha chars
296static bool containsProtocolSection( const QString& string )
297{
298 int len = string.length();
299 static const char prot[] = ":/";
300 for (int i=0; i < len;) {
301 i = string.indexOf( QLatin1String(prot), i );
302 if (i == -1)
303 return false;
304 int j=i-1;
305 for (; j >= 0; j--) {
306 const QChar& ch( string[j] );
307 if (ch.toLatin1() == 0 || !ch.isLetter())
308 break;
309 if (ch.isSpace() && (i-j-1) >= 2)
310 return true;
311 }
312 if (j < 0 && i >= 2)
313 return true; // at least two letters before ":/"
314 i += 3; // skip : and / and one char
315 }
316 return false;
317}
318
319KFileWidget::KFileWidget( const KUrl& _startDir, QWidget *parent )
320 : QWidget(parent), KAbstractFileWidget(), d(new KFileWidgetPrivate(this))
321{
322 KUrl startDir(_startDir);
323 kDebug(kfile_area) << "startDir" << startDir;
324 QString filename;
325
326 d->okButton = new KPushButton(KStandardGuiItem::ok(), this);
327 d->okButton->setDefault(true);
328 d->cancelButton = new KPushButton(KStandardGuiItem::cancel(), this);
329 // The dialog shows them
330 d->okButton->hide();
331 d->cancelButton->hide();
332
333 d->opsWidget = new QWidget(this);
334 QVBoxLayout *opsWidgetLayout = new QVBoxLayout(d->opsWidget);
335 opsWidgetLayout->setMargin(0);
336 opsWidgetLayout->setSpacing(0);
337 //d->toolbar = new KToolBar(this, true);
338 d->toolbar = new KToolBar(d->opsWidget, true);
339 d->toolbar->setObjectName("KFileWidget::toolbar");
340 d->toolbar->setMovable(false);
341 opsWidgetLayout->addWidget(d->toolbar);
342
343 d->model = new KFilePlacesModel(this);
344
345 // Resolve this now so that a 'kfiledialog:' URL, if specified,
346 // does not get inserted into the urlNavigator history.
347 d->url = getStartUrl( startDir, d->fileClass, filename );
348 startDir = d->url;
349
350 // Don't pass startDir to the KUrlNavigator at this stage: as well as
351 // the above, it may also contain a file name which should not get
352 // inserted in that form into the old-style navigation bar history.
353 // Wait until the KIO::stat has been done later.
354 //
355 // The stat cannot be done before this point, bug 172678.
356 d->urlNavigator = new KUrlNavigator(d->model, KUrl(), d->opsWidget); //d->toolbar);
357 d->urlNavigator->setPlacesSelectorVisible(false);
358 opsWidgetLayout->addWidget(d->urlNavigator);
359
360 KUrl u;
361 KUrlComboBox *pathCombo = d->urlNavigator->editor();
362#ifdef Q_WS_WIN
363 foreach( const QFileInfo &drive,QFSFileEngine::drives() )
364 {
365 u.setPath( drive.filePath() );
366 pathCombo->addDefaultUrl(u,
367 KIO::pixmapForUrl( u, 0, KIconLoader::Small ),
368 i18n("Drive: %1", u.toLocalFile()));
369 }
370#else
371 u.setPath(QDir::rootPath());
372 pathCombo->addDefaultUrl(u,
373 KIO::pixmapForUrl(u, 0, KIconLoader::Small),
374 u.toLocalFile());
375#endif
376
377 u.setPath(QDir::homePath());
378 pathCombo->addDefaultUrl(u, KIO::pixmapForUrl(u, 0, KIconLoader::Small),
379 u.path(KUrl::AddTrailingSlash));
380
381 KUrl docPath;
382 docPath.setPath( KGlobalSettings::documentPath() );
383 if ( (u.path(KUrl::AddTrailingSlash) != docPath.path(KUrl::AddTrailingSlash)) &&
384 QDir(docPath.path(KUrl::AddTrailingSlash)).exists() )
385 {
386 pathCombo->addDefaultUrl( docPath,
387 KIO::pixmapForUrl( docPath, 0, KIconLoader::Small ),
388 docPath.path(KUrl::AddTrailingSlash));
389 }
390
391 u.setPath( KGlobalSettings::desktopPath() );
392 pathCombo->addDefaultUrl(u,
393 KIO::pixmapForUrl(u, 0, KIconLoader::Small),
394 u.path(KUrl::AddTrailingSlash));
395
396 d->ops = new KDirOperator(KUrl(), d->opsWidget);
397 d->ops->setObjectName( "KFileWidget::ops" );
398 d->ops->setIsSaving(d->operationMode == Saving);
399 opsWidgetLayout->addWidget(d->ops);
400 connect(d->ops, SIGNAL(urlEntered(KUrl)),
401 SLOT(_k_urlEntered(KUrl)));
402 connect(d->ops, SIGNAL(fileHighlighted(KFileItem)),
403 SLOT(_k_fileHighlighted(KFileItem)));
404 connect(d->ops, SIGNAL(fileSelected(KFileItem)),
405 SLOT(_k_fileSelected(KFileItem)));
406 connect(d->ops, SIGNAL(finishedLoading()),
407 SLOT(_k_slotLoadingFinished()));
408
409 d->ops->setupMenu(KDirOperator::SortActions |
410 KDirOperator::FileActions |
411 KDirOperator::ViewActions);
412 KActionCollection *coll = d->ops->actionCollection();
413 coll->addAssociatedWidget(this);
414
415 // add nav items to the toolbar
416 //
417 // NOTE: The order of the button icons here differs from that
418 // found in the file manager and web browser, but has been discussed
419 // and agreed upon on the kde-core-devel mailing list:
420 //
421 // http://lists.kde.org/?l=kde-core-devel&m=116888382514090&w=2
422
423 coll->action( "up" )->setWhatsThis(i18n("<qt>Click this button to enter the parent folder.<br /><br />"
424 "For instance, if the current location is file:/home/%1 clicking this "
425 "button will take you to file:/home.</qt>", KUser().loginName() ));
426
427 coll->action( "back" )->setWhatsThis(i18n("Click this button to move backwards one step in the browsing history."));
428 coll->action( "forward" )->setWhatsThis(i18n("Click this button to move forward one step in the browsing history."));
429
430 coll->action( "reload" )->setWhatsThis(i18n("Click this button to reload the contents of the current location."));
431 coll->action( "mkdir" )->setShortcut( QKeySequence(Qt::Key_F10) );
432 coll->action( "mkdir" )->setWhatsThis(i18n("Click this button to create a new folder."));
433
434 KAction *goToNavigatorAction = coll->addAction( "gotonavigator", this, SLOT(_k_activateUrlNavigator()) );
435 goToNavigatorAction->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_L) );
436
437 KToggleAction *showSidebarAction =
438 new KToggleAction(i18n("Show Places Navigation Panel"), this);
439 coll->addAction("toggleSpeedbar", showSidebarAction);
440 showSidebarAction->setShortcut( QKeySequence(Qt::Key_F9) );
441 connect( showSidebarAction, SIGNAL(toggled(bool)),
442 SLOT(_k_toggleSpeedbar(bool)) );
443
444 KToggleAction *showBookmarksAction =
445 new KToggleAction(i18n("Show Bookmarks"), this);
446 coll->addAction("toggleBookmarks", showBookmarksAction);
447 connect( showBookmarksAction, SIGNAL(toggled(bool)),
448 SLOT(_k_toggleBookmarks(bool)) );
449
450 KActionMenu *menu = new KActionMenu( KIcon("configure"), i18n("Options"), this);
451 coll->addAction("extra menu", menu);
452 menu->setWhatsThis(i18n("<qt>This is the preferences menu for the file dialog. "
453 "Various options can be accessed from this menu including: <ul>"
454 "<li>how files are sorted in the list</li>"
455 "<li>types of view, including icon and list</li>"
456 "<li>showing of hidden files</li>"
457 "<li>the Places navigation panel</li>"
458 "<li>file previews</li>"
459 "<li>separating folders from files</li></ul></qt>"));
460 menu->addAction(coll->action("sorting menu"));
461 menu->addAction(coll->action("view menu"));
462 menu->addSeparator();
463 menu->addAction(coll->action("decoration menu"));
464 menu->addSeparator();
465 KAction * showHidden = qobject_cast<KAction*>(coll->action( "show hidden" ));
466 if (showHidden) {
467 showHidden->setShortcut(
468 KShortcut( QKeySequence(Qt::ALT + Qt::Key_Period), QKeySequence(Qt::Key_F8) ) );
469 }
470 menu->addAction( showHidden );
471 menu->addAction( showSidebarAction );
472 menu->addAction( showBookmarksAction );
473 coll->action( "inline preview" )->setShortcut( QKeySequence(Qt::Key_F11) );
474 menu->addAction( coll->action( "preview" ));
475
476 menu->setDelayed( false );
477 connect( menu->menu(), SIGNAL(aboutToShow()),
478 d->ops, SLOT(updateSelectionDependentActions()));
479
480 d->iconSizeSlider = new QSlider(this);
481 d->iconSizeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
482 d->iconSizeSlider->setOrientation(Qt::Horizontal);
483 d->iconSizeSlider->setMinimum(0);
484 d->iconSizeSlider->setMaximum(100);
485 d->iconSizeSlider->installEventFilter(this);
486 connect(d->iconSizeSlider, SIGNAL(valueChanged(int)),
487 d->ops, SLOT(setIconsZoom(int)));
488 connect(d->iconSizeSlider, SIGNAL(valueChanged(int)),
489 this, SLOT(_k_slotIconSizeChanged(int)));
490 connect(d->iconSizeSlider, SIGNAL(sliderMoved(int)),
491 this, SLOT(_k_slotIconSizeSliderMoved(int)));
492 connect(d->ops, SIGNAL(currentIconSizeChanged(int)),
493 d->iconSizeSlider, SLOT(setValue(int)));
494
495 KAction *furtherAction = new KAction(KIcon("file-zoom-out"), i18n("Zoom out"), this);
496 connect(furtherAction, SIGNAL(triggered()), SLOT(_k_zoomOutIconsSize()));
497 KAction *closerAction = new KAction(KIcon("file-zoom-in"), i18n("Zoom in"), this);
498 connect(closerAction, SIGNAL(triggered()), SLOT(_k_zoomInIconsSize()));
499
500 QWidget *midSpacer = new QWidget(this);
501 midSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
502
503 QAction *separator = new QAction(this);
504 separator->setSeparator(true);
505
506 QAction *separator2 = new QAction(this);
507 separator2->setSeparator(true);
508
509 d->toolbar->addAction(coll->action("back" ));
510 d->toolbar->addAction(coll->action("forward"));
511 d->toolbar->addAction(coll->action("up"));
512 d->toolbar->addAction(coll->action("reload"));
513 d->toolbar->addAction(separator);
514 d->toolbar->addAction(coll->action("inline preview"));
515 d->toolbar->addWidget(midSpacer);
516 d->toolbar->addAction(furtherAction);
517 d->toolbar->addWidget(d->iconSizeSlider);
518 d->toolbar->addAction(closerAction);
519 d->toolbar->addAction(separator2);
520 d->toolbar->addAction(coll->action("mkdir"));
521 d->toolbar->addAction(menu);
522
523 d->toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
524 d->toolbar->setMovable(false);
525
526 KUrlCompletion *pathCompletionObj = new KUrlCompletion( KUrlCompletion::DirCompletion );
527 pathCombo->setCompletionObject( pathCompletionObj );
528 pathCombo->setAutoDeleteCompletionObject( true );
529
530 connect( d->urlNavigator, SIGNAL(urlChanged(KUrl)),
531 this, SLOT(_k_enterUrl(KUrl)));
532 connect( d->urlNavigator, SIGNAL(returnPressed()),
533 d->ops, SLOT(setFocus()));
534
535 QString whatsThisText;
536
537 // the Location label/edit
538 d->locationLabel = new QLabel(i18n("&Name:"), this);
539 d->locationEdit = new KUrlComboBox(KUrlComboBox::Files, true, this);
540 d->locationEdit->installEventFilter(this);
541 // Properly let the dialog be resized (to smaller). Otherwise we could have
542 // huge dialogs that can't be resized to smaller (it would be as big as the longest
543 // item in this combo box). (ereslibre)
544 d->locationEdit->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
545 connect( d->locationEdit, SIGNAL(editTextChanged(QString)),
546 SLOT(_k_slotLocationChanged(QString)) );
547
548 d->updateLocationWhatsThis();
549 d->locationLabel->setBuddy(d->locationEdit);
550
551 KUrlCompletion *fileCompletionObj = new KUrlCompletion( KUrlCompletion::FileCompletion );
552 d->locationEdit->setCompletionObject( fileCompletionObj );
553 d->locationEdit->setAutoDeleteCompletionObject( true );
554 connect( fileCompletionObj, SIGNAL(match(QString)),
555 SLOT(_k_fileCompletion(QString)) );
556
557 connect(d->locationEdit, SIGNAL(returnPressed(QString)),
558 this, SLOT(_k_locationAccepted(QString)));
559
560 // the Filter label/edit
561 whatsThisText = i18n("<qt>This is the filter to apply to the file list. "
562 "File names that do not match the filter will not be shown.<p>"
563 "You may select from one of the preset filters in the "
564 "drop down menu, or you may enter a custom filter "
565 "directly into the text area.</p><p>"
566 "Wildcards such as * and ? are allowed.</p></qt>");
567 d->filterLabel = new QLabel(i18n("&Filter:"), this);
568 d->filterLabel->setWhatsThis(whatsThisText);
569 d->filterWidget = new KFileFilterCombo(this);
570 // Properly let the dialog be resized (to smaller). Otherwise we could have
571 // huge dialogs that can't be resized to smaller (it would be as big as the longest
572 // item in this combo box). (ereslibre)
573 d->filterWidget->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
574 d->filterWidget->setWhatsThis(whatsThisText);
575 d->filterLabel->setBuddy(d->filterWidget);
576 connect(d->filterWidget, SIGNAL(filterChanged()), SLOT(_k_slotFilterChanged()));
577
578 d->filterDelayTimer.setSingleShot(true);
579 d->filterDelayTimer.setInterval(300);
580 connect(d->filterWidget, SIGNAL(editTextChanged(QString)), &d->filterDelayTimer, SLOT(start()));
581 connect(&d->filterDelayTimer, SIGNAL(timeout()), SLOT(_k_slotFilterChanged()));
582
583 // the Automatically Select Extension checkbox
584 // (the text, visibility etc. is set in updateAutoSelectExtension(), which is called by readConfig())
585 d->autoSelectExtCheckBox = new QCheckBox (this);
586 d->autoSelectExtCheckBox->setStyleSheet(QString("QCheckBox { padding-top: %1px; }").arg(KDialog::spacingHint()));
587 connect(d->autoSelectExtCheckBox, SIGNAL(clicked()), SLOT(_k_slotAutoSelectExtClicked()));
588
589 d->initGUI(); // activate GM
590
591 // read our configuration
592 KSharedConfig::Ptr config = KGlobal::config();
593 KConfigGroup group(config, ConfigGroup);
594 readConfig(group);
595
596 coll->action("inline preview")->setChecked(d->ops->isInlinePreviewShown());
597 d->iconSizeSlider->setValue(d->ops->iconsZoom());
598
599 KFilePreviewGenerator *pg = d->ops->previewGenerator();
600 if (pg) {
601 coll->action("inline preview")->setChecked(pg->isPreviewShown());
602 }
603
604 // getStartUrl() above will have resolved the startDir parameter into
605 // a directory and file name in the two cases: (a) where it is a
606 // special "kfiledialog:" URL, or (b) where it is a plain file name
607 // only without directory or protocol. For any other startDir
608 // specified, it is not possible to resolve whether there is a file name
609 // present just by looking at the URL; the only way to be sure is
610 // to stat it.
611 bool statRes = false;
612 if ( filename.isEmpty() )
613 {
614 KIO::StatJob *statJob = KIO::stat(startDir, KIO::HideProgressInfo);
615 statRes = KIO::NetAccess::synchronousRun(statJob, this);
616 kDebug(kfile_area) << "stat of" << startDir << "-> statRes" << statRes << "isDir" << statJob->statResult().isDir();
617 if (!statRes || !statJob->statResult().isDir()) {
618 filename = startDir.fileName();
619 startDir.setPath(startDir.directory());
620 kDebug(kfile_area) << "statJob -> startDir" << startDir << "filename" << filename;
621 }
622 }
623
624 d->ops->setUrl(startDir, true);
625 d->urlNavigator->setLocationUrl(startDir);
626 if (d->placesView) {
627 d->placesView->setUrl(startDir);
628 }
629
630 // We have a file name either explicitly specified, or have checked that
631 // we could stat it and it is not a directory. Set it.
632 if (!filename.isEmpty()) {
633 QLineEdit* lineEdit = d->locationEdit->lineEdit();
634 kDebug(kfile_area) << "selecting filename" << filename;
635 if (statRes) {
636 d->setLocationText(filename);
637 } else {
638 lineEdit->setText(filename);
639 // Preserve this filename when clicking on the view (cf _k_fileHighlighted)
640 lineEdit->setModified(true);
641 }
642 lineEdit->selectAll();
643 }
644
645 d->locationEdit->setFocus();
646}
647
648KFileWidget::~KFileWidget()
649{
650 KSharedConfig::Ptr config = KGlobal::config();
651 config->sync();
652
653 delete d;
654}
655
656void KFileWidget::setLocationLabel(const QString& text)
657{
658 d->locationLabel->setText(text);
659}
660
661void KFileWidget::setFilter(const QString& filter)
662{
663 int pos = filter.indexOf('/');
664
665 // Check for an un-escaped '/', if found
666 // interpret as a MIME filter.
667
668 if (pos > 0 && filter[pos - 1] != '\\') {
669 QStringList filters = filter.split(' ', QString::SkipEmptyParts);
670 setMimeFilter( filters );
671 return;
672 }
673
674 // Strip the escape characters from
675 // escaped '/' characters.
676
677 QString copy (filter);
678 for (pos = 0; (pos = copy.indexOf("\\/", pos)) != -1; ++pos)
679 copy.remove(pos, 1);
680
681 d->ops->clearFilter();
682 d->filterWidget->setFilter(copy);
683 d->ops->setNameFilter(d->filterWidget->currentFilter());
684 d->ops->updateDir();
685 d->hasDefaultFilter = false;
686 d->filterWidget->setEditable( true );
687
688 d->updateAutoSelectExtension ();
689}
690
691QString KFileWidget::currentFilter() const
692{
693 return d->filterWidget->currentFilter();
694}
695
696void KFileWidget::setMimeFilter( const QStringList& mimeTypes,
697 const QString& defaultType )
698{
699 d->filterWidget->setMimeFilter( mimeTypes, defaultType );
700
701 QStringList types = d->filterWidget->currentFilter().split(' ', QString::SkipEmptyParts); //QStringList::split(" ", d->filterWidget->currentFilter());
702 types.append( QLatin1String( "inode/directory" ));
703 d->ops->clearFilter();
704 d->ops->setMimeFilter( types );
705 d->hasDefaultFilter = !defaultType.isEmpty();
706 d->filterWidget->setEditable( !d->hasDefaultFilter ||
707 d->operationMode != Saving );
708
709 d->updateAutoSelectExtension ();
710}
711
712void KFileWidget::clearFilter()
713{
714 d->filterWidget->setFilter( QString() );
715 d->ops->clearFilter();
716 d->hasDefaultFilter = false;
717 d->filterWidget->setEditable( true );
718
719 d->updateAutoSelectExtension ();
720}
721
722QString KFileWidget::currentMimeFilter() const
723{
724 int i = d->filterWidget->currentIndex();
725 if (d->filterWidget->showsAllTypes() && i == 0)
726 return QString(); // The "all types" item has no mimetype
727
728 return d->filterWidget->filters()[i];
729}
730
731KMimeType::Ptr KFileWidget::currentFilterMimeType()
732{
733 return KMimeType::mimeType( currentMimeFilter() );
734}
735
736void KFileWidget::setPreviewWidget(KPreviewWidgetBase *w) {
737 d->ops->setPreviewWidget(w);
738 d->ops->clearHistory();
739 d->hasView = true;
740}
741
742KUrl KFileWidgetPrivate::getCompleteUrl(const QString &_url) const
743{
744// kDebug(kfile_area) << "got url " << _url;
745
746 const QString url = KShell::tildeExpand(_url);
747 KUrl u;
748
749 if (QDir::isAbsolutePath(url)) {
750 u = url;
751 } else {
752 KUrl relativeUrlTest(ops->url());
753 relativeUrlTest.addPath(url);
754 if (!ops->dirLister()->findByUrl(relativeUrlTest).isNull() ||
755 !KProtocolInfo::isKnownProtocol(relativeUrlTest)) {
756 u = relativeUrlTest;
757 } else {
758 u = url;
759 }
760 }
761
762 return u;
763}
764
765// Called by KFileDialog
766void KFileWidget::slotOk()
767{
768// kDebug(kfile_area) << "slotOk\n";
769
770 const KFileItemList items = d->ops->selectedItems();
771 const QString locationEditCurrentText(KShell::tildeExpand(d->locationEditCurrentText()));
772
773 KUrl::List locationEditCurrentTextList(d->tokenize(locationEditCurrentText));
774 KFile::Modes mode = d->ops->mode();
775
776 // if there is nothing to do, just return from here
777 if (!locationEditCurrentTextList.count()) {
778 return;
779 }
780
781 // Make sure that one of the modes was provided
782 if (!((mode & KFile::File) || (mode & KFile::Directory) || (mode & KFile::Files))) {
783 mode |= KFile::File;
784 kDebug(kfile_area) << "No mode() provided";
785 }
786
787 // if we are on file mode, and the list of provided files/folder is greater than one, inform
788 // the user about it
789 if (locationEditCurrentTextList.count() > 1) {
790 if (mode & KFile::File) {
791 KMessageBox::sorry(this,
792 i18n("You can only select one file"),
793 i18n("More than one file provided"));
794 return;
795 }
796
817 if (!d->differentHierarchyLevelItemsEntered) { // avoid infinite recursion. running this
818 KUrl::List urlList; // one time is always enough.
819 int start = 0;
820 KUrl topMostUrl;
821 KIO::StatJob *statJob = 0;
822 bool res = false;
823
824 // we need to check for a valid first url, so in theory we only iterate one time over
825 // this loop. However it can happen that the user did
826 // "home/foo/nonexistantfile" "boot/grub/menu.lst", so we look for a good first
827 // candidate.
828 while (!res && start < locationEditCurrentTextList.count()) {
829 topMostUrl = locationEditCurrentTextList.at(start);
830 statJob = KIO::stat(topMostUrl, KIO::HideProgressInfo);
831 res = KIO::NetAccess::synchronousRun(statJob, this);
832 start++;
833 }
834
835 Q_ASSERT(statJob);
836
837 // if this is not a dir, strip the filename. after this we have an existent and valid
838 // dir (if we stated correctly the file, setting a null filename won't make any bad).
839 if (!statJob->statResult().isDir()) {
840 topMostUrl.setFileName(QString());
841 }
842
843 // now the funny part. for the rest of filenames, go and look for the closest ancestor
844 // of all them.
845 for (int i = start; i < locationEditCurrentTextList.count(); ++i) {
846 KUrl currUrl = locationEditCurrentTextList.at(i);
847 KIO::StatJob *statJob = KIO::stat(currUrl, KIO::HideProgressInfo);
848 bool res = KIO::NetAccess::synchronousRun(statJob, this);
849 if (res) {
850 // again, we don't care about filenames
851 if (!statJob->statResult().isDir()) {
852 currUrl.setFileName(QString());
853 }
854
855 // iterate while this item is contained on the top most url
856 while (!topMostUrl.isParentOf(currUrl)) {
857 topMostUrl = topMostUrl.upUrl();
858 }
859 }
860 }
861
862 // now recalculate all paths for them being relative in base of the top most url
863 for (int i = 0; i < locationEditCurrentTextList.count(); ++i) {
864 locationEditCurrentTextList[i] = KUrl::relativeUrl(topMostUrl, locationEditCurrentTextList[i]);
865 }
866
867 d->ops->setUrl(topMostUrl, true);
868 const bool signalsBlocked = d->locationEdit->lineEdit()->blockSignals(true);
869 QStringList stringList;
870 foreach (const KUrl &url, locationEditCurrentTextList) {
871 stringList << url.prettyUrl();
872 }
873 d->locationEdit->lineEdit()->setText(QString("\"%1\"").arg(stringList.join("\" \"")));
874 d->locationEdit->lineEdit()->blockSignals(signalsBlocked);
875
876 d->differentHierarchyLevelItemsEntered = true;
877 slotOk();
878 return;
879 }
883 } else if (locationEditCurrentTextList.count()) {
884 // if we are on file or files mode, and we have an absolute url written by
885 // the user, convert it to relative
886 if (!locationEditCurrentText.isEmpty() && !(mode & KFile::Directory) &&
887 (QDir::isAbsolutePath(locationEditCurrentText) ||
888 containsProtocolSection(locationEditCurrentText))) {
889
890 QString fileName;
891 KUrl url(locationEditCurrentText);
892 if (d->operationMode == Opening) {
893 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
894 bool res = KIO::NetAccess::synchronousRun(statJob, this);
895 if (res) {
896 if (!statJob->statResult().isDir()) {
897 url.adjustPath(KUrl::RemoveTrailingSlash);
898 fileName = url.fileName();
899 url.setFileName(QString());
900 } else {
901 url.adjustPath(KUrl::AddTrailingSlash);
902 }
903 }
904 } else {
905 KUrl directory = url;
906 directory.setFileName(QString());
907 //Check if the folder exists
908 KIO::StatJob * statJob = KIO::stat(directory, KIO::HideProgressInfo);
909 bool res = KIO::NetAccess::synchronousRun(statJob, this);
910 if (res) {
911 if (statJob->statResult().isDir()) {
912 url.adjustPath(KUrl::RemoveTrailingSlash);
913 fileName = url.fileName();
914 url.setFileName(QString());
915 }
916 }
917 }
918 d->ops->setUrl(url, true);
919 const bool signalsBlocked = d->locationEdit->lineEdit()->blockSignals(true);
920 d->locationEdit->lineEdit()->setText(fileName);
921 d->locationEdit->lineEdit()->blockSignals(signalsBlocked);
922 slotOk();
923 return;
924 }
925 }
926
927 // restore it
928 d->differentHierarchyLevelItemsEntered = false;
929
930 // locationEditCurrentTextList contains absolute paths
931 // this is the general loop for the File and Files mode. Obviously we know
932 // that the File mode will iterate only one time here
933 bool directoryMode = (mode & KFile::Directory);
934 bool onlyDirectoryMode = directoryMode && !(mode & KFile::File) && !(mode & KFile::Files);
935 KUrl::List::ConstIterator it = locationEditCurrentTextList.constBegin();
936 bool filesInList = false;
937 while (it != locationEditCurrentTextList.constEnd()) {
938 KUrl url(*it);
939
940 if (d->operationMode == Saving && !directoryMode) {
941 d->appendExtension(url);
942 }
943
944 d->url = url;
945 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
946 bool res = KIO::NetAccess::synchronousRun(statJob, this);
947
948 if (!KAuthorized::authorizeUrlAction("open", KUrl(), url)) {
949 QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, d->url.prettyUrl());
950 KMessageBox::error(this, msg);
951 return;
952 }
953
954 // if we are on local mode, make sure we haven't got a remote base url
955 if ((mode & KFile::LocalOnly) && !d->mostLocalUrl(d->url).isLocalFile()) {
956 KMessageBox::sorry(this,
957 i18n("You can only select local files"),
958 i18n("Remote files not accepted"));
959 return;
960 }
961
962 // if we are given a folder when not on directory mode, let's get into it
963 if (res && !directoryMode && statJob->statResult().isDir()) {
964 // check if we were given more than one folder, in that case we don't know to which one
965 // cd
966 ++it;
967 while (it != locationEditCurrentTextList.constEnd()) {
968 KUrl checkUrl(*it);
969 KIO::StatJob *checkStatJob = KIO::stat(checkUrl, KIO::HideProgressInfo);
970 bool res = KIO::NetAccess::synchronousRun(checkStatJob, this);
971 if (res && checkStatJob->statResult().isDir()) {
972 KMessageBox::sorry(this, i18n("More than one folder has been selected and this dialog does not accept folders, so it is not possible to decide which one to enter. Please select only one folder to list it."), i18n("More than one folder provided"));
973 return;
974 } else if (res) {
975 filesInList = true;
976 }
977 ++it;
978 }
979 if (filesInList) {
980 KMessageBox::information(this, i18n("At least one folder and one file has been selected. Selected files will be ignored and the selected folder will be listed"), i18n("Files and folders selected"));
981 }
982 d->ops->setUrl(url, true);
983 const bool signalsBlocked = d->locationEdit->lineEdit()->blockSignals(true);
984 d->locationEdit->lineEdit()->setText(QString());
985 d->locationEdit->lineEdit()->blockSignals(signalsBlocked);
986 return;
987 } else if (!(mode & KFile::ExistingOnly) || res) {
988 // if we don't care about ExistingOnly flag, add the file even if
989 // it doesn't exist. If we care about it, don't add it to the list
990 if (!onlyDirectoryMode || (res && statJob->statResult().isDir())) {
991 d->urlList << url;
992 }
993 filesInList = true;
994 } else {
995 KMessageBox::sorry(this, i18n("The file \"%1\" could not be found", url.pathOrUrl()), i18n("Cannot open file"));
996 return; // do not emit accepted() if we had ExistingOnly flag and stat failed
997 }
998
999 if ((d->operationMode == Saving) && d->confirmOverwrite && !d->toOverwrite(url)) {
1000 return;
1001 }
1002
1003 ++it;
1004 }
1005
1006 // if we have reached this point and we didn't return before, that is because
1007 // we want this dialog to be accepted
1008 emit accepted();
1009}
1010
1011void KFileWidget::accept()
1012{
1013 d->inAccept = true; // parseSelectedUrls() checks that
1014
1015 *lastDirectory = d->ops->url();
1016 if (!d->fileClass.isEmpty())
1017 KRecentDirs::add(d->fileClass, d->ops->url().url());
1018
1019 // clear the topmost item, we insert it as full path later on as item 1
1020 d->locationEdit->setItemText( 0, QString() );
1021
1022 const KUrl::List list = selectedUrls();
1023 QList<KUrl>::const_iterator it = list.begin();
1024 int atmost = d->locationEdit->maxItems(); //don't add more items than necessary
1025 for ( ; it != list.end() && atmost > 0; ++it ) {
1026 const KUrl& url = *it;
1027 // we strip the last slash (-1) because KUrlComboBox does that as well
1028 // when operating in file-mode. If we wouldn't , dupe-finding wouldn't
1029 // work.
1030 QString file = url.isLocalFile() ? url.toLocalFile(KUrl::RemoveTrailingSlash) : url.prettyUrl(KUrl::RemoveTrailingSlash);
1031
1032 // remove dupes
1033 for ( int i = 1; i < d->locationEdit->count(); i++ ) {
1034 if ( d->locationEdit->itemText( i ) == file ) {
1035 d->locationEdit->removeItem( i-- );
1036 break;
1037 }
1038 }
1039 //FIXME I don't think this works correctly when the KUrlComboBox has some default urls.
1040 //KUrlComboBox should provide a function to add an url and rotate the existing ones, keeping
1041 //track of maxItems, and we shouldn't be able to insert items as we please.
1042 d->locationEdit->insertItem( 1,file);
1043 atmost--;
1044 }
1045
1046 d->writeViewConfig();
1047 d->saveRecentFiles();
1048
1049 d->addToRecentDocuments();
1050
1051 if (!(mode() & KFile::Files)) { // single selection
1052 emit fileSelected(d->url.url()); // old
1053 emit fileSelected(d->url);
1054 }
1055
1056 d->ops->close();
1057}
1058
1059
1060void KFileWidgetPrivate::_k_fileHighlighted(const KFileItem &i)
1061{
1062 if ((!i.isNull() && i.isDir() ) ||
1063 (locationEdit->hasFocus() && !locationEdit->currentText().isEmpty())) // don't disturb
1064 return;
1065
1066 const bool modified = locationEdit->lineEdit()->isModified();
1067
1068 if (!(ops->mode() & KFile::Files)) {
1069 if (i.isNull()) {
1070 if (!modified) {
1071 setLocationText(KUrl());
1072 }
1073 return;
1074 }
1075
1076 url = i.url();
1077
1078 if (!locationEdit->hasFocus()) { // don't disturb while editing
1079 setLocationText( url );
1080 }
1081
1082 emit q->fileHighlighted(url.url()); // old
1083 emit q->fileHighlighted(url);
1084 } else {
1085 multiSelectionChanged();
1086 emit q->selectionChanged();
1087 }
1088
1089 locationEdit->lineEdit()->setModified( false );
1090 locationEdit->lineEdit()->selectAll();
1091}
1092
1093void KFileWidgetPrivate::_k_fileSelected(const KFileItem &i)
1094{
1095 if (!i.isNull() && i.isDir()) {
1096 return;
1097 }
1098
1099 if (!(ops->mode() & KFile::Files)) {
1100 if (i.isNull()) {
1101 setLocationText(KUrl());
1102 return;
1103 }
1104 setLocationText(i.url());
1105 } else {
1106 multiSelectionChanged();
1107 emit q->selectionChanged();
1108 }
1109
1110 // if we are saving, let another chance to the user before accepting the dialog (or trying to
1111 // accept). This way the user can choose a file and add a "_2" for instance to the filename
1112 if (operationMode == KFileWidget::Saving) {
1113 locationEdit->setFocus();
1114 } else {
1115 q->slotOk();
1116 }
1117}
1118
1119
1120// I know it's slow to always iterate thru the whole filelist
1121// (d->ops->selectedItems()), but what can we do?
1122void KFileWidgetPrivate::multiSelectionChanged()
1123{
1124 if (locationEdit->hasFocus() && !locationEdit->currentText().isEmpty()) { // don't disturb
1125 return;
1126 }
1127
1128 const KFileItemList list = ops->selectedItems();
1129
1130 if (list.isEmpty()) {
1131 setLocationText(KUrl());
1132 return;
1133 }
1134
1135 setLocationText(list.urlList());
1136}
1137
1138void KFileWidgetPrivate::setDummyHistoryEntry( const QString& text, const QPixmap& icon,
1139 bool usePreviousPixmapIfNull )
1140{
1141 // setCurrentItem() will cause textChanged() being emitted,
1142 // so slotLocationChanged() will be called. Make sure we don't clear
1143 // the KDirOperator's view-selection in there
1144 QObject::disconnect( locationEdit, SIGNAL(editTextChanged(QString)),
1145 q, SLOT(_k_slotLocationChanged(QString)) );
1146
1147 bool dummyExists = dummyAdded;
1148
1149 int cursorPosition = locationEdit->lineEdit()->cursorPosition();
1150
1151 if ( dummyAdded ) {
1152 if ( !icon.isNull() ) {
1153 locationEdit->setItemIcon( 0, icon );
1154 locationEdit->setItemText( 0, text );
1155 } else {
1156 if ( !usePreviousPixmapIfNull ) {
1157 locationEdit->setItemIcon( 0, QPixmap() );
1158 }
1159 locationEdit->setItemText( 0, text );
1160 }
1161 } else {
1162 if ( !text.isEmpty() ) {
1163 if ( !icon.isNull() ) {
1164 locationEdit->insertItem( 0, icon, text );
1165 } else {
1166 if ( !usePreviousPixmapIfNull ) {
1167 locationEdit->insertItem( 0, QPixmap(), text );
1168 } else {
1169 locationEdit->insertItem( 0, text );
1170 }
1171 }
1172 dummyAdded = true;
1173 dummyExists = true;
1174 }
1175 }
1176
1177 if ( dummyExists && !text.isEmpty() ) {
1178 locationEdit->setCurrentIndex( 0 );
1179 }
1180
1181 locationEdit->lineEdit()->setCursorPosition( cursorPosition );
1182
1183 QObject::connect( locationEdit, SIGNAL(editTextChanged(QString)),
1184 q, SLOT(_k_slotLocationChanged(QString)) );
1185}
1186
1187void KFileWidgetPrivate::removeDummyHistoryEntry()
1188{
1189 if ( !dummyAdded ) {
1190 return;
1191 }
1192
1193 // setCurrentItem() will cause textChanged() being emitted,
1194 // so slotLocationChanged() will be called. Make sure we don't clear
1195 // the KDirOperator's view-selection in there
1196 QObject::disconnect( locationEdit, SIGNAL(editTextChanged(QString)),
1197 q, SLOT(_k_slotLocationChanged(QString)) );
1198
1199 if (locationEdit->count()) {
1200 locationEdit->removeItem( 0 );
1201 }
1202 locationEdit->setCurrentIndex( -1 );
1203 dummyAdded = false;
1204
1205 QObject::connect( locationEdit, SIGNAL(editTextChanged(QString)),
1206 q, SLOT(_k_slotLocationChanged(QString)) );
1207}
1208
1209void KFileWidgetPrivate::setLocationText(const KUrl& url)
1210{
1211 if (!url.isEmpty()) {
1212 QPixmap mimeTypeIcon = KIconLoader::global()->loadMimeTypeIcon( KMimeType::iconNameForUrl( url ), KIconLoader::Small );
1213 if (url.hasPath()) {
1214 if (!url.directory().isEmpty())
1215 {
1216 KUrl u(url);
1217 u.setPath(u.directory());
1218 q->setUrl(u, false);
1219 }
1220 else {
1221 q->setUrl(url.path(), false);
1222 }
1223 }
1224 setDummyHistoryEntry(url.fileName() , mimeTypeIcon);
1225 } else {
1226 removeDummyHistoryEntry();
1227 }
1228
1229 // don't change selection when user has clicked on an item
1230 if (operationMode == KFileWidget::Saving && !locationEdit->isVisible()) {
1231 setNonExtSelection();
1232 }
1233}
1234
1235static bool isRelativeUrl(const KUrl &baseUrl, const KUrl& url)
1236{
1237 return KUrl::relativeUrl(baseUrl, url) != url.url();
1238}
1239
1240static QString relativePathOrUrl(const KUrl &baseUrl, const KUrl& url)
1241{
1242 if (isRelativeUrl(baseUrl, url)) {
1243 QString relPath = KUrl::relativePath(baseUrl.path(), url.path());
1244 if (relPath.startsWith("./")) {
1245 relPath = relPath.mid(2);
1246 }
1247 return relPath;
1248 } else {
1249 return url.prettyUrl();
1250 }
1251}
1252
1253void KFileWidgetPrivate::setLocationText( const KUrl::List& urlList )
1254{
1255 const KUrl currUrl = ops->url();
1256
1257 if ( urlList.count() > 1 ) {
1258 QString urls;
1259 foreach (const KUrl &url, urlList) {
1260 urls += QString("\"%1\"").arg(relativePathOrUrl(currUrl, url)) + ' ';
1261 }
1262 urls = urls.left( urls.size() - 1 );
1263
1264 setDummyHistoryEntry( urls, QPixmap(), false );
1265 } else if ( urlList.count() == 1 ) {
1266 const QPixmap mimeTypeIcon = KIconLoader::global()->loadMimeTypeIcon( KMimeType::iconNameForUrl( urlList[0] ), KIconLoader::Small );
1267 setDummyHistoryEntry( relativePathOrUrl(currUrl, urlList[0]), mimeTypeIcon );
1268 } else {
1269 removeDummyHistoryEntry();
1270 }
1271
1272 // don't change selection when user has clicked on an item
1273 if ( operationMode == KFileWidget::Saving && !locationEdit->isVisible())
1274 setNonExtSelection();
1275}
1276
1277void KFileWidgetPrivate::updateLocationWhatsThis()
1278{
1279 QString whatsThisText;
1280 if (operationMode == KFileWidget::Saving)
1281 {
1282 whatsThisText = "<qt>" + i18n("This is the name to save the file as.") +
1283 i18n (autocompletionWhatsThisText);
1284 }
1285 else if (ops->mode() & KFile::Files)
1286 {
1287 whatsThisText = "<qt>" + i18n("This is the list of files to open. More than "
1288 "one file can be specified by listing several "
1289 "files, separated by spaces.") +
1290 i18n (autocompletionWhatsThisText);
1291 }
1292 else
1293 {
1294 whatsThisText = "<qt>" + i18n("This is the name of the file to open.") +
1295 i18n (autocompletionWhatsThisText);
1296 }
1297
1298 locationLabel->setWhatsThis(whatsThisText);
1299 locationEdit->setWhatsThis(whatsThisText);
1300}
1301
1302void KFileWidgetPrivate::initSpeedbar()
1303{
1304 if (placesDock) {
1305 return;
1306 }
1307
1308 placesDock = new QDockWidget(i18nc("@title:window", "Places"), q);
1309 placesDock->setFeatures(QDockWidget::DockWidgetClosable);
1310
1311 placesView = new KFilePlacesView(placesDock);
1312 placesView->setModel(model);
1313 placesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1314
1315 placesView->setObjectName(QLatin1String("url bar"));
1316 QObject::connect(placesView, SIGNAL(urlChanged(KUrl)),
1317 q, SLOT(_k_enterUrl(KUrl)));
1318
1319 // need to set the current url of the urlbar manually (not via urlEntered()
1320 // here, because the initial url of KDirOperator might be the same as the
1321 // one that will be set later (and then urlEntered() won't be emitted).
1322 // TODO: KDE5 ### REMOVE THIS when KDirOperator's initial URL (in the c'tor) is gone.
1323 placesView->setUrl(url);
1324
1325 placesDock->setWidget(placesView);
1326 placesViewSplitter->insertWidget(0, placesDock);
1327
1328 // initialize the size of the splitter
1329 placesViewWidth = configGroup.readEntry(SpeedbarWidth, placesView->sizeHint().width());
1330
1331 QList<int> sizes = placesViewSplitter->sizes();
1332 if (placesViewWidth > 0) {
1333 sizes[0] = placesViewWidth + 1;
1334 sizes[1] = q->width() - placesViewWidth -1;
1335 placesViewSplitter->setSizes(sizes);
1336 }
1337
1338 QObject::connect(placesDock, SIGNAL(visibilityChanged(bool)),
1339 q, SLOT(_k_toggleSpeedbar(bool)));
1340}
1341
1342void KFileWidgetPrivate::initGUI()
1343{
1344 delete boxLayout; // deletes all sub layouts
1345
1346 boxLayout = new QVBoxLayout( q);
1347 boxLayout->setMargin(0); // no additional margin to the already existing
1348
1349 placesViewSplitter = new QSplitter(q);
1350 placesViewSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1351 placesViewSplitter->setChildrenCollapsible(false);
1352 boxLayout->addWidget(placesViewSplitter);
1353
1354 QObject::connect(placesViewSplitter, SIGNAL(splitterMoved(int,int)),
1355 q, SLOT(_k_placesViewSplitterMoved(int,int)));
1356 placesViewSplitter->insertWidget(0, opsWidget);
1357
1358 vbox = new QVBoxLayout();
1359 vbox->setMargin(0);
1360 boxLayout->addLayout(vbox);
1361
1362 lafBox = new QGridLayout();
1363
1364 lafBox->addWidget(locationLabel, 0, 0, Qt::AlignVCenter | Qt::AlignRight);
1365 lafBox->addWidget(locationEdit, 0, 1, Qt::AlignVCenter);
1366 lafBox->addWidget(okButton, 0, 2, Qt::AlignVCenter);
1367
1368 lafBox->addWidget(filterLabel, 1, 0, Qt::AlignVCenter | Qt::AlignRight);
1369 lafBox->addWidget(filterWidget, 1, 1, Qt::AlignVCenter);
1370 lafBox->addWidget(cancelButton, 1, 2, Qt::AlignVCenter);
1371
1372 lafBox->setColumnStretch(1, 4);
1373
1374 vbox->addLayout(lafBox);
1375
1376 // add the Automatically Select Extension checkbox
1377 vbox->addWidget(autoSelectExtCheckBox);
1378
1379 q->setTabOrder(ops, autoSelectExtCheckBox);
1380 q->setTabOrder(autoSelectExtCheckBox, locationEdit);
1381 q->setTabOrder(locationEdit, filterWidget);
1382 q->setTabOrder(filterWidget, okButton);
1383 q->setTabOrder(okButton, cancelButton);
1384 q->setTabOrder(cancelButton, urlNavigator);
1385 q->setTabOrder(urlNavigator, ops);
1386 q->setTabOrder(cancelButton, urlNavigator);
1387 q->setTabOrder(urlNavigator, ops);
1388
1389}
1390
1391void KFileWidgetPrivate::_k_slotFilterChanged()
1392{
1393// kDebug(kfile_area);
1394
1395 filterDelayTimer.stop();
1396
1397 QString filter = filterWidget->currentFilter();
1398 ops->clearFilter();
1399
1400 if ( filter.contains('/') ) {
1401 QStringList types = filter.split(' ', QString::SkipEmptyParts);
1402 types.prepend("inode/directory");
1403 ops->setMimeFilter( types );
1404 }
1405 else if ( filter.contains('*') || filter.contains('?') || filter.contains('[') ) {
1406 ops->setNameFilter( filter );
1407 }
1408 else {
1409 ops->setNameFilter('*' + filter.replace(' ', '*') + '*');
1410 }
1411
1412 ops->updateDir();
1413
1414 updateAutoSelectExtension();
1415
1416 emit q->filterChanged(filter);
1417}
1418
1419
1420void KFileWidget::setUrl(const KUrl& url, bool clearforward)
1421{
1422// kDebug(kfile_area);
1423
1424 d->ops->setUrl(url, clearforward);
1425}
1426
1427// Protected
1428void KFileWidgetPrivate::_k_urlEntered(const KUrl& url)
1429{
1430// kDebug(kfile_area);
1431
1432 QString filename = locationEditCurrentText();
1433
1434 KUrlComboBox* pathCombo = urlNavigator->editor();
1435 if (pathCombo->count() != 0) { // little hack
1436 pathCombo->setUrl(url);
1437 }
1438
1439 bool blocked = locationEdit->blockSignals(true);
1440 if (keepLocation) {
1441 locationEdit->changeUrl(0, KIcon(KMimeType::iconNameForUrl(filename)), filename);
1442 locationEdit->lineEdit()->setModified(true);
1443 }
1444
1445 locationEdit->blockSignals( blocked );
1446
1447 urlNavigator->setLocationUrl(url);
1448
1449 // is trigged in ctor before completion object is set
1450 KUrlCompletion *completion = dynamic_cast<KUrlCompletion*>(locationEdit->completionObject());
1451 if (completion) {
1452 completion->setDir( url.path() );
1453 }
1454
1455 if (placesView) {
1456 placesView->setUrl( url );
1457 }
1458}
1459
1460void KFileWidgetPrivate::_k_locationAccepted(const QString &url)
1461{
1462 Q_UNUSED(url);
1463// kDebug(kfile_area);
1464 q->slotOk();
1465}
1466
1467void KFileWidgetPrivate::_k_enterUrl( const KUrl& url )
1468{
1469// kDebug(kfile_area);
1470
1471 KUrl fixedUrl( url );
1472 // append '/' if needed: url combo does not add it
1473 // tokenize() expects it because uses KUrl::setFileName()
1474 fixedUrl.adjustPath( KUrl::AddTrailingSlash );
1475 q->setUrl( fixedUrl );
1476 if (!locationEdit->hasFocus())
1477 ops->setFocus();
1478}
1479
1480void KFileWidgetPrivate::_k_enterUrl( const QString& url )
1481{
1482// kDebug(kfile_area);
1483
1484 _k_enterUrl( KUrl( KUrlCompletion::replacedPath( url, true, true )) );
1485}
1486
1487bool KFileWidgetPrivate::toOverwrite(const KUrl &url)
1488{
1489// kDebug(kfile_area);
1490
1491 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
1492 bool res = KIO::NetAccess::synchronousRun(statJob, q);
1493
1494 if (res) {
1495 int ret = KMessageBox::warningContinueCancel( q,
1496 i18n( "The file \"%1\" already exists. Do you wish to overwrite it?" ,
1497 url.fileName() ), i18n( "Overwrite File?" ), KStandardGuiItem::overwrite(),
1498 KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous);
1499
1500 if (ret != KMessageBox::Continue) {
1501 return false;
1502 }
1503 return true;
1504 }
1505
1506 return true;
1507}
1508
1509void KFileWidget::setSelection(const QString& url)
1510{
1511// kDebug(kfile_area) << "setSelection " << url;
1512
1513 if (url.isEmpty()) {
1514 return;
1515 }
1516
1517 KUrl u = d->getCompleteUrl(url);
1518 if (!u.isValid()) { // if it still is
1519 kWarning() << url << " is not a correct argument for setSelection!";
1520 return;
1521 }
1522
1523 // Honor protocols that do not support directory listing
1524 if (!u.isRelative() && !KProtocolManager::supportsListing(u))
1525 return;
1526
1527 d->setLocationText(url);
1528}
1529
1530void KFileWidgetPrivate::_k_slotLoadingFinished()
1531{
1532 if (locationEdit->currentText().isEmpty()) {
1533 return;
1534 }
1535
1536 ops->blockSignals(true);
1537 KUrl url = ops->url();
1538 url.adjustPath(KUrl::AddTrailingSlash);
1539 url.setFileName(locationEdit->currentText());
1540 ops->setCurrentItem(url.url());
1541 ops->blockSignals(false);
1542}
1543
1544void KFileWidgetPrivate::_k_fileCompletion( const QString& match )
1545{
1546// kDebug(kfile_area);
1547
1548 if (match.isEmpty() || locationEdit->currentText().contains('"')) {
1549 return;
1550 }
1551
1552 setDummyHistoryEntry(locationEdit->currentText(), KIconLoader::global()->loadMimeTypeIcon( KMimeType::iconNameForUrl( match ), KIconLoader::Small), !locationEdit->currentText().isEmpty());
1553}
1554
1555void KFileWidgetPrivate::_k_slotLocationChanged( const QString& text )
1556{
1557// kDebug(kfile_area);
1558
1559 locationEdit->lineEdit()->setModified(true);
1560
1561 if (text.isEmpty() && ops->view()) {
1562 ops->view()->clearSelection();
1563 }
1564
1565 if (text.isEmpty()) {
1566 removeDummyHistoryEntry();
1567 } else {
1568 setDummyHistoryEntry( text );
1569 }
1570
1571 if (!locationEdit->lineEdit()->text().isEmpty()) {
1572 const KUrl::List urlList(tokenize(text));
1573 QStringList stringList;
1574 foreach (const KUrl &url, urlList) {
1575 stringList << url.url();
1576 }
1577 ops->setCurrentItems(stringList);
1578 }
1579
1580 updateFilter();
1581}
1582
1583KUrl KFileWidget::selectedUrl() const
1584{
1585// kDebug(kfile_area);
1586
1587 if ( d->inAccept )
1588 return d->url;
1589 else
1590 return KUrl();
1591}
1592
1593KUrl::List KFileWidget::selectedUrls() const
1594{
1595// kDebug(kfile_area);
1596
1597 KUrl::List list;
1598 if ( d->inAccept ) {
1599 if (d->ops->mode() & KFile::Files)
1600 list = d->parseSelectedUrls();
1601 else
1602 list.append( d->url );
1603 }
1604 return list;
1605}
1606
1607
1608KUrl::List& KFileWidgetPrivate::parseSelectedUrls()
1609{
1610// kDebug(kfile_area);
1611
1612 if ( filenames.isEmpty() ) {
1613 return urlList;
1614 }
1615
1616 urlList.clear();
1617 if ( filenames.contains( '/' )) { // assume _one_ absolute filename
1618 KUrl u;
1619 if ( containsProtocolSection( filenames ) )
1620 u = filenames;
1621 else
1622 u.setPath( filenames );
1623
1624 if ( u.isValid() )
1625 urlList.append( u );
1626 else
1627 KMessageBox::error( q,
1628 i18n("The chosen filenames do not\n"
1629 "appear to be valid."),
1630 i18n("Invalid Filenames") );
1631 }
1632
1633 else
1634 urlList = tokenize( filenames );
1635
1636 filenames.clear(); // indicate that we parsed that one
1637
1638 return urlList;
1639}
1640
1641
1642// FIXME: current implementation drawback: a filename can't contain quotes
1643KUrl::List KFileWidgetPrivate::tokenize( const QString& line ) const
1644{
1645// kDebug(kfile_area);
1646
1647 KUrl::List urls;
1648 KUrl u( ops->url() );
1649 u.adjustPath(KUrl::AddTrailingSlash);
1650 QString name;
1651
1652 const int count = line.count( QLatin1Char( '"' ) );
1653 if ( count == 0 ) { // no " " -> assume one single file
1654 if (!QDir::isAbsolutePath(line)) {
1655 u.setFileName( line );
1656 if ( u.isValid() )
1657 urls.append( u );
1658 } else {
1659 urls << KUrl(line);
1660 }
1661
1662 return urls;
1663 }
1664
1665 int start = 0;
1666 int index1 = -1, index2 = -1;
1667 while ( true ) {
1668 index1 = line.indexOf( '"', start );
1669 index2 = line.indexOf( '"', index1 + 1 );
1670
1671 if ( index1 < 0 || index2 < 0 )
1672 break;
1673
1674 // get everything between the " "
1675 name = line.mid( index1 + 1, index2 - index1 - 1 );
1676
1677 // since we use setFileName we need to do this under a temporary url
1678 KUrl _u( u );
1679 KUrl currUrl( name );
1680
1681 if ( !QDir::isAbsolutePath(currUrl.url()) ) {
1682 _u.setFileName( name );
1683 } else {
1684 // we allow to insert various absolute paths like:
1685 // "/home/foo/bar.txt" "/boot/grub/menu.lst"
1686 _u = currUrl;
1687 }
1688
1689 if ( _u.isValid() ) {
1690 urls.append( _u );
1691 }
1692
1693 start = index2 + 1;
1694 }
1695
1696 return urls;
1697}
1698
1699
1700QString KFileWidget::selectedFile() const
1701{
1702// kDebug(kfile_area);
1703
1704 if ( d->inAccept ) {
1705 const KUrl url = d->mostLocalUrl(d->url);
1706 if (url.isLocalFile())
1707 return url.toLocalFile();
1708 else {
1709 KMessageBox::sorry( const_cast<KFileWidget*>(this),
1710 i18n("You can only select local files."),
1711 i18n("Remote Files Not Accepted") );
1712 }
1713 }
1714 return QString();
1715}
1716
1717QStringList KFileWidget::selectedFiles() const
1718{
1719// kDebug(kfile_area);
1720
1721 QStringList list;
1722
1723 if (d->inAccept) {
1724 if (d->ops->mode() & KFile::Files) {
1725 const KUrl::List urls = d->parseSelectedUrls();
1726 QList<KUrl>::const_iterator it = urls.begin();
1727 while (it != urls.end()) {
1728 KUrl url = d->mostLocalUrl(*it);
1729 if (url.isLocalFile())
1730 list.append(url.toLocalFile());
1731 ++it;
1732 }
1733 }
1734
1735 else { // single-selection mode
1736 if ( d->url.isLocalFile() )
1737 list.append( d->url.toLocalFile() );
1738 }
1739 }
1740
1741 return list;
1742}
1743
1744KUrl KFileWidget::baseUrl() const
1745{
1746 return d->ops->url();
1747}
1748
1749void KFileWidget::resizeEvent(QResizeEvent* event)
1750{
1751 QWidget::resizeEvent(event);
1752
1753 if (d->placesDock) {
1754 // we don't want our places dock actually changing size when we resize
1755 // and qt doesn't make it easy to enforce such a thing with QSplitter
1756 QList<int> sizes = d->placesViewSplitter->sizes();
1757 sizes[0] = d->placesViewWidth + 1; // without this pixel, our places view is reduced 1 pixel each time is shown.
1758 sizes[1] = width() - d->placesViewWidth - 1;
1759 d->placesViewSplitter->setSizes( sizes );
1760 }
1761}
1762
1763void KFileWidget::showEvent(QShowEvent* event)
1764{
1765 if ( !d->hasView ) { // delayed view-creation
1766 Q_ASSERT( d );
1767 Q_ASSERT( d->ops );
1768 d->ops->setView( KFile::Default );
1769 d->ops->view()->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) );
1770 d->hasView = true;
1771 }
1772 d->ops->clearHistory();
1773
1774 QWidget::showEvent(event);
1775}
1776
1777bool KFileWidget::eventFilter(QObject* watched, QEvent* event)
1778{
1779 const bool res = QWidget::eventFilter(watched, event);
1780
1781 QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
1782 if (watched == d->iconSizeSlider && keyEvent) {
1783 if (keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Up ||
1784 keyEvent->key() == Qt::Key_Right || keyEvent->key() == Qt::Key_Down) {
1785 d->_k_slotIconSizeSliderMoved(d->iconSizeSlider->value());
1786 }
1787 } else if (watched == d->locationEdit && event->type() == QEvent::KeyPress) {
1788 if (keyEvent->modifiers() & Qt::AltModifier) {
1789 switch (keyEvent->key()) {
1790 case Qt::Key_Up:
1791 d->ops->actionCollection()->action("up")->trigger();
1792 break;
1793 case Qt::Key_Left:
1794 d->ops->actionCollection()->action("back")->trigger();
1795 break;
1796 case Qt::Key_Right:
1797 d->ops->actionCollection()->action("forward")->trigger();
1798 break;
1799 default:
1800 break;
1801 }
1802 }
1803 }
1804
1805 return res;
1806}
1807
1808void KFileWidget::setMode( KFile::Modes m )
1809{
1810// kDebug(kfile_area);
1811
1812 d->ops->setMode(m);
1813 if ( d->ops->dirOnlyMode() ) {
1814 d->filterWidget->setDefaultFilter( i18n("*|All Folders") );
1815 }
1816 else {
1817 d->filterWidget->setDefaultFilter( i18n("*|All Files") );
1818 }
1819
1820 d->updateAutoSelectExtension();
1821}
1822
1823KFile::Modes KFileWidget::mode() const
1824{
1825 return d->ops->mode();
1826}
1827
1828
1829void KFileWidgetPrivate::readViewConfig()
1830{
1831 ops->setViewConfig(configGroup);
1832 ops->readConfig(configGroup);
1833 KUrlComboBox *combo = urlNavigator->editor();
1834
1835 autoDirectoryFollowing = configGroup.readEntry(AutoDirectoryFollowing,
1836 DefaultDirectoryFollowing);
1837
1838 KGlobalSettings::Completion cm = (KGlobalSettings::Completion)
1839 configGroup.readEntry( PathComboCompletionMode,
1840 static_cast<int>( KGlobalSettings::completionMode() ) );
1841 if ( cm != KGlobalSettings::completionMode() )
1842 combo->setCompletionMode( cm );
1843
1844 cm = (KGlobalSettings::Completion)
1845 configGroup.readEntry( LocationComboCompletionMode,
1846 static_cast<int>( KGlobalSettings::completionMode() ) );
1847 if ( cm != KGlobalSettings::completionMode() )
1848 locationEdit->setCompletionMode( cm );
1849
1850 // show or don't show the speedbar
1851 _k_toggleSpeedbar( configGroup.readEntry( ShowSpeedbar, true ) );
1852
1853 // show or don't show the bookmarks
1854 _k_toggleBookmarks( configGroup.readEntry(ShowBookmarks, false) );
1855
1856 // does the user want Automatically Select Extension?
1857 autoSelectExtChecked = configGroup.readEntry (AutoSelectExtChecked, DefaultAutoSelectExtChecked);
1858 updateAutoSelectExtension();
1859
1860 // should the URL navigator use the breadcrumb navigation?
1861 urlNavigator->setUrlEditable( !configGroup.readEntry(BreadcrumbNavigation, true) );
1862
1863 // should the URL navigator show the full path?
1864 urlNavigator->setShowFullPath( configGroup.readEntry(ShowFullPath, false) );
1865
1866 int w1 = q->minimumSize().width();
1867 int w2 = toolbar->sizeHint().width();
1868 if (w1 < w2)
1869 q->setMinimumWidth(w2);
1870}
1871
1872void KFileWidgetPrivate::writeViewConfig()
1873{
1874 // these settings are global settings; ALL instances of the file dialog
1875 // should reflect them.
1876 // There is no way to tell KFileOperator::writeConfig() to write to
1877 // kdeglobals so we write settings to a temporary config group then copy
1878 // them all to kdeglobals
1879 KConfig tmp( QString(), KConfig::SimpleConfig );
1880 KConfigGroup tmpGroup( &tmp, ConfigGroup );
1881
1882 KUrlComboBox *pathCombo = urlNavigator->editor();
1883 //saveDialogSize( tmpGroup, KConfigGroup::Persistent | KConfigGroup::Global );
1884 tmpGroup.writeEntry( PathComboCompletionMode, static_cast<int>(pathCombo->completionMode()) );
1885 tmpGroup.writeEntry( LocationComboCompletionMode, static_cast<int>(locationEdit->completionMode()) );
1886
1887 const bool showSpeedbar = placesDock && !placesDock->isHidden();
1888 tmpGroup.writeEntry( ShowSpeedbar, showSpeedbar );
1889 if (showSpeedbar) {
1890 const QList<int> sizes = placesViewSplitter->sizes();
1891 Q_ASSERT( sizes.count() > 0 );
1892 tmpGroup.writeEntry( SpeedbarWidth, sizes[0] );
1893 }
1894
1895 tmpGroup.writeEntry( ShowBookmarks, bookmarkHandler != 0 );
1896 tmpGroup.writeEntry( AutoSelectExtChecked, autoSelectExtChecked );
1897 tmpGroup.writeEntry( BreadcrumbNavigation, !urlNavigator->isUrlEditable() );
1898 tmpGroup.writeEntry( ShowFullPath, urlNavigator->showFullPath() );
1899
1900 ops->writeConfig( tmpGroup );
1901
1902 // Copy saved settings to kdeglobals
1903 tmpGroup.copyTo( &configGroup, KConfigGroup::Persistent | KConfigGroup::Global );
1904}
1905
1906
1907void KFileWidgetPrivate::readRecentFiles()
1908{
1909// kDebug(kfile_area);
1910
1911 QObject::disconnect(locationEdit, SIGNAL(editTextChanged(QString)),
1912 q, SLOT(_k_slotLocationChanged(QString)));
1913
1914 locationEdit->setMaxItems(configGroup.readEntry(RecentFilesNumber, DefaultRecentURLsNumber));
1915 locationEdit->setUrls(configGroup.readPathEntry(RecentFiles, QStringList()),
1916 KUrlComboBox::RemoveBottom);
1917 locationEdit->setCurrentIndex(-1);
1918
1919 QObject::connect(locationEdit, SIGNAL(editTextChanged(QString)),
1920 q, SLOT(_k_slotLocationChanged(QString)));
1921
1922 KUrlComboBox *combo = urlNavigator->editor();
1923 combo->setUrls(configGroup.readPathEntry(RecentURLs, QStringList()), KUrlComboBox::RemoveTop);
1924 combo->setMaxItems(configGroup.readEntry(RecentURLsNumber, DefaultRecentURLsNumber));
1925 combo->setUrl(ops->url());
1926 // since we delayed this moment, initialize the directory of the completion object to
1927 // our current directory (that was very probably set on the constructor)
1928 KUrlCompletion *completion = dynamic_cast<KUrlCompletion*>(locationEdit->completionObject());
1929 if (completion) {
1930 completion->setDir(ops->url().url());
1931 }
1932
1933}
1934
1935void KFileWidgetPrivate::saveRecentFiles()
1936{
1937// kDebug(kfile_area);
1938 configGroup.writePathEntry(RecentFiles, locationEdit->urls());
1939
1940 KUrlComboBox *pathCombo = urlNavigator->editor();
1941 configGroup.writePathEntry(RecentURLs, pathCombo->urls());
1942}
1943
1944KPushButton * KFileWidget::okButton() const
1945{
1946 return d->okButton;
1947}
1948
1949KPushButton * KFileWidget::cancelButton() const
1950{
1951 return d->cancelButton;
1952}
1953
1954// Called by KFileDialog
1955void KFileWidget::slotCancel()
1956{
1957// kDebug(kfile_area);
1958
1959 d->ops->close();
1960
1961 d->writeViewConfig();
1962}
1963
1964void KFileWidget::setKeepLocation( bool keep )
1965{
1966 d->keepLocation = keep;
1967}
1968
1969bool KFileWidget::keepsLocation() const
1970{
1971 return d->keepLocation;
1972}
1973
1974void KFileWidget::setOperationMode( OperationMode mode )
1975{
1976// kDebug(kfile_area);
1977
1978 d->operationMode = mode;
1979 d->keepLocation = (mode == Saving);
1980 d->filterWidget->setEditable( !d->hasDefaultFilter || mode != Saving );
1981 if ( mode == Opening ) {
1982 // don't use KStandardGuiItem::open() here which has trailing ellipsis!
1983 d->okButton->setGuiItem( KGuiItem( i18n( "&Open" ), "document-open") );
1984 // hide the new folder actions...usability team says they shouldn't be in open file dialog
1985 actionCollection()->removeAction( actionCollection()->action("mkdir" ) );
1986 } else if ( mode == Saving ) {
1987 d->okButton->setGuiItem( KStandardGuiItem::save() );
1988 d->setNonExtSelection();
1989 } else {
1990 d->okButton->setGuiItem( KStandardGuiItem::ok() );
1991 }
1992 d->updateLocationWhatsThis();
1993 d->updateAutoSelectExtension();
1994
1995 if (d->ops) {
1996 d->ops->setIsSaving(mode == Saving);
1997 }
1998}
1999
2000KFileWidget::OperationMode KFileWidget::operationMode() const
2001{
2002 return d->operationMode;
2003}
2004
2005void KFileWidgetPrivate::_k_slotAutoSelectExtClicked()
2006{
2007// kDebug (kfile_area) << "slotAutoSelectExtClicked(): "
2008// << autoSelectExtCheckBox->isChecked() << endl;
2009
2010 // whether the _user_ wants it on/off
2011 autoSelectExtChecked = autoSelectExtCheckBox->isChecked();
2012
2013 // update the current filename's extension
2014 updateLocationEditExtension (extension /* extension hasn't changed */);
2015}
2016
2017void KFileWidgetPrivate::_k_placesViewSplitterMoved(int pos, int index)
2018{
2019// kDebug(kfile_area);
2020
2021 // we need to record the size of the splitter when the splitter changes size
2022 // so we can keep the places box the right size!
2023 if (placesDock && index == 1) {
2024 placesViewWidth = pos;
2025// kDebug() << "setting lafBox minwidth to" << placesViewWidth;
2026 lafBox->setColumnMinimumWidth(0, placesViewWidth);
2027 }
2028}
2029
2030void KFileWidgetPrivate::_k_activateUrlNavigator()
2031{
2032// kDebug(kfile_area);
2033
2034 urlNavigator->setUrlEditable(!urlNavigator->isUrlEditable());
2035 if(urlNavigator->isUrlEditable()) {
2036 urlNavigator->setFocus();
2037 urlNavigator->editor()->lineEdit()->selectAll();
2038 }
2039}
2040
2041void KFileWidgetPrivate::_k_zoomOutIconsSize()
2042{
2043 const int currValue = ops->iconsZoom();
2044 const int futValue = qMax(0, currValue - 10);
2045 iconSizeSlider->setValue(futValue);
2046 _k_slotIconSizeSliderMoved(futValue);
2047}
2048
2049void KFileWidgetPrivate::_k_zoomInIconsSize()
2050{
2051 const int currValue = ops->iconsZoom();
2052 const int futValue = qMin(100, currValue + 10);
2053 iconSizeSlider->setValue(futValue);
2054 _k_slotIconSizeSliderMoved(futValue);
2055}
2056
2057void KFileWidgetPrivate::_k_slotIconSizeChanged(int _value)
2058{
2059 int maxSize = KIconLoader::SizeEnormous - KIconLoader::SizeSmall;
2060 int value = (maxSize * _value / 100) + KIconLoader::SizeSmall;
2061 switch (value) {
2062 case KIconLoader::SizeSmall:
2063 case KIconLoader::SizeSmallMedium:
2064 case KIconLoader::SizeMedium:
2065 case KIconLoader::SizeLarge:
2066 case KIconLoader::SizeHuge:
2067 case KIconLoader::SizeEnormous:
2068 iconSizeSlider->setToolTip(i18n("Icon size: %1 pixels (standard size)", value));
2069 break;
2070 default:
2071 iconSizeSlider->setToolTip(i18n("Icon size: %1 pixels", value));
2072 break;
2073 }
2074}
2075
2076void KFileWidgetPrivate::_k_slotIconSizeSliderMoved(int _value)
2077{
2078 // Force this to be called in case this slot is called first on the
2079 // slider move.
2080 _k_slotIconSizeChanged(_value);
2081
2082 QPoint global(iconSizeSlider->rect().topLeft());
2083 global.ry() += iconSizeSlider->height() / 2;
2084 QHelpEvent toolTipEvent(QEvent::ToolTip, QPoint(0, 0), iconSizeSlider->mapToGlobal(global));
2085 QApplication::sendEvent(iconSizeSlider, &toolTipEvent);
2086}
2087
2088static QString getExtensionFromPatternList(const QStringList &patternList)
2089{
2090// kDebug(kfile_area);
2091
2092 QString ret;
2093// kDebug (kfile_area) << "\tgetExtension " << patternList;
2094
2095 QStringList::ConstIterator patternListEnd = patternList.end();
2096 for (QStringList::ConstIterator it = patternList.begin();
2097 it != patternListEnd;
2098 ++it)
2099 {
2100// kDebug (kfile_area) << "\t\ttry: \'" << (*it) << "\'";
2101
2102 // is this pattern like "*.BMP" rather than useless things like:
2103 //
2104 // README
2105 // *.
2106 // *.*
2107 // *.JP*G
2108 // *.JP?
2109 if ((*it).startsWith (QLatin1String("*.")) &&
2110 (*it).length() > 2 &&
2111 (*it).indexOf('*', 2) < 0 && (*it).indexOf ('?', 2) < 0)
2112 {
2113 ret = (*it).mid (1);
2114 break;
2115 }
2116 }
2117
2118 return ret;
2119}
2120
2121static QString stripUndisplayable (const QString &string)
2122{
2123 QString ret = string;
2124
2125 ret.remove (':');
2126 ret = KGlobal::locale()->removeAcceleratorMarker (ret);
2127
2128 return ret;
2129}
2130
2131
2132//QString KFileWidget::currentFilterExtension()
2133//{
2134// return d->extension;
2135//}
2136
2137void KFileWidgetPrivate::updateAutoSelectExtension()
2138{
2139 if (!autoSelectExtCheckBox) return;
2140
2141 //
2142 // Figure out an extension for the Automatically Select Extension thing
2143 // (some Windows users apparently don't know what to do when confronted
2144 // with a text file called "COPYING" but do know what to do with
2145 // COPYING.txt ...)
2146 //
2147
2148// kDebug (kfile_area) << "Figure out an extension: ";
2149 QString lastExtension = extension;
2150 extension.clear();
2151
2152 // Automatically Select Extension is only valid if the user is _saving_ a _file_
2153 if ((operationMode == KFileWidget::Saving) && (ops->mode() & KFile::File))
2154 {
2155 //
2156 // Get an extension from the filter
2157 //
2158
2159 QString filter = filterWidget->currentFilter();
2160 if (!filter.isEmpty())
2161 {
2162 // if the currently selected filename already has an extension which
2163 // is also included in the currently allowed extensions, keep it
2164 // otherwise use the default extension
2165 QString currentExtension = KMimeType::extractKnownExtension(locationEditCurrentText());
2166 if ( currentExtension.isEmpty() )
2167 currentExtension = locationEditCurrentText().section(QLatin1Char('.'), -1, -1);
2168 kDebug (kfile_area) << "filter:" << filter << "locationEdit:" << locationEditCurrentText()
2169 << "currentExtension:" << currentExtension;
2170
2171 QString defaultExtension;
2172 QStringList extensionList;
2173
2174 // e.g. "*.cpp"
2175 if (filter.indexOf ('/') < 0)
2176 {
2177 extensionList = filter.split(' ', QString::SkipEmptyParts);
2178 defaultExtension = getExtensionFromPatternList(extensionList);
2179 }
2180 // e.g. "text/html"
2181 else
2182 {
2183 KMimeType::Ptr mime = KMimeType::mimeType (filter);
2184 if (mime)
2185 {
2186 extensionList = mime->patterns();
2187 defaultExtension = mime->mainExtension();
2188 }
2189 }
2190
2191 if ( !currentExtension.isEmpty() && extensionList.contains(QLatin1String("*.") + currentExtension) )
2192 extension = QLatin1Char('.') + currentExtension;
2193 else
2194 extension = defaultExtension;
2195
2196 kDebug (kfile_area) << "List:" << extensionList << "auto-selected extension:" << extension;
2197 }
2198
2199
2200 //
2201 // GUI: checkbox
2202 //
2203
2204 QString whatsThisExtension;
2205 if (!extension.isEmpty())
2206 {
2207 // remember: sync any changes to the string with below
2208 autoSelectExtCheckBox->setText (i18n ("Automatically select filename e&xtension (%1)", extension));
2209 whatsThisExtension = i18n ("the extension <b>%1</b>", extension);
2210
2211 autoSelectExtCheckBox->setEnabled (true);
2212 autoSelectExtCheckBox->setChecked (autoSelectExtChecked);
2213 }
2214 else
2215 {
2216 // remember: sync any changes to the string with above
2217 autoSelectExtCheckBox->setText (i18n ("Automatically select filename e&xtension"));
2218 whatsThisExtension = i18n ("a suitable extension");
2219
2220 autoSelectExtCheckBox->setChecked (false);
2221 autoSelectExtCheckBox->setEnabled (false);
2222 }
2223
2224 const QString locationLabelText = stripUndisplayable (locationLabel->text());
2225 const QString filterLabelText = stripUndisplayable (filterLabel->text());
2226 autoSelectExtCheckBox->setWhatsThis( "<qt>" +
2227 i18n (
2228 "This option enables some convenient features for "
2229 "saving files with extensions:<br />"
2230 "<ol>"
2231 "<li>Any extension specified in the <b>%1</b> text "
2232 "area will be updated if you change the file type "
2233 "to save in.<br />"
2234 "<br /></li>"
2235 "<li>If no extension is specified in the <b>%2</b> "
2236 "text area when you click "
2237 "<b>Save</b>, %3 will be added to the end of the "
2238 "filename (if the filename does not already exist). "
2239 "This extension is based on the file type that you "
2240 "have chosen to save in.<br />"
2241 "<br />"
2242 "If you do not want KDE to supply an extension for the "
2243 "filename, you can either turn this option off or you "
2244 "can suppress it by adding a period (.) to the end of "
2245 "the filename (the period will be automatically "
2246 "removed)."
2247 "</li>"
2248 "</ol>"
2249 "If unsure, keep this option enabled as it makes your "
2250 "files more manageable."
2251 ,
2252 locationLabelText,
2253 locationLabelText,
2254 whatsThisExtension)
2255 + "</qt>"
2256 );
2257
2258 autoSelectExtCheckBox->show();
2259
2260
2261 // update the current filename's extension
2262 updateLocationEditExtension (lastExtension);
2263 }
2264 // Automatically Select Extension not valid
2265 else
2266 {
2267 autoSelectExtCheckBox->setChecked (false);
2268 autoSelectExtCheckBox->hide();
2269 }
2270}
2271
2272// Updates the extension of the filename specified in d->locationEdit if the
2273// Automatically Select Extension feature is enabled.
2274// (this prevents you from accidently saving "file.kwd" as RTF, for example)
2275void KFileWidgetPrivate::updateLocationEditExtension (const QString &lastExtension)
2276{
2277 if (!autoSelectExtCheckBox->isChecked() || extension.isEmpty())
2278 return;
2279
2280 QString urlStr = locationEditCurrentText();
2281 if (urlStr.isEmpty())
2282 return;
2283
2284 KUrl url = getCompleteUrl(urlStr);
2285// kDebug (kfile_area) << "updateLocationEditExtension (" << url << ")";
2286
2287 const int fileNameOffset = urlStr.lastIndexOf ('/') + 1;
2288 QString fileName = urlStr.mid (fileNameOffset);
2289
2290 const int dot = fileName.lastIndexOf ('.');
2291 const int len = fileName.length();
2292 if (dot > 0 && // has an extension already and it's not a hidden file
2293 // like ".hidden" (but we do accept ".hidden.ext")
2294 dot != len - 1 // and not deliberately suppressing extension
2295 )
2296 {
2297 // exists?
2298 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
2299 bool result = KIO::NetAccess::synchronousRun(statJob, q);
2300 if (result)
2301 {
2302// kDebug (kfile_area) << "\tfile exists";
2303
2304 if (statJob->statResult().isDir())
2305 {
2306// kDebug (kfile_area) << "\tisDir - won't alter extension";
2307 return;
2308 }
2309
2310 // --- fall through ---
2311 }
2312
2313
2314 //
2315 // try to get rid of the current extension
2316 //
2317
2318 // catch "double extensions" like ".tar.gz"
2319 if (lastExtension.length() && fileName.endsWith (lastExtension))
2320 fileName.truncate (len - lastExtension.length());
2321 else if (extension.length() && fileName.endsWith (extension))
2322 fileName.truncate (len - extension.length());
2323 // can only handle "single extensions"
2324 else
2325 fileName.truncate (dot);
2326
2327 // add extension
2328 const QString newText = urlStr.left (fileNameOffset) + fileName + extension;
2329 if ( newText != locationEditCurrentText() )
2330 {
2331 locationEdit->setItemText(locationEdit->currentIndex(),urlStr.left (fileNameOffset) + fileName + extension);
2332 locationEdit->lineEdit()->setModified (true);
2333 }
2334 }
2335}
2336
2337// Updates the filter if the extension of the filename specified in d->locationEdit is changed
2338// (this prevents you from accidently saving "file.kwd" as RTF, for example)
2339void KFileWidgetPrivate::updateFilter()
2340{
2341// kDebug(kfile_area);
2342
2343 if ((operationMode == KFileWidget::Saving) && (ops->mode() & KFile::File) ) {
2344 QString urlStr = locationEditCurrentText();
2345 if (urlStr.isEmpty())
2346 return;
2347
2348 if( filterWidget->isMimeFilter()) {
2349 KMimeType::Ptr mime = KMimeType::findByPath(urlStr, 0, true);
2350 if (mime && mime->name() != KMimeType::defaultMimeType()) {
2351 if (filterWidget->currentFilter() != mime->name() &&
2352 filterWidget->filters().indexOf(mime->name()) != -1)
2353 filterWidget->setCurrentFilter(mime->name());
2354 }
2355 } else {
2356 QString filename = urlStr.mid( urlStr.lastIndexOf( KDIR_SEPARATOR ) + 1 ); // only filename
2357 foreach( const QString& filter, filterWidget->filters()) {
2358 QStringList patterns = filter.left( filter.indexOf( '|' )).split ( ' ', QString::SkipEmptyParts ); // '*.foo *.bar|Foo type' -> '*.foo', '*.bar'
2359 foreach ( const QString& p, patterns ) {
2360 if( KMimeType::matchFileName( filename, p )) {
2361 if ( p != "*" ) { // never match the catch-all filter
2362 filterWidget->setCurrentFilter( filter );
2363 }
2364 return; // do not repeat, could match a later filter
2365 }
2366 }
2367 }
2368 }
2369 }
2370}
2371
2372// applies only to a file that doesn't already exist
2373void KFileWidgetPrivate::appendExtension (KUrl &url)
2374{
2375// kDebug(kfile_area);
2376
2377 if (!autoSelectExtCheckBox->isChecked() || extension.isEmpty())
2378 return;
2379
2380 QString fileName = url.fileName();
2381 if (fileName.isEmpty())
2382 return;
2383
2384// kDebug (kfile_area) << "appendExtension(" << url << ")";
2385
2386 const int len = fileName.length();
2387 const int dot = fileName.lastIndexOf ('.');
2388
2389 const bool suppressExtension = (dot == len - 1);
2390 const bool unspecifiedExtension = (dot <= 0);
2391
2392 // don't KIO::Stat if unnecessary
2393 if (!(suppressExtension || unspecifiedExtension))
2394 return;
2395
2396 // exists?
2397 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
2398 bool res = KIO::NetAccess::synchronousRun(statJob, q);
2399 if (res)
2400 {
2401// kDebug (kfile_area) << "\tfile exists - won't append extension";
2402 return;
2403 }
2404
2405 // suppress automatically append extension?
2406 if (suppressExtension)
2407 {
2408 //
2409 // Strip trailing dot
2410 // This allows lazy people to have autoSelectExtCheckBox->isChecked
2411 // but don't want a file extension to be appended
2412 // e.g. "README." will make a file called "README"
2413 //
2414 // If you really want a name like "README.", then type "README.."
2415 // and the trailing dot will be removed (or just stop being lazy and
2416 // turn off this feature so that you can type "README.")
2417 //
2418// kDebug (kfile_area) << "\tstrip trailing dot";
2419 url.setFileName (fileName.left (len - 1));
2420 }
2421 // evilmatically append extension :) if the user hasn't specified one
2422 else if (unspecifiedExtension)
2423 {
2424// kDebug (kfile_area) << "\tappending extension \'" << extension << "\'...";
2425 url.setFileName (fileName + extension);
2426// kDebug (kfile_area) << "\tsaving as \'" << url << "\'";
2427 }
2428}
2429
2430
2431// adds the selected files/urls to 'recent documents'
2432void KFileWidgetPrivate::addToRecentDocuments()
2433{
2434 int m = ops->mode();
2435 int atmost = KRecentDocument::maximumItems();
2436 //don't add more than we need. KRecentDocument::add() is pretty slow
2437
2438 if (m & KFile::LocalOnly) {
2439 const QStringList files = q->selectedFiles();
2440 QStringList::ConstIterator it = files.begin();
2441 for ( ; it != files.end() && atmost > 0; ++it ) {
2442 KRecentDocument::add( *it );
2443 atmost--;
2444 }
2445 }
2446
2447 else { // urls
2448 const KUrl::List urls = q->selectedUrls();
2449 KUrl::List::ConstIterator it = urls.begin();
2450 for ( ; it != urls.end() && atmost > 0; ++it ) {
2451 if ( (*it).isValid() ) {
2452 KRecentDocument::add( *it );
2453 atmost--;
2454 }
2455 }
2456 }
2457}
2458
2459KUrlComboBox* KFileWidget::locationEdit() const
2460{
2461 return d->locationEdit;
2462}
2463
2464KFileFilterCombo* KFileWidget::filterWidget() const
2465{
2466 return d->filterWidget;
2467}
2468
2469KActionCollection * KFileWidget::actionCollection() const
2470{
2471 return d->ops->actionCollection();
2472}
2473
2474void KFileWidgetPrivate::_k_toggleSpeedbar(bool show)
2475{
2476 if (show) {
2477 initSpeedbar();
2478 placesDock->show();
2479 lafBox->setColumnMinimumWidth(0, placesViewWidth);
2480
2481 // check to see if they have a home item defined, if not show the home button
2482 KUrl homeURL;
2483 homeURL.setPath( QDir::homePath() );
2484 KFilePlacesModel *model = static_cast<KFilePlacesModel*>(placesView->model());
2485 for (int rowIndex = 0 ; rowIndex < model->rowCount() ; rowIndex++) {
2486 QModelIndex index = model->index(rowIndex, 0);
2487 KUrl url = model->url(index);
2488
2489 if ( homeURL.equals( url, KUrl::CompareWithoutTrailingSlash ) ) {
2490 toolbar->removeAction( ops->actionCollection()->action( "home" ) );
2491 break;
2492 }
2493 }
2494 } else {
2495 if (q->sender() == placesDock && placesDock && placesDock->isVisibleTo(q)) {
2496 // we didn't *really* go away! the dialog was simply hidden or
2497 // we changed virtual desktops or ...
2498 return;
2499 }
2500
2501 if (placesDock) {
2502 placesDock->hide();
2503 }
2504
2505 QAction* homeAction = ops->actionCollection()->action("home");
2506 QAction* reloadAction = ops->actionCollection()->action("reload");
2507 if (!toolbar->actions().contains(homeAction)) {
2508 toolbar->insertAction(reloadAction, homeAction);
2509 }
2510
2511 // reset the lafbox to not follow the width of the splitter
2512 lafBox->setColumnMinimumWidth(0, 0);
2513 }
2514
2515 static_cast<KToggleAction *>(q->actionCollection()->action("toggleSpeedbar"))->setChecked(show);
2516
2517 // if we don't show the places panel, at least show the places menu
2518 urlNavigator->setPlacesSelectorVisible(!show);
2519}
2520
2521void KFileWidgetPrivate::_k_toggleBookmarks(bool show)
2522{
2523 if (show)
2524 {
2525 if (bookmarkHandler)
2526 {
2527 return;
2528 }
2529
2530 bookmarkHandler = new KFileBookmarkHandler( q );
2531 q->connect( bookmarkHandler, SIGNAL(openUrl(QString)),
2532 SLOT(_k_enterUrl(QString)));
2533
2534 bookmarkButton = new KActionMenu(KIcon("bookmarks"),i18n("Bookmarks"), q);
2535 bookmarkButton->setDelayed(false);
2536 q->actionCollection()->addAction("bookmark", bookmarkButton);
2537 bookmarkButton->setMenu(bookmarkHandler->menu());
2538 bookmarkButton->setWhatsThis(i18n("<qt>This button allows you to bookmark specific locations. "
2539 "Click on this button to open the bookmark menu where you may add, "
2540 "edit or select a bookmark.<br /><br />"
2541 "These bookmarks are specific to the file dialog, but otherwise operate "
2542 "like bookmarks elsewhere in KDE.</qt>"));
2543 toolbar->addAction(bookmarkButton);
2544 }
2545 else if (bookmarkHandler)
2546 {
2547 delete bookmarkHandler;
2548 bookmarkHandler = 0;
2549 delete bookmarkButton;
2550 bookmarkButton = 0;
2551 }
2552
2553 static_cast<KToggleAction *>(q->actionCollection()->action("toggleBookmarks"))->setChecked( show );
2554}
2555
2556
2557// static, overloaded
2558KUrl KFileWidget::getStartUrl( const KUrl& startDir,
2559 QString& recentDirClass )
2560{
2561 QString fileName; // result discarded
2562 return getStartUrl( startDir, recentDirClass, fileName );
2563}
2564
2565
2566// static, overloaded
2567KUrl KFileWidget::getStartUrl( const KUrl& startDir,
2568 QString& recentDirClass,
2569 QString& fileName )
2570{
2571 recentDirClass.clear();
2572 fileName.clear();
2573 KUrl ret;
2574
2575 bool useDefaultStartDir = startDir.isEmpty();
2576 if ( !useDefaultStartDir )
2577 {
2578 if ( startDir.protocol() == "kfiledialog" )
2579 {
2580
2581// The startDir URL with this protocol may be in the format:
2582// directory() fileName()
2583// 1. kfiledialog:///keyword "/" keyword
2584// 2. kfiledialog:///keyword?global "/" keyword
2585// 3. kfiledialog:///keyword/ "/" keyword
2586// 4. kfiledialog:///keyword/?global "/" keyword
2587// 5. kfiledialog:///keyword/filename /keyword filename
2588// 6. kfiledialog:///keyword/filename?global /keyword filename
2589
2590 QString keyword;
2591 QString urlDir = startDir.directory();
2592 QString urlFile = startDir.fileName();
2593 if ( urlDir == "/" ) // '1'..'4' above
2594 {
2595 keyword = urlFile;
2596 fileName.clear();
2597 }
2598 else // '5' or '6' above
2599 {
2600 keyword = urlDir.mid( 1 );
2601 fileName = urlFile;
2602 }
2603
2604 if ( startDir.query() == "?global" )
2605 recentDirClass = QString( "::%1" ).arg( keyword );
2606 else
2607 recentDirClass = QString( ":%1" ).arg( keyword );
2608
2609 ret = KUrl( KRecentDirs::dir(recentDirClass) );
2610 }
2611 else // not special "kfiledialog" URL
2612 {
2613 // "foo.png" only gives us a file name, the default start dir will be used.
2614 // "file:foo.png" (from KHTML/webkit, due to fromPath()) means the same
2615 // (and is the reason why we don't just use QUrl::isRelative()).
2616
2617 // In all other cases (startDir contains a directory path, or has no
2618 // fileName for us anyway, such as smb://), startDir is indeed a dir url.
2619
2620 if (!startDir.directory().isEmpty() ||
2621 startDir.fileName().isEmpty()) {
2622 // can use start directory
2623 ret = startDir; // will be checked by stat later
2624 // If we won't be able to list it (e.g. http), then use default
2625 if ( !KProtocolManager::supportsListing( ret ) ) {
2626 useDefaultStartDir = true;
2627 fileName = startDir.fileName();
2628 }
2629 }
2630 else // file name only
2631 {
2632 fileName = startDir.fileName();
2633 useDefaultStartDir = true;
2634 }
2635 }
2636 }
2637
2638 if ( useDefaultStartDir )
2639 {
2640 if (lastDirectory->isEmpty()) {
2641 lastDirectory->setPath(KGlobalSettings::documentPath());
2642 KUrl home;
2643 home.setPath( QDir::homePath() );
2644 // if there is no docpath set (== home dir), we prefer the current
2645 // directory over it. We also prefer the homedir when our CWD is
2646 // different from our homedirectory or when the document dir
2647 // does not exist
2648 if ( lastDirectory->path(KUrl::AddTrailingSlash) == home.path(KUrl::AddTrailingSlash) ||
2649 QDir::currentPath() != QDir::homePath() ||
2650 !QDir(lastDirectory->path(KUrl::AddTrailingSlash)).exists() )
2651 lastDirectory->setPath(QDir::currentPath());
2652 }
2653 ret = *lastDirectory;
2654 }
2655
2656 kDebug(kfile_area) << "for" << startDir << "->" << ret << "recentDirClass" << recentDirClass << "fileName" << fileName;
2657 return ret;
2658}
2659
2660void KFileWidget::setStartDir( const KUrl& directory )
2661{
2662 if ( directory.isValid() )
2663 *lastDirectory = directory;
2664}
2665
2666void KFileWidgetPrivate::setNonExtSelection()
2667{
2668 // Enhanced rename: Don't highlight the file extension.
2669 QString filename = locationEditCurrentText();
2670 QString extension = KMimeType::extractKnownExtension( filename );
2671
2672 if ( !extension.isEmpty() )
2673 locationEdit->lineEdit()->setSelection( 0, filename.length() - extension.length() - 1 );
2674 else
2675 {
2676 int lastDot = filename.lastIndexOf( '.' );
2677 if ( lastDot > 0 )
2678 locationEdit->lineEdit()->setSelection( 0, lastDot );
2679 }
2680}
2681
2682KToolBar * KFileWidget::toolBar() const
2683{
2684 return d->toolbar;
2685}
2686
2687void KFileWidget::setCustomWidget(QWidget* widget)
2688{
2689 delete d->bottomCustomWidget;
2690 d->bottomCustomWidget = widget;
2691
2692 // add it to the dialog, below the filter list box.
2693
2694 // Change the parent so that this widget is a child of the main widget
2695 d->bottomCustomWidget->setParent( this );
2696
2697 d->vbox->addWidget( d->bottomCustomWidget );
2698 //d->vbox->addSpacing(3); // can't do this every time...
2699
2700 // FIXME: This should adjust the tab orders so that the custom widget
2701 // comes after the Cancel button. The code appears to do this, but the result
2702 // somehow screws up the tab order of the file path combo box. Not a major
2703 // problem, but ideally the tab order with a custom widget should be
2704 // the same as the order without one.
2705 setTabOrder(d->cancelButton, d->bottomCustomWidget);
2706 setTabOrder(d->bottomCustomWidget, d->urlNavigator);
2707}
2708
2709void KFileWidget::setCustomWidget(const QString& text, QWidget* widget)
2710{
2711 delete d->labeledCustomWidget;
2712 d->labeledCustomWidget = widget;
2713
2714 QLabel* label = new QLabel(text, this);
2715 label->setAlignment(Qt::AlignRight);
2716 d->lafBox->addWidget(label, 2, 0, Qt::AlignVCenter);
2717 d->lafBox->addWidget(widget, 2, 1, Qt::AlignVCenter);
2718}
2719
2720void KFileWidget::virtual_hook( int id, void* data )
2721{
2722 // this is a workaround to avoid binary compatibility breakage
2723 // since setConfirmOverwrite in kabstractfilewidget.h is a new function
2724 // introduced for 4.2. As stated in kabstractfilewidget.h this workaround
2725 // is going to become a virtual function for KDE5
2726
2727 switch (id) {
2728 case 0: { // setConfirmOverwrite(bool)
2729 bool *enable = static_cast<bool*>(data);
2730 d->confirmOverwrite = *enable;
2731 }
2732 break;
2733 case 1: { // setInlinePreviewShown(bool)
2734 bool *show = static_cast<bool*>(data);
2735 d->setInlinePreviewShown(*show);
2736 }
2737 break;
2738 default:
2739 break;
2740 }
2741}
2742
2743KDirOperator* KFileWidget::dirOperator()
2744{
2745 return d->ops;
2746}
2747
2748void KFileWidget::readConfig( KConfigGroup& group )
2749{
2750 d->configGroup = group;
2751 d->readViewConfig();
2752 d->readRecentFiles();
2753}
2754
2755QString KFileWidgetPrivate::locationEditCurrentText() const
2756{
2757 return QDir::fromNativeSeparators(locationEdit->currentText());
2758}
2759
2760KUrl KFileWidgetPrivate::mostLocalUrl(const KUrl &url)
2761{
2762 if (url.isLocalFile()) {
2763 return url;
2764 }
2765
2766 KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo);
2767 bool res = KIO::NetAccess::synchronousRun(statJob, q);
2768
2769 if (!res) {
2770 return url;
2771 }
2772
2773 const QString path = statJob->statResult().stringValue(KIO::UDSEntry::UDS_LOCAL_PATH);
2774 if (!path.isEmpty()) {
2775 KUrl newUrl;
2776 newUrl.setPath(path);
2777 return newUrl;
2778 }
2779
2780 return url;
2781}
2782
2783void KFileWidgetPrivate::setInlinePreviewShown(bool show)
2784{
2785 ops->setInlinePreviewShown(show);
2786}
2787
2788
2789#include "kfilewidget.moc"
KAbstractFileWidget
KAbstractFileWidget::OperationMode
OperationMode
KAbstractFileWidget::Opening
Opening
KAbstractFileWidget::Saving
Saving
KActionCollection
KActionCollection::action
QAction * action(const QString &name) const
KActionCollection::addAssociatedWidget
void addAssociatedWidget(QWidget *widget)
KActionCollection::addAction
KAction * addAction(const QString &name, const QObject *receiver=0, const char *member=0)
KActionCollection::removeAction
void removeAction(QAction *action)
KActionMenu
KActionMenu::setDelayed
void setDelayed(bool delayed)
KActionMenu::addSeparator
QAction * addSeparator()
KActionMenu::menu
KMenu * menu()
KActionMenu::addAction
void addAction(QAction *action)
KAction
KAction::setShortcut
void setShortcut(const KShortcut &shortcut, ShortcutTypes type=ShortcutTypes(ActiveShortcut|DefaultShortcut))
KCompletionBase::completionMode
KGlobalSettings::Completion completionMode() const
KCompletionBase::setAutoDeleteCompletionObject
void setAutoDeleteCompletionObject(bool autoDelete)
KCompletionBase::setCompletionMode
virtual void setCompletionMode(KGlobalSettings::Completion mode)
KConfigBase::Persistent
Persistent
KConfigBase::Global
Global
KConfigGroup
KConfig
KConfig::SimpleConfig
SimpleConfig
KDialog::spacingHint
static int spacingHint()
KDirOperator
This widget works as a network transparent filebrowser.
Definition: kdiroperator.h:102
KDirOperator::FileActions
@ FileActions
Definition: kdiroperator.h:114
KDirOperator::ViewActions
@ ViewActions
Definition: kdiroperator.h:112
KDirOperator::SortActions
@ SortActions
Definition: kdiroperator.h:111
KFileBookmarkHandler
Note: Ported to new KBookmarkMenu, but untested.
Definition: kfilebookmarkhandler_p.h:32
KFileFilterCombo
Definition: kfilefiltercombo.h:30
KFileItemList
KFileItem
KFileItem::isDir
bool isDir() const
KFileItem::isNull
bool isNull() const
KFileItem::url
KUrl url() const
KFilePlacesModel
This class is a list view model.
Definition: kfileplacesmodel.h:41
KFilePlacesModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
Get the number of rows for a model index.
Definition: kfileplacesmodel.cpp:266
KFilePlacesModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the children model index for the given row and column.
Definition: kfileplacesmodel.cpp:249
KFilePlacesModel::url
KUrl url(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:177
KFilePlacesView
This class allows to display a KFilePlacesModel.
Definition: kfileplacesview.h:35
KFilePreviewGenerator
Generates previews for files of an item view.
Definition: kfilepreviewgenerator.h:51
KFilePreviewGenerator::isPreviewShown
bool isPreviewShown() const
Definition: kfilepreviewgenerator.cpp:1262
KFileWidget
Definition: kfilewidget.h:40
KFileWidget::setSelection
virtual void setSelection(const QString &name)
Sets the file name to preselect to name.
Definition: kfilewidget.cpp:1509
KFileWidget::getStartUrl
static KUrl getStartUrl(const KUrl &startDir, QString &recentDirClass)
This method implements the logic to determine the user's default directory to be listed.
Definition: kfilewidget.cpp:2558
KFileWidget::dirOperator
KDirOperator * dirOperator()
Definition: kfilewidget.cpp:2743
KFileWidget::setMode
virtual void setMode(KFile::Modes m)
Sets the mode of the dialog.
Definition: kfilewidget.cpp:1808
KFileWidget::setFilter
virtual void setFilter(const QString &filter)
Sets the filter to be used to filter.
Definition: kfilewidget.cpp:661
KFileWidget::selectedFile
virtual QString selectedFile() const
Returns the full path of the selected file in the local filesystem.
Definition: kfilewidget.cpp:1700
KFileWidget::accepted
void accepted()
Emitted by slotOk() (directly or asynchronously) once everything has been done.
KFileWidget::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: kfilewidget.cpp:2720
KFileWidget::setStartDir
static void setStartDir(const KUrl &directory)
Definition: kfilewidget.cpp:2660
KFileWidget::accept
virtual void accept()
Definition: kfilewidget.cpp:1011
KFileWidget::baseUrl
virtual KUrl baseUrl() const
Definition: kfilewidget.cpp:1744
KFileWidget::KFileWidget
KFileWidget(const KUrl &startDir, QWidget *parent)
Constructs a file selector widget.
Definition: kfilewidget.cpp:319
KFileWidget::operationMode
virtual OperationMode operationMode() const
Definition: kfilewidget.cpp:2000
KFileWidget::locationEdit
KUrlComboBox * locationEdit() const
Definition: kfilewidget.cpp:2459
KFileWidget::readConfig
void readConfig(KConfigGroup &group)
reads the configuration for this widget from the given config group
Definition: kfilewidget.cpp:2748
KFileWidget::selectedUrl
virtual KUrl selectedUrl() const
Definition: kfilewidget.cpp:1583
KFileWidget::cancelButton
KPushButton * cancelButton() const
Definition: kfilewidget.cpp:1949
KFileWidget::setUrl
virtual void setUrl(const KUrl &url, bool clearforward=true)
Sets the directory to view.
Definition: kfilewidget.cpp:1420
KFileWidget::~KFileWidget
virtual ~KFileWidget()
Destructor.
Definition: kfilewidget.cpp:648
KFileWidget::setLocationLabel
virtual void setLocationLabel(const QString &text)
Sets the text to be displayed in front of the selection.
Definition: kfilewidget.cpp:656
KFileWidget::slotCancel
virtual void slotCancel()
Definition: kfilewidget.cpp:1955
KFileWidget::mode
virtual KFile::Modes mode() const
Returns the mode of the filedialog.
Definition: kfilewidget.cpp:1823
KFileWidget::slotOk
virtual void slotOk()
Called when clicking ok (when this widget is used in KFileDialog) Might or might not call accept().
Definition: kfilewidget.cpp:766
KFileWidget::filterWidget
KFileFilterCombo * filterWidget() const
Definition: kfilewidget.cpp:2464
KFileWidget::toolBar
KToolBar * toolBar() const
Returns a pointer to the toolbar.
Definition: kfilewidget.cpp:2682
KFileWidget::setKeepLocation
virtual void setKeepLocation(bool keep)
Sets whether the filename/url should be kept when changing directories.
Definition: kfilewidget.cpp:1964
KFileWidget::actionCollection
KActionCollection * actionCollection() const
Definition: kfilewidget.cpp:2469
KFileWidget::selectedFiles
virtual QStringList selectedFiles() const
Returns a list of all selected local files.
Definition: kfilewidget.cpp:1717
KFileWidget::fileSelected
void fileSelected(const KUrl &)
Emitted when the user selects a file.
KFileWidget::keepsLocation
virtual bool keepsLocation() const
Definition: kfilewidget.cpp:1969
KFileWidget::setOperationMode
virtual void setOperationMode(OperationMode)
Sets the operational mode of the filedialog to Saving, Opening or Other.
Definition: kfilewidget.cpp:1974
KFileWidget::filterChanged
void filterChanged(const QString &filter)
Emitted when the filter changed, i.e.
KFileWidget::okButton
KPushButton * okButton() const
Definition: kfilewidget.cpp:1944
KFileWidget::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
Definition: kfilewidget.cpp:1749
KFileWidget::currentMimeFilter
virtual QString currentMimeFilter() const
The mimetype for the desired output format.
Definition: kfilewidget.cpp:722
KFileWidget::fileHighlighted
void fileHighlighted(const KUrl &)
Emitted when the user highlights a file.
KFileWidget::setMimeFilter
virtual void setMimeFilter(const QStringList &types, const QString &defaultType=QString())
Sets the filter up to specify the output type.
Definition: kfilewidget.cpp:696
KFileWidget::setCustomWidget
virtual void setCustomWidget(QWidget *widget)
Set a custom widget that should be added to the file dialog.
Definition: kfilewidget.cpp:2687
KFileWidget::selectedUrls
virtual KUrl::List selectedUrls() const
Definition: kfilewidget.cpp:1593
KFileWidget::showEvent
virtual void showEvent(QShowEvent *event)
Definition: kfilewidget.cpp:1763
KFileWidget::setPreviewWidget
virtual void setPreviewWidget(KPreviewWidgetBase *w)
Adds a preview widget and enters the preview mode.
Definition: kfilewidget.cpp:736
KFileWidget::currentFilter
virtual QString currentFilter() const
Returns the current filter as entered by the user or one of the predefined set via setFilter().
Definition: kfilewidget.cpp:691
KFileWidget::clearFilter
virtual void clearFilter()
Clears any mime- or namefilter.
Definition: kfilewidget.cpp:712
KFileWidget::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
Definition: kfilewidget.cpp:1777
KFileWidget::currentFilterMimeType
virtual KMimeType::Ptr currentFilterMimeType()
Returns the mimetype for the desired output format.
Definition: kfilewidget.cpp:731
KFile::Default
Default
KFile::LocalOnly
LocalOnly
KFile::Files
Files
KFile::Directory
Directory
KFile::ExistingOnly
ExistingOnly
KFile::File
File
KGlobalSettings::desktopPath
static QString desktopPath()
KGlobalSettings::completionMode
static Completion completionMode()
KGlobalSettings::Completion
Completion
KGlobalSettings::documentPath
static QString documentPath()
KGuiItem
KIO::NetAccess::synchronousRun
static bool synchronousRun(Job *job, QWidget *window, QByteArray *data=0, KUrl *finalURL=0, QMap< QString, QString > *metaData=0)
KIO::StatJob
KIO::StatJob::statResult
const UDSEntry & statResult() const
KIO::UDSEntry::stringValue
QString stringValue(uint field) const
KIO::UDSEntry::UDS_LOCAL_PATH
UDS_LOCAL_PATH
KIO::UDSEntry::isDir
bool isDir() const
KIconLoader::Small
Small
KIconLoader::global
static KIconLoader * global()
KIconLoader::loadMimeTypeIcon
QPixmap loadMimeTypeIcon(const QString &iconName, KIconLoader::Group group, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList(), QString *path_store=0) const
KIconLoader::SizeHuge
SizeHuge
KIconLoader::SizeMedium
SizeMedium
KIconLoader::SizeEnormous
SizeEnormous
KIconLoader::SizeSmallMedium
SizeSmallMedium
KIconLoader::SizeSmall
SizeSmall
KIconLoader::SizeLarge
SizeLarge
KIcon
KLocale::removeAcceleratorMarker
QString removeAcceleratorMarker(const QString &label) const
KMessageBox::error
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
KMessageBox::warningContinueCancel
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
KMessageBox::Continue
Continue
KMessageBox::sorry
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
KMessageBox::information
static void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
KMessageBox::Notify
Notify
KMessageBox::Dangerous
Dangerous
KMimeType::defaultMimeType
static QString defaultMimeType()
KMimeType::iconNameForUrl
static QString iconNameForUrl(const KUrl &url, mode_t mode=0)
KMimeType::mimeType
static Ptr mimeType(const QString &name, FindByNameOption options=ResolveAliases)
KMimeType::matchFileName
static bool matchFileName(const QString &filename, const QString &pattern)
KMimeType::findByPath
static Ptr findByPath(const QString &path, mode_t mode=0, bool fast_mode=false, int *accuracy=0)
KMimeType::extractKnownExtension
static QString extractKnownExtension(const QString &fileName)
KPreviewWidgetBase
KProtocolManager::supportsListing
static bool supportsListing(const KUrl &url)
KPushButton
KRecentDocument::maximumItems
static int maximumItems()
KRecentDocument::add
static void add(const KUrl &url)
KSharedPtr< KSharedConfig >
KShortcut
KToggleAction
KToolBar
KUrlComboBox
KUrlComboBox::setUrls
void setUrls(const QStringList &urls)
KUrlComboBox::addDefaultUrl
void addDefaultUrl(const KUrl &url, const QIcon &icon, const QString &text=QString())
KUrlComboBox::RemoveBottom
RemoveBottom
KUrlComboBox::RemoveTop
RemoveTop
KUrlComboBox::setUrl
void setUrl(const KUrl &url)
KUrlComboBox::setCompletionObject
virtual void setCompletionObject(KCompletion *compObj, bool hsig=true)
KUrlComboBox::urls
QStringList urls
KUrlComboBox::setMaxItems
void setMaxItems(int)
KUrlComboBox::Files
Files
KUrlCompletion
KUrlCompletion::DirCompletion
DirCompletion
KUrlCompletion::FileCompletion
FileCompletion
KUrlCompletion::replacedPath
QString replacedPath(const QString &text) const
KUrlNavigator
Widget that allows to navigate through the paths of an URL.
Definition: kurlnavigator.h:76
KUrl::List
KUrl
KUrl::pathOrUrl
QString pathOrUrl() const
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::hasPath
bool hasPath() const
KUrl::RemoveTrailingSlash
RemoveTrailingSlash
KUrl::AddTrailingSlash
AddTrailingSlash
KUrl::adjustPath
void adjustPath(AdjustPathOption trailing)
KUrl::relativeUrl
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::upUrl
KUrl upUrl() const
KUrl::setFileName
void setFileName(const QString &_txt)
KUrl::equals
bool equals(const KUrl &u, const EqualsOptions &options=0) const
KUrl::query
QString query() const
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
KUrl::isLocalFile
bool isLocalFile() const
KUrl::CompareWithoutTrailingSlash
CompareWithoutTrailingSlash
KUrl::setPath
void setPath(const QString &path)
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
KUrl::protocol
QString protocol() const
KUrl::relativePath
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
KUser
QAction
QLabel
QLineEdit
QList
QObject
QWidget
config-kfile.h
kfile_area
const int kfile_area
ConfigGroup
#define ConfigGroup
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
kDebug
#define kDebug
kWarning
#define kWarning
job.h
jobuidelegate.h
kactioncollection.h
kauthorized.h
kdebug.h
kdiroperator.h
kdirselectdialog.h
kfilebookmarkhandler_p.h
kfilefiltercombo.h
kfileitemdelegate.h
kfileplacesmodel.h
kfileplacesview.h
kfilepreviewgenerator.h
relativePathOrUrl
static QString relativePathOrUrl(const KUrl &baseUrl, const KUrl &url)
Definition: kfilewidget.cpp:1240
containsProtocolSection
static bool containsProtocolSection(const QString &string)
Definition: kfilewidget.cpp:296
isRelativeUrl
static bool isRelativeUrl(const KUrl &baseUrl, const KUrl &url)
Definition: kfilewidget.cpp:1235
stripUndisplayable
static QString stripUndisplayable(const QString &string)
Definition: kfilewidget.cpp:2121
autocompletionWhatsThisText
static const char autocompletionWhatsThisText[]
Definition: kfilewidget.cpp:290
getExtensionFromPatternList
static QString getExtensionFromPatternList(const QStringList &patternList)
Definition: kfilewidget.cpp:2088
kfilewidget.h
kimagefilepreview.h
timeout
int timeout
i18n
QString i18n(const char *text)
i18nc
QString i18nc(const char *ctxt, const char *text)
kmenu.h
kmessagebox.h
kmimetype.h
kprotocolmanager.h
kpushbutton.h
krecentdirs.h
krecentdocument.h
kshell.h
ktoolbar.h
kurlcombobox.h
kurlcompletion.h
kurlnavigator.h
kuser.h
KAuthorized::authorizeUrlAction
bool authorizeUrlAction(const QString &action, const KUrl &baseUrl, const KUrl &destUrl)
KGlobal::locale
KLocale * locale()
config
KSharedConfigPtr config()
KIO::pixmapForUrl
QPixmap pixmapForUrl(const KUrl &_url, mode_t _mode=0, KIconLoader::Group _group=KIconLoader::Desktop, int _force_size=0, int _state=0, QString *_path=0)
mostLocalUrl
StatJob * mostLocalUrl(const KUrl &url, JobFlags flags=DefaultFlags)
KIO::buildErrorString
QString buildErrorString(int errorCode, const QString &errorText)
KIO::stat
StatJob * stat(const KUrl &url, bool sideIsSource, short int details, JobFlags flags=DefaultFlags)
KIO::HideProgressInfo
HideProgressInfo
KIO::ERR_ACCESS_DENIED
ERR_ACCESS_DENIED
mimeTypes
QStringList mimeTypes(Mode mode=Writing)
types
QStringList types(Mode mode=Writing)
group
group
KRecentDirs::dir
QString dir(const QString &fileClass)
list
QStringList list(const QString &fileClass)
KRecentDirs::add
void add(const QString &fileClass, const QString &directory)
KShell::tildeExpand
QString tildeExpand(const QString &path)
copy
KAction * copy(const QObject *recvr, const char *slot, QObject *parent)
home
KAction * home(const QObject *recvr, const char *slot, QObject *parent)
name
const char * name(StandardAction id)
KStandardGuiItem::overwrite
KGuiItem overwrite()
KStandardGuiItem::cancel
KGuiItem cancel()
KStandardGuiItem::ok
KGuiItem ok()
KStandardGuiItem::save
KGuiItem save()
label
QString label(StandardShortcut id)
completion
const KShortcut & completion()
netaccess.h
scheduler.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KFile

Skip menu "KFile"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal