OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Delete unused custom paragraph styles.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets
View previous topic :: View next topic  
Author Message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Sun Oct 22, 2006 2:51 pm    Post subject: Delete unused custom paragraph styles. Reply with quote

EDIT: See Villeroy's version, further down, for a more sophisticated macro which handles different types of styles.

Over here http://www.oooforum.org/forum/viewtopic.phtml?t=31625 someone asked for this and thinking it would get little use I did a basic Basic macro. Apparently more people use this than I anticipated - it seems that importing MS Word documents leads to this. For this reason I have updated the macro to handle styles found in tables and frames. It still does not handle headers, footers or footnotes, but if needed I can try to add them.

OOo's predefined paragraph styles can not be deleted!

Hopefully you will be able to copy and paste this macro without problems but I would point out that that the function "PreDefineStyles" uses many "_"s to continue code to the next line. The "_" should be the last character is such a line and some times copy & paste will insert a space after one of these and you will get a macro error. Just delete the trailing space(s).
Code:
Sub DeleteExcessParagraphStyles 'Version 2, John Vigor, Jr., 10/22/06
'>>>>>>>>>>>>>USER VARIABLES<<<<<<<<<<<<<<
ShowFirstMessage = True 'Change to False to avoid 1st message.
ShowStylesInUse = False 'Change to True to display currently
'used styles. "Standard" is the internal name for "Default". 
AskDelete = True 'Change to False if you don't want to be
'asked about deleting any style.
'>>>>>>>>>>>END USER VARIABLES<<<<<<<<<<<<
Dim inUse()
oDoc = ThisComponent
If ShowFirstMessage then
 a$ = "Remove unused styles?" & chr(13) & "This will not affect OOo's predefined styles."
 If MsgBox(a$,4,"Paragraph Style Remover") = 7 then End
EndIf
PreDefined = PreDefineStyles 'Array of all predefined paragraph styles.
oEnum = oDoc.Text.createEnumeration
While oEnum.hasMoreElements
 thisElement = oEnum.nextElement
 If Not thisElement.SupportsService("com.sun.star.text.TextTable") then
   FillInUse(InUse,thisElement)
  Else EnumerateTable(InUse,thisElement)
 EndIf
Wend
oFrames = oDoc.getTextFrames
cnt = oFrames.getCount - 1
For c = 0 to cnt
 thisFrame = oFrames.getByIndex(c)
 oEnum = thisFrame.createEnumeration
 While oEnum.hasMoreElements
  thisElement = oEnum.nextElement
  If Not thisElement.SupportsService("com.sun.star.text.TextTable") then
    FillInUse(InUse,thisElement)
   Else EnumerateTable(InUse,thisElement)
  EndIf
 Wend
Next
If ShowStylesInUse then
 Print "Current document styles are " & Join(inUse()," - ")
EndIf
oStyles = oDoc.getStyleFamilies
oParaStyles = oStyles.getByName("ParagraphStyles")
oParaStyleNames() = oParaStyles.getElementNames()
For i = 0 to uBound(oParaStyleNames)
 thisName = oParaStyleNames(i)
 Do
  For c = 0 to uBound(inUse())
   If inUse(c) = thisName then Exit Do
  Next c
  For c = 0 to uBound(PreDefined())
   If PreDefined(c) = thisName then Exit Do
  Next c
  If AskDelete then
   a$ = "Delete unused paragraph style <" & thisName & ">? "
   iAns = MsgBox(a$,3)
   If iAns = 2 then End 'Cancel button.
   If iAns = 7 then goto Skip 'No button.
  EndIf
  oParaStyles.removeByName(thisName)
  DeletedStyles = DeletedStyles & thisName & Chr(13)
  SKIP:
 Loop Until c > uBound(inUse())
Next i
If Len(DeletedStyles) = 0 then DeletedStyles = "None"
MsgBox (DeletedStyles,,"The following unused custom styles were deleted:")
End Sub

Sub EnumerateTable(InUse,thisElement)
aCellNames = thisElement.getCellNames
For c = 0 to uBound(aCellNames)
 oCell = thisElement.getCellByName(aCellNames(c))
 ParaEnum = oCell.createEnumeration
 While ParaEnum.hasMoreElements
  thisPara = ParaEnum.nextElement
  FillInUse(InUse,thisPara)
 Wend
Next 
End Sub

Sub FillInUse(InUse,Para)
Do
 For i = 0 to uBound(inUse())
  If inUse(i) = Para.ParaStyleName then Exit Do
 Next
 ReDim Preserve inUse(i)
 inUse(i) = Para.ParaStyleName
