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

KFile

  • sources
  • kde-4.14
  • kdelibs
  • 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 
73 class KFileWidgetPrivate
74 {
75 public:
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 
288 K_GLOBAL_STATIC(KUrl, lastDirectory) // to set the start path
289 
290 static 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
296 static 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 
319 KFileWidget::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 
648 KFileWidget::~KFileWidget()
649 {
650  KSharedConfig::Ptr config = KGlobal::config();
651  config->sync();
652 
653  delete d;
654 }
655 
656 void KFileWidget::setLocationLabel(const QString& text)
657 {
658  d->locationLabel->setText(text);
659 }
660 
661 void 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 
691 QString KFileWidget::currentFilter() const
692 {
693  return d->filterWidget->currentFilter();
694 }
695 
696 void 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 
712 void 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 
722 QString 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 
731 KMimeType::Ptr KFileWidget::currentFilterMimeType()
732 {
733  return KMimeType::mimeType( currentMimeFilter() );
734 }
735 
736 void KFileWidget::setPreviewWidget(KPreviewWidgetBase *w) {
737  d->ops->setPreviewWidget(w);
738  d->ops->clearHistory();
739  d->hasView = true;
740 }
741 
742 KUrl 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
766 void 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 
1011 void 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 
1060 void 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 
1093 void 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?
1122 void 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 
1138 void 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 
1187 void 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 
1209 void 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 
1235 static bool isRelativeUrl(const KUrl &baseUrl, const KUrl& url)
1236 {
1237  return KUrl::relativeUrl(baseUrl, url) != url.url();
1238 }
1239 
1240 static 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 
1253 void 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 
1277 void 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 
1302 void 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 
1342 void 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 
1391 void 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 
1420 void KFileWidget::setUrl(const KUrl& url, bool clearforward)
1421 {
1422 // kDebug(kfile_area);
1423 
1424  d->ops->setUrl(url, clearforward);
1425 }
1426 
1427 // Protected
1428 void 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 
1460 void KFileWidgetPrivate::_k_locationAccepted(const QString &url)
1461 {
1462  Q_UNUSED(url);
1463 // kDebug(kfile_area);
1464  q->slotOk();
1465 }
1466 
1467 void 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 
1480 void KFileWidgetPrivate::_k_enterUrl( const QString& url )
1481 {
1482 // kDebug(kfile_area);
1483 
1484  _k_enterUrl( KUrl( KUrlCompletion::replacedPath( url, true, true )) );
1485 }
1486 
1487 bool 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 
1509 void 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 
1530 void 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 
1544 void 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 
1555 void 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 
1583 KUrl KFileWidget::selectedUrl() const
1584 {
1585 // kDebug(kfile_area);
1586 
1587  if ( d->inAccept )
1588  return d->url;
1589  else
1590  return KUrl();
1591 }
1592 
1593 KUrl::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 
1608 KUrl::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
1643 KUrl::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 
1700 QString 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 
1717 QStringList 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 
1744 KUrl KFileWidget::baseUrl() const
1745 {
1746  return d->ops->url();
1747 }
1748 
1749 void 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 
1763 void 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 
1777 bool 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 
1808 void 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 
1823 KFile::Modes KFileWidget::mode() const
1824 {
1825  return d->ops->mode();
1826 }
1827 
1828 
1829 void 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 
1872 void 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 
1907 void 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 
1935 void 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 
1944 KPushButton * KFileWidget::okButton() const
1945 {
1946  return d->okButton;
1947 }
1948 
1949 KPushButton * KFileWidget::cancelButton() const
1950 {
1951  return d->cancelButton;
1952 }
1953 
1954 // Called by KFileDialog
1955 void KFileWidget::slotCancel()
1956 {
1957 // kDebug(kfile_area);
1958 
1959  d->ops->close();
1960 
1961  d->writeViewConfig();
1962 }
1963 
1964 void KFileWidget::setKeepLocation( bool keep )
1965 {
1966  d->keepLocation = keep;
1967 }
1968 
1969 bool KFileWidget::keepsLocation() const
1970 {
1971  return d->keepLocation;
1972 }
1973 
1974 void 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 
2000 KFileWidget::OperationMode KFileWidget::operationMode() const
2001 {
2002  return d->operationMode;
2003 }
2004 
2005 void 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 
2017 void 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 
2030 void 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 
2041 void 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 
2049 void 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 
2057 void 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 
2076 void 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 
2088 static 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 
2121 static 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 
2137 void 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)
2275 void 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)
2339 void 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
2373 void 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'
2432 void 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 
2459 KUrlComboBox* KFileWidget::locationEdit() const
2460 {
2461  return d->locationEdit;
2462 }
2463 
2464 KFileFilterCombo* KFileWidget::filterWidget() const
2465 {
2466  return d->filterWidget;
2467 }
2468 
2469 KActionCollection * KFileWidget::actionCollection() const
2470 {
2471  return d->ops->actionCollection();
2472 }
2473 
2474 void 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 
2521 void 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
2558 KUrl 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
2567 KUrl 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 
2660 void KFileWidget::setStartDir( const KUrl& directory )
2661 {
2662  if ( directory.isValid() )
2663  *lastDirectory = directory;
2664 }
2665 
2666 void 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 
2682 KToolBar * KFileWidget::toolBar() const
2683 {
2684  return d->toolbar;
2685 }
2686 
2687 void 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 
2709 void 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 
2720 void 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 
2743 KDirOperator* KFileWidget::dirOperator()
2744 {
2745  return d->ops;
2746 }
2747 
2748 void KFileWidget::readConfig( KConfigGroup& group )
2749 {
2750  d->configGroup = group;
2751  d->readViewConfig();
2752  d->readRecentFiles();
2753 }
2754 
2755 QString KFileWidgetPrivate::locationEditCurrentText() const
2756 {
2757  return QDir::fromNativeSeparators(locationEdit->currentText());
2758 }
2759 
2760 KUrl 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 
2783 void KFileWidgetPrivate::setInlinePreviewShown(bool show)
2784 {
2785  ops->setInlinePreviewShown(show);
2786 }
2787 
2788 
2789 #include "kfilewidget.moc"
KFileWidget::slotCancel
virtual void slotCancel()
Definition: kfilewidget.cpp:1955
KAbstractFileWidget::Saving
KStandardGuiItem::cancel
KGuiItem cancel()
KFilePlacesModel::url
KUrl url(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:177
i18n
QString i18n(const char *text)
KIconLoader::SizeMedium
QList::clear
void clear()
QModelIndex
KSharedPtr< KSharedConfig >
KUrl::adjustPath
void adjustPath(AdjustPathOption trailing)
KPushButton
KIconLoader::SizeLarge
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QEvent
KConfig::sync
void sync()
KFileWidget::currentFilterMimeType
virtual KMimeType::Ptr currentFilterMimeType()
Returns the mimetype for the desired output format.
Definition: kfilewidget.cpp:731
QResizeEvent
KActionCollection
QWidget
QKeyEvent::modifiers
Qt::KeyboardModifiers modifiers() const
KFileWidget::cancelButton
KPushButton * cancelButton() const
Definition: kfilewidget.cpp:1949
kuser.h
QEvent::type
Type type() const
isRelativeUrl
static bool isRelativeUrl(const KUrl &baseUrl, const KUrl &url)
Definition: kfilewidget.cpp:1235
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
QPoint::ry
int & ry()
netaccess.h
KUrl::RemoveTrailingSlash
KFileWidget::setUrl
virtual void setUrl(const KUrl &url, bool clearforward=true)
Sets the directory to view.
Definition: kfilewidget.cpp:1420
KUrl::relativeUrl
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
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
KMessageBox::Continue
QWidget::isHidden
bool isHidden() const
QString::truncate
void truncate(int position)
KFileWidget::setStartDir
static void setStartDir(const KUrl &directory)
Definition: kfilewidget.cpp:2660
KFileWidget::fileHighlighted
void fileHighlighted(const KUrl &)
Emitted when the user highlights a file.
KDirOperator::FileActions
Definition: kdiroperator.h:114
KFileItem::isDir
bool isDir() const
kdebug.h
QAction::setSeparator
void setSeparator(bool b)
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
kmimetype.h
KUrl::relativePath
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
KUrl::AddTrailingSlash
KUrlComboBox::setCompletionObject
virtual void setCompletionObject(KCompletion *compObj, bool hsig=true)
QDir::fromNativeSeparators
QString fromNativeSeparators(const QString &pathName)
KFileWidget::clearFilter
virtual void clearFilter()
Clears any mime- or namefilter.
Definition: kfilewidget.cpp:712
KFilePreviewGenerator
Generates previews for files of an item view.
Definition: kfilepreviewgenerator.h:50
QDockWidget
KIconLoader::global
static KIconLoader * global()
KFileWidget::setKeepLocation
virtual void setKeepLocation(bool keep)
Sets whether the filename/url should be kept when changing directories.
Definition: kfilewidget.cpp:1964
QLineEdit::setText
void setText(const QString &)
KFileWidget::baseUrl
virtual KUrl baseUrl() const
Definition: kfilewidget.cpp:1744
group
KActionMenu::addAction
void addAction(QAction *action)
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
KProtocolInfo::isKnownProtocol
static bool isKnownProtocol(const KUrl &url)
kauthorized.h
KGlobalSettings::desktopPath
static QString desktopPath()
KFile::Directory
copy
KAction * copy(const QObject *recvr, const char *slot, QObject *parent)
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
timeout
int timeout
QAction::setChecked
void setChecked(bool)
KFileItem::isNull
bool isNull() const
KFileWidget::showEvent
virtual void showEvent(QShowEvent *event)
Definition: kfilewidget.cpp:1763
kactioncollection.h
label
QString label(StandardShortcut id)
KMessageBox::information
static void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
KIO::HideProgressInfo
KIconLoader::SizeSmallMedium
QSizePolicy
KUrlComboBox::RemoveTop
KFilePlacesView
This class allows to display a KFilePlacesModel.
Definition: kfileplacesview.h:34
KAbstractFileWidget::Opening
kshell.h
QString::size
int size() const
KFileBookmarkHandler
Note: Ported to new KBookmarkMenu, but untested.
Definition: kfilebookmarkhandler_p.h:31
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
KFileWidget::selectedFile
virtual QString selectedFile() const
Returns the full path of the selected file in the local filesystem.
Definition: kfilewidget.cpp:1700
name
const char * name(StandardAction id)
KFileWidget::setPreviewWidget
virtual void setPreviewWidget(KPreviewWidgetBase *w)
Adds a preview widget and enters the preview mode.
Definition: kfilewidget.cpp:736
KIO::UDSEntry::isDir
bool isDir() const
KRecentDirs::add
void add(const QString &fileClass, const QString &directory)
KIO::NetAccess::synchronousRun
static bool synchronousRun(Job *job, QWidget *window, QByteArray *data=0, KUrl *finalURL=0, QMap< QString, QString > *metaData=0)
kfileitemdelegate.h
KFile::Files
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
KIO::stat
StatJob * stat(const KUrl &url, JobFlags flags=DefaultFlags)
QLabel::setAlignment
void setAlignment(QFlags< Qt::AlignmentFlag >)
KConfig::SimpleConfig
KFileWidget
Definition: kfilewidget.h:39
KActionCollection::addAction
QAction * addAction(const QString &name, QAction *action)
KIO::StatJob
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
KIO::UDSEntry::UDS_LOCAL_PATH
QGridLayout
QPoint
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)
QStringList::join
QString join(const QString &separator) const
KUrl::CompareWithoutTrailingSlash
QString::remove
QString & remove(int position, int n)
KRecentDocument::add
static void add(const KUrl &url)
mostLocalUrl
StatJob * mostLocalUrl(const KUrl &url, JobFlags flags=DefaultFlags)
QDir::currentPath
QString currentPath()
KFile::File
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
relativePathOrUrl
static QString relativePathOrUrl(const KUrl &baseUrl, const KUrl &url)
Definition: kfilewidget.cpp:1240
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QUrl::isEmpty
bool isEmpty() const
QDir::homePath
QString homePath()
KFileWidget::toolBar
KToolBar * toolBar() const
Returns a pointer to the toolbar.
Definition: kfilewidget.cpp:2682
krecentdirs.h
QSlider
KUrl
KUrlComboBox
containsProtocolSection
static bool containsProtocolSection(const QString &string)
Definition: kfilewidget.cpp:296
KFilePlacesModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
Get the number of rows for a model index.
Definition: kfileplacesmodel.cpp:266
config-kfile.h
i18nc
QString i18nc(const char *ctxt, const char *text)
QLineEdit::setModified
void setModified(bool)
KUrlComboBox::setUrls
void setUrls(const QStringList &urls)
config
KSharedConfigPtr config()
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
kprotocolmanager.h
QFSFileEngine::drives
QFileInfoList drives()
KUrl::setPath
void setPath(const QString &path)
KFileWidget::readConfig
void readConfig(KConfigGroup &group)
reads the configuration for this widget from the given config group
Definition: kfilewidget.cpp:2748
KFileWidget::setSelection
virtual void setSelection(const QString &name)
Sets the file name to preselect to name.
Definition: kfilewidget.cpp:1509
KUser
KFileWidget::KFileWidget
KFileWidget(const KUrl &startDir, QWidget *parent)
Constructs a file selector widget.
Definition: kfilewidget.cpp:319
QChar::isLetter
bool isLetter() const
QString::clear
void clear()
scheduler.h
QFileInfo::filePath
QString filePath() const
KShortcut
KFileWidget::setMode
virtual void setMode(KFile::Modes m)
Sets the mode of the dialog.
Definition: kfilewidget.cpp:1808
QWidget::width
int width() const
KFileWidget::~KFileWidget
virtual ~KFileWidget()
Destructor.
Definition: kfilewidget.cpp:648
KIconLoader::SizeEnormous
kimagefilepreview.h
KAbstractFileWidget
KFileWidget::keepsLocation
virtual bool keepsLocation() const
Definition: kfilewidget.cpp:1969
KUrlComboBox::urls
QStringList urls
KUrl::addPath
void addPath(const QString &txt)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
KUrlComboBox::setMaxItems
void setMaxItems(int)
QWidget::showEvent
virtual void showEvent(QShowEvent *event)
QList::count
int count(const T &value) const
QComboBox::count
count
KFileWidget::setFilter
virtual void setFilter(const QString &filter)
Sets the filter to be used to filter.
Definition: kfilewidget.cpp:661
QList::append
void append(const T &value)
QChar::isSpace
bool isSpace() const
KStandardGuiItem::overwrite
KGuiItem overwrite()
KFileWidget::operationMode
virtual OperationMode operationMode() const
Definition: kfilewidget.cpp:2000
QTimer
KIconLoader::Small
KFileWidget::fileSelected
void fileSelected(const KUrl &)
Emitted when the user selects a file.
KFileWidget::okButton
KPushButton * okButton() const
Definition: kfilewidget.cpp:1944
kmenu.h
KUrlComboBox::RemoveBottom
KUrlComboBox::addDefaultUrl
void addDefaultUrl(const KUrl &url, const QString &text=QString())
QShowEvent
QObject
QWidget::setFocus
void setFocus()
KFileWidget::setCustomWidget
virtual void setCustomWidget(QWidget *widget)
Set a custom widget that should be added to the file dialog.
Definition: kfilewidget.cpp:2687
QCheckBox
KGuiItem
KAuthorized::authorizeUrlAction
bool authorizeUrlAction(const QString &action, const KUrl &baseUrl, const KUrl &destUrl)
KUrl::protocol
QString protocol() const
KDirOperator
This widget works as a network transparent filebrowser.
Definition: kdiroperator.h:101
KUrl::upUrl
KUrl upUrl() const
QList::isEmpty
bool isEmpty() const
KMessageBox::sorry
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
QWidget::setTabOrder
void setTabOrder(QWidget *first, QWidget *second)
KIO::buildErrorString
QString buildErrorString(int errorCode, const QString &errorText)
QString::isEmpty
bool isEmpty() const
KComboBox::setCompletionMode
virtual void setCompletionMode(KGlobalSettings::Completion mode)
KMessageBox::Notify
getExtensionFromPatternList
static QString getExtensionFromPatternList(const QStringList &patternList)
Definition: kfilewidget.cpp:2088
QCoreApplication::sendEvent
bool sendEvent(QObject *receiver, QEvent *event)
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KUrl::pathOrUrl
QString pathOrUrl() const
KFileWidget::setOperationMode
virtual void setOperationMode(OperationMode)
Sets the operational mode of the filedialog to Saving, Opening or Other.
Definition: kfilewidget.cpp:1974
KFileItemList
KUrlComboBox::Files
ConfigGroup
#define ConfigGroup
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
KIcon
kfileplacesview.h
KIO::UDSEntry::stringValue
QString stringValue(uint field) const
QWidget::pos
QPoint pos() const
KFileWidget::accepted
void accepted()
Emitted by slotOk() (directly or asynchronously) once everything has been done.
QVBoxLayout
home
KAction * home(const QObject *recvr, const char *slot, QObject *parent)
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
KFileWidget::filterChanged
void filterChanged(const QString &filter)
Emitted when the filter changed, i.e.
KFileWidget::selectedFiles
virtual QStringList selectedFiles() const
Returns a list of all selected local files.
Definition: kfilewidget.cpp:1717
QObject::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
kfilepreviewgenerator.h
kfileplacesmodel.h
stripUndisplayable
static QString stripUndisplayable(const QString &string)
Definition: kfilewidget.cpp:2121
QString
QList< KIO::StatJob * >
KComboBox::setAutoDeleteCompletionObject
void setAutoDeleteCompletionObject(bool autoDelete)
QLineEdit::selectAll
void selectAll()
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
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KFileWidget::locationEdit
KUrlComboBox * locationEdit() const
Definition: kfilewidget.cpp:2459
KActionCollection::removeAction
void removeAction(QAction *action)
KUrl::hasPath
bool hasPath() const
QLayout::setMargin
void setMargin(int margin)
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
QStringList
QObject::signalsBlocked
bool signalsBlocked() const
KActionMenu::menu
KMenu * menu()
QAction::setWhatsThis
void setWhatsThis(const QString &what)
QPixmap
KFileWidget::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
Definition: kfilewidget.cpp:1777
jobuidelegate.h
QFileInfo
types
QStringList types(Mode mode=Writing)
KAction::setShortcut
void setShortcut(const KShortcut &shortcut, ShortcutTypes type=ShortcutTypes(ActiveShortcut|DefaultShortcut))
QList::end
iterator end()
QKeyEvent::key
int key() const
kdirselectdialog.h
QPixmap::isNull
bool isNull() const
KGlobalSettings::documentPath
static QString documentPath()
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QLatin1Char
QAction::setShortcut
void setShortcut(const QKeySequence &shortcut)
KFileWidget::filterWidget
KFileFilterCombo * filterWidget() const
Definition: kfilewidget.cpp:2464
KFile::Default
kpushbutton.h
QChar::toLatin1
char toLatin1() const
KStandardGuiItem::ok
KGuiItem ok()
KIconLoader::SizeHuge
KFilePreviewGenerator::isPreviewShown
bool isPreviewShown() const
Definition: kfilepreviewgenerator.cpp:1262
KIO::ERR_ACCESS_DENIED
KFileFilterCombo
Definition: kfilefiltercombo.h:29
KGlobal::locale
KLocale * locale()
kurlcombobox.h
QDir
KLocale::removeAcceleratorMarker
QString removeAcceleratorMarker(const QString &label) const
job.h
KConfigGroup
QString::replace
QString & replace(int position, int n, QChar after)
KUrl::List
KFile::LocalOnly
QKeyEvent
ktoolbar.h
QSplitter
KConfig
KActionMenu
KUrl::setFileName
void setFileName(const QString &_txt)
QUrl::isValid
bool isValid() const
QDir::isAbsolutePath
bool isAbsolutePath(const QString &path)
QString::mid
QString mid(int position, int n) const
KIconLoader::SizeSmall
KRecentDirs::dir
QString dir(const QString &fileClass)
QLatin1String
QKeySequence
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
KToolBar
QDir::rootPath
QString rootPath()
QString::count
int count() const
QUrl::isRelative
bool isRelative() const
kfilebookmarkhandler_p.h
KActionMenu::addSeparator
QAction * addSeparator()
QAction
KAction
QWidget::QWidget
QWidget(QWidget *parent, QFlags< Qt::WindowType > f)
KFileWidget::actionCollection
KActionCollection * actionCollection() const
Definition: kfilewidget.cpp:2469
KUrlComboBox::setUrl
void setUrl(const KUrl &url)
QList< KUrl >::ConstIterator
typedef ConstIterator
kfilewidget.h
KPreviewWidgetBase
KFileWidget::currentMimeFilter
virtual QString currentMimeFilter() const
The mimetype for the desired output format.
Definition: kfilewidget.cpp:722
KActionCollection::addAssociatedWidget
void addAssociatedWidget(QWidget *widget)
KGlobalSettings::Completion
Completion
krecentdocument.h
KShell::tildeExpand
QString tildeExpand(const QString &path)
QString::length
int length() const
KUrl::query
QString query() const
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QString::section
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
QString::left
QString left(int n) const
KStandardGuiItem::save
KGuiItem save()
KActionCollection::action
QAction * action(int index) const
KToggleAction
QList::prepend
void prepend(const T &value)
KDirOperator::ViewActions
Definition: kdiroperator.h:112
K_GLOBAL_STATIC
K_GLOBAL_STATIC(KUrl, lastDirectory) static const char autocompletionWhatsThisText[]
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KFileWidget::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: kfilewidget.cpp:2720
QLineEdit
QtConcurrent::filter
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
KUrlNavigator
Widget that allows to navigate through the paths of an URL.
Definition: kurlnavigator.h:75
KFileWidget::mode
virtual KFile::Modes mode() const
Returns the mode of the filedialog.
Definition: kfilewidget.cpp:1823
KProtocolManager::supportsListing
static bool supportsListing(const KUrl &url)
KFileWidget::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
Definition: kfilewidget.cpp:1749
QWidget::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
KGlobalSettings::completionMode
static Completion completionMode()
KFileWidget::selectedUrl
virtual KUrl selectedUrl() const
Definition: kfilewidget.cpp:1583
KIO::StatJob::statResult
const UDSEntry & statResult() const
KUrl::isLocalFile
bool isLocalFile() const
kmessagebox.h
kdiroperator.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KMessageBox::Dangerous
QLabel
QHelpEvent
KFile::ExistingOnly
KFileWidget::setLocationLabel
virtual void setLocationLabel(const QString &text)
Sets the text to be displayed in front of the selection.
Definition: kfilewidget.cpp:656
KRecentDocument::maximumItems
static int maximumItems()
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QWidget::event
virtual bool event(QEvent *event)
KUrl::equals
bool equals(const KUrl &u, const EqualsOptions &options=0) const
completion
const KShortcut & completion()
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)
kfile_area
const int kfile_area
QBoxLayout
QList::begin
iterator begin()
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
kurlnavigator.h
KFileItemList::urlList
KUrl::List urlList() const
KComboBox::completionMode
KGlobalSettings::Completion completionMode() const
QBoxLayout::setSpacing
void setSpacing(int spacing)
KFileItem::url
KUrl url() const
KUrlCompletion
KMessageBox::error
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
KActionMenu::setDelayed
void setDelayed(bool delayed)
KFileItem
KAbstractFileWidget::OperationMode
OperationMode
KFileWidget::dirOperator
KDirOperator * dirOperator()
Definition: kfilewidget.cpp:2743
KFileWidget::accept
virtual void accept()
Definition: kfilewidget.cpp:1011
kfilefiltercombo.h
KFileWidget::selectedUrls
virtual KUrl::List selectedUrls() const
Definition: kfilewidget.cpp:1593
KDirOperator::SortActions
Definition: kdiroperator.h:111
list
QStringList list(const QString &fileClass)
kurlcompletion.h
KFilePlacesModel
This class is a list view model.
Definition: kfileplacesmodel.h:40
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:27:27 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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