How to control editor navigation from XUI tree control?

Neither Clay Helberg nor the PTC gurus seem to solve this completely... Last Updated: 2006-10-24

=Original question by N.N.=

I have a tree with nodes that represent sections in a document. I would like the editor to position the cursor at the element selected in the tree. I am using javascript and AOM. Any ideas?

=Clay Helberg answers=

We have a very similar dockable dialog that shows the topic structure of the document. The key bit of code is the following script, which appears as a child of the element (id="topictree") in the XUI dialog:

 // scroll main doc to selected topic dlgdoc = Application.event.target.ownerDocument; // get selected tree node sel = dlgdoc.getElementById("topictree").getElementsByAttribute("selected","true",1); // get the document doc = Application.activeWindow.activeView.document; // if we got the dialog document, then get the parent view's document instead if (doc.name == "topicmap.xml") doc = Application.activeWindow.parent.activeView.document; // as long as there's a selected node, find the corresponding topic element and goto it   if (sel.length > 0) { targetnode = doc.getElementsByAttribute("id",sel.item(0).getAttribute("appdata"),1).item(0); Acl.execute("goto_oid('"+targetnode.firstOID+"');"); }   else { //Application.alert("couldn't find any selected tree nodes"); }

The script assumes that the appdata attribute of the treenode is set to an ID that can be used to identify the target node in the document. We retrieve the document node with that ID using the getElementsByAttribute function (ADocument interface), and then slip into ACL to move the cursor there using the goto_oid function.

=N.N. replies=

Thanx for the help Clay, this worked dandy. Now for the last touch, I now need to set focus from my dialog to the editor automatically so it can have the effect of select a tree node and then start typing at the caret location. I have tried various flavors of setting current_window to no avail.

=Clay Helberg=

I played around a little bit, primarily with the "caret" command, but I couldn't make it do the expected thing from the context of AOM in a docked XUI dialog. I also noticed that docked XUI dialogs don't participate in the F6 cycle (which is supposed to cycle through windows, but does nothing when the cursor is inside a XUI dialog, and ignores XUI dialogs if you start in the edit or command window).

Maybe one of the Arbortext (er, I mean PTC) AOM gurus can help out here...?

=Rob In der Maur (PTC) provides a workaround=

This should be solved in Epic 5.1L. You can use F6 to toggle between edit window, command window and docked dialog.

I also used a trick to programmatically move the focus from a docked dialog to an edit window. As the docked dialog seems to be tied to the editor window, you have to move focus to the command window. If there is no command window, you can briefly create it, set focus to it, move focus to edit window and remove command window. This will have no noticeable effect on the UI.

I know, it's a workaround :)

The example below is in JScript:

/** * @method setEditorFocus * @abstract ensure focus is on Epic's main window rather than on docked dialog * @returns void */ function setEditorFocus { // set cmdline,if not already on, so we can use it to move cursor if (Application.getOption("cmdline") == "off") { Acl.execute("set cmdline=on"); Acl.execute("caret cmd"); Acl.execute("caret edit"); Acl.execute("set cmdline=off"); } }

=N.N. replies=

I tried your suggestion and here are the results:

I upgraded to 5.1M. Out of the box I can make a selection from my tree dialog. The editor window will scroll to the selected location and put the caret in the proper location as before. The focus at this time is still on the tree node. If I press F6 the focus will go to the edit window and place the I-beam right where it is supposed too. That's more than what I had before.

Next I tried the workaround code suggested by Rob. When this executes I can see the focus flash in the command line and then return to the dialog with the tree, not the editor frame. So back to square one.

The desired effect is that the user selects a node from the tree, the editor window navigates to the selected element and the cursor is left in the element so the user can start typing without any additional navigation/focus keystrokes. Is there a way to execute "F6" programmatically?

=Tung Fu (PTC) adds more=

Here is a way to use ACL to move focus to the edit pane:

local win = current_window; local i, arr[]; local count = window_list(arr, 'edit', current_window); for (i = 1; i <= count; i++) { # don't move focus to the docmap view pane if (window_get(arr[i], 'docmapview') == 0) { win = arr[i]; break; }  }   window_activate(win);

The current_window can be an edit pane or a command pane, so I use window_list to make sure I get the window id of an edit pane. I don't want the focus to be in the docmap view pane, and the window_get tells me if a pane is a docmap view.

The window_activate moves focus to a pane/window.

The F6 eventually executes focus_next_pane, which lives in lib/src/init.acl. However, his function is not documented, so it can be changed or removed in a future release.

=N.N. replies=

I coded this function in ACL as follows:

package epspec_func; function focusEdit { local win = current_window; local i, arr[]; local count = window_list(arr, 'edit', current_window); for (i = 1; i <= count; i++) { # don't move focus to the docmap view pane if (window_get(arr[i], 'docmapview') == 0) { win = arr[i]; break; }  }

And then called it from my javascript dialog code:

var sectionTree = xuidoc.getElementById("epspec_sections"); function handletreeSelect(e) {        // get selected tree node sel = xuidoc.getElementById(               "epspec_sections").getElementsByAttribute("selected","true",1) if (sel.length > 0) {            targetnode = actdoc.getElementsByAttribute("id",sel.item(0).getAttribute("appdata"),1).item(0); if(targetnode != null) {                if(targetnode.getNodeName == "bp_instructions") {                   targetnode = argetnode.getElementsByTagName("enter_response").item(0); }               Acl.execute("goto_oid('"+targetnode.firstOID+"');"); Acl.execute("epspec_func::focusEdit"); }        }         e.stopPropagation; }

It did not move the focus. However if I execute the function at the command line, it does as expected. There is something about dialog boxes that keep them from playing well with others. Thanks for the tip - the quest goes on.