[Solved] Automating Impress Insert->File... in VB.NET

Java, C++, C#, Delphi... - Using the UNO bridges
Post Reply
legocjman
Posts: 2
Joined: Thu Oct 09, 2014 4:29 am

[Solved] Automating Impress Insert->File... in VB.NET

Post by legocjman »

Hello, I am trying to merge several presentations into a single presentation through Impress with a VB.NET application I am writing. The Insert/File... method works great, so basically I just need to automate that. So far I haven't found any documentation that relates in how to do this. I have this already working with PowerPoint, but I'm a bit stuck here unfortunately.
Thanks for reading, any help you may have is much appreciated!
Last edited by legocjman on Fri Oct 10, 2014 11:32 am, edited 1 time in total.
OpenOffice 4.1 on Windows 8.1
FJCC
Moderator
Posts: 9248
Joined: Sat Nov 08, 2008 8:08 pm
Location: Colorado, USA

Re: Automating Impress Insert->File... in VB.NET

Post by FJCC »

There is Python code here for merging two presentations. I hope that helps.
OpenOffice 4.1 on Windows 10 and Linux Mint
If your question is answered, please go to your first post, select the Edit button, and add [Solved] to the beginning of the title.
legocjman
Posts: 2
Joined: Thu Oct 09, 2014 4:29 am

Re: Automating Impress Insert->File... in VB.NET

Post by legocjman »

Thanks FJCC! That was just what I needed. I have modified the code to work with VB.NET and posted it below.
There is still the issue that the styles don't get copied over properly, so if you have any ideas on how to fix that they would be much appreciated. Otherwise, I will look more into it tomorrow. Thanks again!

Alright, I have it more or less figured out. There are still a few minor glitches, but it should now correctly copy over the style information for text to the new presentation, slide by slide. There are a few minor layout issues that still occur, but it otherwise works great. Thanks so much to FJCC, I modified some of his code to fix most of the text layout issues. Marked as Solved.

Code: Select all