Loop Until i > uBound(inUse())
End Sub

Function PreDefineStyles
aray = Array("Standard","Text body","Heading","List","Caption",_
"Index","First line indent","Hanging indent","Text body indent",_
"Salutation","Signature","List Indent","Marginalia","Heading 1",_
"Heading 2","Heading 3","Heading 4","Heading 5","Heading 6",_
"Heading 7","Heading 8","Heading 9","Heading 10","Title","Subtitle",_
"Numbering 1 Start","Numbering 1","Numbering 1 End",_
"Numbering 1 Cont.","Numbering 2 Start","Numbering 2",_
"Numbering 2 End","Numbering 2 Cont.","Numbering 3 Start",_
"Numbering 3","Numbering 3 End","Numbering 3 Cont.",_
"Numbering 4 Start","Numbering 4","Numbering 4 End",_
"Numbering 4 Cont.","Numbering 5 Start","Numbering 5",_
"Numbering 5 End","Numbering 5 Cont.","List 1 Start","List 1",_
"List 1 End","List 1 Cont.","List 2 Start","List 2","List 2 End",_
"List 2 Cont.","List 3 Start","List 3","List 3 End","List 3 Cont.",_
"List 4 Start","List 4","List 4 End","List 4 Cont.","List 5 Start",_
"List 5","List 5 End","List 5 Cont.","Index Heading","Index 1",_
"Index 2","Index 3","Index Separator","Contents Heading","Contents 1",_
"Contents 2","Contents 3","Contents 4","Contents 5",_
"User Index Heading","User Index 1","User Index 2","User Index 3",_
"User Index 4","User Index 5","Contents 6","Contents 7","Contents 8",_
"Contents 9","Contents 10","Illustration Index Heading",_
"Illustration Index 1","Object index heading","Object index 1",_
"Table index heading","Table index 1","Bibliography Heading",_
"Bibliography 1","User Index 6","User Index 7","User Index 8",_
"User Index 9","User Index 10","Header","Header left","Header right",_
"Footer","Footer left","Footer right","Table Contents","Table Heading",_
"Illustration","Table","Text","Frame contents","Footnote","Addressee",_
"Sender","Endnote","Drawing","Quotations","Preformatted Text",_
"Horizontal Line","List Contents","List Heading")
PreDefineStyles = aray
End Function


Last edited by JohnV on Sat Nov 17, 2007 9:00 am; edited 1 time in total
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Sat Nov 04, 2006 4:45 am    Post subject: Reply with quote

You're great as usual Smile How about deleting all page styles except for Default? I always face this problem when I scan a document and save to Word or RTF format.
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Mon Nov 06, 2006 6:27 am    Post subject: Reply with quote

esperantisto,

Sorry I missed your obvious reference to page sytles and caused us to exchange messages where I was talking about paragraph styles. As a lurking modarator I have deleted these but will indicate the pertinate facts they disclosed.

You are scanning documents then using ABBYY FineReader to OCR, converting the scanned graphic to text in an MS Word file. This MS Word file is then opened with OOo. The result is a file with its 1st page in the Default page style and every other page in another new custom page style. Example - a 5 page document contains 1 Default page style plus 4 other custom page styles.

Your goal is to delete all of the custom styles and have the entire document use the Default page style. Here's a little macro that will do that. Unlike the macro above, it deletes all custom page styles without regard to whether they are currently in use.

Code:
Sub DeleteCustomPageStyles
oDoc = ThisComponent
oStyles = oDoc.getStyleFamilies
oPageStyles = oStyles.getByName("PageStyles")
oPageStyleNames() = oPageStyles.getElementNames()
For i = 0 to uBound(oPageStyleNames)
 thisName = oPageStyleNames(i)
 oPageStyles.removeByName(thisName)
Next i
End Sub
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Mon Nov 06, 2006 9:57 am    Post subject: Reply with quote

Thanks once again!
Back to top
View user's profile Send private message
Villeroy
Super User
Super User


Joined: 04 Oct 2004
Posts: 10106
Location: Germany

PostPosted: Fri Nov 17, 2006 12:12 pm    Post subject: Reply with quote

Let me contribute my version of this stuff. I works with any stlye family of any doc (except base) and provides a little GUI. May be the start of a nice addon "OrganizeStyles" Idea
Copy everything into one module in order to check it out. Most of the code is from my growing set of Python/Basic-Modules.
Code:

