00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef wTreeS_hPp
00013 #define wTreeS_hPp
00014
00015 #include <iostream>
00016 #include <iomanip>
00017 #include "ocTypes.h"
00018 #include "ocString.h"
00019 #include "read_base.hpp"
00020 #include "cgiTemplates.h"
00021 #include "Session.hpp"
00022 #include <set>
00023 typedef set< string > expandedNodes;
00024
00025
00026 class baseTreeNode
00027 {
00028 protected:
00029 ostream & webIO;
00030
00031
00032
00033 ocString treeNodeStart;
00034 ocString treeNodeLabel;
00035 ocString activeLeaf;
00036 ocString treeNodeEnd;
00037 int count;
00038 bool isLastNode;
00039
00040 public:
00041 cgiTemplates & treeTemplate;
00042
00043 string treeId;
00044
00045 expandedNodes * pExpandedNodes;
00046
00047 baseTreeNode( cgiTemplates & templateIn, ostream & webIo )
00048 : webIO( webIo ),treeTemplate( templateIn ),count(0),level(0),isLastNode(false),pExpandedNodes(0)
00049 {
00050 treeNodeStart = treeTemplate.getParagraph("treeNodeStart");
00051 treeNodeLabel = treeTemplate.getParagraph("treeLabel");
00052 activeLeaf = treeTemplate.getParagraph("activeLeaf");
00053 treeNodeEnd = treeTemplate.getParagraph("treeNodeEnd");
00054 }
00055 virtual ~baseTreeNode() {;}
00056 virtual bool emit( string filter = "" ){;}
00057
00058
00059 void altActiveLeaf( string leaf )
00060 {
00061 activeLeaf = leaf;
00062 }
00063
00064
00065 ocString fields;
00066 ocString from;
00067 ocString location;
00068
00069
00070 ocString childFilter;
00071 int level;
00072
00073
00074 ocString label;
00075
00076
00077 ocString addLink;
00078 string ParentId;
00079 };
00080
00081 typedef vector<baseTreeNode*> nodeHandlers;
00082
00083 class ocTreeNode: public baseTreeNode
00084 {
00085 public:
00086 nodeHandlers handlers;
00087
00088
00089 ocTreeNode( cgiTemplates & templateIn, ostream & webIo )
00090 :baseTreeNode( templateIn, webIo )
00091 {
00092
00093 }
00094 virtual ~ocTreeNode()
00095 {
00096 for( int hi=0; hi < handlers.size(); hi++ )
00097 {
00098
00099 if( this != handlers[hi] )
00100 {
00101 delete handlers[hi];
00102 }
00103 }
00104 }
00105
00106 virtual void indent( int level )
00107 {
00108 for( int i=0; i>level;++i)
00109 {
00110 webIO << " ";
00111 }
00112 }
00113 string UniqID( string id )
00114 {
00115 ocString ID;
00116 ID.append(level);
00117 ID += "_";
00118 ID += id;
00119 return ID;
00120 }
00121
00122 virtual string NodeStart( int level, string id )
00123 {
00124 return treeNodeStart.replace("$ID",UniqID(id).c_str());
00125 }
00126
00127 virtual string NodeLabel( string name )
00128 {
00129 return treeNodeLabel.replace("$label",name);
00130 }
00131
00132 string buildLeafText( openRS & rs )
00133 {
00134
00135 string label = "";
00136 for( int lx=1; lx<rs.getFieldCount(); lx++ )
00137 {
00138 if( label.length() && rs.getField(lx).format().length() ) label += " - ";
00139 label += rs.getField(lx).format();
00140 }
00141 return label;
00142 }
00143 void emitLeaf( string icoBase, openRS & rs )
00144 {
00145 string id = rs.getField(0).format();
00146 string tempLoc = location.replace("$ID", id );
00147 webIO << activeLeaf.replace("$location", tempLoc)
00148 .replace("$label", buildLeafText(rs) )
00149 .replaceAll("$icon$", icoBase )
00150 .replaceAll("$uid",UniqID(id))
00151 .replace("$treeId$",treeId)
00152 .replace("$ID",id);
00153 }
00154 string Filter( baseTreeNode * child, openRS & rs )
00155 {
00156 string temp;
00157 if( child && child->childFilter.length() )
00158 {
00159 temp = child->childFilter.replace("$ID", rs.getField(0).format() );
00160 }
00161 return temp;
00162 }
00163 virtual bool emit( string filter = "" )
00164 {
00165 bool bRet = false;
00166
00167 quickQuery qqry;
00168 openRS & rs =qqry.getRS();
00169
00170
00171 string qry = "select " + fields;
00172 qry += " from " + from;
00173 qry += filter;
00174
00175 if( addLink.length() )
00176 {
00177
00178 if( label.length() )
00179 {
00180 indent(level );
00181 webIO << NodeLabel( label );
00182 }
00183 }
00184
00185
00186 if( rs.open( qry ) )
00187 {
00188
00189 if( addLink.length() == 0 && label.length() )
00190 {
00191 indent(level );
00192 webIO << NodeLabel( label );
00193 }
00194 bRet = true;
00195 string icoBase;
00196 do
00197 {
00198 string id = rs.getField(0).format();
00199 string tempLoc = location.replace("$ID", id.c_str());
00200 if( handlers.size() )
00201 {
00202 icoBase = "expand";
00203 if( pExpandedNodes && pExpandedNodes->find(id) != pExpandedNodes->end() )
00204 icoBase = "contract";
00205 }
00206 else
00207 icoBase="item";
00208
00209 indent(level);
00210 emitLeaf(icoBase,rs);
00211
00212
00213 if( handlers.size() )
00214 {
00215 indent(level);
00216 webIO << NodeStart( level, id.c_str() );
00217 for( int hi=0; hi<handlers.size(); ++hi )
00218 {
00219 bool doExpand = true;
00220 if( pExpandedNodes )
00221 {
00222
00223 if( pExpandedNodes->find(id) == pExpandedNodes->end() )
00224 {
00225
00226 doExpand = false;
00227 }
00228 }
00229
00230 if( handlers[hi] == this )
00231 {
00232 if( doExpand )
00233 {
00234 string tempPid = ParentId;
00235 handlers[hi]->ParentId = id;
00236 handlers[hi]->level++;
00237 handlers[hi]->emit(Filter(handlers[hi],rs));
00238 level--;
00239 ParentId = tempPid;
00240 }
00241 }
00242 else
00243 {
00244 if( doExpand )
00245 {
00246 handlers[hi]->ParentId = id;
00247 handlers[hi]->emit(Filter(handlers[hi],rs));
00248 }
00249 }
00250 }
00251 indent(level);
00252 webIO << treeNodeEnd;
00253 }
00254 } while( rs.next() );
00255 }
00256
00257 if( addLink.length() )
00258 {
00259 indent(level);
00260 webIO << addLink.replace("$ID",ParentId.c_str());
00261 if( count ) count--;
00262 }
00263 return bRet;
00264 }
00265 };
00266
00267
00268
00269 class ocTreeControl
00270 {
00271 cgiTemplates treeTemplate;
00272 ostream & webIO;
00273 nodeHandlers handlers;
00274
00275
00276 ocString treeTop;
00277 ocString treeEnd;
00278 ocString treeNodeLabel;
00279
00280 string UID;
00281
00282
00283
00284 public:
00285 string Title;
00286
00287 ocTreeControl( string templatePath, ostream & webIo )
00288 :webIO(webIo)
00289 {
00290 treeTemplate.load(templatePath.c_str());
00291 treeTop = treeTemplate.getParagraph("treeTop");
00292 treeEnd = treeTemplate.getParagraph("treeEnd");
00293 treeNodeLabel = treeTemplate.getParagraph("treeLabel");
00294 }
00295 virtual ~ ocTreeControl()
00296 {
00297 for( int hi=0; hi < handlers.size(); hi++ )
00298 {
00299 delete handlers[hi];
00300 }
00301 }
00302
00303
00304 void persistantStates(string uid)
00305 {
00306 UID = uid;
00307 }
00308
00309 ocTreeNode * addHandler( int nodeSequence, ocTreeNode * lastNode = 0 )
00310 {
00311 ocTreeNode * newNode = new ocTreeNode(treeTemplate, webIO );
00312 if( newNode )
00313 {
00314 newNode->level = 0;
00315 newNode->treeId = UID;
00316 if( lastNode )
00317 {
00318 newNode->level = lastNode->level + 1;
00319 lastNode->handlers.push_back( newNode );
00320 }
00321 else
00322 {
00323 handlers.push_back( newNode );
00324 }
00325 }
00326 return newNode;
00327 }
00328 void makeRecursive( int nodeSequence, ocTreeNode * lastNode = 0 )
00329 {
00330 if( lastNode )
00331 {
00332 lastNode->handlers.push_back( lastNode );
00333 }
00334 }
00335 bool emit( string filter = "" )
00336 {
00337 webIO << treeTop.replace("$UID",UID);
00338 Session_Obj sess;
00339 string expanded;
00340 if( UID.length() )
00341 {
00342 expanded = sess.GetData(UID);
00343 }
00344 if( Title.length() )
00345 {
00346 webIO << treeNodeLabel.replace("$label",Title) << endl;
00347 }
00348
00349
00350 for( int hi=0; hi < handlers.size(); hi++ )
00351 {
00352 ocTreeNode * theBase = dynamic_cast<ocTreeNode *>(handlers[0]);
00353 if( theBase ) theBase->emit(filter);
00354 }
00355 string script;
00356 if( expanded.length() )
00357 {
00358 script = " Expand these nodes: \n";
00359 script += " expand('";
00360 script += UID;
00361 script += "',";
00362 script += expanded;
00363 script += ");";
00364 }
00365 webIO << treeEnd.replace("$expando",script);
00366 }
00367 };
00368
00369 #endif
00370
00371 #ifdef IN_T2_TESTHARNESS
00372 {
00373 cgiTemplates templ;
00374
00375 templ.load("wTree.html");
00376
00377 script << templ.getParagraph("top");
00378
00379 ocTreeControl tc( "wTree.html", script );
00380 tc.Title = "Site Tree - Test of tree control";
00381 ocTreeNode * theBase = tc.addHandler( 0 );
00382
00383 if( theBase )
00384 {
00385 theBase->fields = "id, name";
00386 theBase->from = "sites";
00387 theBase->location = "http://devlinux/sys/site_ui.cgi?id=$ID";
00388 theBase->label = "<span style=\"font: bold 12pt arial;text-decoration: underline;\">SITES</span>";
00389 }
00390 ocTreeNode * theNext = tc.addHandler( 1, theBase );
00391 if( theNext )
00392 {
00393 theNext->fields = "id, name";
00394 theNext->from = "pages";
00395 theNext->location = "http://devlinux/sys/page_ui.cgi?id=$ID";
00396 theNext->childFilter = " where site_id = $ID ";
00397 theNext->label = "<span style=\"font: bold 9pt/10pt arial\">PAGES</span>";
00398 }
00399 ocTreeNode * theLast = tc.addHandler( 2, theNext);
00400 if( theLast )
00401 {
00402 theLast->fields = "id, name";
00403 theLast->from = "paragraphs";
00404 theLast->location = "http://devlinux/sys/paragraph_ui.cgi?id=$ID";
00405 theLast->childFilter = " where page_id = $ID ";
00406 theLast->label = "<span style=\"font: bold 8pt/10p arial\">PARAGRAPHS</span>";
00407 }
00408 theLast = tc.addHandler( 3, theNext);
00409 if( theLast )
00410 {
00411 theLast->fields = "pm.id, m.name";
00412 theLast->from = "page_menus pm inner join menus m on pm.menu_id = m.id";
00413 theLast->location = "http://devlinux/sys/page_menu_ui.cgi?id=$ID";
00414 theLast->childFilter = " where page_id = $ID ";
00415 theLast->label = "<span style=\"font: bold 8pt/10p arial\">MENUS</span>";
00416 }
00417 tc.emit();
00418 script << templ.getParagraph("end");
00419 }
00420 #endif
00421
00422