00001 #include <QDir> 00002 #include <QStringList> 00003 #include "rqt_mrta/config/configs.h" 00004 #include "rqt_mrta/config/application/robots.h" 00005 #include "utilities/exception.h" 00006 00007 namespace rqt_mrta 00008 { 00009 namespace config 00010 { 00011 Configs::Configs(QObject* parent) : AbstractConfig(parent) {} 00012 00013 Configs::~Configs() 00014 { 00015 for (size_t index(0); index < configs_.count(); index++) 00016 { 00017 if (configs_[index]) 00018 { 00019 delete configs_[index]; 00020 configs_[index] = NULL; 00021 } 00022 } 00023 configs_.clear(); 00024 } 00025 00026 Config* Configs::getConfig(size_t index) const 00027 { 00028 return index < configs_.count() ? configs_[index] : NULL; 00029 } 00030 00031 Config* Configs::getConfig(const QString& id) const 00032 { 00033 for (size_t index(0); index < configs_.count(); index) 00034 { 00035 if (configs_[index]->getId() == id) 00036 { 00037 return configs_[index]; 00038 } 00039 } 00040 return NULL; 00041 } 00042 00043 Config* Configs::addConfig() 00044 { 00045 Config* config = new Config(this); 00046 configs_.append(config); 00047 connect(config, SIGNAL(changed()), this, SLOT(configChanged())); 00048 connect(config, SIGNAL(idChanged(const QString&)), this, 00049 SLOT(configIdChanged(const QString&))); 00050 connect(config, SIGNAL(added(const QString&)), this, 00051 SLOT(configAdded(const QString&))); 00052 connect(config, SIGNAL(removed(const QString&)), this, 00053 SLOT(configRemoved(const QString&))); 00054 connect(config, SIGNAL(cleared(const QString&)), this, 00055 SLOT(configCleared(const QString&))); 00056 connect(config, SIGNAL(nameChanged(const QString&, const QString&)), this, 00057 SLOT(configNameChanged(const QString&, const QString&))); 00058 connect(config, SIGNAL(typeChanged(const QString&, const QMetaType::Type&)), 00059 this, 00060 SLOT(configTypeChanged(const QString&, const QMetaType::Type&))); 00061 connect(config, SIGNAL(valueChanged(const QString&, const QVariant&)), this, 00062 SLOT(configValueChanged(const QString&, const QVariant&))); 00063 connect(config, SIGNAL(defaultValueChanged(const QString&, const QVariant&)), 00064 this, 00065 SLOT(configDefaultValueChanged(const QString&, const QVariant&))); 00066 connect(config, SIGNAL(toolTipChanged(const QString&, const QString&)), this, 00067 SLOT(configToolTipChanged(const QString&, const QString&))); 00068 connect(config, SIGNAL(destroyed()), this, SLOT(configDestroyed())); 00069 emit added(configs_.count() - 1); 00070 emit changed(); 00071 return config; 00072 } 00073 00074 void Configs::removeConfig(Config* config) 00075 { 00076 removeConfig(configs_.indexOf(config)); 00077 } 00078 00079 void Configs::removeConfig(size_t index) 00080 { 00081 if (index >= 0 && index < configs_.count()) 00082 { 00083 QString config_id(configs_[index]->getId()); 00084 configs_.remove(index); 00085 emit removed(config_id); 00086 emit changed(); 00087 } 00088 } 00089 00090 void Configs::clearConfigs() 00091 { 00092 if (!configs_.isEmpty()) 00093 { 00094 for (size_t i(0); i < configs_.count(); ++i) 00095 { 00096 if (configs_[i]) 00097 { 00098 delete configs_[i]; 00099 configs_[i] = NULL; 00100 } 00101 } 00102 configs_.clear(); 00103 emit cleared(); 00104 emit changed(); 00105 } 00106 } 00107 00108 bool Configs::contains(const QString& id) const 00109 { 00110 for (size_t i(0); i < configs_.count(); i++) 00111 { 00112 if (configs_[i]->getId() == id) 00113 { 00114 return true; 00115 } 00116 } 00117 return false; 00118 } 00119 00120 size_t Configs::count() const { return configs_.count(); } 00121 00122 bool Configs::isEmpty() const { return configs_.isEmpty(); } 00123 00124 void Configs::save(QSettings& settings) const 00125 { 00126 settings.beginGroup("configs"); 00127 for (size_t index(0); index < configs_.count(); ++index) 00128 { 00129 settings.beginGroup("config_" + QString::number(index)); 00130 configs_[index]->save(settings); 00131 settings.endGroup(); 00132 } 00133 settings.endGroup(); 00134 } 00135 00136 void Configs::load(QSettings& settings) 00137 { 00138 settings.beginGroup("configs"); 00139 clearConfigs(); 00140 QStringList groups(settings.childGroups()); 00141 for (size_t index(0); index < groups.count(); index++) 00142 { 00143 Config* config = addConfig(); 00144 settings.beginGroup("config_" + QString::number(index)); 00145 config->load(settings); 00146 settings.endGroup(); 00147 } 00148 settings.endGroup(); 00149 } 00150 00151 void Configs::reset() { clearConfigs(); } 00152 00153 void Configs::write(QDataStream& stream) const 00154 { 00155 stream << configs_.count(); 00156 for (size_t index(0); index < configs_.count(); ++index) 00157 { 00158 configs_[index]->write(stream); 00159 } 00160 } 00161 00162 void Configs::read(QDataStream& stream) 00163 { 00164 quint64 count; 00165 stream >> count; 00166 clearConfigs(); 00167 for (size_t index(0); index < count; ++index) 00168 { 00169 configs_[index]->read(stream); 00170 } 00171 } 00172 00173 Configs& Configs::operator=(const Configs& config) 00174 { 00175 while (configs_.count() < config.configs_.count()) 00176 { 00177 addConfig(); 00178 } 00179 while (configs_.count() > config.configs_.count()) 00180 { 00181 removeConfig(configs_.count() - 1); 00182 } 00183 for (size_t index(0); index < configs_.count(); ++index) 00184 { 00185 *configs_[index] = *config.configs_[index]; 00186 } 00187 return *this; 00188 } 00189 00190 void Configs::setConfigs(const Configs& configs, 00191 const application::Robots& robots, 00192 const QString& robots_config_id) 00193 { 00194 clearConfigs(); 00195 Config* robots_config = configs.getConfig(robots_config_id); 00196 for (size_t i(0); i < configs.count(); i++) 00197 { 00198 Config* template_config = configs.getConfig(i); 00199 bool is_robot_template = robots_config && template_config == robots_config; 00200 size_t count = is_robot_template ? robots.count() : 1; 00201 for (size_t j(0); j < count; j++) 00202 { 00203 Config* config = addConfig(); 00204 *config = *template_config; 00205 config->hideArrays(); 00206 if (is_robot_template) 00207 { 00208 config->setId(robots.getRobot(j)->getId() + "_" + config->getId()); 00209 } 00210 } 00211 } 00212 } 00213 00214 QString Configs::validate() const 00215 { 00216 if (configs_.isEmpty()) 00217 { 00218 return "Enter the system robots."; 00219 } 00220 QString validation; 00221 for (size_t i(0); i < configs_.count(); i++) 00222 { 00223 validation = configs_[i]->validate(); 00224 if (!validation.isEmpty()) 00225 { 00226 break; 00227 } 00228 } 00229 return validation; 00230 } 00231 00232 QStringList Configs::willBeGenerated() const 00233 { 00234 QStringList list; 00235 for (size_t index(0); index < configs_.count(); index++) 00236 { 00237 list.append("config/" + configs_[index]->getId() + ".yaml"); 00238 } 00239 return list; 00240 } 00241 00242 void Configs::saveAsYaml(const QString& package_url) const 00243 { 00244 QDir package(package_url); 00245 if (!package.exists()) 00246 { 00247 throw utilities::Exception("Inexistent package."); 00248 } 00249 if (package.cd("config")) 00250 { 00251 package.cd(".."); 00252 } 00253 else if (!package.mkdir("config")) 00254 { 00255 throw utilities::Exception("Unable to create the config folder."); 00256 } 00257 for (size_t index(0); index < configs_.count(); index++) 00258 { 00259 QString validation(configs_[index]->validate()); 00260 if (!validation.isEmpty()) 00261 { 00262 ROS_ERROR("%s", validation.toStdString().c_str()); 00263 continue; 00264 } 00265 configs_[index]->saveAsYaml(package.path() + "/config/" + 00266 configs_[index]->getId()); 00267 } 00268 } 00269 00270 void Configs::configChanged() { emit changed(); } 00271 00272 void Configs::configIdChanged(const QString& config_id) 00273 { 00274 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00275 if (index != -1) 00276 { 00277 emit configIdChanged(index, config_id); 00278 emit changed(); 00279 } 00280 } 00281 00282 void Configs::configAdded(const QString& full_name) 00283 { 00284 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00285 if (index != -1) 00286 { 00287 emit configAdded(index, full_name); 00288 emit changed(); 00289 } 00290 } 00291 00292 void Configs::configRemoved(const QString& full_name) 00293 { 00294 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00295 if (index != -1) 00296 { 00297 emit configRemoved(index, full_name); 00298 emit changed(); 00299 } 00300 } 00301 00302 void Configs::configCleared(const QString& full_name) 00303 { 00304 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00305 if (index != -1) 00306 { 00307 emit configCleared(index, full_name); 00308 emit changed(); 00309 } 00310 } 00311 00312 void Configs::configNameChanged(const QString& previous_name, 00313 const QString& name) 00314 { 00315 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00316 if (index != -1) 00317 { 00318 emit configNameChanged(index, previous_name, name); 00319 emit changed(); 00320 } 00321 } 00322 00323 void Configs::configTypeChanged(const QString& name, 00324 const QMetaType::Type& type) 00325 { 00326 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00327 if (index != -1) 00328 { 00329 emit configTypeChanged(index, name, type); 00330 emit changed(); 00331 } 00332 } 00333 00334 void Configs::configValueChanged(const QString& name, const QVariant& value) 00335 { 00336 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00337 if (index != -1) 00338 { 00339 emit configValueChanged(index, name, value); 00340 emit changed(); 00341 } 00342 } 00343 00344 void Configs::configDefaultValueChanged(const QString& name, 00345 const QVariant& default_value) 00346 { 00347 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00348 if (index != -1) 00349 { 00350 emit configDefaultValueChanged(index, name, default_value); 00351 emit changed(); 00352 } 00353 } 00354 00355 void Configs::configToolTipChanged(const QString& name, const QString& tool_tip) 00356 { 00357 int index(configs_.indexOf(static_cast<Config*>(sender()))); 00358 if (index != -1) 00359 { 00360 emit configToolTipChanged(index, name, tool_tip); 00361 emit changed(); 00362 } 00363 } 00364 00365 void Configs::configDestroyed() 00366 { 00367 Config* config = static_cast<Config*>(sender()); 00368 int index(configs_.indexOf(config)); 00369 if (index != -1) 00370 { 00371 QString config_id(config->getId()); 00372 configs_.remove(index); 00373 emit removed(config_id); 00374 emit changed(); 00375 } 00376 } 00377 } 00378 }