~ubuntu-branches/debian/stretch/bibus/stretch

« back to all changes in this revision

Viewing changes to .pc/fix-finalize-with-LO4.patch/bibOOo/bibOOoBase.py

  • Committer: Package Import Robot
  • Author(s): Jan Beyer
  • Date: 2014-09-02 21:54:07 UTC
  • mfrom: (4.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20140902215407-0002tj24epm8y6u8
Tags: 1.5.2-4
* Add a patch for compatibility with python-wxgtk3.0 (Closes: #758943)
  - Reworked patching bibOOo/bibOOoBase.py as separate patch
* Standards-Version 3.9.5 (no changes needed)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2004,2005 Pierre Martineau <pmartino@users.sourceforge.net>
2
 
# This file is part of bibOOo, a python package to manipulate
3
 
# bibliography in an OpenOffice.org writer document.
4
 
#
5
 
# bibOOo is part of Bibus a free software;
6
 
# you can redistribute it and/or modify
7
 
# it under the terms of the GNU General Public License as published by
8
 
# the Free Software Foundation; either version 2 of the License, or
9
 
# (at your option) any later version.
10
 
#/home/pmartino/Desktop/Bibus/bibus-cvs/bibus/bibOOo/bibOOoBase.py
11
 
# bibOOo is distributed in the hope that it will be useful,
12
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
# GNU General Public License for more details.
15
 
#
16
 
# You should have received a copy of the GNU General Public License
17
 
# along with Bibus; if not, write to the Free Software
18
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
19
 
#
20
 
# this class implements basic interaction between a biliographic software and OOo
21
 
 
22
 
from __future__ import generators       # py2.2, to be removed in python 2.3
23
 
import sys, os
24
 
import uno
25
 
# below we commented the normal way to call the class/constants
26
 
# the form used is to be compatible with cx_freeze
27
 
#from com.sun.star.connection import NoConnectException
28
 
NoConnectException = uno.getClass("com.sun.star.connection.NoConnectException")
29
 
#from com.sun.star.uno  import RuntimeException
30
 
RuntimeException = uno.getClass("com.sun.star.uno.RuntimeException")
31
 
#from com.sun.star.lang import IllegalArgumentException, DisposedException
32
 
IllegalArgumentException = uno.getClass("com.sun.star.lang.IllegalArgumentException")
33
 
DisposedException = uno.getClass("com.sun.star.lang.DisposedException")
34
 
#from com.sun.star.io import IOException
35
 
IOException = uno.getClass("com.sun.star.io.IOException")
36
 
#from com.sun.star.container import NoSuchElementException
37
 
NoSuchElementException = uno.getClass("com.sun.star.container.NoSuchElementException")
38
 
#from com.sun.star.util import URL
39
 
URL = uno.getClass("com.sun.star.util.URL")
40
 
#from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK
41
 
PARAGRAPH_BREAK = uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK")
42
 
#from com.sun.star.beans import PropertyValue
43
 
PropertyValue = uno.getClass("com.sun.star.beans.PropertyValue")
44
 
#from com.sun.star.beans.PropertyState import DIRECT_VALUE
45
 
DIRECT_VALUE = uno.getConstantByName("com.sun.star.beans.PropertyState.DIRECT_VALUE")
46
 
#from com.sun.star.lang import Locale
47
 
Locale = uno.getClass("com.sun.star.lang.Locale")
48
 
# Styles
49
 
#from com.sun.star.awt.FontSlant import ITALIC, NONE
50
 
#FontSlantNone = NONE
51
 
ITALIC = uno.getConstantByName("com.sun.star.awt.FontSlant.ITALIC")
52
 
FontSlantNone = uno.getConstantByName("com.sun.star.awt.FontSlant.NONE")
53
 
#from com.sun.star.awt.FontWeight import BOLD, NORMAL
54
 
BOLD = uno.getConstantByName("com.sun.star.awt.FontWeight.BOLD")
55
 
NORMAL = uno.getConstantByName("com.sun.star.awt.FontWeight.NORMAL")
56
 
#from com.sun.star.awt.FontUnderline import SINGLE, NONE
57
 
#FontUnderlineNone = NONE
58
 
SINGLE = uno.getConstantByName("com.sun.star.awt.FontUnderline.SINGLE")
59
 
FontUnderlineNone = uno.getConstantByName("com.sun.star.awt.FontUnderline.NONE")
60
 
#from com.sun.star.style.CaseMap import UPPERCASE,SMALLCAPS, NONE
61
 
#CaseMapNone = NONE
62
 
UPPERCASE = uno.getConstantByName("com.sun.star.style.CaseMap.UPPERCASE")
63
 
SMALLCAPS = uno.getConstantByName("com.sun.star.style.CaseMap.SMALLCAPS")
64
 
CaseMapNone = uno.getConstantByName("com.sun.star.style.CaseMap.NONE")
65
 
#
66
 
 
67
 
from bibOOo.CONST import *
68
 
 
69
 
class bibOOo_Error(Exception):
70
 
        """Main error class
71
 
        bibOOo_Error--|
72
 
                      |-----bibOOo_NoConnect-----|
73
 
                      |                          |----bibOOo_NoOffice
74
 
                      |                          |----bibOOo_NoWriter
75
 
                      |
76
 
                      |-----bibOOo_ExecError-----|
77
 
                                                 |----bibOOo_PositionError
78
 
                                                 |----bibOOo_StyleError
79
 
                                                 |----bibOOo_IOError
80
 
        """
81
 
        msg = ''
82
 
        def __init__(self,OOo=''):
83
 
                self.OOo = OOo  # we propagate the OOo error message in this attribute or an additional information
84
 
 
85
 
class bibOOo_NoConnect(bibOOo_Error):
86
 
        """Global class for connection error"""
87
 
        msg = _("Cannot connect to Openoffice. See Documentation.")
88
 
class bibOOo_NoOffice(bibOOo_NoConnect):
89
 
        """We were not able to connect to a OOo instance"""
90
 
        msg = _("Cannot connect to Openoffice. See Documentation.")
91
 
class bibOOo_NoWriter(bibOOo_NoConnect):
92
 
        """The top most OOo document is not a writer doc"""
93
 
        msg = _("The front document in OOo must be a Writer document.")
94
 
 
95
 
class bibOOo_ExecError(bibOOo_Error):
96
 
        """Parent class for all error related to bibOOo specific problems"""
97
 
        msg = _("Non allowed operation""")
98
 
class bibOOo_PositionError(bibOOo_ExecError):
99
 
        """We are trying to apply a function at a non suited position"""
100
 
        msg = _("Incorrect position")
101
 
class bibOOo_StyleError(bibOOo_ExecError):
102
 
        """Error in the style file"""
103
 
        msg = _("Style format Error")
104
 
class bibOOo_IOError(bibOOo_ExecError):
105
 
        """File error operation"""
106
 
        msg = _("File error operation")
107
 
 
108
 
class bibOOo_Ref(object):
109
 
        """This class is a wrapper for OOo in-text citations
110
 
        You can access the citation
111
 
        as attributes : bibRef.Author etc...
112
 
        Can be used to set or read citations in the current doc"""
113
 
 
114
 
        def __init__(self,bibOOo_instance,OOoRef=None,ref=(),dbdict={}):
115
 
                """
116
 
                model is the document model in which we want to create the citation.
117
 
                bibOOo_instance is needed only if OOoRef == None
118
 
                OORef = "com.sun.star.text.TextField.Bibliography"
119
 
                if OORef == None, we create a "com.sun.star.text.TextField.Bibliography"
120
 
                from
121
 
                                a list/tuple = (identifier,BibliographicType,....,ISBN)
122
 
                                or
123
 
                                dbdict = dictionary = {'Identifier':'toto', 'BibliographicType':1, 'Address':'NY', 'Annote':'Note', ...}
124
 
                                the dbdict.keys() may be incomplete => Absent fields will be set to '', BibliographicType to 1 = ARTICLE
125
 
                or an empty reference of type = 1 (ARTICLE)
126
 
                then in all cases we wrap the OOo object
127
 
                """
128
 
                if not OOoRef:
129
 
                        self.OOoRef = bibOOo_instance.model.createInstance("com.sun.star.text.TextField.Bibliography")
130
 
                        if ref:
131
 
                                self.setRef(ref)
132
 
                                #tmp = [ PropertyValue(field,0,ref[OO_BIBLIOGRAPHIC_FIELDS[field]],DIRECT_VALUE) for field in OO_BIB_FIELDS ]
133
 
                        elif dbdict:
134
 
                                tmp=[]
135
 
                                for field in OO_BIB_FIELDS:
136
 
                                        try: tmp.append( PropertyValue(field,0,dbdict[field],DIRECT_VALUE) )
137
 
                                        except KeyError: tmp.append( PropertyValue(field,0,'',DIRECT_VALUE) )
138
 
                                if 'BibliographicType' in dbdict.keys():
139
 
                                        tmp[1] = PropertyValue('BibiliographicType',0,dbdict['BibliographicType'],DIRECT_VALUE) # to correct spelling error in OOo
140
 
                                if tmp[1].Value == '':
141
 
                                        tmp[1] = PropertyValue('BibiliographicType',0,1,DIRECT_VALUE)   # default type == ARTICLE
142
 
                                self.OOoRef.Fields = tuple(tmp)
143
 
                        else:
144
 
                                #tmp = [ PropertyValue(field,0,'',DIRECT_VALUE) for field in OO_BIB_FIELDS ]
145
 
                                #tmp[1] = PropertyValue('BibiliographicType',0,1,DIRECT_VALUE) # ARTICLE
146
 
                                self.setRef( ('', 1, '', '', '','', '', '', '', '', '','', '', '', '', '', '', '','', '', '', '', '', '', '', '','', '', '', '', '') )
147
 
                        #self.OOoRef.Fields = tuple(tmp)
148
 
                else:
149
 
                        self.OOoRef = OOoRef
150
 
                        
151
 
        #def __eq__(self,other):                                                        # suppressed because it did not work in Ubuntu 7.10
152
 
        #       return self.Identifier == other.Identifier
153
 
                
154
 
        #def __ne__(self,other):
155
 
        #       return self.Identifier != other.Identifier
156
 
 
157
 
        def __getattr__(self,attr):
158
 
                """ If it is a BIBLIOGRAPHIC_FIELDS, we return the value
159
 
                otherwise, we return the attribute of the OORef
160
 
                This way we can directly access the method of the OOo ref object """
161
 
                if attr in OO_BIB_FIELDS:
162
 
                        return self.OOoRef.Fields[OO_BIBLIOGRAPHIC_FIELDS[attr]].Value
163
 
                elif attr == 'BibliographicType':       # spelling error in OOo
164
 
                        return self.OOoRef.Fields[1].Value
165
 
                else:
166
 
                        return getattr(self.OOoRef,attr)
167
 
 
168
 
        def __setattr__(self,attr,value):
169
 
                if attr in OO_BIB_FIELDS:
170
 
                        tmp = list(self.OOoRef.Fields)
171
 
                        tmp[OO_BIBLIOGRAPHIC_FIELDS[attr]] = PropertyValue(attr,0,value,DIRECT_VALUE)
172
 
                        self.OOoRef.Fields = tuple(tmp)
173
 
                elif attr == 'BibliographicType':       # spelling error in OOo
174
 
                        tmp = list(self.OOoRef.Fields)
175
 
                        tmp[1] = PropertyValue('BibiliographicType',0,value,DIRECT_VALUE)
176
 
                        self.OOoRef.Fields = tuple(tmp)
177
 
                elif attr == 'OOoRef':
178
 
                        object.__setattr__(self,'OOoRef',value)
179
 
                else:
180
 
                        raise AttributeError
181
 
 
182
 
        def setRef(self,ref):
183
 
                """
184
 
                Set the values of the reference using the data in
185
 
                ref which is a list/tuple.
186
 
                This is much faster than setting field by field
187
 
                """
188
 
                tmp = [ PropertyValue(field,0,ref[OO_BIBLIOGRAPHIC_FIELDS[field]],DIRECT_VALUE) for field in OO_BIB_FIELDS ]
189
 
                self.OOoRef.Fields = tuple(tmp)
190
 
 
191
 
 
192
 
class bibOOoBase(object):
193
 
        """This is the main class to interact with OOo"""
194
 
# ------------------------ Connection setup ------------------------------
195
 
        def __init__(self,con_type=1,host='localhost',port=8100,pipe='OOo_pipe'):
196
 
                """We connect to the running OOo instance
197
 
                con_type = connection_type = 1 if pipe ; 0 if TCP
198
 
                host = host for TCP
199
 
                port = port for TCP
200
 
                pipe = pipe name
201
 
                """
202
 
                if con_type == 0:
203
 
                        OO_CON_STR = "uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext"%(host,port)
204
 
                else:
205
 
                        OO_CON_STR = "uno:pipe,name=%s;urp;StarOffice.ComponentContext"%pipe
206
 
                # get the uno component context from the PyUNO runtime
207
 
                localContext = uno.getComponentContext()
208
 
                # create the UnoUrlResolver
209
 
                resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
210
 
                try:
211
 
                        # connect to the running office
212
 
                        ctx = resolver.resolve( OO_CON_STR )
213
 
                        self.smgr = ctx.ServiceManager
214
 
                        # get the central desktop object
215
 
                        self.desktop = self.smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
216
 
                        # some utilities
217
 
                        self.transformer = MagicTransformer( ctx )      # this is to force PropertyValue.Value to the desired type because of a python bug
218
 
                        self.oTrans = self.smgr.createInstanceWithContext("com.sun.star.util.URLTransformer", ctx ) # used in __freezeBib to format URL
219
 
                        #
220
 
                except NoConnectException, e:
221
 
                        raise bibOOo_NoOffice, e.Message
222
 
                except IllegalArgumentException, e:
223
 
                        #print "The url is invalid (%s)" % e.Message
224
 
                        raise bibOOo_NoOffice, e.Message
225
 
                except RuntimeException, e:
226
 
                        #print "An unknown error occured (%s)" % e.Message
227
 
                        raise bibOOo_NoOffice, e.Message
228
 
 
229
 
        def connectToWriter(self, hilight = False, backColor = 0x00FFFF00, createBib = True, end = True):
230
 
                """connect to the top OOo document if it is a writer doc"""
231
 
                self.bib = None                                 # bibliographic index
232
 
                try:
233
 
                        self.model = self.desktop.getCurrentComponent()
234
 
                        if self.model and self.model.getImplementationName() == 'SwXTextDocument':      # this is a text document
235
 
                                self.controller = self.model.getCurrentController()
236
 
                                self.cursor = self.controller.getViewCursor()   # Current ViewCursor
237
 
                                # access the document's text property
238
 
                                self.text = self.model.Text
239
 
                                # look for the first bibliography index or create a new one at the end if no biblio index present
240
 
                                bibFound = False
241
 
                                for i in range(self.model.getDocumentIndexes().getCount()):
242
 
                                        self.bib = self.model.getDocumentIndexes().getByIndex(i)
243
 
                                        if self.bib.getServiceName() == 'com.sun.star.text.Bibliography':
244
 
                                                bibFound = True
245
 
                                                break
246
 
                                if not bibFound and createBib:
247
 
                                        # we create the bibliography index at the end of the document
248
 
                                        self.createIndex(end)
249
 
                                # we get the com.sun.star.text.FieldMaster.Bibliography after eventually creating it
250
 
                                try:
251
 
                                        self.tfm = self.model.getTextFieldMasters().getByName('com.sun.star.text.FieldMaster.Bibliography')     # the biblio TextFieldMaster
252
 
                                except NoSuchElementException:
253
 
                                        self.tfm = self.model.createInstance("com.sun.star.text.FieldMaster.Bibliography")
254
 
                                self.stylesList = self.model.getStyleFamilies() # styles set XIndexAccess (XStyleFamiliesSupplier interface)
255
 
                                self.__createBaseStyles()                                       # create the styles if needed
256
 
                                self.hilightCitations(hilight, background = backColor)  # hilight citations if required. Just change the CharStyle
257
 
                                #self.setIndexFormat()                                          # set the biblio format REMOVED BECAUSE IT IS TOO SLOW !!!!
258
 
                        else:
259
 
                                #print "You must have a text document opened in OpenOffice.org in oder to be able to use this menu"
260
 
                                raise bibOOo_NoWriter
261
 
                except DisposedException,e:
262
 
                        raise bibOOo_NoOffice,e.Message
263
 
 
264
 
# ------------------------ iteration ------------------------------
265
 
        def __iter__(self):
266
 
                for cit in self.getCitations(None):
267
 
                        yield cit
268
 
 
269
 
# functions to get a sorted list of citations
270
 
        def __isFused(self,x,y,cursor):
271
 
                """Return True if the two citations x & y are separated only by spaces => can be fused"""
272
 
                try:
273
 
                        cursor.gotoRange(x.Anchor.End,False)
274
 
                        if not x.Anchor.Text.compareRegionStarts(cursor,y.Anchor):
275
 
                                return True                     # we should not need it but it does not work if the two ranges start at the same position
276
 
                        cursor.gotoRange(y.Anchor.Start,True)
277
 
                        return not bool(cursor.String.strip(' '))       # if only white spaces between citations => we fuse them
278
 
                #except IllegalArgumentException:
279
 
                except:
280
 
                        return False                                                            # we are not in the same Text or something goes wrong
281
 
 
282
 
        def groupCitations(self,refs):
283
 
                """We group the citations in refs list.
284
 
                We return a list of list.
285
 
                Each list is a group of citations
286
 
                i.e. citations separated by blank spaces"""
287
 
                refs_out=[]
288
 
                if refs:
289
 
                        lastref = refs[0]
290
 
                        tmp_range=[lastref]
291
 
                        tmpcursor = lastref.Anchor.Text.createTextCursor()
292
 
                        for ref in refs[1:]:
293
 
                                if self.__isFused(lastref,ref,tmpcursor):
294
 
                                        tmp_range.append(ref)
295
 
                                else:
296
 
                                        refs_out.append(tmp_range)
297
 
                                        tmp_range = [ref]
298
 
                                        tmpcursor = ref.Anchor.Text.createTextCursor()
299
 
                                lastref = ref
300
 
                        refs_out.append(tmp_range)
301
 
                return refs_out
302
 
 
303
 
        def getCitations(self,order=None):
304
 
                """Return a list of the citations ordered as
305
 
                order == None : unsorted
306
 
                order == index : order of the bibliographic index
307
 
                order == document : order in the document
308
 
                order == group : list of list. Order as document. When citations are consecutives they are in a sub-list.
309
 
                Exemple: "Start doc [1] [2] continue [3] continue [4][5]" will give: [[1,2],[3],[4,5]]
310
 
                """
311
 
                # we first update the index and references.
312
 
                #updateRef()                                    # we update the references to be up-to-date
313
 
                #refs = list(self.tfm.getPropertyValue('DependentTextFields'))  # we get the references
314
 
                refs = [ bibOOo_Ref(self,ref) for ref in self.tfm.getPropertyValue('DependentTextFields') ]     # we get the references and wrap them in bibOOo_Ref objects
315
 
                lbb = len(self.tfm.BracketBefore)       # used later to get the numbers without the brackets
316
 
                lba = -len(self.tfm.BracketAfter)
317
 
                if order == None:
318
 
                        return refs
319
 
                elif order == 'index':
320
 
                        SavedState = self.tfm.IsNumberEntries
321
 
                        self.tfm.IsNumberEntries = True                 # we number citations to get the order of them
322
 
                        self.model.getTextFields().refresh()
323
 
                        #
324
 
                        tmplist = [(int(x.getPresentation(False)[lbb:len(x.getPresentation(False))+lba]), x) for x in refs]
325
 
                        tmplist.sort()
326
 
                        refs = [x for (key, x) in tmplist]
327
 
                        #
328
 
                        self.tfm.IsNumberEntries = SavedState                   # we reverse to the original state
329
 
                        return refs
330
 
                else:
331
 
                        # to sort by document:
332
 
                        # 1) We put for each ref a unique identifier (a number)
333
 
                        # 2) We ask OOo to sort by doc + numbers. As identifiers are uniques => each ref has its own number = order
334
 
                        # 3) We sort using the getPresentation(False)
335
 
                        # 4) We put back the correct identifiers
336
 
                        # 1)
337
 
                        savedIdentifiers=[]
338
 
                        i = 0
339
 
                        for ref in refs:
340
 
                                savedIdentifiers.append(ref.Identifier)
341
 
                                ref.Identifier = repr(i)
342
 
                                i = i+1
343
 
                        # 2)
344
 
                        SavedState = self.tfm.IsNumberEntries, self.tfm.IsSortByPosition
345
 
                        self.tfm.IsNumberEntries = True
346
 
                        self.tfm.IsSortByPosition = True
347
 
                        self.model.getTextFields().refresh()
348
 
                        # 3)
349
 
                        tmplist = [(int(x.getPresentation(False)[lbb:len(x.getPresentation(False))+lba]), x) for x in refs]
350
 
                        tmplist.sort()
351
 
                        refs = [x for (key, x) in tmplist]
352
 
                        # 4)
353
 
                        for ref in refs:
354
 
                                ref.Identifier = savedIdentifiers[int(ref.Identifier)]
355
 
                        #
356
 
                        self.model.getTextFields().refresh()
357
 
                        self.tfm.IsNumberEntries, self.tfm.IsSortByPosition = SavedState
358
 
                        if order == 'document': return refs
359
 
                        if order == 'group' : return self.groupCitations(refs)                                  # order = 'group'
360
 
                        raise ValueError('What are we doing here? bibOOo line 357. order = %r is not a correct value.'%order)
361
 
# end of functions to get a sorted list of citations
362
 
 
363
 
 
364
 
 
365
 
# ------------------------ Index ------------------------------
366
 
        def createIndex(self,end = True):
367
 
                """create bibliographic index at the end if True, or at the current cursor position if False"""
368
 
                cursor = self.text.createTextCursor()
369
 
                if end: cursor.gotoEnd(False)                           # we create at the end of the doc
370
 
                else: cursor.gotoRange(self.cursor,False)       # or at the view cursor
371
 
                self.text.insertControlCharacter(cursor,PARAGRAPH_BREAK,False)
372
 
                self.bib = self.model.createInstance("com.sun.star.text.Bibliography")
373
 
                self.text.insertTextContent(cursor,self.bib,False)
374
 
                if self.text.compareRegionEnds(self.cursor,cursor) == 0: # the viewcursor was at the end of the doc
375
 
                        self.cursor.gotoRange(self.bib.getAnchor().getStart(),False)    # we must relocate it before the index
376
 
                        self.cursor.goLeft(1,False)                     # we are now just before the index
377
 
                self.bib.update()                                               # update the new index (title, etc.)
378
 
 
379
 
        def updateIndex(self):
380
 
                """Update bibliography index"""
381
 
                self.model.getTextFields().refresh()    # refresh the fields in case citation format has changed
382
 
                if self.bib: self.bib.update()                  # update de la biblio if it exists
383
 
 
384
 
        def setIndexFormat(self,format):
385
 
                """
386
 
                set the format of the bibliographic index
387
 
                format is a dictionary:
388
 
                format.keys() = ['SortKeys', 'Title', 'Locale', 'IsNumberEntries', 'SortAlgorithm', 'IsSortByPosition', 'Bracket']
389
 
                exemples:
390
 
                format['index']['Locale']  = 'en_US'
391
 
                format['index']['Title'] = 'Bibliography'
392
 
                format['index']['IsNumberEntries'] = True | False
393
 
                format['index']['SortAlgorithm'] = 'alphanumeric'
394
 
                format['index']['IsSortByPosition'] = True | False    True = sorted in doc order ; False =  sorted as in defined in SortKeys
395
 
                format['index']['Bracket'] = '[]'
396
 
                format['index']['SortKeys'] = ((4, True), (23, True)) = ( (field1,ascending),(field2,ascending), ... )
397
 
                field1, field2 = zero based index of the field in CONST.OO_BIB_FIELDS ( 4 = Author ; 23 = Year )
398
 
                ascending = True
399
 
                descending = False
400
 
                format['ordering']['ARTICLE'] = tuple of tuple = ('text',text,style) | ('field',field_name,style) | ('tab',value,TabStopFillCharacter) | ('tab',None,TabStopFillCharacter)
401
 
                where style = bibOOo_italic | bibOOo_bold ...
402
 
                for tabs, if value = None => right aligned
403
 
                exemple :  ( ('field', u'Author', 0), ('text', u' (', 0), ('field', u'Year', 0), ('text', u')', 0) ) = Einstein (1920)
404
 
                this must be defined for all the references types = BIB_TYPE
405
 
                you can use format['ordering']['JOURNAL'] = format['ordering']['ARTICLE'] etc.. to save space
406
 
                """
407
 
                if not self.bib: return         # if no bib, we it will crash
408
 
                # set Bibliography service
409
 
                self.bib.Locale = Locale(format['index']['Locale'][:2],format['index']['Locale'][-2:],'')
410
 
                self.bib.SortAlgorithm = format['index']['SortAlgorithm']
411
 
                self.bib.Title = format['index']['Title']
412
 
                # set Bibliography FieldMaster
413
 
                self.tfm.IsNumberEntries = bool(format['index']['IsNumberEntries'])
414
 
                self.tfm.IsSortByPosition = bool(format['index']['IsSortByPosition'])
415
 
                if format['index']['Bracket']:
416
 
                        self.tfm.BracketBefore = format['index']['Bracket'][0]
417
 
                        self.tfm.BracketAfter = format['index']['Bracket'][1]
418
 
                else:
419
 
                        self.tfm.BracketBefore = ''
420
 
                        self.tfm.BracketAfter = ''
421
 
                # set Bibliography FieldMaster SortKeys
422
 
                tmp = [ ( PropertyValue('SortKey',0,i[0],DIRECT_VALUE) , PropertyValue('IsSortAscending',0,bool(i[1]),DIRECT_VALUE) ) for i in format['index']['SortKeys'] ]
423
 
                self.tfm.SortKeys = tuple(tmp)
424
 
                # set Bibliography service LevelFormat (=fields ordering)
425
 
                for reftype in BIB_TYPE:
426
 
                        tmp=[]
427
 
                        for token in tuple(format['ordering'][reftype]):
428
 
                                if token[0] == 'text':
429
 
                                        tmp.append((PropertyValue("TokenType",0,"TokenText",DIRECT_VALUE),\
430
 
                                        PropertyValue("CharacterStyleName",0,self.__setStyleName(token[2]),DIRECT_VALUE),\
431
 
                                        PropertyValue("Text",0,token[1],DIRECT_VALUE)))
432
 
                                elif token[0] == 'field':
433
 
                                        tmp.append((PropertyValue("TokenType",0,"TokenBibliographyDataField",DIRECT_VALUE),\
434
 
                                        PropertyValue("CharacterStyleName",0,self.__setStyleName(token[2]),DIRECT_VALUE),\
435
 
                                        PropertyValue("BibliographyDataField",0,OO_BIBLIOGRAPHIC_FIELDS[token[1]],DIRECT_VALUE)))
436
 
                                elif token[0] == 'tab':
437
 
                                        if token[1] != None:
438
 
                                                # PropertyValue("TabStopPosition",0,uno.Any('long',token[1]),DIRECT_VALUE), # does not work!
439
 
                                                # the two following lines are a workaround for this bug.
440
 
                                                special = PropertyValue("TabStopPosition",0,token[1],DIRECT_VALUE)
441
 
                                                special = self.transformer.transform( special, "Value" , uno.Any( "long", token[1] ) )
442
 
                                                tmp.append((PropertyValue("TokenType",0,"TokenTabStop",DIRECT_VALUE),\
443
 
                                                special,\
444
 
                                                PropertyValue("TabStopFillCharacter",0,token[2],DIRECT_VALUE),\
445
 
                                                PropertyValue("CharacterStyleName",0,"",DIRECT_VALUE)))
446
 
                                        else:
447
 
                                                tmp.append((PropertyValue("TokenType",0,"TokenTabStop",DIRECT_VALUE),\
448
 
                                                PropertyValue("TabStopRightAligned",0,True,DIRECT_VALUE),\
449
 
                                                PropertyValue("TabStopFillCharacter",0,token[2],DIRECT_VALUE),\
450
 
                                                PropertyValue("CharacterStyleName",0,"",DIRECT_VALUE)))
451
 
                                else:
452
 
                                        raise bibOOo_StyleError, "Error in the style file: I can't understand a token like %r" %token.__repr__()
453
 
                        # the following two lines are a work around for bug #12504. See python-uno FAQ.
454
 
                        # since self.bib.LevelFormat.replaceByIndex(OO_BIBLIOGRAPHIC_TYPE[reftype]+1,tuple(tmp)) does not work
455
 
                        unoseq = uno.Any("[][]com.sun.star.beans.PropertyValue",tuple(tmp))
456
 
                        uno.invoke(self.bib.LevelFormat,"replaceByIndex",(BIBLIOGRAPHIC_TYPE[reftype]+1,unoseq))
457
 
                        # remark: +1 in the previous line since Index=1=ARTICLE, etc...
458
 
 
459
 
# ------------------------ CharStyles ------------------------------
460
 
        def __createBaseStyles(self):
461
 
                """create base CharStyle for citations and index"""
462
 
                charStyles = self.stylesList.getByName('CharacterStyles')
463
 
                if not charStyles.hasByName(bibOOo_cit_baseCharStyleName):
464
 
                        self.createCharacterStyle(bibOOo_cit_baseCharStyleName,bibOOo_regular,bibOOo_normal,'')
465
 
                if not charStyles.hasByName(bibOOo_index_baseCharStyleName):
466
 
                        self.createCharacterStyle(bibOOo_index_baseCharStyleName,bibOOo_regular,bibOOo_normal,'')
467
 
 
468
 
        def __setStyleName(self,charstyle):
469
 
                """create a charStyle corresponding to charStyle if needed
470
 
                return the style name as:
471
 
                bibOOo_base<''|i><''|b><''|u><''|s|c> where i=italic, b=bold, u=underline, s=smallcaps, c=caps"""
472
 
                # calculating style name
473
 
                italic,bold,underline,caps = '','','',''
474
 
                if charstyle & bibOOo_italic: italic = 'i'
475
 
                if charstyle & bibOOo_bold: bold = 'b'
476
 
                if charstyle & bibOOo_underline: underline = 'u'
477
 
                if charstyle & bibOOo_caps: caps = 'c'
478
 
                elif charstyle & bibOOo_smallcaps: caps = 's'
479
 
                stylename = ''.join( (bibOOo_index_baseCharStyleName,italic,bold,underline,caps) )      # bibOOo_index_base ; bibOOo_index_basei ; etc...
480
 
                # creating style if needed based on bibus_base
481
 
                charStyles = self.stylesList.getByName('CharacterStyles')
482
 
                if not charStyles.hasByName(stylename):
483
 
                        self.createCharacterStyle(stylename,charstyle,bibOOo_normal,bibOOo_index_baseCharStyleName)
484
 
                return stylename
485
 
 
486
 
        def createCharacterStyle(self,charstylename,charstyle,position,parentstylename=''):
487
 
                """
488
 
                create an OOo CharacterStyle "com.sun.star.style.CharacterStyle" with the name charstylename if it does not exist
489
 
                set its parent charstyle to parentstylename
490
 
                set its value to style
491
 
                where style is a combination of
492
 
                from bibOOo_CONST import bibOOo_regular,bibOOo_italic,bibOOo_bold,bibOOo_caps,bibOOo_smallcaps,bibOOo_underline
493
 
                from bibOOo_CONST import bibOOo_normal,bibOOo_exposant,bibOOo_indice
494
 
                style = bibOOo_italic | bibOOo_bold =  italic + bold
495
 
                position = bibOOo_normal (=0) OR bibOOo_exposant (=1) OR bibOOo_indice (= -1)
496
 
                """
497
 
                charStyles = self.stylesList.getByName('CharacterStyles')
498
 
                if not charStyles.hasByName(charstylename):
499
 
                        tmp_style = self.model.createInstance('com.sun.star.style.CharacterStyle')      # create a char style
500
 
                        charStyles.insertByName(charstylename,tmp_style)        # insert the style in the document
501
 
                        if parentstylename: tmp_style.setParentStyle(parentstylename)   # set parent charstyle
502
 
                        # we save the default values default from newly created style
503
 
                        basePosture,baseWeight,baseUnderline,baseCaps = tmp_style.CharPosture, tmp_style.CharWeight, tmp_style.CharUnderline, tmp_style.CharCaseMap
504
 
                        # setting only the specific attributes
505
 
                        if charstyle & bibOOo_italic and basePosture != ITALIC: tmp_style.CharPosture = ITALIC
506
 
                        elif not charstyle & bibOOo_italic and basePosture == ITALIC: tmp_style.CharPosture = FontSlantNone
507
 
                        #
508
 
                        if charstyle & bibOOo_bold and baseWeight != BOLD: tmp_style.CharWeight = BOLD
509
 
                        elif not charstyle & bibOOo_bold and baseWeight == BOLD: tmp_style.CharWeight = NORMAL
510
 
                        #
511
 
                        if charstyle & bibOOo_underline and baseUnderline != SINGLE: tmp_style.CharUnderline = SINGLE
512
 
                        elif not charstyle & bibOOo_underline and baseUnderline == SINGLE: tmp_style.CharUnderline = FontUnderlineNone
513
 
                        #
514
 
                        if charstyle & bibOOo_caps and baseCaps != UPPERCASE: tmp_style.CharCaseMap = UPPERCASE
515
 
                        elif charstyle & bibOOo_smallcaps and baseCaps != SMALLCAPS: tmp_style.CharCaseMap = SMALLCAPS
516
 
                        elif not charstyle & bibOOo_caps and not charstyle & bibOOo_smallcaps and baseCaps!=CaseMapNone: tmp_style.CharCaseMap = CaseMapNone
517
 
                        # CharEscapement = 101 means automatique exposant ; -101 indice ; 0 normal
518
 
                        tmp_style.CharEscapement = 101 * position               # automatic
519
 
                        if tmp_style.CharEscapement:
520
 
                                tmp_style.CharEscapementHeight = 58                             # value ok in French. Other languages ?
521
 
                        else:
522
 
                                tmp_style.CharEscapementHeight = 100
523
 
 
524
 
        def updateCharacterStyle(self,charstylename,charstyle,position,parentstylename=''):
525
 
                """Reset values of style charstylename"""
526
 
                charStyles = self.stylesList.getByName('CharacterStyles')
527
 
                if charStyles.hasByName(charstylename):
528
 
                        tmp_style = charStyles.getByName(charstylename)
529
 
                        # reset all properties to default. Property list must be on alphabetical order!!!!
530
 
                        tmp_style.setPropertiesToDefault( ('CharCaseMap','CharEscapement','CharEscapementHeight','CharPosture','CharUnderline','CharWeight') )
531
 
                        if parentstylename: tmp_style.setParentStyle(parentstylename)   # set parent charstyle
532
 
                        # we save the default values default from newly created style
533
 
                        basePosture,baseWeight,baseUnderline,baseCaps = tmp_style.CharPosture, tmp_style.CharWeight, tmp_style.CharUnderline, tmp_style.CharCaseMap
534
 
                        # setting only the specific attributes
535
 
                        if charstyle & bibOOo_italic and basePosture != ITALIC: tmp_style.CharPosture = ITALIC
536
 
                        elif not charstyle & bibOOo_italic and basePosture == ITALIC: tmp_style.CharPosture = FontSlantNone
537
 
                        #
538
 
                        if charstyle & bibOOo_bold and baseWeight != BOLD: tmp_style.CharWeight = BOLD
539
 
                        elif not charstyle & bibOOo_bold and baseWeight == BOLD: tmp_style.CharWeight = NORMAL
540
 
                        #
541
 
                        if charstyle & bibOOo_underline and baseUnderline != SINGLE: tmp_style.CharUnderline = SINGLE
542
 
                        elif not charstyle & bibOOo_underline and baseUnderline == SINGLE: tmp_style.CharUnderline = FontUnderlineNone
543
 
                        #
544
 
                        if charstyle & bibOOo_caps and baseCaps != UPPERCASE: tmp_style.CharCaseMap = UPPERCASE
545
 
                        elif charstyle & bibOOo_smallcaps and baseCaps != SMALLCAPS: tmp_style.CharCaseMap = SMALLCAPS
546
 
                        elif not charstyle & bibOOo_caps and not charstyle & bibOOo_smallcaps and baseCaps!=CaseMapNone: tmp_style.CharCaseMap = CaseMapNone
547
 
                        # CharEscapement = 101 means automatique exposant ; -101 indice ; 0 normal
548
 
                        tmp_style.CharEscapement = 101 * position               # automatic
549
 
                        if tmp_style.CharEscapement:
550
 
                                tmp_style.CharEscapementHeight = 58                             # value ok in French. Other languages ?
551
 
                        else:
552
 
                                tmp_style.CharEscapementHeight = 100
553
 
 
554
 
 
555
 
        def styleRef(self,ref,charstylename = bibOOo_cit_baseCharStyleName):
556
 
                """Set the CharStyle of the bibOOo_Ref object to charstylename"""
557
 
                c = ref.Anchor.Text.createTextCursorByRange(ref.Anchor)
558
 
                c.CharStyleName = charstylename
559
 
 
560
 
        def hilightCitations(self,hilight = True, citStyleName = bibOOo_cit_baseCharStyleName, background = 0x00FFFF00):
561
 
                """
562
 
                Set the background of charStyle bibOOo_cit_baseCharStyleName
563
 
                to background (default = yellow)
564
 
                if hilight = True
565
 
                elif hilight = False => background = Default
566
 
                """
567
 
                charStyles = self.stylesList.getByName('CharacterStyles')
568
 
                tmp_style = charStyles.getByName(bibOOo_cit_baseCharStyleName)
569
 
                if hilight:
570
 
                        tmp_style.CharBackColor = background                    # background (default = yellow)
571
 
                else:
572
 
                        tmp_style.setPropertyToDefault('CharBackColor') # normal background
573
 
 
574
 
        def resetCitationStyle(self,charstylename = bibOOo_cit_baseCharStyleName):
575
 
                """
576
 
                Reset the style of all the citations to bibOOo_cit_baseCharStyleName
577
 
                This is needed if some citations have been inserted by another means than
578
 
                bibOOo, for instance when the user has used the classical OOo interface.
579
 
                """
580
 
                for ref in self:
581
 
                        c = ref.Anchor.Text.createTextCursorByRange(ref.Anchor)
582
 
                        c.CharStyleName = charstylename                         # reset the style it case it has changed
583
 
 
584
 
# ------------------------ Citations ------------------------------
585
 
        def insertRef(self,ref,charstylename = bibOOo_cit_baseCharStyleName):
586
 
                """bibOOo_Ref object => insert at the current cursor position
587
 
                using CharStyle charstylename
588
 
                """
589
 
                if self.notInBibIndex(self.cursor):
590
 
                        c = self.cursor.Text.createTextCursorByRange(self.cursor)       # Add at cursor location (replace selection)
591
 
                        c.CharStyleName = charstylename
592
 
                        c.Text.insertTextContent(c,ref.OOoRef,True)
593
 
                        self.cursor.setPropertyToDefault('CharStyleName')                       # reset cursor to default
594
 
                else:
595
 
                        raise bibOOo_PositionError,"Try to insert a reference in the Bibliographic index"
596
 
 
597
 
        def createRef(self,ref=(),dbdict={}):
598
 
                """
599
 
                create a bibOOo_Ref object from
600
 
                a tuple/list = (identifier,BibliographicType,....,ISBN)
601
 
                return an empty ARTICLE if ref=()
602
 
                """
603
 
                return bibOOo_Ref(self,None,ref,dbdict)
604
 
 
605
 
# ------------------------ Freezing ------------------------------
606
 
        def __fuse_range(self,numbers,cit_rangesep='-'):
607
 
                """numbers is a sorted list of integers.
608
 
                We return a list of strings where 1,2,3 => '1(cit_rangesep)3' """
609
 
                tmpranges,tmp = [],[]
610
 
                tmp = [numbers[0]]
611
 
                for i in xrange(1,len(numbers)):
612
 
                        if numbers[i] == numbers[i-1] + 1:
613
 
                                        tmp.append(numbers[i])
614
 
                                        continue
615
 
                        else:
616
 
                                if len(tmp) >=3:
617
 
                                        tmpranges.append("%s-%s"%(tmp[0],tmp[-1]))      # we fuse
618
 
                                else:
619
 
                                        tmpranges.extend(map(lambda x:repr(x),tmp))
620
 
                                tmp = [numbers[i]]
621
 
                if len(tmp) >=3:
622
 
                        tmpranges.append("%s%s%s"%(tmp[0],cit_rangesep,tmp[-1]))        # we fuse
623
 
                else:
624
 
                        tmpranges.extend(map(lambda x:repr(x),tmp))
625
 
                return tmpranges
626
 
 
627
 
        def __freezeNumberedCitations(self,messages = lambda i,x:sys.stdout.write('%s\n'%x),cit_sort=True,cit_fuse=True,cit_range=True,cit_separator='; ',cit_rangesep='-'):
628
 
                """
629
 
                format the in-text citations (sort,range,style, etc..)
630
 
                for numbers:
631
 
                        depending on cit_sort,cit_fuse,cit_range we replace
632
 
                        [1] [3][2][5] => [1-3,5] etc...
633
 
                """
634
 
                apply(messages, (.7,msg7 ))
635
 
                if not cit_fuse and not cit_sort:
636
 
                        for ref in self:                                # we don't mind about the order
637
 
                                c = ref.Anchor.Text.createTextCursorByRange(ref.Anchor.End)
638
 
                                ref.Anchor.Text.insertString(c,ref.getPresentation(0),True)
639
 
                else:
640
 
                        refranges = self.getCitations(order='group')
641
 
                        for refs in refranges:
642
 
                                c = refs[0].Anchor.Text.createTextCursorByRange(refs[0].Anchor.End)     # cursor at end
643
 
                                bb = self.tfm.BracketBefore
644
 
                                ba = self.tfm.BracketAfter
645
 
                                lbb = len(bb)
646
 
                                lba = -len(ba)
647
 
                                numbers = [ int(x.getPresentation(False)[lbb:len(x.getPresentation(False))+lba]) for x in refs ]
648
 
                                numbers.sort()
649
 
                                if cit_range:
650
 
                                        ranges = self.__fuse_range(numbers,cit_rangesep)                                                                # calculate ranges
651
 
                                elif cit_sort:
652
 
                                        ranges = [repr(x) for x in numbers]
653
 
                                else:
654
 
                                        print "What are we doing here. bibOOo line 492"
655
 
                                # we insert in the text
656
 
                                refs[0].Anchor.Text.insertString(c,"%s%s%s" %(bb,cit_separator.join(ranges),ba),True)
657
 
 
658
 
        def __freezeIdentifierCitations(self,messages = lambda i,x:sys.stdout.write('%s\n'%x),cit_fuse=True,cit_separator='; '):
659
 
                """
660
 
                for identifiers:
661
 
                        we just copy/paste the identifiers with fusion if cit_fuse = True
662
 
                """
663
 
                apply(messages, (.7,msg7 ))
664
 
                if not cit_fuse:
665
 
                        for ref in self:                                # we don't mind about the order
666
 
                                c = ref.Anchor.Text.createTextCursorByRange(ref.Anchor.End)
667
 
                                ref.Anchor.Text.insertString(c,ref.getPresentation(0),True)
668
 
                else:
669
 
                        refranges = self.getCitations(order='group')
670
 
                        for refs in refranges:
671
 
                                c = refs[0].Anchor.Text.createTextCursorByRange(refs[0].Anchor.End)     # cursor at end
672
 
                                bb = self.tfm.BracketBefore
673
 
                                ba = self.tfm.BracketAfter
674
 
                                lbb = len(bb)
675
 
                                lba = -len(ba)
676
 
                                identifiers = [x.getPresentation(False)[lbb:len(x.getPresentation(False))+lba] for x in refs]
677
 
                                # we insert in the text
678
 
                                refs[0].Anchor.Text.insertString(c,"%s%s%s" %(bb,cit_separator.join(identifiers),ba),True)
679
 
 
680
 
        def freezeCitations(self,messages = lambda i,x:sys.stdout.write('%s\n'%x),cit_sort=True,cit_fuse=True,cit_range=True,cit_separator='; ',cit_rangesep='-'):
681
 
                """
682
 
                format the in-text citations (sort,range,style, etc..)
683
 
                for numbers:
684
 
                        depending on cit_sort,cit_fuse,cit_range we replace
685
 
                        [1] [3][2][5] => [1-3,5] etc...
686
 
                for identifiers:
687
 
                        we just copy/paste the identifiers with fusion if cit_fuse = True
688
 
                """
689
 
                # we first freeze the citations
690
 
                if self.tfm.IsNumberEntries:
691
 
                        self.__freezeNumberedCitations(messages,cit_sort,cit_fuse,cit_range,cit_separator,cit_rangesep)
692
 
                else:
693
 
                        self.__freezeIdentifierCitations(messages,cit_fuse,cit_separator)
694
 
                self.freezeIndex()                                                      # we freeze the index
695
 
                self.tfm.dispose()                                                      # we remove all the citations
696
 
 
697
 
        def freezeIndex(self):
698
 
                """
699
 
                make a copy of the bibliographic index, then remove the index
700
 
                Freeze the index by copying then pasting it.
701
 
                """
702
 
                #Cut = '.uno:Cut'               # 'slot:5710'   # slot values. May change in the future ?
703
 
                Copy = '.uno:Copy'              # 'slot:5711'
704
 
                Paste = '.uno:Paste'    # 'slot:5712'
705
 
                self.cursor.gotoRange(self.bib.Anchor,False)    # select the bib
706
 
                oUrl = URL()
707
 
                oUrl.Complete = Copy    # copy the current selection
708
 
                countOfUrls,parsedUrl = self.oTrans.parseSmart( oUrl, ".uno" )
709
 
                oDisp = self.controller.queryDispatch( parsedUrl, "", 0 )
710
 
                if oDisp != None:
711
 
                        oDisp.dispatch(parsedUrl,())
712
 
                        # Move The cursor After the index
713
 
                        self.cursor.collapseToEnd()
714
 
                        self.cursor.goRight(1,False)
715
 
                        # Then paste the index
716
 
                        oUrl.Complete = Paste   # paste the clipboard
717
 
                        countOfUrls,parsedUrl = self.oTrans.parseSmart( oUrl, ".uno" )
718
 
                        oDisp = self.controller.queryDispatch( parsedUrl, "", 0 )
719
 
                        if oDisp != None:
720
 
                                oDisp.dispatch(parsedUrl,())
721
 
                                self.text.insertControlCharacter(self.cursor,PARAGRAPH_BREAK,False)
722
 
                                # Dispose the index
723
 
                                self.bib.dispose()
724
 
 
725
 
        def __newDoc(self):
726
 
                """Save the current doc if needed, then create a new one = copy"""
727
 
                if self.model.isModified():
728
 
                        raise bibOOo_IOError,"You must first save the current document"
729
 
                if self.model.hasLocation():
730
 
                        self.model.store()
731
 
                else:
732
 
                        raise bibOOo_IOError,"Impossible to save the current document"
733
 
                 # we store the old name
734
 
                name = self.model.getURL()
735
 
                oURL=URL()
736
 
                oURL.Complete=name
737
 
                countOfUrls,parsedUrl = self.oTrans.parseSmart( oURL, "http" )
738
 
                if countOfUrls:
739
 
                        name = os.path.splitext(parsedUrl.Name)[0]
740
 
                else:
741
 
                        name = 'text'
742
 
                #try:
743
 
                #       self.model.storeAsURL(self.model.getLocation(),())
744
 
                #except IOException:
745
 
                #       raise bibOOo_IOError,"Impossible to save the current document"
746
 
                """We open a copy"""
747
 
                fa = self.smgr.createInstance('com.sun.star.ucb.SimpleFileAccess')
748
 
                inputstream = fa.openFileRead(self.model.getLocation())
749
 
                pvDescriptor=(PropertyValue('InputStream',0,inputstream,DIRECT_VALUE),
750
 
                                          PropertyValue('Hidden',0,True,DIRECT_VALUE))
751
 
                self.model = self.desktop.loadComponentFromURL('private:stream', "_default",0,pvDescriptor)     # reload the document from stream
752
 
                self.controller = self.model.getCurrentController()
753
 
                self.cursor = self.controller.getViewCursor()   # Current ViewCursor
754
 
                self.text = self.model.Text
755
 
                # look for the first bibliography index or create a new one at the end if no biblio index present
756
 
                for i in range(self.model.getDocumentIndexes().getCount()):
757
 
                        self.bib = self.model.getDocumentIndexes().getByIndex(i)
758
 
                        if self.bib.getServiceName() == 'com.sun.star.text.Bibliography':
759
 
                                break
760
 
                # we get the com.sun.star.text.FieldMaster.Bibliography after eventually creating it
761
 
                try:
762
 
                        self.tfm = self.model.getTextFieldMasters().getByName('com.sun.star.text.FieldMaster.Bibliography')     # the biblio TextFieldMaster
763
 
                except NoSuchElementException:
764
 
                        self.tfm = self.model.createInstance("com.sun.star.text.FieldMaster.Bibliography")
765
 
                self.stylesList = self.model.getStyleFamilies() # styles XIndexAccess (XStyleFamiliesSupplier interface)
766
 
                # we define a name and we but it in the DocumentInfo Title => in the Windows title
767
 
                self.model.DocumentInfo.Title='%s-formatted' %name
768
 
                #
769
 
                return True
770
 
 
771
 
        def finalize(self,messages = lambda i,x:sys.stdout.write('%s\n'%x),**kwds):
772
 
                """
773
 
                finalize(self,cit_sort=True,cit_fuse=True,cit_range=True,cit_separator='; ')
774
 
                make a copy of the current doc
775
 
                make a copy of the bibliographic index, then remove the index
776
 
                format the in-text citations (sort,range,style, etc..)
777
 
                we print formatting messages in it
778
 
                Default = None = stdout
779
 
                """
780
 
                apply(messages, (.1,msg1) )
781
 
                if not self.__newDoc():                                                         # we try to open a copy of the current doc.
782
 
                        raise bibOOo_IOError,"Cannot save the current document" # error if not possible
783
 
                apply(messages, (.2,msg2) )
784
 
                self.__createBaseStyles()                                                       # create the citation base style if needed
785
 
                apply(messages, (.3,msg3) )
786
 
                self.hilightCitations(False)                    # we don't want to hilight for the final format
787
 
                self.resetCitationStyle()                               # reset the style for the citations
788
 
                # needed to 'freeze' the Anchors because of a bug in OOo ?
789
 
                #fixAnchors = [ref.Anchor for ref in self.getCitations(order=None)]     # bug OOo ?
790
 
                #
791
 
                # self.updateRef()                                                                      # make ref uptodate
792
 
                apply(messages, (.4,msg4) )
793
 
                if not self.bib: self.createIndex()                                     # we create the index if needed
794
 
                self.updateIndex()                                                                      # update index
795
 
                self.freezeCitations(messages = messages,**kwds)
796
 
                apply(messages, (.9,msg5) )
797
 
                self.controller.Frame.ContainerWindow.setVisible(True)  # make the new frame visible
798
 
                self.controller.Frame.ComponentWindow.setVisible(True)  # make the new doc visible
799
 
                self.model.setModified(False)                                           # disable the save button/toolbar icon
800
 
                apply(messages, (1.0,msg6) )
801
 
 
802
 
# ------------------------ Divers ------------------------------
803
 
        def saveDoc(self,url=None):
804
 
                """
805
 
                Store the current doc.
806
 
                if url != None, we use it
807
 
                Otherwise we save using the current location
808
 
                """
809
 
                if not url:
810
 
                        if self.model.hasLocation():
811
 
                                self.model.store()
812
 
                        else:
813
 
                                raise bibOOo_IOError,"Impossible to save the current document"
814
 
                else:
815
 
                        if url.endswith(".sxw"):
816
 
                                pd = (PropertyValue("FilterName",0,"StarOffice XML (Writer)",DIRECT_VALUE),)
817
 
                        elif url.endswith(".odt"):
818
 
                                pd = (PropertyValue("FilterName",0,"writer8",DIRECT_VALUE),)
819
 
                        else:   # default format
820
 
                                pd = ()
821
 
                        try:
822
 
                                self.model.storeAsURL(uno.systemPathToFileUrl(url),pd)
823
 
                        except IOException:
824
 
                                self.model.storeAsURL(uno.systemPathToFileUrl(url),()) # if it fails, we use default format
825
 
 
826
 
        def activate(self):
827
 
                """Give focus to the current OOo document"""
828
 
                frame = self.desktop.getCurrentFrame().getContainerWindow()
829
 
                frame.setFocus()
830
 
 
831
 
        def notInBibIndex(self,cursor):
832
 
                "Return True if the range does not intercept with the Bibliographic index"
833
 
                if self.bib != None and cursor.Text == self.bib.Anchor.Text:                    # must be in the same Text to be compared
834
 
                        curs = cursor.Text.createTextCursorByRange(cursor)
835
 
                        curs.goLeft(1,True)
836
 
                        b=cursor.Text.compareRegionStarts(curs.Start,self.bib.Anchor.End) != 1  # cursor after Bibliography index
837
 
                        curs.collapseToEnd()
838
 
                        curs.goRight(1,False)
839
 
                        a=cursor.Text.compareRegionEnds(curs.End,self.bib.Anchor.Start) != -1   # cursor before Bibliography index
840
 
                        return (a or b)
841
 
                else:
842
 
                        return True                                                                                     # it is not in the same Text and cannot be compared
843
 
 
844
 
# the following code is a workaround to a python-uno bug that makes PropertyValue().Value=uno.Any('long',100) not possible.
845
 
# many thanks to Joerg Budischewski for this code.
846
 
# this is used to set "TabStopPosition" in the Bibliographic index
847
 
class MagicTransformer:
848
 
    def __init__( self , ctx ):
849
 
        self.inv = ctx.ServiceManager.createInstanceWithContext(
850
 
            "com.sun.star.script.Invocation", ctx )
851
 
        self.insp =  ctx.ServiceManager.createInstanceWithContext(
852
 
            "com.sun.star.beans.Introspection", ctx )
853
 
    def transform( self, struct , propName, value ):
854
 
        myinv = self.inv.createInstanceWithArguments( (struct,) )
855
 
        access = self.insp.inspect( myinv )
856
 
        method = access.getMethod( "setValue" , -1 )
857
 
        uno.invoke( method, "invoke", ( myinv, ( propName , value ) ))
858
 
        method = access.getMethod( "getMaterial" , -1 )
859
 
        ret,dummy = method.invoke(myinv,() )
860
 
        return ret
861