aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/dialogs/sortdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/dialogs/sortdialog.cpp')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dialogs/sortdialog.cpp248
1 files changed, 248 insertions, 0 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/sortdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/sortdialog.cpp
new file mode 100644
index 0000000..b1451eb
--- /dev/null
+++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/sortdialog.cpp
@@ -0,0 +1,248 @@
+#include "sortdialog.h"
+#include "ui_sortdialog.h"
+#include "iconmanager.h"
+#include "common/unused.h"
+#include <QComboBox>
+#include <QDebug>
+#include <QPushButton>
+
+SortDialog::SortDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::SortDialog)
+{
+ ui->setupUi(this);
+
+ initActions();
+ ui->list->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+
+ connect(ui->list->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateButtons()));
+ connect(ui->list, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(itemChanged(QTreeWidgetItem*,int)));
+ connect(ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(reset()));
+ connect(ui->list->model(), &QAbstractItemModel::rowsInserted, [=](const QModelIndex & parent, int start, int end)
+ {
+ UNUSED(parent);
+ UNUSED(end);
+ rebuildComboForItem(ui->list->topLevelItem(start));
+ });
+}
+
+SortDialog::~SortDialog()
+{
+ delete ui;
+}
+
+void SortDialog::setColumns(const QStringList& columns)
+{
+ originalColumns = columns;
+ ui->list->clear();
+
+ QTreeWidgetItem* item = nullptr;
+ for (int row = 0, total = columns.size(); row < total; ++row)
+ {
+ item = new QTreeWidgetItem({columns[row], "ASC"});
+ item->setData(2, Qt::UserRole, row);
+ fixItemFlags(item);
+ ui->list->insertTopLevelItem(row, item);
+ item->setCheckState(0, Qt::Unchecked);
+ }
+ ui->list->setHeaderLabels({tr("Column"), tr("Order")});
+ updateButtons();
+}
+
+QueryExecutor::SortList SortDialog::getSortOrder() const
+{
+ QueryExecutor::SortList sortOrder;
+
+ QTreeWidgetItem* item = nullptr;
+ QComboBox* combo = nullptr;
+ for (int row = 0, total = ui->list->topLevelItemCount(); row < total; ++row)
+ {
+ item = ui->list->topLevelItem(row);
+ if (item->checkState(0) != Qt::Checked)
+ continue;
+
+ combo = dynamic_cast<QComboBox*>(ui->list->itemWidget(item, 1));
+ sortOrder << QueryExecutor::Sort((combo->currentText() == "ASC" ? Qt::AscendingOrder : Qt::DescendingOrder), item->data(2, Qt::UserRole).toInt());
+ }
+ return sortOrder;
+}
+
+void SortDialog::setSortOrder(const QueryExecutor::SortList& sortOrder)
+{
+ // Translate sort order into more usable (in here) form
+ QHash<int,QueryExecutor::Sort::Order> checkedColumns;
+ QList<int> checkedColumnsOrder;
+ for (const QueryExecutor::Sort& sort : sortOrder)
+ {
+ checkedColumns[sort.column] = sort.order;
+ checkedColumnsOrder << sort.column;
+ }
+
+ // Select proper columns and set order
+ bool checked;
+ QTreeWidgetItem* item = nullptr;
+ QComboBox* combo = nullptr;
+ for (int row = 0, total = ui->list->topLevelItemCount(); row < total; ++row)
+ {
+ item = ui->list->topLevelItem(row);
+ checked = checkedColumns.contains(item->data(2, Qt::UserRole).toInt());
+ item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked);
+
+ combo = dynamic_cast<QComboBox*>(ui->list->itemWidget(item, 1));
+ combo->setCurrentText(checkedColumns[row] == QueryExecutor::Sort::DESC ? "DESC" : "ASC");
+ }
+
+ // Get selected items as an ordered list of items (in order as defined in the sort order), so we can easly relocate them
+ QList<QTreeWidgetItem*> orderedItems;
+ for (int row : checkedColumnsOrder)
+ orderedItems << ui->list->topLevelItem(row);
+
+ // Move selected items in front, in the same order as they were mentioned in the sort order
+ int newRow = 0;
+ for (QTreeWidgetItem* itemToMove : orderedItems)
+ {
+ ui->list->takeTopLevelItem(ui->list->indexOfTopLevelItem(itemToMove));
+ ui->list->insertTopLevelItem(newRow++, itemToMove);
+ }
+
+ updateState();
+}
+
+QToolBar* SortDialog::getToolBar(int toolbar) const
+{
+ UNUSED(toolbar);
+ return nullptr;
+}
+
+void SortDialog::updateState(QTreeWidgetItem* item)
+{
+ QComboBox* combo = dynamic_cast<QComboBox*>(ui->list->itemWidget(item, 1));
+ if (!combo)
+ return;
+
+ combo->setEnabled(item->checkState(0) == Qt::Checked);
+}
+
+void SortDialog::updateState()
+{
+ for (int row = 0, total = ui->list->topLevelItemCount(); row < total; ++row)
+ updateState(ui->list->topLevelItem(row));
+}
+
+void SortDialog::fixItemFlags(QTreeWidgetItem* item)
+{
+ Qt::ItemFlags flags = item->flags();
+ flags |= Qt::ItemNeverHasChildren;
+ flags |= Qt::ItemIsUserCheckable;
+ flags ^= Qt::ItemIsDropEnabled;
+ flags ^= Qt::ItemIsEditable;
+ item->setFlags(flags);
+}
+
+void SortDialog::rebuildComboForItem(QTreeWidgetItem* item)
+{
+ QComboBox* combo = new QComboBox();
+ combo->addItems({"ASC", "DESC"});
+ combo->setCurrentText(item->text(1));
+ combo->setEnabled(item->checkState(0) == Qt::Checked);
+ ui->list->setItemWidget(item, 1, combo);
+ item->setSizeHint(1, combo->sizeHint()); // bug in Qt? without this comboboxes were misaligned vertically
+
+ connect(combo, &QComboBox::currentTextChanged, [item](const QString& newText)
+ {
+ item->setText(1, newText);
+ });
+
+ updateSortLabel();
+}
+
+void SortDialog::updateSortLabel()
+{
+ QStringList entries;
+ QTreeWidgetItem* item = nullptr;
+ for (int row = 0, total = ui->list->topLevelItemCount(); row < total; ++row)
+ {
+ item = ui->list->topLevelItem(row);
+ if (item->checkState(0) != Qt::Checked)
+ continue;
+
+ entries << item->text(0) + " " + item->text(1);
+ }
+
+ if (entries.size() == 0)
+ {
+ ui->sortByLabel->setVisible(false);
+ }
+ else
+ {
+ static QString label = tr("Sort by: %1");
+ ui->sortByLabel->setText(label.arg(entries.join(", ")));
+ ui->sortByLabel->setVisible(true);
+ }
+}
+
+void SortDialog::itemChanged(QTreeWidgetItem* item, int column)
+{
+ if (column == 0)
+ updateState(item);
+
+ updateSortLabel();
+}
+
+void SortDialog::reset()
+{
+ setColumns(originalColumns);
+}
+
+void SortDialog::updateButtons()
+{
+ QTreeWidgetItem* item = ui->list->currentItem();
+ actionMap[MOVE_UP]->setEnabled(item && ui->list->itemAbove(item) != nullptr);
+ actionMap[MOVE_DOWN]->setEnabled(item && ui->list->itemBelow(item) != nullptr);
+}
+
+void SortDialog::moveCurrentUp()
+{
+ QTreeWidgetItem* item = ui->list->currentItem();
+ if (!item)
+ return;
+
+ int row = ui->list->indexOfTopLevelItem(item);
+ if (row < 1)
+ return;
+
+ ui->list->takeTopLevelItem(row);
+ ui->list->insertTopLevelItem(row - 1, item);
+
+ QModelIndex idx = ui->list->model()->index(row - 1, 0);
+ ui->list->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Rows|QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Current);
+ updateButtons();
+}
+
+void SortDialog::moveCurrentDown()
+{
+ QTreeWidgetItem* item = ui->list->currentItem();
+ if (!item)
+ return;
+
+ int row = ui->list->indexOfTopLevelItem(item);
+ if (row + 1 >= ui->list->topLevelItemCount())
+ return;
+
+ ui->list->takeTopLevelItem(row);
+ ui->list->insertTopLevelItem(row + 1, item);
+
+ QModelIndex idx = ui->list->model()->index(row + 1, 0);
+ ui->list->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Rows|QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Current);
+ updateButtons();
+}
+
+void SortDialog::createActions()
+{
+ createAction(MOVE_UP, ICONS.MOVE_UP, tr("Move column up"), this, SLOT(moveCurrentUp()), ui->toolbar, this);
+ createAction(MOVE_DOWN, ICONS.MOVE_DOWN, tr("Move column down"), this, SLOT(moveCurrentDown()), ui->toolbar, this);
+}
+
+void SortDialog::setupDefShortcuts()
+{
+}