8 #include <libgnomecanvas/libgnomecanvas.h>
11 #include "xo-interface.h"
12 #include "xo-support.h"
13 #include "xo-callbacks.h"
17 #include "xo-shapes.h"
22 struct Journal journal
; // the journal
23 struct BgPdf bgpdf
; // the PDF loader stuff
24 struct UIData ui
; // the user interface data
25 struct UndoItem
*undo
, *redo
; // the undo and redo stacks
29 void init_stuff (int argc
, char *argv
[])
37 gboolean can_xinput
, success
;
38 gchar
*tmppath
, *tmpfn
;
40 // create some data structures needed to populate the preferences
41 ui
.default_page
.bg
= g_new(struct Background
, 1);
43 // initialize config file names
44 tmppath
= g_build_filename(g_get_home_dir(), CONFIG_DIR
, NULL
);
45 mkdir(tmppath
, 0700); // safer (MRU data may be confidential)
46 ui
.mrufile
= g_build_filename(tmppath
, MRU_FILE
, NULL
);
47 ui
.configfile
= g_build_filename(tmppath
, CONFIG_FILE
, NULL
);
50 // initialize preferences
51 init_config_default();
52 load_config_from_file();
53 ui
.font_name
= g_strdup(ui
.default_font_name
);
54 ui
.font_size
= ui
.default_font_size
;
55 ui
.hiliter_alpha_mask
= 0xffffff00 + (guint
)(255*ui
.hiliter_opacity
);
57 // we need an empty canvas prior to creating the journal structures
58 canvas
= GNOME_CANVAS (gnome_canvas_new_aa ());
61 ui
.default_page
.bg
->canvas_item
= NULL
;
62 ui
.layerbox_length
= 0;
64 if (argc
> 2 || (argc
== 2 && argv
[1][0] == '-')) {
65 printf(_("Invalid command line parameters.\n"
66 "Usage: %s [filename.xoj]\n"), argv
[0]);
70 undo
= NULL
; redo
= NULL
;
72 bgpdf
.status
= STATUS_NOT_INIT
;
76 ui
.cur_item_type
= ITEM_NONE
;
78 ui
.cur_path
.coords
= NULL
;
79 ui
.cur_path_storage_alloc
= 0;
80 ui
.cur_path
.ref_count
= 1;
82 ui
.cur_widths_storage_alloc
= 0;
87 ui
.cur_brush
= &(ui
.brushes
[0][ui
.toolno
[0]]);
88 for (j
=0; j
<=NUM_BUTTONS
; j
++)
89 for (i
=0; i
< NUM_STROKE_TOOLS
; i
++) {
90 b
= &(ui
.brushes
[j
][i
]);
93 b
->color_rgba
= predef_colors_rgba
[b
->color_no
];
94 if (i
== TOOL_HIGHLIGHTER
) {
95 b
->color_rgba
&= ui
.hiliter_alpha_mask
;
98 b
->thickness
= predef_thickness
[i
][b
->thickness_no
];
100 for (i
=0; i
<NUM_STROKE_TOOLS
; i
++)
101 g_memmove(ui
.default_brushes
+i
, &(ui
.brushes
[0][i
]), sizeof(struct Brush
));
104 ui
.which_unswitch_button
= 0;
108 // initialize various interface elements
110 gtk_window_set_default_size(GTK_WINDOW (winMain
), ui
.window_default_width
, ui
.window_default_height
);
111 if (ui
.maximize_at_start
) gtk_window_maximize(GTK_WINDOW (winMain
));
112 update_toolbar_and_menu();
113 update_font_button();
115 gtk_check_menu_item_set_active(
116 GTK_CHECK_MENU_ITEM(GET_COMPONENT("journalApplyAllPages")), ui
.bg_apply_all_pages
);
118 gtk_check_menu_item_set_active(
119 GTK_CHECK_MENU_ITEM(GET_COMPONENT("viewFullscreen")), TRUE
);
120 gtk_toggle_tool_button_set_active(
121 GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonFullscreen")), TRUE
);
122 gtk_window_fullscreen(GTK_WINDOW(winMain
));
124 gtk_button_set_relief(GTK_BUTTON(GET_COMPONENT("buttonColorChooser")), GTK_RELIEF_NONE
);
127 add_scroll_bindings();
129 // prevent interface items from stealing focus
130 // glade doesn't properly handle can_focus, so manually set it
131 gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(GET_COMPONENT("comboLayer")), FALSE
);
132 g_signal_connect(GET_COMPONENT("spinPageNo"), "activate",
133 G_CALLBACK(handle_activate_signal
), NULL
);
134 gtk_container_forall(GTK_CONTAINER(winMain
), unset_flags
, (gpointer
)GTK_CAN_FOCUS
);
135 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(canvas
), GTK_CAN_FOCUS
);
136 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(GET_COMPONENT("spinPageNo")), GTK_CAN_FOCUS
);
138 // install hooks on button/key/activation events to make the spinPageNo lose focus
139 gtk_container_forall(GTK_CONTAINER(winMain
), install_focus_hooks
, NULL
);
141 // set up and initialize the canvas
143 gtk_widget_show (GTK_WIDGET (canvas
));
144 w
= GET_COMPONENT("scrolledwindowMain");
145 gtk_container_add (GTK_CONTAINER (w
), GTK_WIDGET (canvas
));
146 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (w
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
147 gtk_widget_set_events (GTK_WIDGET (canvas
), GDK_EXPOSURE_MASK
| GDK_POINTER_MOTION_MASK
| GDK_BUTTON_MOTION_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_KEY_PRESS_MASK
| GDK_ENTER_NOTIFY_MASK
| GDK_LEAVE_NOTIFY_MASK
);
148 gnome_canvas_set_pixels_per_unit (canvas
, ui
.zoom
);
149 gnome_canvas_set_center_scroll_region (canvas
, TRUE
);
150 gtk_layout_get_hadjustment(GTK_LAYOUT (canvas
))->step_increment
= ui
.scrollbar_step_increment
;
151 gtk_layout_get_vadjustment(GTK_LAYOUT (canvas
))->step_increment
= ui
.scrollbar_step_increment
;
153 // set up the page size and canvas size
156 g_signal_connect ((gpointer
) canvas
, "button_press_event",
157 G_CALLBACK (on_canvas_button_press_event
),
159 g_signal_connect ((gpointer
) canvas
, "button_release_event",
160 G_CALLBACK (on_canvas_button_release_event
),
162 g_signal_connect ((gpointer
) canvas
, "enter_notify_event",
163 G_CALLBACK (on_canvas_enter_notify_event
),
165 g_signal_connect ((gpointer
) canvas
, "leave_notify_event",
166 G_CALLBACK (on_canvas_leave_notify_event
),
168 g_signal_connect ((gpointer
) canvas
, "expose_event",
169 G_CALLBACK (on_canvas_expose_event
),
171 g_signal_connect ((gpointer
) canvas
, "key_press_event",
172 G_CALLBACK (on_canvas_key_press_event
),
174 g_signal_connect ((gpointer
) canvas
, "motion_notify_event",
175 G_CALLBACK (on_canvas_motion_notify_event
),
177 g_signal_connect ((gpointer
) gtk_layout_get_vadjustment(GTK_LAYOUT(canvas
)),
178 "value-changed", G_CALLBACK (on_vscroll_changed
),
180 g_object_set_data (G_OBJECT (winMain
), "canvas", canvas
);
182 screen
= gtk_widget_get_screen(winMain
);
183 ui
.screen_width
= gdk_screen_get_width(screen
);
184 ui
.screen_height
= gdk_screen_get_height(screen
);
187 dev_list
= gdk_devices_list();
188 while (dev_list
!= NULL
) {
189 device
= (GdkDevice
*)dev_list
->data
;
190 if (device
!= gdk_device_get_core_pointer() && device
->num_axes
>= 2) {
191 /* get around a GDK bug: map the valuator range CORRECTLY to [0,1] */
192 #ifdef ENABLE_XINPUT_BUGFIX
193 gdk_device_set_axis_use(device
, 0, GDK_AXIS_IGNORE
);
194 gdk_device_set_axis_use(device
, 1, GDK_AXIS_IGNORE
);
196 gdk_device_set_mode(device
, GDK_MODE_SCREEN
);
197 if (g_strrstr(device
->name
, "raser"))
198 gdk_device_set_source(device
, GDK_SOURCE_ERASER
);
201 dev_list
= dev_list
->next
;
204 gtk_widget_set_sensitive(GET_COMPONENT("optionsUseXInput"), FALSE
);
206 ui
.use_xinput
= ui
.allow_xinput
&& can_xinput
;
208 gtk_check_menu_item_set_active(
209 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsProgressiveBG")), ui
.progressive_bg
);
210 gtk_check_menu_item_set_active(
211 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsPrintRuling")), ui
.print_ruling
);
212 gtk_check_menu_item_set_active(
213 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsAutoloadPdfXoj")), ui
.autoload_pdf_xoj
);
214 gtk_check_menu_item_set_active(
215 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsLeftHanded")), ui
.left_handed
);
216 gtk_check_menu_item_set_active(
217 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsShortenMenus")), ui
.shorten_menus
);
218 gtk_check_menu_item_set_active(
219 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsAutoSavePrefs")), ui
.auto_save_prefs
);
220 gtk_check_menu_item_set_active(
221 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsButtonSwitchMapping")), ui
.button_switch_mapping
);
223 hide_unimplemented();
225 update_undo_redo_enabled();
226 update_copy_paste_enabled();
227 update_vbox_order(ui
.vertical_order
[ui
.fullscreen
?1:0]);
228 gtk_widget_grab_focus(GTK_WIDGET(canvas
));
230 // show everything...
232 gtk_widget_show (winMain
);
235 /* this will cause extension events to get enabled/disabled, but
236 we need the windows to be mapped first */
237 gtk_check_menu_item_set_active(
238 GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsUseXInput")), ui
.use_xinput
);
240 /* fix a bug in GTK+ 2.16 and 2.17: scrollbars shouldn't get extended
241 input events from pointer motion when cursor moves into main window */
243 if (!gtk_check_version(2, 16, 0)) {
245 GET_COMPONENT("menubar"),
246 "event", G_CALLBACK (filter_extended_events
),
249 GET_COMPONENT("toolbarMain"),
250 "event", G_CALLBACK (filter_extended_events
),
253 GET_COMPONENT("toolbarPen"),
254 "event", G_CALLBACK (filter_extended_events
),
257 GET_COMPONENT("statusbar"),
258 "event", G_CALLBACK (filter_extended_events
),
261 (gpointer
)(gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(w
))),
262 "event", G_CALLBACK (filter_extended_events
),
265 (gpointer
)(gtk_scrolled_window_get_hscrollbar(GTK_SCROLLED_WINDOW(w
))),
266 "event", G_CALLBACK (filter_extended_events
),
274 // and finally, open a file specified on the command line
275 // (moved here because display parameters weren't initialized yet...)
277 if (argc
== 1) return;
278 set_cursor_busy(TRUE
);
279 if (g_path_is_absolute(argv
[1]))
280 tmpfn
= g_strdup(argv
[1]);
282 tmppath
= g_get_current_dir();
283 tmpfn
= g_build_filename(tmppath
, argv
[1], NULL
);
286 success
= open_journal(tmpfn
);
288 set_cursor_busy(FALSE
);
290 w
= gtk_message_dialog_new(GTK_WINDOW (winMain
), GTK_DIALOG_DESTROY_WITH_PARENT
,
291 GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
, _("Error opening file '%s'"), argv
[1]);
292 gtk_dialog_run(GTK_DIALOG(w
));
293 gtk_widget_destroy(w
);
299 main (int argc
, char *argv
[])
301 gchar
*path
, *path1
, *path2
;
304 bindtextdomain (GETTEXT_PACKAGE
, PACKAGE_LOCALE_DIR
);
305 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
306 textdomain (GETTEXT_PACKAGE
);
310 gtk_init (&argc
, &argv
);
312 add_pixmap_directory (PACKAGE_DATA_DIR
"/" PACKAGE
"/pixmaps");
313 path
= g_path_get_dirname(argv
[0]);
314 path1
= g_build_filename(path
, "pixmaps", NULL
);
315 path2
= g_build_filename(path
, "..", "pixmaps", NULL
);
316 add_pixmap_directory (path1
);
317 add_pixmap_directory (path2
);
318 add_pixmap_directory (path
);
324 * The following code was added by Glade to create one of each component
325 * (except popup menus), just so that you see something after building
326 * the project. Delete any components that you don't want shown initially.
328 winMain
= create_winMain ();
330 init_stuff (argc
, argv
);
331 gtk_window_set_icon(GTK_WINDOW(winMain
), create_pixbuf("xournal.png"));
335 if (bgpdf
.status
!= STATUS_NOT_INIT
) shutdown_bgpdf();
338 if (ui
.auto_save_prefs
) save_config_to_file();