Page 1 of 1
Import chapters tracked changes into master document
Posted: Sat Jan 19, 2019 10:59 pm
by emanuele.gissi
Hi,
I am writing a multi chapter text on OO/LO by using a master document and I have been hit by the following bug:
https://bugs.documentfoundation.org/sho ... ?id=121166
In simple words, the master document does not show the tracked changes of each chapter.
This is very important to me, because we want to publish a document that shows all the changes that were made to the text.
As always, the risk is that my organisation pushes us back to MSOffice...
If I break the links (Edit > Link to external files > Break), OO/LO import all the contents of the chapters in the master file except the tracked changes.
As a workaround, I am trying to write a Python script that mimics the breaking of the link to the external files, while importing the tracked changes of the chapters.
I tried to use odfpy library for this purpose (
https://github.com/eea/odfpy), it imports the tracked changes and it works with simple chapters, but I cannot merge the content of complex chapters in the master document.
So my questions are:
1. Do you see any possible alternative way to achieving the same result?
2. Would it be possible to add the importing of the tracked changes in OO/LO code?
3. Where in OO/LO code is "Edit > Link to external files > Break" managed?
I thank you very much in advance!
Best regards,
Emanuele Gissi
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 12:48 am
by JeJe
Have you seen this thread?
viewtopic.php?f=7&t=91240
The alternative, which I presume you've considered, is to use sections. You can make all the sections you're not working on non-visible so you just see the one you're working on - very similar to having each chapter in a separate file.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 2:04 am
by robleyd
This question has also been posted on
AskLibreOffice
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 3:01 am
by John_Ha
The simplest workaround is to Record Changes in the individual sub .odt files and do each chapter individually.
Another simple workaround is to create a large .odt file of the entire document. In the Master document go File > Export ..., and choose to export as Fred.odt. You now have a single Fred.odt file.
Fred.odt is
still linked to the sub documents and
text in Fred.odt file is protected. Go Format > Sections ..., and untick Link and untick Protected. You now have a stand-alone editable Fred.odt file which will accept Recorded Changes.
You can stay with Fred.odt and accept the changes in Fred.odt. Or, if you want to stay as Master/Sub, accept the changes in Fred and copy and paste the appropriate bits back into the original sub documents.
See
[Tutorial] Differences between Writer and MS Word files for why you should be using .odt files, and for the perils of allowing someone to Record Changes with MS Word.
See
Tracking changes to a document which I immediately found by asking Mrs Google to tell me what she knew about
record changes open office master document.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 9:49 am
by emanuele.gissi
First of all thank you very much for your quick response!
@Jeje
These days I tried to implement with a Python script exactly what I had found on that thread by using odfpy.
IMHO this is the optimal approach for my case.
@John_Ha
We are a large group and everybody is working on a different chapter. So merging it back to an only odt is not a viable solution. Furthermore each chapter contains references to other chapters that get populated only when they are all together in the master document.
The Python script I wrote works well with simple chapter files, but cannot merge complex ones.
I presume that while merging the content.xml text part into the original sections of the chapters in the master doc, I should renumber and relink the IDs of tables, pictures, equations, ...
No problem with styles, because they are fully shared with an only ott template and no direct formatting is used.
I did not find any guidance on how to merge odt files by a script.
Can you point me to something about that?
Thanks again!
Emanuele
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 1:30 pm
by JeJe
(Madcap idea warning) If you enumerate the text portions it includes the tracked changes and the TextPortionType is given "Redline". The Redline text is only given if changes are set to show though. Don't know whether it would even be possible to reconstruct/copy a document TextPortion by TextPortion to include tracked changes but you do have access to all the text portions including tracked changes.
Code: Select all
oParEnum = ThisComponent.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.sun.star.text.Paragraph") Then
nPars = nPars + 1
oSecEnum = oPar.createEnumeration()
Do While oSecEnum.hasMoreElements()
oParSection = oSecEnum.nextElement()
msgbox oParSection.TextPortionType & " " & oparsection.string
Loop
End If
Loop
Edit: 'unless prepared to deal with a lot of message boxes only try this demo on a *tiny* document.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 3:33 pm
by JeJe
this works for a simple sentence with some tracked deletions. MarkRedline sets the charstyle of the deletions to one called "Deleted". Then if the deleted text is then Rejected (ie restored to normal text but it in the "Deleted Style") you can copy and paste into another document and run restoreDeleted with the changes tracked. (Its madcap and nowhere near usable but... )
Code: Select all
sub test()
' markRedline
'reject the deleted changes before the next step
'restoreDeleted
end sub
Sub MarkRedline
dim redline as boolean
oParEnum = ThisComponent.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.sun.star.text.Paragraph") Then
nPars = nPars + 1
oSecEnum = oPar.createEnumeration()
Do While oSecEnum.hasMoreElements()
oParSection = oSecEnum.nextElement()
if oParSection.TextPortionType = "Redline" then redline = not redline
if oParSection.TextPortionType = "Text" then
if redline = true then
oParSection.charstylename = "Deleted"
end if
end if
Loop
End If
Loop
end sub
Sub restoreDeleted
oParEnum = ThisComponent.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
dim redline as boolean
If oPar.supportsService("com.sun.star.text.Paragraph") Then
nPars = nPars + 1
oSecEnum = oPar.createEnumeration()
Do While oSecEnum.hasMoreElements()
oParSection = oSecEnum.nextElement()
if oParSection.TextPortionType = "Text" then
if oParSection.charstylename = "Deleted" then oParsection.string =""
end if
Loop
End If
Loop
end sub
Edit: thinking about it, instead of using a style marker (as you'd need a workaround for the lost existing style)... if you just appended a unique text string to the end of deleted tracked changes marking it as deleted then you can do the above... reject the deletions, copy to a new document, reverse into deleted tracked changes, remove the deleted marker. There's the issue of who made the change, that might be appended to the string as well (?)... its a can of worms...
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 4:04 pm
by John_Ha
emanuele.gissi wrote:I did not find any guidance on how to merge odt files by a script.
Can you point me to something about that?
Sorry - I don't know.
I am wondering if what you are trying to do is logically sensible or indeed logically possible.
A Master document merely has calls to get the sub documents. When the sub documents are "pulled in" they appear on the screen but are Write Protected. The content is not stored in any user accessible file. The Master document shows what the sub document contained when the Master was last updated.
If the Write protection is removed, the Master document on screen can be edited but those edits are not saved anywhere even if you save the Master as a .odm. The only way to save the edits is to export the edited Master as a .odt file which loses the Master/sub documents structure.
(I have not tested, but it is possible that an AutoSaved temporary file may be "a .odT file constructed from the Master together with any edits made on screen" - ie as though the document had been saved as a .odT file. See
[Tutorial] How to find and un-delete AOO temporary files. )
Edit: I have now tested it. The AutoSaved temporary file only contains the link to the sub document - it contains no text from the sub document. |
Assume the changes could be seen in the Master document and the user could now accept or reject them.
- If the Master/sub documents structure is to be kept, the accept or rejection must be made in the sub file and not in the Master document.
- If the Master/sub documents structure can be abandoned, the accept or rejection can be made in the "master" and the "master" then exported as a .odt.
I note that, if the sub document has changes in it, the Master shows that document will all the changes accepted. This is somewhat similar to copying some text which includes changes - when pasted all the changes are applied and only the fully changed text is pasted.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 5:54 pm
by emanuele.gissi
@John_Ha
While I am testing what Jeje proposed, I would like to clarify what is the objective of maintaining the tracked changes in the odm.
I am a professional fire chief of the Italian Fire and Rescue Service (
http://www.vigilfuoco.it). We are writing an update to the Italian Fire Code. After our work, the text will be reviewed by other teams. This is why we need a final pdf of the full odm file with the corrections we made clearly marked.
Find an example chapter of what I mean here:
https://my.pcloud.com/publink/show?code ... 1xuVWCtrYX
The corrections are marked in red and grey.
This is why I would like to show all the corrections in the odm. I do not intend to treat (accept/reject) them there, it is just a matter of showing them there and exporting to a pdf.
Working on separate chapter odts is so convenient and light.
This is why I am trying to write a script that:
- transforms the master odm into and odt,
removes the live links to the chapters,
merges the contents of the chapters (as done by: Edit > Link to external files > Break) but maintains the tracked changes as they are,
exports the full result to a pdf.
Back to Jeje proposal now!
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 9:17 pm
by John_Ha
emanuele
Thank you for your description of what you are trying to do. I need to think about your objectives.
I have used master documents for a number of years and that is why I responded. I know nothing about writing scripts except you can program almost anything if you try hard enough.
I think that you are in a difficult place: it is easy to see the recorded changes in the individual chapters ... but cross references need the entire document to work. But, if you work in the entire document you cannot see (nor accept/reject) the changes in the entire document.
This is why I would like to show all the corrections in the odm.
I am also thinking of workarounds and wondered if you needed to do it in AOO? Have you considered using something like
PDF Split And Merge which can merge individual PDF files? If you create a PDF for each chapter PDFSAM will join all the PDFs together. I don't think it helps with cross references.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 9:21 pm
by emanuele.gissi
@John_Ha
Yes John, this is my plan B: hardwiring the cross references in the chapters and joining on the PDFs.
But I would consider it as a defeat of Libreoffice great automation tools. And quite uncomfortable to manage in an ever changing document.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 9:38 pm
by JeJe
You can get all the information about the changes from the textportion - author, type of change etc.
https://www.openoffice.org/api/docs/com ... rtion.html
Code: Select all
oParEnum = ThisComponent.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.sun.star.text.Paragraph") Then
nPars = nPars + 1
oSecEnum = oPar.createEnumeration()
Do While oSecEnum.hasMoreElements()
oParSection = oSecEnum.nextElement()
if oParSection.TextPortionType = "Redline" then
msgbox oParSection.RedlineType
end if
Loop
End If
Loop
Its just a question of choosing a method to transform the text into a form that can be copied into a new document. As all you want to produce is a pdf document showing the appearance of changes - you could even improve things by adding the information in your PDF about who's made the change in brackets after the change text etc. Or use styles changes to create a pdf with a completely different look for the deletions/changes.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 10:02 pm
by John_Ha
I note that Insert > From file ..., applies the changes so you don't see them.
How about a script which
1. Reads the Master document to get the list of inserted sub documents
2. Opens each document in turn and gets its content.xml
3. Joins all the content.xml together to get a content.xml which is the entire document. You will need to be careful about data above the user content you bring in.
Another thought.
1. Create a single .odt of the complete document before changes are applied.
2. Apply the changes to the individual chapters.
3. Pull all the chapters into the master and export the master as a new document. You now have a fully changed document.
4. Use Edit > Compare ..., to compare the "before" and "after" files.
You now have a single large file with all the changes visible.
A caution. I have found that changes seem to get "super complicated" when files are compared.
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 10:28 pm
by JeJe
Going back to using style changes
If you make "Deleted" and "Inserted" styles that look like changes versions
Run this macro it changes the deleted and inserted portions into those style names
then reject all the deleted changes - don't know whether that can be done in code
copy and paste into the new document
Code: Select all
Sub MarkRedline
dim redline as boolean
oParEnum = ThisComponent.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.sun.star.text.Paragraph") Then
nPars = nPars + 1
oSecEnum = oPar.createEnumeration()
Do While oSecEnum.hasMoreElements()
oParSection = oSecEnum.nextElement()
if oParSection.TextPortionType = "Redline" then
redline = not redline
redlinetype = oParSection.redlinetype
end if
if oParSection.TextPortionType = "Text" then
if redline = true then
select case redlinetype
case "Delete"
oParSection.charstylename = "Deleted"
case "Insert"
oParSection.charstylename = "Inserted"
end select
end if
redlinetype =""
end if
Loop
End If
Loop
end sub
Edit:
The other types of changes can have their own style as well. Handling changes in text tables in the Enumeration might need:
ElseIf oPar.supportsService("com.sun.star.text.TextTable")
Re: Import chapters tracked changes into master document
Posted: Sun Jan 20, 2019 11:01 pm
by emanuele.gissi
@JeJe
This Redline is great. As soon as I start experimenting a little bit on that I will keep this thread posted.
What I am going to miss by using character styles is the lateral line that emphasizes modified paragraphs.
@John_Ha
I did not find any source explaining ho to merge the content.xml. And I have to import all external contents (eg. images) as well.
I presume a lot of renumbering of element ids is required to avoid clashes.
The other solution you propose would be extremely easy to implement and seems great. I am going to try it immediately!
Re: Import chapters tracked changes into master document
Posted: Mon Jan 21, 2019 12:45 pm
by JeJe
You can make redline changes in code. All it needs is an array of user type or similar that stores the information for the redline. Then following the style (or similar) change/copy method you can go loop through and reapply the redline changes with the original time/author/comment etc.
https://www.mail-archive.com/allbugs@op ... 56757.html
https://www.openoffice.org/api/docs/com ... akeRedline
Re: Import chapters tracked changes into master doc [solved]
Posted: Mon Jan 21, 2019 1:22 pm
by emanuele.gissi
This morning I tested the solution proposed by @John_Ha:
1. Create a single .odt of the master document before revision (baseline master document), by breaking links to external chapter files.
2. Create a single .odt of the master document after revision (revised master document), by breaking links to external chapter files.
3. Use Edit > Compare ..., to compare the baseline and the revised document.
The result is surprisingly good. I am quite satisfied. I think this approach solves my problem in a brilliant way!
Anyway, I am studying better the @JeJe redline approach as well, that is very interesting and opens up many possibilities of finer control.
Let me heartly thank you, your support really saved my day.
If you happen to pass in Italy, it will be my pleasure to meet you in person and have a glass of wine (or what else you prefer) together.
Re: Import chapters tracked changes into master document
Posted: Mon Jan 21, 2019 1:35 pm
by John_Ha
emanuele
Thank you - if I am in Italy I shall contact you.
emanuele.gissi wrote:
I did not find any source explaining ho to merge the content.xml. And I have to import all external contents (eg. images) as well.
I presume a lot of renumbering of element ids is required to avoid clashes.
I don't know but it must be possible - after all, it's what Writer does when it uses a Master document. AOO uses random numbers and characters for image names so images would not need renaming.
Re: Import chapters tracked changes into master document
Posted: Thu Jan 24, 2019 3:52 pm
by JeJe
Just seen this: you can enumerate redlines and access them by index
https://wiki.openoffice.org/wiki/Docume ... xt/Redline
Re: Import chapters tracked changes into master doc [solved]
Posted: Thu Jan 24, 2019 7:30 pm
by John_Ha
emanuele.gissi wrote:The result is surprisingly good. I am quite satisfied. I think this approach solves my problem in a brilliant way!
If you want perfection, where perfection is defined as "the enemy of good", I would use the result of the comparison as your new starting point.
Now go to the original files before the changes were made (or a copy of them) and make the changes manually by striking through deletions, changing the colour etc; and by making the inserts in a new colour; and by adding the red lines in the margins (by a graphic?) to highlight changes.
You are now in full control and can make it look exactly how you want it to look. I would define a style for
deletions and one for
inserts so all were identical. Create some 1, 2 and 3 line redline images for use in the margins and ensure that all are placed at exactly the same position relative to the line(s) they highlight.
Re: Import chapters tracked changes into master document
Posted: Tue Jan 29, 2019 10:11 am
by emanuele.gissi
After this discussion, the issue has a workaround, but not a full solution.
So I set up a crowdfunding to solve the issue:
https://freedomsponsors.org/issue/845/t ... r-document
And got in contact with one developer to solve it for the whole Community.
I will keep you posted.
Re: Import chapters tracked changes into master document
Posted: Tue Jan 29, 2019 12:11 pm
by JeJe
Before you part with US$ 100.00... I have a proper working solution now going on from my posts above - it will turn a master document into a normal document with all the files including changes imported, just from calling one sub with the name of the master document. I'll tidy it up and post it in a bit.
Re: Import chapters tracked changes into master document
Posted: Tue Jan 29, 2019 3:37 pm
by JeJe
-Put this code in a module.
-Open a Writer document with some Changes made.
-Make a selection of what you want to copy in that document.
-Run TestSub.
-Wait for the code to complete
It will create a new document with the changes copied over - select Edit/changes/show to see them.
Converting a master document involves looping through each sub-document to successively copy and paste it into a new document - that bit's easy, I just haven't done it yet.
I'll post an extension when finished.
This is only tested on OpenOffice so far and seems to work fine.
Code: Select all
'to do
'- exit if no selection
'-restore selection state, changes states
'full selection if table start
Option Explicit
private type RedlineType 'my custom type
RedlineAuthor as string 'the name of the author of the change.
RedlineDateTime as com.sun.star.util.DateTime 'date and time of the change.
RedlineComment as string ' comment for the change.
RedlineType as string 'Insert, Delete, Format , TextTable, Style
'RedlineSuccessorData 'com.sun.star.beans.PropertyValues RedlineSuccessorData; second level redline data The elements of the sequence are string RedlineAuthor; com::sun::star::util::DateTime RedlineDateTime; string RedlineComment; string RedlineType;
RedlineIdentifier as string 'contains a unique identifier for the redline. This is necessary for file export filters to able to recognize redline portions that point to the same redline.
IsInHeaderFooter as boolean 'boolean IsInHeaderFooter; determines whether the portion is member of a header or footer text.
'RedlineText XText RedlineText;the text of the redline. Only provided if the change is not visible. The visibility depends on the redline display options that are set at the documents property set (RedlineDisplayType).
MergeLastPara as boolean 'whether the last paragraph of a redline text has to be merged with a possible following text content (i.e. a text table)
CharOverline as long
CharColor as long
redlinestart as NEW com.sun.star.text.textrange
redlineend as NEW com.sun.star.text.textrange
cstring as string
end type
Global Redlines(),ubredlines as long, trans ,hasRedlines as boolean
Global DeleteCharColor as long,InsertCharColor as long,FormatCharColor as long,ColorsSet as boolean
sub testsub()
dim Doc,NewDoc
Doc = thisComponent
CopyWithRedlines(doc)
NewDoc = StarDesktop.loadComponentFromURL("private:factory/swriter","_blank",0,Array())
PasteWithRedlines NewDoc
end sub
sub CopyWithRedlines(doc)
setWinPointer Doc,2 'WAIT
' oVC = thisComponent.getCurrentController.getViewCursor
' TC = oVC.getText.createTextCursorByRange(oVC)
On Error goto hr
Doc.lockControllers
with doc
hasRedlines=.getredlines.haselements
if hasRedlines =false then
trans = .currentcontroller.gettransferable
else
UBREDLINES = -1
if ColorsSet = false then
DeleteCharColor = rgb(50,50,50)
InsertCharColor = rgb(100,100,100)
FormatCharColor = rgb(150,150,150)
ColorsSet = true
end if
.UndoManager.enterUndoContext "Copy"
.RedlineDisplayType =2 'inserted and removed
.RecordChanges = false
getallRedlines Doc
trans = .currentcontroller.gettransferable
'thiscomponent.RedlineDisplayType =0 'inserted and removed
with doc.UndoManager
.leaveUndoContext
.undo
.clearRedo
end with
end if
end with ' doc.currentcontroller.select(TC)
setWinPointer Doc,3 'Text
hr:
Doc.unlockControllers
end sub
Sub GetallRedlines(doc)
dim ORedlines,i,RedlineEnum, oRedline, RedlineType as string,RCell, TC
if doc.getredlines.haselements =false then exit sub '
' TC = doc.gettext.createtextcursor
oRedlines = doc.getredlines
ubredlines = oRedlines.count-1
redim redlines(ubredlines)
RedlineEnum = oRedlines.createEnumeration()
Do While RedlineEnum.hasMoreElements()
oRedline = RedlineEnum.nextElement()
Redlines(i) = new RedlineType
RedlineType = oRedline.RedlineType
if RedlineType ="Delete" or RedlineType ="Format" or RedlineType ="Insert" then
with redlines(i)
.RedlineType= RedlineType
.RedlineAuthor= oRedline.RedlineAuthor
.RedlineDateTime = oRedline.RedlineDateTime
.RedlineComment = oRedline.RedlineComment
' RedlineIdentifier as string
.IsInHeaderFooter= oRedline.IsInHeaderFooter
'RedlineText provides access to the text of the redline. This interface is only provided if the change is not visible. The visibility depends on the redline display options that are set at the documents property set (RedlineDisplayType).
.MergeLastPara = oRedline.MergeLastPara
.redlinestart = oRedline.redlinestart
.redlineend = oRedline.redlineend
'
if isempty( oRedline.redlinestart.TextTable(0)) then
TC = doc.Text.createTextCursorByRange(oRedline.redlinestart)
else
RCell=oRedline.redlinestart.cell
TC=RCell.CreateTextCursorByRange(RCell.start)
end if
TC.gotorange(oRedline.redlinestart,false)
TC.gotorange(oRedline.redlineend,true)
.cstring =TC.string
.CharOverline= TC.CharOverline
.CharColor = TC.CharColor
end with
with TC
.CharOverline=7 'DASHdot
select case RedlineType
case "Delete"
.collapsetoend
.string= redlines(i).cstring
.CharColor = DeleteCharColor
case "Insert"
.CharColor = InsertCharColor
case "Format"
.CharColor = FormatCharColor
end select
END WITH
i=i+1
end if
Loop
End Sub
Sub PasteWithRedlines(NewDoc)
setWinPointer NewDoc,2 'wait
On Error goto hr
NewDoc.lockControllers
WITH newdoc
if hasRedlines = false then
.CurrentController.insertTransferable(trans)
else
.UndoManager.enterUndoContext "Insert with changes"
.RecordChanges = false
.RedlineDisplayType =0
.CurrentController.insertTransferable(trans)
.RedlineDisplayType =0
GetOverlines NewDoc ,7
.UndoManager.leaveUndoContext
end if
END WITH
setWinPointer NewDoc,3 'Text
hr:
NewDoc.unlockControllers
end sub
'search replace part loosely adapted from 'https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=75449 (JohnSUN-Pensioner)
Sub GetOverlines(Doc, overlinetype)
dim aRedlineProperties(4) as new com.sun.star.beans.PropertyValue, i,j
Dim oSearch As Variant , oFound As Variant , SrchAttributes(0) As New com.sun.star.beans.PropertyValue,RedlineRange As Variant
oSearch = doc.createSearchDescriptor()
oSearch.SearchString = ".*" 'Regular expression. Match any text
oSearch.SearchRegularExpression=True 'Use regular expressions
SrchAttributes(0).Name = "CharOverline"
SrchAttributes(0).Value =overlinetype 'com.sun.star.awt.FontOverline.BOLD
oSearch.SetSearchAttributes(SrchAttributes())
oFound = doc.findAll(oSearch)
If not IsNull(oFound) Then
For i = 0 To oFound.getCount()-1
RedlineRange = oFound.getByIndex(i)
Select case RedlineRange.CharColor
case DeleteCharColor,InsertCharColor,FormatCharColor
with Redlines(j)
aRedlineProperties(0).Name = "RedlineAuthor"
aRedlineProperties(0).Value = .RedlineAuthor
aRedlineProperties(1).Name = "RedlineComment"
aRedlineProperties(1).Value = .RedlineComment
aRedlineProperties(2).Name = "RedlineDateTime"
aRedlineProperties(2).Value = .RedlineDateTime
'RedlineIdentifier as string 'contains a unique identifier for the redline. This is necessary for file export filters to able to recognize redline portions that point to the same redline.
aRedlineProperties(3).Name = "IsInHeaderFooter"
aRedlineProperties(3).Value = .IsInHeaderFooter
aRedlineProperties(4).Name = "MergeLastPara"
aRedlineProperties(4).Value = .MergeLastPara
on error resume next
RedlineRange.makeRedline(.RedlineType, aRedlineProperties )
RedlineRange.CharOverline = .CharOverline
RedlineRange.CharColor=.CharColor
end with
j=j+1
if j> ubredlines then exit for
end select
next
end if
End Sub
'HELPER
Sub setWinPointer(Doc, Ptype)
dim oPointer
oPointer = createUnoService("com.sun.star.awt.Pointer")
oPointer.setType(Ptype)
Doc.currentcontroller.frame.getcontainerwindow.setPointer(oPointer)
End Sub
EDIT: THERE IS A FAIL FOR WHEN THE CHANGE IS IN A TEXTFRAME. I'll put up fixes in the extension.
Re: Import chapters tracked changes into master document
Posted: Tue Jan 29, 2019 5:45 pm
by JeJe
With a list of your chapter paths all you need is a simple macro that:
-Creates a new blank document
Then
-Loads each document
-Selects the document contents
-Copies and pastes into the blank document using the above code
(A better way is to loop through the master document sections but that should work)
Re: Import chapters tracked changes into master document
Posted: Fri Feb 08, 2019 6:03 pm
by JeJe
Here's that module reposted with the fix in case anyone other than the OP wants it - as I've been distracted by some other programming and not got round to finishing this extension yet.
There's are various ways to solve this - a choice of method that records the changes in some way and modifies the document so the deleted changes aren't removed when copy or gettransferable is used. My method involves using overlines and charcolor changes on the assumption that these exact changes are unlikely to be in a document. Then reversing the process after the insert.
OO has a clipboard hook so developing things so my copy and paste replaces the normal one is probably possible - defaulting to a normal copy/paste if there are not changes in the selection. The hard bit is probably drag and drop mouse events which would require a dnd listener (if possible).
Code: Select all
'to do
'- exit if no selection
'-restore selection state, changes states
'full selection if table start
Option Explicit
private type RedlineType 'my custom type
RedlineAuthor as string 'the name of the author of the change.
RedlineDateTime as com.sun.star.util.DateTime 'date and time of the change.
RedlineComment as string ' comment for the change.
RedlineType as string 'Insert, Delete, Format , TextTable, Style
'RedlineSuccessorData 'com.sun.star.beans.PropertyValues RedlineSuccessorData; second level redline data The elements of the sequence are string RedlineAuthor; com::sun::star::util::DateTime RedlineDateTime; string RedlineComment; string RedlineType;
RedlineIdentifier as string 'contains a unique identifier for the redline. This is necessary for file export filters to able to recognize redline portions that point to the same redline.
IsInHeaderFooter as boolean 'boolean IsInHeaderFooter; determines whether the portion is member of a header or footer text.
'RedlineText XText RedlineText;the text of the redline. Only provided if the change is not visible. The visibility depends on the redline display options that are set at the documents property set (RedlineDisplayType).
MergeLastPara as boolean 'whether the last paragraph of a redline text has to be merged with a possible following text content (i.e. a text table)
CharOverline as long
CharColor as long
redlinestart as NEW com.sun.star.text.textrange
redlineend as NEW com.sun.star.text.textrange
cstring as string
end type
Global Redlines(),ubredlines as long,trans ,hasRedlines as boolean
Global DeleteCharColor as long,InsertCharColor as long,FormatCharColor as long,ColorsSet as boolean
sub testsub()
dim Doc,NewDoc
Doc = ThisComponent
NewDoc = StarDesktop.loadComponentFromURL("private:factory/swriter","_blank",0,Array())
CopyWithRedlines(doc)
PasteWithRedlines NewDoc
end sub
sub CopyWithRedlines(doc)
setWinPointer Doc,2 'WAIT
' oVC = thisComponent.getCurrentController.getViewCursor
' TC = oVC.getText.createTextCursorByRange(oVC)
On Error goto hr
Doc.lockControllers
with doc
hasRedlines=.getredlines.haselements
if hasRedlines =false then
trans = .currentcontroller.gettransferable
else
UBREDLINES = -1
if ColorsSet = false then
DeleteCharColor = rgb(50,50,50)
InsertCharColor = rgb(100,100,100)
FormatCharColor = rgb(150,150,150)
ColorsSet = true
end if
.UndoManager.enterUndoContext "Copy"
.RedlineDisplayType =2 'inserted and removed
.RecordChanges = false
getallRedlines Doc
trans = .currentcontroller.gettransferable
thiscomponent.RedlineDisplayType =0 'inserted and removed
with doc.UndoManager
.leaveUndoContext
.undo
.clearRedo
end with
end if
end with ' doc.currentcontroller.select(TC)
setWinPointer Doc,3 'Text
hr:
Doc.unlockControllers
end sub
Sub GetallRedlines(doc)
dim ORedlines,i,RedlineEnum, oRedline, RedlineType as string,RCell, TC
if doc.getredlines.haselements =false then exit sub '
' TC = doc.gettext.createtextcursor
oRedlines = doc.getredlines
ubredlines = oRedlines.count-1
redim redlines(ubredlines)
RedlineEnum = oRedlines.createEnumeration()
Do While RedlineEnum.hasMoreElements()
oRedline = RedlineEnum.nextElement()
Redlines(i) = new RedlineType
RedlineType = oRedline.RedlineType
if RedlineType ="Delete" or RedlineType ="Format" or RedlineType ="Insert" then
with redlines(i)
.RedlineType= RedlineType
.RedlineAuthor= oRedline.RedlineAuthor
.RedlineDateTime = oRedline.RedlineDateTime
.RedlineComment = oRedline.RedlineComment
' RedlineIdentifier as string
.IsInHeaderFooter= oRedline.IsInHeaderFooter
'RedlineText provides access to the text of the redline. This interface is only provided if the change is not visible. The visibility depends on the redline display options that are set at the documents property set (RedlineDisplayType).
.MergeLastPara = oRedline.MergeLastPara
.redlinestart = oRedline.redlinestart
.redlineend = oRedline.redlineend
'
if isempty(oRedline.redlinestart.TextTable(0)) = false then
RCell=oRedline.redlinestart.cell
TC=RCell.CreateTextCursorByRange(RCell.start)
elseif isempty(oRedline.redlinestart.TextFrame(0))=false then
TC = oRedline.redlinestart.TextFrame(0).text.createTextCursorByRange(oRedline.redlinestart)
else
TC = doc.Text.createTextCursorByRange(oRedline.redlinestart)
end if
TC.gotorange(oRedline.redlinestart,false)
TC.gotorange(oRedline.redlineend,true)
.cstring =TC.string
.CharOverline= TC.CharOverline
.CharColor = TC.CharColor
end with
with TC
.CharOverline=7 'DASHdot
select case RedlineType
case "Delete"
.collapsetoend
.string= redlines(i).cstring
.CharColor = DeleteCharColor
case "Insert"
.CharColor = InsertCharColor
case "Format"
.CharColor = FormatCharColor
end select
END WITH
i=i+1
end if
Loop
End Sub
Sub PasteWithRedlines(NewDoc)
setWinPointer NewDoc,2 'wait
On Error goto hr
NewDoc.lockControllers
WITH NewDoc
if hasRedlines = false then
.CurrentController.insertTransferable(trans)
else
.UndoManager.enterUndoContext "Insert with changes"
.RecordChanges = false
.RedlineDisplayType =0
'.CurrentController.Frame.containerWindow.setFocus()
'.CurrentController.Frame.ContainerWindow.toFront()
.CurrentController.insertTransferable(trans)
.RedlineDisplayType =0
GetOverlines NewDoc ,7
.UndoManager.leaveUndoContext
end if
END WITH
setWinPointer NewDoc,3 'Text
hr:
NewDoc.unlockControllers
end sub
'search replace part loosely adapted from 'https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=75449 (JohnSUN-Pensioner)
Sub GetOverlines(Doc, overlinetype)
dim aRedlineProperties(4) as new com.sun.star.beans.PropertyValue, i,j
Dim oSearch As Variant , oFound As Variant , SrchAttributes(0) As New com.sun.star.beans.PropertyValue,RedlineRange As Variant
oSearch = doc.createSearchDescriptor()
oSearch.SearchString = ".*" 'Regular expression. Match any text
oSearch.SearchRegularExpression=True 'Use regular expressions
SrchAttributes(0).Name = "CharOverline"
SrchAttributes(0).Value =overlinetype 'com.sun.star.awt.FontOverline.BOLD
oSearch.SetSearchAttributes(SrchAttributes())
oFound = doc.findAll(oSearch)
If not IsNull(oFound) Then
For i = 0 To oFound.getCount()-1
RedlineRange = oFound.getByIndex(i)
Select case RedlineRange.CharColor
case DeleteCharColor,InsertCharColor,FormatCharColor
with Redlines(j)
aRedlineProperties(0).Name = "RedlineAuthor"
aRedlineProperties(0).Value = .RedlineAuthor
aRedlineProperties(1).Name = "RedlineComment"
aRedlineProperties(1).Value = .RedlineComment
aRedlineProperties(2).Name = "RedlineDateTime"
aRedlineProperties(2).Value = .RedlineDateTime
'RedlineIdentifier as string 'contains a unique identifier for the redline. This is necessary for file export filters to able to recognize redline portions that point to the same redline.
aRedlineProperties(3).Name = "IsInHeaderFooter"
aRedlineProperties(3).Value = .IsInHeaderFooter
aRedlineProperties(4).Name = "MergeLastPara"
aRedlineProperties(4).Value = .MergeLastPara
on error resume next
RedlineRange.makeRedline(.RedlineType, aRedlineProperties )
RedlineRange.CharOverline = .CharOverline
RedlineRange.CharColor=.CharColor
end with
j=j+1
if j> ubredlines then exit for
end select
next
end if
End Sub
'HELPER
Sub setWinPointer(Doc, Ptype)
dim oPointer
oPointer = createUnoService("com.sun.star.awt.Pointer")
oPointer.setType(Ptype)
Doc.currentcontroller.frame.getcontainerwindow.setPointer(oPointer)
End Sub