DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
ChoiceListDialog.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
4#include "moc_ChoiceListDialog.cpp"
5#include "ChoiceListDialog.h"
6
8 std::string_view ParamName, bool IsOptional, std::string_view IconResourcePath, const std::vector<DynExp::ItemIDType>& Values)
9 : QDialog(parent, Qt::Dialog | Qt::WindowTitleHint),
10 ItemIDsWithLabels(std::move(ItemIDsWithLabels)), ParamName(ParamName), Optional(IsOptional),
11 ItemIcon(IconResourcePath.data()), Values(Values)
12{
13 ui.setupUi(this);
14
15 setWindowTitle(QString("Select items - ") + ParamName.data());
16
17 connect(ui.LWAvailable, &QListWidget::itemChanged, [this](QListWidgetItem*) { ui.LWAvailable->sortItems(); });
18}
19
20void ChoiceListDialog::showEvent(QShowEvent* event)
21{
22 const auto SelectionFilter = [this](bool SelectionState, const auto& IDLabelPair) {
23 return (std::find_if(Values.cbegin(), Values.cend(), [&IDLabelPair = std::as_const(IDLabelPair)](const auto ID) {
24 return IDLabelPair.second == ID;
25 }) == Values.cend()) != SelectionState;
26 };
27
28 const auto SelectedFilter = [&SelectionFilter](const auto& IDLabelPair) { return SelectionFilter(true, IDLabelPair); };
29 const auto NotSelectedFilter = [&SelectionFilter](const auto& IDLabelPair) { return SelectionFilter(false, IDLabelPair); };
30
31 const auto AddListWidgetItem = [this](const decltype(ItemIDsWithLabels)::value_type& Item, QListWidget* List) {
32 auto ListItem = new QListWidgetItem(QString::fromStdString(Item.first), List);
33 ListItem->setIcon(ItemIcon);
34 ListItem->setToolTip("ID " + QString::number(Item.second));
35 ListItem->setData(Qt::UserRole, QVariant::fromValue(Item.second));
36 };
37
38 ui.LWAvailable->clear();
39 for (const auto& Item : ItemIDsWithLabels | std::views::filter(NotSelectedFilter))
40 AddListWidgetItem(Item, ui.LWAvailable);
41
42 // Do not directly insert, to sort first according to Values vector.
44 for (const auto& Item : ItemIDsWithLabels | std::views::filter(SelectedFilter))
45 SelectedItems.push_back(Item);
46
47 std::sort(SelectedItems.begin(), SelectedItems.end(), [&Values = std::as_const(Values)](const auto& a, const auto& b) {
48 const auto ItA = std::find(Values.cbegin(), Values.cend(), a.second);
49 const auto ItB = std::find(Values.cbegin(), Values.cend(), b.second);
50
51 return ItA == Values.cend() || ItB == Values.cend() || ItA - Values.cbegin() < ItB - Values.cbegin();
52 });
53
54 ui.LWSelected->clear();
55 for (const auto& Item : SelectedItems)
56 AddListWidgetItem(Item, ui.LWSelected);
57
58 event->accept();
59}
60
62{
63 auto SelectedItems = ui.LWAvailable->selectedItems();
64 ui.LWAvailable->clearSelection();
65 ui.LWSelected->clearSelection();
66
67 for (auto Item : SelectedItems)
68 {
69 ui.LWSelected->addItem(ui.LWAvailable->takeItem(ui.LWAvailable->row(Item)));
70 Item->setSelected(true);
71 }
72}
73
75{
76 auto SelectedItems = ui.LWSelected->selectedItems();
77 ui.LWAvailable->clearSelection();
78 ui.LWSelected->clearSelection();
79
80 for (auto Item : SelectedItems)
81 {
82 ui.LWAvailable->addItem(ui.LWSelected->takeItem(ui.LWSelected->row(Item)));
83 Item->setSelected(true);
84 }
85}
86
88{
89 auto SelectedItems = ui.LWSelected->selectedItems();
90 std::sort(SelectedItems.begin(), SelectedItems.end(), [this](const auto& a, const auto& b) {
91 return ui.LWSelected->row(a) < ui.LWSelected->row(b);
92 });
93
94 for (auto Item : SelectedItems)
95 {
96 const auto Row = ui.LWSelected->row(Item);
97 if (Row <= 0)
98 continue;
99
100 ui.LWSelected->insertItem(Row - 1, ui.LWSelected->takeItem(Row));
101 Item->setSelected(true);
102 }
103}
104
106{
107 auto SelectedItems = ui.LWSelected->selectedItems();
108 std::sort(SelectedItems.begin(), SelectedItems.end(), [this](const auto& a, const auto& b) {
109 return ui.LWSelected->row(a) > ui.LWSelected->row(b);
110 });
111
112 for (auto Item : SelectedItems)
113 {
114 const auto Row = ui.LWSelected->row(Item);
115 if (Row >= ui.LWSelected->count() - 1)
116 continue;
117
118 ui.LWSelected->insertItem(Row + 1, ui.LWSelected->takeItem(Row));
119 Item->setSelected(true);
120 }
121}
122
124{
125 if (!IsOptional() && !ui.LWSelected->count())
126 {
127 QMessageBox::warning(this, "DynExp - Parameter empty",
128 QString("The parameter \"") + GetParamName().data() + "\" must not be empty. Please assign at least one item.");
129 return;
130 }
131
132 Values.clear();
133 for (Util::return_of_t<decltype(&QListWidget::count)> i = 0; i < ui.LWSelected->count(); ++i)
134 Values.push_back(ui.LWSelected->item(i)->data(Qt::UserRole).value<decltype(Values)::value_type>());
135
136 QDialog::accept();
137}
138
140{
141 QDialog::reject();
142}
Implements a dialog with a list of available items on the left and a list of selected items on the ri...
std::vector< DynExp::ItemIDType > Values
std::string_view GetParamName() const
virtual void showEvent(QShowEvent *event) override
bool IsOptional() const noexcept
virtual void reject() override
const std::string ParamName
const Util::TextValueListType< IndexType > ItemIDsWithLabels
Ui::ChoiceListDialog ui
ChoiceListDialog(QWidget *parent, Util::TextValueListType< IndexType > &&ItemIDsWithLabels, std::string_view ParamName, bool IsOptional, std::string_view IconResourcePath, const std::vector< DynExp::ItemIDType > &Values)
virtual void accept() override
typename member_fn_ptr_traits< CallableT >::return_type return_of_t
Alias for the return type of a member function callable of type CallableT.
Definition Util.h:362
std::vector< std::pair< TextType, ValueType > > TextValueListType
Type of a list containing key-value pairs where key is a text of type Util::TextType.
Definition QtUtil.h:37
Accumulates include statements to provide a precompiled header.