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
00030
00031 #include <swri_console/node_click_handler.h>
00032 #include <swri_console/node_list_model.h>
00033
00034 #include <ros/ros.h>
00035 #include <roscpp/GetLoggers.h>
00036 #include <roscpp/SetLoggerLevel.h>
00037
00038 #include <QMessageBox>
00039 #include <QTextStream>
00040
00041 namespace swri_console
00042 {
00043 const std::string NodeClickHandler::ALL_LOGGERS = "All Loggers";
00044 const std::string NodeClickHandler::GET_LOGGERS_SVC = "/get_loggers";
00045 const std::string NodeClickHandler::SET_LOGGER_LEVEL_SVC = "/set_logger_level";
00046
00047 bool NodeClickHandler::eventFilter(QObject* obj, QEvent* event)
00048 {
00049 QContextMenuEvent* context_event;
00050 QListView* list;
00051
00052 switch (event->type()) {
00053 case QEvent::ContextMenu:
00054 context_event = static_cast<QContextMenuEvent*>(event);
00055
00056
00057 list = static_cast<QListView*>(obj);
00058 if (list == NULL) {
00059 return false;
00060 }
00061
00062 return showContextMenu(list, context_event);
00063 default:
00064
00065 return QObject::eventFilter(obj, event);
00066 }
00067 }
00068
00069 bool NodeClickHandler::showContextMenu(QListView* list, QContextMenuEvent* event)
00070 {
00071 QModelIndexList index_list = list->selectionModel()->selectedIndexes();
00072 if (index_list.isEmpty()) {
00073 return false;
00074 }
00075
00076
00077
00078 NodeListModel* model = static_cast<NodeListModel*>(list->model());
00079 node_name_ = model->nodeName(index_list.first());
00080
00081 std::string service_name = node_name_ + GET_LOGGERS_SVC;
00082 ros::ServiceClient client = nh_.serviceClient<roscpp::GetLoggers>(service_name);
00089 if (!client.waitForExistence(ros::Duration(2.0))) {
00090 ROS_WARN("Timed out while waiting for service at %s.", service_name.c_str());
00091 QMessageBox::warning(list, "Error Getting Loggers", "Timed out waiting for get_loggers service.");
00092 return false;
00093 }
00094
00095 roscpp::GetLoggers srv;
00096
00097 QMenu menu(list);
00098 QAction* label = menu.addAction(QString::fromStdString(node_name_ + " loggers:"));
00099 label->setDisabled(true);
00100
00101 ROS_DEBUG("Getting loggers for %s...", node_name_.c_str());
00102 if (callService(client, srv)) {
00103 all_loggers_.clear();
00104 menu.addMenu(createMenu(QString::fromStdString(ALL_LOGGERS), ""));
00105 Q_FOREACH(const roscpp::Logger& logger, srv.response.loggers) {
00106 ROS_DEBUG("Log level for %s is %s", logger.name.c_str(), logger.level.c_str());
00107 all_loggers_.push_back(logger.name);
00108 QString logger_name = QString::fromStdString(logger.name);
00109
00110 menu.addMenu(createMenu(logger_name, QString::fromStdString(logger.level)));
00111 }
00112 }
00113 else {
00114 std::string error = "Service call to get_loggers failed.";
00115 ROS_WARN("%s", error.c_str());
00116 QMessageBox::warning(list, "Service Call Failed", error.c_str());
00117 }
00118
00119 menu.exec(event->globalPos());
00120
00121 return false;
00122 }
00123
00124 QMenu* NodeClickHandler::createMenu(const QString& logger_name, const QString& current_level)
00125 {
00126 QString action_label;
00127 QTextStream stream(&action_label);
00128 stream << logger_name;
00129 if (!current_level.isEmpty()) {
00130 stream << " (" << current_level.toUpper() << ")";
00131 }
00132
00133 QMenu* nodeMenu = new QMenu(action_label);
00134
00135 const QString levels[] = {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
00136
00137 for (int i = 0; i < 5; i++) {
00138 QAction* action = nodeMenu->addAction(levels[i], this, SLOT(logLevelClicked()));
00139 action->setData(logger_name);
00140 }
00141
00142 return nodeMenu;
00143 }
00144
00145 void NodeClickHandler::logLevelClicked()
00146 {
00147 QAction* action = static_cast<QAction*>(sender());
00148
00149 std::string logger = action->data().toString().toStdString();
00150 std::string level = action->text().toStdString();
00151 ROS_DEBUG("Setting log level for %s/%s to %s", node_name_.c_str(), logger.c_str(), level.c_str());
00152
00153 std::string service_name = node_name_ + SET_LOGGER_LEVEL_SVC;
00154
00155 ros::ServiceClient client = nh_.serviceClient<roscpp::SetLoggerLevel>(service_name);
00156 if (!client.waitForExistence(ros::Duration(2.0))) {
00157 ROS_WARN("Timed out while waiting for service at %s.", service_name.c_str());
00158 QMessageBox::warning(NULL, "Error Getting Loggers", "Timed out waiting for set_logger_level service.");
00159 return;
00160 }
00161
00162 std::vector<std::string> target_loggers;
00163 if (logger == ALL_LOGGERS) {
00164 target_loggers = all_loggers_;
00165 }
00166 else {
00167 target_loggers.push_back(logger);
00168 }
00169
00170 Q_FOREACH (const std::string& logger_name, target_loggers) {
00171 roscpp::SetLoggerLevel srv;
00172 srv.request.level = level;
00173 srv.request.logger = logger_name;
00174 if (callService(client, srv)) {
00175 ROS_DEBUG("Set logger level.");
00176 }
00177 else {
00178 ROS_WARN("Service call to %s failed.", service_name.c_str());
00179 QMessageBox::warning(NULL, "Error Setting Log Level", "Failed to set logger level.");
00180 }
00181 }
00182 }
00183 }
00184