double_list_widget.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Dave Coleman */
36 
37 #include <QVBoxLayout>
38 #include <QHBoxLayout>
39 #include <QGroupBox>
40 #include <QPushButton>
41 #include <QFormLayout>
42 #include <QLineEdit>
43 #include <QMessageBox>
44 #include <QString>
45 #include <QHeaderView>
46 #include "double_list_widget.h"
47 
48 namespace moveit_setup_assistant
49 {
50 // ******************************************************************************************
51 //
52 // ******************************************************************************************
53 DoubleListWidget::DoubleListWidget(QWidget* parent, moveit_setup_assistant::MoveItConfigDataPtr config_data,
54  QString long_name, QString short_name, bool add_ok_cancel)
55  : QWidget(parent), long_name_(long_name), short_name_(short_name), config_data_(config_data)
56 {
57  // Basic widget container
58  QVBoxLayout* layout = new QVBoxLayout();
59 
60  // Label ------------------------------------------------
61  title_ = new QLabel("", this); // specify the title from the parent widget
62  QFont group_title_font(QFont().defaultFamily(), 12, QFont::Bold);
63  title_->setFont(group_title_font);
64  layout->addWidget(title_);
65 
66  // Double selection lists -------------------------------
67  QHBoxLayout* hlayout = new QHBoxLayout();
68 
69  // Left column -------------------------------------------
70  QVBoxLayout* column1 = new QVBoxLayout();
71 
72  // Label
73  column1_label_ = new QLabel(QString("Available ").append(short_name_).append('s'), this);
74  column1->addWidget(column1_label_);
75 
76  // Table
77  data_table_ = new QTableWidget(this);
78  data_table_->setColumnCount(1);
79  data_table_->setSortingEnabled(true);
80  column1->addWidget(data_table_);
81  connect(data_table_->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
82  SLOT(previewSelectedLeft(QItemSelection, QItemSelection)));
83 
84  // Table headers
85  QStringList data_header_list;
86  data_header_list.append(QString(" Names").prepend(short_name_));
87  data_table_->setHorizontalHeaderLabels(data_header_list);
88  data_table_->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);
89 
90  // Add layouts
91  hlayout->addLayout(column1);
92 
93  // Center column ------------------------------------------
94  QVBoxLayout* column2 = new QVBoxLayout();
95  column2->setSizeConstraint(QLayout::SetFixedSize); // constraint it
96 
97  // Right Arrow Button
98  QPushButton* btn_right = new QPushButton(">", this);
99  btn_right->setMaximumSize(25, 80);
100  connect(btn_right, SIGNAL(clicked()), this, SLOT(selectDataButtonClicked()));
101  column2->addWidget(btn_right);
102 
103  // Left Arrow Button
104  QPushButton* btn_left = new QPushButton("<", this);
105  btn_left->setMaximumSize(25, 80);
106  connect(btn_left, SIGNAL(clicked()), this, SLOT(deselectDataButtonClicked()));
107  column2->addWidget(btn_left);
108 
109  // Add layouts
110  hlayout->addLayout(column2);
111 
112  // Right column -------------------------------------------
113  QVBoxLayout* column3 = new QVBoxLayout();
114 
115  // Label
116  column2_label_ = new QLabel(QString("Selected ").append(short_name_).append("s"), this);
117  column3->addWidget(column2_label_);
118 
119  // Table
120  selected_data_table_ = new QTableWidget(this);
121  selected_data_table_->setColumnCount(1);
122  selected_data_table_->setSortingEnabled(true);
123  column3->addWidget(selected_data_table_);
124  connect(selected_data_table_->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
125  SLOT(previewSelectedRight(QItemSelection, QItemSelection)));
126 
127  // Table Headers (use same)
128  selected_data_table_->setHorizontalHeaderLabels(data_header_list);
129 
130  // Add layouts
131  hlayout->addLayout(column3);
132 
133  // End Double Selection List ---------------------------------
134  layout->addLayout(hlayout);
135 
136  if (add_ok_cancel)
137  {
138  // Button controls -------------------------------------------
139  QHBoxLayout* controls_layout = new QHBoxLayout();
140  controls_layout->setContentsMargins(0, 25, 0, 15);
141 
142  // Spacer
143  QWidget* spacer = new QWidget(this);
144  spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
145  controls_layout->addWidget(spacer);
146 
147  // Save
148  QPushButton* btn_save = new QPushButton("&Save", this);
149  // btn_save->setMaximumWidth( 200 );
150  connect(btn_save, SIGNAL(clicked()), this, SIGNAL(doneEditing()));
151  controls_layout->addWidget(btn_save);
152  controls_layout->setAlignment(btn_save, Qt::AlignRight);
153 
154  // Cancel
155  QPushButton* btn_cancel = new QPushButton("&Cancel", this);
156  // btn_cancel->setMaximumWidth( 200 );
157  connect(btn_cancel, SIGNAL(clicked()), this, SIGNAL(cancelEditing()));
158  controls_layout->addWidget(btn_cancel);
159  controls_layout->setAlignment(btn_cancel, Qt::AlignRight);
160 
161  // Add layout
162  layout->addLayout(controls_layout);
163  }
164 
165  // Finish Layout --------------------------------------------------
166  this->setLayout(layout);
167 }
168 
169 // ******************************************************************************************
170 // Set the left box
171 // ******************************************************************************************
172 void DoubleListWidget::setAvailable(const std::vector<std::string>& items)
173 {
174  setTable(items, data_table_);
175 
176  // Resize both tables
177  data_table_->resizeColumnToContents(0);
178  selected_data_table_->setColumnWidth(0, data_table_->columnWidth(0));
179 }
180 
181 // ******************************************************************************************
182 // Set the right box
183 // ******************************************************************************************
184 void DoubleListWidget::setSelected(const std::vector<std::string>& items)
185 {
187 }
188 
190 {
191  selected_data_table_->clearContents();
192  data_table_->clearContents();
193 }
194 
195 void DoubleListWidget::setColumnNames(const QString& col1, const QString& col2)
196 {
197  column1_label_->setText(col1);
198  column2_label_->setText(col2);
199 }
200 
201 // ******************************************************************************************
202 // Convenience function for reusing set table code
203 // ******************************************************************************************
204 void DoubleListWidget::setTable(const std::vector<std::string>& items, QTableWidget* table)
205 {
206  // Disable Table
207  table->setUpdatesEnabled(false); // prevent table from updating until we are completely done
208  table->setDisabled(true); // make sure we disable it so that the cellChanged event is not called
209  table->clearContents();
210 
211  // Set size of datatable
212  table->setRowCount(items.size());
213 
214  // Loop through every item
215  int row = 0;
216  for (std::vector<std::string>::const_iterator data_it = items.begin(); data_it != items.end(); ++data_it)
217  {
218  // This is a hack to prevent a dummy joint from being added. Not really the best place to place this but
219  // here is computationally smart
220  if (*data_it == "ASSUMED_FIXED_ROOT_JOINT")
221  continue;
222 
223  // Create row elements
224  QTableWidgetItem* data_name = new QTableWidgetItem(data_it->c_str());
225  data_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
226 
227  // Add to table
228  table->setItem(row, 0, data_name);
229 
230  // Increment counter
231  ++row;
232  }
233 
234  table->setRowCount(row);
235 
236  // Reenable
237  table->setUpdatesEnabled(true); // prevent table from updating until we are completely done
238  table->setDisabled(false); // make sure we disable it so that the cellChanged event is not called
239 }
240 
241 // ******************************************************************************************
242 // Move selected data right
243 // ******************************************************************************************
245 {
246  // Get list of all selected items
247  QList<QTableWidgetItem*> selected = data_table_->selectedItems();
248 
249  // Loop through all selected items
250  for (int i = 0; i < selected.size(); i++)
251  {
252  std::string name = selected[i]->text().toStdString();
253  bool alreadyExists = false;
254  int rowToAdd = 0;
255 
256  // Check if this selected joint is already in the selected joint table
257  for (int r = 0; r < selected_data_table_->rowCount(); r++)
258  {
259  QTableWidgetItem* item = selected_data_table_->item(r, 0);
260 
261  if (item->text().toStdString() == name)
262  {
263  alreadyExists = true;
264  break;
265  }
266  rowToAdd = r + 1;
267  }
268 
269  // This joint needs to be added to the selected joint table
270  if (!alreadyExists)
271  {
272  selected_data_table_->setRowCount(selected_data_table_->rowCount() + 1);
273  QTableWidgetItem* newItem = new QTableWidgetItem(name.c_str());
274  newItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
275  selected_data_table_->setItem(rowToAdd, 0, newItem);
276  }
277  }
278 
279  Q_EMIT(selectionUpdated());
280 }
281 
282 // ******************************************************************************************
283 // Move selected data left
284 // ******************************************************************************************
286 {
287  // Get list of joints to be removed from selected list
288  QList<QTableWidgetItem*> deselected = selected_data_table_->selectedItems();
289 
290  // loop through deselect list and remove
291  for (int i = 0; i < deselected.size(); i++)
292  {
293  selected_data_table_->removeRow(deselected[i]->row());
294  }
295 
296  Q_EMIT(selectionUpdated());
297 }
298 
299 // ******************************************************************************************
300 // Highlight links of robot for left list
301 // ******************************************************************************************
302 void DoubleListWidget::previewSelectedLeft(const QItemSelection& selected, const QItemSelection& deselected)
303 {
304  const QList<QTableWidgetItem*> selected_items = data_table_->selectedItems();
305  previewSelected(selected_items);
306 }
307 
308 // ******************************************************************************************
309 // Highlight links of robot for right list
310 // ******************************************************************************************
311 void DoubleListWidget::previewSelectedRight(const QItemSelection& selected, const QItemSelection& deselected)
312 {
313  const QList<QTableWidgetItem*> selected_items = selected_data_table_->selectedItems();
314  previewSelected(selected_items);
315 }
316 
317 // ******************************************************************************************
318 // Highlight links of robot
319 // ******************************************************************************************
320 void DoubleListWidget::previewSelected(const QList<QTableWidgetItem*>& selected)
321 {
322  // Check that an element was selected
323  if (!selected.size())
324  return;
325 
326  std::vector<std::string> selected_vector;
327 
328  // Convert QList to std vector
329  for (int i = 0; i < selected.size(); ++i)
330  {
331  selected_vector.push_back(selected[i]->text().toStdString());
332  }
333 
334  // Send to shared function
335  Q_EMIT(previewSelected(selected_vector));
336 }
337 
338 } // namespace moveit_setup_assistant
void setSelected(const std::vector< std::string > &items)
Set the right box.
text
void deselectDataButtonClicked()
Move selected data left.
void setAvailable(const std::vector< std::string > &items)
Loads the availble data list.
void selectDataButtonClicked()
Move selected data right.
void doneEditing()
Event sent when this widget is done making data changes and parent widget can save.
void previewSelected(std::vector< std::string >)
Signal to highlight parts of robot.
void previewSelectedRight(const QItemSelection &selected, const QItemSelection &deselected)
DoubleListWidget(QWidget *parent, moveit_setup_assistant::MoveItConfigDataPtr config_data, QString long_name, QString short_name, bool add_ok_cancel=true)
Constructor.
void cancelEditing()
Event sent when user presses cancel button.
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
void setTable(const std::vector< std::string > &items, QTableWidget *table)
Convenience function for reusing set table code.
r
void selectionUpdated()
When the set of selected items has changed.
void setColumnNames(const QString &col1, const QString &col2)
Set the names of the two columns in the widget.
void previewSelectedLeft(const QItemSelection &selected, const QItemSelection &deselected)
Event when data table is clicked.


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Wed Jul 10 2019 04:04:34