curvelist_panel.cpp
Go to the documentation of this file.
1 #include "curvelist_panel.h"
2 #include "ui_curvelist_panel.h"
4 #include <QDebug>
5 #include <QLayoutItem>
6 #include <QMenu>
7 #include <QSettings>
8 #include <QDrag>
9 #include <QMimeData>
10 #include <QHeaderView>
11 #include <QFontDatabase>
12 #include <QMessageBox>
13 #include <QApplication>
14 #include <QPainter>
15 #include <QCompleter>
16 #include <QStandardItem>
17 #include <QWheelEvent>
18 #include <QItemSelectionModel>
19 
20 class SortedTableItem: public QStandardItem
21 {
22 
23 public:
24  SortedTableItem(const QString& name): QStandardItem(name), str(name.toStdString()) {}
25 
26  bool operator< (const SortedTableItem &other) const
27  {
28  return doj::alphanum_impl(this->str.c_str(),
29  other.str.c_str()) < 0;
30  }
31 private:
32  std::string str;
33 };
34 
35 
36 //-------------------------------------------------
37 
39  QWidget *parent) :
40  QWidget(parent),
41  ui(new Ui::CurveListPanel),
42  _completer( new TreeModelCompleter(this) ),
43  _custom_plots(mapped_math_plots),
44  _point_size(9)
45 {
46  ui->setupUi(this);
47  ui->tableView->viewport()->installEventFilter( this );
48 
49  _model = new QStandardItemModel(0, 2, this);
50 
51  for(auto table_view: {ui->tableView, ui->tableViewCustom})
52  {
53  table_view->viewport()->installEventFilter( this );
54  table_view->setModel( _model );
55  table_view->horizontalHeader()->setStretchLastSection (true);
56  table_view->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
57  }
58 
59  ui->widgetOptions->setVisible(false);
60 
61  ui->radioRegExp->setAutoExclusive(true);
62  ui->radioContains->setAutoExclusive(true);
63  ui->radioPrefix->setAutoExclusive(true);
64 
65  _completer->setCompletionMode( QCompleter::PopupCompletion );
66 
67  QSettings settings;
68 
69  QString active_filter = settings.value("FilterableListWidget.searchFilter").toString();
70  if( active_filter == "radioRegExp"){
71 
72  ui->radioRegExp->setChecked(true);
73  }
74  else if( active_filter == "radioPrefix"){
75 
76  ui->radioPrefix->setChecked(true);
77  }
78  else if( active_filter == "radioContains"){
79 
80  ui->radioContains->setChecked(true);
81  }
82 
83  _point_size = settings.value("FilterableListWidget/table_point_size", 9).toInt();
84 
85  _completer_need_update = ui->radioPrefix->isChecked();
86  ui->lineEdit->setCompleter( _completer_need_update ? _completer : nullptr );
87 
88  ui->splitter->setStretchFactor(0,5);
89  ui->splitter->setStretchFactor(1,1);
90 
91  connect( ui->tableViewCustom->selectionModel(), &QItemSelectionModel::selectionChanged,
93 }
94 
96 {
97  delete ui;
98 }
99 
101 {
102  return _model->rowCount();
103 }
104 
106 {
107  _model->setRowCount(0);
108  _completer->clear();
109  ui->labelNumberDisplayed->setText( "0 of 0");
110 }
111 
112 void CurveListPanel::addItem(const QString &item_name)
113 {
114  if( _model->findItems(item_name).size() > 0)
115  {
116  return;
117  }
118 
119  auto item = new SortedTableItem(item_name);
120  QFont font = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
121  font.setPointSize(_point_size);
122  item->setFont(font);
123  const int row = rowCount();
124  _model->setRowCount(row+1);
125  _model->setItem(row, 0, item);
126 
127  auto val_cell = new QStandardItem("-");
128  val_cell->setTextAlignment(Qt::AlignRight);
129  val_cell->setFlags( Qt::NoItemFlags | Qt::ItemIsEnabled );
130  font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
131  font.setPointSize( _point_size );
132  val_cell->setFont( font );
133  val_cell->setFlags(Qt::NoItemFlags);
134 
135  _model->setItem(row, 1, val_cell );
136 
138  {
139  _completer->addToCompletionTree(item_name);
140  }
141 }
142 
144 {
145  ui->tableView->sortByColumn(0,Qt::AscendingOrder);
146  ui->tableViewCustom->sortByColumn(0,Qt::AscendingOrder);
147 
148  ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
149  ui->tableViewCustom->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
150 
151  updateFilter();
152 }
153 
154 
155 int CurveListPanel::findRowByName(const std::string &text) const
156 {
157  auto item_list = _model->findItems( QString::fromStdString( text ), Qt::MatchExactly);
158  if( item_list.isEmpty())
159  {
160  return -1;
161  }
162  if( item_list.count()>1)
163  {
164  qDebug() << "FilterableListWidget constins multiple rows with the same name";
165  return -1;
166  }
167  return item_list.front()->row();
168 }
169 
170 
172 {
173  on_lineEdit_textChanged( ui->lineEdit->text() );
174 }
175 
176 void CurveListPanel::keyPressEvent(QKeyEvent *event)
177 {
178  if( event->key() == Qt::Key_Delete){
180  }
181 }
182 
183 bool CurveListPanel::eventFilter(QObject *object, QEvent *event)
184 {
185  auto obj = object;
186  while ( obj && obj != ui->tableView && obj != ui->tableViewCustom )
187  {
188  obj = obj->parent();
189  }
190 
191  //Ignore obj different than tableViews
192  if(!obj)
193  {
194  return QWidget::eventFilter(object,event);
195  }
196 
197  bool shift_modifier_pressed = (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier);
198  bool ctrl_modifier_pressed = (QGuiApplication::keyboardModifiers() == Qt::ControlModifier);
199 
200  if(event->type() == QEvent::MouseButtonPress)
201  {
202  QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
203 
204  _dragging = false;
205  _drag_start_pos = mouse_event->pos();
206 
207  if( !shift_modifier_pressed && !ctrl_modifier_pressed )
208  {
209  if( obj == ui->tableView)
210  {
211  ui->tableViewCustom->clearSelection() ;
212  }
213  if( obj == ui->tableViewCustom)
214  {
215  ui->tableView->clearSelection() ;
216  }
217  }
218 
219  if(mouse_event->button() == Qt::LeftButton )
220  {
221  _newX_modifier = false;
222  }
223  else if(mouse_event->button() == Qt::RightButton )
224  {
225  _newX_modifier = true;
226  }
227  else {
228  return false;
229  }
230  return QWidget::eventFilter(object,event);
231  }
232  else if(event->type() == QEvent::MouseMove)
233  {
234  QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
235  double distance_from_click = (mouse_event->pos() - _drag_start_pos).manhattanLength();
236 
237  if ((mouse_event->buttons() == Qt::LeftButton ||
238  mouse_event->buttons() == Qt::RightButton) &&
239  distance_from_click >= QApplication::startDragDistance() &&
240  !_dragging)
241  {
242  _dragging = true;
243  QDrag *drag = new QDrag(this);
244  QMimeData *mimeData = new QMimeData;
245 
246  QByteArray mdata;
247  QDataStream stream(&mdata, QIODevice::WriteOnly);
248 
249  for(const auto& curve_name: getNonHiddenSelectedRows())
250  {
251  stream << QString::fromStdString(curve_name);
252  }
253 
254  if( !_newX_modifier )
255  {
256  mimeData->setData("curveslist/add_curve", mdata);
257  }
258  else
259  {
260  if(getNonHiddenSelectedRows().size() != 1)
261  {
262  return false;
263  }
264  mimeData->setData("curveslist/new_X_axis", mdata);
265 
266  QPixmap cursor( QSize(160,30) );
267  cursor.fill(Qt::transparent);
268 
269  QPainter painter;
270  painter.begin( &cursor);
271  painter.setPen(QColor(22, 22, 22));
272 
273  QString text("set as new X axis");
274  painter.setFont( QFont("Arial", 14 ) );
275 
276  painter.setBackground(Qt::transparent);
277  painter.drawText( QRect(0, 0, 160, 30), Qt::AlignHCenter | Qt::AlignVCenter, text );
278  painter.end();
279 
280  drag->setDragCursor(cursor, Qt::MoveAction);
281  }
282 
283  drag->setMimeData(mimeData);
284  drag->exec(Qt::CopyAction | Qt::MoveAction);
285  }
286  return true;
287  }
288  else if(event->type() == QEvent::Wheel)
289  {
290  QWheelEvent *wheel_event = dynamic_cast<QWheelEvent*>(event);
291  int prev_size = _point_size;
292  if( ctrl_modifier_pressed )
293  {
294  if( _point_size > 6 && wheel_event->delta() < 0 )
295  {
296  _point_size--;
297  }
298  else if( _point_size < 14 && wheel_event->delta() > 0 )
299  {
300  _point_size++;
301  }
302  if( _point_size != prev_size)
303  {
304  auto horizontal = ui->tableView->horizontalHeader();
305  horizontal->setSectionResizeMode(0, QHeaderView::Fixed);
306  horizontal->setSectionResizeMode(1, QHeaderView::Fixed);
307 
308  auto vertical = ui->tableView->verticalHeader();
309  vertical->setSectionResizeMode(0, QHeaderView::Fixed);
310  vertical->setSectionResizeMode(1, QHeaderView::Fixed);
311 
312  for (int row=0; row< rowCount(); row++)
313  {
314  for (int col=0; col< 2; col++)
315  {
316  auto item = _model->item( row, col );
317  auto font = item->font();
318  font.setPointSize( _point_size );
319  item->setFont( font );
320  }
321  }
322 
323  horizontal->setSectionResizeMode(0, QHeaderView::ResizeToContents);
324  horizontal->setSectionResizeMode(1, QHeaderView::Stretch);
325  vertical->setSectionResizeMode(0, QHeaderView::ResizeToContents);
326  vertical->setSectionResizeMode(1, QHeaderView::ResizeToContents);
327 
328  QSettings settings;
329  settings.setValue("FilterableListWidget/table_point_size", _point_size);
330  }
331  return true;
332  }
333  }
334 
335  return QWidget::eventFilter(object,event);
336 }
337 
339 {
340  std::vector<std::string> non_hidden_list;
341 
342  for(auto table_view: {ui->tableView, ui->tableViewCustom})
343  {
344  for (const auto &selected_index : table_view->selectionModel()->selectedRows(0))
345  {
346  if (!table_view->isRowHidden(selected_index.row()))
347  {
348  auto item = _model->item( selected_index.row(), 0 );
349  non_hidden_list.push_back(item->text().toStdString());
350  }
351  }
352  }
353  return non_hidden_list;
354 }
355 
356 QTableView *CurveListPanel::getTableView() const
357 {
358  return ui->tableView;
359 }
360 
361 QTableView *CurveListPanel::getCustomView() const
362 {
363  return ui->tableViewCustom;
364 }
365 
367 {
368  if(checked) {
369  updateFilter();
370  ui->lineEdit->setCompleter( nullptr );
371  QSettings settings;
372  settings.setValue("FilterableListWidget.searchFilter", "radioContains");
373  }
374 }
375 
377 {
378  if(checked) {
379  updateFilter();
380  ui->lineEdit->setCompleter( nullptr );
381  QSettings settings;
382  settings.setValue("FilterableListWidget.searchFilter", "radioRegExp");
383  }
384 }
385 
387 {
388  _completer_need_update = checked;
389 
390  if( checked )
391  {
392  _completer->clear();
393  for (int row=0; row< rowCount(); row++)
394  {
395  auto item = _model->item(row,0);
396  _completer->addToCompletionTree(item->text());
397  }
398 
399  updateFilter();
400  ui->lineEdit->setCompleter( _completer );
401  QSettings settings;
402  settings.setValue("FilterableListWidget.searchFilter", "radioPrefix");
403  }
404 }
405 
407 {
408  updateFilter();
409 }
410 
411 void CurveListPanel::on_lineEdit_textChanged(const QString &search_string)
412 {
413  int item_count = rowCount();
414  int visible_count = 0;
415  bool updated = false;
416 
417  Qt::CaseSensitivity cs = Qt::CaseInsensitive;
418  if( ui->checkBoxCaseSensitive->isChecked())
419  {
420  cs = Qt::CaseSensitive;
421  }
422  QRegExp regexp( search_string, cs, QRegExp::Wildcard );
423  QRegExpValidator v(regexp, nullptr);
424 
425  QStringList spaced_items = search_string.split(' ');
426 
427  for (int row=0; row < rowCount(); row++)
428  {
429  auto item = _model->item(row,0);
430  QString name = item->text();
431  int pos = 0;
432  bool toHide = false;
433 
434  if( search_string.isEmpty() == false )
435  {
436  if( ui->radioRegExp->isChecked())
437  {
438  toHide = v.validate( name, pos ) != QValidator::Acceptable;
439  }
440  else if( ui->radioPrefix->isChecked())
441  {
442  toHide = !name.startsWith( search_string, cs ) ;
443  }
444  else if( ui->radioContains->isChecked())
445  {
446  for (const auto& item: spaced_items)
447  {
448  if( name.contains(item, cs) == false )
449  {
450  toHide = true;
451  break;
452  }
453  }
454  }
455  }
456  if( !toHide ) visible_count++;
457 
458  if( toHide != ui->tableView->isRowHidden(row) ) updated = true;
459 
460  const auto name_std = name.toStdString();
461  const bool is_custom_plot = _custom_plots.count(name_std) > 0;
462 
463 
464  ui->tableView->setRowHidden(row, toHide || is_custom_plot );
465  ui->tableViewCustom->setRowHidden(row, toHide || !is_custom_plot );
466  }
467  ui->labelNumberDisplayed->setText( QString::number( visible_count ) + QString(" of ") +
468  QString::number( item_count ) );
469 
470  if(updated){
471  emit hiddenItemsChanged();
472  }
473 }
474 
476 {
477  ui->widgetOptions->setVisible(checked);
478 }
479 
481 {
482  for(auto table_view: {ui->tableView, ui->tableViewCustom})
483  {
484  if(checked){
485  table_view->hideColumn(1);
486  }
487  else{
488  table_view->showColumn(1);
489  }
490  }
491  emit hiddenItemsChanged();
492 }
493 
495 {
496  QMessageBox::StandardButton reply;
497  reply = QMessageBox::question(nullptr, tr("Warning"),
498  tr("Do you really want to remove these data?\n"),
499  QMessageBox::Yes | QMessageBox::No,
500  QMessageBox::No );
501 
502  if (reply == QMessageBox::Yes)
503  {
505  }
506 
507  // rebuild the tree model
509  {
510  _completer->clear();
511  for (int row=0; row< rowCount(); row++)
512  {
513  auto item = _model->item(row);
514  _completer->addToCompletionTree(item->text());
515  }
516  }
517 
518  updateFilter();
519 }
520 
522 {
523  _model->removeRow(row);
524 }
525 
527 {
528  auto curve_names = getNonHiddenSelectedRows();
529  if( curve_names.empty() )
530  {
531  emit createMathPlot("");
532  }
533  else
534  {
535  createMathPlot( curve_names.front() );
536  }
537  on_lineEdit_textChanged( ui->lineEdit->text() );
538 }
539 
540 //void FilterableListWidget::on_buttonRefreshAll_clicked()
541 //{
542 // for(auto& it: _mapped_math_plots)
543 // {
544 // emit refreshMathPlot( it.second->name() );
545 // }
546 //}
547 
548 void CurveListPanel::onCustomSelectionChanged(const QItemSelection&, const QItemSelection &)
549 {
550  int selected_items = 0;
551 
552  for (const auto &index : ui->tableViewCustom->selectionModel()->selectedRows(0))
553  {
554  if (! ui->tableViewCustom->isRowHidden(index.row()) )
555  {
556  selected_items++;
557  }
558  }
559 
560  bool enabled = selected_items == 1;
561  ui->buttonEditCustom->setEnabled( enabled );
562  ui->buttonEditCustom->setToolTip( enabled ? "Edit the selected custom timeserie" :
563  "Select a single custom Timeserie to Edit it");
564 }
565 
567 {
568  int selected_count = 0;
569  QModelIndex selected_index;
570  auto table_view = ui->tableViewCustom;
571 
572  for (QModelIndex index : table_view->selectionModel()->selectedRows(0))
573  {
574  if (!table_view->isRowHidden( index.row()) )
575  {
576  selected_count++;
577  selected_index = index;
578  }
579  }
580  if( selected_count != 1)
581  {
582  return;
583  }
584 
585  auto item = _model->item( selected_index.row(), 0 );
586  editMathPlot( item->text().toStdString() );
587 }
588 
590 {
591  ui->tableViewCustom->clearSelection();
592  ui->tableView->clearSelection();
593 }
int v
void addItem(const QString &item_name)
int findRowByName(const std::string &text) const
void on_radioRegExp_toggled(bool checked)
void onCustomSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void removeRow(int row)
void editMathPlot(const std::string &plot_name)
void on_radioContains_toggled(bool checked)
void addToCompletionTree(const QString &name)
TreeModelCompleter * _completer
bool eventFilter(QObject *object, QEvent *event) override
std::vector< std::string > getNonHiddenSelectedRows()
QTableView * getTableView() const
void createMathPlot(const std::string &linked_plot)
SortedTableItem(const QString &name)
void deleteCurves(const std::vector< std::string > &curve_names)
virtual void keyPressEvent(QKeyEvent *event) override
Ui::CurveListPanel * ui
CurveListPanel(const CustomPlotMap &mapped_math_plots, QWidget *parent)
char name[1]
std::unordered_map< std::string, CustomPlotPtr > CustomPlotMap
~CurveListPanel() override
QPoint _drag_start_pos
void on_pushButtonSettings_toggled(bool checked)
uintptr_t size
void on_radioPrefix_toggled(bool checked)
void on_buttonEditCustom_clicked()
const CustomPlotMap & _custom_plots
void hiddenItemsChanged()
QStandardItemModel * _model
int rowCount() const
QTableView * getCustomView() const
void on_checkBoxHideSecondColumn_toggled(bool checked)
void on_lineEdit_textChanged(const QString &search_string)
bool operator<(const SortedTableItem &other) const
void on_checkBoxCaseSensitive_toggled(bool checked)
void on_buttonAddCustom_clicked()


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17