Ditamaps Manager Context Menu Customisation

Post here questions and problems related to editing and publishing DITA content.
koushik9020
Posts: 13
Joined: Tue Dec 06, 2022 11:21 am

Ditamaps Manager Context Menu Customisation

Post by koushik9020 »

Hi Team,
I'm using WSDITAMapEditorPage API to customise my context Menu in the ditamaps manager with the below code:

Code: Select all

public void editorOpened(URL editorLocation) {
			  WSDITAMapEditorPage ditaMapEditorPage = (WSDITAMapEditorPage) oxygenWorkspace
					  .getEditorAccess(editorLocation, PluginWorkspace.DITA_MAPS_EDITING_AREA).getCurrentPage();

			  ditaMapEditorPage.setPopUpMenuCustomizer( (popUp, ditaMapDocumentController) -> {
				  AuthorNode[] selectedNodes = ditaMapEditorPage.getSelectedNodes(true);
				  if(!selectedNodes[0].getName().equals("topicref")){
					  return;
				  }
				  JPopupMenu mainPopUp = (JPopupMenu) popUp;
				  JMenu subMenu = new JMenu("Insert");

				  Action defineKeysAction = defineKeys(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
				  subMenu.add(defineKeysAction);
				  mainPopUp.addSeparator();
				 // mainPopUp.add(subMenu, 6);
				  
				  Action insertTopicRefAction = insertTopicReferenceAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
				  subMenu.add(insertTopicRefAction);
				  mainPopUp.addSeparator();
				  mainPopUp.add(subMenu, 6);
			  });
		  }
In the above code I'm trying to create a new JMenu("Insert") and adding the actions(insertTopicRefAction, defineKeysAction) under it which is working fine.

But I'm stuck with adding the same Abstract Actions (insertTopicRefAction, defineKeysAction) to the existing JMenu Under > Append Child in the context Menu of ditamaps manager like below way from my design requirements :
Note that these options appear only when the current map is editable.

Screenshot 2024-01-29 at 4.51.41 PM
Screenshot 2024-01-29 at 4.51.41 PM.png
Screenshot 2024-01-29 at 4.51.41 PM.png (124.27 KiB) Viewed 875 times

How do I add these Abstract Actions under Append Child in the context Menu, please advise.
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Ditamaps Manager Context Menu Customisation

Post by Radu »

Hi,

So you have a "JPopupMenu mainPopUp" which is a Java Swing JPopUpMenu. A JPopupMenu has plenty of API methods to obtain its child components, to iterate them, to find a specific JMenu with a specific name and then to add JMenuItems to it.

https://docs.oracle.com/javase/8/docs/a ... pMenu.html

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
koushik9020
Posts: 13
Joined: Tue Dec 06, 2022 11:21 am

Re: Ditamaps Manager Context Menu Customisation

Post by koushik9020 »

Thank you Radu!

Was able to do it.
koushik9020
Posts: 13
Joined: Tue Dec 06, 2022 11:21 am

Re: Ditamaps Manager Context Menu Customisation

Post by koushik9020 »

I'm using ditamaps manager > newly customised context Menu under> Append Child which open a customised dialog from our side and is supposed to insert an xml fragment as a child under a chapter inside a ditamap.

Is there any API that I could use to accomplish this task, please let me know.
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Ditamaps Manager Context Menu Customisation

Post by Radu »

Hi,
Looking at your code, you already have access to the "WSDITAMapEditorPage":
https://www.oxygenxml.com/InstData/Edit ... rPage.html

You can get the selected AuthorNode's:
https://www.oxygenxml.com/InstData/Edit ... s(boolean)

and then do something like:

Code: Select all

    AuthorNode[] selNodes = ditaMapEditorPage.getSelectedNodes(true);
    if(selNodes != null && selNodes.length > 0) {
      ditaMapEditorPage.getDocumentController().insertXMLFragment("<topicref href='abc'/>", selNodes[0].getEndOffset());
    }
The internal structure of nodes looks like this:
https://www.oxygenxml.com/InstData/Edit ... gment.html
So by inserting at the node "getEndOffset()" I'm inserting just before the end of the element.
To insert as first child I would use "selNodes[0].getStartOffset() + 1".
And to insert as an after sibling I would use "selNodes[0].getEndOffset() + 1".

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
koushik9020
Posts: 13
Joined: Tue Dec 06, 2022 11:21 am

Re: Ditamaps Manager Context Menu Customisation

Post by koushik9020 »

Thank Radu!

This worked.
vishwavaranasi
Posts: 144
Joined: Fri Feb 28, 2020 4:02 pm

Re: Ditamaps Manager Context Menu Customisation

Post by vishwavaranasi »

Hello Radu , extension to the previous question

How do I add Abstract Actions if the selected node from ditamapas manager is a "bookmap".

we have already the popup customization when selectedNodes[0].getName().equals("topicref")

similarly am trying


if(selectedNodes[0].getName().equals("bookmap")){
Action newbookMapAction = NewBookMapAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
bookmapsubMenu.add(newbookMapAction);
mainPopUp.addSeparator();
mainPopUp.add(bookmapsubMenu, 6);
}

but this is not working , when i right click on my bookmap node , no menu is showing up

Please help us here.

Code: Select all

public void editorOpened(URL editorLocation) {
			  WSDITAMapEditorPage ditaMapEditorPage = (WSDITAMapEditorPage) oxygenWorkspace
					  .getEditorAccess(editorLocation, PluginWorkspace.DITA_MAPS_EDITING_AREA).getCurrentPage();

			  ditaMapEditorPage.setPopUpMenuCustomizer( (popUp, ditaMapDocumentController) -> {
				  AuthorNode[] selectedNodes = ditaMapEditorPage.getSelectedNodes(true);
				  if(!selectedNodes[0].getName().equals("topicref")){
					  return;
				  }
				  JPopupMenu mainPopUp = (JPopupMenu) popUp;
				  JMenu subMenu = new JMenu("Insert");

                                  JMenu bookmapsubMenu = new JMenu("BookMapActions");


				  Action defineKeysAction = defineKeys(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
				  subMenu.add(defineKeysAction);
				  mainPopUp.addSeparator();
				 // mainPopUp.add(subMenu, 6);
				  
				  Action insertTopicRefAction = insertTopicReferenceAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
				  subMenu.add(insertTopicRefAction);
				  mainPopUp.addSeparator();
				  mainPopUp.add(subMenu, 6);

                                 Action insertTopicRefAction = insertTopicReferenceAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);

                                    if(selectedNodes[0].getName().equals("bookmap")){
					 Action newbookMapAction = NewBookMapAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
				  bookmapsubMenu.add(newbookMapAction);
				  mainPopUp.addSeparator();
				  mainPopUp.add(bookmapsubMenu, 6);
				  }


			  });
		  }
Thanks,
vishwa
sorin_carbunaru
Posts: 402
Joined: Mon May 09, 2016 9:37 am

Re: Ditamaps Manager Context Menu Customisation

Post by sorin_carbunaru »

Have you checked what "selectedNodes[0].getName()" returns when clicking on a bookmap?

By the way, when working with DITA, it's a best practice to check the "class" attribute of an element instead of the name. At some point you may specialize your DITA framework and create a new elements called, for example, "our_bookmap". Then, the best practice is to check if the "class" attribute contains " bookmap/bookmap ".

Cheers,
Sorin Carbunaru
vishwavaranasi
Posts: 144
Joined: Fri Feb 28, 2020 4:02 pm

Re: Ditamaps Manager Context Menu Customisation

Post by vishwavaranasi »

Thanks Sorin Carbunaru for your reply.

Yes
Have you checked what "selectedNodes[0].getName()" returns when clicking on a bookmap? - IT returns "bookmap"

check the "class" attribute of an element instead of the name

do we have any API for the same?

Thanks,
vishwa
Thanks,
vishwa
sorin_carbunaru
Posts: 402
Joined: Mon May 09, 2016 9:37 am

Re: Ditamaps Manager Context Menu Customisation

Post by sorin_carbunaru »

Use ro.sync.ecss.extensions.api.node.AuthorElement.getAttribute(String) to get the "class" attribute.
vishwavaranasi
Posts: 144
Joined: Fri Feb 28, 2020 4:02 pm

Re: Ditamaps Manager Context Menu Customisation

Post by vishwavaranasi »

tried this

Code: Select all

AuthorNode[] selectedNodes = ditaMapEditorPage.getSelectedNodes(true);
				
				AuthorNode  selectedAuthorNode =selectedNodes[0];
			
				
				String selectedNodeName =selectedAuthorNode.getName();

if(selectedNodeName .equals("bookmap")){
                	  log.info("2222...selected node from DITA_Maps_Manager_AREA: {} ", selectedNodeName );
                	  AuthorElement selElement = (AuthorElement) selectedAuthorNode;

  					AttrValue classAttribute = selElement.getAttribute("class");

  					classAttributeValue = classAttribute.getValue();
  					
  					log.info("3333...selected node from DITA_Maps_Manager_AREA: {} ", classAttributeValue);
  					
  					if (classAttributeValue.contains("- map/map bookmap/bookmap")) {
  						
  						log.info("4444 ..NOT printed this...selected node from DITA_Maps_Manager_AREA: {} ", classAttributeValue);

Action newbookMapAction = NewBookMapAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
bookmapsubMenu.add(newbookMapAction);
						mainPopUp.addSeparator();
						mainPopUp.add(bookmapsubMenu, 6);
					}

its working

Thanks


}
Thanks,
vishwa
sorin_carbunaru
Posts: 402
Joined: Mon May 09, 2016 9:37 am

Re: Ditamaps Manager Context Menu Customisation

Post by sorin_carbunaru »

There's no use in first looking at the element name and then the class attribute. You should first check if the node is an AuthorElement and then check the class attribute.
vishwavaranasi
Posts: 144
Joined: Fri Feb 28, 2020 4:02 pm

Re: Ditamaps Manager Context Menu Customisation

Post by vishwavaranasi »

Yes we tried the same.

it is working for sometime and after we opened multiple bookmaps , going front and back in between the book maps , the menu is not showing up

it is printing the below line when we right lick on the bookmap node

log.info("44444 NOT prined this...selected node from DITA_Maps_Manager_AREA: {} ", classAttributeValue);

but the following lines of adding the action menu is not showing.


Code: Select all

AuthorNode sel = selectedNodes[0];
			    if(sel instanceof ro.sync.ecss.extensions.api.node.AuthorElement) {
			      AuthorElement selElement = (AuthorElement) sel;
			    //  log.info("2222...selected node from DITA_Maps_Manager_AREA: {} ", selectedNodeName);
            	 // AuthorElement selElement = (AuthorElement) selectedAuthorNode;

					AttrValue classAttribute = selElement.getAttribute("class");

					classAttributeValue = classAttribute.getValue();
					
					log.info("3333...selected node from DITA_Maps_Manager_AREA: {} ", classAttributeValue);
					
					if (classAttributeValue.contains("- map/map bookmap/bookmap")) {
						
						log.info("44444 NOT prined this...selected node from DITA_Maps_Manager_AREA: {} ", classAttributeValue);
					Action newbookMapAction = NewBookMapAction(oxygenWorkspace, selectedNodes[0], ditaMapDocumentController);
bookmapsubMenu.add(newbookMapAction);
						mainPopUp.addSeparator();
						mainPopUp.add(bookmapsubMenu, 7);
				}
			    }
image.png
image.png (34.14 KiB) Viewed 289 times
Thanks,
vishwa
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Ditamaps Manager Context Menu Customisation

Post by Radu »

Hi,
Maybe you should put together a small complete sample plugin code exhibiting the problem you are facing and send it to us:
https://www.oxygenxml.com/techSupport.html
Just from looking at 10 lines it's hard to say what the problem is.
If I were to add a popup customizer to the DITA Maps Manager, I would probably use this newer and easier API:

Code: Select all

  public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {
    pluginWorkspaceAccess.addMenusAndToolbarsContributorCustomizer(new MenusAndToolbarsContributorCustomizer() {
      /**
       * @see ro.sync.exml.workspace.api.standalone.actions.MenusAndToolbarsContributorCustomizer#customizeDITAMapPopUpMenu(javax.swing.JPopupMenu, ro.sync.exml.workspace.api.editor.page.ditamap.WSDITAMapEditorPage)
       */
      @Override
      public void customizeDITAMapPopUpMenu(JPopupMenu popUp,
          WSDITAMapEditorPage ditaMapEditorPage) {
        //Get the selected node/nodes
        AuthorNode[] sel = ditaMapEditorPage.getSelectedNodes(true);
        if(sel != null && sel.length > 0) {
          AuthorNode firstSel = sel[0];
          if(firstSel instanceof AuthorElement) {
            AuthorElement firstSelElement = (AuthorElement)firstSel;
            AttrValue classAttr = firstSelElement.getAttribute("class");
            if(classAttr != null && classAttr.getValue().contains(" bookmap/bookmap ")) {
              //A node of type bookmap (the root of a bookmap) is selected.
              popUp.add("Hello");
            }
          }
        }
      }
    });
https://www.oxygenxml.com/InstData/Edit ... mizer.html
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
koushik9020
Posts: 13
Joined: Tue Dec 06, 2022 11:21 am

Re: Ditamaps Manager Context Menu Customisation

Post by koushik9020 »

Hi Oxygen Team,
With the suggestions that we got from here, we were able to customise our context menu in ditamaps manager successfully and we were able to implement it to "Insert Before" & "Insert After" Submenus just like how we did for "Append Child" submenu before.

Now that we have our "Insert Before" & "Insert After" Submenus customised to use our Insert Dialogs for: "Topic Reference..." as shown in the below way:
Screenshot 2024-04-25 at 5.48.44 PM
Screenshot 2024-04-25 at 5.48.44 PM.png
Screenshot 2024-04-25 at 5.48.44 PM.png (267.25 KiB) Viewed 39 times
Screenshot 2024-04-25 at 5.48.54 PM
Screenshot 2024-04-25 at 5.48.54 PM.png
Screenshot 2024-04-25 at 5.48.54 PM.png (302.32 KiB) Viewed 39 times
While validating the Insert TopicRef menu action under 'Insert Before' and 'Insert After' SubMenus. Looks like both are inserting new XML Fragments that we have customised using our Dialogs within the selected node instead of insert before and insert after.

How can we control the behaviour of this, kindly suggest.


Thanks & Regards,
Koushik
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Ditamaps Manager Context Menu Customisation

Post by Radu »

Hi Koushik,
Maybe you can have some common code to insert the XML fragment with parameters to decide how to insert it, something like:

Code: Select all

  public static final int BEFORE = 0;
  public static final int AFTER = 1;
  public static final int APPEND = 2;
  
  public static void insertXMLContent(ro.sync.ecss.extensions.api.AuthorDocumentController controller, AuthorElement target, int position, String xmlFragment) {
    if(position == BEFORE) {
      controller.insertXMLFragment(xmlFragment, target.getStartOffset());
    } else if(position == AFTER) {
      controller.insertXMLFragment(xmlFragment, target.getEndOffset() + 1);
    } else {
      //Inside as last child
      controller.insertXMLFragment(xmlFragment, target.getEndOffset());
    }
  }
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply