39using namespace std::string_literals;
61 std::string
GetUrl()
override {
return ""s; }
63 void Show(
const std::string &)
override {}
65 bool DrawElement(std::shared_ptr<Browsable::RElement> &elem,
const std::string &)
override
68 auto code = elem->GetContent(
"text");
75 auto json = elem->GetContent(
"json");
79 fTitle = elem->GetName() +
".json";
90 auto img = elem->GetContent(
"image64");
112 std::string msg =
fIsEditor ?
"EDITOR:"s :
"IMAGE:"s;
125 void Show(
const std::string &)
override {}
127 std::string
GetKind()
const override {
return "catched"; }
164 fWebWindow->SetDefaultPage(
"file:rootui5sys/browser/browser.html");
168 [
this](
unsigned connid,
const std::string &arg) {
ProcessMsg(connid, arg); });
186 std::string url =
fWebWindow->GetRelativeAddr(win);
193 return widget ? true :
false;
215 fWebWindow->GetManager()->SetShowCallback(
nullptr);
224 std::unique_ptr<RBrowserRequest> request;
227 request = std::make_unique<RBrowserRequest>();
229 request->number = 100;
231 request = TBufferJSON::FromJSON<RBrowserRequest>(msg);
248 if (fname.empty())
return;
250 std::ofstream
f(fname);
259 if (file_path.rfind(
".py") == file_path.length() - 3) {
261 exec.
Form(
"TPython::ExecScript(\"%s\");", file_path.c_str());
275 std::string drawingOptions = args.back();
279 path.insert(path.end(), args.begin(), args.end());
284 if (!elem)
return ""s;
286 auto dflt_action = elem->GetDefaultAction();
290 std::string widget_kind;
293 widget_kind =
"rcanvas";
295 widget_kind =
"tcanvas";
304 new_widget->Show(
"embed");
312 if (widget && widget->DrawElement(elem, drawingOptions)) {
313 widget->SetPath(path);
314 return widget->SendWidgetContent();
319 [path](
const std::shared_ptr<RBrowserWidget> &wg) { return path == wg->GetPath(); });
322 return "SELECT_WIDGET:"s + (*iter)->GetName();
328 std::string widget_kind;
329 switch(dflt_action) {
335 default: widget_kind.clear();
338 if (!widget_kind.empty()) {
339 auto new_widget =
AddWidget(widget_kind);
343 if (new_widget->DrawElement(elem, drawingOptions))
344 new_widget->SetPath(path);
351 for (
auto &pathelem : path)
367 if (!
fWebWindow->NumConnections() || always_start_new_browser) {
393 std::shared_ptr<RBrowserWidget> widget;
395 if (kind ==
"editor")
396 widget = std::make_shared<RBrowserEditorWidget>(
name,
true);
397 else if (kind ==
"image")
398 widget = std::make_shared<RBrowserEditorWidget>(
name,
false);
407 widget->Show(
"embed");
420 if (url.empty())
return nullptr;
424 auto widget = std::make_shared<RBrowserCatchedWidget>(
name, url, kind);
450 [
name](
const std::shared_ptr<RBrowserWidget> &widget) { return name == widget->GetName(); });
463 auto iter = std::find_if(
fWidgets.begin(),
fWidgets.end(), [
name](std::shared_ptr<RBrowserWidget> &widget) { return name == widget->GetName(); });
476 std::vector<std::string> arr;
479 path +=
"/.root_hist" ;
480 std::ifstream infile(path);
484 while (std::getline(infile,
line) && (arr.size() < 1000)) {
485 if(!(std::find(arr.begin(), arr.end(),
line) != arr.end())) {
486 arr.emplace_back(
line);
499 std::vector<std::string> arr;
501 std::ostringstream pathtmp;
504 std::ifstream infile(pathtmp.str());
507 while (std::getline(infile,
line) && (arr.size() < 10000)) {
508 arr.emplace_back(
line);
520 std::vector<std::vector<std::string>> reply;
526 reply.emplace_back(std::vector<std::string>({ widget->GetKind(), widget->GetUrl(), widget->GetName(), widget->GetTitle() }));
530 reply.emplace_back(std::vector<std::string>({
"active", fActiveWidgetName }));
533 if (history.size() > 0) {
534 history.insert(history.begin(),
"history");
535 reply.emplace_back(history);
539 if (logs.size() > 0) {
540 logs.insert(logs.begin(),
"logs");
541 reply.emplace_back(logs);
544 std::string msg =
"INMSG:";
563 std::vector<std::string> arr = { widget->GetKind(), widget->GetUrl(), widget->GetName(), widget->GetTitle() };
573 widget->CheckModified();
581 R__LOG_DEBUG(0,
BrowserLog()) <<
"ProcessMsg len " << arg0.length() <<
" substr(30) " << arg0.substr(0, 30);
583 std::string kind, msg;
584 auto pos = arg0.find(
":");
585 if (pos == std::string::npos) {
588 kind = arg0.substr(0, pos);
589 msg = arg0.substr(pos+1);
592 if (kind ==
"QUIT_ROOT") {
596 }
else if (kind ==
"BRREQ") {
599 if (!json.empty())
fWebWindow->Send(connid, json);
601 }
else if (kind ==
"DBLCLK") {
605 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
606 if (arr && (arr->size() > 2))
614 }
else if (kind ==
"WIDGET_SELECTED") {
618 auto reply = widget->SendWidgetContent();
619 if (!reply.empty())
fWebWindow->Send(connid, reply);
621 }
else if (kind ==
"CLOSE_TAB") {
623 }
else if (kind ==
"GETWORKPATH") {
625 }
else if (kind ==
"CHPATH") {
626 auto path = TBufferJSON::FromJSON<Browsable::RElementPath_t>(msg);
629 }
else if (kind ==
"CMD") {
630 std::string sPrompt =
"root []";
631 std::ostringstream pathtmp;
635 sPrompt = ((
TRint*)
gROOT->GetApplication())->GetPrompt();
636 Gl_histadd((
char *)msg.c_str());
639 std::ofstream ofs(pathtmp.str(), std::ofstream::out | std::ofstream::app);
640 ofs << sPrompt << msg << std::endl;
644 gROOT->ProcessLine(msg.c_str());
647 }
else if (kind ==
"GETHISTORY") {
652 }
else if (kind ==
"GETLOGS") {
657 }
else if (kind ==
"FILEDIALOG") {
659 }
else if (kind ==
"SYNCEDITOR") {
660 auto arr = TBufferJSON::FromJSON<std::vector<std::string>>(msg);
661 if (arr && (arr->size() > 4)) {
662 auto editor = std::dynamic_pointer_cast<RBrowserEditorWidget>(
FindWidget(arr->at(0)));
664 editor->fFirstSend =
true;
665 editor->fTitle = arr->at(1);
666 editor->fFileName = arr->at(2);
667 if (!arr->at(3).empty()) editor->fContent = arr->at(4);
668 if ((arr->size() == 6) && (arr->at(5) ==
"SAVE"))
670 if ((arr->size() == 6) && (arr->at(5) ==
"RUN")) {
676 }
else if (kind ==
"NEWWIDGET") {
680 }
else if (kind ==
"CDWORKDIR") {
#define R__LOG_ERROR(...)
#define R__LOG_DEBUG(DEBUGLEVEL,...)
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
@ 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 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.
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.
std::shared_ptr< RBrowserWidget > FindWidget(const std::string &name) const
Returns active geometry viewer (if any)
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)
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::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 const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
RLogChannel & BrowserLog()
Log channel for Browser diagnostics.