|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* Copyright (C) 2001 Ximian, Inc.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
1e8aac |
* it under the terms of the GNU General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
1e8aac |
* License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
1e8aac |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
1e8aac |
* GNU General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU General Public License
|
|
Packit |
1e8aac |
* along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Authors:
|
|
Packit |
1e8aac |
* Chema Celorio <chema@celorio.com>
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <config.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* SECTION:glade-utils
|
|
Packit |
1e8aac |
* @Title: Glade Utils
|
|
Packit |
1e8aac |
* @Short_Description: Welcome to the zoo.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This is where all of that really usefull miscalanious stuff lands up.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "glade.h"
|
|
Packit |
1e8aac |
#include "glade-project.h"
|
|
Packit |
1e8aac |
#include "glade-command.h"
|
|
Packit |
1e8aac |
#include "glade-debug.h"
|
|
Packit |
1e8aac |
#include "glade-placeholder.h"
|
|
Packit |
1e8aac |
#include "glade-widget.h"
|
|
Packit |
1e8aac |
#include "glade-widget-adaptor.h"
|
|
Packit |
1e8aac |
#include "glade-property.h"
|
|
Packit |
1e8aac |
#include "glade-property-class.h"
|
|
Packit |
1e8aac |
#include "glade-clipboard.h"
|
|
Packit |
1e8aac |
#include "glade-private.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <string.h>
|
|
Packit |
1e8aac |
#include <gdk/gdkkeysyms.h>
|
|
Packit |
1e8aac |
#include <gmodule.h>
|
|
Packit |
1e8aac |
#include <glib/gi18n-lib.h>
|
|
Packit |
1e8aac |
#include <glib/gstdio.h>
|
|
Packit |
1e8aac |
#include <errno.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#ifdef G_OS_WIN32
|
|
Packit |
1e8aac |
#define WIN32_LEAN_AND_MEAN
|
|
Packit |
1e8aac |
#include <windows.h>
|
|
Packit |
1e8aac |
#include <shellapi.h>
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define GLADE_UTIL_COPY_BUFFSIZE 1024
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_compose_get_type_func:
|
|
Packit |
1e8aac |
* @name:
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* TODO: write me
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns:
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
static gchar *
|
|
Packit |
1e8aac |
glade_util_compose_get_type_func (const gchar *name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *retval;
|
|
Packit |
1e8aac |
GString *tmp;
|
|
Packit |
1e8aac |
gint i = 1, j;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
tmp = g_string_new (name);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
while (tmp->str[i])
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (g_ascii_isupper (tmp->str[i]))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
tmp = g_string_insert_c (tmp, i++, '_');
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
j = 0;
|
|
Packit |
1e8aac |
while (g_ascii_isupper (tmp->str[i++]))
|
|
Packit |
1e8aac |
j++;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (j > 2)
|
|
Packit |
1e8aac |
g_string_insert_c (tmp, i - 2, '_');
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
i++;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
tmp = g_string_append (tmp, "_get_type");
|
|
Packit |
1e8aac |
retval = g_ascii_strdown (tmp->str, tmp->len);
|
|
Packit |
1e8aac |
g_string_free (tmp, TRUE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return retval;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_get_type_from_name:
|
|
Packit |
1e8aac |
* @name: the name of the #GType - like 'GtkWidget' or a "get-type" function.
|
|
Packit |
1e8aac |
* @have_func: function-name flag -- true if the name is a "get-type" function.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns the type using the "get type" function name based on @name.
|
|
Packit |
1e8aac |
* If the @have_func flag is true,@name is used directly, otherwise the get-type
|
|
Packit |
1e8aac |
* function is contrived from @name then used.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: the new #GType
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GType
|
|
Packit |
1e8aac |
glade_util_get_type_from_name (const gchar *name, gboolean have_func)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
static GModule *allsymbols = NULL;
|
|
Packit |
1e8aac |
GType (*get_type) (void);
|
|
Packit |
1e8aac |
GType type = 0;
|
|
Packit |
1e8aac |
gchar *func_name = (gchar *) name;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((type = g_type_from_name (name)) == 0 &&
|
|
Packit |
1e8aac |
(have_func ||
|
|
Packit |
1e8aac |
(func_name = glade_util_compose_get_type_func (name)) != NULL))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!allsymbols)
|
|
Packit |
1e8aac |
allsymbols = g_module_open (NULL, 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_module_symbol (allsymbols, func_name, (gpointer) & get_type))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_assert (get_type);
|
|
Packit |
1e8aac |
type = get_type ();
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning (_("We could not find the symbol \"%s\""), func_name);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!have_func)
|
|
Packit |
1e8aac |
g_free (func_name);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (type == 0)
|
|
Packit |
1e8aac |
g_warning (_("Could not get the type from \"%s\""), name);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return type;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_get_pspec_from_funcname:
|
|
Packit |
1e8aac |
* @funcname: the symbol name of a function to generate a #GParamSpec
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A #GParamSpec created by the delagate function
|
|
Packit |
1e8aac |
* specified by @funcname
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GParamSpec *
|
|
Packit |
1e8aac |
glade_utils_get_pspec_from_funcname (const gchar *funcname)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
static GModule *allsymbols = NULL;
|
|
Packit |
1e8aac |
GParamSpec *pspec = NULL;
|
|
Packit |
1e8aac |
GParamSpec *(*get_pspec) (void) = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!allsymbols)
|
|
Packit |
1e8aac |
allsymbols = g_module_open (NULL, 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!g_module_symbol (allsymbols, funcname, (gpointer) & get_pspec))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning (_("We could not find the symbol \"%s\""), funcname);
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_assert (get_pspec);
|
|
Packit |
1e8aac |
pspec = get_pspec ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return pspec;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
_glade_util_dialog_set_hig (GtkDialog *dialog)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *vbox, *action_area;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* HIG spacings */
|
|
Packit |
1e8aac |
vbox = gtk_dialog_get_content_area (dialog);
|
|
Packit |
1e8aac |
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
|
Packit |
1e8aac |
gtk_box_set_spacing (GTK_BOX (vbox), 2); /* 2 * 5 + 2 = 12 */
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
action_area = gtk_dialog_get_action_area (dialog);
|
|
Packit |
1e8aac |
gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
|
|
Packit |
1e8aac |
gtk_box_set_spacing (GTK_BOX (action_area), 6);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_ui_message:
|
|
Packit |
1e8aac |
* @parent: a #GtkWindow cast as a #GtkWidget
|
|
Packit |
1e8aac |
* @type: a #GladeUIMessageType
|
|
Packit |
1e8aac |
* @widget: a #GtkWidget to append to the dialog vbox
|
|
Packit |
1e8aac |
* @format: a printf style format string
|
|
Packit |
1e8aac |
* @...: args for the format.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Creates a new warning dialog window as a child of @parent containing
|
|
Packit |
1e8aac |
* the text of @format, runs it, then destroys it on close. Depending
|
|
Packit |
1e8aac |
* on @type, a cancel button may apear or the icon may change.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: True if the @type was GLADE_UI_ARE_YOU_SURE and the user
|
|
Packit |
1e8aac |
* selected "OK", True if the @type was GLADE_UI_YES_OR_NO and
|
|
Packit |
1e8aac |
* the user selected "YES"; False otherwise.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gint
|
|
Packit |
1e8aac |
glade_util_ui_message (GtkWidget *parent,
|
|
Packit |
1e8aac |
GladeUIMessageType type,
|
|
Packit |
1e8aac |
GtkWidget *widget,
|
|
Packit |
1e8aac |
const gchar *format,
|
|
Packit |
1e8aac |
...)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *dialog;
|
|
Packit |
1e8aac |
GtkMessageType message_type = GTK_MESSAGE_INFO;
|
|
Packit |
1e8aac |
GtkButtonsType buttons_type = GTK_BUTTONS_OK;
|
|
Packit |
1e8aac |
va_list args;
|
|
Packit |
1e8aac |
gchar *string;
|
|
Packit |
1e8aac |
gint response;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
va_start (args, format);
|
|
Packit |
1e8aac |
string = g_strdup_vprintf (format, args);
|
|
Packit |
1e8aac |
va_end (args);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Get message_type */
|
|
Packit |
1e8aac |
switch (type)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case GLADE_UI_INFO:
|
|
Packit |
1e8aac |
message_type = GTK_MESSAGE_INFO;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_UI_WARN:
|
|
Packit |
1e8aac |
case GLADE_UI_ARE_YOU_SURE:
|
|
Packit |
1e8aac |
message_type = GTK_MESSAGE_WARNING;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_UI_ERROR:
|
|
Packit |
1e8aac |
message_type = GTK_MESSAGE_ERROR;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_UI_YES_OR_NO:
|
|
Packit |
1e8aac |
message_type = GTK_MESSAGE_QUESTION;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
g_critical ("Bad arg for glade_util_ui_message");
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Get buttons_type */
|
|
Packit |
1e8aac |
switch (type)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case GLADE_UI_INFO:
|
|
Packit |
1e8aac |
case GLADE_UI_WARN:
|
|
Packit |
1e8aac |
case GLADE_UI_ERROR:
|
|
Packit |
1e8aac |
buttons_type = GTK_BUTTONS_OK;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_UI_ARE_YOU_SURE:
|
|
Packit |
1e8aac |
buttons_type = GTK_BUTTONS_OK_CANCEL;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_UI_YES_OR_NO:
|
|
Packit |
1e8aac |
buttons_type = GTK_BUTTONS_YES_NO;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
g_critical ("Bad arg for glade_util_ui_message");
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
|
|
Packit |
1e8aac |
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
Packit |
1e8aac |
message_type, buttons_type, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), string);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_box_pack_end (GTK_BOX
|
|
Packit |
1e8aac |
(gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
|
Packit |
1e8aac |
widget, TRUE, TRUE, 2);
|
|
Packit |
1e8aac |
gtk_widget_show (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* If theres additional content, make it resizable */
|
|
Packit |
1e8aac |
gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_destroy (dialog);
|
|
Packit |
1e8aac |
g_free (string);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_YES);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_util_check_and_warn_scrollable (GladeWidget *parent,
|
|
Packit |
1e8aac |
GladeWidgetAdaptor *child_adaptor,
|
|
Packit |
1e8aac |
GtkWidget *parent_widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (GTK_IS_SCROLLED_WINDOW (glade_widget_get_object (parent)) &&
|
|
Packit |
1e8aac |
GWA_SCROLLABLE_WIDGET (child_adaptor) == FALSE)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidgetAdaptor *vadaptor =
|
|
Packit |
1e8aac |
glade_widget_adaptor_get_by_type (GTK_TYPE_VIEWPORT);
|
|
Packit |
1e8aac |
GladeWidgetAdaptor *parent_adaptor = glade_widget_get_adaptor (parent);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_util_ui_message (parent_widget,
|
|
Packit |
1e8aac |
GLADE_UI_INFO, NULL,
|
|
Packit |
1e8aac |
_("Cannot add non scrollable %s widget to a %s directly.\n"
|
|
Packit |
1e8aac |
"Add a %s first."),
|
|
Packit |
1e8aac |
glade_widget_adaptor_get_title (child_adaptor),
|
|
Packit |
1e8aac |
glade_widget_adaptor_get_title (parent_adaptor),
|
|
Packit |
1e8aac |
glade_widget_adaptor_get_title (vadaptor));
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
typedef struct
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkStatusbar *statusbar;
|
|
Packit |
1e8aac |
guint context_id;
|
|
Packit |
1e8aac |
guint message_id;
|
|
Packit |
1e8aac |
} FlashInfo;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static const guint flash_length = 3;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
remove_message_timeout (FlashInfo *fi)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_statusbar_remove (fi->statusbar, fi->context_id, fi->message_id);
|
|
Packit |
1e8aac |
g_slice_free (FlashInfo, fi);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* remove the timeout */
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_flash_message:
|
|
Packit |
1e8aac |
* @statusbar: The statusbar
|
|
Packit |
1e8aac |
* @context_id: The message context_id
|
|
Packit |
1e8aac |
* @format: The message to flash on the statusbar
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Flash a temporary message on the statusbar.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_util_flash_message (GtkWidget *statusbar,
|
|
Packit |
1e8aac |
guint context_id,
|
|
Packit |
1e8aac |
gchar *format,
|
|
Packit |
1e8aac |
...)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
va_list args;
|
|
Packit |
1e8aac |
FlashInfo *fi;
|
|
Packit |
1e8aac |
gchar *message;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
|
|
Packit |
1e8aac |
g_return_if_fail (format != NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
va_start (args, format);
|
|
Packit |
1e8aac |
message = g_strdup_vprintf (format, args);
|
|
Packit |
1e8aac |
va_end (args);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
fi = g_slice_new0 (FlashInfo);
|
|
Packit |
1e8aac |
fi->statusbar = GTK_STATUSBAR (statusbar);
|
|
Packit |
1e8aac |
fi->context_id = context_id;
|
|
Packit |
1e8aac |
fi->message_id = gtk_statusbar_push (fi->statusbar, fi->context_id, message);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_timeout_add_seconds (flash_length, (GSourceFunc) remove_message_timeout,
|
|
Packit |
1e8aac |
fi);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (message);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gint
|
|
Packit |
1e8aac |
glade_util_compare_uline_labels (const gchar *labela, const gchar *labelb)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (;;)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gunichar c1, c2;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (*labela == '\0')
|
|
Packit |
1e8aac |
return (*labelb == '\0') ? 0 : -1;
|
|
Packit |
1e8aac |
if (*labelb == '\0')
|
|
Packit |
1e8aac |
return 1;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
c1 = g_utf8_get_char (labela);
|
|
Packit |
1e8aac |
if (c1 == '_')
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
labela = g_utf8_next_char (labela);
|
|
Packit |
1e8aac |
c1 = g_utf8_get_char (labela);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
c2 = g_utf8_get_char (labelb);
|
|
Packit |
1e8aac |
if (c2 == '_')
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
labelb = g_utf8_next_char (labelb);
|
|
Packit |
1e8aac |
c2 = g_utf8_get_char (labelb);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (c1 < c2)
|
|
Packit |
1e8aac |
return -1;
|
|
Packit |
1e8aac |
if (c1 > c2)
|
|
Packit |
1e8aac |
return 1;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
labela = g_utf8_next_char (labela);
|
|
Packit |
1e8aac |
labelb = g_utf8_next_char (labelb);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Shouldn't be reached. */
|
|
Packit |
1e8aac |
return 0;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_compare_stock_labels:
|
|
Packit |
1e8aac |
* @a: a #gconstpointer to a #GtkStockItem
|
|
Packit |
1e8aac |
* @b: a #gconstpointer to a #GtkStockItem
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This is a #GCompareFunc that compares the labels of two stock items,
|
|
Packit |
1e8aac |
* ignoring any '_' characters. It isn't particularly efficient.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: negative value if @a < @b; zero if @a = @b;
|
|
Packit |
1e8aac |
* positive value if @a > @b
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gint
|
|
Packit |
1e8aac |
glade_util_compare_stock_labels (gconstpointer a, gconstpointer b)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *stock_ida = a, *stock_idb = b;
|
|
Packit |
1e8aac |
GtkStockItem itema, itemb;
|
|
Packit |
1e8aac |
gboolean founda, foundb;
|
|
Packit |
1e8aac |
gint retval;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
Packit |
1e8aac |
founda = gtk_stock_lookup (stock_ida, &itema);
|
|
Packit |
1e8aac |
foundb = gtk_stock_lookup (stock_idb, &itemb);
|
|
Packit |
1e8aac |
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (founda)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!foundb)
|
|
Packit |
1e8aac |
retval = -1;
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
/* FIXME: Not ideal for UTF-8. */
|
|
Packit |
1e8aac |
retval = glade_util_compare_uline_labels (itema.label, itemb.label);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!foundb)
|
|
Packit |
1e8aac |
retval = 0;
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
retval = 1;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return retval;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_file_dialog_new:
|
|
Packit |
1e8aac |
* @title: dialog title
|
|
Packit |
1e8aac |
* @project: a #GladeProject used when saving
|
|
Packit |
1e8aac |
* @parent: a parent #GtkWindow for the dialog
|
|
Packit |
1e8aac |
* @action: a #GladeUtilFileDialogType to say if the dialog will open or save
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a "glade file" file chooser dialog. The caller is responsible
|
|
Packit |
1e8aac |
* for showing the dialog
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GtkWidget *
|
|
Packit |
1e8aac |
glade_util_file_dialog_new (const gchar *title,
|
|
Packit |
1e8aac |
GladeProject *project,
|
|
Packit |
1e8aac |
GtkWindow *parent,
|
|
Packit |
1e8aac |
GladeUtilFileDialogType action)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *file_dialog;
|
|
Packit |
1e8aac |
GtkFileFilter *file_filter;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail ((action == GLADE_FILE_DIALOG_ACTION_OPEN ||
|
|
Packit |
1e8aac |
action == GLADE_FILE_DIALOG_ACTION_SAVE), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail ((action != GLADE_FILE_DIALOG_ACTION_SAVE ||
|
|
Packit |
1e8aac |
GLADE_IS_PROJECT (project)), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
file_dialog = gtk_file_chooser_dialog_new (title, parent, action,
|
|
Packit |
1e8aac |
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
|
Packit |
1e8aac |
action ==
|
|
Packit |
1e8aac |
GLADE_FILE_DIALOG_ACTION_OPEN ?
|
|
Packit |
1e8aac |
_("_Open") : _("_Save"),
|
|
Packit |
1e8aac |
GTK_RESPONSE_OK, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
file_filter = gtk_file_filter_new ();
|
|
Packit |
1e8aac |
gtk_file_filter_add_pattern (file_filter, "*");
|
|
Packit |
1e8aac |
gtk_file_filter_set_name (file_filter, _("All Files"));
|
|
Packit |
1e8aac |
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_dialog), file_filter);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
file_filter = gtk_file_filter_new ();
|
|
Packit |
1e8aac |
gtk_file_filter_add_pattern (file_filter, "*.glade");
|
|
Packit |
1e8aac |
gtk_file_filter_set_name (file_filter, _("Libglade Files"));
|
|
Packit |
1e8aac |
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_dialog), file_filter);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
file_filter = gtk_file_filter_new ();
|
|
Packit |
1e8aac |
gtk_file_filter_add_pattern (file_filter, "*.ui");
|
|
Packit |
1e8aac |
gtk_file_filter_set_name (file_filter, _("GtkBuilder Files"));
|
|
Packit |
1e8aac |
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_dialog), file_filter);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
file_filter = gtk_file_filter_new ();
|
|
Packit |
1e8aac |
gtk_file_filter_add_pattern (file_filter, "*.ui");
|
|
Packit |
1e8aac |
gtk_file_filter_add_pattern (file_filter, "*.glade");
|
|
Packit |
1e8aac |
gtk_file_filter_set_name (file_filter, _("All Glade Files"));
|
|
Packit |
1e8aac |
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_dialog), file_filter);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (file_dialog), file_filter);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER
|
|
Packit |
1e8aac |
(file_dialog), TRUE);
|
|
Packit |
1e8aac |
gtk_dialog_set_default_response (GTK_DIALOG (file_dialog), GTK_RESPONSE_OK);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return file_dialog;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_replace:
|
|
Packit |
1e8aac |
* @str: a string
|
|
Packit |
1e8aac |
* @a: a #gchar
|
|
Packit |
1e8aac |
* @b: a #gchar
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Replaces each occurance of the character @a in @str to @b.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_util_replace (gchar *str, gchar a, gchar b)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_if_fail (str != NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
while (*str != 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (*str == a)
|
|
Packit |
1e8aac |
*str = b;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
str = g_utf8_next_char (str);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* _glade_util_strreplace:
|
|
Packit |
1e8aac |
* @str: a string
|
|
Packit |
1e8aac |
* @free_str: wheter to free str or not
|
|
Packit |
1e8aac |
* @key: the key string to search for
|
|
Packit |
1e8aac |
* @replacement: string to replace key
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Replaces each occurance of the string @key in @str to @replacement.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
_glade_util_strreplace (gchar *str,
|
|
Packit |
1e8aac |
gboolean free_str,
|
|
Packit |
1e8aac |
const gchar *key,
|
|
Packit |
1e8aac |
const gchar *replacement)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *retval, **array;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((array = g_strsplit (str, key, -1)) && array[0])
|
|
Packit |
1e8aac |
retval = g_strjoinv (replacement, array);
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
retval = g_strdup (str);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_strfreev (array);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (free_str)
|
|
Packit |
1e8aac |
g_free (str);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return retval;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_read_prop_name:
|
|
Packit |
1e8aac |
* @str: a string
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Return a usable version of a property identifier as found
|
|
Packit |
1e8aac |
* in a freshly parserd #GladeInterface
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_util_read_prop_name (const gchar *str)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *id;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (str != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
id = g_strdup (str);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_util_replace (id, '_', '-');
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return id;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_duplicate_underscores:
|
|
Packit |
1e8aac |
* @name: a string
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Duplicates @name, but the copy has two underscores in place of any single
|
|
Packit |
1e8aac |
* underscore in the original.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a newly allocated string
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_util_duplicate_underscores (const gchar *name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *tmp;
|
|
Packit |
1e8aac |
const gchar *last_tmp = name;
|
|
Packit |
1e8aac |
gchar *underscored_name = g_malloc (strlen (name) * 2 + 1);
|
|
Packit |
1e8aac |
gchar *tmp_underscored = underscored_name;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (tmp = last_tmp; *tmp; tmp = g_utf8_next_char (tmp))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (*tmp == '_')
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
memcpy (tmp_underscored, last_tmp, tmp - last_tmp + 1);
|
|
Packit |
1e8aac |
tmp_underscored += tmp - last_tmp + 1;
|
|
Packit |
1e8aac |
last_tmp = tmp + 1;
|
|
Packit |
1e8aac |
*tmp_underscored++ = '_';
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
memcpy (tmp_underscored, last_tmp, tmp - last_tmp + 1);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return underscored_name;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* taken from gtk... maybe someday we can convince them to
|
|
Packit |
1e8aac |
* expose gtk_container_get_all_children
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
gtk_container_children_callback (GtkWidget *widget, gpointer client_data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList **children;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
children = (GList **) client_data;
|
|
Packit |
1e8aac |
if (!g_list_find (*children, widget))
|
|
Packit |
1e8aac |
*children = g_list_prepend (*children, widget);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_container_get_all_children:
|
|
Packit |
1e8aac |
* @container: a #GtkContainer
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Use this to itterate over all children in a GtkContainer,
|
|
Packit |
1e8aac |
* as it used _forall() instead of _foreach() (and the GTK+ version
|
|
Packit |
1e8aac |
* of this function is simply not exposed).
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Note that glade_widget_class_get_children() is the high-level
|
|
Packit |
1e8aac |
* abstraction and will usually end up calling this function.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a #GList giving the contents of @container
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GList *
|
|
Packit |
1e8aac |
glade_util_container_get_all_children (GtkContainer *container)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *children = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_container_forall (container, gtk_container_children_callback, &children);
|
|
Packit |
1e8aac |
gtk_container_foreach (container, gtk_container_children_callback, &children);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Preserve the natural order by reversing the list */
|
|
Packit |
1e8aac |
return g_list_reverse (children);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_count_placeholders:
|
|
Packit |
1e8aac |
* @parent: a #GladeWidget
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: the amount of #GladePlaceholders parented by @parent
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gint
|
|
Packit |
1e8aac |
glade_util_count_placeholders (GladeWidget *parent)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gint placeholders = 0;
|
|
Packit |
1e8aac |
GList *list, *children;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* count placeholders */
|
|
Packit |
1e8aac |
if ((children =
|
|
Packit |
1e8aac |
glade_widget_adaptor_get_children (glade_widget_get_adaptor (parent),
|
|
Packit |
1e8aac |
glade_widget_get_object (parent))) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (list = children; list && list->data; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (GLADE_IS_PLACEHOLDER (list->data))
|
|
Packit |
1e8aac |
placeholders++;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
g_list_free (children);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return placeholders;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static GtkTreeIter *
|
|
Packit |
1e8aac |
glade_util_find_iter (GtkTreeModel *model,
|
|
Packit |
1e8aac |
GtkTreeIter *iter,
|
|
Packit |
1e8aac |
GladeWidget *findme,
|
|
Packit |
1e8aac |
gint column)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTreeIter *retval = NULL;
|
|
Packit |
1e8aac |
GObject *object = NULL;
|
|
Packit |
1e8aac |
GtkTreeIter *next;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
|
|
Packit |
1e8aac |
g_return_val_if_fail (iter != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
next = gtk_tree_iter_copy (iter);
|
|
Packit |
1e8aac |
g_return_val_if_fail (next != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
while (retval == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *widget;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_tree_model_get (model, next, column, &object, -1);
|
|
Packit |
1e8aac |
if (object &&
|
|
Packit |
1e8aac |
gtk_tree_model_get_column_type (model, column) == G_TYPE_OBJECT)
|
|
Packit |
1e8aac |
g_object_unref (object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
widget = glade_widget_get_from_gobject (object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (widget == findme)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
retval = gtk_tree_iter_copy (next);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (glade_widget_is_ancestor (findme, widget))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (gtk_tree_model_iter_has_child (model, next))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTreeIter child;
|
|
Packit |
1e8aac |
gtk_tree_model_iter_children (model, &child, next);
|
|
Packit |
1e8aac |
if ((retval = glade_util_find_iter
|
|
Packit |
1e8aac |
(model, &child, findme, column)) != NULL)
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Only search the branches where the searched widget
|
|
Packit |
1e8aac |
* is actually a child of the this row, optimize the
|
|
Packit |
1e8aac |
* searching this way
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!gtk_tree_model_iter_next (model, next))
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
gtk_tree_iter_free (next);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return retval;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_find_iter_by_widget:
|
|
Packit |
1e8aac |
* @model: a #GtkTreeModel
|
|
Packit |
1e8aac |
* @findme: a #GladeWidget
|
|
Packit |
1e8aac |
* @column: a #gint
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Looks through @model for the #GtkTreeIter corresponding to
|
|
Packit |
1e8aac |
* @findme under @column.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a newly allocated #GtkTreeIter from @model corresponding
|
|
Packit |
1e8aac |
* to @findme which should be freed with gtk_tree_iter_free()
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GtkTreeIter *
|
|
Packit |
1e8aac |
glade_util_find_iter_by_widget (GtkTreeModel *model,
|
|
Packit |
1e8aac |
GladeWidget *findme,
|
|
Packit |
1e8aac |
gint column)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTreeIter iter;
|
|
Packit |
1e8aac |
if (gtk_tree_model_get_iter_first (model, &iter))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return glade_util_find_iter (model, &iter, findme, column);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_purify_list:
|
|
Packit |
1e8aac |
* @list: A #GList
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A newly allocated version of @list with no
|
|
Packit |
1e8aac |
* duplicate data entries
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GList *
|
|
Packit |
1e8aac |
glade_util_purify_list (GList * list)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *l, *newlist = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (l = list; l; l = l->next)
|
|
Packit |
1e8aac |
if (!g_list_find (newlist, l->data))
|
|
Packit |
1e8aac |
newlist = g_list_prepend (newlist, l->data);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_free (list);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_list_reverse (newlist);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_added_in_list:
|
|
Packit |
1e8aac |
* @old_list: the old #GList
|
|
Packit |
1e8aac |
* @new_list: the new #GList
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A newly allocated #GList of elements that
|
|
Packit |
1e8aac |
* are in @new but not in @old
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GList *
|
|
Packit |
1e8aac |
glade_util_added_in_list (GList *old_list, GList *new_list)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *added = NULL, *list;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (list = new_list; list; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!g_list_find (old_list, list->data))
|
|
Packit |
1e8aac |
added = g_list_prepend (added, list->data);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_list_reverse (added);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_removed_from_list:
|
|
Packit |
1e8aac |
* @old_list: the old #GList
|
|
Packit |
1e8aac |
* @new_list: the new #GList
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A newly allocated #GList of elements that
|
|
Packit |
1e8aac |
* are in @old no longer in @new
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GList *
|
|
Packit |
1e8aac |
glade_util_removed_from_list (GList *old_list, GList *new_list)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *added = NULL, *list;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (list = old_list; list; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!g_list_find (new_list, list->data))
|
|
Packit |
1e8aac |
added = g_list_prepend (added, list->data);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_list_reverse (added);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_canonical_path:
|
|
Packit |
1e8aac |
* @path: any path that may contain ".." or "." components
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: an absolute path to the specified file or directory
|
|
Packit |
1e8aac |
* that contains no ".." or "." components (this does
|
|
Packit |
1e8aac |
* not call readlink like realpath() does).
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Note: on some systems; I think its possible that we dont have
|
|
Packit |
1e8aac |
* permission to execute in the directory in which the glade
|
|
Packit |
1e8aac |
* file resides; I decided finally to do it this way anyway
|
|
Packit |
1e8aac |
* since libc's realpath() does exactly the same.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_util_canonical_path (const gchar *path)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *orig_dir, *dirname, *basename, *direct_dir, *direct_name = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (path != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
basename = g_path_get_basename (path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((orig_dir = g_get_current_dir ()) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if ((dirname = g_path_get_dirname (path)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (g_chdir (dirname) == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if ((direct_dir = g_get_current_dir ()) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
direct_name = g_build_filename (direct_dir, basename, NULL);
|
|
Packit |
1e8aac |
g_free (direct_dir);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("g_path");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_chdir (orig_dir) != 0)
|
|
Packit |
1e8aac |
g_warning ("Unable to chdir back to %s directory (%s)",
|
|
Packit |
1e8aac |
orig_dir, g_strerror (errno));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("Unable to chdir to %s directory (%s)",
|
|
Packit |
1e8aac |
dirname, g_strerror (errno));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (dirname);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("Unable to get directory component of %s\n", path);
|
|
Packit |
1e8aac |
g_free (orig_dir);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (basename)
|
|
Packit |
1e8aac |
g_free (basename);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return direct_name;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static GModule *
|
|
Packit |
1e8aac |
try_load_library (const gchar *library_path, const gchar *library_name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *path = g_module_build_path (library_path, library_name);
|
|
Packit |
1e8aac |
GModule *module = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!library_path || g_file_test (path, G_FILE_TEST_EXISTS))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!(module = g_module_open (path, G_MODULE_BIND_LAZY)))
|
|
Packit |
1e8aac |
g_warning ("Failed to load %s: %s", path, g_module_error ());
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return module;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_load_library:
|
|
Packit |
1e8aac |
* @library_name: name of the library
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Loads the named library from the Glade modules and lib directory or failing that
|
|
Packit |
1e8aac |
* from the standard platform specific directories. (Including /usr/local/lib for unices)
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* The @library_name should not include any platform specifix prefix or suffix,
|
|
Packit |
1e8aac |
* those are automatically added, if needed, by g_module_build_path()
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a #GModule on success, or %NULL on failure.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GModule *
|
|
Packit |
1e8aac |
glade_util_load_library (const gchar *library_name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GModule *module = NULL;
|
|
Packit |
1e8aac |
const gchar *search_path;
|
|
Packit |
1e8aac |
gint i;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((search_path = g_getenv (GLADE_ENV_MODULE_PATH)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar **split;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((split = g_strsplit (search_path, ":", 0)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (i = 0; split[i] != NULL; i++)
|
|
Packit |
1e8aac |
if ((module = try_load_library (split[i], library_name)) != NULL)
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_strfreev (split);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_getenv (GLADE_ENV_TESTING) == NULL && !module)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *paths[] = { glade_app_get_modules_dir (),
|
|
Packit |
1e8aac |
glade_app_get_lib_dir (),
|
|
Packit |
1e8aac |
#ifndef G_OS_WIN32 /* Try local lib dir on Unices */
|
|
Packit |
1e8aac |
"/usr/local/lib",
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
NULL}; /* Use default system paths */
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (i = 0; i < G_N_ELEMENTS (paths); i++)
|
|
Packit |
1e8aac |
if ((module = try_load_library (paths[i], library_name)) != NULL)
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return module;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_file_is_writeable:
|
|
Packit |
1e8aac |
* @path: the path to the file
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Checks whether the file at @path is writeable
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: TRUE if file is writeable
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_util_file_is_writeable (const gchar *path)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GIOChannel *channel;
|
|
Packit |
1e8aac |
g_return_val_if_fail (path != NULL, FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* The only way to really know if the file is writable */
|
|
Packit |
1e8aac |
if ((channel = g_io_channel_new_file (path, "a+", NULL)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_io_channel_unref (channel);
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_have_devhelp:
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: whether the devhelp module is loaded
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_util_have_devhelp (void)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
static gint have_devhelp = -1;
|
|
Packit |
1e8aac |
gchar *ptr;
|
|
Packit |
1e8aac |
gint cnt, ret, major, minor;
|
|
Packit |
1e8aac |
GError *error = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define DEVHELP_OLD_MESSAGE \
|
|
Packit |
1e8aac |
"The DevHelp installed on your system is too old, " \
|
|
Packit |
1e8aac |
"devhelp feature will be disabled."
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define DEVHELP_MISSING_MESSAGE \
|
|
Packit |
1e8aac |
"No DevHelp installed on your system, " \
|
|
Packit |
1e8aac |
"devhelp feature will be disabled."
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (have_devhelp >= 0)
|
|
Packit |
1e8aac |
return have_devhelp;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
have_devhelp = 0;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((ptr = g_find_program_in_path ("devhelp")) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_free (ptr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_spawn_command_line_sync ("devhelp --version",
|
|
Packit |
1e8aac |
&ptr, NULL, &ret, &error))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* If we have a successfull return code.. parse the output.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
if (ret == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar name[16];
|
|
Packit |
1e8aac |
if ((cnt = sscanf (ptr, "%15s %d.%d\n",
|
|
Packit |
1e8aac |
name, &major, &minor)) == 3)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Devhelp 0.12 required.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
if (major >= 2 || (major >= 0 && minor >= 12))
|
|
Packit |
1e8aac |
have_devhelp = 1;
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_message (DEVHELP_OLD_MESSAGE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (ptr != NULL || strlen (ptr) > 0)
|
|
Packit |
1e8aac |
g_warning ("devhelp had unparsable output: "
|
|
Packit |
1e8aac |
"'%s' (parsed %d elements)", ptr, cnt);
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_message (DEVHELP_OLD_MESSAGE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("devhelp had bad return code: '%d'", ret);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Error trying to launch devhelp: %s", error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_message (DEVHELP_MISSING_MESSAGE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return have_devhelp;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_get_devhelp_icon:
|
|
Packit |
1e8aac |
* @size: the preferred icon size
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Creates an image displaying the devhelp icon.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a #GtkImage
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GtkWidget *
|
|
Packit |
1e8aac |
glade_util_get_devhelp_icon (GtkIconSize size)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkIconTheme *icon_theme;
|
|
Packit |
1e8aac |
GdkScreen *screen;
|
|
Packit |
1e8aac |
GtkWidget *image;
|
|
Packit |
1e8aac |
gchar *path;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
image = gtk_image_new ();
|
|
Packit |
1e8aac |
screen = gtk_widget_get_screen (GTK_WIDGET (image));
|
|
Packit |
1e8aac |
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (gtk_icon_theme_has_icon (icon_theme, GLADE_DEVHELP_ICON_NAME))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_image_set_from_icon_name (GTK_IMAGE (image), GLADE_DEVHELP_ICON_NAME,
|
|
Packit |
1e8aac |
size);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
path =
|
|
Packit |
1e8aac |
g_build_filename (glade_app_get_pixmaps_dir (),
|
|
Packit |
1e8aac |
GLADE_DEVHELP_FALLBACK_ICON_FILE, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_image_set_from_file (GTK_IMAGE (image), path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (path);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return image;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_search_devhep:
|
|
Packit |
1e8aac |
* @devhelp: the devhelp widget created by the devhelp module.
|
|
Packit |
1e8aac |
* @book: the devhelp book (or %NULL)
|
|
Packit |
1e8aac |
* @page: the page in the book (or %NULL)
|
|
Packit |
1e8aac |
* @search: the search string (or %NULL)
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Envokes devhelp with the appropriate search string
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_util_search_devhelp (const gchar *book,
|
|
Packit |
1e8aac |
const gchar *page,
|
|
Packit |
1e8aac |
const gchar *search)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GError *error = NULL;
|
|
Packit |
1e8aac |
gchar *book_comm = NULL, *page_comm = NULL, *search_comm = NULL;
|
|
Packit |
1e8aac |
gchar *string;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (glade_util_have_devhelp ());
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (book)
|
|
Packit |
1e8aac |
book_comm = g_strdup_printf ("book:%s", book);
|
|
Packit |
1e8aac |
if (page)
|
|
Packit |
1e8aac |
page_comm = g_strdup_printf (" page:%s", page);
|
|
Packit |
1e8aac |
if (search)
|
|
Packit |
1e8aac |
search_comm = g_strdup_printf (" %s", search);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
string = g_strdup_printf ("devhelp -s \"%s%s%s\"",
|
|
Packit |
1e8aac |
book_comm ? book_comm : "",
|
|
Packit |
1e8aac |
page_comm ? page_comm : "",
|
|
Packit |
1e8aac |
search_comm ? search_comm : "");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_spawn_command_line_async (string, &error) == FALSE)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Error envoking devhelp: %s", error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (string);
|
|
Packit |
1e8aac |
if (book_comm)
|
|
Packit |
1e8aac |
g_free (book_comm);
|
|
Packit |
1e8aac |
if (page_comm)
|
|
Packit |
1e8aac |
g_free (page_comm);
|
|
Packit |
1e8aac |
if (search_comm)
|
|
Packit |
1e8aac |
g_free (search_comm);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GtkWidget *
|
|
Packit |
1e8aac |
glade_util_get_placeholder_from_pointer (GtkContainer *container)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GdkDeviceManager *manager;
|
|
Packit |
1e8aac |
GdkDisplay *display;
|
|
Packit |
1e8aac |
GdkDevice *device;
|
|
Packit |
1e8aac |
GdkWindow *window;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (((display = gtk_widget_get_display (GTK_WIDGET (container))) ||
|
|
Packit |
1e8aac |
(display = gdk_display_get_default ())) &&
|
|
Packit |
1e8aac |
(manager = gdk_display_get_device_manager (display)) &&
|
|
Packit |
1e8aac |
(device = gdk_device_manager_get_client_pointer (manager)) &&
|
|
Packit |
1e8aac |
(window = gdk_device_get_window_at_position (device, NULL, NULL)))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gpointer widget;
|
|
Packit |
1e8aac |
gdk_window_get_user_data (window, &widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return GLADE_IS_PLACEHOLDER (widget) ? GTK_WIDGET (widget) : NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_object_is_loading:
|
|
Packit |
1e8aac |
* @object: A #GObject
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: Whether the object's project is being loaded or not.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_util_object_is_loading (GObject *object)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeProject *project;
|
|
Packit |
1e8aac |
GladeWidget *widget;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
widget = glade_widget_get_from_gobject (object);
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
project = glade_widget_get_project (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return project && glade_project_is_loading (project);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_url_show:
|
|
Packit |
1e8aac |
* @url: An URL to display
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Portable function for showing an URL @url in a web browser.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: TRUE if a web browser was successfully launched, or FALSE
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_util_url_show (const gchar *url)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *widget;
|
|
Packit |
1e8aac |
GError *error = NULL;
|
|
Packit |
1e8aac |
gboolean ret;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (url != NULL, FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
widget = glade_app_get_window ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
ret = gtk_show_uri (gtk_widget_get_screen (widget),
|
|
Packit |
1e8aac |
url, gtk_get_current_event_time (), &error);
|
|
Packit |
1e8aac |
if (error != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *dialog_widget;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
dialog_widget = gtk_message_dialog_new (GTK_WINDOW (widget),
|
|
Packit |
1e8aac |
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
Packit |
1e8aac |
GTK_MESSAGE_ERROR,
|
|
Packit |
1e8aac |
GTK_BUTTONS_CLOSE,
|
|
Packit |
1e8aac |
"%s", _("Could not show link:"));
|
|
Packit |
1e8aac |
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG
|
|
Packit |
1e8aac |
(dialog_widget), "%s",
|
|
Packit |
1e8aac |
error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_signal_connect (dialog_widget, "response",
|
|
Packit |
1e8aac |
G_CALLBACK (gtk_widget_destroy), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_window_present (GTK_WINDOW (dialog_widget));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return ret;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_util_get_file_mtime:
|
|
Packit |
1e8aac |
* @filename: A filename
|
|
Packit |
1e8aac |
* @error: return location for errors
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Gets the UTC modification time of file @filename.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: The mtime of the file, or %0 if the file attributes
|
|
Packit |
1e8aac |
* could not be read.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
time_t
|
|
Packit |
1e8aac |
glade_util_get_file_mtime (const gchar *filename, GError **error)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
struct stat info;
|
|
Packit |
1e8aac |
gint retval;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
retval = g_stat (filename, &info;;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (retval != 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_set_error (error,
|
|
Packit |
1e8aac |
G_FILE_ERROR,
|
|
Packit |
1e8aac |
g_file_error_from_errno (errno),
|
|
Packit |
1e8aac |
"could not stat file '%s': %s", filename,
|
|
Packit |
1e8aac |
g_strerror (errno));
|
|
Packit |
1e8aac |
return (time_t) 0;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return info.st_mtime;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_util_filename_to_icon_name (const gchar *value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *icon_name, *p;
|
|
Packit |
1e8aac |
g_return_val_if_fail (value && value[0], NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
icon_name = g_strdup_printf ("glade-generated-%s", value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((p = strrchr (icon_name, '.')) != NULL)
|
|
Packit |
1e8aac |
*p = '-';
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return icon_name;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_util_icon_name_to_filename (const gchar *value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* sscanf makes us allocate a buffer */
|
|
Packit |
1e8aac |
gchar filename[FILENAME_MAX], *p;
|
|
Packit |
1e8aac |
g_return_val_if_fail (value && value[0], NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
sscanf (value, "glade-generated-%s", filename);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* XXX: Filenames without an extention will evidently
|
|
Packit |
1e8aac |
* break here
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
if ((p = strrchr (filename, '-')) != NULL)
|
|
Packit |
1e8aac |
*p = '.';
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_strdup (filename);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gint
|
|
Packit |
1e8aac |
glade_utils_enum_value_from_string (GType enum_type, const gchar *strval)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gint value = 0;
|
|
Packit |
1e8aac |
const gchar *displayable;
|
|
Packit |
1e8aac |
GValue *gvalue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (strval && strval[0], 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (((displayable =
|
|
Packit |
1e8aac |
glade_get_value_from_displayable (enum_type, strval)) != NULL &&
|
|
Packit |
1e8aac |
(gvalue =
|
|
Packit |
1e8aac |
glade_utils_value_from_string (enum_type, displayable, NULL)) != NULL) ||
|
|
Packit |
1e8aac |
(gvalue =
|
|
Packit |
1e8aac |
glade_utils_value_from_string (enum_type, strval, NULL)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
value = g_value_get_enum (gvalue);
|
|
Packit |
1e8aac |
g_value_unset (gvalue);
|
|
Packit |
1e8aac |
g_free (gvalue);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return value;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gchar *
|
|
Packit |
1e8aac |
glade_utils_enum_string_from_value_real (GType enum_type,
|
|
Packit |
1e8aac |
gint value,
|
|
Packit |
1e8aac |
gboolean displayable)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GValue gvalue = { 0, };
|
|
Packit |
1e8aac |
gchar *string;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_value_init (&gvalue, enum_type);
|
|
Packit |
1e8aac |
g_value_set_enum (&gvalue, value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
string = glade_utils_string_from_value (&gvalue);
|
|
Packit |
1e8aac |
g_value_unset (&gvalue);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (displayable && string)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *dstring = glade_get_displayable_value (enum_type, string);
|
|
Packit |
1e8aac |
if (dstring)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_free (string);
|
|
Packit |
1e8aac |
return g_strdup (dstring);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return string;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_utils_enum_string_from_value (GType enum_type, gint value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return glade_utils_enum_string_from_value_real (enum_type, value, FALSE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_utils_enum_string_from_value_displayable (GType enum_type, gint value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return glade_utils_enum_string_from_value_real (enum_type, value, TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gint
|
|
Packit |
1e8aac |
glade_utils_flags_value_from_string (GType flags_type, const gchar *strval)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gint value = 0;
|
|
Packit |
1e8aac |
const gchar *displayable;
|
|
Packit |
1e8aac |
GValue *gvalue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (strval && strval[0], 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (((displayable =
|
|
Packit |
1e8aac |
glade_get_value_from_displayable (flags_type, strval)) != NULL &&
|
|
Packit |
1e8aac |
(gvalue =
|
|
Packit |
1e8aac |
glade_utils_value_from_string (flags_type, displayable, NULL)) != NULL) ||
|
|
Packit |
1e8aac |
(gvalue =
|
|
Packit |
1e8aac |
glade_utils_value_from_string (flags_type, strval, NULL)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
value = g_value_get_flags (gvalue);
|
|
Packit |
1e8aac |
g_value_unset (gvalue);
|
|
Packit |
1e8aac |
g_free (gvalue);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return value;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gchar *
|
|
Packit |
1e8aac |
glade_utils_flags_string_from_value_real (GType flags_type,
|
|
Packit |
1e8aac |
gint value,
|
|
Packit |
1e8aac |
gboolean displayable)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GValue gvalue = { 0, };
|
|
Packit |
1e8aac |
gchar *string;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_value_init (&gvalue, flags_type);
|
|
Packit |
1e8aac |
g_value_set_flags (&gvalue, value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
string = glade_utils_string_from_value (&gvalue);
|
|
Packit |
1e8aac |
g_value_unset (&gvalue);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (displayable && string)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *dstring = glade_get_displayable_value (flags_type, string);
|
|
Packit |
1e8aac |
if (dstring)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_free (string);
|
|
Packit |
1e8aac |
return g_strdup (dstring);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return string;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_utils_flags_string_from_value (GType flags_type, gint value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return glade_utils_flags_string_from_value_real (flags_type, value, FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_utils_flags_string_from_value_displayable (GType flags_type, gint value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return glade_utils_flags_string_from_value_real (flags_type, value, TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* A hash table of generically created property classes for
|
|
Packit |
1e8aac |
* fundamental types, so we can easily use glade's conversion
|
|
Packit |
1e8aac |
* system without using properties (only GTypes)
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
static GHashTable *generic_property_classes = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
utils_gtype_equal (gconstpointer v1, gconstpointer v2)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return *((const GType *) v1) == *((const GType *) v2);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static guint
|
|
Packit |
1e8aac |
utils_gtype_hash (gconstpointer v)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return *(const GType *) v;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static GladePropertyClass *
|
|
Packit |
1e8aac |
pclass_from_gtype (GType type)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePropertyClass *property_class = NULL;
|
|
Packit |
1e8aac |
GParamSpec *pspec = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!generic_property_classes)
|
|
Packit |
1e8aac |
generic_property_classes =
|
|
Packit |
1e8aac |
g_hash_table_new_full (utils_gtype_hash, utils_gtype_equal, g_free,
|
|
Packit |
1e8aac |
(GDestroyNotify) glade_property_class_free);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
property_class = g_hash_table_lookup (generic_property_classes, &type);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!property_class)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Support enum and flag types, and a hardcoded list of fundamental types */
|
|
Packit |
1e8aac |
if (type == G_TYPE_CHAR)
|
|
Packit |
1e8aac |
pspec = g_param_spec_char ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
G_MININT8, G_MAXINT8, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_UCHAR)
|
|
Packit |
1e8aac |
pspec = g_param_spec_char ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
0, G_MAXUINT8, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_BOOLEAN)
|
|
Packit |
1e8aac |
pspec = g_param_spec_boolean ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
FALSE,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_INT)
|
|
Packit |
1e8aac |
pspec = g_param_spec_int ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
G_MININT, G_MAXINT, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_UINT)
|
|
Packit |
1e8aac |
pspec = g_param_spec_uint ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
0, G_MAXUINT, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_LONG)
|
|
Packit |
1e8aac |
pspec = g_param_spec_long ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
G_MINLONG, G_MAXLONG, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_ULONG)
|
|
Packit |
1e8aac |
pspec = g_param_spec_ulong ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
0, G_MAXULONG, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_INT64)
|
|
Packit |
1e8aac |
pspec = g_param_spec_int64 ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
G_MININT64, G_MAXINT64, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_UINT64)
|
|
Packit |
1e8aac |
pspec = g_param_spec_uint64 ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
0, G_MAXUINT64, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_FLOAT)
|
|
Packit |
1e8aac |
pspec = g_param_spec_float ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
G_MINFLOAT, G_MAXFLOAT, 1.0F,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_DOUBLE)
|
|
Packit |
1e8aac |
pspec = g_param_spec_double ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
G_MINDOUBLE, G_MAXDOUBLE, 1.0F,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_STRING)
|
|
Packit |
1e8aac |
pspec = g_param_spec_string ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
NULL, G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (type == G_TYPE_OBJECT || g_type_is_a (type, G_TYPE_OBJECT))
|
|
Packit |
1e8aac |
pspec = g_param_spec_object ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
type, G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
else if (G_TYPE_IS_ENUM (type))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GEnumClass *eclass = g_type_class_ref (type);
|
|
Packit |
1e8aac |
pspec = g_param_spec_enum ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
type, eclass->minimum,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
g_type_class_unref (eclass);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (G_TYPE_IS_FLAGS (type))
|
|
Packit |
1e8aac |
pspec = g_param_spec_flags ("dummy", "dummy", "dummy",
|
|
Packit |
1e8aac |
type, 0,
|
|
Packit |
1e8aac |
G_PARAM_READABLE | G_PARAM_WRITABLE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (pspec)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if ((property_class =
|
|
Packit |
1e8aac |
glade_property_class_new_from_spec_full (NULL, pspec,
|
|
Packit |
1e8aac |
FALSE)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* XXX If we ever free the hash table, property classes wont touch
|
|
Packit |
1e8aac |
* the allocated pspecs, so they would theoretically be leaked.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
g_hash_table_insert (generic_property_classes,
|
|
Packit |
1e8aac |
g_memdup (&type, sizeof (GType)),
|
|
Packit |
1e8aac |
property_class);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("Unable to create property class for type %s",
|
|
Packit |
1e8aac |
g_type_name (type));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("No generic conversion support for type %s",
|
|
Packit |
1e8aac |
g_type_name (type));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return property_class;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_value_from_string:
|
|
Packit |
1e8aac |
* @type: a #GType to convert with
|
|
Packit |
1e8aac |
* @string: the string to convert
|
|
Packit |
1e8aac |
* @project: the #GladeProject to look for formats of object names when needed
|
|
Packit |
1e8aac |
* @widget: if the value is a gobject, this #GladeWidget will be used to look
|
|
Packit |
1e8aac |
* for an object in the same widget tree.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Allocates and sets a #GValue of type @type
|
|
Packit |
1e8aac |
* set to @string (using glade conversion routines)
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A newly allocated and set #GValue
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GValue *
|
|
Packit |
1e8aac |
glade_utils_value_from_string (GType type,
|
|
Packit |
1e8aac |
const gchar *string,
|
|
Packit |
1e8aac |
GladeProject *project)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePropertyClass *pclass;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
|
|
Packit |
1e8aac |
g_return_val_if_fail (string != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((pclass = pclass_from_gtype (type)) != NULL)
|
|
Packit |
1e8aac |
return glade_property_class_make_gvalue_from_string (pclass, string, project);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_boolean_from_string:
|
|
Packit |
1e8aac |
* @string: the string to convert
|
|
Packit |
1e8aac |
* @value: return location
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Parse a boolean value
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: True if there was an error on the conversion.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_utils_boolean_from_string (const gchar *string, gboolean *value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (string)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *c = string;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Skip white spaces */
|
|
Packit |
1e8aac |
while (g_ascii_isspace (*c))
|
|
Packit |
1e8aac |
c++;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* We only need the first char */
|
|
Packit |
1e8aac |
switch (*c)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case '1':
|
|
Packit |
1e8aac |
case 't':
|
|
Packit |
1e8aac |
case 'T':
|
|
Packit |
1e8aac |
case 'y':
|
|
Packit |
1e8aac |
case 'Y':
|
|
Packit |
1e8aac |
if (value)
|
|
Packit |
1e8aac |
*value = TRUE;
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
case '0':
|
|
Packit |
1e8aac |
case 'f':
|
|
Packit |
1e8aac |
case 'F':
|
|
Packit |
1e8aac |
case 'n':
|
|
Packit |
1e8aac |
case 'N':
|
|
Packit |
1e8aac |
if (value)
|
|
Packit |
1e8aac |
*value = FALSE;
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_string_from_value:
|
|
Packit |
1e8aac |
* @value: a #GValue to convert
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Serializes #GValue into a string
|
|
Packit |
1e8aac |
* (using glade conversion routines)
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A newly allocated string
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_utils_string_from_value (const GValue *value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePropertyClass *pclass;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (value != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((pclass = pclass_from_gtype (G_VALUE_TYPE (value))) != NULL)
|
|
Packit |
1e8aac |
return glade_property_class_make_string_from_gvalue (pclass, value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_liststore_from_enum_type:
|
|
Packit |
1e8aac |
* @enum_type: A #GType
|
|
Packit |
1e8aac |
* @include_empty: wheather to prepend an "Unset" slot
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Creates a liststore suitable for comboboxes and such to
|
|
Packit |
1e8aac |
* chose from a variety of types.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: A new #GtkListStore
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GtkListStore *
|
|
Packit |
1e8aac |
glade_utils_liststore_from_enum_type (GType enum_type, gboolean include_empty)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkListStore *store;
|
|
Packit |
1e8aac |
GtkTreeIter iter;
|
|
Packit |
1e8aac |
GEnumClass *eclass;
|
|
Packit |
1e8aac |
guint i;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
eclass = g_type_class_ref (enum_type);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
store = gtk_list_store_new (1, G_TYPE_STRING);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (include_empty)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_list_store_append (store, &iter);
|
|
Packit |
1e8aac |
gtk_list_store_set (store, &iter, 0, _("None"), -1);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (i = 0; i < eclass->n_values; i++)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *displayable =
|
|
Packit |
1e8aac |
glade_get_displayable_value (enum_type, eclass->values[i].value_nick);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_list_store_append (store, &iter);
|
|
Packit |
1e8aac |
gtk_list_store_set (store, &iter,
|
|
Packit |
1e8aac |
0,
|
|
Packit |
1e8aac |
displayable ? displayable : eclass->values[i].
|
|
Packit |
1e8aac |
value_nick, -1);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_type_class_unref (eclass);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return store;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_hijack_key_press:
|
|
Packit |
1e8aac |
* @win: a #GtkWindow
|
|
Packit |
1e8aac |
* event: the GdkEventKey
|
|
Packit |
1e8aac |
* user_data: unused
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This function is meant to be attached to key-press-event of a toplevel,
|
|
Packit |
1e8aac |
* it simply allows the window contents to treat key events /before/
|
|
Packit |
1e8aac |
* accelerator keys come into play (this way widgets dont get deleted
|
|
Packit |
1e8aac |
* when cutting text in an entry etc.).
|
|
Packit |
1e8aac |
* Creates a liststore suitable for comboboxes and such to
|
|
Packit |
1e8aac |
* chose from a variety of types.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: whether the event was handled
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gint
|
|
Packit |
1e8aac |
glade_utils_hijack_key_press (GtkWindow *win,
|
|
Packit |
1e8aac |
GdkEventKey *event,
|
|
Packit |
1e8aac |
gpointer user_data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *focus_widget;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
focus_widget = gtk_window_get_focus (win);
|
|
Packit |
1e8aac |
if (focus_widget && (event->keyval == GDK_KEY_Delete || /* Filter Delete from accelerator keys */
|
|
Packit |
1e8aac |
((event->state & GDK_CONTROL_MASK) && /* CNTL keys... */
|
|
Packit |
1e8aac |
((event->keyval == GDK_KEY_c || event->keyval == GDK_KEY_C) || /* CNTL-C (copy) */
|
|
Packit |
1e8aac |
(event->keyval == GDK_KEY_x || event->keyval == GDK_KEY_X) || /* CNTL-X (cut) */
|
|
Packit |
1e8aac |
(event->keyval == GDK_KEY_v || event->keyval == GDK_KEY_V) || /* CNTL-V (paste) */
|
|
Packit |
1e8aac |
(event->keyval == GDK_KEY_n || event->keyval == GDK_KEY_N))))) /* CNTL-N (new project) */
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return gtk_widget_event (focus_widget, (GdkEvent *) event);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_utils_cairo_draw_line (cairo_t *cr,
|
|
Packit |
1e8aac |
GdkColor *color,
|
|
Packit |
1e8aac |
gint x1, gint y1,
|
|
Packit |
1e8aac |
gint x2, gint y2)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_save (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
Packit |
1e8aac |
gdk_cairo_set_source_color (cr, color);
|
|
Packit |
1e8aac |
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
Packit |
1e8aac |
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
|
|
Packit |
1e8aac |
cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_restore (cr);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_utils_cairo_draw_rectangle (cairo_t *cr,
|
|
Packit |
1e8aac |
GdkColor *color,
|
|
Packit |
1e8aac |
gboolean filled,
|
|
Packit |
1e8aac |
gint x, gint y,
|
|
Packit |
1e8aac |
gint width, gint height)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
Packit |
1e8aac |
gdk_cairo_set_source_color (cr, color);
|
|
Packit |
1e8aac |
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (filled)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_rectangle (cr, x, y, width, height);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* copied from gedit */
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_utils_replace_home_dir_with_tilde (const gchar *path)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
#ifdef G_OS_UNIX
|
|
Packit |
1e8aac |
gchar *tmp;
|
|
Packit |
1e8aac |
gchar *home;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (path != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Note that g_get_home_dir returns a const string */
|
|
Packit |
1e8aac |
tmp = (gchar *) g_get_home_dir ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (tmp == NULL)
|
|
Packit |
1e8aac |
return g_strdup (path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
home = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
|
|
Packit |
1e8aac |
if (home == NULL)
|
|
Packit |
1e8aac |
return g_strdup (path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (strcmp (path, home) == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_free (home);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_strdup ("~");
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
tmp = home;
|
|
Packit |
1e8aac |
home = g_strdup_printf ("%s/", tmp);
|
|
Packit |
1e8aac |
g_free (tmp);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_str_has_prefix (path, home))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *res;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
res = g_strdup_printf ("~/%s", path + strlen (home));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (home);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return res;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (home);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_strdup (path);
|
|
Packit |
1e8aac |
#else
|
|
Packit |
1e8aac |
return g_strdup (path);
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
draw_tip (cairo_t *cr)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_line_to (cr, 2, 8);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 2, 4);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 0, 4);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 0, 3);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 3, 0);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 6, 3);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 6, 4);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 4, 4);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_translate (cr, 12, 6);
|
|
Packit |
1e8aac |
cairo_rotate (cr, G_PI_2);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
draw_tips (cairo_t *cr)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_move_to (cr, 2, 8);
|
|
Packit |
1e8aac |
draw_tip (cr); draw_tip (cr); draw_tip (cr); draw_tip (cr);
|
|
Packit |
1e8aac |
cairo_close_path (cr);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
draw_pointer (cairo_t *cr)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_line_to (cr, 8, 3);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 19, 14);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 13.75, 14);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 16.5, 19);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 14, 21);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 11, 16);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 7, 19);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 7, 3);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 8, 3);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Needed for private draw functions! */
|
|
Packit |
1e8aac |
#include "glade-design-private.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_pointer_mode_render_icon:
|
|
Packit |
1e8aac |
* @mode: the #GladePointerMode to render as icon
|
|
Packit |
1e8aac |
* @size: icon size
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Render an icon representing the pointer mode.
|
|
Packit |
1e8aac |
* Best view with sizes bigger than GTK_ICON_SIZE_LARGE_TOOLBAR.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GdkPixbuf *
|
|
Packit |
1e8aac |
glade_utils_pointer_mode_render_icon (GladePointerMode mode, GtkIconSize size)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GdkRGBA c1, c2, fg, bg;
|
|
Packit |
1e8aac |
cairo_surface_t *surface;
|
|
Packit |
1e8aac |
gint width, height;
|
|
Packit |
1e8aac |
GdkPixbuf *pix;
|
|
Packit |
1e8aac |
cairo_t *cr;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (gtk_icon_size_lookup (size, &width, &height) == FALSE) return NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
|
Packit |
1e8aac |
cr = cairo_create (surface);
|
|
Packit |
1e8aac |
cairo_scale (cr, width/24.0, height/24.0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Now get colors */
|
|
Packit |
1e8aac |
_glade_design_layout_get_colors (&bg, &fg, &c1, &c2;;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Clear surface */
|
|
Packit |
1e8aac |
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
|
Packit |
1e8aac |
cairo_fill(cr);
|
|
Packit |
1e8aac |
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
switch (mode)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case GLADE_POINTER_SELECT:
|
|
Packit |
1e8aac |
case GLADE_POINTER_ADD_WIDGET:
|
|
Packit |
1e8aac |
cairo_set_line_width (cr, 1);
|
|
Packit |
1e8aac |
cairo_translate (cr, 1.5, 1.5);
|
|
Packit |
1e8aac |
draw_pointer (cr);
|
|
Packit |
1e8aac |
fg.alpha = .16;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &fg;;
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_translate (cr, -1, -1);
|
|
Packit |
1e8aac |
draw_pointer (cr);
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &c2;;
|
|
Packit |
1e8aac |
cairo_fill_preserve (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
fg.alpha = .64;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &fg;;
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_POINTER_DRAG_RESIZE:
|
|
Packit |
1e8aac |
cairo_set_line_width (cr, 1);
|
|
Packit |
1e8aac |
cairo_translate (cr, 10.5, 3.5);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
draw_tips (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
fg.alpha = .16;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &fg;;
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_translate (cr, -1, -1);
|
|
Packit |
1e8aac |
draw_tips (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &c2;;
|
|
Packit |
1e8aac |
cairo_fill_preserve (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
c1.red = MAX (0, c1.red - .1);
|
|
Packit |
1e8aac |
c1.green = MAX (0, c1.green - .1);
|
|
Packit |
1e8aac |
c1.blue = MAX (0, c1.blue - .1);
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &c1;;
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_POINTER_MARGIN_EDIT:
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &bg;;
|
|
Packit |
1e8aac |
cairo_rectangle (cr, 4, 4, 18, 18);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
c1.alpha = .1;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &c1;;
|
|
Packit |
1e8aac |
cairo_rectangle (cr, 6, 6, 16, 16);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_set_line_width (cr, 1);
|
|
Packit |
1e8aac |
fg.alpha = .32;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &fg;;
|
|
Packit |
1e8aac |
cairo_move_to (cr, 16.5, 22);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 16.5, 16.5);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 22, 16.5);
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
c1.alpha = .16;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &c1;;
|
|
Packit |
1e8aac |
cairo_rectangle (cr, 16, 16, 6, 6);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_set_line_width (cr, 2);
|
|
Packit |
1e8aac |
c1.alpha = .75;
|
|
Packit |
1e8aac |
gdk_cairo_set_source_rgba (cr, &c1;;
|
|
Packit |
1e8aac |
cairo_move_to (cr, 6, 22);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 6, 6);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 22, 6);
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
c1.alpha = 1;
|
|
Packit |
1e8aac |
cairo_scale (cr, .75, .75);
|
|
Packit |
1e8aac |
cairo_set_line_width (cr, 4);
|
|
Packit |
1e8aac |
_glade_design_layout_draw_node (cr, 16*1.25, 6*1.25, &c1, &c2;;
|
|
Packit |
1e8aac |
_glade_design_layout_draw_node (cr, 6*1.25, 16*1.25, &c1, &c2;;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GLADE_POINTER_ALIGN_EDIT:
|
|
Packit |
1e8aac |
cairo_scale (cr, 1.5, 1.5);
|
|
Packit |
1e8aac |
cairo_rotate (cr, 45*(G_PI/180));
|
|
Packit |
1e8aac |
cairo_translate (cr, 11, 2);
|
|
Packit |
1e8aac |
_glade_design_layout_draw_pushpin (cr, 2.5, &c1, &c2, &c2, &fg;;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
pix = gdk_pixbuf_get_from_surface (surface, 0, 0,
|
|
Packit |
1e8aac |
cairo_image_surface_get_width (surface),
|
|
Packit |
1e8aac |
cairo_image_surface_get_height (surface));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_surface_destroy (surface);
|
|
Packit |
1e8aac |
cairo_destroy (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return pix;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_utils_get_pointer:
|
|
Packit |
1e8aac |
* @widget: The widget to get the mouse position relative for
|
|
Packit |
1e8aac |
* @window: The window of the current event, or %NULL
|
|
Packit |
1e8aac |
* @device: The device, if not specified, the current event will be expected to have a @device.
|
|
Packit |
1e8aac |
* @x: The location to store the mouse pointer X position
|
|
Packit |
1e8aac |
* @y: The location to store the mouse pointer Y position
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Get's the pointer position relative to @widget, while @window and @device
|
|
Packit |
1e8aac |
* are not absolutely needed, they should be passed wherever possible.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_utils_get_pointer (GtkWidget *widget,
|
|
Packit |
1e8aac |
GdkWindow *window,
|
|
Packit |
1e8aac |
GdkDevice *device,
|
|
Packit |
1e8aac |
gint *x,
|
|
Packit |
1e8aac |
gint *y)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gint device_x = 0, device_y = 0;
|
|
Packit |
1e8aac |
gint final_x = 0, final_y = 0;
|
|
Packit |
1e8aac |
GtkWidget *event_widget = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!device)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GdkEvent *event = gtk_get_current_event ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
device = gdk_event_get_device (event);
|
|
Packit |
1e8aac |
gdk_event_free (event);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GDK_IS_DEVICE (device));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!window)
|
|
Packit |
1e8aac |
window = gtk_widget_get_window (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GDK_IS_WINDOW (window));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gdk_window_get_device_position (window, device, &device_x, &device_y, NULL);
|
|
Packit |
1e8aac |
gdk_window_get_user_data (window, (gpointer)&event_widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (event_widget != widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_widget_translate_coordinates (event_widget,
|
|
Packit |
1e8aac |
widget,
|
|
Packit |
1e8aac |
device_x, device_y,
|
|
Packit |
1e8aac |
&final_x, &final_y);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
final_x = device_x;
|
|
Packit |
1e8aac |
final_y = device_y;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (x)
|
|
Packit |
1e8aac |
*x = final_x;
|
|
Packit |
1e8aac |
if (y)
|
|
Packit |
1e8aac |
*y = final_y;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Use this to disable scroll events on property editors,
|
|
Packit |
1e8aac |
* we dont want them handling scroll because they are inside
|
|
Packit |
1e8aac |
* a scrolled window and interrupt workflow causing unexpected
|
|
Packit |
1e8aac |
* results when scrolled.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
static gint
|
|
Packit |
1e8aac |
abort_scroll_events (GtkWidget *widget,
|
|
Packit |
1e8aac |
GdkEvent *event,
|
|
Packit |
1e8aac |
gpointer user_data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *parent = gtk_widget_get_parent (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Removing the events from the mask doesnt work for
|
|
Packit |
1e8aac |
* stubborn combo boxes which call gtk_widget_add_events()
|
|
Packit |
1e8aac |
* in it's gtk_combo_box_init() - so handle the event and propagate
|
|
Packit |
1e8aac |
* it up the tree so the scrollwindow still handles the scroll event.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gtk_propagate_event (parent, event);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_util_remove_scroll_events (GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gint events = gtk_widget_get_events (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
events &= ~(GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK);
|
|
Packit |
1e8aac |
gtk_widget_set_events (widget, events);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_signal_connect (G_OBJECT (widget), "scroll-event",
|
|
Packit |
1e8aac |
G_CALLBACK (abort_scroll_events), NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* _glade_util_file_get_relative_path:
|
|
Packit |
1e8aac |
* @target: input GFile
|
|
Packit |
1e8aac |
* @source: input GFile
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Gets the path for @source relative to @target even if @source is not a
|
|
Packit |
1e8aac |
* descendant of @target.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
_glade_util_file_get_relative_path (GFile *target, GFile *source)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *relative_path;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((relative_path = g_file_get_relative_path (target, source)) == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GString *relpath = g_string_new ("");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_ref (target);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
while (relative_path == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GFile *old_target = target;
|
|
Packit |
1e8aac |
target = g_file_get_parent (target);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
relative_path = g_file_get_relative_path (target, source);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_string_append (relpath, "..");
|
|
Packit |
1e8aac |
g_string_append_c (relpath, G_DIR_SEPARATOR);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_unref (old_target);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_string_append (relpath, relative_path);
|
|
Packit |
1e8aac |
g_free (relative_path);
|
|
Packit |
1e8aac |
relative_path = g_string_free (relpath, FALSE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return relative_path;
|
|
Packit |
1e8aac |
}
|