IBM Lotus QuickPlace is a great way for teams to collaborate on a project. Out of the box, QuickPlace provides some basic revision controls, such as check out, check in, and the ability to create a new revision. What it doesnât provide is a way to keep track of previous edits a document may have gone through. By integrating QuickPlace with IBM Lotus Domino Document Manager, we can use Domino Document Managerâs revision controls to keep a revision history of a QuickPlace document.
Overview of QuickPlace and Domino Document Manager integration
Our QuickPlace/Domino Document Manager integration is performed by hooking into QuickPlace events (such as creating and editing a document), and by using the Domino Document Manager API. This allows us to store the QuickPlace document in Domino Document Manager, or check out the document in Domino Document Manager, in real time. The Domino Document Manager API will be used to create a corresponding document in Domino Document Manager, to create a new version of a document, and to check out or check in an existing document in Domino Document Manager.
The integration also requires a new QuickPlace theme, and a new document type in Domino Document Manager. Using a modified QuickPlace theme allows us to alter the look and behavior of the QuickPlace. The modified theme hides some QuickPlace actions, and writes a link to the document stored in Domino Document Manager. The new document type is required to store pertinent information about the QuickPlace document.
We use one Domino Document Manager file cabinet to store all the content of one place in QuickPlace. Each folder in the place will have a corresponding binder created in the Domino Document Manager file cabinet. A document created in QuickPlace will result in a document being created in Domino Document Manager. The contents of the QuickPlace page will be copied from QuickPlace to the Domino Document Manager document, meaning it will exist in both places. When a QuickPlace page gets edited, the document in Domino Document Manager will be checked out. When a user publishes changes to a QuickPlace page, a new version is created in Domino Document Manager. A user can click on the link to the document in Domino Document Manager at any time, and view the revision history through the Domino Document Manager UI. From the revision history, the actual contents of the QuickPlace page can be seen. See Figure 1 for a diagram of this process.
Figure 1. QuickPlace/Domino Document Manager integration

