--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<oor:node xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
+ <node oor:name="AddonUI">
+ <node oor:name="OfficeMenuBar">
+ <node oor:name="org.auf.openoffice.CODA" oor:op="replace">
+ <prop oor:name="Context" oor:type="xs:string">
+ <value>com.sun.star.sheet.SpreadsheetDocument</value>
+ </prop>
+ <prop oor:name="Title" oor:type="xs:string">
+ <value>CODA</value>
+ </prop>
+ <prop oor:name="ImageIdentifier" oor:type="xs:string">
+ <value>%origin%/images/coda-26x26.png</value>
+ </prop>
+ <node oor:name="Submenu">
+ <node oor:name="menu01" oor:op="replace">
+ <prop oor:name="Context" oor:type="xs:string">
+ <value>com.sun.star.sheet.SpreadsheetDocument</value>
+ </prop>
+ <prop oor:name="Title" oor:type="xs:string">
+ <value>Coller une interrogation des détails</value>
+ </prop>
+ <prop oor:name="URL" oor:type="xs:string">
+ <value>service:org.auf.openoffice.CODA.CollerDetails?execute</value>
+ </prop>
+ <prop oor:name="Target" oor:type="xs:string">
+ <value>_self</value>
+ </prop>
+ <prop oor:name="ImageIdentifier" oor:type="xs:string">
+ <value/>
+ </prop>
+ </node>
+ <node oor:name="menu02" oor:op="replace">
+ <prop oor:name="Context" oor:type="xs:string">
+ <value>com.sun.star.sheet.SpreadsheetDocument</value>
+ </prop>
+ <prop oor:name="Title" oor:type="xs:string">
+ <value>Coller une interrogation des cumuls</value>
+ </prop>
+ <prop oor:name="URL" oor:type="xs:string">
+ <value>service:org.auf.openoffice.CODA.CollerCumuls?execute</value>
+ </prop>
+ <prop oor:name="Target" oor:type="xs:string">
+ <value>_self</value>
+ </prop>
+ <prop oor:name="ImageIdentifier" oor:type="xs:string">
+ <value/>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+<!--
+ <node oor:name="Images">
+ <node oor:name="org.auf.openoffice.CODA.icone" oor:op="replace">
+ <prop oor:name="URL" oor:type="xs:string">
+ <value>macro:///AUF.CODA.CodaCopieDetails</value>
+ </prop>
+ <node oor:name="UserDefinedImages">
+ <prop oor:name="ImageBigURL">
+ <value>%origin%/AUF/CODA_26.bmp</value>
+ </prop>
+ <prop oor:name="ImageSmallURL">
+ <value>%origin%/AUF/CODA_16.bmp</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+-->
+ </node>
+</oor:node>
--- /dev/null
+#!
+# -*- coding: utf-8 -*-
+import re
+import uno
+import unohelper
+from com.sun.star.awt import WindowDescriptor
+from com.sun.star.awt.WindowClass import MODALTOP
+from com.sun.star.awt.VclWindowPeerAttribute import OK, DEF_OK
+from com.sun.star.uno import Exception as UnoException, RuntimeException
+from com.sun.star.connection import NoConnectException
+from com.sun.star.lang import Locale, IllegalArgumentException
+from com.sun.star.beans import PropertyValue
+#from com.sun.star.util.ParagraphProperties import CENTER
+from com.sun.star.util.NumberFormat import CURRENCY, DATE
+from com.sun.star.container import NoSuchElementException
+
+##############################################################################
+
+def clipboard_data(ctx, mimetype='text/plain;charset=utf-16'):
+ clipboard = ctx.ServiceManager.createInstanceWithContext(
+ "com.sun.star.datatransfer.clipboard.SystemClipboard", ctx)
+ contents = clipboard.getContents()
+ #print "Contents:\n%s\n%s\n%s" % ("-" * 78, "* " + "\n* ".join(dir(contents)), "=" * 78)
+ #flavors = contents.getTransferDataFlavors()
+ #print "Flavors:\n%s\n%s\n%s" % ("-" * 78, "* " + "\n* ".join([flavor.MimeType for flavor in flavors]), "=" * 78)
+ found_flavor = None
+ for flavor in contents.getTransferDataFlavors():
+ if flavor.MimeType == mimetype:
+ found_flavor = flavor
+ break
+ if not found_flavor:
+ raise RuntimeError, u"Erreur : type de données '%s' non disponible.\n" \
+ u"\nAvez-vous bien sélectionné puis copié les données dans CODA ?" \
+ % mimetype
+ data = contents.getTransferData(found_flavor)
+ #print "Data:\n", "-" * 78, "\n", data
+ return data
+
+##############################################################################
+
+def main(ctx, action):
+ data = clipboard_data(ctx)
+
+ numeric_pattern = re.compile('^[+-]?[0-9]+([\. ][0-9][0-9][0-9])*([\.,][0-9]+)?$')
+ date_pattern = re.compile('^([0-9]?[0-9])/([0-9]?[0-9])/([0-9]?[0-9]?[0-9]?[0-9])$')
+
+ if action == 'cumuls':
+ sheet_name = u'CODA-Cumuls'
+ # on découpe le texte reçu en lignes puis en colonnes
+ # on ne garde ici que les 10 premières colonnes
+ data = [row.split('\t')[:10] for row in data.splitlines()]
+ data[0][6] = '' # suppression de la 2nde colonne 'Engagement'
+ data[0][8] = '' # suppression de la colonne 'Colonne9'
+
+ elif action == 'details':
+ sheet_name = u'CODA-Détails'
+ # on découpe le texte reçu en lignes puis en colonnes
+ data = [row.split('\t') for row in data.splitlines()]
+
+ else:
+ raise RuntimeError, u"Action inconnue (erreur de programmation)."
+
+ # on efface la dernière ligne pleine de car. nuls, le cas échéant
+ last = data[len(data)-1]
+ if len(last) == 1 and last[0].strip('\x00') == '':
+ del data[len(data)-1]
+
+ # on détermine le type des données, par colonne
+ for column in range(len(data[0])):
+ if data[0][column] in ('Num doc','PCG'):
+ continue
+ flag_numeric = True
+ for row in range(1,len(data)):
+ value = data[row][column].strip().replace(u'\xa0','')
+ if value and value != '#DEV!' and not re.match(numeric_pattern, value):
+ flag_numeric = False
+ break
+ if flag_numeric:
+ for row in range(1,len(data)):
+ value = data[row][column].strip().replace(u'\xa0','')
+ if value and value != '#DEV!':
+ data[row][column] = float(value.replace('.','').replace(',','.'))
+
+ # on supprime les colonnes inutiles (en partant de la droite)
+ for column in range(len(data[0])-1,-1,-1):
+ diff = False
+ previous = data[1][column]
+ for row in range(2, len(data)):
+ if not diff and data[row][column] != previous:
+ diff = True
+ # s'il y a au moins 2 lignes et que les valeurs dans la colonne
+ # sont toutes identiques et qu'il n'y a pas d'intitulé sur la
+ # colonne alors on supprime toute la colonne
+ if len(data) > 2 and not diff and not data[0][column]:
+ for row in range(len(data)):
+ del data[row][column]
+
+ #print "Data:\n", "-" * 78, "\n", data
+
+ # récupération du document en cours, vérification du type Spreadsheet
+ desktop = ctx.ServiceManager.createInstanceWithContext(
+ "com.sun.star.frame.Desktop", ctx)
+ document = desktop.getCurrentComponent()
+ if not document.supportsService("com.sun.star.sheet.SpreadsheetDocument"):
+ raise RuntimeError, u"Ce n'est pas un document de type Spreadsheet (Calc)."
+
+ # basculement vers la feuille de calcul concernée, création au besoin
+ sheets = document.getSheets()
+ try:
+ sheet = sheets.getByName(sheet_name)
+ new_sheet = False
+ except NoSuchElementException, e:
+ sheets.insertNewByName(sheet_name, 0)
+ sheet = sheets.getByName(sheet_name)
+ new_sheet = True
+ controller = document.getCurrentController()
+ controller.setActiveSheet(sheet)
+
+ # récupération du format monétaire français
+ locale_fr_FR = Locale('fr', 'FR', '')
+ number_formats = document.getNumberFormats()
+ currency_format = number_formats.getStandardFormat(CURRENCY, locale_fr_FR)
+ date_format = number_formats.getStandardFormat(DATE, locale_fr_FR)
+
+ # définition de la zone de travail
+ cell_range = sheet.getCellRangeByPosition(1, 0, len(data[0]), len(data)-1)
+ cursor = sheet.createCursorByRange(cell_range)
+
+ # insertion des données
+ for row in range(1, len(data)):
+ for column in range(len(data[row])):
+ value = data[row][column]
+ cell = cursor.getCellByPosition(column, row)
+ if type(value) == float:
+ cell.Value = value
+ if new_sheet:
+ cell.NumberFormat = currency_format
+ else:
+ m = re.match(date_pattern, value)
+ if m:
+ (day, month, year) = [int(x) for x in m.groups()]
+ if year < 50:
+ year += 2000
+ elif year < 100:
+ year += 1900
+ value = '%02d/%02d/%04d' % (month, day, year)
+ if new_sheet:
+ cell.NumberFormat = date_format
+ cell.Formula = value
+ # insertion des en-têtes, après les données pour un autofit correct
+ for column in range(len(data[0])):
+ cell = cursor.getCellByPosition(column, 0)
+ cell.Formula = data[0][column]
+ if new_sheet:
+ cell.ParaAdjust = 3 # CENTER
+ sheet.Columns.getByIndex(1+column).OptimalWidth = True
+
+##############################################################################
+
+# Show a message box with the UNO based toolkit
+def messageBox(ctx, message):
+ document = XSCRIPTCONTEXT.getDocument()
+ window = document.CurrentController.Frame.ContainerWindow
+
+ aDescriptor = WindowDescriptor()
+ aDescriptor.Type = MODALTOP
+ aDescriptor.WindowServiceName = "infobox"
+ aDescriptor.ParentIndex = -1
+ aDescriptor.Parent = window
+ #aDescriptor.Bounds = Rectangle()
+ aDescriptor.WindowAttributes = OK
+
+ tk = window.getToolkit()
+ msgbox = tk.createWindow(aDescriptor)
+ msgbox.setCaptionText("Collage d'interrogation CODA")
+ msgbox.setMessageText(unicode(message))
+
+ return msgbox.execute()
+
+def coller_cumuls(event=False):
+ u"""Coller une interrogation des cumuls CODA."""
+ ctx = uno.getComponentContext()
+ try:
+ main(ctx, 'cumuls')
+ except Exception, e:
+ messageBox(ctx, e)
+ return None
+
+def coller_details(event=False):
+ u"""Coller une interrogation des détails CODA."""
+ ctx = uno.getComponentContext()
+ try:
+ main(ctx, 'details')
+ except Exception, e:
+ messageBox(ctx, e)
+ return None
+
+g_exportedScripts = (coller_cumuls, coller_details)
+
+##############################################################################
+
+from com.sun.star.task import XJobExecutor
+
+class CollerCumulsJob(unohelper.Base, XJobExecutor):
+ def __init__(self, context):
+ self._context = context
+
+ def trigger(self, args):
+ try:
+ main(self._context, 'cumuls')
+ except Exception, e:
+ messageBox(self._context, e)
+
+class CollerDetailsJob(unohelper.Base, XJobExecutor):
+ def __init__(self, context):
+ self._context = context
+
+ def trigger(self, args):
+ try:
+ main(self._context, 'details')
+ except Exception, e:
+ messageBox(self._context, e)
+
+g_ImplementationHelper = unohelper.ImplementationHelper()
+g_ImplementationHelper.addImplementation( \
+ CollerCumulsJob, "org.auf.openoffice.CODA.CollerCumuls", \
+ ("com.sun.star.task.Job",),)
+g_ImplementationHelper.addImplementation( \
+ CollerDetailsJob, "org.auf.openoffice.CODA.CollerDetails", \
+ ("com.sun.star.task.Job",),)