source: trunk/third/gtkhtml3/src/htmlembedded.c @ 21116

Revision 21116, 10.8 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21115, which included commits to RCS files with non-trunk default branches.
RevLine 
[19538]1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*  This file is part of the GtkHTML library.
3
4    Copyright (C) 1997 Martin Jones (mjones@kde.org)
5    Copyright (C) 1997 Torben Weis (weis@kde.org)
6    Copyright (C) 1999 Helix Code, Inc.
7
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Library General Public
10    License as published by the Free Software Foundation; either
11    version 2 of the License, or (at your option) any later version.
12
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Library General Public License for more details.
17
18    You should have received a copy of the GNU Library General Public License
19    along with this library; see the file COPYING.LIB.  If not, write to
20    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.
22*/
23
24#include <config.h>
25#include <string.h>
26#include <stdio.h>
27#include <gtk/gtksignal.h>
28#include "gtkhtml.h"
29#include "gtkhtml-embedded.h"
30#include "htmlembedded.h"
31#include "htmlframe.h"
32#include "htmliframe.h"
33#include "htmlpainter.h"
34#include "htmlengine.h"
35
36HTMLEmbeddedClass html_embedded_class;
37static HTMLObjectClass *parent_class = NULL;
38
[21115]39#define d(x)
40
[19538]41static void
42copy (HTMLObject *self,
43      HTMLObject *dest)
44{
45        (* HTML_OBJECT_CLASS (parent_class)->copy) (self, dest);
46
47        /* FIXME g_warning ("HTMLEmbedded::copy is not complete."); */
48
49        HTML_EMBEDDED (dest)->name = g_strdup (HTML_EMBEDDED (self)->name);
50        HTML_EMBEDDED (dest)->value = g_strdup (HTML_EMBEDDED (self)->value);
51        HTML_EMBEDDED (dest)->form = HTML_EMBEDDED (self)->form;
52
53        HTML_EMBEDDED (dest)->widget = NULL;
54        HTML_EMBEDDED (dest)->parent = NULL;
55
56        HTML_EMBEDDED (dest)->abs_x = HTML_EMBEDDED (self)->abs_x;
57        HTML_EMBEDDED (dest)->abs_y = HTML_EMBEDDED (self)->abs_y;
58}
59
60static void
61draw (HTMLObject *o,
62      HTMLPainter *p,
63      gint x, gint y,
64      gint width, gint height,
65      gint tx, gint ty)
66{
67        HTMLEmbedded *element = HTML_EMBEDDED(o);
68        gint new_x, new_y;
69
[21115]70        d (printf ("draw embedded %p\n", element));
[19538]71        if (!element->widget)
72                return;
73
74        if (element->parent) {
75                new_x = o->x + tx;
76                new_y = o->y + ty - o->ascent;
77               
78                if (element->widget->parent) {
[21115]79                        if (new_x != element->abs_x || new_y != element->abs_y) {
80                                d (printf ("element: %p moveto: %d,%d shown: %d\n", element, new_x, new_y, GTK_WIDGET_VISIBLE (element->widget)));
[19538]81                                gtk_layout_move (GTK_LAYOUT(element->parent), element->widget, new_x, new_y);
[21115]82                        } else if (!GTK_HTML (element->parent)->engine->expose)
[19538]83                                gtk_widget_queue_draw (element->widget);
84                }
85       
86                element->abs_x = new_x;
87                element->abs_y = new_y;
88               
[21115]89                if (!element->widget->parent) {
90                        d (printf ("element: %p put: %d,%d shown: %d\n", element, new_x, new_y, GTK_WIDGET_VISIBLE (element->widget)));
[19538]91                        gtk_layout_put (GTK_LAYOUT(element->parent), element->widget, new_x, new_y);
[21115]92                }
[19538]93        }
94
[21115]95        d (printf ("draw embedded %p - call painter\n", element));
[19538]96        html_painter_draw_embedded (p, element, tx, ty);
97}
98
99static void
100destroy (HTMLObject *o)
101{
102        HTMLEmbedded *element;
103
[21115]104        d (printf ("destroy embedded %p\n", o));
[19538]105        element = HTML_EMBEDDED (o);
106
107        if(element->name)
108                g_free(element->name);
109        if(element->value)
110                g_free(element->value);
111        if(element->widget) {
112                gtk_widget_hide (element->widget);
113                g_signal_handlers_disconnect_matched (element->widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, element);
114                if (element->changed_id > 0)
115                        g_signal_handler_disconnect (element->widget, element->changed_id);
116                g_object_set_data (G_OBJECT (element->widget), "embeddedelement", NULL);
117                if (element->widget->parent && element->parent) {
118                        g_assert (element->widget->parent == element->parent);
119                        gtk_container_remove (GTK_CONTAINER (element->parent), element->widget);
120                } else {
121                        gtk_object_sink (GTK_OBJECT (element->widget));
122                }
123        }
124
125        HTML_OBJECT_CLASS (parent_class)->destroy (o);
126}
127
128static void
129reset (HTMLEmbedded *e)
130{
131        /* Nothing to do?  */
132}
133
134static gint
135calc_min_width (HTMLObject *self,
136                HTMLPainter *painter)
137{
138        GtkRequisition requisition;
139        GtkWidget *widget;
140        gint pixel_size;
141        gint min_width;
142
143        widget = HTML_EMBEDDED (self)->widget;
144
[21115]145        if (widget == NULL || !GTK_WIDGET_VISIBLE (widget))
[19538]146                return 0;
147     
[21115]148        requisition.width = requisition.height = 0;
[19538]149        gtk_widget_size_request (widget, &requisition);
150        pixel_size = html_painter_get_pixel_size (painter);
151
152        min_width = requisition.width * pixel_size;
153
154        return min_width;
155}
156
157static gboolean
[21115]158html_embedded_real_calc_size (HTMLObject *self, HTMLPainter *painter, GList **changed_objs)
[19538]159{
160        GtkWidget *widget;
161        HTMLEmbedded *emb = HTML_EMBEDDED (self);
162        gint pixel_size;
163        gint old_width, old_ascent, old_descent;
164        GtkRequisition requisition;
165
166        widget = emb->widget;
167        if (widget == NULL)
168                return FALSE;
169
170        pixel_size = html_painter_get_pixel_size (painter);
171
172        old_width = self->width;
173        old_ascent = self->ascent;
174        old_descent = self->descent;
175
[21115]176        requisition.width = requisition.height = 0;
[19538]177        gtk_widget_size_request (widget, &requisition);
178       
179        if (GTK_IS_HTML_EMBEDDED(widget))
180                self->descent = GTK_HTML_EMBEDDED (widget)->descent * pixel_size;
181        else
182                self->descent = 0;
183
184        self->width  = requisition.width  * pixel_size;
185        self->ascent = requisition.height * pixel_size - self->descent;
186
187        if (old_width != self->width || old_ascent != self->ascent || old_ascent != self->descent)
188                return TRUE;
189
190        return FALSE;
191}
192
193static gboolean
194accepts_cursor (HTMLObject *o)
195{
196        return TRUE;
197}
198
199static gchar *
200encode (HTMLEmbedded *e)
201{
202        return g_strdup ("");
203}
204
205void
206html_embedded_reset (HTMLEmbedded *e)
207{
208        HTML_EMBEDDED_CLASS (HTML_OBJECT (e)->klass)->reset (e);
209}
210
211gchar *
212html_embedded_encode (HTMLEmbedded *e)
213{
214        return HTML_EMBEDDED_CLASS (HTML_OBJECT (e)->klass)->encode (e);
215}
216
217void
218html_embedded_reparent (HTMLEmbedded *e, GtkWidget *new_parent)
219{
220        HTML_EMBEDDED_CLASS (HTML_OBJECT (e)->klass)->reparent (e, new_parent);
221}
222
223void
224html_embedded_set_form (HTMLEmbedded *e, HTMLForm *form)
225{
226        e->form = form;
227}
228
229gchar *
230html_embedded_encode_string (const gchar *str)
231{
232        static gchar *safe = "$-._!*(),"; /* RFC 1738 */
233        unsigned pos = 0;
234        GString *encoded = g_string_new ("");
235        gchar buffer[5], *ptr;
236        guchar c;
237       
238        while ( pos < strlen(str) ) {
239
240                c = (unsigned char) str[pos];
241                       
242                if ( (( c >= 'A') && ( c <= 'Z')) ||
243                     (( c >= 'a') && ( c <= 'z')) ||
244                     (( c >= '0') && ( c <= '9')) ||
245                     (strchr(safe, c))
246                     )
247                        {
248                                encoded = g_string_append_c (encoded, c);
249                        }
250                else if ( c == ' ' )
251                        {
252                                encoded = g_string_append_c (encoded, '+');
253                        }
254                else if ( c == '\n' )
255                        {
256                                encoded = g_string_append (encoded, "%0D%0A");
257                        }
258                else if ( c != '\r' )
259                        {
260                                sprintf( buffer, "%%%02X", (int)c );
261                                encoded = g_string_append (encoded, buffer);
262                                }
263                pos++;
264        }
265       
266        ptr = encoded->str;
267
268        g_string_free (encoded, FALSE);
269
270        return ptr;
271}
272
273void
274html_embedded_type_init (void)
275{
276        html_embedded_class_init (&html_embedded_class, HTML_TYPE_EMBEDDED, sizeof (HTMLEmbedded));
277}
278
279void
280html_embedded_class_init (HTMLEmbeddedClass *klass,
281                          HTMLType type,
282                          guint size)
283{
284        HTMLObjectClass *object_class;
285
286        g_return_if_fail (klass != NULL);
287
288        object_class = HTML_OBJECT_CLASS (klass);
289        html_object_class_init (object_class, type, size);
290
291        /* HTMLEmbedded methods.   */
292        klass->reset = reset;
293        klass->encode = encode;
294
295        /* HTMLObject methods.   */
296        object_class->destroy = destroy;
297        object_class->copy = copy;
298        object_class->draw = draw;
299        object_class->accepts_cursor = accepts_cursor;
[21115]300        object_class->calc_size = html_embedded_real_calc_size;
[19538]301        object_class->calc_min_width = calc_min_width;
302
303        parent_class = &html_object_class;
304}
305
306void
307html_embedded_init (HTMLEmbedded *element,
308                   HTMLEmbeddedClass *klass,
309                   GtkWidget *parent,
310                   gchar *name,
311                   gchar *value)
312{
313        HTMLObject *object;
314
[21115]315        d (printf ("embedded %p init\n", element));
316
[19538]317        object = HTML_OBJECT (element);
318        html_object_init (object, HTML_OBJECT_CLASS (klass));
319
320        element->form = NULL;
321        if (name)
322                element->name = g_strdup(name);
323        else
324                element->name = g_strdup("");
325        if (value)
326                element->value = g_strdup(value);
327        else
328                element->value = g_strdup("");
329        element->widget = NULL;
330        element->parent = parent;
331        element->width  = 0;
332        element->height = 0;
333        element->abs_x  = element->abs_y = -1;
334        element->changed_id = 0;
335}
336
337
338static gboolean
339html_embedded_grab_cursor(GtkWidget *eb, GdkEvent *event)
340{
341        /* Keep the focus! Fight the power */
342        return TRUE;
343}
344
345/* called when some state in an embedded html object has changed ... do a redraw */
346static void
347html_embedded_object_changed (GtkHTMLEmbedded *eb, HTMLEngine *e)
348{
349        HTMLObject *object;
350
351        object = HTML_OBJECT (g_object_get_data (G_OBJECT (eb), "embeddedelement"));
352        if (object)
353                html_object_calc_size (object, e->painter, FALSE);
354       
355        html_engine_schedule_update(e);
356}
357
358HTMLEmbedded *
359html_embedded_new_widget (GtkWidget *parent, GtkHTMLEmbedded *eb, HTMLEngine *engine)
360{
361        HTMLEmbedded *em;
362
363        em = g_new0(HTMLEmbedded, 1);
[21115]364        d (printf ("embedded %p new widget\n", em));
365
[19538]366        html_embedded_init (em, HTML_EMBEDDED_CLASS (&html_embedded_class), parent, eb->name, "");
367        html_embedded_set_widget (em, GTK_WIDGET (eb));
368
369        /* pass em as the user_data so that the handler will disconnect
370         * when the object is destoyed
371         */
372        g_signal_connect(eb, "button_press_event", G_CALLBACK (html_embedded_grab_cursor), em);
373        em->changed_id = g_signal_connect (eb, "changed", G_CALLBACK (html_embedded_object_changed), engine);
374        /* printf ("id %u\n", em->changed_id); */
375
376        return em;
377}
378
379static void
380html_embedded_allocate (GtkWidget *w, GtkAllocation  *allocation, HTMLEmbedded *e)
381{
382        if (e->width != allocation->width || e->height != allocation->height) {
383                if (e->width != allocation->width) {
384                        html_object_change_set (HTML_OBJECT (e), HTML_CHANGE_ALL_CALC);
385                        e->width = allocation->width;
386                }
387                e->height = allocation->height;
388               
[21115]389                if (GTK_IS_HTML (w->parent))
390                        html_engine_schedule_update (GTK_HTML (w->parent)->engine);
[19538]391        }
392}
393
394void
395html_embedded_set_widget (HTMLEmbedded *emb, GtkWidget *w)
396{
397        emb->widget = w;
398       
[21115]399        d (printf ("set embedded widget: %p widget: %p\n", emb, w));
[19538]400        gtk_widget_show (w);
401
402        g_object_set_data (G_OBJECT (w), "embeddedelement", emb);
403        g_signal_connect (w, "size_allocate", G_CALLBACK (html_embedded_allocate), emb);
404}
405
406GtkWidget *
407html_embedded_get_widget (HTMLEmbedded *e)
408{
409        return e->widget;
410}
411
412gboolean
413html_object_is_embedded (HTMLObject *o)
414{
415        gboolean rv = FALSE;
416
417        switch (o->klass->type) {
418        case HTML_TYPE_EMBEDDED:
419        case HTML_TYPE_TEXTINPUT:
420        case HTML_TYPE_BUTTON:
421        case HTML_TYPE_IMAGEINPUT:
422        case HTML_TYPE_TEXTAREA:
423        case HTML_TYPE_HIDDEN:
424        case HTML_TYPE_RADIO:
425        case HTML_TYPE_CHECKBOX:
426        case HTML_TYPE_SELECT:
427        case HTML_TYPE_IFRAME:
428        case HTML_TYPE_FRAME:
429                rv = TRUE;
430        default:
431                ;
432        }
433
434        return rv;
435}
436
437gboolean
438html_object_is_frame (HTMLObject *o)
439{
440        return HTML_IS_FRAME (o) || HTML_IS_IFRAME (o);
441}
Note: See TracBrowser for help on using the repository browser.