Commit c27cf4f786f2da42086bd64ec5755639e3ab1df0

Authored by Perry Werneck
1 parent c73219f2
Exists in master and in 1 other branch develop

Fixing macos build.

Showing 1 changed file with 140 additions and 117 deletions   Show diff stats
src/selection/macos/paste.c
... ... @@ -18,7 +18,7 @@
18 18 * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19 19 * St, Fifth Floor, Boston, MA 02110-1301 USA
20 20 *
21   - * Este programa está nomeado como - possui - linhas de código.
  21 + * Este programa está nomeado como selection.c e possui - linhas de código.
22 22 *
23 23 * Contatos:
24 24 *
... ... @@ -28,169 +28,192 @@
28 28 */
29 29  
30 30 #include <clipboard.h>
31   - #include <lib3270/selection.h>
32 31 #include <lib3270/toggle.h>
  32 + #include <v3270/dialogs.h>
  33 + #include <lib3270/popup.h>
33 34  
34 35 /*--[ Implement ]------------------------------------------------------------------------------------*/
35 36  
36   -void v3270_clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj)
  37 +static void text_received(G_GNUC_UNUSED GtkClipboard *clipboard, const gchar *text, GtkWidget *widget)
37 38 {
38   - v3270 * terminal = GTK_V3270(obj);
  39 + v3270_input_text(widget,text,"UTF-8");
  40 +}
  41 +
  42 +static gboolean has_target(const GdkAtom atom, const GdkAtom *atoms, const gint n_atoms)
  43 +{
  44 + gint ix;
39 45  
40   - if(!lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_KEEP_SELECTED))
  46 + for(ix = 0; ix < n_atoms; ix++)
41 47 {
42   - v3270_unselect(GTK_WIDGET(obj));
43   - v3270_clear_selection(terminal);
  48 + if(atom == atoms[ix])
  49 + return TRUE;
44 50 }
45 51  
  52 + return FALSE;
46 53 }
47 54  
48   -void v3270_clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj)
  55 +static void formatted_received(GtkClipboard *clipboard, GtkSelectionData *selection_data, GtkWidget *widget)
