00001 #include "mrta/architecture.h" 00002 #include <QFileInfo> 00003 #include <QFileDialog> 00004 #include <QSettings> 00005 #include <ros/console.h> 00006 #include <ros/package.h> 00007 #include "rqt_mrta/config/application/rqt_mrta_application.h" 00008 #include "rqt_mrta/config/application/rqt_mrta_package.h" 00009 #include "rqt_mrta/define_application_widget.h" 00010 #include "rqt_mrta/ui_define_application_widget.h" 00011 #include "utilities/exception.h" 00012 #include "utilities/xml_settings.h" 00013 00014 namespace rqt_mrta 00015 { 00016 DefineApplicationWidget::DefineApplicationWidget( 00017 QWidget* parent, RqtMrtaApplicationConfig* application_config, 00018 RqtMrtaApplicationPackageConfig* metapackage_config) 00019 : QWidget(parent), ui_(new Ui::DefineApplicationWidget()), 00020 application_config_(NULL), package_config_(NULL) 00021 { 00022 if (!application_config) 00023 { 00024 throw utilities::Exception( 00025 "[DefineApplicationWidget] The application config must not be NULL."); 00026 } 00027 if (!metapackage_config) 00028 { 00029 throw utilities::Exception( 00030 "[DefineApplicationWidget] The metapackage config must not be NULL."); 00031 } 00032 rp_.setQuiet(true); 00033 std::vector<std::string> search_path; 00034 rp_.getSearchPathFromEnv(search_path); 00035 rp_.crawl(search_path, true); 00036 ui_->setupUi(this); 00037 ui_->workspace_push_button->setEnabled(false); 00038 connect(ui_->name_line_edit, SIGNAL(textChanged(const QString&)), this, 00039 SLOT(nameChanged(const QString&))); 00040 connect(ui_->package_line_edit, SIGNAL(textChanged(const QString&)), this, 00041 SLOT(packageChanged(const QString&))); 00042 connect(ui_->workspace_push_button, SIGNAL(clicked()), this, 00043 SLOT(workspaceBrowserButtonClicked())); 00044 connect(ui_->workspace_package_line_edit, SIGNAL(textChanged(const QString&)), 00045 this, SLOT(workspaceUrlChanged(const QString&))); 00046 connect(ui_->version_line_edit, SIGNAL(textChanged(const QString&)), this, 00047 SLOT(versionChanged(const QString&))); 00048 connect(ui_->description_plain_text_edit, SIGNAL(textChanged()), this, 00049 SLOT(descriptionChanged())); 00050 connect(ui_->maintainer_line_edit, SIGNAL(textChanged(const QString&)), this, 00051 SLOT(maintainerChanged(const QString&))); 00052 connect(ui_->maintainer_email_line_edit, SIGNAL(textChanged(const QString&)), 00053 this, SLOT(maintainerEmailChanged(const QString&))); 00054 connect(ui_->license_line_edit, SIGNAL(textChanged(const QString&)), this, 00055 SLOT(licenseChanged(const QString&))); 00056 connect(ui_->run_depends_plain_text_edit, SIGNAL(textChanged()), this, 00057 SLOT(runDependsChanged())); 00058 setApplicationConfig(application_config); 00059 setMetapackageConfig(metapackage_config); 00060 } 00061 00062 DefineApplicationWidget::~DefineApplicationWidget() 00063 { 00064 application_config_ = NULL; 00065 package_config_ = NULL; 00066 if (ui_) 00067 { 00068 delete ui_; 00069 ui_ = NULL; 00070 } 00071 } 00072 00073 RqtMrtaApplicationConfig* DefineApplicationWidget::getApplicationConfig() const 00074 { 00075 return application_config_; 00076 } 00077 00078 RqtMrtaApplicationPackageConfig* 00079 DefineApplicationWidget::getMetapackageConfig() const 00080 { 00081 return package_config_; 00082 } 00083 00084 void DefineApplicationWidget::setApplicationConfig( 00085 RqtMrtaApplicationConfig* config) 00086 { 00087 if (application_config_ != config) 00088 { 00089 if (application_config_) 00090 { 00091 disconnect(application_config_, SIGNAL(changed()), this, SIGNAL(changed())); 00092 disconnect(application_config_, SIGNAL(applicationPackageChanged(const QString&)), 00093 this, SLOT(configPackageChanged(const QString&))); 00094 disconnect(application_config_->getApplication(), 00095 SIGNAL(nameChanged(const QString&)), this, 00096 SLOT(configNameChanged(const QString&))); 00097 } 00098 application_config_ = config; 00099 if (application_config_) 00100 { 00101 connect(application_config_, SIGNAL(changed()), this, SIGNAL(changed())); 00102 connect(application_config_, SIGNAL(applicationPackageChanged(const QString&)), this, 00103 SLOT(configPackageChanged(const QString&))); 00104 connect(application_config_->getApplication(), 00105 SIGNAL(nameChanged(const QString&)), this, 00106 SLOT(configNameChanged(const QString&))); 00107 configNameChanged(application_config_->getApplication()->getName()); 00108 configPackageChanged(application_config_->getApplicationPackage()); 00109 if (package_config_ && 00110 package_config_->getDescription().isEmpty()) 00111 { 00112 configDescriptionChanged( 00113 application_config_->getApplication()->getName()); 00114 } 00115 } 00116 } 00117 } 00118 00119 void DefineApplicationWidget::setMetapackageConfig( 00120 RqtMrtaApplicationPackageConfig* config) 00121 { 00122 if (package_config_ != config) 00123 { 00124 if (package_config_) 00125 { 00126 disconnect(package_config_, SIGNAL(changed()), this, SIGNAL(changed())); 00127 disconnect(package_config_, 00128 SIGNAL(workspaceUrlChanged(const QString&)), this, 00129 SLOT(configWorkspaceUrlChanged(const QString&))); 00130 disconnect(package_config_, SIGNAL(nameChanged(const QString&)), this, 00131 SLOT(configPackageChanged(const QString&))); 00132 disconnect(package_config_, SIGNAL(versionChanged(const QString&)), 00133 this, SLOT(configVersionChanged(const QString&))); 00134 disconnect(package_config_, 00135 SIGNAL(descriptionChanged(const QString&)), this, 00136 SLOT(configDescriptionChanged(const QString&))); 00137 disconnect(package_config_, SIGNAL(maintainerChanged(const QString&)), 00138 this, SLOT(configMaintainerChanged(const QString&))); 00139 disconnect(package_config_, 00140 SIGNAL(maintainerEmailChanged(const QString&)), this, 00141 SLOT(configMaintainerEmailChanged(const QString&))); 00142 disconnect(package_config_, SIGNAL(licenseChanged(const QString&)), 00143 this, SLOT(configLicenseChanged(const QString&))); 00144 disconnect(package_config_, 00145 SIGNAL(runDependsChanged(const QStringList&)), this, 00146 SLOT(configRunDependsChanged(const QStringList&))); 00147 } 00148 package_config_ = config; 00149 if (package_config_) 00150 { 00151 connect(package_config_, SIGNAL(changed()), this, SIGNAL(changed())); 00152 connect(package_config_, SIGNAL(workspaceUrlChanged(const QString&)), 00153 this, SLOT(configWorkspaceUrlChanged(const QString&))); 00154 connect(package_config_, SIGNAL(nameChanged(const QString&)), this, 00155 SLOT(configPackageChanged(const QString&))); 00156 connect(package_config_, SIGNAL(versionChanged(const QString&)), this, 00157 SLOT(configVersionChanged(const QString&))); 00158 connect(package_config_, SIGNAL(descriptionChanged(const QString&)), 00159 this, SLOT(configDescriptionChanged(const QString&))); 00160 connect(package_config_, SIGNAL(maintainerChanged(const QString&)), 00161 this, SLOT(configMaintainerChanged(const QString&))); 00162 connect(package_config_, 00163 SIGNAL(maintainerEmailChanged(const QString&)), this, 00164 SLOT(configMaintainerEmailChanged(const QString&))); 00165 connect(package_config_, SIGNAL(licenseChanged(const QString&)), this, 00166 SLOT(configLicenseChanged(const QString&))); 00167 connect(package_config_, 00168 SIGNAL(runDependsChanged(const QStringList&)), this, 00169 SLOT(configRunDependsChanged(const QStringList&))); 00170 configPackageChanged(package_config_->getName()); 00171 configWorkspaceUrlChanged(package_config_->getWorkspaceUrl()); 00172 configVersionChanged(package_config_->getVersion()); 00173 configDescriptionChanged(package_config_->getDescription()); 00174 configMaintainerChanged(package_config_->getMaintainer()); 00175 configMaintainerEmailChanged(package_config_->getMaintainerEmail()); 00176 configLicenseChanged(package_config_->getLicense()); 00177 configRunDependsChanged(package_config_->getRunDepends()); 00178 } 00179 } 00180 ui_->workspace_push_button->setEnabled(package_config_); 00181 } 00182 00183 void DefineApplicationWidget::configWorkspaceUrlChanged(const QString& url) 00184 { 00185 ui_->workspace_package_line_edit->setText(url); 00186 if (url.isEmpty()) 00187 { 00188 ui_->workspace_status_widget->setCurrentRole( 00189 StatusWidget::Error, "The workspace must be given."); 00190 } 00191 else if (package_config_->workspaceExists()) 00192 { 00193 ui_->workspace_status_widget->setCurrentRole(StatusWidget::Okay); 00194 } 00195 else 00196 { 00197 ui_->workspace_status_widget->setCurrentRole( 00198 StatusWidget::Warn, "The given directory is not a ROS workspace."); 00199 } 00200 } 00201 00202 void DefineApplicationWidget::configNameChanged(const QString& name) 00203 { 00204 ui_->name_line_edit->setText(name); 00205 } 00206 00207 void DefineApplicationWidget::configPackageChanged(const QString& package) 00208 { 00209 ui_->package_line_edit->setText(package); 00210 if (package.isEmpty()) 00211 { 00212 ui_->package_status_widget->setCurrentRole( 00213 StatusWidget::Error, "The package name must not be empty."); 00214 } 00215 else if (package.contains(' ')) 00216 { 00217 ui_->package_status_widget->setCurrentRole( 00218 StatusWidget::Error, "The package name must not be empty."); 00219 } 00220 else 00221 { 00222 ui_->package_status_widget->setCurrentRole( 00223 StatusWidget::Busy, "Verifying if the input package exists..."); 00224 std::string package_path; 00225 rp_.find(package.toStdString(), package_path); 00226 if (package_path.empty()) 00227 { 00228 ui_->package_status_widget->setCurrentRole(StatusWidget::Okay); 00229 } 00230 else 00231 { 00232 ui_->package_status_widget->setCurrentRole( 00233 StatusWidget::Error, "The input package already exists."); 00234 } 00235 } 00236 } 00237 00238 void DefineApplicationWidget::configVersionChanged(const QString& version) 00239 { 00240 ui_->version_line_edit->setText(version); 00241 } 00242 00243 void DefineApplicationWidget::configDescriptionChanged( 00244 const QString& description) 00245 { 00246 ui_->description_plain_text_edit->setPlainText(description); 00247 QTextCursor cursor(ui_->description_plain_text_edit->textCursor()); 00248 cursor.movePosition(QTextCursor::End); 00249 ui_->description_plain_text_edit->setTextCursor(cursor); 00250 } 00251 00252 void DefineApplicationWidget::configMaintainerChanged(const QString& name) 00253 { 00254 ui_->maintainer_line_edit->setText(name); 00255 } 00256 00257 void DefineApplicationWidget::configMaintainerEmailChanged(const QString& email) 00258 { 00259 ui_->maintainer_email_line_edit->setText(email); 00260 } 00261 00262 void DefineApplicationWidget::configLicenseChanged(const QString& license) 00263 { 00264 ui_->license_line_edit->setText(license); 00265 } 00266 00267 void DefineApplicationWidget::configRunDependsChanged( 00268 const QStringList& depends) 00269 { 00270 QString text; 00271 if (!depends.isEmpty()) 00272 { 00273 text += depends[0]; 00274 for (size_t i(1); i < depends.count(); i++) 00275 { 00276 text += " " + depends[i]; 00277 } 00278 } 00279 ui_->run_depends_plain_text_edit->setPlainText(text); 00280 QTextCursor cursor(ui_->run_depends_plain_text_edit->textCursor()); 00281 cursor.movePosition(QTextCursor::End); 00282 ui_->run_depends_plain_text_edit->setTextCursor(cursor); 00283 } 00284 00285 void DefineApplicationWidget::workspaceBrowserButtonClicked() 00286 { 00287 QFileDialog dialog(this, "Select the workspace directory", QDir::homePath()); 00288 dialog.setAcceptMode(QFileDialog::AcceptSave); 00289 dialog.setFileMode(QFileDialog::Directory); 00290 dialog.setOption(QFileDialog::ShowDirsOnly); 00291 dialog.setLabelText(QFileDialog::Accept, "Choose"); 00292 if (dialog.exec() == QDialog::Accepted) 00293 { 00294 package_config_->setWorkspaceUrl(dialog.selectedFiles().first()); 00295 } 00296 } 00297 00298 void DefineApplicationWidget::workspaceUrlChanged(const QString& url) 00299 { 00300 if (package_config_) 00301 { 00302 package_config_->setWorkspaceUrl(url); 00303 } 00304 } 00305 00306 void DefineApplicationWidget::nameChanged(const QString& name) 00307 { 00308 if (application_config_) 00309 { 00310 application_config_->getApplication()->setName(name); 00311 } 00312 } 00313 00314 void DefineApplicationWidget::packageChanged(const QString& package) 00315 { 00316 if (application_config_) 00317 { 00318 application_config_->setApplicationPackage(package); 00319 } 00320 if (package_config_) 00321 { 00322 package_config_->setName(package); 00323 } 00324 } 00325 00326 void DefineApplicationWidget::versionChanged(const QString& version) 00327 { 00328 if (package_config_) 00329 { 00330 package_config_->setVersion(version); 00331 } 00332 } 00333 00334 void DefineApplicationWidget::descriptionChanged() 00335 { 00336 if (package_config_) 00337 { 00338 package_config_->setDescription( 00339 ui_->description_plain_text_edit->toPlainText()); 00340 } 00341 } 00342 00343 void DefineApplicationWidget::maintainerChanged(const QString& name) 00344 { 00345 if (package_config_) 00346 { 00347 package_config_->setMaintainer(name); 00348 } 00349 } 00350 00351 void DefineApplicationWidget::maintainerEmailChanged(const QString& email) 00352 { 00353 if (package_config_) 00354 { 00355 package_config_->setMaintainerEmail(email); 00356 } 00357 } 00358 00359 void DefineApplicationWidget::licenseChanged(const QString& license) 00360 { 00361 if (package_config_) 00362 { 00363 package_config_->setLicense(license); 00364 } 00365 } 00366 00367 void DefineApplicationWidget::runDependsChanged() 00368 { 00369 QString depends(ui_->run_depends_plain_text_edit->toPlainText()); 00370 depends.replace('\n', ' '); 00371 if (package_config_) 00372 { 00373 package_config_->clearRunDepends(); 00374 QStringList run_depends(depends.split(' ')); 00375 run_depends.removeAll(""); 00376 for (size_t i(0); i < run_depends.count(); i++) 00377 { 00378 package_config_->addRunDepend(run_depends[i]); 00379 } 00380 if (run_depends.count() == package_config_->countRunDepends()) 00381 { 00382 ui_->run_depends_status_widget->setCurrentRole(StatusWidget::Okay); 00383 } 00384 else 00385 { 00386 ui_->run_depends_status_widget->setCurrentRole( 00387 StatusWidget::Warn, 00388 "Some run dependency(ies) is(are) not ROS package(s)."); 00389 } 00390 } 00391 } 00392 }