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

KFile

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

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

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