1
/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
3
*This file is part of MlView.
5
*MlView is free software; you can redistribute
6
*it and/or modify it under the terms of
7
*the GNU General Public License as published by the
8
*Free Software Foundation; either version 2,
9
*or (at your option) any later version.
11
*GNU MlView is distributed in the hope that it will
12
*be useful, but WITHOUT ANY WARRANTY;
13
*without even the implied warranty of
14
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
*See the GNU General Public License for more details.
17
*You should have received a copy of the
18
*GNU General Public License along with MlView;
19
*see the file COPYING.
20
*If not, write to the Free Software Foundation,
21
*Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
*See COPYRIGHTS file for copyright information.
28
#include <glade/glade.h>
29
#include "mlview-styled-view.h"
30
#include "mlview-tree-editor2.h"
33
*Implementation of the #MlViewStyledView class.
35
#ifdef MLVIEW_WITH_STYLE
37
#define PRIVATE(obj) ((obj)->priv)
39
struct _MlViewStyledViewPriv {
40
GtkPaned *main_paned ;
41
MlViewTreeEditor2 *tree_editor ;
42
SXBoxView * styled_editor ;
43
gboolean dispose_has_run ;
44
gboolean connected_to_doc ;
45
MlViewXMLDocument *xml_doc ;
46
MlViewAppContext *app_context ;
47
GtkDialog * css_picker_dialog ;
48
GtkEntry *css_picker_author_css_path ;
49
GtkEntry *css_picker_user_css_path ;
50
GtkEntry *css_picker_ua_css_path ;
51
GtkWidget *sewfox_contextual_menu ;
52
GtkWidget *tree_editor_contextual_menu ;
57
/*this must be the last member of this enum*/
61
static MlViewViewAdapterClass *gv_parent_class = NULL ;
62
static guint gv_signals[NUMBER_OF_SIGNALS] = {0} ;
64
static GtkWidget * get_sewfox_contextual_menu (MlViewStyledView *a_this) ;
66
static GtkWidget * get_tree_editor_contextual_menu (MlViewStyledView *a_this) ;
74
mlview_styled_view_dispose (GObject *a_this)
76
MlViewStyledView *thiz = NULL ;
78
g_return_if_fail (a_this
79
&& MLVIEW_IS_STYLED_VIEW (a_this)) ;
81
thiz = MLVIEW_STYLED_VIEW (a_this) ;
82
if (PRIVATE (thiz)->dispose_has_run)
86
&& PRIVATE (thiz)->connected_to_doc == TRUE
87
&& PRIVATE (thiz)->xml_doc) {
88
mlview_styled_view_disconnect_from_doc
90
PRIVATE (thiz)->xml_doc) ;
93
&& PRIVATE (thiz)->xml_doc) {
94
mlview_xml_document_unref (PRIVATE (thiz)->xml_doc) ;
95
PRIVATE (thiz)->xml_doc = NULL ;
97
PRIVATE (thiz)->dispose_has_run = TRUE ;
101
mlview_styled_view_finalize (GObject *a_this)
103
MlViewStyledView *thiz = NULL ;
105
g_return_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this)) ;
107
thiz = MLVIEW_STYLED_VIEW (a_this) ;
108
if (PRIVATE (thiz)) {
109
g_free (PRIVATE (thiz));
110
PRIVATE (thiz) = NULL ;
115
mlview_styled_view_class_init (MlViewStyledViewClass *a_class)
117
GObjectClass *gobject_class = NULL ;
119
g_return_if_fail (a_class != NULL);
121
gv_parent_class = g_type_class_peek_parent (a_class);
122
g_return_if_fail (gv_parent_class) ;
123
gobject_class = G_OBJECT_CLASS (a_class);
124
g_return_if_fail (gobject_class) ;
126
gobject_class->dispose = mlview_styled_view_dispose ;
127
gobject_class->finalize = mlview_styled_view_finalize ;
131
mlview_styled_view_init (MlViewStyledView *a_this)
133
MlViewIView *view_iface = NULL ;
134
g_return_if_fail (a_this
135
&& MLVIEW_IS_STYLED_VIEW (a_this)
136
&& MLVIEW_IS_IVIEW (a_this)) ;
138
if (PRIVATE (a_this) == NULL) {
139
PRIVATE (a_this) = g_try_malloc
140
(sizeof (MlViewStyledViewPriv)) ;
141
if (!PRIVATE (a_this)) {
142
mlview_utils_trace_info ("g_try_malloc failed") ;
145
memset (PRIVATE (a_this), 0,
146
sizeof (MlViewStyledViewPriv)) ;
148
view_iface = MLVIEW_IVIEW_GET_IFACE (a_this) ;
149
g_return_if_fail (view_iface) ;
150
view_iface->execute_action = mlview_styled_view_execute_action ;
151
view_iface->connect_to_doc = mlview_styled_view_connect_to_doc ;
152
view_iface->disconnect_from_doc = mlview_styled_view_disconnect_from_doc ;
156
browse_author_css_button_clicked_cb (GtkWidget *a_button,
157
gpointer a_user_data)
159
MlViewFileSelection *file_sel = NULL ;
160
MlViewStyledView *view = NULL;
164
g_return_if_fail (a_user_data && MLVIEW_IS_STYLED_VIEW (a_user_data)) ;
167
g_return_if_fail (PRIVATE (view) && PRIVATE (view)->app_context) ;
169
file_sel = mlview_app_context_get_file_selector
170
(PRIVATE (view)->app_context, "_(Choose a CSS stylesheet)") ;
171
g_return_if_fail (file_sel) ;
172
button = mlview_file_selection_run (file_sel, TRUE) ;
176
path = g_strdup (gtk_file_selection_get_filename
177
(GTK_FILE_SELECTION (file_sel))) ;
178
gtk_entry_set_text (PRIVATE (view)->css_picker_author_css_path,
193
browse_user_css_button_clicked_cb (GtkWidget *a_button,
194
gpointer a_user_data)
196
MlViewFileSelection *file_sel = NULL ;
197
MlViewStyledView *view = NULL;
201
g_return_if_fail (a_user_data && MLVIEW_IS_STYLED_VIEW (a_user_data)) ;
204
g_return_if_fail (PRIVATE (view) && PRIVATE (view)->app_context) ;
206
file_sel = mlview_app_context_get_file_selector
207
(PRIVATE (view)->app_context, "_(Choose a CSS stylesheet)") ;
208
g_return_if_fail (file_sel) ;
209
button = mlview_file_selection_run (file_sel, TRUE) ;
213
path = g_strdup (gtk_file_selection_get_filename
214
(GTK_FILE_SELECTION (file_sel))) ;
215
gtk_entry_set_text (PRIVATE (view)->css_picker_user_css_path,
230
browse_ua_css_button_clicked_cb (GtkWidget *a_button,
231
gpointer a_user_data)
233
MlViewFileSelection *file_sel = NULL ;
234
MlViewStyledView *view = NULL;
238
g_return_if_fail (a_user_data && MLVIEW_IS_STYLED_VIEW (a_user_data)) ;
241
g_return_if_fail (PRIVATE (view) && PRIVATE (view)->app_context) ;
243
file_sel = mlview_app_context_get_file_selector
244
(PRIVATE (view)->app_context, "_(Choose a CSS stylesheet)") ;
245
g_return_if_fail (file_sel) ;
246
button = mlview_file_selection_run (file_sel, TRUE) ;
250
path = g_strdup (gtk_file_selection_get_filename
251
(GTK_FILE_SELECTION (file_sel))) ;
252
gtk_entry_set_text (PRIVATE (view)->css_picker_ua_css_path,
267
button_press_event_cb (GtkWidget *a_box_view,
269
gpointer a_user_data)
271
MlViewAppContext *ctxt = NULL ;
272
MlViewStyledView *view = NULL ;
273
enum MlViewStatus status = MLVIEW_OK ;
275
g_return_val_if_fail (a_event && a_box_view && SX_IS_BOX_VIEW (a_box_view)
276
&& a_user_data && a_event
277
&& MLVIEW_IS_STYLED_VIEW (a_user_data),
280
view = MLVIEW_STYLED_VIEW (a_user_data) ;
281
ctxt = mlview_styled_view_get_app_context (view) ;
283
switch (a_event->type) {
284
case GDK_BUTTON_PRESS:
285
if (a_event->button.button == 3) {
287
*user pressed the right mouse button.
288
*Notify the application (at least the
289
*editing view that contains use) that
290
*a request for a contextual menu request
293
status = mlview_app_context_notify_contextual_menu_request
294
(ctxt, a_box_view, a_event) ;
295
g_return_val_if_fail (status == MLVIEW_OK, FALSE) ;
306
contextual_menu_request_cb (MlViewAppContext *a_this,
307
GtkWidget *a_request_source,
309
gpointer a_user_data)
311
MlViewStyledView *view = NULL ;
312
GtkWidget * contextual_menu = NULL ;
313
GdkEventButton *button_event = NULL ;
315
g_return_if_fail (a_this && MLVIEW_IS_APP_CONTEXT (a_this)
317
&& GTK_IS_WIDGET (a_request_source)
320
&& MLVIEW_IS_STYLED_VIEW (a_user_data)) ;
322
view = MLVIEW_STYLED_VIEW (a_user_data) ;
323
g_return_if_fail (view && PRIVATE (view)) ;
324
if (a_event->type == GDK_BUTTON_PRESS) {
325
button_event = (GdkEventButton*) a_event;
326
if (GTK_WIDGET (PRIVATE (view)->styled_editor)
327
== a_request_source) {
328
contextual_menu = get_sewfox_contextual_menu (view) ;
329
} else if (GTK_WIDGET (PRIVATE (view)->tree_editor)
330
== a_request_source) {
331
contextual_menu = get_tree_editor_contextual_menu
335
if (contextual_menu && GTK_IS_MENU (contextual_menu)) {
336
gtk_menu_popup (GTK_MENU (contextual_menu),
338
a_this, button_event->button,
339
button_event->time) ;
341
mlview_utils_trace_info ("Null menu returned") ;
347
load_a_cascade_menuitem_clicked_cb (GtkMenuItem *a_item,
348
gpointer a_user_data)
350
MlViewStyledView *view = NULL ;
352
g_return_if_fail (a_item && GTK_IS_MENU_ITEM (a_item)) ;
353
g_return_if_fail (a_user_data && MLVIEW_IS_STYLED_VIEW (a_user_data)) ;
355
view = MLVIEW_STYLED_VIEW (a_user_data) ;
356
mlview_styled_view_update_from_css_paths_interactive (view) ;
360
dump_box_model_menuitem_clicked_cb (GtkMenuItem *a_item,
361
gpointer a_user_data)
363
enum CRStatus status = CR_OK ;
364
SXBoxModel *box_model = NULL ;
365
MlViewStyledView *view = NULL ;
367
g_return_if_fail (a_item && GTK_IS_MENU_ITEM (a_item)) ;
368
g_return_if_fail (a_user_data && MLVIEW_IS_STYLED_VIEW (a_user_data)) ;
370
view = MLVIEW_STYLED_VIEW (a_user_data) ;
371
status = sx_box_view_get_box_model (PRIVATE (view)->styled_editor,
373
if (status == CR_OK && box_model) {
374
sx_box_dump_to_file ((SXBox*)box_model, 2, stdout) ;
376
mlview_utils_trace_info ("Could not get box model") ;
383
add_child_node_menuitem_activated_cb (GtkMenuItem *a_menu_item,
384
gpointer a_user_data)
386
MlViewAction action = {0} ;
387
MlViewStyledView *tree_view = a_user_data ;
389
g_return_if_fail (tree_view
390
&& MLVIEW_STYLED_VIEW (tree_view)) ;
392
action.name = (guchar*)"add-child-node-interactive" ;
393
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
400
insert_previous_node_menuitem_activated_cb (GtkMenuItem *a_menu_item,
401
gpointer a_user_data)
403
MlViewAction action = {0} ;
404
MlViewStyledView *tree_view = a_user_data ;
406
g_return_if_fail (tree_view
407
&& MLVIEW_STYLED_VIEW (tree_view)) ;
409
action.name = (guchar*)"insert-prev-sibling-node-interactive" ;
410
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
415
insert_next_node_menuitem_activated_cb (GtkMenuItem *a_menu_item,
416
gpointer a_user_data)
418
MlViewAction action = {0} ;
419
MlViewStyledView *tree_view = a_user_data ;
421
g_return_if_fail (tree_view
422
&& MLVIEW_STYLED_VIEW (tree_view)) ;
424
action.name = (guchar*) "insert-next-sibling-node-interactive" ;
425
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
430
copy_node_menuitem_activated_cb (GtkMenuItem *a_menu_item,
431
gpointer a_user_data)
433
MlViewAction action = {0} ;
434
MlViewStyledView *tree_view = a_user_data ;
436
g_return_if_fail (tree_view
437
&& MLVIEW_STYLED_VIEW (tree_view)) ;
439
action.name = (guchar*) "copy-node" ;
440
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
446
cut_node_menuitem_activated_cb (GtkMenuItem *a_menu_item,
447
gpointer a_user_data)
449
MlViewAction action = {0} ;
450
MlViewStyledView *tree_view = a_user_data ;
452
g_return_if_fail (tree_view
453
&& MLVIEW_STYLED_VIEW (tree_view)) ;
455
action.name = (guchar*) "cut-node" ;
456
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
461
paste_node_as_child_menuitem_activated_cb (GtkMenuItem *a_menu_item,
462
gpointer a_user_data)
464
MlViewAction action = {0} ;
465
MlViewStyledView *tree_view = a_user_data ;
467
g_return_if_fail (tree_view
468
&& MLVIEW_STYLED_VIEW (tree_view)) ;
470
action.name = (guchar*) "paste-node-as-child" ;
471
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
476
paste_node_as_prev_menuitem_activated_cb (GtkMenuItem *a_menu_item,
477
gpointer a_user_data)
479
MlViewAction action = {0} ;
480
MlViewStyledView *tree_view = a_user_data ;
482
g_return_if_fail (tree_view
483
&& MLVIEW_STYLED_VIEW (tree_view)) ;
485
action.name = (guchar*) "paste-node-as-prev-sibling" ;
486
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
491
paste_node_as_next_menuitem_activated_cb (GtkMenuItem *a_menu_item,
492
gpointer a_user_data)
494
MlViewAction action = {0} ;
495
MlViewStyledView *tree_view = a_user_data ;
497
g_return_if_fail (tree_view
498
&& MLVIEW_STYLED_VIEW (tree_view)) ;
500
action.name = (guchar*) "paste-node-as-next-sibling" ;
501
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
506
search_an_xml_node_menuitem_activated_cb (GtkMenuItem *a_menu_item,
507
gpointer a_user_data)
509
MlViewAction action = {0} ;
510
MlViewStyledView *tree_view = a_user_data ;
512
g_return_if_fail (tree_view
513
&& MLVIEW_STYLED_VIEW (tree_view)) ;
515
action.name = (guchar*) "find-node-that-contains-str-interactive" ;
516
mlview_styled_view_execute_action (MLVIEW_IVIEW(tree_view),
521
expand_current_node_menuitem_activated_cb (GtkMenuItem *a_item,
522
gpointer a_user_data)
524
MlViewAction action = {0} ;
525
MlViewStyledView *tree_view = a_user_data ;
527
g_return_if_fail (tree_view
528
&& MLVIEW_STYLED_VIEW (tree_view)) ;
530
action.name = (guchar*) "expand-tree-to-depth-interactive" ;
531
mlview_styled_view_execute_action (MLVIEW_IVIEW (tree_view),
536
get_css_paths_picker_dialog (MlViewStyledView *a_this)
538
guchar *path = NULL ;
539
GladeXML *glade_xml = NULL ;
541
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this)
545
if (!PRIVATE (a_this)->css_picker_dialog)
547
path = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_DATADIR,
548
"mlview/mlview-css-picker.glade",
551
mlview_utils_trace_info
552
("could not find mlview-css-picker.glade file") ;
555
glade_xml = glade_xml_new (path, "CSSPicker", NULL) ;
557
mlview_utils_trace_info ("could not find mlview-css-picker.glade file") ;
560
PRIVATE (a_this)->css_picker_dialog = GTK_DIALOG
561
(glade_xml_get_widget (glade_xml, "CSSPicker")) ;
562
if (!PRIVATE (a_this)->css_picker_dialog
563
|| !GTK_IS_DIALOG (PRIVATE (a_this)->css_picker_dialog)) {
564
mlview_utils_trace_info ("glade_xml_get_widget() made an unexpected result") ;
566
PRIVATE (a_this)->css_picker_author_css_path =
567
GTK_ENTRY (glade_xml_get_widget (glade_xml,
568
"AuthorCSSPathEntry")) ;
569
g_return_val_if_fail (PRIVATE (a_this)->css_picker_author_css_path,
571
PRIVATE (a_this)->css_picker_user_css_path =
572
GTK_ENTRY (glade_xml_get_widget (glade_xml,
573
"UserCSSPathEntry")) ;
574
g_return_val_if_fail (PRIVATE (a_this)->css_picker_author_css_path,
576
PRIVATE (a_this)->css_picker_ua_css_path =
577
GTK_ENTRY (glade_xml_get_widget (glade_xml,
579
g_return_val_if_fail (PRIVATE (a_this)->css_picker_author_css_path,
581
glade_xml_signal_connect_data (glade_xml, "browse_author_css_button_clicked",
582
G_CALLBACK (browse_author_css_button_clicked_cb),
584
glade_xml_signal_connect_data (glade_xml, "browse_user_css_button_clicked",
585
G_CALLBACK (browse_user_css_button_clicked_cb),
587
glade_xml_signal_connect_data (glade_xml, "browse_ua_css_button_clicked",
588
G_CALLBACK (browse_ua_css_button_clicked_cb),
590
g_object_unref (glade_xml) ;
593
return GTK_WIDGET (PRIVATE (a_this)->css_picker_dialog) ;
601
g_object_unref (glade_xml) ;
608
get_tree_editor_contextual_menu (MlViewStyledView *a_this)
610
GtkWidget *menuitem = NULL, *menu = NULL ;
612
g_return_val_if_fail (a_this
613
&& MLVIEW_IS_STYLED_VIEW (a_this),
616
if (!PRIVATE (a_this)->tree_editor_contextual_menu) {
617
menu = gtk_menu_new () ;
618
menuitem = gtk_menu_item_new_with_label
619
(_("Add child node")) ;
620
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
622
gtk_widget_show (menuitem) ;
623
g_signal_connect (G_OBJECT (menuitem),
626
(add_child_node_menuitem_activated_cb),
628
menuitem = gtk_menu_item_new_with_label
629
(_("Insert next node")) ;
630
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
632
gtk_widget_show (menuitem) ;
633
g_signal_connect (G_OBJECT (menuitem),
636
(insert_next_node_menuitem_activated_cb),
639
menuitem = gtk_menu_item_new_with_label
640
(_("Insert previous node")) ;
641
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
643
gtk_widget_show (menuitem) ;
644
g_signal_connect (G_OBJECT (menuitem),
647
(insert_previous_node_menuitem_activated_cb),
650
menuitem = gtk_separator_menu_item_new () ;
651
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
653
gtk_widget_show (GTK_WIDGET (menuitem)) ;
655
menuitem = gtk_menu_item_new_with_label
657
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
659
gtk_widget_show (GTK_WIDGET (menuitem)) ;
660
g_signal_connect (G_OBJECT (menuitem),
663
(copy_node_menuitem_activated_cb),
666
menuitem = gtk_menu_item_new_with_label
668
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
670
gtk_widget_show (menuitem) ;
671
g_signal_connect (G_OBJECT (menuitem),
673
G_CALLBACK (cut_node_menuitem_activated_cb),
676
menuitem = gtk_separator_menu_item_new () ;
677
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
679
gtk_widget_show (menuitem) ;
681
menuitem = gtk_menu_item_new_with_label
682
(_("Paste node as child")) ;
683
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
685
g_signal_connect (G_OBJECT (menuitem),
688
(paste_node_as_child_menuitem_activated_cb),
690
gtk_widget_show (menuitem) ;
692
menuitem = gtk_menu_item_new_with_label
693
(_("Paste node as prev")) ;
694
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
696
g_signal_connect (G_OBJECT (menuitem),
699
(paste_node_as_prev_menuitem_activated_cb),
701
gtk_widget_show (menuitem) ;
703
menuitem = gtk_menu_item_new_with_label
704
(_("Paste node as next")) ;
705
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
707
g_signal_connect (G_OBJECT (menuitem),
710
(paste_node_as_next_menuitem_activated_cb),
712
gtk_widget_show (menuitem) ;
714
menuitem = gtk_separator_menu_item_new () ;
715
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
717
gtk_widget_show (menuitem) ;
719
menuitem = gtk_menu_item_new_with_label
720
(_("Expand current node")) ;
721
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
723
g_signal_connect (G_OBJECT (menuitem),
726
(expand_current_node_menuitem_activated_cb),
728
gtk_widget_show (menuitem) ;
730
menuitem = gtk_menu_item_new_with_label
731
(_("Find an xml node")) ;
732
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
734
g_signal_connect (G_OBJECT (menuitem),
737
(search_an_xml_node_menuitem_activated_cb),
739
gtk_widget_show (menuitem) ;
740
PRIVATE (a_this)->tree_editor_contextual_menu = menu ;
742
return PRIVATE (a_this)->tree_editor_contextual_menu ;
746
*Builds the contextual menu that should be popup'ed
747
*when the user right clicks on the sewfox widget embedded
748
*in the styled editing view
749
*@param a_this the current instance of #MlViewStyledView
750
*@return the contextual menu or NULL if a problem arises
753
get_sewfox_contextual_menu (MlViewStyledView *a_this)
755
GtkWidget *menuitem = NULL ;
757
g_return_val_if_fail (a_this
758
&& MLVIEW_IS_STYLED_VIEW (a_this),
761
if (!PRIVATE (a_this)->sewfox_contextual_menu) {
762
PRIVATE (a_this)->sewfox_contextual_menu = gtk_menu_new () ;
763
menuitem = gtk_menu_item_new_with_label (_("Load a Cascade")) ;
764
gtk_widget_show (menuitem) ;
765
gtk_menu_shell_append (GTK_MENU_SHELL (PRIVATE (a_this)->sewfox_contextual_menu),
767
g_signal_connect (G_OBJECT (menuitem),
769
G_CALLBACK (load_a_cascade_menuitem_clicked_cb),
771
#ifdef MLVIEW_VERBOSE
772
menuitem = gtk_menu_item_new () ;
773
gtk_widget_show (menuitem) ;
774
gtk_menu_shell_append (GTK_MENU_SHELL (PRIVATE (a_this)->sewfox_contextual_menu),
776
menuitem = gtk_menu_item_new_with_label (_("Dump box model")) ;
777
gtk_menu_shell_append (GTK_MENU_SHELL (PRIVATE (a_this)->sewfox_contextual_menu),
779
gtk_widget_show (menuitem) ;
780
g_signal_connect (G_OBJECT (menuitem),
782
G_CALLBACK (dump_box_model_menuitem_clicked_cb),
786
return PRIVATE (a_this)->sewfox_contextual_menu ;
795
*1/code the methods to edit the document using the left hand
796
*widget, wire them in mlview_styled_view_execute_action().
797
*2/go code some facilities to dump the style structures for easier debuging.
801
*Standard gobject based type getter of the
802
*#MlViewStyledView class.
803
*@return the type identifier of the #MlViewStyledView class.
806
mlview_styled_view_get_type (void)
808
static guint type = 0;
811
static const GTypeInfo type_info = {
812
sizeof (MlViewStyledViewClass),
814
NULL, /*base_finalize*/
816
mlview_styled_view_class_init,
817
NULL, /*class_finalize*/
819
sizeof (MlViewStyledView),
822
mlview_styled_view_init
824
type = g_type_register_static
825
(MLVIEW_TYPE_VIEW_ADAPTER,
826
"MlViewStyledView", &type_info, 0);
832
*Constructor of the #MlViewStyledView class
833
*@param a_doc the xml document to "edit"
834
*@param a_name an arbitrary name for the document (or view)
835
*@param a_app_context the application context. (should not be NULL)
836
*@return the newly created instance of #MlViewStyledView or NULL in case
840
mlview_styled_view_new (MlViewXMLDocument *a_doc,
842
MlViewAppContext *a_app_context)
844
MlViewStyledView *view = NULL ;
846
g_return_val_if_fail (a_doc
847
&& MLVIEW_IS_XML_DOCUMENT (a_doc)
850
view = g_object_new (MLVIEW_TYPE_STYLED_VIEW, NULL) ;
851
mlview_styled_view_construct (view, a_doc, a_name, a_app_context) ;
852
mlview_iview_connect_to_doc (MLVIEW_IVIEW (view),
854
return GTK_WIDGET (view) ;
858
*Instance initializer of #MlViewStyleView; This should be called by
859
*the constructor of #MlViewStyledView
860
*@param a_doc the xml document we want to edit
861
*@param a_view_name an arbitrary name of the view
862
*@param a_app_context the application context to be associated to
864
*@return MLVIEW_OK upon successful completion, an erroro code otherwise.
867
mlview_styled_view_construct (MlViewStyledView *a_this,
868
MlViewXMLDocument *a_doc,
870
MlViewAppContext *a_app_context)
872
enum CRStatus cr_status = CR_OK ;
873
enum MlViewStatus status = MLVIEW_OK ;
874
CRStyleSheet *sheet = NULL ;
875
CRCascade * cascade = NULL ;
876
xmlDoc *xml_doc = NULL ;
878
if (PRIVATE (a_this)->main_paned
879
|| PRIVATE (a_this)->tree_editor
880
|| PRIVATE (a_this)->styled_editor) {
883
status = mlview_view_adapter_construct
884
(MLVIEW_VIEW_ADAPTER (a_this),
886
g_return_val_if_fail (status == MLVIEW_VIEW_ADAPTER_OK,
889
cr_status = sx_box_view_get_default_stylesheet (&sheet) ;
890
if (cr_status != CR_OK || ! sheet)
891
return MLVIEW_ERROR ;
892
cascade = cr_cascade_new (NULL, NULL, sheet) ;
894
mlview_utils_trace_info ("cr_cascade_new() failed") ;
895
status = MLVIEW_ERROR ;
898
xml_doc = mlview_xml_document_get_xml_document (a_doc) ;
900
mlview_utils_trace_info
901
("mlview_xml_document_get_xml_document () failed") ;
905
PRIVATE (a_this)->styled_editor = sx_box_view_new (cascade, xml_doc) ;
906
if (!PRIVATE (a_this)->styled_editor) {
907
mlview_utils_trace_info ("sx_box_new() failed") ;
911
PRIVATE (a_this)->tree_editor = MLVIEW_TREE_EDITOR2
912
(mlview_tree_editor2_new (a_app_context)) ;
913
mlview_tree_editor2_edit_xml_doc (PRIVATE (a_this)->tree_editor,
914
a_doc, (guchar*)"Experimental") ;
915
PRIVATE (a_this)->main_paned = GTK_PANED (gtk_hpaned_new ()) ;
916
gtk_box_pack_start (GTK_BOX (a_this),
917
GTK_WIDGET (PRIVATE (a_this)->main_paned),
919
gtk_paned_add1 (GTK_PANED (PRIVATE (a_this)->main_paned),
920
GTK_WIDGET (PRIVATE (a_this)->tree_editor)) ;
921
gtk_paned_add2 (GTK_PANED (PRIVATE (a_this)->main_paned),
922
GTK_WIDGET (PRIVATE (a_this)->styled_editor)) ;
923
PRIVATE (a_this)->xml_doc = a_doc ;
924
mlview_xml_document_ref (a_doc) ;
925
gtk_widget_show_all (GTK_WIDGET (PRIVATE (a_this)->main_paned)) ;
926
PRIVATE (a_this)->app_context = a_app_context ;
928
g_signal_connect (G_OBJECT (PRIVATE (a_this)->styled_editor),
929
"button-press-event",
930
G_CALLBACK (button_press_event_cb),
932
g_signal_connect (G_OBJECT (a_app_context),
933
"contextual-menu-requested",
934
G_CALLBACK (contextual_menu_request_cb),
943
cr_stylesheet_unref (sheet) ;
947
cr_cascade_unref (cascade) ;
951
xmlFreeDoc (xml_doc) ;
958
*Creates an internal subset node
959
*(<DOCTYPE elname PUBLIC "blah" "blabla">)
960
*@param a_this the current instance of #MlViewStyledView
961
*@return MLVIEW_OK upon successful completion,
962
*an error code otherwise.
965
mlview_styled_view_create_internal_subset_node_interactive (MlViewStyledView *a_this)
967
xmlDoc *native_doc = NULL ;
970
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this)
972
&& PRIVATE (a_this)->app_context,
973
MLVIEW_BAD_PARAM_ERROR) ;
975
if (!PRIVATE (a_this)->xml_doc)
976
return MLVIEW_NO_DOC_IN_VIEW_ERROR ;
977
native_doc = mlview_xml_document_get_xml_document
978
(PRIVATE (a_this)->xml_doc) ;
979
g_return_val_if_fail (native_doc, MLVIEW_ERROR) ;
980
if (native_doc->intSubset) {
981
mlview_app_context_error
982
(PRIVATE (a_this)->app_context,
983
_("The document already has an internal subset defined !")) ;
984
return MLVIEW_INT_SUBSET_ALREADY_PRESENT_ERROR ;
986
mlview_app_context_ask_internal_subset_node_name (&name) ;
988
return mlview_xml_document_create_internal_subset
989
(PRIVATE (a_this)->xml_doc, name,
990
(xmlChar*)"default-public-id",
991
(xmlChar*)"default-system-id",
998
*Interactively add a child node to the currently selected xml node.
999
*@param a_this the current instance of #MlViewStyledView
1000
*@return MLVIEW_OK upon succesful completion, an error code otherwise.
1003
mlview_styled_view_add_child_node_interactive (MlViewStyledView *a_this)
1005
MlViewTreeEditor2 *tree_editor = NULL ;
1007
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this)
1009
&& PRIVATE (a_this)->app_context,
1010
MLVIEW_BAD_PARAM_ERROR) ;
1012
tree_editor = mlview_styled_view_get_tree_editor (a_this) ;
1013
g_return_val_if_fail (tree_editor, MLVIEW_ERROR) ;
1014
mlview_tree_editor2_add_child_node_interactive (tree_editor) ;
1019
*Interactively adds a previous sibling node to the currently selected
1021
*@param a_this the current instance of #MlViewStyledView
1022
*@return MLVIEW_OK upon successful completion, an error code otherwise
1025
mlview_styled_view_insert_prev_sibling_node_interactive (MlViewStyledView *a_this)
1027
MlViewTreeEditor2 *tree_editor = NULL ;
1029
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this),
1030
MLVIEW_BAD_PARAM_ERROR) ;
1032
tree_editor = mlview_styled_view_get_tree_editor (a_this) ;
1033
g_return_val_if_fail (tree_editor, MLVIEW_ERROR) ;
1034
mlview_tree_editor2_insert_prev_sibling_node_interactive (tree_editor) ;
1039
*Interactively insert a next sibling node to the currently selected
1041
*@param a_this the current instance of #MlViewStyledView
1042
*@return MLVIEW_OK upon succesful completion, an error code otherwise.
1045
mlview_styled_view_insert_next_sibling_node_interactive (MlViewStyledView * a_this)
1047
MlViewTreeEditor2 *tree_editor = NULL;
1049
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this),
1050
MLVIEW_BAD_PARAM_ERROR) ;
1052
mlview_styled_view_get_tree_editor
1056
mlview_tree_editor2_insert_next_sibling_node_interactive
1063
*Cuts the currently selected xml node.
1064
*That is, unlink it from the tree and put it in
1065
*the xml node clipboard.
1066
*@param a_this the current instance of #MlViewStyledView
1069
mlview_styled_view_cut_node (MlViewStyledView *a_this)
1071
MlViewTreeEditor2 *tree_editor = NULL;
1072
GtkTreeIter cur_sel_start = {0};
1073
enum MlViewStatus status = MLVIEW_OK ;
1076
mlview_styled_view_get_tree_editor (a_this);
1078
if (tree_editor == NULL)
1080
status = mlview_tree_editor2_get_cur_sel_start_iter
1081
(tree_editor, &cur_sel_start);
1082
g_return_val_if_fail (status == MLVIEW_OK, status) ;
1083
mlview_tree_editor2_cut_node (tree_editor,
1090
*Copy the currently selected xml node into the local clipboard.
1091
*@param a_this the current instance of #MlViewStyledView
1092
*@return MLVIEW_OK upon succesful completion, an error code otherwise.
1095
mlview_styled_view_copy_node (MlViewStyledView *a_this)
1097
MlViewTreeEditor2 *tree_editor = NULL;
1098
GtkTreeIter cur_sel_start = {0} ;
1099
enum MlViewStatus status = MLVIEW_OK ;
1101
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this),
1102
MLVIEW_BAD_PARAM_ERROR);
1105
mlview_styled_view_get_tree_editor
1107
if (tree_editor == NULL)
1109
status = mlview_tree_editor2_get_cur_sel_start_iter
1110
(tree_editor, &cur_sel_start) ;
1111
g_return_val_if_fail (status == MLVIEW_OK, status) ;
1112
mlview_tree_editor2_copy_node (tree_editor,
1119
*Paste the last node found in the clipboard into the xml document
1121
*The pasted node is pasted as a child node of the currently selected
1123
*@param a_this the current instance of #MlViewStyledView
1124
*@return MLVIEW_OK upon succesful completion, an error code otherwise
1127
mlview_styled_view_paste_node_as_child (MlViewStyledView * a_this)
1129
GtkTreeIter cur_sel_start={0} ;
1130
enum MlViewStatus status = MLVIEW_OK;
1132
g_return_val_if_fail (a_this
1133
&& MLVIEW_IS_STYLED_VIEW (a_this)
1135
&& PRIVATE (a_this)->tree_editor,
1136
MLVIEW_BAD_PARAM_ERROR);
1138
status = mlview_tree_editor2_get_cur_sel_start_iter
1139
(PRIVATE (a_this)->tree_editor,
1141
g_return_val_if_fail (status == MLVIEW_OK,
1143
mlview_tree_editor2_paste_node_as_child
1144
(PRIVATE (a_this)->tree_editor,
1151
*Paste the last node found in the clipboard into the xml document
1153
*The pasted node is pasted as a previous sibling node of the
1154
*currently selected xml node.
1155
*@param a_this the current instance of #MlViewStyledView
1158
mlview_styled_view_paste_node_as_prev_sibling (MlViewStyledView * a_this)
1160
GtkTreeIter cur_sel_start={0} ;
1161
enum MlViewStatus status=MLVIEW_OK ;
1163
g_return_val_if_fail (a_this != NULL
1164
&& MLVIEW_IS_STYLED_VIEW (a_this)
1165
&& PRIVATE (a_this),
1166
MLVIEW_BAD_PARAM_ERROR) ;
1168
status = mlview_tree_editor2_get_cur_sel_start_iter
1169
(PRIVATE (a_this)->tree_editor,
1171
g_return_val_if_fail (status == MLVIEW_OK, status) ;
1172
status = mlview_tree_editor2_paste_node_as_sibling
1173
(PRIVATE (a_this)->tree_editor,
1174
&cur_sel_start, TRUE) ;
1179
*Pastes the last node found in the clipboard at
1180
*the place of the the currently selected xml node.
1181
*@param a_this a pointer to the current instance
1182
*of MlViewStyledView.
1185
mlview_styled_view_paste_node_as_next_sibling (MlViewStyledView * a_this)
1187
GtkTreeIter cur_sel_start={0} ;
1188
enum MlViewStatus status = MLVIEW_OK ;
1190
g_return_val_if_fail (a_this != NULL, MLVIEW_BAD_PARAM_ERROR);
1191
g_return_val_if_fail (PRIVATE (a_this) != NULL, MLVIEW_BAD_PARAM_ERROR);
1193
status = mlview_tree_editor2_get_cur_sel_start_iter
1194
(PRIVATE (a_this)->tree_editor,
1196
g_return_val_if_fail (status == MLVIEW_OK, status) ;
1197
mlview_tree_editor2_paste_node_as_sibling
1198
(PRIVATE (a_this)->tree_editor,
1199
&cur_sel_start, FALSE) ;
1204
mlview_styled_view_execute_action (MlViewIView *a_this,
1205
MlViewAction *a_action)
1207
MlViewStyledView *view = NULL ;
1209
g_return_val_if_fail (a_this && MLVIEW_IS_IVIEW (a_this),
1210
MLVIEW_BAD_PARAM_ERROR) ;
1212
view = MLVIEW_STYLED_VIEW (a_this) ;
1213
g_return_val_if_fail (PRIVATE (view), MLVIEW_BAD_PARAM_ERROR) ;
1215
if (!strcmp (a_action->name, "add-child-node-interactive")) {
1216
mlview_styled_view_add_child_node_interactive (view) ;
1217
} else if (!strcmp (a_action->name, "insert-prev-sibling-node-interactive")){
1218
mlview_styled_view_insert_prev_sibling_node_interactive (view) ;
1219
} else if (!strcmp (a_action->name, "insert-next-sibling-node-interactive")) {
1220
mlview_styled_view_insert_next_sibling_node_interactive (view) ;
1221
} else if (!strcmp (a_action->name, "cut-node")) {
1222
mlview_styled_view_cut_node (view) ;
1223
} else if (!strcmp (a_action->name, "copy-node")) {
1224
mlview_styled_view_copy_node (view) ;
1225
} else if (!strcmp (a_action->name, "paste-node-as-child")) {
1226
mlview_styled_view_paste_node_as_child (view) ;
1227
} else if (!strcmp (a_action->name, "paste-node-as-prev-sibling")) {
1228
mlview_styled_view_paste_node_as_prev_sibling (view) ;
1229
} else if (!strcmp (a_action->name, "paste-node-as-next-sibling")) {
1230
mlview_styled_view_paste_node_as_next_sibling (view) ;
1236
*Connects the view to the signals of the document object model.
1237
*This implements the MlViewIView::connect_to_doc() method.
1238
*@param a_this the current instance of #MlViewStyledView
1239
*@param a_doc the document object model to connect to.
1240
*@return MLVIEW_OK upon successful completion, an error code otherwise.
1243
mlview_styled_view_connect_to_doc (MlViewIView *a_this,
1244
MlViewXMLDocument *a_doc)
1246
MlViewStyledView *view = NULL ;
1248
g_return_val_if_fail (a_this
1249
&& MLVIEW_IS_IVIEW (a_this)
1250
&& MLVIEW_IS_STYLED_VIEW (a_this)
1252
&& MLVIEW_IS_XML_DOCUMENT (a_doc),
1253
MLVIEW_BAD_PARAM_ERROR) ;
1255
view = MLVIEW_STYLED_VIEW (a_this) ;
1256
g_return_val_if_fail (view
1258
&& PRIVATE (view)->tree_editor
1259
&& PRIVATE (view)->styled_editor,
1260
MLVIEW_BAD_PARAM_ERROR) ;
1262
if (PRIVATE (view)->connected_to_doc == TRUE)
1265
mlview_tree_editor2_connect_to_doc (PRIVATE (view)->tree_editor,
1268
*TODO: connect the styled editor to the document signals
1270
PRIVATE (view)->connected_to_doc = TRUE ;
1275
*Disonnects the view from the signals of the document object model.
1276
*This implements the MlViewIView::disconnect_from_view() method.
1277
*@param a_this the current instance of #MlViewStyledView
1278
*@param a_doc the document object model to connect to.
1279
*@return MLVIEW_OK upon successful completion, an error code otherwise.
1282
mlview_styled_view_disconnect_from_doc (MlViewIView *a_this,
1283
MlViewXMLDocument *a_doc)
1286
MlViewStyledView *view = NULL ;
1288
g_return_val_if_fail (a_this
1289
&& MLVIEW_IS_IVIEW (a_this)
1290
&& MLVIEW_IS_STYLED_VIEW (a_this)
1292
&& MLVIEW_IS_XML_DOCUMENT (a_doc),
1293
MLVIEW_BAD_PARAM_ERROR) ;
1296
view = MLVIEW_STYLED_VIEW (a_this) ;
1297
g_return_val_if_fail (view
1299
&& PRIVATE (view)->tree_editor
1300
&& PRIVATE (view)->styled_editor,
1301
MLVIEW_BAD_PARAM_ERROR) ;
1303
if (PRIVATE (view)->connected_to_doc == FALSE)
1306
mlview_tree_editor2_disconnect_from_doc (PRIVATE (view)->tree_editor,
1309
*TODO: disconnect the styled editor to the document signals
1316
mlview_styled_view_update_from_css_paths_interactive (MlViewStyledView *a_this)
1318
GtkDialog *dialog = NULL ;
1320
enum CRStatus status = CR_OK ;
1321
guchar *author_css=NULL, *user_css=NULL, *ua_css=NULL ;
1323
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this),
1324
MLVIEW_BAD_PARAM_ERROR) ;
1326
dialog = GTK_DIALOG (get_css_paths_picker_dialog (a_this)) ;
1327
g_return_val_if_fail (dialog, MLVIEW_ERROR) ;
1328
response = gtk_dialog_run (dialog) ;
1330
case GTK_RESPONSE_OK:
1331
author_css = g_strdup
1333
(PRIVATE (a_this)->css_picker_author_css_path)) ;
1336
(PRIVATE (a_this)->css_picker_user_css_path)) ;
1339
(PRIVATE (a_this)->css_picker_ua_css_path)) ;
1340
status = sx_box_view_update_box_model_attrs_from_css
1341
(PRIVATE (a_this)->styled_editor, author_css,
1342
user_css, ua_css, CR_ASCII) ;
1344
g_free (author_css) ;
1356
case GTK_RESPONSE_CANCEL:
1360
gtk_widget_hide (GTK_WIDGET (dialog)) ;
1365
mlview_styled_view_update_from_css_paths (MlViewStyledView *a_this,
1366
guchar *a_author_css_path,
1367
guchar *a_user_css_path,
1368
guchar *a_ua_css_path,
1369
enum CREncoding a_enc)
1371
enum CRStatus status = CR_OK ;
1373
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this)
1374
&& PRIVATE (a_this)->styled_editor,
1375
MLVIEW_BAD_PARAM_ERROR) ;
1377
status = sx_box_view_update_box_model_attrs_from_css
1378
(PRIVATE (a_this)->styled_editor,
1379
a_author_css_path, a_user_css_path,
1380
a_ua_css_path, CR_ASCII) ;
1382
g_return_val_if_fail (status == CR_OK, MLVIEW_ERROR) ;
1389
*Getter of the application context associated to the
1390
*current instance of #MlViewStyledView
1391
*@param a_this the current instance of #MlViewStyledView
1392
*@return the application context associated to the current
1393
*instance of #MlViewStyledView
1396
mlview_styled_view_get_app_context (MlViewStyledView *a_this)
1398
g_return_val_if_fail (a_this
1399
&& MLVIEW_IS_STYLED_VIEW (a_this)
1400
&& PRIVATE (a_this),
1403
return PRIVATE (a_this)->app_context ;
1407
*@param a_this the current instance of #MlViewStyledView
1408
*@param a_app_context the instance of #MlViewAppContext associated
1409
*to the current instance of #MlViewStyledView
1410
*@return MLVIEW_OK upon successful completion, an error code
1414
mlview_styled_view_set_app_context (MlViewStyledView *a_this,
1415
MlViewAppContext *a_app_context)
1417
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this)
1418
&& PRIVATE (a_this),
1419
MLVIEW_BAD_PARAM_ERROR) ;
1421
PRIVATE (a_this)->app_context = a_app_context ;
1427
mlview_styled_view_get_tree_editor (MlViewStyledView *a_this)
1429
g_return_val_if_fail (a_this && MLVIEW_IS_STYLED_VIEW (a_this),
1432
return PRIVATE (a_this)->tree_editor ;
1435
#endif /*MLVIEW_WITH_STYLE*/