Search

What the Quote?

"There's always room for cello."

Laura Hearron

"I hid sweeties and porn clippings in my reversible purple monkey"

Mark Myers

"You can't light cigarettes with chapstick... I've tried, it doesn't work."

Pete Oberlin

« Maintainability | Main| Me as a Simpson »

SnTT: Programmatically Modify Designer Tools Menu

Category show-n-tell thursday
Back in March, Andre posted code for importing design elements from DXL, because the Designer Tools menu includes options for viewing, exporting, and transforming DXL... but not importing. Adding this code to an agent allows you to import design elements into the database containing that agent. Today's tip shows you how to add a custom entry to the Tools menu that does the same thing, but imports the elements into whichever database you currently have open in Designer - without having to first add an import agent to that database. The sample database contains two elements:
  • a hidden agent that is very nearly identical to the code Andre posted.
  • an Actions menu agent that "installs" the import option in your Tools menu.
Here's the meat of the latter agent:

Set dbCurrent = sesCurrent.CurrentDatabase
Set dbBookmarks = sesCurrent.GetDatabase("","bookmark.nsf")
Set outDesignTools = dbBookmarks.GetOutline("DesignTools")
Set oentAlways = outDesignTools.GetFirst()
Set oentImporter = outDesignTools.CreateEntryFrom(oentAlways,oentAlways,True,True)
Let oentImporter.Label = "Import DXL"
Call oentImporter.SetAction(|@Environment("DesignDXLImportTarget";@Subset(@DbName;1) + "!!" + @Subset(@DbName;-1));
@Command( [FileOpenDatabase]; "| & dbCurrent.Server & |":"| & Replace(dbCurrent.FilePath,"\","\\") & |");
@UpdateFormulaContext;
@Command([ToolsRunMacro];"(ImportDXL)");
@PostedCommand([FileCloseWindow])|)
Call outDesignTools.Save()
Msgbox "The Tools menu has been updated. Happy importing."

Why does this work? Your bookmark database contains an outline called "DesignToolsTemplate", which consists entirely of a flat layer of entries, which map to various contexts in Designer: "Always", "Frameset Design", "Frameset List", and so on. If you manually customize your Tools menu, it automatically creates a copy of this outline called "DesignTools". Any tools you add are created as child entries of the context(s) you selected in the wizard, with the entry action set to the formula you specify. In this case, we're programmatically generating the new outline entry (as well as the parent outline, if you've never customized your Tools menu... sadly, this has to be done via an error handler, because db.GetOutline throws an error if the outline doesn't exist instead of just returning Nothing) and setting its label and action. What I particularly like about this is that it's immediate - you don't have to reboot, you don't have to restart Designer... as soon as the agent runs, the menu is updated.

The formula in the new menu item does five things:
  1. sets an INI variable to the location of the database you're in when you invoke the tool
  2. opens the importer database
  3. updates the formula context to gain access to the importer database's agents
  4. runs the import agent (which gets a handle on the target database by reading the same INI variable - this is the only change from Andre's original code)
  5. closes the importer database, returning you to wherever you were
Handy as it is to be able to run agents like this, which exist elsewhere but are aware of where you were when you invoked the tool, I'll warn you in advance: formula executed in a tool while in an element list can get a handle on the current database but not on the selected design element. It only treats a design element as the "current document" if you're editing the element. So if you want to use this same approach to add a tool that acts on a specific design element, add the tool to outline entries ending in "Design"; this will ensure the tool only displays in the menu if it can get a handle on the element's NoteID, UNID, etc.

Comments

Gravatar Image1 - That's a good idea...

Gravatar Image2 - Great tool, I love it already.

Wouldn't it be even nicer to copy the import-agent into the bookmark file as well? That way both the added menu and the agent would work on another pc through replication of bookmark.nsf

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)