1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3
* Copyright © 2001 Matthew Mueller
4
* Copyright © 2002 Jorn Baayen <jorn@nl.linux.org>
5
* Copyright © 2003 Marco Pesenti Gritti <mpeseng@tin.it>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2, or (at your option)
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25
#include "ephy-state.h"
26
#include "ephy-lib-type-builtins.h"
27
#include "ephy-file-helpers.h"
28
#include "ephy-node-db.h"
29
#include "ephy-node-common.h"
34
#define EPHY_STATES_XML_FILE "states.xml"
35
#define EPHY_STATES_XML_ROOT (const xmlChar *)"ephy_states"
36
#define EPHY_STATES_XML_VERSION (const xmlChar *)"1.0"
40
EPHY_NODE_STATE_PROP_NAME = 2,
41
EPHY_NODE_STATE_PROP_WIDTH = 3,
42
EPHY_NODE_STATE_PROP_HEIGHT = 4,
43
EPHY_NODE_STATE_PROP_MAXIMIZE = 5,
44
EPHY_NODE_STATE_PROP_POSITION_X = 6,
45
EPHY_NODE_STATE_PROP_POSITION_Y = 7,
46
EPHY_NODE_STATE_PROP_SIZE = 8,
47
EPHY_NODE_STATE_PROP_POSITION = 9,
48
EPHY_NODE_STATE_PROP_ACTIVE = 10
51
static EphyNode *states = NULL;
52
static EphyNodeDb *states_db = NULL;
55
ephy_states_save (void)
59
xml_file = g_build_filename (ephy_dot_dir (),
63
ephy_node_db_write_to_xml_safe
65
(const xmlChar *)xml_file,
67
EPHY_STATES_XML_VERSION,
76
find_by_name (const char *name)
78
EphyNode *result = NULL;
82
children = ephy_node_get_children (states);
83
for (i = 0; i < children->len; i++)
86
const char *node_name;
88
kid = g_ptr_array_index (children, i);
90
node_name = ephy_node_get_property_string
91
(kid, EPHY_NODE_STATE_PROP_NAME);
92
if (strcmp (node_name, name) == 0)
108
xml_file = g_build_filename (ephy_dot_dir (),
109
EPHY_STATES_XML_FILE,
112
states_db = ephy_node_db_new (EPHY_NODE_DB_STATES);
113
states = ephy_node_new_with_id (states_db, STATES_NODE_ID);
114
ephy_node_db_load_from_file (states_db, xml_file,
115
EPHY_STATES_XML_ROOT,
116
EPHY_STATES_XML_VERSION);
123
ephy_state_window_set_size (GtkWidget *window, EphyNode *node)
125
int width, height, w = -1, h = -1;
126
gboolean maximize, size;
128
width = ephy_node_get_property_int (node, EPHY_NODE_STATE_PROP_WIDTH);
129
height = ephy_node_get_property_int (node, EPHY_NODE_STATE_PROP_HEIGHT);
130
maximize = ephy_node_get_property_boolean (node, EPHY_NODE_STATE_PROP_MAXIMIZE);
131
size = ephy_node_get_property_boolean (node, EPHY_NODE_STATE_PROP_SIZE);
133
gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
134
if (size && w == -1 && h == -1)
137
int screen_width, screen_height;
139
screen = gdk_screen_get_default ();
140
screen_width = gdk_screen_get_width (screen);
141
screen_height = gdk_screen_get_height (screen);
143
gtk_window_set_default_size (GTK_WINDOW (window),
144
MIN (width, screen_width),
145
MIN (height, screen_height));
150
gtk_window_maximize (GTK_WINDOW (window));
155
ephy_state_window_set_position (GtkWidget *window, EphyNode *node)
159
int screen_width, screen_height;
160
gboolean maximize, size;
162
g_return_if_fail (GTK_IS_WINDOW (window));
164
/* Setting the default size doesn't work when the window is already showing. */
165
g_return_if_fail (!gtk_widget_get_visible (window));
167
maximize = ephy_node_get_property_boolean (node, EPHY_NODE_STATE_PROP_MAXIMIZE);
168
size = ephy_node_get_property_boolean (node, EPHY_NODE_STATE_PROP_POSITION);
170
/* Don't set the position of the window if it is maximized */
171
if ((!maximize) && size)
173
x = ephy_node_get_property_int (node, EPHY_NODE_STATE_PROP_POSITION_X);
174
y = ephy_node_get_property_int (node, EPHY_NODE_STATE_PROP_POSITION_Y);
176
screen = gtk_window_get_screen (GTK_WINDOW (window));
177
screen_width = gdk_screen_get_width (screen);
178
screen_height = gdk_screen_get_height (screen);
180
if ((x <= screen_width) && (y <= screen_height) &&
181
(x >= 0) && (y >= 0))
183
gtk_window_move (GTK_WINDOW (window), x, y);
189
ephy_state_save_unmaximized_size (EphyNode *node, int width, int height)
191
ephy_node_set_property_int (node, EPHY_NODE_STATE_PROP_WIDTH,
193
ephy_node_set_property_int (node, EPHY_NODE_STATE_PROP_HEIGHT,
195
ephy_node_set_property_boolean (node, EPHY_NODE_STATE_PROP_SIZE,
200
ephy_state_save_position (EphyNode *node, int x, int y)
202
ephy_node_set_property_int (node, EPHY_NODE_STATE_PROP_POSITION_X,
204
ephy_node_set_property_int (node, EPHY_NODE_STATE_PROP_POSITION_Y,
206
ephy_node_set_property_boolean (node, EPHY_NODE_STATE_PROP_POSITION,
212
ephy_state_window_save_size (GtkWidget *window, EphyNode *node)
216
GdkWindowState state;
218
state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
219
maximize = ((state & GDK_WINDOW_STATE_MAXIMIZED) > 0);
221
gtk_window_get_size (GTK_WINDOW(window),
226
ephy_state_save_unmaximized_size (node, width, height);
229
ephy_node_set_property_boolean (node,
230
EPHY_NODE_STATE_PROP_MAXIMIZE,
235
ephy_state_window_save_position (GtkWidget *window, EphyNode *node)
239
GdkWindowState state;
241
state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
242
maximize = ((state & GDK_WINDOW_STATE_MAXIMIZED) > 0);
244
/* Don't save the position if maximized */
247
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
248
ephy_state_save_position (node, x, y);
253
ephy_state_window_save (GtkWidget *widget, EphyNode *node)
255
EphyStateWindowFlags flags;
257
flags = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "state_flags"));
259
if (flags & EPHY_STATE_WINDOW_SAVE_SIZE)
261
ephy_state_window_save_size (widget, node);
264
if (flags & EPHY_STATE_WINDOW_SAVE_POSITION)
266
ephy_state_window_save_position (widget, node);
271
window_configure_event_cb (GtkWidget *widget,
272
GdkEventConfigure *event,
275
GdkWindowState state;
277
state = gdk_window_get_state (gtk_widget_get_window (widget));
279
if (!(state & GDK_WINDOW_STATE_FULLSCREEN))
281
ephy_state_window_save (widget, node);
288
window_state_event_cb (GtkWidget *widget,
289
GdkEventWindowState *event,
292
if (!(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN))
294
ephy_state_window_save (widget, node);
301
create_window_node (const char *name,
305
EphyStateWindowFlags flags)
309
node = ephy_node_new (states_db);
310
ephy_node_add_child (states, node);
312
ephy_node_set_property_string (node, EPHY_NODE_STATE_PROP_NAME,
314
ephy_node_set_property_boolean (node, EPHY_NODE_STATE_PROP_MAXIMIZE,
317
if (flags & EPHY_STATE_WINDOW_SAVE_SIZE)
319
ephy_state_save_unmaximized_size (node,
324
if (flags & EPHY_STATE_WINDOW_SAVE_POSITION)
326
/* Constants for now, these should be default_width
327
and default_height. */
328
ephy_state_save_position (node, 0, 0);
335
ephy_state_add_window (GtkWidget *window,
340
EphyStateWindowFlags flags)
346
node = find_by_name (name);
349
node = create_window_node (name, default_width, default_height,
353
ephy_state_window_set_size (window, node);
354
ephy_state_window_set_position (window, node);
356
g_object_set_data (G_OBJECT (window), "state_flags", GINT_TO_POINTER (flags));
358
g_signal_connect (window, "configure_event",
359
G_CALLBACK (window_configure_event_cb), node);
360
g_signal_connect (window, "window_state_event",
361
G_CALLBACK (window_state_event_cb), node);
365
paned_sync_position_cb (GtkWidget *paned,
371
width = gtk_paned_get_position (GTK_PANED (paned));
372
ephy_node_set_property_int (node, EPHY_NODE_STATE_PROP_WIDTH,
378
ephy_state_add_paned (GtkWidget *paned,
387
node = find_by_name (name);
390
node = ephy_node_new (states_db);
391
ephy_node_add_child (states, node);
393
ephy_node_set_property_string (node,
394
EPHY_NODE_STATE_PROP_NAME,
396
ephy_node_set_property_int (node,
397
EPHY_NODE_STATE_PROP_WIDTH,
401
width = ephy_node_get_property_int (node, EPHY_NODE_STATE_PROP_WIDTH);
402
gtk_paned_set_position (GTK_PANED (paned), width);
404
g_signal_connect (paned, "notify::position",
405
G_CALLBACK (paned_sync_position_cb), node);
409
sync_expander_cb (GtkExpander *expander,
413
gboolean is_expanded;
415
is_expanded = gtk_expander_get_expanded (expander);
416
ephy_node_set_property_boolean (node,
417
EPHY_NODE_STATE_PROP_ACTIVE,
422
sync_toggle_cb (GtkToggleButton *toggle,
428
is_active = gtk_toggle_button_get_active (toggle);
429
ephy_node_set_property_boolean (node,
430
EPHY_NODE_STATE_PROP_ACTIVE,
435
ephy_state_add_expander (GtkWidget *widget,
437
gboolean default_state)
444
node = find_by_name (name);
447
node = ephy_node_new (states_db);
448
ephy_node_add_child (states, node);
450
ephy_node_set_property_string (node,
451
EPHY_NODE_STATE_PROP_NAME,
453
ephy_node_set_property_boolean (node,
454
EPHY_NODE_STATE_PROP_ACTIVE,
458
active = ephy_node_get_property_boolean
459
(node, EPHY_NODE_STATE_PROP_ACTIVE);
461
if (GTK_IS_TOGGLE_BUTTON (widget))
463
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active);
464
g_signal_connect (widget, "notify::active",
465
G_CALLBACK (sync_toggle_cb), node);
467
else if (GTK_IS_EXPANDER (widget))
469
gtk_expander_set_expanded (GTK_EXPANDER (widget), active);
470
g_signal_connect (widget, "notify::expanded",
471
G_CALLBACK (sync_expander_cb), node);
476
ephy_state_save (void)
481
ephy_node_unref (states);
482
g_object_unref (states_db);