diff --git a/lib/roaming.cc b/lib/roaming.cc index 4a9218d7..f64ca6b0 100644 --- a/lib/roaming.cc +++ b/lib/roaming.cc @@ -227,6 +227,18 @@ RoamingZoneList::moveUp(int row) { return true; } +bool +RoamingZoneList::moveUp(int first, int last) { + if ((0>=first) || (last>=count())) + return false; + beginMoveRows(QModelIndex(), first, last, QModelIndex(), first-1); + for (int row=first; row<=last; row++) + std::swap(_zones[row], _zones[row-1]); + endMoveRows(); + emit modified(); + return true; +} + bool RoamingZoneList::moveDown(int row) { if ((0>row) || ((row-1)>=count())) @@ -238,6 +250,18 @@ RoamingZoneList::moveDown(int row) { return true; } +bool +RoamingZoneList::moveDown(int first, int last) { + if ((0>first) || ((last+1)>=count())) + return false; + beginMoveRows(QModelIndex(), first, last, QModelIndex(), last+2); + for (int row=last; row>=first; row--) + std::swap(_zones[row], _zones[row+1]); + endMoveRows(); + emit modified(); + return true; +} + int RoamingZoneList::rowCount(const QModelIndex &idx) const { Q_UNUSED(idx); diff --git a/lib/roaming.hh b/lib/roaming.hh index 55aeadc2..b133b450 100644 --- a/lib/roaming.hh +++ b/lib/roaming.hh @@ -130,8 +130,12 @@ public: /** Moves the roaming zone at the given row one up. */ bool moveUp(int row); + /** Moves the roaming zones one up. */ + bool moveUp(int first, int last); /** Moves the roaming zone at the given row one down. */ bool moveDown(int row); + /** Moves the roaming zones one down. */ + bool moveDown(int first, int last); /** Implementation of QAbstractListModel, returns the number of rows. */ int rowCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/shared/mainwindow.ui b/shared/mainwindow.ui index 3cd66d54..7b04f1d5 100644 --- a/shared/mainwindow.ui +++ b/shared/mainwindow.ui @@ -849,6 +849,9 @@ + + QAbstractItemView::ContiguousSelection + QAbstractItemView::SelectRows diff --git a/src/application.cc b/src/application.cc index 9dbf7ba9..ab15b08c 100644 --- a/src/application.cc +++ b/src/application.cc @@ -1466,13 +1466,10 @@ Application::onAddRoamingZone() { return; QListView *list = _mainWindow->findChild("roamingZoneList"); - QModelIndex selected = list->selectionModel()->currentIndex(); - - RoamingZone *zone = dialog.zone(); - if (selected.isValid()) - _config->roaming()->addZone(zone, selected.row()+1); - else - _config->roaming()->addZone(zone); + int row=-1; + if (list->selectionModel()->hasSelection()) + row = list->selectionModel()->selection().back().bottom()+1; + _config->roaming()->addZone(dialog.zone(), row); } void @@ -1497,46 +1494,80 @@ Application::onGenRoamingZone() { zone->deleteLater(); return; } - dialog.zone(); - _config->roaming()->addZone(zone); + + QListView *list = _mainWindow->findChild("roamingZoneList"); + int row=-1; + if (list->selectionModel()->hasSelection()) + row = list->selectionModel()->selection().back().bottom()+1; + _config->roaming()->addZone(dialog.zone(), row); } void Application::onRemRoamingZone() { - QModelIndex idx = _mainWindow->findChild("roamingZoneList")->selectionModel()->currentIndex(); - if (! idx.isValid()) { + QListView *list = _mainWindow->findChild("roamingZoneList"); + if (! list->selectionModel()->hasSelection()) { QMessageBox::information( nullptr, tr("Cannot delete roaming zone"), tr("Cannot delete roaming zone: You have to select a zone first.")); return; } - QString name = _config->roaming()->zone(idx.row())->name(); - if (QMessageBox::No == QMessageBox::question( - nullptr, tr("Delete roaming zone?"), tr("Delete roaming zone %1?").arg(name))) - return; - - _config->roaming()->remZone(idx.row()); + // Get selection and ask for deletion + QList rows = getSelectionRows(list->selectionModel()->selection().indexes()); + if (1 == rows.count()) { + QString name = _config->roaming()->zone(rows.first())->name(); + if (QMessageBox::No == QMessageBox::question( + nullptr, tr("Delete roaming zone?"), tr("Delete roaming zone %1?").arg(name))) + return; + } else { + if (QMessageBox::No == QMessageBox::question( + nullptr, tr("Delete roaming zones?"), tr("Delete %1 roaming zones?").arg(rows.count()))) + return; + } + // collect all selected zones + // need to collect them first as rows change when deleting + QList lists; lists.reserve(rows.count()); + foreach (int row, rows) + lists.push_back(_config->roaming()->zone(row)); + // remove + foreach (RoamingZone *zone, lists) + _config->roaming()->remZone(zone); } void Application::onRoamingZoneUp() { QListView *list = _mainWindow->findChild("roamingZoneList"); - QModelIndex selected = list->selectionModel()->currentIndex(); - if ((! selected.isValid()) || (0 >= selected.row())) + // Check if there is a selection + if (! list->selectionModel()->hasSelection()) { + QMessageBox::information( + nullptr, tr("Cannot move roaming zones."), + tr("Cannot move roaming zones: You have to select at least one roaming zone first.")); return; - if (_config->roaming()->moveUp(selected.row())) - list->setCurrentIndex(_config->roaming()->index(selected.row()-1)); + } + // Get selection range assuming only continious selection mode + QPair rows = getSelectionRowRange(list->selectionModel()->selection().indexes()); + if ((0>rows.first) || (0>rows.second)) + return; + // Then move rows + _config->roaming()->moveUp(rows.first, rows.second); } void Application::onRoamingZoneDown() { QListView *list = _mainWindow->findChild("roamingZoneList"); - QModelIndex selected = list->selectionModel()->currentIndex(); - if ((! selected.isValid()) || ((_config->roaming()->count()-1) <= selected.row())) + // Check if there is a selection + if (! list->selectionModel()->hasSelection()) { + QMessageBox::information( + nullptr, tr("Cannot move roaming zones."), + tr("Cannot move roaming zones: You have to select at least one roaming zone first.")); return; - if (_config->roaming()->moveDown(selected.row())) - list->setCurrentIndex(_config->roaming()->index(selected.row()+1)); + } + // Get selection range assuming only continious selection mode + QPair rows = getSelectionRowRange(list->selectionModel()->selection().indexes()); + if ((0>rows.first) || (0>rows.second)) + return; + // Then move rows + _config->roaming()->moveDown(rows.first, rows.second); } void