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

KFile

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

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs-4.8.5 API Reference

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

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