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

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • 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