REM  *****  BASIC  *****
REM Option Explicit
sub test_RemoveUnusedStyles()
'calls: getListBoxDialog, RemoveUnusedStyles
Dim sElements() as string, oFamilies, oFamily, sFamily$, sLabel, oDlg, i%
   oFamilies = thiscomponent.StyleFamilies
   sElements() = oFamilies.getElementNames()
   sLabel = "Pick one style family or <All>"& chr(10) _
         &"in order to remove all unused userdefined styles"
   oDlg = getListboxDialog("Remove Unused Styles", sLabel, sElements())
   With oDlg.getControl("ListBox")
      .addItem("<All>",0)
      .selectItemPos(0,True)
   End With
   i = oDlg.execute()
   sFamily = oDlg.getControl("ListBox").getSelectedItem
   if i = 0 then
      exit sub
   elseif sFamily = "<All>" then
      for i = 0 to uBound(sElements())
         oFamily = oFamilies.getByName(sElements(i))
         RemoveUnusedStyles(oFamily,True)
      next   
   else
      oFamily = thisComponent.StyleFamilies.getByName(sFamily)
      RemoveUnusedStyles(oFamily,True)
   endif
End Sub
Sub RemoveUnusedStyles(oFamily,bAsk as Boolean)
'calls: getStyleNames
Dim sUsed() as String, sMsg$,iAnswer%
sUsed() = getStyleNames(oFamily,bLocalized:=False,bUsed:=False,bUserDef:=true)
'print join(sused(),"; ")
if uBound(sUsed()) > -1 then
   sMsg = "Remove Styles "& Join(sUsed(),";")
   if bAsk then
      iAnswer = msgbox(sMsg,33,"Macro: RemoveUnusedStyles")
   else
      iAnswer = 1
   endif
   if iAnswer = 1 then
      for i= 0 to uBound(sUsed())
         oFamily.removeByName(sUsed(i))
      next
   endif
else
   msgbox "No unused styles to remove. If this is unexpected save, reload and try again"
endif
End Sub

Part of my module Awt.dynDialogs:
Code:

REM  *****  BASIC  *****
REM Option Explicit
REM get a auto-sized dialog with title, label, listbox, OK and Cancel
REM pass sFixedText with linebreaks Chr(10)
Function getListboxDialog(sTitle$,sFixedText$,aListItems())
Dim oDM,oDlg,oTools,oRegion,oRect,oPoint,oSz
   oDM = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
   oDM.Title = sTitle
   REM addAwtModel dialogModel, c.s.s.awt.UnoControl<type>, name of control,
   REM         (propertyNames), (propertyValues) !propertyNames in alpabetical order!
   addAwtModel oDM,"FixedText","FixedText", _
         Array("Label","MultiLine"), _
         Array(sFixedText,True)
   addAwtModel oDM,"ListBox","ListBox", _
         Array("Dropdown","StringItemList"), _
         Array(True,aListItems())
   addAwtModel oDM,"Button","btnOK", _
         Array("DefaultButton","Label","PushButtonType"), _
         Array(True,"OK",com.sun.star.awt.PushButtonType.OK)
   addAwtModel oDM,"Button","btnCancel", _
         Array("Label","PushButtonType"), _
         Array("Cancel",com.sun.star.awt.PushButtonType.CANCEL)
   oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
   oDlg.setModel(oDM)
   oDlg.setVisible(True)
   oTools = oDlg.getPeer.getToolkit
   oRegion = oTools.createRegion
   oPoint = createUnoStruct("com.sun.star.awt.Point")
   oPoint.X = 5
   oPoint.Y = 5
   oRect = stackVertically(oDlg,Array("FixedText","ListBox","btnOK","btnCancel"),oRegion,oPoint,5)
   oDlg.setPosSize(0,0, oRect.Width +oRect.X, oRect.Height +oRect.Y,com.sun.star.awt.PosSize.SIZE)
   getListboxDialog = oDlg
End Function
Sub addAwtModel(oDM,srv,sName,aNames(),aValues())
Dim oCM
   oCM = oDM.createInstance("com.sun.star.awt.UnoControl"+ srv +"Model")
   oCM.setPropertyValues(aNames(),aValues())
   oDM.insertByName(sName,oCM)
End Sub   
Function getControlSize(oCtrl)
'''Return preferred width and/or height, if not already set larger.'''
Dim curPS, prefSz
   curPS = oCtrl.getPosSize()
   prefSz = oCtrl.getPreferredSize()
   if curPS.Width >= prefSz.Width  then prefSz.Width = curPS.Width
   if curPS.Height >= prefSz.Height then prefSz.Height = curPS.Height
