//OpenSCADA file: tuis.cpp /*************************************************************************** * Copyright (C) 2003-2024 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 #include #include #include "tsys.h" #include "tmess.h" #include "tuis.h" #if HAVE_GD_FORCE # include #endif #define DEF_FontSnthHglCode "monospace" using namespace OSCADA; //************************************************* //* TUIS * //************************************************* TUIS::TUIS( ) : TSubSYS(SUI_ID, true), mFontSnthHglCode(dataRes()) { mFontSnthHglCode = DEF_FontSnthHglCode; #if HAVE_GD_FORCE gdFTUseFontConfig(1); #endif } string TUIS::optDescr( ) { return TSYS::strMess(_( "===================== Subsystem \"User interfaces\" options ===============\n" "------ Parameters of the section '%s' of the configuration file ------\n" "FontSnthHglCode Font used in the code syntax highlight, by default \"monospace\".\n\n" ),nodePath().c_str()) + TSubSYS::optDescr(); } void TUIS::load_( ) { //Load parameters from command line //Load parameters from config-file setFontSnthHglCode(TBDS::genPrmGet(nodePath()+"FontSnthHglCode",DEF_FontSnthHglCode)); } void TUIS::save_( ) { //Save parameters to the table "SYS" TBDS::genPrmSet(nodePath()+"FontSnthHglCode", fontSnthHglCode()); } TVariant TUIS::objFuncCall( const string &id, vector &prms, const string &user_lang ) { // string mimeGet(string fnm) - obtaining the MIME type at the file name ''fnm''. if(id == "mimeGet" && prms.size() >= 1) return mimeGet(prms[0].getS(), ""); return TCntrNode::objFuncCall(id, prms, user_lang); } string TUIS::icoGet( const string &inm, string *tp, bool retPath ) { unsigned iT = 0; int hd = -1; string rez, pathi; char types[][5] = {"png", "gif", "jpg", "jpeg"}; for(int off = 0; hd == -1 && (pathi=TSYS::strParse(SYS->icoDir(),0,";",&off)).size(); ) for(iT = 0; iT < sizeof(types)/5; iT++) if((hd=open((pathi+"/"+inm+"."+types[iT]).c_str(),O_RDONLY)) != -1) break; if(hd != -1) { if(tp) *tp = types[iT]; if(retPath) rez = pathi+"/"+inm+"."+types[iT]; else { char buf[prmStrBuf_SZ]; for(int len = 0; (len=read(hd,buf,sizeof(buf))) > 0; ) rez.append(buf,len); } if(close(hd) != 0) mess_warning("TUIS", _("Closing the file %d error '%s (%d)'!"), hd, strerror(errno), errno); } return rez; } string TUIS::docGet( const string &iinm, string *tp, unsigned opt ) { unsigned iTr = 0, iT = 0; string rez, pathi, inm = TSYS::strLine(iinm, 0), lang = TSYS::strLine(iinm, 1), nm = TSYS::strParse(inm, 0, "|"); vector transl; //Find the offline document on the filesystem int hd = -1; char types[][5] = {"pdf", "html", "odt"}; transl.push_back(""); transl.push_back(lang.size()?lang:Mess->langCode()); transl.push_back("en"); for(int off = 0; nm.size() && hd == -1 && (pathi=TSYS::strParse(SYS->docDir(),0,";",&off)).size(); ) for(iTr = 0; iTr < transl.size(); ++iTr) { for(iT = 0; iT < sizeof(types)/5; ++iT) if((hd=open((pathi+"/"+transl[iTr]+"/"+nm+"."+types[iT]).c_str(),O_RDONLY)) != -1) break; if(hd != -1) break; } if(hd != -1) { if(tp) *tp = types[iT]; if(opt&GetPathURL) rez = pathi+"/"+transl[iTr]+"/"+nm+"."+types[iT]; else if(opt&GetContent) { char buf[prmStrBuf_SZ]; for(int len = 0; (len=read(hd,buf,sizeof(buf))) > 0; ) rez.append(buf,len); } else rez = "xdg-open "+pathi+"/"+transl[iTr]+"/"+nm+"."+types[iT]+" &"; if(close(hd) != 0) mess_warning("TUIS", _("Closing the file %d error '%s (%d)'!"), hd, strerror(errno), errno); } // Detect the LTS and connect to the network copy of the offline documentation if(rez.empty() && (nm=TSYS::strParse(inm,0,"|")).size() && TSYS::strParse(inm,1,"|").size()) { TArrayObj *tArr; if((tArr=TRegExp("(0.\\d+|\\d+)\\.\\d+").match(VERSION))) { if(tArr->size() >= 2) { const char *docHost = "ftp.oscada.org/OpenSCADA"; if(opt&GetPathURL) rez = string("http://") + docHost + "/" + tArr->arGet(1).getS() + "/doc/en/" + nm + ".html"; else if(opt&GetContent) ;//rez = req.text(); else rez = string("xdg-open ") + "http://" + docHost + "/" + tArr->arGet(1).getS() + "/doc/en/" + nm + ".html &"; } delete tArr; } } //Use the online document in the network if(rez.empty() && (nm=TSYS::strParse(inm,1,"|")).size()) { const char *docHost = "oscada.org/wiki/Special:MyLanguage"; if(opt&GetPathURL) rez = string("http://") + docHost + "/" + nm; else if(opt&GetContent) ;//rez = req.text(); else rez = string("xdg-open ") + "http://" + docHost + "/" + nm + " &"; } return rez; } string TUIS::docKeyGet( const string &itxt ) { string rezKey; TArrayObj *rez; if((rez=TRegExp("DOC:\\s*(.+)$").match(itxt))) { if(rez->size() >= 2) rezKey = rez->arGet(1).getS(); delete rez; } return rezKey; } string TUIS::mimeGet( const string &inm, const string &fDt, const string &orig ) { string prc = TSYS::strParse(orig,0,";"), stvl; //First init to empty orig if(prc.empty() || TSYS::pathLev(prc,1).empty()) prc = "file/"+ ((inm.rfind(".")==string::npos)?"unknown":inm.substr(inm.rfind(".")+1)); //Adjust to group for used and known ones stvl = TSYS::pathLev(prc, 1); const char *tvl = stvl.c_str(); // Text/documents if(strcasecmp(tvl,"txt") == 0) prc = "text/plain"; else if(strcasecmp(tvl,"xml") == 0) prc = "text/xml"; else if(strcasecmp(tvl,"html") == 0) prc = "text/html"; else if(strcasecmp(tvl,"css") == 0) prc = "text/css"; else if(strcasecmp(tvl,"js") == 0) prc = "text/javascript"; else if(strcasecmp(tvl,"sgml") == 0) prc = "text/sgml"; else if(strcasecmp(tvl,"docbook") == 0) prc = "text/docbook"; else if(strcasecmp(tvl,"csv") == 0) prc = "text/csv"; else if(strcasecmp(tvl,"diff") == 0) prc = "text/diff"; else if(strcasecmp(tvl,"log") == 0) prc = "text/log"; else if(strcasecmp(tvl,"rtf") == 0) prc = "text/rtf"; else if(strcasecmp(tvl,"ics") == 0) prc = "text/calendar"; else if(strcasecmp(tvl,"vcs") == 0) prc = "text/vcalendar"; else if(strcasecmp(tvl,"vcf") == 0 || strcasecmp(tvl,"vct") == 0) prc = "text/vcard"; else if(strcasecmp(tvl,"pdf") == 0) prc = "application/pdf"; else if(strcasecmp(tvl,"odt") == 0) prc = "application/vnd.oasis.opendocument.text"; // Images else if(strcasecmp(tvl,"png") == 0) prc = "image/png"; else if(strcasecmp(tvl,"jpg") == 0 || strcasecmp(tvl,"jpeg") == 0) prc = "image/jpg"; else if(strcasecmp(tvl,"gif") == 0) prc = "image/gif"; else if(strcasecmp(tvl,"tif") == 0 || strcasecmp(tvl,"tiff") == 0) prc = "image/tiff"; else if(strcasecmp(tvl,"xpm") == 0) prc = "image/xpm"; else if(strcasecmp(tvl,"ico") == 0) prc = "image/ico"; else if(strcasecmp(tvl,"pcx") == 0) prc = "image/pcx"; else if(strcasecmp(tvl,"bmp") == 0) prc = "image/bmp"; else if(strcasecmp(tvl,"svg") == 0 || strcasecmp(tvl,"svg+xml") == 0) prc = "image/svg+xml"; //string("image/") + ((fDt.find("name() == "info") { TSubSYS::cntrCmdProc(opt); if(ctrMkNode("area",opt,0,"/sub",_("Subsystem"),R_R_R_)) ctrMkNode("fld",opt,-1,"/sub/fontSnthHglCode",_("Syntax highlight font for code"),RWRWR_,"root",SUI_ID,1,"tp","str"); return; } //Process command to page string a_path = opt->attr("path"); if(a_path == "/sub/fontSnthHglCode") { if(ctrChkNode(opt,"get",RWRWR_,"root",SDAQ_ID,SEC_RD)) opt->setText(fontSnthHglCode()); if(ctrChkNode(opt,"set",RWRWR_,"root",SDAQ_ID,SEC_WR)) setFontSnthHglCode(opt->text()); } else TSubSYS::cntrCmdProc(opt); } //************************************************* //* TUI * //************************************************* TUI::TUI( const string &id ) : TModule(id), runSt(false) { } void TUI::cntrCmdProc( XMLNode *opt ) { //Get page info if(opt->name() == "info") { TModule::cntrCmdProc(opt); if(ctrMkNode("area",opt,0,"/prm",_("User interface"))) if(ctrMkNode("area",opt,-1,"/prm/st",_("State"))) ctrMkNode("fld",opt,-1,"/prm/st/r_st",_("Running"),RWRWR_,"root",SUI_ID,1,"tp","bool"); return; } //Process command to page string a_path = opt->attr("path"); if(a_path == "/prm/st/r_st") { if(ctrChkNode(opt,"get",RWRWR_,"root",SUI_ID,SEC_RD)) opt->setText(runSt?"1":"0"); if(ctrChkNode(opt,"set",RWRWR_,"root",SUI_ID,SEC_WR)) s2i(opt->text()) ? modStart() : modStop(); } else TModule::cntrCmdProc(opt); }