Hello,
Is there a way to visually show the differences of OLE objects?
I have seen similar questions, but have not seen a clear answer. |
Re: Comparing OLE Objects |
Re: Comparing OLE Objects doors36677 - Thu May 06 07:05:21 EDT 2010 here is my id on yahoo "aakhws" Thanks a lot |
Re: Comparing OLE Objects richTextWithOle(o."Object Text") == richTextWithOle(o."Reviewed Text") -Jim |
Re: Comparing OLE Objects SystemAdmin - Tue Feb 21 21:34:25 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Attachments attachment_14792846_oleObjects.inc |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
I have run into an issue which may be of interest to others. Often users will import a file as an OLE into DOORS. For example, a figure is created or placed into a word document and then the word document is imported as an OLE. This results in an OLE embedded in an OLE. Mathias has provided functions that unlock the core data in the outer OLE, but to get to the core data of the inner OLE more work is required. We have told our users to import the core OLEs only, but that process was not always followed. At this point in our process even "invisible" changes to objects cannot be approved. In theory, OLEs could be combined together and embedded into OLEs that are combined with other OLEs, creating a complex hierarchy of OLEs contained within OLEs. A perfect utility would systematically decode all of this and compare appropriate OLE chunks hierarchically and then pop out a "definitive" result. The simplest strategy might be to look for an embedded OLE and then create a message that basically says that the comparison is not possible, that a visual inspection is necessary, or some such approach. An intermediate approach would be to limit the digging at some point and if there is still further digging necessary, to give up and output a message telling the user that the OLE hierarchy is too complex to process. I'll be looking into strategies to get to the "core" OLE(s) where necessary to perform a more perfect comparison, but to limit the digging at some point.
|
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Comparing OLE Objects clhoover - Tue Feb 05 11:38:20 EST 2013 Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 06 08:02:18 EST 2013 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
and how you can compare Doors pictures? Picture are not Ole Objects?
Like this?
For comparing OleObject is not enough to compare the length ? |
Re: Comparing OLE Objects bungle_77 - Thu Jan 02 07:00:00 EST 2014 and how you can compare Doors pictures? Picture are not Ole Objects?
Like this?
For comparing OleObject is not enough to compare the length ? For OLE objects it is a good first step to compare the length of the OLE to check if there has been a change. So if there is a length change (as with pictures) there is a definitive change. However it is easy to think about cases where the OLE object length stays the same, while the content is different. Think about two pictures with the same size and different content. In real life this is of course seldom but thinkable. So it is really a question if you need 100% security in comparison. So to compare pictures it is also not enough to compare the picture filenames. I ended up using openPictFile to get a Stream to the picture files, first comparing the length of the pictures (using a Stat on the Stream) and only if the picture sizes are equal comparing the picture data char by char (be aware of null characters, which will not allow you to read the full data of a picture to a buffer). Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Thu Jan 02 12:43:22 EST 2014 For OLE objects it is a good first step to compare the length of the OLE to check if there has been a change. So if there is a length change (as with pictures) there is a definitive change. However it is easy to think about cases where the OLE object length stays the same, while the content is different. Think about two pictures with the same size and different content. In real life this is of course seldom but thinkable. So it is really a question if you need 100% security in comparison. So to compare pictures it is also not enough to compare the picture filenames. I ended up using openPictFile to get a Stream to the picture files, first comparing the length of the pictures (using a Stat on the Stream) and only if the picture sizes are equal comparing the picture data char by char (be aware of null characters, which will not allow you to read the full data of a picture to a buffer). Regards, Mathias Thanks a lot Mathias for your explanation, it was very precious! my problem is that i have to make the comparison of n attributes in the code of a DXL attribute so the computation can't be too heavy. Reading all the threads about this topic i am realizing you need to make a very complext comparison and you can't be 100% sure to detect the change. In my case in the 99% of the case the objects to compare are identical because i compare a requirement and a clone of a requirement. I am evaluating if it's enough to compare the length of the olebjects (obviously after a check on the text) being aware of the risk that i can't detect the change in the 1% of the cases. Do you think is implementable all your comparison in a DXL Attribute? If i have the constraint that the OleObject shall be only single picture, with the code you wrote above can i be 100% sure to detect everything? |
Re: Comparing OLE Objects bungle_77 - Fri Jan 03 04:37:44 EST 2014 Thanks a lot Mathias for your explanation, it was very precious! my problem is that i have to make the comparison of n attributes in the code of a DXL attribute so the computation can't be too heavy. Reading all the threads about this topic i am realizing you need to make a very complext comparison and you can't be 100% sure to detect the change. In my case in the 99% of the case the objects to compare are identical because i compare a requirement and a clone of a requirement. I am evaluating if it's enough to compare the length of the olebjects (obviously after a check on the text) being aware of the risk that i can't detect the change in the 1% of the cases. Do you think is implementable all your comparison in a DXL Attribute? If i have the constraint that the OleObject shall be only single picture, with the code you wrote above can i be 100% sure to detect everything? Regarding the detection of changes:
Regarding the use of DXL Attributes. I would not use them for this purpose. You need to have write access to the module to create it and it will lock the module for quite some time when opening. With BranchManager we use a GUI-Backed layout DXL for this purpose and a timer for the calculation of the comparison. This allows you to calculate the comparison in background, the user does not need to wait, you can also use it in read only mode, etc. You can read over it here: Here is a more involved example (for the code comments see the original post):
string colCode (string sFileName)
{
Buffer bufFile = create()
int i; for (i = 0; i < length sFileName; i++) {
if (sFileName[i] == '\\') bufFile += "\\"
bufFile += sFileName[i]
}
string sResult = "
noError()
// read the memory address from the file
Stream x = read \"" (stringOf bufFile) "\"
lastError()
// if the file exists we will get a Stream here
if (!null x) {
// read the memory address
int adSkip = 0
x >> adSkip
if (adSkip != 0)
{
Skip sk = addr_ adSkip
int nr = obj. \"Absolute Number\"
string sDisplayVal = \"\"
if (find (sk, nr, sDisplayVal)) {
display sDisplayVal
}
} else {
// now what?
}
} else {
// You might want to show some dummy text here,
// that the cache does not exist
}
"
delete bufFile
return sResult
}
// This is our cache. Key = AbsNo Value = string to display
Skip skBuffer = create()
string sCacheFileName = tempFileName ()
Stream x = write sCacheFileName
x << ((addr_ skBuffer) int) ""
close x
Column c = insert column 0 // insert column
dxl (c, colCode(sCacheFileName) )
title(c, "GUI Backed Layout DXL")
void onClose (DB x) {
deleteFile sCacheFileName
hide x
// delete the column, or let it show its dummy text
delete c
}
bool bPause = false;
void btPauseCallback (DB x) {
bPause = !bPause;
}
// Make a skip with all object in it
Skip skObjects = create();
int iCount = 0, iCurrent = 0; Object o;
for o in entire current Module do put(skObjects, iCount++, o)
// ***************** Put your calculation for Object o here ***************
int gCount = 0
string doCalculation (Object o) {
string sResult = "Hi I am Object " (o."Absolute Number") " and I was updated at " (gCount++) "!\n"
return sResult
}
// ************************************************************************
// This timer callback is responsible for background processing
void timerCallback(DBE x) {
// to be able to process more than one object for each timer call
// we measure the time and stop processing after 50% of the timer
// callback time (100 ms - 50ms = 50ms)
int iStartTime = getTickCount_()
iCurrent ++
// uncomment this if you only want to calculate each object once
// if (iCurrent >= iCount) return
// process pause state
if (bPause) return
// in the example we use this for recalculating from start,
// once we finished calculation for each object
iCurrent = iCurrent % iCount;
// work for 50 ms
while (getTickCount_() - iStartTime < 50) {
// get the object for the calculation
Object oCurrent = null
if (find (skObjects, iCurrent, oCurrent)) {
int nr = oCurrent."Absolute Number"
string s = doCalculation(oCurrent);
put (skBuffer, nr, s, true);
} else {
// wtf?
}
}
// we use this to interactively refresh the calculation because
// otherwise layout DXL is only updated on each click
// you dont need this, you can also apply some tricks here
// to check if the object is visible and only refresh in this case
refresh (current Module)
}
DB gui = centered "Calculating ... "
timer(gui, 0.1, timerCallback, "Calculation")
apply(gui, "Pause", btPauseCallback)
close (gui, true, onClose)
realize gui
setSize(gui, 300, 100)
show gui
Hope that helps, regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Sat Jan 04 15:47:41 EST 2014 Regarding the detection of changes:
Regarding the use of DXL Attributes. I would not use them for this purpose. You need to have write access to the module to create it and it will lock the module for quite some time when opening. With BranchManager we use a GUI-Backed layout DXL for this purpose and a timer for the calculation of the comparison. This allows you to calculate the comparison in background, the user does not need to wait, you can also use it in read only mode, etc. You can read over it here: Here is a more involved example (for the code comments see the original post):
string colCode (string sFileName)
{
Buffer bufFile = create()
int i; for (i = 0; i < length sFileName; i++) {
if (sFileName[i] == '\\') bufFile += "\\"
bufFile += sFileName[i]
}
string sResult = "
noError()
// read the memory address from the file
Stream x = read \"" (stringOf bufFile) "\"
lastError()
// if the file exists we will get a Stream here
if (!null x) {
// read the memory address
int adSkip = 0
x >> adSkip
if (adSkip != 0)
{
Skip sk = addr_ adSkip
int nr = obj. \"Absolute Number\"
string sDisplayVal = \"\"
if (find (sk, nr, sDisplayVal)) {
display sDisplayVal
}
} else {
// now what?
}
} else {
// You might want to show some dummy text here,
// that the cache does not exist
}
"
delete bufFile
return sResult
}
// This is our cache. Key = AbsNo Value = string to display
Skip skBuffer = create()
string sCacheFileName = tempFileName ()
Stream x = write sCacheFileName
x << ((addr_ skBuffer) int) ""
close x
Column c = insert column 0 // insert column
dxl (c, colCode(sCacheFileName) )
title(c, "GUI Backed Layout DXL")
void onClose (DB x) {
deleteFile sCacheFileName
hide x
// delete the column, or let it show its dummy text
delete c
}
bool bPause = false;
void btPauseCallback (DB x) {
bPause = !bPause;
}
// Make a skip with all object in it
Skip skObjects = create();
int iCount = 0, iCurrent = 0; Object o;
for o in entire current Module do put(skObjects, iCount++, o)
// ***************** Put your calculation for Object o here ***************
int gCount = 0
string doCalculation (Object o) {
string sResult = "Hi I am Object " (o."Absolute Number") " and I was updated at " (gCount++) "!\n"
return sResult
}
// ************************************************************************
// This timer callback is responsible for background processing
void timerCallback(DBE x) {
// to be able to process more than one object for each timer call
// we measure the time and stop processing after 50% of the timer
// callback time (100 ms - 50ms = 50ms)
int iStartTime = getTickCount_()
iCurrent ++
// uncomment this if you only want to calculate each object once
// if (iCurrent >= iCount) return
// process pause state
if (bPause) return
// in the example we use this for recalculating from start,
// once we finished calculation for each object
iCurrent = iCurrent % iCount;
// work for 50 ms
while (getTickCount_() - iStartTime < 50) {
// get the object for the calculation
Object oCurrent = null
if (find (skObjects, iCurrent, oCurrent)) {
int nr = oCurrent."Absolute Number"
string s = doCalculation(oCurrent);
put (skBuffer, nr, s, true);
} else {
// wtf?
}
}
// we use this to interactively refresh the calculation because
// otherwise layout DXL is only updated on each click
// you dont need this, you can also apply some tricks here
// to check if the object is visible and only refresh in this case
refresh (current Module)
}
DB gui = centered "Calculating ... "
timer(gui, 0.1, timerCallback, "Calculation")
apply(gui, "Pause", btPauseCallback)
close (gui, true, onClose)
realize gui
setSize(gui, 300, 100)
show gui
Hope that helps, regards, Mathias thanks a lot Mathias, your post is really precious! |
Re: Comparing OLE Objects bungle_77 - Thu Jan 02 07:00:00 EST 2014 and how you can compare Doors pictures? Picture are not Ole Objects?
Like this?
For comparing OleObject is not enough to compare the length ? Length of Picture is good enough. Length of OLE I think is not good enough since someone can reasonably open the OLE object and change "This" to "That" without any change in length. Byte-by-Byte checks I think will fail for both, even when there is no actual change. IIRC years ago, I would copy and OLE, paste to another object, then compare them byte-by-byte and they were not the same. I think it was due to "empty" space in the OLE that gets whatever happens to be in memory or disk at the time of the read. I went through this several years ago and gave up; using a glorified "Last Modified On" approach to figure out if two objecs that were originally identical still were. I found that I never failed to detect a change but I did indeed detect "changes" that didn't actually change anything (since you can "edit" an attr-value and save it, even if you don't actually make a change; and of course you can change and then change back). I would also like to point out that can, if need be, do this:
-Louie |
Re: Comparing OLE Objects llandale - Tue Jan 07 16:24:55 EST 2014 Length of Picture is good enough. Length of OLE I think is not good enough since someone can reasonably open the OLE object and change "This" to "That" without any change in length. Byte-by-Byte checks I think will fail for both, even when there is no actual change. IIRC years ago, I would copy and OLE, paste to another object, then compare them byte-by-byte and they were not the same. I think it was due to "empty" space in the OLE that gets whatever happens to be in memory or disk at the time of the read. I went through this several years ago and gave up; using a glorified "Last Modified On" approach to figure out if two objecs that were originally identical still were. I found that I never failed to detect a change but I did indeed detect "changes" that didn't actually change anything (since you can "edit" an attr-value and save it, even if you don't actually make a change; and of course you can change and then change back). I would also like to point out that can, if need be, do this:
-Louie Hi Louie... Byte by Byte comparison works - for the picture part of an OLE object as well as for DOORS Picture objects. I think the problem of random data only applies to the data part of an OLE object, that means static metafiles embedded as OLE object should also not change. Do you have an example that shows differently? I would also be careful with uncompressed pictures (e.g. bmp), because their size only dependes on their dimensions. So a length comparison will fail as long as the changed picture stays the same size. Last Modified on works well for comparing baselines inside the same module, however for two modules it is more difficult because both objects could actually have changed. Also take care with attributes that have/had the last modification date turned off (I know, who does something like that?). Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Wed Jan 08 04:01:17 EST 2014 Hi Louie... Byte by Byte comparison works - for the picture part of an OLE object as well as for DOORS Picture objects. I think the problem of random data only applies to the data part of an OLE object, that means static metafiles embedded as OLE object should also not change. Do you have an example that shows differently? I would also be careful with uncompressed pictures (e.g. bmp), because their size only dependes on their dimensions. So a length comparison will fail as long as the changed picture stays the same size. Last Modified on works well for comparing baselines inside the same module, however for two modules it is more difficult because both objects could actually have changed. Also take care with attributes that have/had the last modification date turned off (I know, who does something like that?). Regards, Mathias Don't understand nuance of "picture part" vis-a-vis "data part" of the OLE. I was getting a handle on the EmbeddedOleObject, then reading into a Buffer. I was definately not "opening" the OLE and peeking inside. Effort to find out if OLE changed was 11 years ago. My observations above WERE valid but perhaps no longer. As I said I gave up and used a glorified LastModifiedOn approach, which included adding a date attribute to the 2nd module "LastVerifiedOn" or something like that. I didn't have a both-objects-changing issue since the target (in my case) was hard locked down. Anyway, looks like there is no reasonably perfect solution. -Louie |
Re: Comparing OLE Objects Wow, this is the endless story. 1) Do we know how functions like "Tools -> compare modules" or ""Exchange module" are working? I mean, are they able to detect correctly changes within OLE? 2) Is there any way to contact IBM or to open them a ticket for future improvements/updates?
Regards, Daniele |
Re: Comparing OLE Objects dacapri - Tue Jan 28 03:34:51 EST 2014 Wow, this is the endless story. 1) Do we know how functions like "Tools -> compare modules" or ""Exchange module" are working? I mean, are they able to detect correctly changes within OLE? 2) Is there any way to contact IBM or to open them a ticket for future improvements/updates?
Regards, Daniele 1) We know how they work, they do not compare OLE data ... Sometimes they compare modification dates.However the above approach for comparing OLE objects works! So you can detect changes to OLE objects very reliably and fast. 2. Of course. Somebody should create a PR for DOORS with highst priority and title it "DOORS client is changing baselined data" ... Then take the example code here from the forum that proves that when you read the same OLE object from a module several times that you get a different RTF from time to time. The argument would be that baselined data must not change ever. Any argument from IBM about how the DOORS client is not responsible, but Windows or whatever should be met with the argument, that this is about writing RTF to an attribute and getting the same RTF back when you read it. I really wonder if nobody ever created a PR for that and I highly doubt that this is a complex problem to solve on the client side. So my conclusion is, that most people simply do not bother enough about that problem for it to be fixed. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Tue Jan 28 14:00:44 EST 2014 1) We know how they work, they do not compare OLE data ... Sometimes they compare modification dates.However the above approach for comparing OLE objects works! So you can detect changes to OLE objects very reliably and fast. 2. Of course. Somebody should create a PR for DOORS with highst priority and title it "DOORS client is changing baselined data" ... Then take the example code here from the forum that proves that when you read the same OLE object from a module several times that you get a different RTF from time to time. The argument would be that baselined data must not change ever. Any argument from IBM about how the DOORS client is not responsible, but Windows or whatever should be met with the argument, that this is about writing RTF to an attribute and getting the same RTF back when you read it. I really wonder if nobody ever created a PR for that and I highly doubt that this is a complex problem to solve on the client side. So my conclusion is, that most people simply do not bother enough about that problem for it to be fixed. Regards, Mathias Thank you Mathias. I'll first implement your solution and let's see if it will be enough for me. My IBM ID cannot open a PMR,so let's see if somebody else can do it. A colleague of mine wrote to IBM time ago about this problem and they said something like "we know and that's it". :/
Keep in touch.
Bye, |
Re: Comparing OLE Objects Mathias Mamsch - Sat Jan 04 15:47:41 EST 2014 Regarding the detection of changes:
Regarding the use of DXL Attributes. I would not use them for this purpose. You need to have write access to the module to create it and it will lock the module for quite some time when opening. With BranchManager we use a GUI-Backed layout DXL for this purpose and a timer for the calculation of the comparison. This allows you to calculate the comparison in background, the user does not need to wait, you can also use it in read only mode, etc. You can read over it here: Here is a more involved example (for the code comments see the original post):
string colCode (string sFileName)
{
Buffer bufFile = create()
int i; for (i = 0; i < length sFileName; i++) {
if (sFileName[i] == '\\') bufFile += "\\"
bufFile += sFileName[i]
}
string sResult = "
noError()
// read the memory address from the file
Stream x = read \"" (stringOf bufFile) "\"
lastError()
// if the file exists we will get a Stream here
if (!null x) {
// read the memory address
int adSkip = 0
x >> adSkip
if (adSkip != 0)
{
Skip sk = addr_ adSkip
int nr = obj. \"Absolute Number\"
string sDisplayVal = \"\"
if (find (sk, nr, sDisplayVal)) {
display sDisplayVal
}
} else {
// now what?
}
} else {
// You might want to show some dummy text here,
// that the cache does not exist
}
"
delete bufFile
return sResult
}
// This is our cache. Key = AbsNo Value = string to display
Skip skBuffer = create()
string sCacheFileName = tempFileName ()
Stream x = write sCacheFileName
x << ((addr_ skBuffer) int) ""
close x
Column c = insert column 0 // insert column
dxl (c, colCode(sCacheFileName) )
title(c, "GUI Backed Layout DXL")
void onClose (DB x) {
deleteFile sCacheFileName
hide x
// delete the column, or let it show its dummy text
delete c
}
bool bPause = false;
void btPauseCallback (DB x) {
bPause = !bPause;
}
// Make a skip with all object in it
Skip skObjects = create();
int iCount = 0, iCurrent = 0; Object o;
for o in entire current Module do put(skObjects, iCount++, o)
// ***************** Put your calculation for Object o here ***************
int gCount = 0
string doCalculation (Object o) {
string sResult = "Hi I am Object " (o."Absolute Number") " and I was updated at " (gCount++) "!\n"
return sResult
}
// ************************************************************************
// This timer callback is responsible for background processing
void timerCallback(DBE x) {
// to be able to process more than one object for each timer call
// we measure the time and stop processing after 50% of the timer
// callback time (100 ms - 50ms = 50ms)
int iStartTime = getTickCount_()
iCurrent ++
// uncomment this if you only want to calculate each object once
// if (iCurrent >= iCount) return
// process pause state
if (bPause) return
// in the example we use this for recalculating from start,
// once we finished calculation for each object
iCurrent = iCurrent % iCount;
// work for 50 ms
while (getTickCount_() - iStartTime < 50) {
// get the object for the calculation
Object oCurrent = null
if (find (skObjects, iCurrent, oCurrent)) {
int nr = oCurrent."Absolute Number"
string s = doCalculation(oCurrent);
put (skBuffer, nr, s, true);
} else {
// wtf?
}
}
// we use this to interactively refresh the calculation because
// otherwise layout DXL is only updated on each click
// you dont need this, you can also apply some tricks here
// to check if the object is visible and only refresh in this case
refresh (current Module)
}
DB gui = centered "Calculating ... "
timer(gui, 0.1, timerCallback, "Calculation")
apply(gui, "Pause", btPauseCallback)
close (gui, true, onClose)
realize gui
setSize(gui, 300, 100)
show gui
Hope that helps, regards, Mathias i have a problem, i do this instruction:
after this instruction if I check the lengths of o_Son."Object Text" e o_Father."Object Text" , they are not the same. How is it possible?
the defference it seems to be the tag "\lang1040" that there is only in o_Son |
Re: Comparing OLE Objects bungle_77 - Mon Feb 03 10:14:40 EST 2014 i have a problem, i do this instruction:
after this instruction if I check the lengths of o_Son."Object Text" e o_Father."Object Text" , they are not the same. How is it possible?
the defference it seems to be the tag "\lang1040" that there is only in o_Son DOORS actively analyses and changes richtext that you assign to an attribute. During this it tries to correct invalid, incomplete or unsupported richtext. If you only assign for example richText "{\b ABC}" (which is not a valid richtext document) DOORS will wrap this automatically in a "{\rtf1\..." header for you. If you concatenate two richtext documents DOORS will also magically know how to display this richtext. Therefore it can be expected that the assignment of a string richText will not yield exactly the same result when reading it again. However you may want to try with: set( o_Son."Object Text", o_Father."Object Text") if it also shows this behaviour. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Mon Feb 03 17:59:09 EST 2014 DOORS actively analyses and changes richtext that you assign to an attribute. During this it tries to correct invalid, incomplete or unsupported richtext. If you only assign for example richText "{\b ABC}" (which is not a valid richtext document) DOORS will wrap this automatically in a "{\rtf1\..." header for you. If you concatenate two richtext documents DOORS will also magically know how to display this richtext. Therefore it can be expected that the assignment of a string richText will not yield exactly the same result when reading it again. However you may want to try with: set( o_Son."Object Text", o_Father."Object Text") if it also shows this behaviour. Regards, Mathias great it works fine. Thanks again |
Re: Comparing OLE Objects Mathias Mamsch - Mon Feb 03 17:59:09 EST 2014 DOORS actively analyses and changes richtext that you assign to an attribute. During this it tries to correct invalid, incomplete or unsupported richtext. If you only assign for example richText "{\b ABC}" (which is not a valid richtext document) DOORS will wrap this automatically in a "{\rtf1\..." header for you. If you concatenate two richtext documents DOORS will also magically know how to display this richtext. Therefore it can be expected that the assignment of a string richText will not yield exactly the same result when reading it again. However you may want to try with: set( o_Son."Object Text", o_Father."Object Text") if it also shows this behaviour. Regards, Mathias is it possible to use the "set" instruction in append? i have several object text with ole that i have to concatenate in one object text |
Re: Comparing OLE Objects dacapri - Thu Jan 30 03:05:37 EST 2014 Thank you Mathias. I'll first implement your solution and let's see if it will be enough for me. My IBM ID cannot open a PMR,so let's see if somebody else can do it. A colleague of mine wrote to IBM time ago about this problem and they said something like "we know and that's it". :/
Keep in touch.
Bye, Hello, Is there a way to visually show the differences of OLE objects?
|
Re: Comparing OLE Objects EHcnck - Tue Feb 03 11:27:17 EST 2015 Hello, Is there a way to visually show the differences of OLE objects?
Hi > Is there a way to visually show the differences of OLE objects? If you mean "Deltas insid the object", then the answer is no, because this deltas can only be evaluated by the programm which has created the ole-object or by a programm which can handle that file format. Such a function inside of doors is impossible, otherwise doors should provide a diff-viewer for more than 100 file formats. Best regards Wolfgang |
Re: Comparing OLE Objects EHcnck - Tue Feb 03 11:27:17 EST 2015 Hello, Is there a way to visually show the differences of OLE objects?
If by visual comparison you mean something like "it shows you both objects and highlights the differences in the picture for you" then the answer is of course NO. You could of course for every type of OLE object code your own "comparison", e.g. take the one OLE object. Store it to a file. Take the second one. Open it. Invoke Word Comparison with the first one. Display the result as a new OLE object. Or you might not want to do that. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
> Until someone pressures me this change is left as an excercise for the reader. May be our chances are sligtly better, if we find a windows api which handles the stuff. Otherwiese we will have the same problem in the next windows version, isn't it? |
Re: Comparing OLE Objects Wolfgang Uhr - Mon Feb 09 10:47:10 EST 2015 > Until someone pressures me this change is left as an excercise for the reader. May be our chances are sligtly better, if we find a windows api which handles the stuff. Otherwiese we will have the same problem in the next windows version, isn't it? Well I guess its more about parsing the OLE object better, than by a single regular expression that assumes an exact representation. As long as we parse the object according to the RTF specification, then we are not dependent on the windows API. But in that very old file there is just a regexp that would assume the representation of an OLE in an exact sequence of control words - and these changed from one RTF component to another. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Just was wondering if happened to update this for the latest version of DOORS? Thank you. |
Re: Comparing OLE Objects EHcnck - Fri Jul 29 16:11:29 EDT 2016 Just was wondering if happened to update this for the latest version of DOORS? Thank you. No. But a fix is easy to apply. Just make a small OLE Object inside a module, and print its richtext ( print richTextWithOle (current Object)."Object Text" ) You will get something like:
{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Tahoma;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\f0\fs20
{
\object\objemb{\*\objclass Package}\objw795\objh810{\*\objdata
....
{\result{\pict\wmetafile8\picw795\pich810\picwgoal795\pichgoal810
0100090000033b0700000200210600000000050000000b0200000000050000000c02350034001c ... Now notice the regular expressions on top of the code: string reHeader = "{\\\\object\\\\objemb{\\\\\\*\\\\objclass ([^}]+)}\\\\objw([^\\\\{}]+)\\\\objh([^\\\\{}]+)"
string picData = "([^}]+)" As long as the regexps match, the code should work fine. If the regexps do not match, you need to extend them. The permanent fix for the issue would be to parse the tags of the picture / object rtf according to the RTF spec, rather than using a simple regexp for parsing the information. Maybe this helps, regards, Mathias |
Re: Comparing OLE Objects EHcnck - Tue Feb 03 11:27:17 EST 2015 Hello, Is there a way to visually show the differences of OLE objects?
Inside of doors I think the routine is named bufCompare or bufferCompare |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
using your code just activating the ole shows as different, is this correct? |
Re: Comparing OLE Objects EHcnck - Tue Sep 26 15:18:23 EDT 2017 using your code just activating the ole shows as different, is this correct? The code will compare the picture data of the OLE objects, so you just get the information "equal" or "not equal" which is solely based on the attribute value buffer. You do not need to show or activate the OLE object to compare this part of the attribute value. You will not get a "diff" though - if you want to know WHAT is different you need to visually compare the pictures side by side. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Tue Sep 26 15:23:47 EDT 2017 The code will compare the picture data of the OLE objects, so you just get the information "equal" or "not equal" which is solely based on the attribute value buffer. You do not need to show or activate the OLE object to compare this part of the attribute value. You will not get a "diff" though - if you want to know WHAT is different you need to visually compare the pictures side by side. Regards, Mathias No what I'm trying to ask is ... by simply activating the OLE nothing else shows the OLE as changed is this the correct behavior? |
Re: Comparing OLE Objects EHcnck - Tue Sep 26 15:30:27 EDT 2017 No what I'm trying to ask is ... by simply activating the OLE nothing else shows the OLE as changed is this the correct behavior? If I understand you correctly you are asking if it is normal behaviour that you cannot find any difference (e.g. after activating the OLE without making changes), although the code tells you there is a difference. That is possible. After all the code compares the picture data of the OLE object and sometimes you get a small shift of the picture, the picture gets a little larger, some unimportant detail of the picture changes. This will all result in a difference, although there might be no content difference. Without going in the specifics of each OLE application, this is as far as you get. If activating the OLE changes the attribute value, then you changed the OLE. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Hello Mathias, Thank you for the code you shared for OLE object comparison. I tried the same code to extract the data part and the picture part of the OLE object. I can extract data part correctly as you have given val = s [match 5] ; x->m_data = val
But picture part extraction as given below, will not extract the complete Picture data. val = s [match 7] ; x->m_picture = val
It only extract "{\pict{\*\picprop I expected it to extract as below
{\result{\pict{\*\picprop}\wmetafile8\picw975\pich810\picwgoal975\pichgoal810 If this gets extracted completely , then only the code below can be used to extract the picture part.
if (rePic val) { Can you please help in this regard, am i going wrong in understanding the code/regexp?
|
Re: Comparing OLE Objects ckulkarni - Wed Jul 18 02:34:23 EDT 2018 Hello Mathias, Thank you for the code you shared for OLE object comparison. I tried the same code to extract the data part and the picture part of the OLE object. I can extract data part correctly as you have given val = s [match 5] ; x->m_data = val
But picture part extraction as given below, will not extract the complete Picture data. val = s [match 7] ; x->m_picture = val
It only extract "{\pict{\*\picprop I expected it to extract as below
{\result{\pict{\*\picprop}\wmetafile8\picw975\pich810\picwgoal975\pichgoal810 If this gets extracted completely , then only the code below can be used to extract the picture part.
if (rePic val) { Can you please help in this regard, am i going wrong in understanding the code/regexp?
Well as far as I can see, the regexp in the code is listed as follows:
string picHeader = "{\\\\pict\\\\([^\\\\]+)(\\\\picw([^\\\\{}]+))?(\\\\pich([^\\\\]+))?\\\\picwgoal([-0-9]+)\\\\pichgoal([-0-9]+)"
string picData = "([^}]+)"
Your picture data is:
{\pict{\*\picprop}\wmetafile8\picw975\pich810\picwgoal975\pichgoal810 As described in the big fat red header, the regular expression needs to be changed, since DOORS has changed its RTF engine since then (or is using the Windows default one which has changed). In your case it does not seem to match the "\*\picprop" element, so it will parse only until \pict { and then then picData will parse the \*\picprop up to the last "}" ... So changing the regexp will work, however it is only a temporary solution. I still wait for somebody to step in, take for example the RTF Tokenizer I made here: and rewrite the OLE Parser to be able to handle any picture / OLE control words in the header and still be able to parse the OLE to the end. Because when you use a regexp, you always apply an order of the control words and any additional control word in the picture will break the parsing which is kind of bad. Maybe you are the one to rewrite the code to be more stable and post it back here? :-) Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Wed Jul 18 03:12:45 EDT 2018 Well as far as I can see, the regexp in the code is listed as follows:
string picHeader = "{\\\\pict\\\\([^\\\\]+)(\\\\picw([^\\\\{}]+))?(\\\\pich([^\\\\]+))?\\\\picwgoal([-0-9]+)\\\\pichgoal([-0-9]+)"
string picData = "([^}]+)"
Your picture data is:
{\pict{\*\picprop}\wmetafile8\picw975\pich810\picwgoal975\pichgoal810 As described in the big fat red header, the regular expression needs to be changed, since DOORS has changed its RTF engine since then (or is using the Windows default one which has changed). In your case it does not seem to match the "\*\picprop" element, so it will parse only until \pict { and then then picData will parse the \*\picprop up to the last "}" ... So changing the regexp will work, however it is only a temporary solution. I still wait for somebody to step in, take for example the RTF Tokenizer I made here: and rewrite the OLE Parser to be able to handle any picture / OLE control words in the header and still be able to parse the OLE to the end. Because when you use a regexp, you always apply an order of the control words and any additional control word in the picture will break the parsing which is kind of bad. Maybe you are the one to rewrite the code to be more stable and post it back here? :-) Regards, Mathias Thank you Mathias,
I have one more doubt There is a regexp given string reResult = "({\\\\result([^}]+)})"
What will be extracted with this expression? I think it should extract the whole picture data as given below
{\result{\pict{\*\picprop}\wmetafile8\picw3840\pich300\picwgoal3840\pichgoal300 But this seems not working as when the same is extracted, the result is val = s [match 6] ; x->m_picture = val Result is: {\result{\pict{\*\picprop} Regards, Champa
|
Re: Comparing OLE Objects ckulkarni - Wed Jul 18 06:58:38 EDT 2018 Thank you Mathias,
I have one more doubt There is a regexp given string reResult = "({\\\\result([^}]+)})"
What will be extracted with this expression? I think it should extract the whole picture data as given below
{\result{\pict{\*\picprop}\wmetafile8\picw3840\pich300\picwgoal3840\pichgoal300 But this seems not working as when the same is extracted, the result is val = s [match 6] ; x->m_picture = val Result is: {\result{\pict{\*\picprop} Regards, Champa
You are probably right. I am not sure how OLE objects looked, when I made the code, but I guess the unnecessary "{pictprop}" tag was not there, so you could get all picture data, by just parsing to the first closing brace } (instead of correctly parsing till the matching closing brace). In any case, the code should probably be rewritten using a tokenizer. The regexps are too fragile. I am a bit disappointed, that nobody who used the OLE comparison code posted it back later after adapting the regexps but then again I never had the feeling with few exceptions that people were giving back to the community after receiving. Regards, Mathias |
Re: Comparing OLE Objects Mathias Mamsch - Wed Feb 22 12:05:20 EST 2012 EDIT: 01/2015 The regular expressions in the Code need to be changed, since DOORS uses on modern platforms a different rich text component which will create a different OLE representation. Until someone pressures me this change is left as an excercise for the reader.
Oh man, thats it, now I am releasing that stupid code as the giveaway of the day. That whole super secrecy thing of the DXL community sometimes really gives me the creeps. The reason why you are experiencing problems is explained here:
OleObjects ol1 = createOleObjects (obj1.an1)
OleObjects ol2 = createOleObjects (obj2.an2)
// If this happens its bad: Then our regular expression in OleObjects.inc is wrong.
if (null ol1 || null ol2) {
reportError("OLEERROR", "Cannot parse OLE Object in " (identifier obj1) "/" (identifier obj2) "\n")
return false
}
// get the picture data of the first OLE object
Buffer pdi1 = picturedata ol1[0]
Buffer pdi2 = picturedata ol2[0]
if (pdi1 == pdi2) print "Equal!"
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Hello Mathias,
I am using the below function to get the rich text for OLE objects string s = richTextWithOle(obj."Object Text") But when I print the string s I am unable to find the picture part. Example Usual format is ...
{\result{\pict{\*\picprop}\wmetafile8\picw3840\pich300\picwgoal3840\pichgoal300 But i am getting ..{\result{\pict{\*\picprop}\wmetafile8\picw3840\pich300\picwgoal3840\pichgoal300}}} The Red color data is missing.
Earlier I used to get the usual format. But recently i am getting the data with missing picture part data(only meta data is displayed) Can you please help me regarding this? |
Re: Comparing OLE Objects ckulkarni - Wed Sep 05 06:43:27 EDT 2018 Hello Mathias,
I am using the below function to get the rich text for OLE objects string s = richTextWithOle(obj."Object Text") But when I print the string s I am unable to find the picture part. Example Usual format is ...
{\result{\pict{\*\picprop}\wmetafile8\picw3840\pich300\picwgoal3840\pichgoal300 But i am getting ..{\result{\pict{\*\picprop}\wmetafile8\picw3840\pich300\picwgoal3840\pichgoal300}}} The Red color data is missing.
Earlier I used to get the usual format. But recently i am getting the data with missing picture part data(only meta data is displayed) Can you please help me regarding this? Are you saying you are seeing a picture, but if you print the richtext you do not see the picture data? Only two ideas here: - You are looking at the wrong attribute (verify that you really see a picture in Object Text) - The picture is corrupt, whatever you seeing might be a DOORS Image - or the DOORS client is able to show the picture but not to parse the information from the OLE In any way - if you can not see the richtext there is probably nothing you can do. In any case you need to verify, if this is the case for each and every OLE object or if this is specific only to one object or module. Regards, Mathias
|