topic_display.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of Willow Garage, Inc. nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 ********************************************************************/
00034 
00035 #include "topic_display.h"
00036 
00037 namespace rxtools
00038 {
00039 
00040 class TopicNameData : public wxTreeItemData
00041 {
00042 public:
00043   std::string name;
00044 };
00045 
00046 TopicDisplay::TopicDisplay(wxWindow* parent, const std::string& message_type, bool auto_refresh, const wxSize& size)
00047 : GenTopicDisplay(parent, wxID_ANY, wxDefaultPosition, size)
00048 , message_type_(message_type)
00049 {
00050   timer_ = new wxTimer(this);
00051 
00052   Connect(wxEVT_TIMER, wxTimerEventHandler(TopicDisplay::tick), NULL, this);
00053 
00054   if (auto_refresh)
00055   {
00056     timer_->Start(1000);
00057   }
00058 
00059   root_id_ = topic_tree_->AddRoot(wxT("/"));
00060 
00061   refreshTopics();
00062 }
00063 
00064 TopicDisplay::~TopicDisplay()
00065 {
00066   delete timer_;
00067 }
00068 
00069 void TopicDisplay::checkIsTopic(wxTreeEvent& event)
00070 {
00071   if (topic_tree_->GetItemData(event.GetItem()) == NULL)
00072   {
00073     event.Veto();
00074   }
00075 }
00076 
00077 void TopicDisplay::onItemActivated(wxTreeEvent& event)
00078 {
00079   if (topic_tree_->GetItemData(event.GetItem()) == NULL)
00080   {
00081     event.Skip();
00082   }
00083   else
00084   {
00085     wxPostEvent(this, event);
00086   }
00087 }
00088 
00089 void TopicDisplay::refreshTopics()
00090 {
00091   ros::master::V_TopicInfo topics;
00092   ros::master::getTopics(topics);
00093 
00094   // Set all items in cache to tentatively delete
00095   for (M_TopicInfo::iterator i = topic_cache_.begin(); i != topic_cache_.end(); ++i)
00096   {
00097     i->second.save_ = false;
00098   }
00099 
00100   // Loop through all published topics
00101   ros::master::V_TopicInfo::iterator it = topics.begin();
00102   ros::master::V_TopicInfo::iterator end = topics.end();
00103   for (; it != end; ++it)
00104   {
00105     const ros::master::TopicInfo& topic = *it;
00106     if (!message_type_.empty() && topic.datatype != message_type_)
00107     {
00108       continue;
00109     }
00110 
00111     M_TopicInfo::iterator j = topic_cache_.find(topic.name);
00112     if (j == topic_cache_.end())
00113     {
00114       // Topic not in cache yet.  Find right place to put it in the tree
00115       std::istringstream iss(topic.name);
00116       std::string token;
00117 
00118       wxTreeItemId id = root_id_;
00119 
00120       while (getline(iss, token, '/'))
00121       {
00122         if (!token.empty())
00123         {
00124           wxTreeItemIdValue cookie;
00125 
00126           wxTreeItemId child;
00127 
00128           child = topic_tree_->GetFirstChild(id, cookie);
00129 
00130           bool exists = false;
00131           while (child.IsOk())
00132           {
00133             if (topic_tree_->GetItemText(child) == wxString::FromAscii(token.c_str()))
00134             {
00135               exists = true;
00136               break;
00137             }
00138 
00139             child = topic_tree_->GetNextChild(id, cookie);
00140           }
00141 
00142           if (exists)
00143           {
00144             id = child;
00145           }
00146           else
00147           {
00148             id = topic_tree_->AppendItem(id, wxString::FromAscii(token.c_str()));
00149           }
00150         }
00151       }
00152 
00153       // Add to Cache
00154       TopicInfo cache_item;
00155       cache_item.item_ = id;
00156       cache_item.save_ = true;
00157       cache_item.type_ = topic.datatype;
00158       topic_cache_[topic.name] = cache_item;
00159 
00160       // Put data in tree item and rename
00161       TopicNameData* data = new TopicNameData();
00162       data->name = topic.name;
00163       topic_tree_->SetItemText(id, wxString::FromAscii(token.c_str()) + wxT(" (") + wxString::FromAscii(topic.datatype.c_str()) + wxT(")"));
00164       topic_tree_->SetItemData(id, data);
00165       topic_tree_->SetItemBold(id, true);
00166     }
00167     else
00168     {
00169       // Topic already in cache -- keep it there.
00170       j->second.save_ = true;
00171     }
00172   }
00173 
00174   std::vector<M_TopicInfo::iterator> to_erase;
00175 
00176   // Tentatively delete all items in cache which should be removed
00177   for (M_TopicInfo::iterator i = topic_cache_.begin(); i != topic_cache_.end(); i++)
00178   {
00179     if (i->second.save_ == false)
00180     {
00181       to_erase.push_back(i);
00182     }
00183   }
00184 
00185   // Actually delete all items and purge parents as necessary
00186   for (std::vector<M_TopicInfo::iterator>::iterator i = to_erase.begin(); i != to_erase.end(); i++)
00187   {
00188     // Delete item
00189     wxTreeItemId id = (*i)->second.item_;
00190     wxTreeItemId parent_id = topic_tree_->GetItemParent(id);
00191     topic_tree_->Delete(id);
00192 
00193     // Delete all childless parents
00194     while (parent_id != root_id_)
00195     {
00196       if (topic_tree_->HasChildren(parent_id))
00197       {
00198         break;
00199       }
00200       else
00201       {
00202         id = parent_id;
00203         parent_id = topic_tree_->GetItemParent(id);
00204         topic_tree_->Delete(id);
00205       }
00206     }
00207 
00208     // Erase item from cache
00209     topic_cache_.erase(*i);
00210   }
00211 
00212   // Refresh the display
00213   Refresh();
00214 }
00215 
00216 void TopicDisplay::tick(wxTimerEvent& event)
00217 {
00218   refreshTopics();
00219 }
00220 
00221 void TopicDisplay::getSelectedTopics(V_string& topics)
00222 {
00223   wxArrayTreeItemIds selections;
00224 
00225   topic_tree_->GetSelections(selections);
00226 
00227   for (unsigned int i = 0; i < selections.GetCount(); i++)
00228   {
00229     wxTreeItemId id = selections.Item(i);
00230     if (topic_tree_->GetItemData(id) != NULL)
00231     {
00232       TopicNameData* s = (TopicNameData*) topic_tree_->GetItemData(id);
00233       topics.push_back(s->name);
00234     }
00235   }
00236 }
00237 
00238 void TopicDisplay::setMultiselectAllowed(bool allowed)
00239 {
00240   long tree_style = topic_tree_->GetWindowStyle();
00241 
00242   if (allowed)
00243   {
00244     tree_style &= ~wxTR_SINGLE;
00245     tree_style |= wxTR_MULTIPLE;
00246   }
00247   else
00248   {
00249     tree_style &= ~wxTR_MULTIPLE;
00250     tree_style |= wxTR_SINGLE;
00251   }
00252 
00253   topic_tree_->SetWindowStyle(tree_style);
00254   topic_tree_->Refresh();
00255 }
00256 
00257 } // namespace rxtools


rxtools
Author(s): Josh Faust, Rob Wheeler, Ken Conley
autogenerated on Mon Oct 6 2014 07:25:59