//OpenSCADA module UI.VCAEngine file: origwidg.cpp /*************************************************************************** * Copyright (C) 2006-2021 by Roman Savochenko, * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "origwidg.h" #include "vcaengine.h" using namespace VCA; //************************************************* //* PrWidget: Primitive widget template * //************************************************* PrWidget::PrWidget( const string &iid ) : LWidget(iid) { } void PrWidget::preDisable( int flag ) { if(flag) throw TError(mod->nodePath().c_str(),_("Impossible deleting the base primitive-widget.")); Widget::preDisable(flag); } string PrWidget::ico( ) const { if(LWidget::ico().size()) return LWidget::ico(); if(TUIS::icoGet("VCA.wdg_"+id(),NULL,true).size()) return TSYS::strEncode(TUIS::icoGet("VCA.wdg_"+id()),TSYS::base64); return ""; } void PrWidget::setEnable( bool val, bool force ) { if(enable() == val) return; LWidget::setEnable(val); //Init active attributes if(val) { vector ls; attrList(ls); for(unsigned iL = 0; iL < ls.size(); iL++) { AutoHD attr = attrAt(ls[iL]); if(!(attr.at().flgGlob()&Attr::Active)) continue; attr.at().setS(attr.at().getS(),true); attr.at().setModif(0); attrList(ls); } } } bool PrWidget::cntrCmdGeneric( XMLNode *opt ) { //Get page info if(opt->name() == "info") { Widget::cntrCmdGeneric(opt); ctrMkNode("oscada_cntr", opt, -1, "/", TSYS::strMess(_("Base widget '%s'."),id().c_str())); ctrMkNode("fld", opt, -1, "/wdg/st/parent", _("Parent"), R_R_R_, owner().c_str(),grp().c_str(), 2, "tp","str", "dest",""); return true; } //Process command to page string a_path = opt->attr("path"); if(a_path == "/wdg/st/parent" && ctrChkNode(opt,"get",R_R_R_,owner().c_str(),grp().c_str(),SEC_RD)) opt->setText(parentNm()); else return Widget::cntrCmdGeneric(opt); return true; } void PrWidget::cntrCmdProc( XMLNode *opt ) { if(cntrCmdServ(opt)) return; //Get page info if(opt->name() == "info") { cntrCmdGeneric(opt); cntrCmdAttributes(opt ); return; } //Process command to page if(!(cntrCmdGeneric(opt) || cntrCmdAttributes(opt))) TCntrNode::cntrCmdProc(opt); } //************************************************* //* Original widgets based at primitive * //* widget template * //************************************************* //* OrigElFigure: * //* Elementary figure original widget * //************************************************* OrigElFigure::OrigElFigure( ) : PrWidget("ElFigure") { } string OrigElFigure::name( ) const { return _("Elementary figure"); } string OrigElFigure::descr( ) const { return _("Widget of the elementary figure of the finite visualization."); } void OrigElFigure::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("lineWdth",_("Line: width"),TFld::Integer,TFld::NoFlag,"","1","0;99","",i2s(A_ElFigLineW).c_str())); attrAdd(new TFld("lineClr",_("Line: color"),TFld::String,Attr::Color,"","#000000","","",i2s(A_ElFigLineClr).c_str())); attrAdd(new TFld("lineStyle",_("Line: style"),TFld::Integer,TFld::Selectable,"","0", TSYS::strMess("%d;%d;%d",EF_SOLID,EF_DASH,EF_DOT).c_str(),_("Solid;Dashed;Dotted"),i2s(A_ElFigLineStl).c_str())); attrAdd(new TFld("bordWdth",_("Border: width"),TFld::Integer,TFld::NoFlag,"","0","0;99","",i2s(A_ElFigBordW).c_str())); attrAdd(new TFld("bordClr",_("Border: color"),TFld::String,Attr::Color,"","#000000","","",i2s(A_ElFigBordClr).c_str())); attrAdd(new TFld("fillColor",_("Fill: color"),TFld::String,Attr::Color,"","","","",i2s(A_ElFigFillClr).c_str())); attrAdd(new TFld("fillImg",_("Fill: image"),TFld::String,Attr::Image,"","","","",i2s(A_ElFigFillImg).c_str())); attrAdd(new TFld("orient",_("Orientation angle"),TFld::Integer,TFld::NoFlag,"","0","-360;360","",i2s(A_ElFigOrient).c_str())); attrAdd(new TFld("mirror",_("Mirroring"),TFld::Boolean,TFld::NoFlag,"","0","","",i2s(A_ElFigMirror).c_str())); attrAdd(new TFld("elLst",_("Elements list"),TFld::String,TFld::FullText|Attr::Active,"","","","",i2s(A_ElFigElLst).c_str())); } } bool OrigElFigure::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt,src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_ElFigLineClr: case A_ElFigBordClr: case A_ElFigFillClr: el->setAttr("help",Widget::helpColor()); break; case A_ElFigFillImg: el->setAttr("help",Widget::helpImg()); break; case A_ElFigElLst: el->setAttr("SnthHgl","1")->setAttr("help", _("The elements list can contain:\n" " line:({x}|{y}):({x}|{y})[:{width}[:{color}[:{bord_w}[:{bord_clr}[:{line_stl}]]]]]\n" " line:{p1}:{p2}[:w{n}[:c{n}[:w{n}[:c{n}[:s{n}]]]]]\n" " arc:({x}|{y}):({x}|{y}):({x}|{y}):({x}|{y}):({x}|{y})[:{width}[:{color}[:{bord_w}[:{bord_clr}[:{line_stl}]]]]]\n" " arc:{p1}:{p2}:{p3}:{p4}:{p5}[:w{n}[:c{n}[:w{n}[:c{n}[:s{n}]]]]]\n" " bezier:({x}|{y}):({x}|{y}):({x}|{y}):({x}|{y})[:{width}[:{color}[:{bord_w}[:{bord_clr}[:{line_stl}]]]]]\n" " bezier:{p1}:{p2}:{p3}:{p4}[:w{n}[:c{n}[:w{n}[:c{n}[:s{n}]]]]]\n" " fill:({x}|{y}):({x}|{y}):...:({x}|{y})[:{fill_clr}[:{fill_img}]]\n" " fill:{p1}:{p2}:...:{pN}[:c{n}[:i{n}]]\n" "Where:\n" " x, y - direct point (x,y), coordinate in float point pixels;\n" " p1 ... pN - dynamic point 1...n;\n" " width, bord_w - direct line and border width in float point pixels;\n" " w{n} - dynamic width 'n';\n" " color, bord_clr, fill_clr - direct line, border and fill color name or 32bit code whith alpha: {name}[-{AAA}], #RRGGBB-AAA;\n" " c{n} - dynamic color 'n';\n" " line_stl - direct line style: 0-Solid, 1-Dashed, 2-Dotted;\n" " s{n} - dynamic style 'n';\n" " fill_img - direct image of the filling in the form \"[{src}:]{name}\", where:\n" " \"src\" - image source:\n" " file - directly from a local file by the path;\n" " res - from table of DB-mime resources.\n" " \"name\" - file path or mime-resource identifier.\n" " i{n} - dynamic image of the filling 'n'.\n" "For example:\n" " line:(50|25):(90.5|25):2:yellow:3:green:2\n" " arc:(25|50):(25|50):1:4:(25|50)::#000000-0\n" " fill:(25|50):(25|50):c2:i2\n" " fill:(50|25):(90.5|25):(90|50):(50|50):#d3d3d3:h_31")); default: switch((p-A_ElFigIts)%A_ElFigItsSz) { case A_ElFigItClr: el->setAttr("help",Widget::helpColor()); break; case A_ElFigItImg: el->setAttr("help",Widget::helpImg()); break; } break; } } return true; } //Process command to page string a_path = opt->attr("path"); if(a_path == "/attr/elLst" && ctrChkNode(opt,"SnthHgl",RWRWR_,"root",SUI_ID,SEC_RD)) { opt->childAdd("rule")->setAttr("expr","\\:")->setAttr("color","darkblue")->setAttr("font_weight","1"); opt->childAdd("rule")->setAttr("expr","^(arc|line|fill|bezier):")->setAttr("color","darkorange")->setAttr("font_weight","1"); opt->childAdd("rule")->setAttr("expr","\\(\\d*\\.?\\d+\\|\\d*\\.?\\d+\\)")->setAttr("color","#3D87FF")-> childAdd("rule")->setAttr("expr","\\d*\\.?\\d+")->setAttr("color","blue"); opt->childAdd("rule")->setAttr("expr","\\#([0-9a-fA-F]{6}\\-\\d+|[0-9a-fA-F]{6})")->setAttr("color","blue"); } else return Widget::cntrCmdAttributes(opt,src); return true; } bool OrigElFigure::attrChange( Attr &cfg, TVariant prev ) { if((cfg.flgGlob()&Attr::Active) && cfg.id() == "elLst") { string sel, sel1; string ls_prev = prev.getS(); map pntls, pntls_prev, wls, wls_prev, clrls, clrls_prev, imgls, imgls_prev, lstls, lstls_prev; //Parse last attributes list and make point list for(int iP = 0; iP < 2; iP++) { string ls_w = (iP == 0) ? ls_prev : cfg.getS(); map &pntls_w = (iP == 0) ? pntls_prev : pntls; map &wls_w = (iP == 0) ? wls_prev : wls; map &clrls_w = (iP == 0) ? clrls_prev : clrls; map &imgls_w = (iP == 0) ? imgls_prev : imgls; map &lstls_w = (iP == 0) ? lstls_prev : lstls; for(int off = 0; (sel=TSYS::strSepParse(ls_w,0,'\n',&off)).size(); ) { int offe = 0; string fTp = TSYS::strSepParse(sel,0,':',&offe); if(fTp == "line" || fTp == "arc" || fTp == "bezier") { int np = (fTp=="arc") ? 5 : ((fTp=="bezier") ? 4 : 2); for(int i = 0; i < np; i++) pntls_w[s2i(TSYS::strSepParse(sel,0,':',&offe))] = true; if((sel1=TSYS::strSepParse(sel,0,':',&offe)).size() && sel1[0] == 'w') wls_w[s2i(sel1.substr(1))] = true; if((sel1=TSYS::strSepParse(sel,0,':',&offe)).size() && sel1[0] == 'c') clrls_w[s2i(sel1.substr(1))] = true; if((sel1=TSYS::strSepParse(sel,0,':',&offe)).size() && sel1[0] == 'w') wls_w[s2i(sel1.substr(1))] = true; if((sel1=TSYS::strSepParse(sel,0,':',&offe)).size() && sel1[0] == 'c') clrls_w[s2i(sel1.substr(1))] = true; if((sel1=TSYS::strSepParse(sel,0,':',&offe)).size() && sel1[0] == 's') lstls_w[s2i(sel1.substr(1))] = true; } else if(fTp == "fill") for(int zPnt = 0; !(sel1=TSYS::strSepParse(sel,0,':',&offe)).empty() || zPnt < 2; ) { if(sel1.empty()) zPnt++; if(sel1[0] == 'c') clrls_w[s2i(sel1.substr(1))] = true; else if(sel1[0] == 'i') imgls_w[s2i(sel1.substr(1))] = true; } } } //Add new dynamic items // Add no present dynamic points for(map::iterator it = pntls.begin(); it != pntls.end(); ++it) if(it->first && pntls_prev.find(it->first) == pntls_prev.end() && !cfg.owner()->attrPresent("p"+i2s(it->first)+"x")) { cfg.owner()->attrAdd(new TFld(("p"+i2s(it->first)+"x").c_str(),(_("Point ")+i2s(it->first)+":x").c_str(), TFld::Real,Attr::Mutable,"","0","","",i2s(A_ElFigIts+it->first*A_ElFigItsSz+A_ElFigItPntX).c_str())); cfg.owner()->attrAdd(new TFld(("p"+i2s(it->first)+"y").c_str(),(_("Point ")+i2s(it->first)+":y").c_str(), TFld::Real,Attr::Mutable,"","0","","",i2s(A_ElFigIts+it->first*A_ElFigItsSz+A_ElFigItPntY).c_str())); } // Add no present dynamic widths for(map::iterator it = wls.begin(); it != wls.end(); ++it) if(it->first && wls_prev.find(it->first) == wls_prev.end() && !cfg.owner()->attrPresent("w"+i2s(it->first))) cfg.owner()->attrAdd(new TFld(("w"+i2s(it->first)).c_str(),(_("Width ")+i2s(it->first)).c_str(), TFld::Real,Attr::Mutable,"","1","","",i2s(A_ElFigIts+it->first*A_ElFigItsSz+A_ElFigItW).c_str())); // Add no present dynamic colors for(map::iterator it = clrls.begin(); it != clrls.end(); ++it) if(it->first && clrls_prev.find(it->first) == clrls_prev.end() && !cfg.owner()->attrPresent("c"+i2s(it->first))) cfg.owner()->attrAdd(new TFld(("c"+i2s(it->first)).c_str(),(_("Color ")+i2s(it->first)).c_str(), TFld::String,Attr::Mutable|Attr::Color,"","","","",i2s(A_ElFigIts+it->first*A_ElFigItsSz+A_ElFigItClr).c_str())); //>> Add no present dynamic images for(map::iterator it = imgls.begin(); it != imgls.end(); ++it) if(it->first && imgls_prev.find(it->first) == imgls_prev.end() && !cfg.owner()->attrPresent("i"+i2s(it->first))) cfg.owner()->attrAdd(new TFld(("i"+i2s(it->first)).c_str(),(_("Image ")+i2s(it->first)).c_str(), TFld::String,Attr::Mutable|Attr::Image,"","","","",i2s(A_ElFigIts+it->first*A_ElFigItsSz+A_ElFigItImg).c_str())); // Add no present line styles for(map::iterator it = lstls.begin(); it != lstls.end(); ++it) if(it->first && lstls_prev.find(it->first) == lstls_prev.end() && !cfg.owner()->attrPresent("s"+i2s(it->first))) cfg.owner()->attrAdd(new TFld(("s"+i2s(it->first)).c_str(),(_("Style ")+i2s(it->first)).c_str(), TFld::Integer,Attr::Mutable|TFld::Selectable,"","0", TSYS::strMess("%d;%d;%d",EF_SOLID,EF_DASH,EF_DOT).c_str(),_("Solid;Dashed;Dotted"), i2s(A_ElFigIts+it->first*A_ElFigItsSz+A_ElFigItStl).c_str())); //Delete no dynamic items // Delete dynamic points for(map::iterator it = pntls_prev.begin(); it != pntls_prev.end(); ++it) if(it->first && pntls.find(it->first) == pntls.end()) { cfg.owner()->attrDel("p"+i2s(it->first)+"x"); cfg.owner()->attrDel("p"+i2s(it->first)+"y"); } // Delete dynamic widths for(map::iterator it = wls_prev.begin(); it != wls_prev.end(); ++it) if(it->first && wls.find(it->first) == wls.end()) cfg.owner()->attrDel("w"+i2s(it->first)); // Delete dynamic colors for(map::iterator it = clrls_prev.begin(); it != clrls_prev.end(); ++it) if(it->first && clrls.find(it->first) == clrls.end()) cfg.owner()->attrDel("c"+i2s(it->first)); //>> Delete dynamic images for(map::iterator it = imgls_prev.begin(); it != imgls_prev.end(); ++it) if(it->first && imgls.find(it->first) == imgls.end()) cfg.owner()->attrDel("i"+i2s(it->first)); // Delete dynamic line styles for(map::iterator it = lstls_prev.begin(); it != lstls_prev.end(); ++it) if(it->first && lstls.find(it->first) == lstls.end()) cfg.owner()->attrDel("s"+i2s(it->first)); } return Widget::attrChange(cfg, prev); } //************************************************* //* OrigFormEl: Form element original widget * //************************************************* OrigFormEl::OrigFormEl( ) : PrWidget("FormEl") { } string OrigFormEl::name( ) const { return _("Form element"); } string OrigFormEl::descr( ) const { return _("Form element widget of the finite visualization."); } void OrigFormEl::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("elType",_("Element type"),TFld::Integer,TFld::Selectable|Attr::Active,"2","0", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d",F_LINE_ED,F_TEXT_ED,F_CHECK_BOX,F_BUTTON,F_COMBO,F_LIST,F_TREE,F_TABLE,F_SLIDER,F_SCROLL_BAR).c_str(), _("Line edit;Text edit;Check box;Button;Combo box;List;Tree;Table;Slider;Scroll Bar"),i2s(A_FormElType).c_str())); attrAt("name").at().fld().setReserve(i2s(A_FormElName)); } } bool OrigFormEl::attrChange( Attr &cfg, TVariant prev ) { if((cfg.flgGlob()&Attr::Active) && cfg.id() == "elType") { //Delete specific attributes if(cfg.getI() != prev.getI()) switch(prev.getI()) { case F_LINE_ED: cfg.owner()->attrDel("value"); cfg.owner()->attrDel("view"); cfg.owner()->attrDel("cfg"); cfg.owner()->attrDel("confirm"); cfg.owner()->attrDel("font"); break; case F_TEXT_ED: cfg.owner()->attrDel("value"); cfg.owner()->attrDel("wordWrap"); cfg.owner()->attrDel("confirm"); cfg.owner()->attrDel("font"); break; case F_CHECK_BOX: cfg.owner()->attrDel("value"); cfg.owner()->attrDel("font"); break; case F_BUTTON: cfg.owner()->attrDel("value"); cfg.owner()->attrDel("img"); cfg.owner()->attrDel("color"); cfg.owner()->attrDel("colorText"); cfg.owner()->attrDel("mode"); cfg.owner()->attrDel("font"); break; case F_TABLE: cfg.owner()->attrDel("set"); case F_COMBO: case F_LIST: case F_TREE: cfg.owner()->attrDel("value"); cfg.owner()->attrDel("items"); cfg.owner()->attrDel("font"); break; case F_SLIDER: case F_SCROLL_BAR: cfg.owner()->attrDel("value"); cfg.owner()->attrDel("cfg"); break; } //Create specific attributes switch(cfg.getI()) { case F_LINE_ED: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::String,TFld::TransltText|Attr::Mutable,"200","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("view",_("View"),TFld::Integer,TFld::Selectable|Attr::Mutable|Attr::Active,"1","0", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d",FL_TEXT,FL_COMBO,FL_INTEGER,FL_REAL,FL_TIME,FL_DATE,FL_DATE_TM,FL_PASS).c_str(), _("Text;Combo;Integer;Real;Time;Date;Date and time;Password"),i2s(A_FormElMixP1).c_str())); cfg.owner()->attrAdd(new TFld("cfg",_("Configuration"),TFld::String,TFld::FullText|TFld::TransltText|Attr::Mutable,"","","","",i2s(A_FormElMixP2).c_str())); cfg.owner()->attrAdd(new TFld("confirm",_("Confirm"),TFld::Boolean,Attr::Mutable,"","1","","",i2s(A_FormElMixP3).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); break; case F_TEXT_ED: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::String,TFld::FullText|TFld::TransltText|Attr::Mutable,"","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("wordWrap",_("Word wrap"),TFld::Boolean,Attr::Mutable,"1","1","","",i2s(A_FormElMixP1).c_str())); cfg.owner()->attrAdd(new TFld("confirm",_("Confirm"),TFld::Boolean,Attr::Mutable,"","1","","",i2s(A_FormElMixP3).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); break; case F_CHECK_BOX: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::Boolean,Attr::Mutable,"","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); break; case F_BUTTON: cfg.owner()->attrAdd(new TFld("value",_("Repeat"),TFld::String,TFld::TransltText|Attr::Mutable,"","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("img",_("Image"),TFld::String,Attr::Image|Attr::Mutable,"","","","",i2s(A_FormElMixP1).c_str())); cfg.owner()->attrAdd(new TFld("color",_("Color: button"),TFld::String,Attr::Color|Attr::Mutable,"20","","","",i2s(A_FormElMixP2).c_str())); cfg.owner()->attrAdd(new TFld("colorText",_("Color: text"),TFld::String,Attr::Color|Attr::Mutable,"20","","","",i2s(A_FormElMixP4).c_str())); cfg.owner()->attrAdd(new TFld("mode",_("Mode"),TFld::Integer,TFld::Selectable|Attr::Mutable|Attr::Active,"1","0", TSYS::strMess("%d;%d;%d;%d;%d",FBT_STD,FBT_CHECK,FBT_MENU,FBT_LOAD,FBT_SAVE).c_str(), _("Standard;Checkable;Menu;Load;Save"),i2s(A_FormElMixP3).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); break; case F_TABLE: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::String,TFld::TransltText|Attr::Mutable,"255","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("items",_("Items"),TFld::String,TFld::FullText|TFld::TransltText|Attr::Mutable,"","","","",i2s(A_FormElMixP1).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); cfg.owner()->attrAdd(new TFld("set",_("Set value"),TFld::String,Attr::Mutable,"255","","","",i2s(A_FormElMixP2).c_str())); break; case F_LIST: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::String,TFld::FullText|TFld::TransltText|Attr::Mutable,"255","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("items",_("Items"),TFld::String,TFld::FullText|TFld::TransltText|Attr::Mutable,"","","","",i2s(A_FormElMixP1).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); cfg.owner()->attrAdd(new TFld("mult",_("Multiple selection"),TFld::Boolean,Attr::Mutable,"1","0","","",i2s(A_FormElMixP2).c_str())); break; case F_COMBO: case F_TREE: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::String,TFld::TransltText|Attr::Mutable,"255","","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("items",_("Items"),TFld::String,TFld::TransltText|TFld::FullText|Attr::Mutable,"","","","",i2s(A_FormElMixP1).c_str())); cfg.owner()->attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_FormElFont).c_str())); break; case F_SLIDER: case F_SCROLL_BAR: cfg.owner()->attrAdd(new TFld("value",_("Value"),TFld::Integer,Attr::Mutable,"20","0","","",i2s(A_FormElValue).c_str())); cfg.owner()->attrAdd(new TFld("cfg",_("Configuration"),TFld::String,Attr::Mutable,"100","0:0:100:1:10","","",i2s(A_FormElMixP1).c_str())); break; } } //Value type change else if((cfg.flgGlob()&Attr::Active) && ((cfg.id() == "view" && cfg.owner()->attrAt("elType").at().getI() == F_LINE_ED) || (cfg.id() == "mode" && cfg.owner()->attrAt("elType").at().getI() == F_BUTTON))) { unsigned mdfSt = cfg.owner()->attrAt("value").at().modif(); TFld::Type ntp = TFld::String; int flg = Attr::Mutable; Attr::SelfAttrFlgs sflg = cfg.owner()->attrAt("value").at().flgSelf(); string val = cfg.owner()->attrAt("value").at().getS(); string cfgTmpl = cfg.owner()->attrAt("value").at().cfgTempl(); string cfgVal = cfg.owner()->attrAt("value").at().cfgVal(); string vName = _("Value"); if(cfg.id() == "view") switch(cfg.getI()) { case FL_INTEGER: case FL_TIME: ntp = TFld::Integer; break; case FL_REAL: ntp = TFld::Real; break; case FL_DATE: case FL_DATE_TM: ntp = TFld::Integer; flg |= Attr::DateTime; break; default: flg |= TFld::TransltText; break; } else // mode switch(cfg.getI()) { case FBT_STD: ntp = TFld::String; vName = _("Repeat"); break; case FBT_CHECK: ntp = TFld::Boolean; vName = _("Check"); break; case FBT_MENU: ntp = TFld::String; flg |= TFld::FullText; vName = _("Items"); break; case FBT_LOAD: case FBT_SAVE: ntp = TFld::String; flg |= TFld::FullText; vName = _("File content"); break; } int apos = cfg.owner()->attrPos("value"); cfg.owner()->attrDel("value"); cfg.owner()->attrAdd(new TFld("value",vName.c_str(),ntp,flg,"200","","","",i2s(A_FormElValue).c_str()), apos); cfg.owner()->attrAt("value").at().setFlgSelf(sflg); cfg.owner()->attrAt("value").at().setS(val); cfg.owner()->attrAt("value").at().setCfgTempl(cfgTmpl); cfg.owner()->attrAt("value").at().setCfgVal(cfgVal); cfg.owner()->attrAt("value").at().setModif(mdfSt); //!!!! Restore the original modification state } return Widget::attrChange(cfg, prev); } bool OrigFormEl::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt, src); XMLNode *root, *el; int elTp = 0; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) switch((elTp=src->attrAt("elType").at().getI())) { case F_LINE_ED: if((el=ctrId(root,"/font",true))) el->setAttr("help",Widget::helpFont()); if(!(el=ctrId(root,"/cfg",true))) break; switch(src->attrAt("view").at().getI()) { case FL_TEXT: el->setAttr("help",_("Enter text line by the template with the char items:\n" " 'A' - ASCII alphabetic character required. A-Z, a-z.\n" " 'a' - ASCII alphabetic character permitted but not required.\n" " 'N' - ASCII alphanumeric character required. A-Z, a-z, 0-9.\n" " 'n' - ASCII alphanumeric character permitted but not required.\n" " 'X' - Any character required.\n" " 'x' - Any character permitted but not required.\n" " '9' - ASCII digit required. 0-9.\n" " '0' - ASCII digit permitted but not required.\n" " 'D' - ASCII digit required. 1-9.\n" " 'd' - ASCII digit permitted but not required (1-9).\n" " '#' - ASCII digit or plus/minus sign permitted but not required.\n" " 'H' - Hexadecimal character required. A-F, a-f, 0-9.\n" " 'h' - Hexadecimal character permitted but not required.\n" " 'B' - Binary character required. 0-1.\n" " 'b' - Binary character permitted but not required.\n" " '>' - All following alphabetic characters are uppercased.\n" " '<' - All following alphabetic characters are lowercased.\n" " '!' - Switch off case conversion.\n" " '\\' - Use to escape the special characters listed above to use them as separators.")); break; case FL_COMBO: el->setAttr("help",_("List of values the editable combobox by lines.")); break; case FL_INTEGER: el->setAttr("help",_("Integer value configuration in the form: \"{Min}:{Max}:{ChangeStep}:{Prefix}:{Suffix}\".")); break; case FL_REAL: el->setAttr("help",_("Real value configuration in the form: \"{Min}:{Max}:{ChangeStep}:{Prefix}:{Suffix}:{SignsAfterDot}\".")); break; case FL_TIME: case FL_DATE: case FL_DATE_TM: el->setAttr("help",_("Enter date and/or time by the template with the items:\n" " \"d\" - number of the day (1-31);\n" " \"dd\" - number of the day (01-31);\n" " \"ddd\" - acronym of the day ('Mon' ... 'Sun');\n" " \"dddd\" - the full name of the day ('Monday' ... 'Sunday');\n" " \"M\" - number of the month (1-12);\n" " \"MM\" - number of the month (01-12);\n" " \"MMM\" - acronym of the month ('Jan' ... 'Dec');\n" " \"MMMM\" - the full name of the month ('January' ... 'December');\n" " \"yy\" - the last two digits of the year;\n" " \"yyyy\" - the full year;\n" " \"h\" - hour (0-23);\n" " \"hh\" - hour (00-23);\n" " \"m\" - minutes (0-59);\n" " \"mm\" - minutes (00-59);\n" " \"s\" - seconds (0-59);\n" " \"ss\" - seconds (00-59);\n" " \"AP,ap\" - to display AM/PM or am/pm.")); break; } break; case F_TEXT_ED: case F_CHECK_BOX: if((el=ctrId(root,"/font",true))) el->setAttr("help",Widget::helpFont()); break; case F_BUTTON: if((el=ctrId(root,"/img",true))) el->setAttr("help",Widget::helpImg()); if((el=ctrId(root,"/color",true))) el->setAttr("help",Widget::helpColor()); if((el=ctrId(root,"/colorText",true))) el->setAttr("help",Widget::helpColor()); if((el=ctrId(root,"/font",true))) el->setAttr("help",Widget::helpFont()); if((el=ctrId(root,"/mode",true))) el->setAttr("help", _("Operation modes of the button:\n" " \"Standard\" - standard button with the ability to repeat the events when hold (the parameters in \"value\");\n" " \"Checkable\" - checkable button (the value in \"value\");\n" " \"Menu\" - opening menu by click (the list of items in \"value\");\n" " \"Load\" - provides user downloading of small files through the visualization interface;\n" " at the push of a button, in this mode, the dialog opens the file selection for download,\n" " and the content of the selected file is loaded to the attribute \"value\";\n" " \"Save\" - provides user saving small files through the interface of visualization;\n" " after the contents of the file have been written to the \"value\" attribute,\n" " a dialog will be opened for selecting-defining a file to save, after which the contents\n" " of the attribute \"value\" will be saved to the file and it will be cleared itself.")); if((el=ctrId(root,"/value",true))) switch(src->attrAt("mode").at().getI()) { case FBT_STD: el->setAttr("help", _("Parameters of the repeating of the events at holding the button \"{delay}-{interval}\", time in milliseconds.")); break; case FBT_CHECK:el->setAttr("help", _("Value of the toggle.")); break; case FBT_MENU: el->setAttr("help", _("List of menu items in the form \"/grp1/grp2/item1\".")); break; case FBT_LOAD: el->setAttr("help", _("First line of the descriptor \"{FilesTemplate}|{Header}|{FileByDefaultAndLoaded}|{FileMime}\" and the loaded file content from the next line.\n" "The files template writing like to \"Images (*.png *.xpm *.jpg);;CSV-file (*.csv)\".")); break; case FBT_SAVE: el->setAttr("help", _("First line of the descriptor \"{FilesTemplate}|{Header}|{FileByDefault}|{FileMime}\" and the saving file content from the next line.\n" "The files template writing like to \"Images (*.png *.xpm *.jpg);;CSV-file (*.csv)\".")); break; } break; case F_COMBO: case F_LIST: case F_TREE: if((el=ctrId(root,"/items",true))) el->setAttr("help", (elTp==F_TREE)?_("List of the hierarchical items by the path \"/{DIR}/{DIR}/{ITEM}\" per line."):_("List of items-values by lines.")); if((el=ctrId(root,"/font",true))) el->setAttr("help",Widget::helpFont()); break; case F_SLIDER: case F_SCROLL_BAR: if((el=ctrId(root,"/cfg",true))) el->setAttr("help", _("Configuration of the slider in the format: \"{VertOrient}:{Min}:{Max}:{SinglStep}:{PageStep}\".\n" "Where:\n" " \"VertOrient\" - sign of the vertical orientation, the default one is the horizontal orientation;\n" " \"Min\" - minimum value;\n" " \"Max\" - maximum value;\n" " \"SinglStep\" - the size of a single step;\n" " \"PageStep\" - the size of the page step.")); break; case F_TABLE: if((el=ctrId(root,"/items",true))) el->setAttr("SnthHgl","1")->setAttr("help", _("XML tag \"tbl\" for the table fill:\n" " \n" " {Header1}{Header2}\n" " {Row1Column1String}{Row1Column1Integer}\n" " {Row2Column1Logical}{Row2Column2Real}\n" " \n" "Tags:\n" " tbl - Table, the properties at all:\n" " sel - selection mode of the table items:\n" " \"row\" - by rows, \"col\" - by columns, \"cell\" - by cells (by default);\n" " keyID - row-column number of the key, for the selection value get;\n" " colsWdthFit - fits the columns (in the unfixed size) size to fill the full width of the table;\n" " hHdrVis, vHdrVis - visibility of the headers, for horizontal and vertical;\n" " sortEn - enables sorting directly by the columns.\n" " h - Row of the headers. Possible attributes of the header cell tag for the column as a whole:\n" " width - column width, in pixels or percents (10%);\n" " edit - allowing to the cells of the row edition (0 or 1), by default - no (0);\n" " color - column color as a whole into the color name or code;\n" " colorText - color of the column text as a whole into the color name or code;\n" " font - font of the column text in the typical OpenSCADA string;\n" " prec - value precision of the real type cells in the column;\n" " sort - sorting by the column [0 - Descending; 1 - Ascending];\n" " align - alignment the column for: \"left\", \"right\" and \"center\".\n" " r - Row of the values. Possible attributes of the row cell tag for the row as a whole:\n" " color - row color as a whole into the color name or code;\n" " colorText - color of the row text as a whole into the color name or code;\n" " font - font of the row text in the typical OpenSCADA string;\n" " prec - value precision of the real type cells in the row.\n" " s, t, i, r, b - cells of the data types \"String\", \"Text\", \"Integer\", \"Real\" and \"Logical\". Possible attributes:\n" " color - cell color;\n" " colorText - color of the cell text into the color name or code;\n" " font - font of the cell text in the typical OpenSCADA string;\n" " prec - value precision of the real type cell;\n" " img - image of the cell into the form \"[{src}:]{name}\";\n" " edit - allowing the cell edition (0 or 1), by default - no (0);\n" " align - alignment the cell for: \"left\", \"right\" and \"center\".")); if((el=ctrId(root,"/font",true))) el->setAttr("help",Widget::helpFont()); break; } return true; } //Process command to page string a_path = opt->attr("path"); if(a_path == "/attr/items" && ctrChkNode(opt,"SnthHgl",RWRWR_,"root",SUI_ID,SEC_RD)) { opt->childAdd("blk")->setAttr("beg","")->setAttr("color","gray")->setAttr("font_italic","1"); opt->childAdd("blk")->setAttr("beg","<\\?")->setAttr("end","\\?>")->setAttr("color","#666666"); XMLNode *tag = opt->childAdd("blk")->setAttr("beg","<\\w+")->setAttr("end","\\/?>")->setAttr("font_weight","1"); tag->childAdd("rule")->setAttr("expr","\\b\\w+[ ]*(?==)")->setAttr("color","blue"); tag->childAdd("rule")->setAttr("expr","[ ]?\"[^\"]+\"")->setAttr("color","darkgreen"); tag->childAdd("rule")->setAttr("expr","[ ]?'[^']+'")->setAttr("color","darkgreen"); opt->childAdd("rule")->setAttr("expr","<\\/[\\w]+>")->setAttr("font_weight","1"); opt->childAdd("rule")->setAttr("expr","&([a-zA-Z]*|#\\d*);")->setAttr("color","#AF7E00"); } else return Widget::cntrCmdAttributes(opt, src); return true; } bool OrigFormEl::eventProc( const string &ev, Widget *src ) { int elTp = 0; switch((elTp=src->attrAt("elType").at().getI())) { case F_TABLE: { if(ev.compare(0,13,"ws_TableEdit_") != 0 || src->attrAt("items").at().getS().size() > limUserFile_SZ) //Do not apply to the representer after some size break; bool setOK = false; int col = s2i(TSYS::strParse(ev,2,"_")); int row = s2i(TSYS::strParse(ev,3,"_")); XMLNode items("tbl"); items.load(src->attrAt("items").at().getS(), XMLNode::LD_Full); for(int iChR = 0, iR = 0; iChR < (int)items.childSize() && !setOK; iChR++) { XMLNode *chRN = items.childGet(iChR); if(chRN->name() != "r") continue; for(int iChC = 0, iC = 0; iChC < (int)chRN->childSize() && !setOK; iChC++) { XMLNode *chCN = chRN->childGet(iChC); if(!(chCN->name() == "s" || chCN->name() == "t" || chCN->name() == "r" || chCN->name() == "i" || chCN->name() == "b")) continue; if(iC == col && iR == row) { chCN->setText(src->attrAt("set").at().getS(),true); setOK = true; } iC++; } iR++; } if(setOK) src->attrAt("items").at().setS(items.save()); break; } } return false; } //************************************************ //* OrigText: Text element original widget * //************************************************ OrigText::OrigText( ) : PrWidget("Text") { } string OrigText::name( ) const { return _("Text field"); } string OrigText::descr( ) const { return _("Text field widget of the finite visualization."); } void OrigText::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("backColor",_("Background: color"),TFld::String,Attr::Color,"","","","",i2s(A_BackColor).c_str())); attrAdd(new TFld("backImg",_("Background: image"),TFld::String,Attr::Image,"","","","",i2s(A_BackImg).c_str())); attrAdd(new TFld("bordWidth",_("Border: width"),TFld::Integer,TFld::NoFlag,"","0","","",i2s(A_BordWidth).c_str())); attrAdd(new TFld("bordColor",_("Border: color"),TFld::String,Attr::Color,"","#000000","","",i2s(A_BordColor).c_str())); attrAdd(new TFld("bordStyle",_("Border: style"),TFld::Integer,TFld::Selectable,"","3", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d;%d",FBRD_NONE,FBRD_DOT,FBRD_DASH,FBRD_SOL,FBRD_DBL,FBRD_GROOVE,FBRD_RIDGE,FBRD_INSET,FBRD_OUTSET).c_str(), _("None;Dotted;Dashed;Solid;Double;Groove;Ridge;Inset;Outset"),i2s(A_BordStyle).c_str())); attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"50","Arial 11","","",i2s(A_TextFont).c_str())); attrAdd(new TFld("color",_("Color"),TFld::String,Attr::Color,"20","#000000","","",i2s(A_TextColor).c_str())); attrAdd(new TFld("orient",_("Orientation angle"),TFld::Integer,TFld::NoFlag,"3","0","-360;360","",i2s(A_TextOrient).c_str())); attrAdd(new TFld("wordWrap",_("Word wrap"),TFld::Boolean,TFld::NoFlag,"1","1","","",i2s(A_TextWordWrap).c_str())); attrAdd(new TFld("alignment",_("Alignment"),TFld::Integer,TFld::Selectable,"1","0", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d",FT_TOP_LEFT,FT_TOP_RIGHT,FT_TOP_CENTER,FT_TOP_JUST, FT_BT_LEFT,FT_BT_RIGHT,FT_BT_CENTER,FT_BT_JUST,FT_CNTR_LEFT,FT_CNTR_RIGHT,FT_CNTR,FT_CNTR_JUST).c_str(), _("Top left;Top right;Top center;Top justify;" "Bottom left;Bottom right;Bottom center;Bottom justify;" "V center left;V center right;Center;V center justify"),i2s(A_TextAlignment).c_str())); attrAdd(new TFld("inHtml",_("In HTML"),TFld::Boolean,Attr::Active,"1","0","","",i2s(A_TextHTML).c_str())); attrAdd(new TFld("text",_("Text"),TFld::String,TFld::TransltText|TFld::FullText,"","Text","","",i2s(A_TextText).c_str())); attrAdd(new TFld("numbArg",_("Arguments number"),TFld::Integer,Attr::Active,"","0","0;20","",i2s(A_TextNumbArg).c_str())); } } bool OrigText::attrChange( Attr &cfg, TVariant prev ) { if(cfg.flgGlob()&Attr::Active) { int aid = s2i(cfg.fld().reserve()); if(cfg.id() == "numbArg") { string fid("arg"), fnm(_("Argument ")), fidp, fnmp; //Delete specific unnecessary attributes of parameters for(int iP = 0; true; iP++) { fidp = fid+i2s(iP); if(!cfg.owner()->attrPresent(fidp+"val")) break; else if(iP >= cfg.getI()) { cfg.owner()->attrDel(fidp+"val"); cfg.owner()->attrDel(fidp+"tp"); cfg.owner()->attrDel(fidp+"cfg"); } } //Create ullage attributes of parameters for(int iP = 0; iP < cfg.getI(); iP++) { fidp = fid+i2s(iP); fnmp = fnm+i2s(iP); if(cfg.owner()->attrPresent(fidp+"val")) continue; cfg.owner()->attrAdd(new TFld((fidp+"tp").c_str(),(fnmp+_(": type")).c_str(), TFld::Real,TFld::Selectable|Attr::Mutable|Attr::Active,"","0", TSYS::strMess("%d;%d;%d",FT_INT,FT_REAL,FT_STR).c_str(),_("Integer;Real;String"), i2s(A_TextArs+A_TextArsTp+A_TextArsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"val").c_str(),(fnmp+_(": value")).c_str(), TFld::Integer,Attr::Mutable,"","","","",i2s(A_TextArs+A_TextArsVal+A_TextArsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"cfg").c_str(),(fnmp+_(": config")).c_str(), TFld::String,Attr::Mutable,"","","","",i2s(A_TextArs+A_TextArsCfg+A_TextArsSz*iP).c_str())); } } else if(aid >= A_TextArs && (aid%A_TextArsSz) == A_TextArsTp && prev.getI() != cfg.getI()) { int narg = (aid-A_TextArs)/A_TextArsSz; string fid = "arg"+i2s(narg)+"val"; string fnm = _("Argument ")+i2s(narg)+_(": value"); int apos = cfg.owner()->attrPos(fid); VCA::Attr::SelfAttrFlgs sflg = cfg.owner()->attrAt(fid).at().flgSelf(); cfg.owner()->attrDel(fid); cfg.owner()->attrAdd(new TFld(fid.c_str(),fnm.c_str(), (cfg.getI()==1) ? TFld::Real : ((cfg.getI()==2) ? TFld::String : TFld::Integer), ((cfg.getI()==2)?TFld::TransltText:0)|Attr::Mutable,"","","","",i2s(A_TextArs+A_TextArsSz*narg).c_str()), apos); cfg.owner()->attrAt(fid).at().setFlgSelf(sflg); } } return Widget::attrChange(cfg,prev); } bool OrigText::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt, src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) { for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_BackColor: case A_BordColor: case A_TextColor: el->setAttr("help",Widget::helpColor()); break; case A_TextFont: el->setAttr("help",Widget::helpFont()); break; case A_BackImg: el->setAttr("help",Widget::helpImg()); break; case A_TextText: { bool inHTML = src->attrAt("inHtml").at().getB(); if(inHTML) el->setAttr("SnthHgl","1")->setAttr("help",_("Text value in HTML. Use \"%{x}\" for argument \"x\" (from 1) value insert.")); else el->setAttr("SnthHgl","1")->setAttr("help",_("Text value. Use \"%{x}\" for argument \"x\" (from 1) value insert.")); break; } } } for(int iArg = 0; iArg < src->attrAt("numbArg").at().getI(); iArg++) { if(!(el=ctrId(root,"/arg"+i2s(iArg)+"cfg",true))) continue; switch(src->attrAt("arg"+i2s(iArg)+"tp").at().getI()) { case A_TextArsVal: el->setAttr("help",_("Integer value configuration in the form \"{len}\"."));break; case A_TextArsTp: el->setAttr("help",_("Real value configuration in the form: \"{width};{form};{prec}\".\n" "Where \"form\" is 'g', 'e' or 'f'.")); break; case A_TextArsCfg: el->setAttr("help",_("String value configuration in the form \"{len}\".")); break; } } } return true; } //Process command to page string a_path = opt->attr("path"); if(a_path == "/attr/text" && ctrChkNode(opt,"SnthHgl",RWRWR_,"root",SUI_ID,SEC_RD)) { opt->childAdd("rule")->setAttr("expr","%[0-9]")->setAttr("color","darkcyan"); if(src->attrAt("inHtml").at().getB()) { opt->childAdd("blk")->setAttr("beg","")->setAttr("color","gray")->setAttr("font_italic","1"); XMLNode *tag = opt->childAdd("blk")->setAttr("beg","<\\?")->setAttr("end","\\?>")->setAttr("color","#666666"); tag = opt->childAdd("blk")->setAttr("beg","<\\w+")->setAttr("end","\\/?>")->setAttr("font_weight","1"); tag->childAdd("rule")->setAttr("expr","\\b\\w+[ ]*(?==)")->setAttr("color","blue"); tag->childAdd("rule")->setAttr("expr","[ ]?\"[^\"]+\"")->setAttr("color","darkgreen"); tag->childAdd("rule")->setAttr("expr","[ ]?'[^']+'")->setAttr("color","darkgreen"); opt->childAdd("rule")->setAttr("expr","\\%\\d*);")->setAttr("color","cyan"); opt->childAdd("rule")->setAttr("expr","<\\/[\\w]+>")->setAttr("font_weight","1"); opt->childAdd("rule")->setAttr("expr","&([a-zA-Z]*|#\\d*);")->setAttr("color","#AF7E00"); } } else return Widget::cntrCmdAttributes(opt, src); return true; } //************************************************ //* OrigMedia: Media view original widget * //************************************************ OrigMedia::OrigMedia( ) : PrWidget("Media") { } string OrigMedia::name( ) const { return _("Media"); } string OrigMedia::descr( ) const{ return _("Media widget of the finite visualization."); } void OrigMedia::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("backColor",_("Background: color"),TFld::String,Attr::Color,"","#FFFFFF","","",i2s(A_BackColor).c_str())); attrAdd(new TFld("backImg",_("Background: image"),TFld::String,Attr::Image,"","","","",i2s(A_BackImg).c_str())); attrAdd(new TFld("bordWidth",_("Border: width"),TFld::Integer,TFld::NoFlag,"","0","","",i2s(A_BordWidth).c_str())); attrAdd(new TFld("bordColor",_("Border: color"),TFld::String,Attr::Color,"","#000000","","",i2s(A_BordColor).c_str())); attrAdd(new TFld("bordStyle",_("Border: style"),TFld::Integer,TFld::Selectable,"","3", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d;%d",FBRD_NONE,FBRD_DOT,FBRD_DASH,FBRD_SOL,FBRD_DBL,FBRD_GROOVE,FBRD_RIDGE,FBRD_INSET,FBRD_OUTSET).c_str(), _("None;Dotted;Dashed;Solid;Double;Groove;Ridge;Inset;Outset"),i2s(A_BordStyle).c_str())); attrAdd(new TFld("src",_("Source"),TFld::String,0,"50","","","",i2s(A_MediaSrc).c_str())); attrAdd(new TFld("type",_("Type"),TFld::Integer,TFld::Selectable|Attr::Active,"1","0", TSYS::strMess("%d;%d;%d;%d",FM_IMG,FM_ANIM,FM_VIDEO,FM_AUDIO).c_str(),_("Image;Animation;Video;Audio"),i2s(A_MediaType).c_str())); attrAdd(new TFld("areas",_("Map areas"),TFld::Integer,Attr::Active,"2","0","0;100","",i2s(A_MediaAreas).c_str())); } } bool OrigMedia::attrChange( Attr &cfg, TVariant prev ) { if(cfg.flgGlob()&Attr::Active) { if(cfg.id() == "type") { //Delete specific attributes switch(prev.getI()) { case FM_IMG: cfg.owner()->attrDel("fit"); break; case FM_ANIM: cfg.owner()->attrDel("fit"); cfg.owner()->attrDel("speed"); break; case FM_VIDEO: case FM_AUDIO: cfg.owner()->attrDel("play"); cfg.owner()->attrDel("roll"); cfg.owner()->attrDel("pause"); cfg.owner()->attrDel("size"); cfg.owner()->attrDel("seek"); cfg.owner()->attrDel("volume"); break; } //Create specific attributes switch(cfg.getI()) { case FM_IMG: cfg.owner()->attrAdd(new TFld("fit",_("Fit to the widget size"),TFld::Boolean,Attr::Mutable,"","","","",i2s(A_MediaFit).c_str())); break; case FM_ANIM: cfg.owner()->attrAdd(new TFld("fit",_("Fit to the widget size"),TFld::Boolean,Attr::Mutable,"","","","",i2s(A_MediaFit).c_str())); cfg.owner()->attrAdd(new TFld("speed",_("Play speed"),TFld::Integer,Attr::Mutable,"","100","1;900","",i2s(A_MediaSpeedPlay).c_str())); break; case FM_VIDEO: case FM_AUDIO: cfg.owner()->attrAdd(new TFld("play",_("Play"),TFld::Boolean,Attr::Mutable,"","0","","",i2s(A_MediaSpeedPlay).c_str())); cfg.owner()->attrAdd(new TFld("roll",_("Roll play"),TFld::Boolean,Attr::Mutable,"","0","","",i2s(A_MediaRoll).c_str())); cfg.owner()->attrAdd(new TFld("pause",_("Pause"),TFld::Boolean,Attr::Mutable,"","0","","",i2s(A_MediaPause).c_str())); cfg.owner()->attrAdd(new TFld("size",_("Size"),TFld::Real,Attr::Mutable,"","0","0;1e300","",i2s(A_MediaSize).c_str())); cfg.owner()->attrAdd(new TFld("seek",_("Seek"),TFld::Real,Attr::Mutable,"","0","0;1e300","",i2s(A_MediaSeek).c_str())); cfg.owner()->attrAdd(new TFld("volume",_("Volume"),TFld::Real,Attr::Mutable,"","50","0;100","",i2s(A_MediaVolume).c_str())); break; } } else if(cfg.id() == "areas") { string fid("area"), fnm(_("Area ")), fidp, fnmp; //Delete specific unnecessary attributes of map areas for(int iP = 0; true; iP++) { fidp = fid+i2s(iP); if(!cfg.owner()->attrPresent(fidp+"shp")) break; else if(iP >= cfg.getI()) { cfg.owner()->attrDel(fidp+"shp"); cfg.owner()->attrDel(fidp+"coord"); cfg.owner()->attrDel(fidp+"title"); } } //Create ullage attributes of map areas for(int iP = 0; iP < cfg.getI(); iP++) { fidp = fid+i2s(iP); fnmp = fnm+i2s(iP); if(cfg.owner()->attrPresent(fidp+"shp")) continue; cfg.owner()->attrAdd(new TFld((fidp+"shp").c_str(),(fnmp+_(": shape")).c_str(),TFld::Integer,TFld::Selectable|Attr::Mutable,"1","0", TSYS::strMess("%d;%d;%d",FM_RECT,FM_POLY,FM_CIRCLE).c_str(),_("Rect;Poly;Circle"),i2s(A_MediaArs+A_MediaArShape+A_MediaArsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"coord").c_str(),(fnmp+_(": coordinates")).c_str(),TFld::String,Attr::Mutable,"","", "","",i2s(A_MediaArs+A_MediaArCoord+A_MediaArsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"title").c_str(),(fnmp+_(": title")).c_str(),TFld::String,TFld::TransltText|Attr::Mutable,"","", "","",i2s(A_MediaArs+A_MediaArTitle+A_MediaArsSz*iP).c_str())); } } } return Widget::attrChange(cfg,prev); } bool OrigMedia::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt,src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) { for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_BackColor: case A_BordColor: el->setAttr("help",Widget::helpColor()); break; case A_BackImg: el->setAttr("help",Widget::helpImg()); break; case A_MediaSrc: el->setAttr("dest","sel_ed")->setAttr("select","/attrImg/sel_"+el->attr("id"))->setAttr("help", _("Name of the media source in the form \"[{src}:]{name}\", where:\n" " \"src\" - source:\n" " file - directly from a local file (for visualizator or engine) by the path;\n" " res - from table of DB-mime resources;\n" " stream - stream URL to play video and audio.\n" " \"name\" - file path or mime-resource identifier.\n" "Examples:\n" " \"res:workMedia\" - from the table of DB-mime resources for the ID \"workMedia\";\n" " \"workMedia\" - like to the previous;\n" " \"file:/var/tmp/workMedia.mng\" - from a local file by the path \"/var/tmp/workMedia.mng\";\n" " \"stream:http://localhost.localhost:5050\" - playing the stream video and audio from the URL.")); break; case A_MediaType: el->setAttr("help", _("Media type variant:\n" " \"Image\" - raster or vector image, like to: PNG, JPEG, GIF, SVG;\n" " \"Animation\" - simple animation image, like to: GIF, MNG;\n" " \"Full video\" - full video, audio or stream, like to: OGG, OGM, AVI, MKV, MPG, MP3, MP4.")); break; } } for(int iA = 0; iA < src->attrAt("areas").at().getI(); iA++) { el = ctrId(root,TSYS::strMess("/area%dcoord",iA),true); if(!el) continue; switch(src->attrAt(TSYS::strMess("area%dshp",iA)).at().getI()) { case FM_RECT: el->setAttr("help",_("Rectangle area in the form \"x1,y1,x2,y2\".")); break; case FM_POLY: el->setAttr("help",_("Polygon area in the form \"x1,y1,x2,y2,xN,yN\".")); break; case FM_CIRCLE: el->setAttr("help",_("Circle area in the form \"x,y,r\".")); break; } } } return true; } //Process command to page return Widget::cntrCmdAttributes(opt,src); } //************************************************ //* OrigDiagram: Diagram original widget * //************************************************ OrigDiagram::OrigDiagram( ) : PrWidget("Diagram") { } string OrigDiagram::name( ) const { return _("Diagram"); } string OrigDiagram::descr( ) const { return _("Diagram widget of the finite visualization."); } void OrigDiagram::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("backColor",_("Background: color"),TFld::String,Attr::Color,"","black","","",i2s(A_BackColor).c_str())); attrAdd(new TFld("backImg",_("Background: image"),TFld::String,Attr::Image,"","","","",i2s(A_BackImg).c_str())); attrAdd(new TFld("bordWidth",_("Border: width"),TFld::Integer,TFld::NoFlag,"","0","","",i2s(A_BordWidth).c_str())); attrAdd(new TFld("bordColor",_("Border: color"),TFld::String,Attr::Color,"","#000000","","",i2s(A_BordColor).c_str())); attrAdd(new TFld("bordStyle",_("Border: style"),TFld::Integer,TFld::Selectable,"","3", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d;%d",FBRD_NONE,FBRD_DOT,FBRD_DASH,FBRD_SOL,FBRD_DBL,FBRD_GROOVE,FBRD_RIDGE,FBRD_INSET,FBRD_OUTSET).c_str(), _("None;Dotted;Dashed;Solid;Double;Groove;Ridge;Inset;Outset"),i2s(A_BordStyle).c_str())); attrAdd(new TFld("trcPer",_("Tracing period, seconds"),TFld::Real,TFld::NoFlag,"","0","0;360","",i2s(A_DiagramTrcPer).c_str())); attrAdd(new TFld("type",_("Type"),TFld::Integer,TFld::Selectable|Attr::Active,"1","0", TSYS::strMess("%d;%d;%d",FD_TRND,FD_SPECTR,FD_XY).c_str(),_("Trend;Spectrum;XY"),i2s(A_DiagramType).c_str())); } } bool OrigDiagram::attrChange( Attr &cfg, TVariant prev ) { if(!(cfg.flgGlob()&Attr::Active)) return Widget::attrChange(cfg, prev); if(cfg.id() == "active" && cfg.getB() != prev.getB()) { if(!cfg.getB()) { cfg.owner()->attrDel("curSek"); cfg.owner()->attrDel("curUSek"); cfg.owner()->attrDel("curColor"); } else { cfg.owner()->attrAdd(new TFld("curSek",_("Cursor: seconds"),TFld::Integer,Attr::DateTime|Attr::Mutable,"","","","",i2s(A_DiagramCurSek).c_str())); cfg.owner()->attrAdd(new TFld("curUSek",_("Cursor: microseconds"),TFld::Integer,Attr::Mutable,"","","","",i2s(A_DiagramCurUSek).c_str())); cfg.owner()->attrAdd(new TFld("curColor",_("Cursor: color"),TFld::String,Attr::Color|Attr::Mutable,"","white","","",i2s(A_DiagramCurColor).c_str())); } } else if(cfg.id() == "type") { //Delete specific attributes switch(prev.getI()) { case FD_TRND: if(!(cfg.getI() == FD_TRND)) cfg.owner()->attrDel("sclHorPer"); } // Create specific attributes switch(cfg.getI()) { case FD_TRND: cfg.owner()->attrAdd(new TFld("sclHorPer",_("Scale: horizontal grid size, seconds"),TFld::Real,Attr::Mutable, "","0","0;3e6","",i2s(A_DiagramSclHorPer).c_str())); case FD_SPECTR: case FD_XY: cfg.owner()->attrAdd(new TFld("tSek",_("Time: seconds"),TFld::Integer,Attr::DateTime|Attr::Mutable,"","","","",i2s(A_DiagramTSek).c_str())); cfg.owner()->attrAdd(new TFld("tUSek",_("Time: microseconds"),TFld::Integer,Attr::Mutable,"","","","",i2s(A_DiagramTUSek).c_str())); cfg.owner()->attrAdd(new TFld("tSize",_("Size, seconds"),TFld::Real,Attr::Mutable,"","60","0;32e6","",i2s(A_DiagramTSize).c_str())); if(cfg.owner()->attrAt("active").at().getB()) { cfg.owner()->attrAdd(new TFld("curSek",_("Cursor: seconds"),TFld::Integer,Attr::DateTime|Attr::Mutable,"","","","",i2s(A_DiagramCurSek).c_str())); cfg.owner()->attrAdd(new TFld("curUSek",_("Cursor: microseconds"),TFld::Integer,Attr::Mutable,"","","","",i2s(A_DiagramCurUSek).c_str())); cfg.owner()->attrAdd(new TFld("curColor",_("Cursor: color"),TFld::String,Attr::Color|Attr::Mutable,"","white","","",i2s(A_DiagramCurColor).c_str())); } cfg.owner()->attrAdd(new TFld("sclColor",_("Scale: color"),TFld::String,Attr::Color|Attr::Mutable,"","grey","","",i2s(A_DiagramSclColor).c_str())); cfg.owner()->attrAdd(new TFld("sclHor",_("Scale: horizontal"),TFld::Integer,Attr::Mutable|TFld::Selectable,"1",i2s(FD_NO).c_str(), TSYS::strMess("%d;%d;%d;%d;%d;%d;%d",FD_NO,FD_GRD,FD_MARKS,FD_GRD_MARKS,FD_GRD_LOG,FD_MARKS_LOG,FD_GRD_MARKS_LOG).c_str(), _("No draw;Grid;Markers;Grid and markers;Grid (log);Markers (log);Grid and markers (log)"),i2s(A_DiagramSclHor).c_str())); cfg.owner()->attrAdd(new TFld("sclHorScl",_("Scale: horizontal scale (%)"),TFld::Real,Attr::Mutable,"","100","10;1000","",i2s(A_DiagramSclHorScl).c_str())); cfg.owner()->attrAdd(new TFld("sclHorSclOff",_("Scale: horizontal scale offset (%)"),TFld::Real,Attr::Mutable,"","0","-100;100","",i2s(A_DiagramSclHorSclOff).c_str())); cfg.owner()->attrAdd(new TFld("sclVer",_("Scale: vertical"),TFld::Integer,Attr::Mutable|TFld::Selectable,"1",i2s(FD_NO).c_str(), TSYS::strMess("%d;%d;%d;%d;%d;%d;%d",FD_NO,FD_GRD,FD_MARKS,FD_GRD_MARKS,FD_GRD_LOG,FD_MARKS_LOG,FD_GRD_MARKS_LOG).c_str(), _("No draw;Grid;Markers;Grid and markers;Grid (log);Markers (log);Grid and markers (log)"),i2s(A_DiagramSclVer).c_str())); cfg.owner()->attrAdd(new TFld("sclVerScl",_("Scale: vertical scale (%)"),TFld::Real,Attr::Mutable,"","100","10;1000","",i2s(A_DiagramSclVerScl).c_str())); cfg.owner()->attrAdd(new TFld("sclVerSclOff",_("Scale: vertical scale offset (%)"),TFld::Real,Attr::Mutable,"","0","-100;100","",i2s(A_DiagramSclVerSclOff).c_str())); cfg.owner()->attrAdd(new TFld("sclMarkColor",_("Scale: Markers: color"),TFld::String,Attr::Color|Attr::Mutable,"","white","","",i2s(A_DiagramSclMarkColor).c_str())); cfg.owner()->attrAdd(new TFld("sclMarkFont",_("Scale: Markers: font"),TFld::String,Attr::Font|Attr::Mutable,"","Arial 10","","",i2s(A_DiagramSclMarkFont).c_str())); cfg.owner()->attrAdd(new TFld("valArch",_("Value archiver"),TFld::String,Attr::Mutable,"","","","",i2s(A_DiagramValArch).c_str())); cfg.owner()->attrAdd(new TFld("valsForPix",_("Values per pixel"),TFld::Integer,Attr::Mutable,"","1","1;100","",i2s(A_DiagramValsForPix).c_str())); cfg.owner()->attrAdd(new TFld("parNum",_("Parameters number"),TFld::Integer,Attr::Mutable|Attr::Active,"","1","0;100","",i2s(A_DiagramParNum).c_str())); break; } } else if(cfg.id() == "parNum") { string fid("prm"), fnm(_("Parameter ")), fidp, fnmp; //Delete specific unnecessary attributes of parameters for(int iP = 0; true; iP++) { fidp = fid+i2s(iP); if(!cfg.owner()->attrPresent(fidp+"addr")) break; else if(iP >= cfg.getI()) { cfg.owner()->attrDel(fidp+"addr"); cfg.owner()->attrDel(fidp+"bordL"); cfg.owner()->attrDel(fidp+"bordU"); cfg.owner()->attrDel(fidp+"aScale"); cfg.owner()->attrDel(fidp+"color"); cfg.owner()->attrDel(fidp+"width"); cfg.owner()->attrDel(fidp+"scl"); cfg.owner()->attrDel(fidp+"val"); cfg.owner()->attrDel(fidp+"prop"); } } //Create ullage attributes of parameters for(int iP = 0; iP < cfg.getI(); iP++) { fidp = fid+i2s(iP); fnmp = fnm+i2s(iP); if(cfg.owner()->attrPresent(fidp+"addr")) continue; cfg.owner()->attrAdd(new TFld((fidp+"addr").c_str(),(fnmp+_(": address")).c_str(), TFld::String,Attr::Address|Attr::Mutable,"","","","",i2s(A_DiagramTrs+A_DiagramTrAddr+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"bordL").c_str(),(fnmp+_(": view border: lower")).c_str(), TFld::Real,Attr::Mutable,"","","","",i2s(A_DiagramTrs+A_DiagramTrBordL+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"bordU").c_str(),(fnmp+_(": view border: upper")).c_str(), TFld::Real,Attr::Mutable,"","","","",i2s(A_DiagramTrs+A_DiagramTrBordU+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"color").c_str(),(fnmp+_(": color")).c_str(), TFld::String,Attr::Color|Attr::Mutable,"","","","",i2s(A_DiagramTrs+A_DiagramTrClr+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"width").c_str(),(fnmp+_(": width")).c_str(), TFld::Integer,Attr::Mutable,"","1","1;10","",i2s(A_DiagramTrs+A_DiagramTrWdth+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"scl").c_str(),(fnmp+_(": scale")).c_str(),TFld::Integer,Attr::Mutable|TFld::Selectable, "","0","0;2;3;6;7",_("Global;Markers;Grid and markers;Markers (log);Grid and markers (log)"), i2s(A_DiagramTrs+A_DiagramTrScl+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"val").c_str(),(fnmp+_(": value")).c_str(), TFld::Real,Attr::Mutable,"","","","",i2s(A_DiagramTrs+A_DiagramTrVal+A_DiagramTrsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"prop").c_str(),(fnmp+_(": properties")).c_str(), TFld::String,Attr::Mutable,"","","","",i2s(A_DiagramTrs+A_DiagramTrProp+A_DiagramTrsSz*iP).c_str())); } } return Widget::attrChange(cfg,prev); } bool OrigDiagram::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt,src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) { for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_BackColor: case A_BordColor: case A_DiagramSclColor: case A_DiagramSclMarkColor: el->setAttr("help",Widget::helpColor()); break; case A_DiagramSclMarkFont: el->setAttr("help",Widget::helpFont()); break; case A_BackImg: el->setAttr("help",Widget::helpImg()); break; case A_DiagramValArch: el->setAttr("help",_("Value archiver in the form \"{ArchMod}.{ArchiverId}\".")); break; case A_DiagramValsForPix: el->setAttr("help",_("Number of the values per pixel. Increase to enhance the export accuracy at large time intervals.")); break; } } for(int iP = 0; iP < src->attrAt("parNum").at().getI(); iP++) { if((el=ctrId(root,TSYS::strMess("/prm%dcolor",iP),true))) el->setAttr("help",Widget::helpColor()); if((el=ctrId(root,TSYS::strMess("/prm%daddr",iP),true))) el->setAttr("help", _("Full address to the DAQ attribute of the parameter or to the archive.\n" "Data installation by the direct prefix is supported:\n" " \"data:{XMLNodeData}\" - drawing from the direct set data;\n" " \"line:{value}\" - drawing horizontal line by the value, no sense have for the type \"XY\".\n" "Example:\n" " \"/DAQ/System/AutoDA/MemInfo/use\" - address to the attribute \"use\" of the parameter \"MemInfo\"\n" " of the controller \"AutoDA\" of the DAQ module \"System\";\n" " \"/Archive/va_CPULoad_load\" - address to the archive \"CPULoad_load\";\n" " \"data:\n" " 0 3.14\n" " 1 3.141\n" " 5 3.1415 - data for 10 seconds and period in 1 second from \"25.05.2013 10:00:00\";\n" " in the absence of \"tm\" and \"tm_grnd\" they will be set from the range of the diagram,\n" " and setting the attribute \"s\" will allow you to specify the time in seconds;\n" " \"line:3.14159265\" - horizontal line for the value \"3.14159265\".")); if((el=ctrId(root,TSYS::strMess("/prm%dprop",iP),true))) el->setAttr("help", _("Actual archive properties in the form \"{BegArh}:{EndArh}:{DataPeriod}\", where:\n" " \"BegArh\", \"EndArh\", \"DataPeriod\" - begin, end and period of data of the archive in seconds,\n" " it is the real value up to the microseconds deep (1e-6).")); } } return true; } //Process command to page return Widget::cntrCmdAttributes(opt,src); } //************************************************ //* OrigProtocol: Protocol original widget * //************************************************ OrigProtocol::OrigProtocol( ) : PrWidget("Protocol") { } string OrigProtocol::name( ) const { return _("Protocol"); } string OrigProtocol::descr( ) const { return _("Protocol widget of the finite visualization."); } void OrigProtocol::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("backColor",_("Background: color"),TFld::String,Attr::Color,"","","","",i2s(A_BackColor).c_str())); attrAdd(new TFld("backImg",_("Background: image"),TFld::String,Attr::Image,"","","","",i2s(A_BackImg).c_str())); attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"","Arial 11","","",i2s(A_ProtFont).c_str())); attrAdd(new TFld("headVis",_("Header visible"),TFld::Boolean,TFld::NoFlag,"","1","","",i2s(A_ProtHeadVis).c_str())); attrAdd(new TFld("time",_("Time, seconds"),TFld::Integer,Attr::DateTime,"","","","",i2s(A_ProtTime).c_str())); attrAdd(new TFld("tSize",_("Size, seconds"),TFld::Integer,TFld::NoFlag,"","60","0;50000000","",i2s(A_ProtTSize).c_str())); attrAdd(new TFld("trcPer",_("Tracing period, seconds"),TFld::Integer,TFld::NoFlag,"","0","0;360","",i2s(A_ProtTrcPer).c_str())); attrAdd(new TFld("arch",_("Archiver"),TFld::String,0,"","","","",i2s(A_ProtArch).c_str())); attrAdd(new TFld("tmpl",_("Template"),TFld::String,0,"","","","",i2s(A_ProtTmpl).c_str())); attrAdd(new TFld("lev",_("Level"),TFld::Integer,TFld::NoFlag,"","0","-7;7","",i2s(A_ProtLev).c_str())); attrAdd(new TFld("viewOrd",_("View order"),TFld::Integer,TFld::Selectable,"","0", TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d",FP_ON_TM,FP_ON_LEV,FP_ON_CAT,FP_ON_MESS,FP_ON_TM_REV,FP_ON_LEV_REV,FP_ON_CAT_REV,FP_ON_MESS_REV).c_str(), _("On time;On level;On category;On messages;On time (reverse);On level (reverse);On category (reverse);On messages (reverse)"),i2s(A_ProtViewOrd).c_str())); attrAdd(new TFld("col",_("Show columns"),TFld::String,0,"","pos;tm;utm;lev;cat;mess","","",i2s(A_ProtCol).c_str())); attrAdd(new TFld("itProp",_("Item properties"),TFld::Integer,Attr::Active,"","","","",i2s(A_ProtItProp).c_str())); } } bool OrigProtocol::attrChange( Attr &cfg, TVariant prev ) { if(cfg.flgGlob()&Attr::Active) { if(cfg.id() == "itProp") { string fid("it"), fnm(_("Item ")), fidp, fnmp; //Delete specific unnecessary items for(int iP = 0; true; iP++) { fidp = fid + i2s(iP); if(!cfg.owner()->attrPresent(fidp+"lev")) break; else if(iP >= cfg.getI()) { cfg.owner()->attrDel(fidp+"lev"); cfg.owner()->attrDel(fidp+"tmpl"); cfg.owner()->attrDel(fidp+"fnt"); cfg.owner()->attrDel(fidp+"color"); } } //Create ullage items for(int iP = 0; iP < cfg.getI(); iP++) { fidp = fid + i2s(iP); fnmp = fnm + i2s(iP); if(cfg.owner()->attrPresent(fidp+"lev")) continue; cfg.owner()->attrAdd(new TFld((fidp+"lev").c_str(),(fnmp+_(": level")).c_str(), TFld::Integer,Attr::Mutable,"","0","0;7","",i2s(A_ProtProps+A_ProtPropLev+A_ProtPropsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"tmpl").c_str(),(fnmp+_(": template")).c_str(), TFld::String,Attr::Mutable,"","","","",i2s(A_ProtProps+A_ProtPropTmpl+A_ProtPropsSz*iP).c_str())); cfg.owner()->attrAdd(new TFld((fidp+"fnt").c_str(),(fnmp+_(": font")).c_str(), TFld::String,Attr::Font|Attr::Mutable,"","","","",i2s(A_ProtProps+A_ProtPropFnt+A_ProtPropsSz*iP).c_str())); cfg.owner()->attrAdd( new TFld((fidp+"color").c_str(),(fnmp+_(": color")).c_str(), TFld::String,Attr::Color|Attr::Mutable,"","","","",i2s(A_ProtProps+A_ProtPropClr+A_ProtPropsSz*iP).c_str())); } } } return Widget::attrChange(cfg, prev); } bool OrigProtocol::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt,src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) { for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_BackColor: el->setAttr("help",Widget::helpColor()); break; case A_BackImg: el->setAttr("help",Widget::helpImg()); break; case A_ProtFont: el->setAttr("help",Widget::helpFont()); break; case A_ProtArch: el->setAttr("help",_("Messages archiver in the form \"{ArchMod}.{ArchiverId}\".")); break; case A_ProtLev: el->setAttr("help",_("Set value to \"< 0\" for get the current alarms.")); break; case A_ProtTSize: el->setAttr("help",_("Set value to \"0\" for get all alarms, for \"lev\" < 0.")); break; case A_ProtTmpl: el->setAttr("help", _("Category template or the regular expression \"/{re}/\". For the template there reserved the special symbols:\n" " '*' - any multiply symbols group;\n" " '?' - any one symbol;\n" " '\\' - use to shield the special simbols.")); break; case A_ProtCol: el->setAttr("help", _("List of visible and the columns order separated by the symbol ';'. Supported columns:\n" " \"pos\" - row number;\n" " \"tm\" - date and time of the message;\n" " \"utm\" - microseconds part of the message time;\n" " \"lev\" - level of the message;\n" " \"cat\" - category of the message;\n" " \"mess\" - text of the message.")); break; } } for(int iP = 0; iP < src->attrAt("itProp").at().getI(); iP++) { if((el=ctrId(root,TSYS::strMess("/it%dcolor",iP),true))) el->setAttr("help",Widget::helpColor()); if((el=ctrId(root,TSYS::strMess("/it%dfnt",iP),true))) el->setAttr("help",Widget::helpFont()); if((el=ctrId(root,TSYS::strMess("/it%dtmpl",iP),true))) el->setAttr("help", _("Category template or the regular expression \"/{re}/\". For the template there reserved the special symbols:\n" " '*' - any multiply symbols group;\n" " '?' - any one symbol;\n" " '\\' - use to shield the special simbols.")); } } return true; } //Process command to page return Widget::cntrCmdAttributes(opt,src); } //************************************************ //* OrigDocument: Document original widget * //************************************************ const char *OrigDocument::XHTML_entity = "\n" "]>\n"; OrigDocument::OrigDocument( ) : PrWidget("Document") { } string OrigDocument::name( ) const { return _("Document"); } string OrigDocument::descr( ) const { return _("Document widget of the finite visualization."); } void OrigDocument::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("style","CSS",TFld::String,TFld::FullText,"","","","",i2s(A_DocStyle).c_str())); attrAdd(new TFld("tmpl",_("Template"),TFld::String,TFld::TransltText|TFld::FullText,"","","","",i2s(A_DocTmpl).c_str())); attrAdd(new TFld("doc",_("Document"),TFld::String,TFld::TransltText|TFld::FullText,"","","","",i2s(A_DocDoc).c_str())); attrAdd(new TFld("font",_("Font"),TFld::String,Attr::Font,"","Arial 11","","",i2s(A_DocFont).c_str())); attrAdd(new TFld("bTime",_("Time: begin"),TFld::Integer,Attr::DateTime,"","0","","",i2s(A_DocBTime).c_str())); attrAdd(new TFld("time",_("Time: current"),TFld::Integer,Attr::DateTime|Attr::Active,"","0","","",i2s(A_DocTime).c_str())); attrAdd(new TFld("process",_("In the process"),TFld::Boolean,TFld::NoWrite,"","0","","",i2s(A_DocProcess).c_str())); attrAdd(new TFld("n",_("Archive size"),TFld::Integer,Attr::Active,"","0",TSYS::strMess("0;%d",DocArhSize).c_str(),"",i2s(A_DocN).c_str())); } } void OrigDocument::disable( Widget *base ) { if(dynamic_cast(base)) SYS->taskDestroy(base->nodePath('.',true)+".doc", NULL, 3*prmInterf_TM); } bool OrigDocument::attrChange( Attr &cfg, TVariant prev ) { //Document's number change process if(cfg.id() == "n" && cfg.getI() != prev.getI()) { if(!cfg.getI()) { cfg.owner()->attrDel("aCur"); cfg.owner()->attrDel("vCur"); cfg.owner()->attrDel("aDoc"); cfg.owner()->attrDel("aSize"); } else { if(!cfg.owner()->attrPresent("vCur")) cfg.owner()->attrAdd(new TFld("vCur",_("Archive: cursor: view"),TFld::Integer,Attr::NotStored|Attr::Mutable|Attr::Active,"","0", TSYS::strMess("-2;%d",DocArhSize-1).c_str())); if(!cfg.owner()->attrPresent("aCur")) cfg.owner()->attrAdd(new TFld("aCur",_("Archive: cursor: current"),TFld::Integer,Attr::NotStored|Attr::Mutable|Attr::Active,"","0", TSYS::strMess("-1;%d",DocArhSize-1).c_str())); if(!cfg.owner()->attrPresent("aDoc")) cfg.owner()->attrAdd(new TFld("aDoc",_("Archive: current document"),TFld::String,Attr::NotStored|TFld::FullText|Attr::Mutable|Attr::Active)); if(!cfg.owner()->attrPresent("aSize")) cfg.owner()->attrAdd(new TFld("aSize",_("Archive: size"),TFld::Integer,Attr::NotStored|Attr::Mutable)); } } SessWdg *sw = dynamic_cast(cfg.owner()); if(!sw) return Widget::attrChange(cfg,prev); string u, l; if(sw) { u = sw->ownerSess()->reqUser(); l = sw->ownerSess()->reqLang(); } //Make document after time set if(cfg.id() == "time" && (cfg.getI() != prev.getI() || (!cfg.getI() && prev.getI()))) { if(!cfg.getI() && prev.getI()) cfg.setI(prev.getI(),false,true); try { string taskNm = sw->nodePath('.',true)+".doc"; SYS->taskDestroy(taskNm); SYS->taskCreate(taskNm, -1, OrigDocument::DocTask, sw, 2); sw->attrAt("process").at().setB(true); } catch(TError &err) { } } //Load document's from project's DB else if(cfg.id() == "n" && cfg.getI() != prev.getI()) { string tVl; AutoHD aCur, aDoc, vCur; try { aCur = cfg.owner()->attrAt("aCur"); aDoc = cfg.owner()->attrAt("aDoc"); vCur = cfg.owner()->attrAt("vCur"); } catch(TError &err) { } if(!(aCur.freeStat() || aDoc.freeStat() || vCur.freeStat())) { // Archive position load if((tVl=sw->sessAttr("aCur")).size()) aCur.at().setS(tVl, false, true); // Current archive documents load if((tVl=sw->sessAttr("doc"+aCur.at().getS())).size()) aDoc.at().setS(tVl, false, true); // Set current document vCur.at().setI(aCur.at().getI(), false, true); cfg.owner()->attrAt("doc").at().setS(aDoc.at().getS(),false,true); // Parse current document and restore last document's time string cdoc = cfg.owner()->attrAt("doc").at().getS(); if(!cdoc.empty()) { XMLNode xdoc; try { xdoc.load(XHTML_entity+cdoc, false, Mess->charset()); } catch(TError &err) { } cfg.owner()->attrAt("time").at().setS(xdoc.attr("docTime"), false, true); } sizeUpdate(sw); } } //Move the archive cursor else if(cfg.id() == "aCur" && cfg.getI() != prev.getI()) { int n = cfg.owner()->attrAt("n").at().getI(); if(cfg.getI() < 0) cfg.setI(((prev.getI()+1) >= n) ? 0 : (prev.getI()+1), false, true); else if(cfg.getI() >= n) cfg.setI(n-1, false, true); if(cfg.getI() != prev.getI()) { cfg.owner()->attrAt("aDoc").at().setS(trLU(cfg.owner()->attrAt("tmpl").at().getS(),l,u)); if(prev.getI() == cfg.owner()->attrAt("vCur").at().getI()) cfg.owner()->attrAt("vCur").at().setI(cfg.getI()); // Save cursor to document to project's DB if(prev.getI() < n && prev.getI() >= 0) sw->sessAttrSet(cfg.id(), cfg.getS()); } sizeUpdate(sw); } //Document save else if(cfg.id() == "aDoc" && cfg.getS() != prev.getS()) sw->sessAttrSet("doc"+cfg.owner()->attrAt("aCur").at().getS(), cfg.getS()); //Move archive view cursor else if(cfg.id() == "vCur" && cfg.getI() != prev.getI()) { try { AutoHD aCur = cfg.owner()->attrAt("aCur"); int n = cfg.owner()->attrAt("n").at().getI(); if(cfg.getI() < 0) { int docN = prev.getI(); // Search next document if(cfg.getI() == -1) while(docN != aCur.at().getI()) { if(docN != prev.getI() && sw->sessAttr("doc"+i2s(docN),true).size()) break; if(++docN >= n) docN = 0; } // Search previous document else { if(--docN < 0) docN = n-1; if(docN == aCur.at().getI()) docN = prev.getI(); if(!sw->sessAttr("doc"+i2s(docN),true).size()) docN = prev.getI(); } if(docN != cfg.getI()) cfg.setI(docN,false,true); } else if(cfg.getI() >= n) cfg.setI(aCur.at().getI(), false, true); if(cfg.getI() != prev.getI()) cfg.owner()->attrAt("doc").at().setS(sw->sessAttr("doc"+cfg.getS())); } catch(TError &err) { } } return Widget::attrChange(cfg,prev); } bool OrigDocument::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt,src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_DocStyle: el->setAttr("SnthHgl","1")->setAttr("help", _("CSS rules in the rows like to \"body { background-color:#818181; }\"")); break; case A_DocTmpl: el->setAttr("SnthHgl","1")->setAttr("help", _("Document template in XHTML. Starts from the tag \"body\" and include the procedures parts:\n" "\n

