33 #include <QCloseEvent> 34 #include <QHBoxLayout> 37 #include <QListWidget> 38 #include <QMessageBox> 39 #include <QPushButton> 40 #include <QTimerEvent> 41 #include <QVBoxLayout> 43 #include <rosapi/Services.h> 44 #include <rosapi/ServicesForType.h> 58 client =
nh_.
serviceClient<rosapi::ServicesForType>(
"/rosapi/services_for_type");
64 Q_EMIT
fetchingFailed(tr(
"Unable to list ROS services. Is rosapi_node running?"));
79 rosapi::ServicesForType srv;
82 ROS_DEBUG(
"Listing services for type %s", srv.request.type.c_str());
92 Q_EMIT
fetchingFailed(tr(
"Unable to list ROS services. You may have " \
93 "dead nodes; try running \"rosnode cleanup\"."));
102 if (dialog.exec() == QDialog::Accepted) {
112 ok_button_(new QPushButton(
"&Ok")),
113 cancel_button_(new QPushButton(
"&Cancel")),
114 list_widget_(new QListWidget()),
115 name_filter_(new QLineEdit()),
118 QHBoxLayout *filter_box =
new QHBoxLayout();
119 filter_box->addWidget(
new QLabel(
"Filter:"));
122 QHBoxLayout *button_box =
new QHBoxLayout();
123 button_box->addStretch(1);
127 QVBoxLayout *vbox =
new QVBoxLayout();
129 vbox->addLayout(filter_box);
130 vbox->addLayout(button_box);
135 qRegisterMetaType<ServiceStringVector>(
"ServiceStringVector");
138 this, SLOT(accept()));
140 this, SLOT(reject()));
141 connect(
name_filter_, SIGNAL(textChanged(
const QString &)),
146 setWindowTitle(
"Select service...");
181 SIGNAL(fetchingFailed(
const QString)),
197 QMessageBox mbox(this->parentWidget());
198 mbox.setIcon(QMessageBox::Warning);
199 mbox.setText(error_msg);
205 std::vector<std::string> filtered_services;
211 if (QString::fromStdString(service).contains(filter_text, Qt::CaseInsensitive))
213 filtered_services.push_back(service);
217 return filtered_services;
222 std::vector<std::string> next_displayed_services =
filterServices();
229 std::set<std::string> prev_names;
234 std::set<std::string> next_names;
235 for (
size_t i = 0; i < next_displayed_services.size(); i++) {
236 next_names.insert(next_displayed_services[i]);
239 std::set<std::string> added_names;
240 std::set_difference(next_names.begin(), next_names.end(),
241 prev_names.begin(), prev_names.end(),
242 std::inserter(added_names, added_names.end()));
244 std::set<std::string> removed_names;
245 std::set_difference(prev_names.begin(), prev_names.end(),
246 next_names.begin(), next_names.end(),
247 std::inserter(removed_names, removed_names.end()));
256 QListWidgetItem *item =
list_widget_->takeItem(i - removed);
262 for (
size_t i = 0; i < next_displayed_services.size(); i++) {
263 if (added_names.count(next_displayed_services[i]) == 0) {
267 list_widget_->insertItem(i, QString::fromStdString(next_displayed_services[i]));
284 QModelIndex qt_selection =
list_widget_->selectionModel()->currentIndex();
286 if (qt_selection.isValid()) {
287 int row = qt_selection.row();
307 QDialog::closeEvent(event);
void setDatatypeFilter(const std::string &datatype)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
std::vector< std::string > known_services_
void servicesFetched(ServiceStringVector services)
void displayUpdateError(const QString)
bool call(MReq &req, MRes &res)
std::string allowed_datatype_
QPushButton * cancel_button_
const std::string & allowed_datatype_
void closeEvent(QCloseEvent *)
void updateKnownServices(ServiceStringVector services)
SelectServiceDialog(const std::string &datatype="", QWidget *parent=0)
virtual ~SelectServiceDialog()
std::vector< std::string > displayed_services_
boost::shared_ptr< ServiceUpdaterThread > worker_thread_
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
std::string selectedService() const
void timerEvent(QTimerEvent *)
int fetch_services_timer_id_
QT_END_NAMESPACE typedef std::vector< std::string > ServiceStringVector
void updateDisplayedServices()
std::vector< std::string > filterServices()
static std::string selectService(const std::string &datatype, QWidget *parent=0)
void fetchingFailed(const QString error_msg)
QListWidget * list_widget_