RTF ins Clipboard kopieren - wie?

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
pbsol
Beiträge: 7
Registriert: 11.01.2014 12:28

RTF ins Clipboard kopieren - wie?

Beitrag von pbsol »

Ich habe ein kleines Tool geschrieben, das Text einliest, aufbereitet und diesen im RTF-Format ins Clipboard kopiert. Unter Windows gelingt das recht gut; da gab es auch ein schönes Beispiel (weiß nicht mehr wo).

Unter Linux gelingt mir das einfach nicht. Meine Programmierkenntnisse sind jetzt nicht so gut, dass ich GTK+ bis ins Letzte verstehen würde, schon gar nicht die Umsetzung nach Purebasic. Einen einfachen Text kann ich mit

Code: Alles auswählen

clipboard=gtk_clipboard_get_(GDK_SELECTION_PRIMARY)
gtk_clipboard_set_text_(clipboard,text.s,-1)
kopieren. Das ist aber recht sinnlos, da Purebasic entsprechende Funktionen anbietet.

Soweit ich weiß muss man erst einem entsprechende Targets definieren (da habe ich schon Probleme) und dann wahrscheinlich mit

Code: Alles auswählen

gtk_clipboard_set_with_data_(*clipboard,targets,n_targets,*get_func,*clear_func,*user_data)
übertragen. Hier weiß ich insbesondere nicht, wie ich get_func und clear_func in Purebasic ansprechen soll.

Selbst für C gibt es recht wenig Beispiele, wie man so etwas machen könnte. Etwas in der Art (html) findet man hier:
http://www.findthatzip-file.com/search- ... tar.gz.htm

Kann mir jemand einen Tipp oder einen Stückchen Code geben?
walker
Beiträge: 278
Registriert: 29.08.2004 18:39
Wohnort: Bayern

Re: RTF ins Clipboard kopieren - wie?

Beitrag von walker »

Wie machst du das unter Windows?

Es gibt doch

Code: Alles auswählen

SetClipboardText(Text$)
der ist crossplattform .. reicht der nicht? Oder verstehe ich hier etwas falsch?
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: RTF ins Clipboard kopieren - wie?

Beitrag von Bisonte »

Es geht hier vermutlich nicht um einen gewöhnlichen String, sondern um einen Text im RTF Format. Im Grunde gleichbedeutend mit Speicherblock.
Also wie kopiert man einen SpeicherBlock in's ClipBoard und zurück ? Und das ganze crossplatform....
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
pbsol
Beiträge: 7
Registriert: 11.01.2014 12:28

Re: RTF ins Clipboard kopieren - wie?

Beitrag von pbsol »

So wie Bisonte das schreibt. Unter Windows so (Funktion von Green Snake):

Code: Alles auswählen