Before beginning the QuickPlace and Domino Document Manager integration, do the following:
- Install the Domino Document Manager client on the QuickPlace server. This is necessary to work with the Domino Document Manager API. If you will be customizing the code, you must also install the Domino Document Manager client on your development machine.
- Download the QuickPlace development kit from the Sandbox.
- Download the Notes C API toolkit from the developerWorks download page. Follow the instructions in the userâs guide to configure a development environment.
- Download the zip file that contains files used for this sample from the Downloads section at the end of this article. The files provided are the C++ files that make up the QuickPlace hook, a compiled hook file, an HTML file used for the QuickPlace theme, and a Notes database file that contains the new Domino Document Manager document type. Microsoft Visual C++ 6 was used to develop the code, and is required if the code will be customized. Newer versions may work, but I haven't tested them. To implement this example, you should be familiar with C/C++, HTML, JavaScript, and Domino Designer. The majority of the code is in C++, so understanding that language is necessary.
While developing this code, I had Domino 6.5.1, QuickPlace 6.5.1 and Domino Document Manager 6.5.1 installed on my development machine. This helped greatly, because I could step into the code and debug it. If you plan to customize the code, Iâd recommend developing in this type of environment -- it will make things easier. (Debugging will be discussed later in this article.)
The hook is the heart of this integration example. Itâs where the real time integration takes place. This section describes how to set up a project in Visual C++, import the source code, and compile it. A compiled hook is provided in the zip file that accompanies this article. If you decide to use this, you should still read the section later in this article that describes the code. You should be familiar with how it works so you know what to expect.
Create a new Visual C++ project
The first step is to create a new project in Visual C++:
- In Visual C++, select File - New.
- Select the Projects tab, and choose MFC AppWizard (dll). You need to use this type of project so you can call into the Domino Document Manager API.
- Enter a project name and a location, and click OK. Using âQPDDâ as the project name will make things easier as we progress further.
- The MFC AppWizard dialog should be displayed. Select âRegular DLL using shared MFC DLLâ in response to the prompt âWhat type of DLL would you like to create?â Do not select anything in response to the question âWhat features would you like in your DLL?â Either Yes or No can be selected in response to the prompt âWould you like to generate source file comments?â
- Click Finish, then click OK.
Now that we have our project created, we need to add classes that will call into the Domino Document Manager API. The following steps will accomplish this.
- Select View - ClassWizard.
- Click the Add Class button, and select âFrom a type library.â
- Browse to the directory where the Domino Document Manager client is installed (typically c:\lotus\dominodoc), and select the DDOC2API.TLB file.
- Select all the classes listed, starting with IApi and ending with ICategories.
- Click OK, and then click OK again.
You should now have a DDOC2API.CPP and a DDOC2API.H file in your project.
The next step is to import the C++ files from the zip file. If youâve named your project QPDD, do the following first.
- Close Visual C++. Then copy the source files into your project directory. (Be sure to overwrite the QPDD.cpp and QPDD.h files.) Then reopen Visual C++.
- Copy the V++ files to the directory where you created your Visual C++ project. (Only do this if you havenât named your project QPDD.)
- In Visual C++, change the tab on the left side to File View.
- Right-click the Source Files folder and select âAdd files to folder.â Select the following files: rtaccess.c, QPDD.cpp, QPPageFuncs.cpp, and utilities.cpp.
- Right-click the Header Files folder and select âAdd files to folder.â Select the following files: notesapi.h, QPDD.h, QPPageFuncs.h, rtaccess.h, and utilities.h.
If your project is not named QPDD, youâll need to copy some code from QPDD.cpp into the C++ file named after your project:
- Copy the following lines from the top of QPDD.cpp and paste them into <projectname>.cpp (where <projectname> is the name of your project):
//---Utility functions
#include "utilities.h"
//--- QDK header file
#include <qdk.h>
//--- Functions to process QP hook events
#include "QPPageFuncs.h"
//--- The Domino Document Manager API
#include "ddoc2api.h" - Copy the code in QPDD.cpp that begins on line 51, and extends to the end of the file. Paste this into <projectname>.cpp, at the end of the file. Line 51 is the start of a block comment that describes the PageHook function.
- You should now remove QPDD.cpp and QPDD.h from the File View tab in your project. Also, delete the files from the folder where your project resides.
Finally, you have to modify some project settings:
- Bring up the project settings by selecting Project - Settings in Visual C++. Make sure the entire project is selected in the left frame of the dialog box.
- On the C++ tab, in the General category, add W32 as a preprocessor definition. This is required by the Notes C API.
- On the C++ tab, in the Preprocessor category, in the âAdditional include directoriesâ field, add the directories where the QDK is installed, and where the Notes C API is installed (for example: C:\Files\Development\Resources\QDK\include,C:\ Files\Development\Resources \notesapi65\include).
- On the Link tab, in the General category, add notes.lib qdk.obj to the Object/library modules field.
- On the Link tab, in the Input category, in the âAdditional library pathâ field, add the directories where the QDK and Notes C API library files are installed (for example: C:\Imaging\DomDoc\DomDoc Main\Common\notesapi65\lib\mswin32, C:\Files\Development\Resources\QDK\lib\mswin32).
- Select the file rtaccess.c in the left side of the frame of the Project settings dialog box.
- On the C++ tab, in the Precompiled Headers category, select the option âNot using precompiled headers."
- Click OK.
The project should now compile. If you receive errors that mention certain functions are already defined in LIBCMT.lib, do the following: Load the project settings, and make sure the entire project is selected in the left side frame of the dialog box. Select the Link tab, and the Input category. Enter libcmt.lib in the Ignored Libraries field. This will eliminate the error, and the code should compile and link correctly.
When you read through this section, it will be very helpful if you have the code in front of you, so you can reference it as it gets discussed.
Weâll start by looking at the QPDD.cpp file. This file contains the code that registers the hook with QuickPlace, and the function that gets called from QuickPlace. The code that registers the hook with QuickPlace is at the bottom of the file. See the QDK documentation database, qdkdoc.nsf, for more details about hooks and the events that can be processed.
The function PageHook is the one that is called from QuickPlace in the event of an h_Page action. An h_Page action deals with all different aspects of page events (see the QDK documentation for more information). We only want to process ones related to editing and publishing a page. Therefore, one of the first things we check for in the PageHook function is that the page command is either h_MakeDraftFromPublishedVersion or h_Publish. After we determine that a document is either being edited, or published, we call a function to verify the document is configured for Domino Document Manager integration. The function that does this verification is in the utilities.cpp file. Weâll discuss it later. If the document is being edited, we call a function to check out the corresponding document in Domino Document Manager. If the document is being published, we call a function that will either create the document, or create a new version in Domino Document Manager.
The next file weâll look at is QPPageFuncs.cpp. This file contains the two functions that get called from the PageHook function in QPDD.cpp. The first function in the file is cmdCheckOut. It gets called when a page is being edited. All it really does is connect to the Domino Document Manager API, find the document in Domino Document Manager that corresponds to the QuickPlace document being processed, and check it out. The document is checked out in Domino Document Manager so it mirrors the state of the QuickPlace document. If the user saves the QuickPlace page as a draft, we wonât do anything. The Domino Document Manager document will stay checked out (this can be modified; it will be discussed later in the article).
The next function in QPPageFuncs.cpp is copyToDomDoc. This function gets called when a page gets published. It starts by getting some settings and connecting to the Domino Document Manager API. It then checks for a field by the name of h_ddCheckedOut on the QuickPlace document. This field is created when the cmdCheckOut function runs. It tells us that the document is checked out in Domino Document Manager. If this field exists, we get a handle on the working copy of the document in Domino Document Manager. Otherwise, we create a new document in Domino Document Manager.
In the case of a new document, weâll connect to the file cabinet used for this QuickPlace. Then weâll connect to the binder that matches the folder this QuickPlace document is being published to. If the binder doesnât exist, weâll create it. Notice that the binder is created as a Categorized Binder. If this binder type isnât enabled for the file cabinet, an error will occur and the document wonât be stored in Domino Document Manager. After we have a handle on the binder, we create a document in it and set some profile information. The types of information we are setting are the QuickPlace page type, the name and location of the QuickPlace, and other pertinent information on the QuickPlace document.
In the case of an existing document, we simply get a handle on the Domino Document Manager document.
At this point, the code merges and attaches the QuickPlace content if itâs a Microsoft document page. The content will be set later if itâs a link page or a regular page. Other types of pages arenât configured to work in this sample (although it could easily be modified to do so). The next thing to do is to save and check in the Domino Document Manager document. After the document is checked into Domino Document Manager, we will store some information on the QuickPlace document. This is done to keep track of where the document is stored in Domino Document Manager. It also helps in identifying documents stored in Domino Document Manager.
After this information is set, we use the Notes C API to get a handle on the document in Domino Document Manager. We need to do this in the case of a regular QuickPlace page, or a link page. The content of these page types cannot be set through the Domino Document Manager API because it doesnât handle rich text content. For a link page, we simply copy the field on the QuickPlace document that stores the link, and convert it to rich text on the Domino Document Manager document. For a regular page, we copy all attachments and all PageBody fields. Before doing so, we need to delete any fields that may already exist by that name. This scenario will occur when checking in subsequent revisions to Domino Document Manager. After the content is copied to Domino Document Manager, we update and close the handle on the document. The function is done at this point; it just needs to do some clean up of the Domino Document Manager API objects.
This file doesnât need much explanation. It contains three utility functions. The function cLogMessage writes a message to the log file. The function convertTextToRT is used to convert a text field to rich text. The primary use of this function is to support Link pages. The function lnScanField is used by the dumpNoteToLog function in utilities.cpp.
This file contains numerous utility functions. The file is well commented, so I wonât describe each function. I do want to discuss the shouldProcessNote function, however. It is called from the PageHook function in QPDD.cpp. It determines whether or not the hook should process a QuickPlace document. It starts by checking for the h_ddDocID field. The only case in which this field would be present is if we have already processed it before, and a copy exists in Domino Document Manager. If this field isnât present, we continue testing the document against a set of criteria. Hereâs a rundown of the criteria:
- Is this QuickPlace configured for Domino Document Manager integration? If yes, continue.
- Is this page type configured for Domino Document Manager integration? If yes, continue.
- Is this folder configured for Domino Document Manager integration? If yes, return TRUE.
In this demo, integration is configured by a set of Notes.ini variables. There are better ways this integration could be configured, but the idea was to keep it simple. Other ideas on how this could be achieved will be discussed in the following sections.
Configuring the QuickPlace and Domino Document Manager servers
Both the Domino Document Manager and QuickPlace servers need to be configured for integration. These changes are necessary to enable integration, and to provide links between the two products.
Domino Document Manager changes
The Domino Document Manager server needs a new document type created, and some other minor changes. The subform for this new document type is supplied in the database provided in the sample zip file (QPDD.zip), which you can download from the Download section at the end of this article. Open the database in Domino Designer, and copy the subform QuickPlace Page to your file cabinet template (filecab.ntf by default). Also, while the File Cabinet template is open in Domino Designer, open the DocContent form. A field by the name of PageBody needs to be added one line beneath the Body field. The PageBody field is used when a QuickPlace page is stored in Domino Document Manager. The easiest way to create this field is to simply copy and paste the Body field, then rename it PageBody. It should be a rich text, editable field.
After you make these changes to the File Cabinet template, perform a load design on the Domino Document Managerâs server console (so as to update all the file cabinet databases). Then, follow the directions in the Domino Document Manager Administratorâs Guide to create a new document type called QuickPlace Page. After the document type has been created, be sure to enable it in all file cabinets that will store QuickPlace content.
QuickPlace users need to be granted access to the Domino Document Manager file cabinet that stores the QuickPlace content. If they arenât granted access, they wonât be able to view the previous versions. QuickPlace users should be granted reader access, as opposed to editor or manager access. If they are given editor or manager access, they could edit or delete the contents from Domino Document Manager. This would cause the content to be out of synch with that in QuickPlace. For more information about Domino Document Manager security, see the Domino Document Manager Administratorâs Guide.
The QuickPlace server also needs some changes to support the integration. A new theme is needed to display a link to the document in Domino Document Manager (when one exists). The changes to the theme are quite minimal, so they can be incorporated in an existing custom theme, if one exists. For more details on custom themes, see the IBM Redbook, "Customizing QuickPlace."
The only page that needs customization is the Page Layout file. A sample page layout file has been included in the zip file that accompanies the article. The first thing to note about the page is that it contains some JavaScript. The two functions are used to determine if the current page has its content stored in Domino Document Manager, and to write a link to the document in Domino Document Manager. Here is a listing of this JavaScript code:
function isDomDoc(){
// returns 1 if this document has a doc in DomDoc
// returns 0 otherwise
if(fieldNames){
if(fieldNames.h_ddDocID){
// this document is also stored in DomDoc
return 1;
} else {
// Document not stored in DomDoc
return 0;
}
} else {
// must be some kind of error, return 0
return 0;
}
return 0;
}
function writeDomDocLink(){
// Writes a link to the document in DomDoc
if( isDomDoc() ){
document.write('<a href="');
document.write(fieldNames.h_ddURL);
document.write('/');
document.write(fieldNames.h_ddDocDbRepID);
document.write('/(DDMAutoLaunch)?OpenAgent&DocID=');
document.write(fieldNames.h_ddDocURLID);
document.write('&LaunchType=0">View document in
Domino Document Manager</a>');
}
}
|
The next change starts on line 279. It inserts a new row into a table and writes a link to the document in Domino Document Manager. If you donât like where this link is positioned, feel free to move this HTML code to a more suitable location. Hereâs the HTML code that gets inserted:
<tr><!-- Write link for DomDoc document -->
<td><script>writeDomDocLink();</script></td>
</tr>
The other change to the theme is to hide certain actions. These actions are hidden because they arenât configured to work with the Domino Document Manager integration. Leaving them enabled may cause confusion among users as well. Feel free to leave these enabled if you like; just be aware that there is no code in the integration that will process these actions.
Lines 93 and 340 of the page.htm file effectively hides the following actions:
- New Revision. This action is hidden because a new revision is always created with the integration in place. The revision is created in Domino Document Manager, however.
- Revert. This is disabled because there is no code in the integration that processes this action.
- Check Out. This is disabled because the integration happens in the background for the user. They shouldnât need to check out the document.
- Check In. This is disabled because Check Out is disabled, and there is no code in the integration that processes this action.
- Copy. This is disabled because there is no code in the integration that processes this action. Also, if left enabled, the new copy will point to the same document in Domino Document Manager as the original. This will lead to all kinds of problems where editing the original and the new copy will result in updating the same document in Domino Document Manager.
In addition to the new theme in QuickPlace, some Notes.ini settings must be enabled on the QuickPlace server. The following is a list of all the Notes.ini settings, and a description of what they do. Any setting that contains <QuickPlace Name> should be replaced with the actual name of the QuickPlace (as it appears in the url used to connect to it). For example, if your QuickPlace is named qpdd, a Notes.ini setting would be qpdd_ddURL. If these settings are added while Domino is running, Domino will need to be restarted for them to take affect.
- QuickPlaceModules=QPDD.dll registers the hook with QuickPlace.
- <QuickPlace Name>_ddURL=http://server.lotus.com/domdoc/GolfLib.nsf is the url that will be used to connect to the Domino Document Manager API.
- <QuickPlace Name>_ddApiUser=Domino User/Somewhere is the name of the user who will be used to connect to the Domino Document Manager API.
- <QuickPlace Name>_ ddApiPassword=password is the password of the user to use when connecting to the Domino Document Manager API. Storing a password in the Notes.ini isnât a great idea. As explained later in this article, there are other ways that this integration could be enabled. Using Notes.ini settings is the easiest. An alternative would be to hard-code the password in the integration code.
- <QuickPlace Name>_ ddFileCab=File Cabinet is the name of the file cabinet in the Domino Document Manager library where all the QuickPlace content will get stored.
- <QuickPlace Name>_ qpFolders=Discussion,Documents is a comma-separated list of all folders in QuickPlace that should have their content stored in Domino Document Manager.
- <QuickPlace Name>_qpPageTypes=Page,Microsoft Word Page,Microsoft Excel Page,Microsoft PowerPoint Page,Link Page is a comma-separated list of all the page types that will be copied to Domino Document Manager. As mentioned above, only the Microsoft page types, link pages, and regular pages are supported with this integration sample. It could be expanded to handle other types of pages.
After the integration is configured, testing it should be quite easy. Enter the QuickPlace youâve configured for integration. Create a new document, using any of the supported page types, and publish it in a folder that is configured for integration. After the document is published, go back and view it. There should be a link written at the top of the document that says âView document in Domino Document Manager." Clicking this link should take you to the document in Domino Document Manager. If you select Document - View, you should see the contents of the QuickPlace document.
Go back to QuickPlace and locate the document you just created. Edit it, make some changes to the content, and publish it. View the document in QuickPlace again, and click the âView document in Domino Document Managerâ link. Again, you will be taken to the document in Domino Document Manager. By selecting Document - Revision History, you can view a list of all the past versions. Clicking version one, then selecting Document - View, will show the first version of the document. Viewing the second version of the document will show the contents of the document as they now appear. If these steps work for you, congratulations!! The integration is configured properly and working successfully.
If you are able to install Domino, Domino Document Manager and QuickPlace all on your development machine, you can debug the hook code. The ability to debug this code is very helpful when customizing it, as you can see exactly what is happening as it runs. If you donât have this ability, you can add additional logging statements to the code and debug it that way.
Hereâs a list of steps that describe how to configure your Visual C++ project to debug the code.
- Start by opening the project settings. Make sure the Settings For field on the top left contains Win32 Debug.
- Click the Debug tab. The âExecutable for debug sessionâ field should point to the nhttp.exe file that resides in your Domino directory, for example C:\lotus\Domino\nhttp.exe. The âWorking directoryâ field should be the directory in which Domino is installed, for instance c:\Lotus\Domino.
- Change the Category drop-down to âAdditional DLLs.â Add the file qpdd.dll to the list, for example c:\lotus\domino\qpdd.dll.
- Click the C++ tab. For the General category, make sure the field Debug Info is set to âProgram database for edit and continue.â
To actually load the debugger, make sure your code is compiled and the latest DLL is in your Domino program directory. Start Domino, and make sure the HTTP task doesn't load (or shut it down if it does loads). From Visual C++, select Build - Start debug - Go. This will start the HTTP task. After itâs loaded, connect to your QuickPlace and create a page in a folder that is configured for integration. When the page is being published, the debugger should open and you can step through the code (assuming you enabled at least one breakpoint).
There are many things that can be done to our example to make it more powerful. What follows is a list of ideas that can be implemented in this example.
The sample can be modified to save QuickPlace drafts as drafts in Domino Document Manager. Saving drafts in Domino Document Manager would provide the complete history of a QuickPlace document. The code would have to be modified to look for an h_SaveUnderConstruction page command. When this command occurs, a call to shouldProcessNote should be made. This will verify the document meets the set of criteria to be stored in Domino Document Manager. The code should be fashioned after the copyToDomDoc function. It should check if the document is already stored in Domino Document Manager. If it is, the document should be retrieved and a new draft should be made. If the document isnât stored in Domino Document Manager, a new document should be created and checked in as a draft.
The use of Notes.ini settings to enable Domino Document Manager integration could be modified to be more user-friendly. In the original prototype, I created a custom page in QuickPlace that stored all the settings. This way, the settings could be modified through the actual QuickPlace, and the server didnât need to be restarted. The integration code retrieved values from this page rather than Notes.ini settings. Another alternative would be to create a custom database that would store all the settings for multiple QuickPlaces. This method would provide a single point where integration for all QuickPlaces that exist on the server can be configured.
The code can be modified to handle custom QuickPlace pages. For example, if a custom QuickPlace page exists, a new document type can be created in Domino Document Manager based on the QuickPlace page document type. This new document type can contain the custom fields that exist on the QuickPlace page.
The code could be tested in a QuickPlace that uses rooms. The integration code would probably need to be modified to work in such a scenario, but it shouldnât take too much effort.
The link to Domino Document Manager can be hidden, or removed from QuickPlace. With the link removed, thereâs no visible evidence that the content is being stored in Domino Document Manager. In some instances, this may be desired, as the end user wonât know their changes are being tracked.
The code could be modified to work with the actions that are currently hidden in the custom theme. It could also be modified to work with the folder cleanup action. It might be possible to hook into that action and provide a way to migrate multiple documents to Domino Document Manager at once (possibly for QuickPlaces that already exist prior to this integration).
By hooking into QuickPlace events, you can store content in Domino Document Manager in real time. Once the content is there, Domino Document Managerâs full feature set can be used. The contentâs revision history can be viewed, archival settings can enabled, and custom workflows can be implemented. Integrating these two products creates a very powerful tool.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code used in this article | QPDD.zip | 127 KB | HTTP |
Information about download methods
- Download the QuickPlace development kit from the Sandbox.
- Download the Notes C API toolkit from the developerWorks download page.
- For more details on custom themes, see the IBM Redbook, "Customizing QuickPlace."
- Get involved in the developerWorks community by participating in
developerWorks blogs.
Comments (Undergoing maintenance)





