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 »

Danke für die Antwort!!!

Leider funktioniert das mit dem Irgendwas$= PeekS(serializedData, -1, #PB_UTF8) nicht.

Also ich bekommen dann immer nur "GTKTEXTBUFFERCONTENTS-0001".

Den gleichen Text bekomme ich auch, wenn ich die Datei (also die Save-Datei) mit PureBasic öffne.

Wenn ich die Datei mit Pluma-Texteditor öffnen möchte kommt nur:

Die Datei »..../test.txt« konnte nicht geöffnet werden.
Die Zeichenkodierung konnte nicht festgestellt werden.
Bitte stellen Sie sicher, dass Sie nicht versuchen, eine Binärdatei zu öffnen.
Wählen Sie eine Zeichenkodierung aus dem Menü und versuchen Sie es erneut.

Wenn ich die Datei aber zum Beispiel mit Libre Office öffne kommt:
GTKTEXTBUFFERCONTENTS-0001###� <text_view_markup>
<tags>
</tags>
<text>Die ist eine Adaptierung des Text-widget - &apos;Multiple Views&apos;-C-Quelltextes vom gtk-Demo in einen PureBasic-Quellcode mit einer Aufreihung ähnlicher Text-Effekte.
Zudem demonstriert diese Demo ein möglichen Umgang mit den in &apos;C&apos; in puncto Typ und Anzahl flexibler handhabbaren Importen. Hier wird für jede Variation ein eigener Import angelegt!

</text>
</text_view_markup>

Dieser letzte Text sollte eigentlich auch im String stehen. Tut er aber nicht !!!!

Ich habe auch schon Unicode oder Ascii ,etc. probiert.
Das hilft auch nichts.
Der Text wird immer nach "GTKTEXTBUFFERCONTENTS-0001" abgeschnitten.

Libre Office kann den Text aber lesen.

??????
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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 »

Das liegt wohl daran, dass der Text an der Stelle ein Nullbyte hat und deswegen nicht In Nullterminierten Strings gespeichert werden kann.
Du musst den Speicherbereich binär mit WriteData() in die Datei schreiben.
Bild
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

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

Beitrag von Shardik »

Hier ist ein funktionierendes Beispiel, das ich vor einigen Jahren einmal erstellt hatte. Es demonstriert, wie man einen formatierten Text speichert und nach dem Löschen wieder neu lädt und anzeigt. Ich habe es eben erfolgreich unter Linux Mint 18.1 x86 mit Cinnamon und PB 5.44 x86 im ASCII- und Unicode-Modus sowohl mit GTK 2 als auch mit GTK 3 erfolgreich getestet:

Code: Alles auswählen

; Converted from tadeboro's C source code:
; http://www.gtkforums.com/viewtopic.php?t=2300&start=1

EnableExplicit

#RTFTextFile = "RTFTextBuffer"

ImportC ""
  gtk_text_buffer_create_tag(*Buffer.GtkTextBuffer, TagName.P-UTF8,
     PropertyName.P-UTF8, PropertyValue.I, Terminator.I = 0)
  gtk_text_buffer_deserialize(*RegisteredBuffer.GtkTextBuffer,
    *DeserializationBuffer.GtkTextBuffer, FormatAtom.I, *Start.GtkTextIter,
    *SerializationData, SerializationBufferLength.I, *Error.GError)
  gtk_text_buffer_register_deserialize_tagset(*Buffer.GtkTextBuffer, TagSet.P-UTF8)
  gtk_text_buffer_register_serialize_tagset(*Buffer.GtkTextBuffer, TagSet.P-UTF8)
  gtk_text_buffer_serialize(*RegisteredBuffer.GtkTextBuffer,
    *SerializationBuffer.GtkTextBuffer, FormatAtom.I, *Start.GtkTextIter,
    *End.GtkTextIter, *OutputBufferLength)
EndImport

Procedure ChangeTextToBold(*TextBuffer, StartOffset.I, EndOffset.I)
  Protected EndIter.GtkTextIter
  Protected StartIter.GtkTextIter
  Protected TagBold.I

  TagBold = gtk_text_buffer_create_tag(*TextBuffer, "", "weight", 700)
  gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @StartIter, StartOffset)
  gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @EndIter, EndOffset)
  gtk_text_buffer_apply_tag_(*TextBuffer, TagBold, @StartIter, @EndIter)
