##// END OF EJS Templates
Handles state role in variable widget delegate
Alexandre Leroux -
r812:dbdd8e1bf997
parent child
Show More
@@ -1,239 +1,252
1 1 #include <Variable/RenameVariableDialog.h>
2 2 #include <Variable/Variable.h>
3 3 #include <Variable/VariableController.h>
4 4 #include <Variable/VariableInspectorWidget.h>
5 5 #include <Variable/VariableMenuHeaderWidget.h>
6 6 #include <Variable/VariableModel.h>
7 7
8 8 #include <ui_VariableInspectorWidget.h>
9 9
10 10 #include <QMouseEvent>
11 11 #include <QSortFilterProxyModel>
12 12 #include <QStyledItemDelegate>
13 13 #include <QWidgetAction>
14 14
15 15 #include <SqpApplication.h>
16 16
17 17 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
18 18
19 19
20 20 class QProgressBarItemDelegate : public QStyledItemDelegate {
21 21
22 22 public:
23 23 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
24 24
25 25 void paint(QPainter *painter, const QStyleOptionViewItem &option,
26 26 const QModelIndex &index) const
27 27 {
28 28 auto data = index.data(Qt::DisplayRole);
29 29 auto progressData = index.data(VariableRoles::ProgressRole);
30 30 if (data.isValid() && progressData.isValid()) {
31 31 auto name = data.value<QString>();
32 32 auto progress = progressData.value<double>();
33 33 if (progress > 0) {
34 34 auto cancelButtonWidth = 20;
35 35 auto progressBarOption = QStyleOptionProgressBar{};
36 36 auto progressRect = option.rect;
37 37 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
38 38 progressBarOption.rect = progressRect;
39 39 progressBarOption.minimum = 0;
40 40 progressBarOption.maximum = 100;
41 41 progressBarOption.progress = progress;
42 42 progressBarOption.text
43 43 = QString("%1 %2").arg(name).arg(QString::number(progress, 'f', 2) + "%");
44 44 progressBarOption.textVisible = true;
45 45 progressBarOption.textAlignment = Qt::AlignCenter;
46 46
47 47
48 48 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
49 49 painter);
50 50
51 51 // Cancel button
52 52 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
53 53 option.rect.height());
54 54 auto buttonOption = QStyleOptionButton{};
55 55 buttonOption.rect = buttonRect;
56 56 buttonOption.text = "X";
57 57
58 58 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
59 59 }
60 60 else {
61 61 QStyledItemDelegate::paint(painter, option, index);
62 62 }
63 63 }
64 64 else {
65 65 QStyledItemDelegate::paint(painter, option, index);
66
67 // Sets color depending on the state
68 auto stateRoleData = index.data(VariableRoles::StateRole);
69 if (stateRoleData.canConvert<StateData>()) {
70 auto stateData = stateRoleData.value<StateData>();
71
72 auto color = QColor{stateData.value("color").toString()};
73 if (color.isValid()) {
74 auto newOption = option;
75 newOption.palette.setBrush(QPalette::Text, QBrush{color});
76 QStyledItemDelegate::paint(painter, newOption, index);
77 }
78 }
66 79 }
67 80 }
68 81
69 82 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
70 83 const QModelIndex &index)
71 84 {
72 85 if (event->type() == QEvent::MouseButtonRelease) {
73 86 auto data = index.data(Qt::DisplayRole);
74 87 auto progressData = index.data(VariableRoles::ProgressRole);
75 88 if (data.isValid() && progressData.isValid()) {
76 89 auto cancelButtonWidth = 20;
77 90 auto progressRect = option.rect;
78 91 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
79 92 // Cancel button
80 93 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
81 94 option.rect.height());
82 95
83 96 auto e = (QMouseEvent *)event;
84 97 auto clickX = e->x();
85 98 auto clickY = e->y();
86 99
87 100 auto x = buttonRect.left(); // the X coordinate
88 101 auto y = buttonRect.top(); // the Y coordinate
89 102 auto w = buttonRect.width(); // button width
90 103 auto h = buttonRect.height(); // button height
91 104
92 105 if (clickX > x && clickX < x + w) {
93 106 if (clickY > y && clickY < y + h) {
94 107 auto variableModel = sqpApp->variableController().variableModel();
95 108 variableModel->abortProgress(index);
96 109 }
97 110 return true;
98 111 }
99 112 else {
100 113 return QStyledItemDelegate::editorEvent(event, model, option, index);
101 114 }
102 115 }
103 116 else {
104 117 return QStyledItemDelegate::editorEvent(event, model, option, index);
105 118 }
106 119 }
107 120 else {
108 121 return QStyledItemDelegate::editorEvent(event, model, option, index);
109 122 }
110 123
111 124
112 125 return QStyledItemDelegate::editorEvent(event, model, option, index);
113 126 }
114 127 };
115 128
116 129 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
117 130 : QWidget{parent},
118 131 ui{new Ui::VariableInspectorWidget},
119 132 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
120 133 {
121 134 ui->setupUi(this);
122 135
123 136 // Sets model for table
124 137 // auto sortFilterModel = new QSortFilterProxyModel{this};
125 138 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
126 139
127 140 auto variableModel = sqpApp->variableController().variableModel();
128 141 ui->tableView->setModel(variableModel);
129 142
130 143 // Adds extra signal/slot between view and model, so the view can be updated instantly when
131 144 // there is a change of data in the model
132 145 connect(variableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
133 146 SLOT(refresh()));
134 147
135 148 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
136 149 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
137 150
138 151 // Fixes column sizes
139 152 auto model = ui->tableView->model();
140 153 const auto count = model->columnCount();
141 154 for (auto i = 0; i < count; ++i) {
142 155 ui->tableView->setColumnWidth(
143 156 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
144 157 }
145 158
146 159 // Sets selection options
147 160 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
148 161 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
149 162
150 163 // Connection to show a menu when right clicking on the tree
151 164 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 165 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 166 &VariableInspectorWidget::onTableMenuRequested);
154 167 }
155 168
156 169 VariableInspectorWidget::~VariableInspectorWidget()
157 170 {
158 171 delete ui;
159 172 }
160 173
161 174 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
162 175 {
163 176 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
164 177
165 178 // Gets the model to retrieve the underlying selected variables
166 179 auto model = sqpApp->variableController().variableModel();
167 180 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
168 181 for (const auto &selectedRow : qAsConst(selectedRows)) {
169 182 if (auto selectedVariable = model->variable(selectedRow.row())) {
170 183 selectedVariables.push_back(selectedVariable);
171 184 }
172 185 }
173 186
174 187 QMenu tableMenu{};
175 188
176 189 // Emits a signal so that potential receivers can populate the menu before displaying it
177 190 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
178 191
179 192 // Adds menu-specific actions
180 193 if (!selectedVariables.isEmpty()) {
181 194 tableMenu.addSeparator();
182 195
183 196 // 'Rename' and 'Duplicate' actions (only if one variable selected)
184 197 if (selectedVariables.size() == 1) {
185 198 auto selectedVariable = selectedVariables.front();
186 199
187 200 auto duplicateFun = [varW = std::weak_ptr<Variable>(selectedVariable)]()
188 201 {
189 202 if (auto var = varW.lock()) {
190 203 sqpApp->variableController().cloneVariable(var);
191 204 }
192 205 };
193 206
194 207 tableMenu.addAction(tr("Duplicate"), duplicateFun);
195 208
196 209 auto renameFun = [ varW = std::weak_ptr<Variable>(selectedVariable), &model, this ]()
197 210 {
198 211 if (auto var = varW.lock()) {
199 212 // Generates forbidden names (names associated to existing variables)
200 213 auto allVariables = model->variables();
201 214 auto forbiddenNames = QVector<QString>(allVariables.size());
202 215 std::transform(allVariables.cbegin(), allVariables.cend(),
203 216 forbiddenNames.begin(),
204 217 [](const auto &variable) { return variable->name(); });
205 218
206 219 RenameVariableDialog dialog{var->name(), forbiddenNames, this};
207 220 if (dialog.exec() == QDialog::Accepted) {
208 221 var->setName(dialog.name());
209 222 }
210 223 }
211 224 };
212 225
213 226 tableMenu.addAction(tr("Rename..."), renameFun);
214 227 }
215 228
216 229 // 'Delete' action
217 230 auto deleteFun = [&selectedVariables]() {
218 231 sqpApp->variableController().deleteVariables(selectedVariables);
219 232 };
220 233
221 234 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
222 235 }
223 236
224 237 if (!tableMenu.isEmpty()) {
225 238 // Generates menu header (inserted before first action)
226 239 auto firstAction = tableMenu.actions().first();
227 240 auto headerAction = new QWidgetAction{&tableMenu};
228 241 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
229 242 tableMenu.insertAction(firstAction, headerAction);
230 243
231 244 // Displays menu
232 245 tableMenu.exec(QCursor::pos());
233 246 }
234 247 }
235 248
236 249 void VariableInspectorWidget::refresh() noexcept
237 250 {
238 251 ui->tableView->viewport()->update();
239 252 }
General Comments 0
You need to be logged in to leave comments. Login now