// Export module using automation to Word. // Licensed Materials - Property of IBM - some unique copyrights (i.e., the ability // to copy, modify, distribute) may be licensed in certain circumstances // (e.g., sample/template code intended to be used by customers to build upon and // distribute as their own products). // // DOORS - %full_filespec: word.dxl~67:dxl:ERS#2 % %date_created: Thu Apr 23 09:32:39 2009 % // // (c) Copyright IBM Corporation 1993, 2009. All Rights Reserved. // // U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted // by GSA ADP Schedule Contract with IBM Corp. /* Export current DOORS module to Word via automation. OLE objects and pictures are exported. In book form only the main text column is exported. In table form all visible columns are exported. Graphics are exported as fixed-in-place objects, not float-over-text objects. Support for exporting to a named template (other than normal.dot, for instance in order to insert contents of a DOORS module into a corporate standard template with headers, footers, logo etc.) is included in the advanced options. */ pragma runLim,0 // includes #include #include #include #include #include checkPlatform (NLS_("Microsoft Word")) //-------------------------------------------------------------------- OleAutoObj objWord = null OleAutoObj objDocs = null OleAutoObj objDoc = null OleAutoObj objSel = null OleAutoObj objInlineShapes = null OleAutoObj objTables = null OleAutoArgs objArgBlock = null //-------------------------------------------------------------------- const string wordTitle = LS_("String_Export_To_Word",NLSTEMP_("Export To Word")) const string progressTitle = LS_("String_Export_To_Word_Progress",NLSTEMP_("Export To Word Progress")) const string wordMappingTitle = LS_("String_Export_To_Word_Style_Mapping",NLSTEMP_("Export To Word Style Mapping")) bool includeHeadingNumbers = false bool useNormalTemplate = true bool markRowAsHeader = false // latent support for marking first row of table as table header bool autoformatTableOutput = false bool ignoreDOORSTableBorders = false bool doStyleMapping = false bool useParaStyle = true bool useHorizontalLines = false bool saveEveryNObjects = false int saveEveryN = 100 string templateName = (NLS_("normal.dot")) const int maxRowLimit = 32766 // To define a constant for the maximum row limit of 32766 const string doorsBMName = (NLS_("DoorsBM")) int wordMajorVersion = 0 bool issueWarnings = true //Variable which stores whether checkbox is ticked or not bool includeEmptyAttributes = true //Forward declaration for function 'userExportCode' as this function is called in itfu2.inc bool userExportCode(string, int, bool, bool, DB ) //-------------------------------------------------------------------- Module m = null // Advanced dialogue DBE advancedNormalTemplateToggle DBE advancedTemplateName DBE advancedTemplateLabel DBE autoformatToggle DBE ignoreBordersToggle DBE styleMappingToggle DBE useStyleToggle DBE useHorizontalLinesToggle DBE saveEveryNObjectsToggle DBE saveEveryNObjectsField DBE saveEveryNObjectsLabel // Mapping dialogue DB mappingBox = null DBE doorsFeatureList DBE wordStyleList DBE mappingFileName const string zeroList[0] = {} const int mappingListEntries = 15 const int mappingListWidth = 300 const int DefaultPageWidth = 560 int actualPageWidth = 0 bool progressCanceledStatus = false //------------------------Style mapping tables ------------------------ string headingStyleNames[maxWordLevel] string bodyStyleNames[maxWordLevel] const int noFeatureMaps = maxWordLevel*2 const string doorsFeatureNames[noFeatureMaps] = {(NLS_("Level 1 Object Heading")),(NLS_("Level 2 Object Heading")), (NLS_("Level 3 Object Heading")),(NLS_("Level 4 Object Heading")),(NLS_("Level 5 Object Heading")),(NLS_("Level 6 Object Heading")), (NLS_("Level 7 Object Heading")),(NLS_("Level 8 Object Heading")),(NLS_("Level 9 Object Heading")), (NLS_("Level 1 Object Text")),(NLS_("Level 2 Object Text")), (NLS_("Level 3 Object Text")),(NLS_("Level 4 Object Text")),(NLS_("Level 5 Object Text")),(NLS_("Level 6 Object Text")), (NLS_("Level 7 Object Text")),(NLS_("Level 8 Object Text")),(NLS_("Level 9 Object Text"))} string mapToNames[noFeatureMaps] const string mappingsHeader = (NLS_("")) Regexp impTokenReg = regexp (NLS_("<[^>]*>")) Skip wordStyleNames = null // skip list acts as a zero-based array Skip styleOKNames = null // list of styles from "paragraph style" attr that we have verified Skip wordStyleFonts = null // skip list of fonts corresponding to style names Skip wordStyleHasBullets = null // skip list storing word styles which have bullets Skip wordStyleHasIndents = null // skip list storing word styles which have indents int noWordStyles = 0 bool styleWarn = false //----------- Attribute names only used by Word interface ------------ const string AOLEIconic = (NLS_("OLEIconic")) //---------------------------- Error logging -------------------------- DB errorLogWindow = null DBE errorLogText Buffer errorLogBuffer = null const int errorLogWidth = 500 const int errorLogHeight = 300 const string errorLogTitle = LS_("String_Export_To_Word_Errors",NLSTEMP_("Export To Word Errors")) void initErrorLogging() { errorLogBuffer = create 255 setempty errorLogBuffer } void logError(string errDescription, string errMessage, Object o) { // introducing a string variable to provide more context during externalization. string errStr = dxlStrformat(LS_("String__s_failed_with_error_message_s_for_object_sn_n",NLSTEMP_("%s failed with error message: '%s' for object %s\n\n")), errDescription, errMessage, (identifier o) ) errorLogBuffer += errStr /*errorLogBuffer += errDescription errorLogBuffer += " failed with error message: '" errorLogBuffer += errMessage errorLogBuffer += "' for object " errorLogBuffer += (identifier o) errorLogBuffer += (NLS_("\n\n"))*/ } void makeErrorLogWindow() { errorLogWindow = centered errorLogTitle errorLogText = text(errorLogWindow, LS_("String_Errors_which_occurred_during_export",NLSTEMP_("Errors which occurred during export:")), stringOf errorLogBuffer,errorLogWidth,errorLogHeight,true) } void showErrorLog() { if ((length errorLogBuffer) == 0) { return } makeErrorLogWindow delete errorLogBuffer realize errorLogWindow } //------------------------------- Utilities --------------------------- void clearWordState() { exportEndProgress checkRes(olePut(objWord,cPropertyScreenUpdating,true)) halt } void vbaCheckRes(string res) { if (res != (NLS_(""))) { ack (dxlStrformat(LS_("String_OLE_method_failed_s",NLSTEMP_("OLE method failed: %s")), res)) clearWordState } } string vbaGetStyleName(OleAutoObj objDoc, int styleNumber) { OleAutoObj objStyles = null OleAutoObj objStyle = null string styleName = null vbaCheckRes(oleGet(objDoc, cPropertyStyles, objStyles)) if (null objStyles) { ack LS_("String_Unable_to_get_handle_on_styles_collection",NLSTEMP_("Unable to get handle on styles collection")) clearWordState } clear objArgBlock put(objArgBlock, styleNumber) vbaCheckRes(oleMethod(objStyles, cMethodItem, objArgBlock, objStyle)) if (null objStyle) { ack LS_("String_Unable_to_get_handle_on_style",NLSTEMP_("Unable to get handle on style")) clearWordState } vbaCheckRes(oleGet(objStyle, cPropertyNameLocal, styleName)) if (null styleName) { ack LS_("String_Unable_to_get_style_name",NLSTEMP_("Unable to get style name")) clearWordState } closeIfNonNull objStyle closeIfNonNull objStyles return styleName } void fillStyleNameArrays() { int count string styleName for (count = 0; count < maxWordLevel; count++) { styleName = vbaGetStyleName(objDoc,wordHeadingStyles[count]) headingStyleNames[count] = styleName } styleName = vbaGetStyleName(objDoc,wdStyleNormal) for (count = 0; count < maxWordLevel; count++) { bodyStyleNames[count] = styleName } } void collapseSelection() { clear objArgBlock put(objArgBlock, cParamDirection, wdCollapseEnd) vbaCheckRes(oleMethod(objSel, cMethodCollapse, objArgBlock)) } void collapseSelectionBackwards() { clear objArgBlock put(objArgBlock, cParamDirection, wdCollapseStart) vbaCheckRes(oleMethod(objSel, cMethodCollapse, objArgBlock)) } void paraBreak() { vbaCheckRes(oleMethod(objSel, cMethodInsertParagraphAfter)) } void pageBreak() { // default for InsertBreak is to insert a page break vbaCheckRes(oleMethod(objSel, cMethodInsertBreak)) } OleAutoObj getRange(OleAutoObj obj) { OleAutoObj objRange = null vbaCheckRes(oleGet(obj,cPropertyRange,objRange)) if (null objRange) { ack LS_("String_Unable_to_get_range_object",NLSTEMP_("Unable to get range object")) clearWordState } return objRange } int styleIndex(Object o) { int styleLevel = (level o) if (styleLevel > maxWordLevel) { styleLevel = maxWordLevel } styleLevel-- return styleLevel } void assertStyles() { // insert some text // cycle through styles // delete the text /* We have to go through this sorry farce because Word in it's infinite wisdom keeps track of whether or not styles have been used. If they haven't, and some text is pasted in in a style which has the same name as one which already exists, then the style is updated to match what is in the clipboard, rather than keeping it's own formatting properties. The last thing we want to do is overwrite styles in the current template, so we make sure that they are all used before we start */ int count clear objArgBlock put(objArgBlock, LS_("String_Test_text",NLSTEMP_("Test text"))) vbaCheckRes(oleMethod(objSel, cMethodInsertAfter, objArgBlock)) if (useParaStyle) { string styleName for styleName in styleOKNames do { vbaCheckRes(olePut(objSel, cPropertyStyle, styleName)) } } for (count = 0; count < maxWordLevel; count++) { vbaCheckRes(olePut(objSel, cPropertyStyle, headingStyleNames[count])) vbaCheckRes(olePut(objSel, cPropertyStyle, bodyStyleNames[count])) } // Clear down any strange state left by reasserting "Normal" string styleName = vbaGetStyleName(objDoc, wdStyleNormal) vbaCheckRes(olePut(objSel, cPropertyStyle, styleName)) vbaCheckRes(oleMethod(objSel, cMethodDelete)) collapseSelection } void deleteWordStyleNames() { delete wordStyleNames noWordStyles = 0 } void getWordStyleNames(OleAutoObj objDoc) { OleAutoObj objStyles = null OleAutoObj objStyle = null OleAutoObj objFont = null OleAutoObj objParaFormat = null OleAutoObj objListTemplate = null string styleName = null string fontName = null int styleType = 0 int leftIndent = 0 wordStyleNames = create wordStyleFonts = create wordStyleHasBullets = create wordStyleHasIndents = create int count, stylesToCheck noWordStyles = 0 vbaCheckRes(oleGet(objDoc, cPropertyStyles, objStyles)) if (null objStyles) { ack LS_("String_Unable_to_get_handle_on_styles_collection",NLSTEMP_("Unable to get handle on styles collection")) clearWordState } vbaCheckRes(oleGet(objStyles, cPropertyCount, stylesToCheck)) for (count = 1; count <= stylesToCheck; count++) { clear objArgBlock put(objArgBlock, count) vbaCheckRes(oleMethod(objStyles, cMethodItem, objArgBlock, objStyle)) if (null objStyle) { ack LS_("String_Unable_to_get_handle_on_style",NLSTEMP_("Unable to get handle on style")) clearWordState } // Don't use character styles vbaCheckRes(oleGet(objStyle, cPropertyType, styleType)) if (styleType != wdStyleTypeParagraph) { closeIfNonNull objStyle continue } styleName = (NLS_("")) fontName = (NLS_("")) leftIndent = 0 vbaCheckRes(oleGet(objStyle, cPropertyNameLocal, styleName)) if (null styleName) { ack LS_("String_Unable_to_get_style_name",NLSTEMP_("Unable to get style name")) clearWordState } put(wordStyleNames,noWordStyles,styleName) // Now check if the style involves bullets or indenting oleGet(objStyle, cPropertyListTemplate, objListTemplate) if (!(null objListTemplate)) { // The style has some kind of bulleting applied put(wordStyleHasBullets, styleName, styleName) oleCloseAutoObject objListTemplate } oleGet(objStyle, cPropertyParagraphFormat, objParaFormat) oleGet(objParaFormat, cPropertyLeftIndent, leftIndent) if (leftIndent > 0) { // The style has some kind of indenting applied put(wordStyleHasIndents, styleName, styleName) } closeIfNonNull objParaFormat // get font name so we can set the correct default font vbaCheckRes(oleGet(objStyle, cPropertyFont, objFont)) if (null objFont) { ack LS_("String_Unable_to_get_handle_on_font",NLSTEMP_("Unable to get handle on font")) clearWordState } vbaCheckRes(oleGet(objFont, cPropertyName, fontName)) if (null fontName) { ack LS_("String_Unable_to_get_font_name",NLSTEMP_("Unable to get font name")) clearWordState } closeIfNonNull objFont closeIfNonNull objStyle put(wordStyleFonts,styleName,fontName) noWordStyles++ } closeIfNonNull objStyles // , Word gives us styles in almost-but-not-quite alpha order, // we really do need to sort them string tempWordStyles[noWordStyles] for (count = 0; count < noWordStyles; count++) { find(wordStyleNames, count, tempWordStyles[count]) } sort tempWordStyles delete wordStyleNames wordStyleNames = create for (count = 0; count < noWordStyles; count++) { put(wordStyleNames, count, tempWordStyles[count]) } } int wordStyleExists(string sparam) { // binary chop between indices o and noWordStyles-1 // note this routine assumes that the contents of the wordStyleNames // skip list are sorted in ascending alphabetical order int index, botBoundary, topBoundary string styleName if (noWordStyles == 0) { return -1 } botBoundary = 0 topBoundary = noWordStyles - 1 while (true) { index = botBoundary + ((topBoundary - botBoundary)/2) styleName = (NLS_("")) find(wordStyleNames,index,styleName) if (sparam == styleName) { return index } if (index < 0) { return -1 } if (index > noWordStyles) { return -1 } if (botBoundary == topBoundary) { return -1 } if (topBoundary - botBoundary == 1) { // index will already == botBoundary, special case // topBoundary == index+1 find(wordStyleNames,topBoundary,styleName) if (sparam == styleName) { return index } else { return -1 } } // chop if (styleName > sparam) { // chop towards bottom topBoundary = index-1 } else { // chop towards top botBoundary = index+1 } } } void closeMappingBox(DB xx) { int count // Get settings for (count = 0; count < noFeatureMaps; count++) { if (count < maxWordLevel) { headingStyleNames[count] = mapToNames[count] } else { bodyStyleNames[count-maxWordLevel] = mapToNames[count] } } release mappingBox } void featureListSelected(DBE doorsFeatureList) { int index string mappedStyle = null for index in doorsFeatureList do { if (!null mappedStyle) { if (mapToNames[index] != mappedStyle) { // Features with different mappings selected set(wordStyleList,-1) return } } mappedStyle = mapToNames[index] } if (!null mappedStyle) { int count string styleName for (count = 0; count < noWordStyles; count++) { find(wordStyleNames,count,styleName) if (styleName == mappedStyle) { set(wordStyleList,count) return } } } } string featureMappingString(int i) { return doorsFeatureNames[i] (NLS_(" -> ")) mapToNames[i] } bool anyFeatureSelected() { int index for index in doorsFeatureList do { return true } return false } void refreshMapping(int index) { delete(doorsFeatureList,index) insert(doorsFeatureList,index,featureMappingString index) } void styleListSelected(DBE wordStyleList) { // Selected a style // Select all DOORS features to which this is mapped string s = get wordStyleList if (null s) { return } int count Skip replacements = create int noReplacements = 0 if (anyFeatureSelected) { // map selected feature to selected style for index in doorsFeatureList do { put(replacements, noReplacements, index) noReplacements++ } } else { // no features selected, just select any that map to // this style for (count = 0; count < noFeatureMaps; count++) { set(doorsFeatureList, count, mapToNames[count] == s) } } for (count = 0; count < noReplacements; count++) { int replacement = 0 find(replacements, count, replacement) mapToNames[replacement] = s refreshMapping replacement set(doorsFeatureList, replacement, true) } delete replacements } void initMapToName(int index) { if (index < maxWordLevel) { mapToNames[index] = headingStyleNames[index] } else { mapToNames[index]= bodyStyleNames[index-maxWordLevel] } } void initMapToNames() { int count for (count = 0; count < noFeatureMaps; count++) { initMapToName count } } void resetMappingSelections(DBE xx) { int count // Deselect anything in the style list set(wordStyleList, -1) // Style name arrays are already set up, the are only updated // on close, so reinit the mapto names from these initMapToNames // Refresh list for (count = 0; count < noFeatureMaps; count++) { refreshMapping count } } int doorsFeatureToIndex(string s) { int i for (i = 0; i < noFeatureMaps; i++) { if (s == doorsFeatureNames[i]) { return i } } ack (dxlStrformat(LS_("String_Unrecognised_DOORS_feature_name_s",NLSTEMP_("Unrecognised DOORS feature name : %s")), s)) return -1 } int styleNameToIndex(string s) { int i = wordStyleExists s if (i < 0) { warningBox (LS_("String_Word_style_s_is_not_present_in_this_template_using_standard_mapping",NLSTEMP_("Word style '%s' is not present in this template; using standard mapping")), s) } return i } void loadMappingSelections(DBE xx) { Stream str = null int count, styleIndex, doorsIndex string s, rest, token string filename = get mappingFileName if (null filename) { return } // verify file read if (!fileReadable_ filename) { return } str = read filename if (null str) { ack (dxlStrformat(LS_("String_Unable_to_read_from_file_s",NLSTEMP_("Unable to read from file %s")), filename)) return } // verify header str >> s if (s != mappingsHeader) { ack LS_("String_This_file_is_not_a_Word_style_mappings_file",NLSTEMP_("This file is not a Word style mappings file")) close str return } while (!end str) { str >> s if (impTokenReg s) { int doorsIndex rest = s[end 0 + 1:] token = s[start 0 + 1:end 0 - 1] doorsIndex = doorsFeatureToIndex token if (doorsIndex < 0) { close str return } if (impTokenReg rest) { token = rest[start 0 + 1:end 0 - 1] styleIndex = styleNameToIndex token if (styleIndex < 0) { initMapToName doorsIndex } else { mapToNames[doorsIndex] = token } refreshMapping doorsIndex } else { ack (dxlStrformat(LS_("String_Failed_to_parse_linen_s",NLSTEMP_("Failed to parse line\n %s")), s)) close str return } } } close str } void saveMappingSelections(DBE xx) { Stream str = null int count string filename = get mappingFileName if (null filename) { return } // verify overwrite if (!fileOverwriteOK_ filename) { return } str = write filename if (null str) { ack dxlStrformat(LS_("String_Failed_to_open_file_s_for_write",NLSTEMP_("Failed to open file %s for write")), filename) return } // save header str << mappingsHeader (NLS_("\n")) // save body for (count = 0; count < noFeatureMaps; count++) { str << (NLS_("<")) str << doorsFeatureNames[count] str << (NLS_(">")) str << (NLS_("<")) str << mapToNames[count] str << (NLS_(">")) str << (NLS_("\n")) } close str } void makeMappingBox() { DBE dummy, dummy2 mappingBox = centered wordMappingTitle doorsFeatureList = multiList(mappingBox,LS_("String_DOORS_Features",NLSTEMP_("DOORS Features")),mappingListWidth, mappingListEntries,zeroList) doorsFeatureList->(NLS_("top"))->(NLS_("form")) doorsFeatureList->(NLS_("left"))->(NLS_("form")) doorsFeatureList->(NLS_("right"))->(NLS_("unattached")) doorsFeatureList->(NLS_("bottom"))->(NLS_("unattached")) set(doorsFeatureList, featureListSelected) wordStyleList = list(mappingBox,LS_("String_Word_Styles",NLSTEMP_("Word Styles")),mappingListWidth, mappingListEntries,zeroList) wordStyleList->(NLS_("top"))->(NLS_("form")) wordStyleList->(NLS_("left"))->(NLS_("spaced"))->doorsFeatureList wordStyleList->(NLS_("right"))->(NLS_("form")) wordStyleList->(NLS_("bottom"))->(NLS_("unattached")) set(wordStyleList, styleListSelected) dummy = button(mappingBox,LS_("String_Reset",NLSTEMP_("Reset")),resetMappingSelections) dummy->(NLS_("top"))->(NLS_("spaced"))->doorsFeatureList dummy->(NLS_("left"))->(NLS_("form")) dummy->(NLS_("right"))->(NLS_("unattached")) dummy->(NLS_("bottom"))->(NLS_("unattached")) // Load and save buttons dummy2 = button(mappingBox,LS_("String_Load",NLSTEMP_("Load")),loadMappingSelections) dummy2->(NLS_("top"))->(NLS_("spaced"))->doorsFeatureList dummy2->(NLS_("left"))->(NLS_("spaced"))->dummy dummy2->(NLS_("right"))->(NLS_("unattached")) dummy2->(NLS_("bottom"))->(NLS_("unattached")) dummy = button(mappingBox,LS_("String_Save",NLSTEMP_("Save")),saveMappingSelections) dummy->(NLS_("top"))->(NLS_("spaced"))->doorsFeatureList dummy->(NLS_("left"))->(NLS_("spaced"))->dummy2 dummy->(NLS_("right"))->(NLS_("unattached")) dummy->(NLS_("bottom"))->(NLS_("unattached")) dummy = label(mappingBox,LS_("String_Settings_file",NLSTEMP_("Settings file:"))) dummy->(NLS_("top"))->(NLS_("spaced"))->dummy2 dummy->(NLS_("left"))->(NLS_("form")) dummy->(NLS_("right"))->(NLS_("unattached")) dummy->(NLS_("bottom"))->(NLS_("unattached")) string filename = fileGoodName_(m.AName (NLS_("")), (NLS_(".map")), (NLS_(".map"))) mappingFileName = fileName(mappingBox, filename, (NLS_("*.map")), LS_("String_Mapping_files",NLSTEMP_("Mapping files")), false) mappingFileName->(NLS_("top"))->(NLS_("spaced"))->dummy mappingFileName->(NLS_("left"))->(NLS_("form")) mappingFileName->(NLS_("right"))->(NLS_("unattached")) mappingFileName->(NLS_("bottom"))->(NLS_("form")) close(mappingBox,true,closeMappingBox) } void fillMappingBox() { int count string s for (count = 0; count < noFeatureMaps; count++) { insert(doorsFeatureList, count, featureMappingString count) } for (count = 0; count < noWordStyles; count++) { find(wordStyleNames, count, s); insert(wordStyleList, count, s) } } void styleMappingDialogue() { initMapToNames makeMappingBox realize mappingBox fillMappingBox block mappingBox } void registerStyle(string styleName) { if (!null styleName) { if ((wordStyleExists styleName) < 0) { if (!styleWarn) { ack dxlStrformat(LS_("String_The_Word_style_name_s_does_not_exist_in_this_templaten_Standard_mappings_will_be_used_for_unknown_styles",NLSTEMP_("The Word style name '%s' does not exist in this template\nStandard mappings will be used for unknown styles")), styleName) styleWarn = true } } else { // style exists put(styleOKNames,styleName, styleName) } } } void getStyleOKNames(int exportType) { // we need to get a scratch list of all the styles that we're going to // use, on top of those that have been mapped into heading and body styles string styleName string aName Column c styleOKNames = create Object o for o in m do { styleName = paraStyleGetAttributeMap_(o, ALongText) registerStyle styleName styleName = paraStyleGetAttributeMap_(o, AHeading) registerStyle styleName // Need to register the styles of all the attributes in // all the columns for c in m do { aName = attrName c if (!isDumpableAttribute aName) { aName = (NLS_("")) } styleName = paraStyleGetAttributeMap_(o, aName) registerStyle styleName } } } bool styleOK(string styleName) { return (find(styleOKNames,styleName)) } void deleteStyleOKNames() { delete styleOKNames } //--------------------------- VBA Version -------------------------- bool wordPreChecksVBA() { Object curro = current Object m = current Module // Make Word visible if (!doStyleMapping) { makeVisible objWord } // Get documents collection checkRes(oleGet(objWord,cPropertyDocuments,objDocs)) if (null objDocs) { ack LS_("String_Unable_to_get_Documents_collection",NLSTEMP_("Unable to get Documents collection")) return false } // Make a new document if (useNormalTemplate) { checkRes(oleMethod(objDocs,cMethodAdd)) } else { clear objArgBlock put(objArgBlock,templateName) checkRes(oleMethod(objDocs,cMethodAdd,objArgBlock)) } // Get a handle on the document checkRes(oleGet(objWord,cPropertyActiveDocument,objDoc)) if (null objDoc) { ack LS_("String_Unable_to_get_active_document",NLSTEMP_("Unable to get active document")) halt } // Get a handle on the selection object checkRes(oleGet(objWord,cPropertySelection,objSel)) if (null objSel) { ack LS_("String_Unable_to_get_selection_object",NLSTEMP_("Unable to get selection object")) halt } // Get a handle on the shapes collection checkRes(oleGet(objDoc,cPropertyInlineShapes,objInlineShapes)) if (null objInlineShapes) { ack LS_("String_Unable_to_get_inline_shapes_collection",NLSTEMP_("Unable to get inline shapes collection")) halt } // Get a handle on the tables collection checkRes(oleGet(objDoc,cPropertyTables,objTables)) if (null objTables) { ack LS_("String_Unable_to_get_tables_collection",NLSTEMP_("Unable to get tables collection")) halt } return true } string getStyleForAttribute(Object o, string aName) { if (null o) { return bodyStyleNames[0] } if (useParaStyle) { string styleName // attempt to use the paragraph style attribute styleName = paraStyleGetAttributeMap_(o, aName) if (!null styleName) { // Check the style actually exists if (styleOK styleName) { return styleName } } } // either we're not using the paragraph style attribute, or // we failed to find a match int styleLevel // Special case, cells always have attributes in level 4 if (cell o) { styleLevel = cellHeadingLevel - 1 } else { styleLevel = styleIndex o } if (aName == AHeading) { return headingStyleNames[styleLevel] } else { return bodyStyleNames[styleLevel] } } const string fontTableBeginning = (NLS_("\\deff0{\\fonttbl")) // fonts in this part of the font table will be used for anything // outside the Latin-1 character set const string fontTableEnd = (NLS_("{\\f1\\fswiss\\fprq2\\fcharset0 Arial;} {\\f2\\froman\\fprq2\\fcharset2 Symbol;} {\\f3\\fswiss\\fprq2\\fcharset128 Arial Unicode MS;} {\\f4\\fswiss\\fprq2\\fcharset129 Arial Unicode MS;} {\\f5\\fswiss\\fprq2\\fcharset130 Arial Unicode MS;} {\\f6\\fswiss\\fprq2\\fcharset134 Arial Unicode MS;} {\\f7\\fswiss\\fprq2\\fcharset136 Arial Unicode MS;} {\\f8\\fswiss\\fcharset161 Arial;} {\\f9\\fswiss\\fcharset162 Arial;} {\\f10\\fswiss\\fcharset163 Arial;} {\\f11\\fswiss\\fcharset177 Arial;} {\\f12\\fswiss\\fcharset178 Arial;} {\\f13\\fswiss\\fcharset186 Arial;} {\\f14\\fswiss\\fcharset204 Arial;} {\\f15\\fswiss\\fprq2\\fcharset222 Arial Unicode MS;} {\\f16\\fswiss\\fcharset238 Arial;} }")) string makeFontTableFromStyle(string styleName) { // build a font table with the appropriate default font for the style string fontName = (NLS_("")) string defaultFontEntry string fontTable find(wordStyleFonts, styleName, fontName) defaultFontEntry = (NLS_("{\\f0\\fnil ")) fontName (NLS_(";}")) fontTable = fontTableBeginning defaultFontEntry fontTableEnd return fontTable } string applyStyleLockPasteInvokeEx(OleAutoObj objSelection, RTF_string__ s, string styleName, bool useColour, bool useOleClipboard) // Apply to the specified RTF the named style, then attempt to paste // that RTF to the system clipboard, and invoke the paste method on // objSelection. The style is only applied in case the styleName is // not null. // Locks the clipboard, pastes the RTF to the clipboard and then // invokes cMethodPaste on objSelection. // The attempt to acquire a lock on the clipboard before the paste is // to effect inter-process synchronization. This routine will fail if // the clipboard cannot be locked within 2 seconds. // Also puts the colour information (present in the RTF markup) on the clipboard // iff useColour is true AND styleName is non-NULL. // If useOleClipboard is TRUE, then the RTF string is pasted to the OLE // clipboard in types TYMED_ISTREAM and TYMED_HGLOBAL { string fontTable = null bool styleHasIndent = false bool styleHasBullet = false if (!null styleName) { fontTable = makeFontTableFromStyle(styleName) if (find(wordStyleHasBullets, styleName)) { styleHasBullet = true } if (find(wordStyleHasIndents, styleName)) { styleHasIndent = true } } ClipboardLock cl = null while (null cl) { cl = create(2000) if (null cl) { if (!confirm(LS_("String_Unable_to_lock_clipboard_Retry",NLSTEMP_("Unable to lock clipboard. Retry?")))) { break } } } if (!null cl) { noError // ensure that cl is deleted below if (!null styleName) { if(useColour) { setRichClipWithColour(s, styleName, fontTable, !styleHasBullet, !styleHasIndent, useOleClipboard) } else { setRichClip(s, styleName, fontTable, !styleHasBullet, !styleHasIndent, useOleClipboard) } } else { setRichClip(s, useOleClipboard) } string oleResult = oleMethod(objSelection, cMethodPaste) lastError delete cl return oleResult } else { return LS_("String_Unable_to_lock_clipboard",NLSTEMP_("Unable to lock clipboard")) } } string applyStyleLockPasteInvoke(OleAutoObj objSelection, RTF_string__ s, string styleName, bool useOleClipboard) { applyStyleLockPasteInvokeEx(objSelection, s, styleName, false, useOleClipboard) } string applyStyleLockPasteInvokeWithColour(OleAutoObj objSelection, RTF_string__ s, string styleName, bool useOleClipboard) { applyStyleLockPasteInvokeEx(objSelection, s, styleName, true, useOleClipboard) } string lockPasteInvoke(OleAutoObj objSelection, RTF_string__ s) { // The string doesn't contain any ole and so let's use the normal clipboard. return applyStyleLockPasteInvoke(objSelection, s, (NLS_(""), false) /* don't perform style processing */) } string pasteHeading(OleAutoObj objSelection, Object o, bool doNumbers) { string styleName = getStyleForAttribute(o,AHeading) string errmess = null if (doNumbers) { string s = (number o) (NLS_(" ")) // The string s (which is a object number) doesn't contain any ole. errmess = applyStyleLockPasteInvoke(objSelection, richText s, styleName, false) if (null errmess) { collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) // Word can get confused if the heading text is actually formatted -- // it seems to think we are trying to change the heading style // Sometimes it helps to reassert Normal style in between the number // and the heading text vbaCheckRes(olePut(objSel, cPropertyStyle, wdStyleNormal)) // Heading cannot contain OLE, so no need to check there for unregistered data errmess = applyStyleLockPasteInvoke(objSelection, richTextWithOle o.AHeading, styleName, false) } return errmess } else { // Heading cannot contain OLE, so no need to check there for unregistered data return applyStyleLockPasteInvoke(objSelection, richTextWithOle o.AHeading, styleName, false) } } void wordDumpHeadingVBA(Object o) { bool hasHead = hasCopyableHeading o string errMess int styleLevel collapseSelection if (!hasHead) { return } errMess = pasteHeading(objSel, o, includeHeadingNumbers) if (!null errMess) { logError(LS_("String_Error_pasting_object_heading",NLSTEMP_("Error pasting object heading")), errMess, o) } collapseSelection } void wordDumpBodyVBA(Object o) { string errMess if (!hasCopyableText o) { return } collapseSelection Buffer textBuffer = create if (issueWarnings && containsUnregisteredOle(o.ALongText)) { warningBox dxlStrformat(LS_("String_Object_s_contains_one_or_more_unregistered_OLE_objects_in_s_n_n_These_OLE_objects_will_be_exported_as_pictures",NLSTEMP_("Object %s contains one or more unregistered OLE objects in '%s'.\n\nThese OLE objects will be exported as pictures.")), (identifier o), ALongText) } textBuffer = richTextWithOle o.ALongText errMess = applyStyleLockPasteInvoke(objSel, richText tempStringOf textBuffer, getStyleForAttribute(o, ALongText), containsOle(o.ALongText)) delete(textBuffer) if (!null errMess) { logError(dxlStrformat(LS_("String_Error_pasting_attribute_s_to_clipboard",NLSTEMP_("Error pasting attribute '%s' to clipboard")), ALongText), errMess, o) } collapseSelection } void endKey() { // move past the object clear objArgBlock put(objArgBlock, wdStory) vbaCheckRes(oleMethod(objSel,cMethodEndKey,objArgBlock)) } void wordDumpPictureVBA(Object o, OleAutoObj forObj, bool doEnd) { collapseSelection OleAutoObj pictureRange = getRange forObj if (doEnd) { endKey } clear objArgBlock put(objArgBlock, getPictName o) put(objArgBlock,false) put(objArgBlock,true) put(objArgBlock,pictureRange) vbaCheckRes(oleMethod(objInlineShapes, cMethodAddPicture, objArgBlock)) closeIfNonNull pictureRange endKey paraBreak collapseSelection } void wordAddHorizontalLineStandardVBA() { if (wordMajorVersion >= 9) { OleAutoObj objRange = getRange objSel clear objArgBlock put (objArgBlock, objRange) vbaCheckRes(oleMethod(objInlineShapes, (NLS_("AddHorizontalLineStandard")), objArgBlock)) collapseSelection endKey } } void wordDumpColumnValueVBA (Object o, Column c) { string errMess string titleString = (NLS_("{ {\\i ")) (title c) (NLS_("} :} ")) collapseSelection string attrNameString = attrName c bool appendParaBreak = true if (isDumpableAttribute attrNameString) { if (! canRead (m, attrNameString)) { titleString = titleString LS_("String__Read_Locked_Data",NLSTEMP_(" (Read Locked Data)")) lockPasteInvoke(objSel, richText titleString) } else if (includeEmptyAttributes || o.attrNameString (NLS_("")) != (NLS_(""))) { //If includeEmptyAttributes is true then condition will //allow all attributes values for the attribute column. //If includeEmptyAttributes is false then condition will //allow only not null attribute values for attribute //column. Buffer textBuffer = create textBuffer = titleString Buffer textBuffer2 = create probeRichAttr_(o,attrNameString,textBuffer2,true) textBuffer += textBuffer2 if (issueWarnings && containsUnregisteredOle(o.ALongText)) { warningBox dxlStrformat(LS_("String_Object_s_contains_one_or_more_unregistered_OLE_objects_in_s_n_n_These_OLE_objects_will_be_exported_as_pictures",NLSTEMP_("Object %s contains one or more unregistered OLE objects in '%s'.\n\nThese OLE objects will be exported as pictures.")), (identifier o), ALongText) } errMess = applyStyleLockPasteInvoke(objSel, richText tempStringOf textBuffer, getStyleForAttribute(o, attrNameString), containsOle(o.attrNameString)) delete(textBuffer) delete(textBuffer2) appendParaBreak = false } else { appendParaBreak = false } } else if (text (c, o) != (NLS_(""))) { if (attrNameString == (NLS_("Object Identifier"))) { string s = titleString text(c,o) // object identifier wouldn't contain any ole applyStyleLockPasteInvoke(objSel, richText s, getStyleForAttribute(o,(NLS_(""))), false) //This removes a carriage return from the object collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } else { if (issueWarnings && containsUnregisteredOle(c, o)) { warningBox dxlStrformat(LS_("String_Object_s_contains_one_or_more_unregistered_OLE_objects_n_n_These_OLE_objects_will_be_exported_as_pictures",NLSTEMP_("Object %s contains one or more unregistered OLE objects.\n\nThese OLE objects will be exported as pictures.")), (identifier o)) } Buffer titledRTF = create titledRTF = titleString titledRTF += richTextWithOle(c, o) applyStyleLockPasteInvoke(objSel, richText tempStringOf titledRTF,"Normal") delete titledRTF appendParaBreak = false if(null attrNameString) { bool olePresent = false RichText rtf for rtf in stringOf(titledRTF) do { if (rtf.isOle) { olePresent = true break } } // deal with colours only for layout DXL columns applyStyleLockPasteInvokeWithColour(objSel, richText tempStringOf titledRTF,LS_("String_Normal",NLSTEMP_("Normal")), olePresent) } else { lockPasteInvoke(objSel, richText tempStringOf titledRTF) } delete titledRTF } } if (appendParaBreak) { paraBreak } } void wordDumpObjectVBA(Object o) { string errMess if (! canRead o) { RTF_string__ s = (richText (NLS_("> ")) (number o) LS_("String__Read_Locked_Data",NLSTEMP_(" (Read Locked Data)"))) errMess = lockPasteInvoke(objSel, s) if (!null errMess) { logError(LS_("String_Error_pasting_object_number_to_clipboard",NLSTEMP_("Error pasting object number to clipboard")), errMess, o) } if (useHorizontalLines) { wordAddHorizontalLineStandardVBA } return } Object previousO = previous o if (! null previousO and (cell previousO or table previousO)) { // no need to do a parabreak after a table vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) if (useHorizontalLines) { wordAddHorizontalLineStandardVBA } } Column c for c in m do { if (main c) { wordDumpHeadingVBA o wordDumpBodyVBA o if (hasCopyablePicture o) { wordDumpPictureVBA(o, objSel, true) } } else { wordDumpColumnValueVBA (o, c) } } if (useHorizontalLines) { wordAddHorizontalLineStandardVBA } if (null next o) { collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } } void wordDumpTableMarkerVBA(Object o) { collapseSelection // No OLE would be present in object heading attribute applyStyleLockPasteInvoke(objSel, richText cTableMarkerString, getStyleForAttribute(o, AHeading), false) paraBreak collapseSelection } OleAutoObj wordMakeSizedTableVBA(int noRows, int noCols) { OleAutoObj objTable = null OleAutoObj objRange = null // make a table maxCols,rows collapseSelection if (noRows == 0 || noCols == 0) { return } objRange = getRange objSel clear objArgBlock put(objArgBlock, objRange) put(objArgBlock, noRows) put(objArgBlock, noCols) vbaCheckRes(oleMethod(objTables, cMethodAdd, objArgBlock,objTable)) if (null objTable) { ack LS_("String_Failed_to_make_table",NLSTEMP_("Failed to make table")) clearWordState } closeIfNonNull objRange collapseSelection return objTable } void wordSetCellContentsVBAEx(OleAutoObj objCell, Object o, string s, bool useColour, bool olePresent) { if (null s) { return } int styleLevel if (null o) { styleLevel = 0 } else { styleLevel = styleIndex o } vbaCheckRes(oleMethod(objCell, cMethodSelect)) collapseSelectionBackwards if (useColour) { applyStyleLockPasteInvokeWithColour(objSel, richText s, getStyleForAttribute(o,(NLS_(""))), olePresent) } else { applyStyleLockPasteInvoke(objSel, richText s, getStyleForAttribute(o,(NLS_(""))), olePresent) } //This removes a carriage return from the table cell collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } void wordSetCellContentsVBA(OleAutoObj objCell, Object o, string s, bool olePresent) { wordSetCellContentsVBAEx(objCell, o, s, false, olePresent) } void wordSetCellContentsVBAWithColour(OleAutoObj objCell, Object o, string s, bool olePresent) { wordSetCellContentsVBAEx(objCell, o, s, true, olePresent) } //Function to dump the Object text or table cell value void wordDumpTableAttributeVBA(Object o) { string errMess = (NLS_("")) if (!hasCopyableTableAttributes(o)) { return } string attribName = o.(reserved AMainColumnAttribute) Buffer textBuffer = create probeRichAttr_(o,attribName,textBuffer,true) if (0 < length textBuffer) { if (issueWarnings && containsUnregisteredOle(o.attribName)) { warningBox dxlStrformat(LS_("String_Object_s_contains_one_or_more_unregistered_OLE_objects_in_s_n_n_These_OLE_objects_will_be_exported_as_pictures",NLSTEMP_("Object %s contains one or more unregistered OLE objects in '%s'.\n\nThese OLE objects will be exported as pictures.")), (identifier o), attribName) } errMess = applyStyleLockPasteInvoke(objSel, richText tempStringOf textBuffer, getStyleForAttribute(o, attribName), containsOle(o.attribName)) } delete(textBuffer) if (!null errMess) { logError(dxlStrformat(LS_("String_Error_pasting_attribute_s_of_cell",NLSTEMP_("Error pasting attribute '%s' of cell")), attribName), errMess, o) } collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } void wordDumpCellVBA(OleAutoObj objCell, Object o, bool doNumber) { string errMess = (NLS_("")) //Check cell access if (!canRead(o)) { return } vbaCheckRes(oleMethod(objCell, cMethodSelect)) collapseSelectionBackwards //Get the attribute associated with the table (main column attribute) string attributeName = o.(reserved AMainColumnAttribute) if (null attributeName) { bool isPicture = hasPicture o bool hasText = hasCopyableText o bool hasHead = hasCopyableHeading o int styleLevel = styleIndex o if (isPicture) { hasText = false } if (!hasText && !hasHead && !isPicture) { if (doNumber) { string s = number o // No OLE item would be present in object number applyStyleLockPasteInvoke(objSel, richText s, getStyleForAttribute(o,AHeading), false) collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } return } if (hasHead) { errMess = pasteHeading(objSel, o, doNumber) if (!null errMess) { logError(LS_("String_Error_pasting_Object_Heading_heading_of_cell",NLSTEMP_("Error pasting 'Object Heading' heading of cell")), errMess, o) } collapseSelection if (!hasText) { vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } } if (isPicture) { /* picture objects cannot have text */ if (hasCopyablePicture o) { wordDumpPictureVBA(o,objSel,false) return } } if (hasText) { wordDumpBodyVBA(o) vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } } else { wordDumpTableAttributeVBA(o) } } void wordDumpTableCellMarkerVBA(OleAutoObj objCell, Object o) { vbaCheckRes(oleMethod(objCell, cMethodSelect)) collapseSelectionBackwards // No OLE item would be present in object heading attribute applyStyleLockPasteInvoke(objSel, richText cTableMarkerString, getStyleForAttribute(o, AHeading), false) collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } OleAutoObj wordGetNumberedCellVBA(OleAutoObj objTable, int rowNo, int cellNo) { OleAutoObj objCell = null clear objArgBlock put(objArgBlock, rowNo) put(objArgBlock, cellNo) vbaCheckRes(oleMethod(objTable, cMethodCell, objArgBlock,objCell)) if (null objCell) { ack LS_("String_Failed_to_get_cell_handle",NLSTEMP_("Failed to get cell handle")) clearWordState } return objCell } void wordDumpNamedCellVBA(OleAutoObj objCell, Object o, string attrInCell) { if (!canRead(o.attrInCell)) { return } if (null (richTextWithOle o.attrInCell)) { return } string errMess vbaCheckRes(oleMethod(objCell, cMethodSelect)) collapseSelectionBackwards Buffer textBuffer = create fullAttributeValueWithOle_(o,attrInCell,true,textBuffer) errMess = applyStyleLockPasteInvoke(objSel, richText tempStringOf textBuffer, getStyleForAttribute(o,attrInCell), containsOle(o.attrInCell)) delete(textBuffer) if (!null errMess) { logError(LS_("String_Error_pasting_column_attribute_into_table_cell",NLSTEMP_("Error pasting column attribute into table cell")), errMess, o) } collapseSelection vbaCheckRes(oleMethod(objSel, cMethodTypeBackspace)) } void markRowAsTableHeader(OleAutoObj objTable, int rowNo) { OleAutoObj objRows = null OleAutoObj objRow = null vbaCheckRes(oleGet(objTable, cPropertyRows, objRows)) if (null objRows) { ack LS_("String_Failed_to_get_rows_collection",NLSTEMP_("Failed to get rows collection")) clearWordState } clear objArgBlock put(objArgBlock, rowNo) vbaCheckRes(oleMethod(objRows, cMethodItem, objArgBlock, objRow)) if (null objRow) { ack LS_("String_Failed_to_get_row_object",NLSTEMP_("Failed to get row object")) clearWordState } vbaCheckRes(olePut(objRow, cPropertyHeadingFormat, true)) closeIfNonNull objRow closeIfNonNull objRows } OleAutoObj getBordersVBA(OleAutoObj forObj) { OleAutoObj objBorders = null vbaCheckRes(oleGet(forObj, cPropertyBorders, objBorders)) if (null objBorders) { ack LS_("String_Failed_to_get_borders_collection",NLSTEMP_("Failed to get borders collection")) clearWordState } return objBorders } int getLineStyle(bool hasBorder) { if (hasBorder) { return wdLineStyleSingle } else { return wdLineStyleNone } } void enableTableBordersVBA(OleAutoObj objTable, bool hasBorder) { OleAutoObj objBorders = getBordersVBA objTable vbaCheckRes(olePut(objBorders, cPropertyEnable, getLineStyle hasBorder)) closeIfNonNull objBorders } int assessBorders(Object cello) { int count = 0 int cellBorders = getTableCellBorders cello if ((cellBorders & cellBorderLeft) != 0) { count++ } if ((cellBorders & cellBorderRight) != 0) { count++ } if ((cellBorders & cellBorderTop) != 0) { count++ } if ((cellBorders & cellBorderBottom) != 0) { count++ } return count } void setBorderState(OleAutoObj objBorders, int borderNumber, bool hasBorder) { OleAutoObj objBorder = null clear objArgBlock put(objArgBlock, borderNumber) vbaCheckRes(oleMethod(objBorders, cMethodItem, objArgBlock, objBorder)) if (null objBorder) { ack LS_("String_Failed_to_get_border_object",NLSTEMP_("Failed to get border object")) clearWordState } vbaCheckRes(olePut(objBorder, cPropertyLineStyle, getLineStyle hasBorder)) closeIfNonNull objBorder } void setCellBordersVBA(OleAutoObj objCell, Object cello, bool tableIsBordered) { OleAutoObj objBorders = null bool hasBorder int cellBorders = getTableCellBorders cello // Left hasBorder = (cellBorders & cellBorderLeft) != 0 if (hasBorder != tableIsBordered) { if (null objBorders) { objBorders = getBordersVBA objCell } setBorderState(objBorders, 2, hasBorder) } // Right hasBorder = (cellBorders & cellBorderRight) != 0 if (hasBorder != tableIsBordered) { if (null objBorders) { objBorders = getBordersVBA objCell } setBorderState(objBorders, 4, hasBorder) } // Top hasBorder = (cellBorders & cellBorderTop) != 0 if (hasBorder != tableIsBordered) { if (null objBorders) { objBorders = getBordersVBA objCell } setBorderState(objBorders, 1, hasBorder) } // Bottom hasBorder = (cellBorders & cellBorderBottom) != 0 if (hasBorder != tableIsBordered) { if (null objBorders) { objBorders = getBordersVBA objCell } setBorderState(objBorders, 3, hasBorder) } closeIfNonNull objBorders } void setCellWidthVBA(Object cello, OleAutoObj objCell, int maxRowWidth,int actualPageWidth) { // set cell width int cellw = getTableCellWidth cello real cellVal = realOf(cellw ) // Ignore return status. Can fail when our table becomes // wider than Word page if(maxRowWidth > actualPageWidth) { cellVal = (cellVal * realOf(actualPageWidth))/realOf(maxRowWidth) } cellVal = pixToRealPoint (cellVal) olePut(objCell, cPropertyWidth,cellVal) } OleAutoObj nextCellVBA(OleAutoObj objTable, objCell) { OleAutoObj nextCell = null if (null objCell) { nextCell = wordGetNumberedCellVBA(objTable,1,1) } else { vbaCheckRes(oleGet(objCell, cPropertyNext, nextCell)) } if (null nextCell) { ack LS_("String_Unable_to_get_handle_on_next_cell",NLSTEMP_("Unable to get handle on next cell")) clearWordState } closeIfNonNull objCell return nextCell } int getMaxRowWidth(OleAutoObj objTable, Object o) { int noRows = 0 int noCols = 0 int noCells = 0 int maximumVal = 0 int temp = 0 Object rowo,cello OleAutoObj objCell = null for rowo in o do { if (!row rowo) { continue } noRows++ noCells = 0 temp = 0 for cello in rowo do { if (!cell cello) { continue } if (!isVisible cello) { continue } noCells++ objCell = nextCellVBA(objTable, objCell) int cellw = getTableCellWidth cello temp = cellw + temp } if(temp > maximumVal) maximumVal = temp } return maximumVal } void wordDumpTableVBA(Object o) { int noRows = 0 int noCols = 0 int noCells = 0 int count int maxRowWidth = 0 Object rowo,cello OleAutoObj objTable = null OleAutoObj objCell = null string s = null int possibleBorders = 0 int actualBorders = 0 bool tableIsBordered = false Object previousO = previous o if (! null previousO and (cell previousO or table previousO)) { paraBreak } for rowo in o do { if (!row rowo) { continue } noRows++ noCells = 0 for cello in rowo do { if (!cell cello) { continue } if (!isVisible cello) { continue } noCells++ if (!ignoreDOORSTableBorders) { possibleBorders += 4 actualBorders += assessBorders cello } } if (noCells > noCols) { noCols = noCells } if (noCells == 0) { noRows-- } } if (noRows == 0 || noCols == 0) { // badly formed table return } objTable = wordMakeSizedTableVBA(noRows, noCols) if (ignoreDOORSTableBorders) { tableIsBordered = true } else { tableIsBordered = (actualBorders == possibleBorders) } enableTableBordersVBA(objTable,tableIsBordered) // now walk through table setting contents noRows = 0 maxRowWidth = getMaxRowWidth(objTable,o) objCell = null for rowo in o do { if (progressCanceledStatus || exportCheckProgress) { progressCanceledStatus = true break } if (!row rowo) { continue } noRows++ noCells = 0 // Set all the cells in the row for cello in rowo do { if (progressCanceledStatus || exportCheckProgress) { progressCanceledStatus = true break } if (!cell cello) { continue } if (!isVisible cello) { continue } noCells++ objCell = nextCellVBA(objTable, objCell) if (!autoformatTableOutput) then { setCellWidthVBA(cello, objCell,maxRowWidth,actualPageWidth) } wordDumpCellVBA(objCell,cello,false) if (!ignoreDOORSTableBorders) { setCellBordersVBA(objCell,cello,tableIsBordered) } exportStepProgress } // Delete any extraneous cells in this row if (noCells == 0) { noRows-- } else { for (count = noCols; count > noCells; count--) { OleAutoObj deleteCell = wordGetNumberedCellVBA(objTable,noRows,count) vbaCheckRes(oleMethod(deleteCell, cMethodDelete)) closeIfNonNull deleteCell } } } if (progressCanceledStatus) { vbaCheckRes(oleMethod(objTable, (NLS_("Delete")))) } else { closeIfNonNull objCell if (autoformatTableOutput) then // To provide for auto Formatting in case of tabels in Book Layout. { clear objArgBlock put(objArgBlock, wdTableFormatGrid1) checkRes(oleMethod(objTable, cMethodAutoFormat, objArgBlock)) } if (markRowAsHeader) { markRowAsTableHeader(objTable, 1) } vbaCheckRes(oleMethod(objTable, cMethodSelect)) collapseSelection closeIfNonNull objTable collapseSelection } } void formatTableAsDisplay(OleAutoObj objTable) { Column c int i, colCount OleAutoObj objColumns = null OleAutoObj objColumn = null vbaCheckRes(oleGet(objTable, cPropertyColumns, objColumns)) if (null objColumns) { ack LS_("String_Failed_to_get_columns_collection",NLSTEMP_("Failed to get columns collection")) clearWordState } colCount = 1 for c in m do { int i = width c // DOORS column width in pixels i = pixToPoint i clear objArgBlock put(objArgBlock, colCount) vbaCheckRes(oleMethod(objColumns, cMethodItem, objArgBlock,objColumn)) if (null objColumn) { ack dxlStrformat(LS_("String_Unable_to_get_handle_on_column_s",NLSTEMP_("Unable to get handle on column %s")), colCount (NLS_("")) ) clearWordState } // ignore return status from this, in case we blow the width // of the page olePut(objColumn, cPropertyWidth, i) closeIfNonNull objColumn colCount++ } closeIfNonNull objColumns enableTableBordersVBA(objTable,true) markRowAsTableHeader(objTable, 1) } OleAutoObj exportTableLayoutRow(Object o, OleAutoObj objTable, objCell) { Column c string s bool olePresent = false for c in m do { objCell = nextCellVBA(objTable, objCell) if (main c) { if (!canRead o) { // insert read locked string, as per DOORS display wordSetCellContentsVBA(objCell,o,cReadLockedDataMarker, false) } else { if (table o) { wordDumpTableCellMarkerVBA(objCell, o) } else { wordDumpCellVBA(objCell,o,includeHeadingNumbers && (!cell o)) } } } else { string attrInCol = attrName c if (isDumpableAttribute attrInCol) { if (! canRead(m, attrInCol)) { wordSetCellContentsVBA(objCell,o,cReadLockedDataMarker, false) } else { wordDumpNamedCellVBA(objCell,o,attrInCol) } } else { if (attrInCol == (NLS_("Object Identifier"))) { // ole is not present in object identifier. s = text(c,o) } else { if (issueWarnings && containsUnregisteredOle(c, o)) { warningBox (LS_("String_Object_s_contains_one_or_more_unregistered_OLE_objects_n_n_These_OLE_objects_will_be_exported_as_pictures",NLSTEMP_("Object %s contains one or more unregistered OLE objects.\n\nThese OLE objects will be exported as pictures.")), (identifier o)) } //to display date attributes string attrName = attrName(c) if(!null attrName) { string attrText AttrDef ad = find(current Module,attrName) if((!null ad) && (isDateAttribute(ad))){ s = getAttributeDateValue(ad,current Module,o) } else { s = richTextWithOle(c,o) olePresent = containsOle(o.attrName) } } else { s = richTextWithOle(c,o) wordSetCellContentsVBAWithColour(objCell, o, s, olePresent) continue } } if (null s) { continue } wordSetCellContentsVBA(objCell,o,s,olePresent) } } } return objCell } int countTableLayoutRows() { Object o int rows = 0 for o in m do { if (row o) { continue } if (tableContents m) { if (table o) { continue } } else { if (cell o) { continue } } rows++ } return rows } void gotoEndOfTemplate() { clear objArgBlock put(objArgBlock, cParamUnit, wdStory) int moved vbaCheckRes(oleMethod(objSel, cMethodEndKey, objArgBlock, moved)) if (moved > 0) { // insert a page break pageBreak } } bool wordExportSaveDocument() // DESCRIPTION: Saves the Word document // Note this will prompt the user for a filename the first time it is called { string res string answers[] = {LS_("String_Yes",NLSTEMP_("Yes")), LS_("String_No",NLSTEMP_("No"))} int answer res = oleMethod(objDoc, cMethodSave) int nDocs = -1 if (res != (NLS_(""))) { answer = messageBox(LS_("String_Save_operation_is_failed_Do_you_want_to_continue_without_saving",NLSTEMP_("Save operation is failed. Do you want to continue without saving?")), answers, msgWarning) if(answer == 1) { olePut(objWord,cPropertyScreenUpdating,true) clear objArgBlock put(objArgBlock, wdDoNotSaveChanges) oleMethod(objDoc, (NLS_("Close")), objArgBlock) oleGet(objDocs, (NLS_("Count")), nDocs) // If no documents opened, close the application also. if(nDocs <= 0) { oleMethod(objWord, (NLS_("Quit")), objArgBlock) } progressStop() halt() } else { return true } } return false } void wordExportAsTableVBA(DB forWin) { OleAutoObj objTable = null OleAutoObj objCell = null int cols = 0 int rows = 0 int i = 0 Column c Object o string s int rowsRem = 0 Array tables // To define an array of tables to store the total no of rows after splitting the rows int numSinceSave = 0 bool executedOnce = false gotoEndOfTemplate for c in m do { cols++ } if (cols == 0) { ack LS_("String_There_are_no_columns_to_export",NLSTEMP_("There are no columns to export")) return } rows = countTableLayoutRows rowsRem = rows // To store the total rows in a variable to handle the condition when the no of rows are less than 32767 int numTables = 1 //The default no of tables in case there is no splitting // To check if the total no of rows is greater than the MaxRowLimit if(rows > maxRowLimit) { numTables = (rows / maxRowLimit) //To calculate the total no of tables rowsRem = (rows % maxRowLimit) // To calculate the rows remaining // To check if any rows remain and add one more table for it if (rowsRem > 0) { numTables = numTables + 1 } warningBox (LS_("String_There_are_more_than_s_rows_The_rows_will_be_split_into_s_tables",NLSTEMP_("There are more than %s rows. The rows will be split into %s tables.")) , maxRowLimit (NLS_("")), numTables (NLS_("")) ) } // if (rows > maxRowLimit) tables = create (numTables, 1) // create an array of tables // Do export exportInitProgress(forWin, progressTitle, LS_("String_Exporting_object",NLSTEMP_("Exporting object ")), rows) // Too iterate thru the tables array for (i = 0; i < numTables; i++) { if (i == (numTables - 1)) { // To take care of boundary conditions when the total cells are multiples of the maxRowLimit if(rowsRem == 0) { objTable = wordMakeSizedTableVBA(maxRowLimit +1, cols) } else { objTable = wordMakeSizedTableVBA(rowsRem+1, cols) } } // (i == (numTables - 1)) // If the table is not the last table of the array else { objTable = wordMakeSizedTableVBA(maxRowLimit +1, cols) } put(tables, objTable, i, 0) vbaCheckRes(oleMethod(get(tables, i, 0), cMethodSelect)) collapseSelection if(i != (numTables - 1)) { paraBreak } } // for (i = 0; i < numTables; i++) // Set titles for c in m do { objCell = nextCellVBA(get(tables, 0, 0),objCell) s = title c wordSetCellContentsVBA(objCell,null,s,false) } int temp = 0 // To calculate the no of rows in a loop i = 0 // To calculate the no of tables handled // To iterate thru the no of objects in a module and the no of rows. for o in m do { if (row o) { continue } if (tableContents m) { if (table o) { continue } } else { if (cell o) { continue } } if (exportCheckProgress) { break } objCell = exportTableLayoutRow(o, get(tables, i, 0), objCell) exportStepProgress temp++ // increment the variable // if the maxRowLimit is reached if (temp == maxRowLimit) { closeIfNonNull objCell objCell = null i++ // To increment the no of tables in an array temp = 0 // To check if the last table is reached if (i == numTables) { break } // Set titles for c in m do { objCell = nextCellVBA(get(tables, i, 0),objCell) s = title c wordSetCellContentsVBA(objCell, null, s, false) } } // (temp == maxRowLimit) if (saveEveryNObjects) { // increment the counter and check if we need to save numSinceSave++ if (numSinceSave >= saveEveryN && !executedOnce) { executedOnce = wordExportSaveDocument numSinceSave = 0 } } } // for o in m closeIfNonNull objCell objCell = null exportEndProgress // Do post-processing of table layout for (i = 0; i < numTables; i++) { if (autoformatTableOutput) { clear objArgBlock put(objArgBlock, wdTableFormatGrid1) checkRes(oleMethod(get(tables, i, 0), cMethodAutoFormat, objArgBlock)) } else { formatTableAsDisplay get(tables, i, 0) } } // To close the tables array for (i = 0; i < numTables; i++) { closeIfNonNull get(tables, i, 0) } } void wordExportAsBookVBA(DB forWin) { Object o int numSinceSave = 0 int width=-1 int LMargin=-1 bool executedOnce = false { OleAutoObj objPageSetup oleGet(objDoc, cPropertyPageSetup, objPageSetup) if (!null objPageSetup) { oleGet(objPageSetup, cPropertyPageWidth,width) oleGet(objPageSetup, cPropertyLeftMargin,LMargin) closeIfNonNull objPageSetup } } if ((width>0) && (LMargin >=0) && (width > LMargin)) actualPageWidth = (width - LMargin) else actualPageWidth = DefaultPageWidth exportInitProgress(forWin, progressTitle, LS_("String_Exporting_object",NLSTEMP_("Exporting object ")), countTableLayoutRows) gotoEndOfTemplate for o in document m do { if (exportCheckProgress) { break } if (table o) { if (tableContents m) { wordDumpTableVBA o if (progressCanceledStatus || exportCheckProgress) { break } } else { wordDumpTableMarkerVBA o exportStepProgress } } else { if (!isDocumentIgnore o) { wordDumpObjectVBA(o) exportStepProgress } } if (saveEveryNObjects) { // increment the counter and check if we need to save numSinceSave++ if (numSinceSave >= saveEveryN && !executedOnce) { executedOnce = wordExportSaveDocument numSinceSave = 0 } } } // for o in document progressCanceledStatus = false exportEndProgress } void wordDoExportVBA(DB forWin, int exportType) { if (!wordPreChecksVBA) { return } checkRes(olePut(objWord,cPropertyScreenUpdating,false)) // Just fill in from known styles fillStyleNameArrays getWordStyleNames objDoc if (useParaStyle) { getStyleOKNames exportType } if (doStyleMapping) { // Show style mapping dialogue styleMappingDialogue makeVisible objWord } assertStyles if (exportType == layoutTypeBook) { wordExportAsBookVBA forWin } else { wordExportAsTableVBA forWin } collapseSelection if (useParaStyle) { deleteStyleOKNames } if (doStyleMapping || useParaStyle) { deleteWordStyleNames } checkRes(olePut(objWord,cPropertyScreenUpdating,true)) closeIfNonNull objWord closeIfNonNull objDocs closeIfNonNull objDoc closeIfNonNull objSel closeIfNonNull objInlineShapes closeIfNonNull objTables delete objArgBlock } void checkWordVersion() { // ensure that this global is zet to zero wordMajorVersion = 0 string version = getRegistry((NLS_("HKEY_CLASSES_ROOT\\Word.Application\\CurVer")), (NLS_(""))) if (!isVoid_(version)) { Regexp re = regexp (NLS_("Word.Application.")) if (re version) { // strip off the application name string majorVersionString = version[end 0 + 1:] wordMajorVersion = intOf majorVersionString } } } void createWordApplication() { objArgBlock = create if (null objArgBlock) { ack LS_("String_Unable_to_create_argument_block_Low_memory",NLSTEMP_("Unable to create argument block. Low memory?")) return } // attaches to an existing word application objWord = oleGetAutoObject(cObjWordApplication) if (null objWord) { // creates a new word application objWord = oleCreateAutoObject(cObjWordApplication) } } string getTemplatesDirectory() { string s int len // TBD where does Word 2000 store the templates directory? //First try Word 8 templates directory, value is default value s = getRegistry((NLS_("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Office\\8.0\\Common\\FileNew\\LocalTemplates")), null) if (null s) { return s } len = length s // Add on trailing slash if necessary if (s[len-1:] != (FileSep_ (NLS_("")))) { s = s FileSep_ (NLS_("")) } return s } void useTemplateNameSelected(DBE xx) { bool b = get advancedNormalTemplateToggle if (b) { inactive advancedTemplateName inactive advancedTemplateLabel } else { active advancedTemplateName active advancedTemplateLabel } } void saveEveryNSelected(DBE xx) // DESCRIPTION: if periodic save is turned on, activate the field which determines // the frequency of saves { bool b = get saveEveryNObjectsToggle if (b) { active saveEveryNObjectsField } else { inactive saveEveryNObjectsField } } //------------------------- Export UI builder code --------------------------- void updateExportAttrToggle(int) void exportLayoutChanged(DBE xx) { int currentLayout = get xx updateExportAttrToggle(currentLayout) } void exportHeadingsChanged(DBE xx) {} void userAdvancedUIRefresh(DB theBox) {} //------------------------------------------------------------------------ void userAdvancedUISetup(DB theBox, DBE theTab, Skip s) { checkWordVersion() string templatesDir useStyleToggle = toggle(theBox, LS_("String_Use_Paragraph_Style_attribute",NLSTEMP_("Use 'Paragraph Style' attribute")),useParaStyle) useStyleToggle->(NLS_("left"))->(NLS_("inside"))->theTab useStyleToggle->(NLS_("right"))->(NLS_("unattached")) useStyleToggle->(NLS_("top"))->(NLS_("inside"))->theTab useStyleToggle->(NLS_("bottom"))->(NLS_("unattached")) put(s,0,useStyleToggle) styleMappingToggle = toggle(theBox,LS_("String_Allow_style_mapping",NLSTEMP_("Allow style mapping")),doStyleMapping) styleMappingToggle->(NLS_("left"))->(NLS_("inside"))->theTab styleMappingToggle->(NLS_("right"))->(NLS_("unattached")) styleMappingToggle->(NLS_("top"))->(NLS_("spaced"))->useStyleToggle styleMappingToggle->(NLS_("bottom"))->(NLS_("unattached")) put(s,1,styleMappingToggle) ignoreBordersToggle = toggle(theBox,LS_("String_Ignore_DOORS_table_borders_put_all_borders_on_all_cells",NLSTEMP_("Ignore DOORS table borders, put all borders on all cells")),ignoreDOORSTableBorders) ignoreBordersToggle->(NLS_("left"))->(NLS_("inside"))->theTab ignoreBordersToggle->(NLS_("right"))->(NLS_("unattached")) ignoreBordersToggle->(NLS_("top"))->(NLS_("spaced"))->styleMappingToggle ignoreBordersToggle->(NLS_("bottom"))->(NLS_("unattached")) put(s,2,ignoreBordersToggle) autoformatToggle = toggle(theBox,LS_("String_Ignore_DOORS_column_widths_in_table_layout_export_AutoFormat_instead",NLSTEMP_("Ignore DOORS column widths in table layout export, AutoFormat instead")),autoformatTableOutput) autoformatToggle->(NLS_("left"))->(NLS_("inside"))->theTab autoformatToggle->(NLS_("right"))->(NLS_("unattached")) autoformatToggle->(NLS_("top"))->(NLS_("spaced"))->ignoreBordersToggle autoformatToggle->(NLS_("bottom"))->(NLS_("unattached")) put(s,3,autoformatToggle) advancedNormalTemplateToggle = toggle(theBox, LS_("String_Use_normal_template",NLSTEMP_("Use normal template")), useNormalTemplate) advancedNormalTemplateToggle->(NLS_("left"))->(NLS_("inside"))->theTab advancedNormalTemplateToggle->(NLS_("right"))->(NLS_("unattached")) advancedNormalTemplateToggle->(NLS_("top"))->(NLS_("spaced"))->autoformatToggle advancedNormalTemplateToggle->(NLS_("bottom"))->(NLS_("unattached")) put(s,4,advancedNormalTemplateToggle) set(advancedNormalTemplateToggle, useTemplateNameSelected) advancedTemplateLabel= label(theBox, LS_("String_Template_name",NLSTEMP_("Template name:"))) advancedTemplateLabel->(NLS_("left"))->(NLS_("inside"))->theTab advancedTemplateLabel->(NLS_("right"))->(NLS_("unattached")) advancedTemplateLabel->(NLS_("top"))->(NLS_("spaced"))->advancedNormalTemplateToggle advancedTemplateLabel->(NLS_("bottom"))->(NLS_("unattached")) put(s,5,advancedTemplateLabel) templatesDir = getTemplatesDirectory() if (null templatesDir) { templatesDir = (NLS_("normal.dot")) } else { templatesDir = templatesDir (NLS_("normal.dot")) } string templateFilter = (NLS_("*.dot")) string templateDescription = LS_("String_Word_Template",NLSTEMP_("Word Template")) if (wordMajorVersion >= 12) { templateFilter = (NLS_("*.dotx|*.dot")) templateDescription = LS_("String_Word_Template_Word_97_2003_Template",NLSTEMP_("Word Template|Word 97-2003 Template")) } advancedTemplateName = fileName(theBox, templatesDir, templateFilter, templateDescription, false) advancedTemplateName->(NLS_("left"))->(NLS_("inside"))->theTab advancedTemplateName->(NLS_("right"))->(NLS_("unattached")) advancedTemplateName->(NLS_("top"))->(NLS_("spaced"))->advancedTemplateLabel advancedTemplateName->(NLS_("bottom"))->(NLS_("unattached")) put(s,6,advancedTemplateName) useHorizontalLinesToggle = toggle(theBox, LS_("String_Use_horizontal_line_separators_in_book_layout_exports",NLSTEMP_("Use horizontal line separators in book layout exports")), useHorizontalLines) useHorizontalLinesToggle->(NLS_("left"))->(NLS_("inside"))->theTab useHorizontalLinesToggle->(NLS_("right"))->(NLS_("unattached")) useHorizontalLinesToggle->(NLS_("top"))->(NLS_("spaced"))->advancedTemplateName useHorizontalLinesToggle->(NLS_("bottom"))->(NLS_("unattached")) put (s, 7, useHorizontalLinesToggle) saveEveryNObjectsToggle = toggle(theBox, LS_("String_Number_of_objects_after_which_to_save_Word_Document",NLSTEMP_("Number of objects after which to save Word Document")), saveEveryNObjects) saveEveryNObjectsToggle->(NLS_("left"))->(NLS_("inside"))->theTab saveEveryNObjectsToggle->(NLS_("right"))->(NLS_("unattached")) saveEveryNObjectsToggle->(NLS_("top"))->(NLS_("spaced"))->useHorizontalLinesToggle saveEveryNObjectsToggle->(NLS_("bottom"))->(NLS_("inside"))->theTab put (s, 8, saveEveryNObjectsToggle) set(saveEveryNObjectsToggle, saveEveryNSelected) saveEveryNObjectsField = field(theBox, (NLS_("")), saveEveryN (NLS_("")), 5) saveEveryNObjectsField->(NLS_("left"))->(NLS_("flush"))->saveEveryNObjectsToggle saveEveryNObjectsField->(NLS_("right"))->(NLS_("unattached")) saveEveryNObjectsField->(NLS_("top"))->(NLS_("spaced"))->useHorizontalLinesToggle saveEveryNObjectsField->(NLS_("bottom"))->(NLS_("unattached")) put (s, 9, saveEveryNObjectsField) inactive advancedTemplateName inactive advancedTemplateLabel inactive saveEveryNObjectsField } bool userExportOnClose(DB exportBox) { return true } //value of the attribute Toggle itfui2.inc file is called in the //function 'userExportCode' so itfui2.inc is included above the userExportCode function. #include // increase the size of the main db dbHeight = 350 bool userExportCode(string fname, int layout, bool includeHeadings, bool warnUnregOLE, DB exportBox) { issueWarnings = warnUnregOLE autoformatTableOutput = get autoformatToggle ignoreDOORSTableBorders = get ignoreBordersToggle doStyleMapping = get styleMappingToggle useParaStyle = get useStyleToggle //includeEmptyAttributes stores whether the checkbox is ticked or not includeEmptyAttributes = get exportAttributeToggle useNormalTemplate = get advancedNormalTemplateToggle if (!useNormalTemplate) { templateName = get advancedTemplateName if (null templateName) { warningBox (LS_("String_If_you_are_not_using_normal_dot_you_must_supply_the_name_in_then_configured_Word_templates_directory",NLSTEMP_("If you are not using normal.dot you must supply the name in the\nconfigured Word templates directory"))) halt } if (!fileExists_ templateName) { warningBox dxlStrformat(LS_("String_The_template_s_does_not_exist_n_Please_select_a_template_with_full_path_name_before_continuing",NLSTEMP_("The template '%s' does not exist.\nPlease select a template (with full path name) before continuing.")), templateName) halt } } useHorizontalLines = get useHorizontalLinesToggle includeHeadingNumbers = includeHeadings saveEveryNObjects = get saveEveryNObjectsToggle if (saveEveryNObjects) { string numberString = get saveEveryNObjectsField if (isGoodPosInt(numberString)) { saveEveryN = intOf(numberString) } else { errorBox dxlStrformat(LS_("String_Cannot_save_after_every_s_objects_n_Please_specify_a_positive_integer",NLSTEMP_("Cannot save after every %s objects.\nPlease specify a positive integer.")), numberString) halt } } createWordApplication() if (objWord == null) { return false } initErrorLogging Buffer b = create setRichClip b delete b wordDoExportVBA(exportBox, layout) showErrorLog return true } //Contains the implementation for the callback associated with the Tab #include if ((current Module) != null) { // check status if ((current Object) != null) { makeExporterUI(wordTitle, helpExportWord, false, false, null, null) //Since the plain exporters Genral Tab should show a special toggle box change //the default callback association and associate a new one set(exportTab, exportTabSelectedForSpecial) exportTabSelectedForSpecial exportTab block exportBox } else { ack LS_("String_There_are_no_objects_in_the_current_view",NLSTEMP_("There are no objects in the current view.")) } } else { ack LS_("String_There_is_no_current_module_to_export",NLSTEMP_("There is no current module to export.")) } urrent modul