$search
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_display_dialog.h" 00040 00041 namespace rviz 00042 { 00043 00044 NewDisplayDialog::NewDisplayDialog( pluginlib::ClassLoader<Display>* class_loader, 00045 const S_string& current_display_names, 00046 std::string* lookup_name_output, 00047 std::string* display_name_output, 00048 QWidget* parent ) 00049 : QDialog( parent ) 00050 , class_loader_( class_loader ) 00051 , current_display_names_( current_display_names ) 00052 , lookup_name_output_( lookup_name_output ) 00053 , display_name_output_( display_name_output ) 00054 { 00055 //***** Layout 00056 00057 // Display Type group 00058 QGroupBox* type_box = new QGroupBox( "Display Type" ); 00059 00060 QTreeWidget* tree = new QTreeWidget; 00061 tree->setHeaderHidden( true ); 00062 fillTree( tree ); 00063 00064 QLabel* description_label = new QLabel( "Description:" ); 00065 description_ = new QTextBrowser; 00066 description_->setMaximumHeight( 100 ); 00067 description_->setOpenExternalLinks( true ); 00068 00069 QVBoxLayout* type_layout = new QVBoxLayout; 00070 type_layout->addWidget( tree ); 00071 type_layout->addWidget( description_label ); 00072 type_layout->addWidget( description_ ); 00073 00074 type_box->setLayout( type_layout ); 00075 00076 // Display Name group 00077 QGroupBox* name_box = new QGroupBox( "Display Name" ); 00078 00079 name_editor_ = new QLineEdit; 00080 QVBoxLayout* name_layout = new QVBoxLayout; 00081 name_layout->addWidget( name_editor_ ); 00082 name_box->setLayout( name_layout ); 00083 00084 // Buttons 00085 button_box_ = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, 00086 Qt::Horizontal ); 00087 00088 QVBoxLayout* main_layout = new QVBoxLayout; 00089 main_layout->addWidget( type_box ); 00090 main_layout->addWidget( name_box ); 00091 main_layout->addWidget( button_box_ ); 00092 setLayout( main_layout ); 00093 00094 //***** Connections 00095 connect( tree, SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )), 00096 this, SLOT( onDisplaySelected( QTreeWidgetItem* ))); 00097 connect( tree, SIGNAL( itemActivated( QTreeWidgetItem*, int )), 00098 this, SLOT( accept() )); 00099 connect( button_box_, SIGNAL( accepted() ), this, SLOT( accept() )); 00100 connect( button_box_, SIGNAL( rejected() ), this, SLOT( reject() )); 00101 connect( name_editor_, SIGNAL( textEdited( const QString& )), 00102 this, SLOT( onNameChanged() )); 00103 } 00104 00105 void NewDisplayDialog::fillTree( QTreeWidget* tree ) 00106 { 00107 std::vector<std::string> classes = class_loader_->getDeclaredClasses(); 00108 00109 // Map from package names to the corresponding top-level tree widget items. 00110 std::map<std::string, QTreeWidgetItem*> package_items; 00111 00112 std::vector<std::string>::const_iterator ci; 00113 for( ci = classes.begin(); ci != classes.end(); ci++ ) 00114 { 00115 std::string lookup_name = (*ci); 00116 std::string package = class_loader_->getClassPackage( lookup_name ); 00117 std::string description = class_loader_->getClassDescription( lookup_name ); 00118 std::string name = class_loader_->getName( lookup_name ); 00119 00120 QTreeWidgetItem* package_item; 00121 00122 std::map<std::string, QTreeWidgetItem*>::iterator mi; 00123 mi = package_items.find( package ); 00124 if( mi == package_items.end() ) 00125 { 00126 package_item = new QTreeWidgetItem( tree ); 00127 package_item->setText( 0, QString::fromStdString( package )); 00128 package_item->setExpanded( true ); 00129 package_items[ package ] = package_item; 00130 } 00131 else 00132 { 00133 package_item = (*mi).second; 00134 } 00135 QTreeWidgetItem* class_item = new QTreeWidgetItem( package_item ); 00136 class_item->setText( 0, QString::fromStdString( name )); 00137 class_item->setWhatsThis( 0, QString::fromStdString( description )); 00138 // Store the lookup name for each class in the UserRole of the item. 00139 class_item->setData( 0, Qt::UserRole, QString::fromStdString( lookup_name )); 00140 } 00141 } 00142 00143 void NewDisplayDialog::onDisplaySelected( QTreeWidgetItem* selected_item ) 00144 { 00145 QString html = "<html><body>" + selected_item->whatsThis( 0 ) + "</body></html>"; 00146 description_->setHtml( html ); 00147 00148 // We stored the lookup name for the class in the UserRole of the items. 00149 QVariant user_data = selected_item->data( 0, Qt::UserRole ); 00150 bool selection_is_valid = user_data.isValid(); 00151 if( selection_is_valid ) 00152 { 00153 lookup_name_ = user_data.toString().toStdString(); 00154 std::string display_name = selected_item->text( 0 ).toStdString(); 00155 00156 int counter = 1; 00157 std::string name; 00158 do 00159 { 00160 std::stringstream ss; 00161 ss << display_name; 00162 00163 if( counter > 1 ) 00164 { 00165 ss << counter; 00166 } 00167 00168 ++counter; 00169 00170 name = ss.str(); 00171 } while( current_display_names_.find( name ) != current_display_names_.end() ); 00172 00173 name_editor_->setText( QString::fromStdString( name )); 00174 } 00175 else 00176 { 00177 lookup_name_ = ""; 00178 name_editor_->setText( "" ); 00179 } 00180 button_box_->button( QDialogButtonBox::Ok )->setEnabled( isValid() ); 00181 } 00182 00183 bool NewDisplayDialog::isValid() 00184 { 00185 std::string display_name = name_editor_->text().toStdString(); 00186 if( lookup_name_.size() == 0 ) 00187 { 00188 setError( "Select a Display type." ); 00189 return false; 00190 } 00191 if( display_name.size() == 0 ) 00192 { 00193 setError( "Enter a name for the display." ); 00194 return false; 00195 } 00196 if( current_display_names_.find( display_name ) != current_display_names_.end() ) 00197 { 00198 setError( "Name in use. Display names must be unique." ); 00199 return false; 00200 } 00201 setError( "" ); 00202 return true; 00203 } 00204 00205 void NewDisplayDialog::setError( const QString& error_text ) 00206 { 00207 button_box_->button( QDialogButtonBox::Ok )->setToolTip( error_text ); 00208 } 00209 00210 void NewDisplayDialog::onNameChanged() 00211 { 00212 button_box_->button( QDialogButtonBox::Ok )->setEnabled( isValid() ); 00213 } 00214 00215 void NewDisplayDialog::accept() 00216 { 00217 if( isValid() ) 00218 { 00219 *lookup_name_output_ = lookup_name_; 00220 *display_name_output_ = name_editor_->text().toStdString(); 00221 QDialog::accept(); 00222 } 00223 } 00224 00225 } // rviz 00226