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 <QFormLayout>
38 #include <QGroupBox>
39 #include <QHBoxLayout>
40 #include <QHeaderView>
41 #include <QLabel>
42 #include <QLineEdit>
43 #include <QMessageBox>
44 #include <QPushButton>
45 #include <QString>
46 #include <QTableWidget>
47 #include <QVBoxLayout>
48 #include "double_list_widget.h"
49 
50 namespace moveit_setup_assistant
51 {
52 // ******************************************************************************************
53 //
54 // ******************************************************************************************
55 DoubleListWidget::DoubleListWidget(QWidget* parent, const MoveItConfigDataPtr& config_data, const QString& long_name,
56  const QString& short_name, bool add_ok_cancel)
57  : QWidget(parent), long_name_(long_name), short_name_(short_name), config_data_(config_data)
58 {
59  // Basic widget container
60  QVBoxLayout* layout = new QVBoxLayout();
61 
62  // Label ------------------------------------------------
63  title_ = new QLabel("", this); // specify the title from the parent widget
64  QFont group_title_font(QFont().defaultFamily(), 12, QFont::Bold);
65  title_->setFont(group_title_font);
66  layout->addWidget(title_);
67 
68  // Double selection lists -------------------------------
69  QHBoxLayout* hlayout = new QHBoxLayout();
70 
71  // Left column -------------------------------------------
72  QVBoxLayout* column1 = new QVBoxLayout();
73 
74  // Label
75  column1_label_ = new QLabel(QString("Available ").append(short_name_).append('s'), this);
76  column1->addWidget(column1_label_);
77 
78  // Table
79  data_table_ = new QTableWidget(this);
80  data_table_->setColumnCount(1);
81  data_table_->setSortingEnabled(true);
82  column1->addWidget(data_table_);
83  connect(data_table_->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
84  SLOT(previewSelectedLeft(QItemSelection, QItemSelection)));
85 
86  // Table headers
87  QStringList data_header_list;
88  data_header_list.append(QString(" Names").prepend(short_name_));
89  data_table_->setHorizontalHeaderLabels(data_header_list);
90  data_table_->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);
91 
92  // Add layouts
93  hlayout->addLayout(column1);
94 
95  // Center column ------------------------------------------
96  QVBoxLayout* column2 = new QVBoxLayout();
97  column2->setSizeConstraint(QLayout::SetFixedSize); // constraint it
98 
99  // Right Arrow Button
100  QPushButton* btn_right = new QPushButton(">", this);
101  btn_right->setMaximumSize(25, 80);
102  connect(btn_right, SIGNAL(clicked()), this, SLOT(selectDataButtonClicked()));
103  column2->addWidget(btn_right);
104 
105  // Left Arrow Button
106  QPushButton* btn_left = new QPushButton("<", this);
107  btn_left->setMaximumSize(25, 80);
108  connect(btn_left, SIGNAL(clicked()), this, SLOT(deselectDataButtonClicked()));
109  column2->addWidget(btn_left);
110 
111  // Add layouts
112  hlayout->addLayout(column2);
113 
114  // Right column -------------------------------------------
115  QVBoxLayout* column3 = new QVBoxLayout();
116 
117  // Label
118  column2_label_ = new QLabel(QString("Selected ").append(short_name_).append("s"), this);
119  column3->addWidget(column2_label_);
120 
121  // Table
122  selected_data_table_ = new QTableWidget(this);
123  selected_data_table_->setColumnCount(1);
124  selected_data_table_->setSortingEnabled(true);
125  column3->addWidget(selected_data_table_);
126  connect(selected_data_table_->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
127  SLOT(previewSelectedRight(QItemSelection, QItemSelection)));
128 
129  // Table Headers (use same)
130  selected_data_table_->setHorizontalHeaderLabels(data_header_list);
131 
132  // Add layouts
133  hlayout->addLayout(column3);
134 
135  // End Double Selection List ---------------------------------
136  layout->addLayout(hlayout);
137 
138  if (add_ok_cancel)
139  {
140  // Button controls -------------------------------------------
141  QHBoxLayout* controls_layout = new QHBoxLayout();
142  controls_layout->setContentsMargins(0, 25, 0, 15);
143 
144  // Spacer
145  controls_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
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 (const std::string& item : items)
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 (item == "ASSUMED_FIXED_ROOT_JOINT")
221  continue;
222 
223  // Create row elements
224  QTableWidgetItem* data_name = new QTableWidgetItem(item.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 (QTableWidgetItem* item : selected)
251  {
252  std::string name = item->text().toStdString();
253  bool already_exists = false;
254  int row_to_add = 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  already_exists = true;
264  break;
265  }
266  row_to_add = r + 1;
267  }
268 
269  // This joint needs to be added to the selected joint table
270  if (!already_exists)
271  {
272  selected_data_table_->setRowCount(selected_data_table_->rowCount() + 1);
273  QTableWidgetItem* new_item = new QTableWidgetItem(name.c_str());
274  new_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
275  selected_data_table_->setItem(row_to_add, 0, new_item);
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 (QTableWidgetItem* item : deselected)
292  {
293  selected_data_table_->removeRow(item->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.empty())
324  return;
325 
326  std::vector<std::string> selected_vector;
327 
328  // Convert QList to std vector
329  selected_vector.reserve(selected.size());
330  for (QTableWidgetItem* item : selected)
331  selected_vector.emplace_back(item->text().toStdString());
332 
333  // Send to shared function
334  Q_EMIT(previewSelected(selected_vector));
335 }
336 
337 } // namespace moveit_setup_assistant
moveit_setup_assistant::DoubleListWidget::DoubleListWidget
DoubleListWidget(QWidget *parent, const MoveItConfigDataPtr &config_data, const QString &long_name, const QString &short_name, bool add_ok_cancel=true)
Constructor.
Definition: double_list_widget.cpp:87
moveit_setup_assistant::DoubleListWidget::selectDataButtonClicked
void selectDataButtonClicked()
Move selected data right.
Definition: double_list_widget.cpp:276
moveit_setup_assistant::DoubleListWidget::setSelected
void setSelected(const std::vector< std::string > &items)
Set the right box.
Definition: double_list_widget.cpp:216
moveit_setup_assistant::DoubleListWidget::data_table_
QTableWidget * data_table_
Definition: double_list_widget.h:85
double_list_widget.h
moveit_setup_assistant::DoubleListWidget::selected_data_table_
QTableWidget * selected_data_table_
Definition: double_list_widget.h:86
r
r
moveit_setup_assistant::DoubleListWidget::previewSelectedLeft
void previewSelectedLeft(const QItemSelection &selected, const QItemSelection &deselected)
Event when data table is clicked.
Definition: double_list_widget.cpp:334
moveit_setup_assistant::DoubleListWidget::column2_label_
QLabel * column2_label_
Definition: double_list_widget.h:89
moveit_setup_assistant::DoubleListWidget::selectionUpdated
void selectionUpdated()
When the set of selected items has changed.
moveit_setup_assistant::DoubleListWidget::setColumnNames
void setColumnNames(const QString &col1, const QString &col2)
Set the names of the two columns in the widget.
Definition: double_list_widget.cpp:227
name
name
moveit_setup_assistant::DoubleListWidget::setAvailable
void setAvailable(const std::vector< std::string > &items)
Loads the availble data list.
Definition: double_list_widget.cpp:204
moveit_setup_assistant
Definition: compute_default_collisions.h:46
moveit_setup_assistant::DoubleListWidget::previewSelected
void previewSelected(std::vector< std::string >)
Signal to highlight parts of robot.
append
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
moveit_setup_assistant::DoubleListWidget::setTable
void setTable(const std::vector< std::string > &items, QTableWidget *table)
Convenience function for reusing set table code.
Definition: double_list_widget.cpp:236
moveit_setup_assistant::DoubleListWidget::clearContents
void clearContents()
Definition: double_list_widget.cpp:221
moveit_setup_assistant::DoubleListWidget::previewSelectedRight
void previewSelectedRight(const QItemSelection &selected, const QItemSelection &deselected)
Definition: double_list_widget.cpp:343
moveit_setup_assistant::DoubleListWidget::deselectDataButtonClicked
void deselectDataButtonClicked()
Move selected data left.
Definition: double_list_widget.cpp:317
moveit_setup_assistant::DoubleListWidget::column1_label_
QLabel * column1_label_
Definition: double_list_widget.h:88


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Sat May 3 2025 02:28:04