Makro für .uno:Command in Math-OLE object

Hallo zusammen,

wenn das Clipboard MathML enthält, dann soll dies in StarMath umgeformt und sofort als Math-OLE object in das Textdokument eingefügt werden. Das will ich zunächst als Makro probieren.

Meine bisherige Lösung ist am Ende der Mail. Das funktioniert im Prinzip. Aber es ist optisch nicht schön, dass zwischendurch die UI von StarMath erscheint. Gibt es eine Möglichkeit das Kommando .uno:InsertMathMLClipboard auch ohne die UI durchzuführen? Auf das Kommando kann ich leider nicht verzichten, weil dort die ganze Umformung drinsteckt.

Langfristig möchte ich das Ganze im Code haben. Wenn jemand dazu Tipps oder Hinweise hat, würde mich das auch freuen.

Mit freundlichem Gruß
Regina

Sub PasteSpecialMathML
dim bOK as boolean: bOK = FALSE
dim oDocument as variant: oDocument = ThisComponent
dim oCurrentController as variant: oCurrentController = oDocument.getCurrentController()
dim oXCOEO as variant
dim oMathOLE as variant
dim oMathFrame as variant
dim oDispatcher as variant
oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem Verify, that clipboard contains MathML
dim oService as variant
oService = createUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")
dim oContents as variant
oContents = oService.Contents
dim oVecTransferDataFlavors() as variant
oVecTransferDataFlavors = oContents.TransferDataFlavors
dim nIter as integer
dim nEnd as integer: nEnd = UBound(oVecTransferDataFlavors)
dim oCssDatatransferDataFlavor as variant
dim sMime as string
dim sHuman as string
dim nDataFlavorIndex as integer: nDataFlavorIndex = nEnd+1
For nIter=0 to nEnd
  oCssDatatransferDataFlavor = oVecTransferDataFlavors(nIter)
  sMime = oCssDatatransferDataFlavor.MimeType
  sHuman = oCssDatatransferDataFlavor.HumanPresentableName
  if sMime = "application/mathml-presentation+xml" or sMime = "application/mathml+xml" or _
    sHuman = "MathML" or sHuman = "MathML Presentation" then
    nDataFlavorIndex = nIter
    exit for
  end if
next nIter
if nDataFlavorIndex > nEnd then
  msgbox("No MathML in Clipboard")
else
     oMathOLE = oDocument.createInstance("com.sun.star.text.TextEmbeddedObject")
  oMathOLE.CLSID = "078B7ABA-54FC-457F-8551-6147e776a997"
  oMathOLE.AnchorType = com.sun.star.text.TextContentAnchorType.AS_CHARACTER
  rem Actually insert oMathOLE at cursor position in the document
  oMathOLE.attach(oCurrentController.Selection.getByIndex(0) )
  oMathOLE.LeftMargin = 0
  oMathOLE.RightMargin = 0
  oMathOLE.Model.BaseFontHeight = oMathOLE.Anchor.CharHeight
  rem Use the command ".uno:ImportMathMLClipboard" which does the convertion
  rem from MathML to StarMath
  oXCOEO = oMathOLE.ExtendedControlOverEmbeddedObject
  oXCOEO.doVerb(com.sun.star.embed.EmbedVerbs.MS_OLEVERB_OPEN)
  oMathFrame = oMathOLE.Model.CurrentController.Frame
  oDispatcher.executeDispatch(oMathFrame, ".uno:ImportMathMLClipboard", "", 0, Array())
  bOK = oMathOLE.Model.Formula<>""
  oDispatcher.executeDispatch(oMathFrame, ".uno:CloseDoc", "", 0, Array())
  if NOT bOK then
    msgbox("Convertion to StarMath is not possible.")
    oDispatcher.executeDispatch(oCurrentController.Frame, ".uno:SwBackspace", "", 0, Array())
  end if
end if
End Sub

Hallo Regina,

ich habe keinerlei Ahnung vom Coden, aber in anderem Zusammenhang
hatte ich mal gelesen, dass es eine Möglichkeit geben soll, die
Bildschirm-Aktualisierung vorübergehend auszuschalten, so dass er
sich nicht mehr weiter verändern kann und quasi eingefroren wird, um
sie nach der fraglichen Codestelle erst wieder einzuschalten, so
dass man dieses UI-Aufblitzen einfach nur nicht sehen kann.

Vielleicht wäre das ja auch hier eine Möglichkeit?

.... und tschüss

            Franklin

