mirror of https://github.com/Gnucash/gnucash
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
612 lines
15 KiB
612 lines
15 KiB
/* File import from bonoboui to gnumeric by import-bonobo. Do not edit. */
|
|
|
|
/* go-dock-layout.c
|
|
|
|
Copyright (C) 1998 Free Software Foundation
|
|
|
|
All rights reserved.
|
|
|
|
The Gnome Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
The Gnome Library 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
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
Author: Ettore Perazzoli <ettore@comm2000.it>
|
|
*/
|
|
/*
|
|
@NOTATION@
|
|
*/
|
|
|
|
#include <gnumeric-config.h>
|
|
#include <glib/gi18n.h>
|
|
#include <string.h>
|
|
#include <gtk/gtk.h>
|
|
#include <stdio.h>
|
|
|
|
#include "go-dock-layout.h"
|
|
|
|
/* TODO: handle incorrect GO_DOCK_ITEM_BEH_EXCLUSIVE situations. */
|
|
|
|
struct _GoDockLayoutPrivate
|
|
{
|
|
int dummy;
|
|
/* Nothing right now, needs to get filled with the private things */
|
|
/* XXX: When stuff is added, uncomment the allocation in the
|
|
* go_dock_layout_init function! */
|
|
};
|
|
|
|
static GObjectClass *parent_class = NULL;
|
|
|
|
|
|
|
|
static void go_dock_layout_class_init (GoDockLayoutClass *class);
|
|
|
|
static void go_dock_layout_instance_init(GoDockLayout *layout);
|
|
|
|
static void go_dock_layout_finalize (GObject *object);
|
|
|
|
static gint item_compare_func (gconstpointer a,
|
|
gconstpointer b);
|
|
|
|
static gint compare_item_by_name (gconstpointer a,
|
|
gconstpointer b);
|
|
|
|
static gint compare_item_by_pointer (gconstpointer a,
|
|
gconstpointer b);
|
|
|
|
static GList *find (GoDockLayout *layout,
|
|
gconstpointer a,
|
|
GCompareFunc func);
|
|
|
|
static void remove_item (GoDockLayout *layout,
|
|
GList *list);
|
|
|
|
|
|
static void
|
|
go_dock_layout_class_init (GoDockLayoutClass *class)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
|
|
gobject_class->finalize = go_dock_layout_finalize;
|
|
|
|
parent_class = g_type_class_ref (G_TYPE_OBJECT);
|
|
}
|
|
|
|
static void
|
|
go_dock_layout_instance_init (GoDockLayout *layout)
|
|
{
|
|
layout->_priv = NULL;
|
|
/* XXX: when there is some private stuff enable this
|
|
layout->_priv = g_new0(GoDockLayoutPrivate, 1);
|
|
*/
|
|
layout->items = NULL;
|
|
}
|
|
|
|
static void
|
|
go_dock_layout_finalize (GObject *object)
|
|
{
|
|
GoDockLayout *layout;
|
|
|
|
layout = GO_DOCK_LAYOUT (object);
|
|
|
|
while (layout->items)
|
|
remove_item (layout, layout->items);
|
|
|
|
/* Free the private structure */
|
|
g_free (layout->_priv);
|
|
layout->_priv = NULL;
|
|
|
|
if (G_OBJECT_CLASS (parent_class)->finalize)
|
|
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
item_compare_func (gconstpointer a,
|
|
gconstpointer b)
|
|
{
|
|
const GoDockLayoutItem *item_a, *item_b;
|
|
|
|
item_a = a;
|
|
item_b = b;
|
|
|
|
if (item_a->placement != item_b->placement)
|
|
return item_b->placement - item_a->placement;
|
|
|
|
if (item_a->placement == GO_DOCK_FLOATING)
|
|
return 0; /* Floating items don't need to be ordered. */
|
|
else
|
|
{
|
|
if (item_a->position.docked.band_num != item_b->position.docked.band_num)
|
|
return (item_b->position.docked.band_num
|
|
- item_a->position.docked.band_num);
|
|
|
|
return (item_b->position.docked.band_position
|
|
- item_a->position.docked.band_position);
|
|
}
|
|
}
|
|
|
|
static gint
|
|
compare_item_by_name (gconstpointer a, gconstpointer b)
|
|
{
|
|
const GoDockItem *item;
|
|
const gchar *name;
|
|
|
|
item = b;
|
|
name = a;
|
|
|
|
return strcmp (name, item->name);
|
|
}
|
|
|
|
static gint
|
|
compare_item_by_pointer (gconstpointer a, gconstpointer b)
|
|
{
|
|
return a != b;
|
|
}
|
|
|
|
static GList *
|
|
find (GoDockLayout *layout, gconstpointer data, GCompareFunc func)
|
|
{
|
|
GList *p;
|
|
|
|
for (p = layout->items; p != NULL; p = p->next)
|
|
{
|
|
GoDockLayoutItem *item;
|
|
|
|
item = p->data;
|
|
if (! (* func) (data, item->item))
|
|
return p;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
remove_item (GoDockLayout *layout,
|
|
GList *list)
|
|
{
|
|
GoDockItem *item;
|
|
|
|
item = ((GoDockLayoutItem *) list->data)->item;
|
|
|
|
gtk_widget_unref (GTK_WIDGET (item));
|
|
|
|
layout->items = g_list_remove_link (layout->items, list);
|
|
|
|
g_free (list->data);
|
|
g_list_free (list);
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
go_dock_layout_get_type (void)
|
|
{
|
|
static GType layout_type = 0;
|
|
|
|
if (layout_type == 0)
|
|
{
|
|
GTypeInfo layout_info = {
|
|
sizeof (GoDockLayoutClass),
|
|
NULL, NULL,
|
|
(GClassInitFunc)go_dock_layout_class_init,
|
|
NULL, NULL,
|
|
sizeof (GoDockLayout),
|
|
0,
|
|
(GInstanceInitFunc)go_dock_layout_instance_init
|
|
};
|
|
|
|
layout_type = g_type_register_static (G_TYPE_OBJECT, "GoDockLayout", &layout_info, 0);
|
|
}
|
|
|
|
return layout_type;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_new:
|
|
*
|
|
* Description: Create a new #GoDockLayout widget.
|
|
*
|
|
* Returns: The new #GoDockLayout widget.
|
|
**/
|
|
|
|
GoDockLayout *
|
|
go_dock_layout_new (void)
|
|
{
|
|
return GO_DOCK_LAYOUT (g_object_new (GO_TYPE_DOCK_LAYOUT, NULL));
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_add_item:
|
|
* @layout: A #GoDockLayout widget
|
|
* @item: The dock item to be added to @layout
|
|
* @placement: Placement of @item in @layout
|
|
* @band_num: Band number
|
|
* @band_position: Position within the band
|
|
* @offset: Distance from the previous element in the band
|
|
*
|
|
* Description: Add @item to @layout with the specified parameters.
|
|
*
|
|
* Returns: %TRUE if the operation succeeds, %FALSE if it fails.
|
|
**/
|
|
gboolean
|
|
go_dock_layout_add_item (GoDockLayout *layout,
|
|
GoDockItem *item,
|
|
GoDockPlacement placement,
|
|
gint band_num,
|
|
gint band_position,
|
|
gint offset)
|
|
{
|
|
GoDockLayoutItem *new;
|
|
|
|
new = g_new (GoDockLayoutItem, 1);
|
|
new->item = item;
|
|
new->placement = placement;
|
|
new->position.docked.band_num = band_num;
|
|
new->position.docked.band_position = band_position;
|
|
new->position.docked.offset = offset;
|
|
|
|
layout->items = g_list_prepend (layout->items, new);
|
|
|
|
g_object_ref (item);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_add_floating_item:
|
|
* @layout: A #GoDockLayout widget
|
|
* @item: The dock item to be added to @layout
|
|
* @x: X-coordinate for the floating item
|
|
* @y: Y-coordinate for the floating item
|
|
* @orientation: Orientation for the floating item
|
|
*
|
|
* Description: Add @item to @layout as a floating item with the
|
|
* specified (@x, @y) position and @orientation.
|
|
*
|
|
* Returns: %TRUE if the operation succeeds, %FALSE if it fails.
|
|
**/
|
|
|
|
gboolean
|
|
go_dock_layout_add_floating_item (GoDockLayout *layout,
|
|
GoDockItem *item,
|
|
gint x, gint y,
|
|
GtkOrientation orientation)
|
|
{
|
|
GoDockLayoutItem *new;
|
|
|
|
new = g_new (GoDockLayoutItem, 1);
|
|
new->item = item;
|
|
new->placement = GO_DOCK_FLOATING;
|
|
new->position.floating.x = x;
|
|
new->position.floating.y = y;
|
|
new->position.floating.orientation = orientation;
|
|
|
|
layout->items = g_list_prepend (layout->items, new);
|
|
|
|
g_object_ref (item);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_get_item:
|
|
* @layout: A #GoDockLayout widget
|
|
* @item: The #GoDockItem to be retrieved
|
|
*
|
|
* Description: Retrieve a layout item.
|
|
*
|
|
* Returns: The retrieved #GoDockLayoutItem widget.
|
|
**/
|
|
GoDockLayoutItem *
|
|
go_dock_layout_get_item (GoDockLayout *layout,
|
|
GoDockItem *item)
|
|
{
|
|
GList *list;
|
|
|
|
list = find (layout, item, compare_item_by_pointer);
|
|
|
|
if (list == NULL)
|
|
return NULL;
|
|
else
|
|
return list->data;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_get_item_by_name:
|
|
* @layout: A #GoDockLayout widget
|
|
* @name: Name of the item to be retrieved
|
|
*
|
|
* Description: Retrieve the dock item named @name.
|
|
*
|
|
* Returns: The named #GoDockLayoutItem widget.
|
|
**/
|
|
GoDockLayoutItem *
|
|
go_dock_layout_get_item_by_name (GoDockLayout *layout,
|
|
const gchar *name)
|
|
{
|
|
GList *list;
|
|
|
|
list = find (layout, name, compare_item_by_name);
|
|
|
|
if (list == NULL)
|
|
return NULL;
|
|
else
|
|
return list->data;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_remove_item:
|
|
* @layout: A #GoDockLayout widget
|
|
* @item: The #GoDockItem to be removed
|
|
*
|
|
* Description: Remove the specified @item from @layout.
|
|
*
|
|
* Returns: %TRUE if the operation succeeds, %FALSE if it fails.
|
|
**/
|
|
gboolean
|
|
go_dock_layout_remove_item (GoDockLayout *layout,
|
|
GoDockItem *item)
|
|
{
|
|
GList *list;
|
|
|
|
list = find (layout, item, compare_item_by_pointer);
|
|
if (list == NULL)
|
|
return FALSE;
|
|
|
|
remove_item (layout, list);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_remove_item_by_name:
|
|
* @layout: A #GoDockLayout widget
|
|
* @name: Name of the #GoDockItem to be removed
|
|
*
|
|
* Description: Remove the item named @name from @layout.
|
|
*
|
|
* Returns: %TRUE if the operation succeeds, %FALSE if it fails.
|
|
**/
|
|
gboolean
|
|
go_dock_layout_remove_item_by_name (GoDockLayout *layout,
|
|
const gchar *name)
|
|
{
|
|
GList *list;
|
|
|
|
list = find (layout, name, compare_item_by_name);
|
|
if (list == NULL)
|
|
return FALSE;
|
|
|
|
remove_item (layout, list);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* go_dock_layout_add_to_dock:
|
|
* @layout: A #GoDockLayout widget
|
|
* @dock: The #GoDock widget the layout items must be added to
|
|
*
|
|
* Description: Add all the items in @layout to the specified @dock.
|
|
*
|
|
* Returns: %TRUE if the operation succeeds, %FALSE if it fails.
|
|
**/
|
|
gboolean
|
|
go_dock_layout_add_to_dock (GoDockLayout *layout,
|
|
GoDock *dock)
|
|
{
|
|
GoDockLayoutItem *item;
|
|
GList *lp;
|
|
GoDockPlacement last_placement;
|
|
gint last_band_num;
|
|
|
|
if (layout->items == NULL)
|
|
return FALSE;
|
|
|
|
layout->items = g_list_sort (layout->items, item_compare_func);
|
|
|
|
item = layout->items->data;
|
|
|
|
last_placement = GO_DOCK_FLOATING;
|
|
last_band_num = 0;
|
|
|
|
for (lp = layout->items; lp != NULL; lp = lp->next)
|
|
{
|
|
item = lp->data;
|
|
|
|
if (item->placement == GO_DOCK_FLOATING)
|
|
{
|
|
go_dock_add_floating_item (dock,
|
|
item->item,
|
|
item->position.floating.x,
|
|
item->position.floating.y,
|
|
item->position.floating.orientation);
|
|
}
|
|
else
|
|
{
|
|
gboolean need_new;
|
|
|
|
if (last_placement != item->placement
|
|
|| last_band_num != item->position.docked.band_num)
|
|
need_new = TRUE;
|
|
else
|
|
need_new = FALSE;
|
|
|
|
go_dock_add_item (dock,
|
|
item->item,
|
|
item->placement,
|
|
0,
|
|
0,
|
|
item->position.docked.offset,
|
|
need_new);
|
|
|
|
last_band_num = item->position.docked.band_num;
|
|
last_placement = item->placement;
|
|
}
|
|
|
|
gtk_widget_show (GTK_WIDGET (item->item));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/* Layout string functions. */
|
|
|
|
/**
|
|
* go_dock_layout_create_string:
|
|
* @layout: A #GoDockLayout widget
|
|
*
|
|
* Description: Generate a string describing the layout in @layout.
|
|
*
|
|
* Returns: The (malloced) layout string for @layout.
|
|
**/
|
|
gchar *
|
|
go_dock_layout_create_string (GoDockLayout *layout)
|
|
{
|
|
GList *lp;
|
|
guint tmp_count, tmp_alloc;
|
|
gchar **tmp;
|
|
gchar *retval;
|
|
|
|
if (layout->items == NULL)
|
|
return NULL;
|
|
|
|
tmp_alloc = 512;
|
|
tmp = g_new (gchar *, tmp_alloc);
|
|
|
|
tmp_count = 0;
|
|
|
|
for (lp = layout->items; lp != NULL; lp = lp->next)
|
|
{
|
|
GoDockLayoutItem *i;
|
|
|
|
i = lp->data;
|
|
|
|
if (tmp_alloc - tmp_count <= 2)
|
|
{
|
|
tmp_alloc *= 2;
|
|
tmp = g_renew (char *, tmp, tmp_alloc);
|
|
}
|
|
|
|
if (i->placement == GO_DOCK_FLOATING)
|
|
tmp[tmp_count] = g_strdup_printf ("%s\\%d,%d,%d,%d",
|
|
i->item->name,
|
|
(gint) i->placement,
|
|
i->position.floating.x,
|
|
i->position.floating.y,
|
|
i->position.floating.orientation);
|
|
else
|
|
tmp[tmp_count] = g_strdup_printf ("%s\\%d,%d,%d,%d",
|
|
i->item->name,
|
|
(gint) i->placement,
|
|
i->position.docked.band_num,
|
|
i->position.docked.band_position,
|
|
i->position.docked.offset);
|
|
|
|
tmp_count++;
|
|
}
|
|
|
|
tmp[tmp_count] = NULL;
|
|
|
|
retval = g_strjoinv ("\\", tmp);
|
|
g_strfreev (tmp);
|
|
|
|
return retval;
|
|
}
|
|
|
|
/**
|
|
* go_dock_layout_parse_string:
|
|
* @layout: A #GoDockLayout widget
|
|
* @string: A layout string to be parsed
|
|
*
|
|
* Description: Parse the layout string @string, and move around the
|
|
* items in @layout accordingly.
|
|
*
|
|
* Returns: %TRUE if the operation succeeds, %FALSE if it fails.
|
|
**/
|
|
gboolean
|
|
go_dock_layout_parse_string (GoDockLayout *layout,
|
|
const gchar *string)
|
|
{
|
|
gchar **tmp, **p;
|
|
|
|
if (string == NULL)
|
|
return FALSE;
|
|
|
|
tmp = g_strsplit (string, "\\", 0);
|
|
if (tmp == NULL)
|
|
return FALSE;
|
|
|
|
p = tmp;
|
|
while (*p != NULL)
|
|
{
|
|
GList *lp;
|
|
|
|
if (*(p + 1) == NULL)
|
|
{
|
|
g_strfreev (tmp);
|
|
return FALSE;
|
|
}
|
|
|
|
lp = find (layout, *p, compare_item_by_name);
|
|
|
|
if (lp != NULL)
|
|
{
|
|
GoDockLayoutItem *i;
|
|
gint p1, p2, p3, p4;
|
|
|
|
if (sscanf (*(p + 1), "%d,%d,%d,%d", &p1, &p2, &p3, &p4) != 4)
|
|
{
|
|
g_strfreev (tmp);
|
|
return FALSE;
|
|
}
|
|
|
|
if (p1 != (gint) GO_DOCK_TOP
|
|
&& p1 != (gint) GO_DOCK_BOTTOM
|
|
&& p1 != (gint) GO_DOCK_LEFT
|
|
&& p1 != (gint) GO_DOCK_RIGHT
|
|
&& p1 != (gint) GO_DOCK_FLOATING)
|
|
return FALSE;
|
|
|
|
i = lp->data;
|
|
|
|
i->placement = (GoDockPlacement) p1;
|
|
|
|
if (i->placement == GO_DOCK_FLOATING)
|
|
{
|
|
i->position.floating.x = p2;
|
|
i->position.floating.y = p3;
|
|
i->position.floating.orientation = p4;
|
|
}
|
|
else
|
|
{
|
|
i->position.docked.band_num = p2;
|
|
i->position.docked.band_position = p3;
|
|
i->position.docked.offset = p4;
|
|
}
|
|
}
|
|
|
|
p += 2;
|
|
}
|
|
|
|
g_strfreev (tmp);
|
|
|
|
return TRUE;
|
|
}
|