示例#1
0
void DesktopWindow::onIndexesMoved(const QModelIndexList& indexes) {
    auto delegate = static_cast<Fm::FolderItemDelegate*>(listView_->itemDelegateForColumn(0));
    auto itemSize = delegate->itemSize();
    // remember the custom position for the items
    Q_FOREACH(const QModelIndex& index, indexes) {
        // Under some circumstances, Qt might emit indexMoved for
        // every single cells in the same row. (when QAbstractItemView::SelectItems is set)
        // So indexes list may contain several indixes for the same row.
        // Since we only care about rows, not individual cells,
        // let's handle column 0 of every row here.
        if(index.column() == 0) {
            auto file = proxyModel_->fileInfoFromIndex(index);
            QRect itemRect = listView_->rectForIndex(index);
            QPoint tl = itemRect.topLeft();
            QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
            workArea.adjust(12, 12, -12, -12);

            // check if the position is occupied by another item
            auto existingItem = std::find_if(customItemPos_.cbegin(), customItemPos_.cend(), [tl](const std::pair<std::string, QPoint>& elem){
                return elem.second == tl;
            });

            if(existingItem == customItemPos_.cend() // don't put items on each other
                    && tl.x() >= workArea.x() && tl.y() >= workArea.y()
                    && tl.x() + itemSize.width() <= workArea.right() + 1 // for historical reasons (-> Qt doc)
                    && tl.y() + itemSize.height() <= workArea.bottom() + 1) { // as above
                customItemPos_[file->name()] = tl;
                // qDebug() << "indexMoved:" << name << index << itemRect;
            }
        }
    }
    saveItemPositions();
    queueRelayout();
}
示例#2
0
void DesktopWindow::onStickToCurrentPos(bool toggled) {
    QModelIndexList indexes = listView_->selectionModel()->selectedIndexes();
    if(!indexes.isEmpty()) {
        bool relayout(false);
        QModelIndexList::const_iterator it;
        for(it = indexes.constBegin(); it != indexes.constEnd(); ++it) {
            auto file = proxyModel_->fileInfoFromIndex(*it);
            auto name = file->name();
            if(toggled) { // remember the current custom position
                QRect itemRect = listView_->rectForIndex(*it);
                customItemPos_[name] = itemRect.topLeft();
            }
            else { // cancel custom position and perform relayout
                auto item = customItemPos_.find(name);
                if(item != customItemPos_.end()) {
                    customItemPos_.erase(item);
                    relayout = true;
                }
            }
        }
        saveItemPositions();
        if(relayout) {
            relayoutItems();
        }
    }
}
示例#3
0
void DesktopWindow::onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
    Q_UNUSED(parent);
    Q_UNUSED(start);
    Q_UNUSED(end);
    if(!customItemPos_.empty()) {
        // also delete stored custom item positions for the items currently being removed.
        // Here we can't rely on ProxyFolderModel::fileInfoFromIndex() because, although rows
        // aren't removed yet, files are already removed.
        bool changed = false;
        char* dektopPath = Fm::Path::getDesktop().toStr();
        QString desktopDir = QString(dektopPath) + QString("/");
        g_free(dektopPath);
        for(auto it = customItemPos_.cbegin(); it != customItemPos_.cend();) {
            auto& name = it->first;
            if(!QFile::exists(desktopDir + QString::fromStdString(name))) {
                it = customItemPos_.erase(it);
                changed = true;
            }
            else {
                ++it;
            }
        }
        if(changed) {
            saveItemPositions();
        }
    }
    listView_->setUpdatesEnabled(false);
    queueRelayout(100);
}
示例#4
0
void DesktopWindow::onIndexesMoved(const QModelIndexList& indexes) {
  // remember the custom position for the items
  Q_FOREACH(const QModelIndex& index, indexes) {
    // Under some circumstances, Qt might emit indexMoved for
    // every single cells in the same row. (when QAbstractItemView::SelectItems is set)
    // So indexes list may contain several indixes for the same row.
    // Since we only care about rows, not individual cells,
    // let's handle column 0 of every row here.
    if(index.column() == 0) {
      FmFileInfo* file = proxyModel_->fileInfoFromIndex(index);
      QRect itemRect = listView_->rectForIndex(index);
      QPoint tl = itemRect.topLeft();
      QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
      workArea.adjust(12, 12, -12, -12);
      if(customItemPos_.keys(tl).isEmpty() // don't put items on each other
         && tl.x() >= workArea.x() && tl.y() >= workArea.y()
         && tl.x() + listView_->gridSize().width() <= workArea.right() + 1 // for historical reasons (-> Qt doc)
         && tl.y() + listView_->gridSize().height() <= workArea.bottom() + 1) { // as above
        QByteArray name = fm_file_info_get_name(file);
        customItemPos_[name] = tl;
        // qDebug() << "indexMoved:" << name << index << itemRect;
      }
    }
  }
  saveItemPositions();
  queueRelayout();
}
示例#5
0
void DesktopWindow::childDropEvent(QDropEvent* e) {
    const QMimeData* mimeData = e->mimeData();
    bool moveItem = false;
    if(e->source() == listView_ && e->keyboardModifiers() == Qt::NoModifier) {
        // drag source is our list view, and no other modifier keys are pressed
        // => we're dragging desktop items
        if(mimeData->hasFormat("application/x-qabstractitemmodeldatalist")) {
            QModelIndex dropIndex = listView_->indexAt(e->pos());
            if(dropIndex.isValid()) { // drop on an item
                QModelIndexList selected = selectedIndexes(); // the dragged items
                if(selected.contains(dropIndex)) { // drop on self, ignore
                    moveItem = true;
                }
            }
            else { // drop on a blank area
                moveItem = true;
            }
        }
    }
    if(moveItem) {
        e->accept();
    }
    else {
        auto delegate = static_cast<Fm::FolderItemDelegate*>(listView_->itemDelegateForColumn(0));
        auto grid = delegate->itemSize();
        Fm::FolderView::childDropEvent(e);
        // position dropped items successively, starting with the drop rectangle
        if(mimeData->hasUrls()
           && (e->dropAction() == Qt::CopyAction
               || e->dropAction() == Qt::MoveAction
               || e->dropAction() == Qt::LinkAction)) {
            QList<QUrl> urlList = mimeData->urls();
            for(int i = 0; i < urlList.count(); ++i) {
                std::string name = urlList.at(i).fileName().toUtf8().constData();
                if(!name.empty()) { // respect the positions of existing files
                    QString desktopDir = XdgDir::readDesktopDir() + QString(QLatin1String("/"));
                    if(!QFile::exists(desktopDir + QString::fromStdString(name))) {
                        QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
                        workArea.adjust(12, 12, -12, -12);
                        QPoint pos = mapFromGlobal(e->pos());
                        alignToGrid(pos, workArea.topLeft(), grid, listView_->spacing());
                        if(i > 0)
                            pos.setY(pos.y() + grid.height() + listView_->spacing());
                        if(pos.y() + grid.height() > workArea.bottom() + 1) {
                            pos.setX(pos.x() + grid.width() + listView_->spacing());
                            pos.setY(workArea.top());
                        }
                        customItemPos_[name] = pos;
                    }
                }
            }
            saveItemPositions();
        }
    }
}
示例#6
0
void DesktopWindow::onStickToCurrentPos(bool toggled) {
  QAction* action = static_cast<QAction*>(sender());
  Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(action->parent());

  QModelIndexList indexes = listView_->selectionModel()->selectedIndexes();
  if(!indexes.isEmpty()) {
    FmFileInfo* file = menu->firstFile();
    QByteArray name = fm_file_info_get_name(file);
    QModelIndex index = indexes.first();
    if(toggled) { // remember to current custom position
      QRect itemRect = listView_->rectForIndex(index);
      customItemPos_[name] = itemRect.topLeft();
      saveItemPositions();
    }
    else { // cancel custom position and perform relayout
      QHash<QByteArray, QPoint>::iterator it = customItemPos_.find(name);
      if(it != customItemPos_.end()) {
        customItemPos_.erase(it);
        saveItemPositions();
        relayoutItems();
      }
    }
  }
}
示例#7
0
void DesktopWindow::onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
  Q_UNUSED(parent);
  Q_UNUSED(start);
  Q_UNUSED(end);
  if(!customItemPos_.isEmpty()) {
    // also delete stored custom item positions for the items currently being removed.
    // Here we can't rely on ProxyFolderModel::fileInfoFromIndex() because, although rows
    // aren't removed yet, files are already removed.
    QHash<QByteArray, QPoint> _customItemPos = customItemPos_;
    char* dektopPath = fm_path_to_str(fm_path_get_desktop());
    QString desktopDir = QString(dektopPath) + QString("/");
    g_free(dektopPath);
    QHash<QByteArray, QPoint>::iterator it;
    for(it = _customItemPos.begin(); it != _customItemPos.end(); ++it) {
      const QByteArray& name = it.key();
      if(!QFile::exists(desktopDir + QString::fromUtf8(name, name.length())))
        customItemPos_.remove(it.key());
    }
    if(customItemPos_ != _customItemPos)
      saveItemPositions();
  }
  queueRelayout();
}