Copying Impress slides by macro

Creating a macro - Writing a Script - Using the API

Copying Impress slides by macro

Postby Jan_J » Mon Sep 02, 2013 12:36 am

Recently I tried to write a routine that merges slides from 2 or more Impress documents. It has got a form of Python function. Copying has been implemented using .uno:Copy service. Here's the code:
Code: Select all   Expand viewCollapse view
# coding: utf8

import sys
import os
import time
import uno
import pyuno

def mergeFromURL(desk, dispatcher, doc1, url, dt = 1.0):

    ctr1 = doc1.getCurrentController()
    frame1 = ctr1.Frame

    doc2 = desk.loadComponentFromURL(url, "_blank", 0, ())
    ctr2 = doc2.getCurrentController()
    frame2 = ctr2.Frame

    dispatcher.executeDispatch(frame1, ".uno:DiaMode", "", 0, ())
    dispatcher.executeDispatch(frame2, ".uno:DiaMode", "", 0, ())

    for i in range(doc2.DrawPages.Count):

        page2 = doc2.DrawPages.getByIndex(i)
        ctr2.setCurrentPage(page2)
        dispatcher.executeDispatch(frame2, ".uno:Copy", "", 0, ())
        time.sleep(dt)
       
        page1 = doc1.DrawPages.getByIndex(doc1.DrawPages.Count-1)
        ctr1.setCurrentPage(page1)
        dispatcher.executeDispatch(frame1, ".uno:Paste", "", 0, ())
        time.sleep(dt)

    dispatcher.executeDispatch(frame1, ".uno:DrawingMode", "", 0, ())
    doc2.close(False)

def fileNameToUrl(fname):
    if fname[0:7] != 'file://':
        fname = os.path.realpath(fname)
        return pyuno.systemPathToFileUrl(fname)
    else:
        return fname

def mergeFiles(ctx, desk, filelist, outname):
    doc =  desk.loadComponentFromURL("private:factory/simpress", "_blank", 0, ())
    dispatcher = ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx)
    for fname in filelist:
        mergeFromURL(desk, dispatcher, doc, fileNameToUrl(fname))
    doc.DrawPages.remove(doc.DrawPages.getByIndex(0))
    doc.storeAsURL(fileNameToUrl(outname), ())
    doc.close(False)

def asMacro():
    ctx = XSCRIPTCONTEXT.getComponentContext()
    desk = XSCRIPTCONTEXT.getDesktop()
    infiles = [
                    "c:/users/my_user/slides1.odp",
                    "c:/users/my_user/slides2.odp",
                  ]
    outfile = "c:/users/my_user/output.odp"
    mergeFiles(ctx, desk, infiles, outfile)

def asService():
    assert len(sys.argv) >= 2
    localContext = uno.getComponentContext()
    resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
    ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
    desk = ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx)
    infiles = sys.argv[1 : -1]
    outfile = sys.argv[-1]
#    infiles = [
#                    "c:/users/my_user/slides1.odp",
#                    "c:/users/my_user/slides2.odp",
#                  ]
#    outfile = "c:/users/my_user/output.odp"
    mergeFiles(ctx, desk, infiles, outfile)

if __name__ == '__main__':
    asService()
