Creating custom TBrowser actions, bug in TGFileBrowser.cxx?

Hi, I was playing around with the browser and trying to add an action to a custom type (so that you could double-click on it in the browser, e.g. [url=https://root-forum.cern.ch/t/set-own-icon-in-tbrowser/19905/1 here[/url]), and found a bug in TGFileBrowser. (Sorry for not posting on JIRA, for some reason I can’t open a bug.)

You can create actions that call a method on the object, by specifying “->Method()” as the action (in the MIME database). “Draw” and “Browse” are special cased to use the current draw options. But there is no way to call an external function instead of a method. It seems this was intended, you could put “%s” in the action string and it would be replaced by the object name, but the code in TGFileBrowser is a bit nonsensical and doesn’t work.

In particular, if “%s” is in the string, it is replaced. But the “else” branch is not taken, and “act” is never used again.

Also, it seems you are supposed to be able to execute an external command via “! command %s”, but again this will never work since the code just prepended the object name, and only then checks if the first character is “!”.

act = action;
if (act.Contains("%s")) act.ReplaceAll("%s", obj->GetName());
else if (fBrowser && act.Contains("->Browse()")) obj->Browse(fBrowser);
else if (act.Contains("->Draw()")) obj->Draw(GetDrawOption());
else {
   act.Prepend(obj->GetName());
   gInterpreter->SaveGlobalsContext();
   if (act[0] == '!') {
      act.Remove(0, 1);
      gSystem->Exec(act.Data());
   } else {
      // special case for remote object: remote process
      if (obj->InheritsFrom("TRemoteObject"))
         gApplication->SetBit(TApplication::kProcessRemotely);
      gApplication->ProcessLine(act.Data());
   }
}

(Side note: One thing this would be nice for is to be able to add actions to built-in types, e.g.

void DrawTNamed(const TNamed *named) {
    TLatex *lat = new TLatex();
    lat->DrawLatexNDC(0.1, 0.9, named->GetTitle());
}
gClient->GetMimeTypeList()->AddType("[root/tnamed]", "TNamed", "macro_s.xpm", "macro_t.xpm", "DrawTNamed(%s)");

and then you could view TNameds by double-clicking them in the browser. I’m using a couple of TNameds to store metadata in a .root file (source files, cuts, etc.). Of course, the best thing would be to add something like that as a method to TNamed, or even better, add a dedicated metadata holder class, but that is beyond the scope of this bug report :slight_smile:)

cheers,
Jason

Hi Jason,

This should be fixed now in the master and v5-34-00-patches branch. Could you give it a try?

Cheers, Bertrand.

Hi Bertrand,

thanks! I tried the master branch and it works (the “func(%s)” syntax).

cheers,
Jason

Hi Jason,

Good! Thanks for the feedback.

Cheers, Bertrand.