10
10
#include < TBrowser.h>
11
11
#include < TError.h>
12
12
#include < TFile.h>
13
+ #include < TGFrame.h>
13
14
#include < TROOT.h>
14
15
#include < TSystem.h>
15
16
18
19
#include < iostream>
19
20
#include < memory>
20
21
#include < thread>
22
+ #include < string_view>
21
23
22
24
static const char *const kShortHelp = " usage: rootbrowse [-w WEB|-wf] <file.root>\n " ;
23
25
static const char *const kLongHelp = R"(
@@ -53,8 +55,8 @@ struct RootBrowseArgs {
53
55
kLong
54
56
};
55
57
EPrintUsage fPrintHelp = EPrintUsage::kNo ;
56
- const char * fWeb = " on " ;
57
- const char * fFileName = nullptr ;
58
+ std::string_view fWeb ;
59
+ std::string_view fFileName ;
58
60
};
59
61
60
62
static RootBrowseArgs ParseArgs (const char **args, int nArgs)
@@ -64,25 +66,50 @@ static RootBrowseArgs ParseArgs(const char **args, int nArgs)
64
66
65
67
for (int i = 0 ; i < nArgs; ++i) {
66
68
const char *arg = args[i];
69
+
70
+ if (strcmp (arg, " --" ) == 0 ) {
71
+ forcePositional = true ;
72
+ continue ;
73
+ }
74
+
67
75
bool isFlag = !forcePositional && arg[0 ] == ' -' ;
68
76
if (isFlag) {
69
- if (strcmp (arg, " -w" ) == 0 || strcmp (arg, " --web" ) == 0 ) {
77
+ ++arg;
78
+ // Parse long or short flag and its argument into `argStr` / `nxtArgStr`.
79
+ std::string_view argStr, nxtArgStr;
80
+ if (arg[0 ] == ' -' ) {
81
+ ++arg;
82
+ // long flag: may be either of the form `--web off` or `--web=off`
83
+ const char *eq = strchr (arg, ' =' );
84
+ if (eq) {
85
+ argStr = std::string_view (arg, eq - arg);
86
+ nxtArgStr = std::string_view (eq + 1 );
87
+ } else {
88
+ argStr = std::string_view (arg);
89
+ if (i < nArgs - 1 && args[i + 1 ][0 ] != ' -' ) {
90
+ nxtArgStr = args[i + 1 ];
91
+ ++i;
92
+ }
93
+ }
94
+ } else {
95
+ // short flag (note that it might be more than 1 character long, like `-wf`)
96
+ argStr = std::string_view (arg);
70
97
if (i < nArgs - 1 && args[i + 1 ][0 ] != ' -' ) {
98
+ nxtArgStr = args[i + 1 ];
71
99
++i;
72
- outArgs.fWeb = args[i];
73
100
}
74
- } else if (strcmp (arg, " -wf" ) == 0 || strcmp (arg, " --webOff" ) == 0 ) {
75
- outArgs.fWeb = " off" ;
76
- } else if (strcmp (arg, " -h" ) == 0 || strcmp (arg, " --help" ) == 0 ) {
101
+ }
102
+
103
+ if (argStr == " w" || argStr == " web" ) {
104
+ outArgs.fWeb = nxtArgStr.empty () ? " on" : nxtArgStr;
105
+ } else if (argStr == " h" || argStr == " help" ) {
77
106
outArgs.fPrintHelp = RootBrowseArgs::EPrintUsage::kLong ;
78
107
break ;
79
- } else if (strcmp (arg, " --" ) == 0 ) {
80
- forcePositional = true ;
81
- } else {
82
- outArgs.fPrintHelp = RootBrowseArgs::EPrintUsage::kShort ;
83
- break ;
108
+ } else if (argStr == " wf" || argStr == " --webOff" ) {
109
+ outArgs.fWeb = " off" ;
84
110
}
85
- } else if (outArgs.fFileName ) {
111
+
112
+ } else if (!outArgs.fFileName .empty ()) {
86
113
outArgs.fPrintHelp = RootBrowseArgs::EPrintUsage::kShort ;
87
114
break ;
88
115
} else {
@@ -105,23 +132,35 @@ int main(int argc, char **argv)
105
132
return 1 ;
106
133
}
107
134
108
- gROOT ->SetWebDisplay (args.fWeb );
135
+ // NOTE: we need to instantiate TApplication ourselves, otherwise TBrowser
136
+ // will create a batch application that cannot show graphics.
137
+ TApplication app (" rootbrowse" , nullptr , nullptr );
138
+
139
+ if (!args.fWeb .empty ())
140
+ gROOT ->SetWebDisplay (std::string (args.fWeb ).c_str ());
109
141
110
142
std::unique_ptr<TFile> file;
111
- if (args.fFileName ) {
143
+ if (! args.fFileName . empty () ) {
112
144
gErrorIgnoreLevel = kError ;
113
- file = std::unique_ptr<TFile>(TFile::Open (args.fFileName , " READ" ));
145
+ file = std::unique_ptr<TFile>(TFile::Open (std::string ( args.fFileName ). c_str () , " READ" ));
114
146
if (!file || file->IsZombie ()) {
115
147
R__LOG_WARNING (RootBrowseLog ()) << " File " << args.fFileName << " does not exist or is unreadable." ;
116
148
}
117
149
gErrorIgnoreLevel = kUnset ;
118
150
}
119
151
120
- // NOTE: we need to instantiate TApplication ourselves, otherwise TBrowser
121
- // will create a batch application that cannot show graphics.
122
- TApplication app (" rootbrowse" , nullptr , nullptr );
123
-
124
152
auto browser = std::make_unique<TBrowser>();
153
+
154
+ if (gROOT ->IsBatch ())
155
+ return 1 ;
156
+
157
+ // For classic graphics: ensure rootbrowse quits when the window is closed
158
+ if (auto imp = browser->GetBrowserImp ()) {
159
+ if (auto mainframe = imp->GetMainFrame ()) {
160
+ mainframe->Connect (" CloseWindow()" , " TApplication" , &app, " Terminate()" );
161
+ }
162
+ }
163
+
125
164
std::cout << " Press ctrl+c to exit.\n " ;
126
165
while (!gROOT ->IsInterrupted () && !gSystem ->ProcessEvents ()) {
127
166
std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
0 commit comments