| View previous topic :: View next topic |
| Author |
Message |
StudInc Newbie


Joined: 21 Oct 2003 Posts: 1 Location: Oslo, Norway
|
Posted: Thu Oct 23, 2003 9:10 am Post subject: Convert documents in OpenOffice from python |
|
|
I have a few questions that I hope that someone could help me find answers to...
I would like to convert documents (mainly MS Word to PDF) using the filters in OpenOffice..
This I want to from a python-script by using the python-bridge....
The problem is that I can't find much information about using python and OpenOffice, so I hope that someone here could give me some tips about examples in python, or links to more documentation....
So the main questions are:
- is this possible?
- how shuold I get started with this?
PS: I have done the "Hello world"-example in the python-bridge manual..... |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
Posted: Fri Oct 24, 2003 6:19 am Post subject: |
|
|
| Quote: | | I have a few questions that I hope that someone could help me find answers to. |
I have a few answers that I hope someone will find helpful. Unfortunantly, the answer turned out with me posting a much longer set of code than I had intended. (See below.)
I have found that I can pretty much do anything in Python that I can do in Basic. The API, of course, works exactly the same way as in any other language.
So I would divide your question into two sub-problems.
1. How do I use the OOo API to convert documents from MS-Word to PDF.
2. How do I use python programs to drive OOo.
The first question has been answered countless times here in Macros and API. Basically get the Desktop object. Call it's loadComponentFromURL() method to import the word document. Now that you have the document, call its storeToURL() method to save it. Pass an array of com.sun.star.beans.PropertyValue arguments to the storeToURL to specify that you want it saved as PDF. I have written a Basic macro that converts batches of documents at a time. You can get it at OOoMacros.org, or the very latest version from here...
http://kosh.datateamsys.com/~danny/OOo/Tools/
I have posted other conversion examples in Basic here in Macros and API.
The second question has not been answered very well. I'm not sure that I can answer it very well either.
OOo includes its own Python interpreter, because of some sillyness in how the binary stdC library in OOo is different than the standard python distributions. So apparently, OOo compiles its own python such that it shares the same stdC lib as OOo.
You must run the python interpreter that is under the program directory in your OOo installation.
On Win XP I've managed to get IDLE to work from OOo's python interpreter. I did this by also having the same version of standard python installed on my machine. Then I wrote a BAT file in OOo's python directory which I use to start python. Without explaining how it works, here is MY own BAT file which I use to start up OOo's python with the interactive IDLE development environment....
| Code: | @echo off
set PATH="C:\Program Files\OpenOffice.org1.1\program;%PATH%"
set PYTHONPATH=
Set PYTHONPATH=%PYTHONPATH%;C:\Danny\Danny's Python\Modules
set PYTHONPATH=%PYTHONPATH%;C:\Python22\
set PYTHONPATH=%PYTHONPATH%;C:\Python22\DLLs
set PYTHONPATH=%PYTHONPATH%;C:\Python22\lib
set PYTHONPATH=%PYTHONPATH%;C:\Python22\lib\lib-tk
set PYTHONPATH=%PYTHONPATH%;C:\Python22\lib\site-packages
set PYTHONPATH=%PYTHONPATH%;C:\python22\Tools\idle
set PYTHONPATH=%PYTHONPATH%;C:\Program Files\OpenOffice.org1.1\program
set PYTHONPATH=%PYTHONPATH%;C:\Program Files\OpenOffice.org1.1\program\python-core-2.2.2\lib
set PYTHONHOME=C:\Program Files\OpenOffice.org1.1\program\python-core-2.2.2
"C:\Program Files\OpenOffice.org1.1\program\python-core-2.2.2\bin\python.exe" C:\python22\Tools\idle\idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9
|
As you can see, what it basically does is condition the environment variables so that OOo's python first finds its own stuff in its own directories, and then last will look in the standard python installation for stuff. Then I launch OOo's python, with a first argument that starts the idle.py file.
NOTE added on 2005-01-08
Be sure to see this additional note I added below.....
http://www.oooforum.org/forum/viewtopic.php?p=61477#61477
I get the benefit of an interactive IDLE development environment that drives OOo. Talk about productive! I can type in statements one at a time, and watch their effect on OOo. Even in Basic I usually have to type a few statements and run it. Type a few statements and run it. I can do the same in IDLE, but I can additionally type in single statements that alter live global variables that I have, and see the immediate effect on documents. _________________ Want to make OOo Drawings like the colored flower design to the left?
Last edited by DannyB on Sat Jan 08, 2005 9:20 am; edited 2 times in total |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
Posted: Fri Oct 24, 2003 6:44 am Post subject: |
|
|
Forgive me for rambling on, but I'll add some more to my last post.
Here is an example of a simple Python program that I just used.
| Code: | import OOoLib
from OOoLib import *
cSourceFile = r'C:\Documents and Settings\dbrewer\Desktop\test.doc'
cSourceURL = pathnameToUrl( cSourceFile )
cTargetFile = r'C:\Documents and Settings\dbrewer\Desktop\test.pdf'
cTargetURL = pathnameToUrl( cTargetFile )
# Open the source document.
# No filter necessary. OOo will figure it out from the .DOC extension.
oDoc = openURL( cSourceURL )
# Save the newly opened document.
# Use a tupple of property values.
# The only property value is the specification of what Filter to use for saving.
oDoc.storeToURL( cTargetURL, (createPropertyValue("FilterName","writer_pdf_Export"),) )
|
Does what you want. Short and simple.
I suppose I should have added an oDoc.dispose() to close the document, but I neglected to do this in a quickly thrown together example.
Did you NOT want the document to appear on screen? Well, then we need to pass an array of property values to the loadComponentFromURL(), which is actually inside my openURL function. The array would contain one PropertyValue whose name is "Hidden" and value is True.
Of course, the shortness is due to my standard library of useful routines. Lots of stuff is being imported from the import OOoLib statement.
Here is my standard library, which I've never posted before.
| Code: |
# OOoLib 2003-08-29-01
# by Danny Brewer
#
# A module to easily work with OpenOffice.org.
#
# Copyright (c) 2003 Danny Brewer
# Anyone may run this code.
# If you wish to modify or distribute this code, then
# you are granted a license to do so under the terms
# of the Gnu Lesser General Public License.
# See: http://www.gnu.org/licenses/lgpl.html
# Python libraries
import math
import string
# Danny's libraries
import HSBConversions
# OOo's libraries
import uno
#------------------------------------------------------------
# Uno convenience functions
#------------------------------------------------------------
# The ServiceManager of the running OOo.
oServiceManager = False
def getServiceManager( cHost="localhost", cPort="8100" ):
"""Get the ServiceManager from the running OpenOffice.org.
Then retain it in the global variable oServiceManager for future use.
"""
global oServiceManager
if not oServiceManager:
# Get the uno component context from the PyUNO runtime
oLocalContext = uno.getComponentContext()
# Create the UnoUrlResolver on the Python side.
oLocalResolver = oLocalContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", oLocalContext )
# Connect to the running OpenOffice.org and get its context.
oContext = oLocalResolver.resolve( "uno:socket,host=" + cHost + ",port=" + cPort + ";urp;StarOffice.ComponentContext" )
# Get the ServiceManager object
oServiceManager = oContext.ServiceManager
return oServiceManager
# This is the same as ServiceManager.createInstance( ... )
def createUnoService( cClass ):
"""A handy way to create a global objects within the running OOo.
"""
oServiceManager = getServiceManager()
oObj = oServiceManager.createInstance( cClass )
return oObj
# The Desktop object.
oDesktop = False
def getDesktop():
"""An easy way to obtain the Desktop object from a running OOo.
"""
global oDesktop
if not oDesktop:
oDesktop = createUnoService( "com.sun.star.frame.Desktop" )
return oDesktop
# The CoreReflection object.
oCoreReflection = False
def getCoreReflection():
global oCoreReflection
if not oCoreReflection:
oCoreReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )
return oCoreReflection
def createUnoStruct( cTypeName ):
"""Create a UNO struct and return it.
"""
oCoreReflection = getCoreReflection()
# Get the IDL class for the type name
oXIdlClass = oCoreReflection.forName( cTypeName )
# Create the struct.
oReturnValue, oStruct = oXIdlClass.createObject( None )
return oStruct
def createPropertyValue( cName=None, uValue=None, nHandle=None, nState=None ):
"""Create a com.sun.star.beans.PropertyValue struct and return it.
"""
oPropertyValue = createUnoStruct( "com.sun.star.beans.PropertyValue" )
if cName != None:
oPropertyValue.Name = cName
if uValue != None:
oPropertyValue.Value = uValue
if nHandle != None:
oPropertyValue.Handle = nHandle
if nState != None:
oPropertyValue.State = nState
return oPropertyValue
#------------------------------------------------------------
# High level general purpose functions
#------------------------------------------------------------
def openURL( cUrl, tProperties=() ):
"""Open or Create a document from it's URL.
New documents are created from URL's such as:
private:factory/sdraw
private:factory/swriter
private:factory/scalc
private:factory/simpress
"""
oDesktop = getDesktop()
oDocument = oDesktop.loadComponentFromURL( cUrl, "_blank", 0, tProperties )
return oDocument
def makeDrawDocument():
"""Create a new OOo Draw document."""
return openURL( "private:factory/sdraw" )
def makeWriterDocument():
"""Create a new OOo Writer document."""
return openURL( "private:factory/swriter" )
def makeCalcDocument():
"""Create a new OOo Calc document."""
return openURL( "private:factory/scalc" )
def makeImpressDocument():
"""Create a new OOo Impress document."""
return openURL( "private:factory/simpress" )
#------------------------------------------------------------
# Functions for working with Draw documents.
#------------------------------------------------------------
# Notes about some properties and constants for shape objects...
# LineStyle can be one of...
# com.sun.star.drawing.LineStyle.NONE
# com.sun.star.drawing.LineStyle.SOLID
# com.sun.star.drawing.LineStyle.DASH
# CircleKind can be one of...
# com.sun.star.drawing.CircleKind.FULL
# com.sun.star.drawing.CircleKind.SECTION ' a circle with a cut connected by two lines
# com.sun.star.drawing.CircleKind.CUT ' a circle with a cut connected by a line
# com.sun.star.drawing.CircleKind.ARC ' a circle with an open cut
# FillStyle can be one of...
# com.sun.star.drawing.FillStyle.NONE
# com.sun.star.drawing.FillStyle.SOLID
# com.sun.star.drawing.FillStyle.GRADIENT
# com.sun.star.drawing.FillStyle.HATCH
# com.sun.star.drawing.FillStyle.BITMAP
# TextHorizontalAdjust can be one of...
# com.sun.star.drawing.TextHorizontalAdjust.LEFT
# com.sun.star.drawing.TextHorizontalAdjust.CENTER
# com.sun.star.drawing.TextHorizontalAdjust.RIGHT
# com.sun.star.drawing.TextHorizontalAdjust.BLOCK
# TextVerticalAdjust can be one of...
# com.sun.star.drawing.TextVerticalAdjust.TOP
# com.sun.star.drawing.TextVerticalAdjust.CENTER
# com.sun.star.drawing.TextVerticalAdjust.BOTTOM
# com.sun.star.drawing.TextVerticalAdjust.BLOCK
# TextFitToSize can be one of...
# com.sun.star.drawing.TextFitToSizeType.NONE
# com.sun.star.drawing.TextFitToSizeType.PROPORTIONAL
# com.sun.star.drawing.TextFitToSizeType.ALLLINES
# com.sun.star.drawing.TextFitToSizeType.RESIZEATTR
# Useful code snippets...
# Accessing pages of a drawing document.
# oDrawPage = oDrawDoc.getDrawPages().getByIndex( 0 )
# oDrawPage = oDrawDoc.getDrawPages().getCount()
# oDrawPage = oDrawDoc.getDrawPages().insertByIndex( 1 )
#------------------------------------------------------------
# Document functions
#------------------------------------------------------------
def setDrawPageOrientationLandscape( oDrawPage ):
"""Pass in any GenericDrawPage object, and this changes it to landscape orientation,
in addition to swapping the height/width as you would expect.
"""
# Save some settings
nOldWidth = oDrawPage.Width
nOldHeight = oDrawPage.Height
nOldBorderTop = oDrawPage.BorderTop
nOldBorderLeft = oDrawPage.BorderLeft
nOldBorderRight = oDrawPage.BorderRight
nOldBorderBottom = oDrawPage.BorderBottom
# Change so that it will PRINT in landscape
oDrawPage.Orientation = uno.getConstantByName( "com.sun.star.view.PaperOrientation.LANDSCAPE" )
# Now change some paper dimensions to match
oDrawPage.Width = nOldHeight
oDrawPage.Height = nOldWidth
oDrawPage.BorderTop = nOldBorderRight
oDrawPage.BorderLeft = nOldBorderTop
oDrawPage.BorderRight = nOldBorderBottom
oDrawPage.BorderBottom = nOldBorderLeft
#------------------------------------------------------------
# Shape functions
#------------------------------------------------------------
def makeRectangleShape( oDrawDoc, oPosition=None, oSize=None ):
"""Create a new RectangleShape with an optional position and size."""
oShape = makeShape( oDrawDoc, "com.sun.star.drawing.RectangleShape", oPosition, oSize )
return oShape
def makeEllipseShape( oDrawDoc, oPosition=None, oSize=None ):
"""Create a new EllipseShape with an optional position and size."""
oShape = makeShape( oDrawDoc, "com.sun.star.drawing.EllipseShape", oPosition, oSize )
return oShape
def makeLineShape( oDrawDoc, oPosition=None, oSize=None ):
"""Create a new LineShape with an optional position and size."""
oShape = makeShape( oDrawDoc, "com.sun.star.drawing.LineShape", oPosition, oSize )
return oShape
def makeTextShape( oDrawDoc, oPosition=None, oSize=None ):
"""Create a new TextShape with an optional position and size."""
oShape = makeShape( oDrawDoc, "com.sun.star.drawing.TextShape", oPosition, oSize )
return oShape
def makePoint( nX, nY ):
"""Create a com.sun.star.awt.Point struct."""
oPoint = createUnoStruct( "com.sun.star.awt.Point" )
oPoint.X = nX
oPoint.Y = nY
return oPoint
def makeSize( nWidth, nHeight ):
"""Create a com.sun.star.awt.Size struct."""
oSize = createUnoStruct( "com.sun.star.awt.Size" )
oSize.Width = nWidth
oSize.Height = nHeight
return oSize
def findShapeByName( oShapes, cShapeName ):
"""Find a named shape within an XShapes interface.
oShapes can be a drawing page, which supports the XShapes interface.
Thus, you can find a named shape within a draw page, or within a grouped shape,
or within a selection of sseveral shapes.
"""
nNumShapes = oShapes.getCount()
for i in range( nNumShapes ):
oShape = oShapes.getByIndex( i )
cTheShapeName = oShape.getName()
if cTheShapeName == cShapeName:
return oShape
return None
def makeShape( oDrawDoc, cShapeClassName, oPosition=None, oSize=None ):
"""Create a new shape of the specified class.
Position and size arguments are optional.
"""
oShape = oDrawDoc.createInstance( cShapeClassName )
if oPosition != None:
oShape.Position = oPosition
if oSize != None:
oShape.Size = oSize
return oShape
#------------------------------------------------------------
# Color manipulation
#------------------------------------------------------------
def rgbColor( nRed, nGreen, nBlue ):
"""Return an integer which repsents a color.
The color is specified in RGB notation.
Each of nRed, nGreen and nBlue must be a number from 0 to 255.
"""
return (int( nRed ) & 255) << 16 | (int( nGreen ) & 255) << 8 | (int( nBlue ) & 255)
def hsbColor( nHue, nSaturation, nBrightness ):
"""Return an integer which repsents a color.
The color is specified in HSB notation.
Each of nHue, nSaturation and nBrightness must be a number from 0.0 to 1.0.
"""
nRed, nGreen, nBlue = HSBConversions.HSBtoRGB( nHue, nSaturation, nBrightness )
return rgbColor( nRed, nGreen, nBlue )
def redColor( nColor ):
"""Return the Red component of a color as an integer from 0 to 255.
nColor is an integer representing a color.
This function is complimentary to the rgbColor function.
"""
return (int( nColor ) >> 16) & 255
def greenColor( nColor ):
"""Return the Green component of a color as an integer from 0 to 255.
nColor is an integer representing a color.
This function is complimentary to the rgbColor function.
"""
return (int( nColor ) >> 8) & 255
def blueColor( nColor ):
"""Return the Blue component of a color as an integer from 0 to 255.
nColor is an integer representing a color.
This function is complimentary to the rgbColor function.
"""
return int( nColor ) & 255
#------------------------------------------------------------
# Drawing routines
#------------------------------------------------------------
# Multiply this number by an OOo angle in 100'ths of a degree
# to convert to radians.
nRadiansPerHundredthDegree = math.pi / 18000
def drawLine( oDrawDoc, oDrawPage, x1,y1, x2,y2, nLineColor=None ):
"""Draw a line from x1,y1 to x2,y2. Optionally specify line color.
This adds the LineShape to the page.
The LineShape is returned.
"""
# make sure size is non-zero
#if x1 = x2: x2 = x1 + 1
#if y1 = y2: y2 = y1 + 1
oPosition = makePoint( x1, y1 )
oSize = makeSize( x2-x1, y2-y1 )
oShape = makeLineShape( oDrawDoc, oPosition, oSize )
if nLineColor != None:
oShape.LineColor = nLineColor
#oShape.LineWidth = 0
oDrawPage.add( oShape )
return oShape
def drawLineVector( oDrawDoc, oDrawPage, x1,y1, nAngle,nDistance, nLineColor=None ):
"""Draw a line from x1,y1 in the direction of nAngle, for a distance of nDistance.
nAngle is measured in radians, clockwise from the 3 O'Clock (east) direction.
nDistance is in 1000ths of a centimeter.
This adds the LineShape to the page.
The LineShape is returned.
"""
nDX = math.cos( nAngle ) * nDistance
nDY = math.sin( nAngle ) * nDistance
return drawLine( oDrawDoc, oDrawPage, x1,y1, x1+nDX,y1+nDY, nLineColor )
def drawAutoSizingText( oDrawDoc, oDrawPage,
cText, nHeight, nExtraWidthPercent=40 ):
"""Create a TextShape that will automatically resize its characters
to its shape bounding rectangle.
The TextShape is created with a specified height.
The width is determined based on the natural character width of the
text.
The initial position of the text is -10000,-10000, so that the text is not visible.
This returns the TextShape, which has already been added to the drawing page,
at coordinates which make it invisible.
You must set the object's Position property to make the text visible.
(Hint: You may look at the Size property to help you determine where
you want to place the text, for instance if you are trying to center
it, or place it relative to some other shape object.)
If you don't supply nExtraWidthPercent, then a default fudge factor is used.
This is the percentage of the average character width, which is added to the shape's
total width.
"""
# Create TextShape
oShape = makeTextShape( oDrawDoc, makePoint( -10000, -10000 ), makeSize( 1, 1 ) )
# Add it to the page.
oDrawPage.add( oShape )
# Make text stick to upper left corner of the shape rather than centered within the shape.
oShape.TextHorizontalAdjust = uno.getConstantByName( "com.sun.star.drawing.TextHorizontalAdjust.LEFT" )
oShape.TextVerticalAdjust = uno.getConstantByName( "com.sun.star.drawing.TextVerticalAdjust.TOP" )
# Make the shape auto-grow in size, based on the text.
# Once we set the text, in the next step, the shape will grow to some
# unknown size, based on the current font in use.
#oShape.TextAutoGrowHeight = True
oShape.TextAutoGrowWidth = True
# Set the text of the TextShape.
# Because of the TextAutoGrowWidth, the shape now occupies some unknown size.
oShape.setString( cText )
# Get the shape's current size.
nSaveHeight = oShape.Size.Height
nSaveWidth = oShape.Size.Width
# Make the shape NOT auto-grow in size, based on the text.
#oShape.TextAutoGrowHeight = False
oShape.TextAutoGrowWidth = False
# This next setting causes the TextShape to automatically resize its characters
# to fit the size of the text shape.
oShape.TextFitToSize = uno.getConstantByName( "com.sun.star.drawing.TextFitToSizeType.PROPORTIONAL" )
# Calculate the new width, based on the desired height,
# and saved width/height ratio for the current font in use.
nWidth = nSaveWidth * (float(nHeight) / nSaveHeight)
nAverageCharacterWidth = nWidth / len( cText )
nExtraWidth = nAverageCharacterWidth * (nExtraWidthPercent / 100.0)
oShape.TextLeftDistance = nExtraWidth
oShape.TextRightDistance = nExtraWidth
nWidth = nWidth + 2 * nExtraWidth
# Now resize the TextShape.
oShape.Size.Width = nWidth
oShape.Size.Height = nHeight
return oShape
def drawArcPath( oDrawDoc, oDrawPage,
nStartX, nStartY, nStartAngle,
nArcAngle, nArcRadius, bTurnLeft ):
"""Draw an arc of a circle from a starting position and direction.
The arc has a certian radius and arc angle,
and turns either to the left or to the right.
Parameters:
nStartX and nStartY are the starting position of the "turtle".
nStartAngle is the angle direction that the turtle is pointing,
in 100'ths of a degree.
An arc is drawn by moving the turtle forward and turning either left or right as it moves.
nArcAngle is the angle of the arc describing the turtle's path,
in 100'ths of a degree.
nArcRadius is the radius of the arc describing the turtle's path.
bTurnLeft is True if the turtle turns to the left, or False to turn to the right.
Four values are returned.
(1) the circle shape, (2) the new X position, (3) new Y position, and (4) new angle.
Use the last three return values as initial values to draw another arc
which is connected to the ending position of the arc just drawn.
"""
# Figure out how big of a circle that the arc is a part of.
nCircleDiameter = nArcRadius + nArcRadius
oCircleSize = makeSize( nCircleDiameter, nCircleDiameter )
# Figure out the position of the circle (ellipse) shape object.
#
# Determine the angle of the center point from the starting position.
if bTurnLeft:
nCenterPointAngle = nStartAngle + 9000
else:
nCenterPointAngle = nStartAngle - 9000
# Convert to radians.
nCenterPointAngle = nCenterPointAngle * nRadiansPerHundredthDegree
# Determine where the center of the circle shape should be.
nCenterX = nStartX + (nArcRadius * math.cos( nCenterPointAngle ))
nCenterY = nStartY - (nArcRadius * math.sin( nCenterPointAngle ))
oCirclePosition = makePoint( nCenterX - nArcRadius, nCenterY - nArcRadius )
# Figure out what arc portion of the circle needs to be drawn.
# Angles measures in 100'ths of a degree.
if bTurnLeft:
nCircleStartAngle = nStartAngle - 9000
nCircleEndAngle = nCircleStartAngle + nArcAngle
else:
nCircleEndAngle = nStartAngle + 9000
nCircleStartAngle = nCircleEndAngle - nArcAngle
# Make the circle shape.
oCircle = makeEllipseShape( oDrawDoc, oCirclePosition, oCircleSize )
# Fill in its properties
oCircle.FillStyle = uno.getConstantByName( "com.sun.star.drawing.FillStyle.NONE" )
oCircle.CircleKind = uno.getConstantByName( "com.sun.star.drawing.CircleKind.ARC" )
oCircle.CircleStartAngle = nCircleStartAngle
oCircle.CircleEndAngle = nCircleEndAngle
# Put it on the drawing
oDrawPage.add( oCircle )
# Figure out the ending turtle location and direction.
if bTurnLeft:
nEndAngle = nStartAngle - 9000 + nArcAngle
else:
nEndAngle = nStartAngle + 9000 - nArcAngle
# Convert to radians
nEndAngleRad = nEndAngle * nRadiansPerHundredthDegree
# Ending Position
nEndX = nCenterX + (nArcRadius * math.cos( nEndAngleRad ))
nEndY = nCenterY - (nArcRadius * math.sin( nEndAngleRad ))
# Ending angle
if bTurnLeft:
nEndAngle = normalizeOOoAngle( nEndAngle + 9000 )
else:
nEndAngle = normalizeOOoAngle( nEndAngle - 9000 )
return oCircle, nEndX, nEndY, nEndAngle
def drawSpiralOfArcs( oDrawDoc, oDrawPage,
nStartX, nStartY, nStartAngle,
nArcAngle, nArcRadius, bTurnLeft,
nNumArcs,
nRadiusGrowthMultiplier=1.0, nRadiusGrowthAddIn=0 ):
"""Draw a spiral starting from a certian position and direction.
The spiral turns either towards the left or towards the right.
Parameters:
nStartX and nStartY are the starting position of the "turtle".
nStartAngle is the angle direction that the turtle is pointing,
in 100'ths of a degree.
A spiral is drawn by moving the turtle forward and turning either left or right as it moves.
nArcAngle is the angle of the first arc of the spiral,
in 100'ths of a degree.
nArcRadius is the radius of the first arc of the spiral.
bTurnLeft is True if the turtle turns to the left, or False to turn to the right.
nNumArcs is the number of arcs which are drawn.
nRadiusGrowthMultiplier - the radius of the arc is multiplied by this after each arc is drawn.
Use a number such as 1.1 to cause the radius to grow geometrically as the spiral turns.
nRadiusGrowthAddIn - this is added to the radius after each arc.
Use a number, such as the original nArcRadius / number of arcs in a complete circle to cause the radius to grow arithmeteically as the spiral turns.
Four values are returned.
(1) the spiral shape, (2) the new X position, (3) new Y position, and (4) new angle.
Use the last three return values as initial values to draw another arc
which is connected to the ending position of the arc just drawn.
"""
nX = nStartX
nY = nStartY
nAngle = nStartAngle
oShapesToGroup = createUnoService( "com.sun.star.drawing.ShapeCollection" )
for i in range( nNumArcs - 1 ):
oArcShape, nX, nY, nAngle = drawArcPath( oDrawDoc, oDrawPage, nX, nY, nAngle, nArcAngle, nArcRadius, bTurnLeft )
nArcRadius = nArcRadius * nRadiusGrowthMultiplier + nRadiusGrowthAddIn
oShapesToGroup.add( oArcShape )
oSpiralShape = oDrawPage.group( oShapesToGroup )
return oSpiralShape, nX, nY, nAngle
#------------------------------------------------------------
# Styles
#------------------------------------------------------------
def defineStyle( oDrawDoc, cStyleFamily, cStyleName, cParentStyleName=None ):
"""Add a new style to the style catalog if it is not already present.
This returns the style object so that you can alter its properties.
"""
oStyleFamily = oDrawDoc.getStyleFamilies().getByName( cStyleFamily )
# Does the style already exist?
if oStyleFamily.hasByName( cStyleName ):
# then get it so we can return it.
oStyle = oStyleFamily.getByName( cStyleName )
else:
# Create new style object.
oStyle = oDrawDoc.createInstance( "com.sun.star.style.Style" )
# Set its parent style
if cParentStyleName != None:
oStyle.setParentStyle( cParentStyleName )
# Add the new style to the style family.
oStyleFamily.insertByName( cStyleName, oStyle )
return oStyle
def defineGraphicsStyle( oDrawDoc, cStyleName, cParentStyleName=None ):
"""Add a new style to the style catalog if it is not already present.
This returns the style object so that you can alter its properties.
"""
return defineStyle( oDrawDoc, "graphics", cStyleName, cParentStyleName )
def getStyle( oDrawDoc, cStyleFamily, cStyleName ):
"""Lookup and return a style from the document.
"""
return oDrawDoc.getStyleFamilies().getByName( cStyleFamily ).getByName( cStyleName )
def getGraphicsStyle( oDrawDoc, cStyleName ):
"""Lookup and return a graphics style from the document.
"""
return getStyle( oDrawDoc, "graphics", cStyleName )
#------------------------------------------------------------
# General Utility functions
#------------------------------------------------------------
def normalizeOOoAngle( nAngleOOo ):
"""Given an angle in 100'ths of a degree,
adjust it to be from 0 to 360 degrees."""
if nAngleOOo < 0:
nSign = -1
else:
nSign = 1
nAngleOOo = nAngleOOo - (int( abs( nAngleOOo ) / 36000.0 ) * 36000 * nSign)
if nAngleOOo < 0:
nAngleOOo += 36000
return nAngleOOo
def pathnameToUrl( cPathname ):
"""Convert a Windows or Linux pathname into an OOo URL."""
if len( cPathname ) > 1:
if cPathname[1:2] == ":":
cPathname = "/" + cPathname[0] + "|" + cPathname[2:]
cPathname = string.replace( cPathname, "\\", "/" )
cPathname = "file://" + cPathname
return cPathname
|
You'll note that the functions in my library allow a high degree of similarity to how I write my Basic and Java code. _________________ Want to make OOo Drawings like the colored flower design to the left?
Last edited by DannyB on Fri Oct 24, 2003 6:59 am; edited 2 times in total |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
Posted: Fri Oct 24, 2003 6:53 am Post subject: |
|
|
Sorry again, but I just noticed that the above code OOoLib.py depends on another of my modules HSBConversions.py.
| Code: |
# HSBConversions 2003-08-21-01
# by Danny Brewer
#
# HSB to RGB color space conversion routines.
# Copyright (c) 2003 Danny Brewer
# Anyone may run this code.
# If you wish to modify or distribute this code, then
# you are granted a license to do so under the terms
# of the Gnu Lesser General Public License.
# See: http://www.gnu.org/licenses/lgpl.html
def RGBtoHSB( nRed, nGreen, nBlue ):
"""RGB to HSB color space conversion routine.
nRed, nGreen and nBlue are all numbers from 0 to 255.
This routine returns three floating point numbers, nHue, nSaturation, nBrightness.
nHue, nSaturation and nBrightness are all from 0.0 to 1.0.
"""
nMin = min( nRed, nGreen, nBlue )
nMax = max( nRed, nGreen, nBlue )
if nMin == nMax:
# Grayscale
nHue = 0.0
nSaturation = 0.0
nBrightness = nMax
else:
if nRed == nMin:
d = nGreen = nBlue
h = 3.0
elif nGreen == nMin:
d = nBlue - nRed
h = 5.0
else:
d = nRed - nGreen
h = 1.0
nHue = ( h - ( float( d ) / (nMax - nMin) ) ) / 6.0
nSaturation = (nMax - nMin) / float( nMax )
nBrightness = nMax / 255.0
return nHue, nSaturation, nBrightness
def HSBtoRGB( nHue, nSaturation, nBrightness ):
"""HSB to RGB color space conversion routine.
nHue, nSaturation and nBrightness are all from 0.0 to 1.0.
This routine returns three integer numbers, nRed, nGreen, nBlue.
nRed, nGreen and nBlue are all numbers from 0 to 255.
"""
# Scale the brightness from a range of 0.0 thru 1.0
# to a range of 0.0 thru 255.0
# Then truncate to an integer.
nBrightness = int( min( nBrightness * 256.0, 255.0 ) )
if nSaturation == 0.0:
# Grayscale because there is no saturation
nRed = nBrightness
nGreen = nBrightness
nBlue = nBrightness
else:
# Make hue angle be within a single rotation.
# If the hue is > 1.0 or < 0.0, then it has
# "gone around the color wheel" too many times.
# For example, a value of 1.2 means that it has
# gone around the wheel 1.2 times, which is really
# the same ending angle as 0.2 trips around the wheel.
# Scale it back to the 0.0 to 1.0 range.
if nHue > 1.0:
nHue = nHue - int( nHue )
elif nHue < 0.0:
nHue = abs( nHue )
if nHue > 1.0:
nHue = nHue - int( nHue )
nHue = 1.0 - nHue
# Rescale hue to a range of 0.0 thru 6.0
nHue = nHue * 6.0
# Separate hue into int and fractional parts
iHue = int( nHue )
fHue = nHue - iHue
# Is hue even?
if iHue % 2 == 0:
fHue = 1.0 - fHue
#
m = nBrightness * (1.0 - nSaturation)
n = nBrightness * (1.0 - (nSaturation * fHue))
if iHue == 1:
nRed = n
nGreen = nBrightness
nBlue = m
elif iHue == 2:
nRed = m
nGreen = nBrightness
nBlue = n
elif iHue == 3:
nRed = m
nGreen = n
nBlue = nBrightness
elif iHue == 4:
nRed = n
nGreen = m
nBlue = nBrightness
elif iHue == 5:
nRed = nBrightness
nGreen = m
nBlue = n
else:
nRed = nBrightness
nGreen = n
nBlue = m
return nRed, nGreen, nBlue
|
This is getting longer than I planned just to give you a short example program. _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
ianperryman General User

