Go to the documentation of this file.00001 #include <QFile>
00002 #include <QTextStream>
00003 #include <QSettings>
00004 #include <QFileInfo>
00005 #include <QDir>
00006 #include <QFileDialog>
00007 #include <QTableWidget>
00008 #include <QTableWidgetItem>
00009 #include <QHeaderView>
00010 #include <QDebug>
00011 #include <QMessageBox>
00012 #include <QAbstractItemView>
00013
00014 #include "dialog_select_ros_topics.h"
00015 #include "rule_editing.h"
00016 #include "ui_dialog_select_ros_topics.h"
00017
00018
00019 DialogSelectRosTopics::DialogSelectRosTopics(const std::vector<std::pair<QString, QString>>& topic_list,
00020 const Configuration &config,
00021 QWidget *parent) :
00022 QDialog(parent),
00023 ui(new Ui::dialogSelectRosTopics),
00024 _default_selected_topics(config.selected_topics),
00025 _select_all(QKeySequence(Qt::CTRL + Qt::Key_A), this),
00026 _deselect_all(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_A), this)
00027 {
00028
00029 auto flags = this->windowFlags();
00030 this->setWindowFlags( flags | Qt::WindowStaysOnTopHint);
00031
00032 ui->setupUi(this);
00033
00034 ui->checkBoxEnableRules->setChecked( config.use_renaming_rules );
00035 ui->spinBoxArraySize->setValue( config.max_array_size );
00036 ui->checkBoxTimestamp->setChecked( config.use_header_stamp );
00037
00038 if( config.discard_large_arrays )
00039 {
00040 ui->radioMaxDiscard->setChecked(true);
00041 }
00042 else{
00043 ui->radioMaxClamp->setChecked(true);
00044 }
00045
00046 QStringList labels;
00047 labels.push_back("Topic name");
00048 labels.push_back("Datatype");
00049
00050 ui->listRosTopics->setHorizontalHeaderLabels(labels);
00051 ui->listRosTopics->verticalHeader()->setVisible(false);
00052
00053 updateTopicList(topic_list);
00054
00055 if( ui->listRosTopics->rowCount() == 1)
00056 {
00057 ui->listRosTopics->selectRow(0);
00058 }
00059 ui->listRosTopics->setFocus();
00060
00061 _select_all.setContext(Qt::WindowShortcut);
00062 _deselect_all.setContext(Qt::WindowShortcut);
00063
00064 connect( &_select_all, &QShortcut::activated,
00065 ui->listRosTopics, &QAbstractItemView::selectAll );
00066
00067 connect( &_deselect_all, &QShortcut::activated,
00068 ui->listRosTopics, &QAbstractItemView::clearSelection );
00069
00070 on_spinBoxArraySize_valueChanged( ui->spinBoxArraySize->value() );
00071
00072 QSettings settings;
00073 restoreGeometry(settings.value("DialogSelectRosTopics.geometry").toByteArray());
00074
00075 }
00076
00077 void DialogSelectRosTopics::updateTopicList(std::vector<std::pair<QString, QString> > topic_list )
00078 {
00079 std::set<QString> newly_added;
00080
00081
00082 for (const auto& it: topic_list)
00083 {
00084 const QString& topic_name = it.first ;
00085 const QString& type_name = it.second ;
00086
00087 bool found = false;
00088 for(int r=0; r < ui->listRosTopics->rowCount(); r++ )
00089 {
00090 const QTableWidgetItem *item = ui->listRosTopics->item(r,0);
00091 if( item->text() == topic_name){
00092 found = true;
00093 break;
00094 }
00095 }
00096
00097 if( !found )
00098 {
00099 int new_row = ui->listRosTopics->rowCount();
00100 ui->listRosTopics->setRowCount( new_row+1 );
00101
00102
00103 ui->listRosTopics->setItem(new_row, 1, new QTableWidgetItem( type_name ));
00104 ui->listRosTopics->setItem(new_row, 0, new QTableWidgetItem( topic_name ));
00105 newly_added.insert(topic_name);
00106 }
00107 }
00108
00109 ui->listRosTopics->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
00110 ui->listRosTopics->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
00111 ui->listRosTopics->sortByColumn(0, Qt::AscendingOrder);
00112
00113
00114 QModelIndexList selection = ui->listRosTopics->selectionModel()->selectedRows();
00115
00116 for(int row=0; row < ui->listRosTopics->rowCount(); row++ )
00117 {
00118 const QTableWidgetItem *item = ui->listRosTopics->item(row,0);
00119 QString topic_name = item->text();
00120
00121 if(newly_added.count(topic_name) && _default_selected_topics.contains( topic_name ) )
00122 {
00123 bool selected = false;
00124 for (const auto& selected_item: selection)
00125 {
00126 if( selected_item.row() == row)
00127 {
00128 selected = true;
00129 break;
00130 }
00131 }
00132 if( !selected ){
00133 ui->listRosTopics->selectRow(row);
00134 }
00135 }
00136 }
00137
00138 }
00139
00140
00141 DialogSelectRosTopics::~DialogSelectRosTopics()
00142 {
00143 delete ui;
00144 }
00145
00146 DialogSelectRosTopics::Configuration DialogSelectRosTopics::getResult() const
00147 {
00148 Configuration config;
00149 config.selected_topics = _topic_list;
00150 config.max_array_size = ui->spinBoxArraySize->value();
00151 config.use_header_stamp = ui->checkBoxTimestamp->isChecked();
00152 config.discard_large_arrays = ui->radioMaxDiscard->isChecked();
00153 config.use_renaming_rules = ui->checkBoxEnableRules->isChecked();
00154 return config;
00155 }
00156
00157
00158 void DialogSelectRosTopics::on_buttonBox_accepted()
00159 {
00160 QModelIndexList selected_indexes = ui->listRosTopics->selectionModel()->selectedIndexes();
00161 QString selected_topics;
00162
00163 foreach(QModelIndex index, selected_indexes)
00164 {
00165 if(index.column() == 0){
00166 _topic_list.push_back( index.data(Qt::DisplayRole).toString() );
00167 selected_topics.append( _topic_list.back() ).append(" ");
00168 }
00169 }
00170 }
00171
00172 void DialogSelectRosTopics::on_listRosTopics_itemSelectionChanged()
00173 {
00174 QModelIndexList indexes = ui->listRosTopics->selectionModel()->selectedIndexes();
00175
00176 ui->buttonBox->setEnabled( indexes.size() > 0) ;
00177 }
00178
00179
00180 void DialogSelectRosTopics::on_checkBoxEnableRules_toggled(bool checked)
00181 {
00182 ui->pushButtonEditRules->setEnabled( checked );
00183 }
00184
00185 void DialogSelectRosTopics::on_pushButtonEditRules_pressed()
00186 {
00187 RuleEditing* rule_editing = new RuleEditing(this);
00188 rule_editing->exec();
00189 }
00190
00191 void DialogSelectRosTopics::closeEvent(QCloseEvent *event)
00192 {
00193 QSettings settings;
00194 settings.setValue("DialogSelectRosTopics.geometry", saveGeometry());
00195 }
00196
00197 nonstd::optional<double> FlatContainerContainHeaderStamp(const RosIntrospection::FlatMessage& flat_msg)
00198 {
00199 for (const auto& it: flat_msg.value)
00200 {
00201 if( it.second.getTypeID() != RosIntrospection::TIME)
00202 {
00203 continue;
00204 }
00205 const RosIntrospection::StringTreeNode* leaf1 = it.first.node_ptr;
00206 const RosIntrospection::StringTreeNode* leaf2 = leaf1->parent();
00207 if( leaf2 && leaf2->value() == "header" && leaf1->value() == "stamp")
00208 {
00209 return it.second.convert<double>();
00210 }
00211 }
00212 return nonstd::optional<double>();
00213 }
00214
00215 void DialogSelectRosTopics::on_maximumSizeHelp_pressed()
00216 {
00217 QMessageBox msgBox;
00218 msgBox.setWindowTitle("Help");
00219 msgBox.setText("Maximum Size of Arrays:\n\n"
00220 "If the size of an Arrays is larger than this maximum value, the entire array is skipped.\n\n"
00221 "This parameter is used to prevent the user from loading HUGE arrays, "
00222 "such as images, pointclouds, maps, etc.\n"
00223 "The term 'array' refers to the array in a message field,\n\n"
00224 " See http://wiki.ros.org/msg.\n\n"
00225 "This is NOT about the duration of a time series!\n\n"
00226 "MOTIVATION: pretend that a user tries to load a RGB image, which probably contains "
00227 "a few millions pixels.\n"
00228 "Plotjuggler would naively create a single time series for each pixel of the image! "
00229 "That makes no sense, of course, and it would probably freeze your system.\n"
00230 );
00231 msgBox.exec();
00232 }
00233
00234 void DialogSelectRosTopics::on_lineEditFilter_textChanged(const QString& search_string)
00235 {
00236 int visible_count = 0;
00237 bool updated = false;
00238
00239 QStringList spaced_items = search_string.split(' ');
00240
00241 for (int row=0; row < ui->listRosTopics->rowCount(); row++)
00242 {
00243 auto item = ui->listRosTopics->item(row,0);
00244 QString name = item->text();
00245 int pos = 0;
00246 bool toHide = false;
00247
00248 for (const auto& item: spaced_items)
00249 {
00250 if( !name.contains(item) )
00251 {
00252 toHide = true;
00253 break;
00254 }
00255 }
00256 ui->listRosTopics->setRowHidden(row, toHide );
00257 }
00258 }
00259
00260 void DialogSelectRosTopics::on_spinBoxArraySize_valueChanged(int value)
00261 {
00262 if( value > 1000 )
00263 {
00264 ui->spinBoxArraySize->setStyleSheet("QSpinBox { color: red; }");
00265 }
00266 else{
00267 ui->spinBoxArraySize->setStyleSheet("QSpinBox { color: black; }");
00268 }
00269 }
00270
00271
00272