aboutsummaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-08-30 13:37:36 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-08-30 13:40:49 +0800
commitcfb9c32b6657165e4d5e11aa7b47804f679a61f8 (patch)
tree1f9c8954df7a357b5dc20a13ac82bf31c1112083 /shell
parentfefeb30f58447f2fa7bcbee16dbe68a9333ce89d (diff)
parent0f7f4cfe38b3c4cd83efbe9922ae15c5aee00317 (diff)
downloadgsoc2013-evolution-cfb9c32b6657165e4d5e11aa7b47804f679a61f8.tar.gz
gsoc2013-evolution-cfb9c32b6657165e4d5e11aa7b47804f679a61f8.tar.zst
gsoc2013-evolution-cfb9c32b6657165e4d5e11aa7b47804f679a61f8.zip
Merge commit 'origin/kill-bonobo'
Diffstat (limited to 'shell')
-rw-r--r--shell/Evolution-Component.idl137
-rw-r--r--shell/Evolution-ConfigControl.idl26
-rw-r--r--shell/Evolution-Shell.idl87
-rw-r--r--shell/Evolution.idl20
-rw-r--r--shell/GNOME_Evolution_Shell.server.in.in26
-rw-r--r--shell/Makefile.am147
-rw-r--r--shell/apps_evolution_shell.schemas.in48
-rw-r--r--shell/e-active-connection-dialog.glade193
-rw-r--r--shell/e-component-registry.c320
-rw-r--r--shell/e-component-registry.h93
-rw-r--r--shell/e-component-view.c151
-rw-r--r--shell/e-component-view.h73
-rw-r--r--shell/e-corba-config-page.c154
-rw-r--r--shell/e-corba-config-page.h63
-rw-r--r--shell/e-shell-backend.c403
-rw-r--r--shell/e-shell-backend.h139
-rw-r--r--shell/e-shell-common.h (renamed from shell/importer/intelligent.h)19
-rw-r--r--shell/e-shell-constants.h50
-rw-r--r--shell/e-shell-content.c1559
-rw-r--r--shell/e-shell-content.h148
-rw-r--r--shell/e-shell-importer.c330
-rw-r--r--shell/e-shell-importer.h15
-rw-r--r--shell/e-shell-migrate.c351
-rw-r--r--shell/e-shell-migrate.h (renamed from shell/evolution-shell-component-utils.h)43
-rw-r--r--shell/e-shell-nm.c71
-rw-r--r--shell/e-shell-settings-dialog.c355
-rw-r--r--shell/e-shell-settings-dialog.h60
-rw-r--r--shell/e-shell-settings.c702
-rw-r--r--shell/e-shell-settings.h114
-rw-r--r--shell/e-shell-sidebar.c683
-rw-r--r--shell/e-shell-sidebar.h97
-rw-r--r--shell/e-shell-switcher.c700
-rw-r--r--shell/e-shell-switcher.h92
-rw-r--r--shell/e-shell-taskbar.c421
-rw-r--r--shell/e-shell-taskbar.h87
-rw-r--r--shell/e-shell-view.c1173
-rw-r--r--shell/e-shell-view.h180
-rw-r--r--shell/e-shell-window-actions.c2242
-rw-r--r--shell/e-shell-window-actions.h123
-rw-r--r--shell/e-shell-window-commands.c1388
-rw-r--r--shell/e-shell-window-private.c602
-rw-r--r--shell/e-shell-window-private.h128
-rw-r--r--shell/e-shell-window.c1723
-rw-r--r--shell/e-shell-window.h136
-rw-r--r--shell/e-shell.c2276
-rw-r--r--shell/e-shell.h182
-rw-r--r--shell/e-sidebar.c785
-rw-r--r--shell/e-sidebar.h85
-rw-r--r--shell/e-user-creatable-items-handler.c907
-rw-r--r--shell/e-user-creatable-items-handler.h63
-rw-r--r--shell/es-event.c21
-rw-r--r--shell/es-event.h6
-rw-r--r--shell/es-menu.c185
-rw-r--r--shell/es-menu.h92
-rw-r--r--shell/evolution-component.c48
-rw-r--r--shell/evolution-component.h47
-rw-r--r--shell/evolution-config-control.c175
-rw-r--r--shell/evolution-config-control.h64
-rw-r--r--shell/evolution-listener.c71
-rw-r--r--shell/evolution-listener.h54
-rw-r--r--shell/evolution-shell-component-utils.c111
-rw-r--r--shell/import.glade124
-rw-r--r--shell/importer/GNOME_Evolution_Importer.idl97
-rw-r--r--shell/importer/Makefile.am68
-rw-r--r--shell/importer/evolution-importer-client.c267
-rw-r--r--shell/importer/evolution-importer-client.h69
-rw-r--r--shell/importer/evolution-importer-listener.c224
-rw-r--r--shell/importer/evolution-importer-listener.h66
-rw-r--r--shell/importer/evolution-importer.c249
-rw-r--r--shell/importer/evolution-importer.h94
-rw-r--r--shell/importer/evolution-intelligent-importer.c197
-rw-r--r--shell/importer/evolution-intelligent-importer.h69
-rw-r--r--shell/importer/import.glade124
-rw-r--r--shell/importer/intelligent.c469
-rw-r--r--shell/main.c468
-rw-r--r--shell/shell.error.xml27
-rw-r--r--shell/test/GNOME_Evolution_Test.server.in.in39
-rw-r--r--shell/test/Makefile.am34
-rw-r--r--shell/test/e-test-shell-backend.c222
-rw-r--r--shell/test/e-test-shell-backend.h67
-rw-r--r--shell/test/e-test-shell-view.c155
-rw-r--r--shell/test/e-test-shell-view.h66
-rw-r--r--shell/test/evolution-module-test.c (renamed from shell/e-shell-window-commands.h)26
-rw-r--r--shell/test/evolution-test-component.c176
-rw-r--r--shell/test/evolution-test-component.h53
85 files changed, 12914 insertions, 11380 deletions
diff --git a/shell/Evolution-Component.idl b/shell/Evolution-Component.idl
deleted file mode 100644
index ccf806ff91..0000000000
--- a/shell/Evolution-Component.idl
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Interface for the Evolution components.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2003 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_COMPONENT_IDL
-#define _GNOME_EVOLUTION_COMPONENT_IDL
-
-#include <Bonobo.idl>
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-%{
-#pragma include_defs shell/evolution-component.h
-%}
-#pragma inhibit push
-#endif
-#endif
-
-module GNOME {
-module Evolution {
- enum CreatableItem {
- CREATABLE_OBJECT,
- CREATABLE_FOLDER
- };
- enum ShellState {
- USER_OFFLINE,
- FORCED_OFFLINE,
- USER_ONLINE
- };
-
- /* A type of item that the component can create when asked by the user,
- e.g. a mail message or an appointment. */
- struct CreatableItemType {
- string id;
- string description;
- string menuDescription;
- string tooltip;
- char menuShortcut;
- string iconName;
- CreatableItem type;
- };
- typedef sequence <CreatableItemType> CreatableItemTypeList;
-
- interface ComponentView : Bonobo::Unknown {
- void getControls (out Bonobo::Control sidebar_control,
- out Bonobo::Control view_control,
- out Bonobo::Control statusbar_control);
- };
-
- interface Listener : Bonobo::Unknown {
- /* Indicate the change of state is complete */
- void complete();
- };
-
- interface Component : Bonobo::Unknown {
- exception Failed {};
- exception UnknownType {};
- /* We don't know about the old version we're upgrading from */
- exception UnsupportedVersion {};
- /* We encountered a non-recoverable, fatal error, explain why */
- exception UpgradeFailed {
- string what;
- string why;
- };
-
- /*** Upgrade path. ***/
-
- void upgradeFromVersion (in short major, in short minor, in short revision)
- raises (UnsupportedVersion, UpgradeFailed);
-
- /*** Basic functionality. ***/
- ComponentView createView(in ShellView parent,
- in boolean select_item)
- raises (Failed);
-
-
- /* Check if the component can quit.
- Do not perform any quit-related tasks however.
- May be called multiple times, depending on user interaction. */
- boolean requestQuit ();
-
- /* Ask the component to quit. Returns TRUE when the
- component has completed any closing-down tasks, and
- is ready to exit(). This will be called repeatedly
- at intervals until it returns TRUE. */
- boolean quit ();
-
- /* Notify the component of whether the shell is currently
- running in interactive mode or not. (I.e. basically,
- whether there are any Evolution windows on the screen.)
- @new_view_xid is an X Window ID ("None" if @now_interactive
- is FALSE) */
- void interactive (in boolean now_interactive,
- in unsigned long new_view_xid);
-
-
- /*** The following stuff is needed to build the "New" toolbar
- item as well as the "File -> New" submenu. ***/
-
- /* List of creatable items. */
- readonly attribute CreatableItemTypeList userCreatableItems;
-
- /* Pop up a new editing dialog for the item with the specified
- @item_type_name. */
- void requestCreateItem (in string item_type_name)
- raises (UnknownType, Failed);
-
-
- /*** URI handling (e.g. for the command-line, "evolution
- mailto:foo@bar.org") ***/
- void handleURI (in string uri);
-
-
- /*** Send/receive. ***/
-
- void sendAndReceive ();
-
- /* Set the online status of the component asynchronously */
-
- void setLineStatus(in ShellState shell_state, in Listener listener);
- };
-
-};
-};
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-#pragma inhibit pop
-#endif
-#endif
-#endif /* _GNOME_EVOLUTION_COMPONENT_IDL */
diff --git a/shell/Evolution-ConfigControl.idl b/shell/Evolution-ConfigControl.idl
deleted file mode 100644
index 901932d209..0000000000
--- a/shell/Evolution-ConfigControl.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Additional interfaces for the Controls used in configuration dialogs.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_CONFIGCONTROL_IDL
-#define _GNOME_EVOLUTION_CONFIGCONTROL_IDL
-
-module GNOME {
-module Evolution {
- interface ConfigControl : Bonobo::Unknown {
- /* The actual Control. */
- readonly attribute Bonobo::Control control;
-
- /* Get the event source for this control. */
- readonly attribute Bonobo::EventSource eventSource;
- };
-}; /* module Evolution */
-}; /* module GNOME */
-
-#endif
diff --git a/shell/Evolution-Shell.idl b/shell/Evolution-Shell.idl
deleted file mode 100644
index d39ec8edeb..0000000000
--- a/shell/Evolution-Shell.idl
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Interface for the Evolution shell.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_SHELL_IDL
-#define _GNOME_EVOLUTION_SHELL_IDL
-
-#include <Bonobo.idl>
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-%{
-#pragma include_defs shell/evolution-component.h
-%}
-#pragma inhibit push
-#endif
-#endif
-
-module GNOME {
-module Evolution {
-
-
- interface ShellView : Bonobo::Unknown {
- /* Should really use a ComponentView i guess */
- void setTitle(in string component, in string title);
- void setComponent(in string component);
- void setButtonIcon(in string component, in string iconName);
- };
-
- interface Shell : Bonobo::Unknown {
- exception Busy {};
- exception ComponentNotFound {};
- exception InternalError {};
- exception InvalidURI {};
- exception NotFound {};
- exception NotReady {};
- exception UnsupportedSchema {};
-
- /**
- * createNewWindow:
- * @component_id: id or alias of the component to display in the new window.
- *
- */
- ShellView createNewWindow (in string component_id)
- raises (NotReady, ComponentNotFound, UnsupportedSchema, InternalError);
-
- /**
- * handleURI:
- * @uri: URI to handle
- *
- * This handles the specified URI. It is different from
- * `::createNewView' as it doesn't necessarily imply creating a
- * new ShellView. (For example, a `mailto:' URI will invoke
- * the message composer.)
- */
- void handleURI (in string uri)
- raises (NotReady, ComponentNotFound, NotFound, UnsupportedSchema, InvalidURI, InternalError);
-
- /**
- * setLineStatus:
- *
- * Set the shell into on-line or off-line mode.
- */
- void setLineStatus (in boolean online)
- raises (NotReady);
-
- /*
- * Lookup a component by id.
- */
- /*Component findComponent(in string id)
- raises (NotReady, ComponentNotFound);*/
- };
-};
-};
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-#pragma inhibit pop
-#endif
-#endif
-#endif /* _GNOME_EVOLUTION_SHELL_IDL */
diff --git a/shell/Evolution.idl b/shell/Evolution.idl
deleted file mode 100644
index 059d017444..0000000000
--- a/shell/Evolution.idl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * CORBA interface for the Evolution shell.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_IDL
-#define _GNOME_EVOLUTION_IDL
-
-#include <Bonobo.idl>
-
-#include <Evolution-ConfigControl.idl>
-#include <Evolution-Shell.idl>
-#include <Evolution-Component.idl>
-
-#endif
diff --git a/shell/GNOME_Evolution_Shell.server.in.in b/shell/GNOME_Evolution_Shell.server.in.in
deleted file mode 100644
index b055f3000d..0000000000
--- a/shell/GNOME_Evolution_Shell.server.in.in
+++ /dev/null
@@ -1,26 +0,0 @@
-<oaf_info>
-
- <oaf_server iid="OAFIID:GNOME_Evolution_Shell:@VERSION@"
- type="exe"
- location="@BINDIR_IN_SERVER_FILE@/evolution@EXEEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Shell:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Shell"/>
- </oaf_server>
-
- <oaf_server iid="OAFIID:GNOME_Evolution_Shell_Config_Factory:@VERSION@"
- type="exe"
- location="@BINDIR_IN_SERVER_FILE@/evolution-@VERSION@@EXEEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/GenericFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string" _value="Evolution Shell Config factory"/>
- </oaf_server>
-
-</oaf_info>
diff --git a/shell/Makefile.am b/shell/Makefile.am
index ecf0dc4f47..a17c11a875 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -4,6 +4,7 @@ endif
AM_CPPFLAGS = \
-I$(top_srcdir)/widgets \
+ -I$(top_srcdir)/widgets/menus \
-I$(top_srcdir)/widgets/misc \
-I$(top_srcdir) \
-I$(top_srcdir)/shell \
@@ -11,8 +12,11 @@ AM_CPPFLAGS = \
-DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \
-DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
-DEVOLUTION_DATADIR=\""$(datadir)"\" \
+ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_HELPDIR=\""$(evolutionhelpdir)"\" \
+ -DEVOLUTION_MODULEDIR=\""$(moduledir)"\" \
+ -DEVOLUTION_RULEDIR=\""$(privdatadir)"\" \
-DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \
-DEVOLUTION_TOOLSDIR=\""$(privlibexecdir)"\" \
-DPREFIX=\""$(prefix)"\" \
@@ -26,62 +30,15 @@ AM_CPPFLAGS = \
if NM_SUPPORT
AM_CPPFLAGS += \
$(DBUS_GLIB_CFLAGS) \
- $(NM_FLAGS)
+ $(NM_CFLAGS)
endif
bin_PROGRAMS = evolution
-# Shell CORBA stuff
-
-IDLS = \
- Evolution-ConfigControl.idl \
- Evolution-Component.idl \
- Evolution-Shell.idl \
- Evolution.idl
-
-IDL_GENERATED_H = \
- Evolution.h
-
-IDL_GENERATED_C = \
- Evolution-common.c \
- Evolution-skels.c \
- Evolution-stubs.c
-
-idl_defines = \
- -D__evolution_shell_COMPILATION
-
-IDL_GENERATED = $(IDL_GENERATED_H) $(IDL_GENERATED_C)
-
-$(IDL_GENERATED_H): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) $(idl_defines) $(IDL_INCLUDES) $(srcdir)/Evolution.idl
-
-$(IDL_GENERATED_C): $(IDL_GENERATED_H)
-
if NM_SUPPORT
-NM_SUPPORT_FILES = e-shell-nm.c
+NM_SUPPORT_FILES = e-shell-nm.c
endif
-# Data Server CORBA stuff
-DATASERVER_IDL_GENERATED_H = \
- Evolution-DataServer.h
-
-DATASERVER_IDL_GENERATED_C = \
- Evolution-DataServer-common.c \
- Evolution-DataServer-skels.c \
- Evolution-DataServer-stubs.c
-
-DATASERVER_IDL_GENERATED = $(DATASERVER_IDL_GENERATED_C) $(DATASERVER_IDL_GENERATED_H)
-
-$(DATASERVER_IDL_GENERATED_H): $(DATASERVER_IDL)
- $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) $(DATASERVER_IDL)
-
-$(DATASERVER_IDL_GENERATED_C): $(DATASERVER_IDL_GENERATED_H)
-
-
-# IDL install
-
-idl_DATA = $(IDLS)
-
# Shell library
privsolib_LTLIBRARIES = \
@@ -90,33 +47,55 @@ privsolib_LTLIBRARIES = \
eshellincludedir = $(privincludedir)/shell
eshellinclude_HEADERS = \
- Evolution.h \
- e-component-view.h \
- e-user-creatable-items-handler.h \
- evolution-config-control.h \
- evolution-component.h \
- evolution-listener.h \
- evolution-shell-component-utils.h \
- es-event.h \
- es-menu.h
+ e-shell.h \
+ e-shell-backend.h \
+ e-shell-common.h \
+ e-shell-content.h \
+ e-shell-settings.h \
+ e-shell-sidebar.h \
+ e-shell-switcher.h \
+ e-shell-taskbar.h \
+ e-shell-view.h \
+ e-shell-window.h \
+ es-event.h
libeshell_la_SOURCES = \
+ $(NM_SUPPORT_FILES) \
$(IDL_GENERATED) \
- e-component-view.c \
- evolution-component.c \
- evolution-listener.c \
- e-user-creatable-items-handler.c \
- evolution-config-control.c \
- evolution-shell-component-utils.c \
- $(eshellinclude_HEADERS)
+ e-shell.c \
+ e-shell-backend.c \
+ e-shell-content.c \
+ e-shell-settings.c \
+ e-shell-sidebar.c \
+ e-shell-switcher.c \
+ e-shell-taskbar.c \
+ e-shell-view.c \
+ e-shell-window.c \
+ e-shell-window-private.c \
+ e-shell-window-private.h \
+ $(eshellinclude_HEADERS) \
+ e-shell-importer.c \
+ e-shell-importer.h \
+ e-shell-migrate.c \
+ e-shell-migrate.h \
+ e-shell-window-actions.h \
+ e-shell-window-actions.c \
+ es-event.c
libeshell_la_LDFLAGS = $(NO_UNDEFINED)
libeshell_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/smclient/libeggsmclient.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/widgets/menus/libmenus.la \
$(SHELL_LIBS)
+if NM_SUPPORT
+libeshell_la_LIBADD += $(DBUS_GLIB_LIBS)
+endif
+
# Evolution executable
if HAVE_WINDRES
@@ -124,36 +103,14 @@ EVOLUTIONICONRC = evolution-icon.o
endif
evolution_SOURCES = \
- $(DATASERVER_IDL_GENERATED) \
- $(NM_SUPPORT_FILES) \
- e-component-registry.c \
- e-component-registry.h \
e-config-upgrade.c \
e-config-upgrade.h \
- e-corba-config-page.c \
- e-corba-config-page.h \
- e-shell.c \
- e-shell.h \
- e-shell-constants.h \
- e-shell-importer.c \
- e-shell-importer.h \
- e-shell-settings-dialog.c \
- e-shell-settings-dialog.h \
- e-shell-window-commands.c \
- e-shell-window-commands.h \
- e-shell-window.c \
- e-shell-window.h \
- e-shell-view.c \
- e-shell-view.h \
- e-sidebar.c \
- e-sidebar.h \
- es-event.c \
- es-menu.c \
main.c
evolution_LDADD = \
libeshell.la \
$(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \
+ $(top_builddir)/widgets/menus/libmenus.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/e-util/libeutil.la \
$(TZDIALOG_LIBS) \
@@ -166,19 +123,10 @@ endif
# Misc stuff
-server_in_files = GNOME_Evolution_Shell.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
-
error_DATA = shell.error
errordir = $(privdatadir)/errors
@EVO_PLUGIN_RULE@
-glade_DATA = \
- e-active-connection-dialog.glade \
- import.glade
-
# GConf schemas
schemadir = $(GCONF_SCHEMA_FILE_DIR)
@@ -210,10 +158,7 @@ endif
# Extra dist stuff
EXTRA_DIST = \
- $(IDLS) \
- $(server_in_files) \
shell.error.xml \
- $(glade_DATA) \
$(schema_in_files) \
ChangeLog.pre-1-4 \
evolution-nognome.in \
@@ -237,7 +182,7 @@ evolution.pure: evolution
endif
-BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA) $(DATASERVER_IDL_GENERATED) $(error_DATA)
+BUILT_SOURCES = $(error_DATA)
CLEANFILES = $(BUILT_SOURCES)
DISTCLEANFILES = $(schema_DATA)
diff --git a/shell/apps_evolution_shell.schemas.in b/shell/apps_evolution_shell.schemas.in
index c5c6276c25..157df8cb9e 100644
--- a/shell/apps_evolution_shell.schemas.in
+++ b/shell/apps_evolution_shell.schemas.in
@@ -60,7 +60,7 @@
<schema>
<key>/schemas/apps/evolution/shell/current_folder</key>
- <applyto>/apps/evolution/shell/current-folder</applyto>
+ <applyto>/apps/evolution/shell/current_folder</applyto>
<owner>evolution</owner>
<type>string</type>
<locale name="C">
@@ -99,44 +99,54 @@
<!-- View defaults -->
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/width</key>
- <applyto>/apps/evolution/shell/view_defaults/width</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_y</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_y</applyto>
<owner>evolution</owner>
<type>int</type>
- <default>640</default>
<locale name="C">
- <short>Default window width</short>
- <long>The default width for the main window, in pixels.</long>
+ <short>Default window Y coordinate</short>
+ <long>The default Y coordinate for the main window.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/height</key>
- <applyto>/apps/evolution/shell/view_defaults/height</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_x</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_x</applyto>
<owner>evolution</owner>
<type>int</type>
- <default>480</default>
<locale name="C">
- <short>Default window height</short>
- <long>The default height for the main window, in pixels.</long>
+ <short>Default window X coordinate</short>
+ <long>The default X coordinate for the main window.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/maximized</key>
- <applyto>/apps/evolution/shell/view_defaults/maximized</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_width</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_width</applyto>
<owner>evolution</owner>
- <type>bool</type>
- <default>TRUE</default>
+ <type>int</type>
+ <default>640</default>
<locale name="C">
- <short>Default window state</short>
- <long>Whether or not the window should be maximized.</long>
+ <short>Default window width</short>
+ <long>The default width for the main window, in pixels.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_height</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_height</applyto>
+ <owner>evolution</owner>
+ <type>int</type>
+ <default>480</default>
+ <locale name="C">
+ <short>Default window height</short>
+ <long>The default height for the main window, in pixels.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/maximized</key>
- <applyto>/apps/evolution/shell/view_defaults/maximized</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_maximized</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_maximized</applyto>
<owner>evolution</owner>
<type>bool</type>
<default>TRUE</default>
diff --git a/shell/e-active-connection-dialog.glade b/shell/e-active-connection-dialog.glade
deleted file mode 100644
index 534a7948f7..0000000000
--- a/shell/e-active-connection-dialog.glade
+++ /dev/null
@@ -1,193 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkDialog" id="active_connection_dialog">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Active Connections</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
- <property name="modal">False</property>
- <property name="default_width">256</property>
- <property name="default_height">192</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="has_separator">False</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area2">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="cancelbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="response_id">-6</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="okbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-ok</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="response_id">-5</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Active Connections&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="active_connection_treeview">
- <property name="visible">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="instruction_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Click OK to close these connections and go offline</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/shell/e-component-registry.c b/shell/e-component-registry.c
deleted file mode 100644
index 1b36d14512..0000000000
--- a/shell/e-component-registry.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-component-registry.h"
-
-#include <glib/gi18n.h>
-
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-struct _EComponentRegistryPrivate {
- GSList *infos;
-
- guint init:1;
-};
-
-G_DEFINE_TYPE (EComponentRegistry, e_component_registry, G_TYPE_OBJECT)
-
-/* EComponentInfo handling. */
-
-static EComponentInfo *
-component_info_new (const gchar *id,
- GNOME_Evolution_Component iface,
- const gchar *alias,
- const gchar *button_label,
- const gchar *button_tooltips,
- const gchar *menu_label,
- const gchar *menu_accelerator,
- const gchar *icon_name,
- gint sort_order)
-{
- EComponentInfo *info = g_new0 (EComponentInfo, 1);
-
- info->id = g_strdup (id);
- info->iface = bonobo_object_dup_ref(iface, NULL);
- info->alias = g_strdup (alias);
- info->button_label = g_strdup (button_label);
- info->button_tooltips = g_strdup (button_tooltips);
- info->menu_label = g_strdup (menu_label);
- info->menu_accelerator = g_strdup (menu_accelerator);
- info->icon_name = g_strdup (icon_name);
- info->sort_order = sort_order;
-
- return info;
-}
-
-static void
-component_info_free (EComponentInfo *info)
-{
- g_free (info->id);
- g_free (info->alias);
- g_free (info->button_label);
- g_free (info->button_tooltips);
- g_free (info->menu_label);
- g_free (info->menu_accelerator);
-
- if (info->iface != NULL)
- bonobo_object_release_unref (info->iface, NULL);
-
- g_slist_foreach (info->uri_schemas, (GFunc) g_free, NULL);
- g_slist_free (info->uri_schemas);
-
- g_free (info);
-}
-
-static gint
-component_info_compare_func (EComponentInfo *a,
- EComponentInfo *b)
-{
- if (a->sort_order != b->sort_order)
- return a->sort_order - b->sort_order;
-
- return strcmp (a->button_label, b->button_label);
-}
-
-/* Utility methods. */
-
-static void
-set_schemas (EComponentInfo *component_info,
- Bonobo_ServerInfo *server_info)
-{
- Bonobo_ActivationProperty *property = bonobo_server_info_prop_find (server_info, "evolution:uri_schemas");
- Bonobo_StringList *list;
- gint i;
-
- if (property == NULL)
- return;
-
- if (property->v._d != Bonobo_ACTIVATION_P_STRINGV) {
- CORBA_free (property);
- return;
- }
-
- list = & property->v._u.value_stringv;
-
- for (i = 0; i < list->_length; i ++)
- component_info->uri_schemas = g_slist_prepend (component_info->uri_schemas, g_strdup (list->_buffer [i]));
-
- CORBA_free (property);
-}
-
-static void
-query_components (EComponentRegistry *registry)
-{
- Bonobo_ServerInfoList *info_list;
- const gchar * const *language_names;
- CORBA_Environment ev;
- GSList *languages = NULL;
- gchar *query;
- gint i;
-
- if (registry->priv->init)
- return;
-
- registry->priv->init = TRUE;
-
- CORBA_exception_init (&ev);
- query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/Component:%s')", BASE_VERSION);
- info_list = bonobo_activation_query (query, NULL, &ev);
- g_free (query);
-
- if (BONOBO_EX (&ev)) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot query for components: %s\n", ex_text);
- g_free (ex_text);
- CORBA_exception_free (&ev);
- return;
- }
-
- language_names = g_get_language_names ();
- while (*language_names != NULL)
- languages = g_slist_append (languages, (gpointer)(*language_names++));
-
- for (i = 0; i < info_list->_length; i++) {
- const gchar *id;
- const gchar *label;
- const gchar *menu_label;
- const gchar *menu_accelerator;
- const gchar *alias;
- const gchar *icon_name;
- const gchar *sort_order_string;
- const gchar *tooltips;
- EComponentInfo *info;
- gint sort_order;
- GNOME_Evolution_Component iface;
-
- id = info_list->_buffer[i].iid;
- iface = bonobo_activation_activate_from_id ((gchar *)id, 0, NULL, &ev);
- if (BONOBO_EX (&ev) || iface == CORBA_OBJECT_NIL) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
-
- g_warning("Cannot activate '%s': %s\n", id, ex_text);
- g_free(ex_text);
- CORBA_exception_free(&ev);
- CORBA_exception_init(&ev);
- continue;
- }
-
- label = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:button_label", languages);
-
- tooltips = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:button_tooltips", languages);
-
- menu_label = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:menu_label", languages);
-
- menu_accelerator = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:menu_accelerator", languages);
-
- alias = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:component_alias", NULL);
-
- icon_name = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:button_icon", NULL);
-
- sort_order_string = bonobo_server_info_prop_lookup (& info_list->_buffer[i],
- "evolution:button_sort_order", NULL);
- if (sort_order_string == NULL)
- sort_order = 0;
- else
- sort_order = atoi (sort_order_string);
-
- info = component_info_new (id, iface, alias, label, tooltips, menu_label,
- menu_accelerator, icon_name, sort_order);
- set_schemas (info, & info_list->_buffer [i]);
-
- registry->priv->infos = g_slist_prepend (registry->priv->infos, info);
-
- bonobo_object_release_unref(iface, NULL);
- }
- g_slist_free(languages);
-
- CORBA_free (info_list);
- CORBA_exception_free (&ev);
-
- registry->priv->infos = g_slist_sort (registry->priv->infos,
- (GCompareFunc) component_info_compare_func);
-}
-
-/* GObject methods. */
-
-static void
-impl_finalize (GObject *object)
-{
- EComponentRegistry *component_registry;
- EComponentRegistryPrivate *priv;
-
- component_registry = E_COMPONENT_REGISTRY (object);
- priv = component_registry->priv;
-
- g_slist_foreach (priv->infos, (GFunc) component_info_free, NULL);
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_component_registry_parent_class)->finalize) (object);
-}
-
-static void
-e_component_registry_class_init (EComponentRegistryClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_component_registry_init (EComponentRegistry *registry)
-{
- registry->priv = g_new0 (EComponentRegistryPrivate, 1);
-}
-
-EComponentRegistry *
-e_component_registry_new (void)
-{
- return g_object_new (e_component_registry_get_type (), NULL);
-}
-
-GSList *
-e_component_registry_peek_list (EComponentRegistry *registry)
-{
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), NULL);
-
- query_components(registry);
-
- return registry->priv->infos;
-}
-
-EComponentInfo *
-e_component_registry_peek_info (EComponentRegistry *registry,
- enum _EComponentRegistryField field,
- const gchar *key)
-{
- GSList *p, *q;
-
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), NULL);
-
- query_components(registry);
-
- for (p = registry->priv->infos; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
-
- switch (field) {
- case ECR_FIELD_ID:
- if (info->id && (strcmp (info->id, key) == 0))
- return info;
- break;
- case ECR_FIELD_ALIAS:
- if (info->alias && (strcmp (info->alias, key) == 0))
- return info;
- break;
- case ECR_FIELD_SCHEMA:
- for (q = info->uri_schemas; q != NULL; q = q->next)
- if (strcmp((gchar *)q->data, key) == 0)
- return info;
- break;
- }
- }
-
- return NULL;
-}
-
-GNOME_Evolution_Component
-e_component_registry_activate (EComponentRegistry *registry,
- const gchar *id,
- CORBA_Environment *ev)
-{
- EComponentInfo *info;
-
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), CORBA_OBJECT_NIL);
-
- info = e_component_registry_peek_info (registry, ECR_FIELD_ID, id);
- if (info == NULL) {
- g_warning ("%s - Unknown id \"%s\"", G_STRFUNC, id);
- return CORBA_OBJECT_NIL;
- }
-
- /* it isn't in the registry unless it is already activated */
- return bonobo_object_dup_ref (info->iface, NULL);
-}
diff --git a/shell/e-component-registry.h b/shell/e-component-registry.h
deleted file mode 100644
index 373912db03..0000000000
--- a/shell/e-component-registry.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_COMPONENT_REGISTRY_H__
-#define __E_COMPONENT_REGISTRY_H__
-
-#include "Evolution.h"
-
-#include <glib-object.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_COMPONENT_REGISTRY (e_component_registry_get_type ())
-#define E_COMPONENT_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMPONENT_REGISTRY, EComponentRegistry))
-#define E_COMPONENT_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMPONENT_REGISTRY, EComponentRegistryClass))
-#define E_IS_COMPONENT_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
-#define E_IS_COMPONENT_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
-
-typedef struct _EComponentRegistry EComponentRegistry;
-typedef struct _EComponentRegistryPrivate EComponentRegistryPrivate;
-typedef struct _EComponentRegistryClass EComponentRegistryClass;
-
-struct _EComponentRegistry {
- GObject parent;
-
- EComponentRegistryPrivate *priv;
-};
-
-struct _EComponentRegistryClass {
- GObjectClass parent_class;
-};
-
-enum _EComponentRegistryField {
- ECR_FIELD_ID,
- ECR_FIELD_ALIAS,
- ECR_FIELD_SCHEMA
-};
-
-struct _EComponentInfo {
- gchar *id;
-
- gchar *alias;
-
- /* NULL if not activated. */
- GNOME_Evolution_Component iface;
-
- gchar *button_label;
- gchar *button_tooltips;
- gchar *menu_label;
- gchar *menu_accelerator;
- gchar *icon_name;
-
- gint sort_order;
-
- /* List of URI schemas that this component supports. */
- GSList *uri_schemas; /* <char *> */
-};
-typedef struct _EComponentInfo EComponentInfo;
-
-GType e_component_registry_get_type (void);
-EComponentRegistry *e_component_registry_new (void);
-
-GSList *e_component_registry_peek_list (EComponentRegistry *registry);
-EComponentInfo *e_component_registry_peek_info (EComponentRegistry *registry,
- enum _EComponentRegistryField type,
- const gchar *key);
-
-GNOME_Evolution_Component e_component_registry_activate (EComponentRegistry *registry,
- const gchar *id,
- CORBA_Environment *ev);
-
-G_END_DECLS
-
-#endif /* __E_COMPONENT_REGISTRY_H__ */
diff --git a/shell/e-component-view.c b/shell/e-component-view.c
deleted file mode 100644
index 58ea3f9a89..0000000000
--- a/shell/e-component-view.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Helper class for evolution components to setup a view
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include "e-component-view.h"
-
-#include "bonobo/bonobo-control.h"
-
-static BonoboObjectClass *parent_class = NULL;
-
-static void
-impl_ComponentView_getControls(PortableServer_Servant servant,
- Bonobo_Control *side_control,
- Bonobo_Control *view_control,
- Bonobo_Control *statusbar_control,
- CORBA_Environment *ev)
-{
- EComponentView *ecv = (EComponentView *)bonobo_object_from_servant(servant);
-
- *side_control = CORBA_Object_duplicate (BONOBO_OBJREF (ecv->side_control), ev);
- *view_control = CORBA_Object_duplicate (BONOBO_OBJREF (ecv->view_control), ev);
- *statusbar_control = CORBA_Object_duplicate (BONOBO_OBJREF (ecv->statusbar_control), ev);
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- EComponentView *ecv = (EComponentView *)object;
-
- ecv->side_control = NULL;
- ecv->view_control = NULL;
- ecv->statusbar_control = NULL;
-
- ((GObjectClass *)parent_class)->dispose(object);
-}
-
-static void
-impl_finalise (GObject *object)
-{
- EComponentView *ecv = (EComponentView *)object;
-
- g_free(ecv->id);
-
- ((GObjectClass *)parent_class)->finalize(object);
-}
-
-static void
-e_component_view_class_init (EComponentViewClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_ComponentView__epv *epv;
-
- parent_class = g_type_class_ref(bonobo_object_get_type());
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalise;
-
- epv = & klass->epv;
- epv->getControls = impl_ComponentView_getControls;
-}
-
-static void
-e_component_view_init (EComponentView *shell)
-{
-}
-
-EComponentView *e_component_view_new(GNOME_Evolution_ShellView parent, const gchar *id, GtkWidget *side, GtkWidget *view, GtkWidget *statusbar)
-{
- EComponentView *new = g_object_new (e_component_view_get_type (), NULL);
- CORBA_Environment ev = { NULL };
-
- new->id = g_strdup(id);
- new->shell_view = CORBA_Object_duplicate(parent, &ev);
- CORBA_exception_free(&ev);
-
- /* FIXME: hook onto destroys */
- new->side_control = bonobo_control_new(side);
- new->view_control = bonobo_control_new(view);
- new->statusbar_control = bonobo_control_new(statusbar);
-
- return new;
-}
-
-EComponentView *e_component_view_new_controls(GNOME_Evolution_ShellView parent, const gchar *id, BonoboControl *side, BonoboControl *view, BonoboControl *statusbar)
-{
- EComponentView *new = g_object_new (e_component_view_get_type (), NULL);
- CORBA_Environment ev = { NULL };
-
- new->id = g_strdup(id);
- new->shell_view = CORBA_Object_duplicate(parent, &ev);
- CORBA_exception_free(&ev);
-
- /* FIXME: hook onto destroys */
- new->side_control = side;
- new->view_control = view;
- new->statusbar_control = statusbar;
-
- return new;
-}
-
-void
-e_component_view_set_title(EComponentView *ecv, const gchar *title)
-{
- CORBA_Environment ev = { NULL };
-
- /* save roundtrips, check title is the same */
- GNOME_Evolution_ShellView_setTitle(ecv->shell_view, ecv->id, title, &ev);
- CORBA_exception_free(&ev);
-}
-
-void
-e_component_view_set_button_icon (EComponentView *ecv, const gchar *iconName)
-{
- CORBA_Environment ev = { NULL };
-
- /* save roundtrips, check title is the same */
- GNOME_Evolution_ShellView_setButtonIcon(ecv->shell_view, ecv->id, iconName, &ev);
- CORBA_exception_free(&ev);
-}
-
-BONOBO_TYPE_FUNC_FULL (EComponentView, GNOME_Evolution_ComponentView, bonobo_object_get_type(), e_component_view)
-
diff --git a/shell/e-component-view.h b/shell/e-component-view.h
deleted file mode 100644
index ca40e3c381..0000000000
--- a/shell/e-component-view.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_COMPONENT_VIEW_H_
-#define _E_COMPONENT_VIEW_H_
-
-#include <gtk/gtk.h>
-#include <bonobo/bonobo-object.h>
-
-G_BEGIN_DECLS
-
-typedef struct _EComponentView EComponentView;
-typedef struct _EComponentViewPrivate EComponentViewPrivate;
-typedef struct _EComponentViewClass EComponentViewClass;
-
-#include "Evolution.h"
-
-#define E_TYPE_COMPONENT_VIEW (e_component_view_get_type ())
-#define E_COMPONENT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMPONENT_VIEW, EComponentView))
-#define E_COMPONENT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMPONENT_VIEW, EComponentViewClass))
-#define E_IS_COMPONENT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMPONENT_VIEW))
-#define E_IS_COMPONENT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMPONENT_VIEW))
-
-struct _EComponentView {
- BonoboObject parent;
-
- EComponentViewPrivate *priv;
-
- gchar *id;
- GNOME_Evolution_ShellView shell_view;
-
- struct _BonoboControl *side_control;
- struct _BonoboControl *view_control;
- struct _BonoboControl *statusbar_control;
-};
-
-struct _EComponentViewClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_ComponentView__epv epv;
-};
-
-GType e_component_view_get_type(void);
-EComponentView *e_component_view_new(GNOME_Evolution_ShellView shell_view, const gchar *id, GtkWidget *side, GtkWidget *view, GtkWidget *status);
-EComponentView *e_component_view_new_controls(GNOME_Evolution_ShellView parent, const gchar *id, struct _BonoboControl *side, struct _BonoboControl *view, struct _BonoboControl *statusbar);
-
-void e_component_view_set_title(EComponentView *ecv, const gchar *title);
-void e_component_view_set_button_icon (EComponentView *ecv, const gchar *iconName);
-
-G_END_DECLS
-
-#endif /* _E_COMPONENT_VIEW_H_ */
-
diff --git a/shell/e-corba-config-page.c b/shell/e-corba-config-page.c
deleted file mode 100644
index 02f8a631d3..0000000000
--- a/shell/e-corba-config-page.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-corba-config-page.h"
-
-#include "Evolution.h"
-
-#include <string.h>
-
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-listener.h>
-
-struct _ECorbaConfigPagePrivate {
- GNOME_Evolution_ConfigControl config_control_interface;
-};
-
-G_DEFINE_TYPE (ECorbaConfigPage, e_corba_config_page, E_TYPE_CONFIG_PAGE)
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- ECorbaConfigPage *corba_config_page;
- ECorbaConfigPagePrivate *priv;
- CORBA_Environment ev;
-
- corba_config_page = E_CORBA_CONFIG_PAGE (object);
- priv = corba_config_page->priv;
-
- CORBA_exception_init (&ev);
-
- if (priv->config_control_interface != CORBA_OBJECT_NIL) {
- bonobo_object_release_unref (priv->config_control_interface, &ev);
- priv->config_control_interface = CORBA_OBJECT_NIL;
- }
-
- CORBA_exception_free (&ev);
-
- (* G_OBJECT_CLASS (e_corba_config_page_parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- ECorbaConfigPage *corba_config_page;
- ECorbaConfigPagePrivate *priv;
-
- corba_config_page = E_CORBA_CONFIG_PAGE (object);
- priv = corba_config_page->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_corba_config_page_parent_class)->finalize) (object);
-}
-
-/* GTK+ ctors. */
-
-static void
-e_corba_config_page_class_init (ECorbaConfigPageClass *class)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_corba_config_page_init (ECorbaConfigPage *corba_config_page)
-{
- ECorbaConfigPagePrivate *priv;
-
- priv = g_new (ECorbaConfigPagePrivate, 1);
- priv->config_control_interface = CORBA_OBJECT_NIL;
-
- corba_config_page->priv = priv;
-}
-
-
-gboolean
-e_corba_config_page_construct (ECorbaConfigPage *corba_config_page,
- GNOME_Evolution_ConfigControl corba_object)
-{
- Bonobo_Control control;
- GtkWidget *control_widget;
- CORBA_Environment ev;
-
- g_return_val_if_fail (E_IS_CORBA_CONFIG_PAGE (corba_config_page), FALSE);
- g_return_val_if_fail (corba_object != CORBA_OBJECT_NIL, FALSE);
-
- CORBA_exception_init (&ev);
-
- control = GNOME_Evolution_ConfigControl__get_control (corba_object, &ev);
- if (BONOBO_EX (&ev)) {
- g_warning ("Can't get control from ::ConfigControl -- %s", BONOBO_EX_REPOID (&ev));
- CORBA_exception_init (&ev);
- return FALSE;
- }
-
- control_widget = bonobo_widget_new_control_from_objref (control, CORBA_OBJECT_NIL);
- gtk_widget_show (control_widget);
- gtk_container_add (GTK_CONTAINER (corba_config_page), control_widget);
-
- /* Notice we *don't* unref the corba_object here as
- bonobo_widget_new_control_from_objref() effectively takes ownership
- for the object that we get from ::__get_control. */
-
- CORBA_exception_free (&ev);
-
- return TRUE;
-}
-
-GtkWidget *
-e_corba_config_page_new_from_objref (GNOME_Evolution_ConfigControl corba_object)
-{
- ECorbaConfigPage *corba_config_page;
-
- g_return_val_if_fail (corba_object != CORBA_OBJECT_NIL, NULL);
- g_return_val_if_fail (corba_object != CORBA_OBJECT_NIL, NULL);
-
- corba_config_page = g_object_new (e_corba_config_page_get_type (), NULL);
- if (! e_corba_config_page_construct (corba_config_page, corba_object)) {
- gtk_widget_destroy (GTK_WIDGET (corba_config_page));
- return NULL;
- }
-
- return GTK_WIDGET (corba_config_page);
-}
diff --git a/shell/e-corba-config-page.h b/shell/e-corba-config-page.h
deleted file mode 100644
index a09b86d0fe..0000000000
--- a/shell/e-corba-config-page.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CORBA_CONFIG_PAGE_H_
-#define _E_CORBA_CONFIG_PAGE_H_
-
-#include "e-config-page.h"
-
-#include "Evolution.h"
-
-#include <bonobo/bonobo-object.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_CORBA_CONFIG_PAGE (e_corba_config_page_get_type ())
-#define E_CORBA_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CORBA_CONFIG_PAGE, ECorbaConfigPage))
-#define E_CORBA_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CORBA_CONFIG_PAGE, ECorbaConfigPageClass))
-#define E_IS_CORBA_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CORBA_CONFIG_PAGE))
-#define E_IS_CORBA_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CORBA_CONFIG_PAGE))
-
-
-typedef struct _ECorbaConfigPage ECorbaConfigPage;
-typedef struct _ECorbaConfigPagePrivate ECorbaConfigPagePrivate;
-typedef struct _ECorbaConfigPageClass ECorbaConfigPageClass;
-
-struct _ECorbaConfigPage {
- EConfigPage parent;
-
- ECorbaConfigPagePrivate *priv;
-};
-
-struct _ECorbaConfigPageClass {
- EConfigPageClass parent_class;
-};
-
-
-GType e_corba_config_page_get_type (void);
-GtkWidget *e_corba_config_page_new_from_objref (GNOME_Evolution_ConfigControl objref);
-gboolean e_corba_config_page_construct (ECorbaConfigPage *corba_config_page,
- GNOME_Evolution_ConfigControl objref);
-
-G_END_DECLS
-
-#endif /* _E_CORBA_CONFIG_PAGE_H_ */
diff --git a/shell/e-shell-backend.c b/shell/e-shell-backend.c
new file mode 100644
index 0000000000..c996d8ab01
--- /dev/null
+++ b/shell/e-shell-backend.c
@@ -0,0 +1,403 @@
+/*
+ * e-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-backend.h"
+
+#include <errno.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+
+#include "e-shell.h"
+#include "e-shell-view.h"
+
+#define E_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_BACKEND, EShellBackendPrivate))
+
+struct _EShellBackendPrivate {
+
+ gpointer shell; /* weak pointer */
+
+ /* We keep a reference to corresponding EShellView subclass
+ * since it keeps a reference back to us. This ensures the
+ * subclass is not finalized before we are, otherwise it
+ * would leak its EShellBackend reference. */
+ EShellViewClass *shell_view_class;
+
+ gchar *config_dir;
+ gchar *data_dir;
+
+ guint started : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL
+};
+
+enum {
+ ACTIVITY_ADDED,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+shell_backend_set_shell (EShellBackend *shell_backend,
+ EShell *shell)
+{
+ g_return_if_fail (shell_backend->priv->shell == NULL);
+
+ shell_backend->priv->shell = shell;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_backend),
+ &shell_backend->priv->shell);
+}
+
+static void
+shell_backend_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL:
+ shell_backend_set_shell (
+ E_SHELL_BACKEND (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL:
+ g_value_set_object (
+ value, e_shell_backend_get_shell (
+ E_SHELL_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_backend_dispose (GObject *object)
+{
+ EShellBackendPrivate *priv;
+
+ priv = E_SHELL_BACKEND_GET_PRIVATE (object);
+
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell), &priv->shell);
+ priv->shell = NULL;
+ }
+
+ if (priv->shell_view_class != NULL) {
+ g_type_class_unref (priv->shell_view_class);
+ priv->shell_view_class = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_backend_finalize (GObject *object)
+{
+ EShellBackendPrivate *priv;
+
+ priv = E_SHELL_BACKEND_GET_PRIVATE (object);
+
+ g_free (priv->data_dir);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_backend_class_init (EShellBackendClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_backend_set_property;
+ object_class->get_property = shell_backend_get_property;
+ object_class->dispose = shell_backend_dispose;
+ object_class->finalize = shell_backend_finalize;
+
+ /**
+ * EShellBackend:shell
+ *
+ * The #EShell singleton.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ _("Shell"),
+ _("The EShell singleton"),
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellBackend::activity-added
+ * @shell_backend: the #EShellBackend that emitted the signal
+ * @activity: an #EActivity
+ *
+ * Broadcasts a newly added activity.
+ **/
+ signals[ACTIVITY_ADDED] = g_signal_new (
+ "activity-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+}
+
+static void
+shell_backend_init (EShellBackend *shell_backend,
+ EShellBackendClass *class)
+{
+ EShellViewClass *shell_view_class;
+ gchar *dirname;
+
+ shell_backend->priv = E_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ /* Install a reference to ourselves in the corresponding
+ * EShellViewClass structure, */
+ shell_view_class = g_type_class_ref (class->shell_view_type);
+ shell_view_class->shell_backend = g_object_ref (shell_backend);
+ shell_backend->priv->shell_view_class = shell_view_class;
+
+ /* Determine the user data directory for this backend. */
+ shell_backend->priv->data_dir = g_build_filename (
+ e_get_user_data_dir (), class->name, NULL);
+
+ /* Determine the user configuration directory for this backend. */
+ shell_backend->priv->config_dir = g_build_filename (
+ shell_backend->priv->data_dir, "config", NULL);
+
+ /* Create the user configuration directory for this backend,
+ * which should also create the user data directory. */
+ dirname = shell_backend->priv->config_dir;
+ if (g_mkdir_with_parents (dirname, 0777) != 0)
+ g_critical (
+ "Cannot create directory %s: %s",
+ dirname, g_strerror (errno));
+}
+
+GType
+e_shell_backend_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_backend_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EShellBackend", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_backend_compare:
+ * @shell_backend_a: an #EShellBackend
+ * @shell_backend_b: an #EShellBackend
+ *
+ * Using the <structfield>sort_order</structfield> field from both backends'
+ * #EShellBackendClass, compares @shell_backend_a with @shell_mobule_b and
+ * returns -1, 0 or +1 if @shell_backend_a is found to be less than, equal
+ * to or greater than @shell_backend_b, respectively.
+ *
+ * Returns: -1, 0 or +1, for a less than, equal to or greater than result
+ **/
+gint
+e_shell_backend_compare (EShellBackend *shell_backend_a,
+ EShellBackend *shell_backend_b)
+{
+ gint a = E_SHELL_BACKEND_GET_CLASS (shell_backend_a)->sort_order;
+ gint b = E_SHELL_BACKEND_GET_CLASS (shell_backend_b)->sort_order;
+
+ return (a < b) ? -1 : (a > b);
+}
+
+/**
+ * e_shell_backend_get_config_dir:
+ * @shell_backend: an #EShellBackend
+ *
+ * Returns the absolute path to the configuration directory for
+ * @shell_backend. The string is owned by @shell_backend and should
+ * not be modified or freed.
+ *
+ * Returns: the backend's configuration directory
+ **/
+const gchar *
+e_shell_backend_get_config_dir (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+ g_return_val_if_fail (shell_backend->priv->config_dir != NULL, NULL);
+
+ return shell_backend->priv->config_dir;
+}
+
+/**
+ * e_shell_backend_get_data_dir:
+ * @shell_backend: an #EShellBackend
+ *
+ * Returns the absolute path to the data directory for @shell_backend.
+ * The string is owned by @shell_backend and should not be modified or
+ * freed.
+ *
+ * Returns: the backend's data directory
+ **/
+const gchar *
+e_shell_backend_get_data_dir (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+ g_return_val_if_fail (shell_backend->priv->data_dir != NULL, NULL);
+
+ return shell_backend->priv->data_dir;
+}
+
+/**
+ * e_shell_backend_get_shell:
+ * @shell_backend: an #EShellBackend
+ *
+ * Returns the #EShell singleton.
+ *
+ * Returns: the #EShell
+ **/
+EShell *
+e_shell_backend_get_shell (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
+ return E_SHELL (shell_backend->priv->shell);
+}
+
+/**
+ * e_shell_backend_add_activity:
+ * @shell_backend: an #EShellBackend
+ * @activity: an #EActivity
+ *
+ * Emits an #EShellBackend::activity-added signal.
+ **/
+void
+e_shell_backend_add_activity (EShellBackend *shell_backend,
+ EActivity *activity)
+{
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ g_signal_emit (shell_backend, signals[ACTIVITY_ADDED], 0, activity);
+}
+
+/**
+ * e_shell_backend_start:
+ * @shell_backend: an #EShellBackend
+ *
+ * Tells the @shell_backend to begin loading data or running background
+ * tasks which may consume significant resources. This gets called in
+ * reponse to the user switching to the corresponding #EShellView for
+ * the first time. The function is idempotent for each @shell_backend.
+ **/
+void
+e_shell_backend_start (EShellBackend *shell_backend)
+{
+ EShellBackendClass *class;
+
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+
+ if (shell_backend->priv->started)
+ return;
+
+ class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+
+ if (class->start != NULL)
+ class->start (shell_backend);
+
+ shell_backend->priv->started = TRUE;
+}
+
+/**
+ * e_shell_migrate:
+ * @shell_backend: an #EShellBackend
+ * @major: major part of version to migrate from
+ * @minor: minor part of version to migrate from
+ * @micro: micro part of version to migrate from
+ * @error: return location for a #GError, or %NULL
+ *
+ * Attempts to migrate data and settings from version %major.%minor.%micro.
+ * Returns %TRUE if the migration was successful or if no action was
+ * necessary. Returns %FALSE and sets %error if the migration failed.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise
+ **/
+gboolean
+e_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ EShellBackendClass *class;
+
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), TRUE);
+
+ class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+
+ if (class->migrate == NULL)
+ return TRUE;
+
+ return class->migrate (shell_backend, major, minor, micro, error);
+}
diff --git a/shell/e-shell-backend.h b/shell/e-shell-backend.h
new file mode 100644
index 0000000000..6dbbb33ea1
--- /dev/null
+++ b/shell/e-shell-backend.h
@@ -0,0 +1,139 @@
+/*
+ * e-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-backend
+ * @short_description: dynamically loaded capabilities
+ * @include: shell/e-shell-backend.h
+ **/
+
+#ifndef E_SHELL_BACKEND_H
+#define E_SHELL_BACKEND_H
+
+#include <shell/e-shell-common.h>
+#include <misc/e-activity.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_BACKEND \
+ (e_shell_backend_get_type ())
+#define E_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_BACKEND, EShellBackend))
+#define E_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_BACKEND, EShellBackendClass))
+#define E_IS_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_BACKEND))
+#define E_IS_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_BACKEND))
+#define E_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_BACKEND, EShellBackendClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell.h>, because it includes us! */
+struct _EShell;
+
+typedef struct _EShellBackend EShellBackend;
+typedef struct _EShellBackendClass EShellBackendClass;
+typedef struct _EShellBackendPrivate EShellBackendPrivate;
+
+/**
+ * EShellBackend:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellBackend {
+ GObject parent;
+ EShellBackendPrivate *priv;
+};
+
+/**
+ * EShellBackendClass:
+ * @parent_class: The parent class structure.
+ * @name: The name of the backend. Also becomes the name of
+ * the corresponding #EShellView subclass that the
+ * backend will register.
+ * @aliases: Colon-separated list of aliases that can be used
+ * when referring to a backend by name.
+ * @schemes: Colon-separated list of URI schemes. The #EShell
+ * will forward command-line URIs to the appropriate
+ * backend based on this list.
+ * @sort_order: Used to determine the order of backends listed in
+ * the main menu and in the switcher. See
+ * e_shell_backend_compare().
+ * @shell_view_type: #GType for the corresponding #EShellView subclass.
+ * @start: Method for notifying the backend to begin loading
+ * data and running background tasks. This is called
+ * just before the first instantiation of the
+ * corresponding #EShellView subclass. It allows the
+ * backend to delay initialization steps that consume
+ * significant resources until they are actually needed.
+ * @migrate: Method for notifying the backend to migrate data and
+ * settings from the given version. Returns %TRUE if the
+ * migration was successful or if no action was necessary.
+ * Returns %FALSE and sets a #GError if the migration
+ * failed.
+ *
+ * #EShellBackendClass contains a number of important settings for subclasses.
+ **/
+struct _EShellBackendClass {
+ GObjectClass parent_class;
+
+ GType shell_view_type;
+
+ const gchar *name;
+ const gchar *aliases;
+ const gchar *schemes;
+ gint sort_order;
+
+ /* Methods */
+ void (*start) (EShellBackend *shell_backend);
+ gboolean (*migrate) (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+};
+
+GType e_shell_backend_get_type (void);
+gint e_shell_backend_compare (EShellBackend *shell_backend_a,
+ EShellBackend *shell_backend_b);
+const gchar * e_shell_backend_get_config_dir (EShellBackend *shell_backend);
+const gchar * e_shell_backend_get_data_dir (EShellBackend *shell_backend);
+const gchar * e_shell_backend_get_filename (EShellBackend *shell_backend);
+struct _EShell *e_shell_backend_get_shell (EShellBackend *shell_backend);
+void e_shell_backend_add_activity (EShellBackend *shell_backend,
+ EActivity *activity);
+void e_shell_backend_start (EShellBackend *shell_backend);
+gboolean e_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_SHELL_BACKEND_H */
diff --git a/shell/importer/intelligent.h b/shell/e-shell-common.h
index 5f5f7187f2..7ff35091aa 100644
--- a/shell/importer/intelligent.h
+++ b/shell/e-shell-common.h
@@ -1,4 +1,6 @@
/*
+ * e-shell-common.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,16 +15,19 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Kjartan Maraas <kmaraas@gnome.org>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef __INTELLIGENT_H__
-#define __INTELLIGENT_H__
-
-void intelligent_importer_init (void);
+#ifndef E_SHELL_COMMON_H
+#define E_SHELL_COMMON_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#endif /* E_SHELL_COMMON_H */
diff --git a/shell/e-shell-constants.h b/shell/e-shell-constants.h
deleted file mode 100644
index 13beed8aec..0000000000
--- a/shell/e-shell-constants.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_SHELL_CONSTANTS_H
-#define E_SHELL_CONSTANTS_H
-
-#define E_SHELL_URI_PREFIX "evolution:"
-#define E_SHELL_URI_PREFIX_LEN 10
-
-#define E_SHELL_DEFAULTURI_PREFIX "default:"
-#define E_SHELL_DEFAULTURI_PREFIX_LEN 8
-
-#define E_SHELL_MINI_ICON_SUFFIX "-mini"
-#define E_SHELL_MINI_ICON_SUFFIX_LEN 5
-
-#define E_SHELL_ICON_SIZE 48
-#define E_SHELL_MINI_ICON_SIZE 16
-
-#define E_PATH_SEPARATOR '/'
-#define E_PATH_SEPARATOR_S "/"
-
-#define E_LOCAL_STORAGE_NAME "local"
-#define E_SUMMARY_STORAGE_NAME "summary"
-
-#define E_SUMMARY_URI "evolution:/summary"
-#define E_LOCAL_INBOX_URI "evolution:/local/Inbox"
-#define E_LOCAL_CONTACTS_URI "evolution:/local/Contacts"
-#define E_LOCAL_CALENDAR_URI "evolution:/local/Calendar"
-#define E_LOCAL_TASKS_URI "evolution:/local/Tasks"
-
-#endif
diff --git a/shell/e-shell-content.c b/shell/e-shell-content.c
new file mode 100644
index 0000000000..2fc9569bd2
--- /dev/null
+++ b/shell/e-shell-content.c
@@ -0,0 +1,1559 @@
+/*
+ * e-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-content.h"
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-util.h"
+#include "filter/rule-editor.h"
+#include "widgets/misc/e-action-combo-box.h"
+#include "widgets/misc/e-hinted-entry.h"
+
+#include "e-shell-backend.h"
+#include "e-shell-view.h"
+#include "e-shell-window-actions.h"
+
+#define E_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_CONTENT, EShellContentPrivate))
+
+#define STATE_KEY_SEARCH_FILTER "SearchFilter"
+#define STATE_KEY_SEARCH_SCOPE "SearchScope"
+#define STATE_KEY_SEARCH_TEXT "SearchText"
+
+struct _EShellContentPrivate {
+
+ gpointer shell_view; /* weak pointer */
+
+ RuleContext *search_context;
+ FilterRule *search_rule;
+ gchar *system_filename;
+ gchar *user_filename;
+
+ /* Container for the following widgets */
+ GtkWidget *search_bar;
+
+ /* Search bar widgets */
+ GtkWidget *filter_label;
+ GtkWidget *filter_combo_box;
+ GtkWidget *search_label;
+ GtkWidget *search_entry;
+ GtkWidget *scope_label;
+ GtkWidget *scope_combo_box;
+};
+
+enum {
+ PROP_0,
+ PROP_FILTER_ACTION,
+ PROP_FILTER_VALUE,
+ PROP_FILTER_VISIBLE,
+ PROP_SEARCH_CONTEXT,
+ PROP_SEARCH_HINT,
+ PROP_SEARCH_RULE,
+ PROP_SEARCH_TEXT,
+ PROP_SEARCH_VISIBLE,
+ PROP_SCOPE_ACTION,
+ PROP_SCOPE_VALUE,
+ PROP_SCOPE_VISIBLE,
+ PROP_SHELL_VIEW
+};
+
+static gpointer parent_class;
+
+static void
+shell_content_dialog_rule_changed (GtkWidget *dialog,
+ FilterRule *rule)
+{
+ gboolean sensitive;
+
+ sensitive = (rule != NULL) && (rule->parts != NULL);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_APPLY, sensitive);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ EShellContent *shell_content)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkWidget *widget;
+ const gchar *search_text;
+
+ /* EShellView subclasses are responsible for actually
+ * executing the search. This is all cosmetic stuff. */
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ widget = shell_content->priv->search_entry;
+
+ search_text = e_shell_content_get_search_text (shell_content);
+
+ if (search_text != NULL && *search_text != '\0') {
+ GtkStyle *style;
+ const GdkColor *color;
+
+ style = gtk_widget_get_style (widget);
+ color = &style->base[GTK_STATE_SELECTED];
+ gtk_widget_modify_base (widget, GTK_STATE_NORMAL, color);
+
+ style = gtk_widget_get_style (widget);
+ color = &style->text[GTK_STATE_SELECTED];
+ gtk_widget_modify_text (widget, GTK_STATE_NORMAL, color);
+ } else {
+ /* Text color will be updated when we move the focus. */
+ gtk_widget_modify_base (widget, GTK_STATE_NORMAL, NULL);
+ }
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window);
+ gtk_action_set_sensitive (action, TRUE);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_SAVE (shell_window);
+ gtk_action_set_sensitive (action, TRUE);
+
+ /* Direct the focus away from the search entry, so that a
+ * focus-in event is required before the text can be changed.
+ * This will reset the entry to the appropriate visual state. */
+ widget = gtk_bin_get_child (GTK_BIN (shell_content));
+ if (GTK_IS_PANED (widget))
+ widget = gtk_paned_get_child1 (GTK_PANED (widget));
+ gtk_widget_grab_focus (widget);
+}
+
+static void
+shell_content_entry_activated_cb (EShellContent *shell_content,
+ GtkWidget *entry)
+{
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkAction *action;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Verify the shell view is active before proceeding. */
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window);
+ gtk_action_activate (action);
+}
+
+static void
+shell_content_entry_icon_press_cb (EShellContent *shell_content,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+
+ /* Show the search options menu when the icon is pressed. */
+
+ if (icon_pos != GTK_ENTRY_ICON_PRIMARY)
+ return;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS (shell_window);
+ gtk_action_activate (action);
+}
+
+static void
+shell_content_entry_icon_release_cb (EShellContent *shell_content,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+
+ /* Clear the search when the icon is pressed and released. */
+
+ if (icon_pos != GTK_ENTRY_ICON_SECONDARY)
+ return;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window);
+ gtk_action_activate (action);
+}
+
+static gboolean
+shell_content_entry_key_press_cb (EShellContent *shell_content,
+ GdkEventKey *key_event,
+ GtkWidget *entry)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ guint mask;
+
+ mask = gtk_accelerator_get_default_mod_mask ();
+ if ((key_event->state & mask) != GDK_MOD1_MASK)
+ return FALSE;
+
+ if (key_event->keyval != GDK_Down)
+ return FALSE;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS (shell_window);
+ gtk_action_activate (action);
+
+ return TRUE;
+}
+
+static void
+shell_content_init_search_context (EShellContent *shell_content)
+{
+ EShellContentClass *shell_content_class;
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ EShellBackend *shell_backend;
+ RuleContext *context;
+ FilterRule *rule;
+ FilterPart *part;
+ gchar *system_filename;
+ gchar *user_filename;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ g_return_if_fail (shell_view_class->search_rules != NULL);
+
+ shell_content_class = E_SHELL_CONTENT_GET_CLASS (shell_content);
+ g_return_if_fail (shell_content_class->new_search_context != NULL);
+
+ /* The basename for built-in searches is specified in the
+ * shell view class. All built-in search rules live in the
+ * same directory. */
+ system_filename = g_build_filename (
+ EVOLUTION_RULEDIR, shell_view_class->search_rules, NULL);
+
+ /* The filename for custom saved searches is always of
+ * the form "$(shell_backend_data_dir)/searches.xml". */
+ user_filename = g_build_filename (
+ e_shell_backend_get_data_dir (shell_backend),
+ "searches.xml", NULL);
+
+ context = shell_content_class->new_search_context ();
+ rule_context_add_part_set (
+ context, "partset", FILTER_TYPE_PART,
+ rule_context_add_part, rule_context_next_part);
+ rule_context_add_rule_set (
+ context, "ruleset", FILTER_TYPE_RULE,
+ rule_context_add_rule, rule_context_next_rule);
+ rule_context_load (context, system_filename, user_filename);
+
+ /* XXX Not sure why this is necessary. */
+ g_object_set_data_full (
+ G_OBJECT (context), "system",
+ g_strdup (system_filename), g_free);
+ g_object_set_data_full (
+ G_OBJECT (context), "user",
+ g_strdup (user_filename), g_free);
+
+ rule = filter_rule_new ();
+ part = rule_context_next_part (context, NULL);
+ if (part == NULL)
+ g_warning (
+ "Could not load %s search: no parts",
+ e_shell_view_get_name (shell_view));
+ else
+ filter_rule_add_part (rule, filter_part_clone (part));
+
+ shell_content->priv->search_context = context;
+ shell_content->priv->system_filename = system_filename;
+ shell_content->priv->user_filename = user_filename;
+}
+
+static void
+shell_content_set_shell_view (EShellContent *shell_content,
+ EShellView *shell_view)
+{
+ g_return_if_fail (shell_content->priv->shell_view == NULL);
+
+ shell_content->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &shell_content->priv->shell_view);
+}
+
+static void
+shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FILTER_ACTION:
+ e_shell_content_set_filter_action (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_FILTER_VALUE:
+ e_shell_content_set_filter_value (
+ E_SHELL_CONTENT (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_FILTER_VISIBLE:
+ e_shell_content_set_filter_visible (
+ E_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SEARCH_HINT:
+ e_shell_content_set_search_hint (
+ E_SHELL_CONTENT (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SEARCH_RULE:
+ e_shell_content_set_search_rule (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SEARCH_TEXT:
+ e_shell_content_set_search_text (
+ E_SHELL_CONTENT (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SEARCH_VISIBLE:
+ e_shell_content_set_search_visible (
+ E_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SCOPE_ACTION:
+ e_shell_content_set_scope_action (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SCOPE_VALUE:
+ e_shell_content_set_scope_value (
+ E_SHELL_CONTENT (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_SCOPE_VISIBLE:
+ e_shell_content_set_scope_visible (
+ E_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ shell_content_set_shell_view (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FILTER_ACTION:
+ g_value_set_object (
+ value, e_shell_content_get_filter_action (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_FILTER_VALUE:
+ g_value_set_int (
+ value, e_shell_content_get_filter_value (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_FILTER_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_content_get_filter_visible (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_CONTEXT:
+ g_value_set_object (
+ value, e_shell_content_get_search_context (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_HINT:
+ g_value_set_string (
+ value, e_shell_content_get_search_hint (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_RULE:
+ g_value_set_object (
+ value, e_shell_content_get_search_rule (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_TEXT:
+ g_value_set_string (
+ value, e_shell_content_get_search_text (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_content_get_search_visible (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SCOPE_ACTION:
+ g_value_set_object (
+ value, e_shell_content_get_scope_action (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SCOPE_VALUE:
+ g_value_set_int (
+ value, e_shell_content_get_scope_value (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SCOPE_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_content_get_scope_visible (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_shell_content_get_shell_view (
+ E_SHELL_CONTENT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_content_dispose (GObject *object)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->filter_label != NULL) {
+ g_object_unref (priv->filter_label);
+ priv->filter_label = NULL;
+ }
+
+ if (priv->filter_combo_box != NULL) {
+ g_object_unref (priv->filter_combo_box);
+ priv->filter_combo_box = NULL;
+ }
+
+ if (priv->search_context != NULL) {
+ g_object_unref (priv->search_context);
+ priv->search_context = NULL;
+ }
+
+ if (priv->search_label != NULL) {
+ g_object_unref (priv->search_label);
+ priv->search_label = NULL;
+ }
+
+ if (priv->search_entry != NULL) {
+ g_object_unref (priv->search_entry);
+ priv->search_entry = NULL;
+ }
+
+ if (priv->scope_label != NULL) {
+ g_object_unref (priv->scope_label);
+ priv->scope_label = NULL;
+ }
+
+ if (priv->scope_combo_box != NULL) {
+ g_object_unref (priv->scope_combo_box);
+ priv->scope_combo_box = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_content_finalize (GObject *object)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (object);
+
+ g_free (priv->system_filename);
+ g_free (priv->user_filename);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_content_constructed (GObject *object)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkSizeGroup *size_group;
+ GtkAction *action;
+ GtkWidget *widget;
+
+ shell_content = E_SHELL_CONTENT (object);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ size_group = e_shell_view_get_size_group (shell_view);
+
+ widget = shell_content->priv->search_entry;
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window);
+ e_binding_new (
+ G_OBJECT (action), "sensitive",
+ G_OBJECT (widget), "secondary-icon-sensitive");
+ e_binding_new (
+ G_OBJECT (action), "stock-id",
+ G_OBJECT (widget), "secondary-icon-stock");
+ e_binding_new (
+ G_OBJECT (action), "tooltip",
+ G_OBJECT (widget), "secondary-icon-tooltip-text");
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_search_execute_cb), shell_content);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS (shell_window);
+ e_binding_new (
+ G_OBJECT (action), "sensitive",
+ G_OBJECT (widget), "primary-icon-sensitive");
+ e_binding_new (
+ G_OBJECT (action), "stock-id",
+ G_OBJECT (widget), "primary-icon-stock");
+ e_binding_new (
+ G_OBJECT (action), "tooltip",
+ G_OBJECT (widget), "primary-icon-tooltip-text");
+
+ widget = shell_content->priv->search_bar;
+ gtk_size_group_add_widget (size_group, widget);
+
+ shell_content_init_search_context (shell_content);
+}
+
+static void
+shell_content_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EShellContentPrivate *priv;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (widget);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ gtk_widget_size_request (child, requisition);
+
+ child = priv->search_bar;
+ gtk_widget_size_request (child, &child_requisition);
+ requisition->width = MAX (requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+}
+
+static void
+shell_content_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EShellContentPrivate *priv;
+ GtkAllocation child_allocation;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (widget);
+
+ widget->allocation = *allocation;
+
+ child = priv->search_bar;
+ gtk_widget_size_request (child, &child_requisition);
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width;
+ child_allocation.height = child_requisition.height;
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+ child_allocation.y += child_requisition.height;
+ child_allocation.height =
+ allocation->height - child_requisition.height;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+shell_content_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (container);
+
+ /* Look in the internal widgets first. */
+
+ if (widget == priv->search_bar) {
+ gtk_widget_unparent (priv->search_bar);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ return;
+ }
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static void
+shell_content_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (container);
+
+ if (include_internals)
+ callback (priv->search_bar, callback_data);
+
+ /* Chain up to parent's forall() method. */
+ GTK_CONTAINER_CLASS (parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void
+shell_content_class_init (EShellContentClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_content_set_property;
+ object_class->get_property = shell_content_get_property;
+ object_class->dispose = shell_content_dispose;
+ object_class->finalize = shell_content_finalize;
+ object_class->constructed = shell_content_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = shell_content_size_request;
+ widget_class->size_allocate = shell_content_size_allocate;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = shell_content_remove;
+ container_class->forall = shell_content_forall;
+
+ class->new_search_context = rule_context_new;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILTER_ACTION,
+ g_param_spec_object (
+ "filter-action",
+ NULL,
+ NULL,
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILTER_VALUE,
+ g_param_spec_int (
+ "filter-value",
+ NULL,
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILTER_VISIBLE,
+ g_param_spec_boolean (
+ "filter-visible",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_CONTEXT,
+ g_param_spec_object (
+ "search-context",
+ NULL,
+ NULL,
+ RULE_TYPE_CONTEXT,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_HINT,
+ g_param_spec_string (
+ "search-hint",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_RULE,
+ g_param_spec_object (
+ "search-rule",
+ NULL,
+ NULL,
+ FILTER_TYPE_RULE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_TEXT,
+ g_param_spec_string (
+ "search-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_VISIBLE,
+ g_param_spec_boolean (
+ "search-visible",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCOPE_ACTION,
+ g_param_spec_object (
+ "scope-action",
+ NULL,
+ NULL,
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCOPE_VALUE,
+ g_param_spec_int (
+ "scope-value",
+ NULL,
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCOPE_VISIBLE,
+ g_param_spec_boolean (
+ "scope-visible",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ NULL,
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+shell_content_init (EShellContent *shell_content)
+{
+ GtkBox *box;
+ GtkLabel *label;
+ GtkWidget *widget;
+
+ shell_content->priv = E_SHELL_CONTENT_GET_PRIVATE (shell_content);
+
+ GTK_WIDGET_SET_FLAGS (shell_content, GTK_NO_WINDOW);
+
+ /*** Build the Search Bar ***/
+
+ widget = gtk_hbox_new (FALSE, 24);
+ gtk_widget_set_parent (widget, GTK_WIDGET (shell_content));
+ shell_content->priv->search_bar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ /* Filter Combo Widgets */
+
+ box = GTK_BOX (shell_content->priv->search_bar);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ box = GTK_BOX (widget);
+
+ /* Translators: The "Show:" label precedes a combo box that
+ * allows the user to filter the current view. Examples of
+ * items that appear in the combo box are "Unread Messages",
+ * "Important Messages", or "Active Appointments". */
+ widget = gtk_label_new_with_mnemonic (_("Sho_w:"));
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->filter_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_action_combo_box_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->filter_combo_box = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Search Entry Widgets */
+
+ box = GTK_BOX (shell_content->priv->search_bar);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ box = GTK_BOX (widget);
+
+ /* Translators: This is part of the quick search interface.
+ * example: Search: [_______________] in [ Current Folder ] */
+ widget = gtk_label_new_with_mnemonic (_("Sear_ch:"));
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->search_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_hinted_entry_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
+ shell_content->priv->search_entry = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "activate",
+ G_CALLBACK (shell_content_entry_activated_cb),
+ shell_content);
+
+ g_signal_connect_swapped (
+ widget, "icon-press",
+ G_CALLBACK (shell_content_entry_icon_press_cb),
+ shell_content);
+
+ g_signal_connect_swapped (
+ widget, "icon-release",
+ G_CALLBACK (shell_content_entry_icon_release_cb),
+ shell_content);
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (shell_content_entry_key_press_cb),
+ shell_content);
+
+ /* Scope Combo Widgets */
+
+ /* Translators: This is part of the quick search interface.
+ * example: Search: [_______________] in [ Current Folder ] */
+ widget = gtk_label_new_with_mnemonic (_("i_n"));
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->scope_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_action_combo_box_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->scope_combo_box = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+GType
+e_shell_content_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_content_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_BIN, "EShellContent", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_content_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellContent instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellContent instance
+ **/
+GtkWidget *
+e_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_SHELL_CONTENT, "shell-view", shell_view, NULL);
+}
+
+/**
+ * e_shell_content_check_state:
+ * @shell_content: an #EShellContent
+ *
+ * #EShellContent subclasses should implement the
+ * <structfield>check_state</structfield> method in #EShellContentClass
+ * to return a set of flags describing the current content selection.
+ * Subclasses are responsible for defining their own flags. This is
+ * primarily used to assist shell views with updating actions (see
+ * e_shell_view_update_actions()).
+ *
+ * Returns: a set of flags describing the current @shell_content selection
+ **/
+guint32
+e_shell_content_check_state (EShellContent *shell_content)
+{
+ EShellContentClass *shell_content_class;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+ shell_content_class = E_SHELL_CONTENT_GET_CLASS (shell_content);
+ g_return_val_if_fail (shell_content_class->check_state != NULL, 0);
+
+ return shell_content_class->check_state (shell_content);
+}
+
+/**
+ * e_shell_content_get_shell_view:
+ * @shell_content: an #EShellContent
+ *
+ * Returns the #EShellView that was passed to e_shell_content_new().
+ *
+ * Returns: the #EShellView to which @shell_content belongs
+ **/
+EShellView *
+e_shell_content_get_shell_view (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ return E_SHELL_VIEW (shell_content->priv->shell_view);
+}
+
+GtkRadioAction *
+e_shell_content_get_filter_action (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ return e_action_combo_box_get_action (combo_box);
+}
+
+void
+e_shell_content_set_filter_action (EShellContent *shell_content,
+ GtkRadioAction *filter_action)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_set_action (combo_box, filter_action);
+
+ g_object_notify (G_OBJECT (shell_content), "filter-action");
+}
+
+gint
+e_shell_content_get_filter_value (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ return e_action_combo_box_get_current_value (combo_box);
+}
+
+void
+e_shell_content_set_filter_value (EShellContent *shell_content,
+ gint filter_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_set_current_value (combo_box, filter_value);
+
+ g_object_notify (G_OBJECT (shell_content), "filter-value");
+}
+
+gboolean
+e_shell_content_get_filter_visible (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE);
+
+ return GTK_WIDGET_VISIBLE (shell_content->priv->filter_combo_box);
+}
+
+void
+e_shell_content_set_filter_visible (EShellContent *shell_content,
+ gboolean filter_visible)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (filter_visible) {
+ gtk_widget_show (shell_content->priv->filter_label);
+ gtk_widget_show (shell_content->priv->filter_combo_box);
+ } else {
+ gtk_widget_hide (shell_content->priv->filter_label);
+ gtk_widget_hide (shell_content->priv->filter_combo_box);
+ }
+}
+
+void
+e_shell_content_add_filter_separator_before (EShellContent *shell_content,
+ gint action_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_add_separator_before (combo_box, action_value);
+}
+
+void
+e_shell_content_add_filter_separator_after (EShellContent *shell_content,
+ gint action_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_add_separator_after (combo_box, action_value);
+}
+
+RuleContext *
+e_shell_content_get_search_context (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ return shell_content->priv->search_context;
+}
+
+const gchar *
+e_shell_content_get_search_hint (EShellContent *shell_content)
+{
+ EHintedEntry *entry;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ return e_hinted_entry_get_hint (entry);
+}
+
+void
+e_shell_content_set_search_hint (EShellContent *shell_content,
+ const gchar *search_hint)
+{
+ EHintedEntry *entry;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ e_hinted_entry_set_hint (entry, search_hint);
+
+ g_object_notify (G_OBJECT (shell_content), "search-hint");
+}
+
+FilterRule *
+e_shell_content_get_search_rule (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ return shell_content->priv->search_rule;
+}
+
+void
+e_shell_content_set_search_rule (EShellContent *shell_content,
+ FilterRule *search_rule)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (search_rule != NULL) {
+ g_return_if_fail (IS_FILTER_RULE (search_rule));
+ g_object_ref (search_rule);
+ }
+
+ if (shell_content->priv->search_rule != NULL)
+ g_object_unref (shell_content->priv->search_rule);
+
+ shell_content->priv->search_rule = search_rule;
+
+ g_object_notify (G_OBJECT (shell_content), "search-rule");
+}
+
+const gchar *
+e_shell_content_get_search_text (EShellContent *shell_content)
+{
+ EHintedEntry *entry;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ return e_hinted_entry_get_text (entry);
+}
+
+void
+e_shell_content_set_search_text (EShellContent *shell_content,
+ const gchar *search_text)
+{
+ EHintedEntry *entry;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ e_hinted_entry_set_text (entry, search_text);
+
+ g_object_notify (G_OBJECT (shell_content), "search-text");
+}
+
+gboolean
+e_shell_content_get_search_visible (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE);
+
+ return GTK_WIDGET_VISIBLE (shell_content->priv->search_entry);
+}
+
+void
+e_shell_content_set_search_visible (EShellContent *shell_content,
+ gboolean search_visible)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (search_visible) {
+ gtk_widget_show (shell_content->priv->search_label);
+ gtk_widget_show (shell_content->priv->search_entry);
+ } else {
+ gtk_widget_hide (shell_content->priv->search_label);
+ gtk_widget_hide (shell_content->priv->search_entry);
+ }
+}
+
+GtkRadioAction *
+e_shell_content_get_scope_action (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ return e_action_combo_box_get_action (combo_box);
+}
+
+void
+e_shell_content_set_scope_action (EShellContent *shell_content,
+ GtkRadioAction *scope_action)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ e_action_combo_box_set_action (combo_box, scope_action);
+
+ g_object_notify (G_OBJECT (shell_content), "scope-action");
+}
+
+gint
+e_shell_content_get_scope_value (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ return e_action_combo_box_get_current_value (combo_box);
+}
+
+void
+e_shell_content_set_scope_value (EShellContent *shell_content,
+ gint scope_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ e_action_combo_box_set_current_value (combo_box, scope_value);
+
+ g_object_notify (G_OBJECT (shell_content), "scope-value");
+}
+
+gboolean
+e_shell_content_get_scope_visible (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE);
+
+ return GTK_WIDGET_VISIBLE (shell_content->priv->scope_combo_box);
+}
+
+void
+e_shell_content_set_scope_visible (EShellContent *shell_content,
+ gboolean scope_visible)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (scope_visible) {
+ gtk_widget_show (shell_content->priv->scope_label);
+ gtk_widget_show (shell_content->priv->scope_combo_box);
+ } else {
+ gtk_widget_hide (shell_content->priv->scope_label);
+ gtk_widget_hide (shell_content->priv->scope_combo_box);
+ }
+
+ g_object_notify (G_OBJECT (shell_content), "scope-visible");
+}
+
+void
+e_shell_content_run_advanced_search_dialog (EShellContent *shell_content)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ FilterRule *rule;
+ RuleContext *context;
+ const gchar *user_filename;
+ gint response;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ user_filename = shell_content->priv->user_filename;
+
+ rule = e_shell_content_get_search_rule (shell_content);
+
+ if (rule == NULL)
+ rule = filter_rule_new ();
+ else
+ rule = filter_rule_clone (rule);
+
+ context = e_shell_content_get_search_context (shell_content);
+ widget = filter_rule_get_widget (rule, context);
+ filter_rule_set_source (rule, FILTER_SOURCE_INCOMING);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Advanced Search"), GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_APPLY,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 7);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 300);
+
+ gtk_box_pack_start (
+ GTK_BOX (GTK_DIALOG (dialog)->vbox), widget, TRUE, TRUE, 0);
+
+ g_signal_connect_swapped (
+ rule, "changed", G_CALLBACK (
+ shell_content_dialog_rule_changed), dialog);
+
+ shell_content_dialog_rule_changed (dialog, rule);
+
+run:
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_APPLY)
+ goto exit;
+
+ if (!filter_rule_validate (rule))
+ goto run;
+
+ e_shell_content_set_search_rule (shell_content, rule);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window);
+ gtk_action_activate (action);
+
+ if (response == GTK_RESPONSE_APPLY) {
+ if (!rule_context_find_rule (context, rule->name, rule->source))
+ rule_context_add_rule (context, rule);
+ rule_context_save (context, user_filename);
+ goto run;
+ }
+
+exit:
+ g_object_unref (rule);
+ gtk_widget_destroy (dialog);
+}
+
+void
+e_shell_content_run_edit_searches_dialog (EShellContent *shell_content)
+{
+ RuleContext *context;
+ RuleEditor *editor;
+ const gchar *user_filename;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ context = e_shell_content_get_search_context (shell_content);
+ user_filename = shell_content->priv->user_filename;
+
+ editor = rule_editor_new (
+ context, FILTER_SOURCE_INCOMING, _("Searches"));
+ gtk_window_set_title (GTK_WINDOW (editor), _("Searches"));
+
+ if (gtk_dialog_run (GTK_DIALOG (editor)) == GTK_RESPONSE_OK)
+ rule_context_save (context, user_filename);
+
+ gtk_widget_destroy (GTK_WIDGET (editor));
+}
+
+void
+e_shell_content_run_save_search_dialog (EShellContent *shell_content)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ FilterRule *rule;
+ RuleContext *context;
+ const gchar *search_text;
+ const gchar *user_filename;
+ gchar *search_name;
+ gint response;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ user_filename = shell_content->priv->user_filename;
+
+ rule = e_shell_content_get_search_rule (shell_content);
+ g_return_if_fail (IS_FILTER_RULE (rule));
+ rule = filter_rule_clone (rule);
+
+ search_text = e_shell_content_get_search_text (shell_content);
+ if (search_text == NULL || *search_text == '\0')
+ search_text = "''";
+
+ search_name = g_strdup_printf ("%s %s", rule->name, search_text);
+ filter_rule_set_name (rule, search_name);
+ g_free (search_name);
+
+ context = e_shell_content_get_search_context (shell_content);
+ widget = filter_rule_get_widget (rule, context);
+ filter_rule_set_source (rule, FILTER_SOURCE_INCOMING);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Save Search"), GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 7);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300);
+
+ gtk_box_pack_start (
+ GTK_BOX (GTK_DIALOG (dialog)->vbox), widget, TRUE, TRUE, 0);
+
+ g_signal_connect_swapped (
+ rule, "changed", G_CALLBACK (
+ shell_content_dialog_rule_changed), dialog);
+
+ shell_content_dialog_rule_changed (dialog, rule);
+
+run:
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response != GTK_RESPONSE_OK)
+ goto exit;
+
+ if (!filter_rule_validate (rule))
+ goto run;
+
+ rule_context_add_rule (context, rule);
+ rule_context_save (context, user_filename);
+
+exit:
+ g_object_unref (rule);
+ gtk_widget_destroy (dialog);
+}
+
+void
+e_shell_content_restore_state (EShellContent *shell_content,
+ const gchar *group_name)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GKeyFile *key_file;
+ GtkAction *action;
+ GtkWidget *widget;
+ const gchar *key;
+ gchar *string;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+ g_return_if_fail (group_name != NULL);
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ /* Changing the combo boxes triggers searches, so block
+ * the search action until the state is fully restored. */
+ action = e_shell_window_get_action (shell_window, "search-execute");
+ gtk_action_block_activate (action);
+
+ key = STATE_KEY_SEARCH_FILTER;
+ string = g_key_file_get_string (key_file, group_name, key, NULL);
+ if (string != NULL && *string != '\0')
+ action = e_shell_window_get_action (shell_window, string);
+ else
+ action = NULL;
+ if (action != NULL)
+ gtk_action_activate (action);
+ else {
+ /* Pick the first combo box item. */
+ widget = shell_content->priv->filter_combo_box;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ }
+ g_free (string);
+
+ key = STATE_KEY_SEARCH_SCOPE;
+ string = g_key_file_get_string (key_file, group_name, key, NULL);
+ if (string != NULL && *string != '\0')
+ action = e_shell_window_get_action (shell_window, string);
+ else
+ action = NULL;
+ if (action != NULL)
+ gtk_action_activate (action);
+ else {
+ /* Pick the first combo box item. */
+ widget = shell_content->priv->scope_combo_box;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ }
+ g_free (string);
+
+ key = STATE_KEY_SEARCH_TEXT;
+ string = g_key_file_get_string (key_file, group_name, key, NULL);
+ e_shell_content_set_search_text (shell_content, string);
+ g_free (string);
+
+ action = e_shell_window_get_action (shell_window, "search-execute");
+ gtk_action_unblock_activate (action);
+
+ /* Now execute the search. */
+ gtk_action_activate (action);
+}
diff --git a/shell/e-shell-content.h b/shell/e-shell-content.h
new file mode 100644
index 0000000000..8e754fff26
--- /dev/null
+++ b/shell/e-shell-content.h
@@ -0,0 +1,148 @@
+/*
+ * e-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-content
+ * @short_description: the right side of the main window
+ * @include: shell/e-shell-content.h
+ **/
+
+#ifndef E_SHELL_CONTENT_H
+#define E_SHELL_CONTENT_H
+
+#include <shell/e-shell-common.h>
+#include <filter/filter-rule.h>
+#include <filter/rule-context.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_CONTENT \
+ (e_shell_content_get_type ())
+#define E_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_CONTENT, EShellContent))
+#define E_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_CONTENT, EShellContentClass))
+#define E_IS_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_CONTENT))
+#define E_IS_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_CONTENT))
+#define E_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_CONTENT, EShellContentClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellContent EShellContent;
+typedef struct _EShellContentClass EShellContentClass;
+typedef struct _EShellContentPrivate EShellContentPrivate;
+
+/**
+ * EShellContent:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellContent {
+ GtkBin parent;
+ EShellContentPrivate *priv;
+};
+
+struct _EShellContentClass {
+ GtkBinClass parent_class;
+
+ /* Factory Methods */
+ RuleContext * (*new_search_context) (void);
+
+ guint32 (*check_state) (EShellContent *shell_content);
+};
+
+GType e_shell_content_get_type (void);
+GtkWidget * e_shell_content_new (struct _EShellView *shell_view);
+guint32 e_shell_content_check_state (EShellContent *shell_content);
+struct _EShellView *
+ e_shell_content_get_shell_view (EShellContent *shell_content);
+GtkRadioAction *e_shell_content_get_filter_action
+ (EShellContent *shell_content);
+void e_shell_content_set_filter_action
+ (EShellContent *shell_content,
+ GtkRadioAction *filter_action);
+gint e_shell_content_get_filter_value(EShellContent *shell_content);
+void e_shell_content_set_filter_value(EShellContent *shell_content,
+ gint filter_value);
+gboolean e_shell_content_get_filter_visible
+ (EShellContent *shell_content);
+void e_shell_content_set_filter_visible
+ (EShellContent *shell_content,
+ gboolean filter_visible);
+void e_shell_content_add_filter_separator_before
+ (EShellContent *shell_content,
+ gint action_value);
+void e_shell_content_add_filter_separator_after
+ (EShellContent *shell_content,
+ gint action_value);
+RuleContext * e_shell_content_get_search_context
+ (EShellContent *shell_content);
+const gchar * e_shell_content_get_search_hint (EShellContent *shell_content);
+void e_shell_content_set_search_hint (EShellContent *shell_content,
+ const gchar *search_hint);
+FilterRule * e_shell_content_get_search_rule (EShellContent *shell_content);
+void e_shell_content_set_search_rule (EShellContent *shell_content,
+ FilterRule *search_rule);
+const gchar * e_shell_content_get_search_text (EShellContent *shell_content);
+void e_shell_content_set_search_text (EShellContent *shell_content,
+ const gchar *search_text);
+gboolean e_shell_content_get_search_visible
+ (EShellContent *shell_content);
+void e_shell_content_set_search_visible
+ (EShellContent *shell_content,
+ gboolean search_visible);
+GtkRadioAction *e_shell_content_get_scope_action(EShellContent *shell_content);
+void e_shell_content_set_scope_action(EShellContent *shell_content,
+ GtkRadioAction *scope_action);
+gint e_shell_content_get_scope_value (EShellContent *shell_content);
+void e_shell_content_set_scope_value (EShellContent *shell_content,
+ gint scope_value);
+gboolean e_shell_content_get_scope_visible
+ (EShellContent *shell_content);
+void e_shell_content_set_scope_visible
+ (EShellContent *shell_content,
+ gboolean scope_visible);
+const gchar * e_shell_content_get_view_id (EShellContent *shell_content);
+void e_shell_content_set_view_id (EShellContent *shell_content,
+ const gchar *view_id);
+void e_shell_content_run_advanced_search_dialog
+ (EShellContent *shell_content);
+void e_shell_content_run_edit_searches_dialog
+ (EShellContent *shell_content);
+void e_shell_content_run_save_search_dialog
+ (EShellContent *shell_content);
+void e_shell_content_restore_state (EShellContent *shell_content,
+ const gchar *group_name);
+
+G_END_DECLS
+
+#endif /* E_SHELL_CONTENT_H */
diff --git a/shell/e-shell-importer.c b/shell/e-shell-importer.c
index c9953b9589..aba3546443 100644
--- a/shell/e-shell-importer.c
+++ b/shell/e-shell-importer.c
@@ -34,10 +34,6 @@
#include <glib/gi18n.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-edge.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
-
#include "misc/e-gui-utils.h"
#include "e-util/e-dialog-utils.h"
@@ -48,7 +44,6 @@
#include "e-shell.h"
#include "e-shell-window.h"
-#include "e-shell-constants.h"
#include "e-shell-importer.h"
@@ -84,9 +79,7 @@ typedef struct _ImportDialogImporterPage {
typedef struct _ImportData {
EShellWindow *window;
- GladeXML *wizard;
- GtkWidget *dialog;
- GtkWidget *druid;
+ GtkWidget *assistant;
ImportDialogFilePage *filepage;
ImportDialogDestPage *destpage;
ImportDialogTypePage *typepage;
@@ -96,8 +89,6 @@ typedef struct _ImportData {
GtkWidget *typedialog;
GtkWidget *destdialog;
GtkWidget *intelligent;
- GnomeDruidPageEdge *start;
- GnomeDruidPageEdge *finish;
GtkWidget *vbox;
EImport *import;
@@ -236,7 +227,7 @@ filename_changed (GtkWidget *widget,
}
}
- gnome_druid_set_buttons_sensitive(GNOME_DRUID (data->druid), TRUE, fileok, TRUE, FALSE);
+ gtk_assistant_set_page_complete (GTK_ASSISTANT (data->assistant), page->vbox, fileok);
}
static void
@@ -250,29 +241,6 @@ filetype_changed_cb (GtkWidget *combobox, ImportData *data)
filename_changed (data->filepage->filename, data);
}
-#if 0
-static gint
-compare_info_name (gconstpointer data1, const void *data2)
-{
- const Bonobo_ServerInfo *info1 = (Bonobo_ServerInfo *)data1;
- const Bonobo_ServerInfo *info2 = (Bonobo_ServerInfo *)data2;
- const gchar *name1 = get_name_from_component_info (info1);
- const gchar *name2 = get_name_from_component_info (info2);
-
- /* If we can't find a name for a plug-in, its iid will be used
- * for display. Put such plug-ins at the end of the list since
- * their displayed name won't be really user-friendly
- */
- if (name1 == NULL) {
- return -1;
- }
- if (name2 == NULL) {
- return 1;
- }
- return g_utf8_collate (name1, name2);
-}
-#endif
-
static ImportDialogFilePage *
importer_file_page_new (ImportData *data)
{
@@ -328,6 +296,8 @@ importer_file_page_new (ImportData *data)
row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
gtk_label_set_mnemonic_widget(GTK_LABEL(label), page->filetype);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
gtk_widget_show_all (table);
return page;
@@ -342,6 +312,8 @@ importer_dest_page_new (ImportData *data)
page->vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
return page;
}
@@ -359,7 +331,10 @@ importer_type_page_new (ImportData *data)
page->file = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (page->intelligent),
_("Import a _single file"));
gtk_box_pack_start (GTK_BOX (page->vbox), page->file, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
gtk_widget_show_all (page->vbox);
+
return page;
}
@@ -377,23 +352,25 @@ importer_importer_page_new (ImportData *data)
sep = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (page->vbox), sep, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
gtk_widget_show_all (page->vbox);
return page;
}
-static gboolean
-prepare_intelligent_page (GnomeDruidPage *dpage,
- GnomeDruid *druid,
- ImportData *data)
+static void
+prepare_intelligent_page (GtkAssistant *assistant, GtkWidget *apage, ImportData *data)
{
GSList *l;
GtkWidget *table;
gint row;
ImportDialogImporterPage *page = data->importerpage;
- if (page->target != NULL)
- return FALSE;
+ if (page->target != NULL) {
+ gtk_assistant_set_page_complete (assistant, apage, FALSE);
+ return;
+ }
page->target = e_import_target_new_home(data->import, g_get_home_dir());
@@ -403,8 +380,8 @@ prepare_intelligent_page (GnomeDruidPage *dpage,
if (l == NULL) {
gtk_box_pack_start(GTK_BOX (data->importerpage->vbox), create_help("nodata_html"), FALSE, TRUE, 0);
- gnome_druid_set_buttons_sensitive(druid, TRUE, FALSE, TRUE, FALSE);
- return TRUE;
+ gtk_assistant_set_page_complete (assistant, apage, FALSE);
+ return;
}
table = gtk_table_new(g_slist_length(l), 2, FALSE);
@@ -432,33 +409,30 @@ prepare_intelligent_page (GnomeDruidPage *dpage,
gtk_widget_show(table);
gtk_box_pack_start((GtkBox *)data->importerpage->vbox, table, FALSE, FALSE, 0);
- return FALSE;
+ gtk_assistant_set_page_complete (assistant, apage, TRUE);
}
static void
-import_druid_cancel (GnomeDruid *druid,
- ImportData *data)
+import_assistant_cancel (GtkAssistant *assistant, ImportData *data)
{
if (data->import_dialog)
gtk_dialog_response (GTK_DIALOG (data->import_dialog), GTK_RESPONSE_CANCEL);
else
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ gtk_widget_destroy (GTK_WIDGET (data->assistant));
}
static gboolean
-import_druid_esc (GnomeDruid *druid,
- GdkEventKey *event,
- ImportData *data)
+import_assistant_esc (GtkAssistant *assistant, GdkEventKey *event, ImportData *data)
{
if (event->keyval == GDK_Escape) {
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ gtk_widget_destroy (GTK_WIDGET (assistant));
return TRUE;
} else
return FALSE;
}
static void
-import_druid_weak_notify (gpointer blah,
+import_assistant_weak_notify (gpointer blah,
GObject *where_the_object_was)
{
ImportData *data = (ImportData *) blah;
@@ -466,8 +440,8 @@ import_druid_weak_notify (gpointer blah,
if (data->import_dialog && (GObject *)data->import_dialog != where_the_object_was) {
/* postpone freeing of 'data' after the 'import_dialog' will stop,
but also indicate that the 'dialog' gone already */
- data->dialog = NULL;
- g_object_weak_ref ((GObject *)data->import_dialog, import_druid_weak_notify, data);
+ data->assistant = NULL;
+ g_object_weak_ref ((GObject *)data->import_dialog, import_assistant_weak_notify, data);
gtk_dialog_response (GTK_DIALOG (data->import_dialog), GTK_RESPONSE_CANCEL);
return;
}
@@ -481,7 +455,6 @@ import_druid_weak_notify (gpointer blah,
g_object_unref(data->import);
- g_object_unref(data->wizard);
g_free(data);
}
@@ -505,7 +478,7 @@ static void
import_done(EImport *ei, gpointer d)
{
ImportData *data = d;
- gboolean have_dialog = data->dialog != NULL;
+ gboolean have_dialog = data->assistant != NULL;
gtk_widget_destroy (data->import_dialog);
@@ -513,7 +486,7 @@ import_done(EImport *ei, gpointer d)
on the above destroy call */
if (have_dialog) {
data->import_dialog = NULL;
- gtk_widget_destroy (data->dialog);
+ gtk_widget_destroy (data->assistant);
}
}
@@ -532,9 +505,7 @@ import_intelligent_done(EImport *ei, gpointer d)
}
static void
-import_druid_finish (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
+import_assistant_apply (GtkAssistant *assistant, ImportData *data)
{
EImportCompleteFunc done = NULL;
gchar *msg = NULL;
@@ -567,16 +538,14 @@ import_druid_finish (GnomeDruidPage *page,
e_import_import(data->import, data->import_target, data->import_importer, import_status, import_done, data);
} else {
- gtk_widget_destroy(data->dialog);
+ gtk_widget_destroy(data->assistant);
}
g_free(msg);
}
-static gboolean
-prepare_file_page (GnomeDruidPage *dpage,
- GnomeDruid *druid,
- ImportData *data)
+static void
+prepare_file_page (GtkAssistant *assistant, GtkWidget *apage, ImportData *data)
{
GSList *importers, *imp;
GtkListStore *store;
@@ -584,7 +553,7 @@ prepare_file_page (GnomeDruidPage *dpage,
if (page->target != NULL) {
filename_changed(data->filepage->filename, data);
- return FALSE;
+ return;
}
page->target = e_import_target_new_uri(data->import, NULL, NULL);
@@ -613,23 +582,10 @@ prepare_file_page (GnomeDruidPage *dpage,
filename_changed (data->filepage->filename, data);
g_signal_connect (page->filetype, "changed", G_CALLBACK (filetype_changed_cb), data);
-
- return FALSE;
-}
-
-static gboolean
-next_file_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
-{
- /* We dont sensitise the next button if we're not already usable */
- return FALSE;
}
static gboolean
-prepare_dest_page (GnomeDruidPage *dpage,
- GnomeDruid *druid,
- ImportData *data)
+prepare_dest_page (GtkAssistant *assistant, GtkWidget *apage, ImportData *data)
{
ImportDialogDestPage *page = data->destpage;
@@ -643,174 +599,184 @@ prepare_dest_page (GnomeDruidPage *dpage,
gtk_widget_show(page->control);
}
- gtk_box_pack_start((GtkBox *)data->destpage->vbox, page->control, TRUE, TRUE, 0);
+ gtk_box_pack_start ((GtkBox *)data->destpage->vbox, page->control, TRUE, TRUE, 0);
+ gtk_assistant_set_page_complete (assistant, apage, TRUE);
return FALSE;
}
-static gboolean
-next_dest_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
-{
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->finish));
- return TRUE;
-}
-
-static gboolean
-next_type_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
+static void
+dialog_weak_notify (gpointer data,
+ GObject *where_the_dialog_was)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent));
- } else {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog));
- }
+ gboolean *dialog_open = (gboolean *) data;
- return TRUE;
+ *dialog_open = FALSE;
}
-static gboolean
-back_finish_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
+enum {
+ PAGE_START,
+ PAGE_INTELI_OR_DIRECT,
+ PAGE_INTELI_SOURCE,
+ PAGE_FILE_CHOOSE,
+ PAGE_FILE_DEST,
+ PAGE_FINISH
+};
+
+static gint
+forward_cb (gint current_page, gpointer user_data)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent));
- } else {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->destdialog));
+ ImportData *data = user_data;
+
+ switch (current_page) {
+ case PAGE_INTELI_OR_DIRECT:
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent)))
+ return PAGE_INTELI_SOURCE;
+ else
+ return PAGE_FILE_CHOOSE;
+ case PAGE_INTELI_SOURCE:
+ return PAGE_FINISH;
}
- return TRUE;
-}
-
-static gboolean
-back_intelligent_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
-{
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->typedialog));
- return TRUE;
+ return current_page + 1;
}
static void
-dialog_weak_notify (gpointer data,
- GObject *where_the_dialog_was)
+import_assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data)
{
- gboolean *dialog_open = (gboolean *) data;
-
- *dialog_open = FALSE;
+ ImportData *data = user_data;
+
+ if (page == data->importerpage->vbox)
+ prepare_intelligent_page (assistant, page, data);
+ else if (page == data->filepage->vbox)
+ prepare_file_page (assistant, page, data);
+ else if (page == data->destpage->vbox)
+ prepare_dest_page (assistant, page, data);
}
void
e_shell_importer_start_import (EShellWindow *shell_window)
{
+ const gchar *empty_xpm_img[] = {
+ "48 1 2 1",
+ " c None",
+ ". c #FFFFFF",
+ " "};
ImportData *data = g_new0 (ImportData, 1);
- GtkWidget *html;
+ GtkWidget *html, *page;
static gboolean dialog_open = FALSE;
- GdkPixbuf *icon;
- gchar *gladefile;
+ GdkPixbuf *icon, *spacer;
+ GtkAssistant *assistant;
if (dialog_open) {
return;
}
- data->import = e_import_new("org.gnome.evolution.shell.importer");
+ data->import = e_import_new ("org.gnome.evolution.shell.importer");
icon = e_icon_factory_get_icon ("stock_mail-import", GTK_ICON_SIZE_DIALOG);
+ spacer = gdk_pixbuf_new_from_xpm_data (empty_xpm_img);
dialog_open = TRUE;
data->window = shell_window;
+ data->assistant = gtk_assistant_new ();
- gladefile = g_build_filename (EVOLUTION_GLADEDIR, "import.glade", NULL);
- data->wizard = glade_xml_new (gladefile, NULL, NULL);
- g_free (gladefile);
- data->dialog = glade_xml_get_widget (data->wizard, "importwizard");
- gtk_window_set_default_size (GTK_WINDOW (data->dialog), 480, 320);
- gtk_window_set_wmclass (GTK_WINDOW (data->dialog), "importdruid",
- "Evolution:shell");
- e_dialog_set_transient_for (GTK_WINDOW (data->dialog), GTK_WIDGET (shell_window));
- g_object_weak_ref ((GObject *)data->dialog, dialog_weak_notify, &dialog_open);
-
- data->druid = glade_xml_get_widget (data->wizard, "druid1");
- g_signal_connect (data->druid, "cancel",
- G_CALLBACK (import_druid_cancel), data);
- g_signal_connect (data->druid, "key_press_event",
- G_CALLBACK (import_druid_esc), data);
-
- gtk_button_set_use_underline ((GtkButton *)((GnomeDruid *)data->druid)->finish, TRUE);
- gtk_button_set_label((GtkButton *)((GnomeDruid *)data->druid)->finish, _("_Import"));
+ assistant = GTK_ASSISTANT (data->assistant);
+
+ gtk_window_set_position (GTK_WINDOW (assistant), GTK_WIN_POS_CENTER);
+ gtk_window_set_title (GTK_WINDOW (assistant), _("Evolution Import Assistant"));
+ gtk_window_set_default_size (GTK_WINDOW (assistant), 500, 330);
/* Start page */
- data->start = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (data->wizard, "page0"));
- gnome_druid_page_edge_set_logo (data->start, icon);
+ page = gtk_label_new ("");
+ gtk_label_set_line_wrap (GTK_LABEL (page), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (page), 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (page), 12, 12);
+ gtk_label_set_text (GTK_LABEL (page), _(
+ "Welcome to the Evolution Import Assistant.\n"
+ "With this assistant you will be guided through the process of importing external files into Evolution."));
+
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Evolution Import Assistant"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_INTRO);
+ gtk_assistant_set_page_side_image (assistant, page, spacer);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
/* Intelligent or direct import page */
- data->typedialog = glade_xml_get_widget (data->wizard, "page1");
- gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (data->typedialog), icon);
- g_signal_connect (data->typedialog, "next",
- G_CALLBACK (next_type_page), data);
data->typepage = importer_type_page_new (data);
html = create_help ("type_html");
gtk_box_pack_start (GTK_BOX (data->typepage->vbox), html, FALSE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (data->typepage->vbox), html, 0);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->typedialog)->vbox), data->typepage->vbox, TRUE, TRUE, 0);
+ page = data->typepage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Importer Type"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
/* Intelligent importer source page */
- data->intelligent = glade_xml_get_widget (data->wizard, "page2-intelligent");
- gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (data->intelligent), icon);
- g_signal_connect (data->intelligent, "back",
- G_CALLBACK (back_intelligent_page), data);
- g_signal_connect_after (data->intelligent, "prepare",
- G_CALLBACK (prepare_intelligent_page), data);
-
data->importerpage = importer_importer_page_new (data);
html = create_help ("intelligent_html");
gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), html, FALSE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (data->importerpage->vbox), html, 0);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->intelligent)->vbox), data->importerpage->vbox, TRUE, TRUE, 0);
+ page = data->importerpage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Select Information to Import"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
/* File selection and file type page */
- data->filedialog = glade_xml_get_widget (data->wizard, "page2-file");
- gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (data->filedialog), icon);
- g_signal_connect_after (data->filedialog, "prepare",
- G_CALLBACK (prepare_file_page), data);
- g_signal_connect (data->filedialog, "next",
- G_CALLBACK (next_file_page), data);
data->filepage = importer_file_page_new (data);
-
html = create_help ("file_html");
gtk_box_pack_start (GTK_BOX (data->filepage->vbox), html, FALSE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (data->filepage->vbox), html, 0);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->filedialog)->vbox), data->filepage->vbox, TRUE, TRUE, 0);
+ page = data->filepage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Select a File"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
/* File destination page */
- data->destdialog = glade_xml_get_widget (data->wizard, "page3-file");
- g_signal_connect_after (data->destdialog, "prepare",
- G_CALLBACK (prepare_dest_page), data);
- g_signal_connect (data->destdialog, "next",
- G_CALLBACK (next_dest_page), data);
-
data->destpage = importer_dest_page_new (data);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->destdialog)->vbox), data->destpage->vbox, TRUE, TRUE, 0);
+ page = data->destpage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Import Location"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
/* Finish page */
- data->finish = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (data->wizard, "page4"));
- gnome_druid_page_edge_set_logo (data->finish, icon);
- g_signal_connect (data->finish, "back",
- G_CALLBACK (back_finish_page), data);
+ page = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (page), 0.5, 0.5);
+ gtk_label_set_text (GTK_LABEL (page), _("Click \"Apply\" to begin importing the file into Evolution."));
- g_signal_connect (data->finish, "finish",
- G_CALLBACK (import_druid_finish), data);
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Import File"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
+ gtk_assistant_set_page_side_image (assistant, page, spacer);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
- g_object_weak_ref ((GObject *)data->dialog, import_druid_weak_notify, data);
+ /* setup the rest */
+ g_object_weak_ref ((GObject *)assistant, dialog_weak_notify, &dialog_open);
+
+ gtk_assistant_set_forward_page_func (assistant, forward_cb, data, NULL);
+
+ g_signal_connect (assistant, "key_press_event", G_CALLBACK (import_assistant_esc), data);
+ g_signal_connect (assistant, "cancel", G_CALLBACK (import_assistant_cancel), data);
+ g_signal_connect (assistant, "prepare", G_CALLBACK (import_assistant_prepare), data);
+ g_signal_connect (assistant, "apply", G_CALLBACK (import_assistant_apply), data);
+
+ g_object_weak_ref ((GObject *)assistant, import_assistant_weak_notify, data);
g_object_unref (icon);
+ g_object_unref (spacer);
+
+ gtk_assistant_update_buttons_state (assistant);
- gtk_widget_show_all (data->dialog);
+ gtk_widget_show_all (data->assistant);
}
diff --git a/shell/e-shell-importer.h b/shell/e-shell-importer.h
index d9dffcfb0b..bd57fbd4f0 100644
--- a/shell/e-shell-importer.h
+++ b/shell/e-shell-importer.h
@@ -20,9 +20,16 @@
*
*/
-#ifndef _E_SHELL_IMPORTER_H_
-#define _E_SHELL_IMPORTER_H_
+#ifndef E_SHELL_IMPORTER_H
+#define E_SHELL_IMPORTER_H
-void e_shell_importer_start_import (EShellWindow *shell_window);
+#include "e-shell-common.h"
+#include "e-shell-window.h"
-#endif
+G_BEGIN_DECLS
+
+void e_shell_importer_start_import (EShellWindow *shell_window);
+
+G_END_DECLS
+
+#endif /* E_SHELL_IMPORTER_H */
diff --git a/shell/e-shell-migrate.c b/shell/e-shell-migrate.c
new file mode 100644
index 0000000000..18e085f0cc
--- /dev/null
+++ b/shell/e-shell-migrate.c
@@ -0,0 +1,351 @@
+/*
+ * e-shell-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-migrate.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libedataserver/e-xml-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-error.h"
+#include "e-util/e-fsutils.h"
+#include "e-util/e-util.h"
+
+#include "es-event.h"
+
+#define GCONF_VERSION_KEY "/apps/evolution/version"
+#define GCONF_LAST_VERSION_KEY "/apps/evolution/last_version"
+
+static const gchar *
+shell_migrate_get_old_data_dir (void)
+{
+ static gchar *old_data_dir = NULL;
+
+ if (G_UNLIKELY (old_data_dir == NULL))
+ old_data_dir = g_build_filename (
+ g_get_home_dir (), "evolution", NULL);
+
+ return old_data_dir;
+}
+
+static gboolean
+shell_migrate_attempt (EShell *shell,
+ gint major,
+ gint minor,
+ gint micro)
+{
+ GList *backends;
+ gboolean success = TRUE;
+
+ backends = e_shell_get_shell_backends (shell);
+
+ while (success && backends != NULL) {
+ EShellBackend *shell_backend = backends->data;
+ GError *error = NULL;
+
+ success = e_shell_backend_migrate (
+ shell_backend, major, minor, micro, &error);
+
+ if (error != NULL) {
+ gint response;
+
+ response = e_error_run (
+ NULL, "shell:upgrade-failed",
+ error->message, NULL);
+
+ if (response == GTK_RESPONSE_CANCEL)
+ success = FALSE;
+
+ g_error_free (error);
+ }
+
+ backends = g_list_next (backends);
+ }
+
+ return success;
+}
+
+static void
+shell_migrate_get_version (EShell *shell,
+ gint *major,
+ gint *minor,
+ gint *micro)
+{
+ GConfClient *client;
+ const gchar *key;
+ const gchar *old_data_dir;
+ gchar *string;
+
+ old_data_dir = shell_migrate_get_old_data_dir ();
+
+ key = GCONF_VERSION_KEY;
+ client = e_shell_get_gconf_client (shell);
+ string = gconf_client_get_string (client, key, NULL);
+
+ if (string != NULL) {
+ /* Since 1.4.0 we've kept the version key in GConf. */
+ sscanf (string, "%d.%d.%d", major, minor, micro);
+ g_free (string);
+
+ } else if (!g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) {
+ /* If the old data directory does not exist,
+ * it must be a new installation. */
+ *major = 0;
+ *minor = 0;
+ *micro = 0;
+
+ } else {
+ xmlDocPtr doc;
+ xmlNodePtr source;
+ gchar *filename;
+
+ filename = g_build_filename (
+ old_data_dir, "config.xmldb", NULL);
+ doc = e_xml_parse_file (filename);
+ g_free (filename);
+
+ if (doc == NULL)
+ return;
+
+ source = e_bconf_get_path (doc, "/Shell");
+ if (source != NULL) {
+ key = "upgrade_from_1_0_to_1_2_performed";
+ string = e_bconf_get_value (source, key);
+ }
+
+ if (string != NULL && *string == '1') {
+ *major = 1;
+ *minor = 2;
+ *micro = 0;
+ } else {
+ *major = 1;
+ *minor = 0;
+ *micro = 0;
+ }
+
+ g_free (string);
+
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+ }
+}
+
+static gint
+shell_migrate_remove_dir (const gchar *root,
+ const gchar *path)
+{
+ GDir *dir;
+ const gchar *basename;
+ gchar *filename;
+ gint result = -1;
+
+ /* Recursively removes a directory and its contents. */
+
+ dir = g_dir_open (path, 0, NULL);
+ if (dir == NULL)
+ return -1;
+
+ while ((basename = g_dir_read_name (dir)) != NULL) {
+ filename = g_build_filename (path, basename, NULL);
+
+ /* Make sure we haven't strayed from the evolution dir. */
+ g_return_val_if_fail (strlen (path) >= strlen (root), -1);
+ g_return_val_if_fail (g_str_has_prefix (path, root), -1);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
+ if (shell_migrate_remove_dir (root, filename) < 0)
+ goto fail;
+ } else {
+ if (g_unlink (filename) < 0)
+ goto fail;
+ }
+
+ g_free (filename);
+ filename = NULL;
+ }
+
+ result = g_rmdir (path);
+
+fail:
+ g_free (filename);
+ g_dir_close (dir);
+
+ return result;
+}
+
+gboolean
+e_shell_migrate_attempt (EShell *shell)
+{
+ ESEvent *ese;
+ GConfClient *client;
+ const gchar *key;
+ const gchar *old_data_dir;
+ gint major, minor, micro;
+ gint last_major, last_minor, last_micro;
+ gint curr_major, curr_minor, curr_micro;
+ gboolean migrated = FALSE;
+ gchar *string;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+
+ client = e_shell_get_gconf_client (shell);
+ old_data_dir = shell_migrate_get_old_data_dir ();
+
+ if (sscanf (BASE_VERSION, "%d.%d", &curr_major, &curr_minor) != 2) {
+ g_warning ("Could not parse BASE_VERSION (%s)", BASE_VERSION);
+ return TRUE;
+ }
+
+ curr_micro = atoi (UPGRADE_REVISION);
+
+ shell_migrate_get_version (shell, &major, &minor, &micro);
+
+ if (!(curr_major > major ||
+ (curr_major == major && curr_minor > minor) ||
+ (curr_minor == minor && curr_micro > micro)))
+ goto check_old;
+
+ /* If upgrading from < 1.5, we need to copy most data from
+ * ~/evolution to ~/.evolution. Make sure we have the disk
+ * space for it before proceeding. */
+ if (major == 1 && minor < 5) {
+ glong avail;
+ glong usage;
+
+ usage = e_fsutils_usage (old_data_dir);
+ avail = e_fsutils_avail (g_get_home_dir ());
+ if (usage >= 0 && avail >= 0 && avail < usage) {
+ gchar *need;
+ gchar *have;
+
+ need = g_strdup_printf (_("%ld KB"), usage);
+ have = g_strdup_printf (_("%ld KB"), avail);
+
+ e_error_run (
+ NULL, "shell:upgrade-nospace",
+ need, have, NULL);
+
+ g_free (need);
+ g_free (have);
+
+ _exit (EXIT_SUCCESS);
+ }
+ }
+
+ if (!shell_migrate_attempt (shell, major, minor, micro))
+ _exit (EXIT_SUCCESS);
+
+ /* Record a successful migration. */
+ string = g_strdup_printf ("%d.%d.%d", major, minor, micro);
+ gconf_client_set_string (client, GCONF_VERSION_KEY, string, NULL);
+ g_free (string);
+
+ migrated = TRUE;
+
+check_old:
+
+ key = GCONF_LAST_VERSION_KEY;
+
+ /* Try to retrieve the last migrated version from GConf. */
+ string = gconf_client_get_string (client, key, NULL);
+ if (migrated || string == NULL || sscanf (string, "%d.%d.%d",
+ &last_major, &last_minor, &last_micro) != 3) {
+ last_major = major;
+ last_minor = minor;
+ last_micro = micro;
+ }
+ g_free (string);
+
+ /* If the last migrated version was old, check for stuff to remove. */
+ if (last_major == 1 && last_minor < 5 &&
+ g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) {
+
+ gint response;
+
+ string = g_strdup_printf (
+ "%d.%d.%d", last_major, last_minor, last_micro);
+ response = e_error_run (
+ NULL, "shell:upgrade-remove-1-4", string, NULL);
+ g_free (string);
+
+ switch (response) {
+ case GTK_RESPONSE_OK: /* delete */
+ response = e_error_run (
+ NULL,
+ "shell:upgrade-remove-1-4-confirm",
+ NULL);
+ if (response == GTK_RESPONSE_OK)
+ shell_migrate_remove_dir (
+ old_data_dir, old_data_dir);
+ else
+ break;
+ /* fall through */
+
+ case GTK_RESPONSE_ACCEPT: /* keep */
+ last_major = curr_major;
+ last_minor = curr_minor;
+ last_micro = curr_micro;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ last_major = curr_major;
+ last_minor = curr_minor;
+ last_micro = curr_micro;
+ }
+
+ string = g_strdup_printf (
+ "%d.%d.%d", last_major, last_minor, last_micro);
+ gconf_client_set_string (client, key, string, NULL);
+ g_free (string);
+
+ /** @Event: Shell attempted upgrade
+ * @Id: upgrade.done
+ * @Target: ESMenuTargetState
+ *
+ * This event is emitted whenever the shell successfully attempts
+ * an upgrade.
+ **/
+ ese = es_event_peek ();
+ e_event_emit (
+ (EEvent *) ese, "upgrade.done",
+ (EEventTarget *) es_event_target_new_upgrade (
+ ese, curr_major, curr_minor, curr_micro));
+
+ return TRUE;
+}
+
+GQuark
+e_shell_migrate_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string (
+ "e-shell-migrate-error-quark");
+
+ return quark;
+}
diff --git a/shell/evolution-shell-component-utils.h b/shell/e-shell-migrate.h
index 1c2412e230..8ebe69709b 100644
--- a/shell/evolution-shell-component-utils.h
+++ b/shell/e-shell-migrate.h
@@ -1,4 +1,6 @@
/*
+ * e-shell-migrate.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,35 +15,38 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef __EVOLUTION_SHELL_COMPONENT_UTILS_H__
-#define __EVOLUTION_SHELL_COMPONENT_UTILS_H__
+/* This is an EShell extension that handles migrating from older versions. */
-#include <bonobo/bonobo-ui-component.h>
-#include <gtk/gtk.h>
+#ifndef E_SHELL_MIGRATE_H
+#define E_SHELL_MIGRATE_H
-G_BEGIN_DECLS
+#include <shell/e-shell-common.h>
+#include <shell/e-shell.h>
-typedef struct _EPixmap {
- const gchar *path;
- const gchar *name;
- GtkIconSize size;
- gchar *pixbuf;
-} EPixmap;
+/**
+ * E_SHELL_MIGRATE_ERROR:
+ *
+ * Error domain for migration operations. Errors in this domain will be
+ * from the #EShellMigrateError enumeration. See #GError for information
+ * on error domains.
+ **/
+#define E_SHELL_MIGRATE_ERROR \
+ (e_shell_migrate_error_quark ())
-#define E_PIXMAP(path,name,size) { (path), (name), (size), NULL }
-#define E_PIXMAP_END { NULL, NULL, 0, NULL }
+G_BEGIN_DECLS
-/* Takes an array of pixmaps, terminated by E_PIXMAP_END, and loads into uic */
-void e_pixmaps_update (BonoboUIComponent *uic, EPixmap *pixcache);
+/* XXX Need more specific error codes? */
+typedef enum {
+ E_SHELL_MIGRATE_ERROR_FAILED
+} EShellMigrateError;
-gchar *e_get_activation_failure_msg (CORBA_Environment *ev);
+gboolean e_shell_migrate_attempt (EShell *shell);
+GQuark e_shell_migrate_error_quark (void);
G_END_DECLS
-#endif /* __EVOLUTION_SHELL_COMPONENT_UTILS_H__ */
+#endif /* E_SHELL_MIGRATE_H */
diff --git a/shell/e-shell-nm.c b/shell/e-shell-nm.c
index 6a56d0f71b..c520600769 100644
--- a/shell/e-shell-nm.c
+++ b/shell/e-shell-nm.c
@@ -30,48 +30,40 @@
#include <string.h>
#include <glib.h>
#include <e-shell.h>
-#include <Evolution.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <NetworkManager/NetworkManager.h>
-gboolean e_shell_dbus_initialise (EShell *shell);
+static DBusConnection *dbus_connection;
-static DBusConnection *dbus_connection = NULL;
+/* Forward Declaration */
+gboolean e_shell_dbus_initialize (EShell *shell);
static gboolean
-reinit_dbus (gpointer user_data)
+reinit_dbus (EShell *shell)
{
- EShell *shell = user_data;
-
- if (e_shell_dbus_initialise (shell))
- return FALSE;
-
- /* keep trying to re-establish dbus connection */
-
- return TRUE;
+ return !e_shell_dbus_initialize (shell);
}
static DBusHandlerResult
e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED,
- DBusMessage *message, gpointer user_data)
+ DBusMessage *message,
+ gpointer user_data)
{
- const gchar *object;
- EShell *shell = user_data;
- GNOME_Evolution_ShellState shell_state;
- EShellLineStatus line_status;
DBusError error = DBUS_ERROR_INIT;
+ EShell *shell = user_data;
+ const gchar *path;
guint32 state;
- object = dbus_message_get_path (message);
+ path = dbus_message_get_path (message);
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
- object && !strcmp (object, DBUS_PATH_LOCAL)) {
+ path != NULL && strcmp (path, DBUS_PATH_LOCAL) == 0) {
dbus_connection_unref (dbus_connection);
dbus_connection = NULL;
- g_timeout_add_seconds (3, reinit_dbus, shell);
+ g_timeout_add_seconds (3, (GSourceFunc) reinit_dbus, shell);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -89,14 +81,16 @@ e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- line_status = e_shell_get_line_status (shell);
-
- if (line_status == E_SHELL_LINE_STATUS_ONLINE && (state == NM_STATE_ASLEEP || state == NM_STATE_DISCONNECTED)) {
- shell_state = GNOME_Evolution_FORCED_OFFLINE;
- e_shell_set_line_status (shell, shell_state);
- } else if (line_status == E_SHELL_LINE_STATUS_FORCED_OFFLINE && state == NM_STATE_CONNECTED) {
- shell_state = GNOME_Evolution_USER_ONLINE;
- e_shell_set_line_status (shell, shell_state);
+ switch (state) {
+ case NM_STATE_CONNECTED:
+ e_shell_set_network_available (shell, TRUE);
+ break;
+ case NM_STATE_ASLEEP:
+ case NM_STATE_DISCONNECTED:
+ e_shell_set_network_available (shell, FALSE);
+ break;
+ default:
+ break;
}
return DBUS_HANDLER_RESULT_HANDLED;
@@ -109,32 +103,39 @@ check_initial_state (EShell *shell)
guint32 state = -1;
DBusError error = DBUS_ERROR_INIT;
- message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "state");
+ message = dbus_message_new_method_call (
+ NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "state");
/* assuming this should be safe to call syncronously */
- response = dbus_connection_send_with_reply_and_block (dbus_connection, message, 100, &error);
+ response = dbus_connection_send_with_reply_and_block (
+ dbus_connection, message, 100, &error);
if (response)
- dbus_message_get_args (response, &error, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
+ dbus_message_get_args (
+ response, &error, DBUS_TYPE_UINT32,
+ &state, DBUS_TYPE_INVALID);
else {
- g_warning ("%s \n", error.message);
+ g_warning ("%s", error.message);
dbus_error_free (&error);
return;
}
- /* update the state only in the absence of network connection else let the old state prevail */
+ /* Update the state only in the absence of a network connection,
+ * otherwise let the old state prevail. */
if (state == NM_STATE_DISCONNECTED)
- e_shell_set_line_status (shell, GNOME_Evolution_FORCED_OFFLINE);
+ e_shell_set_network_available (shell, FALSE);
dbus_message_unref (message);
dbus_message_unref (response);
}
gboolean
-e_shell_dbus_initialise (EShell *shell)
+e_shell_dbus_initialize (EShell *shell)
{
DBusError error = DBUS_ERROR_INIT;
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+
if (dbus_connection != NULL)
return TRUE;
diff --git a/shell/e-shell-settings-dialog.c b/shell/e-shell-settings-dialog.c
deleted file mode 100644
index 9c7c32d1d5..0000000000
--- a/shell/e-shell-settings-dialog.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib/gi18n.h>
-
-#include "e-shell-settings-dialog.h"
-
-#include "e-corba-config-page.h"
-#include <e-util/e-icon-factory.h>
-
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <bonobo-activation/bonobo-activation.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-struct _EShellSettingsDialogPrivate {
- GHashTable *types;
-};
-
-G_DEFINE_TYPE (EShellSettingsDialog, e_shell_settings_dialog, E_TYPE_MULTI_CONFIG_DIALOG)
-
-
-/* FIXME ugly hack to work around that sizing of invisible widgets is broken
- with Bonobo. */
-
-static void
-set_dialog_size (EShellSettingsDialog *dialog)
-{
- PangoLayout *layout;
- PangoContext *context;
- PangoFontMetrics *metrics;
- gint width, height;
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (dialog), "M");
- context = pango_layout_get_context (layout);
- metrics = pango_context_get_metrics (context,
- gtk_widget_get_style (GTK_WIDGET (dialog))->font_desc,
- pango_context_get_language (context));
-
- pango_layout_get_pixel_size (layout, &width, NULL);
-
- width *= 60;
- height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics)
- + pango_font_metrics_get_descent (metrics)) * 30;
-
- gtk_window_set_default_size((GtkWindow *)dialog, width, height);
- g_object_unref (layout);
- pango_font_metrics_unref (metrics);
-}
-
-
-/* Page handling. */
-
-struct _Page {
- gchar *title;
- gchar *description;
- GdkPixbuf *icon;
- Bonobo_ActivationProperty *type;
- gint priority;
- EConfigPage *page_widget;
-};
-typedef struct _Page Page;
-
-static Page *
-page_new (const gchar *title,
- const gchar *description,
- GdkPixbuf *icon,
- Bonobo_ActivationProperty *type,
- gint priority,
- EConfigPage *page_widget)
-{
- Page *page;
-
- if (icon != NULL)
- g_object_ref (icon);
-
- page = g_new (Page, 1);
- page->title = g_strdup (title);
- page->description = g_strdup (description);
- page->icon = icon;
- page->type = type;
- page->priority = priority;
- page->page_widget = page_widget;
-
- return page;
-}
-
-static void
-page_free (Page *page)
-{
- g_free (page->title);
- g_free (page->description);
-
- if (page->icon != NULL)
- g_object_unref (page->icon);
-
- g_free (page);
-}
-
-static gint
-compare_page_func (gconstpointer a,
- gconstpointer b)
-{
- const Page *page_a;
- const Page *page_b;
-
- page_a = (const Page *) a;
- page_b = (const Page *) b;
-
- if (page_a->priority == page_b->priority)
- return strcmp (page_a->title, page_b->title);
-
- return page_a->priority - page_b->priority;
-}
-
-static GList *
-sort_page_list (GList *list)
-{
- return g_list_sort (list, compare_page_func);
-}
-
-static void
-load_pages (EShellSettingsDialog *dialog)
-{
- EShellSettingsDialogPrivate *priv;
- Bonobo_ServerInfoList *control_list;
- const gchar * const *language_names;
- CORBA_Environment ev;
- GSList *languages = NULL;
- GList *page_list;
- GList *p;
- gint i, j;
-
- priv = dialog->priv;
-
- CORBA_exception_init (&ev);
-
- control_list = bonobo_activation_query ("repo_ids.has('IDL:GNOME/Evolution/ConfigControl:" BASE_VERSION "')", NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION || control_list == NULL) {
- g_warning ("Cannot load configuration pages -- %s", BONOBO_EX_REPOID (&ev));
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-
- language_names = g_get_language_names ();
- while (*language_names != NULL)
- languages = g_slist_append (languages, (gpointer)(*language_names++));
-
- page_list = NULL;
- for (i = 0; i < control_list->_length; i ++) {
- CORBA_Object corba_object;
- Bonobo_ServerInfo *info;
- const gchar *title;
- const gchar *description;
- const gchar *icon_path;
- const gchar *priority_string;
- Bonobo_ActivationProperty *type;
- gint priority;
- GdkPixbuf *icon;
-
- CORBA_exception_init (&ev);
-
- info = & control_list->_buffer[i];
-
- title = bonobo_server_info_prop_lookup (info, "evolution2:config_item:title", languages);
- description = bonobo_server_info_prop_lookup (info, "evolution2:config_item:description", languages);
- icon_path = bonobo_server_info_prop_lookup (info, "evolution2:config_item:icon_name", NULL);
- type = bonobo_server_info_prop_find (info, "evolution2:config_item:type");
- priority_string = bonobo_server_info_prop_lookup (info, "evolution2:config_item:priority", NULL);
-
- if (icon_path == NULL) {
- icon = NULL;
- } else {
- if (g_path_is_absolute (icon_path)) {
- icon = gdk_pixbuf_new_from_file (icon_path, NULL);
- } else {
- icon = e_icon_factory_get_icon (icon_path, GTK_ICON_SIZE_DIALOG);
- }
- }
-
- if (type != NULL && type->v._d != Bonobo_ACTIVATION_P_STRINGV)
- type = NULL;
- if (priority_string == NULL)
- priority = 0xffff;
- else
- priority = atoi (priority_string);
-
- corba_object = bonobo_activation_activate_from_id ((gchar *) info->iid, 0, NULL, &ev);
-
- if (! BONOBO_EX (&ev)) {
- Page *page;
-
- page = page_new (title, description, icon, type, priority,
- E_CONFIG_PAGE (e_corba_config_page_new_from_objref (corba_object)));
-
- page_list = g_list_prepend (page_list, page);
- } else {
- gchar *bonobo_ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot activate %s -- %s", info->iid, bonobo_ex_text);
- g_free (bonobo_ex_text);
- }
-
- if (icon != NULL)
- g_object_unref (icon);
-
- CORBA_exception_free (&ev);
- }
- g_slist_free(languages);
-
- page_list = sort_page_list (page_list);
- for (p = page_list, i = 0; p != NULL; p = p->next, i++) {
- Page *page;
-
- page = (Page *) p->data;
-
- e_multi_config_dialog_add_page (E_MULTI_CONFIG_DIALOG (dialog),
- page->title,
- page->description,
- page->icon,
- page->page_widget);
-
- if (page->type != NULL) {
- Bonobo_StringList list = page->type->v._u.value_stringv;
-
- for (j = 0; j < list._length; j++) {
- if (g_hash_table_lookup (priv->types, list._buffer[j]) == NULL)
- g_hash_table_insert (priv->types, g_strdup (list._buffer[j]),
- GINT_TO_POINTER (i));
- }
- }
-
- page_free (page);
- }
-
- g_list_free (page_list);
- CORBA_free (control_list);
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_finalize (GObject *object)
-{
- EShellSettingsDialog *dialog;
- EShellSettingsDialogPrivate *priv;
-
- dialog = E_SHELL_SETTINGS_DIALOG (object);
- priv = dialog->priv;
-
- g_hash_table_destroy (priv->types);
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_shell_settings_dialog_parent_class)->finalize) (object);
-}
-
-
-static void
-e_shell_settings_dialog_class_init (EShellSettingsDialogClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_shell_settings_dialog_init (EShellSettingsDialog *dialog)
-{
- EShellSettingsDialogPrivate *priv;
-
- priv = g_new (EShellSettingsDialogPrivate, 1);
- priv->types = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
-
- dialog->priv = priv;
-
- load_pages (dialog);
- set_dialog_size (dialog);
-
- gtk_window_set_title (GTK_WINDOW (dialog), _("Evolution Preferences"));
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-}
-
-
-GtkWidget *
-e_shell_settings_dialog_new (void)
-{
- EShellSettingsDialog *new;
-
- new = g_object_new (e_shell_settings_dialog_get_type (), NULL);
-
- return GTK_WIDGET (new);
-}
-
-void
-e_shell_settings_dialog_show_type (EShellSettingsDialog *dialog, const gchar *type)
-{
- EShellSettingsDialogPrivate *priv;
- gpointer key, value;
- gint page;
-
- g_return_if_fail (dialog != NULL);
- g_return_if_fail (E_IS_SHELL_SETTINGS_DIALOG (dialog));
- g_return_if_fail (type != NULL);
-
- priv = dialog->priv;
-
- if (!g_hash_table_lookup_extended (priv->types, type, &key, &value)) {
- gchar *slash, *supertype;
-
- slash = strchr (type, '/');
- if (slash) {
- supertype = g_strndup (type, slash - type);
- value = g_hash_table_lookup (priv->types, type);
- g_free (supertype);
- } else
- value = NULL;
- }
- page = GPOINTER_TO_INT (value);
-
- e_multi_config_dialog_show_page (E_MULTI_CONFIG_DIALOG (dialog), page);
-}
-
diff --git a/shell/e-shell-settings-dialog.h b/shell/e-shell-settings-dialog.h
deleted file mode 100644
index b39bc7beb3..0000000000
--- a/shell/e-shell-settings-dialog.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_SHELL_SETTINGS_DIALOG_H_
-#define _E_SHELL_SETTINGS_DIALOG_H_
-
-#include "e-multi-config-dialog.h"
-
-G_BEGIN_DECLS
-
-#define E_TYPE_SHELL_SETTINGS_DIALOG (e_shell_settings_dialog_get_type ())
-#define E_SHELL_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_SETTINGS_DIALOG, EShellSettingsDialog))
-#define E_SHELL_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_SETTINGS_DIALOG, EShellSettingsDialogClass))
-#define E_IS_SHELL_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_SETTINGS_DIALOG))
-#define E_IS_SHELL_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_SETTINGS_DIALOG))
-
-
-typedef struct _EShellSettingsDialog EShellSettingsDialog;
-typedef struct _EShellSettingsDialogPrivate EShellSettingsDialogPrivate;
-typedef struct _EShellSettingsDialogClass EShellSettingsDialogClass;
-
-struct _EShellSettingsDialog {
- EMultiConfigDialog parent;
-
- EShellSettingsDialogPrivate *priv;
-};
-
-struct _EShellSettingsDialogClass {
- EMultiConfigDialogClass parent_class;
-};
-
-
-GType e_shell_settings_dialog_get_type (void);
-GtkWidget *e_shell_settings_dialog_new (void);
-void e_shell_settings_dialog_show_type (EShellSettingsDialog *dialog,
- const gchar *type);
-
-G_END_DECLS
-
-#endif /* _E_SHELL_SETTINGS_DIALOG_H_ */
diff --git a/shell/e-shell-settings.c b/shell/e-shell-settings.c
new file mode 100644
index 0000000000..21cc855beb
--- /dev/null
+++ b/shell/e-shell-settings.c
@@ -0,0 +1,702 @@
+/*
+ * e-shell-settings.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-settings.h"
+
+#include "e-util/gconf-bridge.h"
+
+#define E_SHELL_SETTINGS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_SETTINGS, EShellSettingsPrivate))
+
+struct _EShellSettingsPrivate {
+ GArray *value_array;
+ guint debug : 1;
+};
+
+static GList *instances;
+static guint property_count;
+static gpointer parent_class;
+
+static GParamSpec *
+shell_settings_pspec_for_key (const gchar *property_name,
+ const gchar *gconf_key)
+{
+ GConfClient *client;
+ GConfEntry *entry;
+ GConfSchema *schema;
+ GConfValue *default_value;
+ GConfValueType value_type;
+ GParamSpec *pspec;
+ const gchar *bad_type;
+ const gchar *schema_name;
+ GError *error = NULL;
+
+ client = gconf_client_get_default ();
+
+ entry = gconf_client_get_entry (client, gconf_key, NULL, TRUE, &error);
+ if (error != NULL) {
+ g_error ("%s", error->message);
+ g_assert_not_reached ();
+ }
+
+ schema_name = gconf_entry_get_schema_name (entry);
+ if (schema_name == NULL) {
+ g_error ("No schema for GConf key '%s'", gconf_key);
+ g_assert_not_reached ();
+ }
+
+ schema = gconf_client_get_schema (client, schema_name, &error);
+ if (error != NULL) {
+ g_error ("%s", error->message);
+ g_assert_not_reached ();
+ }
+
+ value_type = gconf_schema_get_type (schema);
+ default_value = gconf_schema_get_default_value (schema);
+
+ /* If the schema does not specify a default value, make one up. */
+ if (default_value == NULL) {
+ default_value = gconf_value_new (value_type);
+
+ /* XXX This should NOT be necessary, but the GConfValue
+ * documentation claims it is. Bother. */
+ switch (value_type) {
+ case GCONF_VALUE_STRING:
+ gconf_value_set_string (default_value, "");
+ break;
+
+ case GCONF_VALUE_INT:
+ gconf_value_set_int (default_value, 0);
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ gconf_value_set_float (default_value, 0.0);
+ break;
+
+ case GCONF_VALUE_BOOL:
+ gconf_value_set_bool (default_value, FALSE);
+ break;
+
+ default:
+ /* We'll fail in the next switch statement. */
+ break;
+ }
+ }
+
+ switch (value_type) {
+ case GCONF_VALUE_STRING:
+ pspec = g_param_spec_string (
+ property_name, NULL, NULL,
+ gconf_value_get_string (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_INT:
+ pspec = g_param_spec_int (
+ property_name, NULL, NULL,
+ G_MININT, G_MAXINT,
+ gconf_value_get_int (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ pspec = g_param_spec_double (
+ property_name, NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE,
+ gconf_value_get_float (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_BOOL:
+ pspec = g_param_spec_boolean (
+ property_name, NULL, NULL,
+ gconf_value_get_bool (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_SCHEMA:
+ bad_type = "schema";
+ goto fail;
+
+ case GCONF_VALUE_LIST:
+ bad_type = "list";
+ goto fail;
+
+ case GCONF_VALUE_PAIR:
+ bad_type = "pair";
+ goto fail;
+
+ default:
+ bad_type = "invalid";
+ goto fail;
+ }
+
+ gconf_value_free (default_value);
+
+ return pspec;
+
+fail:
+ g_error (
+ "Unable to create EShellSettings property for "
+ "GConf key '%s' of type '%s'", gconf_key, bad_type);
+ g_assert_not_reached ();
+}
+
+static void
+shell_settings_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EShellSettingsPrivate *priv;
+ GValue *dest_value;
+
+ priv = E_SHELL_SETTINGS_GET_PRIVATE (object);
+
+ dest_value = &g_array_index (
+ priv->value_array, GValue, property_id - 1);
+
+ g_value_copy (value, dest_value);
+ g_object_notify (object, pspec->name);
+
+ if (priv->debug) {
+ gchar *contents;
+
+ contents = g_strdup_value_contents (value);
+ g_debug (
+ "Setting '%s' set to '%s' (%s)",
+ pspec->name, contents, G_VALUE_TYPE_NAME (value));
+ g_free (contents);
+ }
+}
+
+static void
+shell_settings_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EShellSettingsPrivate *priv;
+ GValue *src_value;
+
+ priv = E_SHELL_SETTINGS_GET_PRIVATE (object);
+
+ src_value = &g_array_index (
+ priv->value_array, GValue, property_id - 1);
+
+ g_value_copy (src_value, value);
+}
+
+static void
+shell_settings_finalize (GObject *object)
+{
+ EShellSettingsPrivate *priv;
+ guint ii;
+
+ priv = E_SHELL_SETTINGS_GET_PRIVATE (object);
+
+ for (ii = 0; ii < priv->value_array->len; ii++)
+ g_value_unset (&g_array_index (priv->value_array, GValue, ii));
+
+ g_array_free (priv->value_array, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_settings_class_init (EShellSettingsClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellSettingsPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_settings_set_property;
+ object_class->get_property = shell_settings_get_property;
+ object_class->finalize = shell_settings_finalize;
+}
+
+static void
+shell_settings_init (EShellSettings *shell_settings,
+ GObjectClass *object_class)
+{
+ GArray *value_array;
+ GParamSpec **pspecs;
+ guint ii;
+
+ instances = g_list_prepend (instances, shell_settings);
+
+ value_array = g_array_new (FALSE, TRUE, sizeof (GValue));
+ g_array_set_size (value_array, property_count);
+
+ shell_settings->priv = E_SHELL_SETTINGS_GET_PRIVATE (shell_settings);
+ shell_settings->priv->value_array = value_array;
+
+ g_object_freeze_notify (G_OBJECT (shell_settings));
+
+ pspecs = g_object_class_list_properties (object_class, NULL);
+ for (ii = 0; ii < property_count; ii++) {
+ GParamSpec *pspec = pspecs[ii];
+ GValue *value;
+
+ value = &g_array_index (value_array, GValue, ii);
+ g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_param_value_set_default (pspec, value);
+ g_object_notify (G_OBJECT (shell_settings), pspec->name);
+
+ /* FIXME Need to bind those properties that have
+ * associated GConf keys. */
+ }
+ g_free (pspecs);
+
+ g_object_thaw_notify (G_OBJECT (shell_settings));
+}
+
+GType
+e_shell_settings_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellSettingsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_settings_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellSettings),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_settings_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EShellSettings", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_settings_install_property:
+ * @pspec: a #GParamSpec
+ *
+ * Installs a new #EShellSettings class property from @pspec.
+ * This is usually done during initialization of an #EShellBackend
+ * or other dynamically loaded entity.
+ **/
+void
+e_shell_settings_install_property (GParamSpec *pspec)
+{
+ static GObjectClass *class = NULL;
+ GList *iter, *next;
+
+ g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+
+ if (G_UNLIKELY (class == NULL))
+ class = g_type_class_ref (E_TYPE_SHELL_SETTINGS);
+
+ if (g_object_class_find_property (class, pspec->name) != NULL) {
+ g_warning (
+ "Settings property \"%s\" already exists",
+ pspec->name);
+ return;
+ }
+
+ for (iter = instances; iter != NULL; iter = iter->next)
+ g_object_freeze_notify (iter->data);
+
+ g_object_class_install_property (class, ++property_count, pspec);
+
+ for (iter = instances; iter != NULL; iter = iter->next) {
+ EShellSettings *shell_settings;
+ GArray *value_array;
+ GValue *value;
+
+ shell_settings = E_SHELL_SETTINGS (iter->data);
+ value_array = shell_settings->priv->value_array;
+ g_array_set_size (value_array, property_count);
+
+ value = &g_array_index (
+ value_array, GValue, property_count - 1);
+ g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_param_value_set_default (pspec, value);
+ g_object_notify (G_OBJECT (shell_settings), pspec->name);
+ }
+
+ for (iter = instances; iter != NULL; iter = next) {
+ next = iter->next;
+ g_object_thaw_notify (iter->data);
+ }
+}
+
+/**
+ * e_shell_settings_install_property_for_key:
+ * @property_name: the name of the property to install
+ * @gconf_key: the GConf key to bind the property to
+ *
+ * Installs a new #EShellSettings class property by examining the
+ * GConf schema for @gconf_key to determine the appropriate type and
+ * default value. This is usually done during initialization of an
+ * #EShellBackend of other dynamically loaded entity.
+ *
+ * After the class property is installed, all #EShellSettings instances
+ * are bound to @gconf_key, causing @property_name and @gconf_key to have
+ * the same value at all times.
+ **/
+void
+e_shell_settings_install_property_for_key (const gchar *property_name,
+ const gchar *gconf_key)
+{
+ GParamSpec *pspec;
+ GList *iter, *next;
+
+ g_return_if_fail (property_name != NULL);
+ g_return_if_fail (gconf_key != NULL);
+
+ pspec = shell_settings_pspec_for_key (property_name, gconf_key);
+ e_shell_settings_install_property (pspec);
+
+ for (iter = instances; iter != NULL; iter = iter->next)
+ g_object_freeze_notify (iter->data);
+
+ for (iter = instances; iter != NULL; iter = iter->next) {
+ EShellSettings *shell_settings;
+
+ shell_settings = E_SHELL_SETTINGS (iter->data);
+
+ gconf_bridge_bind_property (
+ gconf_bridge_get (), gconf_key,
+ G_OBJECT (shell_settings), property_name);
+ }
+
+ for (iter = instances; iter != NULL; iter = next) {
+ next = iter->next;
+ g_object_thaw_notify (iter->data);
+ }
+}
+
+/**
+ * e_shell_settings_enable_debug:
+ * @shell_settings: an #EShellSettings
+ *
+ * Print a debug message to standard output when a property value changes.
+ **/
+void
+e_shell_settings_enable_debug (EShellSettings *shell_settings)
+{
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+
+ shell_settings->priv->debug = TRUE;
+}
+
+/**
+ * e_shell_settings_get_boolean:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Return the contents of an #EShellSettings property of type
+ * #G_TYPE_BOOLEAN.
+ *
+ * Returns: boolean contents of @property_name
+ **/
+gboolean
+e_shell_settings_get_boolean (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gboolean v_boolean;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), FALSE);
+ g_return_val_if_fail (property_name != NULL, FALSE);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_object_get_property (object, property_name, &value);
+ v_boolean = g_value_get_boolean (&value);
+ g_value_unset (&value);
+
+ return v_boolean;
+}
+
+/**
+ * e_shell_settings_set_boolean:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_boolean: boolean value to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_BOOLEAN
+ * to @v_boolean. If @property_name is bound to a GConf key, the GConf key
+ * will also be set to @v_boolean.
+ **/
+void
+e_shell_settings_set_boolean (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gboolean v_boolean)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, v_boolean);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_int:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_INT.
+ *
+ * Returns: integer contents of @property_name
+ **/
+gint
+e_shell_settings_get_int (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gint v_int;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), 0);
+ g_return_val_if_fail (property_name != NULL, 0);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_INT);
+ g_object_get_property (object, property_name, &value);
+ v_int = g_value_get_int (&value);
+ g_value_unset (&value);
+
+ return v_int;
+}
+
+/**
+ * e_shell_settings_set_int:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_int: integer value to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_INT
+ * to @v_int. If @property_name is bound to a GConf key, the GConf key
+ * will also be set to @v_int.
+ **/
+void
+e_shell_settings_set_int (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gint v_int)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, v_int);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_string:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_STRING. The returned string should be freed using g_free().
+ *
+ * Returns: string contents of @property_name
+ **/
+gchar *
+e_shell_settings_get_string (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gchar *v_string;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_STRING);
+ g_object_get_property (object, property_name, &value);
+ v_string = g_value_dup_string (&value);
+ g_value_unset (&value);
+
+ return v_string;
+}
+
+/**
+ * e_shell_settings_set_string:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_string: string to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_STRING
+ * to @v_string. If @property_name is bound to a GConf key, the GConf key
+ * will also be set to @v_string.
+ **/
+void
+e_shell_settings_set_string (EShellSettings *shell_settings,
+ const gchar *property_name,
+ const gchar *v_string)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, v_string);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_object:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_OBJECT. The caller owns the reference to the returned
+ * object, and should call g_object_unref() when finished with it.
+ *
+ * Returns: a new reference to the object under @property_name
+ **/
+gpointer
+e_shell_settings_get_object (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gpointer v_object;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_OBJECT);
+ g_object_get_property (object, property_name, &value);
+ v_object = g_value_dup_object (&value);
+ g_value_unset (&value);
+
+ return v_object;
+}
+
+/**
+ * e_shell_settings_set_object:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_object: object to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_OBJECT
+ * to @v_object.
+ **/
+void
+e_shell_settings_set_object (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_object)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_OBJECT);
+ g_value_set_object (&value, v_object);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_pointer:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_POINTER.
+ *
+ * Returns: pointer contents of @property_name
+ **/
+gpointer
+e_shell_settings_get_pointer (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gpointer v_pointer;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_POINTER);
+ g_object_get_property (object, property_name, &value);
+ v_pointer = g_value_get_pointer (&value);
+ g_value_unset (&value);
+
+ return v_pointer;
+}
+
+/**
+ * e_shell_settings_set_pointer:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_pointer: pointer to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_POINTER
+ * to @v_pointer.
+ **/
+void
+e_shell_settings_set_pointer (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_pointer)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_POINTER);
+ g_value_set_pointer (&value, v_pointer);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
diff --git a/shell/e-shell-settings.h b/shell/e-shell-settings.h
new file mode 100644
index 0000000000..c1ac497dec
--- /dev/null
+++ b/shell/e-shell-settings.h
@@ -0,0 +1,114 @@
+/*
+ * e-shell-settings.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-settings
+ * @short_description: settings management
+ * @include: shell/e-shell-settings.h
+ **/
+
+#ifndef E_SHELL_SETTINGS_H
+#define E_SHELL_SETTINGS_H
+
+#include <shell/e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_SETTINGS \
+ (e_shell_settings_get_type ())
+#define E_SHELL_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_SETTINGS, EShellSettings))
+#define E_SHELL_SETTINGS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_SETTINGS, EShellSettingsClass))
+#define E_IS_SHELL_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_SETTINGS))
+#define E_IS_SHELL_SETTINGS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_SETTINGS))
+#define E_SHELL_SETTINGS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_SETTINGS, EShellSettingsClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EShellSettings EShellSettings;
+typedef struct _EShellSettingsClass EShellSettingsClass;
+typedef struct _EShellSettingsPrivate EShellSettingsPrivate;
+
+/**
+ * EShellSettings:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellSettings {
+ GObject parent;
+ EShellSettingsPrivate *priv;
+};
+
+struct _EShellSettingsClass {
+ GObjectClass parent_class;
+};
+
+GType e_shell_settings_get_type (void);
+void e_shell_settings_install_property
+ (GParamSpec *pspec);
+void e_shell_settings_install_property_for_key
+ (const gchar *property_name,
+ const gchar *gconf_key);
+void e_shell_settings_enable_debug (EShellSettings *shell_settings);
+
+/* Getters and setters for common EShellSettings property types.
+ * These are more convenient than g_object_get() / g_object_set().
+ * Add more types as needed. If GObject ever adds similar functions,
+ * kill these. */
+
+gboolean e_shell_settings_get_boolean (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_boolean (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gboolean v_boolean);
+gint e_shell_settings_get_int (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_int (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gint v_int);
+gchar * e_shell_settings_get_string (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_string (EShellSettings *shell_settings,
+ const gchar *property_name,
+ const gchar *v_string);
+gpointer e_shell_settings_get_object (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_object (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_object);
+gpointer e_shell_settings_get_pointer (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_pointer (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_pointer);
+
+G_END_DECLS
+
+#endif /* E_SHELL_SETTINGS_H */
diff --git a/shell/e-shell-sidebar.c b/shell/e-shell-sidebar.c
new file mode 100644
index 0000000000..7763e64918
--- /dev/null
+++ b/shell/e-shell-sidebar.c
@@ -0,0 +1,683 @@
+/*
+ * e-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-sidebar.h"
+
+#include <e-shell-view.h>
+
+#define E_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebarPrivate))
+
+struct _EShellSidebarPrivate {
+
+ gpointer shell_view; /* weak pointer */
+
+ GtkWidget *event_box;
+ GtkWidget *image;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+ gchar *primary_text;
+ gchar *secondary_text;
+};
+
+enum {
+ PROP_0,
+ PROP_ICON_NAME,
+ PROP_PRIMARY_TEXT,
+ PROP_SECONDARY_TEXT,
+ PROP_SHELL_VIEW
+};
+
+static gpointer parent_class;
+
+static void
+shell_sidebar_set_shell_view (EShellSidebar *shell_sidebar,
+ EShellView *shell_view)
+{
+ g_return_if_fail (shell_sidebar->priv->shell_view == NULL);
+
+ shell_sidebar->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &shell_sidebar->priv->shell_view);
+}
+
+static void
+shell_sidebar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ICON_NAME:
+ e_shell_sidebar_set_icon_name (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ e_shell_sidebar_set_primary_text (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ e_shell_sidebar_set_secondary_text (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ shell_sidebar_set_shell_view (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ICON_NAME:
+ g_value_set_string (
+ value, e_shell_sidebar_get_icon_name (
+ E_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ g_value_set_string (
+ value, e_shell_sidebar_get_primary_text (
+ E_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ g_value_set_string (
+ value, e_shell_sidebar_get_secondary_text (
+ E_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_shell_sidebar_get_shell_view (
+ E_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_sidebar_dispose (GObject *object)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->image != NULL) {
+ g_object_unref (priv->image);
+ priv->image = NULL;
+ }
+
+ if (priv->event_box != NULL) {
+ g_object_unref (priv->event_box);
+ priv->event_box = NULL;
+ }
+
+ if (priv->primary_label != NULL) {
+ g_object_unref (priv->primary_label);
+ priv->primary_label = NULL;
+ }
+
+ if (priv->secondary_label != NULL) {
+ g_object_unref (priv->secondary_label);
+ priv->secondary_label = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_sidebar_finalize (GObject *object)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ g_free (priv->primary_text);
+ g_free (priv->secondary_text);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_sidebar_constructed (GObject *object)
+{
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ GtkSizeGroup *size_group;
+ GtkAction *action;
+ GtkWidget *container;
+ GtkWidget *widget;
+ gchar *label;
+ gchar *icon_name;
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ size_group = e_shell_view_get_size_group (shell_view);
+ action = e_shell_view_get_action (shell_view);
+
+ widget = shell_sidebar->priv->event_box;
+ gtk_size_group_add_widget (size_group, widget);
+
+ container = widget;
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 6);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ shell_sidebar->priv->image = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ shell_sidebar->priv->primary_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ shell_sidebar->priv->secondary_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_object_get (action, "icon-name", &icon_name, NULL);
+ e_shell_sidebar_set_icon_name (shell_sidebar, icon_name);
+ g_free (icon_name);
+
+ g_object_get (action, "label", &label, NULL);
+ e_shell_sidebar_set_primary_text (shell_sidebar, label);
+ g_free (label);
+}
+
+static void
+shell_sidebar_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EShellSidebarPrivate *priv;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ gtk_widget_size_request (child, requisition);
+
+ child = priv->event_box;
+ gtk_widget_size_request (child, &child_requisition);
+ requisition->width = MAX (requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+}
+
+static void
+shell_sidebar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EShellSidebarPrivate *priv;
+ GtkAllocation child_allocation;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ widget->allocation = *allocation;
+
+ child = priv->event_box;
+ gtk_widget_size_request (child, &child_requisition);
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width;
+ child_allocation.height = child_requisition.height;
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+ child_allocation.y += child_requisition.height;
+ child_allocation.height =
+ allocation->height - child_requisition.height;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+shell_sidebar_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (container);
+
+ /* Look in the internal widgets first. */
+
+ if (widget == priv->event_box) {
+ gtk_widget_unparent (priv->event_box);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ return;
+ }
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static void
+shell_sidebar_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (container);
+
+ if (include_internals)
+ callback (priv->event_box, callback_data);
+
+ /* Chain up to parent's forall() method. */
+ GTK_CONTAINER_CLASS (parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void
+shell_sidebar_class_init (EShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_sidebar_set_property;
+ object_class->get_property = shell_sidebar_get_property;
+ object_class->dispose = shell_sidebar_dispose;
+ object_class->finalize = shell_sidebar_finalize;
+ object_class->constructed = shell_sidebar_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = shell_sidebar_size_request;
+ widget_class->size_allocate = shell_sidebar_size_allocate;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = shell_sidebar_remove;
+ container_class->forall = shell_sidebar_forall;
+
+ /**
+ * EShellSidebar:icon-name
+ *
+ * The named icon is displayed at the top of the sidebar.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_ICON_NAME,
+ g_param_spec_string (
+ "icon-name",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellSidebar:primary-text
+ *
+ * The primary text is displayed in bold at the top of the sidebar.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_PRIMARY_TEXT,
+ g_param_spec_string (
+ "primary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellSidebar:secondary-text
+ *
+ * The secondary text is displayed in a smaller font at the top of
+ * the sidebar.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SECONDARY_TEXT,
+ g_param_spec_string (
+ "secondary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellSidebar:shell-view
+ *
+ * The #EShellView to which the sidebar widget belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ NULL,
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+shell_sidebar_init (EShellSidebar *shell_sidebar)
+{
+ GtkStyle *style;
+ GtkWidget *widget;
+ const GdkColor *color;
+
+ shell_sidebar->priv = E_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
+
+ GTK_WIDGET_SET_FLAGS (shell_sidebar, GTK_NO_WINDOW);
+
+ widget = gtk_event_box_new ();
+ style = gtk_widget_get_style (widget);
+ color = &style->bg[GTK_STATE_ACTIVE];
+ gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, color);
+ gtk_widget_set_parent (widget, GTK_WIDGET (shell_sidebar));
+ shell_sidebar->priv->event_box = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Finish initialization once we have a shell view. */
+}
+
+GType
+e_shell_sidebar_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_BIN, "EShellSidebar", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_sidebar_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellSidebar instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellSidebar instance
+ **/
+GtkWidget *
+e_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+/**
+ * e_shell_sidebar_check_state:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * #EShellSidebar subclasses should implement the
+ * <structfield>check_state</structfield> method in #EShellSidebarClass
+ * to return a set of flags describing the current sidebar selection.
+ * Subclasses are responsible for defining their own flags. This is
+ * primarily used to assist shell views with updating actions (see
+ * e_shell_view_update_actions()).
+ *
+ * Returns: a set of flags describing the current @shell_sidebar selection
+ **/
+guint32
+e_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+ EShellSidebarClass *shell_sidebar_class;
+
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), 0);
+
+ shell_sidebar_class = E_SHELL_SIDEBAR_GET_CLASS (shell_sidebar);
+ g_return_val_if_fail (shell_sidebar_class->check_state != NULL, 0);
+
+ return shell_sidebar_class->check_state (shell_sidebar);
+}
+
+/**
+ * e_shell_sidebar_get_shell_view:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the #EShellView that was passed to e_shell_sidebar_new().
+ *
+ * Returns: the #EShellView to which @shell_sidebar belongs
+ **/
+EShellView *
+e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar)
+{
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ return E_SHELL_VIEW (shell_sidebar->priv->shell_view);
+}
+
+/**
+ * e_shell_sidebar_get_icon_name:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the icon name displayed at the top of the sidebar.
+ *
+ * Returns: the icon name for @shell_sidebar
+ **/
+const gchar *
+e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar)
+{
+ GtkImage *image;
+ const gchar *icon_name;
+
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ image = GTK_IMAGE (shell_sidebar->priv->image);
+ gtk_image_get_icon_name (image, &icon_name, NULL);
+
+ return icon_name;
+}
+
+/**
+ * e_shell_sidebar_set_icon_name:
+ * @shell_sidebar: an #EShellSidebar
+ * @icon_name: a themed icon name
+ *
+ * Sets the icon name displayed at the top of the sidebar.
+ **/
+void
+e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar,
+ const gchar *icon_name)
+{
+ GtkImage *image;
+
+ g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
+
+ image = GTK_IMAGE (shell_sidebar->priv->image);
+ gtk_image_set_from_icon_name (image, icon_name, GTK_ICON_SIZE_MENU);
+
+ g_object_notify (G_OBJECT (shell_sidebar), "icon-name");
+}
+
+/**
+ * e_shell_sidebar_get_primary_text:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the primary text for @shell_sidebar.
+ *
+ * The primary text is displayed in bold at the top of the sidebar. It
+ * defaults to the shell view's label (as seen on the switcher button),
+ * but typically shows the name of the selected item in the sidebar.
+ *
+ * Returns: the primary text for @shell_sidebar
+ **/
+const gchar *
+e_shell_sidebar_get_primary_text (EShellSidebar *shell_sidebar)
+{
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ return shell_sidebar->priv->primary_text;
+}
+
+/**
+ * e_shell_sidebar_set_primary_text:
+ * @shell_sidebar: an #EShellSidebar
+ * @primary_text: text to be displayed in a bold font
+ *
+ * Sets the primary text for @shell_sidebar.
+ *
+ * The primary text is displayed in bold at the top of the sidebar. It
+ * defaults to the shell view's label (as seen on the switcher button),
+ * but typically shows the name of the selected item in the sidebar.
+ **/
+void
+e_shell_sidebar_set_primary_text (EShellSidebar *shell_sidebar,
+ const gchar *primary_text)
+{
+ GtkLabel *label;
+ gchar *markup;
+
+ g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
+
+ g_free (shell_sidebar->priv->primary_text);
+ shell_sidebar->priv->primary_text = g_strdup (primary_text);
+
+ if (primary_text == NULL)
+ primary_text = "";
+
+ label = GTK_LABEL (shell_sidebar->priv->primary_label);
+ markup = g_markup_printf_escaped ("<b>%s</b>", primary_text);
+ gtk_label_set_markup (label, markup);
+ g_free (markup);
+
+ gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar));
+ g_object_notify (G_OBJECT (shell_sidebar), "primary-text");
+}
+
+/**
+ * e_shell_sidebar_get_secondary_text:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the secondary text for @shell_sidebar.
+ *
+ * The secondary text is displayed in a smaller font at the top of the
+ * sidebar. It typically shows information about the contents of the
+ * selected sidebar item, such as total number of items, number of
+ * selected items, etc.
+ *
+ * Returns: the secondary text for @shell_sidebar
+ **/
+const gchar *
+e_shell_sidebar_get_secondary_text (EShellSidebar *shell_sidebar)
+{
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ return shell_sidebar->priv->secondary_text;
+}
+
+/**
+ * e_shell_sidebar_set_secondary_text:
+ * @shell_sidebar: an #EShellSidebar
+ * @secondary_text: text to be displayed in a smaller font
+ *
+ * Sets the secondary text for @shell_sidebar.
+ *
+ * The secondary text is displayed in a smaller font at the top of the
+ * sidebar. It typically shows information about the contents of the
+ * selected sidebar item, such as total number of items, number of
+ * selected items, etc.
+ **/
+void
+e_shell_sidebar_set_secondary_text (EShellSidebar *shell_sidebar,
+ const gchar *secondary_text)
+{
+ GtkLabel *label;
+ gchar *markup;
+
+ g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
+
+ g_free (shell_sidebar->priv->secondary_text);
+ shell_sidebar->priv->secondary_text = g_strdup (secondary_text);
+
+ if (secondary_text == NULL)
+ secondary_text = "";
+
+ label = GTK_LABEL (shell_sidebar->priv->secondary_label);
+ markup = g_markup_printf_escaped ("<small>%s</small>", secondary_text);
+ gtk_label_set_markup (label, markup);
+ g_free (markup);
+
+ gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar));
+ g_object_notify (G_OBJECT (shell_sidebar), "secondary-text");
+}
diff --git a/shell/e-shell-sidebar.h b/shell/e-shell-sidebar.h
new file mode 100644
index 0000000000..5999aa9de2
--- /dev/null
+++ b/shell/e-shell-sidebar.h
@@ -0,0 +1,97 @@
+/*
+ * e-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-sidebar
+ * @short_description: the left side of the main window
+ * @include: shell/e-shell-sidebar.h
+ **/
+
+#ifndef E_SHELL_SIDEBAR_H
+#define E_SHELL_SIDEBAR_H
+
+#include <shell/e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_SIDEBAR \
+ (e_shell_sidebar_get_type ())
+#define E_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebar))
+#define E_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_SIDEBAR, EShellSidebarClass))
+#define E_IS_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_SIDEBAR))
+#define E_IS_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_SIDEBAR))
+#define E_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebarClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellSidebar EShellSidebar;
+typedef struct _EShellSidebarClass EShellSidebarClass;
+typedef struct _EShellSidebarPrivate EShellSidebarPrivate;
+
+/**
+ * EShellSidebar:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellSidebar {
+ GtkBin parent;
+ EShellSidebarPrivate *priv;
+};
+
+struct _EShellSidebarClass {
+ GtkBinClass parent_class;
+
+ guint32 (*check_state) (EShellSidebar *shell_sidebar);
+};
+
+GType e_shell_sidebar_get_type (void);
+GtkWidget * e_shell_sidebar_new (struct _EShellView *shell_view);
+guint32 e_shell_sidebar_check_state (EShellSidebar *shell_sidebar);
+struct _EShellView *
+ e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar);
+const gchar * e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar);
+void e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar,
+ const gchar *icon_name);
+const gchar * e_shell_sidebar_get_primary_text(EShellSidebar *shell_sidebar);
+void e_shell_sidebar_set_primary_text(EShellSidebar *shell_sidebar,
+ const gchar *primary_text);
+const gchar * e_shell_sidebar_get_secondary_text
+ (EShellSidebar *shell_sidebar);
+void e_shell_sidebar_set_secondary_text
+ (EShellSidebar *shell_sidebar,
+ const gchar *secondary_text);
+
+G_END_DECLS
+
+#endif /* E_SHELL_SIDEBAR_H */
diff --git a/shell/e-shell-switcher.c b/shell/e-shell-switcher.c
new file mode 100644
index 0000000000..e1ed8606e5
--- /dev/null
+++ b/shell/e-shell-switcher.c
@@ -0,0 +1,700 @@
+/*
+ * e-shell-switcher.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-switcher.h"
+
+#include <glib/gi18n.h>
+
+#define E_SHELL_SWITCHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherPrivate))
+
+#define H_PADDING 6
+#define V_PADDING 6
+
+struct _EShellSwitcherPrivate {
+ GList *proxies;
+ gboolean style_set;
+ GtkToolbarStyle style;
+ GtkSettings *settings;
+ gulong settings_handler_id;
+ gboolean toolbar_visible;
+};
+
+enum {
+ PROP_0,
+ PROP_TOOLBAR_STYLE,
+ PROP_TOOLBAR_VISIBLE
+};
+
+enum {
+ STYLE_CHANGED,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static gint
+shell_switcher_layout_actions (EShellSwitcher *switcher)
+{
+ GtkAllocation *allocation;
+ gint num_btns = g_list_length (switcher->priv->proxies), btns_per_row;
+ GList **rows, *p;
+ gboolean icons_only;
+ gint row_number;
+ gint max_width = 0;
+ gint max_height = 0;
+ gint row_last;
+ gint x, y;
+ gint i;
+
+ allocation = &GTK_WIDGET (switcher)->allocation;
+ y = allocation->y + allocation->height;
+
+ if (num_btns == 0)
+ return allocation->height;
+
+ icons_only = (switcher->priv->style == GTK_TOOLBAR_ICONS);
+
+ /* Figure out the max width and height. */
+ for (p = switcher->priv->proxies; p != NULL; p = p->next) {
+ GtkWidget *widget = p->data;
+ GtkRequisition requisition;
+
+ gtk_widget_size_request (widget, &requisition);
+ max_height = MAX (max_height, requisition.height);
+ max_width = MAX (max_width, requisition.width);
+ }
+
+ /* Figure out how many rows and columns we'll use. */
+ btns_per_row = MAX (1, allocation->width / (max_width + H_PADDING));
+ if (!icons_only) {
+ /* If using text buttons, we want to try to have a
+ * completely filled-in grid, but if we can't, we want
+ * the odd row to have just a single button. */
+ while (num_btns % btns_per_row > 1)
+ btns_per_row--;
+ }
+
+ /* Assign buttons to rows. */
+ rows = g_new0 (GList *, num_btns / btns_per_row + 1);
+
+ if (!icons_only && num_btns % btns_per_row != 0) {
+ rows[0] = g_list_append (rows[0], switcher->priv->proxies->data);
+
+ p = switcher->priv->proxies->next;
+ row_number = p ? 1 : 0;
+ } else {
+ p = switcher->priv->proxies;
+ row_number = 0;
+ }
+
+ for (; p != NULL; p = p->next) {
+ GtkWidget *widget = p->data;
+
+ if (g_list_length (rows[row_number]) == btns_per_row)
+ row_number++;
+
+ rows[row_number] = g_list_append (rows[row_number], widget);
+ }
+
+ row_last = row_number;
+
+ /* Layout the buttons. */
+ for (i = row_last; i >= 0; i--) {
+ gint len, extra_width;
+
+ x = H_PADDING + allocation->x;
+ y -= max_height;
+ len = g_list_length (rows[i]);
+ if (!icons_only)
+ extra_width = (allocation->width - (len * max_width ) - (len * H_PADDING)) / len;
+ else
+ extra_width = 0;
+ for (p = rows [i]; p != NULL; p = p->next) {
+ GtkAllocation child_allocation;
+
+ child_allocation.x = x;
+ child_allocation.y = y;
+ child_allocation.width = max_width + extra_width;
+ child_allocation.height = max_height;
+
+ gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation);
+
+ x += child_allocation.width + H_PADDING;
+ }
+
+ y -= V_PADDING;
+ }
+
+ for (i = 0; i <= row_last; i ++)
+ g_list_free (rows [i]);
+ g_free (rows);
+
+ return y - allocation->y;
+}
+
+static void
+shell_switcher_toolbar_style_changed_cb (EShellSwitcher *switcher)
+{
+ if (!switcher->priv->style_set) {
+ switcher->priv->style_set = TRUE;
+ e_shell_switcher_unset_style (switcher);
+ }
+}
+
+static void
+shell_switcher_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TOOLBAR_STYLE:
+ e_shell_switcher_set_style (
+ E_SHELL_SWITCHER (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_TOOLBAR_VISIBLE:
+ e_shell_switcher_set_visible (
+ E_SHELL_SWITCHER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_switcher_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TOOLBAR_STYLE:
+ g_value_set_enum (
+ value, e_shell_switcher_get_style (
+ E_SHELL_SWITCHER (object)));
+ return;
+
+ case PROP_TOOLBAR_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_switcher_get_visible (
+ E_SHELL_SWITCHER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_switcher_dispose (GObject *object)
+{
+ EShellSwitcherPrivate *priv;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (object);
+
+ while (priv->proxies != NULL) {
+ GtkWidget *widget = priv->proxies->data;
+ gtk_container_remove (GTK_CONTAINER (object), widget);
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_switcher_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EShellSwitcherPrivate *priv;
+ GtkWidget *child;
+ GList *iter;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_request (child, requisition);
+
+ if (!priv->toolbar_visible)
+ return;
+
+ for (iter = priv->proxies; iter != NULL; iter = iter->next) {
+ GtkWidget *widget = iter->data;
+ GtkRequisition child_requisition;
+
+ gtk_widget_size_request (widget, &child_requisition);
+
+ child_requisition.width += H_PADDING;
+ child_requisition.height += V_PADDING;
+
+ requisition->width = MAX (
+ requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+ }
+}
+
+static void
+shell_switcher_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EShellSwitcher *switcher;
+ GtkAllocation child_allocation;
+ GtkWidget *child;
+ gint height;
+
+ switcher = E_SHELL_SWITCHER (widget);
+
+ widget->allocation = *allocation;
+
+ if (switcher->priv->toolbar_visible)
+ height = shell_switcher_layout_actions (switcher);
+ else
+ height = allocation->height;
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width;
+ child_allocation.height = height;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+shell_switcher_screen_changed (GtkWidget *widget,
+ GdkScreen *previous_screen)
+{
+ EShellSwitcherPrivate *priv;
+ GtkSettings *settings;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
+
+ if (gtk_widget_has_screen (widget))
+ settings = gtk_widget_get_settings (widget);
+ else
+ settings = NULL;
+
+ if (settings == priv->settings)
+ return;
+
+ if (priv->settings != NULL) {
+ g_signal_handler_disconnect (
+ priv->settings, priv->settings_handler_id);
+ g_object_unref (priv->settings);
+ }
+
+ if (settings != NULL) {
+ priv->settings = g_object_ref (settings);
+ priv->settings_handler_id = g_signal_connect_swapped (
+ settings, "notify::gtk-toolbar-style",
+ G_CALLBACK (shell_switcher_toolbar_style_changed_cb),
+ widget);
+ } else
+ priv->settings = NULL;
+
+ shell_switcher_toolbar_style_changed_cb (E_SHELL_SWITCHER (widget));
+}
+
+static void
+shell_switcher_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EShellSwitcherPrivate *priv;
+ GList *link;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (container);
+
+ /* Look in the internal widgets first. */
+
+ link = g_list_find (priv->proxies, widget);
+ if (link != NULL) {
+ GtkWidget *widget = link->data;
+
+ gtk_widget_unparent (widget);
+ priv->proxies = g_list_delete_link (priv->proxies, link);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ return;
+ }
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static void
+shell_switcher_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EShellSwitcherPrivate *priv;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (container);
+
+ if (include_internals)
+ g_list_foreach (
+ priv->proxies, (GFunc) callback, callback_data);
+
+ /* Chain up to parent's forall() method. */
+ GTK_CONTAINER_CLASS (parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void
+shell_switcher_style_changed (EShellSwitcher *switcher,
+ GtkToolbarStyle style)
+{
+ if (switcher->priv->style == style)
+ return;
+
+ switcher->priv->style = style;
+
+ g_list_foreach (
+ switcher->priv->proxies,
+ (GFunc) gtk_tool_item_toolbar_reconfigured, NULL);
+
+ gtk_widget_queue_resize (GTK_WIDGET (switcher));
+ g_object_notify (G_OBJECT (switcher), "toolbar-style");
+}
+
+static GtkIconSize
+shell_switcher_get_icon_size (GtkToolShell *shell)
+{
+ return GTK_ICON_SIZE_LARGE_TOOLBAR;
+}
+
+static GtkOrientation
+shell_switcher_get_orientation (GtkToolShell *shell)
+{
+ return GTK_ORIENTATION_HORIZONTAL;
+}
+
+static GtkToolbarStyle
+shell_switcher_get_style (GtkToolShell *shell)
+{
+ return e_shell_switcher_get_style (E_SHELL_SWITCHER (shell));
+}
+
+static GtkReliefStyle
+shell_switcher_get_relief_style (GtkToolShell *shell)
+{
+ return GTK_RELIEF_NORMAL;
+}
+
+static void
+shell_switcher_class_init (EShellSwitcherClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellSwitcherPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_switcher_set_property;
+ object_class->get_property = shell_switcher_get_property;
+ object_class->dispose = shell_switcher_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = shell_switcher_size_request;
+ widget_class->size_allocate = shell_switcher_size_allocate;
+ widget_class->screen_changed = shell_switcher_screen_changed;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = shell_switcher_remove;
+ container_class->forall = shell_switcher_forall;
+
+ class->style_changed = shell_switcher_style_changed;
+
+ /**
+ * EShellSwitcher:toolbar-style
+ *
+ * The switcher's toolbar style.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TOOLBAR_STYLE,
+ g_param_spec_enum (
+ "toolbar-style",
+ _("Toolbar Style"),
+ _("The switcher's toolbar style"),
+ GTK_TYPE_TOOLBAR_STYLE,
+ E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellSwitcher:toolbar-visible
+ *
+ * Whether the switcher is visible.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TOOLBAR_VISIBLE,
+ g_param_spec_boolean (
+ "toolbar-visible",
+ _("Toolbar Visible"),
+ _("Whether the switcher is visible"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellSwitcher::style-changed
+ * @switcher: the #EShellSwitcher which emitted the signal
+ * @style: the new #GtkToolbarStyle of the switcher
+ *
+ * Emitted when the style of the switcher changes.
+ **/
+ signals[STYLE_CHANGED] = g_signal_new (
+ "style-changed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EShellSwitcherClass, style_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_TOOLBAR_STYLE);
+}
+
+static void
+shell_switcher_init (EShellSwitcher *switcher)
+{
+ switcher->priv = E_SHELL_SWITCHER_GET_PRIVATE (switcher);
+
+ GTK_WIDGET_SET_FLAGS (switcher, GTK_NO_WINDOW);
+}
+
+static void
+shell_switcher_tool_shell_iface_init (GtkToolShellIface *iface)
+{
+ iface->get_icon_size = shell_switcher_get_icon_size;
+ iface->get_orientation = shell_switcher_get_orientation;
+ iface->get_style = shell_switcher_get_style;
+ iface->get_relief_style = shell_switcher_get_relief_style;
+}
+
+GType
+e_shell_switcher_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellSwitcherClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_switcher_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellSwitcher),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_switcher_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo tool_shell_info = {
+ (GInterfaceInitFunc) shell_switcher_tool_shell_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_BIN, "EShellSwitcher", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTK_TYPE_TOOL_SHELL, &tool_shell_info);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_switcher_new:
+ *
+ * Creates a new #EShellSwitcher instance.
+ *
+ * Returns: a new #EShellSwitcher instance
+ **/
+GtkWidget *
+e_shell_switcher_new (void)
+{
+ return g_object_new (E_TYPE_SHELL_SWITCHER, NULL);
+}
+
+/**
+ * e_shell_switcher_add_action:
+ * @switcher: an #EShellSwitcher
+ * @action: a #GtkAction
+ *
+ * Adds a button to @switcher that proxies for @action. Switcher buttons
+ * appear in the order they were added.
+ *
+ * #EShellWindow adds switcher actions in the order given by the
+ * <structfield>sort_order</structfield> field in #EShellBackendClass.
+ **/
+void
+e_shell_switcher_add_action (EShellSwitcher *switcher,
+ GtkAction *action)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ g_object_ref (action);
+ widget = gtk_action_create_tool_item (action);
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), TRUE);
+ gtk_widget_show (widget);
+
+ switcher->priv->proxies = g_list_append (
+ switcher->priv->proxies, widget);
+
+ gtk_widget_set_parent (widget, GTK_WIDGET (switcher));
+ gtk_widget_queue_resize (GTK_WIDGET (switcher));
+}
+
+/**
+ * e_shell_switcher_get_style:
+ * @switcher: an #EShellSwitcher
+ *
+ * Returns whether @switcher has text, icons or both.
+ *
+ * Returns: the current style of @shell
+ **/
+GtkToolbarStyle
+e_shell_switcher_get_style (EShellSwitcher *switcher)
+{
+ g_return_val_if_fail (
+ E_IS_SHELL_SWITCHER (switcher),
+ E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE);
+
+ return switcher->priv->style;
+}
+
+/**
+ * e_shell_switcher_set_style:
+ * @switcher: an #EShellSwitcher
+ * @style: the new style for @switcher
+ *
+ * Alters the view of @switcher to display either icons only, text only,
+ * or both.
+ **/
+void
+e_shell_switcher_set_style (EShellSwitcher *switcher,
+ GtkToolbarStyle style)
+{
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+ switcher->priv->style_set = TRUE;
+ g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
+}
+
+/**
+ * e_shell_switcher_unset_style:
+ * @switcher: an #EShellSwitcher
+ *
+ * Unsets a switcher style set with e_shell_switcher_set_style(), so
+ * that user preferences will be used to determine the switcher style.
+ **/
+void
+e_shell_switcher_unset_style (EShellSwitcher *switcher)
+{
+ GtkSettings *settings;
+ GtkToolbarStyle style;
+
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+ if (!switcher->priv->style_set)
+ return;
+
+ settings = switcher->priv->settings;
+ if (settings != NULL)
+ g_object_get (settings, "gtk-toolbar-style", &style, NULL);
+ else
+ style = E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE;
+
+ if (style == GTK_TOOLBAR_BOTH)
+ style = GTK_TOOLBAR_BOTH_HORIZ;
+
+ if (style != switcher->priv->style)
+ g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
+
+ switcher->priv->style_set = FALSE;
+}
+
+/**
+ * e_shell_switcher_get_visible:
+ * @switcher: an #EShellSwitcher
+ *
+ * Returns %TRUE if the switcher buttons are visible.
+ *
+ * Note that switcher button visibility is different than
+ * @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher
+ * is actually a container widget for #EShellSidebar.
+ *
+ * Returns: %TRUE if the switcher buttons are visible
+ **/
+gboolean
+e_shell_switcher_get_visible (EShellSwitcher *switcher)
+{
+ g_return_val_if_fail (E_IS_SHELL_SWITCHER (switcher), FALSE);
+
+ return switcher->priv->toolbar_visible;
+}
+
+/**
+ * e_shell_switcher_set_visible:
+ * @switcher: an #EShellSwitcher
+ * @visible: whether the switcher buttons should be visible
+ *
+ * Sets the switcher button visiblity to @visible.
+ *
+ * Note that switcher button visibility is different than
+ * @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher
+ * is actually a container widget for #EShellSidebar.
+ **/
+void
+e_shell_switcher_set_visible (EShellSwitcher *switcher,
+ gboolean visible)
+{
+ GList *iter;
+
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+ switcher->priv->toolbar_visible = visible;
+
+ for (iter = switcher->priv->proxies; iter != NULL; iter = iter->next)
+ g_object_set (iter->data, "visible", visible, NULL);
+
+ gtk_widget_queue_resize (GTK_WIDGET (switcher));
+
+ g_object_notify (G_OBJECT (switcher), "toolbar-visible");
+}
diff --git a/shell/e-shell-switcher.h b/shell/e-shell-switcher.h
new file mode 100644
index 0000000000..1cc644595b
--- /dev/null
+++ b/shell/e-shell-switcher.h
@@ -0,0 +1,92 @@
+/*
+ * e-shell-switcher.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-switcher
+ * @short_description: buttons for switching views
+ * @include: shell/e-shell-switcher.h
+ **/
+
+#ifndef E_SHELL_SWITCHER_H
+#define E_SHELL_SWITCHER_H
+
+#include <e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_SWITCHER \
+ (e_shell_switcher_get_type ())
+#define E_SHELL_SWITCHER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcher))
+#define E_SHELL_SWITCHER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_SWITCHER, EShellSwitcherClass))
+#define E_IS_SHELL_SWITCHER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_SWITCHER))
+#define E_IS_SHELL_SWITCHER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_SWITCHER))
+#define E_SHELL_SWITCHER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherClass))
+
+#define E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH_HORIZ
+
+G_BEGIN_DECLS
+
+typedef struct _EShellSwitcher EShellSwitcher;
+typedef struct _EShellSwitcherClass EShellSwitcherClass;
+typedef struct _EShellSwitcherPrivate EShellSwitcherPrivate;
+
+/**
+ * EShellSwitcher:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellSwitcher {
+ GtkBin parent;
+ EShellSwitcherPrivate *priv;
+};
+
+struct _EShellSwitcherClass {
+ GtkBinClass parent_class;
+
+ void (*style_changed) (EShellSwitcher *switcher,
+ GtkToolbarStyle style);
+};
+
+GType e_shell_switcher_get_type (void);
+GtkWidget * e_shell_switcher_new (void);
+void e_shell_switcher_add_action (EShellSwitcher *switcher,
+ GtkAction *action);
+GtkToolbarStyle e_shell_switcher_get_style (EShellSwitcher *switcher);
+void e_shell_switcher_set_style (EShellSwitcher *switcher,
+ GtkToolbarStyle style);
+void e_shell_switcher_unset_style (EShellSwitcher *switcher);
+gboolean e_shell_switcher_get_visible (EShellSwitcher *switcher);
+void e_shell_switcher_set_visible (EShellSwitcher *switcher,
+ gboolean visible);
+
+G_END_DECLS
+
+#endif /* E_SHELL_SWITCHER_H */
diff --git a/shell/e-shell-taskbar.c b/shell/e-shell-taskbar.c
new file mode 100644
index 0000000000..61f27fbc79
--- /dev/null
+++ b/shell/e-shell-taskbar.c
@@ -0,0 +1,421 @@
+/*
+ * e-shell-taskbar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-taskbar.h"
+
+#include <e-shell-view.h>
+
+#include <widgets/misc/e-activity-proxy.h>
+
+#define E_SHELL_TASKBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbarPrivate))
+
+struct _EShellTaskbarPrivate {
+
+ gpointer shell_view; /* weak pointer */
+
+ GtkWidget *label;
+ GtkWidget *hbox;
+
+ GHashTable *proxy_table;
+};
+
+enum {
+ PROP_0,
+ PROP_MESSAGE,
+ PROP_SHELL_VIEW
+};
+
+static gpointer parent_class;
+
+static void
+shell_taskbar_activity_remove (EShellTaskbar *shell_taskbar,
+ EActivity *activity)
+{
+ GtkBox *box;
+ GtkWidget *proxy;
+ GHashTable *proxy_table;
+
+ box = GTK_BOX (shell_taskbar->priv->hbox);
+ proxy_table = shell_taskbar->priv->proxy_table;
+ proxy = g_hash_table_lookup (proxy_table, activity);
+ g_return_if_fail (proxy != NULL);
+
+ g_hash_table_remove (proxy_table, activity);
+ gtk_container_remove (GTK_CONTAINER (box), proxy);
+
+ if (box->children == NULL)
+ gtk_widget_hide (GTK_WIDGET (box));
+}
+
+static void
+shell_taskbar_activity_add (EShellTaskbar *shell_taskbar,
+ EActivity *activity)
+{
+ GtkBox *box;
+ GtkWidget *proxy;
+
+ proxy = e_activity_proxy_new (activity);
+ box = GTK_BOX (shell_taskbar->priv->hbox);
+ gtk_box_pack_start (box, proxy, TRUE, TRUE, 0);
+ gtk_box_reorder_child (box, proxy, 0);
+ gtk_widget_show (GTK_WIDGET (box));
+ gtk_widget_show (proxy);
+
+ g_hash_table_insert (
+ shell_taskbar->priv->proxy_table,
+ g_object_ref (activity), g_object_ref (proxy));
+
+ g_signal_connect_swapped (
+ activity, "cancelled",
+ G_CALLBACK (shell_taskbar_activity_remove), shell_taskbar);
+
+ g_signal_connect_swapped (
+ activity, "completed",
+ G_CALLBACK (shell_taskbar_activity_remove), shell_taskbar);
+}
+
+static void
+shell_taskbar_set_shell_view (EShellTaskbar *shell_taskbar,
+ EShellView *shell_view)
+{
+ g_return_if_fail (shell_taskbar->priv->shell_view == NULL);
+
+ shell_taskbar->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &shell_taskbar->priv->shell_view);
+}
+
+static void
+shell_taskbar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MESSAGE:
+ e_shell_taskbar_set_message (
+ E_SHELL_TASKBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ shell_taskbar_set_shell_view (
+ E_SHELL_TASKBAR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_taskbar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MESSAGE:
+ g_value_set_string (
+ value, e_shell_taskbar_get_message (
+ E_SHELL_TASKBAR (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_shell_taskbar_get_shell_view (
+ E_SHELL_TASKBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_taskbar_dispose (GObject *object)
+{
+ EShellTaskbarPrivate *priv;
+
+ priv = E_SHELL_TASKBAR_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->label != NULL) {
+ g_object_unref (priv->label);
+ priv->label = NULL;
+ }
+
+ if (priv->hbox != NULL) {
+ g_object_unref (priv->hbox);
+ priv->hbox = NULL;
+ }
+
+ g_hash_table_remove_all (priv->proxy_table);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_taskbar_finalize (GObject *object)
+{
+ EShellTaskbarPrivate *priv;
+
+ priv = E_SHELL_TASKBAR_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->proxy_table);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_taskbar_constructed (GObject *object)
+{
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellTaskbar *shell_taskbar;
+
+ shell_taskbar = E_SHELL_TASKBAR (object);
+ shell_view = e_shell_taskbar_get_shell_view (shell_taskbar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ g_signal_connect_swapped (
+ shell_backend, "activity-added",
+ G_CALLBACK (shell_taskbar_activity_add), shell_taskbar);
+}
+
+static void
+shell_taskbar_class_init (EShellTaskbarClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellTaskbarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_taskbar_set_property;
+ object_class->get_property = shell_taskbar_get_property;
+ object_class->dispose = shell_taskbar_dispose;
+ object_class->finalize = shell_taskbar_finalize;
+ object_class->constructed = shell_taskbar_constructed;
+
+ /**
+ * EShellTaskbar:message
+ *
+ * The message to display in the taskbar.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_MESSAGE,
+ g_param_spec_string (
+ "message",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellTaskbar:shell-view
+ *
+ * The #EShellView to which the taskbar widget belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ NULL,
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+shell_taskbar_init (EShellTaskbar *shell_taskbar)
+{
+ GtkWidget *widget;
+ GHashTable *proxy_table;
+ gint height;
+
+ proxy_table = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+
+ shell_taskbar->priv = E_SHELL_TASKBAR_GET_PRIVATE (shell_taskbar);
+ shell_taskbar->priv->proxy_table = proxy_table;
+
+ gtk_box_set_spacing (GTK_BOX (shell_taskbar), 12);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_box_pack_start (GTK_BOX (shell_taskbar), widget, TRUE, TRUE, 0);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ shell_taskbar->priv->label = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (shell_taskbar), widget, TRUE, TRUE, 0);
+ shell_taskbar->priv->hbox = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ /* Make the taskbar large enough to accomodate a small icon.
+ * XXX The "* 2" is a fudge factor to allow for some padding
+ * The true value is probably buried in a style property. */
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
+ gtk_widget_set_size_request (
+ GTK_WIDGET (shell_taskbar), -1, (height * 2));
+}
+
+GType
+e_shell_taskbar_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellTaskbarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_taskbar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellTaskbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_taskbar_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HBOX, "EShellTaskbar", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_taskbar_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellTaskbar instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellTaskbar instance
+ **/
+GtkWidget *
+e_shell_taskbar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_SHELL_TASKBAR, "shell-view", shell_view, NULL);
+}
+
+/**
+ * e_shell_taskbar_get_shell_view:
+ * @shell_taskbar: an #EShellTaskbar
+ *
+ * Returns the #EShellView that was passed to e_shell_taskbar_new().
+ *
+ * Returns: the #EShellView to which @shell_taskbar belongs
+ **/
+EShellView *
+e_shell_taskbar_get_shell_view (EShellTaskbar *shell_taskbar)
+{
+ g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL);
+
+ return shell_taskbar->priv->shell_view;
+}
+
+/**
+ * e_shell_taskbar_get_message:
+ * @shell_taskbar: an #EShellTaskbar
+ *
+ * Returns the message currently shown in the taskbar, or an empty string
+ * if no message is shown. Taskbar messages are used primarily for menu
+ * tooltips.
+ *
+ * Returns: the current taskbar message
+ **/
+const gchar *
+e_shell_taskbar_get_message (EShellTaskbar *shell_taskbar)
+{
+ GtkWidget *label;
+
+ g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL);
+
+ label = shell_taskbar->priv->label;
+
+ return gtk_label_get_text (GTK_LABEL (label));
+}
+
+/**
+ * e_shell_taskbar_set_message:
+ * @shell_taskbar: an #EShellTaskbar
+ * @message: the message to show
+ *
+ * Shows a message in the taskbar. If @message is %NULL or an empty string,
+ * the taskbar message is cleared. Taskbar messages are used primarily for
+ * menu tooltips.
+ **/
+void
+e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar,
+ const gchar *message)
+{
+ GtkWidget *label;
+
+ g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar));
+
+ label = shell_taskbar->priv->label;
+ gtk_label_set_text (GTK_LABEL (label), message);
+
+ if (message != NULL && *message != '\0')
+ gtk_widget_show (label);
+ else
+ gtk_widget_hide (label);
+
+ g_object_notify (G_OBJECT (shell_taskbar), "message");
+}
+
+/**
+ * e_shell_taskbar_unset_message:
+ * @shell_taskbar: an #EShellTaskbar
+ *
+ * This is equivalent to passing a %NULL message to
+ * e_shell_taskbar_set_message().
+ **/
+void
+e_shell_taskbar_unset_message (EShellTaskbar *shell_taskbar)
+{
+ g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar));
+
+ e_shell_taskbar_set_message (shell_taskbar, NULL);
+}
diff --git a/shell/e-shell-taskbar.h b/shell/e-shell-taskbar.h
new file mode 100644
index 0000000000..3c3d40010e
--- /dev/null
+++ b/shell/e-shell-taskbar.h
@@ -0,0 +1,87 @@
+/*
+ * e-shell-taskbar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-taskbar
+ * @short_description: the bottom of the main window
+ * @include: shell/e-shell-taskbar.h
+ **/
+
+#ifndef E_SHELL_TASKBAR_H
+#define E_SHELL_TASKBAR_H
+
+#include <shell/e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_TASKBAR \
+ (e_shell_taskbar_get_type ())
+#define E_SHELL_TASKBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbar))
+#define E_SHELL_TASKBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_TASKBAR, EShellTaskbarClass))
+#define E_IS_SHELL_TASKBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_TASKBAR))
+#define E_IS_SHELL_TASKBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_TASKBAR))
+#define E_SHELL_TASKBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbarClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellTaskbar EShellTaskbar;
+typedef struct _EShellTaskbarClass EShellTaskbarClass;
+typedef struct _EShellTaskbarPrivate EShellTaskbarPrivate;
+
+/**
+ * EShellTaskbar:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellTaskbar {
+ GtkHBox parent;
+ EShellTaskbarPrivate *priv;
+};
+
+struct _EShellTaskbarClass {
+ GtkHBoxClass parent_class;
+};
+
+GType e_shell_taskbar_get_type (void);
+GtkWidget * e_shell_taskbar_new (struct _EShellView *shell_view);
+struct _EShellView *
+ e_shell_taskbar_get_shell_view (EShellTaskbar *shell_taskbar);
+const gchar * e_shell_taskbar_get_message (EShellTaskbar *shell_taskbar);
+void e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar,
+ const gchar *message);
+void e_shell_taskbar_unset_message (EShellTaskbar *shell_taskbar);
+
+G_END_DECLS
+
+#endif /* E_SHELL_TASKBAR_H */
diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c
index 319a0d3c76..5808f9e027 100644
--- a/shell/e-shell-view.c
+++ b/shell/e-shell-view.c
@@ -1,5 +1,5 @@
/*
- * Helper class for evolution shells to setup a view
+ * e-shell-view.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,126 +15,1177 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "e-shell-view.h"
-#include <gtk/gtk.h>
+#include <string.h>
#include <glib/gi18n.h>
-#include "e-shell-view.h"
-#include "e-shell-window.h"
+#include "e-util/e-util.h"
+#include "e-util/e-plugin-ui.h"
+
+#include "e-shell-window-actions.h"
+
+#define E_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_VIEW, EShellViewPrivate))
-static BonoboObjectClass *parent_class = NULL;
+#define STATE_SAVE_TIMEOUT_SECONDS 3
struct _EShellViewPrivate {
- gint dummy;
+
+ gpointer shell_window; /* weak pointer */
+
+ GKeyFile *state_key_file;
+ guint state_save_source_id;
+
+ gchar *title;
+ gchar *view_id;
+ gint page_num;
+ guint merge_id;
+
+ GtkAction *action;
+ GtkSizeGroup *size_group;
+ GtkWidget *shell_content;
+ GtkWidget *shell_sidebar;
+ GtkWidget *shell_taskbar;
};
+enum {
+ PROP_0,
+ PROP_ACTION,
+ PROP_PAGE_NUM,
+ PROP_TITLE,
+ PROP_SHELL_BACKEND,
+ PROP_SHELL_CONTENT,
+ PROP_SHELL_SIDEBAR,
+ PROP_SHELL_TASKBAR,
+ PROP_SHELL_WINDOW,
+ PROP_VIEW_ID
+};
+
+enum {
+ TOGGLED,
+ UPDATE_ACTIONS,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static gulong signals[LAST_SIGNAL];
+
+static void
+shell_view_init_view_collection (EShellViewClass *class)
+{
+ EShellBackend *shell_backend;
+ const gchar *base_dir;
+ const gchar *backend_name;
+ gchar *system_dir;
+ gchar *local_dir;
+
+ shell_backend = class->shell_backend;
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ base_dir = EVOLUTION_GALVIEWSDIR;
+ system_dir = g_build_filename (base_dir, backend_name, NULL);
+
+ base_dir = e_shell_backend_get_data_dir (shell_backend);
+ local_dir = g_build_filename (base_dir, "views", NULL);
+
+ /* The view collection is never destroyed. */
+ class->view_collection = gal_view_collection_new ();
+
+ gal_view_collection_set_title (
+ class->view_collection, class->label);
+
+ gal_view_collection_set_storage_directories (
+ class->view_collection, system_dir, local_dir);
+
+ g_free (system_dir);
+ g_free (local_dir);
+
+ /* This is all we can do. It's up to the subclasses to
+ * add the appropriate factories to the view collection. */
+}
+
static void
-impl_ShellView_setTitle(PortableServer_Servant _servant, const CORBA_char *id, const CORBA_char * title, CORBA_Environment * ev)
+shell_view_update_view_id (EShellView *shell_view,
+ GalViewInstance *view_instance)
{
- EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
- /* To translators: This is the window title and %s is the
- component name. Most translators will want to keep it as is. */
- gchar *tmp = g_strdup_printf(_("%s - Evolution"), title);
+ gchar *view_id;
- e_shell_window_set_title(esw->window, id, tmp);
- g_free(tmp);
+ view_id = gal_view_instance_get_current_view_id (view_instance);
+ e_shell_view_set_view_id (shell_view, view_id);
+ g_free (view_id);
}
static void
-impl_ShellView_setComponent(PortableServer_Servant _servant, const CORBA_char *id, CORBA_Environment * ev)
+shell_view_load_state (EShellView *shell_view)
{
- EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
+ EShellBackend *shell_backend;
+ GKeyFile *key_file;
+ const gchar *config_dir;
+ gchar *filename;
+ GError *error = NULL;
- e_shell_window_switch_to_component(esw->window, id);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ config_dir = e_shell_backend_get_config_dir (shell_backend);
+ filename = g_build_filename (config_dir, "state", NULL);
+
+ /* XXX Should do this asynchronously. */
+ key_file = shell_view->priv->state_key_file;
+ g_key_file_load_from_file (key_file, filename, 0, &error);
+
+ if (error == NULL)
+ goto exit;
+
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ g_warning ("%s", error->message);
+
+ g_error_free (error);
+
+exit:
+ g_free (filename);
}
-struct change_icon_struct {
- const gchar *component_name;
- const gchar *icon_name;
-};
+static void
+shell_view_save_state (EShellView *shell_view)
+{
+ EShellBackend *shell_backend;
+ GKeyFile *key_file;
+ const gchar *config_dir;
+ gchar *contents;
+ gchar *filename;
+ GError *error = NULL;
+
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ config_dir = e_shell_backend_get_config_dir (shell_backend);
+ filename = g_build_filename (config_dir, "state", NULL);
+
+ /* XXX Should do this asynchronously. */
+ key_file = shell_view->priv->state_key_file;
+ contents = g_key_file_to_data (key_file, NULL, NULL);
+ g_file_set_contents (filename, contents, -1, &error);
+ g_free (contents);
+
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (filename);
+}
static gboolean
-change_button_icon_func (EShell *shell, EShellWindow *window, gpointer user_data)
+shell_view_state_timeout_cb (EShellView *shell_view)
{
- struct change_icon_struct *cis = (struct change_icon_struct*)user_data;
+ shell_view_save_state (shell_view);
+ shell_view->priv->state_save_source_id = 0;
- g_return_val_if_fail (window != NULL, FALSE);
- g_return_val_if_fail (cis != NULL, FALSE);
+ return FALSE;
+}
+
+static gboolean
+shell_view_register_ui_manager (EShellView *shell_view)
+{
+ EShellViewClass *shell_view_class;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ const gchar *id;
- e_shell_window_change_component_button_icon (window, cis->component_name, cis->icon_name);
+ /* This is a one-time, post-construction idle callback. */
- return TRUE;
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ id = shell_view_class->ui_manager_id;
+
+ e_plugin_ui_register_manager (ui_manager, id, shell_view);
+
+ if (e_shell_view_is_active (shell_view)) {
+ e_plugin_ui_enable_manager (ui_manager, id);
+ e_shell_view_update_actions (shell_view);
+ }
+
+ return FALSE;
+}
+
+static void
+shell_view_emit_toggled (EShellView *shell_view)
+{
+ g_signal_emit (shell_view, signals[TOGGLED], 0);
}
static void
-impl_ShellView_setButtonIcon (PortableServer_Servant _servant, const CORBA_char *id, const CORBA_char * iconName, CORBA_Environment * ev)
+shell_view_set_action (EShellView *shell_view,
+ GtkAction *action)
{
- EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
- EShell *shell = e_shell_window_peek_shell (esw->window);
+ gchar *label;
+
+ g_return_if_fail (shell_view->priv->action == NULL);
- struct change_icon_struct cis;
- cis.component_name = id;
- cis.icon_name = iconName;
+ shell_view->priv->action = g_object_ref (action);
- e_shell_foreach_shell_window (shell, change_button_icon_func, &cis);
+ g_object_get (action, "label", &label, NULL);
+ e_shell_view_set_title (shell_view, label);
+ g_free (label);
+
+ g_signal_connect_swapped (
+ action, "toggled",
+ G_CALLBACK (shell_view_emit_toggled), shell_view);
}
static void
-impl_dispose (GObject *object)
+shell_view_set_shell_window (EShellView *shell_view,
+ GtkWidget *shell_window)
{
- /*EShellView *esv = (EShellView *)object;*/
+ g_return_if_fail (shell_view->priv->shell_window == NULL);
+
+ shell_view->priv->shell_window = shell_window;
- ((GObjectClass *)parent_class)->dispose(object);
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_window),
+ &shell_view->priv->shell_window);
}
static void
-impl_finalise (GObject *object)
+shell_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- ((GObjectClass *)parent_class)->finalize(object);
+ switch (property_id) {
+ case PROP_ACTION:
+ shell_view_set_action (
+ E_SHELL_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_PAGE_NUM:
+ e_shell_view_set_page_num (
+ E_SHELL_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_TITLE:
+ e_shell_view_set_title (
+ E_SHELL_VIEW (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SHELL_WINDOW:
+ shell_view_set_shell_window (
+ E_SHELL_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_VIEW_ID:
+ e_shell_view_set_view_id (
+ E_SHELL_VIEW (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_shell_view_class_init (EShellViewClass *klass)
+shell_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTION:
+ g_value_set_object (
+ value, e_shell_view_get_action (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_PAGE_NUM:
+ g_value_set_int (
+ value, e_shell_view_get_page_num (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_TITLE:
+ g_value_set_string (
+ value, e_shell_view_get_title (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, e_shell_view_get_shell_backend (
+ E_SHELL_VIEW (object)));
+
+ case PROP_SHELL_CONTENT:
+ g_value_set_object (
+ value, e_shell_view_get_shell_content (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_SIDEBAR:
+ g_value_set_object (
+ value, e_shell_view_get_shell_sidebar (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_TASKBAR:
+ g_value_set_object (
+ value, e_shell_view_get_shell_taskbar (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_WINDOW:
+ g_value_set_object (
+ value, e_shell_view_get_shell_window (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_VIEW_ID:
+ g_value_set_string (
+ value, e_shell_view_get_view_id (
+ E_SHELL_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_view_dispose (GObject *object)
+{
+ EShellViewPrivate *priv;
+
+ priv = E_SHELL_VIEW_GET_PRIVATE (object);
+
+ /* Expedite any pending state saves. */
+ if (priv->state_save_source_id > 0) {
+ g_source_remove (priv->state_save_source_id);
+ priv->state_save_source_id = 0;
+ shell_view_save_state (E_SHELL_VIEW (object));
+ }
+
+ if (priv->shell_window != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_window), &priv->shell_window);
+ priv->shell_window = NULL;
+ }
+
+ if (priv->size_group != NULL) {
+ g_object_unref (priv->size_group);
+ priv->size_group = NULL;
+ }
+
+ if (priv->shell_content != NULL) {
+ g_object_unref (priv->shell_content);
+ priv->shell_content = NULL;
+ }
+
+ if (priv->shell_sidebar != NULL) {
+ g_object_unref (priv->shell_sidebar);
+ priv->shell_sidebar = NULL;
+ }
+
+ if (priv->shell_taskbar != NULL) {
+ g_object_unref (priv->shell_taskbar);
+ priv->shell_taskbar = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_view_finalize (GObject *object)
+{
+ EShellViewPrivate *priv;
+
+ priv = E_SHELL_VIEW_GET_PRIVATE (object);
+
+ g_key_file_free (priv->state_key_file);
+
+ g_free (priv->title);
+ g_free (priv->view_id);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_view_constructed (GObject *object)
+{
+ EShellViewClass *shell_view_class;
+ EShellView *shell_view;
+ GtkWidget *widget;
+
+ shell_view = E_SHELL_VIEW (object);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+
+ /* Defer EPluginUI registration to an idle callback to give the
+ * shell view subclass a chance to register its own actions and
+ * action groups. Registration will immediately load EPlugins
+ * that specify the shell view's GtkUIManager ID, and their
+ * initialization routines may require those actions or action
+ * groups that have not yet been added. */
+ g_idle_add ((GSourceFunc) shell_view_register_ui_manager, shell_view);
+
+ shell_view_load_state (shell_view);
+
+ /* Invoke factory methods. */
+
+ widget = shell_view_class->new_shell_content (shell_view);
+ shell_view->priv->shell_content = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ widget = shell_view_class->new_shell_sidebar (shell_view);
+ shell_view->priv->shell_sidebar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ widget = shell_view_class->new_shell_taskbar (shell_view);
+ shell_view->priv->shell_taskbar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+}
+
+static void
+shell_view_toggled (EShellView *shell_view)
+{
+ EShellViewPrivate *priv = shell_view->priv;
+ EShellViewClass *shell_view_class;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ const gchar *basename, *id;
+ gboolean view_is_active;
+
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_is_active = e_shell_view_is_active (shell_view);
+ basename = shell_view_class->ui_definition;
+ id = shell_view_class->ui_manager_id;
+
+ if (view_is_active && priv->merge_id == 0) {
+ priv->merge_id = e_load_ui_definition (ui_manager, basename);
+ e_plugin_ui_enable_manager (ui_manager, id);
+
+ } else if (!view_is_active && priv->merge_id != 0) {
+ e_plugin_ui_disable_manager (ui_manager, id);
+ gtk_ui_manager_remove_ui (ui_manager, priv->merge_id);
+ priv->merge_id = 0;
+ }
+
+ gtk_ui_manager_ensure_update (ui_manager);
+}
+
+static void
+shell_view_class_init (EShellViewClass *class)
{
GObjectClass *object_class;
- POA_GNOME_Evolution_ShellView__epv *epv;
- parent_class = g_type_class_ref(bonobo_object_get_type());
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_view_set_property;
+ object_class->get_property = shell_view_get_property;
+ object_class->dispose = shell_view_dispose;
+ object_class->finalize = shell_view_finalize;
+ object_class->constructed = shell_view_constructed;
+
+ /* Default Factories */
+ class->new_shell_content = e_shell_content_new;
+ class->new_shell_sidebar = e_shell_sidebar_new;
+ class->new_shell_taskbar = e_shell_taskbar_new;
+
+ class->toggled = shell_view_toggled;
+
+ /**
+ * EShellView:action:
+ *
+ * The #GtkRadioAction registered with #EShellSwitcher.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTION,
+ g_param_spec_object (
+ "action",
+ _("Switcher Action"),
+ _("The switcher action for this shell view"),
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellView:page-num
+ *
+ * The #GtkNotebook page number of the shell view.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_PAGE_NUM,
+ g_param_spec_int (
+ "page-num",
+ _("Page Number"),
+ _("The notebook page number of the shell view"),
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellView:title
+ *
+ * The title of the shell view. Also serves as the #EShellWindow
+ * title when the shell view is active.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ _("Title"),
+ _("The title of the shell view"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellView::shell-backend
+ *
+ * The #EShellBackend for this shell view.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Backend"),
+ _("The EShellBackend for this shell view"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READABLE));
+
+ /**
+ * EShellView:shell-content
+ *
+ * The content widget appears in an #EShellWindow<!-- -->'s
+ * right pane.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_CONTENT,
+ g_param_spec_object (
+ "shell-content",
+ _("Shell Content Widget"),
+ _("The content widget appears in "
+ "a shell window's right pane"),
+ E_TYPE_SHELL_CONTENT,
+ G_PARAM_READABLE));
+
+ /**
+ * EShellView:shell-sidebar
+ *
+ * The sidebar widget appears in an #EShellWindow<!-- -->'s
+ * left pane.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_SIDEBAR,
+ g_param_spec_object (
+ "shell-sidebar",
+ _("Shell Sidebar Widget"),
+ _("The sidebar widget appears in "
+ "a shell window's left pane"),
+ E_TYPE_SHELL_SIDEBAR,
+ G_PARAM_READABLE));
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalise;
+ /**
+ * EShellView:shell-taskbar
+ *
+ * The taskbar widget appears at the bottom of an #EShellWindow.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_TASKBAR,
+ g_param_spec_object (
+ "shell-taskbar",
+ _("Shell Taskbar Widget"),
+ _("The taskbar widget appears at "
+ "the bottom of a shell window"),
+ E_TYPE_SHELL_TASKBAR,
+ G_PARAM_READABLE));
- epv = & klass->epv;
- epv->setTitle = impl_ShellView_setTitle;
- epv->setComponent = impl_ShellView_setComponent;
- epv->setButtonIcon = impl_ShellView_setButtonIcon;
+ /**
+ * EShellView:shell-window
+ *
+ * The #EShellWindow to which the shell view belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_WINDOW,
+ g_param_spec_object (
+ "shell-window",
+ _("Shell Window"),
+ _("The window to which the shell view belongs"),
+ E_TYPE_SHELL_WINDOW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellView:view-id
+ *
+ * The current #GalView ID.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_VIEW_ID,
+ g_param_spec_string (
+ "view-id",
+ _("Current View ID"),
+ _("The current GAL view ID"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellView::toggled
+ * @shell_view: the #EShellView which emitted the signal
+ *
+ * Emitted when @shell_view is activated or deactivated.
+ * Use e_shell_view_is_active() to find out which event has
+ * occurred. The shell view being deactivated is always
+ * notified before the shell view being activated.
+ *
+ * By default, #EShellView adds the UI definition file
+ * given in the <structfield>ui_definition</structfield>
+ * field of #EShellViewClass on activation, and removes the
+ * UI definition on deactivation.
+ **/
+ signals[TOGGLED] = g_signal_new (
+ "toggled",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EShellViewClass, toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * EShellView::update-actions
+ * @shell_view: the #EShellView which emitted the signal
+ *
+ * #EShellView subclasses should override the
+ * <structfield>update_actions</structfield> method in
+ * #EShellViewClass to update sensitivities, labels, or any
+ * other aspect of the #GtkAction<!-- -->s they have registered.
+ *
+ * Plugins can also connect to this signal to be notified
+ * when to update their own #GtkAction<!-- -->s.
+ **/
+ signals[UPDATE_ACTIONS] = g_signal_new (
+ "update-actions",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EShellViewClass, update_actions),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
-e_shell_view_init (EShellView *shell)
+shell_view_init (EShellView *shell_view,
+ EShellViewClass *class)
{
+ GtkSizeGroup *size_group;
+
+ if (class->view_collection == NULL)
+ shell_view_init_view_collection (class);
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+
+ shell_view->priv = E_SHELL_VIEW_GET_PRIVATE (shell_view);
+ shell_view->priv->state_key_file = g_key_file_new ();
+ shell_view->priv->size_group = size_group;
}
-EShellView *e_shell_view_new(struct _EShellWindow *window)
+GType
+e_shell_view_get_type (void)
{
- EShellView *new = g_object_new (e_shell_view_get_type (), NULL);
+ static GType type = 0;
- /* TODO: listen to destroy? */
- new->window = window;
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_view_init,
+ NULL /* value_table */
+ };
- return new;
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EShellView",
+ &type_info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
}
-BONOBO_TYPE_FUNC_FULL (EShellView, GNOME_Evolution_ShellView, bonobo_object_get_type(), e_shell_view)
+/**
+ * e_shell_view_get_name:
+ * @shell_view: an #EShellView
+ *
+ * Returns the view name for @shell_view, which is also the name of
+ * the corresponding #EShellBackend (see the <structfield>name</structfield>
+ * field in #EShellBackendInfo).
+ *
+ * Returns: the view name for @shell_view
+ **/
+const gchar *
+e_shell_view_get_name (EShellView *shell_view)
+{
+ GtkAction *action;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ action = e_shell_view_get_action (shell_view);
+ /* Switcher actions have a secret "view-name" data value.
+ * This gets set in e_shell_window_create_switcher_actions(). */
+ return g_object_get_data (G_OBJECT (action), "view-name");
+}
+
+/**
+ * e_shell_view_get_action:
+ * @shell_view: an #EShellView
+ *
+ * Returns the switcher action for @shell_view.
+ *
+ * An #EShellWindow creates a #GtkRadioAction for each registered subclass
+ * of #EShellView. This action gets passed to the #EShellSwitcher, which
+ * displays a button that proxies the action. The icon at the top of the
+ * sidebar also proxies the action. When @shell_view is active, the
+ * action's icon becomes the #EShellWindow icon.
+ *
+ * Returns: the switcher action for @shell_view
+ **/
+GtkAction *
+e_shell_view_get_action (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->action;
+}
+
+/**
+ * e_shell_view_get_title:
+ * @shell_view: an #EShellView
+ *
+ * Returns the title for @shell_view. When @shell_view is active, the
+ * shell view's title becomes the #EShellWindow title.
+ *
+ * Returns: the title for @shell_view
+ **/
+const gchar *
+e_shell_view_get_title (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->title;
+}
+
+/**
+ * e_shell_view_set_title:
+ * @shell_view: an #EShellView
+ * @title: a title for @shell_view
+ *
+ * Sets the title for @shell_view. When @shell_view is active, the
+ * shell view's title becomes the #EShellWindow title.
+ **/
+void
+e_shell_view_set_title (EShellView *shell_view,
+ const gchar *title)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ if (title == NULL)
+ title = E_SHELL_VIEW_GET_CLASS (shell_view)->label;
+
+ if (g_strcmp0 (shell_view->priv->title, title) == 0)
+ return;
+
+ g_free (shell_view->priv->title);
+ shell_view->priv->title = g_strdup (title);
+
+ g_object_notify (G_OBJECT (shell_view), "title");
+}
+
+/**
+ * e_shell_view_get_view_id:
+ * @shell_view: an #EShellView
+ *
+ * Returns the ID of the currently selected #GalView.
+ *
+ * #EShellView subclasses are responsible for keeping this property in
+ * sync with their #GalViewInstance. #EShellView itself just provides
+ * a place to store the view ID, and emits a #GObject::notify signal
+ * when the property changes.
+ *
+ * Returns: the ID of the current #GalView
+ **/
+const gchar *
+e_shell_view_get_view_id (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->view_id;
+}
+
+/**
+ * e_shell_view_set_view_id:
+ * @shell_view: an #EShellView
+ * @view_id: a #GalView ID
+ *
+ * Selects the #GalView whose ID is equal to @view_id.
+ *
+ * #EShellView subclasses are responsible for keeping this property in
+ * sync with their #GalViewInstance. #EShellView itself just provides
+ * a place to store the view ID, and emits a #GObject::notify signal
+ * when the property changes.
+ **/
+void
+e_shell_view_set_view_id (EShellView *shell_view,
+ const gchar *view_id)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ if (g_strcmp0 (shell_view->priv->view_id, view_id) == 0)
+ return;
+
+ g_free (shell_view->priv->view_id);
+ shell_view->priv->view_id = g_strdup (view_id);
+
+ g_object_notify (G_OBJECT (shell_view), "view-id");
+}
+
+/**
+ * e_shell_view_get_shell_window:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellWindow to which @shell_view belongs.
+ *
+ * Returns: the #EShellWindow to which @shell_view belongs
+ **/
+EShellWindow *
+e_shell_view_get_shell_window (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_WINDOW (shell_view->priv->shell_window);
+}
+
+/**
+ * e_shell_view_is_active:
+ * @shell_view: an #EShellView
+ *
+ * Returns %TRUE if @shell_view is active. That is, if it's currently
+ * visible in its #EShellWindow. An #EShellWindow can only display one
+ * shell view at a time.
+ *
+ * Technically this just checks the #GtkToggleAction:active property of
+ * the shell view's switcher action. See e_shell_view_get_action().
+ *
+ * Returns: %TRUE if @shell_view is active
+ **/
+gboolean
+e_shell_view_is_active (EShellView *shell_view)
+{
+ GtkAction *action;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE);
+
+ action = e_shell_view_get_action (shell_view);
+
+ return gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+}
+
+/**
+ * e_shell_view_get_page_num:
+ * @shell_view: an #EShellView
+ *
+ * This function is only interesting to #EShellWindow. It returns the
+ * #GtkNotebook page number for @shell_view. The rest of the application
+ * should have no need for this.
+ *
+ * Returns: the notebook page number for @shell_view
+ **/
+gint
+e_shell_view_get_page_num (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), -1);
+
+ return shell_view->priv->page_num;
+}
+
+/**
+ * e_shell_view_set_page_num:
+ * @shell_view: an #EShellView
+ * @page_num: a notebook page number
+ *
+ * This function is only interesting to #EShellWindow. It sets the
+ * #GtkNotebook page number for @shell_view. The rest of the application
+ * must never call this because it could mess up shell view switching.
+ **/
+void
+e_shell_view_set_page_num (EShellView *shell_view,
+ gint page_num)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ shell_view->priv->page_num = page_num;
+
+ g_object_notify (G_OBJECT (shell_view), "page-num");
+}
+
+/**
+ * e_shell_view_get_size_group:
+ * @shell_view: an #EShellView
+ *
+ * Returns a #GtkSizeGroup that #EShellContent and #EShellSidebar use
+ * to keep the search bar and sidebar banner vertically aligned. The
+ * rest of the application should have no need for this.
+ *
+ * Returns: a #GtkSizeGroup for internal use
+ **/
+GtkSizeGroup *
+e_shell_view_get_size_group (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->size_group;
+}
+
+/**
+ * e_shell_view_get_shell_backend:
+ * @shell_view: an #EShellView
+ *
+ * Returns the corresponding #EShellBackend for @shell_view.
+ *
+ * Returns: the corresponding #EShellBackend for @shell_view
+ **/
+EShellBackend *
+e_shell_view_get_shell_backend (EShellView *shell_view)
+{
+ EShellViewClass *class;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ g_return_val_if_fail (class->shell_backend != NULL, NULL);
+
+ return class->shell_backend;
+}
+
+/**
+ * e_shell_view_get_shell_content:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellContent instance for @shell_view.
+ *
+ * By default, #EShellView creates a plain #EShellContent during
+ * initialization. But #EShellView subclasses can override the
+ * <structfield>new_shell_content</structfield> factory method
+ * in #EShellViewClass to create a custom #EShellContent.
+ *
+ * Returns: the #EShellContent instance for @shell_view
+ **/
+EShellContent *
+e_shell_view_get_shell_content (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_CONTENT (shell_view->priv->shell_content);
+}
+
+/**
+ * e_shell_view_get_shell_sidebar:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellSidebar instance for @shell_view.
+ *
+ * By default, #EShellView creates a plain #EShellSidebar during
+ * initialization. But #EShellView subclasses can override the
+ * <structfield>new_shell_sidebar</structfield> factory method
+ * in #EShellViewClass to create a custom #EShellSidebar.
+ *
+ * Returns: the #EShellSidebar instance for @shell_view
+ **/
+EShellSidebar *
+e_shell_view_get_shell_sidebar (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_SIDEBAR (shell_view->priv->shell_sidebar);
+}
+
+/**
+ * e_shell_view_get_shell_taskbar:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellTaskbar instance for @shell_view.
+ *
+ * By default, #EShellView creates a plain #EShellTaskbar during
+ * initialization. But #EShellView subclasses can override the
+ * <structfield>new_shell_taskbar</structfield> factory method
+ * in #EShellViewClass to create a custom #EShellTaskbar.
+ *
+ * Returns: the #EShellTaskbar instance for @shell_view
+ **/
+EShellTaskbar *
+e_shell_view_get_shell_taskbar (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_TASKBAR (shell_view->priv->shell_taskbar);
+}
+
+/**
+ * e_shell_view_get_state_key_file:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #GKeyFile holding widget state data for @shell_view.
+ *
+ * Returns: the #GKeyFile for @shell_view
+ **/
+GKeyFile *
+e_shell_view_get_state_key_file (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->state_key_file;
+}
+
+/**
+ * e_shell_view_set_state_dirty:
+ * @shell_view: an #EShellView
+ *
+ * Marks the widget state data as modified (or "dirty") and schedules it
+ * to be saved to disk after a short delay. The delay caps the frequency
+ * of saving to disk.
+ **/
+void
+e_shell_view_set_state_dirty (EShellView *shell_view)
+{
+ guint source_id;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ /* If a timeout is already scheduled, do nothing. */
+ if (shell_view->priv->state_save_source_id > 0)
+ return;
+
+ source_id = g_timeout_add_seconds (
+ STATE_SAVE_TIMEOUT_SECONDS, (GSourceFunc)
+ shell_view_state_timeout_cb, shell_view);
+
+ shell_view->priv->state_save_source_id = source_id;
+}
+
+/**
+ * e_shell_view_update_actions:
+ * @shell_view: an #EShellView
+ *
+ * Emits the #EShellView::update-actions signal.
+ *
+ * #EShellView subclasses should implement the
+ * <structfield>update_actions</structfield> method in #EShellViewClass
+ * to update the various #GtkAction<!-- -->s based on the current
+ * #EShellSidebar and #EShellContent selections. The
+ * #EShellView::update-actions signal is typically emitted just before
+ * showing a popup menu or just after the user selects an item in the
+ * shell view.
+ **/
+void
+e_shell_view_update_actions (EShellView *shell_view)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ g_signal_emit (shell_view, signals[UPDATE_ACTIONS], 0);
+}
+
+/**
+ * e_shell_view_show_popup_menu:
+ * @shell_view: an #EShellView
+ * @widget_path: path in the UI definition
+ * @event: a #GdkEventButton
+ *
+ * Displays a context-sensitive (or "popup") menu that is described in
+ * the UI definition loaded into @shell_view<!-- -->'s user interface
+ * manager. The menu will be shown at the current mouse cursor position.
+ *
+ * The #EShellView::update-actions signal is emitted just prior to
+ * showing the menu to give @shell_view and any plugins that extend
+ * @shell_view a chance to update the menu's actions.
+ **/
+void
+e_shell_view_show_popup_menu (EShellView *shell_view,
+ const gchar *widget_path,
+ GdkEventButton *event)
+{
+ EShellWindow *shell_window;
+ GtkWidget *menu;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ e_shell_view_update_actions (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ menu = e_shell_window_get_managed_widget (shell_window, widget_path);
+ g_return_if_fail (GTK_IS_MENU (menu));
+
+ if (event != NULL)
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+ else
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ 0, gtk_get_current_event_time ());
+}
+
+/**
+ * e_shell_view_new_view_instance:
+ * @shell_view: an #EShellView
+ * @instance_id: a name for the #GalViewInstance
+ *
+ * Creates a new #GalViewInstance and configures it to keep
+ * @shell_view<!-- -->'s #EShellView:view-id property up-to-date.
+ *
+ * Returns: a new #GalViewInstance
+ **/
+GalViewInstance *
+e_shell_view_new_view_instance (EShellView *shell_view,
+ const gchar *instance_id)
+{
+ EShellViewClass *class;
+ GalViewCollection *view_collection;
+ GalViewInstance *view_instance;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ class = E_SHELL_VIEW_GET_CLASS (shell_view);
+
+ view_collection = class->view_collection;
+ view_instance = gal_view_instance_new (view_collection, instance_id);
+
+ g_signal_connect_swapped (
+ view_instance, "changed",
+ G_CALLBACK (shell_view_update_view_id), shell_view);
+
+ return view_instance;
+}
diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h
index 1ca2656bb0..b9a12ab893 100644
--- a/shell/e-shell-view.h
+++ b/shell/e-shell-view.h
@@ -1,6 +1,5 @@
/*
- *
- * This is only a CORBA wrapper around e_shell_window.
+ * e-shell-view.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,46 +19,169 @@
*
*/
-#ifndef _E_SHELL_VIEW_H_
-#define _E_SHELL_VIEW_H_
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-object.h>
+/**
+ * SECTION: e-shell-view
+ * @short_description: views within the main window
+ * @include: shell/e-shell-view.h
+ **/
+
+#ifndef E_SHELL_VIEW_H
+#define E_SHELL_VIEW_H
+
+#include <shell/e-shell-common.h>
+#include <shell/e-shell-backend.h>
+#include <shell/e-shell-content.h>
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-taskbar.h>
+#include <shell/e-shell-window.h>
+
+#include <widgets/menus/gal-view-collection.h>
+#include <widgets/menus/gal-view-instance.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_VIEW \
+ (e_shell_view_get_type ())
+#define E_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_VIEW, EShellView))
+#define E_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_VIEW, EShellViewClass))
+#define E_IS_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_VIEW))
+#define E_IS_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_VIEW))
+#define E_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_VIEW, EShellViewClass))
G_BEGIN_DECLS
-struct _EShell;
-
-typedef struct _EShellView EShellView;
+typedef struct _EShellView EShellView;
+typedef struct _EShellViewClass EShellViewClass;
typedef struct _EShellViewPrivate EShellViewPrivate;
-typedef struct _EShellViewClass EShellViewClass;
-
-#include "Evolution.h"
-
-#define E_TYPE_SHELL_VIEW (e_shell_view_get_type ())
-#define E_SHELL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_VIEW, EShellView))
-#define E_SHELL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_VIEW, EShellViewClass))
-#define E_IS_SHELL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_VIEW))
-#define E_IS_SHELL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_VIEW))
+/**
+ * EShellView:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EShellView {
- BonoboObject parent;
-
- struct _EShellWindow *window;
-
+ GObject parent;
EShellViewPrivate *priv;
};
+/**
+ * EShellViewClass:
+ * @parent_class: The parent class structure.
+ * @label: The initial value for the switcher action's
+ * #GtkAction:label property. See
+ * e_shell_view_get_action().
+ * @icon_name: The initial value for the switcher action's
+ * #GtkAction:icon-name property. See
+ * e_shell_view_get_action().
+ * @ui_definition: Base name of the UI definintion file to add
+ * when the shell view is activated.
+ * @ui_manager_id: The #GtkUIManager ID for #EPluginUI. Plugins
+ * should use to this ID in their "eplug" files to
+ * add menu and toolbar items to the shell view.
+ * @search_options: Widget path in the UI definition to the search
+ * options popup menu. The menu gets shown when the
+ * user clicks the "find" icon in the search entry.
+ * @search_rules: Base name of the XML file containing predefined
+ * search rules for this shell view. The XML files
+ * are usually named something like <filename>
+ * <emphasis>view</emphasis>types.xml</filename>.
+ * @view_collection: A unique #GalViewCollection instance is created
+ * for each subclass and shared across all instances
+ * of that subclass. That much is done automatically
+ * for subclasses, but subclasses are still responsible
+ * for adding the appropriate #GalView factories to the
+ * view collection.
+ * @shell_backend: The corresponding #EShellBackend for the shell view.
+ * @new_shell_content: Factory method for the shell view's #EShellContent.
+ * See e_shell_view_get_shell_content().
+ * @new_shell_sidebar: Factory method for the shell view's #EShellSidebar.
+ * See e_shell_view_get_shell_sidebar().
+ * @new_shell_taskbar: Factory method for the shell view's #EShellTaskbar.
+ * See e_shell_view_get_shell_taskbar().
+ * @toggled: Class method for the #EShellView::toggled signal.
+ * Subclasses should rarely need to override the
+ * default behavior.
+ * @update_actions: Class method for the #EShellView::update_actions
+ * signal. There is no default behavior; subclasses
+ * should override this.
+ *
+ * #EShellViewClass contains a number of important settings for subclasses.
+ **/
struct _EShellViewClass {
- BonoboObjectClass parent_class;
+ GObjectClass parent_class;
- POA_GNOME_Evolution_ShellView__epv epv;
+ /* Initial switcher action values. */
+ const gchar *label;
+ const gchar *icon_name;
+
+ /* Base name of the UI definition file. */
+ const gchar *ui_definition;
+
+ /* GtkUIManager identifier for use with EPluginUI.
+ * Usually "org.gnome.evolution.$(VIEW_NAME)". */
+ const gchar *ui_manager_id;
+
+ /* Widget path to the search options popup menu. */
+ const gchar *search_options;
+
+ /* Base name of the search rule definition file. */
+ const gchar *search_rules;
+
+ /* A unique instance is created for each subclass. */
+ GalViewCollection *view_collection;
+
+ /* This is set by the corresponding EShellBackend. */
+ EShellBackend *shell_backend;
+
+ /* Factory Methods */
+ GtkWidget * (*new_shell_content) (EShellView *shell_view);
+ GtkWidget * (*new_shell_sidebar) (EShellView *shell_view);
+ GtkWidget * (*new_shell_taskbar) (EShellView *shell_view);
+
+ /* Signals */
+ void (*toggled) (EShellView *shell_view);
+ void (*update_actions) (EShellView *shell_view);
};
-GType e_shell_view_get_type (void);
-EShellView *e_shell_view_new(struct _EShellWindow *window);
+GType e_shell_view_get_type (void);
+const gchar * e_shell_view_get_name (EShellView *shell_view);
+GtkAction * e_shell_view_get_action (EShellView *shell_view);
+const gchar * e_shell_view_get_title (EShellView *shell_view);
+void e_shell_view_set_title (EShellView *shell_view,
+ const gchar *title);
+const gchar * e_shell_view_get_view_id (EShellView *shell_view);
+void e_shell_view_set_view_id (EShellView *shell_view,
+ const gchar *view_id);
+gboolean e_shell_view_is_active (EShellView *shell_view);
+gint e_shell_view_get_page_num (EShellView *shell_view);
+void e_shell_view_set_page_num (EShellView *shell_view,
+ gint page_num);
+GtkSizeGroup * e_shell_view_get_size_group (EShellView *shell_view);
+EShellBackend * e_shell_view_get_shell_backend (EShellView *shell_view);
+EShellContent * e_shell_view_get_shell_content (EShellView *shell_view);
+EShellSidebar * e_shell_view_get_shell_sidebar (EShellView *shell_view);
+EShellTaskbar * e_shell_view_get_shell_taskbar (EShellView *shell_view);
+EShellWindow * e_shell_view_get_shell_window (EShellView *shell_view);
+GKeyFile * e_shell_view_get_state_key_file (EShellView *shell_view);
+void e_shell_view_set_state_dirty (EShellView *shell_view);
+void e_shell_view_update_actions (EShellView *shell_view);
+void e_shell_view_show_popup_menu (EShellView *shell_view,
+ const gchar *widget_path,
+ GdkEventButton *event);
+GalViewInstance *
+ e_shell_view_new_view_instance (EShellView *shell_view,
+ const gchar *instance_id);
G_END_DECLS
-#endif /* _E_SHELL_VIEW_H_ */
-
+#endif /* E_SHELL_VIEW_H */
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
new file mode 100644
index 0000000000..77e50c50d4
--- /dev/null
+++ b/shell/e-shell-window-actions.c
@@ -0,0 +1,2242 @@
+/*
+ * e-shell-window-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-window-private.h"
+
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-error.h>
+#include <e-util/e-print.h>
+#include <gal-define-views-dialog.h>
+
+#include <libedataserverui/e-passwords.h>
+
+#include "e-shell-importer.h"
+
+#define EVOLUTION_COPYRIGHT \
+ "Copyright \xC2\xA9 1999 - 2008 Novell, Inc. and Others"
+
+#define EVOLUTION_FAQ \
+ "http://www.go-evolution.org/FAQ"
+
+#define EVOLUTION_WEBSITE \
+ "http://www.gnome.org/projects/evolution/"
+
+/* Authors and Documenters
+ *
+ * The names below must be in UTF-8. The breaking of escaped strings
+ * is so the hexadecimal sequences don't swallow too many characters.
+ *
+ * SO THAT MEANS, FOR 8-BIT CHARACTERS USE \xXX HEX ENCODING ONLY!
+ *
+ * Not all environments are UTF-8 and not all editors can handle it.
+ */
+static const gchar *authors[] = {
+ "Aaron Weber",
+ "Abel Cheung",
+ "Abhishek Parwal",
+ "Adam Weinberger",
+ "Adi Attar",
+ "Ahmad Riza H Nst",
+ "Aidan Delaney",
+ "Aishwarya K",
+ "Akagic Amila",
+ "Akhil Laddha",
+ "Akira Tagoh",
+ "Alastair McKinstry",
+ "Alastair Tse",
+ "Alejandro Andres",
+ "Alessandro Decina",
+ "Alex Graveley",
+ "Alex Jiang",
+ "Alex Jones",
+ "Alex Kloss",
+ "Alexander Shopov",
+ "Alfred Peng",
+ "Ali Abdin",
+ "Ali Akcaagac",
+ "Almer S. Tigelaar",
+ "Amish",
+ "Anand V M",
+ "Anders Carlsson",
+ "Andre Klapper",
+ "Andrea Campi",
+ "Andreas Henriksson",
+ "Andreas Hyden",
+ "Andreas J. Guelzow",
+ "Andreas K\xC3\xB6hler",
+ "Andreas Köhler",
+ "Andrew Ruthven",
+ "Andrew T. Veliath",
+ "Andrew Wu",
+ "Ankit Patel",
+ "Anna Marie Dirks",
+ "Antonio Xu",
+ "Arafat Medini",
+ "Arangel Angov",
+ "Archit Baweja",
+ "Ariel Rios",
+ "Arik Devens",
+ "Armin Bauer",
+ "Arturo Espinosa Aldama",
+ "Arulanandan P",
+ "Arun Prakash",
+ "Arvind Sundararajan",
+ "Arvind",
+ "Ashish",
+ "B S Srinidhi",
+ "Bastien Nocera",
+ "Behnam Esfahbod",
+ "Ben Gamari",
+ "Benjamin Berg",
+ "Benjamin Kahn",
+ "Benoît Dejean",
+ "Bernard Leach",
+ "Bertrand Guiheneuf",
+ "Bharath Acharya",
+ "Bill Zhu",
+ "Bj\xC3\xB6rn Torkelsson",
+ "Björn Lindqvist",
+ "Bob Doan",
+ "Bob Mauchin",
+ "Boby Wang",
+ "Bolian Yin",
+ "Brian Mury",
+ "Brian Pepple",
+ "Bruce Tao",
+ "Calvin Liu",
+ "Cantona Su",
+ "Carl Sun",
+ "Carlos Garcia Campos",
+ "Carlos Garnacho Parro",
+ "Carlos Perell\xC3\xB3" " Mar\xC3\xAD" "n",
+ "Carsten Guenther",
+ "Carsten Schaar",
+ "Changwoo Ryu",
+ "Chao-Hsiung Liao",
+ "Charles Zhang",
+ "Chema Celorio",
+ "Chenthill Palanisamy",
+ "Chpe",
+ "Chris Halls",
+ "Chris Heath",
+ "Chris Phelps",
+ "Chris Toshok",
+ "Christian Hammond",
+ "Christian Kellner",
+ "Christian Kirbach",
+ "Christian Krause",
+ "Christian Kreibich",
+ "Christian Neumair",
+ "Christophe Fergeau",
+ "Christophe Merlet",
+ "Christopher Blizzard",
+ "Christopher J. Lahey",
+ "Christopher R. Gabriel",
+ "Claude Paroz",
+ "Claudio Saavedra",
+ "Clifford R. Conover",
+ "Cody Russell",
+ "Colin Leroy",
+ "Craig Small",
+ "Dafydd Harries",
+ "Damian Ivereigh",
+ "Damien Carbery",
+ "Damon Chaplin",
+ "Dan Berger",
+ "Dan Damian",
+ "Dan Nguyen",
+ "Dan Winship",
+ "Daniel Gryniewicz",
+ "Daniel Nylander",
+ "Daniel van Eeden",
+ "Daniel Veillard",
+ "Daniel Yacob",
+ "Danilo \xC5\xA0" "egan",
+ "Danilo Segan",
+ "Darin Adler",
+ "Dave Benson",
+ "Dave Camp",
+ "Dave Fallon",
+ "Dave Malcolm",
+ "Dave West",
+ "David Farning",
+ "David Kaelbling",
+ "David Malcolm",
+ "David Moore",
+ "David Mosberger",
+ "David Richards",
+ "David Trowbridge",
+ "David Turner",
+ "David Woodhouse",
+ "Denis Washington",
+ "Devashish Sharma",
+ "Diego Escalante Urrelo",
+ "Diego Gonzalez",
+ "Diego Sevilla Ruiz",
+ "Dietmar Maurer",
+ "Dinesh Layek",
+ "Djihed Afifi",
+ "Dmitry Mastrukov",
+ "Dodji Seketeli",
+ "Duarte Loreto",
+ "Dulmandakh Sukhbaatar",
+ "Duncan Mak",
+ "Ebby Wiselyn",
+ "Ed Catmur",
+ "Edd Dumbill",
+ "Edgar Luna Díaz",
+ "Edward Rudd",
+ "Elijah Newren",
+ "Elizabeth Greene",
+ "Elliot Lee",
+ "Elliot Turner",
+ "Eneko Lacunza",
+ "Enver Altin",
+ "Erdal Ronahi",
+ "Eric Busboom",
+ "Eric Zhao",
+ "Eskil Heyn Olsen",
+ "Ettore Perazzoli",
+ "Evan Yan",
+ "Fatih Demir",
+ "Fazlu & Hannah",
+ "Federico Mena Quintero",
+ "Fernando Herrera",
+ "Francisco Javier F. Serrador",
+ "Frank Arnold",
+ "Frank Belew",
+ "Frederic Crozat",
+ "Frederic Peters",
+ "Funda Wang",
+ "Gabor Kelemen",
+ "Ganesh",
+ "Gareth Owen",
+ "Gary Coady",
+ "Gary Ekker",
+ "Gavin Scott",
+ "Gediminas Paulauskas",
+ "Gerg\xC5\x91 \xC3\x89rdi",
+ "George Lebl",
+ "Gerardo Marin",
+ "Gert Kulyk",
+ "Giancarlo Capella",
+ "Gil Osher",
+ "Gilbert Fang",
+ "Gilles Dartiguelongue",
+ "Grahame Bowland",
+ "Greg Hudson",
+ "Gregory Leblanc",
+ "Gregory McLean",
+ "Grzegorz Goawski",
+ "Gustavo Gir\xC3\x8E" "ldez",
+ "Gustavo Maciel Dias Vieira",
+ "H P Nadig",
+ "H\xC3\xA9" "ctor Garc\xC3\xAD" "a \xC3\x81" "lvarez",
+ "Hans Petter Jansson",
+ "Hao Sheng",
+ "Hari Prasad Nadig",
+ "Harish K",
+ "Harish Krishnaswamy",
+ "Harry Lu",
+ "Hasbullah Bin Pit",
+ "Havoc Pennington",
+ "Heath Harrelson",
+ "Hein-Pieter van Braam",
+ "Herbert V. Riedel",
+ "Hiroyuki Ikezoe",
+ "Iain Buchanan",
+ "Iain Holmes",
+ "Ian Campbell",
+ "Ilkka Tuohela",
+ "Irene Huang",
+ "Ismael Olea",
+ "Israel Escalante",
+ "Iv\xC3\xA1" "n Frade",
+ "Iván Frade",
+ "J.H.M. Dassen (Ray)",
+ "JP Rosevear",
+ "J\xC3\xBC" "rg Billeter",
+ "Jürg Billeter",
+ "Jack Jia",
+ "Jacob Ulysses Berkman",
+ "Jacob Berkman",
+ "Jaka Mocnik",
+ "Jakub Steiner",
+ "James Doc Livingston",
+ "James Bowes",
+ "James Henstridge",
+ "James Willcox",
+ "Jan Arne Petersen",
+ "Jan Tichavsky",
+ "Jan Van Buggenhout",
+ "Jared Moore",
+ "Jarkko Ranta",
+ "Jason Leach",
+ "Jason Tackaberry",
+ "Jayaradha",
+ "Jean-Noel Guiheneuf",
+ "Jedy Wang",
+ "Jeff Bailey",
+ "Jeff Cai",
+ "Jeff Garzik",
+ "Jeffrey Stedfast",
+ "Jens Granseuer",
+ "Jens Seidel",
+ "Jeremy Katz",
+ "Jeremy Wise",
+ "Jerome Lacoste",
+ "Jerry Yu",
+ "Jes\xC3\xBA" "s Bravo \xC3\x81" "lvarez",
+ "Jesse Pavel",
+ "Ji Lee",
+ "Joan Sanfeliu",
+ "Jody Goldberg",
+ "Joe Marcus Clarke",
+ "Joe Shaw",
+ "John Gotts",
+ "Johnny Jacob",
+ "Johnny",
+ "Jon Ander Hernandez",
+ "Jon K Hellan",
+ "Jon Oberheide",
+ "Jon Trowbridge",
+ "Jonas Borgstr",
+ "Jonathan Blandford",
+ "Jonathan Dieter",
+ "Jos Dehaes",
+ "Josselin Mouette",
+ "JP Rosvear",
+ "Jukka Zitting",
+ "Jules Colding",
+ "Julian Missig",
+ "Julio M. Merino Vidal",
+ "Jürg Billeter",
+ "Karl Eichwalder",
+ "Karl Relton",
+ "Karsten Br\xC3\xA4" "ckelmann",
+ "Kaushal Kumar",
+ "Kenneth Christiansen",
+ "Kenny Graunke",
+ "Keshav Upadhyaya",
+ "Kevin Breit",
+ "Kevin Piche",
+ "Kevin Vandersloot",
+ "Khasim Shaheed",
+ "Kidd Wang",
+ "Kjartan Maraas",
+ "Krishnan R",
+ "Krisztian Pifko",
+ "Kyle Ambroff",
+ "Larry Ewing",
+ "Laszlo (Laca) Peter",
+ "Laurent Dhima",
+ "Lauris Kaplinski",
+ "Leon Zhang",
+ "Li Yuan",
+ "Loïc Minier",
+ "Loïc Minier",
+ "Lorenzo Gil Sanchez",
+ "Luca Ferretti",
+ "Lucky Wankhede",
+ "Luis Villa",
+ "Lutz M",
+ "M Victor Aloysius J",
+ "Maciej Stachowiak",
+ "Makuchaku",
+ "Malcolm Tredinnick",
+ "Marco Pesenti Gritti",
+ "Marius Andreiana",
+ "Marius Vollmer",
+ "Mark Crichton",
+ "Mark G. Adams",
+ "Mark Gordon",
+ "Mark McLoughlin",
+ "Mark Moulder",
+ "Mark Tearle",
+ "Martha Burke",
+ "Martin Baulig",
+ "Martin Hicks",
+ "Martin Meyer",
+ "Martin Norb\xC3\xA4" "ck",
+ "Martyn Russell",
+ "Masahiro Sakai",
+ "Mathieu Lacage",
+ "Matias Mutchinick",
+ "Matt Bissiri",
+ "Matt Brown",
+ "Matt Loper",
+ "Matt Martin",
+ "Matt Wilson",
+ "Matthew Barnes",
+ "Matthew Daniel",
+ "Matthew Hall",
+ "Matthew Loper",
+ "Matthew Wilson",
+ "Matthias Clasen",
+ "Max Horn",
+ "Maxx Cao",
+ "Mayank Jain",
+ "Meilof Veeningen",
+ "Mengjie Yu",
+ "Michael Granger",
+ "Michael M. Morrison",
+ "Michael MacDonald",
+ "Michael Meeks",
+ "Michael Monreal",
+ "Michael Terry",
+ "Michael Zucchi",
+ "Michel Daenzer",
+ "Miguel Angel Lopez Hernandez",
+ "Miguel de Icaza",
+ "Mikael Hallendal",
+ "Mikael Nilsson",
+ "Mike Castle",
+ "Mike Kestner",
+ "Mike McEwan",
+ "Mikhail Zabaluev",
+ "Milan Crha",
+ "Miles Lane",
+ "Mohammad Damt",
+ "Morten Welinder",
+ "Mubeen Jukaku",
+ "Murray Cumming",
+ "Naba Kumar",
+ "Nagappan Alagappan",
+ "Nancy Cai",
+ "Nat Friedman",
+ "Nathan Owens",
+ "Nicel KM",
+ "Nicholas J Kreucher",
+ "Nicholas Miell",
+ "Nick Sukharev",
+ "Nickolay V. Shmyrev",
+ "Nike Gerdts",
+ "Noel",
+ "Nuno Ferreira",
+ "Nyall Dawson",
+ "Ondrej Jirman",
+ "Oswald Rodrigues",
+ "Owen Taylor",
+ "Oystein Gisnas",
+ "P Chenthill",
+ "P S Chakravarthi",
+ "Pablo Gonzalo del Campo",
+ "Pablo Saratxaga",
+ "Pamplona Hackers",
+ "Paolo Molaro",
+ "Parag Goel",
+ "Parthasarathi Susarla",
+ "Pascal Terjan",
+ "Patrick Ohly",
+ "Paul Bolle",
+ "Paul Lindner",
+ "Pavel Cisler",
+ "Pavel Roskin",
+ "Pavithran",
+ "Pawan Chitrakar",
+ "Pedro Villavicencio",
+ "Peter Pouliot",
+ "Peter Teichman",
+ "Peter Williams",
+ "Peteris Krisjanis",
+ "Petta Pietikainen",
+ "Phil Goembel",
+ "Philip Van Hoof",
+ "Philip Zhao",
+ "Poornima Nayak",
+ "Pratik V. Parikh",
+ "Praveen Kumar",
+ "Priit Laes",
+ "Priyanshu Raj",
+ "Radek Doul\xC3\xADk",
+ "Raghavendran R",
+ "Raja R Harinath",
+ "Rajeev Ramanathan",
+ "Rajesh Ranjan",
+ "Rakesh k.g",
+ "Ramiro Estrugo",
+ "Ranjan Somani",
+ "Ray Strode",
+ "Rhys Jones",
+ "Ricardo Markiewicz",
+ "Richard Boulton",
+ "Richard Hult",
+ "Richard Li",
+ "Rob Bradford",
+ "Robert Brady",
+ "Robert Sedak",
+ "Robin Slomkowski",
+ "Rodney Dawes",
+ "Rodrigo Moya",
+ "Rohini S",
+ "Rohini",
+ "Roland Illig",
+ "Ronald Kuetemeier",
+ "Roozbeh Pournader",
+ "Ross Burton",
+ "Rouslan Solomakhin",
+ "Runa Bhattacharjee",
+ "Russell Steinthal",
+ "Rusty Conover",
+ "Ryan P. Skadberg",
+ "S Antony Vincent Pandian",
+ "S N Tejasvi",
+ "S. \xC3\x87" "a\xC4\x9F" "lar Onur",
+ "S.Antony Vincent Pandian",
+ "S. Caglar Onur",
+ "Sam Creasey",
+ "Sam Yang",
+ "Sam\xC3\xBA" "el J\xC3\xB3" "n Gunnarsson",
+ "Sankar P",
+ "Sanlig Badral",
+ "Sanshao Jiang",
+ "Sarfraaz Ahmed",
+ "Sayamindu Dasgupta",
+ "Sean Atkinson",
+ "Sean Gao",
+ "Sebastian Rittau",
+ "Sebastian Wilhelmi",
+ "Sebastien Bacher",
+ "Sergey Panov",
+ "Seth Alves",
+ "Seth Nickell",
+ "Shakti Sen",
+ "Shi Pu",
+ "Shilpa C",
+ "Shree Krishnan",
+ "Shreyas Srinivasan",
+ "Simon Zheng",
+ "Simos Xenitellis",
+ "Sivaiah Nallagatla",
+ "Srinivasa Ragavan",
+ "Stanislav Brabec",
+ "Stanislav Visnovsky",
+ "Stéphane Raimbault",
+ "Stephen Cook",
+ "Steve Murphy",
+ "Steven Zhang",
+ "Stuart Parmenter",
+ "Subodh Soni",
+ "Suman Manjunath",
+ "Sunil Mohan Adapa",
+ "Suresh Chandrasekharan",
+ "Sushma Rai",
+ "Sven Herzberg",
+ "Szabolcs Ban",
+ "T\xC3\xB5" "ivo Leedj\xC3\xA4" "rv",
+ "Takao Fujiwara",
+ "Takayuki Kusano",
+ "Takeshi Aihana",
+ "Tambet Ingo",
+ "Taylor Hayward",
+ "Ted Percival",
+ "Theppitak Karoonboonyanan",
+ "Thomas Cataldo",
+ "Thomas Klausner",
+ "Thomas Mirlacher",
+ "Thouis R. Jones",
+ "Tim Wo",
+ "Tim Yamin",
+ "Timo Hoenig",
+ "Timo Sirainen",
+ "Timothy Lee",
+ "Timur Bakeyev",
+ "Tino Meinen",
+ "Tobias Mueller",
+ "Tõivo Leedjärv",
+ "Tom Tromey",
+ "Tomas Ogren",
+ "Tomasz K\xC5\x82" "oczko",
+ "Tomislav Vujec",
+ "Tommi Komulainen",
+ "Tommi Vainikainen",
+ "Tony Tsui",
+ "Tor Lillqvist",
+ "Trent Lloyd",
+ "Tuomas J. Lukka",
+ "Tuomas Kuosmanen",
+ "Ulrich Neumann",
+ "Umesh Tiwari",
+ "Umeshtej",
+ "Ushveen Kaur",
+ "V Ravi Kumar Raju",
+ "Vadim Strizhevsky",
+ "Valek Filippov",
+ "Vandana Shenoy .B",
+ "Vardhman Jain",
+ "Veerapuram Varadhan",
+ "Vincent Noel",
+ "Vincent van Adrighem",
+ "Viren",
+ "Vivek Jain",
+ "Vladimer Sichinava",
+ "Vladimir Vukicevic",
+ "Wadim Dziedzic",
+ "Wang Jian",
+ "Wang Xin",
+ "Wayne Davis",
+ "William Jon McCann",
+ "Wouter Bolsterlee",
+ "Xan Lopez",
+ "Xiurong Simon Zheng",
+ "Yanko Kaneti",
+ "Yi Jin",
+ "Yong Sun",
+ "Yu Mengjie",
+ "Yuedong Du",
+ "Yukihiro Nakai",
+ "Yuri Pankov",
+ "Yuri Syrota",
+ "Zach Frey",
+ "Zan Lynx",
+ "Zbigniew Chyla",
+ "\xC3\x98ystein Gisn\xC3\xA5s",
+ "\xC5\xBDygimantas Beru\xC4\x8Dka",
+ NULL
+};
+
+static const gchar *documenters[] = {
+ "Aaron Weber",
+ "Binika Preet",
+ "Dan Winship",
+ "David Trowbridge",
+ "Jessica Prabhakar",
+ "JP Rosevear",
+ "Radhika Nair",
+ NULL
+};
+
+/**
+ * E_SHELL_WINDOW_ACTION_ABOUT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action displays the application's About dialog.
+ *
+ * Main menu item: Help -> About
+ **/
+static void
+action_about_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ gchar *translator_credits;
+
+ /* The translator-credits string is for translators to list
+ * per-language credits for translation, displayed in the
+ * about dialog. */
+ translator_credits = _("translator-credits");
+ if (strcmp (translator_credits, "translator-credits") == 0)
+ translator_credits = NULL;
+
+ gtk_show_about_dialog (
+ GTK_WINDOW (shell_window),
+ "program-name", "Evolution",
+ "version", VERSION,
+ "copyright", EVOLUTION_COPYRIGHT,
+ "comments", _("Groupware Suite"),
+ "website", EVOLUTION_WEBSITE,
+ "website-label", _("Evolution Website"),
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", translator_credits,
+ "logo-icon-name", "evolution",
+ NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_CLOSE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action closes @window. If this is the last window,
+ * the application initiates shutdown.
+ *
+ * Main menu item: File -> Close
+ **/
+static void
+action_close_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ GtkWidget *widget = GTK_WIDGET (shell_window);
+ GdkEvent *event;
+
+ /* Synthesize a delete_event on this window. */
+ event = gdk_event_new (GDK_DELETE);
+ event->any.window = g_object_ref (widget->window);
+ event->any.send_event = TRUE;
+ gtk_main_do_event (event);
+ gdk_event_free (event);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_CONTENTS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the application's user manual.
+ *
+ * Main menu item: Help -> Contents
+ **/
+static void
+action_contents_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_display_help (GTK_WINDOW (shell_window), NULL);
+}
+
+static void
+action_custom_rule_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ FilterRule *rule;
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ rule = g_object_get_data (G_OBJECT (action), "rule");
+ g_return_if_fail (rule != NULL);
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ rule = g_object_get_data (G_OBJECT (action), "rule");
+ g_return_if_fail (IS_FILTER_RULE (rule));
+
+ e_shell_content_set_search_rule (shell_content, rule);
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_FAQ:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a web page with answers to frequently
+ * asked questions about this application.
+ *
+ * Main menu item: Help -> Evolution FAQ
+ **/
+static void
+action_faq_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_show_uri (GTK_WINDOW (shell_window), EVOLUTION_FAQ);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action deletes all stored passwords.
+ *
+ * Main menu item: File -> Forget Passwords
+ **/
+static void
+action_forget_passwords_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ gint response;
+
+ response = e_error_run (
+ GTK_WINDOW (shell_window), "shell:forget-passwords", NULL);
+
+ if (response == GTK_RESPONSE_OK)
+ e_passwords_forget_passwords ();
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a dialog for editing GAL views for
+ * the current shell view.
+ *
+ * Main menu item: View -> Current View -> Define Views...
+ **/
+static void
+action_gal_define_views_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ GalViewCollection *view_collection;
+ GtkWidget *dialog;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ view_collection = shell_view_class->view_collection;
+ g_return_if_fail (view_collection != NULL);
+
+ dialog = gal_define_views_dialog_new (view_collection);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gal_view_collection_save (view_collection);
+ gtk_widget_destroy (dialog);
+
+ e_shell_window_update_view_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW:
+ * @window: an #EShellWindow
+ *
+ * This radio action is selected when using a custom GAL view that has
+ * not been saved.
+ *
+ * Main menu item: View -> Current View -> Custom View
+ **/
+static void
+action_gal_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ const gchar *view_name;
+ const gchar *view_id;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ view_id = g_object_get_data (G_OBJECT (current), "view-id");
+ e_shell_view_set_view_id (shell_view, view_id);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action saves a custom GAL view.
+ *
+ * Main menu item: View -> Current View -> Save Custom View...
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_IMPORT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the Evolution Import Assistant.
+ *
+ * Main menu item: File -> Import...
+ **/
+static void
+action_import_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_shell_importer_start_import (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_NEW_WINDOW:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a new shell window.
+ *
+ * Main menu item: File -> New Window
+ **/
+static void
+action_new_window_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ const gchar *view_name;
+
+ shell = e_shell_window_get_shell (shell_window);
+ view_name = e_shell_window_get_active_view (shell_window);
+
+ e_shell_create_shell_window (shell, view_name);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_PAGE_SETUP:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the application's Page Setup dialog.
+ *
+ * Main menu item: File -> Page Setup...
+ **/
+static void
+action_page_setup_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_print_run_page_setup_dialog (GTK_WINDOW (shell_window));
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_PREFERENCES:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the application's Preferences window.
+ *
+ * Main menu item: Edit -> Preferences
+ **/
+static void
+action_preferences_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ GtkWidget *preferences_window;
+
+ shell = e_shell_window_get_shell (shell_window);
+ preferences_window = e_shell_get_preferences_window (shell);
+
+ gtk_window_set_transient_for (
+ GTK_WINDOW (preferences_window),
+ GTK_WINDOW (shell_window));
+ gtk_window_set_position (
+ GTK_WINDOW (preferences_window),
+ GTK_WIN_POS_CENTER_ON_PARENT);
+ gtk_window_present (GTK_WINDOW (preferences_window));
+
+ /* FIXME Switch to a page appropriate for the current view. */
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_QUICK_REFERENCE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a printable table of useful shortcut
+ * keys for this application.
+ *
+ * Main menu item: Help -> Quick Reference
+ **/
+static void
+action_quick_reference_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ const gchar * const *language_names;
+
+ language_names = g_get_language_names ();
+ while (*language_names != NULL) {
+ const gchar *language = *language_names++;
+ gchar *filename;
+
+ /* This must be a valid language AND a language with
+ * no encoding suffix. The next language should have
+ * no encoding suffix. */
+ if (language == NULL || strchr (language, '.') != NULL)
+ continue;
+
+ filename = g_build_filename (
+ EVOLUTION_HELPDIR, "quickref",
+ language, "quickref.pdf", NULL);
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ GFile *file;
+ gchar *uri;
+ GError *error = NULL;
+
+ file = g_file_new_for_path (filename);
+ uri = g_file_get_uri (file);
+
+ g_app_info_launch_default_for_uri (uri, NULL, &error);
+
+ if (error != NULL) {
+ /* FIXME Show an error dialog. */
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (file);
+ g_free (uri);
+ }
+
+ g_free (filename);
+ }
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_QUIT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action initiates application shutdown.
+ *
+ * Main menu item: File -> Quit
+ **/
+static void
+action_quit_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+
+ shell = e_shell_window_get_shell (shell_window);
+ e_shell_quit (shell);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens an Advanced Search dialog.
+ *
+ * Main menu item: Search -> Advanced Search...
+ **/
+static void
+action_search_advanced_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_run_advanced_search_dialog (shell_content);
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_CLEAR:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action clears the most recent search results.
+ *
+ * Main menu item: Search -> Clear
+ **/
+static void
+action_search_clear_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_set_search_rule (shell_content, NULL);
+ e_shell_content_set_search_text (shell_content, NULL);
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_EDIT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a dialog for editing saved searches.
+ *
+ * Main menu item: Search -> Edit Saved Searches...
+ **/
+static void
+action_search_edit_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_run_edit_searches_dialog (shell_content);
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action executes the current search conditions.
+ *
+ * Main menu item: Search -> Find Now
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action displays a menu of search options.
+ * This appears as a "find" icon in the window's search entry.
+ **/
+static void
+action_search_options_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ const gchar *view_name;
+ const gchar *widget_path;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+
+ widget_path = shell_view_class->search_options;
+ e_shell_view_show_popup_menu (shell_view, widget_path, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_SAVE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action saves the current search conditions.
+ *
+ * Main menu item: Search -> Save Search...
+ **/
+static void
+action_search_save_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_run_save_search_dialog (shell_content);
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEND_RECEIVE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the Send &amp; Receive Mail dialog.
+ *
+ * Main menu item: File -> Send / Receive
+ **/
+static void
+action_send_receive_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+
+ shell = e_shell_window_get_shell (shell_window);
+ e_shell_send_receive (shell, GTK_WINDOW (shell_window));
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the side bar is visible.
+ *
+ * Main menu item: View -> Layout -> Show Side Bar
+ **/
+static void
+action_show_sidebar_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ GtkPaned *paned;
+ GtkWidget *widget;
+ gboolean active;
+
+ paned = GTK_PANED (shell_window->priv->content_pane);
+
+ widget = gtk_paned_get_child1 (paned);
+ active = gtk_toggle_action_get_active (action);
+ g_object_set (widget, "visible", active, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the status bar is visible.
+ *
+ * Main menu item: View -> Layout -> Show Status Bar
+ **/
+static void
+action_show_statusbar_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ GtkWidget *widget;
+ gboolean active;
+
+ widget = shell_window->priv->status_area;
+ active = gtk_toggle_action_get_active (action);
+ g_object_set (widget, "visible", active, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_SWITCHER:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the switcher buttons are visible.
+ *
+ * Main menu item: View -> Switcher Appearance -> Show Buttons
+ **/
+static void
+action_show_switcher_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ EShellSwitcher *switcher;
+ gboolean active;
+
+ switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
+ active = gtk_toggle_action_get_active (action);
+ e_shell_switcher_set_visible (switcher, active);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the tool bar is visible.
+ *
+ * Main menu item: View -> Layout -> Show Tool Bar
+ **/
+static void
+action_show_toolbar_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ GtkWidget *widget;
+ gboolean active;
+
+ widget = shell_window->priv->main_toolbar;
+ active = gtk_toggle_action_get_active (action);
+ g_object_set (widget, "visible", active, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SUBMIT_BUG:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action allows users to report a bug using
+ * Bug Buddy.
+ *
+ * Main menu item: Help -> Submit Bug Report
+ **/
+static void
+action_submit_bug_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ const gchar *command_line;
+ GError *error = NULL;
+
+ command_line = "bug-buddy --package=Evolution";
+
+ g_debug ("Spawning: %s", command_line);
+ g_spawn_command_line_async (command_line, &error);
+
+ if (error != NULL) {
+ const gchar *message;
+
+ if (error->code == G_SPAWN_ERROR_NOENT)
+ message = _("Bug Buddy is not installed.");
+ else
+ message = _("Bug Buddy could not be run.");
+ e_notice (shell_window, GTK_MESSAGE_ERROR, message);
+ g_error_free (error);
+ }
+}
+
+static void
+action_switcher_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ const gchar *view_name;
+
+ view_name = g_object_get_data (G_OBJECT (current), "view-name");
+ e_shell_window_switch_to_view (shell_window, view_name);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons with icons and text.
+ *
+ * Main menu item: View -> Switcher Appearance -> Icons and Text
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons with icons only.
+ *
+ * Main menu item: View -> Switcher Appearance -> Icons Only
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons with text only.
+ *
+ * Main menu item: View -> Switcher Appearance -> Text Only
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons according to the desktop
+ * toolbar setting.
+ *
+ * Main menu item: View -> Switcher Appearance -> Toolbar Style
+ **/
+static void
+action_switcher_style_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ EShellSwitcher *switcher;
+ GtkToolbarStyle style;
+
+ switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
+ style = gtk_radio_action_get_current_value (action);
+
+ switch (style) {
+ case GTK_TOOLBAR_ICONS:
+ case GTK_TOOLBAR_TEXT:
+ case GTK_TOOLBAR_BOTH:
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ e_shell_switcher_set_style (switcher, style);
+ break;
+
+ default:
+ e_shell_switcher_unset_style (switcher);
+ break;
+ }
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SYNC_OPTIONS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the Gnome Pilot settings.
+ *
+ * Main menu item: Edit -> Synchronization Options...
+ **/
+static void
+action_sync_options_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ const gchar *command_line;
+ GError *error = NULL;
+
+ command_line = "gpilotd-control-applet";
+
+ g_debug ("Spawning: %s", command_line);
+ g_spawn_command_line_async (command_line, &error);
+
+ if (error != NULL) {
+ const gchar *message;
+
+ if (error->code == G_SPAWN_ERROR_NOENT)
+ message = _("GNOME Pilot is not installed.");
+ else
+ message = _("GNOME Pilot could not be run.");
+ e_notice (shell_window, GTK_MESSAGE_ERROR, message);
+ g_error_free (error);
+ }
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_WORK_OFFLINE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action puts the application into offline mode.
+ *
+ * Main menu item: File -> Work Offline
+ **/
+static void
+action_work_offline_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_set_online (shell, FALSE);
+
+ /* XXX The sense of the setting is reversed. Would be more
+ * intuitive and less error-prone as "start-online". */
+ e_shell_settings_set_boolean (
+ shell_settings, "start-offline", TRUE);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_WORK_ONLINE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action puts the application into online mode.
+ *
+ * Main menu item: File -> Work Online
+ **/
+static void
+action_work_online_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_set_online (shell, TRUE);
+
+ /* XXX The sense of the setting is reversed. Would be more
+ * intuitive and less error-prone as "start-online". */
+ e_shell_settings_set_boolean (
+ shell_settings, "start-offline", FALSE);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_SHELL:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_SWITCHER:
+ * @window: an #EShellWindow
+ **/
+
+static GtkActionEntry shell_entries[] = {
+
+ { "about",
+ GTK_STOCK_ABOUT,
+ NULL,
+ NULL,
+ N_("Show information about Evolution"),
+ G_CALLBACK (action_about_cb) },
+
+ { "close",
+ GTK_STOCK_CLOSE,
+ N_("_Close Window"),
+ "<Control>w",
+ N_("Close this window"),
+ G_CALLBACK (action_close_cb) },
+
+ { "contents",
+ GTK_STOCK_HELP,
+ N_("_Contents"),
+ "F1",
+ N_("Open the Evolution User Guide"),
+ G_CALLBACK (action_contents_cb) },
+
+ { "faq",
+ "help-faq",
+ N_("Evolution _FAQ"),
+ NULL,
+ N_("Open the Frequently Asked Questions webpage"),
+ G_CALLBACK (action_faq_cb) },
+
+ { "forget-passwords",
+ NULL,
+ N_("_Forget Passwords"),
+ NULL,
+ N_("Forget all remembered passwords"),
+ G_CALLBACK (action_forget_passwords_cb) },
+
+ { "import",
+ "stock_mail-import",
+ N_("I_mport..."),
+ NULL,
+ N_("Import data from other programs"),
+ G_CALLBACK (action_import_cb) },
+
+ { "new-window",
+ "window-new",
+ N_("New _Window"),
+ "<Control><Shift>w",
+ N_("Create a new window displaying this view"),
+ G_CALLBACK (action_new_window_cb) },
+
+ { "preferences",
+ GTK_STOCK_PREFERENCES,
+ NULL,
+ "<Control><Shift>s",
+ N_("Configure Evolution"),
+ G_CALLBACK (action_preferences_cb) },
+
+ { "quick-reference",
+ NULL,
+ N_("_Quick Reference"),
+ NULL,
+ N_("Show Evolution's shortcut keys"),
+ G_CALLBACK (action_quick_reference_cb) },
+
+ { "quit",
+ GTK_STOCK_QUIT,
+ NULL,
+ NULL,
+ N_("Exit the program"),
+ G_CALLBACK (action_quit_cb) },
+
+ { "search-advanced",
+ NULL,
+ N_("_Advanced Search..."),
+ NULL,
+ N_("Construct a more advanced search"),
+ G_CALLBACK (action_search_advanced_cb) },
+
+ { "search-clear",
+ GTK_STOCK_CLEAR,
+ NULL,
+ "<Control><Shift>q",
+ N_("Clear the current search parameters"),
+ G_CALLBACK (action_search_clear_cb) },
+
+ { "search-edit",
+ NULL,
+ N_("_Edit Saved Searches..."),
+ NULL,
+ N_("Manage your saved searches"),
+ G_CALLBACK (action_search_edit_cb) },
+
+ { "search-execute",
+ GTK_STOCK_FIND,
+ N_("_Find Now"),
+ "", /* Block the default Ctrl+F. */
+ N_("Execute the current search parameters"),
+ NULL }, /* Handled by EShellContent and subclasses. */
+
+ { "search-options",
+ GTK_STOCK_FIND,
+ NULL,
+ NULL,
+ N_("Click here to change the search type"),
+ G_CALLBACK (action_search_options_cb) },
+
+ { "search-save",
+ NULL,
+ N_("_Save Search..."),
+ NULL,
+ N_("Save the current search parameters"),
+ G_CALLBACK (action_search_save_cb) },
+
+ { "send-receive",
+ "mail-send-receive",
+ N_("Send / _Receive"),
+ "F9",
+ N_("Send queued items and retrieve new items"),
+ G_CALLBACK (action_send_receive_cb) },
+
+ { "submit-bug",
+ NULL,
+ N_("Submit _Bug Report..."),
+ NULL,
+ N_("Submit a bug report using Bug Buddy"),
+ G_CALLBACK (action_submit_bug_cb) },
+
+ { "sync-options",
+ NULL,
+ N_("_Synchronization Options..."),
+ NULL,
+ N_("Set up Pilot configuration"),
+ G_CALLBACK (action_sync_options_cb) },
+
+ { "work-offline",
+ "stock_disconnect",
+ N_("_Work Offline"),
+ NULL,
+ N_("Put Evolution into offline mode"),
+ G_CALLBACK (action_work_offline_cb) },
+
+ { "work-online",
+ "stock_connect",
+ N_("_Work Online"),
+ NULL,
+ N_("Put Evolution into online mode"),
+ G_CALLBACK (action_work_online_cb) },
+
+ /*** Menus ***/
+
+ { "edit-menu",
+ NULL,
+ N_("_Edit"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "file-menu",
+ NULL,
+ N_("_File"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "help-menu",
+ NULL,
+ N_("_Help"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "layout-menu",
+ NULL,
+ N_("Lay_out"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "new-menu",
+ GTK_STOCK_NEW,
+ N_("_New"),
+ "",
+ NULL,
+ NULL },
+
+ { "search-menu",
+ NULL,
+ N_("_Search"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "switcher-menu",
+ NULL,
+ N_("_Switcher Appearance"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "view-menu",
+ NULL,
+ N_("_View"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "window-menu",
+ NULL,
+ N_("_Window"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static GtkToggleActionEntry shell_toggle_entries[] = {
+
+ { "show-sidebar",
+ NULL,
+ N_("Show Side _Bar"),
+ NULL,
+ N_("Show the side bar"),
+ G_CALLBACK (action_show_sidebar_cb),
+ TRUE },
+
+ { "show-statusbar",
+ NULL,
+ N_("Show _Status Bar"),
+ NULL,
+ N_("Show the status bar"),
+ G_CALLBACK (action_show_statusbar_cb),
+ TRUE },
+
+ { "show-switcher",
+ NULL,
+ N_("Show _Buttons"),
+ NULL,
+ N_("Show the switcher buttons"),
+ G_CALLBACK (action_show_switcher_cb),
+ TRUE },
+
+ { "show-toolbar",
+ NULL,
+ N_("Show _Tool Bar"),
+ NULL,
+ N_("Show the toolbar"),
+ G_CALLBACK (action_show_toolbar_cb),
+ TRUE }
+};
+
+static GtkRadioActionEntry shell_switcher_entries[] = {
+
+ /* This action represents the initial active shell view.
+ * It should not be visible in the UI, nor should it be
+ * possible to switch to it from another shell view. */
+ { "switcher-initial",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ -1 }
+};
+
+static GtkRadioActionEntry shell_switcher_style_entries[] = {
+
+ { "switcher-style-icons",
+ NULL,
+ N_("_Icons Only"),
+ NULL,
+ N_("Display window buttons with icons only"),
+ GTK_TOOLBAR_ICONS },
+
+ { "switcher-style-text",
+ NULL,
+ N_("_Text Only"),
+ NULL,
+ N_("Display window buttons with text only"),
+ GTK_TOOLBAR_TEXT },
+
+ { "switcher-style-both",
+ NULL,
+ N_("Icons _and Text"),
+ NULL,
+ N_("Display window buttons with icons and text"),
+ GTK_TOOLBAR_BOTH_HORIZ },
+
+ { "switcher-style-user",
+ NULL,
+ N_("Tool_bar Style"),
+ NULL,
+ N_("Display window buttons using the desktop toolbar setting"),
+ -1 }
+};
+
+static GtkActionEntry shell_gal_view_entries[] = {
+
+ { "gal-define-views",
+ NULL,
+ N_("Define Views..."),
+ NULL,
+ N_("Create or edit views"),
+ G_CALLBACK (action_gal_define_views_cb) },
+
+ { "gal-save-custom-view",
+ NULL,
+ N_("Save Custom View..."),
+ NULL,
+ N_("Save current custom view"),
+ NULL }, /* Handled by subclasses. */
+
+ /*** Menus ***/
+
+ { "gal-view-menu",
+ NULL,
+ N_("C_urrent View"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static GtkRadioActionEntry shell_gal_view_radio_entries[] = {
+
+ { "gal-custom-view",
+ NULL,
+ N_("Custom View"),
+ NULL,
+ N_("Current view is a customized view"),
+ -1 }
+};
+
+static GtkActionEntry shell_lockdown_print_setup_entries[] = {
+
+ { "page-setup",
+ GTK_STOCK_PAGE_SETUP,
+ NULL,
+ NULL,
+ N_("Change the page settings for your current printer"),
+ G_CALLBACK (action_page_setup_cb) }
+};
+
+static void
+shell_window_extract_actions (EShellWindow *shell_window,
+ GList **source_list,
+ GList **destination_list)
+{
+ const gchar *current_view;
+ GList *match_list = NULL;
+ GList *iter;
+
+ /* Pick out the actions from the source list that are tagged
+ * as belonging to the current EShellView and move them to the
+ * destination list. */
+
+ current_view = e_shell_window_get_active_view (shell_window);
+
+ /* Example: Suppose [A] and [C] are tagged for this EShellView.
+ *
+ * source_list = [A] -> [B] -> [C]
+ * ^ ^
+ * | |
+ * match_list = [ ] --------> [ ]
+ *
+ *
+ * destination_list = [1] -> [2] (other actions)
+ */
+ for (iter = *source_list; iter != NULL; iter = iter->next) {
+ GtkAction *action = iter->data;
+ const gchar *backend_name;
+
+ backend_name = g_object_get_data (
+ G_OBJECT (action), "backend-name");
+
+ if (strcmp (backend_name, current_view) != 0)
+ continue;
+
+ if (g_object_get_data (G_OBJECT (action), "primary"))
+ match_list = g_list_prepend (match_list, iter);
+ else
+ match_list = g_list_append (match_list, iter);
+ }
+
+ /* source_list = [B] match_list = [A] -> [C] */
+ for (iter = match_list; iter != NULL; iter = iter->next) {
+ GList *link = iter->data;
+
+ iter->data = link->data;
+ *source_list = g_list_delete_link (*source_list, link);
+ }
+
+ /* destination_list = [1] -> [2] -> [A] -> [C] */
+ *destination_list = g_list_concat (*destination_list, match_list);
+}
+
+void
+e_shell_window_actions_init (EShellWindow *shell_window)
+{
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ e_load_ui_definition (ui_manager, "evolution-shell.ui");
+
+ /* Shell Actions */
+ action_group = ACTION_GROUP (SHELL);
+ gtk_action_group_add_actions (
+ action_group, shell_entries,
+ G_N_ELEMENTS (shell_entries), shell_window);
+ gtk_action_group_add_toggle_actions (
+ action_group, shell_toggle_entries,
+ G_N_ELEMENTS (shell_toggle_entries), shell_window);
+ gtk_action_group_add_radio_actions (
+ action_group, shell_switcher_style_entries,
+ G_N_ELEMENTS (shell_switcher_style_entries),
+ E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
+ G_CALLBACK (action_switcher_style_cb), shell_window);
+ gtk_action_group_add_actions (
+ action_group, shell_gal_view_entries,
+ G_N_ELEMENTS (shell_gal_view_entries), shell_window);
+ gtk_action_group_add_radio_actions (
+ action_group, shell_gal_view_radio_entries,
+ G_N_ELEMENTS (shell_gal_view_radio_entries),
+ 0, G_CALLBACK (action_gal_view_cb), shell_window);
+
+ /* Switcher Actions */
+ action_group = ACTION_GROUP (SWITCHER);
+ gtk_action_group_add_radio_actions (
+ action_group, shell_switcher_entries,
+ G_N_ELEMENTS (shell_switcher_entries),
+ -1, G_CALLBACK (action_switcher_cb), shell_window);
+
+ /* Lockdown Print Setup Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP);
+ gtk_action_group_add_actions (
+ action_group, shell_lockdown_print_setup_entries,
+ G_N_ELEMENTS (shell_lockdown_print_setup_entries),
+ shell_window);
+
+ /* Fine tuning. */
+
+ g_object_set (ACTION (SEND_RECEIVE), "is-important", TRUE, NULL);
+}
+
+GtkWidget *
+e_shell_window_create_new_menu (EShellWindow *shell_window)
+{
+ GtkActionGroup *action_group;
+ GList *new_item_actions;
+ GList *new_source_actions;
+ GList *iter, *list = NULL;
+ GtkWidget *menu;
+ GtkWidget *separator;
+
+ /* Get sorted lists of "new item" and "new source" actions. */
+
+ action_group = ACTION_GROUP (NEW_ITEM);
+
+ new_item_actions = g_list_sort (
+ gtk_action_group_list_actions (action_group),
+ (GCompareFunc) e_action_compare_by_label);
+
+ action_group = ACTION_GROUP (NEW_SOURCE);
+
+ new_source_actions = g_list_sort (
+ gtk_action_group_list_actions (action_group),
+ (GCompareFunc) e_action_compare_by_label);
+
+ /* Give priority to actions that belong to this shell view. */
+
+ shell_window_extract_actions (
+ shell_window, &new_item_actions, &list);
+
+ shell_window_extract_actions (
+ shell_window, &new_source_actions, &list);
+
+ /* Convert the actions to menu item proxy widgets. */
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ iter->data = gtk_action_create_menu_item (iter->data);
+
+ for (iter = new_item_actions; iter != NULL; iter = iter->next)
+ iter->data = gtk_action_create_menu_item (iter->data);
+
+ for (iter = new_source_actions; iter != NULL; iter = iter->next)
+ iter->data = gtk_action_create_menu_item (iter->data);
+
+ /* Add menu separators. */
+
+ separator = gtk_separator_menu_item_new ();
+ new_item_actions = g_list_prepend (new_item_actions, separator);
+ gtk_widget_show (GTK_WIDGET (separator));
+
+ separator = gtk_separator_menu_item_new ();
+ new_source_actions = g_list_prepend (new_source_actions, separator);
+ gtk_widget_show (GTK_WIDGET (separator));
+
+ /* Merge everything into one list, reflecting the menu layout. */
+
+ list = g_list_concat (list, new_item_actions);
+ new_item_actions = NULL; /* just for clarity */
+
+ list = g_list_concat (list, new_source_actions);
+ new_source_actions = NULL; /* just for clarity */
+
+ /* And finally, build the menu. */
+
+ menu = gtk_menu_new ();
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), iter->data);
+
+ g_list_free (list);
+
+ return menu;
+}
+
+void
+e_shell_window_create_switcher_actions (EShellWindow *shell_window)
+{
+ GSList *group = NULL;
+ GtkRadioAction *action;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ EShellSwitcher *switcher;
+ EShell *shell;
+ GList *list, *iter;
+ guint merge_id;
+ guint ii = 0;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ action_group = ACTION_GROUP (SWITCHER);
+ switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ shell = e_shell_window_get_shell (shell_window);
+ list = e_shell_get_shell_backends (shell);
+
+ /* Construct a group of radio actions from the various EShellView
+ * subclasses and register them with the EShellSwitcher. These
+ * actions are manifested as switcher buttons and View->Window
+ * menu items. */
+
+ action = GTK_RADIO_ACTION (ACTION (SWITCHER_INITIAL));
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EShellBackend *shell_backend = iter->data;
+ EShellBackendClass *backend_class;
+ EShellViewClass *class;
+ GType view_type;
+ const gchar *view_name;
+ gchar *accelerator;
+ gchar *action_name;
+ gchar *tooltip;
+
+ /* The backend name is also the view name. */
+ backend_class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+ view_type = backend_class->shell_view_type;
+ view_name = backend_class->name;
+
+ if (!g_type_is_a (view_type, E_TYPE_SHELL_VIEW)) {
+ g_critical (
+ "%s is not a subclass of %s",
+ g_type_name (view_type),
+ g_type_name (E_TYPE_SHELL_VIEW));
+ continue;
+ }
+
+ class = g_type_class_ref (view_type);
+
+ if (class->label == NULL) {
+ g_critical (
+ "Label member not set on %s",
+ G_OBJECT_CLASS_NAME (class));
+ continue;
+ }
+
+ action_name = g_strdup_printf (SWITCHER_FORMAT, view_name);
+ tooltip = g_strdup_printf (_("Switch to %s"), class->label);
+
+ /* Note, we have to set "icon-name" separately because
+ * gtk_radio_action_new() expects a "stock-id". Sadly,
+ * GTK+ still distinguishes between the two. */
+
+ action = gtk_radio_action_new (
+ action_name, class->label,
+ tooltip, NULL, ii++);
+
+ g_object_set (
+ G_OBJECT (action),
+ "icon-name", class->icon_name, NULL);
+
+ g_object_set_data (
+ G_OBJECT (action),
+ "view-name", (gpointer) view_name);
+
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ /* The first nine views have accelerators Ctrl+(1-9). */
+ if (ii < 10)
+ accelerator = g_strdup_printf ("<Control>%d", ii);
+ else
+ accelerator = g_strdup ("");
+
+ gtk_action_group_add_action_with_accel (
+ action_group, GTK_ACTION (action), accelerator);
+
+ e_shell_switcher_add_action (switcher, GTK_ACTION (action));
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id,
+ "/main-menu/view-menu/window-menu",
+ action_name, action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (accelerator);
+ g_free (action_name);
+ g_free (tooltip);
+
+ g_type_class_unref (class);
+ }
+}
+
+void
+e_shell_window_update_view_menu (EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ GalViewCollection *view_collection;
+ GtkRadioAction *radio_action;
+ GtkAction *action;
+ GSList *radio_group;
+ gboolean visible;
+ const gchar *path;
+ const gchar *view_id;
+ const gchar *view_name;
+ guint merge_id;
+ gint count, ii;
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ g_return_if_fail (shell_view != NULL);
+
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ view_collection = shell_view_class->view_collection;
+ view_id = e_shell_view_get_view_id (shell_view);
+ g_return_if_fail (view_collection != NULL);
+
+ action_group = ACTION_GROUP (GAL_VIEW);
+ merge_id = shell_window->priv->gal_view_merge_id;
+
+ /* Unmerge the previous menu. */
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ e_action_group_remove_all_actions (action_group);
+
+ /* We have a view ID, so forge ahead. */
+ count = gal_view_collection_get_count (view_collection);
+ path = "/main-menu/view-menu/gal-view-menu/gal-view-list";
+
+ /* Prevent spurious activations. */
+ action = ACTION (GAL_CUSTOM_VIEW);
+ g_signal_handlers_block_matched (
+ action, G_SIGNAL_MATCH_FUNC, 0, 0,
+ NULL, action_gal_view_cb, NULL);
+
+ /* Default to "Custom View", unless we find our view ID. */
+ radio_action = GTK_RADIO_ACTION (ACTION (GAL_CUSTOM_VIEW));
+ gtk_radio_action_set_group (radio_action, NULL);
+ radio_group = gtk_radio_action_get_group (radio_action);
+ gtk_radio_action_set_current_value (radio_action, -1);
+
+ /* Add a menu item for each view collection item. */
+ for (ii = 0; ii < count; ii++) {
+ GalViewCollectionItem *item;
+ gchar *action_name;
+ gchar *tooltip;
+
+ item = gal_view_collection_get_view_item (view_collection, ii);
+
+ action_name = g_strdup_printf (
+ "gal-view-%s-%d", view_name, ii);
+ tooltip = g_strdup_printf ("Select view: %s", item->title);
+
+ radio_action = gtk_radio_action_new (
+ action_name, item->title, tooltip, NULL, ii);
+
+ action = GTK_ACTION (radio_action);
+ gtk_radio_action_set_group (radio_action, radio_group);
+ radio_group = gtk_radio_action_get_group (radio_action);
+
+ g_object_set_data_full (
+ G_OBJECT (radio_action), "view-id",
+ g_strdup (item->id), (GDestroyNotify) g_free);
+
+ if (view_id != NULL && strcmp (item->id, view_id) == 0)
+ gtk_radio_action_set_current_value (radio_action, ii);
+
+ gtk_action_group_add_action (action_group, action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, path, action_name,
+ action_name, GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (action_name);
+ g_free (tooltip);
+ }
+
+ /* Doesn't matter which radio action we check. */
+ visible = (gtk_radio_action_get_current_value (radio_action) < 0);
+
+ action = ACTION (GAL_CUSTOM_VIEW);
+ gtk_action_set_visible (action, visible);
+ g_signal_handlers_unblock_matched (
+ action, G_SIGNAL_MATCH_FUNC, 0, 0,
+ NULL, action_gal_view_cb, NULL);
+
+ action = ACTION (GAL_SAVE_CUSTOM_VIEW);
+ gtk_action_set_visible (action, visible);
+}
+
+void
+e_shell_window_update_search_menu (EShellWindow *shell_window)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ RuleContext *context;
+ FilterRule *rule;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *source;
+ const gchar *view_name;
+ gboolean sensitive;
+ guint merge_id;
+ gint ii = 0;
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ context = e_shell_content_get_search_context (shell_content);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ source = FILTER_SOURCE_INCOMING;
+
+ /* Update sensitivity of search actions. */
+
+ sensitive = (e_shell_content_get_search_rule (shell_content) != NULL);
+ gtk_action_set_sensitive (ACTION (SEARCH_CLEAR), sensitive);
+ gtk_action_set_sensitive (ACTION (SEARCH_SAVE), sensitive);
+
+ sensitive = (shell_view_class->search_options != NULL);
+ gtk_action_set_sensitive (ACTION (SEARCH_OPTIONS), sensitive);
+
+ /* Add custom rules to the Search menu. */
+
+ action_group = ACTION_GROUP (CUSTOM_RULES);
+ merge_id = shell_window->priv->custom_rule_merge_id;
+
+ /* Unmerge the previous menu. */
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ e_action_group_remove_all_actions (action_group);
+
+ rule = rule_context_next_rule (context, NULL, source);
+ while (rule != NULL) {
+ GtkAction *action;
+ gchar *action_name;
+ gchar *action_label;
+
+ action_name = g_strdup_printf ("custom-rule-%d", ii++);
+ if (ii < 10)
+ action_label = g_strdup_printf (
+ "_%d. %s", ii, rule->name);
+ else
+ action_label = g_strdup (rule->name);
+
+ action = gtk_action_new (
+ action_name, action_label,
+ _("Execute these search parameters"), NULL);
+
+ g_object_set_data_full (
+ G_OBJECT (action),
+ "rule", g_object_ref (rule),
+ (GDestroyNotify) g_object_unref);
+
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_custom_rule_cb), shell_window);
+
+ gtk_action_group_add_action (action_group, action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id,
+ "/main-menu/search-menu/custom-rules",
+ action_name, action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (action_name);
+ g_free (action_label);
+
+ rule = rule_context_next_rule (context, rule, source);
+ }
+}
diff --git a/shell/e-shell-window-actions.h b/shell/e-shell-window-actions.h
new file mode 100644
index 0000000000..3b8774a494
--- /dev/null
+++ b/shell/e-shell-window-actions.h
@@ -0,0 +1,123 @@
+/*
+ * e-shell-window-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SHELL_WINDOW_ACTIONS_H
+#define E_SHELL_WINDOW_ACTIONS_H
+
+#define E_SHELL_WINDOW_ACTION(window, name) \
+ (e_shell_window_get_action (E_SHELL_WINDOW (window), (name)))
+
+#define E_SHELL_WINDOW_ACTION_GROUP(window, name) \
+ (e_shell_window_get_action_group (E_SHELL_WINDOW (window), (name)))
+
+/* Actions */
+#define E_SHELL_WINDOW_ACTION_ABOUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "about")
+#define E_SHELL_WINDOW_ACTION_CLOSE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "close")
+#define E_SHELL_WINDOW_ACTION_CONTENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contents")
+#define E_SHELL_WINDOW_ACTION_FAQ(window) \
+ E_SHELL_WINDOW_ACTION ((window), "faq")
+#define E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "forget-passwords")
+#define E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "gal-custom-view")
+#define E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "gal-define-views")
+#define E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "gal-save-custom-view")
+#define E_SHELL_WINDOW_ACTION_IMPORT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "import")
+#define E_SHELL_WINDOW_ACTION_NEW_WINDOW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "new-window")
+#define E_SHELL_WINDOW_ACTION_PAGE_SETUP(window) \
+ E_SHELL_WINDOW_ACTION ((window), "page-setup")
+#define E_SHELL_WINDOW_ACTION_PREFERENCES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "preferences")
+#define E_SHELL_WINDOW_ACTION_QUICK_REFERENCE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "quick-reference")
+#define E_SHELL_WINDOW_ACTION_QUIT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "quit")
+#define E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-advanced")
+#define E_SHELL_WINDOW_ACTION_SEARCH_CLEAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-clear")
+#define E_SHELL_WINDOW_ACTION_SEARCH_EDIT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-edit")
+#define E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-execute")
+#define E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-options")
+#define E_SHELL_WINDOW_ACTION_SEARCH_SAVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-save")
+#define E_SHELL_WINDOW_ACTION_SEND_RECEIVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "send-receive")
+#define E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-sidebar")
+#define E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-statusbar")
+#define E_SHELL_WINDOW_ACTION_SHOW_SWITCHER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-switcher")
+#define E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-toolbar")
+#define E_SHELL_WINDOW_ACTION_SUBMIT_BUG(window) \
+ E_SHELL_WINDOW_ACTION ((window), "submit-bug")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_INITIAL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-initial")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-both")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-icons")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-text")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-user")
+#define E_SHELL_WINDOW_ACTION_SYNC_OPTIONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "sync-options")
+#define E_SHELL_WINDOW_ACTION_WORK_OFFLINE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "work-offline")
+#define E_SHELL_WINDOW_ACTION_WORK_ONLINE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "work-online")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "custom-rules")
+#define E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "gal-view")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_APPLICATION_HANDLERS(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-application-handlers")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINTING(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-printing")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINT_SETUP(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-print-setup")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_SAVE_TO_DISK(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-save-to-disk")
+#define E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "new-item")
+#define E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "new-source")
+#define E_SHELL_WINDOW_ACTION_GROUP_SHELL(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "shell")
+#define E_SHELL_WINDOW_ACTION_GROUP_SWITCHER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "switcher")
+
+#endif /* E_SHELL_WINDOW_ACTIONS_H */
diff --git a/shell/e-shell-window-commands.c b/shell/e-shell-window-commands.c
deleted file mode 100644
index 731f17b49b..0000000000
--- a/shell/e-shell-window-commands.c
+++ /dev/null
@@ -1,1388 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include <glib/gprintf.h>
-
-#include <glib/gi18n.h>
-
-#include <gio/gio.h>
-
-#include <bonobo/bonobo-ui-component.h>
-
-#include <libedataserverui/e-passwords.h>
-
-#include <gconf/gconf-client.h>
-
-#include "e-util/e-dialog-utils.h"
-#include "e-util/e-error.h"
-#include "e-util/e-icon-factory.h"
-#include "e-util/e-print.h"
-#include "e-util/e-util.h"
-#include "e-util/e-util-private.h"
-
-#include "e-shell-window-commands.h"
-#include "e-shell-window.h"
-#include "evolution-shell-component-utils.h"
-
-#include "e-shell-importer.h"
-
-#define EVOLUTION_COPYRIGHT \
- "Copyright \xC2\xA9 1999 - 2009 Novell, Inc. and Others"
-
-#define EVOLUTION_WEBSITE \
- "http://www.gnome.org/projects/evolution/"
-
-/* Utility functions. */
-
-static void
-launch_pilot_settings (void)
-{
- GError* error = NULL;
-
- gchar * args = g_find_program_in_path ("gpilotd-control-applet");
- if (args == NULL) {
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("The GNOME Pilot tools do not appear to be installed on this system."));
- return;
- }
-
- g_spawn_command_line_async (args, &error);
- g_free (args);
-
- if (error != NULL) {
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("Error executing %s. (%s)"), args, error->message);
- g_error_free (error);
- }
-}
-
-/* Command callbacks. */
-
-static void
-command_import (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_importer_start_import (window);
-}
-
-static void
-command_page_setup (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_print_run_page_setup_dialog (GTK_WINDOW (window));
-}
-
-static void
-command_close (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- if (e_shell_request_close_window (e_shell_window_peek_shell (window), window))
- gtk_widget_destroy (GTK_WIDGET (window));
-}
-
-static void
-command_quit (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- EShell *shell = e_shell_window_peek_shell (window);
-
- e_shell_quit(shell);
-}
-
-static void
-command_submit_bug (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- const gchar *command_line;
- GError *error = NULL;
-
- command_line = "bug-buddy --sm-disable --package=Evolution";
-
- g_debug ("Spawning: %s", command_line);
-
- if (!g_spawn_command_line_async (command_line, &error)) {
- if (error->code == G_SPAWN_ERROR_NOENT)
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("Bug buddy is not installed."));
- else
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("Bug buddy could not be run."));
- g_error_free (error);
- }
-}
-
-/* must be in utf8, the weird breaking of escaped strings
- is so the hex escape strings dont swallow too many chars
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- So that means, 8 bit characters, use \xXX hex encoding ONLY
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- No all environments are utf8 and not all editors can handle it.
-*/
-static const gchar *authors[] = {
- "Aaron Weber",
- "Abel Cheung",
- "Abhishek Parwal",
- "Adam Weinberger",
- "Adi Attar",
- "Ahmad Riza H Nst",
- "Aidan Delaney",
- "Aishwarya K",
- "Akagic Amila",
- "Akhil Laddha",
- "Akira Tagoh",
- "Alastair McKinstry",
- "Alastair Tse",
- "Alejandro Andres",
- "Ales Nyakhaychyk",
- "Alessandro Decina",
- "Alessio Frusciante",
- "Alex Graveley",
- "Alex Jiang",
- "Alex Jones",
- "Alex Kloss",
- "Alex Rostovtsev",
- "Alexander Didebulidze",
- "Alexander Shopov",
- "Alexander Winston",
- "Alexandre Folle de Menezes",
- "Alfred Peng",
- "Ali Abdin",
- "Ali Akcaagac",
- "Alireza Kheirkhahan",
- "Almer S. Tigelaar",
- "Alp Toker",
- "Amanpreet Singh Alam",
- "Ambuj Chitranshi",
- "Amish",
- "Amitakhya Phukan",
- "Anand V M",
- "Anders Carlsson",
- "Andras Timar",
- "Andrea Campi",
- "Andreas Henriksson",
- "Andreas Hyden",
- "Andreas J. Guelzow",
- "Andreas Köhler",
- "Andrew Ruthven",
- "Andre Klapper",
- "Andrew T. Veliath",
- "Andrew V. Samoilov",
- "Andrew Wu",
- "Ani Peter",
- "Ankit Patel",
- "Anna Marie Dirks",
- "Antonio Xu",
- "Arafat Medini",
- "Arangel Angov",
- "Archit Baweja",
- "Ariel Rios",
- "Arik Devens",
- "Armin Bauer",
- "Arjan Scherpenisse",
- "Arkadiusz Lipiec",
- "Artis Trops",
- "Artur Flinta",
- "Arturo Espinosa Aldama",
- "Arulanandan P",
- "Arun Prakash",
- "Arvind Sundararajan",
- "Ashish Shrivastava",
- "Åsmund Skjæveland",
- "Audrey Simons",
- "Baptiste Mille-Mathias",
- "Baris Cicek",
- "Bastien Nocera",
- "Behnam Esfahbod",
- "Benedikt Roth",
- "Ben Gamari",
- "Benjamin Berg",
- "Benjamin Kahn",
- "Benoît Dejean",
- "Bernard Leach",
- "Bertrand Guiheneuf",
- "Bharath Acharya",
- "Bharat Kumar",
- "Bharathi Gauthaman",
- "Big Iain Holmes",
- "Bill Zhu",
- "Björn Torkelsson",
- "Björn Lindqvist",
- "Bob Doan",
- "Bob Mauchin",
- "Boby Wang",
- "Bolian Yin",
- "Borislav Aleksandrov",
- "Boulton",
- "Brian Mury",
- "Brian Pepple",
- "Brigitte Le Grand",
- "Bruce Tao",
- "B S Srinidhi",
- "Calvin Liu",
- "Cantona Su",
- "Carlos Garcia Campos",
- "Carlos Garnacho Parro",
- "Carlos Perelló Marín",
- "Carl Sun",
- "Carsten Guenther",
- "Carsten Schaar",
- "Changwoo Ryu",
- "Chao-Hsiung Liao",
- "Charles Zhang",
- "Chema Celorio",
- "Chenthill Palanisamy",
- "Christian Persch",
- "Chris Halls",
- "Chris Heath",
- "Chris Lahey",
- "Christian Hammond",
- "Christian Kellner",
- "Christian Kintner",
- "Christian Kirbach",
- "Christian Krause",
- "Christian Kreibich",
- "Christian Meyer",
- "Christian Neumair",
- "Christian Persch",
- "Christian Rose",
- "Christophe Fergeau",
- "Christophe Merlet",
- "Christopher Blizzard",
- "Christopher James Lahey",
- "Christopher R. Gabriel",
- "Chris Phelps",
- "Chris Toshok",
- "Clara Tattoni",
- "Claude Paroz",
- "Claudio Saavedra",
- "Clifford R. Conover",
- "Clytie Siddall",
- "Cody Russell",
- "Colin Leroy",
- "Craig Jeffares",
- "Craig Small",
- "Cyprien Le Pannérer",
- "Dafydd Harries",
- "Damian Ivereigh",
- "Damien Carbery",
- "Damon Chaplin",
- "Daniel Gryniewicz",
- "Daniel Nylander",
- "Daniel van Eeden",
- "Daniel Veillard",
- "Daniel Yacob",
- "Danilo Šegan",
- "Danishka Navin",
- "Dan Korostelev",
- "Danny Baumann",
- "Dan Berger",
- "Dan Damian",
- "Dan Nguyen",
- "Dan Williams",
- "Dan Winship",
- "Darin Adler",
- "Dave Benson",
- "Dave Camp",
- "Dave Fallon",
- "Dave Malcolm",
- "Dave West",
- "David Farning",
- "David Kaelbling",
- "David Lodge",
- "David Malcolm",
- "David Moore",
- "David Mosberger",
- "David O'Callaghan",
- "David Richards",
- "David Trowbridge",
- "David Turner",
- "David Woodhouse",
- "Denis Washington",
- "Devashish Sharma",
- "Diego Escalante Urrelo",
- "Diego Gonzalez",
- "Diego Sevilla Ruiz",
- "Dietmar Maurer",
- "Dinesh Layek",
- "Dirk-Jan C. Binnema",
- "Djihed Afifi",
- "Dmitrijs Ledkovs",
- "Dmitry Mastrukov",
- "Dodji Seketeli",
- "Duarte Loreto",
- "Dulmandakh Sukhbaatar",
- "Duncan Mak",
- "Ebby Wiselyn",
- "Ed Catmur",
- "Edd Dumbill",
- "Edgar Luna Díaz",
- "Edward Rudd",
- "Elijah Newren",
- "Elizabeth Greene",
- "Elliot Lee",
- "Elliot Turner",
- "Emil Hessman",
- "Eneko Lacunza",
- "Enver Altin",
- "Erdal Ronahi",
- "Erdi Gergo",
- "Eric Busboom",
- "Eric Zhao",
- "Eskild Hustvedt"
- "Eskil Heyn Olsen",
- "Espen Stefansen",
- "Ettore Perazzoli",
- "Evandro Fernandes Giovanini",
- "Evan Yan",
- "Fatih Demir",
- "Fazlu & Hannah",
- "Federico Mena Quintero",
- "Fernando Herrera",
- "Ferretti",
- "F. Priyadharshini",
- "Francisco Javier Fernandez Serrador",
- "Frank Arnold",
- "Frank Belew",
- "Frederic Crozat",
- "Frederic Peters",
- "Frederic Riss",
- "Fredrik Wendt",
- "Funda Wang",
- "Gabor Kelemen",
- "Ganesh",
- "Göran Uddeborg",
- "Gareth Owen",
- "Gary Coady",
- "Gary Ekker",
- "Gavin Scott",
- "Gediminas Paulauskas",
- "George Lebl",
- "Gerardo Marin",
- "Gergő Érdi",
- "Gert Kulyk",
- "Giancarlo Capella",
- "Gilbert Fang",
- "Gildas Guillemot",
- "Gil Forcada",
- "Gilles Dartiguelongue",
- "Gil Osher",
- "Gintautas Miliauskas",
- "Goran Rakić",
- "Grahame Bowland",
- "Greg Hudson",
- "Gregory Leblanc",
- "Gregory McLean",
- "Grzegorz Goawski",
- "Guilherme de S. Pastore",
- "Guntupalli Karunakar",
- "Gustavo GirÎldez",
- "Gustavo Maciel Dias Vieira",
- "Gustavo Noronha Silva",
- "Hamed Malek",
- "Hannah & Fazlu",
- "Hans Petter Jansson",
- "Hao Sheng",
- "Hari Prasad Nadig",
- "Harish Krishnaswamy",
- "Harry Lu",
- "Hasbullah Bin Pit",
- "Havoc Pennington",
- "Heath Harrelson",
- "Hein-Pieter van Braam",
- "Héctor García Álvarez",
- "Helgi Þormar Þorbjörnsson",
- "Hendrik Brandt",
- "Hendrik Richter",
- "Herbert V. Riedel",
- "Hessam M. Armandehi",
- "Hiroyuki Ikezoe",
- "Iain Buchanan",
- "Iain Holmes",
- "Ian Campbell",
- "Iassen Pramatarov",
- "Iestyn Pryce",
- "I.Felix",
- "Ignacio Casal Quinteiro",
- "Igor Nestorović",
- "Ihar Hrachyshka",
- "Ilkka Tuohela",
- "Imam Musthaqim",
- "Iñaki Larrañaga",
- "Inaki Larranaga Murgoitio",
- "Indu",
- "Irene Huang",
- "Ismael Olea",
- "Israel Escalante",
- "Ivan Stojmirov",
- "Ivar Smolin",
- "Ivelina Karcheva",
- "Iván Frade",
- "J.H.M. Dassen (Ray)",
- "Jaap A. Haitsma",
- "Jack Jia",
- "Jacob Berkman",
- "Jacob Brown",
- "Jacobo Tarrio Barreiro",
- "Jacob Ulysses Berkman",
- "Jaka Mocnik",
- "Jakub Friedl",
- "Jakub Steiner",
- "James Bowes",
- "James Doc Livingston",
- "James Henstridge",
- "James Westby",
- "James Willcox",
- "Jamil Ahmed",
- "Jan Arne Petersen",
- "Jan Tichavsky",
- "Jan Van Buggenhout",
- "J�rg Billeter",
- "Jared Moore",
- "Jarkko Ranta",
- "Jason Leach",
- "Jason Tackaberry",
- "Jayaradha",
- "Jean-Noel Guiheneuf",
- "Jedy Wang",
- "Jeff Bailey",
- "Jeff Cai",
- "Jeff Garzik",
- "Jeffrey Stedfast",
- "Jens Granseuer",
- "Jens Seidel",
- "Jeremy Katz",
- "Jeremy Messenger",
- "Jeremy Wise",
- "Jerome Lacoste",
- "Jerry Yu",
- "Jesse Pavel",
- "Jesus Bravo Alvarez",
- "Jesse Pavel",
- "Ji Lee",
- "Joan Sanfeliu",
- "João Vale",
- "Joaquim Fellmann",
- "Jody Goldberg",
- "Joe Man",
- "Joe Marcus Clarke",
- "Joe Shaw",
- "Johan Dahlin",
- "Johan Euphrosine",
- "John Gotts",
- "Johnny Jacob",
- "Jon Ander Hernandez",
- "Jonas Borgstr�m",
- "Jonathan Blandford",
- "Jonathan Dieter",
- "Jonathan Ernst",
- "Jonh Wendell",
- "Jon K Hellan",
- "Jon Oberheide",
- "Jon Trowbridge",
- "Jonas Borgstr",
- "Jonathan Blandford",
- "Jonathan Dieter",
- "Joop Stakenborg",
- "Jordi Mallach",
- "Jordi Mas",
- "Jorge Gonzalez",
- "Jörgen Scheibengruber",
- "Jos Dehaes",
- "Josep Puigdemont Casamajó",
- "Josselin Mouette",
- "Jovan Naumovski",
- "JP Rosevear",
- "Juan Manuel García Molina",
- "Juan Pizarro",
- "Jukka Zitting",
- "Jules Colding",
- "Julian Missig",
- "Julien Puydt",
- "Julio M. Merino Vidal",
- "Juraj Kubelka",
- "Jürg Billeter",
- "Justina Klingaitė",
- "Kai Lahmann",
- "Kang Jeong-Hee",
- "Karl Eichwalder",
- "Karl Relton",
- "Karsten Bräckelmann",
- "Kaushal Kumar",
- "Keith Packard",
- "Keld Simonsen",
- "Kenneth Christiansen",
- "Kenneth Nielsen",
- "Kenneth Rohde Christiansen",
- "Kenny Graunke",
- "Keshav Upadhyaya",
- "Kevin Breit",
- "Kevin Piche",
- "Kevin Vandersloot",
- "Khasim Shaheed",
- "Kidd Wang",
- "Kjartan Maraas",
- "Krishnan R",
- "Kostas Papadimas",
- "Krishna Babu K",
- "Krisztian Pifko",
- "Kyle Ambroff",
- "Larry Ewing",
- "Laszlo Dvornik",
- "Laszlo (Laca) Peter",
- "Laurent Dhima",
- "Lauris Kaplinski",
- "Leonardo Ferreira Fontenelle",
- "Leonid Kanter",
- "Leon Zhang",
- "Li Yuan",
- "Loïc Minier",
- "Lorenzo Gil Sanchez",
- "Luca Ferretti",
- "Lucas Rocha",
- "Lucian Langa",
- "Lucky Wankhede",
- "Luis Villa",
- "Lukas Novotny",
- "Lutz M",
- "Maciej Piechotka",
- "Maciej Stachowiak",
- "Makuchaku",
- "Malcolm Tredinnick",
- "Manuel A. Fernández Montecelo",
- "Manuel Borchers",
- "Marcel Telka",
- "Marco Ciampa",
- "Marco Pesenti Gritti",
- "Marius Andreiana",
- "Marius Vollmer",
- "Mark Crichton",
- "Mark G. Adams",
- "Mark Gordon",
- "Mark McLoughlin",
- "Mark Moulder",
- "Mark Tearle",
- "Martha Burke",
- "Martin Baulig",
- "Martin Hicks",
- "Martin Meyer",
- "Martin Norbäck",
- "Martin Willemoes Hansen",
- "Martyn Russell",
- "Masahiro Sakai",
- "Matej Urbančič",
- "Mathieu Lacage",
- "Matias Mutchinick",
- "Matic Žgur",
- "Matt Bissiri",
- "Matt Brown",
- "Matthew Barnes",
- "Matthew Daniel",
- "Matthew Hall",
- "Matthew Loper",
- "Matthew Wilson",
- "Matthias Braun",
- "Matthias Clasen",
- "Matthias Warkus",
- "Matt Loper",
- "Matt Martin",
- "Matt McCutchen",
- "Matt Wilson",
- "Max Horn",
- "Maxim Dziumanenko",
- "Maxx Cao",
- "Mayank Jain",
- "Meelad Zakaria",
- "Meilof Veeningen",
- "Mendel Mobach",
- "Mengjie Yu",
- "Metin Amiroff",
- "Michael Granger",
- "Michael M. Morrison",
- "Michael MacDonald",
- "Michael Meeks",
- "Michael Monreal",
- "Michael Terry",
- "Michael Zucchi",
- "Michal Bukovjan",
- "Michel Daenzer",
- "Miguel Angel Lopez Hernandez",
- "Miguel de Icaza",
- "Mikael Hallendal",
- "Mikael Nilsson",
- "Mike Castle",
- "Mike Kestner",
- "Mike McEwan",
- "Mikhail Zabaluev",
- "Milan Crha",
- "Miles Lane",
- "Miloslav Trmač",
- "MIMOS Open Source Development Group",
- "Mohammad Damt",
- "Moritz Mertinkat",
- "Morten Welinder",
- "Mubeen Jukaku",
- "Mugurel Tudor",
- "Murray Cumming",
- "M Victor Aloysius J",
- "Naba Kumar",
- "Nagappan Alagappan",
- "Nancy Cai",
- "Naresh N",
- "Nat Friedman",
- "Nathan Owens",
- "Nguyễn Thái Ngọc Duy",
- "Nicel KM",
- "Nicholas J Kreucher",
- "Nicholas Miell",
- "Nickolay V. Shmyrev",
- "Nick Sukharev",
- "Nike Gerdts",
- "Nikos Charonitakis",
- "Noel",
- "Nuno Ferreira",
- "Nyall Dawson",
- "Og Maciel",
- "Ole Laursen",
- "Ondrej Jirman",
- "Oswald Rodrigues",
- "Owen Taylor",
- "Øystein Gisnås",
- "Pablo Gonzalo del Campo",
- "Pablo Saratxaga",
- "Pamplona Hackers",
- "Pauli Virtanen",
- "Paolo Borelli",
- "Paolo Molaro",
- "Parag Goel",
- "Parthasarathi Susarla",
- "Pascal Terjan",
- "Patrick Ohly",
- "Paul Bolle",
- "Paul Duffy",
- "Paul Iadonisi",
- "Paul Lindner",
- "Paul Smith",
- "Paulo Gomes Vanzuita",
- "Pavel Cholakov",
- "Pavel Cisler",
- "Pavel Roskin",
- "Pavithran",
- "Pawan Chitrakar",
- "Pedro Villavicencio",
- "Pema Geyleg",
- "Peteris Krisjanis",
- "Peter Bach",
- "Peter Pouliot",
- "Peter Teichman",
- "Peter Williams",
- "Petr Kovar",
- "Petta Pietikainen",
- "Phil Goembel",
- "Philipp Kerling",
- "Philip Van Hoof",
- "Philip Withnall",
- "Philip Zhao",
- "Poornima Nayak",
- "Pramod",
- "Prasad Kandepu",
- "Pratik V. Parikh",
- "Praveen Arimbrathodiyil",
- "Praveen Kumar",
- "Priit Laes",
- "Priyanshu Raj",
- "P S Chakravarthi",
- "Radek Doulik",
- "Raghavendran R",
- "Rahul Bhalerao",
- "Raivis Dejus",
- "Raja R Harinath",
- "Rajeev Ramanathan",
- "Rajesh Ranjan",
- "Rakesh k.g",
- "Ramiro Estrugo",
- "Ranjan Somani",
- "Raphael Higino",
- "Ray Strode",
- "Reinout van Schouwen",
- "Rhys Jones",
- "Ricardo Markiewicz",
- "Richard Boulton",
- "Richard Hult",
- "Richard Li",
- "Rob Bradford",
- "Robert-André Mauchin",
- "Robert Brady",
- "Robert Sedak",
- "Robin Slomkowski",
- "Rodney Dawes",
- "Rodrigo Moya",
- "Roger Zauner",
- "Rohini S",
- "Roland Illig",
- "Ronald Kuetemeier",
- "Roozbeh Pournader",
- "Roshan Kumar Singh",
- "Ross Burton",
- "Rostislav Raykov",
- "Rouslan Solomakhin",
- "Roy-Magne Mo",
- "Runa Bhattacharjee",
- "Russell Steinthal",
- "Russian team",
- "Rusty Conover",
- "Ryan P. Skadberg",
- "Sam Creasey",
- "Sami Pesonen",
- "Samúel Jón Gunnarsson",
- "Sam Yang",
- "Sankar P",
- "Sanlig Badral",
- "Sanshao Jiang",
- "S.Antony Vincent Pandian",
- "Sarfraaz Ahmed",
- "Satoru SATOH",
- "Sayamindu Dasgupta",
- "S. Caglar Onur",
- "Sean Atkinson",
- "Seán de Búrca",
- "Sean Gao",
- "Sebastian Rittau",
- "Sebastian Wilhelmi",
- "Sebastien Bacher",
- "Sergey Panov",
- "Sergio Villar Senín",
- "Seth Alves",
- "Seth Nickell",
- "Shakti Sen",
- "Shankar Prasad",
- "Shi Pu",
- "Shilpa C",
- "Shree Krishnan",
- "Shreyas Srinivasan",
- "Shuai Liu",
- "Sigurd Gartmann",
- "Simon Zheng",
- "Simos Xenitellis",
- "Sitic Vulnerability Advisory",
- "Sivaiah Nallagatla",
- "Slobodan D. Sredojevic",
- "S N Tejasvi",
- "Spiros Papadimitriou",
- "Srinivasa Ragavan",
- "Stanislav Brabec",
- "Stanislav Slusny",
- "Stanislav Visnovsky",
- "Stéphane Raimbault",
- "Stephen Cook",
- "Steve Murphy",
- "Steven Zhang",
- "Stuart Parmenter",
- "Subhransu Behera",
- "Subodh Soni",
- "Suman Manjunath",
- "Sunil Mohan Adapa",
- "Supranee Thirawatthanasuk",
- "Suresh Chandrasekharan",
- "Sushma Rai",
- "Sven Herzberg",
- "Sweta Kothari",
- "Szabolcs Ban",
- "Takao Fujiwara",
- "Takayuki Kusano",
- "Takeshi Aihana",
- "Takuo Kitame",
- "Tambet Ingo",
- "Taylor Hayward",
- "Ted Percival",
- "Telsa Gwynne",
- "Terance Sola",
- "Theppitak Karoonboonyanan",
- "Thierry Moisan",
- "Thierry Randrianiriana",
- "Thomas Cataldo",
- "Thomas Klausner",
- "Thomas Mirlacher",
- "Thouis R. Jones",
- "Tiago Antao",
- "Timo Jyrinki",
- "Timur Bakeyev",
- "Tim Wo",
- "Tim Yamin",
- "Timo Hoenig",
- "Timo Sirainen",
- "Timothy Lee",
- "Timur Bakeyev",
- "Tino Meinen",
- "Tobias Mueller",
- "Tõivo Leedjärv",
- "Tom Tromey",
- "Tomas Ogren",
- "Tomasz Kłoczko",
- "Tomislav Vujec",
- "Tommi Komulainen",
- "Tommi Vainikainen",
- "Tony Tsui",
- "Tor Lillqvist",
- "Trent Lloyd",
- "Tristan Tarrant",
- "Tuomas J. Lukka",
- "Tuomas Kuosmanen",
- "Udomsak Chundang",
- "Ulrich Neumann",
- "Umeshtej",
- "Umesh Tiwari",
- "Ushveen Kaur",
- "Vadim Strizhevsky",
- "Valek Filippov",
- "Vandana Shenoy .B",
- "Vardhman Jain",
- "Vasiliy Faronov",
- "Veerapuram Varadhan",
- "Vincent Carriere",
- "Vincent Noel",
- "Vincent Renardias",
- "Vincent Untz",
- "Vincent van Adrighem",
- "Viren.L",
- "Vivek Jain",
- "Vladimer Sichinava",
- "Vladimir Petkov",
- "Vladimir Vukicevic",
- "Vladimir Melo",
- "V Ravi Kumar Raju",
- "Wadim Dziedzic",
- "Wang Jian",
- "Wang Li",
- "Wang Xin",
- "Washington Lins",
- "Wayne Davis",
- "William Jon McCann",
- "Woodman Tuen",
- "Wouter Bolsterlee",
- "Xan Lopez",
- "Xavier Conde Rueda",
- "Xiurong Simon Zheng",
- "Yair Hershkovitz",
- "Yanko Kaneti",
- "Yannig Marchegay",
- "Yavor Doganov",
- "Yi Jin",
- "Yong Sun",
- "Yuedong Du",
- "Yukihiro Nakai",
- "Yu Mengjie",
- "Yuri Pankov",
- "Yuri Syrota",
- "Yuriy Penkin",
- "Zach Frey",
- "Zan Lynx",
- "Zbigniew Chyla",
- "Zhe Su",
- "Zipeco",
- "Žygimantas Beručka",
- NULL
-};
-
-static const gchar *documentors[] = {
- "Aaron Weber",
- "Binika Preet",
- "Dan Winship",
- "David Trowbridge",
- "Jessica Prabhakar",
- "JP Rosevear",
- "Radhika Nair",
- NULL
-};
-
-static void
-command_about (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- gchar *translator_credits;
-
- /* The translator-credits string is for translators to list
- * per-language credits for translation, displayed in the
- * about dialog. */
- translator_credits = _("translator-credits");
- if (strcmp (translator_credits, "translator-credits") == 0)
- translator_credits = NULL;
-
- gtk_show_about_dialog (
- GTK_WINDOW (window),
- "program-name", "Evolution",
- "version", VERSION,
- "copyright", EVOLUTION_COPYRIGHT,
- "comments", _("Groupware Suite"),
- "website", EVOLUTION_WEBSITE,
- "website-label", _("Evolution Website"),
- "authors", authors,
- "documenters", documentors,
- "translator-credits", translator_credits,
- "logo-icon-name", "evolution",
- NULL);
-}
-
-static void
-command_open_faq (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- const gchar *uri;
-
- uri = "http://www.go-evolution.org/FAQ";
- e_show_uri (GTK_WINDOW (window), uri);
-}
-
-static void
-command_quick_reference (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- gchar *quickref;
- const gchar * const *language_names;
-
- language_names = g_get_language_names ();
- while (*language_names != NULL) {
- const gchar *lang = *language_names++;
-
- /* This has to be a valid language AND a language with
- * no encoding postfix. The language will come up without
- * encoding next */
- if (lang == NULL || strchr (lang, '.') != NULL)
- continue;
-
- quickref = g_build_filename (EVOLUTION_HELPDIR, "quickref", lang, "quickref.pdf", NULL);
- if (g_file_test (quickref, G_FILE_TEST_EXISTS)) {
- GFile *file = g_file_new_for_path (quickref);
-
- if (file) {
- GError *error = NULL;
- gchar *uri = g_file_get_uri (file);
-
- g_app_info_launch_default_for_uri (uri, NULL, &error);
-
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_object_unref (file);
- g_free (uri);
- }
-
- g_free (quickref);
- return;
- }
-
- g_free (quickref);
- }
-}
-
-static void
-command_work_offline (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- EShell *shell;
-
- shell = e_shell_window_peek_shell (window);
- e_shell_set_line_status (shell, GNOME_Evolution_USER_OFFLINE);
-}
-
-static void
-command_work_online (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- EShell *shell;
-
- shell = e_shell_window_peek_shell (window);
- e_shell_set_line_status (shell, GNOME_Evolution_USER_ONLINE);
-}
-
-static void
-command_open_new_window (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_create_window (e_shell_window_peek_shell (window),
- e_shell_window_peek_current_component_id (window),
- window);
-}
-
-/* Actions menu. */
-
-static void
-command_send_receive (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_send_receive (e_shell_window_peek_shell (window));
-}
-
-static void
-command_forget_passwords (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *path)
-{
- if (e_error_run (NULL, "shell:forget-passwords", NULL) == GTK_RESPONSE_OK)
- e_passwords_forget_passwords();
-}
-
-/* Tools menu. */
-
-static void
-command_settings (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_window_show_settings (window);
-}
-
-static void
-command_pilot_settings (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- launch_pilot_settings ();
-}
-
-static BonoboUIVerb file_verbs [] = {
- BONOBO_UI_VERB ("FileImporter", (BonoboUIVerbFn) command_import),
- BONOBO_UI_VERB ("FilePageSetup", (BonoboUIVerbFn) command_page_setup),
- BONOBO_UI_VERB ("FileClose", (BonoboUIVerbFn) command_close),
- BONOBO_UI_VERB ("FileExit", (BonoboUIVerbFn) command_quit),
-
- BONOBO_UI_VERB ("WorkOffline", (BonoboUIVerbFn) command_work_offline),
- BONOBO_UI_VERB ("WorkOnline", (BonoboUIVerbFn) command_work_online),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb new_verbs [] = {
- BONOBO_UI_VERB ("OpenNewWindow", (BonoboUIVerbFn) command_open_new_window),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb actions_verbs[] = {
- BONOBO_UI_VERB ("SendReceive", (BonoboUIVerbFn) command_send_receive),
- BONOBO_UI_VERB ("ForgetPasswords", command_forget_passwords),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb tools_verbs[] = {
- BONOBO_UI_VERB ("Settings", (BonoboUIVerbFn) command_settings),
- BONOBO_UI_VERB ("PilotSettings", (BonoboUIVerbFn) command_pilot_settings),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb help_verbs [] = {
- BONOBO_UI_VERB ("QuickReference", (BonoboUIVerbFn) command_quick_reference),
- BONOBO_UI_VERB ("HelpOpenFAQ", (BonoboUIVerbFn) command_open_faq),
- BONOBO_UI_VERB ("HelpSubmitBug", (BonoboUIVerbFn) command_submit_bug),
- BONOBO_UI_VERB ("HelpAbout", (BonoboUIVerbFn) command_about),
-
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/Toolbar/SendReceive", "mail-send-receive", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/menu/File/OpenNewWindow", "window-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/SendReceive", "mail-send-receive", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/FileImporter", "stock_mail-import", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/Print/FilePageSetup", "stock_print-setup", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/ToggleOffline", "stock_disconnect", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/FileClose", "window-close", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/FileExit", "application-exit", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/Edit/Settings", "preferences-desktop", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/Help/HelpOpenFAQ", "help-faq", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP_END
-};
-
-static EPixmap offline_pixmaps [] = {
- E_PIXMAP ("/menu/File/ToggleOffline", "stock_disconnect", GTK_ICON_SIZE_MENU),
- E_PIXMAP_END
-};
-
-static EPixmap online_pixmaps [] = {
- E_PIXMAP ("/menu/File/ToggleOffline", "stock_connect", GTK_ICON_SIZE_MENU),
- E_PIXMAP_END
-};
-
-/* The Work Online / Work Offline menu item. */
-
-static void
-update_offline_menu_item (EShellWindow *shell_window,
- EShellLineStatus line_status)
-{
- BonoboUIComponent *ui_component;
-
- ui_component = e_shell_window_peek_bonobo_ui_component (shell_window);
-
- switch (line_status) {
- case E_SHELL_LINE_STATUS_OFFLINE:
- case E_SHELL_LINE_STATUS_FORCED_OFFLINE:
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "label", _("_Work Online"), NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "verb", "WorkOnline", NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/commands/ToggleOffline",
- "sensitive", "1", NULL);
- e_pixmaps_update (ui_component, online_pixmaps);
- break;
-
- case E_SHELL_LINE_STATUS_ONLINE:
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "label", _("_Work Offline"), NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "verb", "WorkOffline", NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/commands/ToggleOffline",
- "sensitive", "1", NULL);
- e_pixmaps_update (ui_component, offline_pixmaps);
- break;
-
- case E_SHELL_LINE_STATUS_GOING_OFFLINE:
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "label", _("Work Offline"), NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "verb", "WorkOffline", NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/commands/ToggleOffline",
- "sensitive", "0", NULL);
- e_pixmaps_update (ui_component, offline_pixmaps);
- break;
-
- default:
- g_return_if_reached();
- }
-}
-
-static void
-shell_line_status_changed_cb (EShell *shell,
- EShellLineStatus new_status,
- EShellWindow *shell_window)
-{
- update_offline_menu_item (shell_window, new_status);
-}
-
-static void
-view_buttons_icontext_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_BOTH);
-}
-
-static void
-view_buttons_icon_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_ICON);
-}
-
-static void
-view_buttons_text_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_TEXT);
-}
-
-static void
-view_buttons_toolbar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_TOOLBAR);
-}
-
-static void
-view_buttons_hide_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
- gboolean is_visible;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
-
- is_visible = state[0] == '0';
-
- e_sidebar_set_show_buttons (sidebar, is_visible);
-}
-
-static void
-view_toolbar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- gboolean is_visible;
-
- is_visible = state[0] == '1';
-
- bonobo_ui_component_set_prop (ui_component, "/Toolbar",
- "hidden", is_visible ? "0" : "1", NULL);
-}
-
-static void
-view_statusbar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- GtkWidget *status_bar = e_shell_window_peek_statusbar (shell_window);
- gboolean is_visible;
- GConfClient *gconf_client;
-
- is_visible = state[0] == '1';
- if (is_visible)
- gtk_widget_show (status_bar);
- else
- gtk_widget_hide (status_bar);
- gconf_client = gconf_client_get_default ();
- gconf_client_set_bool (gconf_client,"/apps/evolution/shell/view_defaults/statusbar_visible", is_visible, NULL);
- g_object_unref (gconf_client);
-}
-
-static void
-view_sidebar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- GtkWidget *side_bar = GTK_WIDGET(e_shell_window_peek_sidebar (shell_window));
- gboolean is_visible;
- GConfClient *gconf_client;
-
- is_visible = state[0] == '1';
- if (is_visible)
- gtk_widget_show (side_bar);
- else
- gtk_widget_hide (side_bar);
- gconf_client = gconf_client_get_default ();
- gconf_client_set_bool (gconf_client_get_default (),"/apps/evolution/shell/view_defaults/sidebar_visible", is_visible, NULL);
- g_object_unref (gconf_client);
-}
-
-/* Public API. */
-
-void
-e_shell_window_commands_setup (EShellWindow *shell_window)
-{
- BonoboUIComponent *uic;
- EShell *shell;
-
- g_return_if_fail (shell_window != NULL);
- g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
-
- uic = e_shell_window_peek_bonobo_ui_component (shell_window);
- shell = e_shell_window_peek_shell (shell_window);
-
- bonobo_ui_component_add_verb_list_with_data (uic, file_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, new_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, actions_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, tools_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, help_verbs, shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsIconText",
- (BonoboUIListenerFn)view_buttons_icontext_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsIcon",
- (BonoboUIListenerFn)view_buttons_icon_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsText",
- (BonoboUIListenerFn)view_buttons_text_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsToolbar",
- (BonoboUIListenerFn)view_buttons_toolbar_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsHide",
- (BonoboUIListenerFn)view_buttons_hide_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewToolbar",
- (BonoboUIListenerFn)view_toolbar_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewStatusBar",
- (BonoboUIListenerFn)view_statusbar_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewSideBar",
- (BonoboUIListenerFn)view_sidebar_item_toggled_handler,
- (gpointer)shell_window);
-
- e_pixmaps_update (uic, pixmaps);
-
- /* Set up the work online / work offline menu item. */
- g_signal_connect_object (shell, "line_status_changed",
- G_CALLBACK (shell_line_status_changed_cb), shell_window, 0);
- update_offline_menu_item (shell_window, e_shell_get_line_status (shell));
-}
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
new file mode 100644
index 0000000000..6ee997ddef
--- /dev/null
+++ b/shell/e-shell-window-private.c
@@ -0,0 +1,602 @@
+/*
+ * e-shell-window-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-window-private.h"
+
+static void
+shell_window_save_switcher_style_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ GConfClient *client;
+ GtkToolbarStyle style;
+ const gchar *key;
+ const gchar *string;
+ GError *error = NULL;
+
+ shell = e_shell_window_get_shell (shell_window);
+ client = e_shell_get_gconf_client (shell);
+
+ style = gtk_radio_action_get_current_value (action);
+ key = "/apps/evolution/shell/view_defaults/buttons_style";
+
+ switch (style) {
+ case GTK_TOOLBAR_ICONS:
+ string = "icons";
+ break;
+
+ case GTK_TOOLBAR_TEXT:
+ string = "text";
+ break;
+
+ case GTK_TOOLBAR_BOTH:
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ string = "both";
+ break;
+
+ default:
+ string = "toolbar";
+ break;
+ }
+
+ if (!gconf_client_set_string (client, key, string, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+shell_window_init_switcher_style (EShellWindow *shell_window)
+{
+ EShell *shell;
+ GtkAction *action;
+ GConfClient *client;
+ GtkToolbarStyle style;
+ const gchar *key;
+ gchar *string;
+ GError *error = NULL;
+
+ /* XXX GConfBridge doesn't let you convert between numeric properties
+ * and string keys, so we have to create the binding manually. */
+
+ shell = e_shell_window_get_shell (shell_window);
+ client = e_shell_get_gconf_client (shell);
+
+ action = ACTION (SWITCHER_STYLE_ICONS);
+ key = "/apps/evolution/shell/view_defaults/buttons_style";
+ string = gconf_client_get_string (client, key, &error);
+
+ if (string != NULL) {
+ if (strcmp (string, "icons") == 0)
+ style = GTK_TOOLBAR_ICONS;
+ else if (strcmp (string, "text") == 0)
+ style = GTK_TOOLBAR_TEXT;
+ else if (strcmp (string, "both") == 0)
+ style = GTK_TOOLBAR_BOTH_HORIZ;
+ else
+ style = -1;
+
+ gtk_radio_action_set_current_value (
+ GTK_RADIO_ACTION (action), style);
+ }
+
+ g_signal_connect (
+ action, "changed",
+ G_CALLBACK (shell_window_save_switcher_style_cb),
+ shell_window);
+}
+
+static void
+shell_window_menu_item_select_cb (EShellWindow *shell_window,
+ GtkWidget *menu_item)
+{
+ GtkAction *action;
+ GtkLabel *label;
+ gchar *tooltip = NULL;
+
+ action = g_object_get_data (G_OBJECT (menu_item), "action");
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ g_object_get (action, "tooltip", &tooltip, NULL);
+
+ if (tooltip == NULL)
+ return;
+
+ label = GTK_LABEL (shell_window->priv->tooltip_label);
+ gtk_label_set_text (label, tooltip);
+ g_free (tooltip);
+
+ gtk_widget_show (shell_window->priv->tooltip_label);
+ gtk_widget_hide (shell_window->priv->status_notebook);
+}
+
+static void
+shell_window_menu_item_deselect_cb (EShellWindow *shell_window)
+{
+ gtk_widget_hide (shell_window->priv->tooltip_label);
+ gtk_widget_show (shell_window->priv->status_notebook);
+}
+
+static void
+shell_window_connect_proxy_cb (EShellWindow *shell_window,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ if (!GTK_IS_MENU_ITEM (proxy))
+ return;
+
+ g_object_set_data_full (
+ G_OBJECT (proxy),
+ "action", g_object_ref (action),
+ (GDestroyNotify) g_object_unref);
+
+ g_signal_connect_swapped (
+ proxy, "select",
+ G_CALLBACK (shell_window_menu_item_select_cb),
+ shell_window);
+
+ g_signal_connect_swapped (
+ proxy, "deselect",
+ G_CALLBACK (shell_window_menu_item_deselect_cb),
+ shell_window);
+}
+
+static void
+shell_window_online_button_clicked_cb (EOnlineButton *button,
+ EShellWindow *shell_window)
+{
+ if (e_online_button_get_online (button))
+ gtk_action_activate (ACTION (WORK_OFFLINE));
+ else
+ gtk_action_activate (ACTION (WORK_ONLINE));
+}
+
+void
+e_shell_window_private_init (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+ GHashTable *loaded_views;
+ GArray *signal_handler_ids;
+ GtkAccelGroup *accel_group;
+ GtkToolItem *item;
+ GtkWidget *container;
+ GtkWidget *widget;
+ guint merge_id;
+ gint height;
+
+ loaded_views = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ signal_handler_ids = g_array_new (FALSE, FALSE, sizeof (gulong));
+
+ priv->ui_manager = gtk_ui_manager_new ();
+ priv->loaded_views = loaded_views;
+ priv->active_view = "unknown";
+ priv->signal_handler_ids = signal_handler_ids;
+
+ e_shell_window_add_action_group (shell_window, "shell");
+ e_shell_window_add_action_group (shell_window, "gal-view");
+ e_shell_window_add_action_group (shell_window, "new-item");
+ e_shell_window_add_action_group (shell_window, "new-source");
+ e_shell_window_add_action_group (shell_window, "custom-rules");
+ e_shell_window_add_action_group (shell_window, "switcher");
+ e_shell_window_add_action_group (shell_window, "lockdown-application-handlers");
+ e_shell_window_add_action_group (shell_window, "lockdown-printing");
+ e_shell_window_add_action_group (shell_window, "lockdown-print-setup");
+ e_shell_window_add_action_group (shell_window, "lockdown-save-to-disk");
+
+ merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
+ priv->custom_rule_merge_id = merge_id;
+
+ merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
+ priv->gal_view_merge_id = merge_id;
+
+ gtk_window_set_title (GTK_WINDOW (shell_window), _("Evolution"));
+
+ e_shell_window_actions_init (shell_window);
+
+ accel_group = gtk_ui_manager_get_accel_group (priv->ui_manager);
+ gtk_window_add_accel_group (GTK_WINDOW (shell_window), accel_group);
+
+ g_signal_connect_swapped (
+ priv->ui_manager, "connect-proxy",
+ G_CALLBACK (shell_window_connect_proxy_cb), shell_window);
+
+ /* Construct window widgets. */
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (shell_window), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_shell_window_get_managed_widget (
+ shell_window, "/main-menu");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_menu = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = e_shell_window_get_managed_widget (
+ shell_window, "/main-toolbar");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* XXX Having this separator in the UI definition doesn't work
+ * because GtkUIManager is unaware of the "New" button, so
+ * it makes the separator invisible. One possibility is to
+ * define a GtkAction subclass for which create_tool_item()
+ * returns an EMenuToolButton. Then both this separator
+ * and the "New" button could be added to the UI definition.
+ * Tempting, but the "New" button and its dynamically
+ * generated menu is already a complex beast, and I'm not
+ * convinced having it proxy some new type of GtkAction
+ * is worth the extra effort. */
+ item = gtk_separator_tool_item_new ();
+ gtk_toolbar_insert (GTK_TOOLBAR (widget), item, 0);
+ gtk_widget_show (GTK_WIDGET (item));
+
+ item = e_menu_tool_button_new (_("New"));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
+ gtk_widget_add_accelerator (
+ GTK_WIDGET (item), "clicked",
+ gtk_ui_manager_get_accel_group (priv->ui_manager),
+ GDK_N, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget), item, 0);
+ priv->menu_tool_button = g_object_ref (item);
+ gtk_widget_show (GTK_WIDGET (item));
+
+ widget = gtk_hpaned_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->content_pane = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->status_area = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Make the status area as large as the task bar. */
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
+ gtk_widget_set_size_request (widget, -1, (height * 2) + 6);
+
+ container = priv->content_pane;
+
+ widget = e_shell_switcher_new ();
+ gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, FALSE);
+ priv->switcher = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->content_notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->switcher;
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->sidebar_notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->status_area;
+
+ widget = e_online_button_new ();
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (shell_window_online_button_clicked_cb),
+ shell_window);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
+ priv->online_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->tooltip_label = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->status_notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+void
+e_shell_window_private_constructed (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ GConfBridge *bridge;
+ GtkAction *action;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GObject *object;
+ const gchar *key;
+ const gchar *id;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_watch_window (shell, GTK_WINDOW (shell_window));
+
+ /* Create the switcher actions before we set the initial
+ * shell view, because the shell view relies on them for
+ * default settings during construction. */
+ e_shell_window_create_switcher_actions (shell_window);
+
+ /* Support lockdown. */
+
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-printing",
+ G_OBJECT (action_group), "sensitive");
+
+ action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-print-setup",
+ G_OBJECT (action_group), "sensitive");
+
+ action_group = ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-save-to-disk",
+ G_OBJECT (action_group), "sensitive");
+
+ /* Bind GObject properties to GObject properties. */
+
+ action = ACTION (SEND_RECEIVE);
+
+ e_binding_new (
+ G_OBJECT (shell), "online",
+ G_OBJECT (action), "sensitive");
+
+ action = ACTION (WORK_OFFLINE);
+
+ e_binding_new (
+ G_OBJECT (shell), "online",
+ G_OBJECT (action), "visible");
+
+ e_binding_new (
+ G_OBJECT (shell), "network-available",
+ G_OBJECT (action), "sensitive");
+
+ action = ACTION (WORK_ONLINE);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell), "online",
+ G_OBJECT (action), "visible");
+
+ e_binding_new (
+ G_OBJECT (shell), "network-available",
+ G_OBJECT (action), "sensitive");
+
+ e_binding_new (
+ G_OBJECT (shell), "online",
+ G_OBJECT (priv->online_button), "online");
+
+ e_binding_new (
+ G_OBJECT (shell), "network-available",
+ G_OBJECT (priv->online_button), "sensitive");
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ key = "/apps/evolution/shell/view_defaults/window";
+ gconf_bridge_bind_window (
+ bridge, key, GTK_WINDOW (shell_window), TRUE, TRUE);
+
+ object = G_OBJECT (shell_window);
+ key = "/apps/evolution/shell/view_defaults/component_id";
+ gconf_bridge_bind_property (bridge, key, object, "active-view");
+
+ object = G_OBJECT (priv->content_pane);
+ key = "/apps/evolution/shell/view_defaults/folder_bar/width";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "position");
+
+ object = G_OBJECT (ACTION (SHOW_SIDEBAR));
+ key = "/apps/evolution/shell/view_defaults/sidebar_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (SHOW_STATUSBAR));
+ key = "/apps/evolution/shell/view_defaults/statusbar_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (SHOW_SWITCHER));
+ key = "/apps/evolution/shell/view_defaults/buttons_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (SHOW_TOOLBAR));
+ key = "/apps/evolution/shell/view_defaults/toolbar_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ shell_window_init_switcher_style (shell_window);
+
+ id = "org.gnome.evolution.shell";
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ e_plugin_ui_register_manager (ui_manager, id, shell_window);
+ e_plugin_ui_enable_manager (ui_manager, id);
+}
+
+void
+e_shell_window_private_dispose (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+
+ /* Need to disconnect handlers before we unref the shell. */
+ if (priv->signal_handler_ids != NULL) {
+ GArray *array = priv->signal_handler_ids;
+ gulong handler_id;
+ guint ii;
+
+ for (ii = 0; ii < array->len; ii++) {
+ handler_id = g_array_index (array, gulong, ii);
+ g_signal_handler_disconnect (priv->shell, handler_id);
+ }
+
+ g_array_free (array, TRUE);
+ priv->signal_handler_ids = NULL;
+ }
+
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell), &priv->shell);
+ priv->shell = NULL;
+ }
+
+ DISPOSE (priv->ui_manager);
+
+ g_hash_table_remove_all (priv->loaded_views);
+
+ DISPOSE (priv->main_menu);
+ DISPOSE (priv->main_toolbar);
+ DISPOSE (priv->menu_tool_button);
+ DISPOSE (priv->content_pane);
+ DISPOSE (priv->content_notebook);
+ DISPOSE (priv->sidebar_notebook);
+ DISPOSE (priv->switcher);
+ DISPOSE (priv->status_area);
+ DISPOSE (priv->online_button);
+ DISPOSE (priv->tooltip_label);
+ DISPOSE (priv->status_notebook);
+
+ priv->destroyed = TRUE;
+}
+
+void
+e_shell_window_private_finalize (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+
+ g_hash_table_destroy (priv->loaded_views);
+}
+
+void
+e_shell_window_switch_to_view (EShellWindow *shell_window,
+ const gchar *view_name)
+{
+ GtkNotebook *notebook;
+ EShellView *shell_view;
+ gint page_num;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (view_name != NULL);
+
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+
+ page_num = e_shell_view_get_page_num (shell_view);
+ g_return_if_fail (page_num >= 0);
+
+ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+ gtk_notebook_set_current_page (notebook, page_num);
+
+ notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
+ gtk_notebook_set_current_page (notebook, page_num);
+
+ notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
+ gtk_notebook_set_current_page (notebook, page_num);
+
+ shell_window->priv->active_view = view_name;
+ g_object_notify (G_OBJECT (shell_window), "active-view");
+
+ e_shell_window_update_icon (shell_window);
+ e_shell_window_update_title (shell_window);
+ e_shell_window_update_new_menu (shell_window);
+ e_shell_window_update_view_menu (shell_window);
+ e_shell_window_update_search_menu (shell_window);
+
+ e_shell_view_update_actions (shell_view);
+}
+
+void
+e_shell_window_update_icon (EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ GtkAction *action;
+ const gchar *view_name;
+ gchar *icon_name = NULL;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+
+ action = e_shell_view_get_action (shell_view);
+ g_object_get (action, "icon-name", &icon_name, NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (shell_window), icon_name);
+ g_free (icon_name);
+}
+
+void
+e_shell_window_update_title (EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ const gchar *view_title;
+ const gchar *view_name;
+ gchar *window_title;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ view_title = e_shell_view_get_title (shell_view);
+
+ /* Translators: This is used for the main window title. */
+ window_title = g_strdup_printf (_("%s - Evolution"), view_title);
+ gtk_window_set_title (GTK_WINDOW (shell_window), window_title);
+ g_free (window_title);
+}
+
+void
+e_shell_window_update_new_menu (EShellWindow *shell_window)
+{
+ GtkWidget *menu;
+ GtkWidget *widget;
+ const gchar *path;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ /* Update the "File -> New" submenu. */
+ path = "/main-menu/file-menu/new-menu";
+ menu = e_shell_window_create_new_menu (shell_window);
+ widget = e_shell_window_get_managed_widget (shell_window, path);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
+ gtk_widget_show (widget);
+
+ /* Update the "New" menu tool button submenu. */
+ menu = e_shell_window_create_new_menu (shell_window);
+ widget = shell_window->priv->menu_tool_button;
+ gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget), menu);
+}
diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h
new file mode 100644
index 0000000000..5314a3679f
--- /dev/null
+++ b/shell/e-shell-window-private.h
@@ -0,0 +1,128 @@
+/*
+ * e-shell-window-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SHELL_WINDOW_PRIVATE_H
+#define E_SHELL_WINDOW_PRIVATE_H
+
+#include "e-shell-window.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <e-util/e-util.h>
+#include <e-util/e-binding.h>
+#include <e-util/e-plugin-ui.h>
+#include <e-util/gconf-bridge.h>
+#include <widgets/misc/e-menu-tool-button.h>
+#include <widgets/misc/e-online-button.h>
+
+#include <e-shell.h>
+#include <e-shell-content.h>
+#include <e-shell-view.h>
+#include <e-shell-switcher.h>
+#include <e-shell-window-actions.h>
+
+#define E_SHELL_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_WINDOW, EShellWindowPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* Format for switcher action names.
+ * The last part is the shell view name.
+ * (e.g. switch-to-mail, switch-to-calendar) */
+#define SWITCHER_FORMAT "switch-to-%s"
+
+G_BEGIN_DECLS
+
+struct _EShellWindowPrivate {
+
+ gpointer shell; /* weak pointer */
+
+ /*** UI Management ***/
+
+ GtkUIManager *ui_manager;
+ guint custom_rule_merge_id;
+ guint gal_view_merge_id;
+
+ /*** Shell Views ***/
+
+ GHashTable *loaded_views;
+ const gchar *active_view;
+
+ /*** Widgetry ***/
+
+ GtkWidget *main_menu;
+ GtkWidget *main_toolbar;
+ GtkWidget *menu_tool_button;
+ GtkWidget *content_pane;
+ GtkWidget *content_notebook;
+ GtkWidget *sidebar_notebook;
+ GtkWidget *switcher;
+ GtkWidget *status_area;
+ GtkWidget *online_button;
+ GtkWidget *tooltip_label;
+ GtkWidget *status_notebook;
+
+ /* Miscellaneous */
+
+ /* Shell signal handlers. */
+ GArray *signal_handler_ids;
+
+ guint destroyed : 1; /* XXX Do we still need this? */
+ guint safe_mode : 1;
+};
+
+void e_shell_window_private_init (EShellWindow *shell_window);
+void e_shell_window_private_constructed
+ (EShellWindow *shell_window);
+void e_shell_window_private_dispose (EShellWindow *shell_window);
+void e_shell_window_private_finalize (EShellWindow *shell_window);
+
+/* Private Utilities */
+
+void e_shell_window_actions_init (EShellWindow *shell_window);
+void e_shell_window_switch_to_view (EShellWindow *shell_window,
+ const gchar *view_name);
+GtkWidget * e_shell_window_create_new_menu (EShellWindow *shell_window);
+void e_shell_window_create_switcher_actions
+ (EShellWindow *shell_window);
+void e_shell_window_update_gal_view (EShellWindow *shell_window);
+void e_shell_window_update_icon (EShellWindow *shell_window);
+void e_shell_window_update_title (EShellWindow *shell_window);
+void e_shell_window_update_new_menu (EShellWindow *shell_window);
+void e_shell_window_update_view_menu (EShellWindow *shell_window);
+void e_shell_window_update_search_menu
+ (EShellWindow *shell_window);
+
+G_END_DECLS
+
+#endif /* E_SHELL_WINDOW_PRIVATE_H */
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 69980dc5c5..19392094ee 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -1,4 +1,6 @@
/*
+ * e-shell-window.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,1248 +15,859 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-shell-window.h"
-#include "e-shell-view.h"
-
-#include "Evolution.h"
-
-#include "e-util/e-util-private.h"
-#include "widgets/misc/e-online-button.h"
-
-#include "e-component-registry.h"
-#include "e-shell-window-commands.h"
-#include "e-sidebar.h"
-#include "es-menu.h"
-#include "es-event.h"
-
-#include <gtk/gtk.h>
-
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-widget.h>
-
-#include <glib/gi18n.h>
+#include "e-shell-window-private.h"
#include <gconf/gconf-client.h>
-#include <string.h>
+#include <e-util/e-plugin-ui.h>
+#include <e-util/e-util-private.h>
-#if defined(NM_SUPPORT) && NM_SUPPORT
-gboolean e_shell_dbus_initialise (EShell *shell);
-#endif
-
-/* A view for each component. These are all created when EShellWindow is
- instantiated, but with the widget pointers to NULL and the page number set
- to -1. When the views are created the first time, the widget pointers as
- well as the notebook page value get set. */
-struct _ComponentView {
- gint button_id;
- gchar *component_id;
- gchar *component_alias;
-
- GNOME_Evolution_ComponentView component_view;
- gchar *title;
-
- GtkWidget *sidebar_widget;
- GtkWidget *view_widget;
- GtkWidget *statusbar_widget;
-
- gint notebook_page_num;
+enum {
+ PROP_0,
+ PROP_ACTIVE_VIEW,
+ PROP_SAFE_MODE,
+ PROP_SHELL,
+ PROP_UI_MANAGER
};
-typedef struct _ComponentView ComponentView;
-
-struct _EShellWindowPrivate {
- union {
- EShell *eshell;
- gpointer pointer;
- } shell;
-
- EShellView *shell_view; /* CORBA wrapper for this, just a placeholder */
-
- /* plugin menu manager */
- ESMenu *menu;
- /* All the ComponentViews. */
- GSList *component_views;
+static gpointer parent_class;
- /* The paned widget for the sidebar and component views */
- GtkWidget *paned;
-
- /* The sidebar. */
- GtkWidget *sidebar;
-
- /* Notebooks used to switch between components. */
- GtkWidget *sidebar_notebook;
- GtkWidget *view_notebook;
- GtkWidget *statusbar_notebook;
-
- /* Bonobo foo. */
- BonoboUIComponent *ui_component;
-
- /* The current view (can be NULL initially). */
- ComponentView *current_view;
-
- /* The status bar widgetry. */
- GtkWidget *status_bar;
- GtkWidget *offline_toggle;
- GtkWidget *menu_hint_label;
+static EShellView *
+shell_window_new_view (EShellBackend *shell_backend,
+ EShellWindow *shell_window)
+{
+ GHashTable *loaded_views;
+ EShellView *shell_view;
+ GtkNotebook *notebook;
+ GtkAction *action;
+ GtkWidget *widget;
+ const gchar *name;
+ gint page_num;
+ GType type;
- /* The timeout for saving the window size */
- guint store_window_gsizeimer;
- gboolean destroyed;
-};
+ name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+ type = E_SHELL_BACKEND_GET_CLASS (shell_backend)->shell_view_type;
-enum {
- COMPONENT_CHANGED,
- LAST_SIGNAL
-};
+ /* First off, start the shell backend. */
+ e_shell_backend_start (shell_backend);
-static guint signals[LAST_SIGNAL] = { 0 };
+ /* Determine the page number for the new shell view. */
+ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+ page_num = gtk_notebook_get_n_pages (notebook);
-G_DEFINE_TYPE (EShellWindow, e_shell_window, BONOBO_TYPE_WINDOW)
+ /* Get the switcher action for this view. */
+ action = e_shell_window_get_shell_view_action (shell_window, name);
-static gboolean store_window_size (GtkWidget* widget);
+ /* Create the shell view. */
+ shell_view = g_object_new (
+ type, "action", action, "page-num",page_num,
+ "shell-window", shell_window, NULL);
-/* ComponentView handling. */
+ /* Register the shell view. */
+ loaded_views = shell_window->priv->loaded_views;
+ g_hash_table_insert (loaded_views, g_strdup (name), shell_view);
-static ComponentView *
-component_view_new (const gchar *id, const gchar *alias, gint button_id)
-{
- ComponentView *view = g_new0 (ComponentView, 1);
+ /* Add pages to the various shell window notebooks. */
- view->component_id = g_strdup (id);
- view->component_alias = g_strdup (alias);
- view->button_id = button_id;
- view->notebook_page_num = -1;
+ /* We can't determine the shell view's page number until after the
+ * shell view is fully initialized because the shell view may load
+ * other shell views during initialization, and those other shell
+ * views will append their widgets to the notebooks before us. */
+ page_num = gtk_notebook_get_n_pages (notebook);
+ e_shell_view_set_page_num (shell_view, page_num);
- return view;
-}
+ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+ widget = GTK_WIDGET (e_shell_view_get_shell_content (shell_view));
+ gtk_notebook_append_page (notebook, widget, NULL);
-static void
-component_view_free (ComponentView *view)
-{
- if (view->component_view) {
- CORBA_Environment ev = { NULL };
+ notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
+ widget = GTK_WIDGET (e_shell_view_get_shell_sidebar (shell_view));
+ gtk_notebook_append_page (notebook, widget, NULL);
- CORBA_Object_release(view->component_view, &ev);
- CORBA_exception_free(&ev);
- }
+ notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
+ widget = GTK_WIDGET (e_shell_view_get_shell_taskbar (shell_view));
+ gtk_notebook_append_page (notebook, widget, NULL);
- g_free (view->component_id);
- g_free (view->component_alias);
- g_free (view->title);
- g_free (view);
-}
+ /* Listen for changes that affect the shell window. */
-static void
-component_view_deactivate (ComponentView *view)
-{
- BonoboControlFrame *view_control_frame;
- BonoboControlFrame *sidebar_control_frame;
+ g_signal_connect_swapped (
+ action, "notify::icon-name",
+ G_CALLBACK (e_shell_window_update_icon), shell_window);
- g_return_if_fail (view->sidebar_widget != NULL);
- g_return_if_fail (view->view_widget != NULL);
+ g_signal_connect_swapped (
+ shell_view, "notify::title",
+ G_CALLBACK (e_shell_window_update_title), shell_window);
- view_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->view_widget));
- bonobo_control_frame_control_deactivate (view_control_frame);
+ g_signal_connect_swapped (
+ shell_view, "notify::view-id",
+ G_CALLBACK (e_shell_window_update_view_menu), shell_window);
- sidebar_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->sidebar_widget));
- bonobo_control_frame_control_deactivate (sidebar_control_frame);
+ return shell_view;
}
static void
-component_view_activate (ComponentView *view)
+shell_window_update_close_action_cb (EShellWindow *shell_window)
{
- BonoboControlFrame *view_control_frame;
- BonoboControlFrame *sidebar_control_frame;
+ EShell *shell;
+ GList *watched_windows;
+ gint n_shell_windows = 0;
- g_return_if_fail (view->sidebar_widget != NULL);
- g_return_if_fail (view->view_widget != NULL);
+ shell = e_shell_window_get_shell (shell_window);
+ watched_windows = e_shell_get_watched_windows (shell);
- view_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->view_widget));
- bonobo_control_frame_control_activate (view_control_frame);
+ /* Count the shell windows. */
+ while (watched_windows != NULL) {
+ if (E_IS_SHELL_WINDOW (watched_windows->data))
+ n_shell_windows++;
+ watched_windows = g_list_next (watched_windows);
+ }
- sidebar_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->sidebar_widget));
- bonobo_control_frame_control_activate (sidebar_control_frame);
+ /* Disable Close Window if there's only one shell window.
+ * Helps prevent users from accidentally quitting. */
+ gtk_action_set_sensitive (ACTION (CLOSE), n_shell_windows > 1);
}
static void
-init_view (EShellWindow *window,
- ComponentView *view)
+shell_window_set_shell (EShellWindow *shell_window,
+ EShell *shell)
{
- EShellWindowPrivate *priv = window->priv;
- EComponentRegistry *registry = e_shell_peek_component_registry (window->priv->shell.eshell);
- GNOME_Evolution_Component component_iface;
- GNOME_Evolution_ComponentView component_view;
- Bonobo_UIContainer container;
- Bonobo_Control sidebar_control;
- Bonobo_Control view_control;
- Bonobo_Control statusbar_control;
- CORBA_boolean select_item;
- CORBA_Environment ev;
- gint sidebar_notebook_page_num;
- gint view_notebook_page_num;
-
- g_return_if_fail (view->view_widget == NULL);
- g_return_if_fail (view->sidebar_widget == NULL);
- g_return_if_fail (view->notebook_page_num == -1);
-
- select_item = !e_shell_get_crash_recovery (priv->shell.eshell);
- e_shell_set_crash_recovery (priv->shell.eshell, FALSE);
-
- CORBA_exception_init (&ev);
-
- /* 1. Activate component. (FIXME: Shouldn't do this here.) */
-
- component_iface = e_component_registry_activate (registry, view->component_id, &ev);
- if (BONOBO_EX (&ev) || component_iface == CORBA_OBJECT_NIL) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot activate component %s: %s", view->component_id, ex_text);
- g_free (ex_text);
- CORBA_exception_free (&ev);
- return;
- }
-
- /* 2. Set up view. */
-
- /* The rest of the code assumes that the component is valid and can create
- controls; if this fails something is really wrong in the component
- (e.g. methods not implemented)... So handle it as if there was no
- component at all. */
-
- component_view = GNOME_Evolution_Component_createView(component_iface, BONOBO_OBJREF(priv->shell_view), select_item, &ev);
- if (component_view == NULL || BONOBO_EX (&ev)) {
- g_warning ("Cannot create view for %s", view->component_id);
- bonobo_object_release_unref (component_iface, NULL);
- CORBA_exception_free (&ev);
- return;
- }
-
- GNOME_Evolution_ComponentView_getControls(component_view, &sidebar_control, &view_control, &statusbar_control, &ev);
- if (BONOBO_EX (&ev)) {
- g_warning ("Cannot create view for %s", view->component_id);
- bonobo_object_release_unref (component_iface, NULL);
- CORBA_exception_free (&ev);
- return;
- }
-
- view->component_view = component_view;
-
- CORBA_exception_free (&ev);
+ GArray *array;
+ gulong handler_id;
- container = bonobo_ui_component_get_container (priv->ui_component);
+ g_return_if_fail (shell_window->priv->shell == NULL);
- view->sidebar_widget = bonobo_widget_new_control_from_objref (sidebar_control, container);
- gtk_widget_show (view->sidebar_widget);
- bonobo_object_release_unref (sidebar_control, NULL);
+ shell_window->priv->shell = shell;
- view->view_widget = bonobo_widget_new_control_from_objref (view_control, container);
- gtk_widget_show (view->view_widget);
- bonobo_object_release_unref (view_control, NULL);
+ g_object_add_weak_pointer (
+ G_OBJECT (shell), &shell_window->priv->shell);
- view->statusbar_widget = bonobo_widget_new_control_from_objref (statusbar_control, container);
- gtk_widget_show (view->statusbar_widget);
- bonobo_object_release_unref (statusbar_control, NULL);
+ /* Need to disconnect these when the window is closing. */
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->sidebar_notebook), view->sidebar_widget, NULL);
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->view_notebook), view->view_widget, NULL);
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->statusbar_notebook), view->statusbar_widget, NULL);
+ array = shell_window->priv->signal_handler_ids;
- sidebar_notebook_page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->sidebar_notebook), view->sidebar_widget);
- view_notebook_page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->view_notebook), view->view_widget);
+ handler_id = g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (shell_window_update_close_action_cb),
+ shell_window);
- /* Since we always add a view page and a sidebar page at the same time... */
- g_return_if_fail (sidebar_notebook_page_num == view_notebook_page_num);
+ g_array_append_val (array, handler_id);
- view->notebook_page_num = view_notebook_page_num;
+ handler_id = g_signal_connect_swapped (
+ shell, "window-destroyed",
+ G_CALLBACK (shell_window_update_close_action_cb),
+ shell_window);
- /* 3. Switch to the new page. */
+ g_array_append_val (array, handler_id);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->view_notebook), view_notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->sidebar_notebook), view_notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->statusbar_notebook), view_notebook_page_num);
-
- if (priv->current_view != NULL)
- component_view_deactivate (priv->current_view);
- priv->current_view = view;
- component_view_activate (view);
-
- bonobo_object_release_unref (component_iface, NULL);
+ g_object_notify (G_OBJECT (shell), "online");
}
static void
-switch_view (EShellWindow *window, ComponentView *component_view)
+shell_window_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EShellWindowPrivate *priv = window->priv;
- GConfClient *gconf_client = gconf_client_get_default ();
- EComponentRegistry *registry = e_shell_peek_component_registry (window->priv->shell.eshell);
- EComponentInfo *info = e_component_registry_peek_info (registry,
- ECR_FIELD_ID,
- component_view->component_id);
- gchar *title;
-
- if (component_view->sidebar_widget == NULL) {
- init_view (window, component_view);
- } else {
- if (priv->current_view != NULL)
- component_view_deactivate (priv->current_view);
- priv->current_view = component_view;
- component_view_activate (component_view);
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->view_notebook), component_view->notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->sidebar_notebook), component_view->notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->statusbar_notebook), component_view->notebook_page_num);
- }
-
- if (component_view->title == NULL) {
- /* To translators: This is the window title and %s is the
- component name. Most translators will want to keep it as is. */
- title = g_strdup_printf (_("%s - Evolution"), info->button_label);
- gtk_window_set_title (GTK_WINDOW (window), title);
- g_free (title);
- } else
- gtk_window_set_title (GTK_WINDOW (window), component_view->title);
-
- if (info->icon_name)
- gtk_window_set_icon_name (GTK_WINDOW (window), info->icon_name);
-
- gconf_client_set_string (gconf_client, "/apps/evolution/shell/view_defaults/component_id",
- (component_view->component_alias != NULL
- ? component_view->component_alias
- : component_view->component_id),
- NULL);
-
- g_object_unref (gconf_client);
-
- /** @Event: Shell component activated or switched to.
- * @Id: component.activated
- * @Target: ESEventTargetComponent
- *
- * This event is emitted whenever the shell successfully activates component
- * view.
- */
- e_event_emit ((EEvent *) es_event_peek (), "component.activated", (EEventTarget *) es_event_target_new_component (es_event_peek (), component_view->component_id));
-
- g_signal_emit (window, signals[COMPONENT_CHANGED], 0);
-}
+ switch (property_id) {
+ case PROP_ACTIVE_VIEW:
+ e_shell_window_set_active_view (
+ E_SHELL_WINDOW (object),
+ g_value_get_string (value));
+ return;
-/* Functions to update the sensitivity of buttons and menu items depending on the status. */
+ case PROP_SAFE_MODE:
+ e_shell_window_set_safe_mode (
+ E_SHELL_WINDOW (object),
+ g_value_get_boolean (value));
+ return;
-static void
-update_offline_toggle_status (EShellWindow *window)
-{
- EShellWindowPrivate *priv;
- GtkWidget *widget;
- const gchar *tooltip;
- gboolean online;
- gboolean sensitive;
- guint32 flags = 0;
- ESMenuTargetShell *t;
-
- priv = window->priv;
-
- switch (e_shell_get_line_status (priv->shell.eshell)) {
- case E_SHELL_LINE_STATUS_ONLINE:
- online = TRUE;
- sensitive = TRUE;
- tooltip = _("Evolution is currently online.\n"
- "Click on this button to work offline.");
- flags = ES_MENU_SHELL_ONLINE;
- break;
- case E_SHELL_LINE_STATUS_GOING_OFFLINE:
- online = TRUE;
- sensitive = FALSE;
- tooltip = _("Evolution is in the process of going offline.");
- flags = ES_MENU_SHELL_OFFLINE;
- break;
- case E_SHELL_LINE_STATUS_OFFLINE:
- case E_SHELL_LINE_STATUS_FORCED_OFFLINE:
- online = FALSE;
- sensitive = TRUE;
- tooltip = _("Evolution is currently offline.\n"
- "Click on this button to work online.");
- flags = ES_MENU_SHELL_OFFLINE;
- break;
- default:
- g_return_if_reached ();
+ case PROP_SHELL:
+ shell_window_set_shell (
+ E_SHELL_WINDOW (object),
+ g_value_get_object (value));
+ return;
}
- widget = window->priv->offline_toggle;
- gtk_widget_set_sensitive (widget, sensitive);
- gtk_widget_set_tooltip_text (widget, tooltip);
- e_online_button_set_online (E_ONLINE_BUTTON (widget), online);
-
- /* TODO: If we get more shell flags, this should be centralised */
- t = es_menu_target_new_shell(priv->menu, flags);
- t->target.widget = (GtkWidget *)window;
- e_menu_update_target((EMenu *)priv->menu, t);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-update_send_receive_sensitivity (EShellWindow *window)
+shell_window_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- if (e_shell_get_line_status (window->priv->shell.eshell) == E_SHELL_LINE_STATUS_OFFLINE ||
- e_shell_get_line_status (window->priv->shell.eshell) == E_SHELL_LINE_STATUS_FORCED_OFFLINE)
- bonobo_ui_component_set_prop (window->priv->ui_component,
- "/commands/SendReceive",
- "sensitive", "0", NULL);
- else
- bonobo_ui_component_set_prop (window->priv->ui_component,
- "/commands/SendReceive",
- "sensitive", "1", NULL);
-}
+ switch (property_id) {
+ case PROP_ACTIVE_VIEW:
+ g_value_set_string (
+ value, e_shell_window_get_active_view (
+ E_SHELL_WINDOW (object)));
+ return;
-/* Callbacks. */
+ case PROP_SAFE_MODE:
+ g_value_set_boolean (
+ value, e_shell_window_get_safe_mode (
+ E_SHELL_WINDOW (object)));
+ return;
-static ComponentView *
-get_component_view (EShellWindow *window, gint id)
-{
- GSList *p;
+ case PROP_SHELL:
+ g_value_set_object (
+ value, e_shell_window_get_shell (
+ E_SHELL_WINDOW (object)));
+ return;
- for (p = window->priv->component_views; p; p = p->next) {
- if (((ComponentView *) p->data)->button_id == id)
- return p->data;
+ case PROP_UI_MANAGER:
+ g_value_set_object (
+ value, e_shell_window_get_ui_manager (
+ E_SHELL_WINDOW (object)));
+ return;
}
- g_warning ("Unknown component button id %d", id);
- return NULL;
-}
-
-static void
-sidebar_button_selected_callback (ESidebar *sidebar,
- gint button_id,
- EShellWindow *window)
-{
- ComponentView *component_view;
-
- if ((component_view = get_component_view (window, button_id)))
- switch_view (window, component_view);
-}
-
-static gboolean
-sidebar_button_pressed_callback (ESidebar *sidebar,
- GdkEventButton *event,
- gint button_id,
- EShellWindow *window)
-{
- if (event->type == GDK_BUTTON_PRESS &&
- event->button == 2) {
- /* open it in a new window */
- ComponentView *component_view;
-
- if ((component_view = get_component_view (window, button_id))) {
- e_shell_create_window (window->priv->shell.eshell,
- component_view->component_id,
- window);
- }
- return TRUE;
- }
- return FALSE;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-offline_toggle_clicked_cb (EShellWindow *window)
+shell_window_dispose (GObject *object)
{
- EShell *shell;
- GNOME_Evolution_ShellState shell_state;
-
- shell = window->priv->shell.eshell;
-
- switch (e_shell_get_line_status (shell)) {
- case E_SHELL_LINE_STATUS_ONLINE:
- shell_state = GNOME_Evolution_USER_OFFLINE;
- break;
- case E_SHELL_LINE_STATUS_OFFLINE:
- case E_SHELL_LINE_STATUS_FORCED_OFFLINE:
- shell_state = GNOME_Evolution_USER_ONLINE;
- break;
- default:
- g_return_if_reached();
- }
+ e_shell_window_private_dispose (E_SHELL_WINDOW (object));
- e_shell_set_line_status (shell, shell_state);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-shell_line_status_changed_callback (EShell *shell,
- EShellLineStatus new_status,
- EShellWindow *window)
+shell_window_finalize (GObject *object)
{
- update_offline_toggle_status (window);
- update_send_receive_sensitivity (window);
-}
+ e_shell_window_private_finalize (E_SHELL_WINDOW (object));
-static void
-ui_engine_add_hint_callback (BonoboUIEngine *engine,
- const gchar *hint,
- EShellWindow *window)
-{
- gtk_label_set_text (GTK_LABEL (window->priv->menu_hint_label), hint);
- gtk_widget_show (window->priv->menu_hint_label);
- gtk_widget_hide (window->priv->statusbar_notebook);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-ui_engine_remove_hint_callback (BonoboUIEngine *engine,
- EShellWindow *window)
+shell_window_constructed (GObject *object)
{
- gtk_widget_hide (window->priv->menu_hint_label);
- gtk_widget_show (window->priv->statusbar_notebook);
+ e_shell_window_private_constructed (E_SHELL_WINDOW (object));
}
-/* Widgetry. */
-
static void
-setup_offline_toggle (EShellWindow *window)
+shell_window_class_init (EShellWindowClass *class)
{
- GtkWidget *widget;
+ GObjectClass *object_class;
- g_return_if_fail (window->priv->status_bar != NULL);
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellWindowPrivate));
- widget = e_online_button_new ();
- g_signal_connect_swapped (
- widget, "clicked",
- G_CALLBACK (offline_toggle_clicked_cb), window);
- gtk_box_pack_start (
- GTK_BOX (window->priv->status_bar),
- widget, FALSE, TRUE, 0);
- window->priv->offline_toggle = widget;
- gtk_widget_show (widget);
-
- update_offline_toggle_status (window);
-}
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_window_set_property;
+ object_class->get_property = shell_window_get_property;
+ object_class->dispose = shell_window_dispose;
+ object_class->finalize = shell_window_finalize;
+ object_class->constructed = shell_window_constructed;
-static void
-setup_menu_hint_label (EShellWindow *window)
-{
- EShellWindowPrivate *priv;
-
- priv = window->priv;
-
- priv->menu_hint_label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (priv->menu_hint_label), 0.0, 0.5);
-
- gtk_box_pack_start (GTK_BOX (priv->status_bar), priv->menu_hint_label, TRUE, TRUE, 0);
+ /**
+ * EShellWindow:active-view
+ *
+ * Name of the active #EShellView.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVE_VIEW,
+ g_param_spec_string (
+ "active-view",
+ _("Active Shell View"),
+ _("Name of the active shell view"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellWindow:safe-mode
+ *
+ * Whether the shell window is in safe mode.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SAFE_MODE,
+ g_param_spec_boolean (
+ "safe-mode",
+ _("Safe Mode"),
+ _("Whether the shell window is in safe mode"),
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellWindow:shell
+ *
+ * The #EShell singleton.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ _("Shell"),
+ _("The EShell singleton"),
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellWindow:ui-manager
+ *
+ * The shell window's #GtkUIManager.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_UI_MANAGER,
+ g_param_spec_object (
+ "ui-manager",
+ _("UI Manager"),
+ _("The shell window's GtkUIManager"),
+ GTK_TYPE_UI_MANAGER,
+ G_PARAM_READABLE));
}
static void
-setup_statusbar_notebook (EShellWindow *window)
+shell_window_init (EShellWindow *shell_window)
{
- EShellWindowPrivate *priv;
-
- priv = window->priv;
+ shell_window->priv = E_SHELL_WINDOW_GET_PRIVATE (shell_window);
- priv->statusbar_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->statusbar_notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->statusbar_notebook), FALSE);
-
- gtk_box_pack_start (GTK_BOX (priv->status_bar), priv->statusbar_notebook, TRUE, TRUE, 0);
- gtk_widget_show (priv->statusbar_notebook);
-}
-
-static void
-setup_nm_support (EShellWindow *window)
-{
-#if defined(NM_SUPPORT) && NM_SUPPORT
- e_shell_dbus_initialise (window->priv->shell.eshell);
-#endif
+ e_shell_window_private_init (shell_window);
}
-static void
-setup_status_bar (EShellWindow *window)
+GType
+e_shell_window_get_type (void)
{
- EShellWindowPrivate *priv;
- BonoboUIEngine *ui_engine;
- GConfClient *gconf_client;
- gint height;
-
- priv = window->priv;
-
- priv->status_bar = gtk_hbox_new (FALSE, 2);
+ static GType type = 0;
- /* Make the status bar as large as the task bar. */
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
- gtk_widget_set_size_request (GTK_WIDGET (priv->status_bar), -1, height * 2);
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellWindowClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_window_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellWindow),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_window_init,
+ NULL /* value_table */
+ };
- gconf_client = gconf_client_get_default ();
- if (gconf_client_get_bool (gconf_client,"/apps/evolution/shell/view_defaults/statusbar_visible",NULL))
- gtk_widget_show (priv->status_bar);
- g_object_unref (gconf_client);
-
- /* setup dbus interface here*/
- setup_nm_support (window);
-
- setup_offline_toggle (window);
- setup_menu_hint_label (window);
- setup_statusbar_notebook (window);
-
- ui_engine = bonobo_window_get_ui_engine (BONOBO_WINDOW (window));
+ type = g_type_register_static (
+ GTK_TYPE_WINDOW, "EShellWindow", &type_info, 0);
+ }
- g_signal_connect (ui_engine, "add_hint", G_CALLBACK (ui_engine_add_hint_callback), window);
- g_signal_connect (ui_engine, "remove_hint", G_CALLBACK (ui_engine_remove_hint_callback), window);
+ return type;
}
-static void
-menu_component_selected (BonoboUIComponent *uic,
- EShellWindow *window,
- const gchar *path)
+/**
+ * e_shell_window_new:
+ * @shell: an #EShell
+ * @safe_mode: whether to initialize the window to "safe mode"
+ *
+ * Returns a new #EShellWindow.
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means, but the #EShell usually puts the initial
+ * #EShellWindow into "safe mode" if detects the previous Evolution
+ * session crashed.
+ *
+ * The initial view for the window is determined by GConf key
+ * <filename>/apps/evolution/shell/view_defaults/component_id</filename>.
+ * Or, if the GConf key is not set or can't be read, the first view
+ * in the switcher is used.
+ *
+ * Returns: a new #EShellWindow
+ **/
+GtkWidget *
+e_shell_window_new (EShell *shell,
+ gboolean safe_mode)
{
- gchar *component_id;
-
- component_id = strchr(path, '-');
- if (component_id)
- e_shell_window_switch_to_component (window, component_id+1);
+ return g_object_new (
+ E_TYPE_SHELL_WINDOW,
+ "shell", shell, "safe-mode", safe_mode, NULL);
}
-static GConfEnumStringPair button_styles[] = {
- { E_SIDEBAR_MODE_TEXT, "text" },
- { E_SIDEBAR_MODE_ICON, "icons" },
- { E_SIDEBAR_MODE_BOTH, "both" },
- { E_SIDEBAR_MODE_TOOLBAR, "toolbar" },
- { -1, NULL }
-};
-
-static void
-setup_widgets (EShellWindow *window)
+/**
+ * e_shell_window_get_shell:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns the #EShell that was passed to e_shell_window_new().
+ *
+ * Returns: the #EShell
+ **/
+EShell *
+e_shell_window_get_shell (EShellWindow *shell_window)
{
- EShellWindowPrivate *priv = window->priv;
- EComponentRegistry *registry = e_shell_peek_component_registry (priv->shell.eshell);
- GConfClient *gconf_client = gconf_client_get_default ();
- GtkWidget *contents_vbox;
- GSList *p;
- GString *xml;
- gint button_id;
- gboolean visible;
- gchar *style;
- gint mode;
-
- priv->paned = gtk_hpaned_new ();
- gtk_widget_show (priv->paned);
-
- priv->sidebar = e_sidebar_new ();
- g_signal_connect (priv->sidebar, "button_selected",
- G_CALLBACK (sidebar_button_selected_callback), window);
- g_signal_connect (priv->sidebar, "button_pressed",
- G_CALLBACK (sidebar_button_pressed_callback), window);
- gtk_paned_pack1 (GTK_PANED (priv->paned), priv->sidebar, FALSE, FALSE);
- gtk_widget_show (priv->sidebar);
-
- priv->sidebar_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->sidebar_notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->sidebar_notebook), FALSE);
- e_sidebar_set_selection_widget (E_SIDEBAR (priv->sidebar), priv->sidebar_notebook);
- gtk_widget_show (priv->sidebar_notebook);
-
- priv->view_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->view_notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->view_notebook), FALSE);
- gtk_paned_pack2 (GTK_PANED (priv->paned), priv->view_notebook, TRUE, FALSE);
- gtk_widget_show (priv->view_notebook);
-
- gtk_paned_set_position (GTK_PANED (priv->paned),
- gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/folder_bar/width", NULL));
-
- /* The buttons */
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/buttons_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsHide",
- "state",
- visible ? "0" : "1",
- NULL);
-
- e_sidebar_set_show_buttons (E_SIDEBAR (priv->sidebar), visible);
-
- style = gconf_client_get_string (gconf_client,
- "/apps/evolution/shell/view_defaults/buttons_style",
- NULL);
-
- if (gconf_string_to_enum (button_styles, style, &mode)) {
- switch (mode) {
- case E_SIDEBAR_MODE_TEXT:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsText",
- "state", "1", NULL);
- break;
- case E_SIDEBAR_MODE_ICON:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsIcon",
- "state", "1", NULL);
- break;
- case E_SIDEBAR_MODE_BOTH:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsIconText",
- "state", "1", NULL);
- break;
-
- case E_SIDEBAR_MODE_TOOLBAR:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsToolbar",
- "state", "1", NULL);
- break;
- }
-
- e_sidebar_set_mode (E_SIDEBAR (priv->sidebar), mode);
- }
- g_free (style);
-
- /* Status Bar*/
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/statusbar_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewStatusBar",
- "state",
- visible ? "1" : "0",
- NULL);
-
- /* Side Bar*/
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/sidebar_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewSideBar",
- "state",
- visible ? "1" : "0",
- NULL);
-
- /* The tool bar */
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/toolbar_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewToolbar",
- "state",
- visible ? "1" : "0",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/Toolbar",
- "hidden",
- visible ? "0" : "1",
- NULL);
-
- button_id = 0;
- xml = g_string_new("");
- for (p = e_component_registry_peek_list (registry); p != NULL; p = p->next) {
- gchar *tmp, *tmp2;
- EComponentInfo *info = p->data;
- ComponentView *view = component_view_new (info->id, info->alias, button_id);
- GtkIconInfo *icon_info;
- gint width;
-
- window->priv->component_views = g_slist_prepend (window->priv->component_views, view);
-
- if (!info->button_label || !info->menu_label)
- continue;
- e_sidebar_add_button (E_SIDEBAR (priv->sidebar), info->button_label, info->button_tooltips, info->icon_name, button_id);
-
- g_string_printf(xml, "SwitchComponent-%s", info->alias);
- bonobo_ui_component_add_verb (e_shell_window_peek_bonobo_ui_component (window),
- xml->str,
- (BonoboUIVerbFn)menu_component_selected,
- window);
-
- g_string_printf(xml, "<submenu name=\"View\">"
- "<submenu name=\"Window\">"
- "<placeholder name=\"WindowComponent\">"
- "<menuitem name=\"SwitchComponent-%s\" "
- "verb=\"\" label=\"%s\" accel=\"%s\" tip=\"",
- info->alias,
- info->menu_label,
- info->menu_accelerator);
- tmp = g_strdup_printf (_("Switch to %s"), info->button_label);
- tmp2 = g_markup_escape_text (tmp, -1);
- g_string_append (xml, tmp2);
- g_free (tmp2);
- g_free (tmp);
-
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL);
- icon_info = gtk_icon_theme_lookup_icon (
- gtk_icon_theme_get_default (),
- info->icon_name, width, 0);
- g_string_append_printf(xml, "\" pixtype=\"filename\" pixname=\"%s\"/>"
- "</placeholder></submenu></submenu>\n",
- icon_info ? gtk_icon_info_get_filename (icon_info) : "");
- gtk_icon_info_free (icon_info);
- bonobo_ui_component_set_translate (e_shell_window_peek_bonobo_ui_component (window),
- "/menu",
- xml->str,
- NULL);
- g_string_printf(xml, "<cmd name=\"SwitchComponent-%s\"/>\n", info->alias);
- bonobo_ui_component_set_translate (e_shell_window_peek_bonobo_ui_component (window),
- "/commands",
- xml->str,
- NULL);
- button_id ++;
- }
- g_string_free(xml, TRUE);
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
- setup_status_bar (window);
-
- contents_vbox = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (contents_vbox), priv->paned, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (contents_vbox), priv->status_bar, FALSE, TRUE, 0);
- gtk_widget_show (contents_vbox);
-
- /* We only display this when a menu item is actually selected. */
- gtk_widget_hide (priv->menu_hint_label);
-
- bonobo_window_set_contents (BONOBO_WINDOW (window), contents_vbox);
- g_object_unref (gconf_client);
+ return E_SHELL (shell_window->priv->shell);
}
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
+/**
+ * e_shell_window_get_shell_view:
+ * @shell_window: an #EShellWindow
+ * @view_name: name of a shell view
+ *
+ * Returns the #EShellView named @view_name (see the
+ * <structfield>name</structfield> field in #EShellBackendInfo). This
+ * will also instantiate the #EShellView the first time it's requested.
+ * To reduce resource consumption, Evolution tries to delay instantiating
+ * shell views until the user switches to them. So in general, only the
+ * active view name, as returned by e_shell_window_get_active_view(),
+ * should be requested.
+ *
+ * Returns: the requested #EShellView, or %NULL if no such view is
+ * registered
+ **/
+EShellView *
+e_shell_window_get_shell_view (EShellWindow *shell_window,
+ const gchar *view_name)
{
- EShellWindow *self = E_SHELL_WINDOW (object);
- EShellWindowPrivate *priv = self->priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ GHashTable *loaded_views;
- priv->destroyed = TRUE;
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (view_name != NULL, NULL);
- if (priv->shell.eshell != NULL) {
- g_object_remove_weak_pointer (G_OBJECT (priv->shell.eshell), &priv->shell.pointer);
- priv->shell.eshell = NULL;
- }
+ loaded_views = shell_window->priv->loaded_views;
+ shell_view = g_hash_table_lookup (loaded_views, view_name);
- if (priv->ui_component != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (priv->ui_component));
- priv->ui_component = NULL;
- }
+ if (shell_view != NULL)
+ return shell_view;
- if (priv->store_window_gsizeimer) {
- g_source_remove (priv->store_window_gsizeimer);
- self->priv->store_window_gsizeimer = 0;
+ shell = e_shell_window_get_shell (shell_window);
+ shell_backend = e_shell_get_backend_by_name (shell, view_name);
- /* There was a timer. Let us store the settings.*/
- store_window_size (GTK_WIDGET (self));
+ if (shell_backend == NULL) {
+ g_critical ("Unknown shell view name: %s", view_name);
+ return NULL;
}
- (* G_OBJECT_CLASS (e_shell_window_parent_class)->dispose) (object);
+ return shell_window_new_view (shell_backend, shell_window);
}
-static void
-impl_finalize (GObject *object)
+/**
+ * e_shell_window_get_shell_view_action:
+ * @shell_window: an #EShellWindow
+ * @view_name: name of a shell view
+ *
+ * Returns the switcher action for @view_name.
+ *
+ * An #EShellWindow creates a #GtkRadioAction for each registered subclass
+ * of #EShellView. This action gets passed to the #EShellSwitcher, which
+ * displays a button that proxies the action. When the #EShellView named
+ * @view_name is active, the action's icon becomes the @shell_window icon.
+ *
+ * Returns: the switcher action for the #EShellView named @view_name,
+ * or %NULL if no such shell view exists
+ **/
+GtkAction *
+e_shell_window_get_shell_view_action (EShellWindow *shell_window,
+ const gchar *view_name)
{
- EShellWindowPrivate *priv = E_SHELL_WINDOW (object)->priv;
-
- g_slist_foreach (priv->component_views, (GFunc) component_view_free, NULL);
- g_slist_free (priv->component_views);
-
- g_object_unref(priv->menu);
+ GtkAction *action;
+ gchar *action_name;
- g_free (priv);
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (view_name != NULL, NULL);
- (* G_OBJECT_CLASS (e_shell_window_parent_class)->finalize) (object);
-}
+ action_name = g_strdup_printf (SWITCHER_FORMAT, view_name);
+ action = e_shell_window_get_action (shell_window, action_name);
+ g_free (action_name);
-/* GtkWidget methods */
-static void
-e_shell_window_remove_regsizeimer (EShellWindow* self)
-{
- if (self->priv->store_window_gsizeimer) {
- g_source_remove (self->priv->store_window_gsizeimer);
- self->priv->store_window_gsizeimer = 0;
- }
+ return action;
}
-static gboolean
-impl_window_state (GtkWidget *widget, GdkEventWindowState* ev)
+/**
+ * e_shell_window_get_ui_manager:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns @shell_window<!-- -->'s user interface manager, which
+ * manages the window's menus and toolbars via #GtkAction<!-- -->s.
+ * This is the mechanism by which shell views and plugins can extend
+ * Evolution's menus and toolbars.
+ *
+ * Returns: the #GtkUIManager for @shell_window
+ **/
+GtkUIManager *
+e_shell_window_get_ui_manager (EShellWindow *shell_window)
{
- gboolean retval = FALSE;
-
- /* store only if the window state really changed */
- if ((ev->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0) {
- GConfClient* client = gconf_client_get_default ();
- gconf_client_set_bool (client, "/apps/evolution/shell/view_defaults/maximized",
- (ev->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0, NULL);
- g_object_unref(client);
- }
-
- if ((ev->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0) {
- e_shell_window_remove_regsizeimer (E_SHELL_WINDOW (widget));
- }
-
- if (GTK_WIDGET_CLASS (e_shell_window_parent_class)->window_state_event) {
- retval |= GTK_WIDGET_CLASS (e_shell_window_parent_class)->window_state_event (widget, ev);
- }
-
- return retval;
-}
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
-static gboolean
-store_window_size (GtkWidget* widget)
-{
- GConfClient* client = gconf_client_get_default ();
- gconf_client_set_int (client, "/apps/evolution/shell/view_defaults/width",
- widget->allocation.width, NULL);
- gconf_client_set_int (client, "/apps/evolution/shell/view_defaults/height",
- widget->allocation.height, NULL);
- g_object_unref(client);
-
- E_SHELL_WINDOW (widget)->priv->store_window_gsizeimer = 0;
- return FALSE; /* remove this timeout */
+ return shell_window->priv->ui_manager;
}
-static void
-impl_size_alloc (GtkWidget* widget, GtkAllocation* alloc)
+/**
+ * e_shell_window_get_action:
+ * @shell_window: an #EShellWindow
+ * @action_name: the name of an action
+ *
+ * Returns the #GtkAction named @action_name in @shell_window<!-- -->'s
+ * user interface manager, or %NULL if no such action exists.
+ *
+ * Returns: the #GtkAction named @action_name
+ **/
+GtkAction *
+e_shell_window_get_action (EShellWindow *shell_window,
+ const gchar *action_name)
{
- EShellWindow* self = E_SHELL_WINDOW (widget);
- e_shell_window_remove_regsizeimer(self);
-
- if (GTK_WIDGET_REALIZED(widget) && !(gdk_window_get_state(widget->window) & GDK_WINDOW_STATE_MAXIMIZED)) {
- /* update the size storage timer */
- self->priv->store_window_gsizeimer = g_timeout_add_seconds (1, (GSourceFunc)store_window_size, self);
- }
+ GtkUIManager *ui_manager;
- if (GTK_WIDGET_CLASS (e_shell_window_parent_class)->size_allocate) {
- GTK_WIDGET_CLASS (e_shell_window_parent_class)->size_allocate (widget, alloc);
- }
-}
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
-/* Initialization. */
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
-static void
-e_shell_window_class_init (EShellWindowClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- widget_class->window_state_event = impl_window_state;
- widget_class->size_allocate = impl_size_alloc;
-
- signals[COMPONENT_CHANGED] = g_signal_new ("component_changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EShellWindowClass, component_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ return e_lookup_action (ui_manager, action_name);
}
-static void
-e_shell_window_init (EShellWindow *shell_window)
+/**
+ * e_shell_window_get_action_group:
+ * @shell_window: an #EShellWindow
+ * @group_name: the name of an action group
+ *
+ * Returns the #GtkActionGroup named @group_name in
+ * @shell_window<!-- -->'s user interface manager, or %NULL if no
+ * such action group exists.
+ *
+ * Returns: the #GtkActionGroup named @group_name
+ **/
+GtkActionGroup *
+e_shell_window_get_action_group (EShellWindow *shell_window,
+ const gchar *group_name)
{
- EShellWindowPrivate *priv = g_new0 (EShellWindowPrivate, 1);
+ GtkUIManager *ui_manager;
- priv->shell_view = e_shell_view_new(shell_window);
- priv->destroyed = FALSE;
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
- shell_window->priv = priv;
-
- /** @HookPoint: Shell Main Menu
- * @Id: org.gnome.evolution.shell
- * @Type: ESMenu
- * @Target: ESMenuTargetShell
- *
- * This hook point is used to add bonobo menu's to the main
- * evolution shell window, used for global commands not
- * requiring a specific component.
- */
- priv->menu = es_menu_new("org.gnome.evolution.shell");
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ return e_lookup_action_group (ui_manager, group_name);
}
-/* Instantiation. */
-
+/**
+ * e_shell_window_get_managed_widget:
+ * @shell_window: an #EShellWindow
+ * @widget_path: path in the UI definintion
+ *
+ * Looks up a widget in @shell_window<!-- -->'s user interface manager by
+ * following a path. See gtk_ui_manager_get_widget() for more information
+ * about paths.
+ *
+ * Returns: the widget found by following the path, or %NULL if no widget
+ * was found
+ **/
GtkWidget *
-e_shell_window_new (EShell *shell,
- const gchar *component_id)
+e_shell_window_get_managed_widget (EShellWindow *shell_window,
+ const gchar *widget_path)
{
- EShellWindow *window = g_object_new (e_shell_window_get_type (), NULL);
- EShellWindowPrivate *priv = window->priv;
- GConfClient *gconf_client = gconf_client_get_default ();
- BonoboUIContainer *ui_container;
- gchar *default_component_id = NULL;
- gchar *xmlfile;
- gint width, height;
-
- if (bonobo_window_construct (BONOBO_WINDOW (window),
- bonobo_ui_container_new (),
- "evolution", "Evolution") == NULL) {
- g_object_unref (window);
- g_object_unref (gconf_client);
- return NULL;
- }
-
- window->priv->shell.eshell = shell;
- g_object_add_weak_pointer (G_OBJECT (shell), &window->priv->shell.pointer);
-
- /* FIXME TODO: Add system_exception signal handling and all the other
- stuff from e_shell_view_construct(). */
-
- ui_container = bonobo_window_get_ui_container (BONOBO_WINDOW (window));
-
- priv->ui_component = bonobo_ui_component_new ("evolution");
- bonobo_ui_component_set_container (priv->ui_component,
- bonobo_object_corba_objref (BONOBO_OBJECT (ui_container)),
- NULL);
-
- xmlfile = g_build_filename (EVOLUTION_UIDIR, "evolution.xml", NULL);
- bonobo_ui_util_set_ui (priv->ui_component,
- PREFIX,
- xmlfile,
- "evolution", NULL);
- g_free (xmlfile);
-
- e_shell_window_commands_setup (window);
- e_menu_activate((EMenu *)priv->menu, priv->ui_component, TRUE);
-
- setup_widgets (window);
-
- if (gconf_client_get_bool (gconf_client,"/apps/evolution/shell/view_defaults/sidebar_visible",NULL))
- gtk_widget_show (priv->sidebar);
- else
- gtk_widget_hide (priv->sidebar);
-
- update_send_receive_sensitivity (window);
- g_signal_connect_object (shell, "line_status_changed", G_CALLBACK (shell_line_status_changed_callback), window, 0);
-
- gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
+ GtkUIManager *ui_manager;
+ GtkWidget *widget;
- if (component_id == NULL) {
- component_id = default_component_id =
- gconf_client_get_string (gconf_client,
- "/apps/evolution/shell/view_defaults/component_id",
- NULL);
- if (component_id == NULL)
- component_id = "mail";
- }
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (widget_path != NULL, NULL);
- e_shell_window_switch_to_component (window, component_id);
- g_free(default_component_id);
- g_object_unref (gconf_client);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ widget = gtk_ui_manager_get_widget (ui_manager, widget_path);
- width = gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/width", NULL);
- height = gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/height", NULL);
- gtk_window_set_default_size (GTK_WINDOW (window), (width >= 0) ? width : 0,
- (height >= 0) ? height : 0);
- if (gconf_client_get_bool (gconf_client, "/apps/evolution/shell/view_defaults/maximized", NULL)) {
- gtk_window_maximize (GTK_WINDOW (window));
- }
+ g_return_val_if_fail (widget != NULL, NULL);
- g_object_unref (gconf_client);
- return GTK_WIDGET (window);
+ return widget;
}
-void
-e_shell_window_switch_to_component (EShellWindow *window, const gchar *component_id)
+/**
+ * e_shell_window_get_active_view:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns the name of the active #EShellView.
+ *
+ * Returns: the name of the active view
+ **/
+const gchar *
+e_shell_window_get_active_view (EShellWindow *shell_window)
{
- EShellWindowPrivate *priv = window->priv;
- ComponentView *view = NULL;
- GSList *p;
-
- g_return_if_fail (E_IS_SHELL_WINDOW (window));
- g_return_if_fail (component_id != NULL);
-
- for (p = priv->component_views; p != NULL; p = p->next) {
- ComponentView *this_view = p->data;
-
- if (strcmp (this_view->component_id, component_id) == 0
- || (this_view->component_alias != NULL
- && strcmp (this_view->component_alias, component_id) == 0))
- {
- view = p->data;
- break;
- }
- }
-
- if (view == NULL) {
- g_warning ("Unknown component %s", component_id);
- return;
- }
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
- e_sidebar_select_button (E_SIDEBAR (priv->sidebar), view->button_id);
+ return shell_window->priv->active_view;
}
-const gchar *
-e_shell_window_peek_current_component_id (EShellWindow *window)
+/**
+ * e_shell_window_set_active_view:
+ * @shell_window: an #EShellWindow
+ * @view_name: the name of the shell view to switch to
+ *
+ * Switches @shell_window to the #EShellView named @view_name, causing
+ * the entire content of @shell_window to change. This is typically
+ * called as a result of the user clicking one of the switcher buttons.
+ *
+ * The name of the newly activated shell view is also written to GConf key
+ * <filename>/apps/evolution/shell/view_defaults/component_id</filename>.
+ * This makes the active shell view persistent across Evolution sessions.
+ * It also causes new shell windows created within the current Evolution
+ * session to open to the most recently selected shell view.
+ **/
+void
+e_shell_window_set_active_view (EShellWindow *shell_window,
+ const gchar *view_name)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ GtkAction *action;
+ EShellView *shell_view;
- if (window->priv->current_view == NULL)
- return NULL;
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (view_name != NULL);
- return window->priv->current_view->component_id;
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ g_return_if_fail (shell_view != NULL);
+
+ action = e_shell_view_get_action (shell_view);
+ gtk_action_activate (action);
}
-EShell *
-e_shell_window_peek_shell (EShellWindow *window)
+/**
+ * e_shell_window_get_safe_mode:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window is in "safe mode".
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means. The @shell_window simply manages the
+ * "safe mode" state.
+ *
+ * Returns: %TRUE if @shell_window is in "safe mode"
+ **/
+gboolean
+e_shell_window_get_safe_mode (EShellWindow *shell_window)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
- return window->priv->shell.eshell;
+ return shell_window->priv->safe_mode;
}
-BonoboUIComponent *
-e_shell_window_peek_bonobo_ui_component (EShellWindow *window)
+/**
+ * e_shell_window_set_safe_mode:
+ * @shell_window: an #EShellWindow
+ * @safe_mode: whether to put @shell_window into "safe mode"
+ *
+ * If %TRUE, puts @shell_window into "safe mode".
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means. The @shell_window simply manages the
+ * "safe mode" state.
+ **/
+void
+e_shell_window_set_safe_mode (EShellWindow *shell_window,
+ gboolean safe_mode)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
- return window->priv->ui_component;
+ shell_window->priv->safe_mode = safe_mode;
+
+ g_object_notify (G_OBJECT (shell_window), "safe-mode");
}
-ESidebar *
-e_shell_window_peek_sidebar (EShellWindow *window)
+/**
+ * e_shell_window_add_action_group:
+ * @shell_window: an #EShellWindow
+ * @group_name: the name of the new action group
+ *
+ * Creates a new #GtkActionGroup and adds it to @shell_window<!-- -->'s
+ * user interface manager. This also takes care of details like setting
+ * the translation domain.
+ **/
+void
+e_shell_window_add_action_group (EShellWindow *shell_window,
+ const gchar *group_name)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ const gchar *domain;
- return E_SIDEBAR (window->priv->sidebar);
-}
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (group_name != NULL);
-GtkWidget *
-e_shell_window_peek_statusbar (EShellWindow *window)
-{
- return window->priv->status_bar;
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ domain = GETTEXT_PACKAGE;
+
+ action_group = gtk_action_group_new (group_name);
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
}
+/**
+ * e_shell_window_register_new_item_actions:
+ * @shell_window: an #EShellWindow
+ * @backend_name: name of an #EShellBackend
+ * @entries: an array of #GtkActionEntry<!-- -->s
+ * @n_entries: number of elements in the array
+ *
+ * Registers a list of #GtkAction<!-- -->s to appear in
+ * @shell_window<!-- -->'s "New" menu and toolbar button. This
+ * function should be called from an #EShell<!-- -->'s
+ * #EShell::window-created signal handler. The #EShellBackend calling
+ * this function should pass its own name for the @backend_name argument
+ * (i.e. the <structfield>name</structfield> field from its own
+ * #EShellBackendInfo).
+ *
+ * The registered #GtkAction<!-- -->s should be for creating individual
+ * items such as an email message or a calendar appointment. The action
+ * labels should be marked for translation with the "New" context using
+ * the NC_() macro.
+ **/
void
-e_shell_window_save_defaults (EShellWindow *window)
-{
- GConfClient *client = gconf_client_get_default ();
- gchar *prop;
- const gchar *style;
- gboolean visible;
-
- gconf_client_set_int (client, "/apps/evolution/shell/view_defaults/folder_bar/width",
- gtk_paned_get_position (GTK_PANED (window->priv->paned)), NULL);
-
- /* The button styles */
- if ((style = gconf_enum_to_string (button_styles, e_sidebar_get_mode (E_SIDEBAR (window->priv->sidebar))))) {
- gconf_client_set_string (client,
- "/apps/evolution/shell/view_defaults/buttons_style",
- style, NULL);
- }
+e_shell_window_register_new_item_actions (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries)
+{
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+ GtkUIManager *ui_manager;
+ guint ii;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (backend_name != NULL);
+ g_return_if_fail (entries != NULL);
+
+ action_group = ACTION_GROUP (NEW_ITEM);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+ backend_name = g_intern_string (backend_name);
+
+ /* XXX The action label translations are retrieved from the
+ * message context "New", but gtk_action_group_add_actions()
+ * does not support message contexts. So we have to fetch
+ * the label translations ourselves before adding them to
+ * the action group.
+ *
+ * gtk_action_group_set_translate_func() does not help here
+ * because the action tooltips do not use a message context
+ * (though I suppose they could). */
+ for (ii = 0; ii < n_entries; ii++)
+ entries[ii].label = g_dpgettext2 (
+ GETTEXT_PACKAGE, "New", entries[ii].label);
- /* Button hiding setting */
- prop = bonobo_ui_component_get_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsHide",
- "state",
- NULL);
- if (prop) {
- visible = prop[0] == '0';
- gconf_client_set_bool (client,
- "/apps/evolution/shell/view_defaults/buttons_visible",
- visible,
- NULL);
- g_free (prop);
- }
+ gtk_action_group_add_actions (
+ action_group, entries, n_entries, shell_window);
- /* Toolbar visibility setting */
- prop = bonobo_ui_component_get_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewToolbar",
- "state",
- NULL);
- if (prop) {
- visible = prop[0] == '1';
- gconf_client_set_bool (client,
- "/apps/evolution/shell/view_defaults/toolbar_visible",
- visible,
- NULL);
- g_free (prop);
- }
+ /* Tag each action with the name of the shell backend that
+ * registered it. This is used to help sort actions in the
+ * "New" menu. */
- /* SideBar visibility setting */
- prop = bonobo_ui_component_get_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewSideBar",
- "state",
- NULL);
- if (prop) {
- visible = prop[0] == '1';
- gconf_client_set_bool (client,
- "/apps/evolution/shell/view_defaults/sidebar_visible",
- visible,
- NULL);
- g_free (prop);
- }
+ for (ii = 0; ii < n_entries; ii++) {
+ const gchar *action_name;
+ GtkAction *action;
- g_object_unref (client);
-}
+ action_name = entries[ii].name;
-void
-e_shell_window_show_settings (EShellWindow *window)
-{
- g_return_if_fail (E_IS_SHELL_WINDOW (window));
+ action = gtk_action_group_get_action (
+ action_group, action_name);
- e_shell_show_settings (window->priv->shell.eshell, window->priv->current_view ? window->priv->current_view->component_alias : NULL, window);
-}
+ gtk_action_set_accel_group (action, accel_group);
-void
-e_shell_window_set_title(EShellWindow *window, const gchar *component_id, const gchar *title)
-{
- EShellWindowPrivate *priv = window->priv;
- ComponentView *view = NULL;
- GSList *p;
-
- if (priv->destroyed)
- return;
-
- for (p = priv->component_views; p != NULL; p = p->next) {
- ComponentView *this_view = p->data;
-
- if (strcmp (this_view->component_id, component_id) == 0
- || (this_view->component_alias != NULL
- && strcmp (this_view->component_alias, component_id) == 0)) {
- view = p->data;
- break;
- }
- }
+ g_object_set_data (
+ G_OBJECT (action),
+ "backend-name", (gpointer) backend_name);
- if (view) {
- g_free(view->title);
- view->title = g_strdup(title);
- if (view->title && view == priv->current_view)
- gtk_window_set_title((GtkWindow *)window, title);
+ /* The first action becomes the first item in the "New"
+ * menu, and consequently its icon is shown in the "New"
+ * button when the shell backend's view is active. This
+ * is all sorted out in shell_window_extract_actions().
+ * Note, the data value just needs to be non-zero. */
+ if (ii == 0)
+ g_object_set_data (
+ G_OBJECT (action),
+ "primary", GINT_TO_POINTER (TRUE));
}
+
+ e_shell_window_update_new_menu (shell_window);
}
/**
- * e_shell_window_change_component_button_icon
- * Changes icon of components button at sidebar. For more info how this behaves see
- * info at @ref e_sidebar_change_button_icon.
- * @param window EShellWindow instance.
- * @param component_id ID of the component.
- * @param icon Icon buffer.
+ * e_shell_window_register_new_source_actions:
+ * @shell_window: an #EShellWindow
+ * @backend_name: name of an #EShellBackend
+ * @entries: an array of #GtkActionEntry<!-- -->s
+ * @n_entries: number of elements in the array
+ *
+ * Registers a list of #GtkAction<!-- -->s to appear in
+ * @shell_window<!-- -->'s "New" menu and toolbar button. This
+ * function should be called from an #EShell<!-- -->'s
+ * #EShell::window-created signal handler. The #EShellBackend calling
+ * this function should pass its own name for the @backend_name argument
+ * (i.e. the <structfield>name</structfield> field from its own
+ * #EShellBackendInfo).
+ *
+ * The registered #GtkAction<!-- -->s should be for creating item
+ * containers such as an email folder or a calendar. The action labels
+ * should be marked for translation with the "New" context using the
+ * NC_() macro.
**/
void
-e_shell_window_change_component_button_icon (EShellWindow *window, const gchar *component_id, const gchar *icon_name)
-{
- EShellWindowPrivate *priv;
- GSList *p;
+e_shell_window_register_new_source_actions (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries)
+{
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+ GtkUIManager *ui_manager;
+ guint ii;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (backend_name != NULL);
+ g_return_if_fail (entries != NULL);
+
+ action_group = ACTION_GROUP (NEW_SOURCE);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+ backend_name = g_intern_string (backend_name);
+
+ /* XXX The action label translations are retrieved from the
+ * message context "New", but gtk_action_group_add_actions()
+ * does not support message contexts. So we have to fetch
+ * the label translations ourselves before adding them to
+ * the action group.
+ *
+ * gtk_action_group_set_translate_func() does not help here
+ * because the action tooltips do not use a message context
+ * (though I suppose they could). */
+ for (ii = 0; ii < n_entries; ii++)
+ entries[ii].label = g_dpgettext2 (
+ GETTEXT_PACKAGE, "New", entries[ii].label);
+
+ gtk_action_group_add_actions (
+ action_group, entries, n_entries, shell_window);
- g_return_if_fail (window != NULL);
- g_return_if_fail (component_id != NULL);
+ /* Tag each action with the name of the shell backend that
+ * registered it. This is used to help sort actions in the
+ * "New" menu. */
- priv = window->priv;
+ for (ii = 0; ii < n_entries; ii++) {
+ const gchar *action_name;
+ GtkAction *action;
- if (priv->destroyed)
- return;
+ action_name = entries[ii].name;
- for (p = priv->component_views; p != NULL; p = p->next) {
- ComponentView *this_view = p->data;
+ action = gtk_action_group_get_action (
+ action_group, action_name);
- if (strcmp (this_view->component_id, component_id) == 0
- || (this_view->component_alias != NULL
- && strcmp (this_view->component_alias, component_id) == 0)) {
- e_sidebar_change_button_icon (E_SIDEBAR (priv->sidebar), icon_name, this_view->button_id);
- break;
- }
+ gtk_action_set_accel_group (action, accel_group);
+
+ g_object_set_data (
+ G_OBJECT (action),
+ "backend-name", (gpointer) backend_name);
}
+
+ e_shell_window_update_new_menu (shell_window);
}
diff --git a/shell/e-shell-window.h b/shell/e-shell-window.h
index 7c404fadc8..b867490afb 100644
--- a/shell/e-shell-window.h
+++ b/shell/e-shell-window.h
@@ -1,4 +1,5 @@
/*
+ * e-shell-window.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,63 +15,104 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_SHELL_WINDOW_H_
-#define _E_SHELL_WINDOW_H_
-
-#include <bonobo/bonobo-window.h>
-#include <bonobo/bonobo-ui-component.h>
-#include "e-sidebar.h"
-
-#define E_TYPE_SHELL_WINDOW (e_shell_window_get_type ())
-#define E_SHELL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_WINDOW, EShellWindow))
-#define E_SHELL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_WINDOW, EShellWindowClass))
-#define E_IS_SHELL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_WINDOW))
-#define E_IS_SHELL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_WINDOW))
-
-typedef struct _EShellWindow EShellWindow;
+/**
+ * SECTION: e-shell-window
+ * @short_description: the main window
+ * @include: shell/e-shell-window.h
+ **/
+
+#ifndef E_SHELL_WINDOW_H
+#define E_SHELL_WINDOW_H
+
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_WINDOW \
+ (e_shell_window_get_type ())
+#define E_SHELL_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_WINDOW, EShellWindow))
+#define E_SHELL_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_WINDOW, EShellWindowClass))
+#define E_IS_SHELL_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_WINDOW))
+#define E_IS_SHELL_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_WINDOW))
+#define E_SHELL_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_WINDOW, EShellWindowClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellWindow EShellWindow;
+typedef struct _EShellWindowClass EShellWindowClass;
typedef struct _EShellWindowPrivate EShellWindowPrivate;
-typedef struct _EShellWindowClass EShellWindowClass;
+/**
+ * EShellWindow:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EShellWindow {
- BonoboWindow parent;
-
+ GtkWindow parent;
EShellWindowPrivate *priv;
};
struct _EShellWindowClass {
- BonoboWindowClass parent_class;
-
- void (* component_changed) (EShellWindow *window);
+ GtkWindowClass parent_class;
};
-#include "e-shell.h"
-
-GType e_shell_window_get_type (void);
-
-GtkWidget *e_shell_window_new (EShell *shell,
- const gchar *component_id);
-
-void e_shell_window_switch_to_component (EShellWindow *shell,
- const gchar *component_id);
-const gchar *e_shell_window_peek_current_component_id (EShellWindow *shell);
-
-EShell *e_shell_window_peek_shell (EShellWindow *window);
-BonoboUIComponent *e_shell_window_peek_bonobo_ui_component (EShellWindow *window);
-ESidebar *e_shell_window_peek_sidebar (EShellWindow *window);
-GtkWidget *e_shell_window_peek_statusbar (EShellWindow *window);
-
-void e_shell_window_set_title(EShellWindow *window, const gchar *component_id, const gchar *title);
-
-void e_shell_window_save_defaults (EShellWindow *window);
-void e_shell_window_show_settings (EShellWindow *window);
-
-void e_shell_window_change_component_button_icon (EShellWindow *window, const gchar *component_id, const gchar *icon_name);
-
-#endif /* _E_SHELL_WINDOW_H_ */
+GType e_shell_window_get_type (void);
+GtkWidget * e_shell_window_new (EShell *shell,
+ gboolean safe_mode);
+EShell * e_shell_window_get_shell (EShellWindow *shell_window);
+struct _EShellView *
+ e_shell_window_get_shell_view (EShellWindow *shell_window,
+ const gchar *view_name);
+GtkAction * e_shell_window_get_shell_view_action
+ (EShellWindow *shell_window,
+ const gchar *view_name);
+GtkUIManager * e_shell_window_get_ui_manager (EShellWindow *shell_window);
+GtkAction * e_shell_window_get_action (EShellWindow *shell_window,
+ const gchar *action_name);
+GtkActionGroup *e_shell_window_get_action_group (EShellWindow *shell_window,
+ const gchar *group_name);
+GtkWidget * e_shell_window_get_managed_widget
+ (EShellWindow *shell_window,
+ const gchar *widget_path);
+const gchar * e_shell_window_get_active_view (EShellWindow *shell_window);
+void e_shell_window_set_active_view (EShellWindow *shell_window,
+ const gchar *view_name);
+gboolean e_shell_window_get_safe_mode (EShellWindow *shell_window);
+void e_shell_window_set_safe_mode (EShellWindow *shell_window,
+ gboolean safe_mode);
+void e_shell_window_add_action_group (EShellWindow *shell_window,
+ const gchar *group_name);
+
+/* These should be called from the shell backend's window_created() handler. */
+
+void e_shell_window_register_new_item_actions
+ (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries);
+void e_shell_window_register_new_source_actions
+ (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries);
+
+G_END_DECLS
+
+#endif /* E_SHELL_WINDOW_H */
diff --git a/shell/e-shell.c b/shell/e-shell.c
index e4224f3207..4dd72e3747 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -1,4 +1,6 @@
/*
+ * e-shell.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,1411 +15,1533 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#include <config.h>
-
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <gtk/gtk.h>
-#include <glib/gstdio.h>
-
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkprivate.h>
-#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#elif defined (GDK_WINDOWING_WIN32)
-/* gdkwin32.h includes <windows.h> which stomps over the namespace */
-#undef DATADIR
-#define interface windows_interface
-#include <gdk/gdkwin32.h>
-#undef interface
-#endif
+#include "e-shell.h"
#include <glib/gi18n.h>
-
-#include <gconf/gconf-client.h>
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-moniker-util.h>
-
-#include <libedataserver/e-xml-utils.h>
#include <libedataserverui/e-passwords.h>
-#include "e-util/e-bconf-map.h"
-#include "e-util/e-dialog-utils.h"
-#include "e-util/e-error.h"
-#include "e-util/e-fsutils.h"
#include "e-util/e-util.h"
+#include "e-util/e-module.h"
+#include "smclient/eggsmclient.h"
+#include "widgets/misc/e-preferences-window.h"
-#include "Evolution.h"
-#include "e-shell-constants.h"
-#include "e-shell-settings-dialog.h"
-#include "e-shell.h"
-#include "e-shell-view.h"
-#include "es-event.h"
-#include "evolution-listener.h"
-#include "evolution-shell-component-utils.h"
-
-static void set_line_status_complete(EvolutionListener *el, gpointer data);
+#include "e-shell-backend.h"
+#include "e-shell-migrate.h"
+#include "e-shell-window.h"
-#define PARENT_TYPE bonobo_object_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-static gboolean session_started = FALSE;
+#define E_SHELL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL, EShellPrivate))
struct _EShellPrivate {
- /* IID for registering the object on OAF. */
- gchar *iid;
+ GList *watched_windows;
+ EShellSettings *settings;
+ GConfClient *gconf_client;
+ GtkWidget *preferences_window;
- GList *windows;
+ /* Shell Backends */
+ GList *loaded_backends;
+ GHashTable *backends_by_name;
+ GHashTable *backends_by_scheme;
- /* EUriSchemaRegistry *uri_schema_registry; FIXME */
- EComponentRegistry *component_registry;
+ gpointer preparing_for_line_change; /* weak pointer */
+ gpointer preparing_for_quit; /* weak pointer */
- /* Names for the types of the folders that have maybe crashed. */
- /* FIXME TODO */
- GList *crash_type_names; /* gchar * */
+ guint auto_reconnect : 1;
+ guint network_available : 1;
+ guint online : 1;
+ guint quit_cancelled : 1;
+ guint safe_mode : 1;
+};
- /* Line status and controllers */
- EShellLineStatus line_status;
- gint line_status_pending;
- EShellLineStatus line_status_working;
- EvolutionListener *line_status_listener;
+enum {
+ PROP_0,
+ PROP_NETWORK_AVAILABLE,
+ PROP_ONLINE,
+ PROP_SHELL_SETTINGS
+};
- /* Settings Dialog */
- union {
- GtkWidget *widget;
- gpointer pointer;
- } settings_dialog;
+enum {
+ EVENT,
+ HANDLE_URI,
+ PREPARE_FOR_OFFLINE,
+ PREPARE_FOR_ONLINE,
+ PREPARE_FOR_QUIT,
+ QUIT_REQUESTED,
+ SEND_RECEIVE,
+ WINDOW_CREATED,
+ WINDOW_DESTROYED,
+ LAST_SIGNAL
+};
- /* If we're quitting and things are still busy, a timeout handler */
- guint quit_timeout;
+enum {
+ DEBUG_KEY_SETTINGS = 1 << 0
+};
- /* Whether the shell is succesfully initialized. This is needed during
- the start-up sequence, to avoid CORBA calls to do make wrong things
- to happen while the shell is initializing. */
- guint is_initialized : 1;
+static GDebugKey debug_keys[] = {
+ { "settings", DEBUG_KEY_SETTINGS }
+};
- /* Wether the shell is working in "interactive" mode or not.
- (Currently, it's interactive IIF there is at least one active
- view.) */
- guint is_interactive : 1;
+EShell *default_shell = NULL;
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
- /* Whether quit has been requested, and the shell is now waiting for
- permissions from all the components to quit. */
- guint preparing_to_quit : 1;
+#if NM_SUPPORT
+gboolean e_shell_dbus_initialize (EShell *shell);
+#endif
- /* Whether we are recovering from a crash in the previous session. */
- guint crash_recovery : 1;
-};
+static void
+shell_parse_debug_string (EShell *shell)
+{
+ guint flags;
-/* Signals. */
+ flags = g_parse_debug_string (
+ g_getenv ("EVOLUTION_DEBUG"),
+ debug_keys, G_N_ELEMENTS (debug_keys));
-enum {
- NO_WINDOWS_LEFT,
- LINE_STATUS_CHANGED,
- NEW_WINDOW_CREATED,
- LAST_SIGNAL
-};
+ if (flags & DEBUG_KEY_SETTINGS)
+ e_shell_settings_enable_debug (shell->priv->settings);
+}
-static guint signals[LAST_SIGNAL] = { 0 };
+static void
+shell_notify_online_cb (EShell *shell)
+{
+ gboolean online;
-/* Utility functions. */
+ online = e_shell_get_online (shell);
+ e_passwords_set_online (online);
+}
static gboolean
-get_config_start_offline (void)
+shell_window_delete_event_cb (EShell *shell,
+ GtkWindow *window)
{
- GConfClient *client;
- gboolean value;
+ /* If other windows are open we can safely close this one. */
+ if (g_list_length (shell->priv->watched_windows) > 1)
+ return FALSE;
- client = gconf_client_get_default ();
+ /* Otherwise we initiate application quit. */
+ e_shell_quit (shell);
+
+ return TRUE;
+}
- value = gconf_client_get_bool (client, "/apps/evolution/shell/start_offline", NULL);
+static gboolean
+shell_window_focus_in_event_cb (EShell *shell,
+ GdkEventFocus *event,
+ GtkWindow *window)
+{
+ GList *list, *link;
+
+ /* Keep the watched windows list sorted by most recently focused,
+ * so the first item in the list should always be the currently
+ * focused window. */
+
+ list = shell->priv->watched_windows;
+ link = g_list_find (list, window);
+ g_return_val_if_fail (link != NULL, FALSE);
+
+ if (link != list) {
+ list = g_list_remove_link (list, link);
+ list = g_list_concat (link, list);
+ }
- g_object_unref (client);
+ shell->priv->watched_windows = list;
- return value;
+ return FALSE;
}
-/* Interactivity handling. */
+static void
+shell_window_weak_notify_cb (EShell *shell,
+ GObject *where_the_object_was)
+{
+ GList *list;
+
+ list = shell->priv->watched_windows;
+ list = g_list_remove (list, where_the_object_was);
+ shell->priv->watched_windows = list;
+
+ g_signal_emit (shell, signals[WINDOW_DESTROYED], 0);
+}
static void
-set_interactive (EShell *shell,
- gboolean interactive)
+shell_ready_for_offline (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
- GSList *component_list;
- GSList *p;
- GList *first_element;
- gint num_windows;
- GtkWidget *view;
+ if (!is_last_ref)
+ return;
- g_return_if_fail (E_IS_SHELL (shell));
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
- shell->priv->is_interactive = interactive;
+ e_activity_complete (activity);
- num_windows = g_list_length (shell->priv->windows);
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ shell_ready_for_offline, shell);
- /* We want to send the "interactive" message only when the first
- window is created */
- if (num_windows != 1)
- return;
+ /* Finalize the activity. */
+ g_object_unref (activity);
- first_element = g_list_first (shell->priv->windows);
- view = GTK_WIDGET (first_element->data);
+ shell->priv->online = FALSE;
+ g_object_notify (G_OBJECT (shell), "online");
- component_list = e_component_registry_peek_list (shell->priv->component_registry);
+ g_message ("Offline preparations complete.");
+}
- for (p = component_list; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
- CORBA_Environment ev;
+static void
+shell_prepare_for_offline (EShell *shell)
+{
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_line_change != NULL)
+ return;
- CORBA_exception_init (&ev);
+ g_message ("Preparing for offline mode...");
-#ifdef GDK_WINDOWING_X11
- GNOME_Evolution_Component_interactive (info->iface, interactive,GPOINTER_TO_INT (GDK_WINDOW_XWINDOW (view->window)), &ev);
-#elif defined (GDK_WINDOWING_WIN32)
- GNOME_Evolution_Component_interactive (info->iface, interactive,GPOINTER_TO_INT (GDK_WINDOW_HWND (view->window)), &ev);
-#else
-#error Port this to your windowing system
-#endif
+ shell->priv->preparing_for_line_change =
+ e_activity_new (_("Preparing to go offline..."));
- /* Ignore errors, the components can decide to not implement
- this interface. */
+ g_object_add_toggle_ref (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ (GToggleNotify) shell_ready_for_offline, shell);
- CORBA_exception_free (&ev);
- }
-}
+ g_object_add_weak_pointer (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ &shell->priv->preparing_for_line_change);
-/* CORBA interface implementation. */
+ g_signal_emit (
+ shell, signals[PREPARE_FOR_OFFLINE], 0,
+ shell->priv->preparing_for_line_change);
-static gboolean
-raise_exception_if_not_ready (PortableServer_Servant servant,
- CORBA_Environment *ev)
+ g_object_unref (shell->priv->preparing_for_line_change);
+}
+
+static void
+shell_ready_for_online (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
- EShell *shell;
+ if (!is_last_ref)
+ return;
- shell = E_SHELL (bonobo_object_from_servant (servant));
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
- if (! shell->priv->is_initialized) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Shell_NotReady, NULL);
- return TRUE;
- }
+ e_activity_complete (activity);
- return FALSE;
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ shell_ready_for_online, shell);
+
+ /* Finalize the activity. */
+ g_object_unref (activity);
+
+ shell->priv->online = TRUE;
+ g_object_notify (G_OBJECT (shell), "online");
+
+ g_message ("Online preparations complete.");
}
-static GNOME_Evolution_ShellView
-impl_Shell_createNewWindow (PortableServer_Servant servant,
- const CORBA_char *component_id,
- CORBA_Environment *ev)
+static void
+shell_prepare_for_online (EShell *shell)
{
- BonoboObject *bonobo_object;
- EShell *shell;
- EShellWindow *shell_window;
- EShellView *shell_view;
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_line_change != NULL)
+ return;
- if (raise_exception_if_not_ready (servant, ev))
- return CORBA_OBJECT_NIL;
+ g_message ("Preparing for online mode...");
- bonobo_object = bonobo_object_from_servant (servant);
- shell = E_SHELL (bonobo_object);
+ shell->priv->preparing_for_line_change =
+ e_activity_new (_("Preparing to go online..."));
- if (component_id[0] == '\0')
- component_id = NULL;
+ g_object_add_toggle_ref (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ (GToggleNotify) shell_ready_for_online, shell);
- shell_window = e_shell_create_window (shell, component_id, NULL);
- if (shell_window == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Shell_ComponentNotFound, NULL);
- return CORBA_OBJECT_NIL;
- }
+ g_object_add_weak_pointer (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ &shell->priv->preparing_for_line_change);
- /* refs?? */
- shell_view = e_shell_view_new(shell_window);
-
- return BONOBO_OBJREF(shell_view);
+ g_signal_emit (
+ shell, signals[PREPARE_FOR_ONLINE], 0,
+ shell->priv->preparing_for_line_change);
+ g_object_unref (shell->priv->preparing_for_line_change);
}
static void
-impl_Shell_handleURI (PortableServer_Servant servant,
- const CORBA_char *uri,
- CORBA_Environment *ev)
+shell_ready_for_quit (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
- EShell *shell = E_SHELL (bonobo_object_from_servant (servant));
- EComponentInfo *component_info;
- gchar *schema, *p;
- gint show = FALSE;
-
- schema = g_alloca(strlen(uri)+1);
- strcpy(schema, uri);
- p = strchr(schema, ':');
- if (p)
- *p = 0;
-
- component_info = e_component_registry_peek_info(shell->priv->component_registry, ECR_FIELD_SCHEMA, schema);
- if (component_info == NULL) {
- show = TRUE;
- component_info = e_component_registry_peek_info(shell->priv->component_registry, ECR_FIELD_ALIAS, schema);
- }
+ GList *list;
- if (component_info == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_UnsupportedSchema, NULL);
+ if (!is_last_ref)
return;
- }
- if (show) {
- GtkWidget *shell_window;
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
- shell_window = (GtkWidget *)e_shell_create_window (shell, component_info->id, NULL);
- if (shell_window == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_ComponentNotFound, NULL);
- return;
- }
- }
+ e_activity_complete (activity);
+
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ shell_ready_for_quit, shell);
+
+ /* Finalize the activity. */
+ g_object_ref (activity);
+
+ g_message ("Quit preparations complete.");
- GNOME_Evolution_Component_handleURI (component_info->iface, uri, ev);
- /* not an error not to implement it */
- if (ev->_id != NULL && strcmp(ev->_id, ex_CORBA_NO_IMPLEMENT) == 0)
- memset(ev, 0, sizeof(*ev));
+ /* Destroy all watched windows. Note, we iterate over a -copy-
+ * of the watched windows list because the act of destroying a
+ * watched window will modify the watched windows list, which
+ * would derail the iteration. */
+ list = g_list_copy (e_shell_get_watched_windows (shell));
+ g_list_foreach (list, (GFunc) gtk_widget_destroy, NULL);
+ g_list_free (list);
}
static void
-impl_Shell_setLineStatus (PortableServer_Servant servant,
- CORBA_boolean online,
- CORBA_Environment *ev)
+shell_prepare_for_quit (EShell *shell)
{
- BonoboObject *bonobo_object;
- EShell *shell;
+ GList *list, *iter;
- if (raise_exception_if_not_ready (servant, ev))
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_quit != NULL)
return;
- bonobo_object = bonobo_object_from_servant (servant);
- shell = E_SHELL (bonobo_object);
+ g_message ("Preparing to quit...");
- /* let the password manager know out online status */
- e_passwords_set_online(online);
+ shell->priv->preparing_for_quit =
+ e_activity_new (_("Preparing to quit..."));
- if (online)
- e_shell_set_line_status (shell, GNOME_Evolution_USER_ONLINE);
- else
- e_shell_set_line_status (shell, GNOME_Evolution_USER_OFFLINE);
-}
-/*
-static GNOME_Evolution_Component
-impl_Shell_findComponent(PortableServer_Servant servant,
- const CORBA_char *id,
- CORBA_Environment *ev)
-{
- EShell *shell;
- EComponentInfo *ci;
-
- if (raise_exception_if_not_ready (servant, ev))
- return CORBA_OBJECT_NIL;
-
- shell = (EShell *)bonobo_object_from_servant (servant);
- ci = e_component_registry_peek_info(shell->priv->component_registry, ECR_FIELD_ALIAS, id);
- if (ci == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_ComponentNotFound, NULL);
- return CORBA_OBJECT_NIL;
- } else if (ci->iface == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_NotReady, NULL);
- return CORBA_OBJECT_NIL;
- } else {
- return ci->iface;
- }
-}
-*/
+ g_object_add_toggle_ref (
+ G_OBJECT (shell->priv->preparing_for_quit),
+ (GToggleNotify) shell_ready_for_quit, shell);
-/* EShellWindow handling and bookkeeping. */
+ g_object_add_weak_pointer (
+ G_OBJECT (shell->priv->preparing_for_quit),
+ &shell->priv->preparing_for_quit);
-static gint
-window_delete_event_cb (GtkWidget *widget,
- GdkEventAny *ev,
- gpointer data)
-{
- EShell *shell;
+ g_signal_emit (
+ shell, signals[PREPARE_FOR_QUIT], 0,
+ shell->priv->preparing_for_quit);
- g_return_val_if_fail (E_IS_SHELL_WINDOW (widget), TRUE);
- shell = E_SHELL (data);
+ g_object_unref (shell->priv->preparing_for_quit);
- return ! e_shell_request_close_window (shell, E_SHELL_WINDOW (widget));
+ /* Desensitize all watched windows to prevent user action. */
+ list = e_shell_get_watched_windows (shell);
+ for (iter = list; iter != NULL; iter = iter->next)
+ gtk_widget_set_sensitive (GTK_WIDGET (iter->data), FALSE);
}
static gboolean
-notify_no_windows_left_idle_cb (gpointer data)
+shell_request_quit (EShell *shell)
{
- EShell *shell;
- EShellPrivate *priv;
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_quit != NULL)
+ return TRUE;
+
+ /* Give the application a chance to cancel quit. */
+ shell->priv->quit_cancelled = FALSE;
+ g_signal_emit (shell, signals[QUIT_REQUESTED], 0);
+
+ return !shell->priv->quit_cancelled;
+}
- shell = E_SHELL (data);
- priv = shell->priv;
+static void
+shell_load_modules (EShell *shell)
+{
+ GList *modules;
- set_interactive (shell, FALSE);
+ /* Load all shared library modules. */
+ modules = e_module_load_all_in_directory (EVOLUTION_MODULEDIR);
- g_signal_emit (shell, signals [NO_WINDOWS_LEFT], 0);
+ while (modules != NULL) {
+ g_type_module_unuse (G_TYPE_MODULE (modules->data));
+ modules = g_list_delete_link (modules, modules);
+ }
+}
- if (priv->iid != NULL)
- bonobo_activation_active_server_unregister (priv->iid,
- bonobo_object_corba_objref (BONOBO_OBJECT (shell)));
- bonobo_object_unref (BONOBO_OBJECT (shell));
+/* Helper for shell_process_backend() */
+static void
+shell_split_and_insert_items (GHashTable *hash_table,
+ const gchar *items,
+ EShellBackend *shell_backend)
+{
+ gpointer key;
+ gchar **strv;
+ gint ii;
- return FALSE;
+ strv = g_strsplit_set (items, ":", -1);
+
+ for (ii = 0; strv[ii] != NULL; ii++) {
+ key = (gpointer) g_intern_string (strv[ii]);
+ g_hash_table_insert (hash_table, key, shell_backend);
+ }
+
+ g_strfreev (strv);
}
static void
-window_weak_notify (gpointer data,
- GObject *where_the_object_was)
+shell_process_backend (EShell *shell,
+ EShellBackend *shell_backend)
{
- EShell *shell;
- gint num_windows;
+ EShellBackendClass *class;
+ GHashTable *backends_by_name;
+ GHashTable *backends_by_scheme;
+ const gchar *string;
- shell = E_SHELL (data);
+ shell->priv->loaded_backends = g_list_insert_sorted (
+ shell->priv->loaded_backends, shell_backend,
+ (GCompareFunc) e_shell_backend_compare);
- num_windows = g_list_length (shell->priv->windows);
+ /* Bookkeeping */
- /* If this is our last window, save settings now because in the callback
- for no_windows_left shell->priv->windows will be NULL and settings won't
- be saved because of that. */
- if (num_windows == 1)
- e_shell_save_settings (shell);
+ class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+ backends_by_name = shell->priv->backends_by_name;
+ backends_by_scheme = shell->priv->backends_by_scheme;
- shell->priv->windows = g_list_remove (shell->priv->windows, where_the_object_was);
+ if ((string = class->name) != NULL)
+ g_hash_table_insert (
+ backends_by_name, (gpointer)
+ g_intern_string (string), shell_backend);
- if (shell->priv->windows == NULL) {
- bonobo_object_ref (BONOBO_OBJECT (shell));
- g_idle_add (notify_no_windows_left_idle_cb, shell);
- }
-}
+ if ((string = class->aliases) != NULL)
+ shell_split_and_insert_items (
+ backends_by_name, string, shell_backend);
-/* GObject methods. */
+ if ((string = class->schemes) != NULL)
+ shell_split_and_insert_items (
+ backends_by_scheme, string, shell_backend);
+}
static void
-impl_dispose (GObject *object)
+shell_create_backends (EShell *shell)
{
- EShell *shell;
- EShellPrivate *priv;
- GList *p;
+ GType *children;
+ guint ii, n_children;
- shell = E_SHELL (object);
- priv = shell->priv;
+ /* Create an instance of each EShellBackend subclass. */
+ children = g_type_children (E_TYPE_SHELL_BACKEND, &n_children);
- priv->is_initialized = FALSE;
+ for (ii = 0; ii < n_children; ii++) {
+ EShellBackend *shell_backend;
+ GType type = children[ii];
-#if 0 /* FIXME */
- if (priv->uri_schema_registry != NULL) {
- g_object_unref (priv->uri_schema_registry);
- priv->uri_schema_registry = NULL;
+ shell_backend = g_object_new (type, "shell", shell, NULL);
+ shell_process_backend (shell, shell_backend);
}
-#endif
- if (priv->component_registry != NULL) {
- g_object_unref (priv->component_registry);
- priv->component_registry = NULL;
- }
+ g_free (children);
+}
- if (priv->quit_timeout) {
- g_source_remove(priv->quit_timeout);
- priv->quit_timeout = 0;
- }
+static void
+shell_sm_quit_requested_cb (EShell *shell,
+ EggSMClient *sm_client)
+{
+ gboolean will_quit;
- for (p = priv->windows; p != NULL; p = p->next) {
- EShellWindow *window;
+ /* If preparations are already in progress then we have already
+ * committed ourselves to quitting, and can answer 'yes'. */
+ if (shell->priv->preparing_for_quit == NULL)
+ will_quit = shell_request_quit (shell);
+ else
+ will_quit = TRUE;
- window = E_SHELL_WINDOW (p->data);
+ egg_sm_client_will_quit (sm_client, will_quit);
+}
- g_signal_handlers_disconnect_by_func (window, G_CALLBACK (window_delete_event_cb), shell);
- g_object_weak_unref (G_OBJECT (window), window_weak_notify, shell);
+static void
+shell_sm_quit_cancelled_cb (EShell *shell,
+ EggSMClient *sm_client)
+{
+ /* Nothing to do. This is just to aid debugging. */
+}
- gtk_object_destroy (GTK_OBJECT (window));
+static void
+shell_sm_quit_cb (EShell *shell,
+ EggSMClient *sm_client)
+{
+ shell_prepare_for_quit (shell);
+}
+
+static void
+shell_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_NETWORK_AVAILABLE:
+ e_shell_set_network_available (
+ E_SHELL (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_ONLINE:
+ e_shell_set_online (
+ E_SHELL (object),
+ g_value_get_boolean (value));
+ return;
}
- g_list_free (priv->windows);
- priv->windows = NULL;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- /* No unreffing for these as they are aggregate. */
- /* bonobo_object_unref (BONOBO_OBJECT (priv->corba_storage_registry)); */
+static void
+shell_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_NETWORK_AVAILABLE:
+ g_value_set_boolean (
+ value, e_shell_get_network_available (
+ E_SHELL (object)));
+ return;
- if (priv->settings_dialog.widget != NULL) {
- gtk_widget_destroy (priv->settings_dialog.widget);
- priv->settings_dialog.widget = NULL;
- }
+ case PROP_ONLINE:
+ g_value_set_boolean (
+ value, e_shell_get_online (
+ E_SHELL (object)));
+ return;
- if (priv->line_status_listener) {
- priv->line_status_listener->complete = NULL;
- bonobo_object_unref(BONOBO_OBJECT(priv->line_status_listener));
- priv->line_status_listener = NULL;
+ case PROP_SHELL_SETTINGS:
+ g_value_set_object (
+ value, e_shell_get_shell_settings (
+ E_SHELL (object)));
+ return;
}
- g_free (priv->iid);
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-impl_finalize (GObject *object)
+shell_dispose (GObject *object)
{
- EShell *shell;
EShellPrivate *priv;
- shell = E_SHELL (object);
- priv = shell->priv;
+ priv = E_SHELL_GET_PRIVATE (object);
- g_list_foreach (priv->crash_type_names, (GFunc) g_free, NULL);
- g_list_free (priv->crash_type_names);
+ if (priv->settings != NULL) {
+ g_object_unref (priv->settings);
+ priv->settings = NULL;
+ }
- g_free (priv);
+ if (priv->gconf_client != NULL) {
+ g_object_unref (priv->gconf_client);
+ priv->gconf_client = NULL;
+ }
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
+ if (priv->preferences_window != NULL) {
+ g_object_unref (priv->preferences_window);
+ priv->preferences_window = NULL;
+ }
-/* Initialization. */
+ g_list_foreach (priv->loaded_backends, (GFunc) g_object_unref, NULL);
+ g_list_free (priv->loaded_backends);
+ priv->loaded_backends = NULL;
-static void
-e_shell_class_init (EShellClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_Shell__epv *epv;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- signals[NO_WINDOWS_LEFT] =
- g_signal_new ("no_windows_left",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, no_windows_left),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[LINE_STATUS_CHANGED] =
- g_signal_new ("line_status_changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, line_status_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- signals[NEW_WINDOW_CREATED] =
- g_signal_new ("new_window_created",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, new_window_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-
- epv = & klass->epv;
- epv->createNewWindow = impl_Shell_createNewWindow;
- epv->handleURI = impl_Shell_handleURI;
- epv->setLineStatus = impl_Shell_setLineStatus;
-/* epv->findComponent = impl_Shell_findComponent;*/
+ if (priv->preparing_for_line_change != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->preparing_for_line_change),
+ &priv->preparing_for_line_change);
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-e_shell_init (EShell *shell)
+shell_finalize (GObject *object)
{
EShellPrivate *priv;
- priv = g_new0 (EShellPrivate, 1);
- priv->line_status = E_SHELL_LINE_STATUS_OFFLINE;
- priv->component_registry = e_component_registry_new ();
+ priv = E_SHELL_GET_PRIVATE (object);
- shell->priv = priv;
+ g_hash_table_destroy (priv->backends_by_name);
+ g_hash_table_destroy (priv->backends_by_scheme);
- priv->line_status_listener = evolution_listener_new(set_line_status_complete, shell);
+ /* Indicates a clean shut down to the next session. */
+ if (!unique_app_is_running (UNIQUE_APP (object)))
+ e_file_lock_destroy ();
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-detect_version (GConfClient *gconf, gint *major, gint *minor, gint *revision)
+shell_constructed (GObject *object)
{
- gchar *val, *evolution_dir;
- struct stat st;
-
- evolution_dir = g_build_filename (g_get_home_dir (), "evolution", NULL);
-
- val = gconf_client_get_string(gconf, "/apps/evolution/version", NULL);
- if (val) {
- /* Since 1.4.0 We've been keeping the version key in gconf */
- sscanf(val, "%d.%d.%d", major, minor, revision);
- g_free(val);
- } else if (g_lstat (evolution_dir, &st) != 0 || !S_ISDIR (st.st_mode)) {
- /* If ~/evolution does not exit or is not a directory it must be a new installation */
- *major = 0;
- *minor = 0;
- *revision = 0;
- } else {
- xmlDocPtr config_doc;
- xmlNodePtr source;
- gchar *tmp;
-
- tmp = g_build_filename (evolution_dir, "config.xmldb", NULL);
- config_doc = e_xml_parse_file (tmp);
- g_free (tmp);
- tmp = NULL;
-
- if (config_doc
- && (source = e_bconf_get_path (config_doc, "/Shell"))
- && (tmp = e_bconf_get_value (source, "upgrade_from_1_0_to_1_2_performed"))
- && tmp[0] == '1' ) {
- *major = 1;
- *minor = 2;
- *revision = 0;
- } else {
- *major = 1;
- *minor = 0;
- *revision = 0;
- }
- g_free (tmp);
- if (config_doc)
- xmlFreeDoc (config_doc);
- }
+ /* The first EShell instance is the default. */
+ if (default_shell == NULL)
+ default_shell = g_object_ref (object);
+
+ /* UniqueApp will have by this point determined whether we're
+ * the only Evolution process running. If so, proceed normally.
+ * Otherwise we just issue commands to the other process. */
+ if (unique_app_is_running (UNIQUE_APP (object)))
+ return;
+
+ e_file_lock_create ();
- g_free (evolution_dir);
+ shell_load_modules (E_SHELL (object));
+ shell_create_backends (E_SHELL (object));
+
+ e_shell_migrate_attempt (E_SHELL (object));
}
-/* calls components to perform upgrade */
static gboolean
-attempt_upgrade (EShell *shell, gint major, gint minor, gint revision)
+shell_message_handle_new (EShell *shell,
+ UniqueMessageData *data)
{
- GSList *component_infos, *p;
- gboolean success;
- gint res;
-
- success = TRUE;
-
- component_infos = e_component_registry_peek_list (shell->priv->component_registry);
- for (p = component_infos; success && p != NULL; p = p->next) {
- const EComponentInfo *info = p->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Component_upgradeFromVersion (info->iface, major, minor, revision, &ev);
-
- if (BONOBO_EX (&ev)) {
- gchar *exception_text;
- CORBA_char *id = CORBA_exception_id(&ev);
-
- if (strcmp (id, ex_CORBA_NO_IMPLEMENT) == 0) {
- /* Ignore components that do not implement this version, it
- might just mean that they don't need an upgrade path. */
- } else if (strcmp (id, ex_GNOME_Evolution_Component_UpgradeFailed) == 0) {
- GNOME_Evolution_Component_UpgradeFailed *ex = CORBA_exception_value(&ev);
-
- res = e_error_run(NULL, "shell:upgrade-failed", ex->what, ex->why, NULL);
- if (res == GTK_RESPONSE_CANCEL)
- success = FALSE;
- } else if (strcmp (id, ex_GNOME_Evolution_Component_UnsupportedVersion) == 0) {
- /* This is non-fatal */
- /* DO WE CARE??? */
- printf("Upgrade of component failed, unsupported prior version\n");
- } else {
- exception_text = bonobo_exception_get_text (&ev);
- res = e_error_run(NULL, "shell:upgrade-failed", exception_text, _("Unknown system error."), NULL);
- g_free (exception_text);
- if (res == GTK_RESPONSE_CANCEL)
- success = FALSE;
- }
- }
- CORBA_exception_free (&ev);
- }
+ gchar *view_name;
+
+ view_name = unique_message_data_get_text (data);
+ e_shell_create_shell_window (shell, view_name);
+ g_free (view_name);
- return success;
+ return TRUE;
}
-/**
- * e_shell_construct:
- * @shell: An EShell object to construct
- * @iid: OAFIID for registering the shell into the name server
- * @startup_line_mode: How to set up the line mode (online or offline) initally.
- *
- * Construct @shell so that it uses the specified @corba_object.
- *
- * Return value: The result of the operation.
- **/
-EShellConstructResult
-e_shell_construct (EShell *shell,
- const gchar *iid,
- EShellStartupLineMode startup_line_mode)
+static gboolean
+shell_message_handle_open (EShell *shell,
+ UniqueMessageData *data)
{
- EShellPrivate *priv;
- CORBA_Object corba_object;
- gboolean start_online;
- GSList *component;
-
- g_return_val_if_fail (E_IS_SHELL (shell), E_SHELL_CONSTRUCT_RESULT_INVALIDARG);
- g_return_val_if_fail (startup_line_mode == E_SHELL_STARTUP_LINE_MODE_CONFIG
- || startup_line_mode == E_SHELL_STARTUP_LINE_MODE_ONLINE
- || startup_line_mode == E_SHELL_STARTUP_LINE_MODE_OFFLINE,
- E_SHELL_CONSTRUCT_RESULT_INVALIDARG);
-
- priv = shell->priv;
- priv->iid = g_strdup (iid);
-
- /* Now we can register into OAF. Notice that we shouldn't be
- registering into OAF until we are sure we can complete. */
-
- /* FIXME: Multi-display stuff. */
- corba_object = bonobo_object_corba_objref (BONOBO_OBJECT (shell));
- if (bonobo_activation_active_server_register (iid, corba_object) != Bonobo_ACTIVATION_REG_SUCCESS)
- return E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER;
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- /* activate all the components (peek list does this implictly) */
- /* Do we really need to assign the result of this to the list? */
- component = e_component_registry_peek_list (shell->priv->component_registry);
-
- e_shell_attempt_upgrade(shell);
-
- priv->is_initialized = TRUE;
-
- switch (startup_line_mode) {
- case E_SHELL_STARTUP_LINE_MODE_CONFIG:
- start_online = ! get_config_start_offline ();
- break;
- case E_SHELL_STARTUP_LINE_MODE_ONLINE:
- start_online = TRUE;
- break;
- case E_SHELL_STARTUP_LINE_MODE_OFFLINE:
- start_online = FALSE;
- break;
- default:
- start_online = FALSE; /* Make compiler happy. */
- g_return_val_if_reached(E_SHELL_CONSTRUCT_RESULT_OK);
- }
+ gchar **uris;
- e_passwords_set_online(start_online);
+ uris = unique_message_data_get_uris (data);
+ e_shell_handle_uris (shell, uris);
+ g_strfreev (uris);
- if (start_online)
- e_shell_set_line_status (shell, GNOME_Evolution_USER_ONLINE);
- else
- e_shell_set_line_status (shell, GNOME_Evolution_USER_OFFLINE);
+ return TRUE;
+}
+
+static gboolean
+shell_message_handle_close (EShell *shell,
+ UniqueMessageData *data)
+{
+ e_shell_quit (shell);
- return E_SHELL_CONSTRUCT_RESULT_OK;
+ return TRUE;
}
-/**
- * e_shell_new:
- * @start_online: Whether to start in on-line mode or not.
- * @construct_result_return: A pointer to an EShellConstructResult variable into
- * which the result of the operation will be stored.
- *
- * Create a new EShell.
- *
- * Return value:
- **/
-EShell *
-e_shell_new (EShellStartupLineMode startup_line_mode,
- EShellConstructResult *construct_result_return)
+static UniqueResponse
+shell_message_received (UniqueApp *app,
+ gint command,
+ UniqueMessageData *data,
+ guint time_)
{
- EShell *new;
- EShellConstructResult construct_result;
+ EShell *shell = E_SHELL (app);
- new = g_object_new (e_shell_get_type (), NULL);
+ switch (command) {
+ case UNIQUE_ACTIVATE:
+ break; /* use the default behavior */
- construct_result = e_shell_construct (new, E_SHELL_OAFIID, startup_line_mode);
+ case UNIQUE_NEW:
+ if (shell_message_handle_new (shell, data))
+ return UNIQUE_RESPONSE_OK;
+ break;
- if (construct_result != E_SHELL_CONSTRUCT_RESULT_OK) {
- *construct_result_return = construct_result;
- bonobo_object_unref (BONOBO_OBJECT (new));
- return NULL;
- }
+ case UNIQUE_OPEN:
+ if (shell_message_handle_open (shell, data))
+ return UNIQUE_RESPONSE_OK;
+ break;
- *construct_result_return = E_SHELL_CONSTRUCT_RESULT_OK;
- return new;
-}
+ case UNIQUE_CLOSE:
+ if (shell_message_handle_close (shell, data))
+ return UNIQUE_RESPONSE_OK;
+ break;
-static gint
-remove_dir(const gchar *root, const gchar *path)
-{
- GDir *dir;
- const gchar *dname;
- gint res = -1;
- gchar *new = NULL;
- struct stat st;
-
- dir = g_dir_open(path, 0, NULL);
- if (dir == NULL)
- return -1;
-
- while ( (dname = g_dir_read_name(dir)) ) {
- new = g_build_filename(path, dname, NULL);
- if (g_stat(new, &st) == -1)
- goto fail;
-
- /* make sure we're really removing something from evolution dir */
- g_return_val_if_fail (strlen(path) >= strlen(root)
- && strncmp(root, path, strlen(root)) == 0, -1);
-
- if (S_ISDIR(st.st_mode)) {
- if (remove_dir(root, new) == -1)
- goto fail;
- } else {
- if (g_unlink(new) == -1)
- goto fail;
- }
- g_free(new);
- new = NULL;
+ default:
+ break;
}
- res = g_rmdir(path);
-fail:
- g_free(new);
- g_dir_close(dir);
- return res;
+ /* Chain up to parent's message_received() method. */
+ return UNIQUE_APP_CLASS (parent_class)->
+ message_received (app, command, data, time_);
}
-/**
- * e_shell_attempt_upgrade:
- * @shell:
- *
- * Upgrade config and components from the currently installed version.
- *
- * Return value: %TRUE If it works. If it fails the application will exit.
- **/
-gboolean
-e_shell_attempt_upgrade (EShell *shell)
+static void
+shell_class_init (EShellClass *class)
{
- GConfClient *gconf_client;
- gint major = 0, minor = 0, revision = 0;
- gint lmajor, lminor, lrevision;
- gint cmajor, cminor, crevision;
- gchar *version_string, *last_version = NULL;
- gint done_upgrade = FALSE;
- gchar *oldpath;
- struct stat st;
- ESEvent *ese;
-
- gconf_client = gconf_client_get_default();
-
- oldpath = g_build_filename(g_get_home_dir(), "evolution", NULL);
-
- g_return_val_if_fail (sscanf(BASE_VERSION, "%u.%u", &cmajor, &cminor) == 2, TRUE);
- crevision = atoi(UPGRADE_REVISION);
-
- detect_version (gconf_client, &major, &minor, &revision);
-
- if (!(cmajor > major
- || (cmajor == major && cminor > minor)
- || (cminor == minor && crevision > revision)))
- goto check_old;
-
- /* if upgrading from < 1.5, we need to copy most data from ~/evolution to ~/.evolution */
- if (major == 1 && minor < 5) {
- long size, space;
-
- size = e_fsutils_usage(oldpath);
- space = e_fsutils_avail(g_get_home_dir());
- if (size != -1 && space != -1 && space < size) {
- gchar *required = g_strdup_printf(_("%ld KB"), size);
- gchar *have = g_strdup_printf(_("%ld KB"), space);
-
- e_error_run(NULL, "shell:upgrade-nospace", required, have, NULL);
- g_free(required);
- g_free(have);
- _exit(0);
- }
- }
+ GObjectClass *object_class;
+ UniqueAppClass *unique_app_class;
- if (!attempt_upgrade (shell, major, minor, revision))
- _exit(0);
-
- /* mark as upgraded */
- version_string = g_strdup_printf ("%s.%s", BASE_VERSION, UPGRADE_REVISION);
- gconf_client_set_string (gconf_client, "/apps/evolution/version", version_string, NULL);
- done_upgrade = TRUE;
-
-check_old:
- /* if the last upgraded version was old, check for stuff to remove */
- if (done_upgrade
- || (last_version = gconf_client_get_string (gconf_client, "/apps/evolution/last_version", NULL)) == NULL
- || sscanf(last_version, "%d.%d.%d", &lmajor, &lminor, &lrevision) != 3) {
- lmajor = major;
- lminor = minor;
- lrevision = revision;
- }
- g_free(last_version);
-
- if (lmajor == 1 && lminor < 5
- && g_stat(oldpath, &st) == 0
- && S_ISDIR(st.st_mode)) {
- gint res;
-
- last_version = g_strdup_printf("%d.%d.%d", lmajor, lminor, lrevision);
- res = e_error_run(NULL, "shell:upgrade-remove-1-4", last_version, NULL);
- g_free(last_version);
-
- switch (res) {
- case GTK_RESPONSE_OK: /* 'delete' */
- if (e_error_run(NULL, "shell:upgrade-remove-1-4-confirm", NULL) == GTK_RESPONSE_OK)
- remove_dir(oldpath, oldpath);
- else
- break;
- /* falls through */
- case GTK_RESPONSE_ACCEPT: /* 'keep' */
- lmajor = cmajor;
- lminor = cminor;
- lrevision = crevision;
- break;
- default:
- /* cancel - noop */
- break;
- }
- } else {
- /* otherwise 'last version' is now the same as current */
- lmajor = cmajor;
- lminor = cminor;
- lrevision = crevision;
- }
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellPrivate));
- last_version = g_strdup_printf("%d.%d.%d", lmajor, lminor, lrevision);
- gconf_client_set_string (gconf_client, "/apps/evolution/last_version", last_version, NULL);
- g_free(last_version);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_set_property;
+ object_class->get_property = shell_get_property;
+ object_class->dispose = shell_dispose;
+ object_class->finalize = shell_finalize;
+ object_class->constructed = shell_constructed;
- g_free(oldpath);
- g_object_unref (gconf_client);
+ unique_app_class = UNIQUE_APP_CLASS (class);
+ unique_app_class->message_received = shell_message_received;
- /** @Event: Shell attempted upgrade
- * @Id: upgrade.done
- * @Target: ESMenuTargetState
+ /**
+ * EShell:network-available
*
- * This event is emitted whenever the shell successfully attempts an upgrade.
+ * Whether the network is available.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_NETWORK_AVAILABLE,
+ g_param_spec_boolean (
+ "network-available",
+ _("Network Available"),
+ _("Whether the network is available"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShell:online
*
- */
- ese = es_event_peek();
- e_event_emit((EEvent *)ese, "upgrade.done", (EEventTarget *)es_event_target_new_upgrade(ese, cmajor, cminor, crevision));
-
- return TRUE;
+ * Whether the shell is online.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ONLINE,
+ g_param_spec_boolean (
+ "online",
+ _("Online"),
+ _("Whether the shell is online"),
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShell:settings
+ *
+ * The #EShellSettings object stores application settings.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_SETTINGS,
+ g_param_spec_object (
+ "shell-settings",
+ _("Shell Settings"),
+ _("Application-wide settings"),
+ E_TYPE_SHELL_SETTINGS,
+ G_PARAM_READABLE));
+
+ /**
+ * EShell::event
+ * @shell: the #EShell which emitted the signal
+ * @event_data: data associated with the event
+ *
+ * This signal is used to broadcast custom events to the entire
+ * application. The nature of @event_data depends on the event
+ * being broadcast. The signal's detail denotes the event.
+ **/
+ signals[EVENT] = g_signal_new (
+ "event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ /**
+ * EShell::handle-uri
+ * @shell: the #EShell which emitted the signal
+ * @uri: the URI to be handled
+ *
+ * Emitted when @shell receives a URI to be handled, usually by
+ * way of a command-line argument. An #EShellBackend should listen
+ * for this signal and try to handle the URI, usually by opening an
+ * editor window for the identified resource.
+ *
+ * Returns: %TRUE if the URI could be handled, %FALSE otherwise
+ **/
+ signals[HANDLE_URI] = g_signal_new (
+ "handle-uri",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, g_signal_accumulator_true_handled, NULL,
+ e_marshal_BOOLEAN__STRING,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_STRING);
+
+ /**
+ * EShell::prepare-for-offline
+ * @shell: the #EShell which emitted the signal
+ * @activity: the #EActivity for offline preparations
+ *
+ * Emitted when the user elects to work offline. An #EShellBackend
+ * should listen for this signal and make preparations for working
+ * in offline mode.
+ *
+ * If preparations for working offline cannot immediately be
+ * completed (such as when synchronizing with a remote server),
+ * the #EShellBackend should reference the @activity until
+ * preparations are complete, and then unreference the @activity.
+ * This will delay Evolution from actually going to offline mode
+ * until all backends have unreferenced @activity.
+ **/
+ signals[PREPARE_FOR_OFFLINE] = g_signal_new (
+ "prepare-for-offline",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+
+ /**
+ * EShell::prepare-for-online
+ * @shell: the #EShell which emitted the signal
+ * @activity: the #EActivity for offline preparations
+ *
+ * Emitted when the user elects to work online. An #EShellBackend
+ * should listen for this signal and make preparations for working
+ * in online mode.
+ *
+ * If preparations for working online cannot immediately be
+ * completed (such as when re-connecting to a remote server), the
+ * #EShellBackend should reference the @activity until preparations
+ * are complete, and then unreference the @activity. This will
+ * delay Evolution from actually going to online mode until all
+ * backends have unreferenced @activity.
+ **/
+ signals[PREPARE_FOR_ONLINE] = g_signal_new (
+ "prepare-for-online",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+
+ /**
+ * EShell::prepare-for-quit
+ * @shell: the #EShell which emitted the signal
+ * @activity: the #EActivity for quit preparations
+ *
+ * Emitted when the user elects to quit the application, after
+ * #EShell::quit-requested. An #EShellBackend should listen for
+ * this signal and make preparations for shutting down.
+ *
+ * If preparations for shutting down cannot immediately be completed
+ * (such as when there are uncompleted network operations), the
+ * #EShellBackend should reference the @activity until preparations
+ * are complete, and then unreference the @activity. This will
+ * delay Evolution from actually shutting down until all backends
+ * have unreferenced @activity.
+ **/
+ signals[PREPARE_FOR_QUIT] = g_signal_new (
+ "prepare-for-quit",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+
+ /**
+ * EShell::quit-requested
+ * @shell: the #EShell which emitted the signal
+ *
+ * Emitted when the user elects to quit the application, before
+ * #EShell::prepare-for-quit.
+ *
+ * #EShellBackend<!-- -->s and editor windows can listen for
+ * this signal to prompt the user to save changes or finish
+ * scheduled operations immediately (such as sending mail in
+ * Outbox). If the user elects to cancel, the signal handler
+ * should call e_shell_cancel_quit() to abort the quit.
+ **/
+ signals[QUIT_REQUESTED] = g_signal_new (
+ "quit-requested",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * EShell::send-receive
+ * @shell: the #EShell which emitted the signal
+ * @parent: a parent #GtkWindow
+ *
+ * Emitted when the user chooses the "Send / Receive" action.
+ * The parent window can be used for showing transient windows.
+ **/
+ signals[SEND_RECEIVE] = g_signal_new (
+ "send-receive",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_WINDOW);
+
+ /**
+ * EShell::window-created
+ * @shell: the #EShell which emitted the signal
+ * @window: the newly created #GtkWindow
+ *
+ * Emitted when @shell begins watching a newly created window.
+ **/
+ signals[WINDOW_CREATED] = g_signal_new (
+ "window-created",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_WINDOW);
+
+ /**
+ * EShell::window-destroyed
+ * @shell: the #EShell which emitted the signal
+ *
+ * Emitted when a watched is destroyed.
+ **/
+ signals[WINDOW_DESTROYED] = g_signal_new (
+ "window-destroyed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* Install some application-wide settings. */
+
+ e_shell_settings_install_property (
+ g_param_spec_string (
+ "file-chooser-folder",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
}
-/**
- * e_shell_create_window:
- * @shell: The shell for which to create a new window.
- * @component_id: Id or alias of the component to display in the new window.
- * @template_window: Window from which to copy the window settings (can be %NULL).
- *
- * Create a new window for @uri.
- *
- * Return value: The new window.
- **/
-EShellWindow *
-e_shell_create_window (EShell *shell,
- const gchar *component_id,
- EShellWindow *template_window)
+static void
+shell_init (EShell *shell)
{
- EShellWindow *window;
+ GHashTable *backends_by_name;
+ GHashTable *backends_by_scheme;
+ EggSMClient *sm_client;
- /* FIXME need to actually copy settings from template_window. */
+ shell->priv = E_SHELL_GET_PRIVATE (shell);
- g_return_val_if_fail (shell != NULL, NULL);
- g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ backends_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+ backends_by_scheme = g_hash_table_new (g_str_hash, g_str_equal);
- window = E_SHELL_WINDOW (e_shell_window_new (shell, component_id));
+ shell->priv->settings = g_object_new (E_TYPE_SHELL_SETTINGS, NULL);
+ shell->priv->gconf_client = gconf_client_get_default ();
+ shell->priv->preferences_window = e_preferences_window_new ();
+ shell->priv->backends_by_name = backends_by_name;
+ shell->priv->backends_by_scheme = backends_by_scheme;
+ shell->priv->safe_mode = e_file_lock_exists ();
- g_signal_connect (window, "delete_event", G_CALLBACK (window_delete_event_cb), shell);
- g_object_weak_ref (G_OBJECT (window), window_weak_notify, shell);
- shell->priv->windows = g_list_prepend (shell->priv->windows, window);
+ g_object_ref_sink (shell->priv->preferences_window);
- g_signal_emit (shell, signals[NEW_WINDOW_CREATED], 0, window);
+#if NM_SUPPORT
+ e_shell_dbus_initialize (shell);
+#endif
- gtk_widget_show (GTK_WIDGET (window));
+ shell_parse_debug_string (shell);
- e_error_default_parent((GtkWindow *)window);
+ g_signal_connect (
+ shell, "notify::online",
+ G_CALLBACK (shell_notify_online_cb), NULL);
- set_interactive (shell, TRUE);
+ /* XXX Do this after creating the EShellSettings instance,
+ * otherwise the GConf bindings will not get set up. */
- if (!session_started) {
- ESEvent *ese;
+ e_shell_settings_install_property_for_key (
+ "start-offline",
+ "/apps/evolution/shell/start_offline");
- session_started = TRUE;
- ese = es_event_peek();
- e_event_emit((EEvent *)ese, "started.done", (EEventTarget *)es_event_target_new_shell(ese, shell));
- }
- return window;
-}
+ e_shell_settings_install_property_for_key (
+ "disable-application-handlers",
+ "/desktop/gnome/lockdown/disable_application_handlers");
-gboolean
-e_shell_request_close_window (EShell *shell,
- EShellWindow *shell_window)
-{
- g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
+ e_shell_settings_install_property_for_key (
+ "disable-command-line",
+ "/desktop/gnome/lockdown/disable_command_line");
- e_shell_save_settings (shell);
+ e_shell_settings_install_property_for_key (
+ "disable-printing",
+ "/desktop/gnome/lockdown/disable_printing");
- if (g_list_length (shell->priv->windows) != 1) {
- /* Not the last window. */
- return TRUE;
+ e_shell_settings_install_property_for_key (
+ "disable-print-setup",
+ "/desktop/gnome/lockdown/disable_print_setup");
+
+ e_shell_settings_install_property_for_key (
+ "disable-save-to-disk",
+ "/desktop/gnome/lockdown/disable_save_to_disk");
+
+ /*** Session Management ***/
+
+ sm_client = egg_sm_client_get ();
+
+ /* Not participating in session saving yet. */
+ egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NO_RESTART);
+
+ g_signal_connect_swapped (
+ sm_client, "quit-requested",
+ G_CALLBACK (shell_sm_quit_requested_cb), shell);
+
+ g_signal_connect_swapped (
+ sm_client, "quit-cancelled",
+ G_CALLBACK (shell_sm_quit_cancelled_cb), shell);
+
+ g_signal_connect_swapped (
+ sm_client, "quit",
+ G_CALLBACK (shell_sm_quit_cb), shell);
+}
+
+GType
+e_shell_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShell),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ UNIQUE_TYPE_APP, "EShell", &type_info, 0);
}
- return e_shell_quit(shell);
+ return type;
}
-#if 0 /* FIXME */
/**
- * e_shell_peek_uri_schema_registry:
- * @shell: An EShell object.
+ * e_shell_get_default:
*
- * Get the schema registry associated to @shell.
+ * Returns the #EShell created by <function>main()</function>.
*
- * Return value: A pointer to the EUriSchemaRegistry associated to @shell.
+ * Try to obtain the #EShell from elsewhere if you can. This function
+ * is intended as a temporary workaround for when that proves difficult.
+ *
+ * Returns: the #EShell singleton
**/
-EUriSchemaRegistry *
-e_shell_peek_uri_schema_registry (EShell *shell)
+EShell *
+e_shell_get_default (void)
{
- g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ /* Emit a warning if we call this too early. */
+ g_return_val_if_fail (default_shell != NULL, NULL);
- return shell->priv->uri_schema_registry;
+ return default_shell;
}
-#endif
/**
- * e_shell_peek_component_registry:
- * @shell:
+ * e_shell_get_shell_backends:
+ * @shell: an #EShell
*
- * Get the component registry associated to @shell.
+ * Returns a list of loaded #EShellBackend instances. The list is
+ * owned by @shell and should not be modified or freed.
*
- * Return value:
+ * Returns: a list of loaded #EShellBackend instances
**/
-EComponentRegistry *
-e_shell_peek_component_registry (EShell *shell)
+GList *
+e_shell_get_shell_backends (EShell *shell)
{
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- return shell->priv->component_registry;
+ return shell->priv->loaded_backends;
}
/**
- * e_shell_save_settings:
- * @shell:
+ * e_shell_get_canonical_name:
+ * @shell: an #EShell
+ * @name: the name or alias of an #EShellBackend
*
- * Save the settings for this shell.
+ * Returns the canonical name for the #EShellBackend whose name or alias
+ * is @name.
*
- * Return value: %TRUE if it worked, %FALSE otherwise. Even if %FALSE is
- * returned, it is possible that at least part of the settings for the windows
- * have been saved.
+ * Returns: the canonical #EShellBackend name
**/
-gboolean
-e_shell_save_settings (EShell *shell)
+const gchar *
+e_shell_get_canonical_name (EShell *shell,
+ const gchar *name)
{
- GConfClient *client;
- gboolean is_offline;
+ EShellBackend *shell_backend;
- is_offline = ( e_shell_get_line_status (shell) == E_SHELL_LINE_STATUS_OFFLINE );
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- client = gconf_client_get_default ();
- gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", is_offline, NULL);
- g_object_unref (client);
+ /* Handle NULL name arguments silently. */
+ if (name == NULL)
+ return NULL;
- return TRUE;
+ shell_backend = e_shell_get_backend_by_name (shell, name);
+
+ if (shell_backend == NULL)
+ return NULL;
+
+ return E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
}
/**
- * e_shell_close_all_windows:
- * @shell:
+ * e_shell_get_backend_by_name:
+ * @shell: an #EShell
+ * @name: the name or alias of an #EShellBackend
+ *
+ * Returns the corresponding #EShellBackend for the given name or alias,
+ * or %NULL if @name is not recognized.
*
- * Destroy all the windows in @shell.
+ * Returns: the #EShellBackend named @name, or %NULL
**/
-void
-e_shell_close_all_windows (EShell *shell)
+EShellBackend *
+e_shell_get_backend_by_name (EShell *shell,
+ const gchar *name)
{
- EShellPrivate *priv;
- GList *p, *pnext;
-
- g_return_if_fail (shell != NULL);
- g_return_if_fail (E_IS_SHELL (shell));
+ GHashTable *hash_table;
- if (shell->priv->windows)
- e_shell_save_settings (shell);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
- priv = shell->priv;
- for (p = priv->windows; p != NULL; p = pnext) {
- pnext = p->next;
+ hash_table = shell->priv->backends_by_name;
- /* Note that this will also remove the window from the list... Hence the
- need for the pnext variable. */
- gtk_widget_destroy (GTK_WIDGET (p->data));
- }
+ return g_hash_table_lookup (hash_table, name);
}
/**
- * e_shell_get_line_status:
- * @shell: A pointer to an EShell object.
+ * e_shell_get_backend_by_scheme:
+ * @shell: an #EShell
+ * @scheme: a URI scheme
*
- * Get the line status for @shell.
+ * Returns the #EShellBackend that implements the given URI scheme,
+ * or %NULL if @scheme is not recognized.
*
- * Return value: The current line status for @shell.
+ * Returns: the #EShellBackend that implements @scheme, or %NULL
**/
-EShellLineStatus
-e_shell_get_line_status (EShell *shell)
+EShellBackend *
+e_shell_get_backend_by_scheme (EShell *shell,
+ const gchar *scheme)
{
- g_return_val_if_fail (shell != NULL, E_SHELL_LINE_STATUS_OFFLINE);
- g_return_val_if_fail (E_IS_SHELL (shell), E_SHELL_LINE_STATUS_OFFLINE);
+ GHashTable *hash_table;
- return shell->priv->line_status;
-}
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (scheme != NULL, NULL);
-/* Offline/online handling. */
+ hash_table = shell->priv->backends_by_scheme;
-static void
-set_line_status_finished(EShell *shell)
+ return g_hash_table_lookup (hash_table, scheme);
+}
+/**
+ * e_shell_get_shell_settings:
+ * @shell: an #EShell
+ *
+ * Returns the #EShellSettings instance for @shell.
+ *
+ * Returns: the #EShellSettings instance for @shell
+ **/
+EShellSettings *
+e_shell_get_shell_settings (EShell *shell)
{
- EShellPrivate *priv = shell->priv;
- ESEvent *ese;
-
- priv->line_status = priv->line_status_working;
-
- e_passwords_set_online (priv->line_status == E_SHELL_LINE_STATUS_ONLINE);
- g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- /** @Event: Shell online state changed
- * @Id: state.changed
- * @Target: ESMenuTargetState
- *
- * This event is emitted whenever the shell online state changes.
- *
- * Only the online and offline states are emitted.
- */
- ese = es_event_peek();
- e_event_emit((EEvent *)ese, "state.changed", (EEventTarget *)es_event_target_new_state(ese, priv->line_status == E_SHELL_LINE_STATUS_ONLINE));
+ return shell->priv->settings;
}
-static void
-set_line_status_complete(EvolutionListener *el, gpointer data)
+/**
+ * e_shell_get_gconf_client:
+ * @shell: an #EShell
+ *
+ * Returns the default #GConfClient. This function is purely for
+ * convenience. The @shell owns the reference so you don't have to.
+ *
+ * Returns: the default #GConfClient
+ **/
+GConfClient *
+e_shell_get_gconf_client (EShell *shell)
{
- EShell *shell = data;
- EShellPrivate *priv = shell->priv;
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- if (priv->line_status_pending > 0) {
- priv->line_status_pending--;
- if (priv->line_status_pending == 0)
- set_line_status_finished(shell);
- }
+ return shell->priv->gconf_client;
}
-void
-e_shell_set_line_status (EShell *shell,
- GNOME_Evolution_ShellState shell_state)
+/**
+ * e_shell_create_shell_window:
+ * @shell: an #EShell
+ * @view_name: name of the initial shell view, or %NULL
+ *
+ * Creates a new #EShellWindow and emits the #EShell::window-created
+ * signal. Use this function instead of e_shell_window_new() so that
+ * @shell can track the window.
+ *
+ * Returns: a new #EShellWindow
+ **/
+GtkWidget *
+e_shell_create_shell_window (EShell *shell,
+ const gchar *view_name)
{
- EShellPrivate *priv;
- GSList *component_infos;
- GSList *p;
- CORBA_Environment ev;
- GConfClient *client;
- gboolean is_online;
- gboolean forced = FALSE;
-
- priv = shell->priv;
-
- if (shell_state == GNOME_Evolution_FORCED_OFFLINE || shell_state == GNOME_Evolution_USER_OFFLINE) {
- is_online = FALSE;
- if (shell_state == GNOME_Evolution_FORCED_OFFLINE)
- forced = TRUE;
- } else
- is_online = TRUE;
+ GtkWidget *shell_window;
+ UniqueMessageData *data;
+ UniqueApp *app;
- if ((is_online && priv->line_status == E_SHELL_LINE_STATUS_ONLINE)
- || (!is_online && priv->line_status == E_SHELL_LINE_STATUS_OFFLINE && !forced))
- return;
-
- /* we use 'going offline' to mean 'changing status' now */
- priv->line_status = E_SHELL_LINE_STATUS_GOING_OFFLINE;
- g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- client = gconf_client_get_default ();
- if (!forced)
- gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", !is_online, NULL);
- g_object_unref (client);
+ app = UNIQUE_APP (shell);
- priv->line_status_working = is_online ? E_SHELL_LINE_STATUS_ONLINE: forced?E_SHELL_LINE_STATUS_FORCED_OFFLINE:E_SHELL_LINE_STATUS_OFFLINE;
- /* we start at 2: setLineStatus could recursively call back, we therefore
- `need to not complete till we're really complete */
- priv->line_status_pending += 2;
+ if (unique_app_is_running (app))
+ goto unique;
- component_infos = e_component_registry_peek_list (priv->component_registry);
- for (p = component_infos; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
+ view_name = e_shell_get_canonical_name (shell, view_name);
- CORBA_exception_init (&ev);
+ /* EShellWindow initializes its active view from a GConf key,
+ * so set the key ahead of time to control the intial view. */
+ if (view_name != NULL) {
+ GConfClient *client;
+ const gchar *key;
+ GError *error = NULL;
- GNOME_Evolution_Component_setLineStatus(info->iface, shell_state, bonobo_object_corba_objref((BonoboObject *)priv->line_status_listener), &ev);
- if (ev._major == CORBA_NO_EXCEPTION)
- priv->line_status_pending++;
+ client = e_shell_get_gconf_client (shell);
+ key = "/apps/evolution/shell/view_defaults/component_id";
+ gconf_client_set_string (client, key, view_name, &error);
- CORBA_exception_free (&ev);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
}
- priv->line_status_pending -= 2;
- if (priv->line_status_pending == 0)
- set_line_status_finished(shell);
-}
+ shell_window = e_shell_window_new (shell, shell->priv->safe_mode);
-gboolean
-e_shell_get_crash_recovery (EShell *shell)
-{
- g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+ gtk_widget_show (shell_window);
- return shell->priv->crash_recovery;
-}
+ return shell_window;
-void
-e_shell_set_crash_recovery (EShell *shell,
- gboolean crash_recovery)
-{
- g_return_if_fail (E_IS_SHELL (shell));
+unique: /* Send a message to the other Evolution process. */
+
+ /* XXX Do something with UniqueResponse? */
- shell->priv->crash_recovery = crash_recovery;
+ if (view_name != NULL) {
+ data = unique_message_data_new ();
+ unique_message_data_set_text (data, view_name, -1);
+ unique_app_send_message (app, UNIQUE_NEW, data);
+ unique_message_data_free (data);
+ } else
+ unique_app_send_message (app, UNIQUE_ACTIVATE, NULL);
+
+ return NULL;
}
-void
-e_shell_send_receive (EShell *shell)
+/**
+ * e_shell_handle_uris:
+ * @shell: an #EShell
+ * @uris: %NULL-terminated list of URIs
+ *
+ * Emits the #EShell::handle-uri signal for each URI.
+ *
+ * Returns: the number of URIs successfully handled
+ **/
+guint
+e_shell_handle_uris (EShell *shell,
+ gchar **uris)
{
- GSList *component_list;
- GSList *p;
+ UniqueApp *app;
+ UniqueMessageData *data;
+ guint n_handled = 0;
+ gint ii;
- g_return_if_fail (E_IS_SHELL (shell));
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+ g_return_val_if_fail (uris != NULL, FALSE);
- component_list = e_component_registry_peek_list (shell->priv->component_registry);
+ app = UNIQUE_APP (shell);
- for (p = component_list; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
- CORBA_Environment ev;
+ if (unique_app_is_running (app))
+ goto unique;
- CORBA_exception_init (&ev);
+ for (ii = 0; uris[ii] != NULL; ii++) {
+ gboolean handled;
- GNOME_Evolution_Component_sendAndReceive (info->iface, &ev);
+ g_signal_emit (
+ shell, signals[HANDLE_URI],
+ 0, uris[ii], &handled);
+ n_handled += handled ? 1 : 0;
+ }
- /* Ignore errors, the components can decide to not implement
- this interface. */
+ return n_handled;
- CORBA_exception_free (&ev);
- }
+unique: /* Send a message to the other Evolution process. */
+
+ /* XXX Do something with UniqueResponse? */
+
+ data = unique_message_data_new ();
+ unique_message_data_set_uris (data, uris);
+ unique_app_send_message (app, UNIQUE_OPEN, data);
+ unique_message_data_free (data);
+
+ /* As far as we're concerned, all URIs have been handled. */
+
+ return g_strv_length (uris);
}
+/**
+ * e_shell_watch_window:
+ * @shell: an #EShell
+ * @window: a #GtkWindow
+ *
+ * Makes @shell "watch" a newly created toplevel window, and emits the
+ * #EShell::window-created signal. All #EShellWindow<!-- -->s should be
+ * watched, along with any editor or viewer windows that may be shown in
+ * response to e_shell_handle_uris(). When the last watched window is
+ * closed, Evolution terminates.
+ **/
void
-e_shell_show_settings (EShell *shell,
- const gchar *type,
- EShellWindow *shell_window)
+e_shell_watch_window (EShell *shell,
+ GtkWindow *window)
{
- EShellPrivate *priv;
+ GList *list;
- g_return_if_fail (shell != NULL);
g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (GTK_IS_WINDOW (window));
- priv = shell->priv;
+ list = shell->priv->watched_windows;
- if (priv->settings_dialog.widget != NULL) {
- gdk_window_show (priv->settings_dialog.widget->window);
- gtk_widget_grab_focus (priv->settings_dialog.widget);
+ /* Ignore duplicates. */
+ if (g_list_find (list, window) != NULL)
return;
- }
- priv->settings_dialog.widget = e_shell_settings_dialog_new ();
+ list = g_list_prepend (list, window);
+ shell->priv->watched_windows = list;
- if (type != NULL)
- e_shell_settings_dialog_show_type (E_SHELL_SETTINGS_DIALOG (priv->settings_dialog.widget), type);
+ unique_app_watch_window (UNIQUE_APP (shell), window);
- g_object_add_weak_pointer (G_OBJECT (priv->settings_dialog.widget), &priv->settings_dialog.pointer);
+ g_signal_connect_swapped (
+ window, "delete-event",
+ G_CALLBACK (shell_window_delete_event_cb), shell);
- gtk_window_set_transient_for (GTK_WINDOW (priv->settings_dialog.widget), GTK_WINDOW (shell_window));
- gtk_widget_show (priv->settings_dialog.widget);
-}
+ g_signal_connect_swapped (
+ window, "focus-in-event",
+ G_CALLBACK (shell_window_focus_in_event_cb), shell);
-const gchar *
-e_shell_construct_result_to_string (EShellConstructResult result)
-{
- switch (result) {
- case E_SHELL_CONSTRUCT_RESULT_OK:
- return _("OK");
- case E_SHELL_CONSTRUCT_RESULT_INVALIDARG:
- return _("Invalid arguments");
- case E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER:
- return _("Cannot register on OAF");
- case E_SHELL_CONSTRUCT_RESULT_NOCONFIGDB:
- return _("Configuration Database not found");
- case E_SHELL_CONSTRUCT_RESULT_GENERICERROR:
- return _("Generic error");
- default:
- return _("Unknown error");
- }
+ g_object_weak_ref (
+ G_OBJECT (window), (GWeakNotify)
+ shell_window_weak_notify_cb, shell);
+
+ g_signal_emit (shell, signals[WINDOW_CREATED], 0, window);
}
-/* timeout handler, so returns TRUE if we can't quit yet */
-static gboolean
-es_run_quit(EShell *shell)
+/**
+ * e_shell_get_watched_windows:
+ * @shell: an #EShell
+ *
+ * Returns a list of windows being watched by @shell. The list is sorted
+ * by the most recently focused window, such that the first instance is the
+ * currently focused window. (Useful for choosing a parent for a transient
+ * window.) The list is owned by @shell and should not be modified or freed.
+ *
+ * Returns: a list of watched windows
+ **/
+GList *
+e_shell_get_watched_windows (EShell *shell)
{
- EShellPrivate *priv;
- GSList *component_infos;
- GSList *sp;
- CORBA_boolean done_quit;
-
- g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
-
- priv = shell->priv;
- priv->preparing_to_quit = TRUE;
-
- component_infos = e_component_registry_peek_list (priv->component_registry);
- done_quit = TRUE;
- for (sp = component_infos; sp != NULL; sp = sp->next) {
- EComponentInfo *info = sp->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- done_quit = GNOME_Evolution_Component_quit(info->iface, &ev);
- if (BONOBO_EX (&ev)) {
- /* The component might not implement the interface, in which case we assume we can quit. */
- done_quit = TRUE;
- }
-
- CORBA_exception_free (&ev);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- if (!done_quit)
- break;
- }
+ return shell->priv->watched_windows;
+}
- if (done_quit) {
- if (priv->quit_timeout) {
- g_source_remove(priv->quit_timeout);
- priv->quit_timeout = 0;
- }
- e_shell_close_all_windows(shell);
- } else if (priv->quit_timeout == 0) {
- priv->quit_timeout = g_timeout_add(500, (GSourceFunc)es_run_quit, shell);
- }
+/**
+ * e_shell_send_receive:
+ * @shell: an #EShell
+ * @parent: the parent #GtkWindow
+ *
+ * Emits the #EShell::send-receive signal.
+ **/
+void
+e_shell_send_receive (EShell *shell,
+ GtkWindow *parent)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (GTK_IS_WINDOW (parent));
- return !done_quit;
+ g_signal_emit (shell, signals[SEND_RECEIVE], 0, parent);
}
+/**
+ * e_shell_get_network_available:
+ * @shell: an #EShell
+ *
+ * Returns %TRUE if a network is available.
+ *
+ * Returns: %TRUE if a network is available
+ **/
gboolean
-e_shell_can_quit (EShell *shell)
+e_shell_get_network_available (EShell *shell)
{
- EShellPrivate *priv;
- GSList *component_infos;
- GSList *sp;
- CORBA_boolean can_quit;
-
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- priv = shell->priv;
-
- if (priv->preparing_to_quit)
- return FALSE;
-
- component_infos = e_component_registry_peek_list (priv->component_registry);
- can_quit = TRUE;
- for (sp = component_infos; sp != NULL; sp = sp->next) {
- EComponentInfo *info = sp->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
+ return shell->priv->network_available;
+}
- can_quit = GNOME_Evolution_Component_requestQuit (info->iface, &ev);
- if (BONOBO_EX (&ev)) {
- /* The component might not implement the interface, in which case we assume we can quit. */
- can_quit = TRUE;
- }
+/**
+ * e_shell_set_network_available:
+ * @shell: an #EShell
+ * @network_available: whether a network is available
+ *
+ * Sets whether a network is available. This is usually called in
+ * response to a status change signal from NetworkManager. If the
+ * network becomes unavailable while #EShell:online is %TRUE, the
+ * @shell will force #EShell:online to %FALSE until the network
+ * becomes available again.
+ **/
+void
+e_shell_set_network_available (EShell *shell,
+ gboolean network_available)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
- CORBA_exception_free (&ev);
+ if (network_available == shell->priv->network_available)
+ return;
- if (! can_quit)
- break;
+ shell->priv->network_available = network_available;
+ g_object_notify (G_OBJECT (shell), "network-available");
+
+ /* If we're being forced offline, perhaps due to a network outage,
+ * reconnect automatically when the network becomes available. */
+ if (!network_available && shell->priv->online) {
+ g_message ("Network disconnected. Forced offline.");
+ e_shell_set_online (shell, FALSE);
+ shell->priv->auto_reconnect = TRUE;
+ } else if (network_available && shell->priv->auto_reconnect) {
+ g_message ("Connection established. Going online.");
+ e_shell_set_online (shell, TRUE);
+ shell->priv->auto_reconnect = FALSE;
}
-
- return can_quit;
}
+/**
+ * e_shell_get_online:
+ * @shell: an #EShell
+ *
+ * Returns %TRUE if Evolution is online, %FALSE if Evolution is offline.
+ * Evolution may be offline because the user elected to work offline, or
+ * because the network has become unavailable.
+ *
+ * Returns: %TRUE if Evolution is online
+ **/
gboolean
-e_shell_do_quit (EShell *shell)
+e_shell_get_online (EShell *shell)
{
- EShellPrivate *priv;
- GList *p;
- gboolean can_quit;
-
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- priv = shell->priv;
-
- if (priv->preparing_to_quit)
- return FALSE;
-
- for (p = shell->priv->windows; p != NULL; p = p->next) {
- gtk_widget_set_sensitive (GTK_WIDGET (p->data), FALSE);
-
- if (p == shell->priv->windows)
- e_shell_window_save_defaults (p->data);
- }
+ return shell->priv->online;
+}
- can_quit = !es_run_quit (shell);
+/**
+ * e_shell_set_online:
+ * @shell: an #EShell
+ * @online: %TRUE to go online, %FALSE to go offline
+ *
+ * Asynchronously places Evolution in online or offline mode.
+ **/
+void
+e_shell_set_online (EShell *shell,
+ gboolean online)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
- /* Mark a safe quit by destroying the lock. */
- e_file_lock_destroy ();
+ if (online == shell->priv->online)
+ return;
- return can_quit;
+ if (online)
+ shell_prepare_for_online (shell);
+ else
+ shell_prepare_for_offline (shell);
}
-gboolean
-e_shell_quit (EShell *shell)
+/**
+ * e_shell_get_preferences_window:
+ * @shell: an #EShell
+ *
+ * Returns the Evolution Preferences window.
+ *
+ * Returns: the preferences window
+ **/
+GtkWidget *
+e_shell_get_preferences_window (EShell *shell)
{
- return e_shell_can_quit (shell) && e_shell_do_quit (shell);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ return shell->priv->preferences_window;
}
/**
- * gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
- * Function used in @ref e_shell_foreach_shell_window.
- * @param shell Pointer to EShell.
- * @param window Pointer to EShellWindow.
- * @param user_data User's data passed to @ref main_shell_foreach_shell_window.
- * @return TRUE if need to go to next window, FALSE when stop looking for next window.
+ * e_shell_event:
+ * @shell: an #EShell
+ * @event_name: the name of the event
+ * @event_data: data associated with the event
+ *
+ * The #EShell::event signal acts as a cheap mechanism for broadcasting
+ * events to the rest of the application, such as new mail arriving. The
+ * @event_name is used as the signal detail, and @event_data may point to
+ * an object or data structure associated with the event.
**/
+void
+e_shell_event (EShell *shell,
+ const gchar *event_name,
+ gpointer event_data)
+{
+ GQuark detail;
+
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (event_name != NULL);
+
+ detail = g_quark_from_string (event_name);
+ g_signal_emit (shell, signals[EVENT], detail, event_data);
+}
-/**
- * e_shell_foreach_shell_window
- * This will call function callback for all known EShellWindow of main shell.
- * When there is no shell active, then this will do nothing.
- * @param shell EShell instance.
- * @param func Function to be called.
- * @param user_data User data to pass to func.
- **/
void
-e_shell_foreach_shell_window (EShell *shell, EMainShellFunc func, gpointer user_data)
+e_shell_quit (EShell *shell)
{
- EShellPrivate *priv;
- GList *p;
+ g_return_if_fail (E_IS_SHELL (shell));
- if (!shell)
+ if (!shell_request_quit (shell))
return;
- priv = shell->priv;
+ shell_prepare_for_quit (shell);
+}
- for (p = priv->windows; p != NULL; p = p->next) {
- EShellWindow *window;
+/**
+ * e_shell_cancel_quit:
+ * @shell: an #EShell
+ *
+ * This function may only be called from #EShell::quit-requested signal
+ * handlers to prevent Evolution from quitting. Calling this will stop
+ * further emission of the #EShell::quit-requested signal.
+ *
+ * Note: This function has no effect during a #EShell::prepare-for-quit
+ * signal emission.
+ **/
+void
+e_shell_cancel_quit (EShell *shell)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
- window = E_SHELL_WINDOW (p->data);
+ shell->priv->quit_cancelled = TRUE;
- if (window && !func (shell, window, user_data))
- break;
- }
+ g_signal_stop_emission (shell, signals[QUIT_REQUESTED], 0);
}
-
-BONOBO_TYPE_FUNC_FULL (EShell, GNOME_Evolution_Shell, PARENT_TYPE, e_shell)
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 00f4266562..818607e1fb 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -1,4 +1,6 @@
/*
+ * e-shell.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,126 +15,98 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_SHELL_H_
-#define _E_SHELL_H_
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-object.h>
+/**
+ * SECTION: e-shell
+ * @short_description: the backbone of Evolution
+ * @include: shell/e-shell.h
+ **/
+
+#ifndef E_SHELL_H
+#define E_SHELL_H
+
+#include <unique/unique.h>
+#include <gconf/gconf-client.h>
+#include <shell/e-shell-common.h>
+#include <shell/e-shell-backend.h>
+#include <shell/e-shell-settings.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL \
+ (e_shell_get_type ())
+#define E_SHELL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL, EShell))
+#define E_SHELL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL, EShellClass))
+#define E_IS_SHELL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL))
+#define E_IS_SHELL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL))
+#define E_SHELL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL, EShellClass))
G_BEGIN_DECLS
-typedef struct _EShell EShell;
+typedef struct _EShell EShell;
+typedef struct _EShellClass EShellClass;
typedef struct _EShellPrivate EShellPrivate;
-typedef struct _EShellClass EShellClass;
-
-#include "Evolution.h"
-
-#include "e-component-registry.h"
-#include "e-shell-window.h"
-
-#define E_TYPE_SHELL (e_shell_get_type ())
-#define E_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL, EShell))
-#define E_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL, EShellClass))
-#define E_IS_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL))
-#define E_IS_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL))
-
-enum _EShellLineStatus {
- E_SHELL_LINE_STATUS_ONLINE,
- E_SHELL_LINE_STATUS_GOING_OFFLINE, /* NB: really means changing state in either direction */
- E_SHELL_LINE_STATUS_OFFLINE,
- E_SHELL_LINE_STATUS_FORCED_OFFLINE
-};
-typedef enum _EShellLineStatus EShellLineStatus;
-
-enum _EShellStartupLineMode {
- E_SHELL_STARTUP_LINE_MODE_CONFIG,
- E_SHELL_STARTUP_LINE_MODE_ONLINE,
- E_SHELL_STARTUP_LINE_MODE_OFFLINE
-};
-typedef enum _EShellStartupLineMode EShellStartupLineMode;
+/**
+ * EShell:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EShell {
- BonoboObject parent;
-
+ UniqueApp parent;
EShellPrivate *priv;
};
struct _EShellClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Shell__epv epv;
-
- void (* no_windows_left) (EShell *shell);
- void (* line_status_changed) (EShell *shell, EShellLineStatus status);
- void (* new_window_created) (EShell *shell, EShellWindow *window);
+ UniqueAppClass parent_class;
};
-/* ID for registering the shell in the OAF name service. */
-#define E_SHELL_OAFIID "OAFIID:GNOME_Evolution_Shell:" BASE_VERSION
-
-enum _EShellConstructResult {
- E_SHELL_CONSTRUCT_RESULT_OK,
- E_SHELL_CONSTRUCT_RESULT_INVALIDARG,
- E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER,
- E_SHELL_CONSTRUCT_RESULT_NOCONFIGDB,
- E_SHELL_CONSTRUCT_RESULT_GENERICERROR
-};
-typedef enum _EShellConstructResult EShellConstructResult;
-
-GType e_shell_get_type (void);
-EShellConstructResult e_shell_construct (EShell *shell,
- const gchar *iid,
- EShellStartupLineMode startup_line_mode);
-EShell *e_shell_new (EShellStartupLineMode startup_line_mode,
- EShellConstructResult *construct_result_return);
-
-gboolean e_shell_attempt_upgrade (EShell *shell);
-
-EShellWindow *e_shell_create_window (EShell *shell,
- const gchar *component_id,
- EShellWindow *template_window);
-gboolean e_shell_request_close_window (EShell *shell,
- EShellWindow *window);
-
-#if 0
-EUriSchemaRegistry *e_shell_peek_uri_schema_registry (EShell *shell);
-#endif
-
-EComponentRegistry *e_shell_peek_component_registry (EShell *shell);
-
-gboolean e_shell_save_settings (EShell *shell);
-void e_shell_close_all_windows (EShell *shell);
-
-EShellLineStatus e_shell_get_line_status (EShell *shell);
-void e_shell_set_line_status (EShell *shell,
- GNOME_Evolution_ShellState shell_state);
-
-gboolean e_shell_get_crash_recovery (EShell *shell);
-void e_shell_set_crash_recovery (EShell *shell,
- gboolean crash_recovery);
-
-void e_shell_send_receive (EShell *shell);
-
-void e_shell_show_settings (EShell *shell,
- const gchar *type,
- EShellWindow *shell_window);
-
-gboolean e_shell_can_quit (EShell *shell);
-gboolean e_shell_do_quit (EShell *shell);
-gboolean e_shell_quit (EShell *shell);
-
-const gchar *e_shell_construct_result_to_string (EShellConstructResult result);
-
-typedef gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
-void e_shell_foreach_shell_window (EShell *shell, EMainShellFunc func, gpointer user_data);
+GType e_shell_get_type (void);
+EShell * e_shell_get_default (void);
+GList * e_shell_get_shell_backends (EShell *shell);
+const gchar * e_shell_get_canonical_name (EShell *shell,
+ const gchar *name);
+EShellBackend * e_shell_get_backend_by_name (EShell *shell,
+ const gchar *name);
+EShellBackend * e_shell_get_backend_by_scheme (EShell *shell,
+ const gchar *scheme);
+EShellSettings *e_shell_get_shell_settings (EShell *shell);
+GConfClient * e_shell_get_gconf_client (EShell *shell);
+GtkWidget * e_shell_create_shell_window (EShell *shell,
+ const gchar *view_name);
+guint e_shell_handle_uris (EShell *shell,
+ gchar **uris);
+void e_shell_watch_window (EShell *shell,
+ GtkWindow *window);
+GList * e_shell_get_watched_windows (EShell *shell);
+void e_shell_send_receive (EShell *shell,
+ GtkWindow *parent);
+gboolean e_shell_get_network_available (EShell *shell);
+void e_shell_set_network_available (EShell *shell,
+ gboolean network_available);
+gboolean e_shell_get_online (EShell *shell);
+void e_shell_set_online (EShell *shell,
+ gboolean online);
+GtkWidget * e_shell_get_preferences_window (EShell *shell);
+void e_shell_event (EShell *shell,
+ const gchar *event_name,
+ gpointer event_data);
+void e_shell_quit (EShell *shell);
+void e_shell_cancel_quit (EShell *shell);
G_END_DECLS
-#endif /* _E_SHELL_H_ */
+#endif /* E_SHELL_H */
diff --git a/shell/e-sidebar.c b/shell/e-sidebar.c
deleted file mode 100644
index 3942de727b..0000000000
--- a/shell/e-sidebar.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-sidebar.h"
-
-#include "e-util/e-util.h"
-
-#include <gconf/gconf-client.h>
-
-typedef struct {
- GtkWidget *button_widget;
- GtkWidget *label;
- GtkWidget *icon;
- GtkWidget *hbox;
- gchar *default_icon_name;
- gint id;
-} Button;
-
-struct _ESidebarPrivate {
- ESidebarMode mode;
- ESidebarMode toolbar_mode;
-
- gboolean show;
-
- GtkWidget *selection_widget;
- GSList *buttons;
-
- guint style_changed_id;
-
- gboolean in_toggle;
-};
-
-enum {
- BUTTON_SELECTED,
- BUTTON_PRESSED,
- NUM_SIGNALS
-};
-
-static guint signals[NUM_SIGNALS] = { 0 };
-
-G_DEFINE_TYPE (ESidebar, e_sidebar, GTK_TYPE_CONTAINER)
-
-#define INTERNAL_MODE(sidebar) (sidebar->priv->mode == E_SIDEBAR_MODE_TOOLBAR ? sidebar->priv->toolbar_mode : sidebar->priv->mode)
-#define H_PADDING 6
-#define V_PADDING 6
-
-/* Utility functions. */
-
-static Button *
-button_new (GtkWidget *button_widget,
- GtkWidget *label,
- GtkWidget *icon,
- GtkWidget *hbox,
- gint id)
-{
- Button *button = g_new (Button, 1);
- const gchar *icon_name;
-
- button->button_widget = button_widget;
- button->label = label;
- button->icon = icon;
- button->hbox = hbox;
- button->id = id;
-
- gtk_image_get_icon_name (GTK_IMAGE (icon), &icon_name, NULL);
- button->default_icon_name = g_strdup (icon_name);
-
- g_object_ref (button_widget);
- g_object_ref (label);
- g_object_ref (icon);
- g_object_ref (hbox);
-
- return button;
-}
-
-static void
-button_free (Button *button)
-{
- g_object_unref (button->button_widget);
- g_object_unref (button->label);
- g_object_unref (button->icon);
- g_object_unref (button->hbox);
- g_free (button->default_icon_name);
- g_free (button);
-}
-
-static void
-update_buttons (ESidebar *sidebar, gint new_selected_id)
-{
- GSList *p;
-
- sidebar->priv->in_toggle = TRUE;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->id == new_selected_id)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), FALSE);
- }
-
- sidebar->priv->in_toggle = FALSE;
-}
-
-/* Callbacks. */
-
-static void
-button_toggled_callback (GtkToggleButton *toggle_button,
- ESidebar *sidebar)
-{
- gint id = 0;
- gboolean is_active = FALSE;
- GSList *p;
-
- if (sidebar->priv->in_toggle)
- return;
-
- sidebar->priv->in_toggle = TRUE;
-
- if (gtk_toggle_button_get_active (toggle_button))
- is_active = TRUE;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->button_widget != GTK_WIDGET (toggle_button)) {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), FALSE);
- } else {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), TRUE);
- id = button->id;
- }
- }
-
- sidebar->priv->in_toggle = FALSE;
-
- if (is_active)
- g_signal_emit (sidebar, signals[BUTTON_SELECTED], 0, id);
-}
-
-static gboolean
-button_pressed_callback (GtkToggleButton *toggle_button,
- GdkEventButton *event,
- ESidebar *sidebar)
-{
- gboolean return_val = FALSE;
- GSList *p;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->button_widget == GTK_WIDGET (toggle_button))
- g_signal_emit (sidebar, signals [BUTTON_PRESSED],
- 0, event, button->id, &return_val);
- }
-
- return return_val;
-}
-
-static gboolean
-button_query_tooltip (GtkWidget *widget,
- gint x,
- gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip,
- ESidebar *sidebar)
-{
- /* Show the tooltip only if the label is hidden */
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_ICON) {
- gchar *tip;
-
- tip = g_object_get_data (G_OBJECT (widget),
- "ESidebar:button-tooltip");
- if (tip) {
- gtk_tooltip_set_text (tooltip, tip);
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* Layout. */
-
-static gint
-layout_buttons (ESidebar *sidebar)
-{
- GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation;
- ESidebarMode mode;
- gboolean icons_only;
- gint num_btns = g_slist_length (sidebar->priv->buttons), btns_per_row;
- GSList **rows, *p;
- Button *button;
- gint row_number;
- gint max_btn_width = 0, max_btn_height = 0;
- gint row_last;
- gint x, y;
- gint i;
-
- y = allocation->y + allocation->height - V_PADDING - 1;
-
- if (num_btns == 0)
- return y;
-
- mode = INTERNAL_MODE (sidebar);
- icons_only = (mode == E_SIDEBAR_MODE_ICON);
-
- /* Figure out the max width and height */
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- GtkRequisition requisition;
-
- button = p->data;
- gtk_widget_size_request (GTK_WIDGET (button->button_widget), &requisition);
-
- max_btn_height = MAX (max_btn_height, requisition.height);
- max_btn_width = MAX (max_btn_width, requisition.width);
- }
-
- /* Figure out how many rows and columns we'll use. */
- btns_per_row = allocation->width / (max_btn_width + H_PADDING);
- if (!icons_only) {
- /* If using text buttons, we want to try to have a
- * completely filled-in grid, but if we can't, we want
- * the odd row to have just a single button.
- */
- while (num_btns % btns_per_row > 1)
- btns_per_row--;
- }
-
- /* Assign buttons to rows */
- rows = g_new0 (GSList *, num_btns / btns_per_row + 1);
-
- if (!icons_only && num_btns % btns_per_row != 0) {
- button = sidebar->priv->buttons->data;
- rows [0] = g_slist_append (rows [0], button->button_widget);
-
- p = sidebar->priv->buttons->next;
- row_number = p ? 1 : 0;
- } else {
- p = sidebar->priv->buttons;
- row_number = 0;
- }
-
- for (; p != NULL; p = p->next) {
- button = p->data;
-
- if (g_slist_length (rows [row_number]) == btns_per_row)
- row_number ++;
-
- rows [row_number] = g_slist_append (rows [row_number], button->button_widget);
- }
-
- row_last = row_number;
-
- /* Layout the buttons. */
- for (i = row_last; i >= 0; i --) {
- gint len, extra_width;
-
- y -= max_btn_height;
- x = H_PADDING + allocation->x;
- len = g_slist_length (rows[i]);
- if (mode == E_SIDEBAR_MODE_TEXT || mode == E_SIDEBAR_MODE_BOTH)
- extra_width = (allocation->width - (len * max_btn_width ) - (len * H_PADDING)) / len;
- else
- extra_width = 0;
- for (p = rows [i]; p != NULL; p = p->next) {
- GtkAllocation child_allocation;
-
- child_allocation.x = x;
- child_allocation.y = y;
- child_allocation.width = max_btn_width + extra_width;
- child_allocation.height = max_btn_height;
-
- gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation);
-
- x += child_allocation.width + H_PADDING;
- }
-
- y -= V_PADDING;
- }
-
- for (i = 0; i <= row_last; i ++)
- g_slist_free (rows [i]);
- g_free (rows);
-
- return y;
-}
-
-static void
-do_layout (ESidebar *sidebar)
-{
- GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation;
- GtkAllocation child_allocation;
- gint y;
-
- if (sidebar->priv->show)
- y = layout_buttons (sidebar);
- else
- y = allocation->y + allocation->height;
-
- /* Place the selection widget. */
- child_allocation.x = allocation->x;
- child_allocation.y = allocation->y;
- child_allocation.width = allocation->width;
- child_allocation.height = y - allocation->y;
-
- gtk_widget_size_allocate (sidebar->priv->selection_widget, & child_allocation);
-}
-
-/* GtkContainer methods. */
-
-static void
-impl_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- ESidebar *sidebar = E_SIDEBAR (container);
- GSList *p;
-
- if (sidebar->priv->selection_widget != NULL)
- (* callback) (sidebar->priv->selection_widget, callback_data);
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- GtkWidget *widget = ((Button *) p->data)->button_widget;
- (* callback) (widget, callback_data);
- }
-}
-
-static void
-impl_remove (GtkContainer *container,
- GtkWidget *widget)
-{
- ESidebar *sidebar = E_SIDEBAR (container);
- GSList *p;
-
- if (widget == sidebar->priv->selection_widget) {
- e_sidebar_set_selection_widget (sidebar, NULL);
- return;
- }
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- GtkWidget *button_widget = ((Button *) p->data)->button_widget;
-
- if (button_widget == widget) {
- gtk_widget_unparent (button_widget);
- sidebar->priv->buttons = g_slist_remove_link (sidebar->priv->buttons, p);
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
- break;
- }
- }
-}
-
-/* GtkWidget methods. */
-
-static void
-impl_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- ESidebar *sidebar = E_SIDEBAR (widget);
- GSList *p;
-
- if (sidebar->priv->selection_widget == NULL) {
- requisition->width = 2 * H_PADDING;
- requisition->height = 2 * V_PADDING;
- } else {
- gtk_widget_size_request (sidebar->priv->selection_widget, requisition);
- }
-
- if (!sidebar->priv->show)
- return;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
- GtkRequisition button_requisition;
-
- gtk_widget_size_request (button->button_widget, &button_requisition);
-
- requisition->width = MAX (requisition->width, button_requisition.width + 2 * H_PADDING);
- requisition->height += button_requisition.height + V_PADDING;
- }
-}
-
-static void
-impl_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- widget->allocation = *allocation;
-
- do_layout (E_SIDEBAR (widget));
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- ESidebarPrivate *priv = E_SIDEBAR (object)->priv;
- GConfClient *gconf_client = gconf_client_get_default ();
-
- g_slist_foreach (priv->buttons, (GFunc) button_free, NULL);
- g_slist_free (priv->buttons);
- priv->buttons = NULL;
-
- if (priv->style_changed_id) {
- gconf_client_notify_remove (gconf_client, priv->style_changed_id);
- priv->style_changed_id = 0;
- }
-
- g_object_unref (gconf_client);
-
- (* G_OBJECT_CLASS (e_sidebar_parent_class)->dispose) (object);
-}
-
-static gboolean
-boolean_handled_accumulator (GSignalInvocationHint *ihint,
- GValue *return_accu,
- const GValue *handler_return,
- gpointer dummy)
-{
- gboolean handled;
-
- handled = g_value_get_boolean (handler_return);
- g_value_set_boolean (return_accu, handled);
-
- return !handled;
-}
-
-static void
-impl_finalize (GObject *object)
-{
- ESidebarPrivate *priv = E_SIDEBAR (object)->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_sidebar_parent_class)->finalize) (object);
-}
-
-/* Initialization. */
-
-static void
-e_sidebar_class_init (ESidebarClass *klass)
-{
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- container_class->forall = impl_forall;
- container_class->remove = impl_remove;
-
- widget_class->size_request = impl_size_request;
- widget_class->size_allocate = impl_size_allocate;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- signals[BUTTON_SELECTED]
- = g_signal_new ("button_selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ESidebarClass, button_selected),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
- signals[BUTTON_PRESSED]
- = g_signal_new ("button_pressed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESidebarClass, button_pressed),
- boolean_handled_accumulator, NULL,
- e_marshal_NONE__POINTER_INT,
- G_TYPE_BOOLEAN, 2,
- G_TYPE_POINTER, G_TYPE_INT);
-}
-
-static void
-e_sidebar_init (ESidebar *sidebar)
-{
- ESidebarPrivate *priv;
-
- GTK_WIDGET_SET_FLAGS (sidebar, GTK_NO_WINDOW);
-
- priv = g_new0 (ESidebarPrivate, 1);
- sidebar->priv = priv;
-
- priv->mode = E_SIDEBAR_MODE_TEXT;
-}
-
-GtkWidget *
-e_sidebar_new (void)
-{
- ESidebar *sidebar = g_object_new (e_sidebar_get_type (), NULL);
-
- return GTK_WIDGET (sidebar);
-}
-
-void
-e_sidebar_set_selection_widget (ESidebar *sidebar, GtkWidget *widget)
-{
- if (sidebar->priv->selection_widget != NULL)
- gtk_widget_unparent (sidebar->priv->selection_widget);
-
- sidebar->priv->selection_widget = widget;
-
- if (widget != NULL)
- gtk_widget_set_parent (widget, GTK_WIDGET (sidebar));
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-void
-e_sidebar_add_button (ESidebar *sidebar,
- const gchar *label,
- const gchar *tooltips,
- const gchar *icon_name,
- gint id)
-{
- GtkWidget *button_widget;
- GtkWidget *hbox;
- GtkWidget *icon_widget;
- GtkWidget *label_widget;
-
- button_widget = gtk_toggle_button_new ();
- if (sidebar->priv->show)
- gtk_widget_show (button_widget);
- g_signal_connect (button_widget, "toggled", G_CALLBACK (button_toggled_callback), sidebar);
- g_signal_connect (button_widget, "button_press_event",
- G_CALLBACK (button_pressed_callback), sidebar);
-
- hbox = gtk_hbox_new (FALSE, 3);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
- gtk_widget_show (hbox);
-
- icon_widget = gtk_image_new_from_icon_name (
- icon_name, GTK_ICON_SIZE_BUTTON);
- gtk_widget_show (icon_widget);
-
- label_widget = gtk_label_new (label);
- gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
- gtk_widget_show (label_widget);
-
- g_object_set_data_full (G_OBJECT (button_widget),
- "ESidebar:button-tooltip",
- g_strdup (tooltips),
- g_free);
- gtk_widget_set_has_tooltip (button_widget, TRUE);
- g_signal_connect (button_widget, "query-tooltip",
- G_CALLBACK (button_query_tooltip), sidebar);
-
- switch (INTERNAL_MODE (sidebar)) {
- case E_SIDEBAR_MODE_TEXT:
- gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0);
- break;
- case E_SIDEBAR_MODE_ICON:
- gtk_box_pack_start (GTK_BOX (hbox), icon_widget, TRUE, TRUE, 0);
- break;
- case E_SIDEBAR_MODE_BOTH:
- default:
- gtk_box_pack_start (GTK_BOX (hbox), icon_widget, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0);
- break;
- }
-
- gtk_container_add (GTK_CONTAINER (button_widget), hbox);
-
- sidebar->priv->buttons = g_slist_append (sidebar->priv->buttons, button_new (button_widget, label_widget, icon_widget, hbox, id));
- gtk_widget_set_parent (button_widget, GTK_WIDGET (sidebar));
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-/**
- * e_sidebar_change_button_icon
- * @sidebar: an #ESidebar
- * @icon_name: button icon name, or %NULL
- * @button_id: component's button ID, for which change the icon.
- *
- * This will change icon in icon_widget of the button of known component.
- * You cannot change icon as in a stack, only one default icon will be stored.
- **/
-void
-e_sidebar_change_button_icon (ESidebar *sidebar, const gchar *icon_name, gint button_id)
-{
- GSList *p;
-
- g_return_if_fail (sidebar != NULL);
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->id == button_id) {
- if (!button->icon)
- break;
-
- if (icon_name == NULL)
- icon_name = button->default_icon_name;
-
- gtk_image_set_from_icon_name (
- GTK_IMAGE (button->icon),
- icon_name, GTK_ICON_SIZE_BUTTON);
-
- break;
- }
- }
-}
-
-void
-e_sidebar_select_button (ESidebar *sidebar, gint id)
-{
- update_buttons (sidebar, id);
-
- g_signal_emit (sidebar, signals[BUTTON_SELECTED], 0, id);
-}
-
-ESidebarMode
-e_sidebar_get_mode (ESidebar *sidebar)
-{
- return sidebar->priv->mode;
-}
-
-static GConfEnumStringPair toolbar_styles[] = {
- { E_SIDEBAR_MODE_TEXT, "text" },
- { E_SIDEBAR_MODE_ICON, "icons" },
- { E_SIDEBAR_MODE_BOTH, "both" },
- { E_SIDEBAR_MODE_BOTH, "both-horiz" },
- { E_SIDEBAR_MODE_BOTH, "both_horiz" },
- { -1, NULL }
-};
-
-static void
-set_mode_internal (ESidebar *sidebar, ESidebarMode mode )
-{
- GSList *p;
-
- if (mode == INTERNAL_MODE (sidebar))
- return;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- switch (mode) {
- case E_SIDEBAR_MODE_TEXT:
- gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon);
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_ICON) {
- gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0);
- gtk_widget_show (button->label);
- }
- break;
- case E_SIDEBAR_MODE_ICON:
- gtk_container_remove(GTK_CONTAINER (button->hbox), button->label);
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_TEXT) {
- gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, TRUE, TRUE, 0);
- gtk_widget_show (button->icon);
- } else
- gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon,
- "expand", TRUE,
- NULL);
- break;
- case E_SIDEBAR_MODE_BOTH:
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_TEXT) {
- gtk_container_remove (GTK_CONTAINER (button->hbox), button->label);
- gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, FALSE, TRUE, 0);
- gtk_widget_show (button->icon);
- } else {
- gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon,
- "expand", FALSE,
- NULL);
- }
-
- gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0);
- gtk_widget_show (button->label);
- break;
- default:
- break;
- }
- }
-}
-
-static void
-style_changed_notify (GConfClient *gconf, guint id, GConfEntry *entry, gpointer data)
-{
- ESidebar *sidebar = data;
- gchar *val;
- gint mode;
-
- val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL);
- if (val == NULL || !gconf_string_to_enum (toolbar_styles, val, &mode))
- mode = E_SIDEBAR_MODE_BOTH;
- g_free(val);
-
- set_mode_internal (E_SIDEBAR (sidebar), mode);
- sidebar->priv->toolbar_mode = mode;
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-void
-e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode)
-{
- GConfClient *gconf_client = gconf_client_get_default ();
-
- if (sidebar->priv->mode == mode)
- return;
-
- if (sidebar->priv->mode == E_SIDEBAR_MODE_TOOLBAR) {
- if (sidebar->priv->style_changed_id) {
- gconf_client_notify_remove (gconf_client, sidebar->priv->style_changed_id);
- sidebar->priv->style_changed_id = 0;
- }
- }
-
- if (mode != E_SIDEBAR_MODE_TOOLBAR) {
- set_mode_internal (sidebar, mode);
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
- } else {
- /* This is a little bit tricky, toolbar mode is more
- * of a meta-mode where the actual mode is dictated by
- * the gnome toolbar setting, so that is why we have
- * the is_toolbar_mode bool - it tracks the toolbar
- * mode while the mode member is the actual look and
- * feel */
- sidebar->priv->style_changed_id = gconf_client_notify_add (gconf_client,
- "/desktop/gnome/interface/toolbar_style",
- style_changed_notify, sidebar, NULL, NULL);
- style_changed_notify (gconf_client, 0, NULL, sidebar);
- }
-
- g_object_unref (gconf_client);
-
- sidebar->priv->mode = mode;
-}
-
-void
-e_sidebar_set_show_buttons (ESidebar *sidebar, gboolean show)
-{
- GSList *p;
-
- if (sidebar->priv->show == show)
- return;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (show)
- gtk_widget_show (button->button_widget);
- else
- gtk_widget_hide (button->button_widget);
- }
-
- sidebar->priv->show = show;
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-gboolean
-e_sidebar_get_show_buttons (ESidebar *sidebar)
-{
- return sidebar->priv->show;
-}
diff --git a/shell/e-sidebar.h b/shell/e-sidebar.h
deleted file mode 100644
index 9e450f8e7b..0000000000
--- a/shell/e-sidebar.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_SIDEBAR_H_
-#define _E_SIDEBAR_H_
-
-#include <gtk/gtk.h>
-
-#define E_TYPE_SIDEBAR (e_sidebar_get_type ())
-#define E_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SIDEBAR, ESidebar))
-#define E_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SIDEBAR, ESidebarClass))
-#define E_IS_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SIDEBAR))
-#define E_IS_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SIDEBAR))
-
-typedef struct _ESidebar ESidebar;
-typedef struct _ESidebarPrivate ESidebarPrivate;
-typedef struct _ESidebarClass ESidebarClass;
-
-typedef enum {
- E_SIDEBAR_MODE_TEXT,
- E_SIDEBAR_MODE_ICON,
- E_SIDEBAR_MODE_BOTH,
- E_SIDEBAR_MODE_TOOLBAR
-} ESidebarMode;
-
-struct _ESidebar {
- GtkContainer parent;
-
- ESidebarPrivate *priv;
-};
-
-struct _ESidebarClass {
- GtkContainerClass parent_class;
-
- /* signals */
- void (* button_selected) (ESidebar *sidebar, gint id);
- void (* button_pressed) (ESidebar *sidebar, GdkEventButton *event, gint id);
-};
-
-GType e_sidebar_get_type (void);
-GtkWidget *e_sidebar_new (void);
-
-void e_sidebar_set_selection_widget (ESidebar *sidebar,
- GtkWidget *widget);
-
-void e_sidebar_add_button (ESidebar *sidebar,
- const gchar *label,
- const gchar *tooltips,
- const gchar *icon_name,
- gint id);
-
-void e_sidebar_select_button (ESidebar *sidebar,
- gint id);
-
-void e_sidebar_change_button_icon (ESidebar *sidebar,
- const gchar *icon_name,
- gint button_id);
-
-ESidebarMode e_sidebar_get_mode (ESidebar *sidebar);
-void e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode);
-
-void e_sidebar_set_show_buttons (ESidebar *sidebar, gboolean show);
-gboolean e_sidebar_get_show_buttons (ESidebar *sidebar);
-
-#endif /* _E_SIDEBAR_H_ */
diff --git a/shell/e-user-creatable-items-handler.c b/shell/e-user-creatable-items-handler.c
deleted file mode 100644
index 6fef2b7309..0000000000
--- a/shell/e-user-creatable-items-handler.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-user-creatable-items-handler.h"
-#include <e-util/e-icon-factory.h>
-#include "Evolution.h"
-
-#include "e-util/e-corba-utils.h"
-#include "misc/e-combo-button.h"
-
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-control.h>
-
-#include <gtk/gtk.h>
-#include <glib/gi18n-lib.h>
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include <gconf/gconf-client.h>
-
-struct _Component {
- gchar *id, *alias;
- GNOME_Evolution_Component component;
- GNOME_Evolution_CreatableItemTypeList *type_list;
-};
-typedef struct _Component Component;
-
-/* Representation of a single menu item. */
-struct _MenuItem {
- const gchar *label;
- gchar shortcut;
- gchar *verb;
- gchar *tooltip;
- gchar *component;
- GdkPixbuf *icon;
- GdkPixbuf *icon_toolbar;
-};
-typedef struct _MenuItem MenuItem;
-
-struct _EUserCreatableItemsHandlerPrivate {
- /* This component's alias */
- gchar *this_component;
-
- /* For creating items on the view */
- EUserCreatableItemsHandlerCreate create_local;
- gpointer create_data;
-
- /* The components that register user creatable items. */
- GSList *components; /* Component */
-
- /* The "New ..." menu items. */
- GSList *objects; /* MenuItem */
- GSList *folders; /* MenuItem */
-
- /* The default item (the mailer's "message" item). To be used when the
- component in the view we are in doesn't provide a default user
- creatable type. This pointer always points to one of the menu items
- in ->objects. */
- const MenuItem *fallback_menu_item;
- const MenuItem *default_menu_item;
-
- gchar *menu_xml;
- GtkWidget *new_button, *new_menu;
- BonoboControl *new_control;
- GtkAccelGroup *accel_group;
-};
-
-enum {
- PROP_THIS_COMPONENT = 1,
- LAST_PROP
-};
-
-G_DEFINE_TYPE (EUserCreatableItemsHandler, e_user_creatable_items_handler, G_TYPE_OBJECT)
-
-/* Component struct handling. */
-
-static Component *
-component_new (const gchar *id,
- const gchar *component_alias,
- GNOME_Evolution_Component component)
-{
- CORBA_Environment ev;
- Component *new;
-
- CORBA_exception_init (&ev);
-
- new = g_new (Component, 1);
- new->id = g_strdup (id);
- new->alias = g_strdup (component_alias);
-
- new->type_list = GNOME_Evolution_Component__get_userCreatableItems (component, &ev);
- if (BONOBO_EX (&ev))
- new->type_list = NULL;
-
- new->component = component;
- Bonobo_Unknown_ref (new->component, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- new->type_list = NULL;
-
- CORBA_exception_free (&ev);
-
- return new;
-}
-
-static void
-component_free (Component *component)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- Bonobo_Unknown_unref (component->component, &ev);
-
- g_free (component->id);
- g_free (component->alias);
-
- if (component->type_list != NULL)
- CORBA_free (component->type_list);
-
- CORBA_exception_free (&ev);
-
- g_free (component);
-}
-
-static const gchar *component_query =
- "repo_ids.has ('IDL:GNOME/Evolution/Component:" BASE_VERSION "')";
-
-static void
-get_components_from_bonobo (EUserCreatableItemsHandler *handler)
-{
- Bonobo_ServerInfoList *info_list;
- Bonobo_ActivationProperty *property;
- CORBA_Environment ev;
- const gchar *alias;
- gchar *iid;
- GNOME_Evolution_Component corba_component;
- Component *component;
- gint i;
-
- CORBA_exception_init (&ev);
- info_list = bonobo_activation_query (component_query, NULL, &ev);
- if (BONOBO_EX (&ev)) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot query for components: %s\n", ex_text);
- g_free (ex_text);
- CORBA_exception_free (&ev);
- return;
- }
-
- for (i = 0; i < info_list->_length; i++) {
- iid = info_list->_buffer[i].iid;
- corba_component = bonobo_activation_activate_from_id (iid, Bonobo_ACTIVATION_FLAG_EXISTING_ONLY, NULL, &ev);
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- continue;
- }
-
- property = bonobo_server_info_prop_find (&info_list->_buffer[i],
- "evolution:component_alias");
- alias = property ? property->v._u.value_string : "unknown";
-
- component = component_new (iid, alias, corba_component);
- handler->priv->components = g_slist_prepend (handler->priv->components, component);
- }
-
- CORBA_free (info_list);
-}
-
-/* Helper functions. */
-
-static gboolean
-item_is_default (const MenuItem *item,
- const gchar *component)
-{
- if (component == NULL)
- return FALSE;
-
- if (strcmp (item->component, component) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static gchar *
-create_verb (EUserCreatableItemsHandler *handler, gint component_num, const gchar *comp, const gchar *type_id)
-{
- return g_strdup_printf ("EUserCreatableItemsHandler-%s:%d:%s", comp, component_num, type_id);
-}
-
-/* Setting up menu items for the "File -> New" submenu and the "New" toolbar
- button. */
-
-static void
-ensure_menu_items (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- GSList *objects, *folders;
- GSList *p;
- gint component_num;
- const gchar *default_verb;
-
- priv = handler->priv;
- if (priv->objects != NULL)
- return;
-
- objects = folders = NULL;
- component_num = 0;
- default_verb = NULL;
- for (p = priv->components; p != NULL; p = p->next) {
- const Component *component;
- gint i;
-
- component = (const Component *) p->data;
- if (component->type_list != NULL) {
- for (i = 0; i < component->type_list->_length; i ++) {
- const GNOME_Evolution_CreatableItemType *corba_item;
- MenuItem *item;
-
- corba_item = (const GNOME_Evolution_CreatableItemType *) component->type_list->_buffer + i;
-
- item = g_new (MenuItem, 1);
- item->label = corba_item->menuDescription;
- item->shortcut = corba_item->menuShortcut;
- item->verb = create_verb (handler, component_num, component->alias, corba_item->id);
- item->tooltip = corba_item->tooltip;
- item->component = g_strdup (component->alias);
-
- if (strcmp (item->component, "mail") == 0
- && strcmp (corba_item->id, "message") == 0)
- default_verb = item->verb;
-
- if (corba_item->iconName == NULL || *corba_item->iconName == '\0') {
- item->icon = NULL;
- item->icon_toolbar = NULL;
- } else {
- item->icon = e_icon_factory_get_icon (corba_item->iconName, GTK_ICON_SIZE_MENU);
- if (item_is_default (item, component->alias))
- item->icon_toolbar = e_icon_factory_get_icon (corba_item->iconName, GTK_ICON_SIZE_LARGE_TOOLBAR);
- else
- item->icon_toolbar = NULL;
- }
-
- if (corba_item->type == GNOME_Evolution_CREATABLE_OBJECT)
- objects = g_slist_prepend (objects, item);
- else
- folders = g_slist_prepend (folders, item);
- }
- }
-
- component_num ++;
- }
-
- priv->objects = g_slist_reverse (objects);
- priv->folders = g_slist_reverse (folders);
-
- priv->fallback_menu_item = NULL;
- if (default_verb != NULL) {
- for (p = priv->objects; p != NULL; p = p->next) {
- const MenuItem *item;
-
- item = (const MenuItem *) p->data;
- if (strcmp (item->verb, default_verb) == 0)
- priv->fallback_menu_item = item;
- }
- }
-}
-
-static void
-free_menu_items (GSList *menu_items)
-{
- GSList *p;
-
- if (menu_items == NULL)
- return;
-
- for (p = menu_items; p != NULL; p = p->next) {
- MenuItem *item;
-
- item = (MenuItem *) p->data;
- g_free (item->verb);
-
- if (item->icon != NULL)
- g_object_unref (item->icon);
-
- if (item->icon_toolbar != NULL)
- g_object_unref (item->icon_toolbar);
-
- g_free (item->component);
- g_free (item);
- }
-
- g_slist_free (menu_items);
-}
-
-static const MenuItem *
-get_default_action_for_view (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- const GSList *p;
-
- priv = handler->priv;
-
- for (p = priv->objects; p != NULL; p = p->next) {
- const MenuItem *item;
-
- item = (const MenuItem *) p->data;
- if (item_is_default (item, priv->this_component))
- return item;
- }
-
- return priv->fallback_menu_item;
-}
-
-/* Verb handling. */
-
-static void
-execute_verb (EUserCreatableItemsHandler *handler,
- const gchar *verb_name)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- const Component *component;
- gint component_number;
- const gchar *p;
- const gchar *id;
- GSList *component_list_item;
- gint i;
-
- priv = handler->priv;
-
- p = strchr (verb_name, ':');
- g_return_if_fail (p != NULL);
- component_number = atoi (p + 1);
-
- p = strchr (p + 1, ':');
- g_return_if_fail (p != NULL);
- id = p + 1;
-
- component_list_item = g_slist_nth (priv->components, component_number);
- g_return_if_fail (component_list_item != NULL);
-
- component = (const Component *) component_list_item->data;
-
- if (component->type_list == NULL)
- return;
-
- /* TODO: why do we actually iterate this? Is it just to check we have it in the menu? The
- search isn't used otherwise */
- for (i = 0; i < component->type_list->_length; i ++) {
- if (strcmp (component->type_list->_buffer[i].id, id) == 0) {
- if (priv->create_local && priv->this_component && strcmp(priv->this_component, component->alias) == 0) {
- priv->create_local(handler, id, priv->create_data);
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Component_requestCreateItem (component->component, id, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_warning ("Error in requestCreateItem -- %s", BONOBO_EX_REPOID (&ev));
-
- CORBA_exception_free (&ev);
- }
- return;
- }
- }
-}
-
-static void
-verb_fn (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *verb_name)
-{
- EUserCreatableItemsHandler *handler=
- E_USER_CREATABLE_ITEMS_HANDLER (data);
-
- execute_verb (handler, verb_name);
-}
-
-static void
-add_verbs (EUserCreatableItemsHandler *handler,
- BonoboUIComponent *ui_component)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- gint component_num;
- GSList *p;
-
- priv = handler->priv;
-
- component_num = 0;
- for (p = priv->components; p != NULL; p = p->next) {
- const Component *component;
- gint i;
-
- component = (const Component *) p->data;
-
- if (component->type_list != NULL) {
- for (i = 0; i < component->type_list->_length; i ++) {
- gchar *verb_name;
-
- verb_name = create_verb (handler,
- component_num,
- component->alias,
- component->type_list->_buffer[i].id);
-
- bonobo_ui_component_add_verb (ui_component, verb_name, verb_fn, handler);
-
- g_free (verb_name);
- }
- }
-
- component_num ++;
- }
-}
-
-/* Generic menu construction code */
-
-static gint
-item_types_sort_func (gconstpointer a,
- gconstpointer b)
-{
- const MenuItem *item_a;
- const MenuItem *item_b;
- const gchar *p1, *p2;
-
- item_a = (const MenuItem *) a;
- item_b = (const MenuItem *) b;
-
- p1 = item_a->label;
- p2 = item_b->label;
-
- while (*p1 != '\0' && *p2 != '\0') {
- if (*p1 == '_') {
- p1 ++;
- continue;
- }
-
- if (*p2 == '_') {
- p2 ++;
- continue;
- }
-
- if (toupper ((gint) *p1) < toupper ((gint) *p2))
- return -1;
- else if (toupper ((gint) *p1) > toupper ((gint) *p2))
- return +1;
-
- p1 ++, p2 ++;
- }
-
- if (*p1 == '\0') {
- if (*p2 == '\0')
- return 0;
- else
- return -1;
- } else {
- return +1;
- }
-}
-
-typedef void (*EUserCreatableItemsHandlerMenuItemFunc) (EUserCreatableItemsHandler *, gpointer, MenuItem *, gboolean);
-typedef void (*EUserCreatableItemsHandlerSeparatorFunc) (EUserCreatableItemsHandler *, gpointer, gint);
-
-static void
-construct_menu (EUserCreatableItemsHandler *handler, gpointer menu,
- EUserCreatableItemsHandlerMenuItemFunc menu_item_func,
- EUserCreatableItemsHandlerSeparatorFunc separator_func)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- MenuItem *item;
- GSList *p, *items;
- gboolean first = TRUE;
-
- priv = handler->priv;
-
- /* First add the current component's creatable objects */
- for (p = priv->objects; p != NULL; p = p->next) {
- item = p->data;
- if (item_is_default (item, priv->this_component)) {
- menu_item_func (handler, menu, item, first);
- first = FALSE;
- }
- }
-
- /* Then its creatable folders */
- for (p = priv->folders; p != NULL; p = p->next) {
- item = p->data;
- if (item_is_default (item, priv->this_component))
- menu_item_func (handler, menu, item, FALSE);
- }
-
- /* Then a separator */
- separator_func (handler, menu, 1);
-
- /* Then the objects from other components. */
- items = NULL;
- for (p = priv->objects; p != NULL; p = p->next) {
- item = p->data;
- if (! item_is_default (item, priv->this_component))
- items = g_slist_prepend (items, item);
- }
-
- items = g_slist_sort (items, item_types_sort_func);
- for (p = items; p != NULL; p = p->next)
- menu_item_func (handler, menu, p->data, FALSE);
- g_slist_free (items);
-
- /* Another separator */
- separator_func (handler, menu, 2);
-
- /* And finally the folders from other components */
- items = NULL;
- for (p = priv->folders; p != NULL; p = p->next) {
- item = p->data;
- if (! item_is_default (item, priv->this_component))
- items = g_slist_prepend (items, item);
- }
-
- items = g_slist_sort (items, item_types_sort_func);
- for (p = items; p != NULL; p = p->next)
- menu_item_func (handler, menu, p->data, FALSE);
- g_slist_free (items);
-}
-
-/* The XML description for "File -> New". */
-
-static void
-xml_menu_item_func (EUserCreatableItemsHandler *handler, gpointer menu,
- MenuItem *item, gboolean first)
-{
- GString *xml = menu;
- gchar *encoded_label;
- gchar *encoded_tooltip;
-
- encoded_label = bonobo_ui_util_encode_str (item->label);
- g_string_append_printf (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
- item->verb, item->verb, encoded_label);
-
- if (first)
- g_string_append_printf (xml, " accel=\"*Control*N\"");
- else if (item->shortcut != '\0')
- g_string_append_printf (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
-
- if (item->icon != NULL) {
- gchar *icon_xml;
-
- icon_xml = bonobo_ui_util_pixbuf_to_xml (item->icon);
- g_string_append_printf (xml, " pixtype=\"pixbuf\" pixname=\"%s\"", icon_xml);
- g_free (icon_xml);
- }
-
- encoded_tooltip = bonobo_ui_util_encode_str (item->tooltip);
- g_string_append_printf (xml, " tip=\"%s\"", encoded_tooltip);
-
- g_string_append (xml, "/> ");
-
- g_free (encoded_label);
- g_free (encoded_tooltip);
-}
-
-static void
-xml_separator_func (EUserCreatableItemsHandler *handler, gpointer menu, gint nth)
-{
- GString *xml = menu;
-
- g_string_append_printf (xml, "<separator f=\"\" name=\"EUserCreatableItemsHandlerSeparator%d\"/>", nth);
-}
-
-static void
-create_menu_xml (EUserCreatableItemsHandler *handler)
-{
- GString *xml;
-
- xml = g_string_new ("<placeholder name=\"NewMenu\">");
- construct_menu (handler, xml, xml_menu_item_func, xml_separator_func);
- g_string_append (xml, "</placeholder>");
-
- handler->priv->menu_xml = xml->str;
- g_string_free (xml, FALSE);
-}
-
-/* The GtkMenu for the toolbar button. */
-
-static void
-menuitem_activate (GtkMenuItem *item, gpointer data)
-{
- EUserCreatableItemsHandler *handler = data;
- const gchar *verb;
-
- verb = g_object_get_data (G_OBJECT (item), "EUserCreatableItemsHandler:verb");
- execute_verb (handler, verb);
-}
-
-static void
-default_activate (EComboButton *combo_button, gpointer data)
-{
- EUserCreatableItemsHandler *handler = data;
-
- execute_verb (handler, handler->priv->default_menu_item->verb);
-}
-
-static void
-gtk_menu_item_func (EUserCreatableItemsHandler *handler, gpointer menu,
- MenuItem *item, gboolean first)
-{
- GtkWidget *menuitem, *icon;
-
- menuitem = gtk_image_menu_item_new_with_mnemonic (item->label);
-
- if (item->icon) {
- icon = gtk_image_new_from_pixbuf (item->icon);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- icon);
- }
-
- if (first) {
- gtk_widget_add_accelerator (menuitem, "activate",
- handler->priv->accel_group,
- 'n', GDK_CONTROL_MASK,
- GTK_ACCEL_VISIBLE);
- } else if (item->shortcut != '\0') {
- gtk_widget_add_accelerator (menuitem, "activate",
- handler->priv->accel_group,
- item->shortcut,
- GDK_CONTROL_MASK | GDK_SHIFT_MASK,
- GTK_ACCEL_VISIBLE);
- }
-
- g_object_set_data (G_OBJECT (menuitem), "EUserCreatableItemsHandler:verb", item->verb);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (menuitem_activate), handler);
-
- gtk_menu_shell_append (menu, menuitem);
-}
-
-static void
-gtk_separator_func (EUserCreatableItemsHandler *handler, gpointer menu, gint nth)
-{
- gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
-}
-
-static void
-set_combo_button_style (EComboButton *button, const gchar *style, GdkPixbuf *icon)
-{
- if (!g_ascii_strcasecmp (style,"both-horiz")) {
- e_combo_button_pack_hbox (button);
- e_combo_button_set_label (button, _("New"));
- e_combo_button_set_icon (button, icon);
- }
- else if (!g_ascii_strcasecmp (style,"icons")) {
- e_combo_button_pack_hbox (button);
- e_combo_button_set_icon (button, icon);
- e_combo_button_set_label (button, "");
- }
- else if (!g_ascii_strcasecmp(style,"text")) {
- e_combo_button_pack_hbox (button);
- e_combo_button_set_label (button, _("New"));
- e_combo_button_set_icon (button, NULL);
- } else { /* Default to both */
- e_combo_button_pack_vbox (button);
- e_combo_button_set_icon (button, icon);
- e_combo_button_set_label (button, _("New"));
- }
-}
-
-static void
-new_button_change (GConfClient *gconf,
- guint connection_id,
- GConfEntry *entry,
- EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- gchar *val;
-
- priv = handler->priv;
- val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL);
-
- set_combo_button_style (E_COMBO_BUTTON (priv->new_button),
- val, priv->default_menu_item->icon_toolbar ? priv->default_menu_item->icon_toolbar : priv->default_menu_item->icon);
-
- g_free (val);
- gtk_widget_show (priv->new_button);
-}
-
-static void
-setup_toolbar_button (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- GConfClient *gconf = gconf_client_get_default ();
- gchar *val;
-
- priv = handler->priv;
- val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL);
-
- priv->new_button = e_combo_button_new ();
- priv->new_menu = gtk_menu_new ();
- priv->accel_group = gtk_accel_group_new ();
- construct_menu (handler, priv->new_menu,
- gtk_menu_item_func, gtk_separator_func);
- gtk_widget_show_all (priv->new_menu);
- e_combo_button_set_menu (E_COMBO_BUTTON (priv->new_button),
- GTK_MENU (priv->new_menu));
-
- g_signal_connect (priv->new_button, "activate_default",
- G_CALLBACK (default_activate), handler);
-
- priv->new_control = bonobo_control_new (priv->new_button);
-
- priv->default_menu_item = get_default_action_for_view (handler);
- if (!priv->default_menu_item) {
- gtk_widget_set_sensitive (priv->new_button, FALSE);
- g_object_unref (gconf);
- return;
- }
-
- gtk_widget_set_sensitive (priv->new_button, TRUE);
-
- set_combo_button_style (E_COMBO_BUTTON (priv->new_button),
- val, priv->default_menu_item->icon_toolbar ? priv->default_menu_item->icon_toolbar : priv->default_menu_item->icon);
-
- gconf_client_notify_add(gconf,"/desktop/gnome/interface/toolbar_style",
- (GConfClientNotifyFunc)new_button_change, handler, NULL, NULL);
-
- gtk_widget_set_tooltip_text (priv->new_button,
- priv->default_menu_item->tooltip);
- gtk_widget_show (priv->new_button);
-
- g_free (val);
- g_object_unref (gconf);
-}
-
-/* GObject methods. */
-
-static void
-impl_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- EUserCreatableItemsHandler *handler =
- E_USER_CREATABLE_ITEMS_HANDLER (object);
-
- switch (prop_id) {
- case PROP_THIS_COMPONENT:
- handler->priv->this_component = g_value_dup_string (value);
-
- get_components_from_bonobo (handler);
- ensure_menu_items (handler);
- break;
- default:
- break;
- }
-}
-
-static void
-impl_dispose (GObject *object)
-{
- EUserCreatableItemsHandler *handler;
- EUserCreatableItemsHandlerPrivate *priv;
- GSList *p;
-
- handler = E_USER_CREATABLE_ITEMS_HANDLER (object);
- priv = handler->priv;
-
- for (p = priv->components; p != NULL; p = p->next)
- component_free ((Component *) p->data);
-
- g_slist_free (priv->components);
- priv->components = NULL;
-
- if (priv->new_control) {
- bonobo_object_unref (priv->new_control);
- priv->new_control = NULL;
- }
-
- if (priv->accel_group) {
- g_object_unref (priv->accel_group);
- priv->accel_group = NULL;
- }
-
- (* G_OBJECT_CLASS (e_user_creatable_items_handler_parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EUserCreatableItemsHandler *handler;
- EUserCreatableItemsHandlerPrivate *priv;
-
- handler = E_USER_CREATABLE_ITEMS_HANDLER (object);
- priv = handler->priv;
-
- g_free (priv->this_component);
-
- free_menu_items (priv->objects);
- free_menu_items (priv->folders);
-
- g_free (priv->menu_xml);
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_user_creatable_items_handler_parent_class)->finalize) (object);
-}
-
-static void
-e_user_creatable_items_handler_class_init (EUserCreatableItemsHandlerClass *klass)
-{
- GObjectClass *object_class;
-
- bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
- object_class->set_property = impl_set_property;
-
- g_object_class_install_property (
- object_class, PROP_THIS_COMPONENT,
- g_param_spec_string ("this_component", "Component alias",
- "The component_alias of this component",
- NULL,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-e_user_creatable_items_handler_init (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
-
- priv = g_new0 (EUserCreatableItemsHandlerPrivate, 1);
-
- handler->priv = priv;
-}
-
-EUserCreatableItemsHandler *
-e_user_creatable_items_handler_new (const gchar *component_alias,
- EUserCreatableItemsHandlerCreate create_local, gpointer data)
-{
- EUserCreatableItemsHandler *handler;
-
- handler = g_object_new (e_user_creatable_items_handler_get_type (),
- "this_component", component_alias,
- NULL);
- handler->priv->create_local = create_local;
- handler->priv->create_data = data;
-
- return handler;
-}
-
-/**
- * e_user_creatable_items_handler_activate:
- * @handler: the #EUserCreatableItemsHandler
- * @ui_component: the #BonoboUIComponent to attach to
- *
- * Set up the menus and toolbar items for @ui_component.
- **/
-void
-e_user_creatable_items_handler_activate (EUserCreatableItemsHandler *handler,
- BonoboUIComponent *ui_component)
-{
- EUserCreatableItemsHandlerPrivate *priv;
-
- g_return_if_fail (E_IS_USER_CREATABLE_ITEMS_HANDLER (handler));
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (ui_component));
-
- priv = handler->priv;
-
- if (!priv->menu_xml) {
- create_menu_xml (handler);
- setup_toolbar_button (handler);
- add_verbs (handler, ui_component);
- }
-
- bonobo_ui_component_set (ui_component, "/menu/File/New",
- priv->menu_xml, NULL);
-
- bonobo_ui_component_object_set (ui_component,
- "/Toolbar/NewComboButton",
- BONOBO_OBJREF (priv->new_control),
- NULL);
-}
diff --git a/shell/e-user-creatable-items-handler.h b/shell/e-user-creatable-items-handler.h
deleted file mode 100644
index cb978bdb37..0000000000
--- a/shell/e-user-creatable-items-handler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_USER_CREATABLE_ITEMS_HANDLER_H_
-#define _E_USER_CREATABLE_ITEMS_HANDLER_H_
-
-#include <glib-object.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-window.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_USER_CREATABLE_ITEMS_HANDLER (e_user_creatable_items_handler_get_type ())
-#define E_USER_CREATABLE_ITEMS_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_USER_CREATABLE_ITEMS_HANDLER, EUserCreatableItemsHandler))
-#define E_USER_CREATABLE_ITEMS_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_USER_CREATABLE_ITEMS_HANDLER, EUserCreatableItemsHandlerClass))
-#define E_IS_USER_CREATABLE_ITEMS_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_USER_CREATABLE_ITEMS_HANDLER))
-#define E_IS_USER_CREATABLE_ITEMS_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_USER_CREATABLE_ITEMS_HANDLER))
-
-typedef struct _EUserCreatableItemsHandler EUserCreatableItemsHandler;
-typedef struct _EUserCreatableItemsHandlerPrivate EUserCreatableItemsHandlerPrivate;
-typedef struct _EUserCreatableItemsHandlerClass EUserCreatableItemsHandlerClass;
-
-typedef void (*EUserCreatableItemsHandlerCreate)(EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data);
-
-struct _EUserCreatableItemsHandler {
- GObject parent;
-
- EUserCreatableItemsHandlerPrivate *priv;
-};
-
-struct _EUserCreatableItemsHandlerClass {
- GObjectClass parent_class;
-};
-
-GType e_user_creatable_items_handler_get_type (void);
-EUserCreatableItemsHandler *e_user_creatable_items_handler_new (const gchar *component_alias,
- EUserCreatableItemsHandlerCreate create_local, gpointer data);
-
-void e_user_creatable_items_handler_activate (EUserCreatableItemsHandler *handler,
- BonoboUIComponent *ui_component);
-
-G_END_DECLS
-
-#endif /* _E_USER_CREATABLE_ITEMS_HANDLER_H_ */
diff --git a/shell/es-event.c b/shell/es-event.c
index 5740d585c7..c647827586 100644
--- a/shell/es-event.c
+++ b/shell/es-event.c
@@ -91,11 +91,10 @@ es_event_get_type(void)
/**
* es_event_peek:
- * @void:
*
* Get the singular instance of the shell event handler.
*
- * Return value:
+ * Return: the shell event handler
**/
ESEvent *es_event_peek(void)
{
@@ -112,6 +111,14 @@ ESEvent *es_event_peek(void)
return es_event;
}
+ESEventTargetShell *
+es_event_target_new (ESEvent *eme)
+{
+ return e_event_target_new (
+ &eme->event, ES_EVENT_TARGET_SHELL,
+ sizeof (ESEventTargetShell));
+}
+
ESEventTargetState *
es_event_target_new_state(ESEvent *eme, gint state)
{
@@ -130,16 +137,6 @@ es_event_target_new_state(ESEvent *eme, gint state)
return t;
}
-ESEventTargetShell *
-es_event_target_new_shell(ESEvent *eme, EShell *shell)
-{
- ESEventTargetShell *t = e_event_target_new(&eme->event, ES_EVENT_TARGET_SHELL, sizeof(*t));
-
- t->shell = shell;
-
- return t;
-}
-
ESEventTargetUpgrade *
es_event_target_new_upgrade(ESEvent *eme, gint major, gint minor, gint revision)
{
diff --git a/shell/es-event.h b/shell/es-event.h
index b422151a56..7bb9fcd781 100644
--- a/shell/es-event.h
+++ b/shell/es-event.h
@@ -30,8 +30,6 @@
G_BEGIN_DECLS
-struct _EShell; /* Avoid including "e-shell.h" */
-
typedef struct _ESEvent ESEvent;
typedef struct _ESEventClass ESEventClass;
@@ -56,8 +54,6 @@ typedef struct _ESEventTargetComponent ESEventTargetComponent;
struct _ESEventTargetShell {
EEventTarget target;
-
- struct _EShell *shell;
};
struct _ESEventTargetState {
@@ -97,8 +93,8 @@ GType es_event_get_type(void);
ESEvent *es_event_peek(void);
+ESEventTargetShell *es_event_target_new(ESEvent *eme);
ESEventTargetState *es_event_target_new_state(ESEvent *emp, gint state);
-ESEventTargetShell *es_event_target_new_shell(ESEvent *eme, struct _EShell *shell);
ESEventTargetUpgrade *es_event_target_new_upgrade(ESEvent *emp, gint major, gint minor, gint revision);
ESEventTargetComponent *es_event_target_new_component(ESEvent *eme, const gchar *id);
diff --git a/shell/es-menu.c b/shell/es-menu.c
deleted file mode 100644
index d272d613be..0000000000
--- a/shell/es-menu.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include "es-menu.h"
-
-static GObjectClass *esm_parent;
-
-static void
-esm_init(GObject *o)
-{
- /*ESMenu *esm = (ESMenu *)o; */
-}
-
-static void
-esm_finalise(GObject *o)
-{
- ((GObjectClass *)esm_parent)->finalize(o);
-}
-
-static void
-esm_target_free(EMenu *ep, EMenuTarget *t)
-{
- switch (t->type) {
- case ES_MENU_TARGET_SHELL: {
- ESMenuTargetShell *s = (ESMenuTargetShell *)t;
-
- s = s;
- break; }
- }
-
- ((EMenuClass *)esm_parent)->target_free(ep, t);
-}
-
-static void
-esm_class_init(GObjectClass *klass)
-{
- klass->finalize = esm_finalise;
- ((EMenuClass *)klass)->target_free = esm_target_free;
-}
-
-GType
-es_menu_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(ESMenuClass),
- NULL, NULL,
- (GClassInitFunc)esm_class_init,
- NULL, NULL,
- sizeof(ESMenu), 0,
- (GInstanceInitFunc)esm_init
- };
- esm_parent = g_type_class_ref(e_menu_get_type());
- type = g_type_register_static(e_menu_get_type(), "ESMenu", &info, 0);
- }
-
- return type;
-}
-
-ESMenu *es_menu_new(const gchar *menuid)
-{
- ESMenu *esm = g_object_new(es_menu_get_type(), NULL);
-
- e_menu_construct(&esm->menu, menuid);
-
- return esm;
-}
-
-/**
- * es_menu_target_new_shell:
- * @esm:
- * @flags:
- *
- * Create a new menu target for the shell.
- *
- * Return value:
- **/
-ESMenuTargetShell *
-es_menu_target_new_shell(ESMenu *esm, guint32 flags)
-{
- ESMenuTargetShell *t = e_menu_target_new(&esm->menu, ES_MENU_TARGET_SHELL, sizeof(*t));
- guint32 mask = ~0;
-
- mask &= ~ flags;
- t->target.mask = mask;
-
- return t;
-}
-
-/* ********************************************************************** */
-
-static gpointer esph_parent_class;
-#define esph ((ESMenuHook *)eph)
-
-static const EMenuHookTargetMask esph_shell_masks[] = {
- { "online", ES_MENU_SHELL_ONLINE },
- { "offline", ES_MENU_SHELL_OFFLINE },
- { NULL }
-};
-
-static const EMenuHookTargetMap esph_targets[] = {
- { "shell", ES_MENU_TARGET_SHELL, esph_shell_masks },
- { NULL }
-};
-
-static void
-esph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)esph_parent_class)->finalize(o);
-}
-
-static void
-esph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- /** @HookClass: Shell Main Menu
- * @Id: org.gnome.evolution.shell.bonobomenu:1.0
- * @Target: ESMenuTargetShell
- *
- * A hook for the main menus from the shell component.
- *
- * These menu's will be available from all components, but
- * will have no context for the current component.
- **/
-
- ((GObjectClass *)klass)->finalize = esph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.shell.bonobomenu:1.0";
-
- for (i=0;esph_targets[i].type;i++)
- e_menu_hook_class_add_target_map((EMenuHookClass *)klass, &esph_targets[i]);
-
- /* FIXME: leaks parent set class? */
- ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(es_menu_get_type());
-}
-
-GType
-es_menu_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(ESMenuHookClass), NULL, NULL, (GClassInitFunc) esph_class_init, NULL, NULL,
- sizeof(ESMenuHook), 0, (GInstanceInitFunc) NULL,
- };
-
- esph_parent_class = g_type_class_ref(e_menu_hook_get_type());
- type = g_type_register_static(e_menu_hook_get_type(), "ESMenuHook", &info, 0);
- }
-
- return type;
-}
diff --git a/shell/es-menu.h b/shell/es-menu.h
deleted file mode 100644
index d8ac21a567..0000000000
--- a/shell/es-menu.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __ES_MENU_H__
-#define __ES_MENU_H__
-
-#include <glib-object.h>
-
-#include "e-util/e-menu.h"
-
-G_BEGIN_DECLS
-
-typedef struct _ESMenu ESMenu;
-typedef struct _ESMenuClass ESMenuClass;
-
-/* Current target description */
-/* Types of popup tagets */
-enum _es_menu_target_t {
- ES_MENU_TARGET_SHELL
-};
-
-/* Flags that describe a TARGET_SHELL */
-enum {
- ES_MENU_SHELL_ONLINE = 1<<0,
- ES_MENU_SHELL_OFFLINE = 1<<1
-};
-
-typedef struct _ESMenuTargetShell ESMenuTargetShell;
-
-struct _ESMenuTargetShell {
- EMenuTarget target;
-
- /* current component?? */
-};
-
-typedef struct _EMenuItem ESMenuItem;
-
-/* The object */
-struct _ESMenu {
- EMenu menu;
-
- struct _ESMenuPrivate *priv;
-};
-
-struct _ESMenuClass {
- EMenuClass menu_class;
-};
-
-GType es_menu_get_type(void);
-
-ESMenu *es_menu_new(const gchar *menuid);
-
-ESMenuTargetShell *es_menu_target_new_shell(ESMenu *emp, guint32 flags);
-
-/* ********************************************************************** */
-
-typedef struct _ESMenuHook ESMenuHook;
-typedef struct _ESMenuHookClass ESMenuHookClass;
-
-struct _ESMenuHook {
- EMenuHook hook;
-};
-
-struct _ESMenuHookClass {
- EMenuHookClass hook_class;
-};
-
-GType es_menu_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __ES_MENU_H__ */
diff --git a/shell/evolution-component.c b/shell/evolution-component.c
deleted file mode 100644
index 49824c9545..0000000000
--- a/shell/evolution-component.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-component.h"
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-/* Evolution.Component */
-
-/* Initialization */
-
-static void
-evolution_component_class_init (EvolutionComponentClass *klass)
-{
- parent_class = g_type_class_peek_parent (klass);
-}
-
-static void
-evolution_component_init(EvolutionComponent *emf, EvolutionComponentClass *klass)
-{
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionComponent, GNOME_Evolution_Component, PARENT_TYPE, evolution_component)
diff --git a/shell/evolution-component.h b/shell/evolution-component.h
deleted file mode 100644
index 302263a657..0000000000
--- a/shell/evolution-component.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *
- * Abstract class wrapper for EvolutionComponent
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _EVOLUTION_COMPONENT_H_
-#define _EVOLUTION_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-#include "shell/Evolution.h"
-
-typedef struct _EvolutionComponent EvolutionComponent;
-typedef struct _EvolutionComponentClass EvolutionComponentClass;
-
-struct _EvolutionComponent {
- BonoboObject parent;
-};
-
-struct _EvolutionComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType evolution_component_get_type(void);
-
-#endif /* _EVOLUTION_COMPONENT_H_ */
diff --git a/shell/evolution-config-control.c b/shell/evolution-config-control.c
deleted file mode 100644
index a0d3f473a2..0000000000
--- a/shell/evolution-config-control.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-config-control.h"
-
-#include <e-util/e-util.h>
-
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-event-source.h>
-
-
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionConfigControlPrivate {
- BonoboControl *control;
- BonoboEventSource *event_source;
-};
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (object);
- priv = config_control->priv;
-
- if (priv->control != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (priv->control));
- priv->control = NULL;
- }
-
- if (priv->event_source != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (priv->event_source));
- priv->event_source = NULL;
- }
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (object);
- priv = config_control->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-
-/* Evolution::ConfigControl CORBA methods. */
-
-static Bonobo_Control
-impl__get_control (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (bonobo_object_from_servant (servant));
- priv = config_control->priv;
-
- bonobo_object_ref (BONOBO_OBJECT (priv->control));
-
- return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (priv->control)), ev);
-}
-
-static Bonobo_EventSource
-impl__get_eventSource (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (bonobo_object_from_servant (servant));
- priv = config_control->priv;
-
- bonobo_object_ref (BONOBO_OBJECT (priv->event_source));
-
- return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (priv->event_source)), ev);
-}
-
-
-static void
-evolution_config_control_class_init (EvolutionConfigControlClass *class)
-{
- POA_GNOME_Evolution_ConfigControl__epv *epv;
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- epv = &class->epv;
- epv->_get_control = impl__get_control;
- epv->_get_eventSource = impl__get_eventSource;
-
- parent_class = g_type_class_ref (PARENT_TYPE);
-}
-
-static void
-evolution_config_control_init (EvolutionConfigControl *config_control)
-{
- EvolutionConfigControlPrivate *priv;
-
- priv = g_new (EvolutionConfigControlPrivate, 1);
- priv->control = NULL;
- priv->event_source = bonobo_event_source_new ();
-
- config_control->priv = priv;
-}
-
-
-void
-evolution_config_control_construct (EvolutionConfigControl *control,
- GtkWidget *widget)
-{
- EvolutionConfigControlPrivate *priv;
-
- g_return_if_fail (EVOLUTION_IS_CONFIG_CONTROL (control));
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- priv = control->priv;
-
- priv->control = bonobo_control_new (widget);
-}
-
-EvolutionConfigControl *
-evolution_config_control_new (GtkWidget *widget)
-{
- EvolutionConfigControl *new;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- new = g_object_new (evolution_config_control_get_type (), NULL);
- evolution_config_control_construct (new, widget);
-
- return new;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionConfigControl,
- GNOME_Evolution_ConfigControl,
- PARENT_TYPE,
- evolution_config_control)
diff --git a/shell/evolution-config-control.h b/shell/evolution-config-control.h
deleted file mode 100644
index 59d7aba210..0000000000
--- a/shell/evolution-config-control.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_CONFIG_CONTROL_H
-#define EVOLUTION_CONFIG_CONTROL_H
-
-#include "Evolution.h"
-
-#include <bonobo/bonobo-object.h>
-#include <gtk/gtk.h>
-
-#ifdef cplusplus
-extern "C" {
-#pragma }
-#endif /* cplusplus */
-
-#define EVOLUTION_TYPE_CONFIG_CONTROL (evolution_config_control_get_type ())
-#define EVOLUTION_CONFIG_CONTROL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_CONFIG_CONTROL, EvolutionConfigControl))
-#define EVOLUTION_CONFIG_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_CONFIG_CONTROL, EvolutionConfigControlClass))
-#define EVOLUTION_IS_CONFIG_CONTROL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_CONFIG_CONTROL))
-#define EVOLUTION_IS_CONFIG_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_CONFIG_CONTROL))
-
-typedef struct _EvolutionConfigControl EvolutionConfigControl;
-typedef struct _EvolutionConfigControlPrivate EvolutionConfigControlPrivate;
-typedef struct _EvolutionConfigControlClass EvolutionConfigControlClass;
-
-struct _EvolutionConfigControl {
- BonoboObject parent;
-
- EvolutionConfigControlPrivate *priv;
-};
-
-struct _EvolutionConfigControlClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_ConfigControl__epv epv;
-};
-
-
-GType evolution_config_control_get_type (void);
-EvolutionConfigControl *evolution_config_control_new (GtkWidget *widget);
-void evolution_config_control_construct (EvolutionConfigControl *control,
- GtkWidget *widget);
-
-#endif /* EVOLUTION_CONFIG_CONTROL_H */
diff --git a/shell/evolution-listener.c b/shell/evolution-listener.c
deleted file mode 100644
index 3209450134..0000000000
--- a/shell/evolution-listener.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-listener.h"
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-/* Evolution.Listener */
-static void
-impl_complete(PortableServer_Servant _servant, CORBA_Environment * ev)
-{
- EvolutionListener *el = (EvolutionListener *)bonobo_object_from_servant(_servant);
-
- if (el->complete)
- el->complete(el, el->data);
-}
-
-static void
-evolution_listener_class_init (EvolutionListenerClass *klass)
-{
- POA_GNOME_Evolution_Listener__epv *epv = &klass->epv;
-
- parent_class = g_type_class_peek_parent (klass);
-
- epv->complete = impl_complete;
-}
-
-static void
-evolution_listener_init(EvolutionListener *emf, EvolutionListenerClass *klass)
-{
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionListener, GNOME_Evolution_Listener, PARENT_TYPE, evolution_listener)
-
-EvolutionListener *
-evolution_listener_new(EvolutionListenerFunc complete, gpointer data)
-{
- EvolutionListener *el;
-
- el = g_object_new(evolution_listener_get_type(), NULL);
- el->complete = complete;
- el->data = data;
-
- return el;
-}
diff --git a/shell/evolution-listener.h b/shell/evolution-listener.h
deleted file mode 100644
index 9637342099..0000000000
--- a/shell/evolution-listener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * Abstract class wrapper for EvolutionListener
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _EVOLUTION_LISTENER_H_
-#define _EVOLUTION_LISTENER_H_
-
-#include <bonobo/bonobo-object.h>
-#include "shell/Evolution.h"
-
-typedef struct _EvolutionListener EvolutionListener;
-typedef struct _EvolutionListenerClass EvolutionListenerClass;
-
-typedef void (*EvolutionListenerFunc)(EvolutionListener *, gpointer );
-
-struct _EvolutionListener {
- BonoboObject parent;
-
- /* we dont need signals, so why bother wasting resources on it */
- EvolutionListenerFunc complete;
- gpointer data;
-};
-
-struct _EvolutionListenerClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Listener__epv epv;
-};
-
-GType evolution_listener_get_type(void);
-EvolutionListener *evolution_listener_new(EvolutionListenerFunc complete, gpointer data);
-
-#endif /* _EVOLUTION_LISTENER_H_ */
diff --git a/shell/evolution-shell-component-utils.c b/shell/evolution-shell-component-utils.c
deleted file mode 100644
index 7301a3741b..0000000000
--- a/shell/evolution-shell-component-utils.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-shell-component-utils.h"
-#include <e-util/e-icon-factory.h>
-#include "e-util/e-dialog-utils.h"
-
-#include <string.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo-activation/bonobo-activation.h>
-
-static void free_pixmaps (void);
-static GSList *inited_arrays = NULL;
-
-void e_pixmaps_update (BonoboUIComponent *uic, EPixmap *pixcache)
-{
- static gint done_init = 0;
- gint i;
-
- if (!done_init) {
- g_atexit (free_pixmaps);
- done_init = 1;
- }
-
- if (g_slist_find (inited_arrays, pixcache) == NULL)
- inited_arrays = g_slist_prepend (inited_arrays, pixcache);
-
- for (i = 0; pixcache [i].path; i++) {
- if (!pixcache [i].pixbuf) {
- GdkPixbuf *pixbuf;
-
- pixbuf = e_icon_factory_get_icon (pixcache [i].name, pixcache [i].size);
- pixcache [i].pixbuf = bonobo_ui_util_pixbuf_to_xml (pixbuf);
- g_object_unref (pixbuf);
- bonobo_ui_component_set_prop (uic,
- pixcache [i].path, "pixname",
- pixcache [i].pixbuf, NULL);
- } else {
- bonobo_ui_component_set_prop (uic, pixcache [i].path,
- "pixname",
- pixcache [i].pixbuf,
- NULL);
- }
- }
-}
-
-static void
-free_pixmaps (void)
-{
- gint i;
- GSList *li;
-
- for (li = inited_arrays; li != NULL; li = li->next) {
- EPixmap *pixcache = li->data;
- for (i = 0; pixcache [i].path; i++)
- g_free (pixcache [i].pixbuf);
- }
-
- g_slist_free (inited_arrays);
-}
-
-/**
- * e_get_activation_failure_msg:
- * @ev: An exception returned by an oaf_activate call.
- *
- * Get a descriptive error message from @ev.
- *
- * Return value: A newly allocated string with the printable error message.
- **/
-gchar *
-e_get_activation_failure_msg (CORBA_Environment *ev)
-{
- g_return_val_if_fail (ev != NULL, NULL);
-
- if (CORBA_exception_id (ev) == NULL)
- return NULL;
-
- if (strcmp (CORBA_exception_id (ev), ex_Bonobo_GeneralError) != 0) {
- return bonobo_exception_get_text (ev);
- } else {
- const Bonobo_GeneralError *oaf_general_error;
-
- oaf_general_error = CORBA_exception_value (ev);
- return g_strdup (oaf_general_error->description);
- }
-}
diff --git a/shell/import.glade b/shell/import.glade
deleted file mode 100644
index 389d2feee3..0000000000
--- a/shell/import.glade
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="importwizard">
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
-
- <child>
- <widget class="GnomeDruid" id="druid1">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="show_help">False</property>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page0">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_START</property>
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="text" translatable="yes">Welcome to the Evolution Import Assistant.
-With this assistant you will be guided through the process of
-importing external files into Evolution.</property>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Importer Type</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox2">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select a File</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox1">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page3-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Import Location</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-intelligent">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select Information to Import</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page4">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_FINISH</property>
- <property name="title" translatable="yes">Import File</property>
- <property name="text" translatable="yes">Click &quot;Import&quot; to begin importing the file into Evolution. </property>
- </widget>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/shell/importer/GNOME_Evolution_Importer.idl b/shell/importer/GNOME_Evolution_Importer.idl
deleted file mode 100644
index e33ca150ae..0000000000
--- a/shell/importer/GNOME_Evolution_Importer.idl
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Interfaces for the importer framework.
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- */
-
-#include <Bonobo.idl>
-
-module GNOME {
-module Evolution {
- interface ImporterListener : Bonobo::Unknown {
- enum ImporterResult {
- OK,
- UNSUPPORTED_OPERATION,
- NOT_READY,
- BUSY,
- UNKNOWN_DATA,
- BAD_DATA,
- BAD_FILE
- };
-
- /**
- * notifyResult:
- * @result: The result of the import.
- * @more_items: Are there any more items to be processed?
- *
- * Notifies the listener of the result and whether there are
- * any more items to be imported.
- */
- oneway void notifyResult (in ImporterResult result,
- in boolean more_items);
- };
-
- interface Importer : Bonobo::Unknown {
-
- /**
- * processItem:
- * @listener: The ImporterListener that will be notified of the
- * progress.
- *
- * Processes the next item.
- *
- */
- oneway void processItem (in ImporterListener listener);
-
- /**
- * getError:
- *
- * Retrieve a detailed explaination of the error.
- *
- * Returns: A string.
- */
- string getError ();
-
- void createControl (out Bonobo::Control control);
-
- /**
- * supportFormat:
- * @filename: The filename of the file.
- *
- * Checks if the importer created by this factory can
- * import the file specified.
- *
- * Returns: A boolean, TRUE if it can import the file,
- * FALSE otherwise.
- */
- boolean supportFormat (in string filename);
-
- /**
- * loadFile:
- * @filename: The filename of the file.
- * @folderpath: The full pathname to the folder.
- * @foldertpe: The type of the folder to import to.
- *
- * Loads the file and prepares an Importer object that can
- * process files of this type.
- *
- * Returns: An Importer object.
- */
- boolean loadFile (in string filename);
- };
-
- interface IntelligentImporter : Bonobo::Unknown {
-
- readonly attribute string importername;
- readonly attribute string message;
-
- boolean canImport ();
-
- void importData ();
- };
-};
-};
diff --git a/shell/importer/Makefile.am b/shell/importer/Makefile.am
deleted file mode 100644
index 06735179af..0000000000
--- a/shell/importer/Makefile.am
+++ /dev/null
@@ -1,68 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/shell \
- -I$(top_builddir)/shell \
- -DG_LOG_DOMAIN=\"Evolution-Importer\" \
- -DEVOLUTION_GLADEDIR="\"$(gladedir)\"" \
- $(SHELL_CFLAGS)
-
-privlib_LTLIBRARIES = libevolution-importer.la
-
-
-# IDL stuff
-
-IDLS = GNOME_Evolution_Importer.idl
-
-IDL_GENERATED_H = \
- GNOME_Evolution_Importer.h
-
-IDL_GENERATED_C = \
- GNOME_Evolution_Importer-common.c \
- GNOME_Evolution_Importer-skels.c \
- GNOME_Evolution_Importer-stubs.c
-
-IDL_GENERATED = $(IDL_GENERATED_H) $(IDL_GENERATED_C)
-
-$(IDL_GENERATED_H): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) $(srcdir)/GNOME_Evolution_Importer.idl
-
-$(IDL_GENERATED_C): $(IDL_GENERATED_H)
-
-idl_DATA = $(IDLS)
-
-
-# Component
-
-libevolution_importerincludedir = $(privincludedir)/importer
-libevolution_importer_la_SOURCES = \
- $(IDL_GENERATED) \
- evolution-intelligent-importer.c \
- evolution-importer-client.c \
- evolution-importer-listener.c \
- evolution-importer.c \
- intelligent.c \
- intelligent.h
-
-libevolution_importerinclude_HEADERS = \
- GNOME_Evolution_Importer.h \
- evolution-intelligent-importer.h \
- evolution-importer-client.h \
- evolution-importer-listener.h \
- evolution-importer.h
-
-libevolution_importer_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(SHELL_LIBS)
-
-glade_DATA = import.glade
-
-EXTRA_DIST = $(glade_DATA) $(IDLS)
-
-BUILT_SOURCES= $(IDL_GENERATED)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
-
-
--include $(top_srcdir)/git.mk
diff --git a/shell/importer/evolution-importer-client.c b/shell/importer/evolution-importer-client.c
deleted file mode 100644
index 66a82836e3..0000000000
--- a/shell/importer/evolution-importer-client.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Based on evolution-shell-component-client.c by Ettore Perazzoli
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-importer-client.h"
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
-
-#include "GNOME_Evolution_Importer.h"
-
-G_DEFINE_TYPE (EvolutionImporterClient, evolution_importer_client, G_TYPE_OBJECT)
-
-
-static void
-finalise (GObject *object)
-{
- /* FIXME: should this unref the client->objref?? */
-
- (* G_OBJECT_CLASS (evolution_importer_client_parent_class)->finalize) (object);
-}
-
-static void
-evolution_importer_client_class_init (EvolutionImporterClientClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = finalise;
-}
-
-static void
-evolution_importer_client_init (EvolutionImporterClient *client)
-{
-}
-
-/**
- * evolution_importer_client_new:
- * @objref: The CORBA_Object to make a client for.
- *
- * Makes a client for @objref. @objref should be an Evolution_Importer.
- *
- * Returns: A newly created EvolutionImporterClient.
- */
-EvolutionImporterClient *
-evolution_importer_client_new (const CORBA_Object objref)
-{
- EvolutionImporterClient *client;
-
- g_return_val_if_fail (objref != CORBA_OBJECT_NIL, NULL);
-
- client = g_object_new (evolution_importer_client_get_type (), NULL);
- client->objref = objref;
-
- return client;
-}
-
-/**
- * evolution_importer_client_new_from_id:
- * @id: The oafiid of the component to make a client for.
- *
- * Makes a client for the object returned by activating @id.
- *
- * Returns: A newly created EvolutionImporterClient.
- */
-EvolutionImporterClient *
-evolution_importer_client_new_from_id (const gchar *id)
-{
- CORBA_Environment ev;
- CORBA_Object objref;
-
- g_return_val_if_fail (id != NULL, NULL);
-
- CORBA_exception_init (&ev);
- objref = bonobo_activation_activate_from_id ((gchar *) id, 0, NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- g_warning ("Could not start %s.", id);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
- if (objref == CORBA_OBJECT_NIL) {
- g_warning ("Could not activate component %s", id);
- return NULL;
- }
-
- return evolution_importer_client_new (objref);
-}
-
-/* API */
-GtkWidget *
-evolution_importer_client_create_control (EvolutionImporterClient *client)
-{
- GNOME_Evolution_Importer corba_importer;
- GtkWidget *widget = NULL;
- Bonobo_Control control;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), NULL);
-
- CORBA_exception_init (&ev);
- corba_importer = client->objref;
- GNOME_Evolution_Importer_createControl (corba_importer, &control, &ev);
-
- if (!BONOBO_EX (&ev)) {
- /* FIXME Pass in container? */
- widget = bonobo_widget_new_control_from_objref (control, NULL);
- gtk_widget_show (widget);
- }
-
- CORBA_exception_free (&ev);
-
- return widget;
-}
-
-/**
- * evolution_importer_client_support_format:
- * @client: The EvolutionImporterClient.
- * @filename: Name of the file to check.
- *
- * Checks whether @client is able to import @filename.
- *
- * Returns: TRUE if @client can import @filename, FALSE otherwise.
- */
-gboolean
-evolution_importer_client_support_format (EvolutionImporterClient *client,
- const gchar *filename)
-{
- GNOME_Evolution_Importer corba_importer;
- gboolean result;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
-
- CORBA_exception_init (&ev);
- corba_importer = client->objref;
- result = GNOME_Evolution_Importer_supportFormat (corba_importer,
- filename, &ev);
- CORBA_exception_free (&ev);
-
- return result;
-}
-
-/**
- * evolution_importer_client_load_file:
- * @client: The EvolutionImporterClient.
- * @filename: The file to load.
- * @physical_uri: The physical URI of the folder to import data into.
- * @folder_type: The type of the folder represented by @physical_uri.
- *
- * Loads and initialises the importer.
- *
- * Returns: TRUE on sucess, FALSE on failure.
- */
-gboolean
-evolution_importer_client_load_file (EvolutionImporterClient *client, const gchar *filename)
-{
- GNOME_Evolution_Importer corba_importer;
- gboolean result;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
-
- CORBA_exception_init (&ev);
- corba_importer = client->objref;
- result = GNOME_Evolution_Importer_loadFile (corba_importer, filename, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Oh there *WAS* an exception.\nIt was %s",
- CORBA_exception_id (&ev));
- CORBA_exception_free (&ev);
- return FALSE;
- }
- CORBA_exception_free (&ev);
-
- return result;
-}
-
-/**
- * evolution_importer_client_process_item:
- * @client: The EvolutionImporterClient.
- * @listener: The EvolutionImporterListener.
- *
- * Starts importing the next item in the file. @listener will be notified
- * when the item has finished.
- */
-void
-evolution_importer_client_process_item (EvolutionImporterClient *client,
- EvolutionImporterListener *listener)
-{
- GNOME_Evolution_Importer corba_importer;
- GNOME_Evolution_ImporterListener corba_listener;
- CORBA_Environment ev;
-
- g_return_if_fail (client != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client));
- g_return_if_fail (listener != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER_LISTENER (listener));
-
- CORBA_exception_init (&ev);
-
- corba_importer = client->objref;
- corba_listener = bonobo_object_corba_objref (BONOBO_OBJECT (listener));
- GNOME_Evolution_Importer_processItem (corba_importer,
- corba_listener, &ev);
- CORBA_exception_free (&ev);
-}
-
-/**
- * evolution_importer_client_get_error:
- * @client: The EvolutionImporterClient.
- *
- * Gets the error as a string.
- *
- * Returns: The error as a string. If there is no error NULL is returned.
- * Importers need not support this method and if so, NULL is also returned.
- */
-const gchar *
-evolution_importer_client_get_error (EvolutionImporterClient *client)
-{
- GNOME_Evolution_Importer corba_importer;
- CORBA_char *str;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), NULL);
-
- corba_importer = client->objref;
-
- CORBA_exception_init (&ev);
- str = GNOME_Evolution_Importer_getError (corba_importer, &ev);
-
- return str;
-}
diff --git a/shell/importer/evolution-importer-client.h b/shell/importer/evolution-importer-client.h
deleted file mode 100644
index e94584216d..0000000000
--- a/shell/importer/evolution-importer-client.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_IMPORTER_CLIENT_H
-#define EVOLUTION_IMPORTER_CLIENT_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <importer/evolution-importer.h>
-#include <importer/evolution-importer-listener.h>
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_IMPORTER_CLIENT (evolution_importer_client_get_type ())
-#define EVOLUTION_IMPORTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_IMPORTER_CLIENT, EvolutionImporterClient))
-#define EVOLUTION_IMPORTER_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_IMPORTER_CLIENT, EvolutionImporterClientClass))
-#define EVOLUTION_IS_IMPORTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_IMPORTER_CLIENT))
-#define EVOLUTION_IS_IMPORTER_CLIENT_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE ((klass), EVOLUTION_TYPE_IMPORTER_CLIENT))
-
-
-typedef struct _EvolutionImporterClient EvolutionImporterClient;
-typedef struct _EvolutionImporterClientClass EvolutionImporterClientClass;
-
-struct _EvolutionImporterClient {
- GObject parent_type;
-
- GNOME_Evolution_Importer objref;
-};
-
-struct _EvolutionImporterClientClass {
- GObjectClass parent_class;
-};
-
-GType evolution_importer_client_get_type (void);
-
-EvolutionImporterClient *evolution_importer_client_new (const CORBA_Object objref);
-EvolutionImporterClient *evolution_importer_client_new_from_id (const gchar *id);
-
-GtkWidget *evolution_importer_client_create_control (EvolutionImporterClient *client);
-gboolean evolution_importer_client_support_format (EvolutionImporterClient *client,
- const gchar *filename);
-gboolean evolution_importer_client_load_file (EvolutionImporterClient *client,
- const gchar *filename);
-void evolution_importer_client_process_item (EvolutionImporterClient *client,
- EvolutionImporterListener *listener);
-const gchar *evolution_importer_client_get_error (EvolutionImporterClient *client);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/evolution-importer-listener.c b/shell/importer/evolution-importer-listener.c
deleted file mode 100644
index ffac2d3ab4..0000000000
--- a/shell/importer/evolution-importer-listener.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-importer-listener.h"
-
-#include <bonobo/bonobo-object.h>
-#include <e-util/e-util.h>
-
-#include "GNOME_Evolution_Importer.h"
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionImporterListenerPrivate {
- EvolutionImporterListenerCallback callback;
-
- gpointer closure;
-};
-
-#if 0
-static POA_GNOME_Evolution_ImporterListener__vepv Listener_vepv;
-
-static POA_GNOME_Evolution_ImporterListener *
-create_servant (void)
-{
- POA_GNOME_Evolution_ImporterListener *servant;
- CORBA_Environment ev;
-
- servant = (POA_GNOME_Evolution_ImporterListener *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &Listener_vepv;
-
- CORBA_exception_init (&ev);
- POA_GNOME_Evolution_ImporterListener__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- return servant;
-}
-#endif
-
-static EvolutionImporterResult
-corba_result_to_evolution (GNOME_Evolution_ImporterListener_ImporterResult corba_result)
-{
- switch (corba_result) {
- case GNOME_Evolution_ImporterListener_OK:
- return EVOLUTION_IMPORTER_OK;
- case GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION:
- return EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION;
- case GNOME_Evolution_ImporterListener_UNKNOWN_DATA:
- return EVOLUTION_IMPORTER_UNKNOWN_DATA;
- case GNOME_Evolution_ImporterListener_BAD_DATA:
- return EVOLUTION_IMPORTER_BAD_DATA;
- case GNOME_Evolution_ImporterListener_BAD_FILE:
- return EVOLUTION_IMPORTER_BAD_FILE;
- case GNOME_Evolution_ImporterListener_NOT_READY:
- return EVOLUTION_IMPORTER_NOT_READY;
- case GNOME_Evolution_ImporterListener_BUSY:
- return EVOLUTION_IMPORTER_BUSY;
- default:
- return EVOLUTION_IMPORTER_UNKNOWN_ERROR;
- }
-}
-
-static inline EvolutionImporterListener *
-evolution_importer_listener_from_servant (PortableServer_Servant servant)
-{
- return EVOLUTION_IMPORTER_LISTENER (bonobo_object_from_servant (servant));
-}
-
-static void
-impl_GNOME_Evolution_ImporterListener_notifyResult (PortableServer_Servant servant,
- GNOME_Evolution_ImporterListener_ImporterResult result,
- CORBA_boolean more_items,
- CORBA_Environment *ev)
-{
- EvolutionImporterListener *listener;
- EvolutionImporterListenerPrivate *priv;
- EvolutionImporterResult out_result;
-
- listener = evolution_importer_listener_from_servant (servant);
- priv = listener->priv;
-
- out_result = corba_result_to_evolution (result);
- if (priv->callback) {
- (priv->callback) (listener, out_result, more_items,
- priv->closure);
- }
-
- return;
-}
-
-
-/* GObject methods */
-static void
-finalise (GObject *object)
-{
- EvolutionImporterListener *listener;
- EvolutionImporterListenerPrivate *priv;
-
- listener = EVOLUTION_IMPORTER_LISTENER (object);
- priv = listener->priv;
-
- if (priv == NULL)
- return;
-
- g_free (priv);
- listener->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize(object);
-}
-
-#if 0
-static void
-corba_class_init (void)
-{
- POA_GNOME_Evolution_ImporterListener__vepv *vepv;
- POA_GNOME_Evolution_ImporterListener__epv *epv;
- PortableServer_ServantBase__epv *base_epv;
-
- base_epv = g_new0 (PortableServer_ServantBase__epv, 1);
- base_epv->_private = NULL;
- base_epv->finalize = NULL;
- base_epv->default_POA = NULL;
-
- epv = g_new0 (POA_GNOME_Evolution_ImporterListener__epv, 1);
- epv->notifyResult = impl_GNOME_Evolution_ImporterListener_notifyResult;
-
- vepv = &Listener_vepv;
- vepv->_base_epv = base_epv;
- vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
- vepv->GNOME_Evolution_ImporterListener_epv = epv;
-}
-#endif
-
-static void
-evolution_importer_listener_class_init (EvolutionImporterListenerClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_ImporterListener__epv *epv = &klass->epv;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = finalise;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
- epv->notifyResult = impl_GNOME_Evolution_ImporterListener_notifyResult;
-}
-
-static void
-evolution_importer_listener_init (EvolutionImporterListener *listener)
-{
- EvolutionImporterListenerPrivate *priv;
-
- priv = g_new0 (EvolutionImporterListenerPrivate, 1);
- listener->priv = priv;
-}
-
-static void
-evolution_importer_listener_construct (EvolutionImporterListener *listener,
- EvolutionImporterListenerCallback callback,
- gpointer closure)
-{
- EvolutionImporterListenerPrivate *priv;
-
- g_return_if_fail (listener != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER_LISTENER (listener));
- g_return_if_fail (callback != NULL);
-
- priv = listener->priv;
- priv->callback = callback;
- priv->closure = closure;
-}
-
-/**
- * evolution_importer_listener_new
- * @callback: The #EvolutionImporterListenerCallback callback.
- * @closure: The data that will be passed to that callback.
- *
- * Creates a new #EvolutionImporterListener object which calls @callback when
- * something happens.
- * Returns: A newly allocated #EvolutionImporterListener.
- */
-EvolutionImporterListener *
-evolution_importer_listener_new (EvolutionImporterListenerCallback callback,
- gpointer closure)
-{
- EvolutionImporterListener *listener;
-
- listener = g_object_new (evolution_importer_listener_get_type (), NULL);
-
- evolution_importer_listener_construct (listener, callback, closure);
- return listener;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionImporterListener,
- GNOME_Evolution_ImporterListener,
- PARENT_TYPE, evolution_importer_listener);
diff --git a/shell/importer/evolution-importer-listener.h b/shell/importer/evolution-importer-listener.h
deleted file mode 100644
index 39bf2a0493..0000000000
--- a/shell/importer/evolution-importer-listener.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_IMPORTER_LISTENER_H
-#define EVOLUTION_IMPORTER_LISTENER_H
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <importer/GNOME_Evolution_Importer.h>
-#include "evolution-importer.h"
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_IMPORTER_LISTENER (evolution_importer_listener_get_type ())
-#define EVOLUTION_IMPORTER_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_IMPORTER_LISTENER, EvolutionImporterListener))
-#define EVOLUTION_IMPORTER_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_IMPORTER_LISTENER, EvolutionImporterListenerClass))
-#define EVOLUTION_IS_IMPORTER_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_IMPORTER_LISTENER))
-#define EVOLUTION_IS_IMPORTER_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_IMPORTER_LISTENER))
-
-typedef struct _EvolutionImporterListener EvolutionImporterListener;
-typedef struct _EvolutionImporterListenerPrivate EvolutionImporterListenerPrivate;
-typedef struct _EvolutionImporterListenerClass EvolutionImporterListenerClass;
-
-typedef void (* EvolutionImporterListenerCallback) (EvolutionImporterListener *listener,
- EvolutionImporterResult result,
- gboolean more_items,
- gpointer closure);
-struct _EvolutionImporterListener {
- BonoboObject parent;
-
- EvolutionImporterListenerPrivate *priv;
-};
-
-struct _EvolutionImporterListenerClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_ImporterListener__epv epv;
-};
-
-GType evolution_importer_listener_get_type (void);
-
-EvolutionImporterListener *evolution_importer_listener_new (EvolutionImporterListenerCallback callback,
- gpointer closure);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/evolution-importer.c b/shell/importer/evolution-importer.c
deleted file mode 100644
index 17e118094b..0000000000
--- a/shell/importer/evolution-importer.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-importer.h"
-
-#include <bonobo/bonobo-object.h>
-#include <e-util/e-util.h>
-
-#include "GNOME_Evolution_Importer.h"
-
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionImporterPrivate {
- EvolutionImporterCreateControlFn create_control_fn;
- EvolutionImporterLoadFileFn load_file_fn;
- EvolutionImporterSupportFormatFn support_format_fn;
- EvolutionImporterProcessItemFn process_item_fn;
- EvolutionImporterGetErrorFn get_error_fn;
-
- gpointer closure;
-};
-
-
-static inline EvolutionImporter *
-evolution_importer_from_servant (PortableServer_Servant servant)
-{
- return EVOLUTION_IMPORTER (bonobo_object_from_servant (servant));
-}
-
-static void
-impl_GNOME_Evolution_Importer_createControl (PortableServer_Servant servant,
- Bonobo_Control *control,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->create_control_fn != NULL)
- (priv->create_control_fn) (importer, control, priv->closure);
- else
- CORBA_exception_set_system (ev, ex_CORBA_NO_IMPLEMENT, CORBA_COMPLETED_NO);
-}
-
-static CORBA_boolean
-impl_GNOME_Evolution_Importer_supportFormat (PortableServer_Servant servant,
- const CORBA_char *filename,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->support_format_fn != NULL)
- return (priv->support_format_fn) (importer, filename,
- priv->closure);
- else
- return FALSE;
-}
-
-static CORBA_boolean
-impl_GNOME_Evolution_Importer_loadFile (PortableServer_Servant servant,
- const CORBA_char *filename,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->load_file_fn != NULL)
- return (priv->load_file_fn) (importer, filename, priv->closure);
- else
- return FALSE;
-}
-
-static void
-impl_GNOME_Evolution_Importer_processItem (PortableServer_Servant servant,
- GNOME_Evolution_ImporterListener listener,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->process_item_fn != NULL)
- (priv->process_item_fn) (importer, listener, priv->closure, ev);
- else
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, FALSE, ev);
-}
-
-static CORBA_char *
-impl_GNOME_Evolution_Importer_getError (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
- CORBA_char *out_str;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->get_error_fn != NULL) {
- out_str = (priv->get_error_fn) (importer, priv->closure);
- return CORBA_string_dup (out_str ? out_str : "");
- } else
- return CORBA_string_dup ("");
-}
-
-
-static void
-finalise (GObject *object)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = EVOLUTION_IMPORTER (object);
- priv = importer->priv;
-
- if (priv == NULL)
- return;
-
- g_free (priv);
- importer->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-evolution_importer_class_init (EvolutionImporterClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_Importer__epv *epv = &klass->epv;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = finalise;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
- epv->createControl = impl_GNOME_Evolution_Importer_createControl;
- epv->supportFormat = impl_GNOME_Evolution_Importer_supportFormat;
- epv->loadFile = impl_GNOME_Evolution_Importer_loadFile;
- epv->processItem = impl_GNOME_Evolution_Importer_processItem;
- epv->getError = impl_GNOME_Evolution_Importer_getError;
-}
-
-static void
-evolution_importer_init (EvolutionImporter *importer)
-{
- EvolutionImporterPrivate *priv;
-
- priv = g_new0 (EvolutionImporterPrivate, 1);
-
- importer->priv = priv;
-}
-
-
-
-static void
-evolution_importer_construct (EvolutionImporter *importer,
- EvolutionImporterCreateControlFn create_control_fn,
- EvolutionImporterSupportFormatFn support_format_fn,
- EvolutionImporterLoadFileFn load_file_fn,
- EvolutionImporterProcessItemFn process_item_fn,
- EvolutionImporterGetErrorFn get_error_fn,
- gpointer closure)
-{
- EvolutionImporterPrivate *priv;
-
- g_return_if_fail (importer != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER (importer));
- g_return_if_fail (support_format_fn != NULL);
- g_return_if_fail (load_file_fn != NULL);
- g_return_if_fail (process_item_fn != NULL);
-
- priv = importer->priv;
- priv->create_control_fn = create_control_fn;
- priv->support_format_fn = support_format_fn;
- priv->load_file_fn = load_file_fn;
- priv->process_item_fn = process_item_fn;
- priv->get_error_fn = get_error_fn;
-
- priv->closure = closure;
-}
-
-/**
- * evolution_importer_new:
- * @support_format_fn: The function to be called by the supportFormat method.
- * @load_file_fn: The function to be called by the loadFile method.
- * @process_item_fn: The function to be called by the processItem method.
- * @get_error_fn: The function to be called by the getError method.
- * @closure: The data to be passed to all of the above functions.
- *
- * Creates a new EvolutionImporter object. Of the parameters only
- * @get_error_function and @closure may be #NULL.
- *
- * Returns: A newly created EvolutionImporter object.
- */
-EvolutionImporter *
-evolution_importer_new (EvolutionImporterCreateControlFn create_control_fn,
- EvolutionImporterSupportFormatFn support_format_fn,
- EvolutionImporterLoadFileFn load_file_fn,
- EvolutionImporterProcessItemFn process_item_fn,
- EvolutionImporterGetErrorFn get_error_fn,
- gpointer closure)
-{
- EvolutionImporter *importer;
-
- importer = g_object_new(evolution_importer_get_type (), NULL);
- evolution_importer_construct (importer, create_control_fn, support_format_fn, load_file_fn,
- process_item_fn, get_error_fn, closure);
- return importer;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionImporter,
- GNOME_Evolution_Importer,
- PARENT_TYPE,
- evolution_importer);
diff --git a/shell/importer/evolution-importer.h b/shell/importer/evolution-importer.h
deleted file mode 100644
index 05eae39b43..0000000000
--- a/shell/importer/evolution-importer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_IMPORTER_H
-#define EVOLUTION_IMPORTER_H
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <importer/GNOME_Evolution_Importer.h>
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_IMPORTER (evolution_importer_get_type ())
-#define EVOLUTION_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_IMPORTER, EvolutionImporter))
-#define EVOLUTION_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_IMPORTER, EvolutionImporterClass))
-#define EVOLUTION_IS_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_IMPORTER))
-#define EVOLUTION_IS_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_IMPORTER))
-
-typedef struct _EvolutionImporter EvolutionImporter;
-typedef struct _EvolutionImporterPrivate EvolutionImporterPrivate;
-typedef struct _EvolutionImporterClass EvolutionImporterClass;
-
-typedef void (* EvolutionImporterCreateControlFn) (EvolutionImporter *importer,
- Bonobo_Control *control,
- gpointer closure);
-
-typedef gboolean (* EvolutionImporterSupportFormatFn) (EvolutionImporter *importer,
- const gchar *filename,
- gpointer closure);
-typedef gboolean (* EvolutionImporterLoadFileFn) (EvolutionImporter *importer,
- const gchar *filename,
- gpointer closure);
-typedef void (* EvolutionImporterProcessItemFn) (EvolutionImporter *importer,
- CORBA_Object listener,
- gpointer closure,
- CORBA_Environment *ev);
-typedef gchar *(* EvolutionImporterGetErrorFn) (EvolutionImporter *importer,
- gpointer closure);
-
-typedef enum {
- EVOLUTION_IMPORTER_OK,
- EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION,
- EVOLUTION_IMPORTER_INTERRUPTED,
- EVOLUTION_IMPORTER_BUSY,
- EVOLUTION_IMPORTER_NOT_READY,
- EVOLUTION_IMPORTER_UNKNOWN_DATA,
- EVOLUTION_IMPORTER_BAD_DATA,
- EVOLUTION_IMPORTER_BAD_FILE,
- EVOLUTION_IMPORTER_UNKNOWN_ERROR
-} EvolutionImporterResult;
-
-struct _EvolutionImporter {
- BonoboObject parent;
-
- EvolutionImporterPrivate *priv;
-};
-
-struct _EvolutionImporterClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Importer__epv epv;
-};
-
-GType evolution_importer_get_type (void);
-
-EvolutionImporter *evolution_importer_new (EvolutionImporterCreateControlFn create_control_fn,
- EvolutionImporterSupportFormatFn support_format_fn,
- EvolutionImporterLoadFileFn load_file_fn,
- EvolutionImporterProcessItemFn process_item_fn,
- EvolutionImporterGetErrorFn get_error_fn,
- void *closure);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/evolution-intelligent-importer.c b/shell/importer/evolution-intelligent-importer.c
deleted file mode 100644
index 48c767cfde..0000000000
--- a/shell/importer/evolution-intelligent-importer.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-intelligent-importer.h"
-
-#include <bonobo/bonobo-object.h>
-
-#include "GNOME_Evolution_Importer.h"
-
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionIntelligentImporterPrivate {
- EvolutionIntelligentImporterCanImportFn can_import_fn;
- EvolutionIntelligentImporterImportDataFn import_data_fn;
-
- gchar *importername;
- gchar *message;
- gpointer closure;
-};
-
-
-static inline EvolutionIntelligentImporter *
-evolution_intelligent_importer_from_servant (PortableServer_Servant servant)
-{
- return EVOLUTION_INTELLIGENT_IMPORTER (bonobo_object_from_servant (servant));
-}
-
-static CORBA_char *
-impl_GNOME_Evolution_IntelligentImporter__get_importername (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = evolution_intelligent_importer_from_servant (servant);
-
- return CORBA_string_dup (ii->priv->importername ?
- ii->priv->importername : "");
-}
-
-static CORBA_char *
-impl_GNOME_Evolution_IntelligentImporter__get_message (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = evolution_intelligent_importer_from_servant (servant);
-
- return CORBA_string_dup (ii->priv->message ?
- ii->priv->message : "");
-}
-
-static CORBA_boolean
-impl_GNOME_Evolution_IntelligentImporter_canImport (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
- EvolutionIntelligentImporterPrivate *priv;
-
- ii = evolution_intelligent_importer_from_servant (servant);
- priv = ii->priv;
-
- if (priv->can_import_fn != NULL)
- return (priv->can_import_fn) (ii, priv->closure);
- else
- return FALSE;
-}
-
-static void
-impl_GNOME_Evolution_IntelligentImporter_importData (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
- EvolutionIntelligentImporterPrivate *priv;
-
- ii = evolution_intelligent_importer_from_servant (servant);
- priv = ii->priv;
-
- if (priv->import_data_fn)
- (priv->import_data_fn) (ii, priv->closure);
-}
-
-
-static void
-finalise (GObject *object)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = EVOLUTION_INTELLIGENT_IMPORTER (object);
-
- if (ii->priv == NULL)
- return;
-
- g_free (ii->priv->importername);
- g_free (ii->priv);
- ii->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-evolution_intelligent_importer_class_init (EvolutionIntelligentImporterClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_IntelligentImporter__epv *epv = &klass->epv;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = finalise;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
- epv->_get_importername = impl_GNOME_Evolution_IntelligentImporter__get_importername;
- epv->_get_message = impl_GNOME_Evolution_IntelligentImporter__get_message;
- epv->canImport = impl_GNOME_Evolution_IntelligentImporter_canImport;
- epv->importData = impl_GNOME_Evolution_IntelligentImporter_importData;
-}
-
-static void
-evolution_intelligent_importer_init (EvolutionIntelligentImporter *ii)
-{
- ii->priv = g_new0 (EvolutionIntelligentImporterPrivate, 1);
-}
-
-
-static void
-evolution_intelligent_importer_construct (EvolutionIntelligentImporter *ii,
- EvolutionIntelligentImporterCanImportFn can_import_fn,
- EvolutionIntelligentImporterImportDataFn import_data_fn,
- const gchar *importername,
- const gchar *message,
- gpointer closure)
-{
- g_return_if_fail (ii != NULL);
- ii->priv->importername = g_strdup (importername);
- ii->priv->message = g_strdup (message);
-
- ii->priv->can_import_fn = can_import_fn;
- ii->priv->import_data_fn = import_data_fn;
- ii->priv->closure = closure;
-}
-
-/**
- * evolution_intelligent_importer_new:
- * can_import_fn: The function that will be called to see if this importer can do
- * anything.
- * import_data_fn: The function that will be called when the importer should
- * import the data.
- * importername: The name of this importer.
- * message: The message that will be displayed when the importer can import.
- * closure: The data to be passed to @can_import_fn and @import_data_fn.
- *
- * Creates a new IntelligentImporter.
- *
- * Returns: A newly allocated EvolutionIntelligentImporter.
- */
-EvolutionIntelligentImporter *
-evolution_intelligent_importer_new (EvolutionIntelligentImporterCanImportFn can_import_fn,
- EvolutionIntelligentImporterImportDataFn import_data_fn,
- const gchar *importername,
- const gchar *message,
- gpointer closure)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = g_object_new (evolution_intelligent_importer_get_type (), NULL);
- evolution_intelligent_importer_construct (ii, can_import_fn,
- import_data_fn, importername,
- message, closure);
- return ii;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionIntelligentImporter,
- GNOME_Evolution_IntelligentImporter,
- PARENT_TYPE,
- evolution_intelligent_importer);
diff --git a/shell/importer/evolution-intelligent-importer.h b/shell/importer/evolution-intelligent-importer.h
deleted file mode 100644
index d9613d3f66..0000000000
--- a/shell/importer/evolution-intelligent-importer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_INTELLIGENT_IMPORTER_H
-#define EVOLUTION_INTELLIGENT_IMPORTER_H
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <importer/GNOME_Evolution_Importer.h>
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_INTELLIGENT_IMPORTER (evolution_intelligent_importer_get_type ())
-#define EVOLUTION_INTELLIGENT_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_INTELLIGENT_IMPORTER, EvolutionIntelligentImporter))
-#define EVOLUTION_INTELLIGENT_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_INTELLIGENT_IMPORTER, EvolutionIntelligentImporterClass))
-#define EVOLUTION_IS_INTELLIGENT_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_INTELLIGENT_IMPORTER))
-#define EVOLUTION_IS_INTELLIGENT_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_INTELLIGENT_IMPORTER))
-
-typedef struct _EvolutionIntelligentImporter EvolutionIntelligentImporter;
-typedef struct _EvolutionIntelligentImporterPrivate EvolutionIntelligentImporterPrivate;
-typedef struct _EvolutionIntelligentImporterClass EvolutionIntelligentImporterClass;
-
-typedef gboolean (* EvolutionIntelligentImporterCanImportFn) (EvolutionIntelligentImporter *ii,
- gpointer closure);
-typedef void (* EvolutionIntelligentImporterImportDataFn) (EvolutionIntelligentImporter *ii,
- gpointer closure);
-
-struct _EvolutionIntelligentImporter {
- BonoboObject parent;
-
- EvolutionIntelligentImporterPrivate *priv;
-};
-
-struct _EvolutionIntelligentImporterClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_IntelligentImporter__epv epv;
-};
-
-GType evolution_intelligent_importer_get_type (void);
-
-EvolutionIntelligentImporter *evolution_intelligent_importer_new (EvolutionIntelligentImporterCanImportFn can_import_fn,
- EvolutionIntelligentImporterImportDataFn import_data_fn,
- const gchar *importername,
- const gchar *message,
- gpointer closure);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/import.glade b/shell/importer/import.glade
deleted file mode 100644
index 389d2feee3..0000000000
--- a/shell/importer/import.glade
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="importwizard">
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
-
- <child>
- <widget class="GnomeDruid" id="druid1">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="show_help">False</property>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page0">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_START</property>
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="text" translatable="yes">Welcome to the Evolution Import Assistant.
-With this assistant you will be guided through the process of
-importing external files into Evolution.</property>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Importer Type</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox2">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select a File</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox1">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page3-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Import Location</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-intelligent">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select Information to Import</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page4">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_FINISH</property>
- <property name="title" translatable="yes">Import File</property>
- <property name="text" translatable="yes">Click &quot;Import&quot; to begin importing the file into Evolution. </property>
- </widget>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/shell/importer/intelligent.c b/shell/importer/intelligent.c
deleted file mode 100644
index 8b7ebaa743..0000000000
--- a/shell/importer/intelligent.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "intelligent.h"
-
-#include <gtk/gtk.h>
-
-#include <libgnome/gnome-config.h>
-#include <glib/gi18n.h>
-
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-widget.h>
-
-#include "intelligent.h"
-#include "GNOME_Evolution_Importer.h"
-
-/* Prototypes */
-
-void intelligent_importer_init (void);
-
-/* End prototypes */
-
-typedef struct {
- CORBA_Object object;
- Bonobo_Control control;
- GtkWidget *widget;
-
- gchar *name;
- gchar *blurb;
- gchar *iid;
-} IntelligentImporterData;
-
-typedef struct {
- GtkWidget *dialog;
- GtkWidget *placeholder;
- GtkWidget *clist;
- BonoboWidget *current;
-
- GList *importers;
-
- gint running;
-} IntelligentImporterDialog;
-
-typedef struct {
- CORBA_Object importer;
- gchar *iid;
-} SelectedImporterData;
-
-static void
-free_importer_dialog (IntelligentImporterDialog *d)
-{
- GList *l;
-
- for (l = d->importers; l; l = l->next) {
- CORBA_Environment ev;
- IntelligentImporterData *data;
-
- data = l->data;
-
- CORBA_exception_init (&ev);
- if (data->object != CORBA_OBJECT_NIL)
- bonobo_object_release_unref (data->object, &ev);
-
- g_free (data->iid);
- g_free (data->name);
- g_free (data->blurb);
- g_free (data);
- }
-
- g_list_free (d->importers);
- gtk_widget_destroy (d->dialog);
- g_free (d);
-}
-
-static void
-start_importers (GList *selected)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- for (; selected; selected = selected->next) {
- SelectedImporterData *selection = selected->data;
-
- GNOME_Evolution_IntelligentImporter_importData (selection->importer, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Error importing %s\n%s", selection->iid,
- CORBA_exception_id (&ev));
- }
- }
- CORBA_exception_free (&ev);
-}
-
-static GList *
-get_intelligent_importers (void)
-{
- Bonobo_ServerInfoList *info_list;
- GList *iids_ret = NULL;
- CORBA_Environment ev;
- gint i;
-
- CORBA_exception_init (&ev);
- info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/IntelligentImporter:" BASE_VERSION "')", NULL, &ev);
- CORBA_exception_free (&ev);
-
- for (i = 0; i < info_list->_length; i++) {
- const Bonobo_ServerInfo *info;
-
- info = info_list->_buffer + i;
- iids_ret = g_list_prepend (iids_ret, g_strdup (info->iid));
- }
-
- return iids_ret;
-}
-
-static void
-select_row_cb (GtkCList *clist,
- gint row,
- gint column,
- GdkEvent *ev,
- IntelligentImporterDialog *d)
-{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (d->placeholder), row);
-}
-
-static void
-unselect_row_cb (GtkCList *clist,
- gint row,
- gint column,
- GdkEvent *ev,
- IntelligentImporterDialog *d)
-{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (d->placeholder), d->running);
-}
-
-static IntelligentImporterDialog *
-create_gui (GList *importers)
-{
- GtkWidget *dialog, *clist, *sw, *label;
- GtkWidget *hbox, *vbox, *dummy;
- IntelligentImporterDialog *d;
- GList *l;
- gint running = 0;
-
- d = g_new (IntelligentImporterDialog, 1);
- d->dialog = dialog = gtk_dialog_new();
- gtk_dialog_set_has_separator ((GtkDialog *) dialog, FALSE);
- gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *)dialog)->vbox, 0);
- gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *)dialog)->action_area, 12);
-
- gtk_window_set_title((GtkWindow *)dialog, _("Importers"));
- dummy = gtk_button_new_from_stock(GTK_STOCK_CONVERT);
- gtk_button_set_label((GtkButton *)dummy, _("Import"));
- gtk_dialog_add_action_widget((GtkDialog *)dialog, dummy, GTK_RESPONSE_ACCEPT);
-
- dummy = gtk_button_new_from_stock(GTK_STOCK_NO);
- gtk_button_set_label((GtkButton *)dummy, _("Do not import"));
- gtk_dialog_add_action_widget((GtkDialog *)dialog, dummy, GTK_RESPONSE_REJECT);
-
- dummy = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
- gtk_button_set_label((GtkButton *)dummy, _("Do not ask me again"));
- gtk_dialog_add_action_widget((GtkDialog *)dialog, dummy, GTK_RESPONSE_CANCEL);
- d->importers = NULL;
- d->current = NULL;
-
- d->clist = clist = gtk_clist_new (1);
- gtk_clist_set_selection_mode (GTK_CLIST (d->clist), GTK_SELECTION_MULTIPLE);
-
- label = gtk_label_new (_("Evolution can import data from the following files:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label,
- TRUE, TRUE, 0);
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
- TRUE, TRUE, 0);
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
- gtk_widget_set_size_request (sw, 300, 150);
- gtk_container_add (GTK_CONTAINER (sw), clist);
- gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0);
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
-
- d->placeholder = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (d->placeholder), FALSE);
- gtk_box_pack_start (GTK_BOX (vbox), d->placeholder, TRUE, TRUE, 0);
-
- for (l = importers; l; l = l->next) {
- IntelligentImporterData *data;
- CORBA_Environment ev;
- gboolean dontaskagain, can_run;
- gchar *text[1], *prefix;
-
- /* Check if we want to show this one again */
- prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", g_get_home_dir ());
- gnome_config_push_prefix (prefix);
- g_free (prefix);
-
- dontaskagain = gnome_config_get_bool (l->data);
- gnome_config_pop_prefix ();
-
- if (dontaskagain)
- continue;
-
- data = g_new0 (IntelligentImporterData, 1);
- data->iid = g_strdup (l->data);
-
- CORBA_exception_init (&ev);
- data->object = bonobo_activation_activate_from_id ((gchar *) data->iid, 0,
- NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not start %s: %s", data->iid,
- CORBA_exception_id (&ev));
- CORBA_exception_free (&ev);
-
- /* Clean up the IntelligentImporterData */
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- CORBA_exception_free (&ev);
- if (data->object == CORBA_OBJECT_NIL) {
- g_warning ("Could not activate_component %s", data->iid);
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- CORBA_exception_init (&ev);
- can_run = GNOME_Evolution_IntelligentImporter_canImport (data->object,
- &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not get canImport(%s): %s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data);
- continue;
- }
- CORBA_exception_free (&ev);
-
- if (can_run == FALSE) {
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- running++;
-
- data->name = g_strdup (GNOME_Evolution_IntelligentImporter__get_importername (data->object, &ev));
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not get name(%s): %s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- data->blurb = g_strdup (GNOME_Evolution_IntelligentImporter__get_message (data->object, &ev));
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not get message(%s): %s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data->name);
- g_free (data);
- continue;
- }
-
- data->control = Bonobo_Unknown_queryInterface (data->object,
- "IDL:Bonobo/Control:1.0", &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not QI for Bonobo/Control:1.0 %s:%s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data->name);
- g_free (data->blurb);
- continue;
- }
- if (data->control != CORBA_OBJECT_NIL) {
- data->widget = bonobo_widget_new_control_from_objref (data->control, CORBA_OBJECT_NIL);
- /* Ref this widget so even if we remove it from the
- containers it will always have an extra ref. */
- gtk_widget_show (data->widget);
- g_object_ref (data->widget);
- } else {
- data->widget = gtk_label_new ("");
- }
-
- CORBA_exception_free (&ev);
-
- d->importers = g_list_prepend (d->importers, data);
- gtk_notebook_prepend_page (GTK_NOTEBOOK (d->placeholder),
- data->widget, NULL);
- text[0] = data->name;
- gtk_clist_prepend (GTK_CLIST (clist), text);
- }
-
- d->running = running;
- dummy = gtk_drawing_area_new ();
- gtk_widget_show (dummy);
- gtk_notebook_append_page (GTK_NOTEBOOK (d->placeholder),
- dummy, NULL);
- /* Set the start to the blank page */
- gtk_notebook_set_current_page (GTK_NOTEBOOK (d->placeholder), running);
-
- g_signal_connect((clist), "select-row",
- G_CALLBACK (select_row_cb), d);
- g_signal_connect((clist), "unselect-row",
- G_CALLBACK (unselect_row_cb), d);
-
- gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
- return d;
-}
-
-void
-intelligent_importer_init (void)
-{
- GList *importers, *l, *selected = NULL;
- IntelligentImporterDialog *d;
- gchar *prefix;
- gboolean dontaskagain;
- gint resp;
-
- prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", g_get_home_dir());
- gnome_config_push_prefix (prefix);
- g_free (prefix);
-
- dontaskagain = gnome_config_get_bool ("Dontaskagain=False");
- gnome_config_pop_prefix ();
-
- if (dontaskagain) {
- return;
- }
-
- importers = get_intelligent_importers ();
- if (importers == NULL)
- return; /* No intelligent importers. Easy :) */
-
- d = create_gui (importers);
- if (d->running == 0) {
- free_importer_dialog (d);
- return; /* No runnable intelligent importers. */
- }
-
- resp = gtk_dialog_run((GtkDialog *)d->dialog);
- gtk_widget_destroy(d->dialog);
- switch (resp) {
- case GTK_RESPONSE_ACCEPT:
- /* Make a list of the importers */
-
- /* FIXME: Sort this list and don't do it a slow way */
- for (l = GTK_CLIST (d->clist)->selection; l; l = l->next) {
- IntelligentImporterData *data;
- SelectedImporterData *new_data;
- CORBA_Environment ev;
- gchar *iid;
-
- data = g_list_nth_data (d->importers, GPOINTER_TO_INT (l->data));
- iid = g_strdup (data->iid);
-
- new_data = g_new (SelectedImporterData, 1);
- new_data->iid = iid;
-
- /* Reference the remote object, and duplicate the
- local one. */
- CORBA_exception_init (&ev);
- new_data->importer = bonobo_object_dup_ref (data->object, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Error duplicating %s\n%s", iid,
- CORBA_exception_id (&ev));
- g_free (iid);
- CORBA_exception_free (&ev);
- g_free (new_data);
- continue;
- }
- CORBA_exception_free (&ev);
-
- selected = g_list_prepend (selected, new_data);
- }
-
- /* Now destroy all the importers, as we've kept references to
- the ones we need */
- free_importer_dialog (d);
-
- if (selected != NULL) {
- /* Restart the selected ones */
- start_importers (selected);
-
- /* Free the selected list */
- for (l = selected; l; l = l->next) {
- CORBA_Environment ev;
- SelectedImporterData *selection = l->data;
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (selection->importer, &ev);
- CORBA_exception_free (&ev);
-
- g_free (selection->iid);
- g_free (selection);
- }
- g_list_free (selected);
- }
-
- break;
-
- case GTK_RESPONSE_CANCEL: /* Dont ask again */
- prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", g_get_home_dir());
- gnome_config_push_prefix (prefix);
- g_free (prefix);
-
- gnome_config_set_bool ("Dontaskagain", TRUE);
- gnome_config_pop_prefix ();
-
- gnome_config_sync ();
- gnome_config_drop_all ();
- g_print ("Not asking again");
- free_importer_dialog (d);
- break;
-
- default:
- case GTK_RESPONSE_REJECT: /* No button */
- free_importer_dialog (d);
- break;
- }
-
- g_list_free (importers);
-}
diff --git a/shell/main.c b/shell/main.c
index 21cc278c7f..72333c17f7 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h> /* for copied UniqueApp code */
#include <glib/gstdio.h>
#ifdef G_OS_WIN32
@@ -40,12 +41,10 @@
#include "e-util/e-bconf-map.h"
#include <e-util/e-icon-factory.h>
-#include "e-shell-constants.h"
#include "e-util/e-profile-event.h"
#include "e-util/e-util.h"
#include "e-shell.h"
-#include "es-menu.h"
#include "es-event.h"
#include "e-util/e-util-private.h"
@@ -57,22 +56,13 @@
#include <gconf/gconf-client.h>
#include <glib/gi18n.h>
-#include <libgnome/gnome-sound.h>
-#include <libgnomeui/gnome-ui-init.h>
-#include <libgnomeui/gnome-client.h>
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <bonobo-activation/bonobo-activation.h>
+#include <libedataserver/e-categories.h>
#include <libedataserverui/e-passwords.h>
#include <glade/glade.h>
#include "e-config-upgrade.h"
-#include "Evolution-DataServer.h"
#include <misc/e-cursors.h>
#include "e-util/e-error.h"
@@ -98,13 +88,11 @@
#define DEVELOPMENT 1
#endif
-static EShell *shell = NULL;
-
/* Command-line options. */
static gboolean start_online = FALSE;
static gboolean start_offline = FALSE;
static gboolean setup_only = FALSE;
-static gboolean killev = FALSE;
+static gboolean force_shutdown = FALSE;
#ifdef DEVELOPMENT
static gboolean force_migrate = FALSE;
#endif
@@ -112,84 +100,43 @@ static gboolean disable_eplugin = FALSE;
static gboolean disable_preview = FALSE;
static gboolean idle_cb (gchar **uris);
-static gchar *default_component_id = NULL;
+static gchar *requested_view = NULL;
static gchar *evolution_debug_log = NULL;
static gchar **remaining_args;
-static void
-no_windows_left_cb (EShell *shell, gpointer data)
-{
- bonobo_object_unref (BONOBO_OBJECT (shell));
- bonobo_main_quit ();
-}
-
-static void
-shell_weak_notify (gpointer data,
- GObject *where_the_object_was)
-{
- bonobo_main_quit ();
-}
-
-#ifdef KILL_PROCESS_CMD
+/* Defined in <e-shell.h> */
+extern EShell *default_shell;
static void
-kill_dataserver (void)
+categories_icon_theme_hack (void)
{
- g_message ("Killing old version of evolution-data-server...");
-
- system (KILL_PROCESS_CMD " -9 lt-evolution-data-server 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.0 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.2 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.4 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.6 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.8 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.10 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.12 2> /dev/null");
-
- system (KILL_PROCESS_CMD " -9 lt-evolution-alarm-notify 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-alarm-notify 2> /dev/null");
+ GtkIconTheme *icon_theme;
+ const gchar *category_name;
+ const gchar *filename;
+ gchar *dirname;
+
+ /* XXX Allow the category icons to be referenced as named
+ * icons, since GtkAction does not support GdkPixbufs. */
+
+ /* Get the icon file for some default category. Doesn't matter
+ * which, so long as it has an icon. We're just interested in
+ * the directory components. */
+ category_name = _("Birthday");
+ filename = e_categories_get_icon_file_for (category_name);
+ g_return_if_fail (filename != NULL && *filename != '\0');
+
+ /* Extract the directory components. */
+ dirname = g_path_get_dirname (filename);
+
+ /* Add it to the icon theme's search path. This relies on
+ * GtkIconTheme's legacy feature of using image files found
+ * directly in the search path. */
+ icon_theme = gtk_icon_theme_get_default ();
+ gtk_icon_theme_append_search_path (icon_theme, dirname);
+
+ g_free (dirname);
}
-static void
-kill_old_dataserver (void)
-{
- GNOME_Evolution_DataServer_InterfaceCheck iface;
- CORBA_Environment ev;
- CORBA_char *version;
-
- CORBA_exception_init (&ev);
-
- /* FIXME Should we really kill it off? We also shouldn't hard code the version */
- iface = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) "OAFIID:GNOME_Evolution_DataServer_InterfaceCheck", 0, NULL, &ev);
- if (BONOBO_EX (&ev) || iface == CORBA_OBJECT_NIL) {
- kill_dataserver ();
- CORBA_exception_free (&ev);
- return;
- }
-
- version = GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion (iface, &ev);
- if (BONOBO_EX (&ev)) {
- kill_dataserver ();
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- if (strcmp (version, DATASERVER_VERSION) != 0) {
- CORBA_free (version);
- kill_dataserver ();
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_free (version);
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
-}
-#endif
-
#ifdef DEVELOPMENT
/* Warning dialog to scare people off a little bit. */
@@ -269,8 +216,6 @@ show_development_warning(void)
gtk_widget_destroy (warning_dialog);
- idle_cb (NULL);
-
return skip;
}
@@ -291,124 +236,26 @@ destroy_config (GConfClient *client)
#endif /* DEVELOPMENT */
-static void
-open_uris (GNOME_Evolution_Shell corba_shell, gchar **uris)
-{
- CORBA_Environment ev;
- guint n_uris, ii;
-
- g_return_if_fail (uris != NULL);
- n_uris = g_strv_length (uris);
-
- CORBA_exception_init (&ev);
-
- for (ii = 0; ii < n_uris; ii++) {
- GNOME_Evolution_Shell_handleURI (corba_shell, uris[ii], &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Invalid URI: %s", uris[ii]);
- CORBA_exception_free (&ev);
- }
- }
-
- CORBA_exception_free (&ev);
-}
-
/* This is for doing stuff that requires the GTK+ loop to be running already. */
static gboolean
idle_cb (gchar **uris)
{
- GNOME_Evolution_Shell corba_shell;
- CORBA_Environment ev;
- EShellConstructResult result;
- EShellStartupLineMode startup_line_mode;
-
- g_return_val_if_fail (uris == NULL || g_strv_length (uris) > 0, FALSE);
-
-#ifdef KILL_PROCESS_CMD
- kill_old_dataserver ();
-#endif
+ EShell *shell;
- CORBA_exception_init (&ev);
-
- if (! start_online && ! start_offline)
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_CONFIG;
- else if (start_online)
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_ONLINE;
- else
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_OFFLINE;
-
- shell = e_shell_new (startup_line_mode, &result);
-
- switch (result) {
- case E_SHELL_CONSTRUCT_RESULT_OK:
- e_shell_set_crash_recovery (shell, e_file_lock_exists ());
- g_signal_connect (shell, "no_windows_left", G_CALLBACK (no_windows_left_cb), NULL);
- g_object_weak_ref (G_OBJECT (shell), shell_weak_notify, NULL);
- corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell));
- corba_shell = CORBA_Object_duplicate (corba_shell, &ev);
- break;
-
- case E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER:
- corba_shell = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) E_SHELL_OAFIID, 0, NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION || corba_shell == CORBA_OBJECT_NIL) {
- e_error_run(NULL, "shell:noshell", NULL);
- CORBA_exception_free (&ev);
- bonobo_main_quit ();
- return FALSE;
- }
- break;
+ shell = e_shell_get_default ();
- default:
- e_error_run(NULL, "shell:noshell-reason",
- e_shell_construct_result_to_string(result), NULL);
- CORBA_exception_free (&ev);
- bonobo_main_quit ();
- return FALSE;
+ /* These calls do the right thing when another Evolution
+ * process is running. */
+ if (uris != NULL && *uris != NULL) {
+ if (e_shell_handle_uris (shell, uris) == 0)
+ gtk_main_quit ();
+ } else
+ e_shell_create_shell_window (shell, requested_view);
- }
-
- if (shell != NULL) {
- if (uris != NULL)
- open_uris (corba_shell, uris);
- else {
- e_file_lock_create ();
- e_shell_create_window (shell, default_component_id, NULL);
- }
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- if (uris != NULL)
- open_uris (corba_shell, uris);
- else
- if (default_component_id == NULL)
- GNOME_Evolution_Shell_createNewWindow (corba_shell, "", &ev);
- else
- GNOME_Evolution_Shell_createNewWindow (corba_shell, default_component_id, &ev);
-
- CORBA_exception_free (&ev);
- }
-
- CORBA_Object_release (corba_shell, &ev);
-
- CORBA_exception_free (&ev);
-
- if (shell == NULL) {
- /*there is another instance but because we don't open any windows
- we must notify the startup was complete manually*/
- gdk_notify_startup_complete ();
- bonobo_main_quit ();
- }
-
- /* This must be done after Bonobo has created all the components. For
- * example the mail component makes the global variable `session` which
- * is being used by several EPlugins */
-
- if (!disable_eplugin) {
- e_plugin_load_plugins_with_missing_symbols ();
- }
+ /* If another Evolution process is running, we're done. */
+ if (unique_app_is_running (UNIQUE_APP (shell)))
+ gtk_main_quit ();
return FALSE;
}
@@ -470,27 +317,15 @@ setup_segv_redirect (void)
#define setup_segv_redirect() (void)0
#endif
-static gint
-gnome_master_client_save_yourself_cb (GnomeClient *client, GnomeSaveStyle save_style, gint shutdown, GnomeInteractStyle interact_style, gint fast, gpointer user_data)
-{
- return !shell || e_shell_can_quit (shell);
-}
-
-static void
-gnome_master_client_die_cb (GnomeClient *client)
-{
- e_shell_do_quit (shell);
-}
-
-static const GOptionEntry options[] = {
- { "component", 'c', 0, G_OPTION_ARG_STRING, &default_component_id,
+static GOptionEntry entries[] = {
+ { "component", 'c', 0, G_OPTION_ARG_STRING, &requested_view,
N_("Start Evolution activating the specified component"), NULL },
{ "offline", '\0', 0, G_OPTION_ARG_NONE, &start_offline,
N_("Start in offline mode"), NULL },
{ "online", '\0', 0, G_OPTION_ARG_NONE, &start_online,
N_("Start in online mode"), NULL },
#ifdef KILL_PROCESS_CMD
- { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &killev,
+ { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &force_shutdown,
N_("Forcibly shut down all Evolution components"), NULL },
#endif
#ifdef DEVELOPMENT
@@ -514,8 +349,7 @@ static void
set_paths (void)
{
/* Set PATH to include the Evolution executable's folder
- * and the lib/evolution/$(BASE_VERSION)/components folder.
- */
+ * and the lib/evolution/$(BASE_VERSION)/components folder. */
wchar_t exe_filename[MAX_PATH];
wchar_t *p;
gchar *exe_folder_utf8;
@@ -536,60 +370,99 @@ set_paths (void)
*p = L'\0';
top_folder_utf8 = g_utf16_to_utf8 (exe_filename, -1, NULL, NULL, NULL);
- components_folder_utf8 =
- g_strconcat (top_folder_utf8,
- "/lib/evolution/" BASE_VERSION "/components",
- NULL);
-
- path = g_build_path (";",
- exe_folder_utf8,
- components_folder_utf8,
- g_getenv ("PATH"),
- NULL);
+ components_folder_utf8 = g_strconcat (
+ top_folder_utf8, "/lib/evolution/"
+ BASE_VERSION "/components", NULL);
+
+ path = g_build_path (
+ ";", exe_folder_utf8,
+ components_folder_utf8, g_getenv ("PATH"), NULL);
if (!g_setenv ("PATH", path, TRUE))
- g_warning ("Could not set PATH for Evolution and its child processes");
+ g_warning ("Could not set PATH for Evolution "
+ "and its child processes");
g_free (path);
g_free (exe_folder_utf8);
g_free (components_folder_utf8);
- /* Set BONOBO_ACTIVATION_PATH */
- if (g_getenv ("BONOBO_ACTIVATION_PATH" ) == NULL) {
- path = g_build_filename (top_folder_utf8,
- "lib/bonobo/servers",
- NULL);
- if (!g_setenv ("BONOBO_ACTIVATION_PATH", path, TRUE))
- g_warning ("Could not set BONOBO_ACTIVATION_PATH");
- g_free (path);
- }
g_free (top_folder_utf8);
}
#endif
+static void
+shell_window_destroyed_cb (EShell *shell)
+{
+ if (e_shell_get_watched_windows (shell) == NULL)
+ gtk_main_quit ();
+}
+
+static void
+create_default_shell (void)
+{
+ EShell *shell;
+ GConfClient *client;
+ gboolean online = TRUE;
+ GError *error = NULL;
+
+ client = gconf_client_get_default ();
+
+ if (start_online)
+ online = TRUE;
+ else if (start_offline)
+ online = FALSE;
+ else {
+ const gchar *key;
+ gboolean value;
+
+ key = "/apps/evolution/shell/start_offline";
+ value = gconf_client_get_bool (client, key, &error);
+ if (error == NULL)
+ online = !value;
+ else {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ }
+
+ shell = g_object_new (
+ E_TYPE_SHELL,
+ "name", "org.gnome.evolution",
+ "online", online,
+ NULL);
+
+ g_signal_connect (
+ shell, "window-destroyed",
+ G_CALLBACK (shell_window_destroyed_cb), NULL);
+
+ g_object_unref (client);
+
+ /* EShell keeps its own reference to the first instance for use
+ * in e_shell_get_default(), so it's safe to unreference here. */
+ g_object_unref (shell);
+
+ g_idle_add ((GSourceFunc) idle_cb, remaining_args);
+}
+
gint
main (gint argc, gchar **argv)
{
#ifdef G_OS_WIN32
- if (fileno (stdout) != -1 &&
- _get_osfhandle (fileno (stdout)) != -1)
- {
- /* stdout is fine, presumably redirected to a file or pipe */
- }
- else
- {
- typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
+ if (fileno (stdout) != -1 && _get_osfhandle (fileno (stdout)) != -1) {
+ /* stdout is fine, presumably redirected to a file or pipe */
+ } else {
+ typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
- AttachConsole_t p_AttachConsole =
- (AttachConsole_t) GetProcAddress (GetModuleHandle ("kernel32.dll"), "AttachConsole");
+ AttachConsole_t p_AttachConsole =
+ (AttachConsole_t) GetProcAddress (
+ GetModuleHandle ("kernel32.dll"), "AttachConsole");
- if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
+ if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
{
- freopen ("CONOUT$", "w", stdout);
- dup2 (fileno (stdout), 1);
- freopen ("CONOUT$", "w", stderr);
- dup2 (fileno (stderr), 2);
-
- }
+ freopen ("CONOUT$", "w", stdout);
+ dup2 (fileno (stdout), 1);
+ freopen ("CONOUT$", "w", stderr);
+ dup2 (fileno (stderr), 2);
+ }
}
extern void link_shutdown (void);
@@ -599,10 +472,8 @@ main (gint argc, gchar **argv)
#ifdef DEVELOPMENT
gboolean skip_warning_dialog;
#endif
- GnomeProgram *program;
- GnomeClient *master_client;
- GOptionContext *context;
gchar *filename;
+ GError *error = NULL;
/* Make ElectricFence work. */
free (malloc (10));
@@ -611,21 +482,19 @@ main (gint argc, gchar **argv)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- context = g_option_context_new (_("- The Evolution PIM and Email Client"));
-
- g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-
- g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
-
#ifdef G_OS_WIN32
set_paths ();
#endif
- program = gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv,
- GNOME_PROGRAM_STANDARD_PROPERTIES,
- GNOME_PARAM_GOPTION_CONTEXT, context,
- GNOME_PARAM_HUMAN_READABLE_NAME, _("Evolution"),
- NULL);
+ gtk_init_with_args (
+ &argc, &argv,
+ _("- The Evolution PIM and Email Client"),
+ entries, (gchar *) GETTEXT_PACKAGE, &error);
+ if (error != NULL) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (1);
+ }
#ifdef G_OS_WIN32
if (strcmp (gettext (""), "") == 0) {
@@ -639,15 +508,14 @@ main (gint argc, gchar **argv)
}
#endif
if (start_online && start_offline) {
- fprintf (stderr, _("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"),
+ g_printerr (_("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"),
argv[0], argv[0]);
exit (1);
}
- if (killev) {
- filename = g_build_filename (EVOLUTION_TOOLSDIR,
- "killev",
- NULL);
+ if (force_shutdown) {
+ filename = g_build_filename (
+ EVOLUTION_TOOLSDIR, "killev", NULL);
execl (filename, "killev", NULL);
/* Not reached */
exit (0);
@@ -656,11 +524,10 @@ main (gint argc, gchar **argv)
client = gconf_client_get_default ();
#ifdef DEVELOPMENT
-
- if (force_migrate) {
+ if (force_migrate)
destroy_config (client);
- }
#endif
+
if (disable_preview) {
gconf_client_set_bool (client, "/apps/evolution/mail/display/show_preview", FALSE, NULL);
gconf_client_set_bool (client, "/apps/evolution/mail/display/safe_list", TRUE, NULL);
@@ -682,37 +549,19 @@ main (gint argc, gchar **argv)
g_warning ("Could not set up debugging output file.");
}
- master_client = gnome_master_client ();
-
- g_signal_connect (G_OBJECT (master_client), "save_yourself", G_CALLBACK (gnome_master_client_save_yourself_cb), NULL);
- g_signal_connect (G_OBJECT (master_client), "die", G_CALLBACK (gnome_master_client_die_cb), NULL);
-
glade_init ();
e_cursors_init ();
e_icon_factory_init ();
- e_passwords_init();
+ e_passwords_init ();
gtk_window_set_default_icon_name ("evolution");
if (setup_only)
exit (0);
- gnome_sound_init ("localhost");
+ categories_icon_theme_hack ();
gtk_accel_map_load (e_get_accels_filename ());
- if (!disable_eplugin) {
- e_plugin_register_type(e_plugin_lib_get_type());
- e_plugin_hook_register_type(es_menu_hook_get_type());
- e_plugin_hook_register_type(es_event_hook_get_type());
-#ifdef ENABLE_PROFILING
- e_plugin_hook_register_type(e_profile_event_hook_get_type());
-#endif
- e_plugin_hook_register_type(e_plugin_type_hook_get_type());
- e_plugin_hook_register_type(e_import_hook_get_type());
- e_plugin_hook_register_type(E_TYPE_PLUGIN_UI_HOOK);
- e_plugin_load_plugins ();
- }
-
#ifdef DEVELOPMENT
skip_warning_dialog = gconf_client_get_bool (
client, SKIP_WARNING_DIALOG_KEY, NULL);
@@ -721,24 +570,41 @@ main (gint argc, gchar **argv)
gconf_client_set_bool (
client, SKIP_WARNING_DIALOG_KEY,
show_development_warning (), NULL);
- else
- g_idle_add ((GSourceFunc) idle_cb, remaining_args);
-
-#else
- g_idle_add ((GSourceFunc) idle_cb, remaining_args);
#endif
+
g_object_unref (client);
- bonobo_main ();
+ create_default_shell ();
+
+ if (!disable_eplugin) {
+ /* Register built-in plugin hook types. */
+ es_event_hook_get_type ();
+#ifdef ENABLE_PROFILING
+ e_profile_event_hook_get_type ();
+#endif
+ e_import_hook_get_type ();
+ e_plugin_ui_hook_get_type ();
+
+ /* All EPlugin and EPluginHook subclasses should be
+ * registered in GType now, so load plugins now. */
+ e_plugin_load_plugins ();
+ }
+
+ gtk_main ();
+
+ /* Drop what should be the last reference to the shell.
+ * Emit a warning if references are leaking somewhere. */
+ g_object_unref (default_shell);
+ if (E_IS_SHELL (default_shell))
+ g_warning ("Shell not finalized on exit");
gtk_accel_map_save (e_get_accels_filename ());
e_icon_factory_shutdown ();
- g_object_unref (program);
- gnome_sound_shutdown ();
e_cursors_shutdown ();
#ifdef G_OS_WIN32
link_shutdown ();
#endif
+
return 0;
}
diff --git a/shell/shell.error.xml b/shell/shell.error.xml
index 7ae57dec58..603d5ed955 100644
--- a/shell/shell.error.xml
+++ b/shell/shell.error.xml
@@ -16,9 +16,8 @@ You will need to make more space available in your home directory before you can
</error>
<error id="upgrade-failed" type="error">
- <_primary>Upgrade from previous version failed:
-{0}</_primary>
- <_secondary xml:space="preserve">{1}
+ <_primary>Upgrade from previous version failed:</_primary>
+ <_secondary xml:space="preserve">{0}
If you choose to continue, you may not have access to some of your old data.
</_secondary>
@@ -51,28 +50,6 @@ Once deleted, you cannot downgrade to the previous version of Evolution without
<button stock="gtk-delete" response="GTK_RESPONSE_OK"/>
</error>
- <error id="noshell" type="error">
- <_title>Cannot start Evolution</_title>
- <_primary>Evolution can not start.</_primary>
- <_secondary xml:space="preserve">Your system configuration does not match your Evolution configuration.
-
-Click help for details</_secondary>
- <help uri="http://go-evolution.org/FAQ#What_does_.22Your_system_configuration_does_not_match_your_Evolution_configuration.22_mean.3F"/>
- <button stock="gtk-quit" response="GTK_RESPONSE_CANCEL"/>
- </error>
-
- <error id="noshell-reason" type="error">
- <_title>Cannot start Evolution</_title>
- <_primary>Evolution can not start.</_primary>
- <_secondary xml:space="preserve">Your system configuration does not match your Evolution configuration:
-
-{0}
-
-Click help for details.</_secondary>
- <help uri="http://go-evolution.org/FAQ#What_does_.22Your_system_configuration_does_not_match_your_Evolution_configuration.22_mean.3F"/>
- <button stock="gtk-quit" response="GTK_RESPONSE_CANCEL"/>
- </error>
-
<error id="forget-passwords" type="question" default="GTK_RESPONSE_CANCEL">
<_primary>Are you sure you want to forget all remembered passwords?</_primary>
<_secondary xml:space="preserve">Forgetting your passwords will clear all remembered passwords. You will be reprompted next time they are needed.</_secondary>
diff --git a/shell/test/GNOME_Evolution_Test.server.in.in b/shell/test/GNOME_Evolution_Test.server.in.in
deleted file mode 100644
index ef0db8b1ac..0000000000
--- a/shell/test/GNOME_Evolution_Test.server.in.in
+++ /dev/null
@@ -1,39 +0,0 @@
-<oaf_info>
-
- <!-- (factory) -->
- <oaf_server iid="OAFIID:GNOME_Evolution_Test_Factory:@VERSION@"
- type="shlib"
- location="@COMPONENTDIR_IN_SERVER_FILE@/libevolution-test@SOEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Test"/>
- </oaf_server>
-
- <!-- Component Interface -->
-
- <oaf_server iid="OAFIID:GNOME_Evolution_Test_Component:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Test_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Component:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string" _value="Evolution Test component"/>
-
- <oaf_attribute name="evolution:component_alias" type="string" value="test"/>
-
- <oaf_attribute name="evolution:button_label" type="string" _value="Test"/>
- <oaf_attribute name="evolution:button_sort_order" type="string" value="-1"/>
- <oaf_attribute name="evolution:button_icon" type="string" value="stock_mail"/>
-
- <oaf_attribute name="evolution:component_icon" type="string" value="stock_mail"/>
- <oaf_attribute name="evolution:component_display_order" type="number" value="1"/>
-
- </oaf_server>
-
-</oaf_info>
diff --git a/shell/test/Makefile.am b/shell/test/Makefile.am
index 8a2efd8a4a..10b1bfb81b 100644
--- a/shell/test/Makefile.am
+++ b/shell/test/Makefile.am
@@ -1,37 +1,27 @@
-component_LTLIBRARIES = libevolution-test.la
+module_LTLIBRARIES = libevolution-module-test.la
AM_CPPFLAGS = \
+ -I$(top_srcdir) \
-I$(top_srcdir)/shell \
+ -I$(top_srcdir)/widgets \
+ -I$(top_srcdir)/widgets/menus \
-I$(top_srcdir)/widgets/misc \
-I$(top_builddir)/shell \
-DG_LOG_DOMAIN=\"evolution-test\" \
$(EVOLUTION_TEST_CFLAGS)
-libevolution_test_la_SOURCES = \
- evolution-test-component.c \
- evolution-test-component.h
+libevolution_module_test_la_SOURCES = \
+ evolution-module-test.c \
+ e-test-shell-backend.c \
+ e-test-shell-backend.h \
+ e-test-shell-view.c \
+ e-test-shell-view.h
-libevolution_test_la_LIBADD = \
+libevolution_module_test_la_LIBADD = \
$(top_builddir)/shell/libeshell.la \
$(EVOLUTION_TEST_LIBS)
-libevolution_test_la_LDFLAGS = \
+libevolution_module_test_la_LDFLAGS = \
-avoid-version -module $(NO_UNDEFINED)
-testserver_in_files = GNOME_Evolution_Test.server.in.in
-testserver_DATA = $(testserver_in_files:.server.in.in=.server)
-testserverdir = $(serverdir)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
-
-BUILT_SOURCES = $(testserver_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
-EXTRA_DIST = \
- $(testserver_in_files) \
- GNOME_Evolution_Test.server.in.in
-
-dist-hook:
- cd $(distdir); rm -f $(BUILD_SOURCES)
-
-include $(top_srcdir)/git.mk
diff --git a/shell/test/e-test-shell-backend.c b/shell/test/e-test-shell-backend.c
new file mode 100644
index 0000000000..6a6c03bddd
--- /dev/null
+++ b/shell/test/e-test-shell-backend.c
@@ -0,0 +1,222 @@
+/*
+ * e-test-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-test-shell-backend.h"
+
+#include <glib/gi18n.h>
+
+#include "shell/e-shell.h"
+#include "shell/e-shell-window.h"
+
+#include "e-test-shell-view.h"
+
+#define E_TEST_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackendPrivate))
+
+struct _ETestShellBackendPrivate {
+ gint placeholder;
+};
+
+static gpointer parent_class;
+static GType test_shell_backend_type;
+
+static void
+action_test_item_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static void
+action_test_source_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "test-item-new",
+ "document-new",
+ NC_("New", "_Test Item"),
+ NULL,
+ N_("Create a new test item"),
+ G_CALLBACK (action_test_item_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "test-source-new",
+ "folder-new",
+ NC_("New", "Test _Source"),
+ NULL,
+ N_("Create a new test source"),
+ G_CALLBACK (action_test_source_new_cb) }
+};
+
+static void
+test_shell_backend_start (EShellBackend *shell_backend)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static gboolean
+test_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ g_debug ("%s (from %d.%d.%d)", G_STRFUNC, major, minor, micro);
+
+ return TRUE;
+}
+
+static gboolean
+test_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
+ const gchar *uri)
+{
+ g_debug ("%s (uri=%s)", G_STRFUNC, uri);
+
+ return FALSE;
+}
+
+static void
+test_shell_backend_send_receive_cb (EShellBackend *shell_backend,
+ GtkWindow *parent_window)
+{
+ g_debug ("%s (window=%p)", G_STRFUNC, parent_window);
+}
+
+static void
+test_shell_backend_window_created_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
+{
+ const gchar *backend_name;
+
+ g_debug ("%s (%s)", G_STRFUNC, G_OBJECT_TYPE_NAME (window));
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+}
+
+static void
+test_shell_backend_window_destroyed_cb (EShellBackend *shell_backend)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static void
+test_shell_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "handle-uri",
+ G_CALLBACK (test_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "send-receive",
+ G_CALLBACK (test_shell_backend_send_receive_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (test_shell_backend_window_created_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-destroyed",
+ G_CALLBACK (test_shell_backend_window_destroyed_cb),
+ shell_backend);
+}
+
+static void
+test_shell_backend_class_init (ETestShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETestShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = test_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_TEST_SHELL_VIEW;
+ shell_backend_class->name = "test";
+ shell_backend_class->aliases = "monkey";
+ shell_backend_class->schemes = "";
+ shell_backend_class->sort_order = 100;
+ shell_backend_class->start = test_shell_backend_start;
+ shell_backend_class->migrate = test_shell_backend_migrate;
+}
+
+static void
+test_shell_backend_init (ETestShellBackend *test_shell_backend)
+{
+ test_shell_backend->priv =
+ E_TEST_SHELL_BACKEND_GET_PRIVATE (test_shell_backend);
+}
+
+GType
+e_test_shell_backend_get_type (void)
+{
+ return test_shell_backend_type;
+}
+
+void
+e_test_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ETestShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) test_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETestShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) test_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ test_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "ETestShellBackend", &type_info, 0);
+}
diff --git a/shell/test/e-test-shell-backend.h b/shell/test/e-test-shell-backend.h
new file mode 100644
index 0000000000..0d342bfbcc
--- /dev/null
+++ b/shell/test/e-test-shell-backend.h
@@ -0,0 +1,67 @@
+/*
+ * e-test-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TEST_SHELL_BACKEND_H
+#define E_TEST_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TEST_SHELL_BACKEND \
+ (e_test_shell_backend_get_type ())
+#define E_TEST_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackend))
+#define E_TEST_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackendClass))
+#define E_IS_TEST_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND))
+#define E_IS_TEST_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TEST_SHELL_BACKEND))
+#define E_TEST_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETestShellBackend ETestShellBackend;
+typedef struct _ETestShellBackendClass ETestShellBackendClass;
+typedef struct _ETestShellBackendPrivate ETestShellBackendPrivate;
+
+struct _ETestShellBackend {
+ EShellBackend parent;
+ ETestShellBackendPrivate *priv;
+};
+
+struct _ETestShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_test_shell_backend_get_type (void);
+void e_test_shell_backend_register_type
+ (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_TEST_SHELL_BACKEND_H */
diff --git a/shell/test/e-test-shell-view.c b/shell/test/e-test-shell-view.c
new file mode 100644
index 0000000000..b4464cc68f
--- /dev/null
+++ b/shell/test/e-test-shell-view.c
@@ -0,0 +1,155 @@
+/*
+ * e-test-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-test-shell-view.h"
+
+#include "shell/e-shell-content.h"
+#include "shell/e-shell-sidebar.h"
+
+#define E_TEST_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellViewPrivate))
+
+struct _ETestShellViewPrivate {
+ EActivity *activity;
+};
+
+static gpointer parent_class;
+static GType test_shell_view_type;
+
+static void
+test_shell_view_toggled (EShellView *shell_view)
+{
+#if 0
+ gboolean is_active;
+ const gchar *active;
+
+ is_active = e_shell_view_is_active (shell_view);
+ active = is_active ? "active" : "inactive";
+ g_debug ("%s (now %s)", G_STRFUNC, active);
+#endif
+}
+
+static void
+test_shell_view_dispose (GObject *object)
+{
+ ETestShellViewPrivate *priv;
+
+ priv = E_TEST_SHELL_VIEW_GET_PRIVATE (object);
+
+ if (priv->activity != NULL) {
+ e_activity_complete (priv->activity);
+ g_object_unref (priv->activity);
+ priv->activity = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+test_shell_view_constructed (GObject *object)
+{
+ ETestShellViewPrivate *priv;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellBackend *shell_backend;
+ EShellView *shell_view;
+ EActivity *activity;
+ GtkWidget *widget;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ priv = E_TEST_SHELL_VIEW_GET_PRIVATE (object);
+
+ shell_view = E_SHELL_VIEW (object);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ widget = gtk_label_new ("Content Widget");
+ gtk_container_add (GTK_CONTAINER (shell_content), widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new ("Sidebar Widget");
+ gtk_container_add (GTK_CONTAINER (shell_sidebar), widget);
+ gtk_widget_show (widget);
+
+ activity = e_activity_new ("Test Activity");
+ e_activity_set_allow_cancel (activity, TRUE);
+ e_shell_backend_add_activity (shell_backend, activity);
+ priv->activity = activity;
+}
+
+static void
+test_shell_view_class_init (ETestShellViewClass *class,
+ GTypeModule *type_module)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETestShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = test_shell_view_dispose;
+ object_class->constructed = test_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = "Test";
+ shell_view_class->icon_name = "face-monkey";
+ shell_view_class->toggled = test_shell_view_toggled;
+}
+
+static void
+test_shell_view_init (ETestShellView *test_shell_view)
+{
+ test_shell_view->priv =
+ E_TEST_SHELL_VIEW_GET_PRIVATE (test_shell_view);
+}
+
+GType
+e_test_shell_view_get_type (void)
+{
+ return test_shell_view_type;
+}
+
+void
+e_test_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ETestShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) test_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ type_module,
+ sizeof (ETestShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) test_shell_view_init,
+ NULL /* value_table */
+ };
+
+ test_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "ETestShellView", &type_info, 0);
+}
diff --git a/shell/test/e-test-shell-view.h b/shell/test/e-test-shell-view.h
new file mode 100644
index 0000000000..85c33bfb39
--- /dev/null
+++ b/shell/test/e-test-shell-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-test-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TEST_SHELL_VIEW_H
+#define E_TEST_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TEST_SHELL_VIEW \
+ (e_test_shell_view_get_type ())
+#define E_TEST_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellView))
+#define E_TEST_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TEST_SHELL_VIEW, ETestShellViewClass))
+#define E_IS_TEST_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TEST_SHELL_VIEW))
+#define E_IS_TEST_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TEST_SHELL_VIEW))
+#define E_TEST_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETestShellView ETestShellView;
+typedef struct _ETestShellViewClass ETestShellViewClass;
+typedef struct _ETestShellViewPrivate ETestShellViewPrivate;
+
+struct _ETestShellView {
+ EShellView parent;
+ ETestShellViewPrivate *priv;
+};
+
+struct _ETestShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_test_shell_view_get_type (void);
+void e_test_shell_view_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_TEST_SHELL_VIEW_H */
diff --git a/shell/e-shell-window-commands.h b/shell/test/evolution-module-test.c
index 0696a8a5d0..1fe3c7c0d0 100644
--- a/shell/e-shell-window-commands.h
+++ b/shell/test/evolution-module-test.c
@@ -1,4 +1,5 @@
/*
+ * evolution-module-test.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,18 +15,27 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_SHELL_WINDOW_COMMANDS_H_
-#define _E_SHELL_WINDOW_COMMANDS_H_
+#include "e-test-shell-backend.h"
+#include "e-test-shell-view.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
-#include "e-shell-window.h"
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
-void e_shell_window_commands_setup (EShellWindow *window);
+ e_test_shell_backend_register_type (type_module);
+ e_test_shell_view_register_type (type_module);
+}
-#endif /* _E_SHELL_WINDOW_COMMANDS_H_ */
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/shell/test/evolution-test-component.c b/shell/test/evolution-test-component.c
deleted file mode 100644
index aaca1339c7..0000000000
--- a/shell/test/evolution-test-component.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-shlib-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-exception.h>
-#include <gtk/gtk.h>
-#include "e-task-bar.h"
-#include "evolution-test-component.h"
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Test_Factory:" BASE_VERSION
-#define TEST_COMPONENT_ID "OAFIID:GNOME_Evolution_Test_Component:" BASE_VERSION
-#define CREATE_TEST_ID "test"
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionTestComponentPrivate {
- BonoboControl *view_control;
- BonoboControl *sidebar_control;
- BonoboControl *status_control;
-};
-
-/* GObject methods */
-
-static void
-impl_dispose (GObject *object)
-{
- EvolutionTestComponentPrivate *priv;
-
- priv = EVOLUTION_TEST_COMPONENT (object)->priv;
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EvolutionTestComponentPrivate *priv = EVOLUTION_TEST_COMPONENT (object)->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-/* Evolution::Component CORBA methods */
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
- const CORBA_short major,
- const CORBA_short minor,
- const CORBA_short revision,
- CORBA_Environment *ev)
-{
- EvolutionTestComponent *component = EVOLUTION_TEST_COMPONENT (bonobo_object_from_servant (servant));
- EvolutionTestComponentPrivate *priv;
-
- priv = component->priv;
-
- g_message ("Upgrading from %d.%d.%d", major, minor, revision);
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 1;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = CREATE_TEST_ID;
- list->_buffer[0].description = _("New Test");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Test");
- list->_buffer[0].tooltip = _("Create a new test item");
- list->_buffer[0].menuShortcut = 'i';
- list->_buffer[0].iconName = "";
-
- return list;
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- EvolutionTestComponent *evolution_test_component = EVOLUTION_TEST_COMPONENT (bonobo_object_from_servant (servant));
- EvolutionTestComponentPrivate *priv;
-
- priv = evolution_test_component->priv;
-
- if (strcmp (item_type_name, CREATE_TEST_ID) == 0) {
- g_message ("Creating test item");
- } else {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
- return;
- }
-}
-
-/* Initialization */
-
-static void
-evolution_test_component_class_init (EvolutionTestComponentClass *klass)
-{
- POA_GNOME_Evolution_Component__epv *epv = &klass->epv;
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-evolution_test_component_init (EvolutionTestComponent *component, EvolutionTestComponentClass *klass)
-{
- EvolutionTestComponentPrivate *priv;
-
- priv = g_new0 (EvolutionTestComponentPrivate, 1);
-
- component->priv = priv;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionTestComponent, GNOME_Evolution_Component, PARENT_TYPE, evolution_test_component)
-
-static BonoboObject *
-factory (BonoboGenericFactory *factory,
- const gchar *component_id,
- gpointer closure)
-{
- if (strcmp (component_id, TEST_COMPONENT_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (g_object_new (EVOLUTION_TEST_TYPE_COMPONENT, NULL));
- bonobo_object_ref (object);
- return object;
- }
-
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
-
- return NULL;
-}
-
-BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Calendar component factory", factory, NULL)
diff --git a/shell/test/evolution-test-component.h b/shell/test/evolution-test-component.h
deleted file mode 100644
index 5809348321..0000000000
--- a/shell/test/evolution-test-component.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _EVOLUTION_TEST_COMPONENT_H_
-#define _EVOLUTION_TEST_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-#include "Evolution.h"
-
-#define EVOLUTION_TEST_TYPE_COMPONENT (evolution_test_component_get_type ())
-#define EVOLUTION_TEST_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TEST_TYPE_COMPONENT, EvolutionTestComponent))
-#define EVOLUTION_TEST_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TEST_TYPE_COMPONENT, EvolutionTestComponentClass))
-#define EVOLUTION_TEST_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TEST_TYPE_COMPONENT))
-#define EVOLUTION_TEST_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TEST_TYPE_COMPONENT))
-
-typedef struct _EvolutionTestComponent EvolutionTestComponent;
-typedef struct _EvolutionTestComponentPrivate EvolutionTestComponentPrivate;
-typedef struct _EvolutionTestComponentClass EvolutionTestComponentClass;
-
-struct _EvolutionTestComponent {
- BonoboObject parent;
-
- EvolutionTestComponentPrivate *priv;
-};
-
-struct _EvolutionTestComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType evolution_test_component_get_type (void);
-
-#endif /* _EVOLUTION_TEST_COMPONENT_H_ */