Hallo Franklin,

danke für die Anregung. Ich weiß allerdings nicht, wie ich das Fenster, das bei "Open" aufgeht, verstecken könnte. Die Standardaktion für Öffnen von Fenstern ist ja "Öffnen im Vordergrund" und was anderes macht im Normalfall auch keinen Sinn. Und wenn ich mit dem Fenster im Nachhinein etwas mache, ist es zu spät.

Franklin Schiftan schrieb:

Hallo Regina,

ich hatte Dein 'zwischendurch die UI von StarMath erscheint' so
verstanden, dass es einen bestimmten temporären Bereich gibt, wo
diese StarMath-UI aufgrund Deines Makro-Codes erscheint.

Es ist ja nicht notwendig, ein Öffnen-Fenster komplett zu
verstecken, wenn es grundsätzlich sinnvoll und notwendig ist und
hier auch nicht stört. Wenn es aber nur temporär erscheint,
eigentlich gar nicht gebraucht wird, aber dann auch wieder von
alleine verschwindet, dann würde man diesen Vorgang doch gar nicht
bemerken, wenn wie gesagt für diese Zeit die Aktualisierung / das
Neuzeichnen des Bildschirmes komplett ausgeschaltet und erst
hinterher wieder eingeschaltet würde.

Wie gesagt habe ich solch einen Workaround vor vielen, vielen Jahren
in einem anderen Zusammenhang mal miterlebt. Sorry, dass ich es
heute nicht mehr genauer benennen kann.

.... und tschüss

            Franklin

Hallo Franklin,

danke für die Anregung. Ich weiß allerdings nicht, wie ich das
Fenster, das bei "Open" aufgeht, verstecken könnte. Die
Standardaktion für Öffnen von Fenstern ist ja "Öffnen im
Vordergrund" und was anderes macht im Normalfall auch keinen
Sinn. Und wenn ich mit dem Fenster im Nachhinein etwas mache, ist
es zu spät.

Franklin Schiftan schrieb:

Hallo Regina,

ich habe keinerlei Ahnung vom Coden, aber in anderem
Zusammenhang hatte ich mal gelesen, dass es eine Möglichkeit
geben soll, die Bildschirm-Aktualisierung vorübergehend
auszuschalten, so dass er sich nicht mehr weiter verändern kann
und quasi eingefroren wird, um sie nach der fraglichen
Codestelle erst wieder einzuschalten, so dass man dieses
UI-Aufblitzen einfach nur nicht sehen kann.

Vielleicht wäre das ja auch hier eine Möglichkeit?

.... und tschüss

Franklin

Hallo zusammen,

wenn das Clipboard MathML enthält, dann soll dies in StarMath
umgeformt und sofort als Math-OLE object in das Textdokument
eingefügt werden. Das will ich zunächst als Makro probieren.

Meine bisherige Lösung ist am Ende der Mail. Das funktioniert
im Prinzip. Aber es ist optisch nicht schön, dass
zwischendurch die UI von StarMath erscheint. Gibt es eine
Möglichkeit das Kommando .uno:InsertMathMLClipboard auch ohne
die UI durchzuführen? Auf das Kommando kann ich leider nicht
verzichten, weil dort die ganze Umformung drinsteckt.

Langfristig möchte ich das Ganze im Code haben. Wenn jemand
dazu Tipps oder Hinweise hat, würde mich das auch freuen.

Mit freundlichem Gruß Regina

Sub PasteSpecialMathML dim bOK as boolean: bOK = FALSE dim
oDocument as variant: oDocument = ThisComponent dim
oCurrentController as variant: oCurrentController =
oDocument.getCurrentController() dim oXCOEO as variant dim
oMathOLE as variant dim oMathFrame as variant dim oDispatcher
as variant oDispatcher =
createUnoService("com.sun.star.frame.DispatchHelper")

rem Verify, that clipboard contains MathML dim oService as
variant oService =
createUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")

dim oContents as variant

