Suche rtf (richedit) Control für Linux

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Suche rtf (richedit) Control für Linux

Beitrag von ccode_new »

Der Grund des Ganzen ist:

Ich benötige für das Speichern und das Lesen ein plattformübergreifendes Format.

Und dieses Format möchte ich mir nun basteln.

Also ich möchte die formatierte Textdatei z.B. unter Linux speichern und unter Windows lesen können.
Genauso möchte ich eine formatierte Textdatei unter Windows erstellen können und unter Linux lesen können.

Das Linux GTK_TEXT_VIEW kann ja keine rtf-Daten lesen und die Windows-Richedit-Control kann keine GTKTEXTBUFFERCONTENTS-0001 - Daten lesen.

Irgend wie versuche ich jetzt ein einheitliches Format zu basteln.

Ja das ist kompliziert.

Bin für jegliche Tipps dankbar.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: Suche rtf (richedit) Control für Linux

Beitrag von Shardik »

ccode_new hat geschrieben:Der Grund des Ganzen ist:

Ich benötige für das Speichern und das Lesen ein plattformübergreifendes Format.

Und dieses Format möchte ich mir nun basteln.

Also ich möchte die formatierte Textdatei z.B. unter Linux speichern und unter Windows lesen können.
Genauso möchte ich eine formatierte Textdatei unter Windows erstellen können und unter Linux lesen können.
Ich habe vor drei Jahren einmal ein ähnliches Projekt begonnen gehabt, aber dann nicht zu Ende geführt. Das folgende Beispielprogramm generiert einen RTF-Text (unter MacOS und Windows) und einen mit speziellen Tags versehenen Text unter Linux und erlaubt die Darstellung von fettem, kursivem und unterstrichenem Text (auch kombiniert), der unter Windows, Linux und MacOS im EditorGadget gleich dargestellt wird. Bei einer noch fehlenden Lese- und Speicherfunktion empfiehlt es sich, den Text vor der Ausgabe im EditorGadget abzuspeichern, da das EditorGadget in Linux mit dem RTF-Format nichts anfangen kann und MacOS und Windows das RTF-Format leicht unterschiedlich handhaben. Der Text vor der Ausgabe im EditorGadget kann beliebig zwischen den einzelnen Betriebssystemen ausgetauscht werden.

Ich habe das untenstehende Beispiel erfolgreich auf folgenden Betriebssystemen getestet:
- MacOS 10.6.8 (Snow Leopard) mit PB 5.44 x86 im ASCII- und Unicode-Modus und mit PB 5.60 x86
- Linux Mint 18.1 x64 Cinnamon in GTK 2 und GTK 3 mit PB 5.44 x64 im ASCII- und Unicode-Modus und mit PB 5.60 x64
- Lubuntu 16.04 x86 LXDE in GTK 2 und GTK 3 mit PB 5.44 x86 im ASCII- und Unicode-Modus und mit PB 5.60 x86
- Windows XP SP3 mit PB 5.44 x86 im ASCII- und Unicode-Modus und mit PB 5.60 x86
- Windows 7 x64 SP1 mit PB 5.44 x86 und x64 im ASCII- und Unicode-Modus und mit PB 5.60 x86 und x64

Code: Alles auswählen

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC ""
     gtk_text_buffer_create_tag(*Buffer.GtkTextBuffer, TagCharacter.P-UTF8,
       PropertyName.P-UTF8, PropertyValue.I, Terminator.I = 0)
  EndImport
CompilerEndIf

Structure TagEntry
  Character.S
  AttributeName.S
  StartOffset.I
  EndOffset.I
EndStructure

