~ubuntu-branches/debian/stretch/gnome-builder/stretch

« back to all changes in this revision

Viewing changes to src/html/gb-html-view.c

  • Committer: Package Import Robot
  • Author(s): Andreas Henriksson
  • Date: 2015-10-11 12:38:45 UTC
  • Revision ID: package-import@ubuntu.com-20151011123845-a0hvkz01se0p1p5a
Tags: upstream-3.16.3
ImportĀ upstreamĀ versionĀ 3.16.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gb-html-view.c
 
2
 *
 
3
 * Copyright (C) 2014 Christian Hergert <christian@hergert.me>
 
4
 *
 
5
 * This program is free software: you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation, either version 3 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
#define G_LOG_DOMAIN "gb-html-view"
 
20
 
 
21
#include <glib/gi18n.h>
 
22
#include <gtksourceview/gtksourcefile.h>
 
23
#include <ide.h>
 
24
#include <webkit2/webkit2.h>
 
25
 
 
26
#include "gb-editor-document.h"
 
27
#include "gb-html-document.h"
 
28
#include "gb-html-view.h"
 
29
#include "gb-widget.h"
 
30
 
 
31
struct _GbHtmlView
 
32
{
 
33
  GbView          parent_instance;
 
34
 
 
35
  /* Objects owned by view */
 
36
  GbHtmlDocument *document;
 
37
 
 
38
  /* References owned by Gtk template */
 
39
  WebKitWebView  *web_view1;
 
40
  WebKitWebView  *web_view2;
 
41
 
 
42
  GtkPaned       *paned;
 
43
};
 
44
 
 
45
G_DEFINE_TYPE (GbHtmlView, gb_html_view, GB_TYPE_VIEW)
 
46
 
 
47
enum {
 
48
  PROP_0,
 
49
  PROP_DOCUMENT,
 
50
  LAST_PROP
 
51
};
 
52
 
 
53
static GParamSpec *gParamSpecs [LAST_PROP];
 
54
 
 
55
static void
 
56
gb_html_view_changed (GbHtmlView    *self,
 
57
                      GtkTextBuffer *buffer)
 
58
{
 
59
  gchar *content;
 
60
  gchar *base_uri = NULL;
 
61
 
 
62
  IDE_ENTRY;
 
63
 
 
64
  g_return_if_fail (GB_IS_HTML_VIEW (self));
 
65
  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
 
66
 
 
67
  if (GB_IS_EDITOR_DOCUMENT (self->document))
 
68
    {
 
69
      IdeFile *file;
 
70
 
 
71
      file = ide_buffer_get_file (IDE_BUFFER (self->document));
 
72
 
 
73
      if (file)
 
74
        {
 
75
          GFile *location;
 
76
 
 
77
          location = ide_file_get_file (file);
 
78
 
 
79
          if (location)
 
80
            base_uri = g_file_get_uri (location);
 
81
        }
 
82
    }
 
83
 
 
84
  content = gb_html_document_get_content (self->document);
 
85
  webkit_web_view_load_html (self->web_view1, content, base_uri);
 
86
  if (self->web_view2 != NULL)
 
87
    webkit_web_view_load_html (self->web_view2, content, base_uri);
 
88
 
 
89
  g_free (content);
 
90
  g_free (base_uri);
 
91
 
 
92
  IDE_EXIT;
 
93
}
 
94
 
 
95
static void
 
96
gb_html_view_connect (GbHtmlView     *self,
 
97
                      GbHtmlDocument *document)
 
98
{
 
99
  GtkTextBuffer *buffer;
 
100
 
 
101
  g_return_if_fail (GB_IS_HTML_VIEW (self));
 
102
  g_return_if_fail (GB_IS_HTML_DOCUMENT (document));
 
103
 
 
104
  buffer = gb_html_document_get_buffer (document);
 
105
  if (!buffer)
 
106
    return;
 
107
 
 
108
  g_signal_connect_object (buffer,
 
109
                           "changed",
 
110
                           G_CALLBACK (gb_html_view_changed),
 
111
                           self,
 
112
                           G_CONNECT_SWAPPED);
 
113
 
 
114
  gb_html_view_changed (self, buffer);
 
115
}
 
116
 
 
117
static void
 
118
gb_html_view_disconnect (GbHtmlView     *self,
 
119
                         GbHtmlDocument *document)
 