oContents = oService.Contents dim oVecTransferDataFlavors()
as variant oVecTransferDataFlavors =
oContents.TransferDataFlavors dim nIter as integer dim nEnd
as integer: nEnd = UBound(oVecTransferDataFlavors) dim
oCssDatatransferDataFlavor as variant dim sMime as string dim
sHuman as string dim nDataFlavorIndex as integer:
nDataFlavorIndex = nEnd+1 For nIter=0 to nEnd
oCssDatatransferDataFlavor = oVecTransferDataFlavors(nIter)
sMime = oCssDatatransferDataFlavor.MimeType sHuman =
oCssDatatransferDataFlavor.HumanPresentableName if sMime =
"application/mathml-presentation+xml" or sMime =
"application/mathml+xml" or _ sHuman = "MathML" or sHuman =
"MathML Presentation" then nDataFlavorIndex = nIter exit for
end if next nIter if nDataFlavorIndex > nEnd then msgbox("No
MathML in Clipboard") else oMathOLE =
oDocument.createInstance("com.sun.star.text.TextEmbeddedObject")

oMathOLE.CLSID = "078B7ABA-54FC-457F-8551-6147e776a997"

Hey Franklin, Regina,

hmm, es gibt die Möglichkeit, den Controller des Dokumentes zu "blocken" ("lockControllers"), das verhindert das Neuzeichnen eines Dokumentes auf dem Bildschirm.

Ich denke, das meinst Du, Franklin.

Jedes Dokument hat einen "currentController" - den man sperren kann.

Aber: Wird ein neues Dokument erzeugt, hat das keinen Einfluss - das bekommt ja einen eigenen Controller verpasst.

Ich denke, hier ist das Problem der Uno-Befehl - der verweist ja auf ein internes Programm und das kannst Du nicht verändern.

Ich bin mir nicht sicher, ob es API Methoden gibt, die die Umwandlung des MathML Objektes in ein StarMath Objekt bewerkstelligen können - das wäre dann der vorzuziehende Weg. Denn das MathML Objekt kannst Du ja problemlos aus der Zwischenablage bekommen.

Aber für die Umwandlung habe ich keinen Einsteigspunkt. Sorry.

Viele Grüße

Thomas

Hallo Regina,

[...] wenn wie gesagt für diese Zeit die Aktualisierung / das
Neuzeichnen des Bildschirmes komplett ausgeschaltet und erst
hinterher wieder eingeschaltet würde.

[...entsorgt...]

Hallo Thomas,

Thomas Krumbein schrieb:

Hey Franklin, Regina,

hmm, es gibt die Möglichkeit, den Controller des Dokumentes zu "blocken"
("lockControllers"), das verhindert das Neuzeichnen eines Dokumentes auf
dem Bildschirm.

Ich denke, das meinst Du, Franklin.

Jedes Dokument hat einen "currentController" - den man sperren kann.

Aber: Wird ein neues Dokument erzeugt, hat das keinen Einfluss - das
bekommt ja einen eigenen Controller verpasst.

Ich habe auch ausprobiert das Math-Objekt nur einzufügen und nicht zu aktivieren. Aber dann habe ich kein Model und kein Frame und kann daher den Dispatcher nicht benutzen.

Ich denke, hier ist das Problem der Uno-Befehl - der verweist ja auf ein
internes Programm und das kannst Du nicht verändern.

Ich bin mir nicht sicher, ob es API Methoden gibt, die die Umwandlung
des MathML Objektes in ein StarMath Objekt bewerkstelligen können -

Bei dem Uno-Befehl wird zum Umwandeln ein Memorystream benutzt, der dann im Prinzip die gleichen Methoden benutzt wie sie auch beim Importieren einer Datei benutzt werden. Das schließt den XML-Parser ein und das Erzeugen des StarMath-Strings.

das

wäre dann der vorzuziehende Weg. Denn das MathML Objekt kannst Du ja
problemlos aus der Zwischenablage bekommen.

Das tatsächliche Lesen der Zwischenablage macht erst der Uno-Befehl.

Aber für die Umwandlung habe ich keinen Einsteigspunkt. Sorry.

Das Umwandeln funktioniert mit .uno:ImportMathMLClipboard.

Im Makro ist das Problem, dass ich den Dispatcher nur benutzen kann, wenn das Math-Objekt aktiviert ist. Deshalb meine Frage, ob es noch einen Trick gibt, ein .uno Kommando zu benutzen, wenn das Math-OLE-Objekt nicht aktiv ist. Oder ob man es irgendwie aktivieren kann, aber ohne dass die Math-UI auch aktiviert wird. Oder ob man beim "Öffnen" irgendwie Parameter mitgeben kann, die dafür sorgen, dass das neue Fenster hinter dem Dokument liegt?

Aber wenn dir nichts einfällt, gehe ich mal davon aus, dass es nicht möglich ist. Es ist auch kein schwerwiegendes Problem, weil die Funktionalität als solche ja gegeben ist.

Mit freundlichen Grüßen
Regina