49 56 {
50   - v3270 * terminal = GTK_V3270(obj);
  57 + const struct SelectionHeader *selection = (const struct SelectionHeader *) gtk_selection_data_get_data(selection_data);
51 58  
52   - if(!terminal->selection.blocks)
53   - {
54   - return;
55   - }
  59 + v3270 * terminal = GTK_V3270(widget);
56 60  
57   - switch(target)
  61 + debug(
  62 + "Received formatted data with %u bytes: Build=%u rows=%u cols=%u",
  63 + selection->length,
  64 + selection->build,
  65 + selection->rows,
  66 + selection->cols
  67 + );
  68 +
  69 + if(selection->cols != lib3270_get_width(terminal->host) || selection->rows != lib3270_get_height(terminal->host))
58 70 {
59   - case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text
60   - {
61   - g_autofree gchar *text = v3270_get_copy_as_text(terminal,"UTF-8");
62   - gtk_selection_data_set_text(selection,text,-1);
63   - }
64   - break;
  71 + GtkWidget * dialog =
  72 + gtk_message_dialog_new(
  73 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  74 + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
  75 + GTK_MESSAGE_INFO,
  76 + GTK_BUTTONS_NONE,
  77 + _("Not the same terminal type")
  78 + );
65 79  
66   - case CLIPBOARD_TYPE_CSV:
67   - {
68   - g_autofree gchar *text = v3270_get_copy_as_table(terminal,";","UTF-8");
69   - debug("Selection:\n%s",text);
70   - gtk_selection_data_set(
71   - selection,
72   - gdk_atom_intern_static_string("text/csv"),
73   - 8,
74   - (guchar *) text,
75   - strlen(text)
76   - );
77   - }
78   - break;
79 80  
80   - case CLIPBOARD_TYPE_HTML:
81   - {
82   - g_autofree gchar *text = v3270_get_copy_as_html(terminal,"UTF-8");
83   - //debug("Selection:\n%s",text);
84   - gtk_selection_data_set(
85   - selection,
86   - gdk_atom_intern_static_string("text/html"),
87   - 8,
88   - (guchar *) text,
89   - strlen(text)
90   - );
91   - }
92   - break;
  81 + gtk_window_set_title(GTK_WINDOW(dialog),_("Can't paste"));
  82 +
  83 + gtk_dialog_add_buttons(
  84 + GTK_DIALOG (dialog),
  85 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  86 + _("_Paste as text"), GTK_RESPONSE_APPLY,
  87 + NULL
  88 + );
  89 +
  90 + gtk_dialog_set_default_response(GTK_DIALOG (dialog),GTK_RESPONSE_APPLY);
93 91  
94   - case CLIPBOARD_TYPE_V3270_FORMATTED:
  92 + gint response = gtk_dialog_run(GTK_DIALOG(dialog));
  93 +
  94 + gtk_widget_destroy(dialog);
  95 +
  96 + if(response == GTK_RESPONSE_APPLY)
95 97 {
96   - g_autofree gchar *data = v3270_get_copy_as_data_block(terminal);
97   - gtk_selection_data_set(
98   - selection,
99   - GTK_V3270_GET_CLASS(obj)->clipboard_formatted,
100   - 8,
101   - (guchar *) data,
102   - ((struct SelectionHeader *) data)->length
  98 + gtk_clipboard_request_text(
  99 + clipboard,
  100 + (GtkClipboardTextReceivedFunc) text_received,
  101 + (gpointer) widget
103 102 );
104 103 }
105   - break;
106 104  
107   - case CLIPBOARD_TYPE_PIXBUFF:
108   - {
109   - GdkPixbuf * pixbuff = v3270_get_selection_as_pixbuf(terminal, terminal->selection.blocks, FALSE);
  105 + return;
110 106  
111   - debug("%s: pixbuff=%p (blocks=%p)",__FUNCTION__,pixbuff,terminal->selection.blocks);
  107 + }
112 108  
113   - if(pixbuff)
114   - {
115   - gtk_selection_data_set_pixbuf(selection,pixbuff);
116   - g_object_unref(pixbuff);
117   - }
  109 + if(!v3270_set_from_data_block(terminal, selection))
  110 + {
  111 + debug("%s: Can't paste data",__FUNCTION__);
  112 +
  113 + LIB3270_POPUP popup = {
  114 + .name = "cantpaste",
  115 + .title = _("Can't paste"),
  116 + .summary = _("Unable to paste formatted data."),
  117 + .body = _("None of the screens in the clipboard match with the current one."),
  118 + .label = _("_Paste as text")
  119 + };
  120 +
  121 + if(v3270_popup_dialog_show(widget,&popup,1) == GTK_RESPONSE_APPLY)
  122 + {
  123 + gtk_clipboard_request_text(
  124 + clipboard,
  125 + (GtkClipboardTextReceivedFunc) text_received,
  126 + (gpointer) widget
  127 + );
118 128 }
119   - break;
120 129  
121   - default:
122   - g_warning("Unexpected clipboard type %d\n",target);
  130 + return;
  131 +
123 132 }
124   -}
125 133  
126   -void v3270_update_system_clipboard(GtkWidget *widget)
127   -{
128   - v3270 * terminal = GTK_V3270(widget);
  134 +}
129 135  
130   - if(!terminal->selection.blocks)
131   - {
132   - // No clipboard data, return.
133   - v3270_emit_copy_state(widget);
134   - return;
135   - }
  136 +static void targets_received(GtkClipboard *clipboard, GdkAtom *atoms, gint n_atoms, GtkWidget *widget) {
136 137  
137   - // Has clipboard data, inform system.
138   - GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,terminal->selection.target);
  138 + // If smart paste is enabled try to get formatted clipboard.
  139 + gboolean screen_paste = ((GTK_V3270(widget)->selection.options & V3270_SELECTION_SCREEN_PASTE) != 0);
139 140  
140   - // Create target list
141   - //
142   - // Reference: https://cpp.hotexamples.com/examples/-/-/g_list_insert_sorted/cpp-g_list_insert_sorted-function-examples.html
143   - //
144   - GtkTargetList * list = gtk_target_list_new(NULL,0);
  141 + debug("%s: Screen paste is %s", __FUNCTION__, screen_paste ? "enabled" : "disabled");
145 142  
146   - gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT);
  143 + if(screen_paste && has_target(GTK_V3270_GET_CLASS(widget)->clipboard_formatted,atoms,n_atoms)) {
147 144  
148   - if((terminal->selection.options & V3270_SELECTION_PLAIN_TEXT) == 0)
149   - {
150   - static const GtkTargetEntry targets[] = {
151   - { "text/csv", 0, CLIPBOARD_TYPE_CSV },
152   - { "text/html", 0, CLIPBOARD_TYPE_HTML },
153   - { "application/x-v3270-formatted", 0, CLIPBOARD_TYPE_V3270_FORMATTED },
154   - };
  145 + debug("Clipboard as TN3270 \"%s\" data",gdk_atom_name(GTK_V3270_GET_CLASS(widget)->clipboard_formatted));
155 146  
156   - gtk_target_list_add_table(list, targets, G_N_ELEMENTS(targets));
  147 + gtk_clipboard_request_contents(
  148 + clipboard,
  149 + GTK_V3270_GET_CLASS(widget)->clipboard_formatted,
  150 + (GtkClipboardReceivedFunc) formatted_received,
  151 + (gpointer) widget
  152 + );
157 153  
  154 + return;
158 155 }
159 156  
160   - if(terminal->selection.options & V3270_SELECTION_PIXBUFF)
161   - {
162   - gtk_target_list_add_image_targets(list,CLIPBOARD_TYPE_PIXBUFF,TRUE);
163   - }
  157 + // No smart paste or formatted data on clipboard, request as text.
  158 + gtk_clipboard_request_text(
  159 + clipboard,
  160 + (GtkClipboardTextReceivedFunc) text_received,
  161 + (gpointer) widget
  162 + );
  163 +
  164 +}
164 165  
165   - int n_targets;
166   - GtkTargetEntry * targets = gtk_target_table_new_from_list(list, &n_targets);
  166 +LIB3270_EXPORT void v3270_clipboard_get_from_url(GtkWidget *widget, const gchar *url)
  167 +{
  168 + g_return_if_fail(GTK_IS_V3270(widget));
  169 +
  170 + GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,GTK_V3270(widget)->selection.target);
167 171  
168   -#ifdef DEBUG
  172 + if(!url || !*url || g_str_has_prefix(url,"clipboard://") || g_str_has_prefix(url,"tn3270://"))
169 173 {
170   - int ix;
171   - for(ix = 0; ix < n_targets; ix++) {
172   - debug("target(%d)=\"%s\"",ix,targets[ix].target);
173   - }
  174 + gtk_clipboard_request_targets(
  175 + clipboard,
  176 + (GtkClipboardTargetsReceivedFunc) targets_received,
  177 + (gpointer) widget
  178 + );
174 179 }
175   -#endif // DEBUG
176   -
177   - if(gtk_clipboard_set_with_owner(
  180 + else if(g_str_has_prefix(url,"text://"))
  181 + {
  182 + gtk_clipboard_request_text(
178 183 clipboard,
179   - targets,
180   - n_targets,
181   - (GtkClipboardGetFunc) v3270_clipboard_get,
182   - (GtkClipboardClearFunc) v3270_clipboard_clear,
183   - G_OBJECT(widget)
184   - ))
  184 + (GtkClipboardTextReceivedFunc) text_received,
  185 + (gpointer) widget
  186 + );
  187 + }
  188 + else if(g_str_has_prefix(url,"file://"))
185 189 {
186   - gtk_clipboard_set_can_store(clipboard,targets,1);
  190 + GtkWidget * dialog = v3270_load_dialog_new(widget, url+7);
  191 + gtk_widget_show_all(dialog);
  192 + v3270_load_dialog_run(dialog);
  193 + gtk_widget_destroy(dialog);
  194 + }
  195 + else if(g_str_has_prefix(url,"screen://"))
  196 + {
  197 + gtk_clipboard_request_contents(
  198 + clipboard,
  199 + GTK_V3270_GET_CLASS(widget)->clipboard_formatted,
  200 + (GtkClipboardReceivedFunc) formatted_received,
  201 + (gpointer) widget
  202 + );
187 203 }
188 204  
189   - gtk_target_table_free(targets, n_targets);
190   - gtk_target_list_unref(list);
  205 +}
191 206  
192   - v3270_emit_copy_state(widget);
193 207  
  208 +LIB3270_EXPORT void v3270_paste(GtkWidget *widget)
  209 +{
  210 + debug("%s",__FUNCTION__);
  211 + v3270_clipboard_get_from_url(widget,NULL);
194 212 }
195 213  
  214 +LIB3270_EXPORT void v3270_paste_text(GtkWidget *widget)
  215 +{
  216 + debug("%s",__FUNCTION__);
  217 + v3270_clipboard_get_from_url(widget,"text://");
  218 +}
196 219  
... ...