42using namespace std::string_literals;
64 std::string
GetUrl()
override {
return ""s; }
66 void Show(
const std::string &)
override {}
68 bool DrawElement(std::shared_ptr<Browsable::RElement> &elem,
const std::string & =
"")
override
71 auto code = elem->GetContent(
"text");
78 auto json = elem->GetContent(
"json");
82 fTitle = elem->GetName() +
".json";
93 auto img = elem->GetContent(
"image64");
115 std::string msg =
fIsEditor ?
"EDITOR:"s :
"IMAGE:"s;
142 std::string
GetKind()
const override {
return "info"s; }
144 std::string
GetUrl()
override {
return ""s; }
146 void Show(
const std::string &)
override {}
148 bool DrawElement(std::shared_ptr<Browsable::RElement> &,
const std::string & =
"")
override {
return false; }
155 std::ostringstream pathtmp;
158 std::ofstream ofs(pathtmp.str(), std::ofstream::out | std::ofstream::app);
163 gROOT->ProcessLine(
".g");
166 std::ifstream infile(pathtmp.str());
180 int indx = 0, last_prompt = -1;
181 for (
auto &
line : logs) {
187 if (last_prompt < 0) {
196 for (
auto &
line : logs) {
228 void Show(
const std::string &)
override {}
230 std::string
GetKind()
const override {
return "catched"s; }
258 if (
gROOT->IsWebDisplayBatch()) {
259 ::Warning(
"RBrowser::RBrowser",
"The RBrowser cannot run in web batch mode");
263 std::ostringstream pathtmp;
272 fWebWindow->SetDefaultPage(
"file:rootui5sys/browser/browser.html");
276 [
this](
unsigned connid,
const std::string &arg) {
if ((connid ==
fConnId) && (
fConnId != 0xffffff))
ProcessMsg(connid, arg); });
303 return widget ? true :
false;
326 fWebWindow->GetManager()->SetShowCallback(
nullptr);
334 std::unique_ptr<RBrowserRequest> request;
337 request = std::make_unique<RBrowserRequest>();
339 request->number = 100;
341 request = TBufferJSON::FromJSON<RBrowserRequest>(msg);
358 if (fname.empty())
return;
360 std::ofstream
f(fname);
369 if (file_path.rfind(
".py") == file_path.length() - 3) {
371 exec.
Form(
"TPython::ExecScript(\"%s\");", file_path.c_str());
385 std::string opt = args.back();
389 path.insert(path.end(), args.begin(), args.end());
394 if (!elem)
return ""s;
396 auto dflt_action = elem->GetDefaultAction();
400 std::string widget_kind;
403 widget_kind =
"rcanvas";
405 widget_kind =
"tcanvas";
415 new_widget->fBrowser =
this;
417 new_widget->Show(
"embed");
426 elem->GetChildsIter();
430 if (widget && widget->DrawElement(elem, opt)) {
431 widget->SetPath(path);
432 return widget->SendWidgetContent();
437 [path](
const std::shared_ptr<RBrowserWidget> &wg) { return path == wg->GetPath(); });
440 return "SELECT_WIDGET:"s + (*iter)->GetName();
446 std::string widget_kind;
447 switch(dflt_action) {
454 default: widget_kind.clear();
457 if (!widget_kind.empty()) {
458 auto new_widget =
AddWidget(widget_kind);
462 if (new_widget->DrawElement(elem, opt))
463 new_widget->SetPath(path);
470 for (
auto &pathelem : path)
487 if (!
fWebWindow->NumConnections() || always_start_new_browser) {
511 std::shared_ptr<RBrowserWidget> widget;
513 if (kind ==
"editor"s)
514 widget = std::make_shared<RBrowserEditorWidget>(
name,
true);
515 else if (kind ==
"image"s)
516 widget = std::make_shared<RBrowserEditorWidget>(
name,
false);
517 else if (kind ==
"info"s)
518 widget = std::make_shared<RBrowserInfoWidget>(
name);
527 widget->fBrowser =
this;
528 widget->Show(
"embed");
541 if (url.empty())
return nullptr;
545 auto widget = std::make_shared<RBrowserCatchedWidget>(
name, url, kind);
571 [
name, kind](
const std::shared_ptr<RBrowserWidget> &widget) {
572 return kind.empty() ? name == widget->GetName() : kind == widget->GetKind();
586 auto iter = std::find_if(
fWidgets.begin(),
fWidgets.end(), [
name](std::shared_ptr<RBrowserWidget> &widget) { return name == widget->GetName(); });
599 std::vector<std::string> arr;
602 path +=
"/.root_hist" ;
603 std::ifstream infile(path);
607 while (std::getline(infile,
line) && (arr.size() < 1000)) {
608 if(!(std::find(arr.begin(), arr.end(),
line) != arr.end())) {
609 arr.emplace_back(
line);
622 std::vector<std::string> arr;
627 while (std::getline(infile,
line) && (arr.size() < 10000)) {
628 arr.emplace_back(
line);
640 std::vector<std::vector<std::string>> reply;
646 reply.emplace_back(std::vector<std::string>({ widget->GetKind(), widget->GetUrl(), widget->GetName(), widget->GetTitle() }));
650 reply.emplace_back(std::vector<std::string>({
"active"s, fActiveWidgetName }));
653 if (history.size() > 0) {
654 history.insert(history.begin(),
"history"s);
655 reply.emplace_back(history);
659 if (logs.size() > 0) {
660 logs.insert(logs.begin(),
"logs"s);
661 reply.emplace_back(logs);
664 reply.emplace_back(std::vector<std::string>({
671 std::string msg =
"INMSG:";
690 std::vector<std::string> arr = { widget->GetKind(), widget->GetUrl(), widget->GetName(), widget->GetTitle(),
701 widget->CheckModified();
709 R__LOG_DEBUG(0,
BrowserLog()) <<
"ProcessMsg len " << arg0.length() <<
" substr(30) " << arg0.substr(0, 30);
711 std::string kind, msg;
712 auto pos = arg0.find(
":");
713 if (pos == std::string::npos) {
716 kind = arg0.substr(0, pos);
717 msg = arg0.substr(pos+1);
720 if (kind ==
"QUIT_ROOT") {
724 }
else if (kind ==
"BRREQ") {
729 }
else if (kind ==
"DBLCLK") {
733 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
734 if (arr && (arr->size() > 2))
742 }
else if (kind ==
"WIDGET_SELECTED") {
746 auto reply = widget->SendWidgetContent();
747 if (!reply.empty())
fWebWindow->Send(connid, reply);
749 }
else if (kind ==
"CLOSE_TAB") {
751 }
else if (kind ==
"GETWORKPATH") {
753 }
else if (kind ==
"CHPATH") {
754 auto path = TBufferJSON::FromJSON<Browsable::RElementPath_t>(msg);
757 }
else if (kind ==
"CMD") {
758 std::string sPrompt =
"root []";
761 sPrompt = ((
TRint*)
gROOT->GetApplication())->GetPrompt();
762 Gl_histadd((
char *)msg.c_str());
766 ofs << sPrompt << msg << std::endl;
770 gROOT->ProcessLine(msg.c_str());
774 auto widget = std::dynamic_pointer_cast<RBrowserInfoWidget>(
FindWidget(
""s,
"info"s));
778 widget = std::dynamic_pointer_cast<RBrowserInfoWidget>(new_widget);
780 fWebWindow->Send(connid,
"SELECT_WIDGET:"s + widget->GetName());
785 widget->RefreshFromLogs(sPrompt + msg,
GetRootLogs());
789 }
else if (kind ==
"GETHISTORY") {
794 }
else if (kind ==
"GETLOGS") {
799 }
else if (kind ==
"FILEDIALOG") {
801 }
else if (kind ==
"SYNCEDITOR") {
802 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
803 if (arr && (arr->size() > 4)) {
804 auto editor = std::dynamic_pointer_cast<RBrowserEditorWidget>(
FindWidget(arr->at(0)));
806 editor->fFirstSend =
true;
807 editor->fTitle = arr->at(1);
808 editor->fFileName = arr->at(2);
809 if (!arr->at(3).empty()) editor->fContent = arr->at(4);
810 if ((arr->size() == 6) && (arr->at(5) ==
"SAVE"))
812 if ((arr->size() == 6) && (arr->at(5) ==
"RUN")) {
818 }
else if (kind ==
"GETINFO") {
819 auto info = std::dynamic_pointer_cast<RBrowserInfoWidget>(
FindWidget(msg));
822 fWebWindow->Send(connid, info->SendWidgetContent());
824 }
else if (kind ==
"NEWWIDGET") {
828 }
else if (kind ==
"CDWORKDIR") {
836 }
else if (kind ==
"OPTIONS") {
837 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
838 if (arr && (arr->size() == 3)) {
871 if (widget->GetTitle() != title)
874 if (!kind.empty() && (widget->GetKind() != kind))
878 fWebWindow->Send(0,
"SELECT_WIDGET:"s + widget->GetName());
#define R__LOG_ERROR(...)
#define R__LOG_DEBUG(DEBUGLEVEL,...)
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t win
R__EXTERN TSystem * gSystem
static int ExtractItemIndex(std::string &name)
Extract index from name Index coded by client with ###<indx>$$$ suffix Such coding used by browser to...
static std::string GetPathAsString(const RElementPath_t &path)
Converts element path back to string.
@ kActEdit
can provide data for text editor
@ kActCanvas
indicate that it is canvas and should be drawn directly
@ kActBrowse
just browse (expand) item
@ kActGeom
can be shown in geometry viewer
@ kActDraw7
can be drawn inside ROOT7 canvas
@ kActTree
can be shown in tree viewer
@ kActImage
can be shown in image viewer, can provide image
@ kActDraw6
can be drawn inside ROOT6 canvas
static RElementPath_t ParsePath(const std::string &str)
Parse string path to produce RElementPath_t One should avoid to use string pathes as much as possible...
static bool SetClassDrawOption(const ClassArg &, const std::string &)
Set draw option for the class Return true if entry for the class exists.
static std::string GetClassDrawOption(const ClassArg &)
Return configured draw option for the class.
static RElementPath_t GetWorkingPath(const std::string &workdir="")
Return working path in browser hierarchy.
std::shared_ptr< Browsable::RElement > GetSubElement(const Browsable::RElementPath_t &path)
Returns sub-element starting from top, using cached data.
const Browsable::RElementPath_t & GetWorkingPath() const
void ClearCache()
Clear internal objects cache.
std::string ProcessRequest(const RBrowserRequest &request)
Process browser request, returns string with JSON of RBrowserReply data.
void SetWorkingPath(const Browsable::RElementPath_t &path)
set working directory relative to top element
void CreateDefaultElements()
Create default elements shown in the RBrowser.
std::shared_ptr< RBrowserWidget > AddWidget(const std::string &kind)
Creates new widget.
std::vector< std::string > GetRootHistory()
Get content of history file.
void AddInitWidget(const std::string &kind)
Create new widget and send init message to the client.
void SetWorkingPath(const std::string &path)
Set working path in the browser.
std::string NewWidgetMsg(std::shared_ptr< RBrowserWidget > &widget)
Create message which send to client to create new widget.
bool GetUseRCanvas() const
std::shared_ptr< RWebWindow > fWebWindow
! web window to browser
std::shared_ptr< RBrowserWidget > GetActiveWidget() const
void Show(const RWebDisplayArgs &args="", bool always_start_new_browser=false)
show Browser in specified place
std::string GetCurrentWorkingDirectory()
Return the current directory of ROOT.
std::shared_ptr< RBrowserWidget > AddCatchedWidget(const std::string &url, const std::string &kind)
Add widget catched from external scripts.
std::shared_ptr< RBrowserWidget > FindWidget(const std::string &name, const std::string &kind="") const
Find widget by name or kind.
virtual ~RBrowser()
destructor
int fWidgetCnt
! counter for created widgets
RBrowserData fBrowsable
! central browsing element
void ProcessSaveFile(const std::string &fname, const std::string &content)
Process file save command in the editor.
void CheckWidgtesModified()
Check if any widget was modified and update if necessary.
std::string ProcessBrowserRequest(const std::string &msg)
Process browser request.
std::string fActiveWidgetName
! name of active widget
std::vector< std::string > GetRootLogs()
Get content of log file.
void ProcessMsg(unsigned connid, const std::string &arg)
Process received message from the client.
bool fCatchWindowShow
! if arbitrary RWebWindow::Show calls should be catched by browser
RBrowser(bool use_rcanvas=true)
constructor
void CloseTab(const std::string &name)
Close and delete specified widget.
void SetUseRCanvas(bool on=true)
bool ActivateWidget(const std::string &title, const std::string &kind="")
Activate widget in RBrowser One should specify title and (optionally) kind of widget like "tcanvas" o...
void SendInitMsg(unsigned connid)
Process client connect.
std::string ProcessDblClick(std::vector< std::string > &args)
Process dbl click on browser item.
unsigned fConnId
! default connection id
void ProcessRunMacro(const std::string &file_path)
Process run macro command in the editor.
std::string fPromptFileOutput
! file name for prompt output
std::vector< std::shared_ptr< RBrowserWidget > > fWidgets
! all browser widgets
static std::shared_ptr< RFileDialog > Embedded(const std::shared_ptr< RWebWindow > &window, const std::string &args)
Create dialog instance to use as embedded dialog inside other widget Embedded dialog started on the c...
Holds different arguments for starting browser with RWebDisplayHandle::Display() method.
const std::string & GetWidgetKind() const
returns widget kind
Represents web window, which can be shown in web browser or any other supported environment.
static std::shared_ptr< RWebWindow > Create()
Create new RWebWindow Using default RWebWindowsManager.
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
static TString ToJSON(const T *obj, Int_t compact=0, const char *member_name=nullptr)
@ kNoSpaces
no new lines plus remove all spaces around "," and ":" symbols
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
const char * Data() const
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
virtual int GetPid()
Get process id.
virtual const char * UnixPathName(const char *unixpathname)
Convert from a local pathname to a Unix pathname.
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
virtual int Unlink(const char *name)
Unlink, i.e.
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
RLogChannel & BrowserLog()
Log channel for Browser diagnostics.