Import chapters tracked changes into master document

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Import chapters tracked changes into master document

Post 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
OpenOffice 3.2 on Ubuntu 9.10
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
robleyd
Moderator
Posts: 5055
Joined: Mon Aug 19, 2013 3:47 am
Location: Murbko, Australia

Re: Import chapters tracked changes into master document

Post by robleyd »

This question has also been posted on AskLibreOffice
Cheers
David
OS - Slackware 15 64 bit
Apache OpenOffice 4.1.15
LibreOffice 24.2.1.2; SlackBuild for 24.2.1 by Eric Hameleers
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: Import chapters tracked changes into master document

Post 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.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Re: Import chapters tracked changes into master document

Post 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
OpenOffice 3.2 on Ubuntu 9.10
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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...
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: Import chapters tracked changes into master document

Post 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.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Re: Import chapters tracked changes into master document

Post 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!
OpenOffice 3.2 on Ubuntu 9.10
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: Import chapters tracked changes into master document

Post 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.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Re: Import chapters tracked changes into master document

Post 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.
OpenOffice 3.2 on Ubuntu 9.10
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: Import chapters tracked changes into master document

Post 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.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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")
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Re: Import chapters tracked changes into master document

Post 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!
OpenOffice 3.2 on Ubuntu 9.10
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Re: Import chapters tracked changes into master doc [solved]

Post 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.
OpenOffice 3.2 on Ubuntu 9.10
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: Import chapters tracked changes into master document

Post by John_Ha »

emanuele

Thank you - if I am in Italy I shall contact you. :super:
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.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post by JeJe »

Just seen this: you can enumerate redlines and access them by index

https://wiki.openoffice.org/wiki/Docume ... xt/Redline
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
John_Ha
Volunteer
Posts: 9583
Joined: Fri Sep 18, 2009 5:51 pm
Location: UK

Re: Import chapters tracked changes into master doc [solved]

Post 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.
LO 6.4.4.2, Windows 10 Home 64 bit

See the Writer Guide, the Writer FAQ, the Writer Tutorials and Writer for students.

Remember: Always save your Writer files as .odt files. - see here for the many reasons why.
emanuele.gissi
Posts: 9
Joined: Sun Dec 13, 2009 3:08 am

Re: Import chapters tracked changes into master document

Post 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.
OpenOffice 3.2 on Ubuntu 9.10
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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.
Last edited by JeJe on Wed Jan 30, 2019 1:02 am, edited 1 time in total.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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)
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Import chapters tracked changes into master document

Post 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

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Post Reply