Value

\n")); break; case A_DocDoc: el->setAttr("SnthHgl","1")->setAttr("help",_("Final document in XHTML, starting from the tag \"body\".")); break; case A_DocTime: el->setAttr("help",_("Write the time for the document generation from the specified one or zero for regeneration.")); break; case A_DocFont: el->setAttr("help",Widget::helpFont()); break; default: if(el->attr("id") == "aDoc") el->setAttr("SnthHgl","1")->setAttr("help",_("Current archive document in XHTML, starting from the tag \"body\".")); } } return true; } //Process command to page string a_path = opt->attr("path"); if((a_path == "/attr/tmpl" || a_path == "/attr/doc" || a_path == "/attr/aDoc") && ctrChkNode(opt,"SnthHgl",RWRWR_,"root",SUI_ID,SEC_RD)) { opt->childAdd("blk")->setAttr("beg","")->setAttr("color","gray")->setAttr("font_italic","1"); XMLNode *tag = opt->childAdd("blk")->setAttr("beg","<\\?")->setAttr("end","\\?>")->setAttr("color","#666666"); // Get document's language syntax highlight. try { string dcLng; TArrayObj *reRez = TRegExp(".*.*","").match(src->attrAt(a_path.substr(6)).at().getS()); if(reRez->propGet("length").getI() >= 2) dcLng = reRez->arGet(1).getS(); delete reRez; if(dcLng.size()) SYS->daq().at().at(TSYS::strParse(dcLng,0,".")).at().compileFuncSynthHighl(TSYS::strParse(dcLng,1,"."),*tag); } catch(...) { } tag = opt->childAdd("blk")->setAttr("beg","<\\w+")->setAttr("end","\\/?>")->setAttr("font_weight","1"); tag->childAdd("rule")->setAttr("expr","\\b\\w+[ ]*(?==)")->setAttr("color","blue"); tag->childAdd("rule")->setAttr("expr","[ ]?\"[^\"]+\"")->setAttr("color","darkgreen"); tag->childAdd("rule")->setAttr("expr","[ ]?'[^']+'")->setAttr("color","darkgreen"); opt->childAdd("rule")->setAttr("expr","<\\/[\\w]+>")->setAttr("font_weight","1"); opt->childAdd("rule")->setAttr("expr","&([a-zA-Z]*|#\\d*);")->setAttr("color","#AF7E00"); } else if(a_path == "/attr/style" && ctrChkNode(opt,"SnthHgl",RWRWR_,"root",SUI_ID,SEC_RD)) { opt->childAdd("blk")->setAttr("beg", "/\\*")->setAttr("end", "\\*/")->setAttr("color", "gray")->setAttr("font_italic", "1"); opt->childAdd("blk")->setAttr("beg", "\\{")->setAttr("end", "\\}")->setAttr("color", "#666666")-> childAdd("rule")->setAttr("expr", ":[^;]+")->setAttr("color", "blue"); opt->childAdd("rule")->setAttr("expr", "(\\.|#)\\w+\\s")->setAttr("color", "darkorange"); } else return Widget::cntrCmdAttributes(opt,src); return true; } void OrigDocument::sizeUpdate( SessWdg *sw ) { try { AutoHD aCur = sw->attrAt("aCur"); AutoHD aSize = sw->attrAt("aSize"); int n = sw->attrAt("n").at().getI(); int rSz = n; if(aCur.at().getI() < n && (!sw->sessAttr("doc"+i2s(aCur.at().getI()+1),true).size() || !sw->sessAttr("doc"+i2s(n-1),true).size())) rSz = aCur.at().getI()+1; aSize.at().setI(rSz); } catch(TError &err) { } } TVariant OrigDocument::objFuncCall_w( const string &iid, vector &prms, const string &user, Widget *src ) { // string getArhDoc(integer nDoc) - get archive document text to 'nDoc' depth. // nDoc - archive document at depth (0-{aSize-1}) if(iid == "getArhDoc" && prms.size() >= 1) { int nDoc = prms[0].getI(); int aCur = src->attrAt("aCur").at().getI(); int aSize = src->attrAt("aSize").at().getI(); SessWdg *sw = dynamic_cast(src); if(!sw || nDoc < 0 || nDoc >= aSize) return ""; aCur -= nDoc; if(aCur < 0) aCur += aSize; return sw->sessAttr("doc"+i2s(aCur)); } return TVariant(); } string OrigDocument::makeDoc( const string &tmpl, Widget *wdg ) { SessWdg *sw = (SessWdg*)wdg; string u = sw->ownerSess()->reqUser(), l = sw->ownerSess()->reqLang(); XMLNode xdoc; string iLang; //Process instruction language string wProgO; //Object of work program time_t lstTime = 0; //Last time TFunction funcIO(TSYS::path2sepstr(wdg->path(),'_')); funcIO.setStor(wdg->calcProgStors("doc")); TValFunc funcV(wdg->id()+"_doc", NULL, false); funcV.setUser(u); funcV.setLang(l); vector als; //Parse template try { if(!tmpl.empty()) xdoc.load(XHTML_entity+tmpl, true, Mess->charset()); else return ""; } catch(TError &err) { mess_err(wdg->nodePath().c_str(),_("Error parsing the document: %s."),err.mess.c_str()); return ""; } //Prepare call instructions environment if(strcasecmp(xdoc.name().c_str(),"body") == 0) { iLang = xdoc.attr("docProcLang"); lstTime = s2i(xdoc.attr("docTime")); } if(sTrm(iLang).empty()) iLang = "JavaLikeCalc.JavaScript"; if(!lstTime) lstTime = wdg->attrAt("bTime").at().getI(); // Add generic io funcIO.ioIns(new IO("rez",_("Result"),IO::String,IO::Return), A_DocCalcPrmRez); funcIO.ioIns(new IO("time",_("Document time"),IO::Integer,IO::Default), A_DocCalcPrmTime); funcIO.ioIns(new IO("bTime",_("Document begin time"),IO::Integer,IO::Default), A_DocCalcPrmBTime); funcIO.ioIns(new IO("lTime",_("Last time"),IO::Integer,IO::Default), A_DocCalcPrmLTime); funcIO.ioIns(new IO("rTime",_("Repeat time, seconds"),IO::Integer,IO::Default), A_DocCalcPrmRTime); funcIO.ioIns(new IO("rTimeU",_("Repeat time, microseconds"),IO::Integer,IO::Default), A_DocCalcPrmRTimeU); funcIO.ioIns(new IO("rPer",_("Repeat period"),IO::Real,IO::Default), A_DocCalcPrmRPer); funcIO.ioIns(new IO("mTime",_("Message time, seconds"),IO::Integer,IO::Default), A_DocCalcPrmMTime); funcIO.ioIns(new IO("mTimeU",_("Message time, microseconds"),IO::Integer,IO::Default), A_DocCalcPrmMTimeU); funcIO.ioIns(new IO("mLev",_("Message level"),IO::Integer,IO::Default), A_DocCalcPrmMLev); funcIO.ioIns(new IO("mCat",_("Message category"),IO::String,IO::Default), A_DocCalcPrmMCat); funcIO.ioIns(new IO("mVal",_("Message value"),IO::String,IO::Default), A_DocCalcPrmMVal); // Add user io wdg->attrList(als); for(unsigned iA = 0; iA < als.size(); iA++) { AutoHD cattr = wdg->attrAt(als[iA]); if(!(cattr.at().flgGlob()&Attr::IsUser)) continue; funcIO.ioAdd(new IO(als[iA].c_str(),cattr.at().name().c_str(),cattr.at().fld().typeIO(),IO::Output)); } try { // Compile empty function for binding to object wProgO = SYS->daq().at().at(TSYS::strSepParse(iLang,0,'.')).at().compileFunc(TSYS::strSepParse(iLang,1,'.'),funcIO,""); // Connect to compiled function funcV.setFunc(&((AutoHD)SYS->nodeAt(wProgO)).at()); // Load values of generic IO funcV.setI(A_DocCalcPrmTime, wdg->attrAt("time").at().getI()); funcV.setI(A_DocCalcPrmBTime, wdg->attrAt("bTime").at().getI()); funcV.setI(A_DocCalcPrmLTime, lstTime); // Load values of user IO for(int iA = 12; iA < funcV.ioSize(); iA++) funcV.set(iA,wdg->attrAt(funcV.func()->io(iA)->id()).at().get()); } catch(TError &err) { mess_err(wdg->nodePath().c_str(),_("Error compiling function for the document: %s"),err.mess.c_str()); return ""; } //Warning timeout message subtree add to generic tree xdoc.childAdd()->load(TSYS::strMess( _("\n" "