Procedure.i CopyRichTextToClipboard(rtf.s)
  Protected format.i
  Protected *globalMemory
  Protected *lock
  Protected result.i
 
  format = RegisterClipboardFormat_("Rich Text Format")
  If Not format
    ProcedureReturn #False
  EndIf
 
  If Not OpenClipboard_(#Null)
    ProcedureReturn #False
  Else
    EmptyClipboard_()
      
    *globalMemory = GlobalAlloc_(#GMEM_MOVEABLE | #GMEM_DDESHARE, Len(rtf) + 1)
    If Not *globalMemory
      ProcedureReturn #False
    EndIf
   
    *lock = GlobalLock_(*globalMemory)
    If Not *lock
      GlobalFree_(*globalMemory)
      ProcedureReturn #False
    EndIf
    
    PokeS(*lock, rtf, -1, #PB_Ascii) ; Text in ASCII umwandeln (falls Unicode verwendet wird) und schreiben.
    GlobalUnlock_(*globalMemory)
   
    result = SetClipboardData_(format, *globalMemory)
   
    GlobalFree_(*globalMemory)
    CloseClipboard_()
   
    ProcedureReturn result
  EndIf
 
  ProcedureReturn #False
EndProcedure
http://www.development-lounge.de/viewtopic.php?t=5978

Ansonsten erhält man immer nur den reinen Text, ohne Formatierungen und mit rtf-Steueranweisungen.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: RTF ins Clipboard kopieren - wie?

Beitrag von ts-soft »

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
pbsol
Beiträge: 7
Registriert: 11.01.2014 12:28

Re: RTF ins Clipboard kopieren - wie?

Beitrag von pbsol »

Ja, kenne ich natürlich. Hilft mir leider nicht weiter.

Gibt es irgendwo Literatur, die einem bei der Umsetzung hilft? Die PB-Hilfe ist da eher schweigsam und verweist immer auf den fortgeschrittenen/professionellen Programmierer, der solche Funktionen benötigt. Zudem sind eher Windows-Beispiele als GTK-Beispiele zu finden, das macht es nicht unbedingt leichter.
pbsol
Beiträge: 7
Registriert: 11.01.2014 12:28

Re: RTF ins Clipboard kopieren - wie?

Beitrag von pbsol »

Also ich habe es jetzt hinbekommen. Hatte die Lösung eigentlich schon recht lange, habe aber immer eine Unicode Executable erstellt und damit funktioniert es nicht. Und hier bräuchte ich nochmal Hilfe. Erst einmal der Code:

Code: Alles auswählen

gtk_init_(0,0)

; Clipboard Targets
Enumeration
  #TARGET_STRING
  #TARGET_RTF
EndEnumeration

Global Dim targets.GtkTargetEntry(2)

targets(0)\target=@"STRING"
targets(0)\flags=0
targets(0)\info=#TARGET_STRING

targets(1)\target=@"text/rtf"
targets(1)\flags=0
targets(1)\info=#TARGET_RTF
; Ende Target-Definition

Global n_targets=ArraySize(targets()) ; Anzahl der Targets

Global clipboard=gtk_clipboard_get_(GDK_SELECTION_PRIMARY) ;Clipboard oeffnen

Global rtf.s = "{\rtf1\ansi\ansicpg1252\deff0\deflang3082{\fonttbl{\f0\fswiss\fcharset0 Verdana;}}"  ;rtf das kopiert wird
rtf.s + "{\colortbl ;\red255\green102\blue0;\red128\green128\blue128;}"
rtf.s + "\viewkind4\uc1\pard\qc\f0\fs20\par"
rtf.s + "\cf1\ul\b\i\fs28 RTF RTF \cf2\fs20\par"
rtf.s + "\cf0\ulnone\b0\i0\par"
rtf.s + "\cf2 geht fast alles \par"
rtf.s + "\par"
rtf.s + "\cf2 bis auf Umlaute \par"
rtf.s + "\par"
rtf.s + "}"

ProcedureC get_func(clipboard,selection_data,info,user_data) ;rtf ins Clipboard 
  length=Len(rtf)
  Select info
    Case #TARGET_STRING
      gtk_selection_data_set_text_(selection_data,rtf,length)
    Case #TARGET_RTF
      gtk_selection_data_set_(selection_data,gdk_atom_intern_("text/rtf", #False),8,rtf,length)
  EndSelect
EndProcedure

gtk_clipboard_set_with_data_(clipboard,targets(),n_targets,@get_func(),#Null,#Null) ;hier werden u.a. die Targets uebertragen targets()

; Dummy-Fenster, muss waehrend des Programmtests geoffnet bleiben

OpenWindow(0, 0, 0, 345, 105, "GTK clipboard test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Den Inhalt könnt Ihr z.B. in OpenOffice kopieren oder als Text in einen Editor.

Ein kleines Python-Skript zeigt schön die Targets und den Inhalt:

Code: Alles auswählen

#!/usr/bin/python

import glib, gtk

def test_clipboard():
    clipboard = gtk.Clipboard()
    targets = clipboard.wait_for_targets()
    print "Targets available:", ", ".join(map(str, targets))
    for target in targets:
        print "Trying '%s'..." % str(target)
        contents = clipboard.wait_for_contents(target)
        if contents:
            print contents.data

def main():
    mainloop = glib.MainLoop()
    def cb():
        test_clipboard()
        mainloop.quit()
    glib.idle_add(cb)
    mainloop.run()

if __name__ == "__main__":
    main()
Und hiermit kann man das Problem erkennen. Wenn ich Unicode Executable auswähle, stimmen die Targets nicht mehr, statt "text/rtf" steht nur noch "t" und statt "STRING" nur noch "S". Die Daten sind zwar im Clipboard, aber keine Anwendung kann mit "t" oder "S" etwas anfangen.

Hat jemand eine Idee, wie es mit Unicode klappen könnte?
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: RTF ins Clipboard kopieren - wie?

Beitrag von NicTheQuick »

Du hättest eigentlich nur die Bits ändern müssen. Mit '8 * SizeOf(Character)' bleibt es dynamisch und funktioniert mit und ohne Unicode. Mehr hab ich aber auch nicht getestet. Aber das Einfügen in OpenOffice klappt auch mit Umlauten.

Code: Alles auswählen

gtk_init_(0,0)

; Clipboard Targets
Enumeration
  #TARGET_STRING
  #TARGET_RTF
EndEnumeration

Global Dim targets.GtkTargetEntry(2)

targets(0)\target=@"STRING"
targets(0)\flags=0
targets(0)\info=#TARGET_STRING

targets(1)\target=@"text/rtf"
targets(1)\flags=0
targets(1)\info=#TARGET_RTF
; Ende Target-Definition

Global n_targets=ArraySize(targets()) ; Anzahl der Targets

Global clipboard=gtk_clipboard_get_(GDK_SELECTION_PRIMARY) ;Clipboard oeffnen

Global rtf.s = "{\rtf1\ansi\ansicpg1252\deff0\deflang3082{\fonttbl{\f0\fswiss\fcharset0 Verdana;}}" +  ;rtf das kopiert wird
               "{\colortbl ;\red255\green102\blue0;\red128\green128\blue128;}" +
               "\viewkind4\uc1\pard\qc\f0\fs20\par" +
               "\cf1\ul\b\i\fs28 RTF RTF \cf2\fs20\par" +
               "\cf0\ulnone\b0\i0\par" +
               "\cf2 geht fast alles \par" +
               "\par" +
               "\cf2 bis auf Umlaute \par" +
               "\par" +
               "\cf2 ÄÖÜäöüß \par" +
               "\par" +
               "}"

Global *rtf_Ascii = AllocateMemory(Len(rtf) + 1)
PokeS(*rtf_Ascii, rtf, #PB_Ascii)

ProcedureC get_func(clipboard,selection_data,info,user_data) ;rtf ins Clipboard
  length=Len(rtf)
  Select info
    Case #TARGET_STRING
      gtk_selection_data_set_text_(selection_data,rtf,length)
    Case #TARGET_RTF
      gtk_selection_data_set_(selection_data, gdk_atom_intern_("text/rtf", #False), 8 * SizeOf(Character), @rtf, length)
  EndSelect
EndProcedure

gtk_clipboard_set_with_data_(clipboard,targets(),n_targets,@get_func(),#Null,#Null) ;hier werden u.a. die Targets uebertragen targets()

; Dummy-Fenster, muss waehrend des Programmtests geoffnet bleiben

OpenWindow(0, 0, 0, 345, 105, "GTK clipboard test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: RTF ins Clipboard kopieren - wie?

Beitrag von ts-soft »

@NicTheQuick
Mit Deiner Änderung funktionieren zwar die Umlaute, aber nicht im Unicode-Mode (da geht gar nichts).
Mit Import der Funktionen mit Pseudotype hatte ich auch noch kein Glück. Und den
text als ASCII in einen Speicher poken will auch nicht so recht. Sehr empfindlich die
Sache, fehlt mir leider im moment die Zeit für.

Aber irgendwie so in dieser Richtung sollte es funktionieren.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
pbsol
Beiträge: 7
Registriert: 11.01.2014 12:28

Re: RTF ins Clipboard kopieren - wie?

Beitrag von pbsol »

Jep, ist mir auch gerade aufgefallen. Arbeite mit 32 Bit Ubuntu 12.04 LTS, daran wird es wohl nicht liegen, oder? Das mit den Umlauten geht jetzt jedenfalls. Vielen Dank!
Antworten