getControlSize = prefSz
End Function
Function stackVertically(oDlg,sNames(),oRegion,oPoint,optional spc)
'calls: getControlSize
'''Stack list of controls vertically, starting at point with optional spaces below.
'Calculate and set preferred width and/or height if not already set >= preferredSize.
'Out: resized oRegion with added rectangles.
'Returns new bounds of region'''
Dim y&, i%, s$, c, sz
   if isMissing(spc) then spc = 0
   y = oPoint.Y
   for i = 0 to uBound(sNames())
      s = sNames(i)
      c = oDlg.getControl(s)
      sz = getControlSize(c)
      c.setPosSize(oPoint.X, y, sz.Width, sz.Height, com.sun.star.awt.PosSize.POSSIZE)
      oRegion.unionRectangle(c.getPosSize())
      y = y +sz.Height +spc
   next
stackVertically = oRegion.getBounds()
End Function

Part of my module Standard.myTools.
Code:

'calls: bas_PushArray
'returns: a string-array of style-names
'oFamily:= a style family, derived from a doc (writer,calc,draw,impress)
'bLocalized:= return localized names of the builtin styles (eg. builtin "Default" --> german "Standard")
'bUsed:= only used styles. true/false for used/unused, missing for all
'bUserDef:= only builtin styles. true/false for userDefined/Builtin, missing for all
Function getStyleNames(oFamily,bLocalized as Boolean, _
         optional bUsed, optional bUserDef)
Dim oStyle,i%,sNames$(),sName$,chkUse as Boolean, chkUDef as Boolean
for i = 0 to oFamily.getCount -1
   oStyle = oFamily.getByIndex(i)
   if bLocalized then
      sName = oStyle.DisplayName
   else
      sName = oStyle.getName
   endif
   if (vartype(bUsed) = 11)then
      chkUse = (bUsed EQV oStyle.isInUse)
   else
      chkUse = True
   endif
   if (vartype(bUserDef) = 11) then
      chkUDef = (bUserDef EQV oStyle.isUserDefined)
   else
      chkUDef = True
   endif
   If chkUse AND chkUDef then
      bas_Pusharray sNames(),sName
   endif
next
getStyleNames = sNames()
End Function
'very simple routine appending some element to an array which can be undimensioned (LBound > UBound)
Sub bas_PushArray(xArray(),vNextElement)
Dim iUB%,iLB%
   iLB = lBound(xArray())
   iUB = uBound(xArray())
   If iLB > iUB then
      iUB = iLB
      redim xArray(iLB To iUB)
   else
      iUB = iUB +1
      redim preserve xArray(iLB To iUB)
   endif
   xArray(iUB) = vNextElement
End Sub


Last edited by Villeroy on Sat Feb 02, 2008 1:19 pm; edited 2 times in total
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Sat Nov 18, 2006 10:33 am    Post subject: Reply with quote

Villeroy,

Very nice! What else do you have in mind for an "OrganizeStyles" addon?
Back to top
View user's profile Send private message
Villeroy
Super User
Super User


Joined: 04 Oct 2004
Posts: 10106
Location: Germany

PostPosted: Sat Nov 18, 2006 11:26 am    Post subject: Reply with quote

JohnV wrote:
Villeroy,

Very nice! What else do you have in mind for an "OrganizeStyles" addon?


For each style in ${MulipleStylesSelection}
Create new style based on ${SingleStyleSelection}
Named with Prefix|Suffix ${string}

Result:
Heading1
+-Heading1_DE
Heading2
+-Heading2_DE

Or in Calc:
Currency
+-Currency_unlocked
Date
+Date_unlocked
_________________
Rest in peace, oooforum.org
Get help on https://forum.openoffice.org
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Thu Dec 28, 2006 5:44 am    Post subject: Reply with quote

JohnV, may I ask for some icing on the cake?

After I remove all custom page styles with your macro, I have the first paragraph of each page (except, obviously, the first) containing page break with the Default page style. Since all pages are in Default, this is superfluous. Could you add some code to convert those breaks into plane page breaks (with no style)?
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Thu Dec 28, 2006 9:08 am    Post subject: Reply with quote