EndProcedure

Procedure LoadRTFText(*TextBuffer, DeserializationFormat.I)
  Protected *Error.GError
  Protected *FileBuffer
  Protected StartIter.GtkTextIter

  If ReadFile(0, GetTemporaryDirectory() + #RTFTextFile)
    *FileBuffer = AllocateMemory(Lof(0))
    ReadData(0, *FileBuffer, MemorySize(*FileBuffer))
    gtk_text_buffer_get_start_iter_(*TextBuffer, @StartIter)

    If gtk_text_buffer_deserialize(*TextBuffer, *TextBuffer,
      DeserializationFormat, @StartIter, *FileBuffer, MemorySize(*FileBuffer),
      @*Error) = 0
      MessageRequester("Error", "Deserialization failed:" + #CR$ +
        PeekS(*Error\message, -1, #PB_UTF8))
    EndIf

    CloseFile(0)
    FreeMemory(*FileBuffer)
  EndIf
EndProcedure

Procedure SaveRTFText(*TextBuffer, SerializationFormat.I)
  Protected BufferSize.I
  Protected *FileBuffer
  Protected EndIter.GtkTextIter
  Protected StartIter.GtkTextIter

  gtk_text_buffer_get_start_iter_(*TextBuffer, @StartIter)
  gtk_text_buffer_get_end_iter_(*TextBuffer, @EndIter)
  *FileBuffer = gtk_text_buffer_serialize(*TextBuffer, *TextBuffer,
     SerializationFormat, @StartIter, @EndIter, @BufferSize)
  
  If *FileBuffer 
    If CreateFile(0, GetTemporaryDirectory() + #RTFTextFile)
      WriteData(0, *FileBuffer, BufferSize)
      CloseFile(0)
    EndIf
    
    g_free_(*FileBuffer)
  EndIf
EndProcedure

Define DeserializationFormat.I
Define SerializationFormat.I
Define *TextBuffer

OpenWindow(0, 100, 100, 300, 100, "EditorGadget")
EditorGadget(0, 10, 10, 280, 50)
ButtonGadget(1, 10, 68, 90, 25, "Load text")
DisableGadget(1, #True)
ButtonGadget(2, 105, 68, 90, 25, "Save text")
ButtonGadget(3, 200, 68, 90, 25, "Clear")

*TextBuffer = gtk_text_view_get_buffer_(GadgetID(0))
DeserializationFormat = gtk_text_buffer_register_deserialize_tagset(*TextBuffer,
  "default")
SerializationFormat = gtk_text_buffer_register_serialize_tagset(*TextBuffer,
  "default")

SetGadgetText(0, "Bold text")
ChangeTextToBold(*TextBuffer, 0, 4)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      DeleteFile(GetTemporaryDirectory() + #RTFTextFile)
      Break
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          LoadRTFText(*TextBuffer, DeserializationFormat)
        Case 2
          SaveRTFText(*TextBuffer, SerializationFormat)
          DisableGadget(1, #False)
        Case 3
          SetGadgetText(0, "")
      EndSelect
  EndSelect
ForEver
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,

zu spät !!! :wink:

In der Zwischenzeit bin ich schon weiter. :mrgreen:

Ich habe das mit den speichern und lesen des File's ja so gelöst:

success = g_file_set_contents(filename, serializedData, plen, #Null)

success = g_file_get_contents(filename, @serializedData, @plen, #Null)

Aber so:

Code: Alles auswählen

If *FileBuffer
    If CreateFile(0, GetTemporaryDirectory() + #RTFTextFile)
      WriteData(0, *FileBuffer, BufferSize)
      CloseFile(0)
    EndIf
   
    g_free_(*FileBuffer)
  EndIf
geht natürlich auch.

Aber in einen String kann man es so trotzdem noch nicht speichern.
Wie bekomme ich aus den Binär-Dateien einen String ?
Ohne das File auszulesen.

Ich habe gestern noch nicht weiter probiert. Aber Ich werde heute Abend mal weiter probieren.

__________________________________________________
Code-Tags hinzugefügt
03.07.2017
RSBasic
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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 »

Binärdaten kann man nicht in einem String speichern wegen möglicher Nullbytes.

Beschreib mal lieber, was du genau vorhast und warum du unbedingt Strings brauchst.
Bild
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 Nic der Schnelle,
NicTheQuick hat geschrieben:Binärdaten kann man nicht in einem String speichern wegen möglicher Nullbytes.
DAS MUSS GEHEN.

-> Kann man diese Nullbytes und andere störende Zeichen den nicht irgend wie filtern?
-> LibreOffice/Notepad,... kann doch z.Bsp. mit irgend einem Algo die Binärdatei auch als Textdatei darstellen (also quasi als String) und stört sich nicht an Nullbytes.

Also muss man das irgend wie konvertieren können.

*Ach so noch so ein Gedanke: Binärdateien kann man ja z.Bsp. als Base64-String (wie Bilder, ...) speichern, oder ?
-> Das ist aber nicht ganz das Ziel.

....
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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 »

Du kannst so oft sagen wie du willst, dass es gehen muss, es geht aber nicht.

Du kannst natürlich über die Binärdaten iterieren und alle Nullbytes durch ein Nicht-Nullbyte ersetzen. Dann geht es durchaus. Aber wie liegen die Binärdaten denn vor? Als Unicode, Ascii, UTF-8? Damit was sinnvolles rauskommt, muss ja wissen wie man die Daten anzupacken hat. Das Argument mit Notepad und Libreoffice hat nichts mit Nullterminierten Strings zu tun. Du kannst auch keine Binärdaten in C-Strings packen, da die auch immer auf ein Nullbyte enden. In vielen anderen Sprachen geht das ebenfalls nicht.

Und du hast immer noch nicht gesagt, was du vor hast.
Bild
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 »

Na dann eben nicht als String, sondern als Anreihung von Ints oder Chars.

Es soll nur möglich sein diese serialisieren Daten wie Strings weiterzubearbeiten.

Also z.B. diese Ausgabe:

Code: Alles auswählen

<text_view_markup>
 <tags>
  <tag name="FreeSerif" priority="37">
   <attr name="family" type="gchararray" value="FreeSerif" />
  </tag>
  <tag name="bold-2" priority="36">
   <attr name="weight" type="gint" value="700" />
  </tag>
  <tag name="new_size" priority="38">
   <attr name="size" type="gint" value="12288" />
  </tag>
  <tag name="bold" priority="5">
   <attr name="weight" type="gint" value="700" />
  </tag>
 </tags>
...soll nicht in einem Memorybereich im Arbeitsspeicher oder auf der Festplatte (als File) vergammeln, sondern mit Stringfunktionen weiter bearbeitbar sein.

Dabei könnte ich die erstelle Datei ja Zeilen, Word oder sogar Zeichenweise einlesen und als String speichern.
-> Das möchte ich aber nicht, sondern den Weg über das "File" umgehen.

__________________________________________________
Code-Tags hinzugefügt
03.07.2017
RSBasic
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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 »

Hab dir mal Debugs eingebaut, wie es geht:

Code: Alles auswählen

; Converted from tadeboro's C source code:
; http://www.gtkforums.com/viewtopic.php?t=2300&start=1

EnableExplicit

#RTFTextFile = "/home/nicolas/tmp/purebasic/RTFTextBuffer"

ImportC ""
	gtk_text_buffer_create_tag(*Buffer.GtkTextBuffer, TagName.P-UTF8,
	                           PropertyName.P-UTF8, PropertyValue.I, Terminator.I = 0)
	gtk_text_buffer_deserialize(*RegisteredBuffer.GtkTextBuffer,
	                            *DeserializationBuffer.GtkTextBuffer, FormatAtom.I, *Start.GtkTextIter,
	                            *SerializationData, SerializationBufferLength.I, *Error.GError)
	gtk_text_buffer_register_deserialize_tagset(*Buffer.GtkTextBuffer, TagSet.P-UTF8)
	gtk_text_buffer_register_serialize_tagset(*Buffer.GtkTextBuffer, TagSet.P-UTF8)
	gtk_text_buffer_serialize(*RegisteredBuffer.GtkTextBuffer,
	                          *SerializationBuffer.GtkTextBuffer, FormatAtom.I, *Start.GtkTextIter,
	                          *End.GtkTextIter, *OutputBufferLength)
EndImport

Procedure ChangeTextToBold(*TextBuffer, StartOffset.I, EndOffset.I)
	Protected EndIter.GtkTextIter
	Protected StartIter.GtkTextIter
	Protected TagBold.I
	
	TagBold = gtk_text_buffer_create_tag(*TextBuffer, "", "weight", 700)
	gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @StartIter, StartOffset)
	gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @EndIter, EndOffset)
	gtk_text_buffer_apply_tag_(*TextBuffer, TagBold, @StartIter, @EndIter)
EndProcedure

Procedure LoadRTFText(*TextBuffer, DeserializationFormat.I)
	Protected *Error.GError
	Protected *FileBuffer
	Protected StartIter.GtkTextIter
	
	If ReadFile(0, #RTFTextFile)
		*FileBuffer = AllocateMemory(Lof(0))
		ReadData(0, *FileBuffer, MemorySize(*FileBuffer))
		gtk_text_buffer_get_start_iter_(*TextBuffer, @StartIter)
		
		If gtk_text_buffer_deserialize(*TextBuffer, *TextBuffer,
		                               DeserializationFormat, @StartIter, *FileBuffer, MemorySize(*FileBuffer),
		                               @*Error) = 0
			MessageRequester("Error", "Deserialization failed:" + #CR$ +
			                          PeekS(*Error\message, -1, #PB_UTF8))
		EndIf
		
		CloseFile(0)
		FreeMemory(*FileBuffer)
	EndIf
EndProcedure

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 SaveRTFText(*TextBuffer, SerializationFormat.I)
	Protected BufferSize.I
	Protected *FileBuffer.RTFText
	Protected EndIter.GtkTextIter
	Protected StartIter.GtkTextIter
	
	gtk_text_buffer_get_start_iter_(*TextBuffer, @StartIter)
	gtk_text_buffer_get_end_iter_(*TextBuffer, @EndIter)
	*FileBuffer = gtk_text_buffer_serialize(*TextBuffer, *TextBuffer,
	                                        SerializationFormat, @StartIter, @EndIter, @BufferSize)
	
	If *FileBuffer
		Debug "Type: " + PeekS(@*FileBuffer\typ, 26, #PB_Ascii)
		Debug "Text length: " + StrU(SwapBytes(*FileBuffer\length), #PB_Long)
		Debug "Text: " + PeekS(@*FileBuffer\text, BufferSize - 30, #PB_Ascii)
	
		If CreateFile(0, #RTFTextFile)
			WriteData(0, *FileBuffer, BufferSize)
			CloseFile(0)
		EndIf
		
		g_free_(*FileBuffer)
	EndIf
EndProcedure

Define DeserializationFormat.I
Define SerializationFormat.I
Define *TextBuffer

OpenWindow(0, 100, 100, 300, 100, "EditorGadget")
EditorGadget(0, 10, 10, 280, 50)
ButtonGadget(1, 10, 68, 90, 25, "Load text")
DisableGadget(1, #True)
ButtonGadget(2, 105, 68, 90, 25, "Save text")
ButtonGadget(3, 200, 68, 90, 25, "Clear")

*TextBuffer = gtk_text_view_get_buffer_(GadgetID(0))
DeserializationFormat = gtk_text_buffer_register_deserialize_tagset(*TextBuffer,
                                                                    "default")
SerializationFormat = gtk_text_buffer_register_serialize_tagset(*TextBuffer,
                                                                "default")

SetGadgetText(0, "Bold text")
ChangeTextToBold(*TextBuffer, 0, 4)

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			DeleteFile(GetTemporaryDirectory() + #RTFTextFile)
			Break
		Case #PB_Event_Gadget
			Select EventGadget()
				Case 1
					LoadRTFText(*TextBuffer, DeserializationFormat)
				Case 2
					SaveRTFText(*TextBuffer, SerializationFormat)
					DisableGadget(1, #False)
				Case 3
					SetGadgetText(0, "")
			EndSelect
	EndSelect
ForEver 
Bild
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 »

:praise: NicTheQuick

Du hast es halt einfach drauf. :wink:

Vielen Dank !
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Antworten