void PlacesModel::onMountAdded(GVolumeMonitor* monitor, GMount* mount, PlacesModel* pThis) { GVolume* vol = g_mount_get_volume(mount); if(vol) { // mount-added is also emitted when a volume is newly mounted. PlacesModelVolumeItem* item = pThis->itemFromVolume(vol); if(item && !item->path()) { // update the mounted volume and show a button for eject. GFile* gf = g_mount_get_root(mount); FmPath* path = fm_path_new_for_gfile(gf); g_object_unref(gf); item->setPath(path); if(path) fm_path_unref(path); // update the mount indicator (eject button) QStandardItem* ejectBtn = item->parent()->child(item->row(), 1); Q_ASSERT(ejectBtn); ejectBtn->setIcon(pThis->ejectIcon_); } g_object_unref(vol); } else { // network mounts and others PlacesModelMountItem* item = pThis->itemFromMount(mount); /* for some unknown reasons, sometimes we get repeated mount-added * signals and added a device more than one. So, make a sanity check here. */ if(!item) { item = new PlacesModelMountItem(mount); QStandardItem* eject_btn = new QStandardItem(pThis->ejectIcon_, ""); pThis->devicesRoot->appendRow(QList<QStandardItem*>() << item << eject_btn); } } }
void PlacesView::activateRow(int type, const QModelIndex& index) { if(!index.parent().isValid()) // ignore root items return; PlacesModelItem* item = static_cast<PlacesModelItem*>(model_->itemFromIndex(index)); if(item) { FmPath* path = item->path(); if(!path) { // check if mounting volumes is needed if(item->type() == PlacesModelItem::Volume) { PlacesModelVolumeItem* volumeItem = static_cast<PlacesModelVolumeItem*>(item); if(!volumeItem->isMounted()) { // Mount the volume GVolume* volume = volumeItem->volume(); MountOperation* op = new MountOperation(true, this); op->mount(volume); // connect(op, SIGNAL(finished(GError*)), SLOT(onMountOperationFinished(GError*))); // blocking here until the mount operation is finished? // FIXME: update status of the volume after mount is finished!! if(!op->wait()) return; path = item->path(); } } } if(path) { Q_EMIT chdirRequested(type, path); } } }
void PlacesView::onEjectVolume() { PlacesModel::ItemAction* action = static_cast<PlacesModel::ItemAction*>(sender()); if(!action->index().isValid()) return; PlacesModelVolumeItem* item = static_cast<PlacesModelVolumeItem*>(model_->itemFromIndex(action->index())); MountOperation* op = new MountOperation(true, this); op->eject(item->volume()); op->wait(); }
void PlacesModel::onVolumeChanged(GVolumeMonitor* monitor, GVolume* volume, PlacesModel* pThis) { PlacesModelVolumeItem* item = pThis->itemFromVolume(volume); if(item) { item->update(); if(!item->isMounted()) { // the volume is unmounted, remove the eject button if needed // remove the eject button for the volume (at column 1 of the same row) QStandardItem* ejectBtn = item->parent()->child(item->row(), 1); Q_ASSERT(ejectBtn); ejectBtn->setIcon(QIcon()); } } }
void PlacesModel::onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, PlacesModel* pThis) { // for some unknown reasons, sometimes we get repeated volume-added // signals and added a device more than one. So, make a sanity check here. PlacesModelVolumeItem* volumeItem = pThis->itemFromVolume(volume); if(!volumeItem) { volumeItem = new PlacesModelVolumeItem(volume); QStandardItem* ejectBtn = new QStandardItem(); if(volumeItem->isMounted()) ejectBtn->setIcon(pThis->ejectIcon_); pThis->devicesRoot->appendRow(QList<QStandardItem*>() << volumeItem << ejectBtn); } }
PlacesModelVolumeItem* PlacesModel::itemFromVolume(GVolume* volume) { int rowCount = devicesRoot->rowCount(); for(int i = 0; i < rowCount; ++i) { PlacesModelItem* item = static_cast<PlacesModelItem*>(devicesRoot->child(i, 0)); if(item->type() == PlacesModelItem::Volume) { PlacesModelVolumeItem* volumeItem = static_cast<PlacesModelVolumeItem*>(item); if(volumeItem->volume() == volume) return volumeItem; } } return NULL; }
void PlacesView::onEjectButtonClicked(PlacesModelItem* item) { // The eject button is clicked for a device item (volume or mount) if(item->type() == PlacesModelItem::Volume) { PlacesModelVolumeItem* volumeItem = static_cast<PlacesModelVolumeItem*>(item); MountOperation* op = new MountOperation(true, this); if(volumeItem->canEject()) // do eject if applicable op->eject(volumeItem->volume()); else // otherwise, do unmount instead op->unmount(volumeItem->volume()); } else if(item->type() == PlacesModelItem::Mount) { PlacesModelMountItem* mountItem = static_cast<PlacesModelMountItem*>(item); MountOperation* op = new MountOperation(true, this); op->unmount(mountItem->mount()); } qDebug("PlacesView::onEjectButtonClicked"); }
void PlacesView::contextMenuEvent(QContextMenuEvent* event) { QModelIndex index = indexAt(event->pos()); if(index.isValid() && index.parent().isValid()) { if(index.column() != 0) // the real item is at column 0 index = index.sibling(index.row(), 0); // Do not take the ownership of the menu since // it will be deleted with deleteLater() upon hidden. // This is possibly related to #145 - https://github.com/lxde/pcmanfm-qt/issues/145 QMenu* menu = new QMenu(); QAction* action; PlacesModelItem* item = static_cast<PlacesModelItem*>(model_->itemFromIndex(index)); if(item->type() != PlacesModelItem::Mount && (item->type() != PlacesModelItem::Volume || static_cast<PlacesModelVolumeItem*>(item)->isMounted())) { action = new PlacesModel::ItemAction(item->index(), tr("Open in New Tab"), menu); connect(action, &QAction::triggered, this, &PlacesView::onOpenNewTab); menu->addAction(action); action = new PlacesModel::ItemAction(item->index(), tr("Open in New Window"), menu); connect(action, &QAction::triggered, this, &PlacesView::onOpenNewWindow); menu->addAction(action); } switch(item->type()) { case PlacesModelItem::Places: { FmPath* path = item->path(); if(path && fm_path_equal(fm_path_get_trash(), path)) { action = new PlacesModel::ItemAction(item->index(), tr("Empty Trash"), menu); connect(action, &QAction::triggered, this, &PlacesView::onEmptyTrash); menu->addAction(action); } break; } case PlacesModelItem::Bookmark: { // create context menu for bookmark item if(item->index().row() > 0) { action = new PlacesModel::ItemAction(item->index(), tr("Move Bookmark Up"), menu); connect(action, &QAction::triggered, this, &PlacesView::onMoveBookmarkUp); menu->addAction(action); } if(item->index().row() < model_->rowCount()) { action = new PlacesModel::ItemAction(item->index(), tr("Move Bookmark Down"), menu); connect(action, &QAction::triggered, this, &PlacesView::onMoveBookmarkDown); menu->addAction(action); } action = new PlacesModel::ItemAction(item->index(), tr("Rename Bookmark"), menu); connect(action, &QAction::triggered, this, &PlacesView::onRenameBookmark); menu->addAction(action); action = new PlacesModel::ItemAction(item->index(), tr("Remove Bookmark"), menu); connect(action, &QAction::triggered, this, &PlacesView::onDeleteBookmark); menu->addAction(action); break; } case PlacesModelItem::Volume: { PlacesModelVolumeItem* volumeItem = static_cast<PlacesModelVolumeItem*>(item); if(volumeItem->isMounted()) { action = new PlacesModel::ItemAction(item->index(), tr("Unmount"), menu); connect(action, &QAction::triggered, this, &PlacesView::onUnmountVolume); } else { action = new PlacesModel::ItemAction(item->index(), tr("Mount"), menu); connect(action, &QAction::triggered, this, &PlacesView::onMountVolume); } menu->addAction(action); if(volumeItem->canEject()) { action = new PlacesModel::ItemAction(item->index(), tr("Eject"), menu); connect(action, &QAction::triggered, this, &PlacesView::onEjectVolume); menu->addAction(action); } break; } case PlacesModelItem::Mount: { action = new PlacesModel::ItemAction(item->index(), tr("Unmount"), menu); connect(action, &QAction::triggered, this, &PlacesView::onUnmountMount); menu->addAction(action); break; } } if(menu->actions().size()) { menu->popup(mapToGlobal(event->pos())); connect(menu, &QMenu::aboutToHide, menu, &QMenu::deleteLater); } else { menu->deleteLater(); } } }
void PlacesModel::onVolumeRemoved(GVolumeMonitor* monitor, GVolume* volume, PlacesModel* pThis) { PlacesModelVolumeItem* item = pThis->itemFromVolume(volume); if(item) { pThis->devicesRoot->removeRow(item->row()); } }