Python-Makro: Als Ganzes rückgäng machen

Hallo zusammen!

In Python habe ich ein Makro geschrieben, das eine Zeichenfolge bis zu einem bestimmten Zeichen löscht; das können 15 Zeichen sein. Wenn ich das Makro laufen lasse und danach Strg-Z drücke, um den Vorgang rückgängig zu machen, wird nur das zuletzt gelöschte Zeichen wiederhergestellt und nicht die ganze Lösch-Folge (im Beispiel 15 Zeichen).

Wie erreiche ich, dass das Makro als “Einheit” gesehen wird und die gesamte Arbeit des Makros auf einmal rückgängig gemacht wird? (Im Beispiel sollten alle 15 Zeichen auf einmal gelöscht werden und nicht nur das letzte.)

Beste Grüße
Frank

Hallo
Klingt so als ob dein python-code maximal ineffizient arbeitet!? Möchtest du den Code hier zeigen?

Das kann gut sein: Ich bin kein Programmierer. Hier ist der Code:

def W_nach_rechts_loeschen(**args):
    # soll mal das Wort rechts vom Cursor löschen
    
    import string
    doc = XSCRIPTCONTEXT.getDocument()
    text = doc.Text
    view = doc.getCurrentController()
    vC = view.ViewCursor
    tC = doc.Text.createTextCursorByRange(vC)
    Sonderzeichen = ",;:.?!-_–=/()<>‚‘“”"
    # ein Wortzeichen steht für ein Wort oder trennt Wortteile:
    Wortzeichen = "█§$%&€@#"
    Stopper = "  -_./"

    fertig = False
    tC.goRight(1, True )
    Z1 = tC.getString()
    istWortzeichen = Wortzeichen.find(Z1)
    istSonderzeichen = Sonderzeichen.find(Z1)
    tC.goLeft(1, True )

    if Z1 == " ":                     # Z1 ist ein Leerzeichen
        # ----------------------------------------------------------------------
        # Leerzeichen gefunden: lösche alle weiteren Leerzeichen
        # ----------------------------------------------------------------------
        while not fertig:
            if not tC.isEndOfParagraph():
                tC.goRight(1, True)
                Z2 = tC.getString()
                if  Z2 == " ":
                    text.insertString (tC, "", 1)
                    tC.collapseToStart()
                else:
                    tC.goLeft(1, True)
                    tC.collapseToStart()
                fertig = (( Z2 != " " ) or tC.isEndOfParagraph() )
        fertig = (( Z2 != " " ) or tC.isEndOfParagraph() )
# -------------------------------------------------------------------------------------
# Jetzt sind alle Leerzeichen gelöscht (und eins bleibt stehen).
# Unterscheide 5 Fälle:
# 1) Wortzeichen 2) Sonderzeichen 3) Ziffer 4) Buchstabe
# 5) Absatzanfang
# -------------------------------------------------------------------------------------

    fertig = False

    if istWortzeichen > -1:       # Z1 ist ein Wortzeichen
#        text.insertString(tC, "---ist Wortzeichen---", 1)
        # ----------------------------------------------------------------------
        # Z1 ist ein Wortzeichen:
        # lösche bis zum nächsten
        # [Leerzeichen | geschützten Leerzeichen]:
        # noch durch geschütztes Leerzeichen ersetzen!
        # ---------------------------------------------------------------------
        while not fertig:
            if not tC.isEndOfParagraph():
                tC.goRight(1, True)
                Z2 = tC.getString()
                # istWortzeichen = Wortzeichen.find(Z2)
                if  (Z2 != "ĸ") and (Z2 != " "):   # Z2 ist ein (geschütztes) Leerzeichen
                    text.insertString (tC, "", 1)
                    tC.collapseToStart()
                else:
                    text.insertString(tC, "", 1)
                    tC.collapseToStart()
                fertig = ( (Z2 == "ĸ") or (Z2 == " ") or tC.isEndOfParagraph() )
        fertig = ( (Z2 == "ĸ") or (Z2 == " ") or tC.isEndOfParagraph() )

    elif istSonderzeichen > -1: # Z1 ist ein Sonderzeichen
        # ----------------------------------------------------------------------
        # Z1 ist ein Sonderzeichen:
        # lösche alle Sonder- und Leerzeichen
        # bis zum nächsten anderen  Zeichen:
        # ----------------------------------------------------------------------
        while not fertig:
            if not tC.isEndOfParagraph():
                tC.goRight(1, True)
                Z2 = tC.getString()
                istSonderzeichen = Sonderzeichen.find(Z2)
                if  (istSonderzeichen > -1) or (Z2 == " "):   # Z2 ist Sonderzeichen
                    text.insertString (tC, "", 1)
                    tC.collapseToStart()
                else:
                    text.insertString(tC, "", 1) # war: tC.goLeft(1, True)
                    tC.collapseToStart()
                fertig = (( istSonderzeichen == -1) or tC.isEndOfParagraph() )
        fertig = (( istSonderzeichen == -1) or tC.isEndOfParagraph() )
        tC.goRight(1, True)
        text.insertString(tC, " ", 1)
        tC.collapseToStart()
    
    elif Z1.isdigit():                  # Z1 ist eine Ziffer
