ConfigurationEditor.cc
Go to the documentation of this file.00001 #include "ConfigurationEditor.h"
00002 #include "Behaviors/Controls/NullControl.h"
00003 #include "Shared/plistCollections.h"
00004 #include "Shared/Config.h"
00005 #include "Shared/string_util.h"
00006 #include "Wireless/Wireless.h"
00007 #include <exception>
00008
00009 using namespace std;
00010
00011 void ConfigurationEditor::init() {
00012 if(root==NULL)
00013 setRootCollection(config);
00014 pushSlot(NULL);
00015 }
00016
00017 void ConfigurationEditor::refresh() {
00018 plist::Collection * curcol = (path.size()==0) ? root : dynamic_cast<plist::Collection*>(root->resolveEntry(path));
00019 if(curcol==NULL) {
00020 clearSlots();
00021 pushSlot(new NullControl("[NULL Collection]"));
00022 ControlBase::refresh();
00023 return;
00024 }
00025 for(unsigned int i=0; i<options.size(); ++i) {
00026 if(StringInputControl * input = dynamic_cast<StringInputControl*>(options[i])) {
00027 if(input->getLastInput().size()>0) {
00028 plist::PrimitiveBase * prim=NULL;
00029 if(dynamic_cast<plist::DictionaryBase*>(curcol)) {
00030 std::string key=input->getName();
00031 key=key.substr(0,key.find('='));
00032 prim = dynamic_cast<plist::PrimitiveBase*>(curcol->resolveEntry(key));
00033 if(prim==NULL) {
00034 std::cerr << "ERROR: key " << key << " was set but does not correspond to a primitive value" << std::endl;
00035 continue;
00036 }
00037 } else if(plist::ArrayBase* arr = dynamic_cast<plist::ArrayBase*>(curcol)) {
00038 prim = dynamic_cast<plist::PrimitiveBase*>(&arr->getEntry(i-3));
00039 if(prim==NULL) {
00040 std::cerr << "ERROR: array entry " << i-3 << " is a collection, cannot set value" << std::endl;
00041 continue;
00042 }
00043 } else {
00044 std::cerr << "ERROR: unknown collection type" << std::endl;
00045 break;
00046 }
00047
00048 try {
00049 prim->set(input->getLastInput());
00050 } catch(const std::exception& e) {
00051 std::cerr << "ERROR: unable to set item " << i << " to value " << input->getLastInput() << '\n'
00052 << " An exception occurred: " << e.what() << std::endl;
00053 } catch(...) {
00054 std::cerr << "ERROR: unable to set item '" << i << "' to value '" << input->getLastInput() << "', an exception occurred." << std::endl;
00055 }
00056 }
00057 }
00058 }
00059
00060 for(std::vector<ControlBase*>::iterator it=options.begin(); it!=options.end(); ++it)
00061 if(*it!=NULL && *it!=&load && *it!=&save)
00062 delete *it;
00063 options.clear();
00064 pushSlot(&load);
00065 pushSlot(&save);
00066 pushSlot(NULL);
00067 if(curcol->size()==0) {
00068 pushSlot(new NullControl("[Empty Collection]"));
00069 } else if(plist::DictionaryBase * d = dynamic_cast<plist::DictionaryBase*>(curcol)) {
00070 for(plist::DictionaryBase::const_iterator it=d->begin(); it!=d->end(); ++it) {
00071 if(plist::NamedEnumerationBase * neb = dynamic_cast<plist::NamedEnumerationBase*>(it->second)) {
00072 pushSlot(new NamedEnumerationEditor(it->first+"="+neb->get(),d->getComment(it->first),*neb));
00073 } else if(plist::PrimitiveBase * po = dynamic_cast<plist::PrimitiveBase*>(it->second)) {
00074 pushSlot(new StringInputControl(it->first+"="+po->get(),d->getComment(it->first)));
00075 } else if(dynamic_cast<plist::Collection*>(it->second)) {
00076 ConfigurationEditor * sube = new ConfigurationEditor(it->first,d->getComment(it->first),root);
00077 sube->setPath(path.size()==0 ? it->first : path+plist::Collection::subCollectionSep()+it->first);
00078 pushSlot(sube);
00079 } else {
00080 std::cerr << "WARNING: unknown type for " << it->first << ": " << it->second->toString() << std::endl;
00081 }
00082 }
00083 } else if(plist::ArrayBase * a = dynamic_cast<plist::ArrayBase*>(curcol)) {
00084 for(unsigned int i=0; i<a->size(); ++i) {
00085 if(plist::NamedEnumerationBase * neb = dynamic_cast<plist::NamedEnumerationBase*>(&a->getEntry(i))) {
00086 pushSlot(new NamedEnumerationEditor(neb->get(),a->getComment(i),*neb));
00087 } else if(plist::PrimitiveBase * po = dynamic_cast<plist::PrimitiveBase*>(&a->getEntry(i))) {
00088 pushSlot(new StringInputControl(po->get(),a->getComment(i)));
00089 } else if(dynamic_cast<plist::Collection*>(&a->getEntry(i))) {
00090 stringstream en;
00091 en << "[Entry " << i << "]";
00092 ConfigurationEditor * sube = new ConfigurationEditor(en.str(),a->getComment(i),root);
00093 stringstream ss;
00094 if(path.size()==0)
00095 ss << i;
00096 else
00097 ss << path << plist::Collection::subCollectionSep() << i;
00098 sube->setPath(ss.str());
00099 pushSlot(sube);
00100 } else {
00101 std::cerr << "WARNING: unknown type for entry " << i << ": " << a->getEntry(i).toString() << std::endl;
00102 }
00103 }
00104 }
00105 ControlBase::refresh();
00106 }
00107
00108 void ConfigurationEditor::clearSlots() {
00109
00110 for(std::vector<ControlBase*>::iterator it=options.begin(); it!=options.end(); ++it)
00111 if(*it==&load || *it==&save)
00112 *it=NULL;
00113 ControlBase::clearSlots();
00114 }
00115
00116 void ConfigurationEditor::setRootCollection(plist::Collection* rootCollection) {
00117 if(root==rootCollection)
00118 return;
00119 root=rootCollection;
00120 load.setRootCollection(root);
00121 save.setRootCollection(root);
00122 for(unsigned int i=0; i<options.size(); i++)
00123 if(ConfigurationEditor * confe = dynamic_cast<ConfigurationEditor*>(options[i]))
00124 confe->setRootCollection(root);
00125 }
00126
00127 void ConfigurationEditor::setPath(const std::string& p) {
00128 path=p;
00129 }
00130
00131 plist::Dictionary& ConfigurationEditor::getObjectTemplates() {
00132 static plist::Dictionary dict;
00133 if(dict.size()==0) {
00134
00135 dict.addEntry("float",new plist::Primitive<float>);
00136 dict.addEntry("int",new plist::Primitive<int>);
00137 dict.addEntry("int (unsigned)",new plist::Primitive<unsigned int>);
00138 dict.addEntry("string",new plist::Primitive<std::string>);
00139 dict.addEntry("sub-array",new plist::Array);
00140 dict.addEntry("sub-dictionary",new plist::Dictionary);
00141 }
00142 return dict;
00143 }
00144
00145 ControlBase* ConfigurationEditor::LoadSettings::selectedFile(const std::string& f) {
00146 if(rootcol==NULL) {
00147 std::cerr << "ERROR: Unable to load, no plist::Collection has been provided" << std::endl;
00148 return NULL;
00149 }
00150 rootcol->loadFile(f.c_str());
00151 return NULL;
00152 }
00153 ControlBase* ConfigurationEditor::SaveSettings::selectedFile(const std::string& f) {
00154 if(rootcol==NULL) {
00155 std::cerr << "ERROR: Unable to save, no plist::Collection has been provided" << std::endl;
00156 return NULL;
00157 }
00158 rootcol->saveFile(f.c_str());
00159 return NULL;
00160 }
00161
00162 void ConfigurationEditor::AddCollectionEntry::refresh() {
00163 options.clear();
00164 for(plist::Dictionary::const_iterator it=ConfigurationEditor::getObjectTemplates().begin(); it!=ConfigurationEditor::getObjectTemplates().end(); ++it) {
00165 if(tgt->canContain(*it->second)) {
00166 #ifdef PLATFORM_APERIOS
00167
00168 plist::ObjectBase * cpy = static_cast<plist::ObjectBase*>((void*)it->second->clone());
00169 #else
00170 plist::ObjectBase * cpy = static_cast<plist::ObjectBase*>(it->second->clone());
00171 #endif
00172 pushSlot(new ConfigurationEditor::NewCollectionEntry(it->first,*tgt,*cpy));
00173 }
00174 }
00175 }
00176
00177 void ConfigurationEditor::NewCollectionEntry::refresh() {
00178 std::string key;
00179 if(options.size()>0 && options[0]!=NULL)
00180 key=dynamic_cast<const StringInputControl&>(*options[0]).getLastInput();
00181 options.clear();
00182 StringInputControl * keyEdit=NULL;
00183 if(dynamic_cast<plist::DictionaryBase*>(tgt)) {
00184 keyEdit = new StringInputControl("Key: "+key,"Enter key for the dictionary entry");
00185 } else if(dynamic_cast<plist::ArrayBase*>(tgt)) {
00186 if(key=="")
00187 key="end";
00188 keyEdit = new StringInputControl("Position: "+key,"Enter an index position or keyword 'end', optionally followed by '-n' to offset from the end");
00189 }
00190 keyEdit->takeInput(key);
00191 pushSlot(keyEdit);
00192 if(plist::PrimitiveBase * po = dynamic_cast<plist::PrimitiveBase*>(obj)) {
00193 pushSlot(new StringInputControl(po->get(),"Enter the intial value for the item"));
00194 } else if(plist::Collection * c = dynamic_cast<plist::Collection*>(obj)) {
00195 ConfigurationEditor * sube = new ConfigurationEditor("sub-entries...","Add entries to the new collection",c);
00196 pushSlot(sube);
00197 } else if(obj!=NULL) {
00198 std::cerr << "WARNING: unknown type for NewCollectionEntry editor" << ": " << obj->toString() << std::endl;
00199 }
00200 pushSlot(NULL);
00201 pushSlot(new NullControl("Commit Entry"));
00202 }
00203
00204 ControlBase * ConfigurationEditor::NewCollectionEntry::doSelect() {
00205 if(hilights.size()!=1 || hilights.front()!=options.size()-1)
00206 return ControlBase::doSelect();
00207
00208 if(plist::DictionaryBase* d = dynamic_cast<plist::DictionaryBase*>(tgt)) {
00209 std::string key = dynamic_cast<const StringInputControl&>(*options[0]).getLastInput();
00210 reinterpret_cast<plist::DictionaryBase::EntryConstraint<plist::ObjectBase>*>(d)->addEntry(key,obj);
00211 } else if(plist::ArrayBase* a = dynamic_cast<plist::ArrayBase*>(tgt)) {
00212 std::string key = dynamic_cast<const StringInputControl&>(*options[0]).getLastInput();
00213 int idx;
00214 if(key=="" || string_util::makeLower(key).substr(0,3)=="end") {
00215 idx=a->size();
00216 if(key.size()>3)
00217 idx+=atoi(key.substr(3).c_str());
00218 } else {
00219 idx=atoi(key.c_str()) % (options.size()+1);
00220 if(idx<0)
00221 idx+=options.size()+1;
00222 }
00223 reinterpret_cast<plist::ArrayBase::EntryConstraint<plist::ObjectBase>*>(a)->addEntry(idx,obj);
00224 }
00225 return NULL;
00226 }
00227
00228 void ConfigurationEditor::NamedEnumerationEditor::refresh() {
00229 options.clear();
00230 std::map<int,std::string> names;
00231 tgt->getPreferredNames(names);
00232 for(std::map<int,std::string>::const_iterator it=names.begin(); it!=names.end(); ++it)
00233 pushSlot(new NullControl(it->second));
00234 ControlBase::refresh();
00235 if(gui_comm!=NULL && wireless->isConnected(gui_comm->sock)) {
00236 if(userPrompt.size()>0)
00237 gui_comm->printf("status\n%td\n%s\n",std::count(userPrompt.begin(),userPrompt.end(),'\n'),userPrompt.c_str());
00238 }
00239 }
00240
00241 ControlBase * ConfigurationEditor::NamedEnumerationEditor::doSelect() {
00242 if(hilights.size()!=1)
00243 return this;
00244 clearLastInput();
00245 tgt->set(options[hilights.front()]->getName());
00246 return NULL;
00247 }
00248
00249
00250
00251
00252