1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 A simple API to cite references in OpenOffice.org
24
25 Based on code from Bibus <http://bibus-biblio.sourceforge.net/>.
26 """
27
28 import uno
29 from gettext import gettext as _
30
31 from Pyblio.Cite.WP import CommunicationError, OperationError
32 from Pyblio.Store import Key
33
34 DIRECT_VALUE = uno.getConstantByName("com.sun.star.beans.PropertyState.DIRECT_VALUE")
35 PARAGRAPH_BREAK = uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK")
36
37 PropertyValue = uno.getClass("com.sun.star.beans.PropertyValue")
38 NoSuchElementException = uno.getClass("com.sun.star.container.NoSuchElementException")
39 NoConnectException = uno.getClass("com.sun.star.connection.NoConnectException")
40
41 ITALIC = (uno.getConstantByName("com.sun.star.awt.FontSlant.ITALIC"),
42 uno.getConstantByName("com.sun.star.awt.FontSlant.NONE"))
43
44 OO_BIBLIOGRAPHIC_FIELDS = {}
45 for f in ('Custom1', 'Custom2', 'Identifier'):
46 OO_BIBLIOGRAPHIC_FIELDS[f] = \
47 uno.getConstantByName("com.sun.star.text.BibliographyDataField." + f.upper())
48
49 from Pyblio.Format.OpenOffice import Generator, ITALIC
50
51 import re
52
53 _x_pyblio_re = re.compile(r'X-PYBLIO<(\d+)>')
54 _x_pyblio_extra_re = re.compile(r'X-PYBLIO-EXTRA:(.*)')
55
57 MASTER = 'com.sun.star.text.FieldMaster.Bibliography'
58
59 FRAME = u'Bibliography (Pybliographer)'
60
61 - def __init__(self, connection=('pipe', 'OOo_pipe')):
62 self.remote = connection
63 self.smgr = None
64 return
65
67 return self.smgr is not None
68
70 self.smgr = None
71 self.desktop = None
72 self.model = None
73 self.controller = None
74 self.cursor = None
75 self.text = None
76 self.tfm = None
77 self.frame = None
78
80 if self.is_connected():
81 return
82
83 localContext = uno.getComponentContext()
84 resolver = localContext.ServiceManager.createInstanceWithContext(
85 "com.sun.star.bridge.UnoUrlResolver", localContext )
86
87 if self.remote[0] == 'pipe':
88 cnx_parameter = 'pipe,name=%s' % self.remote[1]
89 elif self.remote[0] == 'socket':
90 cnx_parameter = 'socket,host=%s,port=%d' % self.remote[1:]
91 else:
92 cnx_parameter = ''
93 try:
94 ctx = resolver.resolve("uno:%s;urp;StarOffice.ComponentContext" % (
95 cnx_parameter))
96 except NoConnectException, msg:
97 raise CommunicationError(_("Unable to contact OpenOffice.org: %s" % msg))
98
99 self.smgr = ctx.ServiceManager
100 self.desktop = self.smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx)
101
102 self.model = self.desktop.getCurrentComponent()
103 if not (self.model and self.model.getImplementationName() == 'SwXTextDocument'):
104 raise OperationError(_("You are not in a text document"))
105
106 self.controller = self.model.getCurrentController()
107 self.cursor = self.controller.getViewCursor()
108 self.text = self.model.Text
109
110 try:
111 self.tfm = self.model.getTextFieldMasters().getByName(self.MASTER)
112 except NoSuchElementException:
113 self.tfm = self.model.createInstance(self.MASTER)
114
115
116 try:
117 self.frame = self.model.getTextSections().getByName(self.FRAME)
118 except NoSuchElementException:
119 self.frame = None
120 return
121
122 - def cite(self, keys, db):
123 """ Insert a list of references in the document, at the
124 cursor location. Each reference is a tuple
125 (visible_key, internal_id, extra_data)
126 """
127 for ref, key, extra in keys:
128 oref = self._makeRef(ref, key, extra)
129 c = self.cursor.Text.createTextCursorByRange(self.cursor)
130 c.Text.insertTextContent(c, oref, True)
131 self.cursor.setPropertyToDefault('CharStyleName')
132 return
133
135 """ Fetch all the references in the document, in order of appearance """
136
137 refs = list(self.tfm.getPropertyValue('DependentTextFields'))
138
139
140 def cmp(a, b):
141 return self.text.compareRegionStarts(b.Anchor.Start,
142 a.Anchor.Start)
143 refs.sort(cmp)
144 return [r for r in [self._parseRef(ref) for ref in refs] if r]
145
147
148
149
150
151 refs = list(self.tfm.getPropertyValue('DependentTextFields'))
152 for ref in refs:
153 fields = self._parseRef(ref)
154 if not fields:
155 continue
156 uid, old_name, extra = fields
157 if uid in keymap:
158 nref = self._makeRef(uid, keymap[uid], extra)
159 c = self.cursor.Text.createTextCursorByRange(ref.getAnchor())
160 c.Text.insertTextContent(c, nref, True)
161
162 return self.fetch()
163
165 if not self.frame:
166 self._createFrame()
167
168 f = self.frame
169 t = self.text
170 c = self.text.createTextCursorByRange(self.frame.Anchor.Start)
171
172 f.Anchor.setString('')
173 return Generator(t, c)
174
176 self.frame = self.model.createInstance("com.sun.star.text.TextSection")
177 self.frame.setName(self.FRAME)
178
179 self.text.insertString(self.cursor, '\x0a', False)
180 c = self.cursor.Text.createTextCursorByRange(self.cursor)
181 self.text.insertString(c, '\x0a', False)
182 c.goLeft(1, False)
183 self.text.insertTextContent(c, self.frame, False)
184
185 c = self.text.createTextCursorByRange(self.frame.Anchor.Start)
186 c.CharPosture = ITALIC[0]
187 self.text.insertString(c, _('Bibliography will appear here...'), False)
188 c.CharPosture = ITALIC[1]
189
190 return self.frame
191
192 - def _makeRef(self, ref, visible_key, extra):
193 """ Create a reference ready to be inserted in the document. """
194
195 if extra is not None:
196 extra = 'X-PYBLIO-EXTRA:%s' % extra
197
198 oref = self.model.createInstance("com.sun.star.text.TextField.Bibliography")
199 oref.Fields = (PropertyValue('Identifier', 0, visible_key, DIRECT_VALUE),
200 PropertyValue('Custom1', 0, 'X-PYBLIO<%s>' % ref, DIRECT_VALUE),
201 PropertyValue('Custom2', 0, extra, DIRECT_VALUE),)
202 return oref
203
220