LibreOffice - How to create a file dialog via python macro?

2.1k views Asked by At

I'd like to know if it's possible to create a standard file dialog to save a pdf via a python macro. I've tried to write some code based on this outdated documentation: wiki.openoffice.org but LibreOffice crashes after execution:

import os
import uno
import sys
import traceback
from com.sun.star.ui.dialogs.TemplateDescription import FILESAVE_SIMPLE

def file_dialog():
    try:
        oCtx = uno.getComponentContext()
        oServiceManager = oCtx.getServiceManager()

        oFilePicker = oServiceManager.createInstanceWithArgumentsAndContext(
                'com.sun.star.ui.dialogs.FilePicker',
                (FILESAVE_SIMPLE,),
                oCtx
            )

        oFilePicker.Title = 'Export as'

        #oDisp = oFilePicker.Text

        oFilePicker.execute()

    except:
        pass
        #oDisp = traceback.format_exc(sys.exc_info()[2])

At the end I need to pass the selected path to write the document, but oDisp = oFilePicker.Text returns: (<type 'exceptions.AttributeError'>. Moreover is there a way to set the file type?

Does anyone have experience with it?

2

There are 2 answers

2
Lyrl On

I used Xray on the oFilePicker object. There are a couple of interesting methods called setCurrentFilter and appendFilterGroup. Just based on the names, they might be used to filter what file types are visible. Unfortunately I'm not sure how to use them.

Also with Xray, I determined that Text is not a method or property of the oFilePicker object. I'm not sure what the code snippet is trying to do there? If retrieve the filepath, 1) that needs to be done after the .execute and 2) the selected filepath is stored as an array of strings, so the path has to be pulled out of the array. Most of my work in OpenOffice is in StarBasic; below is a working example in Basic of printing the filepath selected by the user:

Sub TestFilePicker
    oFilePickerDlg = createUnoService( "com.sun.star.ui.dialogs.FilePicker" )
    oFilePickerDlg.setTitle("My test title")

    If oFilePickerDlg.execute() > 0 Then
        Print ConvertFromURL(oFilePickerDlg.Files(0))
    End If

End Sub
5
ngulam On

Answer given and accepted (because the question was cross posted!) here:

import uno
from com.sun.star.beans import PropertyValue

#shortcut:
createUnoService = (
        XSCRIPTCONTEXT
        .getComponentContext()
        .getServiceManager()
        .createInstance 
                    )

def pypdf_test():

    desktop = XSCRIPTCONTEXT.getDesktop()
    doc = desktop.getCurrentComponent()

    # filter data
    fdata = []
    fdata1 = PropertyValue()
    fdata1.Name = "SelectPdfVersion"
    fdata1.Value = 1
    fdata2 = PropertyValue()
    fdata2.Name = "Quality"
    fdata2.Value = 100
    fdata.append(fdata1)
    fdata.append(fdata2)

    args = []
    arg1 = PropertyValue()
    arg1.Name = "FilterName"
    arg1.Value = "writer_web_pdf_Export"
    arg2 = PropertyValue()
    arg2.Name = "FilterData"
    arg2.Value = uno.Any("[]com.sun.star.beans.PropertyValue", tuple(fdata) )
    args.append(arg1)
    args.append(arg2)
    fileurl = FilePicker()
    if fileurl:        
        doc.storeToURL( fileurl, tuple(args) )

def FilePicker(path=None, mode=1):
    """
    Datei öffnen:  `mode in (0, 6, 7, 8, 9)`
    Datei Schreiben `mode in (1, 2, 3, 4, 5, 10)`
    see: ('''http://api.libreoffice.org/docs/idl/ref/
            namespacecom_1_1sun_1_1star_1_1ui_1_1
            dialogs_1_1TemplateDescription.html''' )
    """

    filepicker = createUnoService( "com.sun.star.ui.dialogs.OfficeFilePicker" )
    if path:
        filepicker.setDisplayDirectory(path )
    filepicker.initialize( ( mode,) )
    if filepicker.execute():
        return filepicker.getFiles()[0]