/* Copyright (C) 2015 * swift project Community / Contributors * * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, * including this file, may be copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE file. */ #include "blackgui/menus/menuaction.h" #include "blackgui/views/viewdbobjects.h" #include "blackmisc/icons.h" #include #include #include #include #include #include using namespace BlackMisc; using namespace BlackGui; using namespace BlackGui::Models; using namespace BlackGui::Menus; namespace BlackGui { namespace Views { template CViewWithDbObjects::CViewWithDbObjects(QWidget *parent) : CViewBase(parent) { // void } template ObjectType CViewWithDbObjects::latestObject() const { return this->container().latestObject(); } template ObjectType CViewWithDbObjects::oldestObject() const { return this->container().oldestObject(); } template void CViewWithDbObjects::selectDbKey(const KeyType &key) { const QSet set({key}); this->selectDbKeys(set); } template void CViewWithDbObjects::selectDbKeys(const QSet &keys) { if (keys.isEmpty()) { return; } this->clearSelection(); int r = -1; QSet rows; for (const ObjectType &obj : CViewBase::containerOrFilteredContainer()) { r++; if (!obj.hasValidDbKey()) { continue; } if (keys.contains(obj.getDbKey())) { rows.insert(r); } } this->selectRows(rows); } template QSet CViewWithDbObjects::selectedDbKeys() const { if (!this->hasSelection()) { return QSet(); } const ContainerType selected(this->selectedObjects()); return selected.toDbKeySet(); } template int CViewWithDbObjects::removeDbKeys(const QSet &keys) { if (keys.isEmpty()) { return 0; } if (this->isEmpty()) { return 0; } ContainerType newObjects(this->container()); int delta = newObjects.removeObjectsWithKeys(keys); if (delta > 0) { this->updateContainerMaybeAsync(newObjects); } return delta; } template int CViewWithDbObjects::replaceOrAddObjectsByKey(const ContainerType &container) { if (container.isEmpty()) { return 0; } ContainerType copy(this->container()); int c = copy.replaceOrAddObjectsByKey(container); if (c == 0) { return 0; } this->updateContainerMaybeAsync(copy); return c; } template void CViewWithDbObjects::customMenu(Menus::CMenuActions &menuActions) { CViewBase::customMenu(menuActions); } template COrderableViewWithDbObjects::COrderableViewWithDbObjects(QWidget *parent) : CViewWithDbObjects::CViewWithDbObjects(parent) { // void } template void COrderableViewWithDbObjects::customMenu(CMenuActions &menuActions) { if (this->m_menus.testFlag(CViewBaseNonTemplate::MenuOrderable) && this->hasSelection()) { const int maxOrder = this->rowCount() - 1; CMenuAction menu = menuActions.addMenuViewOrder(); if (this->m_menuActions.isEmpty()) { // predefine menus this->m_menuActions = QList({ nullptr, nullptr, nullptr, nullptr}); if (!this->m_menuActions[0]) { this->m_frame = new QFrame(this); QHBoxLayout *layout = new QHBoxLayout(this->m_frame); layout->setMargin(2); this->m_frame->setLayout(layout); this->m_leOrder = new QLineEdit(this->m_frame); QLabel *icon = new QLabel(this->m_frame); icon->setPixmap(menu.getPixmap()); layout->addWidget(icon); QLabel *label = new QLabel(this->m_frame); label->setText("Order:"); layout->addWidget(label); layout->addWidget(this->m_leOrder); this->m_validator = new QIntValidator(0, maxOrder, this); this->m_leOrder->setValidator(this->m_validator); QWidgetAction *orderAction = new QWidgetAction(this); orderAction->setDefaultWidget(this->m_frame); QObject::connect(this->m_leOrder, &QLineEdit::returnPressed, this, &COrderableViewWithDbObjects::ps_orderToLineEdit); this->m_menuActions[0] = orderAction; } } this->m_validator->setRange(0, maxOrder); this->m_leOrder->setPlaceholderText("New order 0-" + QString::number(maxOrder)); menuActions.addAction(this->m_menuActions[0], CMenuAction::pathViewOrder()); this->m_menuActions[1] = menuActions.addAction(CIcons::arrowMediumNorth16(), "To top", CMenuAction::pathViewOrder(), { this, &COrderableViewWithDbObjects::ps_orderToTop }); this->m_menuActions[2] = menuActions.addAction(CIcons::arrowMediumSouth16(), "To bottom", CMenuAction::pathViewOrder(), { this, &COrderableViewWithDbObjects::ps_orderToBottom }); this->m_menuActions[3] = menuActions.addAction(CIcons::arrowMediumWest16(), "Freeze current order", CMenuAction::pathViewOrder(), { this, &COrderableViewWithDbObjects::ps_freezeCurrentOrder }); } CViewWithDbObjects::customMenu(menuActions); } template void COrderableViewWithDbObjects::selectObjects(const ContainerType &selectedObjects) { if (!selectedObjects.isEmpty()) { this->selectDbKeys(selectedObjects.toDbKeySet()); } } template void COrderableViewWithDbObjects::moveSelectedItems(int order) { if (this->isEmpty()) { return; } const ContainerType objs(this->selectedObjects()); if (objs.isEmpty()) { return; } this->m_model->moveItems(objs, order); } template void COrderableViewWithDbObjects::ps_orderToTop() { this->moveSelectedItems(0); } template void COrderableViewWithDbObjects::ps_orderToBottom() { int c = this->model()->rowCount() - 1; if (c >= 0) { this->moveSelectedItems(c); } } template void COrderableViewWithDbObjects::ps_orderToLineEdit() { if (this->isEmpty()) { return; } QLineEdit *le = qobject_cast(QObject::sender()); if (!le || le->text().isEmpty()) { return; } const int order = le->text().toInt(); this->moveSelectedItems(order); } template void COrderableViewWithDbObjects::ps_freezeCurrentOrder() { ContainerType objects = this->container(); objects.freezeOrder(); this->updateContainerAsync(objects, false); } // see here for the reason of thess forward instantiations // http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects; template class COrderableViewWithDbObjects; template class COrderableViewWithDbObjects; } // namespace } // namespace