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

KFile

  • sources
  • kde-4.14
  • kdelibs
  • kfile
kfileplacesmodel.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
3  Copyright (C) 2007 David Faure <faure@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 
19 */
20 #include "kfileplacesmodel.h"
21 #include "kfileplacesitem_p.h"
22 
23 #ifdef _WIN32_WCE
24 #include "Windows.h"
25 #include "WinBase.h"
26 #include <QtCore/QDir>
27 #endif
28 
29 #include <QtCore/QMimeData>
30 #include <QtCore/QTimer>
31 #include <QtCore/QFile>
32 #include <QtGui/QColor>
33 #include <QtGui/QAction>
34 
35 #include <kfileitem.h>
36 #include <kglobal.h>
37 #include <klocale.h>
38 #include <kuser.h>
39 #include <kstandarddirs.h>
40 #include <kcomponentdata.h>
41 #include <kicon.h>
42 #include <kmimetype.h>
43 #include <kdebug.h>
44 
45 #include <kbookmarkmanager.h>
46 #include <kbookmark.h>
47 
48 #include <kio/netaccess.h>
49 #include <kprotocolinfo.h>
50 
51 #include <solid/devicenotifier.h>
52 #include <solid/storageaccess.h>
53 #include <solid/storagedrive.h>
54 #include <solid/storagevolume.h>
55 #include <solid/opticaldrive.h>
56 #include <solid/opticaldisc.h>
57 #include <solid/portablemediaplayer.h>
58 #include <solid/predicate.h>
59 
60 class KFilePlacesModel::Private
61 {
62 public:
63  Private(KFilePlacesModel *self) : q(self), bookmarkManager(0) {}
64  ~Private()
65  {
66  qDeleteAll(items);
67  }
68 
69  KFilePlacesModel *q;
70 
71  QList<KFilePlacesItem*> items;
72  QSet<QString> availableDevices;
73  QMap<QObject*, QPersistentModelIndex> setupInProgress;
74 
75  Solid::Predicate predicate;
76  KBookmarkManager *bookmarkManager;
77 
78  void reloadAndSignal();
79  QList<KFilePlacesItem *> loadBookmarkList();
80 
81  void _k_initDeviceList();
82  void _k_deviceAdded(const QString &udi);
83  void _k_deviceRemoved(const QString &udi);
84  void _k_itemChanged(const QString &udi);
85  void _k_reloadBookmarks();
86  void _k_storageSetupDone(Solid::ErrorType error, QVariant errorData);
87  void _k_storageTeardownDone(Solid::ErrorType error, QVariant errorData);
88 };
89 
90 KFilePlacesModel::KFilePlacesModel(QObject *parent)
91  : QAbstractItemModel(parent), d(new Private(this))
92 {
93  const QString file = KStandardDirs().localxdgdatadir() + "user-places.xbel";
94  d->bookmarkManager = KBookmarkManager::managerForExternalFile(file);
95 
96  // Let's put some places in there if it's empty. We have a corner case here:
97  // Given you have bookmarked some folders (which have been saved on
98  // ~/.local/share/user-places.xbel (according to freedesktop bookmarks spec), and
99  // deleted the home directory ~/.kde, the call managerForFile() will return the
100  // bookmark manager for the fallback "kfilePlaces", making root.first().isNull() being
101  // false (you have your own items bookmarked), resulting on only being added your own
102  // bookmarks, and not the default ones too. So, we also check if kfileplaces/bookmarks.xml
103  // file exists, and if it doesn't, we also add the default places. (ereslibre)
104  KBookmarkGroup root = d->bookmarkManager->root();
105  if (root.first().isNull() || !QFile::exists(file)) {
106 
107  // NOTE: The context for these I18N_NOOP2 calls has to be "KFile System Bookmarks".
108  // The real i18nc call is made later, with this context, so the two must match.
109  //
110  // createSystemBookmark actually does nothing with its third argument,
111  // but we have to give it something so the I18N_NOOP2 calls stay here for now.
112  //
113  // (coles, 13th May 2009)
114 
115  KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
116  "Home", I18N_NOOP2("KFile System Bookmarks", "Home"),
117  KUrl(KUser().homeDir()), "user-home");
118  KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
119  "Network", I18N_NOOP2("KFile System Bookmarks", "Network"),
120  KUrl("remote:/"), "network-workgroup");
121 #if defined(_WIN32_WCE)
122  // adding drives
123  foreach ( const QFileInfo& info, QDir::drives() ) {
124  QString driveIcon = "drive-harddisk";
125  KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
126  info.absoluteFilePath(), info.absoluteFilePath(),
127  KUrl(info.absoluteFilePath()), driveIcon);
128  }
129 #elif !defined(Q_OS_WIN)
130  KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
131  "Root", I18N_NOOP2("KFile System Bookmarks", "Root"),
132  KUrl("/"), "folder-red");
133 #endif
134  KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
135  "Trash", I18N_NOOP2("KFile System Bookmarks", "Trash"),
136  KUrl("trash:/"), "user-trash");
137 
138  // Force bookmarks to be saved. If on open/save dialog and the bookmarks are not saved, QFile::exists
139  // will always return false, which opening/closing all the time the open/save dialog would case the
140  // bookmarks to be added once each time, having lots of times each bookmark. This forces the defaults
141  // to be saved on the bookmarks.xml file. Of course, the complete list of bookmarks (those that come from
142  // user-places.xbel will be filled later). (ereslibre)
143  d->bookmarkManager->saveAs(file);
144  }
145 
146  QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
147  " OR "
148  "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]"
149  " OR "
150  "OpticalDisc.availableContent & 'Audio' ]"
151  " OR "
152  "StorageAccess.ignored == false ]");
153 
154  if (KProtocolInfo::isKnownProtocol("mtp")) {
155  predicate.prepend("[");
156  predicate.append(" OR PortableMediaPlayer.supportedProtocols == 'mtp']");
157  }
158 
159  d->predicate = Solid::Predicate::fromString(predicate);
160 
161  Q_ASSERT(d->predicate.isValid());
162 
163  connect(d->bookmarkManager, SIGNAL(changed(QString,QString)),
164  this, SLOT(_k_reloadBookmarks()));
165  connect(d->bookmarkManager, SIGNAL(bookmarksChanged(QString)),
166  this, SLOT(_k_reloadBookmarks()));
167 
168  d->_k_reloadBookmarks();
169  QTimer::singleShot(0, this, SLOT(_k_initDeviceList()));
170 }
171 
172 KFilePlacesModel::~KFilePlacesModel()
173 {
174  delete d;
175 }
176 
177 KUrl KFilePlacesModel::url(const QModelIndex &index) const
178 {
179  return KUrl(data(index, UrlRole).toUrl());
180 }
181 
182 bool KFilePlacesModel::setupNeeded(const QModelIndex &index) const
183 {
184  return data(index, SetupNeededRole).toBool();
185 }
186 
187 KIcon KFilePlacesModel::icon(const QModelIndex &index) const
188 {
189  return KIcon(data(index, Qt::DecorationRole).value<QIcon>());
190 }
191 
192 QString KFilePlacesModel::text(const QModelIndex &index) const
193 {
194  return data(index, Qt::DisplayRole).toString();
195 }
196 
197 bool KFilePlacesModel::isHidden(const QModelIndex &index) const
198 {
199  return data(index, HiddenRole).toBool();
200 }
201 
202 bool KFilePlacesModel::isDevice(const QModelIndex &index) const
203 {
204  if (!index.isValid())
205  return false;
206 
207  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
208 
209  return item->isDevice();
210 }
211 
212 Solid::Device KFilePlacesModel::deviceForIndex(const QModelIndex &index) const
213 {
214  if (!index.isValid())
215  return Solid::Device();
216 
217  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
218 
219  if (item->isDevice()) {
220  return item->device();
221  } else {
222  return Solid::Device();
223  }
224 }
225 
226 KBookmark KFilePlacesModel::bookmarkForIndex(const QModelIndex &index) const
227 {
228  if (!index.isValid())
229  return KBookmark();
230 
231  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
232 
233  if (!item->isDevice()) {
234  return item->bookmark();
235  } else {
236  return KBookmark();
237  }
238 }
239 
240 QVariant KFilePlacesModel::data(const QModelIndex &index, int role) const
241 {
242  if (!index.isValid())
243  return QVariant();
244 
245  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
246  return item->data(role);
247 }
248 
249 QModelIndex KFilePlacesModel::index(int row, int column, const QModelIndex &parent) const
250 {
251  if (row<0 || column!=0 || row>=d->items.size())
252  return QModelIndex();
253 
254  if (parent.isValid())
255  return QModelIndex();
256 
257  return createIndex(row, column, d->items.at(row));
258 }
259 
260 QModelIndex KFilePlacesModel::parent(const QModelIndex &child) const
261 {
262  Q_UNUSED(child);
263  return QModelIndex();
264 }
265 
266 int KFilePlacesModel::rowCount(const QModelIndex &parent) const
267 {
268  if (parent.isValid())
269  return 0;
270  else
271  return d->items.size();
272 }
273 
274 int KFilePlacesModel::columnCount(const QModelIndex &parent) const
275 {
276  Q_UNUSED(parent)
277  // We only know 1 piece of information for a particular entry
278  return 1;
279 }
280 
281 QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const
282 {
283  int foundRow = -1;
284  int maxLength = 0;
285 
286  // Search the item which is equal to the URL or at least is a parent URL.
287  // If there are more than one possible item URL candidates, choose the item
288  // which covers the bigger range of the URL.
289  for (int row = 0; row<d->items.size(); ++row) {
290  KFilePlacesItem *item = d->items[row];
291  KUrl itemUrl = KUrl(item->data(UrlRole).toUrl());
292 
293  if (itemUrl.isParentOf(url)) {
294  const int length = itemUrl.prettyUrl().length();
295  if (length > maxLength) {
296  foundRow = row;
297  maxLength = length;
298  }
299  }
300  }
301 
302  if (foundRow==-1)
303  return QModelIndex();
304  else
305  return createIndex(foundRow, 0, d->items[foundRow]);
306 }
307 
308 void KFilePlacesModel::Private::_k_initDeviceList()
309 {
310  Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance();
311 
312  connect(notifier, SIGNAL(deviceAdded(QString)),
313  q, SLOT(_k_deviceAdded(QString)));
314  connect(notifier, SIGNAL(deviceRemoved(QString)),
315  q, SLOT(_k_deviceRemoved(QString)));
316 
317  const QList<Solid::Device> &deviceList = Solid::Device::listFromQuery(predicate);
318 
319  foreach(const Solid::Device &device, deviceList) {
320  availableDevices << device.udi();
321  }
322 
323  _k_reloadBookmarks();
324 }
325 
326 void KFilePlacesModel::Private::_k_deviceAdded(const QString &udi)
327 {
328  Solid::Device d(udi);
329 
330  if (predicate.matches(d)) {
331  availableDevices << udi;
332  _k_reloadBookmarks();
333  }
334 }
335 
336 void KFilePlacesModel::Private::_k_deviceRemoved(const QString &udi)
337 {
338  if (availableDevices.contains(udi)) {
339  availableDevices.remove(udi);
340  _k_reloadBookmarks();
341  }
342 }
343 
344 void KFilePlacesModel::Private::_k_itemChanged(const QString &id)
345 {
346  for (int row = 0; row<items.size(); ++row) {
347  if (items.at(row)->id()==id) {
348  QModelIndex index = q->index(row, 0);
349  emit q->dataChanged(index, index);
350  }
351  }
352 }
353 
354 void KFilePlacesModel::Private::_k_reloadBookmarks()
355 {
356  QList<KFilePlacesItem*> currentItems = loadBookmarkList();
357 
358  QList<KFilePlacesItem*>::Iterator it_i = items.begin();
359  QList<KFilePlacesItem*>::Iterator it_c = currentItems.begin();
360 
361  QList<KFilePlacesItem*>::Iterator end_i = items.end();
362  QList<KFilePlacesItem*>::Iterator end_c = currentItems.end();
363 
364  while (it_i!=end_i || it_c!=end_c) {
365  if (it_i==end_i && it_c!=end_c) {
366  int row = items.count();
367 
368  q->beginInsertRows(QModelIndex(), row, row);
369  it_i = items.insert(it_i, *it_c);
370  ++it_i;
371  it_c = currentItems.erase(it_c);
372 
373  end_i = items.end();
374  end_c = currentItems.end();
375  q->endInsertRows();
376 
377  } else if (it_i!=end_i && it_c==end_c) {
378  int row = items.indexOf(*it_i);
379 
380  q->beginRemoveRows(QModelIndex(), row, row);
381  delete *it_i;
382  it_i = items.erase(it_i);
383 
384  end_i = items.end();
385  end_c = currentItems.end();
386  q->endRemoveRows();
387 
388  } else if ((*it_i)->id()==(*it_c)->id()) {
389  bool shouldEmit = !((*it_i)->bookmark()==(*it_c)->bookmark());
390  (*it_i)->setBookmark((*it_c)->bookmark());
391  if (shouldEmit) {
392  int row = items.indexOf(*it_i);
393  QModelIndex idx = q->index(row, 0);
394  emit q->dataChanged(idx, idx);
395  }
396  ++it_i;
397  ++it_c;
398  } else if ((*it_i)->id()!=(*it_c)->id()) {
399  int row = items.indexOf(*it_i);
400 
401  if (it_i+1!=end_i && (*(it_i+1))->id()==(*it_c)->id()) { // if the next one matches, it's a remove
402  q->beginRemoveRows(QModelIndex(), row, row);
403  delete *it_i;
404  it_i = items.erase(it_i);
405 
406  end_i = items.end();
407  end_c = currentItems.end();
408  q->endRemoveRows();
409  } else {
410  q->beginInsertRows(QModelIndex(), row, row);
411  it_i = items.insert(it_i, *it_c);
412  ++it_i;
413  it_c = currentItems.erase(it_c);
414 
415  end_i = items.end();
416  end_c = currentItems.end();
417  q->endInsertRows();
418  }
419  }
420  }
421 
422  qDeleteAll(currentItems);
423  currentItems.clear();
424 }
425 
426 QList<KFilePlacesItem *> KFilePlacesModel::Private::loadBookmarkList()
427 {
428  QList<KFilePlacesItem*> items;
429 
430  KBookmarkGroup root = bookmarkManager->root();
431  KBookmark bookmark = root.first();
432  QSet<QString> devices = availableDevices;
433 
434  while (!bookmark.isNull()) {
435  QString udi = bookmark.metaDataItem("UDI");
436  QString appName = bookmark.metaDataItem("OnlyInApp");
437  bool deviceAvailable = devices.remove(udi);
438 
439  bool allowedHere = appName.isEmpty() || (appName==KGlobal::mainComponent().componentName());
440 
441  if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
442  KFilePlacesItem *item;
443  if (deviceAvailable) {
444  item = new KFilePlacesItem(bookmarkManager, bookmark.address(), udi);
445  // TODO: Update bookmark internal element
446  } else {
447  item = new KFilePlacesItem(bookmarkManager, bookmark.address());
448  }
449  connect(item, SIGNAL(itemChanged(QString)),
450  q, SLOT(_k_itemChanged(QString)));
451  items << item;
452  }
453 
454  bookmark = root.next(bookmark);
455  }
456 
457  // Add bookmarks for the remaining devices, they were previously unknown
458  foreach (const QString &udi, devices) {
459  bookmark = KFilePlacesItem::createDeviceBookmark(bookmarkManager, udi);
460  if (!bookmark.isNull()) {
461  KFilePlacesItem *item = new KFilePlacesItem(bookmarkManager,
462  bookmark.address(), udi);
463  connect(item, SIGNAL(itemChanged(QString)),
464  q, SLOT(_k_itemChanged(QString)));
465  // TODO: Update bookmark internal element
466  items << item;
467  }
468  }
469 
470  return items;
471 }
472 
473 void KFilePlacesModel::Private::reloadAndSignal()
474 {
475  bookmarkManager->emitChanged(bookmarkManager->root()); // ... we'll get relisted anyway
476 }
477 
478 Qt::DropActions KFilePlacesModel::supportedDropActions() const
479 {
480  return Qt::ActionMask;
481 }
482 
483 Qt::ItemFlags KFilePlacesModel::flags(const QModelIndex &index) const
484 {
485  Qt::ItemFlags res = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
486 
487  if (index.isValid())
488  res|= Qt::ItemIsDragEnabled;
489 
490  if (!index.isValid())
491  res|= Qt::ItemIsDropEnabled;
492 
493  return res;
494 }
495 
496 static QString _k_internalMimetype(const KFilePlacesModel * const self)
497 {
498  return QString("application/x-kfileplacesmodel-")+QString::number((qptrdiff)self);
499 }
500 
501 QStringList KFilePlacesModel::mimeTypes() const
502 {
503  QStringList types;
504 
505  types << _k_internalMimetype(this) << "text/uri-list";
506 
507  return types;
508 }
509 
510 QMimeData *KFilePlacesModel::mimeData(const QModelIndexList &indexes) const
511 {
512  KUrl::List urls;
513  QByteArray itemData;
514 
515  QDataStream stream(&itemData, QIODevice::WriteOnly);
516 
517  foreach (const QModelIndex &index, indexes) {
518  KUrl itemUrl = url(index);
519  if (itemUrl.isValid())
520  urls << itemUrl;
521  stream << index.row();
522  }
523 
524  QMimeData *mimeData = new QMimeData();
525 
526  if (!urls.isEmpty())
527  urls.populateMimeData(mimeData);
528 
529  mimeData->setData(_k_internalMimetype(this), itemData);
530 
531  return mimeData;
532 }
533 
534 bool KFilePlacesModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
535  int row, int column, const QModelIndex &parent)
536 {
537  if (action == Qt::IgnoreAction)
538  return true;
539 
540  if (column > 0)
541  return false;
542 
543  if (row==-1 && parent.isValid()) {
544  return false; // Don't allow to move an item onto another one,
545  // too easy for the user to mess something up
546  // If we really really want to allow copying files this way,
547  // let's do it in the views to get the good old drop menu
548  }
549 
550 
551  KBookmark afterBookmark;
552 
553  if (row==-1) {
554  // The dropped item is moved or added to the last position
555 
556  KFilePlacesItem *lastItem = d->items.last();
557  afterBookmark = lastItem->bookmark();
558 
559  } else {
560  // The dropped item is moved or added before position 'row', ie after position 'row-1'
561 
562  if (row>0) {
563  KFilePlacesItem *afterItem = d->items[row-1];
564  afterBookmark = afterItem->bookmark();
565  }
566  }
567 
568  if (data->hasFormat(_k_internalMimetype(this))) {
569  // The operation is an internal move
570  QByteArray itemData = data->data(_k_internalMimetype(this));
571  QDataStream stream(&itemData, QIODevice::ReadOnly);
572  int itemRow;
573 
574  stream >> itemRow;
575 
576  KFilePlacesItem *item = d->items[itemRow];
577  KBookmark bookmark = item->bookmark();
578 
579  int destRow = row == -1 ? d->items.count() : row;
580  // The item is not moved when the drop indicator is on either item edge
581  if (itemRow == destRow || itemRow + 1 == destRow) {
582  return false;
583  }
584 
585  beginMoveRows(QModelIndex(), itemRow, itemRow, QModelIndex(), destRow);
586  d->bookmarkManager->root().moveBookmark(bookmark, afterBookmark);
587  // Move item ourselves so that _k_reloadBookmarks() does not consider
588  // the move as a remove + insert.
589  //
590  // 2nd argument of QList::move() expects the final destination index,
591  // but 'row' is the value of the destination index before the moved
592  // item has been removed from its original position. That is why we
593  // adjust if necessary.
594  d->items.move(itemRow, itemRow < destRow ? (destRow - 1) : destRow);
595  endMoveRows();
596  } else if (data->hasFormat("text/uri-list")) {
597  // The operation is an add
598  KUrl::List urls = KUrl::List::fromMimeData(data);
599 
600  KBookmarkGroup group = d->bookmarkManager->root();
601 
602  foreach (const KUrl &url, urls) {
603  // TODO: use KIO::stat in order to get the UDS_DISPLAY_NAME too
604  KMimeType::Ptr mimetype = KMimeType::mimeType(KIO::NetAccess::mimetype(url, 0));
605 
606  if (!mimetype) {
607  kWarning() << "URL not added to Places as mimetype could not be determined!";
608  continue;
609  }
610 
611  if (!mimetype->is("inode/directory")) {
612  // Only directories are allowed
613  continue;
614  }
615 
616  KBookmark bookmark = KFilePlacesItem::createBookmark(d->bookmarkManager,
617  url.fileName(), url,
618  mimetype->iconName(url));
619  group.moveBookmark(bookmark, afterBookmark);
620  afterBookmark = bookmark;
621  }
622 
623  } else {
624  // Oops, shouldn't happen thanks to mimeTypes()
625  kWarning() << ": received wrong mimedata, " << data->formats();
626  return false;
627  }
628 
629  d->reloadAndSignal();
630 
631  return true;
632 }
633 
634 void KFilePlacesModel::addPlace(const QString &text, const KUrl &url,
635  const QString &iconName, const QString &appName)
636 {
637  addPlace(text, url, iconName, appName, QModelIndex());
638 }
639 
640 void KFilePlacesModel::addPlace(const QString &text, const KUrl &url,
641  const QString &iconName, const QString &appName,
642  const QModelIndex &after)
643 {
644  KBookmark bookmark = KFilePlacesItem::createBookmark(d->bookmarkManager,
645  text, url, iconName);
646 
647  if (!appName.isEmpty()) {
648  bookmark.setMetaDataItem("OnlyInApp", appName);
649  }
650 
651  if (after.isValid()) {
652  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(after.internalPointer());
653  d->bookmarkManager->root().moveBookmark(bookmark, item->bookmark());
654  }
655 
656  d->reloadAndSignal();
657 }
658 
659 void KFilePlacesModel::editPlace(const QModelIndex &index, const QString &text, const KUrl &url,
660  const QString &iconName, const QString &appName)
661 {
662  if (!index.isValid()) return;
663 
664  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
665 
666  if (item->isDevice()) return;
667 
668  KBookmark bookmark = item->bookmark();
669 
670  if (bookmark.isNull()) return;
671 
672  bookmark.setFullText(text);
673  bookmark.setUrl(url);
674  bookmark.setIcon(iconName);
675  bookmark.setMetaDataItem("OnlyInApp", appName);
676 
677  d->reloadAndSignal();
678  emit dataChanged(index, index);
679 }
680 
681 void KFilePlacesModel::removePlace(const QModelIndex &index) const
682 {
683  if (!index.isValid()) return;
684 
685  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
686 
687  if (item->isDevice()) return;
688 
689  KBookmark bookmark = item->bookmark();
690 
691  if (bookmark.isNull()) return;
692 
693  d->bookmarkManager->root().deleteBookmark(bookmark);
694  d->reloadAndSignal();
695 }
696 
697 void KFilePlacesModel::setPlaceHidden(const QModelIndex &index, bool hidden)
698 {
699  if (!index.isValid()) return;
700 
701  KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
702 
703  KBookmark bookmark = item->bookmark();
704 
705  if (bookmark.isNull()) return;
706 
707  bookmark.setMetaDataItem("IsHidden", (hidden ? "true" : "false"));
708 
709  d->reloadAndSignal();
710  emit dataChanged(index, index);
711 }
712 
713 int KFilePlacesModel::hiddenCount() const
714 {
715  int rows = rowCount();
716  int hidden = 0;
717 
718  for (int i=0; i<rows; ++i) {
719  if (isHidden(index(i, 0))) {
720  hidden++;
721  }
722  }
723 
724  return hidden;
725 }
726 
727 QAction *KFilePlacesModel::teardownActionForIndex(const QModelIndex &index) const
728 {
729  Solid::Device device = deviceForIndex(index);
730 
731  if (device.is<Solid::StorageAccess>() && device.as<Solid::StorageAccess>()->isAccessible()) {
732 
733  Solid::StorageDrive *drive = device.as<Solid::StorageDrive>();
734 
735  if (drive==0) {
736  drive = device.parent().as<Solid::StorageDrive>();
737  }
738 
739  bool hotpluggable = false;
740  bool removable = false;
741 
742  if (drive!=0) {
743  hotpluggable = drive->isHotpluggable();
744  removable = drive->isRemovable();
745  }
746 
747  QString iconName;
748  QString text;
749  QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
750 
751  if (device.is<Solid::OpticalDisc>()) {
752  text = i18n("&Release '%1'", label);
753  } else if (removable || hotpluggable) {
754  text = i18n("&Safely Remove '%1'", label);
755  iconName = "media-eject";
756  } else {
757  text = i18n("&Unmount '%1'", label);
758  iconName = "media-eject";
759  }
760 
761  if (!iconName.isEmpty()) {
762  return new QAction(KIcon(iconName), text, 0);
763  } else {
764  return new QAction(text, 0);
765  }
766  }
767 
768  return 0;
769 }
770 
771 QAction *KFilePlacesModel::ejectActionForIndex(const QModelIndex &index) const
772 {
773  Solid::Device device = deviceForIndex(index);
774 
775  if (device.is<Solid::OpticalDisc>()) {
776 
777  QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
778  QString text = i18n("&Eject '%1'", label);
779 
780  return new QAction(KIcon("media-eject"), text, 0);
781  }
782 
783  return 0;
784 }
785 
786 void KFilePlacesModel::requestTeardown(const QModelIndex &index)
787 {
788  Solid::Device device = deviceForIndex(index);
789  Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
790 
791  if (access!=0) {
792  connect(access, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString)),
793  this, SLOT(_k_storageTeardownDone(Solid::ErrorType,QVariant)));
794 
795  access->teardown();
796  }
797 }
798 
799 void KFilePlacesModel::requestEject(const QModelIndex &index)
800 {
801  Solid::Device device = deviceForIndex(index);
802 
803  Solid::OpticalDrive *drive = device.parent().as<Solid::OpticalDrive>();
804 
805  if (drive!=0) {
806  connect(drive, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString)),
807  this, SLOT(_k_storageTeardownDone(Solid::ErrorType,QVariant)));
808 
809  drive->eject();
810  } else {
811  QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
812  QString message = i18n("The device '%1' is not a disk and cannot be ejected.", label);
813  emit errorMessage(message);
814  }
815 }
816 
817 void KFilePlacesModel::requestSetup(const QModelIndex &index)
818 {
819  Solid::Device device = deviceForIndex(index);
820 
821  if (device.is<Solid::StorageAccess>()
822  && !d->setupInProgress.contains(device.as<Solid::StorageAccess>())
823  && !device.as<Solid::StorageAccess>()->isAccessible()) {
824 
825  Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
826 
827  d->setupInProgress[access] = index;
828 
829  connect(access, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString)),
830  this, SLOT(_k_storageSetupDone(Solid::ErrorType,QVariant)));
831 
832  access->setup();
833  }
834 }
835 
836 void KFilePlacesModel::Private::_k_storageSetupDone(Solid::ErrorType error, QVariant errorData)
837 {
838  QPersistentModelIndex index = setupInProgress.take(q->sender());
839 
840  if (!index.isValid()) {
841  return;
842  }
843 
844  if (!error) {
845  emit q->setupDone(index, true);
846  } else {
847  if (errorData.isValid()) {
848  emit q->errorMessage(i18n("An error occurred while accessing '%1', the system responded: %2",
849  q->text(index),
850  errorData.toString()));
851  } else {
852  emit q->errorMessage(i18n("An error occurred while accessing '%1'",
853  q->text(index)));
854  }
855  emit q->setupDone(index, false);
856  }
857 
858 }
859 
860 void KFilePlacesModel::Private::_k_storageTeardownDone(Solid::ErrorType error, QVariant errorData)
861 {
862  if (error && errorData.isValid()) {
863  emit q->errorMessage(errorData.toString());
864  }
865 }
866 
867 #include "kfileplacesmodel.moc"
KFilePlacesModel::url
KUrl url(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:177
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
i18n
QString i18n(const char *text)
QVariant::toUrl
QUrl toUrl() const
QList::clear
void clear()
QModelIndex
storagevolume.h
KBookmarkGroup::moveBookmark
bool moveBookmark(const KBookmark &bookmark, const KBookmark &after)
kuser.h
QString::append
QString & append(QChar ch)
QMimeData::data
QByteArray data(const QString &mimeType) const
netaccess.h
kfileplacesitem_p.h
kbookmarkmanager.h
I18N_NOOP2
I18N_NOOP2("KCharSelect section name","European Alphabets")
Solid::Device::as
DevIface * as()
KFilePlacesItem::createBookmark
static KBookmark createBookmark(KBookmarkManager *manager, const QString &label, const KUrl &url, const QString &iconName, KFilePlacesItem *after=0)
Definition: kfileplacesitem.cpp:234
KFilePlacesModel::setPlaceHidden
void setPlaceHidden(const QModelIndex &index, bool hidden)
Definition: kfileplacesmodel.cpp:697
kdebug.h
KFilePlacesModel::requestSetup
void requestSetup(const QModelIndex &index)
Definition: kfileplacesmodel.cpp:817
kmimetype.h
storagedrive.h
QAbstractItemModel::beginMoveRows
bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
QByteArray
KUrl::List::populateMimeData
void populateMimeData(QMimeData *mimeData, const KUrl::MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
notifier
SOLID_EXPORT Notifier * notifier()
group
KFilePlacesModel::isDevice
bool isDevice(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:202
KProtocolInfo::isKnownProtocol
static bool isKnownProtocol(const KUrl &url)
QMimeData::hasFormat
virtual bool hasFormat(const QString &mimeType) const
QDataStream
QAbstractItemModel::itemData
virtual QMap< int, QVariant > itemData(const QModelIndex &index) const
QString::prepend
QString & prepend(QChar ch)
mimetype
MimetypeJob * mimetype(const KUrl &url, JobFlags flags=DefaultFlags)
label
QString label(StandardShortcut id)
QMap< QObject *, QPersistentModelIndex >
KFilePlacesItem::createSystemBookmark
static KBookmark createSystemBookmark(KBookmarkManager *manager, const QString &untranslatedLabel, const QString &translatedLabel, const KUrl &url, const QString &iconName)
Definition: kfileplacesitem.cpp:261
KIO::NetAccess::mimetype
static QString mimetype(const KUrl &url, QWidget *window)
Solid::Device
KFilePlacesModel::setupDone
void setupDone(const QModelIndex &index, bool success)
KFilePlacesModel::requestTeardown
void requestTeardown(const QModelIndex &index)
Definition: kfileplacesmodel.cpp:786
KFilePlacesModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the children model index for the given row and column.
Definition: kfileplacesmodel.cpp:249
KBookmark::setIcon
void setIcon(const QString &icon)
KFilePlacesModel::UrlRole
Definition: kfileplacesmodel.h:45
KFilePlacesModel::text
QString text(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:192
KFilePlacesModel::addPlace
void addPlace(const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
Definition: kfileplacesmodel.cpp:634
QList::erase
iterator erase(iterator pos)
KBookmarkManager
QFile::exists
bool exists() const
KFilePlacesModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:483
KFilePlacesModel::teardownActionForIndex
QAction * teardownActionForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:727
KFilePlacesModel::requestEject
void requestEject(const QModelIndex &index)
Definition: kfileplacesmodel.cpp:799
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
klocale.h
KFilePlacesModel::setupNeeded
bool setupNeeded(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:182
KBookmark
QMimeData
KUrl
KFilePlacesModel::data
QVariant data(const QModelIndex &index, int role) const
Get a visible data based on Qt role for the given index.
Definition: kfileplacesmodel.cpp:240
KFilePlacesModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
Get the number of rows for a model index.
Definition: kfileplacesmodel.cpp:266
KUser
Solid::OpticalDrive::eject
bool eject()
QList::indexOf
int indexOf(const T &value, int from) const
Solid::StorageAccess::isAccessible
bool isAccessible() const
KFilePlacesModel::supportedDropActions
Qt::DropActions supportedDropActions() const
Definition: kfileplacesmodel.cpp:478
KFilePlacesModel::Private
friend class Private
Definition: kfileplacesmodel.h:148
KFilePlacesItem::device
Solid::Device device() const
Definition: kfileplacesitem.cpp:112
KFilePlacesItem::isDevice
bool isDevice() const
Definition: kfileplacesitem.cpp:86
Solid::ErrorType
ErrorType
QModelIndex::isValid
bool isValid() const
kglobal.h
QString::number
QString number(int n, int base)
QPersistentModelIndex::isValid
bool isValid() const
KFilePlacesModel::isHidden
bool isHidden(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:197
KFilePlacesModel::removePlace
void removePlace(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:681
Solid::OpticalDisc
KFilePlacesModel::icon
KIcon icon(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:187
QAbstractItemModel::dataChanged
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
KUrl::List::fromMimeData
static KUrl::List fromMimeData(const QMimeData *mimeData, KUrl::MetaDataMap *metaData=0)
KFilePlacesItem::bookmark
KBookmark bookmark() const
Definition: kfileplacesitem.cpp:91
Solid::Device::listFromQuery
static QList< Device > listFromQuery(const Predicate &predicate, const QString &parentUdi=QString())
QObject
KBookmark::setFullText
void setFullText(const QString &fullText)
KFilePlacesModel::SetupNeededRole
Definition: kfileplacesmodel.h:47
KFilePlacesModel::closestItem
QModelIndex closestItem(const KUrl &url) const
Returns the closest item for the URL url.
Definition: kfileplacesmodel.cpp:281
KStandardDirs
QList::isEmpty
bool isEmpty() const
QFileInfo::absoluteFilePath
QString absoluteFilePath() const
QString::isEmpty
bool isEmpty() const
KFilePlacesItem
Definition: kfileplacesitem_p.h:40
QModelIndex::row
int row() const
KFilePlacesModel::bookmarkForIndex
KBookmark bookmarkForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:226
KFilePlacesModel::deviceForIndex
Solid::Device deviceForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:212
QAbstractItemModel::endMoveRows
void endMoveRows()
Solid::Predicate::fromString
static Predicate fromString(const QString &predicate)
Solid::StorageAccess
KIcon
KFilePlacesModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const
Get the number of columns for a model index.
Definition: kfileplacesmodel.cpp:274
KFilePlacesModel::KFilePlacesModel
KFilePlacesModel(QObject *parent=0)
Definition: kfileplacesmodel.cpp:90
Solid::Device::is
bool is() const
KStandardDirs::localxdgdatadir
QString localxdgdatadir() const
QModelIndex::internalPointer
void * internalPointer() const
KFilePlacesModel::ejectActionForIndex
QAction * ejectActionForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:771
KBookmarkManager::managerForExternalFile
static KBookmarkManager * managerForExternalFile(const QString &bookmarksFile)
kfileplacesmodel.h
QSet< QString >
QDir::drives
QFileInfoList drives()
KBookmarkGroup
Solid::Device::udi
QString udi() const
KComponentData::componentName
QString componentName() const
QString
QList< KFilePlacesItem * >
KFilePlacesModel::~KFilePlacesModel
~KFilePlacesModel()
Definition: kfileplacesmodel.cpp:172
portablemediaplayer.h
QStringList
QAbstractItemModel::createIndex
QModelIndex createIndex(int row, int column, void *ptr) const
QFileInfo
types
QStringList types(Mode mode=Writing)
QList::end
iterator end()
kprotocolinfo.h
KBookmark::metaDataItem
QString metaDataItem(const QString &key) const
storageaccess.h
Solid::Device::parent
Device parent() const
homeDir
QString homeDir(const QString &user)
KBookmark::setMetaDataItem
void setMetaDataItem(const QString &key, const QString &value, MetaDataOverwriteMode mode=OverwriteMetaData)
opticaldrive.h
KFilePlacesModel::editPlace
void editPlace(const QModelIndex &index, const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
Definition: kfileplacesmodel.cpp:659
QString::replace
QString & replace(int position, int n, QChar after)
KUrl::List
QPersistentModelIndex
kbookmark.h
QUrl::isValid
bool isValid() const
KFilePlacesItem::data
QVariant data(int role) const
Definition: kfileplacesitem.cpp:131
QSet::remove
bool remove(const T &value)
KFilePlacesModel::errorMessage
void errorMessage(const QString &message)
Qt::DropActions
typedef DropActions
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
QList::insert
void insert(int i, const T &value)
predicate.h
access
int access(const QString &path, int mode)
Solid::DeviceNotifier
Solid::Predicate
kstandarddirs.h
KFilePlacesModel::HiddenRole
Definition: kfileplacesmodel.h:46
QAction
opticaldisc.h
KGlobal::mainComponent
const KComponentData & mainComponent()
QString::length
int length() const
QVariant::toBool
bool toBool() const
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QAbstractItemModel
KFilePlacesItem::createDeviceBookmark
static KBookmark createDeviceBookmark(KBookmarkManager *manager, const QString &udi)
Definition: kfileplacesitem.cpp:277
QMimeData::formats
virtual QStringList formats() const
QVariant::isValid
bool isValid() const
Solid::StorageAccess::teardown
bool teardown()
QMimeData::setData
void setData(const QString &mimeType, const QByteArray &data)
KFilePlacesModel::mimeTypes
QStringList mimeTypes() const
Definition: kfileplacesmodel.cpp:501
KFilePlacesModel::mimeData
QMimeData * mimeData(const QModelIndexList &indexes) const
Definition: kfileplacesmodel.cpp:510
KFilePlacesModel::hiddenCount
int hiddenCount() const
Definition: kfileplacesmodel.cpp:713
KBookmark::setUrl
void setUrl(const KUrl &url)
kcomponentdata.h
kicon.h
Solid::StorageDrive
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
KBookmark::isNull
bool isNull() const
KBookmarkGroup::next
KBookmark next(const KBookmark &current) const
KFilePlacesModel::dropMimeData
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Definition: kfileplacesmodel.cpp:534
QVariant::toString
QString toString() const
KBookmarkGroup::first
KBookmark first() const
QList::begin
iterator begin()
_k_internalMimetype
static QString _k_internalMimetype(const KFilePlacesModel *const self)
Definition: kfileplacesmodel.cpp:496
kfileitem.h
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Solid::StorageAccess::setup
bool setup()
KBookmark::address
QString address() const
devicenotifier.h
Solid::OpticalDrive
QTimer::singleShot
singleShot
QVariant
Qt::ItemFlags
typedef ItemFlags
KFilePlacesModel
This class is a list view model.
Definition: kfileplacesmodel.h:40
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:27:26 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs API Reference

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

Search



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

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