3 classvar <>defaultHomeUrl;
4 classvar <>openNewWindows = false;
15 NotificationCenter.register(SCDoc, \docMapDidUpdate, this) {
16 if(WebView.implClass.respondsTo(\clearCache)) {
24 if( singleton.isNil ) {
26 singleton.window.onClose = {
34 *new { arg aHomeUrl, newWin;
35 if( aHomeUrl.isNil ) {
36 aHomeUrl = defaultHomeUrl ?? { SCDoc.helpTargetDir ++ "/Help.html" };
38 ^super.new.init( aHomeUrl, newWin ?? { openNewWindows } );
42 if(openNewWindows,{this.new},{this.instance}).goTo(url);
46 this.goTo(SCDoc.helpTargetDir++"/Browse.html");
49 text = if(text.notNil) {"#"++text} {""};
50 this.goTo(SCDoc.helpTargetDir++"/Search.html"++text);
53 this.goTo(SCDoc.findHelpFile(text));
55 *openHelpForMethod {|method|
56 var cls = method.ownerClass;
57 var met = method.name.asString;
59 cls = cls.name.asString.drop(5);
62 cls = cls.name.asString;
65 this.goTo(Help.dir+/+"Classes"+/+cls++".html#"++met);
69 ^("file://" ++ SCDoc.helpTargetDir +/+ "OldHelpWrapper.html#"++url++"?"++
70 SCDoc.helpTargetDir +/+ if((c=url.basename.split($.).first).asSymbol.asClass.notNil)
71 {"Classes" +/+ c ++ ".html"}
72 {"Guides/WritingHelp.html"})
75 goTo {|url, brokenAction|
76 var newPath, oldPath, plainTextExts = #[".sc",".scd",".txt",".schelp"];
78 //FIXME: since multiple scdoc queries can be running at the same time,
79 //it would be best to create a queue and run them in order, but only use the url from the last.
83 ^this.openTextFile(url);
90 brokenAction = brokenAction ? {SCDoc.helpTargetDir++"/BrokenLink.html#"++url};
93 url = SCDoc.prepareHelpForURL(url) ?? brokenAction;
94 #newPath, oldPath = [url,webView.url].collect {|x|
95 if(x.notEmpty) {x.findRegexp("(^\\w+://)?([^#]+)(#.*)?")[1..].flop[1][1]}
97 // detect old helpfiles and open them in OldHelpWrapper
98 if(block{|break| Help.do {|key,path| if(url.endsWith(path)) {break.value(true)}}; false}) {
99 url = HelpBrowser.getOldWrapUrl(url)
102 // needed since onLoadFinished is not called if the path did not change:
103 if(newPath == oldPath) {webView.onLoadFinished.value};
105 webView.html = err.errorString;
111 goHome { this.goTo(homeUrl); }
113 goBack { webView.back; }
115 goForward { webView.forward; }
117 /* ------------------------------ private ------------------------------ */
119 init { arg aHomeUrl, aNewWin;
121 var lblFind, txtFind, findView, saveSize, toggleFind;
122 var strh = "Tj".bounds.height;
123 var vPad = 10, hPad = 20;
131 winRect = Rect(0, 0, 800, (Window.screenBounds.height * 0.8).floor);
132 winRect = winRect.moveToPoint(winRect.centerIn(Window.screenBounds));
134 window = Window.new( bounds: winRect ).name_("SuperCollider Help");
140 [[\Back,"<"], [\Forward,">"], [\Reload, "Reload"]].do { |item|
142 var w = str.bounds.width + hPad;
143 toolbar[item[0]] = Button( window, Rect(x,y,w,h) ).states_([[str]]);
148 str = "Quick lookup:";
149 w = str.bounds.width + 5;
150 StaticText(window, Rect(x,y,w,h)).string_(str);
153 srchBox = TextField.new( window, Rect(x,y,w,h) ).resize_(1);
154 if(GUI.current.id == \qt) {
155 srchBox.toolTip = "Smart quick help lookup. Prefix with # to just search.";
157 srchBox.action = {|x|
158 if(x.string.notEmpty) {
159 this.goTo(if(x.string.first==$#)
160 {SCDoc.helpTargetDir++"/Search.html#"++x.string.drop(1)}
161 {SCDoc.findHelpFile(x.string)}
166 openNewWin = aNewWin;
168 if(GUI.current.respondsTo(\checkBox)) {
169 str = "Open links in new window";
170 w = str.bounds.width + 50;
171 CheckBox.new (window, Rect(x, y, w, h) )
175 .action_({ |b| openNewWin = b.value });
177 str = "Open links in same window";
178 w = str.bounds.width + 5;
179 Button.new( window, Rect(x, y, w, h) )
181 .states_([[str],["Open links in new window"]])
182 .value_(openNewWin.asInteger)
183 .action_({ |b| openNewWin = b.value.asBoolean });
189 findView = CompositeView(window, Rect(x,y,w,h+10)).visible_(false).resize_(2);
192 x = winRect.width - marg - w;
193 txtFind = TextField.new( findView, Rect(x,y,w,h) ).resize_(3);
194 str = "Find text in document:";
195 w = str.bounds.width + 5;
197 lblFind = StaticText.new( findView, Rect(x, y, w, h) )
203 w = winRect.width - 10;
204 h = winRect.height - y - marg;
205 webView = WebView.new( window, Rect(x,y,w,h) ).resize_(5);
206 webView.html = "Please wait while initializing Help... (This might take several seconds the first time)";
208 if(webView.respondsTo(\setFontFamily)) {
209 webView.setFontFamily(\fixed, Platform.case(
211 \linux, { "Andale Mono" },
216 webView.onLoadFinished = {
218 window.name = "SuperCollider Help: %".format(webView.title);
220 webView.onLoadFailed = { this.stopAnim };
221 webView.onLinkActivated = {|wv, url|
222 var newPath, oldPath;
224 #newPath, oldPath = [url,webView.url].collect {|x|
225 if(x.notEmpty) {x.findRegexp("(^\\w+://)?([^#]+)(#.*)?")[1..].flop[1][1]}
228 if(newPath!=oldPath) {
229 HelpBrowser.new(newWin:true).goTo(url);
234 if(webView.respondsTo(\onReload_)) {
235 webView.onReload = {|wv, url|
241 if(findView.visible.not) {
242 saveSize = webView.bounds;
243 h = findView.bounds.height + marg;
244 webView.bounds = Rect(saveSize.left,saveSize.top+h,saveSize.width,saveSize.height-h);
245 findView.visible = true;
248 webView.bounds = saveSize;
249 findView.visible = false;
253 webView.enterInterpretsSelection = true;
254 webView.keyDownAction = { arg view, char, mods;
255 if( (char.ascii == 13) && (mods.isCtrl || mods.isCmd || mods.isShift) ) {
256 view.tryPerform(\evaluateJavaScript,"selectLine()");
259 window.view.keyDownAction = { arg view, char, mods;
260 if( ((char.ascii == 6) && mods.isCtrl) || (char == $f && mods.isCmd) ) {
264 if(findView.visible) {toggleFind.value};
268 toolbar[\Back].action = { this.goBack };
269 toolbar[\Forward].action = { this.goForward };
270 toolbar[\Reload].action = { this.goTo( webView.url ) };
271 txtFind.action = { |x| webView.findText( x.string ); };
275 var win, winRect, txt, file, fonts;
276 path = path.replace("%20"," ").findRegexp("(^\\w+://)?([^#]+)(#.*)?")[1..].flop[1][1];
277 if(File.exists(path)) {
280 webView.url = SCDoc.helpTargetDir++"/BrokenLink.html#"++path;
286 var progress = [">---","->--","-->-","--->"];
287 animCount = animCount + 1;
293 window.name = ("Loading"+p);
295 if(animCount==0) {break.value};
299 // lblStatus.string_("");
305 animCount = animCount - 1;
313 HelpBrowser.instance.goHome;