Private Sub MergePresentations(ByVal UnoDispatchHelper As Object, ByVal TargetPresentation As Object, ByVal SourceFile As Object, ByVal OperationDelay As Integer)

	' Presentation merge code is a modified version of the source found at https://forum.openoffice.org/pl/forum/viewtopic.php?f=10&p=8847#p8847.

	' Arguments:
	' UnoDispatchHelper: UnoDispatchHelper=CreateUnoService("com.sun.star.frame.DispatchHelper") (OOoDisp from Bernard Marcelly's VB.NET OOo tool (http://bernard.marcelly.perso.sfr.fr/index2.html))
	' TargetPresentation: Loaded presentation to copy slides to.
	' SourceFile: Source to copy slides from.
	' OperationDelay: Time delay between slide copy/paste operations in milliseconds.

	Dim oArgs(2),
		oDummy(-1),
		SourcePresentation,
		SourceControl, TargetControl,
		SourceFrame, TargetFrame,
		SourcePage, TargetPage,
		SourceShape, TargetShape,
		SourceText, TargetText,
		SourceParagraphEnum, TargetParagraphEnum,
		SourceParagraph, TargetParagraph,
		SourcePortion, TargetPortion,
		SourcePortionEnum, TargetPortionEnum As Object

	Dim Slide As Integer = 0
	Dim Shape As Integer = 0

	' Arguments for opening the file to merge.
	oArgs(0) = MakePropertyValue("ReadOnly", True)
	oArgs(1) = MakePropertyValue("Password", String.Empty)
	oArgs(2) = MakePropertyValue("Hidden", True)

	TargetControl = TargetPresentation.getCurrentController()
	TargetFrame = TargetControl.frame

	'SourcePresentation = StarDesktop.loadComponentFromURL(ConvertToURL(SourceFile), "_blank", 0, oArgs)
	SourcePresentation = StarDesktop.loadComponentFromURL("file:///" + SourceFile, "_blank", 0, oArgs)
	SourceControl = SourcePresentation.getCurrentController()
	SourceFrame = SourceControl.Frame

	' Change the view to the Slide Sorter.
	UnoDispatchHelper.executeDispatch(TargetFrame, ".uno:DiaMode", "", 0, oDummy)
	UnoDispatchHelper.executeDispatch(SourceFrame, ".uno:DiaMode", "", 0, oDummy)

	' Copy and paste all slides from the source presentation into the target presentation.
	For Slide = 0 To SourcePresentation.DrawPages.Count - 1

		' Copy the slide from the source.
		SourcePage = SourcePresentation.DrawPages.getByIndex(Slide)
		SourceControl.setCurrentPage(SourcePage)
		UnoDispatchHelper.executeDispatch(SourceFrame, ".uno:Copy", "", 0, oDummy)
		System.Threading.Thread.Sleep(OperationDelay)

		' Paste the slide in target.
		TargetPage = TargetPresentation.DrawPages.getByIndex(TargetPresentation.Drawpages.Count - 1)
		TargetControl.setCurrentPage(TargetPage)
		UnoDispatchHelper.executeDispatch(TargetFrame, ".uno:Paste", "", 0, oDummy)

		' Set the target to the newly pasted page.
		TargetPage = TargetPresentation.DrawPages.getByIndex(TargetPresentation.Drawpages.Count - 1)
		' Fix the text properties
		' Thanks to FJCC, code is a modified version of the source found at https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=25069.
		For Shape = 0 To SourcePage.Count - 1
			If (Shape < TargetPage.Count) Then
				SourceShape = SourcePage.getByIndex(Shape) ' Get each shape on the DrawPage.
				TargetShape = TargetPage.getByIndex(Shape)
				SourceText = SourceShape.getText()  ' It seems every shape has a Text object.
				TargetText = TargetShape.getText()
				SourceParagraphEnum = SourceText.createEnumeration
				TargetParagraphEnum = TargetText.createEnumeration
				While SourceParagraphEnum.hasMoreElements
					SourceParagraph = SourceParagraphEnum.nextElement
					TargetParagraph = TargetParagraphEnum.nextElement
					SourcePortionEnum = SourceParagraph.createEnumeration  ' A Portion is a part of a paragraph with constant formatting.
					TargetPortionEnum = TargetParagraph.createEnumeration
					While SourcePortionEnum.hasMoreElements
						SourcePortion = SourcePortionEnum.nextElement
						TargetPortion = TargetPortionEnum.nextElement
						If SourcePortion.String <> String.Empty AndAlso TargetPortion.string <> String.Empty Then 'The String of many Shapes is empty, e.g. if the shape just contains an image.

							' Copy the text properties over.
							' API Reference: http://www.openoffice.org/api/docs/common/ref/com/sun/star/style/CharacterProperties.html
							TargetPortion.CharFontFamily = SourcePortion.CharFontFamily
							TargetPortion.CharFontName = SourcePortion.CharFontName
							TargetPortion.CharFontStyleName = SourcePortion.CharFontStyleName
							TargetPortion.CharFontCharSet = SourcePortion.CharFontCharSet
							TargetPortion.CharColor = SourcePortion.CharColor
							TargetPortion.CharHeight = SourcePortion.CharHeight
							TargetPortion.CharUnderline = SourcePortion.CharUnderline
							TargetPortion.CharWeight = SourcePortion.CharWeight
							TargetPortion.CharPosture = SourcePortion.CharPosture
							TargetPortion.CharLocale = SourcePortion.CharLocale
							TargetPortion.CharFontPitch = SourcePortion.CharFontPitch
							TargetPortion.CharEscapement = SourcePortion.CharEscapement
							TargetPortion.CharAutoKerning = SourcePortion.CharAutoKerning
							'TargetPortion.CharBackColor = SourcePortion.CharBackColor
							'TargetPortion.CharBackTransparent = SourcePortion.CharBackTransparent
							'TargetPortion.CharCaseMap = SourcePortion.CharCaseMap
							TargetPortion.CharCrossedOut = SourcePortion.CharCrossedOut
							'TargetPortion.CharFlash = SourcePortion.CharFlash
							TargetPortion.CharStrikeout = SourcePortion.CharStrikeout
							TargetPortion.CharWordMode = SourcePortion.CharWordMode
							TargetPortion.CharKerning = SourcePortion.CharKerning
							TargetPortion.CharLocale = SourcePortion.CharLocale
							'TargetPortion.CharKeepTogether = SourcePortion.CharKeepTogether
							'TargetPortion.CharNoLineBreak = SourcePortion.CharNoLineBreak
							TargetPortion.CharShadowed = SourcePortion.CharShadowed
							'TargetPortion.CharFontType = SourcePortion.CharFontType
							'TargetPortion.CharStyleName = SourcePortion.CharStyleName
							TargetPortion.CharContoured = SourcePortion.CharContoured
							'TargetPortion.CharCombineIsOn = SourcePortion.CharCombineIsOn
							'TargetPortion.CharCombinePrefix = SourcePortion.CharCombinePrefix
							'TargetPortion.CharCombineSuffix = SourcePortion.CharCombineSuffix
							TargetPortion.CharEmphasis = SourcePortion.CharEmphasis
							TargetPortion.CharRelief = SourcePortion.CharRelief
							'TargetPortion.RubyText = SourcePortion.RubyText
							'TargetPortion.RubyAdjust = SourcePortion.RubyAdjust
							'TargetPortion.RubyCharStyleName = SourcePortion.RubyCharStyleName
							'TargetPortion.RubyIsAbove = SourcePortion.RubyIsAbove
							'TargetPortion.CharRotation = SourcePortion.CharRotation
							'TargetPortion.CharRotationIsFitToLine = SourcePortion.CharRotationIsFitToLine
							TargetPortion.CharScaleWidth = SourcePortion.CharScaleWidth
							'TargetPortion.HyperLinkURL = SourcePortion.HyperLinkURL
							'TargetPortion.HyperLinkTarget = SourcePortion.HyperLinkTarget
							'TargetPortion.HyperLinkName = SourcePortion.HyperLinkName
							'TargetPortion.VisitedCharStyleName = SourcePortion.VisitedCharStyleName
							'TargetPortion.UnvisitedCharStyleName = SourcePortion.UnvisitedCharStyleName
							TargetPortion.CharEscapementHeight = SourcePortion.CharEscapementHeight
							'TargetPortion.CharNoHyphenation = SourcePortion.CharNoHyphenation
							TargetPortion.CharUnderlineColor = SourcePortion.CharUnderlineColor
							TargetPortion.CharUnderlineHasColor = SourcePortion.CharUnderlineHasColor
							'TargetPortion.CharStyleNames = SourcePortion.CharStyleNames
							'TargetPortion.CharHidden = SourcePortion.CharHidden
							TargetPortion.TextUserDefinedAttributes = SourcePortion.TextUserDefinedAttributes

						End If
					End While
				End While
			End If
		Next Shape


		' Delay between slides.
		System.Threading.Thread.Sleep(OperationDelay)

	Next Slide

	' Clean up and change the view from Slide Sorter back to Normal.
	UnoDispatchHelper.executeDispatch(TargetFrame, ".uno:DrawingMode", "", 0, oDummy)
	SourcePresentation.close(False)

	' Select the first slide in the presentation again.
	TargetControl.setCurrentPage(TargetPresentation.DrawPages.getByIndex(0))

End Sub
OpenOffice 4.1 on Windows 8.1
vanderk
Posts: 6
Joined: Wed Nov 02, 2016 2:42 pm

Re: [Solved] Automating Impress Insert->File... in VB.NET

Post by vanderk »

I realize this is a really old post. I am trying to convert this VB example to C#. I commented out the loop through the shapes just to see if I could merge two presentations. I get a prompt from OO asking if I want to apply the formatting. That alert happens for every slide. What am I missing? I am not even sure that I am doing this correctly.

Code: Select all

private static void MergePresentations(object TargetPresentation, string SourceFile, int OperationDelay)
        {
	        // Presentation merge code is a modified version of the source found at https://forum.openoffice.org/pl/forum/viewtopic.php?f=10&p=8847#p8847.

	        // Arguments:
	        // UnoDispatchHelper: UnoDispatchHelper=CreateUnoService("com.sun.star.frame.DispatchHelper") (OOoDisp from Bernard Marcelly's VB.NET OOo tool (http://bernard.marcelly.perso.sfr.fr/index2.html))
	        // TargetPresentation: Loaded presentation to copy slides to.
	        // SourceFile: Source to copy slides from.
	        // OperationDelay: Time delay between slide copy/paste operations in milliseconds.
            
            var oArgs = new PropertyValue[3];
            var oDummy = new PropertyValue[1];
	        object SourcePresentation = null;
	        object SourceControl = null;
	        object TargetControl = null;
	        object SourceFrame = null;
	        object TargetFrame = null;
	        object SourcePage = null;
	        object TargetPage = null;
	        object SourceShape = null;
	        object TargetShape = null;
	        object SourceText = null;
	        object TargetText = null;
	        object SourceParagraphEnum = null;
	        object TargetParagraphEnum = null;
	        object SourceParagraph = null;
	        object TargetParagraph = null;
	        object SourcePortion = null;
	        object TargetPortion = null;
	        object SourcePortionEnum = null;
	        object TargetPortionEnum = null;

	        int Slide = 0;
	        int Shape = 0;

	        // Arguments for opening the file to merge.
	        oArgs[0] = MakeProperty("ReadOnly", true);
	        oArgs[1] = MakeProperty("Password", string.Empty);
	        oArgs[2] = MakeProperty("Hidden", true);

            TargetControl = ((XModel) TargetPresentation).getCurrentController();
            TargetFrame = ((XController) TargetControl).getFrame();

	        //SourcePresentation = StarDesktop.loadComponentFromURL(ConvertToURL(SourceFile), "_blank", 0, oArgs)
            XComponentLoader starDesktop = (XComponentLoader) GetServiceManager().createInstance("com.sun.star.frame.Desktop");
	        SourcePresentation = starDesktop.loadComponentFromURL(PathConverter(SourceFile), "_blank", 0, oArgs);
	        SourceControl = ((XModel) SourcePresentation).getCurrentController();
            SourceFrame = ((XController) SourceControl).getFrame();

	        // Change the view to the Slide Sorter.
            var UnoDispatchHelper = (XDispatchHelper)CreateUnoService("com.sun.star.frame.DispatchHelper");
	        UnoDispatchHelper.executeDispatch((XDispatchProvider)TargetFrame, ".uno:DiaMode", "", 0, oDummy);
	        UnoDispatchHelper.executeDispatch((XDispatchProvider)SourceFrame, ".uno:DiaMode", "", 0, oDummy);

	        // Copy and paste all slides from the source presentation into the target presentation.
            var sourceDrawPageSupplier = (XDrawPagesSupplier) SourcePresentation;
            for (Slide = 0; Slide <= sourceDrawPageSupplier.getDrawPages().getCount() - 1; Slide++)
            {
		        // Copy the slide from the source.
                SourcePage = sourceDrawPageSupplier.getDrawPages().getByIndex(Slide).Value;
		        ((XDrawView)SourceControl).setCurrentPage((XDrawPage)SourcePage);
                UnoDispatchHelper.executeDispatch((XDispatchProvider)SourceFrame, ".uno:Copy", "", 0, oDummy);
		        System.Threading.Thread.Sleep(OperationDelay);

		        // Paste the slide in target.
                var targetDrawPageSupplier = (XDrawPagesSupplier)TargetPresentation;
                TargetPage = targetDrawPageSupplier.getDrawPages().getByIndex(targetDrawPageSupplier.getDrawPages().getCount() - 1).Value; ;
                ((XDrawView)TargetControl).setCurrentPage((XDrawPage)TargetPage);
                UnoDispatchHelper.executeDispatch((XDispatchProvider)TargetFrame, ".uno:Paste", "", 0, oDummy);

		        // Set the target to the newly pasted page.
                TargetPage = targetDrawPageSupplier.getDrawPages().getByIndex(targetDrawPageSupplier.getDrawPages().getCount() - 1);
		
               // loop through shapes was below this line

		        // Delay between slides.
		        System.Threading.Thread.Sleep(OperationDelay);

	        }

	        // Clean up and change the view from Slide Sorter back to Normal.
            UnoDispatchHelper.executeDispatch((XDispatchProvider)TargetFrame, ".uno:DrawingMode", "", 0, oDummy);
	        ((XCloseable)SourcePresentation).close(false);

	        // Select the first slide in the presentation again.
            //targetDrawPageSupplier.getDrawPages().getByIndex(targetDrawPageSupplier.getDrawPages().getCount() - 1);
	        //TargetControl.setCurrentPage(TargetPresentation.DrawPages.getByIndex(0));

        }
OpenOffice 4.1.2 on Windows 7 and 10
vanderk
Posts: 6
Joined: Wed Nov 02, 2016 2:42 pm

Re: [Solved] Automating Impress Insert->File... in VB.NET

Post by vanderk »

It turns out that the prompts were because I was creating a new empty presentation so my slides that were being pasted were a different format than the presentation they were being pasted into. I have been able to merge multiple presentations (ppt files) but I notice that in presenter view and slide sorter the images are blurry. The slides display correctly but the preview is blurry. If I edit the presentation manually and move the image slightly then the preview looks normal.
OpenOffice 4.1.2 on Windows 7 and 10
Post Reply