From 40af45bb1c47dd5c13a4e73a450a86a1af65e861 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 6 Jan 2026 16:30:52 +0500 Subject: [PATCH 1/2] feat: allow moving accounts in list Signed-off-by: Octol1ttle Signed-off-by: Octol1ttle --- launcher/minecraft/auth/AccountList.cpp | 18 +++++++++++++ launcher/minecraft/auth/AccountList.h | 1 + launcher/ui/pages/global/AccountListPage.cpp | 28 ++++++++++++++++++++ launcher/ui/pages/global/AccountListPage.h | 2 ++ launcher/ui/pages/global/AccountListPage.ui | 12 +++++++++ 5 files changed, 61 insertions(+) diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index cef79d200..5059c5cfa 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -168,6 +168,24 @@ void AccountList::removeAccount(QModelIndex index) } } +void AccountList::moveAccount(QModelIndex index, int delta) { + int row = index.row(); + int newRow = row + delta; + if (index.isValid() && row < m_accounts.size() && newRow >= 0 && newRow < m_accounts.size()) { + auto account = m_accounts.at(row); + + beginRemoveRows(QModelIndex(), row, row); + m_accounts.removeAt(row); + endRemoveRows(); + + beginInsertRows(QModelIndex(), newRow, newRow); + m_accounts.insert(newRow, account); + endInsertRows(); + + onListChanged(); + } +} + MinecraftAccountPtr AccountList::defaultAccount() const { return m_defaultAccount; diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h index 2f1276312..7438369a1 100644 --- a/launcher/minecraft/auth/AccountList.h +++ b/launcher/minecraft/auth/AccountList.h @@ -78,6 +78,7 @@ class AccountList : public QAbstractListModel { void addAccount(MinecraftAccountPtr account); void removeAccount(QModelIndex index); + void moveAccount(QModelIndex index, int delta); int findAccountByProfileId(const QString& profileId) const; MinecraftAccountPtr getAccountByProfileName(const QString& profileName) const; QStringList profileNames() const; diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index ff250888a..e84ca8ca4 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -210,11 +210,17 @@ void AccountListPage::updateButtonStates() bool hasSelection = !selection.empty(); bool accountIsReady = false; bool accountIsOnline = false; + bool accountCanMoveUp = false; + bool accountCanMoveDown = false; if (hasSelection) { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); accountIsReady = !account->isActive(); accountIsOnline = account->accountType() != AccountType::Offline; + + accountCanMoveUp = selected.row() > 0; + int indexOfLast = m_accounts->count() - 1; + accountCanMoveDown = selected.row() < indexOfLast; } ui->actionRemove->setEnabled(accountIsReady); ui->actionSetDefault->setEnabled(accountIsReady); @@ -228,6 +234,8 @@ void AccountListPage::updateButtonStates() ui->actionNoDefault->setEnabled(true); ui->actionNoDefault->setChecked(false); } + ui->actionMoveUp->setEnabled(accountCanMoveUp); + ui->actionMoveDown->setEnabled(accountCanMoveDown); ui->listView->resizeColumnToContents(3); } @@ -241,3 +249,23 @@ void AccountListPage::on_actionManageSkins_triggered() dialog.exec(); } } + +void AccountListPage::on_actionMoveUp_triggered() +{ + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.size() > 0) { + QModelIndex selected = selection.first(); + m_accounts->moveAccount(selected, -1); + ui->listView->selectionModel()->select(ui->listView->indexAbove(selected), QItemSelectionModel::SelectCurrent); + } +} + +void AccountListPage::on_actionMoveDown_triggered() +{ + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.size() > 0) { + QModelIndex selected = selection.first(); + m_accounts->moveAccount(selected, 1); + ui->listView->selectionModel()->select(ui->listView->indexBelow(selected), QItemSelectionModel::SelectCurrent); + } +} diff --git a/launcher/ui/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h index 2841b9456..a35f76c44 100644 --- a/launcher/ui/pages/global/AccountListPage.h +++ b/launcher/ui/pages/global/AccountListPage.h @@ -76,6 +76,8 @@ class AccountListPage : public QMainWindow, public BasePage { void on_actionSetDefault_triggered(); void on_actionNoDefault_triggered(); void on_actionManageSkins_triggered(); + void on_actionMoveUp_triggered(); + void on_actionMoveDown_triggered(); void listChanged(); diff --git a/launcher/ui/pages/global/AccountListPage.ui b/launcher/ui/pages/global/AccountListPage.ui index c9b770ab2..6fa004ed7 100644 --- a/launcher/ui/pages/global/AccountListPage.ui +++ b/launcher/ui/pages/global/AccountListPage.ui @@ -58,6 +58,8 @@ + + @@ -105,6 +107,16 @@ Remo&ve + + + Move &Up + + + + + Move &Down + + From fa88edf8c380553c0facee402919f06f61f1361c Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Wed, 7 Jan 2026 20:09:33 +0500 Subject: [PATCH 2/2] Use real move instead of remove-then-insert Signed-off-by: Octol1ttle Signed-off-by: Octol1ttle --- launcher/minecraft/auth/AccountList.cpp | 22 ++++++++++---------- launcher/ui/pages/global/AccountListPage.cpp | 2 -- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 5059c5cfa..24e1d9aae 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -169,20 +169,20 @@ void AccountList::removeAccount(QModelIndex index) } void AccountList::moveAccount(QModelIndex index, int delta) { - int row = index.row(); - int newRow = row + delta; + const int row = index.row(); + const int newRow = row + delta; if (index.isValid() && row < m_accounts.size() && newRow >= 0 && newRow < m_accounts.size()) { - auto account = m_accounts.at(row); + // Qt is stupid, https://doc.qt.io/qt-6/qabstractitemmodel.html#beginMoveRows + const int modelDestinationRow = (newRow > row) ? newRow + 1 : newRow; - beginRemoveRows(QModelIndex(), row, row); - m_accounts.removeAt(row); - endRemoveRows(); + if (beginMoveRows(QModelIndex(), row, row, QModelIndex(), modelDestinationRow)) { + m_accounts.move(row, newRow); + endMoveRows(); - beginInsertRows(QModelIndex(), newRow, newRow); - m_accounts.insert(newRow, account); - endInsertRows(); - - onListChanged(); + onListChanged(); + } else { + qCritical().noquote() << "AccountList: failed to move account from" << row << "to" << newRow << QString("(%1 accounts in total)").arg(this->count()); + } } } diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index e84ca8ca4..725960b94 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -256,7 +256,6 @@ void AccountListPage::on_actionMoveUp_triggered() if (selection.size() > 0) { QModelIndex selected = selection.first(); m_accounts->moveAccount(selected, -1); - ui->listView->selectionModel()->select(ui->listView->indexAbove(selected), QItemSelectionModel::SelectCurrent); } } @@ -266,6 +265,5 @@ void AccountListPage::on_actionMoveDown_triggered() if (selection.size() > 0) { QModelIndex selected = selection.first(); m_accounts->moveAccount(selected, 1); - ui->listView->selectionModel()->select(ui->listView->indexBelow(selected), QItemSelectionModel::SelectCurrent); } }