00001
00002
00003
00004 #include <map>
00005 #include <set>
00006 #include <string>
00007
00008 #include "description.hh"
00009 #include "Text.hh"
00010
00015 static string rmWhiteSpaces(const string& s)
00016 {
00017 size_t i = s.find_first_not_of(" \t");
00018 size_t j = s.find_last_not_of(" \t");
00019
00020 if ( (i != string::npos) & (j != string::npos) ) {
00021 return s.substr(i, 1+j-i);
00022 } else {
00023 return "";
00024 }
00025 }
00026
00030 static void extractMetadata(const string& fulllabel, string& label, map<string, set<string> >& metadata)
00031 {
00032 enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
00033 int state = kLabel; int deep = 0;
00034 string key, value;
00035
00036 for (size_t i=0; i < fulllabel.size(); i++) {
00037 char c = fulllabel[i];
00038 switch (state) {
00039 case kLabel :
00040 assert (deep == 0);
00041 switch (c) {
00042 case '\\' : state = kEscape1; break;
00043 case '[' : state = kKey; deep++; break;
00044 default : label += c;
00045 }
00046 break;
00047
00048 case kEscape1 :
00049 label += c;
00050 state = kLabel;
00051 break;
00052
00053 case kEscape2 :
00054 key += c;
00055 state = kKey;
00056 break;
00057
00058 case kEscape3 :
00059 value += c;
00060 state = kValue;
00061 break;
00062
00063 case kKey :
00064 assert (deep > 0);
00065 switch (c) {
00066 case '\\' : state = kEscape2;
00067 break;
00068
00069 case '[' : deep++;
00070 key += c;
00071 break;
00072
00073 case ':' : if (deep == 1) {
00074 state = kValue;
00075 } else {
00076 key += c;
00077 }
00078 break;
00079 case ']' : deep--;
00080 if (deep < 1) {
00081 metadata[rmWhiteSpaces(key)].insert("");
00082 state = kLabel;
00083 key="";
00084 value="";
00085 } else {
00086 key += c;
00087 }
00088 break;
00089 default : key += c;
00090 }
00091 break;
00092
00093 case kValue :
00094 assert (deep > 0);
00095 switch (c) {
00096 case '\\' : state = kEscape3;
00097 break;
00098
00099 case '[' : deep++;
00100 value += c;
00101 break;
00102
00103 case ']' : deep--;
00104 if (deep < 1) {
00105 metadata[rmWhiteSpaces(key)].insert(rmWhiteSpaces(value));
00106 state = kLabel;
00107 key="";
00108 value="";
00109 } else {
00110 value += c;
00111 }
00112 break;
00113 default : value += c;
00114 }
00115 break;
00116
00117 default :
00118 cerr << "ERROR unrecognized state " << state << endl;
00119 }
00120 }
00121 label = rmWhiteSpaces(label);
00122 }
00123
00124
00128 static string xmlize(const string& fullsrc)
00129 {
00130 map<string, set<string> > metadata;
00131 string dst;
00132 string src;
00133
00134 extractMetadata(fullsrc, src, metadata);
00135
00136 for (size_t i=0; i<src.size(); i++) {
00137 if (src[i] == '"' & (i==0 | i==src.size()-1)) {
00138
00139 } else {
00140 switch (src[i]) {
00141 case '<' : dst += "<"; break;
00142 case '>' : dst += ">"; break;
00143 case '&' : dst += "&"; break;
00144 default : dst += src[i];
00145 }
00146 }
00147 }
00148 return dst;
00149 }
00150
00151 void Description::print(int n, ostream& fout)
00152 {
00153 list<string>::iterator s;
00154 list<int>::iterator t;
00155
00156 tab(n,fout); fout << "<faust>";
00157
00158 tab(n+1,fout); fout << "<name>" << xmlize(fName) << "</name>";
00159 tab(n+1,fout); fout << "<author>" << xmlize(fAuthor) << "</author>";
00160 tab(n+1,fout); fout << "<copyright>" << xmlize(fCopyright) << "</copyright>";
00161 tab(n+1,fout); fout << "<license>" << xmlize(fLicense) << "</license>";
00162 tab(n+1,fout); fout << "<version>" << xmlize(fVersion) << "</version>";
00163 tab(n+1,fout); fout << "<inputs>" << fInputs << "</inputs>";
00164 tab(n+1,fout); fout << "<outputs>" << fOutputs << "</outputs>";
00165
00166 tab(n+1,fout); fout << "<ui>";
00167
00168
00169 tab(n+2,fout); fout << "<activewidgets>";
00170 tab(n+3,fout); fout << "<count>" << fActiveWidgetCount << "</count>";
00171 for (s = fActiveLines.begin(); s != fActiveLines.end(); s++) {
00172 tab(n+3, fout); fout << *s;
00173 }
00174 tab(n+2,fout); fout << "</activewidgets>";
00175
00176 tab(n+2,fout);
00177
00178
00179 tab(n+2,fout); fout << "<passivewidgets>";
00180 tab(n+3,fout); fout << "<count>" << fPassiveWidgetCount << "</count>";
00181 for (s = fPassiveLines.begin(); s != fPassiveLines.end(); s++) {
00182 tab(n+3, fout); fout << *s;
00183 }
00184 tab(n+2,fout); fout << "</passivewidgets>";
00185
00186
00187 tab(n+2,fout);
00188
00189
00190 tab(n+2,fout); fout << "<layout>";
00191 for ( t = fLayoutTabs.begin(), s = fLayoutLines.begin();
00192 s != fLayoutLines.end(); t++, s++) {
00193 tab(n+3+*t, fout); fout << *s;
00194 }
00195 tab(n+2,fout); fout << "</layout>";
00196
00197 tab(n+1,fout); fout << "</ui>";
00198
00199
00200 tab(n,fout); fout << "</faust>" << endl;
00201
00202 }
00203
00204 void Description::ui(Tree t)
00205 {
00206 addGroup(0,t);
00207 }
00208
00209
00210 void Description::addGroup(int level, Tree t)
00211 {
00212 Tree label, elements, varname, sig;
00213 const char* groupnames[] = {"vgroup", "hgroup", "tgroup"};
00214
00215 if (isUiFolder(t, label, elements)) {
00216
00217 const int orient = tree2int(left(label));
00218 const char * str = tree2str(right(label));
00219
00220 addLayoutLine(level, subst("<group type=\"$0\">", groupnames[orient]));
00221 addLayoutLine(level+1, subst("<label>$0</label>", xmlize(str)));
00222 while (!isNil(elements)) {
00223 addGroup(level+1, right(hd(elements)));
00224 elements = tl(elements);
00225 }
00226 addLayoutLine(level, "</group>");
00227
00228 } else if (isUiWidget(t, label, varname, sig)) {
00229
00230 int w = addWidget(label, varname, sig);
00231 addLayoutLine(level, subst("<widgetref id=\"$0\" />", T(w)));
00232
00233 } else {
00234
00235 fprintf(stderr, "error in user interface generation 2\n");
00236 exit(1);
00237
00238 }
00239 }
00240
00241 void Description::tab (int n, ostream& fout)
00242 {
00243 fout << '\n';
00244 while (n--) fout << '\t';
00245 }
00246
00247 int Description::addWidget(Tree label, Tree varname, Tree sig)
00248 {
00249 Tree path, c, x, y, z;
00250
00251
00252
00253 if ( isSigButton(sig, path) ) {
00254
00255 fWidgetID++;
00256 fActiveWidgetCount++;
00257 addActiveLine(subst("<widget type=\"button\" id=\"$0\">", T(fWidgetID)));
00258 addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00259 addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00260 addActiveLine("</widget>");
00261
00262 } else if ( isSigCheckbox(sig, path) ) {
00263
00264 fWidgetID++;
00265 fActiveWidgetCount++;
00266 addActiveLine(subst("<widget type=\"checkbox\" id=\"$0\">", T(fWidgetID)));
00267 addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00268 addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00269 addActiveLine("</widget>");
00270
00271 } else if ( isSigVSlider(sig, path,c,x,y,z) ) {
00272
00273 fWidgetID++;
00274 fActiveWidgetCount++;
00275 addActiveLine(subst("<widget type=\"vslider\" id=\"$0\">", T(fWidgetID)));
00276 addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00277 addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00278 addActiveLine(subst("\t<init>$0</init>", T(tree2double(c))));
00279 addActiveLine(subst("\t<min>$0</min>", T(tree2double(x))));
00280 addActiveLine(subst("\t<max>$0</max>", T(tree2double(y))));
00281 addActiveLine(subst("\t<step>$0</step>", T(tree2double(z))));
00282 addActiveLine("</widget>");
00283
00284 } else if ( isSigHSlider(sig, path,c,x,y,z) ) {
00285
00286 fWidgetID++;
00287 fActiveWidgetCount++;
00288 addActiveLine(subst("<widget type=\"hslider\" id=\"$0\">", T(fWidgetID)));
00289 addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00290 addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00291 addActiveLine(subst("\t<init>$0</init>", T(tree2double(c))));
00292 addActiveLine(subst("\t<min>$0</min>", T(tree2double(x))));
00293 addActiveLine(subst("\t<max>$0</max>", T(tree2double(y))));
00294 addActiveLine(subst("\t<step>$0</step>", T(tree2double(z))));
00295 addActiveLine("</widget>");
00296
00297 } else if ( isSigNumEntry(sig, path,c,x,y,z) ) {
00298
00299 fWidgetID++;
00300 fActiveWidgetCount++;
00301 addActiveLine(subst("<widget type=\"nentry\" id=\"$0\">", T(fWidgetID)));
00302 addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00303 addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00304 addActiveLine(subst("\t<init>$0</init>", T(tree2double(c))));
00305 addActiveLine(subst("\t<min>$0</min>", T(tree2double(x))));
00306 addActiveLine(subst("\t<max>$0</max>", T(tree2double(y))));
00307 addActiveLine(subst("\t<step>$0</step>", T(tree2double(z))));
00308 addActiveLine("</widget>");
00309
00310
00311
00312
00313 } else if ( isSigVBargraph(sig,path,x,y,z) ) {
00314
00315 fWidgetID++;
00316 fPassiveWidgetCount++;
00317 addPassiveLine(subst("<widget type=\"vbargraph\" id=\"$0\">", T(fWidgetID)));
00318 addPassiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00319 addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00320 addPassiveLine(subst("\t<min>$0</min>", T(tree2double(x))));
00321 addPassiveLine(subst("\t<max>$0</max>", T(tree2double(y))));
00322 addPassiveLine("</widget>");
00323
00324 } else if ( isSigHBargraph(sig,path,x,y,z) ) {
00325
00326 fWidgetID++;
00327 fPassiveWidgetCount++;
00328 addPassiveLine(subst("<widget type=\"hbargraph\" id=\"$0\">", T(fWidgetID)));
00329 addPassiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00330 addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00331 addPassiveLine(subst("\t<min>$0</min>", T(tree2double(x))));
00332 addPassiveLine(subst("\t<max>$0</max>", T(tree2double(y))));
00333 addPassiveLine("</widget>");
00334
00335 } else {
00336 fprintf(stderr, "Error describing widget : unrecognized expression\n");
00337 exit(1);
00338 }
00339
00340 return fWidgetID;
00341 }
00342
00343
00344