// Para Compare Versions with Attributes /* // Para Compare Versions //--------------------------------------------------------------------------- // Function: Compare any two versions of the current module // including attributes in the two versions. //--------------------------------------------------------------------------- //********************************** History ****************************** // Name: Date: // Jürgen Albrecht 2008-01-15 // Reinhold Lauer 2010-10-19 Included added/deleted attributes // Reinhold Lauer 2010-10-29 Added entire main column option // Added unchanged attributes option //--------------------------------------------------------------------------- */ pragma runLim, 0 Module mLaunchingModule = null Stream strmOutput string sCellBorders = "\\clbrdrt\\brdrs\\brdrw15\\brdrcf11 \\clbrdrl\\brdrs\\brdrw15\\brdrcf11 \\clbrdrb\\brdrs\\brdrw15\\brdrcf11 \\clbrdrr\\brdrs\\brdrw15\\brdrcf11 " Regexp hasSlash = regexp "[\\\\]" Regexp hasColorTable = regexp "colortbl[^}]*}" DB dbCompareVersions = null DBE dbeListNewer = null DBE dbeListOlder = null DBE dbeAttrNameList = null DBE dbeOutputFileBrowse = null DBE dbeShowAsMarkup = null DBE dbeShowEntireMainColumn = null DBE dbeShowUnchangedAttributes = null // Add elements to a sorted list if the element is not listed void addElementToList (DBE dbeList, string sNewElementName) { int iElementPosition // 3 to skip Object Heading, Object Short Text, and Object Text for (iElementPosition = 3; iElementPosition < noElems dbeList; iElementPosition++) { string sAttrName = get (dbeList, iElementPosition) if(sAttrName == sNewElementName) return // exists already if(sAttrName > sNewElementName) break // insert here } insert (dbeList, iElementPosition, sNewElementName) set (dbeList, iElementPosition, true) } // Fill the attributes list with module attributes void addModuleAttibutesToList (Module mModule) { AttrDef adAttrDefinition for adAttrDefinition in mModule do { if (adAttrDefinition.module || adAttrDefinition.system) continue addElementToList (dbeAttrNameList, adAttrDefinition.name "") } } // Build a skip list which maps absolute numbers onto their corresponding objects Skip getAbsoluteNumbers(Module mModule) { Skip skResult = create Object oObject for oObject in entire mModule do { if (isDeleted oObject) continue int iAbsultueNumber = oObject."Absolute Number" put (skResult, iAbsultueNumber, oObject) } return skResult } string sPreviousObjectId = "" // Compare an attribute of two objects with same absolute number or agaist a null object bool compareObjects (Object oNewer, oOlder, string sAttrName) { string sObjectId = "" string sObjectNumber = "" Buffer buffNewerAttr = create string sNewerAttr = null Buffer buffOlderAttr = create string sOlderAttr = null Buffer buffAttrDifference = create bool bShowAsMarkup = get dbeShowAsMarkup bool bShowEntireMainColumn = get dbeShowEntireMainColumn bool bShowUnchangedAttributes = get dbeShowUnchangedAttributes bool bAttrChanged = false bool bShowMainColumn = false sNewerAttr = probeAttribute_(oNewer, sAttrName, false) // get newer attribute if it exists if (!null sNewerAttr) buffNewerAttr = sNewerAttr else buffNewerAttr = "" sOlderAttr = probeAttribute_(oOlder, sAttrName, false) // get older attribute if it exists if (!null sOlderAttr) buffOlderAttr = sOlderAttr else buffOlderAttr = "" if (buffNewerAttr != buffOlderAttr) bAttrChanged = true // attribute changed if (!null oNewer) { sObjectId = identifier oNewer // get the identifer if (sAttrName == "Object Heading") sObjectNumber = " - " number oNewer } else { sObjectId = identifier oOlder if (sAttrName == "Object Heading") sObjectNumber = " - " number oOlder } if (bShowEntireMainColumn) { if (sAttrName == "Object Heading" || sAttrName == "Object Short Text" || sAttrName == "Object Text") { bShowMainColumn = length buffNewerAttr > 0 // don't show empty text } } if (length buffNewerAttr == 0) bShowUnchangedAttributes = false // don't show empty text if (bAttrChanged || bShowMainColumn || bShowUnchangedAttributes) { if (sObjectId == sPreviousObjectId) sObjectId = "" else sPreviousObjectId = sObjectId strmOutput << "\\trowd \\trgaph108\\trleft-108\\trkeep" if (bShowAsMarkup) { diff (buffAttrDifference, buffOlderAttr, buffNewerAttr, "\\cf1\\strike ", "\\cf3 ") string sRTFragment if (hasColorTable buffAttrDifference) { sRTFragment = buffAttrDifference[end 0 + 1:(length buffAttrDifference) - 3] } else { sRTFragment = richTextFragment stringOf buffAttrDifference } strmOutput << sCellBorders "\\cellx1026 " sCellBorders "\\cellx2727 " sCellBorders "\\cellx9531\n" if (sAttrName == "Object Heading") { strmOutput << "\\intbl \\b \\fs16 " sObjectId "\\cell \\cf2 " sAttrName sObjectNumber "\\cf0 \\cell " sRTFragment "\\b0\\cell\\row\n" } else { strmOutput << "\\intbl \\b \\fs16 " sObjectId "\\b0 \\cell \\cf2 " sAttrName sObjectNumber "\\cf0 \\cell " sRTFragment "\\cell\\row\n" } } else { sNewerAttr = richTextFragment probeRichAttr_(oNewer, sAttrName, false) sOlderAttr = richTextFragment probeRichAttr_(oOlder, sAttrName, false) strmOutput << sCellBorders "\\cellx1026 " sCellBorders "\\cellx2727 " sCellBorders "\\cellx6129 " sCellBorders "\\cellx9531\n" if (sAttrName == "Object Heading") { strmOutput << "\\intbl \\b \\fs16 " sObjectId "\\cell \\cf2 " sAttrName sObjectNumber "\\cf0 \\cell " sOlderAttr "\\cell " sNewerAttr "\\b0\\cell\\row\n" } else { strmOutput << "\\intbl \\b \\fs16 " sObjectId "\\b0 \\cell \\cf2 " sAttrName sObjectNumber "\\cf0 \\cell " sOlderAttr "\\cell " sNewerAttr "\\cell\\row\n" } } } delete buffNewerAttr delete buffOlderAttr delete buffAttrDifference return bAttrChanged } // Compare the two versions of the module void applyCompareVersions (DB dbKlick) { string sNewerName = get dbeListNewer // baseline name string sOlderName = get dbeListOlder string sOutputFileName = get dbeOutputFileBrowse string sCurrentModuleName = mLaunchingModule."Name" if (!hasSlash sOutputFileName) { sOutputFileName = currentDirectory "\\" sOutputFileName } strmOutput = write sOutputFileName // file header strmOutput << "{\\rtf1\\deff0{\\fonttbl{\\f0\\fswiss\\fcharset177 Times New Roman;}}{\\colortbl ;\\red255\\green0\\blue0;\\red0\\green125\\blue0;\\red0\\green0\\blue255;}\n" strmOutput << "\\paperw11906\\paperh16838\\margl1134\\margr567\\margt1134\\margb851\\headery567\\footery567\n" strmOutput << "\\b \\ul \\fs24 Para Compare Versions in " sCurrentModuleName "\\ul0 \\b0 \\par \\par\n" Baseline bBaseline Baseline blNewer Baseline blOlder for bBaseline in mLaunchingModule do { string sBaseline = (major bBaseline) "." (minor bBaseline) " " (suffix bBaseline) if (sNewerName == sBaseline) blNewer = bBaseline if (sOlderName == sBaseline) blOlder = bBaseline } Module mNewer Module mOlder if (get dbeListNewer == 0) { mNewer = mLaunchingModule // the newer module is the current version } else { progressStart (dbCompareVersions, "Para Compare Versions", "", 1) progressMessage "Loading newer version..." mNewer = load (blNewer, false) addModuleAttibutesToList(mNewer) progressStop } progressStart (dbCompareVersions, "Para Compare Versions", "", 1) progressMessage "Loading older version..." mOlder = load (blOlder, false) addModuleAttibutesToList(mOlder) progressStop int iObjectCount = 0 int iObjectsQuantity = 0 int iDifferences = 0 string sAttrName // Skip skNewerAbsoluteNumbers = getAbsoluteNumbers mNewer // build caches of absnos -> objects Skip skOlderAbsoluteNumbers = getAbsoluteNumbers mOlder // show newer attributes strmOutput << "\\fs24 \\ul Objects in both versions \\ul0 \\par \\par\n" strmOutput << "\\trowd \\trgaph108\\trleft-108\\trhdr" strmOutput << sCellBorders "\\cellx1026 " sCellBorders "\\cellx2727 " sCellBorders "\\cellx6129 " sCellBorders "\\cellx9531\n" strmOutput << "\\intbl \\b \\fs20 Identifier\\cell Attribute\\cell Older Version\\par " sOlderName " \\cell Newer Version\\par " sNewerName "\\b0 \\cell\\row\n" Object oNewer for oNewer in entire mNewer do { if (isDeleted oNewer) continue iObjectsQuantity++ } progressStart (dbCompareVersions, "Para Compare Versions", "", iObjectsQuantity) progressMessage "Comparing attributes of newer objects..." for oNewer in entire mNewer do // sorted according to order in module { if (isDeleted oNewer) continue progressStep iObjectCount++ Object oOlder = null int iNewerAbsoluteNumber = oNewer."Absolute Number" if(find(skOlderAbsoluteNumbers, iNewerAbsoluteNumber, oOlder)) { delete (skOlderAbsoluteNumbers, iNewerAbsoluteNumber) } for sAttrName in dbeAttrNameList do { if(compareObjects(oNewer, oOlder, sAttrName)) iDifferences++ } } progressStop // show deleted older attributes strmOutput << "\\pard \\fs24 \\par \\ul Objects only in older version \\ul0 \\par \\par\n" strmOutput << "\\trowd \\trgaph108\\trleft-108\\trhdr" strmOutput << sCellBorders "\\cellx1026 " sCellBorders "\\cellx2727 " sCellBorders "\\cellx6129 " sCellBorders "\\cellx9531\n" strmOutput << "\\intbl \\b \\fs20 Identifier\\cell Attribute\\cell Older Version\\par " sOlderName " \\cell Newer Version\\par " sNewerName "\\b0 \\cell\\row\n" Object oOlder for oOlder in skOlderAbsoluteNumbers do { iObjectsQuantity++ } progressStart (dbCompareVersions, "Para Compare Versions", "", iObjectsQuantity) progressMessage "Checking attributes of deleted older objects..." oNewer = null // no newer object exsist iObjectCount = 0 for oOlder in skOlderAbsoluteNumbers do // sorted according to absolute number { progressStep iObjectCount++ for sAttrName in dbeAttrNameList do { if(compareObjects(oNewer, oOlder, sAttrName)) iDifferences++ } } progressStop strmOutput << "\\pard \\fs24 \\par " iDifferences " differences found.\\par \\par }" close strmOutput //delete skNewerAbsoluteNumbers // delete caches delete skOlderAbsoluteNumbers if (mNewer != mLaunchingModule) close mNewer close mOlder current = mLaunchingModule // return to former current module } // Make sure that the newer version is really newer void checkVersionSelection(DBE dbeKlick) { int iNewerIndex = get dbeListNewer // position in list int iOlderIndex = get dbeListOlder if (dbeKlick == dbeListOlder && iNewerIndex > iOlderIndex) set (dbeListNewer, iOlderIndex) if (dbeKlick == dbeListNewer && iNewerIndex > iOlderIndex) set (dbeListOlder, iNewerIndex) } // Main program mLaunchingModule = current if (null mLaunchingModule) { ack "Para Compare Versions requires a current module!\nStart it from the current version of a module..." halt } if (baseline mLaunchingModule) { ack "Para Compare Versions can not be started from a baseline!\nStart it from the current version of the module..." halt } Baseline bBaseline int iBaselineCount = 0 for bBaseline in mLaunchingModule do { iBaselineCount++ } if (iBaselineCount == 0) { ack "Para Compare Versions did not find a version to compare to!\nMake a baseline..." halt } // Dialog for selecting two baselines for comparison int iHalfWidth = 275 string sCurrentModuleName = mLaunchingModule."Name" string strEmptyArr[] = {} dbCompareVersions = create "Para Compare Versions in " sCurrentModuleName "" dbeListNewer = list (dbCompareVersions, "Newer version", iHalfWidth, 9, strEmptyArr) dbeListNewer->"left"->"form" dbeListNewer->"right"->"unattached" dbeListOlder = list(dbCompareVersions, "Older version to compare with", iHalfWidth, 9, strEmptyArr) dbeListOlder->"left"->"form" dbeListOlder->"right"->"unattached" dbeAttrNameList = multiList (dbCompareVersions, "Attributes to compare", iHalfWidth, 20, strEmptyArr) dbeAttrNameList->"top"->"aligned"->dbeListNewer dbeAttrNameList->"left"->"flush"->dbeListNewer dbeAttrNameList->"right"->"unattached" dbeShowAsMarkup = toggle (dbCompareVersions,"Show changes as markup", true) dbeShowAsMarkup->"top"->"flush"->dbeListOlder beside dbCompareVersions dbeShowEntireMainColumn = toggle (dbCompareVersions,"Show entire main column", true) dbeShowUnchangedAttributes= toggle (dbCompareVersions,"Show unchanged attributes", true) left dbCompareVersions dbeOutputFileBrowse = fileName (dbCompareVersions, "Output File ", "D:\\Doors Export\\Para Compare Versions " sCurrentModuleName ".rtf", "*.rtf", "Rich Text Files", false) dbeOutputFileBrowse->"left"->"form" // dummy to get the copy right in the right place DBE dbeDummy = label (dbCompareVersions, "") dbeDummy->"top"->"spaced"->dbeOutputFileBrowse dbeDummy->"left"->"form" DBE dbeCopyRight = label (dbCompareVersions, "Copyright (C) Reinhold Lauer 2010") dbeCopyRight->"bottom"->"spaced"->dbeDummy dbeCopyRight->"left"->"form" inactive (dbeCopyRight) apply (dbCompareVersions, "Compare", applyCompareVersions) realize (dbCompareVersions, 0, 0) // we realize so that the lists can be populated using insert // fill the newer and older version lists int iListLength = 0 for bBaseline in mLaunchingModule do { string sBaseline = (major bBaseline) "." (minor bBaseline) " " (suffix bBaseline) insert (dbeListNewer, 0, sBaseline) insert (dbeListOlder, 0, sBaseline) iListLength++ } insert (dbeListNewer, 0, "current at " today "") // add the current version delete (dbeListNewer, iListLength) // the newer version can not be the first version set (dbeListNewer, 0) set (dbeListOlder, 0) set (dbeListNewer, checkVersionSelection, checkVersionSelection) set (dbeListOlder, checkVersionSelection, checkVersionSelection) // add the attributes to the list insert (dbeAttrNameList, 0, "Object Heading") set (dbeAttrNameList, 0, true) insert (dbeAttrNameList, 1, "Object Short Text") set (dbeAttrNameList, 1, true) insert (dbeAttrNameList, 2, "Object Text") set (dbeAttrNameList, 2, true) addModuleAttibutesToList (mLaunchingModule) show dbCompareVersionsingModule) show dbCompareVersio