#        text.insertString(tC, "---ist Ziffer---", 1)
        # ----------------------------------------------------------------------
        # Z1 ist eine Ziffer:
        # lösche alles bis zum nächsten Stopper:
        # ----------------------------------------------------------------------
        while not fertig:
            if not tC.isEndOfParagraph():
                tC.goRight(1, True)
                Z2 = tC.getString()
                istStopper = Stopper.find(Z2)
                text.insertString (tC, "", 1)
                tC.collapseToStart()
            fertig = (( istStopper > -1) or tC.isEndOfParagraph() )
            # "." ist ein Stopper, hinter dem ein Leerzeichen gelöscht werden muss:
            if Z2 == ".":
                tC.goRight(1, True)
                text.insertString(tC, "", 1)
                tC.collapseToStart()

    elif Z1.isalpha():
        # ----------------------------------------------------------------------
        # Z1 ist ein Buchstabe:
        # lösche alles bis zum nächsten Stopper:
        # (nicht mit Ziffer zusammenfassen, um später
        # ggf. eine getrennte Behandlung zu ermöglichen)
        # ----------------------------------------------------------------------
        while not fertig:
            if not tC.isEndOfParagraph():
                tC.goRight(1, True)
                Z2 = tC.getString()
                istStopper = Stopper.find(Z2)
                text.insertString (tC, "", 1)
                tC.collapseToStart()
            fertig = (( istStopper > -1) or tC.isEndOfParagraph() )
            # "." ist ein Stopper, hinter dem ein Leerzeichen gelöscht werden muss:
            if Z2 == ".":
                tC.goRight(1, True)
                text.insertString(tC, "", 1)
                tC.collapseToStart()
        
    elif tC.isEndOfParagraph():
        tC.goRight(1, True)
        text.insertString(tC, " ", 1)
        tC.collapseToStart()

Oha !!!

… welche real existierende Aufgabenstellung möchtest du mit diesem grausamen Spaghetti-code lösen? Kannst du da ein passendes writer-dokument hochladen?

Vielen Dank für die Blumen :wink:

Mein Problem habe wohl nur ich: Ich möchte einen Text, den eine Spracherkennung liefert, schnell (das ist wörtlich gemeint) korrigieren. Dazu gehört das Löschen von Wörtern. Die eingebaute Writer-Funktion macht nicht ganz das, was ich erreichen möchte.

Daher möchte ich selbst definieren, was ein Wort ist bzw. bis wohin aber der aktuellen Cursor-Position gelöscht werden soll. Aus diesem Grunde habe ich mir die Möglichkeit geschaffen, Sonderzeichen und “Stopper” zu definieren.

Ein passendes Writer-Dokument ist jeder längere Text. Ein Hochladen erübrigt sich dadurch.

Bist du dir sicher?! …

… und hast eine sinnvolle Erklärung für diese ominöse Prüfung ( das ist kein K sondern das Unicodezeichen 312 (SMALL CAPITAL LETTER KRA)

und weitere Hilfeversuche erübrigen sich u.a, auch deshalb!

Ja, ich bin mir sicher, dass jeder längere Text - genauer: jeder längere Text, der redigiert werden muss - ein passendes Dokument ist, weil es um das Löschen von Wörtern geht. Aber hier kann man sich einen kurzen Beispieltext herunterladen.
Das Zeichen, das aussieht wie ein K, aber keines ist, füge ich absichtlich an manchen Textstellen ein. Da brauche ich ein Zeichen, das sonst nicht im Text vorkommt, aber schnell eingegeben werden kann.
Ich hoffe, diese Zusatzangaben helfen bei der Lösung meines Problems: Wie erreiche ich, dass ein LibreOffice-Makro als Ganzes rückgängig gemacht wird?

Es gibt LibreOffice: XUndoManager Interface Reference, habe ich persönlich noch nie benutzt. Du findest aber Topics dazu.
Auch bei den alten Hasen: https://forum.openoffice.org/en/forum/viewtopic.php?p=511372#p511372

1 Like