Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <mapviz/select_frame_dialog.h>
00030
00031 #include <algorithm>
00032 #include <set>
00033
00034 #include <QListWidget>
00035 #include <QLineEdit>
00036 #include <QVBoxLayout>
00037 #include <QHBoxLayout>
00038 #include <QPushButton>
00039 #include <QLabel>
00040 #include <QTimerEvent>
00041
00042 #include <tf/transform_listener.h>
00043
00044 namespace mapviz
00045 {
00046 std::string SelectFrameDialog::selectFrame(
00047 boost::shared_ptr<tf::TransformListener> tf_listener,
00048 QWidget *parent)
00049 {
00050 SelectFrameDialog dialog(tf_listener, parent);
00051 dialog.allowMultipleFrames(false);
00052 if (dialog.exec() == QDialog::Accepted) {
00053 return dialog.selectedFrame();
00054 } else {
00055 return "";
00056 }
00057 }
00058
00059 std::vector<std::string> SelectFrameDialog::selectFrames(
00060 boost::shared_ptr<tf::TransformListener> tf_listener,
00061 QWidget *parent)
00062 {
00063 SelectFrameDialog dialog(tf_listener, parent);
00064 dialog.allowMultipleFrames(true);
00065 if (dialog.exec() == QDialog::Accepted) {
00066 return dialog.selectedFrames();
00067 } else {
00068 return std::vector<std::string>();
00069 }
00070 }
00071
00072 SelectFrameDialog::SelectFrameDialog(
00073 boost::shared_ptr<tf::TransformListener> tf_listener,
00074 QWidget *parent)
00075 :
00076 tf_(tf_listener),
00077 ok_button_(new QPushButton("&Ok")),
00078 cancel_button_(new QPushButton("&Cancel")),
00079 list_widget_(new QListWidget()),
00080 name_filter_(new QLineEdit())
00081 {
00082 QHBoxLayout *filter_box = new QHBoxLayout();
00083 filter_box->addWidget(new QLabel("Filter:"));
00084 filter_box->addWidget(name_filter_);
00085
00086 QHBoxLayout *button_box = new QHBoxLayout();
00087 button_box->addStretch(1);
00088 button_box->addWidget(cancel_button_);
00089 button_box->addWidget(ok_button_);
00090
00091 QVBoxLayout *vbox = new QVBoxLayout();
00092 vbox->addWidget(list_widget_);
00093 vbox->addLayout(filter_box);
00094 vbox->addLayout(button_box);
00095 setLayout(vbox);
00096
00097 connect(ok_button_, SIGNAL(clicked(bool)),
00098 this, SLOT(accept()));
00099 connect(cancel_button_, SIGNAL(clicked(bool)),
00100 this, SLOT(reject()));
00101 connect(name_filter_, SIGNAL(textChanged(const QString &)),
00102 this, SLOT(updateDisplayedFrames()));
00103
00104 ok_button_->setDefault(true);
00105
00106 allowMultipleFrames(false);
00107 setWindowTitle("Select frames...");
00108
00109 resize(600, 600);
00110
00111 fetch_frames_timer_id_ = startTimer(1000);
00112 fetchFrames();
00113 }
00114
00115 void SelectFrameDialog::timerEvent(QTimerEvent *event)
00116 {
00117 if (event->timerId() == fetch_frames_timer_id_) {
00118 fetchFrames();
00119 }
00120 }
00121
00122 void SelectFrameDialog::closeEvent(QCloseEvent *event)
00123 {
00124
00125 killTimer(fetch_frames_timer_id_);
00126 QDialog::closeEvent(event);
00127 }
00128
00129 void SelectFrameDialog::allowMultipleFrames(
00130 bool allow)
00131 {
00132 if (allow) {
00133 list_widget_->setSelectionMode(QAbstractItemView::MultiSelection);
00134 } else {
00135 list_widget_->setSelectionMode(QAbstractItemView::SingleSelection);
00136 }
00137 }
00138
00139 std::string SelectFrameDialog::selectedFrame() const
00140 {
00141 std::vector<std::string> selection = selectedFrames();
00142 if (selection.empty()) {
00143 return "";
00144 } else {
00145 return selection.front();
00146 }
00147 }
00148
00149 std::vector<std::string> SelectFrameDialog::selectedFrames() const
00150 {
00151 QModelIndexList qt_selection = list_widget_->selectionModel()->selectedIndexes();
00152
00153 std::vector<std::string> selection;
00154 selection.resize(qt_selection.size());
00155 for (int i = 0; i < qt_selection.size(); i++) {
00156 if (!qt_selection[i].isValid()) {
00157 continue;
00158 }
00159
00160 int row = qt_selection[i].row();
00161 if (row < 0 || static_cast<size_t>(row) >= displayed_frames_.size()) {
00162 continue;
00163 }
00164
00165 selection[i] = displayed_frames_[row];
00166 }
00167
00168 return selection;
00169 }
00170
00171 void SelectFrameDialog::fetchFrames()
00172 {
00173 if (!tf_) { return; }
00174
00175 known_frames_.clear();
00176 tf_->getFrameStrings(known_frames_);
00177 std::sort(known_frames_.begin(), known_frames_.end());
00178 updateDisplayedFrames();
00179 }
00180
00181 std::vector<std::string> SelectFrameDialog::filterFrames(
00182 const std::vector<std::string> &frames) const
00183 {
00184 QString frame_filter = name_filter_->text();
00185 std::vector<std::string> filtered;
00186
00187 for (size_t i = 0; i < frames.size(); i++) {
00188 QString frame_name = QString::fromStdString(frames[i]);
00189 if (!frame_filter.isEmpty() &&
00190 !frame_name.contains(frame_filter, Qt::CaseInsensitive)) {
00191 continue;
00192 }
00193
00194 filtered.push_back(frames[i]);
00195 }
00196
00197 return filtered;
00198 }
00199
00200 void SelectFrameDialog::updateDisplayedFrames()
00201 {
00202 std::vector<std::string> next_displayed_frames = filterFrames(known_frames_);
00203
00204
00205
00206
00207
00208
00209 std::set<std::string> prev_names;
00210 prev_names.insert(displayed_frames_.begin(), displayed_frames_.end());
00211
00212 std::set<std::string> next_names;
00213 next_names.insert(next_displayed_frames.begin(), next_displayed_frames.end());
00214
00215 std::set<std::string> added_names;
00216 std::set_difference(next_names.begin(), next_names.end(),
00217 prev_names.begin(), prev_names.end(),
00218 std::inserter(added_names, added_names.end()));
00219
00220 std::set<std::string> removed_names;
00221 std::set_difference(prev_names.begin(), prev_names.end(),
00222 next_names.begin(), next_names.end(),
00223 std::inserter(removed_names, removed_names.end()));
00224
00225
00226 size_t removed = 0;
00227 for (size_t i = 0; i < displayed_frames_.size(); i++) {
00228 if (removed_names.count(displayed_frames_[i]) == 0) {
00229 continue;
00230 }
00231
00232 QListWidgetItem *item = list_widget_->takeItem(i - removed);
00233 delete item;
00234 removed++;
00235 }
00236
00237
00238 for (size_t i = 0; i < next_displayed_frames.size(); i++) {
00239 if (added_names.count(next_displayed_frames[i]) == 0) {
00240 continue;
00241 }
00242
00243 list_widget_->insertItem(i, QString::fromStdString(next_displayed_frames[i]));
00244 if (list_widget_->count() == 1) {
00245 list_widget_->setCurrentRow(0);
00246 }
00247 }
00248
00249 displayed_frames_.swap(next_displayed_frames);
00250 }
00251 }