120
{
 
121
  GtkTextBuffer *buffer;
 
122
 
 
123
  g_return_if_fail (GB_IS_HTML_VIEW (self));
 
124
  g_return_if_fail (GB_IS_HTML_DOCUMENT (document));
 
125
 
 
126
  buffer = gb_html_document_get_buffer (document);
 
127
  if (!buffer)
 
128
    return;
 
129
 
 
130
  g_signal_handlers_disconnect_by_func (buffer,
 
131
                                        G_CALLBACK (gb_html_view_changed),
 
132
                                        self);
 
133
}
 
134
 
 
135
static GbDocument *
 
136
gb_html_view_get_document (GbView *view)
 
137
{
 
138
  GbHtmlView *self = (GbHtmlView *)view;
 
139
 
 
140
  g_return_val_if_fail (GB_IS_HTML_VIEW (self), NULL);
 
141
 
 
142
  return GB_DOCUMENT (self->document);
 
143
}
 
144
 
 
145
static void
 
146
gb_html_view_set_document (GbHtmlView *self,
 
147
                           GbDocument *document)
 
148
{
 
149
  g_return_if_fail (GB_IS_HTML_VIEW (self));
 
150
  g_return_if_fail (GB_IS_DOCUMENT (document));
 
151
 
 
152
  if (!GB_IS_HTML_DOCUMENT (document))
 
153
    {
 
154
      g_warning ("GbHtmlView does not know how to handle a document "
 
155
                 "of type %s",
 
156
                 g_type_name (G_TYPE_FROM_INSTANCE (document)));
 
157
      return;
 
158
    }
 
159
 
 
160
  if (document != (GbDocument *)self->document)
 
161
    {
 
162
      if (self->document)
 
163
        {
 
164
          gb_html_view_disconnect (self, self->document);
 
165
          g_clear_object (&self->document);
 
166
        }
 
167
 
 
168
      if (document)
 
169
        {
 
170
          self->document = g_object_ref (document);
 
171
          gb_html_view_connect (self, self->document);
 
172
        }
 
173
 
 
174
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DOCUMENT]);
 
175
    }
 
176
}
 
177
 
 
178
static GbView *
 
179
gb_html_view_create_split (GbView *view)
 
180
{
 
181
  GbView *ret;
 
182
 
 
183
  g_assert (GB_IS_HTML_VIEW (view));
 
184
 
 
185
  ret = g_object_new (GB_TYPE_HTML_VIEW,
 
186
                      "document", gb_html_view_get_document (view),
 
187
                      "visible", TRUE,
 
188
                      NULL);
 
189
 
 
190
  return ret;
 
191
}
 
192
 
 
193
static void
 
194
gb_html_view_set_split_view (GbView   *view,
 
195
                             gboolean  split_view)
 
196
{
 
197
  GbHtmlView *self = (GbHtmlView *)view;
 
198
 
 
199
  g_assert (GB_IS_HTML_VIEW (self));
 
200
 
 
201
  g_return_if_fail (GB_IS_HTML_VIEW (view));
 
202
 
 
203
  if (split_view && (self->web_view2 != NULL))
 
204
    return;
 
205
 
 
206
  if (!split_view && (self->web_view2 == NULL))
 
207
    return;
 
208
 
 
209
  if (split_view)
 
210
    {
 
211
      GtkTextBuffer *buffer = gb_html_document_get_buffer (self->document);
 
212
      if (!buffer)
 
213
        return;
 
214
 
 
215
      self->web_view2 = g_object_new (WEBKIT_TYPE_WEB_VIEW,
 
216
                                      "visible", TRUE,
 
217
                                      NULL);
 
218
      gtk_container_add_with_properties (GTK_CONTAINER (self->paned), GTK_WIDGET (self->web_view2),
 
219
                                         "shrink", FALSE,
 
220
                                         "resize", TRUE,
 
221
                                         NULL);
 
222
      gtk_widget_grab_focus (GTK_WIDGET (self->web_view2));
 
223
      gb_html_view_changed (self, buffer);
 
224
    }
 
225
  else
 
226
    {
 
227
      GtkWidget *copy = GTK_WIDGET (self->web_view2);
 
228
 
 
229
      self->web_view2 = NULL;
 
230
      gtk_container_remove (GTK_CONTAINER (self->paned), copy);
 
231
      gtk_widget_grab_focus (GTK_WIDGET (self->web_view1));
 
232
    }
 
233
}
 
234
 
 
235
static void
 
236
gb_html_view_refresh (GSimpleAction *action,
 
237
                      GVariant      *parameters,
 
238
                      gpointer       user_data)
 