(see also http://forum.openoffice.org/pl/forum/vi ... 8847#p8847)

1. The script, however, makes full copy of the content only when Impress is running in visual mode. Trying to use it in server (or --headless) mode on Linux with no X Server results in partial copying (slides are inserted, but the content is not complete). I suspect the Copy service to be dependent on GUI. Any idea how to get near equivalent feature usable with no X environment?

2. Similar StarBasic code can be run as macro inside Impress session. It uses wait() function in place of time.sleep(). Call of Python routine as a macro is not successfull: copying is not executed, no matter how long the time lag is.
Last edited by Jan_J on Mon Sep 02, 2013 2:53 pm, edited 1 time in total.
JJ ∙ http://forum.openoffice.org/pl/
LO 6.2 ∙ AOO 4.1.7 ∙ Python 3.8 ∙ Unicode 13 ∙ LᴬTeX 2ε ∙ XML ∙ Unix tools ∙ Linux (2.6|3.x) ∙ Fedora ∙ CentOS ∙ SUSE
Jan_J
 
Posts: 146
Joined: Wed Apr 29, 2009 1:42 pm
Location: Poland

Re: Copying Impress slides by macro

Postby pasty757 » Mon Sep 02, 2013 1:40 pm

I use the following to copy a "template slide" which exists in the deck to make a new slide... I haven't tried without having the GUI active... but this does the job for me.

Code: Select all   Expand viewCollapse view
Sub SwitchMode(ModeNum As Integer)
       
   Dim oDispatch As Object
    Dim Modes(1) As String
   Dim oFrame As Object
   Wait 500
    Modes(0) = ".uno:DrawingMode"   'Normal
    Modes(1) = ".uno:DiaMode"       'Sorter
   ' Other modes ".uno:OutlineMode", ".uno:NotesMode", ".uno:HandoutMode"

    oFrame   = oReportDeck.CurrentController.Frame
    oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
   oDispatch.executeDispatch(oFrame, Modes(ModeNum), "", 0, Array())
   Wait 500
End Sub



Function LoadSlide(templateName as String) As String
   ' Duplicate the template slide and use this ...

   Dim oSlide as Object
   Dim oPage as Object
   Dim NoArg()
   oDispatch = createUnoService( "com.sun.star.frame.DispatchHelper")
   oSlide = oSlides.getByName(templateName)      ' Get the slide template
   switchMode(0)   'Switch to normal
   oReportDeck.CurrentController.setCurrentPage(oSlide)
   switchMode(1)    'Switch to sorter
   oReportDeck.CurrentController.setCurrentPage(oSlide)
   oProvider = oReportDeck.CurrentController.Frame
   ' Will use Copy and Paste approach
   oDispatch.executeDispatch(oProvider, ".uno:Copy","", 0, NoArg())
   SwitchMode(0)    'Switch to normal
   oSlide = oSlides.getByIndex(oSlides.Count()-1)   ' Go to last slide...
   oReportDeck.CurrentController.setCurrentPage(oSlide)
   SwitchMode(1)   'Swithch to sorter
   oReportDeck.CurrentController.setCurrentPage(oSlide)
   oDispatch.executeDispatch(oProvider, ".uno:Paste", "", 0, NoArg())
   iSlides = iSlides + 1                     ' Increment the slide counter
   LoadSlide = "ReportDeck - " & iSlides                ' Set the return value
   oSlide = oSlides.getByIndex(oSlides.Count()-1)
   oSlide.name = "ReportDeck - " & iSlides         ' Give the slide a name.

End Function
Lotus Symphony / OpenOffice 4.0.0 on Windows XP
pasty757
 
Posts: 24
Joined: Mon Nov 12, 2012 3:25 pm

Re: Copying Impress slides by macro

Postby Jan_J » Mon Sep 02, 2013 8:59 pm

Yes, that is very similar to mine, apart form the language. Basic version of my code also runs OK as a macro.
I have problems with different behaviour of Wait (Basic) and os.sleep (Python) functions, and with C&P when GUI is not present.
JJ ∙ http://forum.openoffice.org/pl/
LO 6.2 ∙ AOO 4.1.7 ∙ Python 3.8 ∙ Unicode 13 ∙ LᴬTeX 2ε ∙ XML ∙ Unix tools ∙ Linux (2.6|3.x) ∙ Fedora ∙ CentOS ∙ SUSE
Jan_J
 
Posts: 146
Joined: Wed Apr 29, 2009 1:42 pm
Location: Poland


Return to Macros and UNO API

Who is online

Users browsing this forum: No registered users and 7 guests