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

KFile

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

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs-4.10.5 API Reference

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

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