Procedure AddTextWithAttributes(EditorGadgetID.I, AttributeText.S)
  Static NewList Tag.TagEntry()

  Protected Offset.I
  Protected RTFTag.S
  Protected TagCharacter.S
  Protected TagList.S
  Protected TagOffset.I

  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Static TagTable.I

      Protected AttributeValue.S
      Protected EndIter.GtkTextIter
      Protected NewTextOffset.I
      Protected StartIter.GtkTextIter
      Protected *TextBuffer = gtk_text_view_get_buffer_(GadgetID(EditorGadgetID))
    CompilerCase #PB_OS_MacOS
      Protected AttributeString.I
      Protected AttributeTextASCII.S
      Protected DataObject.I
      Protected TextStorage.I
    CompilerCase #PB_OS_Windows
      Protected AttributeTextASCII.S
  CompilerEndSelect

  ; ----- Beim ersten Aufruf neue Tag-Tabelle anlegen und die RTF-Tags (für
  ;       MacOS und Windows) oder die Linux-spezifischen Tags definieren
 
  If ListSize(Tag()) = 0
    Repeat
      Read.S TagCharacter
     
      If TagCharacter = ""
        Break
      Else
        AddElement(Tag())
        Tag()\Character = TagCharacter
        Read.S Tag()\AttributeName

        CompilerIf #PB_Compiler_OS = #PB_OS_Linux
          Read.S AttributeValue
          gtk_text_buffer_create_tag(*TextBuffer, Tag()\Character,
            Tag()\AttributeName, Val(AttributeValue))
        CompilerEndIf
      EndIf
    ForEver
  Else
    ForEach Tag()
      Tag()\StartOffset = 0
      Tag()\EndOffset = 0
    Next
  EndIf

  ; ----- Alle Tags finden und in LinkedList Tag() mit Tag-Zeichen,
  ;       Attributnamen, Start- und Stopp-Offset eintragen

  Repeat
    Offset = FindString(AttributeText, "[")
   
    If Offset = 0
      Break
    Else
      TagList = ""
      TagOffset = Offset + 1
      RTFTag = "{"
     
      Repeat
        TagCharacter = Mid(AttributeText, TagOffset, 1)
       
        If TagCharacter = "]"
          Break
        Else
          If FindString(TagList, TagCharacter) = 0
            TagList + TagCharacter
          EndIf
         
          ForEach Tag()
            If Tag()\Character = TagCharacter
              If Tag()\StartOffset = 0
                Tag()\StartOffset = Offset
                RTFTag + "\" + Tag()\AttributeName + " "
              Else
                Tag()\EndOffset = Offset
                RTFTag = "}"
              EndIf

              Break
            EndIf
          Next
        EndIf
       
        TagOffset + 1
      ForEver

      CompilerIf #PB_Compiler_OS = #PB_OS_Linux
        AttributeText = ReplaceString(AttributeText, "[" + TagList + "]", "",
          #PB_String_NoCase, Offset, 1)
      CompilerElse
        AttributeText = ReplaceString(AttributeText, "[" + TagList + "]",
          RTFTag, #PB_String_NoCase, Offset, 1)
        AttributeText = ReplaceString(AttributeText, #CR$, "\line")
      CompilerEndIf

      TagList = ""
    EndIf
  ForEver

  ; ----- Neuen Text mit Attributen an schon vorhandenen anhängen

  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      NewTextOffset = gtk_text_buffer_get_char_count_(*TextBuffer)
      gtk_text_buffer_get_end_iter_(*TextBuffer, @EndIter)
      gtk_text_buffer_insert_(*TextBuffer, @EndIter, AttributeText, -1)
     
      If ListSize(Tag()) > 0
        ; ----- Alle Tags aus Liste in *TextBuffer eintragen

        ForEach Tag()
          gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @StartIter,
            NewTextOffset + Tag()\StartOffset - 1)
          gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @EndIter,
            NewTextOffset + Tag()\EndOffset - 1)
          gtk_text_buffer_apply_tag_by_name_(*TextBuffer, Tag()\Character,
            @StartIter, @EndIter)
        Next
      EndIf
    CompilerCase #PB_OS_MacOS
      AttributeText = "{\rtf1" + AttributeText + "}"
      AttributeTextASCII = Space(StringByteLength(AttributeText, #PB_Ascii))
      PokeS(@AttributeTextASCII, AttributeText, -1, #PB_Ascii)
      DataObject = CocoaMessage(0, 0,
        "NSData dataWithBytes:", @AttributeTextASCII, 
        "length:", Len(AttributeText))

      If DataObject
        AttributeString = CocoaMessage(0, 0, "NSAttributedString alloc")
        CocoaMessage(@AttributeString, AttributeString,
          "initWithRTF:@", @DataObject,
          "documentAttributes:", 0)
 
        If AttributeString
          TextStorage = CocoaMessage(0, GadgetID(0), "textStorage")
          CocoaMessage(0, TextStorage, "appendAttributedString:",
            AttributeString)
          CocoaMessage(0, AttributeString, "release")
        EndIf
      EndIf
    CompilerCase #PB_OS_Windows
      AttributeText = "{\rtf1" + AttributeText + "}"
      AttributeTextASCII = Space(StringByteLength(AttributeText, #PB_Ascii))
      PokeS(@AttributeTextASCII, AttributeText, -1, #PB_Ascii)
      SendMessage_(GadgetID(EditorGadgetID), #EM_SETSEL, -1, -1)
      SendMessage_(GadgetID(EditorGadgetID), #EM_REPLACESEL, 0,
        AttributeTextASCII)
  CompilerEndSelect
EndProcedure

OpenWindow(0, 100, 100, 400, 100, "EditorGadget with text attributes")
EditorGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
AddTextWithAttributes(0,
  "Dies ist [b]fetter Text[b] und der folgende ist [u]unterstrichen[u]." +
  #CR$)
AddTextWithAttributes(0, "Nun folgt noch [i]kursiv[i]." + #CR$)
AddTextWithAttributes(0,
  "Und gleichzeitig [biu]fett und kursiv und unterstrichen[biu].")

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

End

; ----- Tag-Definitionen

DataSection
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    Data.S "b", "weight", "700"
    Data.S "i", "style", "2"
    Data.S "u", "underline", "1"
  CompilerElse
    Data.S "b", "b"
    Data.S "i", "i"
    Data.S "u", "ul"
  CompilerEndIf

  Data.S ""
EndDataSection
Update: Ich habe den Änderungsvorschlag von ccode_new aus dem folgenden Beitrag übernommen; damit funktioniert dieses Beispielprogramm jetzt unter Linux auch im Unicode-Modus. Und ich habe Änderungen für MacOS und Windows eingebaut, sodass das Programm jetzt auch unter MacOS und Windows im Unicode-Modus läuft. Außerdem habe ich das Programm jetzt erfolgreich auch unter Lubuntu 16.04 x86 mit LXDE und Windows XP SP3 x86 getestet.
Zuletzt geändert von Shardik am 21.06.2017 20:38, insgesamt 4-mal geändert.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Suche rtf (richedit) Control für Linux

Beitrag von ccode_new »

Hi Shardik

Na mal sehen ob ich von deinem Code etwas gebrauchen kann.

Auf jedenfall ist hier schon mal ein Fehler:

Code: Alles auswählen

;Fehler: gtk_text_buffer_insert_(*TextBuffer, @EndIter, AttributeText, StringByteLength(AttributeText))
gtk_text_buffer_insert_(*TextBuffer, @EndIter, AttributeText, -1)
Es ist schön das dir das Thema nicht unbekannt ist.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: Suche rtf (richedit) Control für Linux

Beitrag von Shardik »

Ich habe mein obiges Beispielprogramm jetzt so angepaßt, dass es unter Linux, MacOS und Windows sowohl im ASCII- als auch im Unicode-Modus funktioniert.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Suche rtf (richedit) Control für Linux

Beitrag von ccode_new »

Hallo Leute,

ich habe da mal was sau-geiles gefunden.

Hier als kompilierte Lib: https://workupload.com/file/PzFgaAt

Hier als Source: https://sourceforge.net/projects/osxcart/

Test:

Code: Alles auswählen

ImportC "libosxcart-0.so"
  rtf_register_serialize_format(*buffer.GtkTextBuffer)
EndImport

Procedure.l SwapBytes(i.l)
   ProcedureReturn (i << 24) | ((i >> 24) & $ff) | ((i << 8) & $ff0000) | ((i >> 8) & $ff00)
 EndProcedure
 
Structure RTFText
   typ.a[26]
   length.l  ;big endian
   text.a[0]
 EndStructure

Procedure Editor_Save(buffer, filename.s)
  Protected.GtkTextIter istart, iend
  Protected grtSerializeFormat
  Protected *serializedData.RTFText
  Protected plen
  Protected.b success
  Protected sText.s
  
  ;grtSerializeFormat = gtk_text_buffer_register_serialize_tagset(buffer, #Null$)
  grtSerializeFormat = rtf_register_serialize_format(buffer) ;Hiermit ist es jetzt im RTF-Format !!
  gtk_text_buffer_get_bounds_(buffer, @istart, @iend)
  *serializedData = gtk_text_buffer_serialize(buffer, buffer, grtSerializeFormat, @istart, @iend, @plen)
  success = g_file_set_contents(filename, *serializedData, plen, #Null)

  Debug "Type: " + PeekS(@*serializedData\typ, 26, #PB_UTF8)
  Debug "Text length: " + StrU(SwapBytes(*serializedData\length), #PB_Long)
  sText = PeekS(@*serializedData\text, plen - 30, #PB_UTF8)
  
  Debug sText
  
  g_free(*serializedData)
  gtk_text_buffer_unregister_serialize_format(buffer, grtSerializeFormat)
EndProcedure
Ist ja mal so was von geil!!!
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
TroaX
Beiträge: 661
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Pop_OS! | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Pop_OS!
Wohnort: NRW
Kontaktdaten:

Re: Suche rtf (richedit) Control für Linux

Beitrag von TroaX »

Ich hatte damals den TinyMCE und das WebGadget verwendet. Die gespeicherten Dokumente konnten in jedem Browser verwendet werden :mrgreen:

Funktionierte damals sogar mit dem WebGadget unter Windows.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Pop_OS!
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box :lol:
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Suche rtf (richedit) Control für Linux

Beitrag von ccode_new »

Mmmmh!!!

Zu früh gefreut.

Unter Linux: Ubuntu Mate 16.04 funktioniert die Lib wunderbar, aber ich habe es jetzt mal unter OpenSuse 42.2 getestet.

Das Programm stürzt sofort ab.

Es ist dabei egal ob mit Debugger oder ohne Debugger.

Als Fehlermeldung bringt mir PureBasic nur:

[Uhrzeit] [WARNING] Gtk (ERROR): GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported
[Uhrzeit] Das mit dem Debugger getestete Executable endete unerwartet.

Es sind sowohl alle benötigten gtk3 und gtk2 -Libs installiert.
Auch das umstellen auf gtk2-Subsystem bringt den selben Fehler.

Ich hoffe jemand kann helfen.
-------------------
Ich bekomme den Fehler unter OpenSuse nicht weg. :cry:
(egal ob gtk2 oder gtk3 -Subsystem!!!)

Unter Ubuntu Mate 16.04 funktioniert die Lib auch nur mit gtk2-Subsystem.

Irgend wie müsste man die Lib doch auch für gtk3 kompilieren können?

Anleitungen wären hilfreich.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Suche rtf (richedit) Control für Linux

Beitrag von ccode_new »

Ok!
Ich bin schon einen Schritt weiter.

Wenn ich die osxcart-1.2.0 - Lib kompiliere mache ich:

./configure
make
make install

Alles mit sudo-Rechten.

Die erstellte .so Datei befindet sich dann im Verzeichnis:
/usr/local/lib

Die .so Datei kann ich auch bei Verwendung von gtk-2.0 in meinem Programm nutzen.


Aber mein Programm soll gtk-3.0 nutzen, aber die Lib nutzt ja gtk-2.0 .


Wenn ich das hier:
https://github.com/ptomato/osxcart/tree/gtk3 (Branch:gtk3)

mit:

sh ./autogen.sh
./configure
make
make install

...kompiliere ist zwar die Fehlermeldung weg, aber das Programm stürzt trotzdem einfach ab.

Nur jetzt kommt gar keine Fehlermeldung mehr.

??????

Ich bitte um Hilfe.

Es wird auch nur ins /usr/local/lib/ installiert.

...und nicht ins ../lib64/ Verzeichnis.

Die Lib scheint aber eine 64 bit zu sein. Geprüft mit ldd. (Nutzt /lib64)

Auf jedenfall funktioniert die erstellte Lib nicht mit gtk2 und auch nicht mit gtk3. Aber die Fehlermeldung ist weg.

Wenn ich PureBasic jetzt in von der Konsole (Terminal) aus starte kommt:

./purebasic

(purebasic:23644): Gtk-WARNING **: Theme directory base/ of theme oxygen has no size field

/tmp/purebasic_compilation0.out: error while loading shared libraries: libosxcart-1.so.0: cannot open shared object file: No such file or directory

Das verstehe ich nicht?

Die Lib kann PureBasic aber finden.
Wenn ich einen falschen Name angebe nörgelt PB auch rum. Hier stimmt aber das Verzeichnis und der Name.

Bin ratlos :?
Bitte um Hilfe !!!
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Suche rtf (richedit) Control für Linux

Beitrag von ccode_new »

Hi Leute,

ich bin immer noch vollkommen ratlos und von gtk genervt.

Ich versehe einfach (noch) nicht warum diese Version:

https://github.com/ptomato/osxcart/rele ... 2.0.tar.xz

mit gtk-2 (und nur mit gtk-2 Subsystem) funktioniert und jede andere Version

z.B. diese

https://github.com/ptomato/osxcart/tree/master (Branch:master)

oder diese:

https://github.com/ptomato/osxcart/tree/gvariant (Branch:gvariant)

oder ganz besonders diese:

https://github.com/ptomato/osxcart/tree/gtk3 (Branch:gtk3)

weder mit gtk-2 noch mit gtk-3 funktioniert.
(allso garnicht !!!)

Jede dieser Versionen lässt sich compilieren. (Ich musste zwar noch z.B. die gtk-doc-tools installieren und autoconf, etc updaten, aber jede der Version erstellt eine 64bit Lib)
Aber nur eine Version (osxcart-1.2.0) kann ich mit PureBasic verwenden.

Was mir dabei noch komisches aufgefallen ist:

Die Lib heißt z.B. "libosxcart-0.so.0.1.1" oder ähnlich und diesen Name gebe ich auch unter PureBasic an.

PureBasic findet die Lib dann auch, aber stürzt beim Laden der Lib einfach ab.

In der Konsole steht dann aber ein anderer Name.
Nämlich dieser: "libosxcart-0.so.0"

Diesen Name konnte ich auch in folgender Zeile der "libosxcart-0.la" Datei lokalisieren.

# The name that we can dlopen(3).
dlname='libosxcart-0.so.0'

Kann es etwas damit zu tuen haben ?

Es muss doch irgend wie möglich sein die Lib auch unter gtk3 zu nutzen.
Oder?

Danke für jede Hilfe.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Suche rtf (richedit) Control für Linux

Beitrag von NicTheQuick »

Ich gebe beim "Import" von Systembibliotheken nicht den Namen der .so-Datei an, sondern mache es so wie man es z.B. bei GCC angeben müsste. Hier ein Beispiel aus meinem libusb-Wrapper:

Code: Alles auswählen

ImportC "-lusb-1.0" ;/lib/x86_64-linux-gnu/libusb-1.0.so.0
Ich weiß leider nicht, wie es dann bei dir genau heißen müsste, aber vielleicht so:

Code: Alles auswählen

ImportC "-losxcart-0"
Aber ich vermute das Problem ist, dass du deine Bibliothek in das Verzeichnis "/usr/local/lib" installiert hast. Dieser Pfad ist unüblich, aber Standard in den meisten ThirdParty-Makefiles. Du kannst ihn deinem System bekannt machen, indem du die Datei "/etc/ld.so.conf.d/99-usrlib.conf" anlegst und als Inhalt einfach die Zeile "/usr/local/lib" hinzufügst. Anschließend rufst du noch ein "sudo ldconfig" auf und dann sollte es gehen. Die temporäre Alternative wäre es dein Purebasic-Programm so aufzurufen:

Code: Alles auswählen

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib" /tmp/purebasic_compilation0.out
Oder in zwei Zeilen:

Code: Alles auswählen

~$ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
~$ /tmp/purebasic_compilation0.out
Edit:
Und bezüglich der Namensgebung von Bibliotheken. Das sind oftmals symbolische Links. Nutzt man libusb-0.1.so.4.4.4 wird man immer Version 0.1.4.4.4 bekommen. Nutzt man libusb-0.1.so.4 kommt man in meinem Fall auf die selbe Version, aber es wäre auch möglich auf eine neuere zu kommen, wie z.B. libusb-0.1.so.4.5.0, wenn diese installiert wurde.

Code: Alles auswählen

lrwxrwxrwx 1 root root    19 Jan  8  2016 libusb-0.1.so.4 -> libusb-0.1.so.4.4.4
-rw-r--r-- 1 root root 30944 Jan  8  2016 libusb-0.1.so.4.4.4
lrwxrwxrwx 1 root root    19 Okt 23  2015 libusb-1.0.so.0 -> libusb-1.0.so.0.1.0
-rw-r--r-- 1 root root 97056 Okt 23  2015 libusb-1.0.so.0.1.0
Bild
Antworten