esperantisto,
EDITED Jan. 8 and 9, 2007 to provide new code.
I think this is the code you want.
Code:
Sub DeletePageStyleFromAutoPageBreaks
Dim oDoc,oVC
oDoc = thisComponent
oVC = oDoc.CurrentController.getViewCursor
oVC.jumpToFirstPage
While oVC.jumpToNextPage
'If oVC.PageStyleName = "Standard" then 'limit to Default page style.
 If isEmpty(oVC.TextTable) then
   If oVC.BreakType = 0 Or oVC.BreakType = 4 then
    oVC.BreakType = 4 : oVC.PageDescName = ""
   EndIf
  ElseIf oVC.TextTable.BreakType = 0 Or oVC.TextTable.BreakType = 4 then
   oVC.TextTable.BreakType = 4 : oVC.TextTable.PageDescName = "" 
 EndIf
'EndIf
Wend
oVC.jumpToFirstPage
End Sub


Last edited by JohnV on Tue Jan 09, 2007 3:52 pm; edited 2 times in total
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Fri Dec 29, 2006 1:18 am    Post subject: Reply with quote

JohnV.

Sorry, looks like I haven't explained clearly enough what I want. So, the macro you've provided does not work for me.

I've uploaded an archive (http://rapidshare.com/files/9369956/sample.zip) with 3 files as illustration. Please, pay attention to the pages 2-4, namely, to the 1st paragraphs on the pages 2 and 4 and to the table on the page 3 in the files after_two_macros.odt (what I get after running the macro to remove custom page styles and the last macro you've provided) and what_i_want.odt, there, I've manually changed page break types for the paragraphs and the table.
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Fri Dec 29, 2006 1:21 am    Post subject: Reply with quote

rapidshare.com seems to have some problems, so I"ve uploaded a copy to http://webfile.ru/1260697
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Sat Dec 30, 2006 11:55 am    Post subject: Reply with quote

esperantisto,

I'm at a loss to understand what you want.

When I look at After_scan_OOo I see a 5 page document with one Default (portriat) page style and pages 2-5 in Corvert 1 or Convert 2 which are both landsape and need to be in order to properly display the tables they contain.

If the first macro you run is "Sub DeleteCustomPageStyles" then you are deleting custom paragraph styles that are in use and thus forcing pages 2-4 to Default which again is portriat where they don't display correctly.

When I look at What_I_want the pages also don't display correctly with lots of text running off the right side of the pages.

It appears that this is not an appropriate document in which to you should attempt to force in use page styles to Default.
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Thu Jan 04, 2007 5:36 am    Post subject: Reply with quote

Please, don't pay attention to the page orientation. I just took a working example I had at hand. After I run the both macros, I have only Default style for all pages, and if I call up the paragraph properties dialog for the first paragraph of any page (except the 1st) or the table properties dialog, if the page begins straight with a table, I see, that the paragraph/table invokes a page break with the Default style (the respective box ticked). I want to untick the boxes, so that the page breaks did not force any page style.
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Thu Jan 04, 2007 6:17 am    Post subject: Reply with quote

To illustrate what I want, here's a piece of code I've forged:
Code:
 oCursor = oDoc.Text.CreateTextCursor()
 oCursor.GoToStart(False)
   Do
   If oCursor.BreakType <> com.sun.star.style.BreakType.PAGE_BEFORE Then
    If NOT IsEmpty(oCursor.PageDescName) Then
      oCursor.PageDescName = ""
    End If
   End If
   Loop Until NOT oCursor.gotoNextParagraph(False)

This code looks good to me, but it does not work Sad It just removes page breaks.
Back to top
View user's profile Send private message
esperantisto
Super User
Super User


Joined: 26 Dec 2003
Posts: 779
Location: Belarus

PostPosted: Thu Jan 04, 2007 11:16 pm    Post subject: Reply with quote

Finally solved it for paragraphs Very Happy : ! So the code looks:
Code:
Sub DeleteAutoPageBreaks
oDoc = ThisComponent
oStyles = oDoc.getStyleFamilies
oPageStyles = oStyles.getByName("PageStyles")
oPageStyleNames() = oPageStyles.getElementNames()
For i = 0 to uBound(oPageStyleNames)
 thisName = oPageStyleNames(i)
 oPageStyles.removeByName(thisName)
Next i
 oCursor = oDoc.Text.CreateTextCursor()
 oCursor.GoToStart(False)
   Do
   If oCursor.BreakType <> com.sun.star.style.BreakType.PAGE_BEFORE Then
    If NOT IsEmpty(oCursor.PageDescName) Then
      oCursor.PageDescName = ""
      oCursor.BreakType = com.sun.star.style.BreakType.PAGE_BEFORE
    End If
   End If
   Loop Until NOT oCursor.gotoNextParagraph(False)
End Sub


This works, although I can't understand how Wink

Now I need to guess the code also for tables.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets All times are GMT - 8 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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