239
{
 
240
  GtkTextBuffer *buffer;
 
241
  GbHtmlView *self = user_data;
 
242
 
 
243
  g_return_if_fail (GB_IS_HTML_VIEW (self));
 
244
 
 
245
  if (!self->document)
 
246
    return;
 
247
 
 
248
  buffer = gb_html_document_get_buffer (self->document);
 
249
  if (!buffer)
 
250
    return;
 
251
 
 
252
  gb_html_view_changed (self, buffer);
 
253
}
 
254
 
 
255
static void
 
256
gb_html_view_finalize (GObject *object)
 
257
{
 
258
  GbHtmlView *self = (GbHtmlView *)object;
 
259
 
 
260
  g_clear_object (&self->document);
 
261
 
 
262
  G_OBJECT_CLASS (gb_html_view_parent_class)->finalize (object);
 
263
}
 
264
 
 
265
static void
 
266
gb_html_view_get_property (GObject    *object,
 
267
                           guint       prop_id,
 
268
                           GValue     *value,
 
269
                           GParamSpec *pspec)
 
270
{
 
271
  GbHtmlView *self = GB_HTML_VIEW (object);
 
272
 
 
273
  switch (prop_id)
 
274
    {
 
275
    case PROP_DOCUMENT:
 
276
      g_value_set_object (value,
 
277
                          gb_html_view_get_document (GB_VIEW (self)));
 
278
      break;
 
279
 
 
280
    default:
 
281
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
282
    }
 
283
}
 
284
 
 
285
static void
 
286
gb_html_view_set_property (GObject      *object,
 
287
                           guint         prop_id,
 
288
                           const GValue *value,
 
289
                           GParamSpec   *pspec)
 
290
{
 
291
  GbHtmlView *self = GB_HTML_VIEW (object);
 
292
 
 
293
  switch (prop_id)
 
294
    {
 
295
    case PROP_DOCUMENT:
 
296
      gb_html_view_set_document (self, g_value_get_object (value));
 
297
      break;
 
298
 
 
299
    default:
 
300
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
301
    }
 
302
}
 
303
 
 
304
static void
 
305
gb_html_view_class_init (GbHtmlViewClass *klass)
 
306
{
 
307
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
308
  GbViewClass *view_class = GB_VIEW_CLASS (klass);
 
309
 
 
310
  object_class->finalize = gb_html_view_finalize;
 
311
  object_class->get_property = gb_html_view_get_property;
 
312
  object_class->set_property = gb_html_view_set_property;
 
313
 
 
314
  view_class->get_document = gb_html_view_get_document;
 
315
  view_class->create_split = gb_html_view_create_split;
 
316
  view_class->set_split_view =  gb_html_view_set_split_view;
 
317
 
 
318
  gParamSpecs [PROP_DOCUMENT] =
 
319
    g_param_spec_object ("document",
 
320
                         _("Document"),
 
321
                         _("The document to view as HTML."),
 
322
                         GB_TYPE_DOCUMENT,
 
323
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
324
 
 
325
  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
 
326
 
 
327
  GB_WIDGET_CLASS_TEMPLATE (klass, "gb-html-view.ui");
 
328
  GB_WIDGET_CLASS_BIND (klass, GbHtmlView, web_view1);
 
329
  GB_WIDGET_CLASS_BIND (klass, GbHtmlView, paned);
 
330
 
 
331
  g_type_ensure (WEBKIT_TYPE_WEB_VIEW);
 
332
}
 
333
 
 
334
static void
 
335
gb_html_view_init (GbHtmlView *self)
 
336
{
 
337
  static const GActionEntry entries[] = {
 
338
    { "refresh", gb_html_view_refresh },
 
339
  };
 
340
  GSimpleActionGroup *actions;
 
341
  GtkWidget *controls;
 
342
 
 
343
  gtk_widget_init_template (GTK_WIDGET (self));
 
344
 
 
345
  controls = gb_view_get_controls (GB_VIEW (self));
 
346
 
 
347
  actions = g_simple_action_group_new ();
 
348
  g_action_map_add_action_entries (G_ACTION_MAP (actions), entries,
 
349
                                   G_N_ELEMENTS (entries), self);
 
350
  gtk_widget_insert_action_group (GTK_WIDGET (self), "html-view",
 
351
                                  G_ACTION_GROUP (actions));
 
352
  gtk_widget_insert_action_group (controls, "html-view",
 
353
                                  G_ACTION_GROUP (actions));
 
354
  g_object_unref (actions);
 
355
}