Index: compile_rules.py
==================================================================
--- compile_rules.py
+++ compile_rules.py
@@ -432,17 +432,23 @@
lLine = []
lRuleLine = []
lTest = []
lOpt = []
zBookmark = re.compile("^!!+")
+ zGraphLink = re.compile(r"^@@@@GRAPHLINK>(\w+)@@@@")
for i, sLine in enumerate(lRules, 1):
if sLine.startswith('#END'):
printBookmark(0, "BREAK BY #END", i)
break
elif sLine.startswith("#"):
pass
+ elif sLine.startswith("@@@@"):
+ m = re.match(r"^@@@@GRAPHLINK>(\w+)@@@@", sLine.strip())
+ if m:
+ #lRuleLine.append(["@GRAPHLINK", m.group(1)])
+ printBookmark(1, "@GRAPHLINK: " + m.group(1), i)
elif sLine.startswith("DEF:"):
m = re.match("DEF: +([a-zA-Z_][a-zA-Z_0-9]*) +(.+)$", sLine.strip())
if m:
dDEF["{"+m.group(1)+"}"] = m.group(2)
else:
Index: gc_core/py/__init__.py
==================================================================
--- gc_core/py/__init__.py
+++ gc_core/py/__init__.py
@@ -0,0 +1,2 @@
+
+from .grammar_checker import *
ADDED gc_core/py/grammar_checker.py
Index: gc_core/py/grammar_checker.py
==================================================================
--- /dev/null
+++ gc_core/py/grammar_checker.py
@@ -0,0 +1,73 @@
+# Grammalecte
+# Main class: wrapper
+
+import importlib
+import json
+
+from . import text
+
+
+class GrammarChecker:
+
+ def __init__ (self, sLangCode, sContext="Python"):
+ self.sLangCode = sLangCode
+ # Grammar checker engine
+ self.gce = importlib.import_module("."+sLangCode, "grammalecte")
+ self.gce.load(sContext)
+ # Spell checker
+ self.oSpellChecker = self.gce.getSpellChecker()
+ # Lexicographer
+ self.oLexicographer = None
+ # Text formatter
+ self.oTextFormatter = None
+
+ def getGCEngine (self):
+ return self.gce
+
+ def getSpellChecker (self):
+ return self.oSpellChecker
+
+ def getTextFormatter (self):
+ if self.oTextFormatter == None:
+ self.tf = importlib.import_module("."+self.sLangCode+".textformatter", "grammalecte")
+ self.oTextFormatter = self.tf.TextFormatter()
+ return self.oTextFormatter
+
+ def getLexicographer (self):
+ if self.oLexicographer == None:
+ self.lxg = importlib.import_module("."+self.sLangCode+".lexicographe", "grammalecte")
+ self.oLexicographer = self.lxg.Lexicographe(self.oSpellChecker)
+ return self.oLexicographer
+
+ def displayGCOptions (self):
+ self.gce.displayOptions()
+
+ def getParagraphErrors (self, sText, dOptions=None, bContext=False, bSpellSugg=False, bDebug=False):
+ "returns a tuple: (grammar errors, spelling errors)"
+ aGrammErrs = self.gce.parse(sText, "FR", bDebug=bDebug, dOptions=dOptions, bContext=bContext)
+ aSpellErrs = self.oSpellChecker.parseParagraph(sText, bSpellSugg)
+ return aGrammErrs, aSpellErrs
+
+ def generateText (self, sText, bEmptyIfNoErrors=False, bSpellSugg=False, nWidth=100, bDebug=False):
+ pass
+
+ def generateTextAsJSON (self, sText, bContext=False, bEmptyIfNoErrors=False, bSpellSugg=False, bReturnText=False, bDebug=False):
+ pass
+
+ def generateParagraph (self, sText, dOptions=None, bEmptyIfNoErrors=False, bSpellSugg=False, nWidth=100, bDebug=False):
+ aGrammErrs, aSpellErrs = self.getParagraphErrors(sText, dOptions, False, bSpellSugg, bDebug)
+ if bEmptyIfNoErrors and not aGrammErrs and not aSpellErrs:
+ return ""
+ return text.generateParagraph(sText, aGrammErrs, aSpellErrs, nWidth)
+
+ def generateParagraphAsJSON (self, iIndex, sText, dOptions=None, bContext=False, bEmptyIfNoErrors=False, bSpellSugg=False, bReturnText=False, lLineSet=None, bDebug=False):
+ aGrammErrs, aSpellErrs = self.getParagraphErrors(sText, dOptions, bContext, bSpellSugg, bDebug)
+ aGrammErrs = list(aGrammErrs)
+ if bEmptyIfNoErrors and not aGrammErrs and not aSpellErrs:
+ return ""
+ if lLineSet:
+ aGrammErrs, aSpellErrs = text.convertToXY(aGrammErrs, aSpellErrs, lLineSet)
+ return json.dumps({ "lGrammarErrors": aGrammErrs, "lSpellingErrors": aSpellErrs }, ensure_ascii=False)
+ if bReturnText:
+ return json.dumps({ "iParagraph": iIndex, "sText": sText, "lGrammarErrors": aGrammErrs, "lSpellingErrors": aSpellErrs }, ensure_ascii=False)
+ return json.dumps({ "iParagraph": iIndex, "lGrammarErrors": aGrammErrs, "lSpellingErrors": aSpellErrs }, ensure_ascii=False)
Index: gc_lang/fr/config.ini
==================================================================
--- gc_lang/fr/config.ini
+++ gc_lang/fr/config.ini
@@ -92,10 +92,13 @@
# TextFormatter
oxt/TextFormatter/TextFormatter.py = pythonpath/TextFormatter.py
oxt/TextFormatter/tf_strings.py = pythonpath/tf_strings.py
oxt/TextFormatter/tf_options.py = pythonpath/tf_options.py
oxt/TextFormatter/tf_tabrep.py = pythonpath/tf_tabrep.py
+# Lexicographer
+oxt/Lexicographer/Enumerator.py = pythonpath/Enumerator.py
+oxt/Lexicographer/enum_strings.py = pythonpath/enum_strings.py
# Conjugueur
oxt/Conjugueur/Conjugueur.py = pythonpath/Conjugueur.py
# Modify author
oxt/ChangeAuthor/Author.py = pythonpath/Author.py
oxt/ChangeAuthor/ca_strings.py = pythonpath/ca_strings.py
Index: gc_lang/fr/oxt/AppLauncher.py
==================================================================
--- gc_lang/fr/oxt/AppLauncher.py
+++ gc_lang/fr/oxt/AppLauncher.py
@@ -56,10 +56,14 @@
xDialog.run(self.sLang)
elif sCmd == "OP":
import Options
xDialog = Options.GC_Options(self.ctx)
xDialog.run(self.sLang)
+ elif sCmd == "EN":
+ import Enumerator
+ xDialog = Enumerator.Enumerator(self.ctx)
+ xDialog.run(self.sLang)
elif sCmd.startswith("FA/"):
findAll(sCmd[6:], (sCmd[3:4] == "y"), (sCmd[4:5] == "y"))
# elif sCmd.startswith("URL/"):
# # Call from context menu to launch URL?
# # http://opengrok.libreoffice.org/xref/core/sw/source/ui/lingu/olmenu.cxx#785
ADDED gc_lang/fr/oxt/Lexicographer/Enumerator.py
Index: gc_lang/fr/oxt/Lexicographer/Enumerator.py
==================================================================
--- /dev/null
+++ gc_lang/fr/oxt/Lexicographer/Enumerator.py
@@ -0,0 +1,304 @@
+# Dictionary Options
+# by Olivier R.
+# License: MPL 2
+
+import unohelper
+import uno
+import traceback
+
+import helpers
+import enum_strings
+import grammalecte.graphspell as sc
+
+from com.sun.star.task import XJobExecutor
+from com.sun.star.awt import XActionListener
+from com.sun.star.beans import PropertyValue
+
+
+def hexToRBG (sHexa):
+ r = int(sHexa[:2], 16)
+ g = int(sHexa[2:4], 16)
+ b = int(sHexa[4:], 16)
+ return (r & 255) << 16 | (g & 255) << 8 | (b & 255)
+
+
+def _waitPointer (funcDecorated):
+ def wrapper (*args, **kwargs):
+ # self is the first parameter if the decorator is applied on a object
+ self = args[0]
+ # before
+ xPointer = self.xSvMgr.createInstanceWithContext("com.sun.star.awt.Pointer", self.ctx)
+ xPointer.setType(uno.getConstantByName("com.sun.star.awt.SystemPointer.WAIT"))
+ xWindowPeer = self.xContainer.getPeer()
+ xWindowPeer.setPointer(xPointer)
+ for x in xWindowPeer.Windows:
+ x.setPointer(xPointer)
+ # processing
+ result = funcDecorated(*args, **kwargs)
+ # after
+ xPointer.setType(uno.getConstantByName("com.sun.star.awt.SystemPointer.ARROW"))
+ xWindowPeer.setPointer(xPointer)
+ for x in xWindowPeer.Windows:
+ x.setPointer(xPointer)
+ self.xContainer.setVisible(True) # seems necessary to refresh the dialog box and text widgets (why?)
+ # return
+ return result
+ return wrapper
+
+
+class Enumerator (unohelper.Base, XActionListener, XJobExecutor):
+
+ def __init__ (self, ctx):
+ self.ctx = ctx
+ self.xSvMgr = self.ctx.ServiceManager
+ self.xDesktop = self.xSvMgr.createInstanceWithContext("com.sun.star.frame.Desktop", self.ctx)
+ self.xDocument = self.xDesktop.getCurrentComponent()
+ self.xContainer = None
+ self.xDialog = None
+ self.oSpellChecker = None
+
+ def _addWidget (self, name, wtype, x, y, w, h, **kwargs):
+ xWidget = self.xDialog.createInstance('com.sun.star.awt.UnoControl%sModel' % wtype)
+ xWidget.Name = name
+ xWidget.PositionX = x
+ xWidget.PositionY = y
+ xWidget.Width = w
+ xWidget.Height = h
+ for k, w in kwargs.items():
+ setattr(xWidget, k, w)
+ self.xDialog.insertByName(name, xWidget)
+ return xWidget
+
+ def _addGrid (self, name, x, y, w, h, columns, **kwargs):
+ xGridModel = self.xDialog.createInstance('com.sun.star.awt.grid.UnoControlGridModel')
+ xGridModel.Name = name
+ xGridModel.PositionX = x
+ xGridModel.PositionY = y
+ xGridModel.Width = w
+ xGridModel.Height = h
+ xColumnModel = xGridModel.ColumnModel
+ for e in columns:
+ xCol = xColumnModel.createColumn()
+ for k, w in e.items():
+ setattr(xCol, k, w)
+ xColumnModel.addColumn(xCol)
+ for k, w in kwargs.items():
+ setattr(xGridModel, k, w)
+ self.xDialog.insertByName(name, xGridModel)
+ return xGridModel
+
+ def run (self, sLang):
+ self.dUI = enum_strings.getUI(sLang)
+
+ # dialog
+ self.xDialog = self.xSvMgr.createInstanceWithContext('com.sun.star.awt.UnoControlDialogModel', self.ctx)
+ self.xDialog.Width = 240
+ self.xDialog.Height = 280
+ self.xDialog.Title = self.dUI.get('title', "#title#")
+ xWindowSize = helpers.getWindowSize()
+ self.xDialog.PositionX = int((xWindowSize.Width / 2) - (self.xDialog.Width / 2))
+ self.xDialog.PositionY = int((xWindowSize.Height / 2) - (self.xDialog.Height / 2))
+
+ # fonts
+ xFDTitle = uno.createUnoStruct("com.sun.star.awt.FontDescriptor")
+ xFDTitle.Height = 9
+ xFDTitle.Weight = uno.getConstantByName("com.sun.star.awt.FontWeight.BOLD")
+ xFDTitle.Name = "Verdana"
+
+ xFDSubTitle = uno.createUnoStruct("com.sun.star.awt.FontDescriptor")
+ xFDSubTitle.Height = 8
+ xFDSubTitle.Weight = uno.getConstantByName("com.sun.star.awt.FontWeight.BOLD")
+ xFDSubTitle.Name = "Verdana"
+
+ # widget
+ nX = 10
+ nY1 = 5
+ nY2 = nY1 + 225
+
+ nWidth = self.xDialog.Width - 20
+ nHeight = 10
+
+ # List
+ self._addWidget("list_section", 'FixedLine', nX, nY1, nWidth, nHeight, Label = self.dUI.get("list_section", "#err"), FontDescriptor = xFDTitle)
+ self._addWidget('count_button', 'Button', nX, nY1+12, 70, 10, Label = self.dUI.get('count_button', "#err"))
+ self._addWidget('count2_button', 'Button', nX+75, nY1+12, 70, 10, Label = self.dUI.get('count2_button', "#err"))
+ self._addWidget('unknown_button', 'Button', nX+150, nY1+12, 70, 10, Label = self.dUI.get('unknown_button', "#err"))
+ self.xGridModel = self._addGrid("list_grid", nX, nY1+25, nWidth, 180, [
+ {"Title": self.dUI.get("words", "#err"), "ColumnWidth": 175},
+ {"Title": "Occurrences", "ColumnWidth": 45}
+ ])
+ self._addWidget('num_of_entries', 'FixedText', nX, nY1+210, 60, nHeight, Label = self.dUI.get('num_of_entries', "#err"), Align = 2)
+ self.xNumWord = self._addWidget('num_of_entries_res', 'FixedText', nX+65, nY1+210, 30, nHeight, Label = "—")
+ self._addWidget('tot_of_entries', 'FixedText', nX+100, nY1+210, 60, nHeight, Label = self.dUI.get('tot_of_entries', "#err"), Align = 2)
+ self.xTotWord = self._addWidget('tot_of_entries_res', 'FixedText', nX+165, nY1+210, 30, nHeight, Label = "—")
+
+ # Tag
+ # Note: the only way to group RadioButtons is to create them successively
+ self._addWidget("dformat_section", 'FixedLine', nX, nY2, 90, nHeight, Label = self.dUI.get("dformat_section", "#err"), FontDescriptor = xFDTitle)
+ self._addWidget("charstyle_section", 'FixedLine', nX+100, nY2, 90, nHeight, Label = self.dUI.get("charstyle_section", "#err"), FontDescriptor = xFDTitle)
+ self.xUnderline = self._addWidget('underline', 'RadioButton', nX, nY2+12, 40, nHeight, Label = self.dUI.get('underline', "#err"))
+ self.xNoUnderline = self._addWidget('nounderline', 'RadioButton', nX+50, nY2+12, 40, nHeight, Label = self.dUI.get('nounderline', "#err"))
+ self.xAccent = self._addWidget('accentuation', 'RadioButton', nX+100, nY2+12, 50, nHeight, Label = self.dUI.get('accentuation', "#err"))
+ self.xNoAccent = self._addWidget('noaccentuation', 'RadioButton', nX+155, nY2+12, 40, nHeight, Label = self.dUI.get('noaccentuation', "#err"))
+
+ self.xTag = self._addWidget('tag_button', 'Button', self.xDialog.Width-40, nY2+10, 30, 11, Label = self.dUI.get('tag_button', "#err"), FontDescriptor = xFDTitle, TextColor = 0x005500)
+
+ # Progress bar
+ self.xProgressBar = self._addWidget('progress_bar', 'ProgressBar', nX, self.xDialog.Height-25, 160, 14)
+ self.xProgressBar.ProgressValueMin = 0
+ self.xProgressBar.ProgressValueMax = 1 # to calculate
+
+ # Close
+ self._addWidget('close_button', 'Button', self.xDialog.Width-60, self.xDialog.Height-25, 50, 14, Label = self.dUI.get('close_button', "#err"), FontDescriptor = xFDTitle, TextColor = 0x550000)
+
+ # container
+ self.xContainer = self.xSvMgr.createInstanceWithContext('com.sun.star.awt.UnoControlDialog', self.ctx)
+ self.xContainer.setModel(self.xDialog)
+ self.xGridControl = self.xContainer.getControl('list_grid')
+ self.xContainer.getControl('count_button').addActionListener(self)
+ self.xContainer.getControl('count_button').setActionCommand('Count')
+ self.xContainer.getControl('count2_button').addActionListener(self)
+ self.xContainer.getControl('count2_button').setActionCommand('CountByLemma')
+ self.xContainer.getControl('unknown_button').addActionListener(self)
+ self.xContainer.getControl('unknown_button').setActionCommand('UnknownWords')
+ self.xContainer.getControl('tag_button').addActionListener(self)
+ self.xContainer.getControl('tag_button').setActionCommand('Tag')
+ self.xContainer.getControl('close_button').addActionListener(self)
+ self.xContainer.getControl('close_button').setActionCommand('Close')
+ self.xContainer.setVisible(False)
+ xToolkit = self.xSvMgr.createInstanceWithContext('com.sun.star.awt.ExtToolkit', self.ctx)
+ self.xContainer.createPeer(xToolkit, None)
+ self.xContainer.execute()
+
+ # XActionListener
+ def actionPerformed (self, xActionEvent):
+ try:
+ if xActionEvent.ActionCommand == "Count":
+ self.count(self.dUI.get("words", "#err"))
+ self.xTag.Enabled = True
+ elif xActionEvent.ActionCommand == "CountByLemma":
+ self.count(self.dUI.get("lemmas", "#err"), bByLemma=True)
+ self.xTag.Enabled = False
+ elif xActionEvent.ActionCommand == "UnknownWords":
+ self.count(self.dUI.get("unknown_words", "#err"), bOnlyUnknownWords=True)
+ self.xTag.Enabled = True
+ elif xActionEvent.ActionCommand == "Tag":
+ nRow = self.xGridControl.getCurrentRow()
+ if nRow == -1:
+ return
+ sWord = self.xGridModel.GridDataModel.getCellData(0, nRow)
+ if not sWord:
+ return
+ sAction = ""
+ if self.xUnderline.State:
+ sAction = "underline"
+ elif self.xNoUnderline.State:
+ sAction = "nounderline"
+ elif self.xAccent.State:
+ sAction = "accentuation"
+ elif self.xNoAccent.State:
+ sAction = "noaccentuation"
+ self.tagText(sWord, sAction)
+ elif xActionEvent.ActionCommand == "Close":
+ self.xContainer.endExecute()
+ except:
+ traceback.print_exc()
+
+ # XJobExecutor
+ def trigger (self, args):
+ try:
+ xDialog = Enumerator(self.ctx)
+ xDialog.run()
+ except:
+ traceback.print_exc()
+
+ # Code
+ def _setTitleOfFirstColumn (self, sTitle):
+ xColumnModel = self.xGridModel.ColumnModel
+ xColumn = xColumnModel.getColumn(0)
+ xColumn.Title = sTitle
+
+ def _getParagraphsFromText (self):
+ "generator: returns full document text paragraph by paragraph"
+ xCursor = self.xDocument.Text.createTextCursor()
+ xCursor.gotoStart(False)
+ xCursor.gotoEndOfParagraph(True)
+ yield xCursor.getString()
+ while xCursor.gotoNextParagraph(False):
+ xCursor.gotoEndOfParagraph(True)
+ yield xCursor.getString()
+
+ def _countParagraph (self):
+ i = 1
+ xCursor = self.xDocument.Text.createTextCursor()
+ xCursor.gotoStart(False)
+ while xCursor.gotoNextParagraph(False):
+ i += 1
+ return i
+
+ @_waitPointer
+ def count (self, sTitle, bByLemma=False, bOnlyUnknownWords=False):
+ if not self.oSpellChecker:
+ self.oSpellChecker = sc.SpellChecker("fr")
+ self._setTitleOfFirstColumn(sTitle)
+ self.xProgressBar.ProgressValueMax = self._countParagraph() * 2
+ self.xProgressBar.ProgressValue = 0
+ xGridDataModel = self.xGridModel.GridDataModel
+ xGridDataModel.removeAllRows()
+ dWord = {}
+ for sParagraph in self._getParagraphsFromText():
+ dWord = self.oSpellChecker.countWordsOccurrences(sParagraph, bByLemma, bOnlyUnknownWords, dWord)
+ self.xProgressBar.ProgressValue += 1
+ self.xProgressBar.ProgressValueMax += len(dWord)
+ i = 0
+ nTotOccur = 0
+ for k, w in sorted(dWord.items(), key=lambda t: t[1], reverse=True):
+ xGridDataModel.addRow(i, (k, w))
+ self.xProgressBar.ProgressValue += 1
+ i += 1
+ nTotOccur += w
+ self.xProgressBar.ProgressValue = self.xProgressBar.ProgressValueMax
+ self.xNumWord.Label = str(i)
+ self.xTotWord.Label = nTotOccur
+
+ @_waitPointer
+ def tagText (self, sWord, sAction=""):
+ if not sAction:
+ return
+ self.xProgressBar.ProgressValueMax = self._countParagraph()
+ self.xProgressBar.ProgressValue = 0
+ xCursor = self.xDocument.Text.createTextCursor()
+ #helpers.xray(xCursor)
+ xCursor.gotoStart(False)
+ xCursor.gotoEndOfParagraph(True)
+ sParagraph = xCursor.getString()
+ if sWord in sParagraph:
+ self._tagParagraph(sWord, xCursor, sAction)
+ self.xProgressBar.ProgressValue += 1
+ while xCursor.gotoNextParagraph(False):
+ xCursor.gotoEndOfParagraph(True)
+ sParagraph = xCursor.getString()
+ if sWord in sParagraph:
+ self._tagParagraph(sWord, xCursor, sAction)
+ self.xProgressBar.ProgressValue += 1
+ self.xProgressBar.ProgressValue = self.xProgressBar.ProgressValueMax
+
+ def _tagParagraph (self, sWord, xCursor, sAction):
+ xCursor.gotoStartOfParagraph(False)
+ while xCursor.gotoNextWord(False):
+ if xCursor.isStartOfWord():
+ xCursor.gotoEndOfWord(True)
+ if sWord == xCursor.getString():
+ if sAction == "underline":
+ xCursor.CharBackColor = hexToRBG("AA0000")
+ elif sAction == "nounderline":
+ xCursor.CharBackColor = hexToRBG("FFFFFF")
+ elif sAction == "accentuation":
+ xCursor.CharStyleName = "Emphasis"
+ elif sAction == "noaccentuation":
+ #xCursor.CharStyleName = "Default Style" # doesn’t work
+ xCursor.setPropertyToDefault("CharStyleName")
+
+
+#g_ImplementationHelper = unohelper.ImplementationHelper()
+#g_ImplementationHelper.addImplementation(Enumerator, 'net.grammalecte.enumerator', ('com.sun.star.task.Job',))
ADDED gc_lang/fr/oxt/Lexicographer/enum_strings.py
Index: gc_lang/fr/oxt/Lexicographer/enum_strings.py
==================================================================
--- /dev/null
+++ gc_lang/fr/oxt/Lexicographer/enum_strings.py
@@ -0,0 +1,55 @@
+def getUI (sLang):
+ if sLang in dStrings:
+ return dStrings[sLang]
+ return dStrings["fr"]
+
+dStrings = {
+ "fr": {
+ "title": "Grammalecte · Recenseur de mots",
+
+ "list_section": "Calcul des occurrences des mots",
+ "count_button": "Compter tout",
+ "count2_button": "Compter par lemme",
+ "unknown_button": "Mots inconnus",
+ "num_of_entries": "Nombre d’entrées :",
+ "tot_of_entries": "Total des entrées :",
+
+ "words": "Mots",
+ "lemmas": "Lemmes",
+ "unknown_words": "Mots inconnus",
+
+ "dformat_section": "Formatage direct",
+ "charstyle_section": "Style de caractères",
+ "underline": "Surligner",
+ "nounderline": "Effacer",
+ "accentuation": "Accentuation",
+ "noaccentuation": "Aucun",
+ "tag_button": "Taguer",
+
+ "close_button": "Fermer",
+ },
+ "en": {
+ "title": "Grammalecte · Enumerator of Words",
+
+ "list_section": "Words",
+ "count_button": "Count all",
+ "count2_button": "Count by lemma",
+ "unknown_button": "Unknown words",
+ "num_of_entries": "Number of entries:",
+ "tot_of_entries": "Total of words:",
+
+ "words": "Words",
+ "lemmas": "Lemmas",
+ "unknown_words": "Unknown words",
+
+ "dformat_section": "Direct format",
+ "charstyle_section": "Character style",
+ "underline": "Underline",
+ "nounderline": "Erase",
+ "accentuation": "Accentuation",
+ "noaccentuation": "None",
+ "tag_button": "Tag",
+
+ "close_button": "Close",
+ },
+}
Index: gc_lang/fr/oxt/addons.xcu
==================================================================
--- gc_lang/fr/oxt/addons.xcu
+++ gc_lang/fr/oxt/addons.xcu
@@ -69,10 +69,26 @@
com.sun.star.text.TextDocument,com.sun.star.text.GlobalDocument,com.sun.star.text.WebDocument,com.sun.star.presentation.PresentationDocument
+
+ service:net.grammalecte.AppLauncher?EN
+
+
+
+ ~Recenseur de mots…
+ ~Enumerator of words…
+
+
+ _self
+
+
+ com.sun.star.text.TextDocument,com.sun.star.text.GlobalDocument,com.sun.star.text.WebDocument,com.sun.star.presentation.PresentationDocument
+
+
+
service:net.grammalecte.AppLauncher?MA
@@ -87,19 +103,19 @@
com.sun.star.text.TextDocument,com.sun.star.text.GlobalDocument,com.sun.star.text.WebDocument
-
+
private:separator
com.sun.star.text.TextDocument,com.sun.star.text.GlobalDocument,com.sun.star.text.WebDocument,com.sun.star.presentation.PresentationDocument
-
+
service:net.grammalecte.AppLauncher?OP