Joined: 16 Jan 2004 Posts: 7 Location: Ottawa
|
Posted: Fri Jan 16, 2004 12:16 pm Post subject: tried to make example work in "batch" mode caused |
|
|
I modified your example slightly to run the command as you suggested in Hidden mode. I also opened soffice in invisible mode. I used your tool UnoConnectionListener-2003-11-03-01.sxd to setup UNO with my local host.
# I could not remember the python syntax for a boolean true, so I used 1==1 which evalutates to true
oDoc = openURL( cSourceURL,(createPropertyValue("Hidden",1==1),) )
I opened OO with "soffice -invisible"
It core dumped when I after I executed the storeToURL ....
oDoc.storeToURL( cTargetURL, (createPropertyValue("FilterName","writer_pdf_Export"),) )
It works fine if I don't use the "Hidden" property.
I was using a Linux OO 1.1.0 |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
|
| Back to top |
|
 |
accabrown Power User

Joined: 21 Apr 2004 Posts: 75 Location: England
|
Posted: Wed Apr 21, 2004 4:26 am Post subject: another ooo python library |
|
|
which might be some use to someone
| Code: |
#!/usr/bin/python
# acb's first try at a python/ooo script
# cribbed from all sorts of examples.
# round up the usual suspects
import sys,os,os.path,string
import re
import uno
import unohelper
from com.sun.star.uno import RuntimeException
from com.sun.star.connection import NoConnectException
from com.sun.star.lang import IllegalArgumentException
from com.sun.star.io import IOException
from com.sun.star.beans import UnknownPropertyException
# bootstrap uno component context
# make some stuff generally available -- a desktop, pathsetter, and anything else that seems useful
class Writerslice:
def __init__(self):
try:
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext )
try:
smgr = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" )
except NoConnectException, e:
print "OpenOffice process not found or not listening"
print e.Message
except RuntimeException, e:
print "An unknown error occured: " + e.Message
raise e
remoteContext = smgr.getPropertyValue( "DefaultContext" )
self.pathsetter=smgr.createInstanceWithContext("com.sun.star.util.PathSettings",remoteContext)
self.desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",remoteContext)
try:
self.ActiveDocument=self.desktop.getCurrentComponent()
except RuntimeException, e:
print "Failed to load Active document ( "+ e.Message+ ")"
raise e
if self.ActiveDocument==None:
print "no active document when initialising"
except RuntimeException, e:
print 'failure in __init__ routine'
print e.Message
raise e
def getActiveDocument(self):
''' returns the current open component as an object'''
try:
self.ActiveDocument=self.desktop.getCurrentComponent()
except RuntimeException, e:
print "Failed to load Active document ( "+ e.Message+ ")"
def dumbquoteToascii(self,astring):
'''returns a copy of astring with all the smartquotes
and dashes stripped out and replaced by ascii chars'''
tmpstring=astring.replace(u'\u201c',r'"')
astring=tmpstring.replace(u'\u201d',r'"')
tmpstring=astring.replace(u'\u2018',r"'")
astring=tmpstring.replace(u'\u2019',r"'")
tmpstring=astring.replace(u'\u2013',r"--") # OOO uses en dashes (2013) not word's em dashes (2014)
tmpstring=astring.replace(u'\u2014',r"--") # OOO uses en dashes (2013) not word's em dashes (2014)
astring=tmpstring.replace(u'\u2026',r'...') # ellipsis (...)
return astring
def getTextFromDoc(self):
''' gets a document object and returns the cleaned text to stdout
returns None on Failure, with an error message to stdout, so can check for success'''
try:
mytext=self.ActiveDocument.Text
rawtext= mytext.getString()
cleantext=self.dumbquoteToascii(rawtext)
try:
return cleantext.encode('utf-8') # maybe
#return cleantext
except UnicodeError, e:
print 'unicode error in getTextFromDoc'
print e
return None
except:
print "error retrieving text in getTextfromDoc"
#print e
return None
def getAllStyledText(self,astyle):
'''accepts a style name; checks it for sanity; returns a list of the text contents of
all pars in that style in the AD)'''
if not astyle in self.listActiveStyles():
# print 'The Style named %s not found in this document' %(astyle)
return None
else:
listopars=[]
oSD=self.ActiveDocument.createSearchDescriptor()
oSD.SearchStyles=1
oSD.SearchString=astyle
gotmany=self.ActiveDocument.findAll(oSD)
if gotmany.getCount()>0:
for numpars in range(gotmany.getCount()):
partext=gotmany.getByIndex(numpars).getString()
if partext<>'\r': # don't want empty pars
listopars.append(partext)
return listopars
def getWordCount(self):
return str(self.ActiveDocument.WordCount)
def isFileOpen(self,systempath):
fileURL=unohelper.systemPathToFileUrl(systempath)
openfiles=self.desktop.getComponents().createEnumeration()
while openfiles.hasMoreElements():
anotherfile=openfiles.nextElement()
try:
if anotherfile.getLocation()==fileURL:
foundit=1
except:
continue # it may not have a location -- ignore it if so
return foundit
def loadFile(self,systempath):
'''makes ActiveDocument the file whose system path is given as a string.
either by loading it from disk, or if it is open, switching to it'''
fileURL=unohelper.systemPathToFileUrl(systempath)
# the next section sorts through the open files
openfiles=self.desktop.getComponents().createEnumeration()
while openfiles.hasMoreElements():
anotherfile=openfiles.nextElement()
if anotherfile.getLocation()==fileURL:
anotherfile.getCurrentController().getFrame().activate()
self.ActiveDocument=anotherfile
break
self.ActiveDocument = self.desktop.loadComponentFromURL( fileURL,"_blank", 0, () )
def loadHiddenFile(self,systempath):
'''chesks to see file not open; switches to it if it is; loads invisibly otherwise.'''
from com.sun.star.container import NoSuchElementException
alreadyopen=0
fileURL=unohelper.systemPathToFileUrl(systempath)
# the next section sorts through the open files
openfiles=self.desktop.getComponents().createEnumeration()
while openfiles.hasMoreElements():
try:
anotherfile=openfiles.nextElement()
except NoSuchElementException:
break
try:
if anotherfile.getLocation()==fileURL:
alreadyopen=1
anotherfile.getCurrentController().getFrame().activate()
self.ActiveDocument=anotherfile
break
except:
break
if not alreadyopen:
from com.sun.star.beans import PropertyValue
myProps=PropertyValue()
myProps.Name="Hidden"
myProps.Value=1
try:
self.ActiveDocument= self.desktop.loadComponentFromURL( fileURL,"_blank", 0, (myProps,) )
except:
print "Failure to load %s" %systempath
def closefile(self):
'''closes the active cdocument'''
self.ActiveDocument.close(1)
def chdir(self,adir):
''' accepts a string and changes the active directory to it. So wants a fully qualified path'''
self.pathsetter.Work=unohelper.systemPathToFileUrl(adir)
def getCurrentOOODir(self):
'''just prints out the active directrory, for checking'''
print self.pathsetter.Work
def convertToURL(self,astring):
'''now just a wrapper for a less memorable name'''
return unohelper.systemPathToFileUrl(astring)
def convertFromURL(self,anURL):
'''now just a wrapper for the unohelper funciton I forget'''
return unohelper.fileUrlToSystemPath(anURL)
def listAllStyles(self):
'''provides a (very long) list of all the paragraph styles available to a document'''
listostyles=[]
if self.ActiveDocument:
allstyles=self.ActiveDocument.getStyleFamilies().getByName('ParagraphStyles')
for things in range(allstyles.getCount()):
listostyles.append(allstyles.getByIndex(things).DisplayName)
return listostyles
def listActiveStyles(self):
'''returns a list containing only the paragraph styles in use in a document'''
listostyles=[]
if self.ActiveDocument:
allstyles=self.ActiveDocument.getStyleFamilies().getByName('ParagraphStyles')
for things in range(allstyles.getCount()):
if allstyles.getByIndex(things).isInUse():
listostyles.append(allstyles.getByIndex(things).DisplayName)
return listostyles
def listCharStyles(self):
'''provides a (very long) list of all the Character styles available to a document'''
listostyles=[]
if self.ActiveDocument:
allstyles=self.ActiveDocument.getStyleFamilies().getByName('CharacterStyles')
for things in range(allstyles.getCount()):
listostyles.append(allstyles.getByIndex(things).DisplayName)
return listostyles
def setBoldasHTML(self):
'''replaces OO writer's Bold with HTML formatting'''
repldesc=self.ActiveDocument.createReplaceDescriptor()
repldesc.ValueSearch=1
from com.sun.star.beans import PropertyValue
from com.sun.star.awt.FontWeight import BOLD
myStruct=PropertyValue()
myStruct.Name="CharWeight"
myStruct.Value=BOLD
repldesc.setSearchAttributes((myStruct,))
repldesc.SearchRegularExpression=1
repldesc.SearchString='.*'
repldesc.ReplaceString = "<strong>&</strong>"
numdone=self.ActiveDocument.replaceAll(repldesc)
print ' %s Bold occurences tarted up ' %numdone
def setItalasHTML(self):
'''replaces OO writer's Italics with HTML formatting'''
repldesc=self.ActiveDocument.createReplaceDescriptor()
repldesc.ValueSearch=1
from com.sun.star.beans import PropertyValue
from com.sun.star.awt.FontSlant import ITALIC
myStruct=PropertyValue()
myStruct.Name="CharPosture"
myStruct.Value=ITALIC
repldesc.setSearchAttributes((myStruct,))
repldesc.SearchRegularExpression=1
repldesc.SearchString='.*'
repldesc.ReplaceString = "<em>&</em>"
numdone=self.ActiveDocument.replaceAll(repldesc)
print ' %s Italic occurences tarted up ' %numdone
def getslug(self):
'''extracts from the active document a string containing
all paragraphs written in the styles 'slug', 'heading1', or
(for word documents) 'Heading 1'.
or, failing those, the title'''
listostuff=[]
# print 'looking for slug text (enhanced)'
possibleheadings=('Slug',
'slug',
'heading1',
'Heading 1')
for styles in possibleheadings:
if self.getAllStyledText(styles):
listostuff=self.getAllStyledText(styles)
break
if not listostuff:
return None
else:
return string.join(listostuff,' ')
def getSmallPrint(self):
'''returns a string of the small printed text'''
listostuff=self.getAllStyledText("Small Print")
if listostuff:
return string.join(listostuff,' ')
def listNormalPars(self):
return getAllStyledText("Default")
def lastThreeWords(self,randomstring):
''' pass in a string of chars and spaces,
returns the last a string with the last three words in it'''
import string
return string.join(randomstring.split(' ')[-3:])
def getAllQuotes(self):
'''returns a list of all the double-quoted strings in the ActiveDocument)'''
import string
import re
listoquotes=[]
doublequotes=re.compile(u'\u201c(.+?)\u201d',re.DOTALL)
stringoftext=self.ActiveDocument.getText().getString()
listoquotes=doublequotes.findall(stringoftext)
return listoquotes
def dategrabber(self,maybedate):
'''Takes a string and checks the last three words
to see if they form a date. Returns a date value if they do.'''
from mx.DateTime.Parser import DateFromString
try:
testbit=self.lastThreeWords(maybedate) # last three words
except:
return None
try:
DateFromString(testbit)
return testbit
except:
return None
def insertbq(self,listoquotes,astring):
''' accepts a list of strings from getallquotes:
writes long ones back between blockquote tags to 'astring'.
These may or may not contain paragraph returns and inner quotes.
'''
import string
for quotes in listoquotes :
if string.count(quotes,' ')>50 :
newquote='<blockquote>'+quotes+'</blockquote>'
snurfle=astring.replace(quotes,newquote)
astring=snurfle # the old soft-shoe shuffle
return astring
def dumbquoteToHTML(self,astring):
'''returns a copy of astring with all the smartquotes
and dashes stripped out and replaced by HTML entities'''
tmpstring=astring.replace(u'\u201c',r'“')
astring=tmpstring.replace(u'\u201d',r'”')
tmpstring=astring.replace(u'\u2018',r"‘")
astring=tmpstring.replace(u'\u2019',r"’")
tmpstring=astring.replace(u'\u2013',r" ") # em dashes are #2013 in OOo
astring=tmpstring.replace(u'\u2026',r'…') # and the ellipsis (...)
return astring
if __name__=="__main__":
ws=Writerslice()
| [/quote] |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|