26 #include <QtCore/QDir> 29 #include <QtCore/QMimeData> 30 #include <QtCore/QTimer> 31 #include <QtCore/QFile> 32 #include <QtGui/QColor> 33 #include <QtGui/QAction> 78 void reloadAndSignal();
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();
105 if (root.
first().
isNull() || !QFile::exists(file)) {
116 "Home",
I18N_NOOP2(
"KFile System Bookmarks",
"Home"),
119 "Network",
I18N_NOOP2(
"KFile System Bookmarks",
"Network"),
120 KUrl(
"remote:/"),
"network-workgroup");
121 #if defined(_WIN32_WCE) 123 foreach (
const QFileInfo& info, QDir::drives() ) {
124 QString driveIcon =
"drive-harddisk";
126 info.absoluteFilePath(), info.absoluteFilePath(),
127 KUrl(info.absoluteFilePath()), driveIcon);
129 #elif !defined(Q_OS_WIN) 131 "Root",
I18N_NOOP2(
"KFile System Bookmarks",
"Root"),
132 KUrl(
"/"),
"folder-red");
135 "Trash",
I18N_NOOP2(
"KFile System Bookmarks",
"Trash"),
136 KUrl(
"trash:/"),
"user-trash");
143 d->bookmarkManager->saveAs(file);
146 QString predicate(
"[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]" 148 "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]" 150 "OpticalDisc.availableContent & 'Audio' ]" 152 "StorageAccess.ignored == false ]");
155 predicate.prepend(
"[");
156 predicate.append(
" OR PortableMediaPlayer.supportedProtocols == 'mtp']");
161 Q_ASSERT(d->predicate.isValid());
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()));
168 d->_k_reloadBookmarks();
169 QTimer::singleShot(0,
this, SLOT(_k_initDeviceList()));
194 return data(
index, Qt::DisplayRole).toString();
204 if (!
index.isValid())
214 if (!
index.isValid())
228 if (!
index.isValid())
242 if (!
index.isValid())
246 return item->
data(role);
251 if (row<0 || column!=0 || row>=d->items.size())
252 return QModelIndex();
255 return QModelIndex();
257 return createIndex(row, column, d->items.at(row));
263 return QModelIndex();
271 return d->items.size();
289 for (
int row = 0; row<d->items.size(); ++row) {
294 const int length = itemUrl.
prettyUrl().length();
295 if (length > maxLength) {
303 return QModelIndex();
305 return createIndex(foundRow, 0, d->items[foundRow]);
308 void KFilePlacesModel::Private::_k_initDeviceList()
312 connect(notifier, SIGNAL(deviceAdded(QString)),
313 q, SLOT(_k_deviceAdded(QString)));
314 connect(notifier, SIGNAL(deviceRemoved(QString)),
315 q, SLOT(_k_deviceRemoved(QString)));
320 availableDevices << device.
udi();
323 _k_reloadBookmarks();
326 void KFilePlacesModel::Private::_k_deviceAdded(
const QString &udi)
330 if (predicate.matches(d)) {
331 availableDevices << udi;
332 _k_reloadBookmarks();
336 void KFilePlacesModel::Private::_k_deviceRemoved(
const QString &udi)
338 if (availableDevices.contains(udi)) {
339 availableDevices.remove(udi);
340 _k_reloadBookmarks();
344 void KFilePlacesModel::Private::_k_itemChanged(
const QString &
id)
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);
354 void KFilePlacesModel::Private::_k_reloadBookmarks()
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();
368 q->beginInsertRows(QModelIndex(), row, row);
369 it_i = items.insert(it_i, *it_c);
371 it_c = currentItems.erase(it_c);
374 end_c = currentItems.end();
377 }
else if (it_i!=end_i && it_c==end_c) {
378 int row = items.indexOf(*it_i);
380 q->beginRemoveRows(QModelIndex(), row, row);
382 it_i = items.erase(it_i);
385 end_c = currentItems.end();
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());
392 int row = items.indexOf(*it_i);
393 QModelIndex idx = q->index(row, 0);
394 emit q->dataChanged(idx, idx);
398 }
else if ((*it_i)->id()!=(*it_c)->id()) {
399 int row = items.indexOf(*it_i);
401 if (it_i+1!=end_i && (*(it_i+1))->
id()==(*it_c)->id()) {
402 q->beginRemoveRows(QModelIndex(), row, row);
404 it_i = items.erase(it_i);
407 end_c = currentItems.end();
410 q->beginInsertRows(QModelIndex(), row, row);
411 it_i = items.insert(it_i, *it_c);
413 it_c = currentItems.erase(it_c);
416 end_c = currentItems.end();
422 qDeleteAll(currentItems);
423 currentItems.clear();
434 while (!bookmark.
isNull()) {
437 bool deviceAvailable = devices.remove(udi);
441 if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
443 if (deviceAvailable) {
449 connect(item, SIGNAL(itemChanged(QString)),
450 q, SLOT(_k_itemChanged(QString)));
454 bookmark = root.
next(bookmark);
458 foreach (
const QString &udi, devices) {
463 connect(item, SIGNAL(itemChanged(QString)),
464 q, SLOT(_k_itemChanged(QString)));
473 void KFilePlacesModel::Private::reloadAndSignal()
475 bookmarkManager->emitChanged(bookmarkManager->root());
480 return Qt::ActionMask;
485 Qt::ItemFlags res = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
488 res|= Qt::ItemIsDragEnabled;
490 if (!
index.isValid())
491 res|= Qt::ItemIsDropEnabled;
498 return QString(
"application/x-kfileplacesmodel-")+QString::number((qptrdiff)
self);
505 types << _k_internalMimetype(
this) <<
"text/uri-list";
515 QDataStream stream(&itemData, QIODevice::WriteOnly);
517 foreach (
const QModelIndex &
index, indexes) {
519 if (itemUrl.isValid())
521 stream <<
index.row();
524 QMimeData *
mimeData =
new QMimeData();
529 mimeData->setData(_k_internalMimetype(
this), itemData);
535 int row,
int column,
const QModelIndex &parent)
537 if (action == Qt::IgnoreAction)
543 if (row==-1 &&
parent.isValid()) {
557 afterBookmark = lastItem->
bookmark();
564 afterBookmark = afterItem->
bookmark();
568 if (
data->hasFormat(_k_internalMimetype(
this))) {
570 QByteArray itemData =
data->data(_k_internalMimetype(
this));
571 QDataStream stream(&itemData, QIODevice::ReadOnly);
579 int destRow = row == -1 ? d->items.count() : row;
581 if (itemRow == destRow || itemRow + 1 == destRow) {
585 beginMoveRows(QModelIndex(), itemRow, itemRow, QModelIndex(), destRow);
586 d->bookmarkManager->root().moveBookmark(bookmark, afterBookmark);
594 d->items.move(itemRow, itemRow < destRow ? (destRow - 1) : destRow);
596 }
else if (
data->hasFormat(
"text/uri-list")) {
602 foreach (
const KUrl &
url, urls) {
607 kWarning() <<
"URL not added to Places as mimetype could not be determined!";
611 if (!
mimetype->is(
"inode/directory")) {
619 group.moveBookmark(bookmark, afterBookmark);
620 afterBookmark = bookmark;
625 kWarning() <<
": received wrong mimedata, " <<
data->formats();
629 d->reloadAndSignal();
635 const QString &iconName,
const QString &appName)
641 const QString &iconName,
const QString &appName,
642 const QModelIndex &after)
647 if (!appName.isEmpty()) {
651 if (after.isValid()) {
652 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(after.internalPointer());
653 d->bookmarkManager->root().moveBookmark(bookmark, item->
bookmark());
656 d->reloadAndSignal();
660 const QString &iconName,
const QString &appName)
662 if (!
index.isValid())
return;
670 if (bookmark.
isNull())
return;
677 d->reloadAndSignal();
683 if (!
index.isValid())
return;
691 if (bookmark.
isNull())
return;
693 d->bookmarkManager->root().deleteBookmark(bookmark);
694 d->reloadAndSignal();
699 if (!
index.isValid())
return;
705 if (bookmark.isNull())
return;
709 d->reloadAndSignal();
718 for (
int i=0; i<rows; ++i) {
739 bool hotpluggable =
false;
740 bool removable =
false;
749 QString
label =
data(
index, Qt::DisplayRole).toString().replace(
'&',
"&&");
752 text =
i18n(
"&Release '%1'", label);
753 }
else if (removable || hotpluggable) {
754 text =
i18n(
"&Safely Remove '%1'", label);
755 iconName =
"media-eject";
757 text =
i18n(
"&Unmount '%1'", label);
758 iconName =
"media-eject";
761 if (!iconName.isEmpty()) {
777 QString
label =
data(
index, Qt::DisplayRole).toString().replace(
'&',
"&&");
778 QString
text =
i18n(
"&Eject '%1'", label);
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);
836 void KFilePlacesModel::Private::_k_storageSetupDone(
Solid::ErrorType error, QVariant errorData)
838 QPersistentModelIndex index = setupInProgress.take(q->sender());
840 if (!index.isValid()) {
845 emit q->setupDone(index,
true);
847 if (errorData.isValid()) {
848 emit q->errorMessage(
i18n(
"An error occurred while accessing '%1', the system responded: %2",
850 errorData.toString()));
852 emit q->errorMessage(
i18n(
"An error occurred while accessing '%1'",
855 emit q->setupDone(index,
false);
860 void KFilePlacesModel::Private::_k_storageTeardownDone(
Solid::ErrorType error, QVariant errorData)
862 if (error && errorData.isValid()) {
863 emit q->errorMessage(errorData.toString());
867 #include "kfileplacesmodel.moc" KBookmark bookmark() const
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
QString i18n(const char *text)
bool setupNeeded(const QModelIndex &index) const
static KBookmark createBookmark(KBookmarkManager *manager, const QString &label, const KUrl &url, const QString &iconName, KFilePlacesItem *after=0)
void setPlaceHidden(const QModelIndex &index, bool hidden)
Solid::Device device() const
void requestSetup(const QModelIndex &index)
void removePlace(const QModelIndex &index) const
SOLID_EXPORT Notifier * notifier()
static bool isKnownProtocol(const KUrl &url)
QString localxdgdatadir() const
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the children model index for the given row and column.
MimetypeJob * mimetype(const KUrl &url, JobFlags flags=DefaultFlags)
void populateMimeData(QMimeData *mimeData, const KUrl::MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
QModelIndex parent(const QModelIndex &child) const
Get the parent QModelIndex for the given model child.
QString label(StandardShortcut id)
bool isHotpluggable() const
QString text(const QModelIndex &index) const
static KBookmark createSystemBookmark(KBookmarkManager *manager, const QString &untranslatedLabel, const QString &translatedLabel, const KUrl &url, const QString &iconName)
static QString mimetype(const KUrl &url, QWidget *window)
void setupDone(const QModelIndex &index, bool success)
void requestTeardown(const QModelIndex &index)
void setIcon(const QString &icon)
QAction * ejectActionForIndex(const QModelIndex &index) const
void addPlace(const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
int rowCount(const QModelIndex &parent=QModelIndex()) const
Get the number of rows for a model index.
QString metaDataItem(const QString &key) const
void requestEject(const QModelIndex &index)
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
QMimeData * mimeData(const QModelIndexList &indexes) const
QAction * teardownActionForIndex(const QModelIndex &index) const
QString componentName() const
static DeviceNotifier * instance()
static KUrl::List fromMimeData(const QMimeData *mimeData, KUrl::MetaDataMap *metaData=0)
static QList< Device > listFromQuery(const Predicate &predicate, const QString &parentUdi=QString())
void setFullText(const QString &fullText)
bool isDevice(const QModelIndex &index) const
bool isParentOf(const KUrl &u) const
KIcon icon(const QModelIndex &index) const
static Predicate fromString(const QString &predicate)
KFilePlacesModel(QObject *parent=0)
static KBookmarkManager * managerForExternalFile(const QString &bookmarksFile)
bool isHidden(const QModelIndex &index) const
KUrl url(const QModelIndex &index) const
QVariant data(int role) const
QStringList types(Mode mode=Writing)
QString homeDir(const QString &user)
QModelIndex closestItem(const KUrl &url) const
Returns the closest item for the URL url.
void setMetaDataItem(const QString &key, const QString &value, MetaDataOverwriteMode mode=OverwriteMetaData)
I18N_NOOP2("KCharSelect section name", "European Alphabets")
bool isAccessible() const
void editPlace(const QModelIndex &index, const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
QStringList mimeTypes() const
void errorMessage(const QString &message)
int access(const QString &path, int mode)
KBookmark next(const KBookmark ¤t) const
const KComponentData & mainComponent()
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
static KBookmark createDeviceBookmark(KBookmarkManager *manager, const QString &udi)
static Ptr mimeType(const QString &name, FindByNameOption options=ResolveAliases)
QVariant data(const QModelIndex &index, int role) const
Get a visible data based on Qt role for the given index.
void setUrl(const KUrl &url)
Solid::Device deviceForIndex(const QModelIndex &index) const
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
KBookmark bookmarkForIndex(const QModelIndex &index) const
Qt::ItemFlags flags(const QModelIndex &index) const
Qt::DropActions supportedDropActions() const
int columnCount(const QModelIndex &parent=QModelIndex()) const
Get the number of columns for a model index.
This class is a list view model.