The document is forming now ...

\n" "

The document is too big for generating into the standard user interface timeout (%ds). " "And for now the document is into the building. " "You can wait the forming finish or terminate the process by select lesser time interval for the document.

\n" "

The building progress:\n" "

    \n" "

    \n" ""),prmInterf_TM), false, Mess->charset()); //Node proocess OrigDocument::nodeProcess(wdg, &xdoc, funcV, funcIO, iLang); //Remove warning timeout message subtree xdoc.childDel(xdoc.childSize()-1); xdoc.setAttr("docTime", i2s(funcV.getI(A_DocCalcPrmTime))); return xdoc.save(0, Mess->charset()); } void OrigDocument::nodeProcess( Widget *wdg, XMLNode *xcur, TValFunc &funcV, TFunction &funcIO, const string &iLang, bool instrDel, time_t upTo ) { //Progress warning node XMLNode *progrNode = NULL; if(!upTo) upTo = time(NULL)+prmInterf_TM; //Process instructions if(xcur->childGet("attr("docAppend"))) for(unsigned i_t = 0; i_t < xcur->childSize(); ) { if(xcur->childGet(i_t)->name().compare(0,4,"childDel(i_t); else i_t++; } //Call procedures for(int i_t = 0; i_t < (int)xcur->childSize(); i_t++) { XMLNode *curPrc = xcur->childGet(i_t); if(curPrc->name().compare(0,4,"daq().at().at(TSYS::strSepParse(iLang,0,'.')). at().compileFunc(TSYS::strSepParse(iLang,1,'.'), funcIO, curPrc->text()); // Call funcV.setS(A_DocCalcPrmRez, ""); funcV.calc(); // Load result to XML tree XMLNode xproc; xproc.load(string(XHTML_entity)+""+funcV.getS(A_DocCalcPrmRez)+"", true, Mess->charset()); // Set result for(unsigned i_tr = 0; i_tr < xproc.childSize(); i_tr++) *(xcur->childAdd()) = *xproc.childGet(i_tr); if(instrDel) xcur->childDel(i_t--); } catch(TError &err) { mess_err(wdg->nodePath().c_str(),_("Error executing instruction '%s': %s"), TSYS::strSepParse(iLang,1,'.').c_str(), err.mess.c_str()); mess_err(wdg->nodePath().c_str(),_("Error code: %s"), curPrc->text().c_str()); } } } float dRpt = 1; string dAMess; //Go to include nodes for(unsigned iC = 0; iC < xcur->childSize(); iC++) { XMLNode *reptN = xcur->childGet(iC); if(reptN->name().size() && reptN->name()[0] == '<') continue; // Repeat tags if(funcV.getI(A_DocCalcPrmBTime) && (dRpt=s2r(reptN->attr("docRept"))) > 1e-6) { int rCnt = 0; bool docRevers = s2i(reptN->attr("docRevers")); funcV.setR(A_DocCalcPrmRPer, dRpt); int64_t wTime = (int64_t)funcV.getI(A_DocCalcPrmTime)*1000000; int64_t bTime = (int64_t)funcV.getI(A_DocCalcPrmBTime)*1000000; int64_t lstTime = (int64_t)funcV.getI(A_DocCalcPrmLTime)*1000000; int64_t perRpt = (int64_t)(1000000*dRpt); int64_t rTime = bTime + perRpt*((lstTime-bTime)/perRpt); if(lstTime && lstTime < bTime) rTime -= perRpt; //if(((time-rTime)/perRpt) > 1000) continue; // Progress prepare if(!progrNode) { progrNode = xcur->root(); progrNode = progrNode->childGet(progrNode->childSize()-1)->getElementBy("id","progress"); } progrNode->childAdd("li")->setText(TSYS::strMess(_("Data block %d: %0.2f%% loaded."),progrNode->childSize(),0)); while(rTime < wTime && !TSYS::taskEndRun()) { //Drop current changes and continue if(time(NULL) >= upTo) { upTo = time(NULL) + prmInterf_TM; if(!wdg->attrAt("n").at().getI() || wdg->attrAt("aCur").at().getI() == wdg->attrAt("vCur").at().getI()) { progrNode->childGet(progrNode->childSize()-1)-> setText(TSYS::strMess(_("Data block %d: %0.2f%% loaded."),progrNode->childSize(),100*(float)(rTime-bTime)/(float)(wTime-bTime))); XMLNode *rootN = xcur->root(); wdg->attrAt("doc").at().setS(rootN->childGet(rootN->childSize()-1)->save(0,Mess->charset())); } } //Process if(s2i(reptN->attr("docRptEnd"))) { int iN = docRevers?(iC+1):iC; *(xcur->childIns(iN)) = *reptN; OrigDocument::nodeClear(xcur->childGet(iN)); if(!docRevers) iC++; rCnt++; } int64_t rTimeT = vmin(rTime+perRpt, wTime); funcV.setI(A_DocCalcPrmRTime, rTimeT/1000000); funcV.setI(A_DocCalcPrmRTimeU, rTimeT%1000000); funcV.setR(A_DocCalcPrmRPer, (rTimeT-rTime)/1000000.0); OrigDocument::nodeProcess(wdg, reptN, funcV, funcIO, iLang, false, upTo); reptN->setAttr("docRptEnd", ((rTimeT-rTime)==perRpt)?"1":"0"); rTime = rTimeT; } funcV.setI(A_DocCalcPrmRTime, 0); funcV.setI(A_DocCalcPrmRTimeU, 0); funcV.setR(A_DocCalcPrmRPer, 0); if(docRevers) iC += rCnt; progrNode->childGet(progrNode->childSize()-1)->setText(TSYS::strMess(_("Data block %d: %0.2f%% loaded."),progrNode->childSize(),100)); } // Repeat messages else if(!(dAMess=xcur->childGet(iC)->attr("docAMess")).empty()) { int rCnt = 0; XMLNode *reptN = xcur->childGet(iC); bool docRevers = s2i(xcur->childGet(iC)->attr("docRevers")); string docAMessArchs = xcur->childGet(iC)->attr("docAMessArchs"); int off = 0; int dACat = s2i(TSYS::strSepParse(dAMess,0,':',&off)); string dATmpl = dAMess.substr(off); vector mess; SYS->archive().at().messGet(funcV.getI(A_DocCalcPrmLTime), funcV.getI(A_DocCalcPrmTime), mess, dATmpl, (TMess::Type)dACat, docAMessArchs); // Progress bar prepare if(!progrNode) { progrNode = xcur->root(); progrNode = progrNode->childGet(progrNode->childSize()-1)->getElementBy("id","progress"); } progrNode->childAdd("li")->setText(TSYS::strMess(_("Messages block %d: %0.2f%% loaded."),progrNode->childSize(),0)); for(unsigned iR = 0; iR < mess.size() && !TSYS::taskEndRun(); iR++) { // Drop current changes and continue if(time(NULL) >= upTo) { upTo = time(NULL)+prmInterf_TM; if(!wdg->attrAt("n").at().getI() || wdg->attrAt("aCur").at().getI() == wdg->attrAt("vCur").at().getI()) { progrNode->childGet(progrNode->childSize()-1)-> setText(TSYS::strMess(_("Messages block %d: %0.2f%% loaded."),progrNode->childSize(),100*(float)iR/(float)mess.size())); XMLNode *rootN = xcur->root(); wdg->attrAt("doc").at().setS(rootN->childGet(rootN->childSize()-1)->save(0,Mess->charset())); } } if(s2i(reptN->attr("docRptEnd"))) { unsigned iN = (docRevers ? (iC+1) : iC); *(xcur->childIns(iN)) = *reptN; nodeClear(xcur->childGet(iN)); if(!docRevers) iC++; rCnt++; } funcV.setI(A_DocCalcPrmMTime, mess[iR].time); funcV.setI(A_DocCalcPrmMTimeU, mess[iR].utime); funcV.setI(A_DocCalcPrmMLev, mess[iR].level); funcV.setS(A_DocCalcPrmMCat, mess[iR].categ); funcV.setS(A_DocCalcPrmMVal, mess[iR].mess); nodeProcess(wdg, reptN, funcV, funcIO, iLang, false, upTo); reptN->setAttr("docRptEnd", "1"); } progrNode->childGet(progrNode->childSize()-1)->setText(TSYS::strMess(_("Messages block %d: %0.2f%% loaded."),progrNode->childSize(),100)); funcV.setI(A_DocCalcPrmMTime, 0); funcV.setI(A_DocCalcPrmMTimeU, 0); funcV.setI(A_DocCalcPrmMLev, 0); funcV.setS(A_DocCalcPrmMCat, ""); funcV.setS(A_DocCalcPrmMVal, ""); if(docRevers) iC += rCnt; } else nodeProcess(wdg,xcur->childGet(iC),funcV,funcIO,iLang,instrDel,upTo); } } void OrigDocument::nodeClear( XMLNode *xcur ) { xcur->attrDel("docRept"); xcur->attrDel("docRptEnd"); xcur->attrDel("docRevers"); xcur->attrDel("docAMess"); for(unsigned iC = 0; iC < xcur->childSize(); ) if(xcur->childGet(iC)->name().compare(0,4,"childDel(iC); else nodeClear(xcur->childGet(iC++)); } void *OrigDocument::DocTask( void *param ) { SessWdg *sw = (SessWdg*)param; string u = sw->ownerSess()->reqUser(), l = sw->ownerSess()->reqLang(); // The document generation try { string mkDk; if(!sw->attrAt("n").at().getI()) { mkDk = sw->attrAt("doc").at().getS(); if(mkDk.empty()) mkDk = trLU(sw->attrAt("tmpl").at().getS(), l, u); mkDk = OrigDocument::makeDoc(mkDk,sw); sw->attrAt("doc").at().setS(mkDk); } else { AutoHD aCur, aDoc, vCur; try { aCur = sw->attrAt("aCur"); aDoc = sw->attrAt("aDoc"); vCur = sw->attrAt("vCur"); } catch(TError &err) { } if(!(aCur.freeStat() || aDoc.freeStat() || vCur.freeStat())) { //int aCur = aCur.at().getI(); mkDk = aDoc.at().getS(); if(mkDk.empty()) mkDk = trLU(sw->attrAt("tmpl").at().getS(), l, u); mkDk = makeDoc(mkDk, sw); aDoc.at().setS(mkDk); if(aCur.at().getI() == vCur.at().getI()) sw->attrAt("doc").at().setS(mkDk); } } } catch(TError &err) { mess_err(err.cat.c_str(), "%s", err.mess.c_str()); mess_err(sw->nodePath().c_str(), _("Document generation terminated.")); } sw->attrAt("process").at().setB(false); return NULL; } //************************************************ //* OrigFunction: User function original widget * //************************************************ OrigFunction::OrigFunction( ) : PrWidget("Function") { } string OrigFunction::name( ) const { return _("Built-in function"); } string OrigFunction::descr( ) const { return _("Built-in function widget."); } //************************************************ //* OrigBox: User element original widget * //************************************************ OrigBox::OrigBox( ) : PrWidget("Box") { } string OrigBox::name( ) const { return _("Group of elements"); } string OrigBox::descr( ) const { return _("Widget of the group of elements of the finite visualization."); } void OrigBox::postEnable( int flag ) { LWidget::postEnable(flag); if(flag&TCntrNode::NodeConnect) { attrAdd(new TFld("pgOpenSrc",_("Page: source of the opening"),TFld::String,0,"","","","",i2s(A_PG_OPEN_SRC).c_str())); attrAdd(new TFld("pgGrp",_("Page: group"),TFld::String,0,"","","","",i2s(A_PG_GRP).c_str())); attrAdd(new TFld("backColor",_("Background: color"),TFld::String,Attr::Color,"","#FFFFFF","","",i2s(A_BackColor).c_str())); attrAdd(new TFld("backImg",_("Background: image"),TFld::String,Attr::Image,"","","","",i2s(A_BackImg).c_str())); attrAdd(new TFld("bordWidth",_("Border: width"),TFld::Integer,TFld::NoFlag,"","0","","",i2s(A_BordWidth).c_str())); attrAdd(new TFld("bordColor",_("Border: color"),TFld::String,Attr::Color,"","#000000","","",i2s(A_BordColor).c_str())); attrAdd(new TFld("bordStyle",_("Border: style"),TFld::Integer,TFld::Selectable,"",i2s(FBRD_SOL).c_str(), TSYS::strMess("%d;%d;%d;%d;%d;%d;%d;%d;%d",FBRD_NONE,FBRD_DOT,FBRD_DASH,FBRD_SOL,FBRD_DBL,FBRD_GROOVE,FBRD_RIDGE,FBRD_INSET,FBRD_OUTSET).c_str(), _("None;Dotted;Dashed;Solid;Double;Groove;Ridge;Inset;Outset"),i2s(A_BordStyle).c_str())); } } bool OrigBox::cntrCmdAttributes( XMLNode *opt, Widget *src ) { if(!src) src = this; //Get page info if(opt->name() == "info") { Widget::cntrCmdAttributes(opt,src); XMLNode *root, *el; if((root=ctrMkNode("area",opt,-1,"/attr",_("Attributes")))) for(unsigned iCh = 0; iCh < root->childSize(); iCh++) { el = root->childGet(iCh); int p = s2i(el->attr("p")); switch(p) { case A_BackColor: case A_BordColor: el->setAttr("help",Widget::helpColor()); break; case A_BackImg: el->setAttr("help",Widget::helpImg()); break; } } return true; } //Process command to page return Widget::cntrCmdAttributes(opt,src); }