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 <map>
00031 
00032 #include <boost/filesystem.hpp>
00033 
00034 #include <ros/package.h>
00035 #include <ros/ros.h>
00036 
00037 #include <QGroupBox>
00038 #include <QTreeWidget>
00039 #include <QLabel>
00040 #include <QLineEdit>
00041 #include <QTextBrowser>
00042 #include <QVBoxLayout>
00043 #include <QDialogButtonBox>
00044 #include <QPushButton>
00045 
00046 #include "new_object_dialog.h"
00047 #include "rviz/load_resource.h"
00048 
00049 namespace rviz
00050 {
00051 
00052 NewObjectDialog::NewObjectDialog( Factory* factory,
00053                                   const QString& object_type,
00054                                   const QStringList& disallowed_display_names,
00055                                   const QStringList& disallowed_class_lookup_names,
00056                                   QString* lookup_name_output,
00057                                   QString* display_name_output,
00058                                   QWidget* parent )
00059 : QDialog( parent )
00060 , factory_( factory )
00061 , disallowed_display_names_( disallowed_display_names )
00062 , disallowed_class_lookup_names_( disallowed_class_lookup_names )
00063 , lookup_name_output_( lookup_name_output )
00064 , display_name_output_( display_name_output )
00065 {
00066   //***** Layout
00067 
00068   // Display Type group
00069   QGroupBox* type_box = new QGroupBox( object_type + " Type" );
00070   
00071   QTreeWidget* tree = new QTreeWidget;
00072   tree->setHeaderHidden( true );
00073   fillTree( tree );
00074 
00075   QLabel* description_label = new QLabel( "Description:" );
00076   description_ = new QTextBrowser;
00077   description_->setMaximumHeight( 100 );
00078   description_->setOpenExternalLinks( true );
00079 
00080   QVBoxLayout* type_layout = new QVBoxLayout;
00081   type_layout->addWidget( tree );
00082   type_layout->addWidget( description_label );
00083   type_layout->addWidget( description_ );
00084 
00085   type_box->setLayout( type_layout );
00086 
00087   // Display Name group
00088   QGroupBox* name_box;
00089   if( display_name_output_ )
00090   {
00091     name_box = new QGroupBox( object_type + " Name" );
00092     name_editor_ = new QLineEdit;
00093     QVBoxLayout* name_layout = new QVBoxLayout;
00094     name_layout->addWidget( name_editor_ );
00095     name_box->setLayout( name_layout );
00096   }
00097 
00098   // Buttons
00099   button_box_ = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
00100                                       Qt::Horizontal );
00101 
00102   QVBoxLayout* main_layout = new QVBoxLayout;
00103   main_layout->addWidget( type_box );
00104   if( display_name_output_ )
00105   {
00106     main_layout->addWidget( name_box );
00107   }
00108   main_layout->addWidget( button_box_ );
00109   setLayout( main_layout );
00110 
00111   //***** Connections
00112   connect( tree, SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
00113            this, SLOT( onDisplaySelected( QTreeWidgetItem* )));
00114   connect( tree, SIGNAL( itemActivated( QTreeWidgetItem*, int )),
00115            this, SLOT( accept() ));
00116   connect( button_box_, SIGNAL( accepted() ), this, SLOT( accept() ));
00117   connect( button_box_, SIGNAL( rejected() ), this, SLOT( reject() ));
00118 
00119   if( display_name_output_ )
00120   {
00121     connect( name_editor_, SIGNAL( textEdited( const QString& )),
00122              this, SLOT( onNameChanged() ));
00123   }
00124 }
00125 
00126 QSize NewObjectDialog::sizeHint () const
00127 {
00128   return( QSize(500,660) );
00129 }
00130 
00131 void NewObjectDialog::fillTree( QTreeWidget* tree )
00132 {
00133   QIcon default_package_icon = loadPixmap( "package://rviz/icons/default_package_icon.png" );
00134 
00135   QStringList classes = factory_->getDeclaredClassIds();
00136   classes.sort();
00137 
00138   // Map from package names to the corresponding top-level tree widget items.
00139   std::map<QString, QTreeWidgetItem*> package_items;
00140 
00141   for( int i = 0; i < classes.size(); i++ )
00142   {
00143     QString lookup_name = classes[ i ];
00144     QString package = factory_->getClassPackage( lookup_name );
00145     QString description = factory_->getClassDescription( lookup_name );
00146     QString name = factory_->getClassName( lookup_name );
00147 
00148     QTreeWidgetItem* package_item;
00149 
00150     std::map<QString, QTreeWidgetItem*>::iterator mi;
00151     mi = package_items.find( package );
00152     if( mi == package_items.end() )
00153     {
00154       package_item = new QTreeWidgetItem( tree );
00155       package_item->setText( 0, package );
00156       package_item->setIcon( 0, default_package_icon );
00157 
00158       package_item->setExpanded( true );
00159       package_items[ package ] = package_item;
00160     }
00161     else
00162     {
00163       package_item = (*mi).second;
00164     }
00165     QTreeWidgetItem* class_item = new QTreeWidgetItem( package_item );
00166 
00167     class_item->setIcon( 0, factory_->getIcon( lookup_name ) );
00168 
00169     class_item->setText( 0, name );
00170     class_item->setWhatsThis( 0, description );
00171     // Store the lookup name for each class in the UserRole of the item.
00172     class_item->setData( 0, Qt::UserRole, lookup_name );
00173     class_item->setDisabled( disallowed_class_lookup_names_.contains( lookup_name ));
00174   }
00175 }
00176 
00177 void NewObjectDialog::onDisplaySelected( QTreeWidgetItem* selected_item )
00178 {
00179   QString html = "<html><body>" + selected_item->whatsThis( 0 ) + "</body></html>";
00180   description_->setHtml( html );
00181 
00182   // We stored the lookup name for the class in the UserRole of the items.
00183   QVariant user_data = selected_item->data( 0, Qt::UserRole );
00184   bool selection_is_valid = user_data.isValid();
00185   if( selection_is_valid )
00186   {
00187     lookup_name_ = user_data.toString();
00188     if( display_name_output_ )
00189     {
00190       QString display_name = selected_item->text( 0 );
00191 
00192       int counter = 1;
00193       QString name;
00194       do
00195       {
00196         name = display_name;
00197         if( counter > 1 )
00198         {
00199           name += QString::number( counter );
00200         }
00201         ++counter;
00202  
00203       } while( disallowed_display_names_.contains( name ));
00204  
00205       name_editor_->setText( name );
00206     }
00207   }
00208   else
00209   {
00210     lookup_name_ = "";
00211     if( display_name_output_ )
00212     {
00213       name_editor_->setText( "" );
00214     }
00215   }
00216   button_box_->button( QDialogButtonBox::Ok )->setEnabled( isValid() );
00217 }
00218 
00219 bool NewObjectDialog::isValid()
00220 {
00221   if( lookup_name_.size() == 0 )
00222   {
00223     setError( "Select a Display type." );
00224     return false;
00225   }
00226   if( display_name_output_ )
00227   {
00228     QString display_name = name_editor_->text();
00229     if( display_name.size() == 0 )
00230     {
00231       setError( "Enter a name for the display." );
00232       return false;
00233     }
00234     if( disallowed_display_names_.contains( display_name ))
00235     {
00236       setError( "Name in use.  Display names must be unique." );
00237       return false;
00238     }
00239   }
00240   setError( "" );
00241   return true;
00242 }
00243 
00244 void NewObjectDialog::setError( const QString& error_text )
00245 {
00246   button_box_->button( QDialogButtonBox::Ok )->setToolTip( error_text );
00247 }
00248 
00249 void NewObjectDialog::onNameChanged()
00250 {
00251   button_box_->button( QDialogButtonBox::Ok )->setEnabled( isValid() );
00252 }
00253 
00254 void NewObjectDialog::accept()
00255 {
00256   if( isValid() )
00257   {
00258     *lookup_name_output_ = lookup_name_;
00259     if( display_name_output_ )
00260     {
00261       *display_name_output_ = name_editor_->text();
00262     }
00263     QDialog::accept();
00264   }
00265 }
00266 
00267 } // rviz
00268 


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Thu Aug 27 2015 15:02:27