IL291371B2 - Method and Computer Program Product for Organized Document Creation - Google Patents

Method and Computer Program Product for Organized Document Creation

Info

Publication number
IL291371B2
IL291371B2 IL291371A IL29137122A IL291371B2 IL 291371 B2 IL291371 B2 IL 291371B2 IL 291371 A IL291371 A IL 291371A IL 29137122 A IL29137122 A IL 29137122A IL 291371 B2 IL291371 B2 IL 291371B2
Authority
IL
Israel
Prior art keywords
template
boilerplate
text
add
ribbon
Prior art date
Application number
IL291371A
Other languages
Hebrew (he)
Other versions
IL291371B1 (en
IL291371A (en
Inventor
Topper Jonathan
Topper Betsalel
Original Assignee
Topper Betsalel
Topper Jonathan
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Topper Betsalel, Topper Jonathan filed Critical Topper Betsalel
Priority to IL291371A priority Critical patent/IL291371B2/en
Publication of IL291371A publication Critical patent/IL291371A/en
Publication of IL291371B1 publication Critical patent/IL291371B1/en
Publication of IL291371B2 publication Critical patent/IL291371B2/en

Links

Classifications

    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F40/00Handling natural language data
    • G06F40/10Text processing
    • G06F40/166Editing, e.g. inserting or deleting
    • G06F40/186Templates
    • BPERFORMING OPERATIONS; TRANSPORTING
    • B41PRINTING; LINING MACHINES; TYPEWRITERS; STAMPS
    • B41BMACHINES OR ACCESSORIES FOR MAKING, SETTING, OR DISTRIBUTING TYPE; TYPE; PHOTOGRAPHIC OR PHOTOELECTRIC COMPOSING DEVICES
    • B41B23/00Auxiliary devices for modifying, mixing or correcting text or layout in connection with photographic or photoelectronic composing
    • BPERFORMING OPERATIONS; TRANSPORTING
    • B41PRINTING; LINING MACHINES; TYPEWRITERS; STAMPS
    • B41BMACHINES OR ACCESSORIES FOR MAKING, SETTING, OR DISTRIBUTING TYPE; TYPE; PHOTOGRAPHIC OR PHOTOELECTRIC COMPOSING DEVICES
    • B41B23/00Auxiliary devices for modifying, mixing or correcting text or layout in connection with photographic or photoelectronic composing
    • B41B23/04Auxiliary devices for modifying, mixing or correcting text or layout in connection with photographic or photoelectronic composing for facilitating hand correction of texts
    • BPERFORMING OPERATIONS; TRANSPORTING
    • B41PRINTING; LINING MACHINES; TYPEWRITERS; STAMPS
    • B41BMACHINES OR ACCESSORIES FOR MAKING, SETTING, OR DISTRIBUTING TYPE; TYPE; PHOTOGRAPHIC OR PHOTOELECTRIC COMPOSING DEVICES
    • B41B23/00Auxiliary devices for modifying, mixing or correcting text or layout in connection with photographic or photoelectronic composing
    • B41B23/06Auxiliary devices for modifying, mixing or correcting text or layout in connection with photographic or photoelectronic composing for correcting texts by removing incorrect lines from one film and splicing-in corrected lines from another film
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F3/00Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
    • G06F3/01Input arrangements or combined input and output arrangements for interaction between user and computer
    • G06F3/048Interaction techniques based on graphical user interfaces [GUI]
    • G06F3/0484Interaction techniques based on graphical user interfaces [GUI] for the control of specific functions or operations, e.g. selecting or manipulating an object, an image or a displayed text element, setting a parameter value or selecting a range
    • G06F3/04842Selection of displayed objects or displayed text elements
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F40/00Handling natural language data
    • G06F40/10Text processing
    • G06F40/12Use of codes for handling textual entities
    • G06F40/131Fragmentation of text files, e.g. creating reusable text-blocks; Linking to fragments, e.g. using XInclude; Namespaces
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F40/00Handling natural language data
    • G06F40/10Text processing
    • G06F40/12Use of codes for handling textual entities
    • G06F40/149Adaptation of the text data for streaming purposes, e.g. Efficient XML Interchange [EXI] format
    • GPHYSICS
    • G06COMPUTING OR CALCULATING; COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F7/00Methods or arrangements for processing data by operating upon the order or content of the data handled
    • GPHYSICS
    • G10MUSICAL INSTRUMENTS; ACOUSTICS
    • G10LSPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
    • G10L13/00Speech synthesis; Text to speech systems
    • G10L13/06Elementary speech units used in speech synthesisers; Concatenation rules
    • GPHYSICS
    • G10MUSICAL INSTRUMENTS; ACOUSTICS
    • G10LSPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
    • G10L13/00Speech synthesis; Text to speech systems
    • G10L13/08Text analysis or generation of parameters for speech synthesis out of text, e.g. grapheme to phoneme translation, prosody generation or stress or intonation determination
    • GPHYSICS
    • G10MUSICAL INSTRUMENTS; ACOUSTICS
    • G10LSPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
    • G10L13/00Speech synthesis; Text to speech systems
    • G10L13/08Text analysis or generation of parameters for speech synthesis out of text, e.g. grapheme to phoneme translation, prosody generation or stress or intonation determination
    • G10L13/086Detection of language
    • GPHYSICS
    • G10MUSICAL INSTRUMENTS; ACOUSTICS
    • G10LSPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
    • G10L13/00Speech synthesis; Text to speech systems
    • G10L13/08Text analysis or generation of parameters for speech synthesis out of text, e.g. grapheme to phoneme translation, prosody generation or stress or intonation determination
    • G10L13/10Prosody rules derived from text; Stress or intonation

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • Health & Medical Sciences (AREA)
  • Audiology, Speech & Language Pathology (AREA)
  • Computational Linguistics (AREA)
  • General Engineering & Computer Science (AREA)
  • Human Computer Interaction (AREA)
  • Multimedia (AREA)
  • General Physics & Mathematics (AREA)
  • Acoustics & Sound (AREA)
  • Artificial Intelligence (AREA)
  • General Health & Medical Sciences (AREA)
  • Document Processing Apparatus (AREA)

Description

Method and Computer Program Product for Organized Document Creation FIELD OF THE INVENTIONThis invention relates to text processing and more particularly to the use of pre-formatted text segments or building blocks to compile documents.
BACKGROUND OF THE INVENTIONWord-processing software commonly provides a feature for creating and storing reusable text segments that may quickly be inserted into an active document, typically by typing an acronym that identifies the required text segment. The present application will be described with particular reference to Microsoft Word™. Microsoft, Windows, Word, Excel, Outlook and SQL Server are trademarks or registered trademarks of Microsoft Corporation, Redmond, Washington, USA in the United States and other countries. Constant reference will be made to these products without denoting each time that they are trademarks. Microsoft Windows is a multi-task operating system that allows multiple applications to be active at the same time. Likewise, within any given application such as Microsoft Word there may be multiple windows, each containing a different document. The currently displayed window is known as the active window and if this contains a Word™ document, then this document is known as the active document. The term template within the context of word processing software, refers to a customized pre-formatted document. Microsoft Word also provides for graphical user interfaces (GUI) to be attached to or associated with a template. Such GUIs can be of two distinct kinds. One is a form that is created using Visual Basic for Applications (VBA), which is provided with Microsoft Office and allows customization of the Office suite of programs including Word and Outlook. An example of a simple VBA form within the context of the VBA editor is shown in Fig. 1. VBA is an event-driven program and the form is an object having associated properties and methods. One such method is automatically executed on initializing the form and populates a combo or dropdown box, which is itself an object in the form, with user-selectable entries. Also provided are command buttons labelled "Add" and "Close" which, when pressed or "clicked" execute suitable events.
The VBA form can be associated with a template by adding to the template a module, which contains named procedures or subroutines that are called from within Microsoft Word. One way to do this, albeit not the best way, is to type [ALT][F8] which lists all programs or as they are often called Macros associated with the active template or document. For the sake of completeness, it should be noted that Microsoft Word associates a default template with every document, even one that is not based on a user-customized template. The default template is known as the normal template and serves as a global template since it is accessible to all documents under Microsoft Word. The normal template Normal.dotm is located in a ‘User templates’ folder whose default is C:Users%User%AppDataRoamingMicrosoftTemplates where %User% is the user’s computer login name. The User templates folder may be changed within Microsoft Word via an option called File Locations shown in Fig. 2 and accessed via File – Options – Advanced – File Locations. The user interface (UI) shown in Fig. 2 also allows for a Startup folder to be defined. In Office 2019 it is set by default to C:Program Files (x86)Microsoft OfficerootOffice16 Startup but we have changed it to C:Program FilesMicrosoft OfficeStartup so as to be independent of the version of Microsoft Office. All templates located in either the User templates folder or the Startup folder are automatically accessible to all documents and therefore all macros associated with these templates will likewise be accessible to all documents regardless of whether or not they are based on user-defined templates. In the following description, we refer to such templates as global templates and when we come to describe a specific implementation of the invention, we will assume that the global template is stored in the Startup folder. But it could equally well be stored in the User templates folder. If a custom template is not global, then any macros embedded in the custom template will also be operative when the custom template is referenced by an active document. A second kind of GUI associated with a document is the so-called ribbon. The UI Ribbon was introduced in Office 2007 to replace what were previously referred to as command bars. Command bars were user-customized objects that were associated with a template and into which commands could be embedded, thereby allowing specialized operations to be associated with the template and thus to be executed by a document based on that template. The UI Ribbon or more simply ribbon is an enhanced implementation of the command bar object and, unlike the original command bar which floated in the active window and could be moved around using the mouse, the ribbon is fixed at the top of the application window. 35 Mention has already been made of text segments that are embedded within a template and inserted into the active document by typing an acronym or shortcut. In Microsoft Word these are commonly referred to as building blocks of which conventional autotexts are a subclass. An autotext entry is a segment of reusable content that may include features such as tables, equations, content controls and graphics as well as formatted text having attributes such as bold, italics, etc. Fig. 3 shows the various stages of a conventional approach to creating an autotext entry. The text is typed and attributes are applied, such as font changes and font attributes. The specimen text in Fig. 3 includes some initial text in Arial 12pt with subsequent text in Times New Roman 12pt. The initial text includes one word, example whose size has been set to 16pt and the subsequent text includes the word Autotext in italics. Having typed the autotext entry and applied the required attributes, it is stored in the normal template by selecting the text and typing [Alt][F3]. This displays a dialog box, wherein the name of the new entry defaults to the first few characters of the string, but can and typically will be changed to something more coherent. In the figure, we have changed its name to "Example". Gallery defaults to Autotext indicating that the building block will be saved as an autotext entry by default, since this is the default associated with [Alt][F3]. Clicking on the command button "OK" saves the autotext by default to the normal template, but it can be saved to another template in the expanded combo box as shown in the figure i.e. Specification.dotm or Building Blocks.dotx(en-US), the latter being a default template for storing building blocks. There are other types of building block, and these may be created and saved differently; but for the sake of clarity and simplicity we will confine our discussion to autotext entries. If the user now types the first few characters of an autotext entry such as "exam", a message pops up as shown in Fig. 3 to inform the user that this corresponds to the name of an autotext entry stored in the active template. The user can insert the autotext entry by pressing or can type alternative text, as required. The manner in which autotext entries are stored in a document is beyond the scope of this invention. But what is important by way of further background is that they are stored invisibly in the internal structure of the host template. There is usually no need for them to be rendered visible in the template, although they can be activated by typing their respective names or shortcuts; or by selecting the Insert tab followed by Quick Parts – Autotext. This displays a dropdown menu containing all autotext entries in the active template (or templates) with their respective font attributes, allowing a required entry to be selected for insertion into the active template or document. 35 More than one template can be associated with the active document. For example, this patent application was prepared based on a template called specification.dotm, which contains several autotext entries that are specific to patent applications, such as standard boilerplate text, disclaimers and so on. There may also be stored other types of building block relating to standard text blocks. These may be stored under other categories of building block by saving under a different Gallery, but for our purpose we assume that all boilerplate text is stored as autotext. In addition to the autotext entries embedded in the template specification.dotm, there may be other autotext entries embedded in the normal template or any other template that is stored in the startup folder, and these will always be active in addition to those embedded in the underlying document template. Furthermore, templates that are not stored in the startup folder, and whose embedded autotext is therefore not active by default, may be activated to render their autotext accessible when editing the active document. This can be done manually via the Developer Tab in the UI Ribbon, which is hidden by default; or it can be done programmatically as explained below. In many office environments, document preparation requires the concatenation of standard blocks of text and the use of autotext goes far to facilitate this. But over time, as an ever-increasing library of autotexts is created it becomes tedious to remember the shortcut or acronym for a required autotext entry or, alternatively, to display a large list of autotexts that then need to be scanned and manually selected. This drawback can be mitigated by associating a much smaller subset of autotexts with a specific template on which each standard document is then based. But this, too, has its drawbacks since many documents are typically composed of a limited number of boilerplate text segments, which vary according to document type. For example, consider an intellectual property firm that needs to report to a client an official notification received from the patent office. Official notifications fall into several different categories, which may depend on jurisdiction. For example, the European Patent Office may request information regarding search results of a priority application; the US Patent Office may raise a so-called restriction requirement for the applicant to elect a group of claims directed to a single invention. But notwithstanding regional nuances, substantive examination relates to novelty, obviousness, sufficiency (enablement), clarity and unity of invention and reporting letters to clients as well as responses to the patent examiner are typically based on pre-formatted blocks of boilerplate text. It is impractical and inconvenient to base every report or response on a different template, partly because of the difficulty in 35 managing large numbers of templates. Moreover, identical text segments may be relevant for different types of document; and it is time-consuming to incorporate the same text segments in multiple templates and cumbersome to edit and maintain multiple occurrences of identical segments that are distributed among a multitude of different templates. Yet a further consideration is that templates that nominally relate to identical subject matter may nevertheless be required to deliver variable content depending on external factors. For example, some organizations insist that all reporting letters for a given topic follow a consistent format; but others may allow flexibility in how different staff present information. Likewise, content may vary according to different practice groups. For example, an IP professional whose technical field relates to computer software may wish to relate to Beauregard claims; while another practice group may need to relate to sequence listings. Consequently, if templates are produced and maintained centrally by an IT department, such that all users in an organization have access to identical templates, a standard template may not serve all users. This will be true also for organizations that wish to preserve flexibility that allows users to customize text, while benefitting from standard boilerplate text that is common to all departments or practice groups. In a typical organizational setup, central development and maintenance of templates mitigates against such flexibility and provides an "all or nothing" option. Users do have the flexibility to create personalized autotexts and store them in templates located in their startup folder. But personalized autotexts are not amenable to ongoing maintenance at the corporate level and cannot seamlessly be integrated with corporate features. For example, a personalized autotext cannot be enhanced or customized by incorporating data extracted from a database.
SUMMARY OF THE INVENTION It is an object of the invention to provide a method using reusable content for facilitating modular document creation, which integrates preformatted text segments stored in a boilerplate template with a pre-programmed procedure in a global template or add-in that is independent of the boilerplate template, wherein the procedure displays autotext entries according to subject matter in a dropdown menu, inserts a selected text segment into an active document and optionally augments the text segment with additional text based on data extracted from a database.
In a first aspect of the invention, this object is realized by a computer-implemented method for facilitating organized document creation, the method comprising: (a) creating with a word-processor text segments at least one of which has a programmable placeholder and a predefined category indicative of a subject associated with the text segment; (b) storing the text segments in a boilerplate template with their respective names and categories and any formatting attributes applied to the text segments; (c) saving the boilerplate template; (d) prior to or during subsequent processing by an application using the word- processor of an active document related to said subject, calling a first pre-programmed procedure in an add-in that is independent of the boilerplate template to read the boilerplate template and populate a menu in a graphical user interface of the application with the respective names of all text segments in the boilerplate template corresponding to said predefined category for selection by the user; and (e) upon selection by the user from the menu of a selected name corresponding to one of the text segments having a programmable placeholder, calling a second pre-programmed procedure in the add-in to insert into the active document the text segment corresponding to the selected name together with auxiliary text that is not part of the text segment. In a variation of the invention there is provided a computer-implemented method for facilitating organized document creation, the method comprising: (a) creating text segments using a word-processor; (b) assigning to each of said text segments a respective name identifying the text segment and a category having a name indicative of a subject associated with the corresponding text segment; (c) storing the text segments in a boilerplate template with their respective names and categories and any formatting attributes applied to the text segments; (d) saving the boilerplate template; (e) prior to or during subsequent processing of an active document using an application that uses the word-processor, calling a first pre-programmed procedure in an add-in that is independent of the boilerplate template to read the boilerplate template and populate a first menu in a graphical user interface of the application with each unique category name for selection by a user; 35 (f) upon selection by the user of a selected category displayed in the first menu, calling a second pre-programmed procedure in the add-in to dynamically populate a second menu in the graphical user interface with the respective names of all text segments in the boilerplate template corresponding to the selected category for selection by the user; and (g) upon selection by the user of a selected name from the second menu, calling a third pre-programmed procedure in the add-in to insert into the active document the text segment corresponding to the selected name. In an embodiment reduced to practice, the word-processor is Microsoft Word™ and the text segments are autotext entries stored in a user-specific boilerplate template. The display of autotext entries is controlled by a global template that typically is common to all users in an organization and which includes program code that reads the user’s boilerplate template and displays the autotext entries in an application ribbon dropdown menu. Selection from the dropdown menu automatically inserts into the active document formatted text corresponding to the selected autotext entry. The autotext entry may include a programmable placeholder, such as a content control or bookmark into which the program code automatically inserts auxiliary text that is not part of the selected autotext entry and may be extracted from a database. The use of placeholders to insert text extracted from a database is well-established. Such placeholders maybe bookmarks, which indicate a location in the text at which external data may be added. Likewise, formfields, which were upgraded to content controls in Microsoft Word 2007, allow for variable text to be inserted into the formfield or content control. These controls may also be dropdown menus having preformatted content, which may either be selected manually by the user or programmed using code, typically written in VBA that is incorporated into a template on which the active document is based. The use of Open Database Connectivity (ODBC) is also well-known for extracting data from remote data sources. Typically, remote data is extracted from a database using a query written in SQL (Structured Query Language), which is called by program code in the template on which the active document is based. Content controls serve as an obvious receptacle into which such externally derived data may be inserted. Moreover, content controls replicate many features of Microsoft Forms of the kind shown in Fig. 1 and have their own events, which are called when the user enters into or exits from the content control. Different types of content control are available such as checkboxes and combo boxes (dropdown menus), each having type-specific events that may be used to initiate actions when changed manually or which may be initiated automatically under program control. 35 In summary, Microsoft provides many techniques for augmenting pre-formatted data using external data sources. However, to the best of our knowledge, no suggestion has been made to dynamically source a dropdown menu with the names of autotext entries according to styles associated therewith; or to augment data in autotext entries with external data using ODBC as disclosed by the present invention. As will be explained in greater detail below, the invention provides for a level of flexibility that significantly enhances the versatility of autotext in its conventional form; and allows for fast and intuitive document creation in a modular manner using pre-formatted text segments that can be picked simply by selecting from a dropdown menu. Moreover, selected autotext entries may include document-specific data that is automatically extracted from an external data source and integrated with the autotext entry in a completely transparent manner.
BRIEF DESCRIPTION OF THE DRAWINGSIn order to understand the invention and to see how it may be carried out in practice, embodiments will now be described, by way of non-limiting example only, with reference to the accompanying drawings, in which: Fig. 1 shows pictorially a conventional Microsoft Form programmed using VBA; Fig. 2 shows pictorially part of a user interface in Microsoft Word for defining locations of user-defined templates; Fig. 3 shows pictorially successive stages in Microsoft Word for creating and using autotext entries; Figs. 4a to 4c show pictorially successive stages in Microsoft Word for creating new styles; Fig. 5 shows a detail of the unzipped file structure of a Microsoft Word template having a file extension .dotm; Fig. 6 shows a detail of the unzipped file structure of the zip file ‘CustomUI’ shown in Fig. 5; Fig. 7 shows pictorially part of the custom UI ribbon according to the invention; Fig. 8 shows a partial list of VBA modules in the global template; Fig. 9 shows pictorially an initial stage in configuring a letter using an interface according to the invention; Figs. 10a to 10d are flow charts showing the functionality of the callbacks for the first dropdown in the custom UI ribbon; Figs. 11a to 11d are flow charts showing the functionality of the callbacks for the second dropdown in the custom UI ribbon; Figs. 12a to 12c are flow charts showing the functionality of the callbacks for the third dropdown in the custom UI ribbon; Fig. 13 shows a text segment having a programmable placeholder that is augmented based on data in a computerized database; Figs. 14a and 14b are screen images showing subsequent stages during insertion of an autotext entry and automatic augmentation of a programmable placeholder; Fig. 14c shows a text segment whose selection and insertion are shown in Fig. 14b and which has a programmable placeholder that is augmented automatically; Fig. 15 is a screen image showing details of a UI ribbon for a document template having a single subject category; Figs. 16a and 16b are screen images showing details of a UI ribbon for the boilerplate editor; Fig. 17 is a screen image showing use of the boilerplate editor to edit an autotext; Fig. 18 is an edited screen image showing use of the boilerplate editor to create an autotext; Fig. 19 is an edited screen image showing details of a UI ribbon for an embodiment of the invention implemented under Microsoft Outlook™; Fig. 20is an edited screen image showing partial details of the "Symbols" Tab in the UI ribbon shown in Fig. 19; and Fig. 21is an edited screen image showing partial details of the "Automation" Tab in the UI ribbon shown in Fig. 19.
DETAILED DESCRIPTION OF EMBODIMENTSOrganization of description The invention will be described with reference to flowcharts that explain the principles according to which one skilled in the art will be able to carry out the invention. Code segments in VBA are tabulated in an Appendix at the end of the description prior to the claims, and the code is heavily commented to provide a more detailed description of an actual implementa-tion of the invention on a bilingual operating system supporting Hebrew and English. Partial code segments relate to English and Hebrew letters only and can be skipped without unduly derogating from the reader’s understanding of the invention. The code for populating dropdowns for other types of document template has been deleted, but is essentially the same as shown with suitable adjustment to the names of array variables and boilerplate templates.
General principles As noted above, in accordance with one embodiment, the invention is based on the integration between two MS Word™ templates. A first template contains autotext entries, each constituting a text segment that is formatted with a style whose name is indicative of an associated subject category. The text segment may be as short as a few words or may be a large block of text extending over many paragraphs and including all of Microsoft Word’s features, such as font attributes, content controls, bookmarks, tables, equations and so on. By way of example, an IP firm receives an office action from the patent office and typically reports this to the client. On receiving the client’s instructions, an IP professional prepares and files a response at the patent office and reports to the client. Each of these events may be docketed in a computerized docketing system. When reporting receipt of an office action, there are usually standard blocks of text that are repeated from one reporting letter to another, possibly with minor variations. The same is true when responding to the patent office; and is also true when reporting back to the client. But in all three cases the standard blocks of text are typically different. To accommodate these differences, we can employ different templates each incorporating all possible variations that are pertinent to the type of document being formatted, i.e. one for reporting an office action, another for formatting a response and so on. During document formation, those segments of text that are not required are then deleted, either manually or under program control. As opposed to the above subtractive method which deletes unwanted text segments, the invention employs an additive method and for the sake of example, we will assume in the following description that we are composing a document using a blank document, typically based on a letter template that may include artwork relating to the firm’s logo or have a textbox or table for accommodating such artwork. Either way, the letter template need not contain any code, since all the necessary code relating to the invention is stored in a global template that is, by definition, accessible to all documents. There are two essential stages to implementing the invention: (i) creation of a boilerplate template containing autotext entries; and (ii) creation of a document template containing a ribbon having one or more dropdown menus that call associated program code, which may be contained within a VBA module of the document template but more commonly is contained within a VBA module of a global template. These stages will now be described.
Creation of the boilerplate templateCreation of the boilerplate template is trivial and is based on Microsoft Word’s inbuilt features, as described above with reference to Fig. 3. At this stage, we will note parenthetically that creation and more particularly the subsequent maintenance of autotext entries using Word’s inbuilt features is cumbersome, requiring a lot of manual effort on the part of the user. To this end, there is described below a novel editor that works under Microsoft Word and greatly simplifies both the creation and maintenance of autotext entries. However, for the present it will be assumed that we have already prepared a boilerplate template that contains multiple text segments each having a style whose name is indicative of a different subject such as Office Action, Response, Prior Art, New Filing, General and so on. Figs. 4a to 4c show pictorially successive stages in Microsoft Word for creating new styles. The screen image shown in Fig. 4a is displayed by clicking on the ‘Home’ tab in the main ribbon. Clicking on the encircled icon in the far-right lower corner of the Styles tab opens the Styles menu shown in Fig. 4b and clicking on the encircled icon in the far- left lower corner of the Styles menu opens the Styles dialog shown in Fig. 4c. This allows for paragraph and font formatting to be changed, but for the purpose of the present invention the only essential change is to change the style name shown as ‘Style1’ in Fig. 4c to the name of a subject category such as Office Action or Response, as required. Once the boilerplate text is entered and the required style is applied, the autotext is saved as described above with reference to Fig. 3. The boilerplate template is saved to a known folder under a user-specified name, which may be unique for a specific user. For example, we use a boilerplate template called ‘BoilerPlate-Eng-SM.dotx’, which resides in a folder called ‘C:Program FilesMicrosoft OfficeTemplatesStandard Letters’. The component ‘Eng’ denotes that the language of the boilerplate template is English since we use a complementary boilerplate template for Hebrew called ‘BoilerPlate-Heb-SM.dotx’. The component ‘SM’ is a unique identifier for the user comprising any unique sequence of characters, possibly the user’s initials.
Creation of the document templateA document template is a Word template typically having an extension .dotm on which standard documents having an extension .dotx are based. A template of type .dotm may include VBA code; but we can also realize the invention using a template having an extension .dotx which cannot include embedded VBA code, but whose ribbon elements call VBA code in a separate global template. The present invention relates specifically to the UI ribbon and, as such, can equally well be implemented with either template format. 35 For the purpose of our discussion, we will describe two English-language document templates, one called EngLetter.dotm and the other DN_English.dotm on which reporting letters and invoices (debit notes) are based. Splitting the XML definitions and the callbacks between two different templates allows different document templates to address common callbacks, which simplifies program maintenance. Creation of the document template is divided into two parts: (i) the UI Ribbon and (ii) the program code. As noted above, while the program code and the UI ribbon may be embedded in the same template, it is more convenient to split them, so that a custom UI Ribbon is associated with a specific template, while the code that is called when interacting with elements in the UI ribbon is stored in a global template. We can then display the appropriate UI ribbon for the active document by ‘adding in’ the template on which the active document is based, while the underlying XML that defines the layout of the UI ribbon can associate user-actions with program code in the global template. For those unfamiliar with the UI ribbon this will become clearer from the following description. The UI Ribbon is extensively documented on-line. As such, it may be assumed that those skilled in the art will know how to customize the UI Ribbon without further description. However, for the sake of completeness, we provide some background and examples. By way of introduction, Microsoft Word documents compatible with Word 2007 and above have file extensions conforming to Office Open XML Formats i.e., .docx, .docm, .dotx or .dotm. These documents are in fact zip folders, as can be seen by changing their extension to .zip, which can be opened to reveal several components. Specifically, if the template includes its own UI ribbon, this is included as a discrete component in the zip file called ‘CustomUI’ as shown in Fig. 5. This component is itself a zip file whose subcomponents are shown in Fig. 6 including an XML file called CustomUI14.xml, which can be extracted and edited, ideally using an XML editor such as XML Notepad but less ideally using a text editor such as Notepad, both of which are Microsoft products and provided as part of the Office suite or downloadable from Microsoft. CustomUI14.xml is a Ribbon customization for versions of Microsoft Office from 2010 including Office 2019. It is possible that the number ‘14’ may change in subsequent versions of Office. In any event, its name is not important: what is important is that the same name appears as the target in the XML definition in ‘.rels’ contained in the _rels folder in the zip file (also shown in Fig. 5), i.e.
It is possible to create or edit the components of the zip folder, specifically ‘CustomUI14.xml’ and ‘.rels’, replace them in the original zip file and change the extension of the modified zip file back to the original Office Open XML extension. Needless to say, this is laborious and time-consuming. It is far easier to use proprietary tools such as Visual Studio as described below with reference to the UI Ribbon in Microsoft Outlook. However, better still for Microsoft Word™ is the Office RibbonX Editor that is freely downloadable from GitHub, Inc. at https://github.com/fernandreu/office-ribbonx-editor. This editor allows any Microsoft Word document conforming to Office open document file format to be opened and for its Custom UI part to be edited or for a new UI ribbon to be created, including the XML and the embedding of images that are referenced by the XML properties. Table I shows part of the XML contained in CustomUI14.xml and seen by double-clicking on the component CustomUI14.xml in Fig. 6. The XML is customized according to the graphical components and functionality built into the template. Consequently, the XML shown in Table I relates specifically to the present invention and defines the features that must be included in the GUI of the document template. Statements relating to ribbon functionality are case-sensitive. Thus, referring to Table I the first statement defines the XML version and specifies that the ribbon to be attached to the template is ‘standalone’, i.e., it does not include the features of the integral UI ribbon shipped with Microsoft Word. The ribbon definition commences with and ends with as the last statement in the file. The parameter onLoad="UIRibbon_JJTMacros.Engletter_Onload" specifies a user-defined macro that is called when the ribbon is first loaded. In our case, this macro is called ‘Engletter_Onload’ and is contained within a module called ‘UIRibbon_JJTMacros’ in a global template. It will be recalled that a global template is any template contained in the Startup or User templates folder as defined with reference to Fig. 2. If more than one template is located in one of these folders, they will all be global, in which case only one global template should reference the specified ‘onLoad’ macro. The statement marks the start of the ribbon definition, which ends with the closing statement . The ribbon definition starts with the keyword which signifies the start of the tabs definition and ends with . Note ‘tabs’ is in the plural because a ribbon may have multiple tabs, such as File, Home, Insert, Draw, Design, Layout in the standard ribbon for Microsoft Word 2019 with which the present document was prepared. The ribbon which is embedded into our document template has three dropdown menus that are arranged on a single tab defined by the XML string , which assigns a unique ID 35 ("EngLetter") and a label that appears on the tab, such as File, Home etc. in the standard Word ribbon. There are two ways to assign properties such as labels, item labels in dropdown menus and names of procedures to be executed when a ribbon object is activated. One way is to hard code the property into the ribbon definition. Table II shows part of an XML definition for a command button whose properties are hard-coded in the XML definition. The XML in Table II defines a button in the custom ribbon for specification.dotm to which reference has already been made and which serves as the template on which this document was prepared. The command button displays an icon stored in a zip file called ‘images’ within the file structure as shown in Fig. 6. The button has a unique ID set to "Embolden" and an image that is part of the file structure and is named "Embolden". The button has a blank label, and a screentip and supertip which are rendered visible when the mouse hovers over the button to display text hard-coded into the XML definition, which indicates the button’s functionality. Clicking on the button invokes the ‘onAction’ callback and executes a procedure called "Embolden" stored in the same template. The term ‘callback’ denotes an external procedure that is called when the button or other ribbon object is activated. For the sake of abundant clarity, use of the word "Embolden" to relate to three different elements is purely a matter of choice. There is no ambiguity because the identifiers relate to different properties of the ribbon elements. The XML shown in Table II is used in specification.dotm because this template is used to prepare English language patent specifications. It is therefore assumed that the user will be comfortable with English-language labels and tips regardless of the default language of the ribbon, which is determined by language settings in the Windows™ operating system. But an embodiment of the invention facilitates modular construction of documents in a language other than the default ribbon language. To this end, in the XML shown in Table I, we use ‘getLabel’ to call the procedure "UIRibbon_JJTMacros.getLabel" instead of hard-coding the tab label. Having defined the tab, we now add to the tab three dropdown menus, which for cosmetic appeal we have chosen to arrange in three horizontally separated groups having a vertical line to separate between each adjacent pair of dropdown menus and displays a label describing each dropdown menu. Again, in order to allow for multi-lingual support, the labels are not hard-coded but are defined at runtime i.e., when loading the ribbon, by calling named procedures located in a global template as described in greater detail below. These procedures apply different labels according to a user-defined language preference. The definition of a dropdown menu includes additional callbacks all of which reference the global template. Specifically, GetItemCount determines the number of items to be inserted into the dropdown menu; GetItemLabel determines the 35 label i.e., description of each item; and GetSelectedItemIndex is used to select a default or initial item. Manually selecting an item from the dropdown menu invokes the OnAction callback, which of course is different for each of the three dropdown menus. Fig. 7 shows pictorially part of the custom UI ribbon denoted 10 as defined by the XML in Table I. The ribbon 10 includes a tab 11 having a label ‘Smart Autotext (English)’, which contains three dropdown menus 12, 13 and 14 whose respective labels 15 are ‘Attorney’, ‘Letter Style’ and ‘Autotext’. As noted above, the ribbon 10 is embedded within a document template called EngLetter.dotm, which is used to create English language letters. It will further be recalled that the labels 15 are applied at runtime when the ribbon is loaded using VBA code in a global template. This code is essentially the engine which drives the invention and will now be described.
Creation of the global templateIn the following discussion, we will relate to a template called JJTMacros.dotm located in the startup folder as defined with reference to Fig. 2. With reference to Fig. 8, it is seen that JJTMacros.dotm includes a VBA module 20 called UIRibbon_JJTMacros. This module contains a number of VBA procedures (sometimes called macros), which are called by the XML definition when loading the document templates EngLetter.dotm and HebLetter.dotm. As seen in the XML definition shown in Fig. 1, when the ribbon is loaded, it calls a procedure named UIRibbon_JJTMacros.Engletter_Onload. This name denotes a procedure called Engletter_Onload, which is located in the module UIRibbon_JJTMacros. The ribbon is loaded only once when its document template is loaded for the first time. Thus, if several letters based on the same template are opened concurrently, the ribbon is loaded only for the first letter; and conversely is unloaded only when all the letters are closed. This has important ramifications because the dropdown menus in the ribbon are dynamically populated from respective arrays. The code that is called to do this needs to be able to identify both the ribbon and the control, corresponding to the dropdown menu. To this end, each ribbon is assigned a logical handle by the onload procedure. If VBA crashes for any reason, typically owing to a runtime error in a macro called by an active document, then the logical handle will be lost from memory. This may not matter for static data in the ribbon, such as buttons and even for dropdown menus whose contents, once input, remain fixed, because the internal accounting which deter-mines the control ID, i.e. which element of the ribbon is actuated and which keeps track of the currently selected item in a dropdown box, are stored in memory that is independent of VBA. But for labels that must be set dynamically under VBA, if VBA crashes it will no longer be possible to reset the ribbon controls. 35 Ideally this should not be a problem, but in practice VBA macros are often created in-house without the attention to error handling that is expected of professional software. If VBA crashes it is not possible to reload the active ribbon simply by opening a new document based on this ribbon because, as explained above, the onLoad callback is actuated only once when the ribbon is loaded for the first time. We therefore provide a feature to restore a ribbon transparently after VBA crashes. Our approach is based on code developed for Excel by MVP Rory Archibald and shared by Ron de Bruin at http://www.rondebruin.nl/[Contact].htm, which uses the VBA function ObjPtr(obj) to return the address (or pointer) for an interface referenced by the object variable, obj. We store this on disk. In the event of a fatal VBA error, which causes the ribbon object to become lost, we retrieve the pointer from disk and reinitiate the ribbon. With this in mind, the onload callback UIRibbon_JJTMacros.Engletter_Onload is shown in Table III. EngletterRibbon is a global variable of type IRibbonUI. Global variables are defined in a module of JJTMacros.dotm called Global_Module shown in Fig. 8. We need different global variables for the respective ribbon in every document template. So, for our letter and invoice templates in both English and Hebrew we define four global variables as shown in Table IV. The input parameter ribbon in Table III also of type IRibbonUI is the logical handle assigned by MS Word when loading the ribbon. Each ribbon has a different logical handle and points to a different object in memory. Table V shows the code for StoreObjPtr, which creates a text file EngLetter.txt which stores the address (or pointer) of EngletterRibbon. TemplatePath is a global string variable, which is set to ‘c:Program FilesMicrosoft OfficeTemplates’ but can be any folder to which the user has both read and write access. In a multi-user environment, each user will need exclusive access to a different file; so if the file is saved on a network drive common to all users, the procedure will need to be modified to assign a different name to each file. In the event of a VBA error resulting in loss of global variables, we can reload the ribbon object using a procedure of the kind shown in Table VI, which references two functions GetObjPtr and RestoreObjRibbon whose code is shown in Tables VII and VIII. GetObjPtr extracts the address of the ribbon object from the text file created by StoreObjPtr. The address is passed to RestoreObjRibbon, which restores the ribbon object. CopyMemory is an API that is declared at the start of a module as shown in Table IX. The VBA code shown in Tables V to IX allows a ribbon whose object is no longer defined to be restored and then repopulated in a manner that is transparent to the user. While this feature is based on known techniques, it has been found greatly to enhance the usability of the invention because the 35 dynamic dropdown menus will function even in the case of a runtime error in an unrelated user-created Macro that causes VBA to crash. Fig. 9 shows pictorially an initial stage in configuring a letter using an interface according to the invention. The Figure shows part of a fictitious letter to Microsoft regarding a British patent in their name. It is seen that the ribbon tab is as partially shown in Fig. 7, which is loaded when the document template EngLetter.dotm is opened for the first time. We have expanded the first dropdown menu to display the names of IP staff, each of whom may have a different boilerplate text. These names are extracted from an SQL Server database table, part of which is shown in Table X. The global template includes code that queries this table using ODBC and populates the first dropdown menu 12 with user names. It is seen that Elizabeth Bennet is highlighted because she is the default attorney for this case, which is identified by a unique file code 22, in this case 137101. In a preferred embodiment of the invention, code is provided that populates the first dropdown menu 12 and also sets the selected element to the default user. Referring back to Table I, we see that the first dropdown menu is defined by the following XML: Before describing an enabling embodiment, we will first describe the functionality of the callbacks for the three dropdowns in the custom UI ribbon with reference to the flow charts shown in Figs. 10 to 12. Thus, with reference to Fig. 10a it is seen that GetItemCount for the first dropdown (DD1) compiles an array of users and sets the number of items in the dropdown to the number of users plus 1. We add 1 because the first label in the dropdown is set to a header, in this case "Select Attorney" as can be seen in Figs. 7 and 9. In a multi-language implementation, the arrays which source the dropdowns have one column for each language. The column used to source the dropdowns is then selected according to the default interface language for a specific user. GetItemLabel shown in Fig. 10b is called iteratively for each item in the dropdown. For each iteration, an index initially set to 0 is incremented, and the label to be assigned to the corresponding index is set to the default header for index=0 or to the corresponding element in the user array.
GetSelectedItemIndex shown in Fig. 10c sets the index of the dropdown to a predetermined value in order to display a specific label. By default, it sets the index to zero, which displays the header. But an actual implementation of the invention determines which user has overall responsibility for a case, the dropdown label is set accordingly and, more importantly, the boilerplate template that is used will be specific to this user, if indeed such a boilerplate template exists. OnAction shown in Fig. 10d compiles an array of unique subject categories in the boilerplate template for the selected staff member or the default boilerplate template, as appropriate. In a multi-language implementation, alternative names must be assigned for each language. This is most easily done by maintaining a dictionary of subject categories with translations for each language, most simply implemented using a database table and reading the required translation using ODBC; but this does of course mean that any new subject category must be added to the database and its translations entered. If no entry is found in the database table, the default language is used. The flowcharts shown in Figs. 10a to 10d show the functionality of the callbacks, but not the actual implementation that will be better understood from specimen code described below. In practice, two commands invalidate and invalidatecontrol are provided that allow for the complete ribbon or a specific ribbon control to be initialized. Use of invalidate to reset the ribbon has already been demonstrated in the reload procedure documented in Table VI. When we select a specific user and compile a list of subject categories (i.e., autotext styles) in the appropriate boilerplate template, invalidatecontrol is used to repopulate the second dropdown. Likewise, when we select a specific subject category from the second dropdown, invalidatecontrol is used to repopulate the third dropdown. By such means, we can dynamically update the dropdowns according to user-selections. Figs. 11a to 11d are flow charts showing the functionality of the callbacks for the second dropdown, DD2 in the custom UI ribbon. The functionality is similar for DD2 as for DD1, but whereas for DD1, GetSelectedItemIndex allows us to default to a specific user based on "ownership" of the active document, for DD2 we can use GetSelectedItemIndex to default to a specific subject matter. To take a simple example from the world of IP, a reporting letter to a client relating to a granted patent typically relates to renewals, which are paid periodically to maintain the patent in force. A docketing system that includes database tables containing relevant docketing events and renewal terms can be used to determine whether the current system date falls within a predetermined window of a docketing event or renewal term, in which case it is quite likely that any letter to be sent to 35 the client or to the patent office relates to this docketing event or renewal. If the boilerplate template includes standard text segments whose style or subject category corresponds to this docketing event or renewal, then we can default to this style or subject category and populate the third dropdown with corresponding autotexts. Of course, setting the second dropdown to a default value does not preclude selection of a different category, but we have found that in most cases the default subject category does correspond to what would otherwise need to be manually selected, thus saving time. Also psychologically, there is something very attractive or ‘user-friendly’ in creating a new document based on a general document template and finding that the desired subject category and autotext segments are already pre-selected by default. When GetSelectedItemIndex sets a non-zero index for DD1 or DD2 corresponding to a default staff member or subject category, and when the index is changed by manual user selection, we can optionally save the index as a named document variable in the active document. We can then include code in the Document_Open() event of the document template, e.g., EngLetter.dotm for reading the document variable to determine the indices for DD1 and DD2 and then select the respective items. This will ensure that by default the selected items appear in the respective dropdowns when a saved document is reopened. Figs. 12a to 12c are flow charts showing the functionality of the callbacks for the third dropdown in the custom UI ribbon. Here also, no further elaboration is required apart from the OnAction callback of which two features are particularly significant. The first is that the selected autotext is inserted from the boilerplate template in rich text format. What this mean is that any formatting associated with the selected autotext is preserved. This functionality is achieved by virtue of the interaction between the boilerplate template storing the autotexts, the document template defining the UI ribbon and the global template storing the program code that identifies a selected autotext in the UI Ribbon, finds the selected autotext in the boilerplate template and inserts it into the active document. The second distinctive feature of the OnAction callback shown in Fig. 12c is the ability to augment a selected autotext with additional information that is compiled based on document-specific data that is extracted from a database using ODBC. Consider, for example, a letter to a client reporting an Office Action having a specified date and term for response. Conventional IP docketing systems typically require that both dates be entered into the database and the reporting letter then extracts both dates from the database and may use bookmarks or other placeholders to enter the dates into the reporting letter. In contrast, a system according to the invention can use programmable place-holders to prompt the user to enter the date of the office action and can use a rules-based 35 database table to extract the term and compute the due date. In Microsoft Word™ the programmable placeholder is preferably a content control and the autotext can be of the kind shown in Fig. 13, which shows two content controls 25 and 26 whose tags are shown in design mode, thus identifying one as the date of an office action and the other as the due date. On exiting the first content control 25, an event is triggered which may determine a file code that uniquely identifies the current application in a database, determines the country such as USA and determines that the standard term for response to an office action from the USPTO is 3-months and computes the due date by adding 3 months to the date of the office action as entered by the user into the content control. Having done this, it can enter the computed due date into the second content control and can even automatically add or update a docketing event in the docketing system. Figs. 14a and 14b are screen images showing subsequent stages during insertion of an autotext entry and automatic augmentation of a programmable placeholder. Thus, Fig. 14a shows a first stage where the user has selected as the required subject category "Office Action" from the second dropdown 13. This populates the third dropdown 14 with autotexts relating to the reporting of an Office Action as shown in Fig. 14b. The document template is a general template used to compile an English language letter, which is opened responsive to the user entering the file code 22, shown as ‘155489’ in the figures. As further shown in Fig. 14b, user selects "IPRP unfavorable" corresponding to an autotext having a single content control 27 shown in display mode in Fig. 14c into which the PCT application number corresponding to this file must be entered. Conventionally this would require manual entry of the PCT application number, shown (fictitiously) as ‘PCT/GB2020/123456’ typically by accessing the database, finding the PCT number corresponding to the current file identified by the file code ‘155489’ and copy/pasting to the content control. Alternatively, a custom template might be created for all Office Action reports, which would include every conceivable standard text segment. The relevant code for extracting the PCT number from the database and inserting into the content control would then be embedded in the custom template. Both of these approaches are undesirable for different reasons. The first is clearly cumbersome and more time-consuming than the automatic augmentation achieved by the invention. The second approach is also unsatisfactory for three principal reasons. First, it is subtractive meaning that such a ‘custom’ template requires that every conceivable scenario be covered and that those not relevant to the current report be deleted. Precisely because examination reports vary from one case to another and are clearly unpredictable, this results in the user deleting most of the standard text segments, which may consume more 35 time than it saves. Secondly, the creation of Word™ templates entails a measure of skill that is typically beyond the average user. This is particularly true for templates that require programming knowledge of the objects underlying the Word™ application. It is certainly well within the capabilities of the user to add standard blocks of text to the template to cater for scenarios not originally contemplated, provided that they do not include programmable placeholders. But the template then becomes user-specific, which prevents its ongoing development and maintenance by IT staff and may result in user-specific changes being lost if templates stored on a user’s local disk drive are subsequently replaced by the IT staff with a revised template. Furthermore, in organizations where all users access a central network repository as is increasingly common with cloud-based computing, local users may be foreclosed from making their own changes to a template that is shared by all users. Thirdly, even in an organization where self-customization is possible without the risk of loss, an autotext added to a subject-specific document template will not be listed in the dropdowns 13 and 14 shown in Fig. 7. The present invention circumvents these problems by allowing the creation and maintenance by any user of a user-specific boilerplate template that is independent of any centralized development. It is true that the full benefit of autotexts having programmable placeholders such as those shown in Figs. 13 and 14c requires supporting program code in the global template, without which the automatic augmentation described above will not be facilitated. But a global template may include code that inserts database content into content controls having predefined tags; and it is certainly well within the capability of the average user to create an autotext entry having one or more content controls whose tags correspond to such predefined tags. The invention will then take care to augment the content controls transparently with the relevant content using code such as shown in Table XX. With this in mind and reverting to Fig. 12c, the OnAction callback for the third dropdown inserts the autotext and contains code that determines that the autotext includes a content control whose tag is ‘IPRP’ and then executes auxiliary code specific to this tag which uses ODBC to extract from the docketing system the PCT number corresponding to file code ‘155489’. The matching PCT number is then inserted into the content control so that the resulting insert is as shown in Fig. 14b.
Single subject document templatesThe above description relates to an embodiment of the invention having dropdowns and 14 for subject category (or style) and autotexts. The provision of the first dropdown to allow for user-specific boilerplate templates is a useful feature albeit not a requirement. But there are applications where documents based on a document template relate to a single 35 subject category only. For example, a debit note or invoice include typically relates to only a small number of billable items that can conveniently be accommodated in a single dropdown without the need to divide them into separate subject categories such as new filing, prosecution, allowance, renewals and so on. We could then modify the XML shown in Table I to omit the second dropdown, DD2, relating to subject category. Alternatively, we can retain the subject category dropdown and populate it with only a single item called ‘Debit Note’ (in addition to the header), which allows us to immediately populate the third dropdown, DDwith all autotexts in the boilerplate template relating to a single style called ‘Debit Note’. Reverting to the flowchart in Fig. 11c, when the tag for the dropdowns defined by the XML shown in Table I relates to a debit note, the program code in the global template that compiles the array of subject categories is adjusted to include only the single subject category ‘Debit Note’ in the array. As a result, GetSelectedItemIndex for the second dropdown auto-matically defaults to ‘Debit Note’ and the third dropdown is pre-populated with autotexts whose style matches this subject category as seen in Fig. 15, which shows both dropdowns activated for the sake of illustration. In practice, each dropdown shows only a single item when inactive and only one dropdown can be activated at any given time. The autotexts relating to the debit note may include placeholders such as content controls that are augmented automatically based on data in the database. Thus, we could include an item for reporting an Office Action and specify its date; or we could apply a discount and specify a percentage discount based on data in the database. For example, if a client Optics (UK) Ltd. to whom the documents shown in Figs. 14 and 15 are directed is entitled to a discount of 15% on our service charge, the OnAction callback for the third dropdown 14 can be programmed to extract this from the database and insert it into the content control. We will now explain in detail how the callbacks interact with the global template to populate the dropdown menu. The label is assigned using UIRibbon_JJTMacros.getLabel, which, as already noted, is a procedure called GetLabel in module UIRibbon_JJTMacros. We use the same procedure GetLabel to assign the label for all ribbon controls in all of our custom ribbons. In Table XI we show a significantly reduced part of the callback that relates only to dropdown controls that are dynamically populated. The callback has two input arguments: control is set to the ribbon control that calls the procedure, which sets returnedVal to the label. As seen in the XML, the first dropdown has an ID="DD1" and is part of a group whose ID="Attorney" and whose label is set by calling "UIRibbon_JJTMacros.getLabel". Group is also a control which defines a distinct area of the ribbon within which other controls are located. When getLabel is called for this Group control, the input argument points to the Group control, whose ID we know to be 35 "Attorney". Statement Select Case control.id assigns a string to returnedVal corresponding to the required label. It is seen that if control.id equals "Attorney" returnedVal is set to "Attorney" and this is displayed in the first group and denoted by 15 in Fig. 7. Table XII shows a fairly simple function GetUserLang, which is called by GetLabel to determine the language of Microsoft Office as set in the regional settings. JJTEnglish and JJTHebrew are global constants set to ‘0’ and ‘1’ respectively. So, the value of GetUserLang will be 0 or 1 depending on whether the interface language is English or Hebrew. Obviously, this fairly simple function is described by way of example only and can be extended for other languages. It works fine for a bilingual interface since it does not require discrimination between different English dialects, each having a different value of Application.LanguageSettings.LanguageID(msoLanguageIDUI), as shown in Table XIII. If it is required that labels be defined for multiple languages, then of course the Select Case statement in GetLabel will need to accommodate all possible values of GetUserLang. A full list of language IDs can be found at https://docs.microsoft.com/en-us/office/vba/api/office.msolanguageid. Alternatively, instead of hard-coding the label strings in the procedure GetLabel, we could maintain a database table, for example, in SQL Server mapping each label to a different string value for each supported language and for each control ID. The procedure GetLabel could then call a stored procedure in SQL Server to assign the result to returnedVal. By choice, the dropdown "DD1" does not have its own label since we have associated the label with the group and have elected to place each dropdown in a separate group. This ensures that the three dropdowns are placed side by side in the ribbon. If we had not put them in separate groups, they would be aligned vertically. The dropdowns are populated using three callbacks, GetItemCount, GetItemLabel and GetSelectedItemIndex, which are now described. Parenthetically, it is noted that sizeString determines the width of the dropdown, which is a function of the number of ‘W’s in the string. It is set by trial and error to ensure that the longest label is fully accommodated. Items are added to the dropdowns by first calling GetItemCount to determine the number of items to be added and then for each item, calls GetItemLabel to get the respective label. The item labels for each dropdown are stored as string variables in a respective global two-dimensional array. Table XIV shows all the global variables required by GetItemCount and GetItemLabel. Table XV shows the code for GetItemCount and includes comments, which explain in sufficient detail how the code operates. As for all callbacks for the UI ribbon controls, the input argument ‘control’ references the ribbon object that calls the procedure, in our case a 35 dropdown, and ‘Count’ is set by the procedure to the number of items to be inserted. For the sake of abundant clarity, in VBA each comment line must start with a single apostrophe. There is no facility to delimit a complete block of comments (as there is in SQL Server). In reformatting the VBA code, some apostrophes have been deleted. It should further be noted that Table XV shows only the relevant code for the three dropdowns for the UI ribbons in letters and debit notes (English and Hebrew) and for the six dropdowns in the boilerplate ribbon. The boilerplate ribbon provides a user-friendly interface for creating and editing autotexts and is described in further detail below. Also, for the sake of brevity, we have omitted some code for the Hebrew letter and debit note, since it is identical to that for the English templates except that the qualifier ‘ENG’ is changed to ‘HEB’. Likewise, some procedures that are called by the procedure but are not are essential for carrying out the invention are described only functionally since the skilled programmer will easily be able to reproduce their functionality. As noted above, Table XV includes code executed by GetItemCount for the three dropdowns in both English and Hebrew letters and debit notes. But it also includes code for three more dropdowns DD4, DD5 and DD6, whose functionality is described below. It will be understood that the subject categories and autotexts extracted from the boilerplate templates will be ordered randomly. Although not essential, it makes for ease of use if they are sorted alphabetically prior to display by their respective dropdowns. This is done using the procedure BinarySort shown in Table XVI. Table XVII shows the code for GetItemLabel and includes comments, which explain in sufficient detail how the code operates. As can be seen from the XML in Table I, the OnAction callbacks are different for each of the three dropdowns. Table XVIII shows the code for GetStaffNames which is called when a user is selected in DD1; Table XIX shows the code for GetStyles which is called when a style or subject category is selected in DD2; and Table XX shows the code for GetAutotextEntries which is called when an autotext is selected in DD3. As noted above, only partial code is listed for populating the dropdowns DD2 and DD3 when opening documents based on letter templates and some auxiliary code is omitted, although the listed code can be used to realize a workable implementation. The functionality of the second dropdown DD2 is self-explanatory but we will add here some further explanation regarding the OnAction callback for DD3, shown partially in Table XX. When the user selects an autotext entry from the third dropdown DD3, OnAction inserts the selected autotext and then optionally augments the autotext according to program code specific to the selected autotext. By way of example, if the autotext is "IPRP Unfavorable" 35 as shown in Fig. 14b, OnAction calls a procedure, such as an SQL stored procedure, that extracts the PCT filing number from the docketing system and inserts it into the content control whose tag is "IPRP" as shown in Fig. 14c, the resulting autotext entry now appearing as shown in Fig. 14b. As noted previously such an implementation is hard-coded into the global template and is therefore beyond reach of the end-user. But in an integrated system where Microsoft Word™ is wholly integrated with a database such as SQL Server through ODBC, we can incorporate stored procedures for all or the most common fields that extract the named field for a given file code and the global template can enter the field into any content controls whose tag has the same name as the field. In effect this is what is shown in Table XX where after the insertion of smart autotext, the code loops through all content controls and augments named content controls with data extracted from the database. End-users can create their own autotexts and incorporate content controls whose tag is set to any one of the named tags in the ‘Select Case’ statement and these autotexts will be augmented without their having to make any changes to the global template. The ability to create and manage autotexts in an organized manner and to augment them after insertion with auxiliary data in a manner that is transparent to the end-user is a powerful feature that lies at the heart of the present invention. Table XXI shows partial VBA code for GetSelectedItemIndex according to the logic shown in Figs. 10c and 11c for dropdowns DD1 and DD2, respectively. The code is extensively commented thus obviating the need for detailed description here. An output variable index is set to the selected row (starting at zero) in the dropdown. By default, index is set to zero, which thus displays the header, i.e., "Select Letter Type" as shown in Fig. 7. But as explained above, if the active document is based on a document template associated with a subject category (i.e., letter style), index is set accordingly so that the second dropdown DD2 displays the corresponding label. The third dropdown DD3 is then populated with the autotexts matching this style. The same applies if the active document is associated with a file corresponding, for example, to a patent application for which there is a matching docketing event that corresponds to a subject category in the boilerplate template. Likewise, if the file is associated with a staff member in the docketing database, the index of the first dropdown DD1 will be set accordingly as shown in Fig. 9.
The Boilerplate EditorThe above description allows one skilled in the art to carry out the invention particu-larly when read in conjunction with the code shown in the Appendix. However, creating autotexts using the standard Microsoft Word™ interface shown in Fig. 3 is time-consuming 35 and editing existing autotexts requires that they be inserted into a document, edited as required and then effectively re-created by saving under their original name. A similar approach is required to change the style of an autotext entry. To rename an existing autotext entry is even more cumbersome: it must be inserted into a document, saved under the new name and the original entry must be deleted. Microsoft Word™ does provide an interface for copying autotexts and other building blocks from one template to another, but this requires knowledge of the advanced options and is probably out of the scope of many users. Figs. 16a and 16b are screen images showing partial details of a UI ribbon for the boilerplate editor based on a template called boilerplate.dotm. The XML for this ribbon is shown in Table XXII. As seen, there are two groups of dropdown menus labeled Source and Target, each group being functionally identical to what is described above and shown in Fig. 7, the only difference being that they are displayed vertically to preserve space. All the other objects in the ribbon are buttons whose functionality is fairly self-explanatory, but whose main functions will briefly be described. The boilerplate editor provides the following functions: ➢ Change Language ➢ Save, Add, Delete, Rename and Copy Item ➢ Copy, Add and Delete Style ➢ Compile List The boilerplate editor may be used with both the English and Hebrew boilerplate templates, the language being selected by pressing the appropriate ChangeLanguage toggle button. Selecting a letter style and an autotext inserts the autotext in a new document as shown in Fig. 17. The text can be edited freely and then saved under its original name and style by clicking on the Save Item button (constituting a first selector in the UI ribbon). If, prior to saving, we select a different style from the second dropdown, and then save, the autotext will be saved under the selected style thus ensuring that the autotext entry will subsequently be associated with the newly selected subject category or style rather than the original. A new autotext can be created by first selecting the style with which it is to be associated and then clicking Add Item (constituting a second selector in the UI ribbon). This causes a popup dialog to emerge as shown in Fig. 18 prompting entry of the autotext name. If the name entered by the user already exists, the user will be prompted to save under a different name or to override the current version. Saving the item by clicking on the Save Item button will now save the autotext in association with the selected style. In the example shown in the figure, the content of the active document will be saved as a new autotext called "Cost Estimate" under the subject category "Outlook". 35 The code for Add Item shown in Table XXIII is for the most part self-explanatory, with one important exception that will be further explained now. In an embodiment of the invention described below with reference to Figs. 19 to 21, the UI ribbon and supporting program code is implemented in a DLL (dynamic link library) or COM file that is injected into Microsoft Outlook™ as an Add-in. This allows the boilerplate to be accessed also from within Outlook and for standard text segments to be selected according to subject category for insertion into and active email item. But this locks the boilerplate template and prevents changes to the boilerplate template from being saved. The statement: If OutlookAddinOn Then RemoveOutlookAddin removes the Add-in from Outlook by emulating manual removal under the Developer tab, so that changes to the boilerplate template made using the boilerplate editor can be saved. The full code for RemoveOutlookAddin is shown in Table XXIV. Copy Item (constituting a third selector in the UI ribbon) copies a selected autotext from the source boilerplate to a selected target. Delete Item, Rename Item, Add Style (constituting fourth, fifth and sixth selectors, respectively, in the UI ribbon) and Delete Style are self-explanatory. Copy Style copies a selected style from the source boilerplate to a selected target. Compile list opens a new document and lists all styles followed by their associated autotexts and is a useful tool to render visible contents of the boilerplate, which are normally hidden. For the sake of completeness, the code for Rename Item is shown in Table XXV. The full code for the other features of the boilerplate editor is not listed, but anyone familiar with VBA programming under Microsoft Word™ will have no difficulty in writing suitable code based on the code listed in Tables XXIII and XXV. The dropdowns are populated as described in detail above and their OnAction callbacks function as described to insert a selected autotext entry into a blank document. The VBA code for the buttons should be straightforward for those familiar with the objects of Microsoft Word™, but we provide the code for Add Item and Rename Item, since these are likely to be the most commonly used and the VBA code for the other functions follows similar logic. When we make a change to the boilerplate template, we need to save the template in order for the change to be reflected in the UI ribbon’s dropdowns. As will be described below, we have implemented the invention also in Microsoft Outlook™, which uses Micro-soft Word™ as its editor. This requires creation of a DLL that is added using Options–Add-ins. Creation of a custom ribbon under Outlook is not as straightforward as Word™ or other Microsoft Office applications and requires a knowledge of Visual Studio, which is beyond the scope of this description. The inventors have implemented the invention in Outlook. 35 Fig. 19 is a screen image showing details of a UI ribbon for an embodiment of the invention implemented under Microsoft Outlook™. The UI ribbon has two custom tabs whose labels are "Automation" and "Symbols". The "Symbols" XML for the ribbon defines two rows of buttons whose images are upper- and lower-case Greek symbols and whose onAction callback, a detail of which is shown in Table XXVI, inserts the appropriate Unicode symbol into the active document or email corresponding to upper- and lower-case alpha (A and α). These symbols can, of course, be equally well inserted using Insert-Symbol i.e., the Symbol command in the Insert tab, but this requires multiple selections whereas the Symbols tab allows direct insertion of a required symbol with a single click. This being said, the Symbols tab is based on standard UI programming and is described only because it is part of the UI ribbon: it is not a feature of the present invention. In order to display the tabs at sufficient magnification to maintain legibility, the Greek symbols after pi ( π) are omitted and the Automation tab has been moved so that both custom tabs can be seen in the same screen image. In practice, the actual location of the tabs in the UI ribbon is determined by the ribbon XML. It should also be noted that the custom tabs are relevant only when editing an email; so, they are not displayed in the home page when Microsoft Outlook™ is launched but only when creating a new email or replying to a received email. Fig. 21 is an edited screen image showing partial details of the "Automation" Tab in the UI ribbon shown in Fig. 19. It is seen that the graphical interface is similar to that shown in Figs. 7 and 9 except that the dropdowns in Fig. 19 belong to a single group, such that they appear vertically, similar to their appearance in the boilerplate editor shown in Fig. 16a. The XML definitions for the three dropdowns labelled Staff Name, Letter Style and Autotext are essentially the same as for the MS Word™ implementation described above with reference to Fig. 6 (apart from the single grouping of the dropdowns). Their callbacks are similar but not quite the same, because in the MS Word™ implementation the Word™ object is intrinsic whereas in MS Outlook™ we need to add a reference to the MS Word™ object corresponding to the editor in the body of the active Outlook mail item. Again, this is conventional VBA for MS Office integration and will be familiar to those skilled in the relevant art. For the sake of completeness, Table XXVI shows the XML definition for the Auto-mation tab shown in Fig. 19. We have included an alternative definition that is commented-out (i.e., inactive), based on comboboxes instead of dropdowns. While they are implement-ed differently in that their callbacks are different, they are functionally equivalent and the UI ribbon for both MS Word™ and MS Outlook™ can be implemented using either dropdowns 35 or comboboxes or even a mixture of the two. Thus, in the context of the invention and the appended claims, reference to a menu in the graphical user interface denotes either a dropdown or a combobox. It will be seen from Table XXVII that in addition to the three dropdowns DD1, DD2 and DD3, there are three toggle buttons that allow for selection of a desired proofing language, specifically Hebrew, US English and UK English each identified by an image corresponding to the national flag for Israel, USA and UK, respectively. There then follows a fourth dropdown DD4 which is populated with staff names and allows an auto-signature to be inserted or for an existing auto-signature to be replaced with the signature of the selected staff member. The automation tab also includes a button, which when actuated causes a VB form to open and allow for key combinations such as ALT-1 to be defined corresponding to specific autotexts, thereby allowing the user to insert a desired autotext simply by typing a preset key combination. This feature is not part of the invention and so is not described further, Table XXVIII shows that the onAction callbacks for the dropdowns DD1, DD2 and DD3 in the UI ribbon are functionally identical to the flow charts of Figs. 10d, 11d and 12c, respectively, implemented in MS Word™ by procedures GetStaffNames, GetStyles and GetAutotextEntries summarized in Tables XVIII, XIX and XX, respectively. Structurally, the Outlook™ implementation includes the code in a single callback, but this is simply a design choice. More significantly, the callback must instantiate MS Word™ which it does using the following code: Dim myolapp As Outlook.Application Dim myInspector As Outlook.Inspector myolapp = CreateObject("Outlook.Application") myInspector = myolapp.ActiveInspector If Not myInspector Is Nothing Then objDoc = myInspector.WordEditor BPlate = Path & BPName objDoc.Application.AddIns.Add(BPlate) oTmp = objDoc.Application.Templates(BPlate) For Each oAT In oTmp.AutoTextEntries If Not itemLabels.Contains(oAT.StyleName) Then itemLabels.Add(oAT.StyleName) End If Next It will be understood that this code is written in Visual Basic rather than VBA. The two languages are similar but not identical. Thus, in the above code segment, itemLabels is an array corresponding to EngLetterStyleList in the MS Word™ implementation and is populated differently. objDoc is a Word™ document object corresponding to the body of the current email item to which the selected boilerplate template is rendered accessible as 40 an Add-in. oTmp is an object corresponding to the boilerplate template and oAT is an object corresponding to the autotext entries stored in the boilerplate template. Since Word™ is the underlying text editor in Outlook™, the invention can be implemented in Outlook™ in much the same way as in Word™. Reverting to the XML definition shown in Table XXVII and the three toggle buttons shown in Figs. 19 and 21, the code for the ChangeLanguage callbacks will not be described in detail partly because it is not a feature of the invention and also because it basically emulates the standard features of Word™ and Outlook™, both of which allow the proofing language to be changed. But in addition to changing the proofing language, the callback also checks whether the signature language has changed and, if so, checks whether a signature file exists for the selected user in the target language. To this end, Hebrew and English signature files in HTML are stored in a dedicated folder and are named according to the user ID. For example, staff member Elizabeth Bennet has an ID "EB" and has English and Hebrew signature files stored in C:signatures named Autosignature_EB.htm and Autosignature_heb_EB.htm, respectively. The signatures are bookmarked and the onAction callback replaces the range of the current signature bookmark with the HTML content of the complementary signature file and applies paragraph text alignment corresponding to the target language. It will be appreciated that while embodiments of the invention have been described with particular reference to Microsoft Word™ and Outlook™, the principles of the invention may be applicable to other word-processing software. Preferred embodiments exploit the UI ribbon that is part of the Microsoft Office suite of programs, some aspects of which are proprietary to Microsoft and thus may not be available in rival products. Nevertheless, the principles of the invention may also be applied to command bars that were used in MS Word™ prior to Office 2007 and have been emulated by open-source word processing software. Microsoft allowed for the embedding into their command bars of ActiveX™ controls such as dropdowns and textboxes that allowed for dynamic population of a dropdown and insertion of autotexts. The inventors developed an unpublished test version of the program under MS Word 2003 using floating command bars and ActiveX™ controls. It worked but was unstable and required frequent tweaking of the Registry file. The UI Ribbon offers a stable environment that is fully portable across Microsoft Office platforms. It will further be understood that while the first dropdown menu DD1 is used to populate different staff names, it can alternatively be populated with any other label that is indicative of a specific boilerplate template. So, for example, in the case described where we may wish to assign different boilerplate templates to each user, we could of 35 course simply display the names of the different available boilerplate templates, or the IDs of the different staff members; or the boilerplate templates could be stored in different folders and we could display the folder names. It will also be appreciated that in the MS Word™ implementation of the invention, a global template is used to store the VBA code in the form of macros. The global template operates as an Add-in that allows its macros to be accessible to the active document. The UI ribbon can be built into the same global template or can be built into a document template on which the active document is based. In the Outlook™ implementation, the Add-in is a DLL or COM file that is created using Visual Studio. These files can be added using the COM Add-ins feature on the Developer tab, while DLLs are automatically added-in by Visual Studio during compilation or publication. In both the MS Word™ and Outlook™ implementations, the Add-ins are global to the application and are independent of the boilerplate template. Another difference is that in the Word™ implementation, the UI ribbon is handled by the document template on which the active document is based. In other words, the UI ribbon XML definition and its callbacks are encoded in different documents. In the Outlook™ implementation, the XML and the callbacks are part of the same project, although in fact they also are maintained as separate files in the project folder and are displayed in separate tabs of the Visual Studio integrated development environment. However, they are integrated as a composite solution and are incorporated into Outlook™ as a single Add-in. Nevertheless, in both implementations the boilerplates are created and maintained separately and the autotexts are made available to the host application (i.e. Word™ or Outlook™) in an organized manner according to boilerplate name and subject category. It will also be understood that the invention contemplates a computer program readable by a computer for executing the method of the invention and a machine- readable memory tangibly embodying a program of instructions executable by the machine for executing the method of the invention. The description of the above embodiments is not intended to be limiting, the scope of protection being provided only by the appended claims. In particular it should be noted that features that are described with reference to one or more embodiments are described by way of example rather than by way of limitation to those embodiments. Thus, unless stated otherwise or unless particular combinations are clearly inadmissible, optional features that are described with reference to only some embodiments are assumed to be likewise applicable to all other embodiments also. 35 APPENDIX: VB Code Segments Table I: Partial UI Ribbon XML definition for document template Table II: UI Ribbon XML definition for hard-coded button Table III: onload callback for UI Ribbon Sub Engletter_Onload(ribbon As IRibbonUI) Set EngletterRibbon = ribbon StoreObjPtr ("EngLetter") End Sub Table IV: Global UI Ribbon object variables Public EngletterRibbon As IRibbonUI 'Used for English letter Public HebletterRibbon As IRibbonUI 'Used for Hebrew letter Public EngDNRibbon As IRibbonUI 'Used for English Debit Note Public HebDNRibbon As IRibbonUI 'Used for Hebrew Debit Note Table V: Procedure for storing pointer to ribbon object Sub StoreObjPtr(ByVal ObjectName As String) Dim TextFile As Integer Dim obj As Object Select Case ObjectName Case "EngLetter" Set obj = EngletterRibbon Case "HebLetter" Set obj = HebletterRibbon Case "BPRibbon" Set obj = BPRibbon Case Else Exit Sub End Select If obj Is Nothing Then Exit Sub TextFile = FreeFile Open TemplatePath & ObjectName & ".txt" For Output As TextFile Write #TextFile, ObjPtr(obj) Close #TextFile End Sub Table VI: Partial procedure for reloading ribbon object Public Sub Reload_UIRibbon(ByVal RibbonType As String) Select Case RibbonType Case "HebLetter" If HebletterRibbon Is Nothing Then Set HebletterRibbon = RestoreObjRibbon(GetObjPtr(RibbonType)) HebletterRibbon.Invalidate Else HebletterRibbon.Invalidate End If Case "EngLetter" If EngletterRibbon Is Nothing Then Set EngletterRibbon = RestoreObjRibbon(GetObjPtr(RibbonType)) EngletterRibbon.Invalidate Else EngletterRibbon.Invalidate End If End Select End Sub Table VII: Function GetObjPtr #If Win64 Then Function GetObjPtr(ByVal objType As String) As LongPtr #Else Function GetObjPtr(ByVal objType As String) As Long #End If Dim TextFile As Integer TextFile = FreeFile Open TemplatePath & objType & ".txt" For Input As TextFile GetObjPtr = Input(LOF(TextFile), TextFile) Close TextFile End Function Table VIII: Procedure for restoring ribbon object #If Win64 Then Function RestoreObjRibbon(ByVal lObjectPointer As LongPtr) As Object #Else Function RestoreObjRibbon(ByVal lObjectPointer As Long) As Object #End If Dim objRibbon As IRibbonUI CopyMemory objRibbon, lObjectPointer, LenB(lObjectPointer) Set RestoreObjRibbon = objRibbon Set objRibbon = Nothing End Function Table IX: CopyMemory API Declaration #If Win64 Then Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long) #Else Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long) #End If Table X: Database Users Table (example) Code Title Eng_Name Heb_Name Identifier 2 Sally Mason ס א מ יל י ןוסי SM 1 John Dunn 'ג ו ןאד ן JD 1 Joseph Messinger רגניסמ ףסוי JM 2 Elizabeth Bennet טנב טבזילא EB 5 Ruth Hermon ןומרה תור RH 0 Patent Office םיטנטפה תושר PO 0 Renewals םישודיח RNW Table XI: Partial code of getLabel referenced in UI ribbon’s XML Sub getLabel(control As IRibbonControl, ByRef returnedVal) If GetUserLang = JJTEnglish Then Hebrewmode = False Else Hebrewmode = True End If If Hebrewmode Then Select Case control.id Case "EngLetter" returnedVal = " )תילגנא( םכח טסקטוטוא" Case "HebLetter" returnedVal = " )תירבע( םכח טסקטוטוא" End Select Else Select Case control.id Case "EngDebitNote", "HebDebitNote", "DN" returnedVal = "Debit Note" Case "EngLetter" returnedVal = "Smart Autotext (English)" Case "HebLetter" returnedVal = "Smart Autotext (Hebrew)" Case "Attorney" returnedVal = "Attorney" Case "Style" returnedVal = "Letter Style" Case "SmartAutotext" returnedVal = "Smart Autotext" Case "Autotext" returnedVal = "Autotext" Case "Shortcuts" returnedVal = "Shortcuts" End Select End If End Sub Table XII: Get Interface Language Function GetUserLang() As Integer Select Case Application.LanguageSettings.LanguageID(msoLanguageIDUI) Case msoLanguageIDHebrew GetUserLang = JJTHebrew Case Else GetUserLang = JJTEnglish End Select End Function Table XIII: Interface Language ID for different English forms or dialects msoLanguageIDEnglishAUS 3081 Australia msoLanguageIDEnglishBelize 10249 Belize msoLanguageIDEnglishCanadian 4105 Canadian msoLanguageIDEnglishCaribbean 9225 Caribbean msoLanguageIDEnglishIndonesia 14345 Indonesia msoLanguageIDEnglishIreland 6153 Ireland msoLanguageIDEnglishJamaica 8201 Jamaica msoLanguageIDEnglishNewZealand 5129 NewZealand msoLanguageIDEnglishPhilippines 13321 Philippines msoLanguageIDEnglishSouthAfrica 7177 South Africa msoLanguageIDEnglishTrinidadTobago 11273 Trinidad Tobago msoLanguageIDEnglishUK 2057 UK msoLanguageIDEnglishUS 1033 US msoLanguageIDEnglishZimbabwe 12297 Zimbabwe Table XIV: Global Array definitions Public ListAttorneys() As Staff 'Staff is a Type whose partial definition is: Type Staff Code As Integer Eng_Initials As String identifier As String Eng_Prefix As String Eng_Name As String Heb_Prefix As String Heb_Name As String End Type Public EngletterRibbon As IRibbonUI 'Used for English letter Public HebletterRibbon As IRibbonUI 'Used for Hebrew letter Public EngDNRibbon As IRibbonUI 'Used for English Debit Note Public HebDNRibbon As IRibbonUI 'Used for Hebrew Debit Note Public BPRibbon As IRibbonUI 'Used for BoilerPlate in AddIns Public UIRibbon_Style As String Public Count As Integer Public MyTag As String Public SelectedAutoText, SelectedStyle, SelectedStaff As String Public EngLetterStyleList(), HebLetterStyleList() As String Public EngDNStyleList(), HebDNStyleList() As String Public EngletterAutoTextList(), HebletterAutoTextList() As String Public EngDNAutoTextList(), HebDNAutoTextList() As String Public SourceBPFile, TargetBPFile, SourceBPStyle, TargetBPStyle, BPAutotextName As String Public oTmp As Template Public oTgt As Template Table XV: Partial VBA code for GetItemCount Public Sub GetItemCount(ByVal control As IRibbonControl, ByRef Count) 'Tell the ribbon how many items to show in the Dropdown 'Note that bilingual support is provided for Registrar templates and templates in Hebrew 'to local clients. 'The number of entries in each Dropdown box is 1 + the number of elements in the array because the first entry in the Dropdown box is a header Dim i, j As Integer, oAT As AutoTextEntry Dim BPName, Path, FirstChar, EnglishChars, Tag As String 'Note that if there is no activedocument, this procedure will fail when trying to assign 'ActiveDocument.BuiltInDocumentProperties(wdPropertyTemplate). So if no documents 'are open we need to quit in order avoid an error. Such an error would occur when closing a 'document that is the only current document, upon trying to reactivate the main ribbon. Simply 'put, if there's no open document there can't be a ribbon so we need to check this in all the 'ribbon procedures for this module. It applies to any procedure that needs to be called by 'this ribbon If Documents.Count = 0 Then Exit Sub 'This Callback determines the number of items in the Dropdown box identified by Control.ID and creates a two-dimensional array containing labels based on a Tag in the ribbon XML. We use the same code for letterhead and debit note ribbons and more recently for the BoilerPlate ribbon. However, the letterhead and debit note ribbons are language-specific. In other words, the ID associated with their respective ribbons is different for Hebrew and English, so the code knows which arrays to populate from the value of Control.Tag. Thus, if Control.Tag is "EngLetter" we know this is an English letter and the Autotexts are contained in Array EngletterAutoTextList() from which the labels of the Dropdown DD3 are populated. But the BoilerPlate uses the same ribbon for both Hebrew and English boilerplates and includes togglebuttons that allow a desired language to be selected. So in this case, we need to set either EngletterAutoTextList() or HebletterAutoTextList() and populate Dropdowns DD3 or DDaccording to LangType. 'The boilerplate ribbon uses the same autotext arrays as EngLetter and HebLetter depending on language. So rather than repeat identical code for populating the autotext Dropdowns DDand DD6 we set the appropriate arrays based on Select Case Tag where Tag is Control.Tag for all ribbons except boilerplate where it is set to EngLetter and HebLetter depending on language. If control.Tag = "BPlate" Then If LangType = JJTEnglish Then Tag = "EngLetter" Else Tag = "HebLetter" End If Else Tag = control.Tag End If EnglishChars = "abcdefghijklmnopqrstuvwxyz" On Error GoTo Initialize Select Case control.id 'Control.id is the Dropdown ID as specified in the XML definition Case "DD1" GetAttorneys 'Defines ListAttorneys() - Requires ODBC connection Count = 1 + UBound(ListAttorneys) Case "DD4" 'DD4 holds the names of the staff members whose selection determines the target Boilerplate template to which autotext items in the source Boilerplate template can be copied. We obviously do not want to copy from a source template to the same target template so if iSourceAttny > 0 this means we have selected a name from DD1 and we omit this name from DD4. iSourceAttny is assigned by GetStaffNames() shown in Table XVI. If (iSourceAttny = Empty) Or (iSourceAttny = 0) Then Count = 1 + UBound(ListAttorneys) Else Count = UBound(ListAttorneys) End If 'As noted above, we use this procedure for invoking the GetItemCount callback for all Dropdown controls. We could have a separate callback for each Dropdown and change the XML shown in Table I so that each Dropdown references its own callback. Both approaches have their advantages and drawbacks. Our approach allows us to copy the XML definition between document templates with very little change; and maintenance of a single procedure is easier. 'For the three Dropdown controls DD1, DD2 and DD3 in the English letter document template we maintain three arrays defined in Table XIV. These arrays are respectively ListAttorneys(), EngLetterStyleList() and EngletterAutoTextList(). Corresponding arrays are maintained for the other document templates (Hebrew letter and English and Hebrew debit notes) 'The following code is executed for the Dropdowns DD2, DD5 containing style names. The style arrays such as EngLetterStyleList() etc. are compiled by GetStaffNames() shown in Table XVIII. However, once EngLetterStyleList() is defined it contains a list of unique styles in the boilerplate template, corresponding to the number of different subject categories associated with the autotext entries. The object of GetItemCount() is to determine the number of items to put into the Dropdown: this is always 1 + the number of rows in the array that sources the Dropdown. Thus, for DD2 and DD5 in the English letter document template this is 1 + UBound(EngLetterStyleList, 2). We add because the first item label of DD2 and DD5 is set to "Select Letter Type" Case "DD2", "DD5" Select Case control.Tag Case "EngLetter" Count = 1 + UBound(EngLetterStyleList, 2) Case "EngDN" Count = 1 + UBound(EngDNStyleList, 2) Case "HebLetter" Count = 1 + UBound(HebLetterStyleList, 2) Case "HebDN" Count = 1 + UBound(HebDNStyleList, 2) Case "BPlate" If LangType = JJTEnglish Then Count = 1 + UBound(EngLetterStyleList, 2) Else Count = 1 + UBound(HebLetterStyleList, 2) End If End Select Case "DD3", "DD6" Count = 1 'The following three lines of code are not essential for populating the Dropdowns, but they add some intelligence for firms having a database which stores case data including a file code that is unique for each case and serves as a primary key and is added as a Word™ document variable to each document created by staff members. We have developed an interface that is not part of the present invention that creates Word™ documents by first entering the file code into a custom interface. Our database maps each code to a specific staff member and therefore if we know the file code, we can determine the staff member. This is done before opening the document template on which the letter or debit note is based, and allows us to use the boilerplate template for the relevant staff member. 'GetDocVariable() is a VBA function which reads the document variable corresponding to File_code if it exists and GetFileAttorney() extracts the responsible staff member, whose unique identifier determines which boilerplate template to use. If there is no file code document variable or no staff member is assigned to the file or if no boilerplate template is found for the specified staff member, we use a default boilerplate template "BoilerPlate-Eng-SM.dotx" File_Code = GetDocVariable("File_Code") If File_Code <> vbNullString Then GetFileAttorney (File_Code) If Attorney.identifier = vbNullString Then Attorney.identifier = "SM" 'Tag is part of the XML definition for the Dropdown as shown in Table I: for DD1 tag="EngLetter". In the corresponding XML for the Hebrew letter document template, it is set to "HebLetter" and the tags for the debit note templates are "EngDN" and "HebDN". For the letter and debit note templates, Tag is set to control.Tag and is passed to the procedure via the input argument Control. Select Case Tag Case "EngLetter" BPName = "BoilerPlate-Eng-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesStandard Letters" If Dir(Path & BPName) = vbNullString Then BPName = "BoilerPlate-Eng-SM.dotx" Set oTmp = Templates(Path & BPName) ReDim EngletterAutoTextList(1, 0) For Each oAT In oTmp.AutoTextEntries If oAT.StyleName = SelectedStyle Then ReDim Preserve EngletterAutoTextList(1, Count) FirstChar = LCase(Left(oAT.Name, 1)) If InStr(1, EnglishChars, FirstChar) > 0 Then 'Autotext is English If Hebrewmode Then 'We always display index EngletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) EngletterAutoTextList(1, Count) = oAT.Name Else EngletterAutoTextList(0, Count) = oAT.Name EngletterAutoTextList(1, Count) = oAT.Name End If Else If Hebrewmode Then 'We always display index EngletterAutoTextList(0, Count) = oAT.Name EngletterAutoTextList(1, Count) = oAT.Name Else EngletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) EngletterAutoTextList(1, Count) = oAT.Name End If End If Count = Count + End If Next 'The order in which Autotext entries are inserted into the array AutoTextList() is not alphabetic. So we sort into alphabetical order BinarySort EngletterAutoTextList() Case "HebLetter" BPName = "BoilerPlate-Heb-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesםיבתכמ" If Dir(Path & BPName) = vbNullString Then BPName = "BoilerPlate-Heb-SM.dotx" Set oTmp = Templates(Path & BPName) ReDim HebletterAutoTextList(1, 0) For Each oAT In oTmp.AutoTextEntries If oAT.StyleName = SelectedStyle Then ReDim Preserve HebletterAutoTextList(1, Count) FirstChar = LCase(Left(oAT.Name, 1)) If InStr(1, EnglishChars, FirstChar) > 0 Then 'Autotext is English If Hebrewmode Then 'We always display index HebletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) HebletterAutoTextList(1, Count) = oAT.Name Else HebletterAutoTextList(0, Count) = oAT.Name HebletterAutoTextList(1, Count) = oAT.Name End If Else If Hebrewmode Then 'We always display index HebletterAutoTextList(0, Count) = oAT.Name HebletterAutoTextList(1, Count) = oAT.Name Else HebletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) HebletterAutoTextList(1, Count) = oAT.Name End If End If Count = Count + End If Next 'The order in which Autotext entries are inserted into the array AutoTextList() is not alphabetic. So we sort into alphabetical order BinarySort HebletterAutoTextList() Case Else If LangType = JJTEnglish Then BPName = "BoilerPlate-Eng-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesStandard Letters" If Dir(Path & BPName) = "" Then BPName = "BoilerPlate-Eng-SM.dotx" Set oTmp = Templates(Path & BPName) ReDim EngletterAutoTextList(1, 0) For Each oAT In oTmp.AutoTextEntries If oAT.StyleName = SelectedStyle Then ReDim Preserve EngletterAutoTextList(1, Count) FirstChar = LCase(Left(oAT.Name, 1)) If InStr(1, EnglishChars, FirstChar) > 0 Then 'Autotext is English If Hebrewmode Then 'We always display index EngletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) EngletterAutoTextList(1, Count) = oAT.Name Else EngletterAutoTextList(0, Count) = oAT.Name EngletterAutoTextList(1, Count) = oAT.Name End If Else If Hebrewmode Then 'We always display index EngletterAutoTextList(0, Count) = oAT.Name EngletterAutoTextList(1, Count) = oAT.Name Else EngletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) EngletterAutoTextList(1, Count) = oAT.Name End If End If Count = Count + End If Next BinarySort EngletterAutoTextList() Else BPName = "BoilerPlate-Heb-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesםיבתכמ" If Dir(Path & BPName) = "" Then BPName = "BoilerPlate-Heb-SM.dotx" Set oTmp = Templates(Path & BPName) ReDim HebletterAutoTextList(1, 0) For Each oAT In oTmp.AutoTextEntries If oAT.StyleName = SelectedStyle Then ReDim Preserve HebletterAutoTextList(1, Count) FirstChar = LCase(Left(oAT.Name, 1)) If InStr(1, EnglishChars, FirstChar) > 0 Then 'Autotext is English If Hebrewmode Then 'We always display index HebletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) HebletterAutoTextList(1, Count) = oAT.Name Else HebletterAutoTextList(0, Count) = oAT.Name HebletterAutoTextList(1, Count) = oAT.Name End If Else If Hebrewmode Then 'We always display index HebletterAutoTextList(0, Count) = oAT.Name HebletterAutoTextList(1, Count) = oAT.Name Else HebletterAutoTextList(0, Count) = GetAlternateLabel(oAT.Name) HebletterAutoTextList(1, Count) = oAT.Name End If End If Count = Count + 1 End If Next BinarySort HebletterAutoTextList() End If End Select 'Case Control.tag End Select 'Case control.id Exit Sub Initialize: Count = Resume Next End Sub Table XVI: Procedure BinarySort Sub BinarySort(ByRef List() As String, Optional Numeric As Boolean = False) 'This procedure is based on an algorithm described by Tom Swan in his excellent book on 'Turbo Pascal 5.5. The first index of List() is [1] 'Optional input Argument allows us to sort numeric strings. This is necessary because although Val(9) < Val(28), Str(9) > Str (28) because 9 > 2! Therefore, when sorting numeric strings, the input argument Numeric must be set to TRUE. Dim Element, i, j, Bottom, Top, Middle As Integer Dim Temp, TempClone As Variant Dim Rank As Long Dim ErrorCheck As Long 'Get the number of dimensions in Array List() On Error GoTo FinalDimension For Rank = 1 To 600 'It is necessary to do something with the LBound to force it 'to generate an error so that we can determine the rank ErrorCheck = LBound(List, Rank) Next Rank Sort: 'Currently assumes we are sorting the first column: If UBound(List, Rank) < 2 Then Exit Sub For i = 2 To UBound(List, Rank) If Rank > 1 Then Temp = List(Rank - 2, i) TempClone = List(Rank - 1, i) Else Temp = List(i) End If Bottom = Top = i - While Bottom <= Top Middle = (Bottom + Top) / If Rank > 1 Then If Numeric Then If Val(Temp) < Val(List(Rank - 2, Middle)) Then Top = Middle - Else Bottom = Middle + End If Else If Temp < List(Rank - 2, Middle) Then Top = Middle - Else Bottom = Middle + End If End If Else If Numeric Then If Val(Temp) < Val(List(Middle)) Then Top = Middle - Else Bottom = Middle + End If Else If Temp < List(Middle) Then Top = Middle - Else Bottom = Middle + End If End If End If Wend If Rank > 1 Then For j = i - 1 To Bottom Step - List(Rank - 1, j + 1) = List(Rank - 1, j) List(Rank - 2, j + 1) = List(Rank - 2, j) Next j List(Rank - 2, Bottom) = Temp List(Rank - 1, Bottom) = TempClone Else For j = i - 1 To Bottom Step - List(j + 1) = List(j) Next j List(Bottom) = Temp End If Next i Exit Sub FinalDimension: Rank = Rank - GoTo Sort End Sub Table XVII: Partial VBA code for GetItemLabel Public Sub GetItemLabel(ByVal control As IRibbonControl, Index As Integer, ByRef Label) 'This procedure fires once for each item in the Dropdown. Index is received as 0, 1, 2, etc. and label is returned. Dim oAT As AutoTextEntry Dim i As Integer If GetUserLang = JJTEnglish Then Hebrewmode = False Else Hebrewmode = True End If Select Case control.id Case "DD1" Select Case Index Case If Hebrewmode Then Label = "שמתשמ םש רחב" Else Label = "Select Attorney" End If Case Else If Hebrewmode Then Label = ListAttorneys(Index).Heb_Name Else Label = ListAttorneys(Index).Eng_Name End If End Select Case "DD4" Select Case Index Case If Hebrewmode Then Label = "שמתשמ םש רחב" Else Label = "Select Attorney" End If Case Else 'iSourceAttny is index of DD1: we omit from DD4 the name selected in DD1 If iSourceAttny = Empty Then iSourceAttny = If iSourceAttny = 0 Then If Hebrewmode Then Label = ListAttorneys(Index).Heb_Name Else Label = ListAttorneys(Index).Eng_Name End If ElseIf iSourceAttny > Index Then If Hebrewmode Then Label = ListAttorneys(Index).Heb_Name Else Label = ListAttorneys(Index).Eng_Name End If ElseIf iSourceAttny <= Index Then If Hebrewmode Then Label = ListAttorneys(Index + 1).Heb_Name Else Label = ListAttorneys(Index + 1).Eng_Name End If End If End Select Case "DD2", "DD5" Select Case Index Case If Hebrewmode Then Label = " גוס רחב בתכמ " Else Label = "Select Letter Type" End If Case Else 'Label is always set to the display name, which may not be the same as the actual Stylename. 'For example, Hebrew styles my be displayed in English: so the Style םישודיח is displayed as Hebrew Renewal Letters. SelectedStyle is set to the actual Stylename since it is compared with oat.StyleName in GetItemCount() which defines the Array AutoTextList() Select Case control.Tag Case "EngLetter" Label = EngLetterStyleList(0, Index) SelectedStyle = EngLetterStyleList(1, Index) Case "HebLetter" Label = HebLetterStyleList(0, Index) SelectedStyle = HebLetterStyleList(1, Index) Case "BPlate" If LangType = JJTEnglish Then Label = EngLetterStyleList(0, Index) SelectedStyle = EngLetterStyleList(1, Index) Else Label = HebLetterStyleList(0, Index) SelectedStyle = HebLetterStyleList(1, Index) End If End Select 'Case Control.tag End Select 'Case index Case "DD3", "DD6" Select Case Index Case If Hebrewmode Then Label = "טסקטוטוא רחב" Else Label = "Select Autotext" End If Case Else Select Case control.Tag Case "EngLetter" Label = EngletterAutoTextList(0, Index) Case "BPlate" If LangType = JJTEnglish Then Label = EngletterAutoTextList(0, Index) Else Label = HebletterAutoTextList(0, Index) End If End Select 'Case control.tag End Select 'Case index End Select 'Case control.id End Sub Table XVIII: Partial VBA code for GetStaffNames Sub GetStaffNames(ByVal control As IRibbonControl, selectedID As String, iAttny As Integer) Dim BPName, Path, BaseTemplateName, filename, Tag As String Dim StyleFound, DocumentSaved As Boolean, i As Integer, iBPlate, ThisLang As Variant Dim oAT As AutoTextEntry, FirstChar, EnglishChars As String 'This procedure is called by the UIRibbon to populate the first Dropdown Box whose ID is "DD1". The input argument Control points to the UIRibbon control object and Control.tag is the value of the tag associated with the control as defined by the XML. We have elected to name the Dropdown boxes DD1, DD2 and DD3 in all ribbons that use dynamic content. This leads to a problem: how do we know to which ribbon the DD1 or DDDropdown etc. refers? We must know this because when any item is changed in any of these Dropdown boxes i.e. by user selection, we need to update the corresponding Dropdowns in the same ribbon. We do this by assigning a Tag to the Dropdowns in the XML code underlying the ribbon and setting the value of the Tag according to the name of the ribbon. E.g. Dropdown id="DD1" tag="EngLetter" If Documents.Count = 0 Then Exit Sub DocumentSaved = ActiveDocument.Saved EnglishChars = "abcdefghijklmnopqrstuvwxyz" 'Initialize Style Array for current Ribbon. The boilerplate ribbon uses the same style arrays as 'EngLetter and HebLetter depending on language. So rather than repeat identical code for the boilerplate styles we set the appropriate arrays based on Select Case Tag where Tag is Control.Tag for all ribbons except boilerplate where it is set to EngLetter and HebLetter depending on language. If control.Tag = "BPlate" Then If LangType = JJTEnglish Then Tag = "EngLetter" Else Tag = "HebLetter" End If Else Tag = control.Tag End If Select Case Tag Case "EngLetter" ReDim EngLetterStyleList(1, 0) LangType = JJTEnglish Case "HebLetter" ReDim HebLetterStyleList(1, 0) LangType = JJTHebrew End Select 'The following code gets the code of the attorney responsible for this file and stores it as a document variable "BPlate". This is done as follows: 'iAttny is an input argument equal to the listindex of the Dropdown containing StaffNames. By default it is set externally to the user associated with the current file. If iAttny > 0, this means that a user was selected manually from the Dropdown and we select the boilerplate template accordingly. If iAttny = 0 then either there is no default user associated with the current file or the typist manually set the user to the first entry (header) of the Dropdown box. Since we cannot be sure which of these is the case, we first try to see if there is a user associated with the file and, if so, we set the boilerplate template accordingly. If not, we set it to the default boilerplate ‘Dropdowns DD1, DD2 and DD3 are used in the letterhead ribbon and also in the boilerplate Ribbon but the value of Control.Tag is different for the English and Hebrew letterheads and for the boilerplate ribbons, which allows us to distinguish between the Dropdowns of the three ribbons. For the boilerplate, the index of DD1 (Staff name) is assigned to iSourceAttny. This is distinguished from the index of DD1 for the letterhead ribbons, which is the value of iAttny Select Case control.id Case "DD1" If control.Tag = "BPlate" Then iSourceAttny = iAttny 'Sets iSourceAttny to selected index of DD1. At the end of this procedure we invalidate DD4, which populates DD4 according to the index of DD If iAttny > 0 Then 'An attorney was selected either manually or by default GetAttorneys Attorney.identifier = ListAttorneys(iAttny).identifier Else 'See if an attorney is defined via document variable BPlate iBPlate = GetDocVariable("BPlate") If iBPlate <> vbNullString Then iAttny = iBPlate 'If even now iAttny = 0, this means that the file does not have the document variable "BPlate" or that it is set to 0. So we now try to find whether there is a default attorney for this File. In fact there should always be a default attorney, but iAttny will also be 0 if the user did not manually select an attorney from the Dropdown box If iAttny = 0 Then File_Code = GetDocVariable("File_Code") If File_Code <> vbNullString Then GetFileAttorney (File_Code) iAttny = Attorney.Code End If End If End If 'If iAttny is still 0, this means that no file user was set in the database. In this case, set it to default ID so that default boilerplate is used: If iAttny = 0 Then iAttny = Attorney.identifier = "EB" Identifier of default user’s boilerplate End If 'Store current value of iAttny to save repeating this loop in future when the document is opened. ActiveDocument.Variables("BPlate").Value = iAttny 'Store in active document 'Adding a document variable sets ActiveDocument.Saved to False. We set it to True so that if we close the active document without further editing, we will not be prompted to save file ActiveDocument.Saved = DocumentSaved Case "DD4" 'We want to set iTargetAttny to the index in ListAttorneys() corresponding to the selected item in DD4. Unlike DD1 where iSourceAttny is the index of the selected item, this is not the case for DD4 because all attorneys are displayed in DD1 while DD4 displays all the attorneys apart from the one selected in DD4. iAttny is the index of the selected target attorney. If this is less than the index of the selected source attorney in DD1, then iTargetAttny will be the index of DD4. But if iAttny ≥ iSourceAttny corresponding to the index of the selected source attorney in DD1, then because the item corresponding to iSourceAttny does not appear in DD4, iTargetAttny will be 1+ the index of DD If iAttny < iSourceAttny Then iTargetAttny = iAttny Else iTargetAttny = iAttny + End If End Select 'The following sets the boilerplate according to the Control Tag set in the ribbon XML Select Case Tag Case "EngLetter", "EngDN", "OAT" BPName = "boilerplate-Eng-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesStandard Letters" Case "HebLetter", "HebDN" BPName = "boilerplate-Heb-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesîëúáéí" Case Else If Application.Keyboard = 1037 Then LangType = JJTHebrew BPName = "boilerplate-Heb-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesםיבתכמ" Else LangType = JJTEnglish BPName = "boilerplate-Eng-" & Attorney.identifier & ".dotx" Path = "C:program filesmicrosoft officeTemplatesStandard Letters" End If End Select 'Now that we know the attorney, we define the name of the Boilerplate template. If there is no Boilerplate template for the selected attorney, use default template If Dir(Path & BPName) = vbNullString Then Select Case Tag Case "EngLetter", "EngDN", "OAT" BPName = "boilerplate-Eng-JJT.dotx" Case Else BPName = "boilerplate-Heb-JJT.dotx" End Select End If Select Case control.id Case "DD1" SourceBPFile = Path & BPName Case "DD4" TargetBPFile = Path & BPName If Dir(TargetBPFile) = vbNullString Then TargetBPFile = SourceBPFile End Select If Dir(Path & BPName) = vbNullString Then Exit Sub 'If boilerplate is not found, exit 'We now add the Boilerplate template since until it is added it cannot be included in the 'collection of active templates in oTmp and then we set the new entry in oTmp() to the 'newly added Boilerplate template If ActiveDocument.ProtectionType <> wdNoProtection Then ActiveDocument.Unprotect AddIns.Add Path & BPName Set oTmp = Templates(Path & BPName) Once oTmp is set to the boilerplate we can then access all the AutoText entries in the boilerplate for populating the Dropdown. In this way we have the flexibility of accessing a different library of AutoText options depending on which Boilerplate template we use, while allowing us to develop the code which manages the Dropdown in the calling template. So we can set up different boilerplates for different users and the appropriate text will be embedded without the need for a customized document template 'StyleList() and AutoTextList() are both two-column arrays starting at index=1 so as to permit binary sorting into alphabetical order. The first column of each row StyleList(0, i) is always the display name and is language-dependent. The second column of each row StyleList(1, i) or AutoTextList(1,i) is always the actual name of the Style or Autotext For Each oAT In oTmp.AutoTextEntries Select Case Tag Case "EngLetter" StyleFound = False For i = 0 To UBound(EngLetterStyleList, 2) If EngLetterStyleList(1, i) = oAT.StyleName Then StyleFound = True Exit For End If Next i Case "HebLetter" StyleFound = False For i = 0 To UBound(HebLetterStyleList, 2) If HebLetterStyleList(1, i) = oAT.StyleName Then StyleFound = True Exit For End If Next i End Select 'If the style is not already in the list of unique styles we add it to the Dropdown. However, we can exclude Styles that are in the Autotext template e.g. "boilerplate-Eng-EB.dotx" but that do not belong to the active document If Not StyleFound Then Select Case Tag Case "EngLetter", "HebLetter" Select Case oAT.StyleName Case "Debit Note", "ןובשח" 'For the boilerplate ribbon, we want to display also Debit Note styles. But these are omitted from the ribbon for letters If control.Tag <> "BPlate" Then StyleFound = True 'Ensures DN styles are not displayed End Select Case Else Select Case oAT.StyleName Case "Debit Note", "ןובשח" StyleFound = True 'Ensures DN styles are not displayed End Select End Select End If 'The above loop may reset the value of the Boolean variable StyleFound from TRUE to FALSE. 'If it is now FALSE we invoke the following loop: If Not StyleFound Then Select Case Tag Case "EngLetter" i = UBound(EngLetterStyleList, 2) + ReDim Preserve EngLetterStyleList(1, i) FirstChar = LCase(Left(oAT.StyleName, 1)) If InStr(1, EnglishChars, FirstChar) > 0 Then 'Stylename is English If Hebrewmode Then 'We always display index EngLetterStyleList(0, i) = GetAlternateLabel(oAT.StyleName) EngLetterStyleList(1, i) = oAT.StyleName Else EngLetterStyleList(0, i) = oAT.StyleName EngLetterStyleList(1, i) = oAT.StyleName End If Else If Hebrewmode Then 'We always display index EngLetterStyleList(0, i) = oAT.StyleName EngLetterStyleList(1, i) = oAT.StyleName Else EngLetterStyleList(0, i) = GetAlternateLabel(oAT.StyleName) EngLetterStyleList(1, i) = oAT.StyleName End If End If Case "HebLetter" i = UBound(HebLetterStyleList, 2) + ReDim Preserve HebLetterStyleList(1, i) FirstChar = LCase(Left(oAT.StyleName, 1)) ‘Code excised – uses similar code as for EngLetter but with array HebLetterStyleList() End Select End If 'If Not StyleFound Next 'The order in which Autotext entries are inserted into the array StyleList() is not alphabetic. 'So we sort into alphabetical order. If there is only one style, display this by default Select Case control.Tag Case "EngLetter" BinarySort EngLetterStyleList() If UBound(EngLetterStyleList, 2) = 1 Then SelectedStyle = EngLetterStyleList(1, 1) Case "HebLetter" BinarySort HebLetterStyleList() If UBound(HebLetterStyleList, 2) = 1 Then SelectedStyle = HebLetterStyleList(1, 1) End Select On Error GoTo Reload_UIRibbon 'We define different ribbon objects for Hebrew and English letters. These are defined in the 'OnLoad procedure for the corresponding templates. We now invalidate the Dropdown boxes in the respective template, which populates the Dropdown boxes Select Case control.Tag Case "EngLetter" EngletterRibbon.InvalidateControl ("DD2") EngletterRibbon.InvalidateControl ("DD3") Case "HebLetter" HebletterRibbon.InvalidateControl ("DD2") HebletterRibbon.InvalidateControl ("DD3") Case "BPlate" If control.id = "DD1" Then BPRibbon.InvalidateControl ("DD2") BPRibbon.InvalidateControl ("DD3") BPRibbon.InvalidateControl ("DD4") Else BPRibbon.InvalidateControl ("DD5") BPRibbon.InvalidateControl ("DD6") End If End Select Exit Sub Reload_UIRibbon: Reload_UIRibbon control.Tag Exit Sub DefineListAttorneys: GetAttorneys Resume Next End Sub Table XIX: Partial VBA code for GetStyles Sub GetStyles(ByVal control As IRibbonControl, selectedID As String, Index As Integer) 'UI Ribbon callback for Dropdowns DD2 in the letterhead and DD2, DD5 in the boilerplate 'The input argument index is the index of the selected Style in DD2 or DD4. SelectedStyle is a global variable that is set to the label of the selected style and is then used by GetAutotextEntries to populate Dropdowns DD3 and DD6. On Error GoTo Reload_UIRibbon Select Case control.Tag Case "EngLetter" SelectedStyle = EngLetterStyleList(1, Index) Case "HebLetter" SelectedStyle = HebLetterStyleList(1, Index) Case "BPlate" If control.id = "DD2" Then If LangType = JJTEnglish Then SourceBPStyle = EngLetterStyleList(1, Index) Else SourceBPStyle = HebLetterStyleList(1, Index) End If SelectedStyle = SourceBPStyle Else If LangType = JJTEnglish Then TargetBPStyle = EngLetterStyleList(1, Index) Else TargetBPStyle = HebLetterStyleList(1, Index) End If SelectedStyle = TargetBPStyle End If End Select UIRibbon_Style = vbNullString 'Reset labels of Dropdown boxes DD3 and DD6 containing the autotexts for the selected Style Select Case control.Tag Case "EngLetter" EngletterRibbon.InvalidateControl ("DD3") Case "HebLetter" HebletterRibbon.InvalidateControl ("DD3") Case "BPlate" If control.id = "DD2" Then BPRibbon.InvalidateControl ("DD3") Else BPRibbon.InvalidateControl ("DD6") End If End Select 'Save index of selected Style to ActiveDocument to facilitate auto-restore in event of fatal loss If control.Tag <> "BPlate" And Index > 0 And control.id = "DD2" Then AddDocVariable "DD2_index", Str(Index) Exit Sub Reload_UIRibbon: Reload_UIRibbon control.Tag Exit Sub End Sub Table XX: Partial VBA code for GetAutotextEntries Sub GetAutotextEntries(ByVal control As IRibbonControl, selectedID As String, Index As Integer) Dim SavePath, filename, SaveFileName, OADate, InstrByDate, ResponseDate As String Dim BPName, Path, AttorneyID, MyAddress, Attention, Tag, ClientID As String Dim EarliestPubDate, HKDeadline, PayDate As Date Dim Response, i, iDuration, iLast, Duration, iAttny, iContact As Integer Dim Cost As Single Dim MyRange As Range, aCC, bCC As ContentControl Dim CodeTemplate As Template Dim oAT As AutoTextEntry Dim ReportOA, InvoiceeFound As Boolean If Index = 0 Then Exit Sub Tag = control.Tag If Tag = "BPlate" Then If ActiveDocument.content.Characters.Count > 1 Then With Selection .WholeStory .EndKey Extend:=wdExtend .Delete 'Delete selection End With End If If LangType = JJTEnglish Then Tag = "EngLetter" Else Tag = "HebLetter" End If End If 'Insert selected autotext entry On Error GoTo ErrorHandler If VariableExists("BPLate", ActiveDocument) Then iAttny = ActiveDocument.Variables("BPlate").Value If iAttny = 0 Then AttorneyID = "EB" 'Default boilerplate Else If IsNull(File_Code) Then AttorneyID = "EB" ElseIf File_Code = vbNullString Then AttorneyID = "EB" Else GetFileAttorney File_Code AttorneyID = Attorney.identifier End If End If Select Case Tag 'Tag is part of the XML ribbon definition Case "EngLetter" LangType = JJTEnglish BPName = "BoilerPlate-Eng-" & AttorneyID & ".dotx" Path = "C:program filesmicrosoft officeTemplatesStandard Letters" If Dir(Path & BPName) = vbNullString Then BPName = "BoilerPlate-Eng-EB.dotx" Set oTmp = Templates(Path & BPName) For Each oAT In oTmp.AutoTextEntries If oAT.Name = EngletterAutoTextList(1, Index) Then BPAutotextName = EngletterAutoTextList(1, Index) oAT.Insert Selection.Range, RichText:=True Exit For End If Next Case "HebLetter" LangType = JJTHebrew BPName = "BoilerPlate-Heb-" & AttorneyID & ".dotx" Path = "C:program filesmicrosoft officeTemplatesםיבתכמ" If Dir(Path & BPName) = vbNullString Then BPName = "BoilerPlate-Heb-EB.dotx" Set oTmp = Templates(Path & BPName) For Each oAT In oTmp.AutoTextEntries If oAT.Name = HebletterAutoTextList(1, Index) Then BPAutotextName = HebletterAutoTextList(1, Index) oAT.Insert Selection.Range, RichText:=True Exit For End If Next End Select 'Execute smart code Select Case control.Tag Case "BPlate" Exit Sub Case "EngLetter" Select Case EngletterAutoTextList(1, Index) 'Here we call procedures for augmenting placeholders in English autotexts. The following code relates to the example shown in Fig. 14c, where GetPCTInfo extracts the PCT application no. from the database for the active document based on its file code and inserts into the content control whose tag is IPRP. Case "IPRP Unfavorable" GetPCTInfo End Select 'Case EngletterAutoTextList(1, index) Case "HebLetter" Select Case HebletterAutoTextList(1, Index) 'Here we call procedures for augmenting placeholders in Hebrew autotexts End Select 'Case HebletterAutoTextList(1, index) End Select 'Case Control.tag 'The following loop enters data into commonly used Content Controls that may be embedded as part of Autotexts. We have deleted most cases and will elaborate on the Case corresponding to the content control tag in Fig. 13 whose Tag is "DueDate". We call a procedure that computes the due date based on an open docketing event and we then insert it into the content control For Each acc In ActiveDocument.ContentControls Select Case acc.Tag Case "DueDate" DueDate = GetDueDate(File_Code) If LangType = JJTEnglish Then acc.Range.Text = format(DueDate, "mmmm d, yyyy") Else acc.Range.Text = format(DueDate, "d.m.yyyy") End If End Select Next 'The following loop forces the cursor to remain inside a Content Control whose Tag is "Select" 'Typically this is used to prompt the user to enter specific data such as a date. For Each acc In ActiveDocument.ContentControls If acc.Tag = "Select" Then acc.Range.Select Exit For End If Next Exit Sub ErrorHandler: Exit Sub NoClient: 'If data is missing, we extract document variables and use these to access the database using ODBC to re-create missing arrays. We then resume to the statement following the error. If document variables have been added to the active document corresponding to the selected index in the Styles array, we can default to this index in DD2 and re-populate DD Resume Next End Sub Table XXI: Partial VBA code for GetSelectedItemIndex 'Callback Dropdown GetSelectedIndex Public Sub GetSelectedItemIndex(ByVal control As IRibbonControl, ByRef Index) Dim i, iAttny As Integer Dim oAT As AutoTextEntry Dim POEventDate, POResponseDate, Tag As String Dim EventFound, PostGrant As Boolean 'This procedure is used to set the default index of a Dropdown box. Generally, it used to ensure the first item in the Dropdown is selected when the control is displayed. This may simply say "Select Attorney" and the like. But we set the default index more intelligently by trying to predict the value that is most likely to be required. If Documents.Count = 0 Then Exit Sub On Error GoTo Quit Select Case control.id 'This is called by the first Dropdown containing staff names whenever the ribbon is first activated or reloaded using ribbon invalidate. If the ribbon is reloaded after a fatal error that loses all global variables, we can nevertheless restore the previously selected index of DDfrom the document variables File_Code or BPLate which can be extracted from the active document and used to define the index. If we don't do this, index defaults to zero which displays the label "Select Attorney".
'Furthermore, once the index for DD1 is set to any value other than zero, the callback 'GetStaffNames is called and sets the Styles in DD2. 'In GetStyles. we store the index of the selected style as a document variable in order to restore to the previously selected Style in the event of fatal loss. Case "DD1" If control.Tag = "BPlate" Then Index = iSourceAttny Else If IsNull(File_Code) Then File_Code = GetDocVariable("File_Code") If File_Code = vbNullString Then File_Code = GetDocVariable("File_Code") If File_Code <> vbNullString Then GetFileAttorney File_Code iAttny = Attorney.Code End If If VariableExists("BPLate", ActiveDocument) Then _ iAttny = ActiveDocument.Variables("BPlate").Value If iAttny <= UBound(ListAttorneys) Then Index = iAttny 'This is true if ListAttorneys(i).code =i: see GetAttorneys() Else Index = End If If Index > 0 Then GetStaffNames control, control.id, iAttny End If Case "DD2", "DD5" 'DD2 contains a list of styles that determine which Autotext entries are displayed. The selected Style thus corresponds to a specific letter type e.g. Allowance, Office Action and so on. We try to determine to which Style to default according to the latest PO docketing Event. Not all standard letters have docketing events, so we first determine whether there are PO events for the current File_Code and if so whether the most recent PO Event corresponds to a Ribbon style. If so, we display that Style as the default; otherwise we display the first Style in the listbox 'Procedure GetStyles() adds a Document Variable called "DD2_index" to the active document. 'The following code sets index to the value of this document variable if it exists so as to display the previously selected Style by default when either the ribbon is reloaded or when a saved document is opened 'Note that this sets the default of DD5 to the current setting of DD2, which means that by default the target Style for the boilerplate is the same as the source 'The following line initializes SelectedStyle = vbNullString so that by default DD3 is empty unless a Style in DD2 is selected SelectedStyle = vbNullString If control.Tag <> "BPlate" Then i = GetDocVariable("DD2_index") If i <> vbNullString Then Index = Val(i) Exit Sub End If 'The following code is used to guess the identity of the Style that is most likely to be the one required according to the most recent event and whether a response has been filed. 'GetPOEventDate gets the date of the most recent Patent Office event e.g. S18, OA, NOA etc. 'GetPOResponseDate gets the date when the last PO event was closed. If this is equal to or later than the latest PO event, then we know that a response was filed to the event. But if it's earlier than the most recent PO event, we know that it relates to an earlier event and the most recent PO event is therefore still open.
'On this basis, we can assert that: ' 1.If there's an open PO event and we are writing an English letter, we are reporting the event to the client ' 2.If there's an open PO event and we are writing a Hebrew letter, we are either reporting the event to an Israeli client or we are responding to the Israel Patent Office. But in most cases, there need be no ambiguity because we can tell if the event has been reported, the only exception being when we respond to the Examiner without having first reported to the client. ' 3.If the PO event is closed and we are writing an English letter, we are reporting our response to the client ' 4.If the PO event is closed and we are writing a Hebrew letter, we are probably reporting our response to a local client although we could be filing a supplementary response ' 5.If the patent is granted, we are probably reporting a renewal payment to the client. 'So we have two possibilities for each language and we accommodate these using two flags in 'Table UIRibbon_Legends: one for language and one that establishes if we are reporting the 'event or responding to the Patent Office i.e. Open/Closed PostGrant = False If IsDate(RegDate) Then If (DateDiff("d", RegDate, Date) > 300) Then PostGrant = True End If If Not PostGrant Then POEventDate = GetPOEventDate(File_Code) POResponseDate = GetPOResponseDate(File_Code) EventFound = False If IsDate(POEventDate) Then If Not IsDate(POResponseDate) Then EventFound = True ElseIf DateValue(POResponseDate) < DateValue(POEventDate) Then EventFound = True ElseIf (DateDiff("d", Date, POEventDate) < 30) Then EventFound = True End If If Not EventFound And IsDate(POResponseDate) Then _ If (DateDiff("d", Date, POResponseDate) < 30) Then EventFound = True End If End If End If 'End If control.Tag <> "BPlate" On Error GoTo Quit 'The boilerplate ribbon uses the same autotext arrays as EngLetter and HebLetter depending on language. Rather than repeat identical code for populating the autotext Dropdowns DDand DD6 we set the appropriate arrays based on Control.Tag for all ribbons except boilerplate and for boilerplate to EngLetter and HebLetter depending on language. If control.Tag = "BPlate" Then If LangType = JJTEnglish Then Tag = "EngLetter" Else Tag = "HebLetter" End If Else Tag = control.Tag End If Select Case Tag Case "EngLetter" If UBound(EngLetterStyleList, 2) = 1 Then 'Only one style in list, show as default SelectedStyle = EngLetterStyleList(1, 1) Index = ElseIf control.Tag = "BPlate" Then Index = ElseIf PostGrant Or EventFound Then 'Default to matching PO docketing event 'GetUIRibbon_Legend gets UR Ribbon English Label that corresponds to most recent PO Event from Tables [Events]. StyleList() is a 2-column array that for each Style stores in StyleList(0, i) the display Stylename and in StyleList(1, i) stores the actual Stylename which is compared with UIRibbon_Style If PostGrant Then UIRibbon_Style = "Renewal" Else UIRibbon_Style = GetUIRibbon_Legend(File_Code) End If SelectedStyle = UIRibbon_Style For i = 1 To UBound(EngLetterStyleList, 2) If EngLetterStyleList(1, i) = UIRibbon_Style Then Exit For Next If Not i > UBound(EngLetterStyleList, 2) Then Index = i Else Index = End If Else 'No matching style so show header Index = End If Case "EngDN" 'Code excised for brevity Case Else Index = End Select 'End Case tag Case Else 'Do nothing End Select ' End Select Case control.id Quit: End Sub Table XXII: XML definition for UI Ribbon of Boilerplate Editor sizeString="WWWWWWWWWWW" getItemLabel="UIRibbon_JJTMacros.GetItemLabel" getSelectedItemIndex="UIRibbon_JJTMacros.GetSelectedItemIndex" getLabel="UIRibbon_BoilerPlate.GetLabel" onAction="UIRibbon_JJTMacros.GetStyles" /> Table XXIII: Add Item Button for Boilerplate Editor Sub AddBPItem(Control As IRibbonControl) 'This procedure is called by clicking Add Item on the Boiler Plate ribbon and saves the current window to the currently selected Boilerplate under the current style using the name of an autotext entry entered by the user. It then deletes the current selection. It selects the whole of the active document. The selection constitutes the range for the autotext. 'Note that a nominally empty document has a single Chr(13) that we do not want to append to the autotext: so we move left (back) one character so as to un-select the last Chr(13) 'Note that we must have at least one Chr(13) at the end of the selection because otherwise the Style formatting will not be saved for the last paragraph. If (SourceBPFile = vbNullString) Or (SelectedStyle = vbNullString) Then Exit Sub BPMode = 0 'Changes how UserForm reacts BPAddItem_Frm.Show 'Prompts for entry of new item name and checks it does not already exist If NewItemName = vbNullString Then Exit Sub On Error GoTo With Selection .WholeStory .EndKey Extend:=wdExtend ActiveDocument.CopyStylesFromTemplate SourceBPFile .Style = ActiveDocument.Styles(SelectedStyle) Set oTmp = Templates(SourceBPFile) oTmp.AutoTextEntries.Add NewItemName, .Range If OutlookAddinOn Then RemoveOutlookAddin oTmp.Save 'Save template .Delete 'Delete selection End With BPRibbon.InvalidateControl ("DD3") End Sub Table XXIV: RemoveOutlookAddin Sub RemoveOutlookAddin() Dim lngRetVal As Long, objOutlook As Outlook.Application Dim ObjMail As MailItem, objInsp As Inspector Dim objDoc As Word.Document, objWord As Word.Application, olAddIn As AddIn 'This procedure is called by Boilerplate utilities prior to saving the Boilerplate template, which is opened as an Addin. If the AddIn is already open in Outlook because the Automation Tab in Outlook was opened before opening MS Word, Err.Number = 5995 will occur upon trying to save the BoilerPlate in MS Word. Err.Number = 5995 is a fatal error that can be trapped and corrected but there is no way to avoid the system error message: "Word cannot save this file because it is already open elsewhere". In other words, we can trap Err.Number = 5995 and we can remove AddIns from Outlook in order to avoid this error message being displayed for subsequent attempts to save the AddIn, but the message will occur the first time we try to save a BoilerPlate template that was opened in Outlook before opening Word. This message is not something we want to encounter 'The solution is to close all BoilerPlate templates in Outlook before saving them in Word. Since this requires that we instantiate MS Outlook in Word and this does add some delay, we do this only the first time we save the BoilerPlate template in Word and set the global Boolean flag OutlookAddinOn = False. It is initially set to True when the ribbon is loaded. Calling procedures call RemoveOutlookAddin() only if OutlookAddinOn = True If SourceBPFile = vbNullString Then Exit Sub 'If Outlook is open, get the existing object otherwise create it lngRetVal = FindWindowByClass("rctrl_renwnd32", 0&) 'If Outlook is open, get the existing object otherwise there can be no conflict: so we can exit. But we do not set OutlookAddinOn = False because if subsequently MS Outlook is opened and the Automation Tag was opened, we do need to release any Addins If lngRetVal <> 0 Then Set objOutlook = GetObject(, "Outlook.application") Else Exit Sub End If Set ObjMail = objOutlook.CreateItem(olmailitem) Set objInsp = ObjMail.GetInspector If objInsp.EditorType = olEditorWord Then Set objDoc = objInsp.WordEditor If objDoc Is Nothing Then OutlookAddinOn = False Exit Sub End If Set objWord = objDoc.Application For Each olAddIn In objWord.AddIns 'Remove all Boilerplate Addins from Outlook If InStr(1, olAddIn.Name, "BoilerPlate") > 0 Then olAddIn.Delete Next olAddIn OutlookAddinOn = False End If End Sub Table XXV: Rename Item Button for Boilerplate Editor Sub RenameBPItem(Control As IRibbonControl) Dim i As Integer, NewName As String 'This procedure is called by clicking Rename Item on the Boiler Plate ribbon If (SourceBPFile = vbNullString) Or (BPAutotextName = vbNullString) Then Exit Sub Set oTmp = Templates(SourceBPFile) For i = 1 To oTmp.AutoTextEntries.Count If oTmp.AutoTextEntries(i).Name = BPAutotextName Then BPMode = 1 'Changes how UserForm reacts BPAddItem_Frm.Show 'Prompts for entry of new item name and checks it does not 'already exist If NewItemName = vbNullString Then Exit Sub 'Caused by clicking cancel oTmp.AutoTextEntries(i).Name = NewItemName If OutlookAddinOn Then RemoveOutlookAddin oTmp.Save 'Save template With Selection .WholeStory .EndKey Extend:=wdExtend .Delete 'Delete selection End With Exit For End If Next i BPRibbon.InvalidateControl ("DD3") End Sub Table XXVI: Code for custom UI ribbon in Microsoft Outlook Public Sub GetSymbol(ByVal Control As IRibbonControl) Dim myolapp As Outlook.Application, myInspector As Outlook.Inspector Dim myomail As Outlook.MailItem, objSel As Word.Selection Dim BiDiFontName As String myolapp = CreateObject("Outlook.Application") myInspector = myolapp.ActiveInspector myomail = TryCast(myInspector.CurrentItem, Outlook.MailItem) objDoc = myInspector.WordEditor objSel = objDoc.Windows(1).Selection On Error Resume Next Select Case Control.Id Case "Alpha_uc" objSel.InsertSymbol(Font:="Symbol", CharacterNumber:=-4031, Unicode:=True) Case "Alpha_lc" objSel.InsertSymbol(Font:="Symbol", CharacterNumber:=-3999, Unicode:=True) Table XXVII: XML definition for Automation tab of UI Ribbon of Outlook Addin Table XXVIII: onAction callbacks for custom UI ribbon in Microsoft Outlook Public Sub OnActionCallback(ByVal control As Office.IRibbonControl, ByVal text As String, ByVal index As Integer) 'The input argument "text" is the selected content of the Dropdown box; but it's not being used 'index is the index of the Dropdown box Dim i As Integer, BPName, Path, FirstChar, EnglishChars As String, Start, Last As Long Dim MyStyle As Word.Style, MyRange As Word.Range, StyleFound As Boolean, MyColor, MycolorBi, MyFontSize, MyFontSizeBi As Long, MyLang, MyFont, MyFontBi, MyOAT As String Dim EarliestPubDate, InstrByDate, MyDueDate As Date Dim aCC, bCC As Word.ContentControl Dim MyInstrDate As String Dim format As String = "MMMM d, yyyy" Dim myCurrentLanguage As InputLanguage = InputLanguage.CurrentInputLanguage Dim myolapp As Outlook.Application Dim myInspector As Outlook.Inspector EnglishChars = "abcdefghijklmnopqrstuvwxyz" MyLang = myCurrentLanguage.Culture.ThreeLetterISOLanguageName If MyLang = "eng" Then LangType = JJTEnglish Else LangType = JJTHebrew End If Select Case control.Id Case "CB1", "DD1" myolapp = CreateObject("Outlook.Application") myInspector = myolapp.ActiveInspector If Not myInspector Is Nothing Then objDoc = myInspector.WordEditor If LangType = JJTEnglish Then Path = "C:program filesmicrosoft officeTemplatesStandard Letters" BPName = "BoilerPlate-Eng-JJT.dotx" Else Path = "C:program filesmicrosoft officeTemplatesםיבתכמ" BPName = "BoilerPlate-Heb-JJT.dotx" End If iAttny = index 'Now that we know the attorney, we define the name of the BoilerPlate template If iAttny <= ListAttorneys.Count - 1 Then If LangType = JJTEnglish Then BPName = "BoilerPlate-Eng-" & ListAttorneys(iAttny).Identifier & ".dotx" 'If there is no BoilerPlate template for the selected attorney, use default If Dir(Path & BPName) = "" Then BPName = "BoilerPlate-Eng-EB.dotx" Else BPName = "BoilerPlate-Heb-" & ListAttorneys(iAttny).Identifier & ".dotx" If Dir(Path & BPName) = "" Then BPName = "BoilerPlate-Heb-EB.dotx" End If End If 'If Not myInspector Is Nothing objDoc.Application.AddIns.Add(BPlate) oTmp = objDoc.Application.Templates(BPlate) itemLabels.Clear() For Each oAT In oTmp.AutoTextEntries If Not itemLabels.Contains(oAT.StyleName) Then itemLabels.Add(oAT.StyleName) End If Next 'Lists starts at index (0) so we obtain each entry of itemLabels by reading from '0 to itemLabels.Count- 'On the other hand, EngStyleList and HebStyleList are both 2-d arrays whose row 'index must start at 1 so that we can sort the elements (rows) using BinarySort ReDim EngStyleList(1, itemLabels.Count) ReDim HebStyleList(1, itemLabels.Count) For i = 0 To itemLabels.Count - FirstChar = LCase(Left(itemLabels(i), 1)) If LangType = JJTEnglish Then If InStr(1, EnglishChars, FirstChar) > 0 Then 'Stylename is English If Hebrewmode Then 'We always display index EngStyleList(0, i + 1) = GetAlternateLabel(itemLabels(i)) EngStyleList(1, i + 1) = itemLabels(i) Else EngStyleList(0, i + 1) = itemLabels(i) EngStyleList(1, i + 1) = itemLabels(i) End If Else If Hebrewmode Then 'We always display index EngStyleList(0, i + 1) = itemLabels(i) EngStyleList(1, i + 1) = itemLabels(i) Else EngStyleList(0, i + 1) = GetAlternateLabel(itemLabels(i)) EngStyleList(1, i + 1) = itemLabels(i) End If End If Else 'LangType=JJTHebrew If InStr(1, EnglishChars, FirstChar) > 0 Then 'Stylename is English If Hebrewmode Then 'We always display index HebStyleList(0, i + 1) = GetAlternateLabel(itemLabels(i)) HebStyleList(1, i + 1) = itemLabels(i) Else HebStyleList(0, i + 1) = itemLabels(i) HebStyleList(1, i + 1) = itemLabels(i) End If Else If Hebrewmode Then 'We always display index HebStyleList(0, i + 1) = itemLabels(i) HebStyleList(1, i + 1) = itemLabels(i) Else HebStyleList(0, i + 1) = GetAlternateLabel(itemLabels(i)) HebStyleList(1, i + 1) = itemLabels(i) End If End If End If Next If LangType = JJTEnglish Then BinarySort(EngStyleList) Else BinarySort(HebStyleList) End If Me.ribbon.InvalidateControl("DD2") End If Case "DD2" itemLabels.Clear() Dim myolapp As Outlook.Application Dim myInspector As Outlook.Inspector myolapp = CreateObject("Outlook.Application") myInspector = myolapp.ActiveInspector If Not myInspector Is Nothing Then objDoc = myInspector.WordEditor objDoc.Application.AddIns.Add(BPlate) oTmp = objDoc.Application.Templates(BPlate) For Each oAT In oTmp.AutoTextEntries If ((LangType = JJTEnglish) And (oAT.StyleName = EngStyleList(1, index))) _ Or ((LangType = JJTHebrew) And (oAT.StyleName = HebStyleList(1, index))) Then itemLabels.Add(oAT.Name) End If Next oAT ReDim AutoTextList(1, itemLabels.Count) For i = 0 To itemLabels.Count - FirstChar = LCase(Left(itemLabels(i), 1)) If InStr(1, EnglishChars, FirstChar) > 0 Then 'Autotext is English If Hebrewmode Then 'We always display index AutoTextList(0, i + 1) = GetAlternateLabel(itemLabels(i)) AutoTextList(1, i + 1) = itemLabels(i) Else AutoTextList(0, i + 1) = itemLabels(i) AutoTextList(1, i + 1) = itemLabels(i) End If Else If Hebrewmode Then 'We always display index AutoTextList(0, i + 1) = itemLabels(i) AutoTextList(1, i + 1) = itemLabels(i) Else AutoTextList(0, i + 1) = GetAlternateLabel(itemLabels(i)) AutoTextList(1, i + 1) = itemLabels(i) End If End If Next i BinarySort(AutoTextList) If LangType = JJTEnglish Then SelectedStyle = EngStyleList(1, index) Else SelectedStyle = HebStyleList(1, index) End If Me.ribbon.InvalidateControl("DD3") End If Case "DD4" iSignature = index If SignatureLanguage = Nothing Then If LangType = JJTHebrew Then SignatureLanguage = "Hebrew" Else SignatureLanguage = "English_US" End If End If ReplaceSignature(SignatureLanguage, iSignature, ChangeSignature:=True) Case "DD3" Dim myolapp As Outlook.Application Dim myInspector As Outlook.Inspector Dim objSel As Word.Selection myolapp = CreateObject("Outlook.Application") myInspector = myolapp.ActiveInspector If Not myInspector Is Nothing Then objDoc = myInspector.WordEditor objDoc.Application.AddIns.Add(BPlate) oTmp = objDoc.Application.Templates(BPlate) objSel = objDoc.Windows(1).Selection 'The input argument Text corresponds to the label in the current combobox. This is the display 'value of the Autotext but it may not necessarily be the name of the current Autotext entry, 'which may have been translated. In all cases, AutoTextList(0, i) is the display name of the 'i-th Autotext and AutoTextList(1, i) is the actual name of the current Autotext entry MyOAT = vbNullString For Each oAT In oTmp.AutoTextEntries If oAT.StyleName = SelectedStyle Then MyOAT = AutoTextList(1, index) If oAT.Name = MyOAT Then Start = objSel.Range.Start oAT.Insert(objSel.Range, RichText:=True) End If End If Next 'The following loop enters data into Content Controls that may be embedded as part of Autotexts For Each aCC In objDoc.ContentControls Select Case aCC.Tag Case "OADate" If File_code <> vbNullString Then OADate = GetPOEventDate(File_code) aCC.Range.Text = OADate.ToString(format) End If Case "ResponseDate" ‘We can include custom code for populating different control controls End Select Next 'The Boiler plate styles are formatted for Word documents that may not (and usually do not) have the same style as email. So we need to change the attributes of the boiler plate text to match the body of the e-mail. One way to achieve this is to create a new Style called EMailID which has all the font and paragraph attributes that we want in the body of our e-mail. Each user can set this as he or she wishes. To allow for the possibility that a user may not have created this style, we check whether it exists and if not, we apply the formatting discretely Last = objSel.Range.End MyRange = objDoc.Range(Start, Last) StyleFound = False For Each MyStyle In objDoc.Styles If LangType = JJTEnglish Then If MyStyle.NameLocal = "EMailEng" Then StyleFound = True Exit For End If Else If MyStyle.NameLocal = "EMailHeb" Then StyleFound = True Exit For End If End If Next If StyleFound Then If LangType = JJTEnglish Then MyRange.Style = objDoc.Styles("EMailEng") Else MyRange.Style = objDoc.Styles("EMailHeb") End If Else MyColor = objSel.Font.ColorIndex MycolorBi = objSel.Font.ColorIndexBi MyFont = objSel.Font.Name MyFontBi = objSel.Font.NameBi MyFontSize = objSel.Font.Size MyFontSizeBi = objSel.Font.SizeBi MyRange.Font.ColorIndex = MyColor MyRange.Font.ColorIndexBi = MycolorBi MyRange.Font.Name = MyFont MyRange.Font.NameBi = MyFontBi MyRange.Font.Size = MyFontSize MyRange.Font.SizeBi = MyFontSize End If End If ' If Not myInspector Is Nothing End Select ' Select Case control.Id End Sub

Claims (34)

- 69 - 291371/ CLAIMS:
1. A computer-implemented method for facilitating organized document creation, said method comprising: (a) creating text segments using a word-processor; (b) assigning to each of said text segments a respective name identifying the text segment and a category having a name indicative of a subject associated with the corresponding text segment; (c) storing the text segments in a boilerplate template with their respective names and categories and any formatting attributes applied to the text segments; (d) saving the boilerplate template; (e) creating and displaying an active document using said word-processor or a word-processor compatible therewith on a computer having access to the boilerplate template; (f) prior to or during subsequent processing of the active document using an application that uses the word-processor, calling a first pre-programmed procedure in an add-in that is independent of the boilerplate template to read the boilerplate template and populate a first menu in a graphical user interface of the application with each unique category name for selection by a user; (g) upon selection by the user of a selected category displayed in the first menu, calling a second pre-programmed procedure in the add-in to dynamically populate a second menu in the graphical user interface with the respective names of all text segments in the boilerplate template corresponding to the selected category for selection by the user; and (h) upon selection by the user of a selected name from the second menu, calling a third pre-programmed procedure in the add-in to insert into the active document the text segment corresponding to the selected name.
2. A computer-implemented method for facilitating organized document creation, the method comprising: (a) creating with a word-processor text segments at least one of which has a programmable placeholder and a predefined category indicative of a subject associated with the text segment; - 70 - 291371/ (b) storing the text segments in a boilerplate template with their respective names and categories and any formatting attributes applied to the text segments; (c) saving the boilerplate template; (d) creating and displaying an active document related to said subject using said word-processor or a word-processor compatible therewith on a computer having access to the boilerplate template; (e) prior to or during subsequent processing of the active document, calling a first pre-programmed procedure in an add-in that is independent of the boilerplate template to read the boilerplate template and populate a menu in a graphical user interface of the application with the respective names of all text segments in the boilerplate template corresponding to said predefined category for selection by the user; and (f) upon selection by the user from the menu of a selected name corresponding to one of the text segments having a programmable placeholder, calling a second pre-programmed procedure in the add-in to insert into the active document the text segment corresponding to the selected name together with auxiliary text that is not part of the text segment.
3. The method according to claim 1, wherein the text segment includes a program-mable placeholder into which the third pre-programmed procedure automatically inserts auxiliary text that is not part of the text segment.
4. The method according to claim 3, wherein the programmable placeholder is a content control or bookmark or field.
5. The method according to any one of claims 2 to 4, wherein the auxiliary text is based on data in a computerized database.
6. The method according to claim 5, wherein the computerized database is a docketing system and the data is a docketing event.
7. The method according to any one of claims 1 to 6, wherein the graphical user interface is a ribbon displayed at the top of an application window.
8. The method according to any one of claims 1 to 6, wherein the graphical user interface is a floating command bar displayed in an application window. - 71 - 291371/
9. The method according to claim 7 or 8, wherein the ribbon or command bar is associated with a document template that is associated with or accessed by the active document.
10. The method according to claim 9, including: (g) populating a third menu in the graphical user interface with names of different document templates each having an associated ribbon or command bar; and (h) upon selection of a document template from the third menu: i) associating a boilerplate template with the selected document template; ii) displaying the ribbon or command bar belonging to the associated boilerplate template; and iii) populating the first menu of said ribbon or command bar with the category names encoded in the associated boilerplate template.
11. The method according to claim 9 or 10, including: (i) populating a fourth menu in the graphical user interface with names indicative of different boilerplate templates; and (j) upon selection of a name from the fourth menu: i) associating a default boilerplate template with the selected name; ii) displaying the ribbon or command bar belonging to the associated default boilerplate template; and iii) populating the first menu of said ribbon or command bar with the category names encoded in the associated default boilerplate template.
12. The method according to claim 11, wherein the names assigned to the fourth menu are names of users for each of whom there may be a dedicate boilerplate template.
13. The method according to any one of the preceding claims, wherein the word- processor is one of a multi-application suite of programs and the graphical user interface is associated with a different program in said suite that uses the word-processor for text editing.
14. The method according to any one of claims 1 to 13, wherein the add-in is a global template. 30 - 72 - 291371/
15. The method according to any one of claims 1 to 13, wherein the add-in is a software module such as a DLL or COM file that is injected into the application.
16. The method according to any one of claims 1 to 15, wherein the word-processor is Microsoft Word ™, the text segment is a building block and the category of the text segment corresponds to a category of the building block.
17. The method according to any one of claims 1 to 15, wherein the text segment is an autotext and a formatting style of the text segment corresponds to the subject category.
18. The method according to any one of claims 1 to 17, further including: saving with the active document data indicative of an index of a respective selected item in any one of the menus in the graphical user; retrieving said data when the document is subsequently re-opened; and automatically setting the index of the respective menu to display a previously selected item by default.
19. A computer-program product including a non-transitory computer readable memory storing program code instructions, which when executed on a suitable computer carry out the method according to any one of the preceding claims.
20. A computer-program add-in including a computer readable memory storing program code instructions, which when injected into an application that uses a word-processor to create and display an active document on a computer, are configured to: (a) read a boilerplate template containing text segments and associated categories to determine a respective name identifying each text segment in the boilerplate template associated with a predefined category; (b) populate a menu in a graphical user interface of the application with the respective names of all of the text segments associated with the predefined category; and (c) responsive to selection by the user from the menu of a selected name corres-ponding to one of the text segments having a programmable placeholder, insert into the active document the text segment corresponding to the selected name and to insert at the programmable placeholder auxiliary text that is not part of the text segment. - 73 - 291371/
21. A computer-program add-in including a computer readable memory storing program code instructions, which when injected into an application that uses a word-processor to create and display an active document on a computer, are configured to: (a) read a boilerplate template containing text segments and associated categories to determine a respective category name identifying each unique category; (b) populate a first menu in a graphical user interface of the application with each unique category name; (c) upon selection by the user of a selected category displayed in the first menu, dynamically populate a second menu in the graphical user interface with the respective names of all text segments in the boilerplate template corresponding to the selected category; and (d) upon selection by the user of a selected name from the second menu, calling a third pre-programmed procedure in the add-in to insert into the active document the text segment corresponding to the selected name.
22. The add-in according to claim 21, wherein the text segment includes a program-mable placeholder and the program code instructions are configured to automatically insert auxiliary text that is not part of the text segment at said placeholder.
23. The add-in according to claim 20 or 22, wherein the program code instructions are further configured to extract data from a computerized database and to formulate the auxiliary text based on said data.
24. The add-in according to any one of claims 21 to 23, wherein the word-processor is one of a multi-application suite of programs and the graphical user interface is associated with a different program in said suite that uses the word-processor for text editing.
25. The add-in according to claim 24, wherein: the program is an email program used to create and send email messages, the graphical user interface is a custom ribbon displayed by the email program, and the add-in is configured to insert selected text segments into a body of the email message.
26. The add-in according to claim 25, wherein the UI ribbon has a language selector for allowing the email message to default to a selected language. - 74 - 291371/
27. The add-in according to claim 26, being responsive to a change in language from a source language to a selected target language for replacing a source signature block with a target signature block formulate and formatted according to the target language.
28. The add-in according to claim 21, wherein the program code instructions are responsive to user-actuation of a first selector in the graphical user interface for saving content in the active document in the boilerplate template under the selected name and category.
29. The add-in according to claim 28, wherein the program code instructions are responsive to user-actuation of a second selector in the graphical user interface for prompting entry of a new name and saving content in the active document as a new text segment in the boilerplate template under the category currently selected in the first menu and under the new name provided by the user.
30. The add-in according to claim 28 or 29, wherein the program code instructions are responsive to user-actuation of a third selector in the graphical user interface for copying content in the active document as a new text segment to a selected target boilerplate template.
31. The add-in according to any one of claims 28 to 30, wherein the program code instructions are responsive to user-actuation of a fourth selector in the graphical user interface for deleting a specified text segment from the boilerplate.
32. The add-in according to any one of claims 28 to 31, wherein the program code instructions are responsive to user-actuation of a fifth selector in the graphical user interface for renaming a selected text segment under the category currently selected in the first menu.
33. The add-in according to any one of claims 28 to 32, wherein the program code instructions are responsive to user-actuation of a sixth selector in the graphical user interface for prompting entry of a new category name and saving content in the active document under the new category.
34. The add-in according to any one of claims 28 to 33, wherein: the word-processor is a first program of a multi-application suite of programs, and the program code instructions are responsive to the boilerplate template being locked by a second program in said suite that uses the word-processor for text editing - 75 - 291371/ and which uses a second add-in for accessing the boilerplate template, for removing the second add-in from the second program so as to allow changes to the boilerplate template made using the first program to be saved.
IL291371A 2022-03-14 2022-03-14 Method and Computer Program Product for Organized Document Creation IL291371B2 (en)

