new_object_dialog.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <QGroupBox>
00031 #include <QTreeWidget>
00032 #include <QLabel>
00033 #include <QLineEdit>
00034 #include <QTextBrowser>
00035 #include <QVBoxLayout>
00036 #include <QDialogButtonBox>
00037 #include <QPushButton>
00038 
00039 #include "new_object_dialog.h"
00040 
00041 namespace rviz
00042 {
00043 
00044 NewObjectDialog::NewObjectDialog( pluginlib::ClassLoaderBase* class_loader,
00045                                   const std::string& object_type,
00046                                   const S_string& current_display_names,
00047                                   std::string* lookup_name_output,
00048                                   std::string* display_name_output,
00049                                   QWidget* parent )
00050 : QDialog( parent )
00051 , class_loader_( class_loader )
00052 , current_display_names_( current_display_names )
00053 , lookup_name_output_( lookup_name_output )
00054 , display_name_output_( display_name_output )
00055 {
00056   //***** Layout
00057 
00058   // Display Type group
00059   QGroupBox* type_box = new QGroupBox( QString::fromStdString( object_type + " Type" ));
00060   
00061   QTreeWidget* tree = new QTreeWidget;
00062   tree->setHeaderHidden( true );
00063   fillTree( tree );
00064 
00065   QLabel* description_label = new QLabel( "Description:" );
00066   description_ = new QTextBrowser;
00067   description_->setMaximumHeight( 100 );
00068   description_->setOpenExternalLinks( true );
00069 
00070   QVBoxLayout* type_layout = new QVBoxLayout;
00071   type_layout->addWidget( tree );
00072   type_layout->addWidget( description_label );
00073   type_layout->addWidget( description_ );
00074 
00075   type_box->setLayout( type_layout );
00076 
00077   // Display Name group
00078   QGroupBox* name_box = new QGroupBox( QString::fromStdString( object_type + " Name" ));
00079   
00080   name_editor_ = new QLineEdit;
00081   QVBoxLayout* name_layout = new QVBoxLayout;
00082   name_layout->addWidget( name_editor_ );
00083   name_box->setLayout( name_layout );
00084 
00085   // Buttons
00086   button_box_ = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
00087                                       Qt::Horizontal );
00088 
00089   QVBoxLayout* main_layout = new QVBoxLayout;
00090   main_layout->addWidget( type_box );
00091   main_layout->addWidget( name_box );
00092   main_layout->addWidget( button_box_ );
00093   setLayout( main_layout );
00094 
00095   //***** Connections
00096   connect( tree, SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
00097            this, SLOT( onDisplaySelected( QTreeWidgetItem* )));
00098   connect( tree, SIGNAL( itemActivated( QTreeWidgetItem*, int )),
00099            this, SLOT( accept() ));
00100   connect( button_box_, SIGNAL( accepted() ), this, SLOT( accept() ));
00101   connect( button_box_, SIGNAL( rejected() ), this, SLOT( reject() ));
00102   connect( name_editor_, SIGNAL( textEdited( const QString& )),
00103            this, SLOT( onNameChanged() ));
00104 }
00105 
00106 void NewObjectDialog::fillTree( QTreeWidget* tree )
00107 {
00108   std::vector<std::string> classes = class_loader_->getDeclaredClasses();
00109 
00110   // Map from package names to the corresponding top-level tree widget items.
00111   std::map<std::string, QTreeWidgetItem*> package_items;
00112 
00113   std::vector<std::string>::const_iterator ci;
00114   for( ci = classes.begin(); ci != classes.end(); ci++ )
00115   {
00116     std::string lookup_name = (*ci);
00117     std::string package = class_loader_->getClassPackage( lookup_name );
00118     std::string description = class_loader_->getClassDescription( lookup_name );
00119     std::string name = class_loader_->getName( lookup_name );
00120 
00121     QTreeWidgetItem* package_item;
00122 
00123     std::map<std::string, QTreeWidgetItem*>::iterator mi;
00124     mi = package_items.find( package );
00125     if( mi == package_items.end() )
00126     {
00127       package_item = new QTreeWidgetItem( tree );
00128       package_item->setText( 0, QString::fromStdString( package ));
00129       package_item->setExpanded( true );
00130       package_items[ package ] = package_item;
00131     }
00132     else
00133     {
00134       package_item = (*mi).second;
00135     }
00136     QTreeWidgetItem* class_item = new QTreeWidgetItem( package_item );
00137     class_item->setText( 0, QString::fromStdString( name ));
00138     class_item->setWhatsThis( 0, QString::fromStdString( description ));
00139     // Store the lookup name for each class in the UserRole of the item.
00140     class_item->setData( 0, Qt::UserRole, QString::fromStdString( lookup_name ));
00141   }
00142 }
00143 
00144 void NewObjectDialog::onDisplaySelected( QTreeWidgetItem* selected_item )
00145 {
00146   QString html = "<html><body>" + selected_item->whatsThis( 0 ) + "</body></html>";
00147   description_->setHtml( html );
00148 
00149   // We stored the lookup name for the class in the UserRole of the items.
00150   QVariant user_data = selected_item->data( 0, Qt::UserRole );
00151   bool selection_is_valid = user_data.isValid();
00152   if( selection_is_valid )
00153   {
00154     lookup_name_ = user_data.toString().toStdString();
00155     std::string display_name = selected_item->text( 0 ).toStdString();
00156 
00157     int counter = 1;
00158     std::string name;
00159     do
00160     {
00161       std::stringstream ss;
00162       ss << display_name;
00163  
00164       if( counter > 1 )
00165       {
00166         ss << counter;
00167       }
00168  
00169       ++counter;
00170  
00171       name = ss.str();
00172     } while( current_display_names_.find( name ) != current_display_names_.end() );
00173  
00174     name_editor_->setText( QString::fromStdString( name ));
00175   }
00176   else
00177   {
00178     lookup_name_ = "";
00179     name_editor_->setText( "" );
00180   }
00181   button_box_->button( QDialogButtonBox::Ok )->setEnabled( isValid() );
00182 }
00183 
00184 bool NewObjectDialog::isValid()
00185 {
00186   std::string display_name = name_editor_->text().toStdString();
00187   if( lookup_name_.size() == 0 )
00188   {
00189     setError( "Select a Display type." );
00190     return false;
00191   }
00192   if( display_name.size() == 0 )
00193   {
00194     setError( "Enter a name for the display." );
00195     return false;
00196   }
00197   if( current_display_names_.find( display_name ) != current_display_names_.end() )
00198   {
00199     setError( "Name in use.  Display names must be unique." );
00200     return false;
00201   }
00202   setError( "" );
00203   return true;
00204 }
00205 
00206 void NewObjectDialog::setError( const QString& error_text )
00207 {
00208   button_box_->button( QDialogButtonBox::Ok )->setToolTip( error_text );
00209 }
00210 
00211 void NewObjectDialog::onNameChanged()
00212 {
00213   button_box_->button( QDialogButtonBox::Ok )->setEnabled( isValid() );
00214 }
00215 
00216 void NewObjectDialog::accept()
00217 {
00218   if( isValid() )
00219   {
00220     *lookup_name_output_ = lookup_name_;
00221     *display_name_output_ = name_editor_->text().toStdString();
00222     QDialog::accept();
00223   }
00224 }
00225 
00226 } // rviz
00227 


rviz
Author(s): Dave Hershberger, Josh Faust
autogenerated on Mon Jan 6 2014 11:54:32