Logo ROOT  
Reference Guide
RBrowser.cxx
Go to the documentation of this file.
1// Authors: Bertrand Bellenot <bertrand.bellenot@cern.ch> Sergey Linev <S.Linev@gsi.de>
2// Date: 2019-02-28
3// Warning: This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
4
5/*************************************************************************
6 * Copyright (C) 1995-2021, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#include <ROOT/RBrowser.hxx>
14
16
17#include <ROOT/RLogger.hxx>
18#include <ROOT/RFileDialog.hxx>
20
21#include "RBrowserWidget.hxx"
22
23#include "TString.h"
24#include "TSystem.h"
25#include "TROOT.h"
26#include "TBufferJSON.h"
27#include "TApplication.h"
28#include "TRint.h"
29#include "Getline.h"
30
31#include <sstream>
32#include <iostream>
33#include <algorithm>
34#include <memory>
35#include <mutex>
36#include <thread>
37#include <fstream>
38
39using namespace std::string_literals;
40
41using namespace ROOT::Experimental;
42
43
45public:
46
47 bool fIsEditor{true}; ///<! either editor or image viewer
48 std::string fTitle;
49 std::string fFileName;
50 std::string fContent;
51 bool fFirstSend{false}; ///<! if editor content was send at least one
52 std::string fItemPath; ///<! item path in the browser
53
54 RBrowserEditorWidget(const std::string &name, bool is_editor = true) : RBrowserWidget(name), fIsEditor(is_editor) {}
55 virtual ~RBrowserEditorWidget() = default;
56
57 void ResetConn() override { fFirstSend = false; }
58
59 std::string GetKind() const override { return fIsEditor ? "editor"s : "image"s; }
60 std::string GetTitle() override { return fTitle; }
61 std::string GetUrl() override { return ""s; }
62
63 void Show(const std::string &) override {}
64
65 bool DrawElement(std::shared_ptr<Browsable::RElement> &elem, const std::string &, bool) override
66 {
67 if (fIsEditor && elem->IsCapable(Browsable::RElement::kActEdit)) {
68 auto code = elem->GetContent("text");
69 if (!code.empty()) {
70 fFirstSend = false;
71 fContent = code;
72 fTitle = elem->GetName();
73 fFileName = elem->GetContent("filename");
74 } else {
75 auto json = elem->GetContent("json");
76 if (!json.empty()) {
77 fFirstSend = false;
78 fContent = json;
79 fTitle = elem->GetName() + ".json";
80 fFileName = "";
81 }
82 }
83 if (!fContent.empty()) {
84 // page->fItemPath = item_path;
85 return true;
86 }
87 }
88
89 if (!fIsEditor && elem->IsCapable(Browsable::RElement::kActImage)) {
90 auto img = elem->GetContent("image64");
91 if (!img.empty()) {
92 fFirstSend = false;
93 fContent = img;
94 fTitle = elem->GetName();
95 fFileName = elem->GetContent("filename");
96 // fItemPath = item_path;
97
98 return true;
99 }
100 }
101
102 return false;
103 }
104
105 std::string SendWidgetContent() override
106 {
107 if (fFirstSend) return ""s;
108
109 fFirstSend = true;
110 std::vector<std::string> args = { GetName(), fTitle, fFileName, fContent };
111
112 std::string msg = fIsEditor ? "EDITOR:"s : "IMAGE:"s;
113 msg += TBufferJSON::ToJSON(&args).Data();
114 return msg;
115 }
116
117};
118
120public:
121
122 std::string fUrl; // url of catched widget
123 std::string fCatchedKind; // kind of catched widget
124
125 void Show(const std::string &) override {}
126
127 std::string GetKind() const override { return "catched"; }
128
129 std::string GetUrl() override { return fUrl; }
130
131 std::string GetTitle() override { return fCatchedKind; }
132
133 RBrowserCatchedWidget(const std::string &name, const std::string &url, const std::string &kind) :
135 fUrl(url),
136 fCatchedKind(kind)
137 {
138 }
139};
140
141
142/** \class ROOT::Experimental::RBrowser
143\ingroup rbrowser
144\brief Web-based %ROOT file browser
145
146RBrowser requires one of the supported web browsers:
147 - Google Chrome (preferable)
148 - Mozilla Firefox
149
150\image html v7_rbrowser.png
151
152*/
153
154//////////////////////////////////////////////////////////////////////////////////////////////
155/// constructor
156
157RBrowser::RBrowser(bool use_rcanvas)
158{
159 SetUseRCanvas(use_rcanvas);
160
162
164 fWebWindow->SetDefaultPage("file:rootui5sys/browser/browser.html");
165
166 // this is call-back, invoked when message received via websocket
167 fWebWindow->SetCallBacks([this](unsigned connid) { fConnId = connid; SendInitMsg(connid); },
168 [this](unsigned connid, const std::string &arg) { ProcessMsg(connid, arg); });
169 fWebWindow->SetGeometry(1200, 700); // configure predefined window geometry
170 fWebWindow->SetConnLimit(1); // the only connection is allowed
171 fWebWindow->SetMaxQueueLength(30); // number of allowed entries in the window queue
172
173 fWebWindow->GetManager()->SetShowCallback([this](RWebWindow &win, const RWebDisplayArgs &args) -> bool {
174
175 std::string kind;
176
177 if (args.GetWidgetKind() == "RCanvas")
178 kind = "rcanvas";
179 else if (args.GetWidgetKind() == "TCanvas")
180 kind = "tcanvas";
181 else if (args.GetWidgetKind() == "REveGeomViewer")
182 kind = "geom";
183
184 if (!fWebWindow || !fCatchWindowShow || kind.empty()) return false;
185
186 std::string url = fWebWindow->GetRelativeAddr(win);
187
188 auto widget = AddCatchedWidget(url, kind);
189
190 if (widget && fWebWindow && (fWebWindow->NumConnections() > 0))
191 fWebWindow->Send(0, NewWidgetMsg(widget));
192
193 return widget ? true : false;
194 });
195
196 Show();
197
198 // add first canvas by default
199
200 //if (GetUseRCanvas())
201 // AddWidget("rcanvas");
202 //else
203 // AddWidget("tcanvas");
204
205 // AddWidget("geom"); // add geometry viewer at the beginning
206
207 // AddWidget("editor"); // one can add empty editor if necessary
208}
209
210//////////////////////////////////////////////////////////////////////////////////////////////
211/// destructor
212
214{
215 fWebWindow->GetManager()->SetShowCallback(nullptr);
216}
217
218
219//////////////////////////////////////////////////////////////////////////////////////////////
220/// Process browser request
221
222std::string RBrowser::ProcessBrowserRequest(const std::string &msg)
223{
224 std::unique_ptr<RBrowserRequest> request;
225
226 if (msg.empty()) {
227 request = std::make_unique<RBrowserRequest>();
228 request->first = 0;
229 request->number = 100;
230 } else {
231 request = TBufferJSON::FromJSON<RBrowserRequest>(msg);
232 }
233
234 if (!request)
235 return ""s;
236
237 if (request->path.empty() && fWidgets.empty() && fBrowsable.GetWorkingPath().empty())
239
240 return "BREPL:"s + fBrowsable.ProcessRequest(*request.get());
241}
242
243/////////////////////////////////////////////////////////////////////////////////
244/// Process file save command in the editor
245
246void RBrowser::ProcessSaveFile(const std::string &fname, const std::string &content)
247{
248 if (fname.empty()) return;
249 R__LOG_DEBUG(0, BrowserLog()) << "SaveFile " << fname << " content length " << content.length();
250 std::ofstream f(fname);
251 f << content;
252}
253
254/////////////////////////////////////////////////////////////////////////////////
255/// Process run macro command in the editor
256
257void RBrowser::ProcessRunMacro(const std::string &file_path)
258{
259 if (file_path.rfind(".py") == file_path.length() - 3) {
260 TString exec;
261 exec.Form("TPython::ExecScript(\"%s\");", file_path.c_str());
262 gROOT->ProcessLine(exec.Data());
263 } else {
264 gInterpreter->ExecuteMacro(file_path.c_str());
265 }
266}
267
268/////////////////////////////////////////////////////////////////////////////////
269/// Process dbl click on browser item
270
271std::string RBrowser::ProcessDblClick(std::vector<std::string> &args)
272{
273 args.pop_back(); // remove exec string, not used now
274
275 std::string doAppend = args.back();
276 args.pop_back(); // remove append option
277
278 std::string drawingOptions = args.back();
279 args.pop_back(); // remove draw option
280
281 auto path = fBrowsable.GetWorkingPath();
282 path.insert(path.end(), args.begin(), args.end());
283
284 R__LOG_DEBUG(0, BrowserLog()) << "DoubleClick " << Browsable::RElement::GetPathAsString(path);
285
286 auto elem = fBrowsable.GetSubElement(path);
287 if (!elem) return ""s;
288
289 auto dflt_action = elem->GetDefaultAction();
290
291 // special case when canvas is clicked - always start new widget
292 if (dflt_action == Browsable::RElement::kActCanvas) {
293 std::string widget_kind;
294
295 if (elem->IsCapable(Browsable::RElement::kActDraw7))
296 widget_kind = "rcanvas";
297 else
298 widget_kind = "tcanvas";
299
300 std::string name = widget_kind + std::to_string(++fWidgetCnt);
301
302 auto new_widget = RBrowserWidgetProvider::CreateWidgetFor(widget_kind, name, elem);
303
304 if (!new_widget)
305 return ""s;
306
307 new_widget->Show("embed");
308 fWidgets.emplace_back(new_widget);
309 fActiveWidgetName = new_widget->GetName();
310
311 return NewWidgetMsg(new_widget);
312 }
313
314 auto widget = GetActiveWidget();
315 if (widget && widget->DrawElement(elem, drawingOptions, doAppend == "true"s)) {
316 widget->SetPath(path);
317 return widget->SendWidgetContent();
318 }
319
320 // check if element was drawn in other widget and just activate that widget
321 auto iter = std::find_if(fWidgets.begin(), fWidgets.end(),
322 [path](const std::shared_ptr<RBrowserWidget> &wg) { return path == wg->GetPath(); });
323
324 if (iter != fWidgets.end())
325 return "SELECT_WIDGET:"s + (*iter)->GetName();
326
327 // check if object can be drawn in RCanvas even when default action is drawing in TCanvas
328 if ((dflt_action == Browsable::RElement::kActDraw6) && GetUseRCanvas() && elem->IsCapable(Browsable::RElement::kActDraw7))
329 dflt_action = Browsable::RElement::kActDraw7;
330
331 std::string widget_kind;
332 switch(dflt_action) {
333 case Browsable::RElement::kActGeom: widget_kind = "geom"; break;
334 case Browsable::RElement::kActDraw6: widget_kind = "tcanvas"; break;
335 case Browsable::RElement::kActDraw7: widget_kind = "rcanvas"; break;
336 case Browsable::RElement::kActEdit: widget_kind = "editor"; break;
337 case Browsable::RElement::kActImage: widget_kind = "image"; break;
338 default: widget_kind.clear();
339 }
340
341 if (!widget_kind.empty()) {
342 auto new_widget = AddWidget(widget_kind);
343 if (new_widget) {
344 // draw object before client side is created - should not be a problem
345 // after widget add in browser, connection will be established and data provided
346 if (new_widget->DrawElement(elem, drawingOptions, false))
347 new_widget->SetPath(path);
348 return NewWidgetMsg(new_widget);
349 }
350 }
351
352 if (elem->IsCapable(Browsable::RElement::kActBrowse) && (elem->GetNumChilds() > 0)) {
353 // remove extra index in subitems name
354 for (auto &pathelem : path)
358 }
359
360 return ""s;
361}
362
363/////////////////////////////////////////////////////////////////////////////////
364/// Show or update RBrowser in web window
365/// If web window already started - just refresh it like "reload" button does
366/// If no web window exists or \param always_start_new_browser configured, starts new window
367/// \param args display arguments
368
369void RBrowser::Show(const RWebDisplayArgs &args, bool always_start_new_browser)
370{
371 if (!fWebWindow->NumConnections() || always_start_new_browser) {
372 fWebWindow->Show(args);
373 } else {
374 SendInitMsg(0);
375 }
376}
377
378///////////////////////////////////////////////////////////////////////////////////////////////////////
379/// Hide ROOT Browser
380
382{
383 if (!fWebWindow)
384 return;
385
386 fWebWindow->CloseConnections();
387}
388
389
390//////////////////////////////////////////////////////////////////////////////////////////////
391/// Creates new widget
392
393std::shared_ptr<RBrowserWidget> RBrowser::AddWidget(const std::string &kind)
394{
395 std::string name = kind + std::to_string(++fWidgetCnt);
396
397 std::shared_ptr<RBrowserWidget> widget;
398
399 if (kind == "editor")
400 widget = std::make_shared<RBrowserEditorWidget>(name, true);
401 else if (kind == "image")
402 widget = std::make_shared<RBrowserEditorWidget>(name, false);
403 else
405
406 if (!widget) {
407 R__LOG_ERROR(BrowserLog()) << "Fail to create widget of kind " << kind;
408 return nullptr;
409 }
410
411 widget->Show("embed");
412 fWidgets.emplace_back(widget);
413
415
416 return widget;
417}
418
419//////////////////////////////////////////////////////////////////////////////////////////////
420/// Add widget catched from external scripts
421
422std::shared_ptr<RBrowserWidget> RBrowser::AddCatchedWidget(const std::string &url, const std::string &kind)
423{
424 if (url.empty()) return nullptr;
425
426 std::string name = "catched"s + std::to_string(++fWidgetCnt);
427
428 auto widget = std::make_shared<RBrowserCatchedWidget>(name, url, kind);
429
430 fWidgets.emplace_back(widget);
431
433
434 return widget;
435}
436
437
438//////////////////////////////////////////////////////////////////////////////////////////////
439/// Create new widget and send init message to the client
440
441void RBrowser::AddInitWidget(const std::string &kind)
442{
443 auto widget = AddWidget(kind);
444 if (widget && fWebWindow && (fWebWindow->NumConnections() > 0))
445 fWebWindow->Send(0, NewWidgetMsg(widget));
446}
447
448//////////////////////////////////////////////////////////////////////////////////////////////
449/// Returns active geometry viewer (if any)
450
451std::shared_ptr<RBrowserWidget> RBrowser::FindWidget(const std::string &name) const
452{
453 auto iter = std::find_if(fWidgets.begin(), fWidgets.end(),
454 [name](const std::shared_ptr<RBrowserWidget> &widget) { return name == widget->GetName(); });
455
456 if (iter != fWidgets.end())
457 return *iter;
458
459 return nullptr;
460}
461
462//////////////////////////////////////////////////////////////////////////////////////////////
463/// Close and delete specified widget
464
465void RBrowser::CloseTab(const std::string &name)
466{
467 auto iter = std::find_if(fWidgets.begin(), fWidgets.end(), [name](std::shared_ptr<RBrowserWidget> &widget) { return name == widget->GetName(); });
468 if (iter != fWidgets.end())
469 fWidgets.erase(iter);
470
471 if (fActiveWidgetName == name)
472 fActiveWidgetName.clear();
473}
474
475//////////////////////////////////////////////////////////////////////////////////////////////
476/// Get content of history file
477
478std::vector<std::string> RBrowser::GetRootHistory()
479{
480 std::vector<std::string> arr;
481
482 std::string path = gSystem->UnixPathName(gSystem->HomeDirectory());
483 path += "/.root_hist" ;
484 std::ifstream infile(path);
485
486 if (infile) {
487 std::string line;
488 while (std::getline(infile, line) && (arr.size() < 1000)) {
489 if(!(std::find(arr.begin(), arr.end(), line) != arr.end())) {
490 arr.emplace_back(line);
491 }
492 }
493 }
494
495 return arr;
496}
497
498//////////////////////////////////////////////////////////////////////////////////////////////
499/// Get content of log file
500
501std::vector<std::string> RBrowser::GetRootLogs()
502{
503 std::vector<std::string> arr;
504
505 std::ostringstream pathtmp;
506 pathtmp << gSystem->TempDirectory() << "/command." << gSystem->GetPid() << ".log";
507
508 std::ifstream infile(pathtmp.str());
509 if (infile) {
510 std::string line;
511 while (std::getline(infile, line) && (arr.size() < 10000)) {
512 arr.emplace_back(line);
513 }
514 }
515
516 return arr;
517}
518
519//////////////////////////////////////////////////////////////////////////////////////////////
520/// Process client connect
521
522void RBrowser::SendInitMsg(unsigned connid)
523{
524 std::vector<std::vector<std::string>> reply;
525
526 reply.emplace_back(fBrowsable.GetWorkingPath()); // first element is current path
527
528 for (auto &widget : fWidgets) {
529 widget->ResetConn();
530 reply.emplace_back(std::vector<std::string>({ widget->GetKind(), widget->GetUrl(), widget->GetName(), widget->GetTitle() }));
531 }
532
533 if (!fActiveWidgetName.empty())
534 reply.emplace_back(std::vector<std::string>({ "active", fActiveWidgetName }));
535
536 auto history = GetRootHistory();
537 if (history.size() > 0) {
538 history.insert(history.begin(), "history");
539 reply.emplace_back(history);
540 }
541
542 auto logs = GetRootLogs();
543 if (logs.size() > 0) {
544 logs.insert(logs.begin(), "logs");
545 reply.emplace_back(logs);
546 }
547
548 std::string msg = "INMSG:";
549 msg.append(TBufferJSON::ToJSON(&reply, TBufferJSON::kNoSpaces).Data());
550
551 fWebWindow->Send(connid, msg);
552}
553
554//////////////////////////////////////////////////////////////////////////////////////////////
555/// Return the current directory of ROOT
556
558{
559 return "WORKPATH:"s + TBufferJSON::ToJSON(&fBrowsable.GetWorkingPath()).Data();
560}
561
562//////////////////////////////////////////////////////////////////////////////////////////////
563/// Create message which send to client to create new widget
564
565std::string RBrowser::NewWidgetMsg(std::shared_ptr<RBrowserWidget> &widget)
566{
567 std::vector<std::string> arr = { widget->GetKind(), widget->GetUrl(), widget->GetName(), widget->GetTitle() };
568 return "NEWWIDGET:"s + TBufferJSON::ToJSON(&arr, TBufferJSON::kNoSpaces).Data();
569}
570
571//////////////////////////////////////////////////////////////////////////////////////////////
572/// Check if any widget was modified and update if necessary
573
575{
576 for (auto &widget : fWidgets)
577 widget->CheckModified();
578}
579
580//////////////////////////////////////////////////////////////////////////////////////////////
581/// Process received message from the client
582
583void RBrowser::ProcessMsg(unsigned connid, const std::string &arg0)
584{
585 R__LOG_DEBUG(0, BrowserLog()) << "ProcessMsg len " << arg0.length() << " substr(30) " << arg0.substr(0, 30);
586
587 std::string kind, msg;
588 auto pos = arg0.find(":");
589 if (pos == std::string::npos) {
590 kind = arg0;
591 } else {
592 kind = arg0.substr(0, pos);
593 msg = arg0.substr(pos+1);
594 }
595
596 if (kind == "QUIT_ROOT") {
597
598 fWebWindow->TerminateROOT();
599
600 } else if (kind == "BRREQ") {
601 // central place for processing browser requests
602 auto json = ProcessBrowserRequest(msg);
603 if (!json.empty()) fWebWindow->Send(connid, json);
604
605 } else if (kind == "DBLCLK") {
606
607 std::string reply;
608
609 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
610 if (arr && (arr->size() > 2))
611 reply = ProcessDblClick(*arr);
612
613 if (reply.empty())
614 reply = "NOPE";
615
616 fWebWindow->Send(connid, reply);
617
618 } else if (kind == "WIDGET_SELECTED") {
619 fActiveWidgetName = msg;
620 auto widget = GetActiveWidget();
621 if (widget) {
622 auto reply = widget->SendWidgetContent();
623 if (!reply.empty()) fWebWindow->Send(connid, reply);
624 }
625 } else if (kind == "CLOSE_TAB") {
626 CloseTab(msg);
627 } else if (kind == "GETWORKPATH") {
628 fWebWindow->Send(connid, GetCurrentWorkingDirectory());
629 } else if (kind == "CHPATH") {
630 auto path = TBufferJSON::FromJSON<Browsable::RElementPath_t>(msg);
631 if (path) fBrowsable.SetWorkingPath(*path);
632 fWebWindow->Send(connid, GetCurrentWorkingDirectory());
633 } else if (kind == "CMD") {
634 std::string sPrompt = "root []";
635 std::ostringstream pathtmp;
636 pathtmp << gSystem->TempDirectory() << "/command." << gSystem->GetPid() << ".log";
637 TApplication *app = gROOT->GetApplication();
638 if (app->InheritsFrom("TRint")) {
639 sPrompt = ((TRint*)gROOT->GetApplication())->GetPrompt();
640 Gl_histadd((char *)msg.c_str());
641 }
642
643 std::ofstream ofs(pathtmp.str(), std::ofstream::out | std::ofstream::app);
644 ofs << sPrompt << msg << std::endl;
645 ofs.close();
646
647 gSystem->RedirectOutput(pathtmp.str().c_str(), "a");
648 gROOT->ProcessLine(msg.c_str());
649 gSystem->RedirectOutput(nullptr);
651 } else if (kind == "GETHISTORY") {
652
653 auto history = GetRootHistory();
654
655 fWebWindow->Send(connid, "HISTORY:"s + TBufferJSON::ToJSON(&history, TBufferJSON::kNoSpaces).Data());
656 } else if (kind == "GETLOGS") {
657
658 auto logs = GetRootLogs();
659 fWebWindow->Send(connid, "LOGS:"s + TBufferJSON::ToJSON(&logs, TBufferJSON::kNoSpaces).Data());
660
661 } else if (kind == "FILEDIALOG") {
663 } else if (kind == "SYNCEDITOR") {
664 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
665 if (arr && (arr->size() > 4)) {
666 auto editor = std::dynamic_pointer_cast<RBrowserEditorWidget>(FindWidget(arr->at(0)));
667 if (editor) {
668 editor->fFirstSend = true;
669 editor->fTitle = arr->at(1);
670 editor->fFileName = arr->at(2);
671 if (!arr->at(3).empty()) editor->fContent = arr->at(4);
672 if ((arr->size() == 6) && (arr->at(5) == "SAVE"))
673 ProcessSaveFile(editor->fFileName, editor->fContent);
674 if ((arr->size() == 6) && (arr->at(5) == "RUN")) {
675 ProcessSaveFile(editor->fFileName, editor->fContent);
676 ProcessRunMacro(editor->fFileName);
677 }
678 }
679 }
680 } else if (kind == "NEWWIDGET") {
681 auto widget = AddWidget(msg);
682 if (widget)
683 fWebWindow->Send(connid, NewWidgetMsg(widget));
684 } else if (kind == "CDWORKDIR") {
686 if (fBrowsable.GetWorkingPath() != wrkdir) {
688 } else {
690 }
691 fWebWindow->Send(connid, GetCurrentWorkingDirectory());
692 }
693}
694
695//////////////////////////////////////////////////////////////////////////////////////////////
696/// Set working path in the browser
697
698void RBrowser::SetWorkingPath(const std::string &path)
699{
701 auto elem = fBrowsable.GetSubElement(p);
702 if (elem) {
704 if (fWebWindow && (fWebWindow->NumConnections() > 0))
706 }
707}
708
#define R__LOG_ERROR(...)
Definition: RLogger.hxx:362
#define R__LOG_DEBUG(DEBUGLEVEL,...)
Definition: RLogger.hxx:365
#define f(i)
Definition: RSha256.hxx:104
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
char name[80]
Definition: TGX11.cxx:110
#define gInterpreter
Definition: TInterpreter.h:564
#define gROOT
Definition: TROOT.h:404
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
void Show(const std::string &) override
Definition: RBrowser.cxx:125
RBrowserCatchedWidget(const std::string &name, const std::string &url, const std::string &kind)
Definition: RBrowser.cxx:133
std::string fCatchedKind
Definition: RBrowser.cxx:123
std::string GetTitle() override
Definition: RBrowser.cxx:131
std::string GetUrl() override
Definition: RBrowser.cxx:129
std::string GetKind() const override
Definition: RBrowser.cxx:127
bool fIsEditor
! either editor or image viewer
Definition: RBrowser.cxx:47
void ResetConn() override
Definition: RBrowser.cxx:57
std::string GetTitle() override
Definition: RBrowser.cxx:60
std::string GetUrl() override
Definition: RBrowser.cxx:61
std::string SendWidgetContent() override
Definition: RBrowser.cxx:105
RBrowserEditorWidget(const std::string &name, bool is_editor=true)
Definition: RBrowser.cxx:54
std::string fContent
Definition: RBrowser.cxx:50
std::string fItemPath
! item path in the browser
Definition: RBrowser.cxx:52
std::string GetKind() const override
Definition: RBrowser.cxx:59
bool fFirstSend
! if editor content was send at least one
Definition: RBrowser.cxx:51
void Show(const std::string &) override
Definition: RBrowser.cxx:63
std::string fTitle
Definition: RBrowser.cxx:48
std::string fFileName
Definition: RBrowser.cxx:49
bool DrawElement(std::shared_ptr< Browsable::RElement > &elem, const std::string &, bool) override
Definition: RBrowser.cxx:65
virtual ~RBrowserEditorWidget()=default
static int ExtractItemIndex(std::string &name)
Extract index from name Index coded by client with ###<indx>$$$ suffix Such coding used by browser to...
Definition: RElement.cxx:164
static std::string GetPathAsString(const RElementPath_t &path)
Converts element path back to string.
Definition: RElement.cxx:146
@ kActEdit
can provide data for text editor
Definition: RElement.hxx:52
@ kActCanvas
indicate that it is canvas and should be drawn directly
Definition: RElement.hxx:56
@ kActBrowse
just browse (expand) item
Definition: RElement.hxx:51
@ kActGeom
can be shown in geometry viewer
Definition: RElement.hxx:57
@ kActDraw7
can be drawn inside ROOT7 canvas
Definition: RElement.hxx:55
@ kActImage
can be shown in image viewer, can provide image
Definition: RElement.hxx:53
@ kActDraw6
can be drawn inside ROOT6 canvas
Definition: RElement.hxx:54
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...
Definition: RElement.cxx:102
static RElementPath_t GetWorkingPath(const std::string &workdir="")
Return working path in browser hierarchy.
Definition: RSysFile.cxx:573
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.
static std::shared_ptr< RBrowserWidget > CreateWidgetFor(const std::string &kind, const std::string &name, std::shared_ptr< Browsable::RElement > &element)
Create specified widget for existing object.
static std::shared_ptr< RBrowserWidget > CreateWidget(const std::string &kind, const std::string &name)
Create specified widget.
Abstract Web-based widget, which can be used in the RBrowser Used to embed canvas,...
const std::string & GetName() const
std::shared_ptr< RBrowserWidget > AddWidget(const std::string &kind)
Creates new widget.
Definition: RBrowser.cxx:393
std::vector< std::string > GetRootHistory()
Get content of history file.
Definition: RBrowser.cxx:478
void AddInitWidget(const std::string &kind)
Create new widget and send init message to the client.
Definition: RBrowser.cxx:441
void SetWorkingPath(const std::string &path)
Set working path in the browser.
Definition: RBrowser.cxx:698
void Hide()
hide Browser
Definition: RBrowser.cxx:381
std::string NewWidgetMsg(std::shared_ptr< RBrowserWidget > &widget)
Create message which send to client to create new widget.
Definition: RBrowser.cxx:565
std::shared_ptr< RWebWindow > fWebWindow
! web window to browser
Definition: RBrowser.hxx:40
std::shared_ptr< RBrowserWidget > GetActiveWidget() const
Definition: RBrowser.hxx:47
void Show(const RWebDisplayArgs &args="", bool always_start_new_browser=false)
show Browser in specified place
Definition: RBrowser.cxx:369
std::string GetCurrentWorkingDirectory()
Return the current directory of ROOT.
Definition: RBrowser.cxx:557
std::shared_ptr< RBrowserWidget > AddCatchedWidget(const std::string &url, const std::string &kind)
Add widget catched from external scripts.
Definition: RBrowser.cxx:422
virtual ~RBrowser()
destructor
Definition: RBrowser.cxx:213
int fWidgetCnt
! counter for created widgets
Definition: RBrowser.hxx:38
RBrowserData fBrowsable
! central browsing element
Definition: RBrowser.hxx:42
void ProcessSaveFile(const std::string &fname, const std::string &content)
Process file save command in the editor.
Definition: RBrowser.cxx:246
void CheckWidgtesModified()
Check if any widget was modified and update if necessary.
Definition: RBrowser.cxx:574
std::string ProcessBrowserRequest(const std::string &msg)
Process browser request.
Definition: RBrowser.cxx:222
std::string fActiveWidgetName
! name of active widget
Definition: RBrowser.hxx:36
std::vector< std::string > GetRootLogs()
Get content of log file.
Definition: RBrowser.cxx:501
void ProcessMsg(unsigned connid, const std::string &arg)
Process received message from the client.
Definition: RBrowser.cxx:583
std::shared_ptr< RBrowserWidget > FindWidget(const std::string &name) const
Returns active geometry viewer (if any)
Definition: RBrowser.cxx:451
bool fCatchWindowShow
! if arbitrary RWebWindow::Show calls should be catched by browser
Definition: RBrowser.hxx:35
void CloseTab(const std::string &name)
Close and delete specified widget.
Definition: RBrowser.cxx:465
void SetUseRCanvas(bool on=true)
Definition: RBrowser.hxx:73
void SendInitMsg(unsigned connid)
Process client connect.
Definition: RBrowser.cxx:522
std::string ProcessDblClick(std::vector< std::string > &args)
Process dbl click on browser item.
Definition: RBrowser.cxx:271
unsigned fConnId
! default connection id
Definition: RBrowser.hxx:32
void ProcessRunMacro(const std::string &file_path)
Process run macro command in the editor.
Definition: RBrowser.cxx:257
std::vector< std::shared_ptr< RBrowserWidget > > fWidgets
! all browser widgets
Definition: RBrowser.hxx:37
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.
Definition: RWebWindow.hxx:53
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...
Definition: TApplication.h:39
static TString ToJSON(const T *obj, Int_t compact=0, const char *member_name=nullptr)
Definition: TBufferJSON.h:75
@ kNoSpaces
no new lines plus remove all spaces around "," and ":" symbols
Definition: TBufferJSON.h:39
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:449
Definition: TRint.h:31
Basic string class.
Definition: TString.h:136
const char * Data() const
Definition: TString.h:369
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2319
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1713
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:710
virtual const char * UnixPathName(const char *unixpathname)
Convert from a local pathname to a Unix pathname.
Definition: TSystem.cxx:1063
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition: TSystem.cxx:888
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1482
TLine * line
RLogChannel & BrowserLog()
Log channel for Browser diagnostics.
static constexpr double s
basic_json<> json
Definition: REveElement.hxx:62