Priority Applications (1)

Application Number Priority Date Filing Date Title
IL291371A IL291371B2 (en) 2022-03-14 2022-03-14 Method and Computer Program Product for Organized Document Creation

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
IL291371A IL291371B2 (en) 2022-03-14 2022-03-14 Method and Computer Program Product for Organized Document Creation

Publications (3)

Publication Number Publication Date
IL291371A IL291371A (en) 2023-10-01
IL291371B1 IL291371B1 (en) 2025-06-01
IL291371B2 true IL291371B2 (en) 2025-10-01

Family

ID=88293340

Family Applications (1)

Application Number Title Priority Date Filing Date
IL291371A IL291371B2 (en) 2022-03-14 2022-03-14 Method and Computer Program Product for Organized Document Creation

Country Status (1)

Country Link
IL (1) IL291371B2 (en)

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20120254730A1 (en) * 2011-03-28 2012-10-04 Microsoft Corporation Techniques to create structured document templates using enhanced content controls

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20120254730A1 (en) * 2011-03-28 2012-10-04 Microsoft Corporation Techniques to create structured document templates using enhanced content controls

Also Published As

Publication number Publication date
IL291371B1 (en) 2025-06-01
IL291371A (en) 2023-10-01

Similar Documents

Publication Publication Date Title
US5206951A (en) Integration of data between typed objects by mutual, direct invocation between object managers corresponding to object types
US5261080A (en) Matchmaker for assisting and executing the providing and conversion of data between objects in a data processing system storing data in typed objects having different data formats
US5369778A (en) Data processor that customizes program behavior by using a resource retrieval capability
US5226161A (en) Integration of data between typed data structures by mutual direct invocation between data managers corresponding to data types
US8689137B2 (en) Command user interface for displaying selectable functionality controls in a database application
KR101031700B1 (en) Programming interface to computer platform
EP0304071B1 (en) Data integration by object management
WO2003038607A1 (en) Structures and methods for managing software and documentation
US5542086A (en) Document type metamorphosis in an object-oriented operating system having a graphical user interface
Lomax VB & VBA in a nutshell: The language
US20080005752A1 (en) Methods, systems, and computer program products for generating application processes by linking applications
Raines et al. TCL/TK in a nutshell: a desktop quick reference
Neumann et al. Wafe-An X Toolkit Based Frontend for Application Programs in Various Programming Languages.
EP0304072B1 (en) Customization by automated resource substitution
JP2001318791A (en) Method and system for changing text file for computer. configuration
IL291371B2 (en) Method and Computer Program Product for Organized Document Creation
Christ The xkwic user manual
Shalfield et al. WIN-PROLOG 8.1
Munro Introduction to Scripting
Gamma et al. ET++ 2.2-Introduction and Installation
Skibo et al. Working with Microsoft visual studio 2005
MacDonald The Book of Visual Basic 2005: NET Insight for Classic VB Developers
File Moving Your Application to BridgeVIEW 2.0
Beaudouin-Lafon et al. Iconic shells for multitasking workstations
Shalfield et al. Logic Programming Associates Ltd. Studio 30 The Royal Victoria Patriotic Building Trinity Road London SW18 3SX