Commit | Line | Data |
---|---|---|
4d9c5a11 P |
1 | #! |
2 | # -*- coding: utf-8 -*- | |
3 | """ | |
4 | Macro pour faciliter l'intégration des données d'une feuille de calcul | |
5 | vers un wiki MoinMoin. | |
6 | ||
7 | Copyright : Agence universitaire de la Francophonie | |
8 | Licence : GNU General Public Licence, version 2 | |
9 | Auteur : Jean Christophe André | |
10 | Date de création : septembre 2009 | |
11 | """ | |
12 | import uno | |
13 | import unohelper | |
14 | from com.sun.star.task import XJobExecutor | |
15 | from com.sun.star.beans import PropertyValue | |
16 | from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA | |
17 | from com.sun.star.table.CellHoriJustify import STANDARD, LEFT, CENTER, RIGHT | |
fd5790fa P |
18 | from com.sun.star.table.CellVertJustify import STANDARD, TOP, CENTER as MIDDLE, BOTTOM |
19 | from com.sun.star.awt.FontWeight import DONTKNOW, NORMAL, BOLD | |
4d9c5a11 | 20 | |
7b4557ff P |
21 | _settings = { |
22 | 'MoinMoinOldStyle': True, | |
23 | 'MoinMoinVertOnMulti': True, | |
24 | } | |
fd5790fa P |
25 | |
26 | def getRangeSize(sheet, cursor): | |
27 | r = cursor.getRangeAddress() | |
28 | realRange = sheet.getCellRangeByPosition(r.StartColumn, r.StartRow, | |
29 | r.EndColumn, r.EndRow) | |
30 | return (realRange.Columns.Count, realRange.Rows.Count) | |
4d9c5a11 | 31 | |
fd5790fa P |
32 | def getCellRealPosition(cursor, column, row): |
33 | r = cursor.getRangeAddress() | |
34 | return (r.StartColumn + column, r.StartRow + row) | |
35 | ||
36 | def cell2moin(cell): | |
7b4557ff P |
37 | global _settings |
38 | cell_string = cell.getString() | |
39 | if not cell_string: return '' | |
40 | cell_string = cell_string.replace('\n','<<BR>>') | |
41 | if _settings['MoinMoinOldStyle']: | |
42 | if hasattr(cell, 'CharWeight') and cell.CharWeight == BOLD: | |
43 | cell_string = "'''%s'''" % cell_string | |
44 | return cell_string | |
fd5790fa P |
45 | |
46 | def calc2moin(ctx): | |
7b4557ff | 47 | global _settings |
fd5790fa | 48 | data = list() |
4d9c5a11 P |
49 | |
50 | # récupération du document en cours, vérification du type Spreadsheet | |
51 | smgr = ctx.ServiceManager | |
52 | desktop = smgr.createInstanceWithContext( | |
53 | "com.sun.star.frame.Desktop", ctx) | |
54 | curdoc = desktop.getCurrentComponent() | |
55 | if not curdoc.supportsService("com.sun.star.sheet.SpreadsheetDocument"): | |
c842a98f | 56 | raise RuntimeError(u"Ce n'est pas un document de type Spreadsheet (Calc).") |
4d9c5a11 P |
57 | controller = curdoc.getCurrentController() |
58 | sheet = controller.getActiveSheet() | |
7b4557ff | 59 | #open('/tmp/calc2moin.log','a').write('sheet=[%s]\n' % ', '.join(dir(sheet))) |
4d9c5a11 P |
60 | |
61 | # localisation de la la zone déjà utilisée | |
62 | cursor = sheet.createCursor() | |
63 | cursor.gotoEndOfUsedArea(False) | |
64 | cursor.gotoStartOfUsedArea(True) | |
fd5790fa | 65 | columns, rows = getRangeSize(sheet, cursor) |
4d9c5a11 | 66 | for row in range(rows): |
fd5790fa | 67 | row_data = list() |
7b4557ff | 68 | row_has_multiline_cell = False |
fd5790fa P |
69 | column = 0 |
70 | while column < columns: | |
4d9c5a11 P |
71 | cell = cursor.getCellByPosition(column, row) |
72 | cell_type = cell.getType() | |
73 | cell_string = cell.getString() | |
7b4557ff P |
74 | if not row_has_multiline_cell: |
75 | row_has_multiline_cell = '\n' in cell_string | |
fd5790fa P |
76 | # calcul de l'étendue de la cellule courante |
77 | if cell.getIsMerged(): | |
78 | c, r = getCellRealPosition(cursor, column, row) | |
79 | cellRange = sheet.getCellRangeByPosition(c, r, c, r) | |
80 | cursor2 = sheet.createCursorByRange(cellRange) | |
81 | cursor2.collapseToMergedArea() | |
82 | cell_colspan, cell_rowspan = getRangeSize(sheet, cursor2) | |
7b4557ff | 83 | #open('/tmp/calc2moin.log','a').write('Merged(%d,%d)=[%d,%d]\n' % (column,row,cell_colspan,cell_rowspan)) |
fd5790fa P |
84 | else: |
85 | cell_colspan, cell_rowspan = 1, 1 | |
86 | # traitement des attributs et styles de la cellule | |
87 | cell_attributes = list() | |
88 | cell_styles = list() | |
89 | if cell_string and hasattr(cell, 'HoriJustify'): | |
4d9c5a11 P |
90 | horiJustify = cell.getPropertyValue('HoriJustify') |
91 | if horiJustify == LEFT: | |
fd5790fa P |
92 | if cell_colspan > 1 or cell_rowspan > 1: |
93 | text_align = 'left' | |
94 | text_align_old = '(' | |
95 | else: | |
96 | text_align = '' # left par défaut si span == 1 | |
97 | text_align_old = '' | |
4d9c5a11 | 98 | elif horiJustify == CENTER: |
fd5790fa P |
99 | if cell_colspan == 1 and cell_rowspan == 1: |
100 | text_align = 'center' | |
101 | text_align_old = ':' | |
102 | else: | |
103 | text_align = '' # center par défaut si span > 1 | |
104 | text_align_old = '' | |
4d9c5a11 P |
105 | elif horiJustify == RIGHT: |
106 | text_align = 'right' | |
fd5790fa | 107 | text_align_old = ')' |
4d9c5a11 P |
108 | else: |
109 | if cell_type == TEXT: | |
7b4557ff P |
110 | if cell_colspan > 1 or cell_rowspan > 1: |
111 | text_align = 'left' | |
112 | text_align_old = '(' | |
113 | else: | |
114 | text_align = '' # left par défaut si span == 1 | |
115 | text_align_old = '' | |
4d9c5a11 P |
116 | elif cell_type != EMPTY: |
117 | text_align = 'right' | |
fd5790fa P |
118 | text_align_old = ')' |
119 | if text_align: | |
7b4557ff | 120 | if _settings['MoinMoinOldStyle']: |
fd5790fa P |
121 | cell_attributes.append(text_align_old) |
122 | else: | |
123 | cell_styles.append('text-align: ' + text_align) | |
7b4557ff P |
124 | if cell_string and hasattr(cell, 'VertJustify') and \ |
125 | (row_has_multiline_cell or not _settings['MoinMoinVertOnMulti']): | |
fd5790fa P |
126 | vertJustify = cell.getPropertyValue('VertJustify') |
127 | if vertJustify == 1: #TOP(1) | |
128 | vertical_align = 'top' | |
129 | vertical_align_old = '^' | |
130 | elif vertJustify == 2: #MIDDLE(2) | |
131 | vertical_align = '' # middle par défaut | |
132 | vertical_align_old = '' | |
133 | else: #STANDARD(0), BOTTOM(3) | |
134 | vertical_align = 'bottom' | |
135 | vertical_align_old = 'v' | |
136 | if vertical_align: | |
7b4557ff | 137 | if _settings['MoinMoinOldStyle']: |
fd5790fa P |
138 | cell_attributes.append(vertical_align_old) |
139 | else: | |
140 | cell_styles.append('vertical-align: ' + vertical_align) | |
141 | if cell_string and hasattr(cell, 'CharWeight'): | |
142 | charWeight = cell.getPropertyValue('CharWeight') | |
7b4557ff P |
143 | if charWeight == BOLD and not _settings['MoinMoinOldStyle']: |
144 | cell_styles.append('font-weight: bold') | |
fd5790fa P |
145 | if cell_rowspan > 1: |
146 | cell_attributes.append('|%d' % cell_rowspan) | |
147 | if cell_colspan > 1: | |
148 | cell_attributes.append('-%d' % cell_colspan) | |
149 | if hasattr(cell, 'CellBackColor'): | |
150 | color = cell.getPropertyValue('CellBackColor') | |
151 | if color >= 0: | |
7b4557ff | 152 | if _settings['MoinMoinOldStyle']: |
fd5790fa P |
153 | cell_attributes.append('#%06x' % color) |
154 | else: | |
155 | cell_styles.append('background: #%06x' % color) | |
156 | if hasattr(cell, 'CharColor'): | |
157 | color = cell.getPropertyValue('CharColor') | |
158 | if color >= 0: | |
159 | cell_styles.append('color: #%06x' % color) | |
160 | # compilation des styles de la cellule | |
4d9c5a11 | 161 | if cell_styles: |
fd5790fa P |
162 | cell_attributes.insert(0, 'style="%s;"' % '; '.join(cell_styles)) |
163 | # ajout de la définition de la cellule à la ligne courante | |
164 | cell_data = list() | |
165 | if cell_attributes: | |
166 | cell_data.append('<' + ''.join(cell_attributes) + '>') | |
4d9c5a11 | 167 | if cell_string: |
fd5790fa | 168 | cell_data.append(cell2moin(cell)) |
4d9c5a11 P |
169 | else: |
170 | cell_data.append(' ') | |
171 | row_data.append(''.join(cell_data)) | |
fd5790fa | 172 | column += cell_colspan |
4d9c5a11 P |
173 | # display row's code |
174 | data.append('||' + '||'.join(row_data) + '||') | |
175 | ||
176 | # | |
177 | # création d'un document Writer pour écrire le code MoinMoin | |
178 | # | |
179 | # ouverture d'un document Writer caché | |
180 | hidden = PropertyValue() | |
181 | hidden.Name = "Hidden" | |
182 | hidden.Value = True | |
183 | doc = desktop.loadComponentFromURL( | |
184 | "private:factory/swriter", "_blank", 0, (hidden, ) ) | |
185 | text = doc.Text | |
186 | textcursor = text.createTextCursor() | |
187 | text.insertString(textcursor, '\n'.join(data) + '\n', 0) | |
188 | # on copie ça dans le presse papier | |
189 | dispatcher = smgr.createInstanceWithContext( | |
190 | "com.sun.star.frame.DispatchHelper", ctx) | |
191 | frame = doc.getCurrentController().getFrame() | |
192 | dispatcher.executeDispatch(frame, ".uno:SelectAll", "", 0, ()) | |
193 | dispatcher.executeDispatch(frame, ".uno:Copy", "", 0, ()) | |
194 | doc.close(True) | |
195 | ||
196 | ############################################################################## | |
197 | ||
198 | def copier(event=False): | |
199 | u"""Copier une feuille de calcul vers un wiki MoinMoin.""" | |
200 | ctx = uno.getComponentContext() | |
201 | calc2moin(ctx) | |
202 | return None | |
203 | ||
fd5790fa P |
204 | # lists the scripts, that shall be visible inside OOo. Can be omited, if |
205 | # all functions shall be visible, however here getNewString shall be surpressed | |
4d9c5a11 P |
206 | g_exportedScripts = (copier, ) |
207 | ||
208 | ############################################################################## | |
209 | ||
210 | class CopierJob(unohelper.Base, XJobExecutor): | |
211 | def __init__(self, context): | |
212 | self._context = context | |
7b4557ff P |
213 | self._readConfig() |
214 | ||
215 | def _readConfig(self): | |
216 | cfgprov = self._context.ServiceManager.createInstanceWithContext( | |
217 | "com.sun.star.configuration.ConfigurationProvider", self._context) | |
218 | node = PropertyValue() | |
219 | node.Name = "nodepath" | |
220 | node.Value = "/org.auf.openoffice.macros/General" | |
221 | ConfigReader = cfgprov.createInstanceWithArguments( | |
222 | "com.sun.star.configuration.ConfigurationAccess", (node,)) | |
223 | cfgnames = ("MoinMoinOldStyle", "MoinMoinVertOnMulti", ) | |
224 | cfgvalues = ConfigReader.getPropertyValues(cfgnames) | |
225 | if not cfgvalues: | |
226 | raise RuntimeError("Unable to read the configuration.") | |
227 | global _settings | |
228 | _settings = dict(zip(cfgnames, cfgvalues)) | |
4d9c5a11 P |
229 | |
230 | def trigger(self, args): | |
231 | calc2moin(self._context) | |
232 | ||
233 | g_ImplementationHelper = unohelper.ImplementationHelper() | |
234 | g_ImplementationHelper.addImplementation( \ | |
235 | CopierJob, "org.auf.openoffice.calc2moin.Copier", \ | |
236 | ("com.sun.star.task.Job",),) |