Files
evolution/shell/e-shell-taskbar.c
Matthew Barnes 3e3c13b439 Replace EActivityHandler with a new activity-tracking system that uses
EActivity objects instead of numeric handler IDs.  Create an EActivity,
configure it, and (optionally) connect to its "cancelled" and "completed"
signals.  Then hand it to the shell view via e_shell_view_add_activity().
When finished with the activity, call e_activity_finish() and unref it.

svn path=/branches/kill-bonobo/; revision=36391
2008-09-19 16:52:08 +00:00

371 lines
9.2 KiB
C

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-shell-taskbar.c
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#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;
EShellViewClass *shell_view_class;
EShellTaskbar *shell_taskbar;
EShellModule *shell_module;
shell_taskbar = E_SHELL_TASKBAR (object);
shell_view = e_shell_taskbar_get_shell_view (shell_taskbar);
shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
shell_module = E_SHELL_MODULE (shell_view_class->type_module);
g_signal_connect_swapped (
shell_module, "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;
g_object_class_install_property (
object_class,
PROP_MESSAGE,
g_param_spec_string (
"message",
NULL,
NULL,
NULL,
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_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, 1);
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;
}
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);
}
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;
}
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));
}
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");
}
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);
}