Better logging functions

master
Yevgen Muntyan 2006-03-15 02:16:42 -06:00
parent 18ad1c03a4
commit a16b9c9965
16 changed files with 564 additions and 349 deletions

View File

@ -20,7 +20,7 @@ AC_DEFUN([MOO_AC_SET_DIRS],[
AC_SUBST(MOO_DATA_DIR)
AC_DEFINE_UNQUOTED(MOO_DATA_DIR, "${MOO_DATA_DIR}", [data dir])
MOO_LIB_DIR="${prefix}/${datadir}/$1"
MOO_LIB_DIR="${prefix}/${libdir}/$1"
AC_SUBST(MOO_LIB_DIR)
AC_DEFINE_UNQUOTED(MOO_LIB_DIR, "${MOO_LIB_DIR}", [lib dir])

View File

@ -27,6 +27,7 @@
#include "mooedit/mooplugin-macro.h"
#define PLUGIN_SUFFIX ".py"
#define LIBDIR "lib"
typedef struct _MooPyPluginData MooPyPluginData;
@ -96,12 +97,6 @@ decref (MooPyObject *obj)
}
}
static void
err_print (void)
{
PyErr_Print ();
}
static MooPyObject *
py_object_from_gobject (gpointer gobj)
@ -182,6 +177,13 @@ get_script_dict (const char *name)
}
static void
err_print (void)
{
PyErr_Print ();
}
static gboolean
moo_python_api_init (void)
{
@ -202,11 +204,21 @@ moo_python_api_init (void)
}
g_assert (moo_python_running ());
Py_Initialize ();
moo_py_init_print_funcs ();
main_mod = PyImport_AddModule ((char*)"__main__");
Py_XINCREF ((PyObject*) main_mod);
if (!main_mod)
{
g_warning ("%s: could not import __main__", G_STRLOC);
PyErr_Print ();
moo_python_init (MOO_PY_API_VERSION, NULL);
return FALSE;
}
Py_XINCREF ((PyObject*) main_mod);
return TRUE;
}
@ -255,7 +267,7 @@ out:
static void
moo_python_plugin_read_dir (const char *path)
moo_python_plugin_read_dir (const char *path)
{
GDir *dir;
const char *name;
@ -289,10 +301,32 @@ moo_python_plugin_read_dir (const char *path)
static void
moo_python_plugin_read_dirs ()
moo_python_plugin_read_dirs (void)
{
char **d;
char **dirs = moo_get_plugin_dirs ();
PyObject *sys = NULL, *path = NULL;
sys = PyImport_ImportModule ((char*) "sys");
if (sys)
path = PyObject_GetAttrString (sys, (char*) "path");
if (!path || !PyList_Check (path))
{
g_critical ("%s: oops", G_STRLOC);
}
else
{
for (d = dirs; d && *d; ++d)
{
char *libdir = g_build_filename (*d, LIBDIR, NULL);
PyObject *s = PyString_FromString (libdir);
PyList_Append (path, s);
Py_XDECREF (s);
g_free (libdir);
}
}
for (d = dirs; d && *d; ++d)
moo_python_plugin_read_dir (*d);
@ -310,6 +344,7 @@ _moo_python_plugin_init (void)
if (!_moo_pygtk_init ())
{
PyErr_Print ();
moo_python_init (MOO_PY_API_VERSION, NULL);
return FALSE;
}

View File

@ -17,6 +17,7 @@
#endif
#include "moopython/moopython-utils.h"
#include "mooutils/moocompat.h"
#include "mooutils/mooutils-misc.h"
#ifdef MOO_USE_PYGTK
# define NO_IMPORT_PYGOBJECT
# include "pygobject.h"
@ -220,3 +221,191 @@ moo_py_object_get_type (void)
return type;
}
char *
moo_py_err_string (void)
{
PyObject *exc, *value, *tb;
PyObject *str_exc, *str_value, *str_tb;
GString *string;
PyErr_Fetch (&exc, &value, &tb);
PyErr_NormalizeException (&exc, &value, &tb);
if (!exc)
return NULL;
string = g_string_new (NULL);
str_exc = PyObject_Str (exc);
str_value = PyObject_Str (value);
str_tb = PyObject_Str (tb);
if (str_exc)
g_string_append_printf (string, "%s\n", PyString_AS_STRING (str_exc));
if (str_value)
g_string_append_printf (string, "%s\n", PyString_AS_STRING (str_value));
if (str_tb)
g_string_append_printf (string, "%s\n", PyString_AS_STRING (str_tb));
Py_XDECREF(exc);
Py_XDECREF(value);
Py_XDECREF(tb);
Py_XDECREF(str_exc);
Py_XDECREF(str_value);
Py_XDECREF(str_tb);
return g_string_free (string, FALSE);
}
/***********************************************************************/
/* File-like object for sys.stdout and sys.stderr
*/
typedef struct {
PyObject_HEAD
GPrintFunc write_func;
} MooPyFile;
// static int
// moo_py_file_new (PyObject *self, PyObject *args, PyObject *kwargs)
// {
// if (!PyArg_ParseTuple (args, (char*) ""))
// return -1;
//
// return 0;
// }
static PyObject *
moo_py_file_close (G_GNUC_UNUSED PyObject *self)
{
return_None;
}
static PyObject *
moo_py_file_flush (G_GNUC_UNUSED PyObject *self)
{
return_None;
}
static PyObject *
moo_py_file_write (PyObject *self, PyObject *args)
{
char *string;
MooPyFile *file = (MooPyFile *) self;
if (!PyArg_ParseTuple (args, (char*) "s", &string))
return NULL;
if (!file->write_func)
return_RuntimeErr ("no write function installed");
file->write_func (string);
return_None;
}
static PyMethodDef MooPyFile_methods[] = {
{ (char*) "close", (PyCFunction) moo_py_file_close, METH_NOARGS, NULL },
{ (char*) "flush", (PyCFunction) moo_py_file_flush, METH_NOARGS, NULL },
{ (char*) "write", (PyCFunction) moo_py_file_write, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
static PyTypeObject MooPyFile_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
(char*) "MooPyFile", /* tp_name */
sizeof (MooPyFile), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor) 0, /* tp_dealloc */
(printfunc) 0, /* tp_print */
(getattrfunc) 0, /* tp_getattr */
(setattrfunc) 0, /* tp_setattr */
(cmpfunc) 0, /* tp_compare */
(reprfunc) 0, /* tp_repr */
(PyNumberMethods*) 0, /* tp_as_number */
(PySequenceMethods*) 0, /* tp_as_sequence */
(PyMappingMethods*) 0, /* tp_as_mapping */
(hashfunc) 0, /* tp_hash */
(ternaryfunc) 0, /* tp_call */
(reprfunc) 0, /* tp_str */
(getattrofunc) 0, /* tp_getattro */
(setattrofunc) 0, /* tp_setattro */
(PyBufferProcs*) 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
NULL, /* Documentation string */
(traverseproc) 0, /* tp_traverse */
(inquiry) 0, /* tp_clear */
(richcmpfunc) 0, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc) 0, /* tp_iter */
(iternextfunc) 0, /* tp_iternext */
MooPyFile_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
(descrgetfunc) 0, /* tp_descr_get */
(descrsetfunc) 0, /* tp_descr_set */
0, /* tp_dictoffset */
// (initproc) moo_py_file_new, /* tp_init */
(initproc) 0, /* tp_init */
(allocfunc) 0, /* tp_alloc */
(newfunc) 0, /* tp_new */
(freefunc) 0, /* tp_free */
(inquiry) 0, /* tp_is_gc */
NULL, NULL, NULL, NULL, NULL, NULL
};
static void
set_file (const char *name,
GPrintFunc func)
{
MooPyFile *file;
file = PyObject_New (MooPyFile, &MooPyFile_Type);
if (!file)
{
PyErr_Print ();
return;
}
file->write_func = func;
if (PySys_SetObject ((char*) name, (PyObject*) file))
PyErr_Print ();
Py_DECREF (file);
}
void
moo_py_init_print_funcs (void)
{
static gboolean done;
if (done)
return;
done = TRUE;
if (PyType_Ready (&MooPyFile_Type) < 0)
{
g_critical ("could not init MooPyFile type");
return;
}
set_file ("stdout", moo_print);
set_file ("stderr", moo_print_err);
}

View File

@ -39,6 +39,10 @@ PyObject *moo_string_slist_to_pyobject (GSList *list);
PyObject *moo_gvalue_to_pyobject (const GValue *val);
char *moo_py_err_string (void);
void moo_py_init_print_funcs (void);
#define return_None G_STMT_START {Py_INCREF(Py_None); return Py_None;} G_STMT_END
#define return_Self G_STMT_START {Py_INCREF((PyObject*)self); return (PyObject*)self;} G_STMT_END

View File

@ -17,6 +17,7 @@
#include <glib.h>
#include "moopython/pygtk/moo-pygtk.h"
#include "moopython/pygtk/mooterm-mod.h"
#include "moopython/moopython-utils.h"
static char *moo_term_module_doc = (char*)"_moo_term module.";

View File

@ -1063,21 +1063,11 @@
(return-type "none")
)
(define-function log_window_write
(c-name "moo_log_window_write")
(return-type "none")
(parameters
'("const-gchar*" "log_domain")
'("GLogLevelFlags" "flags")
'("const-gchar*" "message")
)
)
(define-function set_log_func_window
(c-name "moo_set_log_func_window")
(return-type "none")
(parameters
'("int" "show")
'("gboolean" "show_now")
)
)
@ -1089,12 +1079,14 @@
)
)
(define-function set_log_func
(c-name "moo_set_log_func")
(define-function set_log_func_silent
(c-name "moo_set_log_func_silent")
(return-type "none")
)
(define-function reset_log_func
(c-name "moo_reset_log_func")
(return-type "none")
(parameters
'("int" "show_log")
)
)

View File

@ -62,6 +62,7 @@ mooutils_sources = \
$(mooutils)/mooglade.c \
$(mooutils)/moohistoryentry.c \
$(mooutils)/moohistorylist.c \
$(mooutils)/moologwindow-glade.h \
$(mooutils)/moomarkup.c \
$(mooutils)/moomenuaction.c \
$(mooutils)/moomenumgr.c \
@ -108,6 +109,7 @@ mooutils_built_sources = \
$(mooutils)/moomarshals.h \
$(mooutils)/mooaccelbutton-glade.h \
$(mooutils)/mooaccelprefs-glade.h \
$(mooutils)/moologwindow-glade.h \
$(mooutils)/stock-moo.h
$(mooutils)/moomarshals.c: $(mooutils)/moomarshals.list
@ -127,6 +129,10 @@ $(mooutils)/mooaccelprefs-glade.h: $(mooutils_srcdir)/glade/shortcutsprefs.glade
mkdir -p $(mooutils)
sh $(mooutils_srcdir)/xml2h.sh MOO_SHORTCUTS_PREFS_GLADE_UI \
$(mooutils_srcdir)/glade/shortcutsprefs.glade > $(mooutils)/mooaccelprefs-glade.h
$(mooutils)/moologwindow-glade.h: $(mooutils_srcdir)/glade/moologwindow.glade
mkdir -p $(mooutils)
sh $(mooutils_srcdir)/xml2h.sh MOO_LOG_WINDOW_GLADE_UI \
$(mooutils_srcdir)/glade/moologwindow.glade > $(mooutils)/moologwindow-glade.h
mooutils_pixmaps = \
$(mooutils_srcdir)/pixmaps/gap.png \

View File

@ -7,5 +7,4 @@ mooutils_glade = $(mooutils)/glade
moo_extra_dist += \
$(mooutils_glade)/shortcutdialog.glade \
$(mooutils_glade)/shortcutsprefs.glade \
$(mooutils_glade)/toolbar.sh \
$(mooutils_glade)/support.sh
$(mooutils_glade)/moologwindow.glade

View File

@ -0,0 +1,55 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="window">
<property name="title" translatable="yes">Log</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">400</property>
<property name="default_height">300</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_CHAR</property>
<property name="cursor_visible">False</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
</widget>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,49 +0,0 @@
if [ ! -z $1 ]; then
if [ ! -e $1 ]; then
echo $0: error, file $1 doesn\'t exist
exit 1
fi
fi
macros () {
cat <<EOF
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# define Q_(String) g_strip_context ((String), gettext (String))
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define Q_(String) g_strip_context ((String), (String))
# define N_(String) (String)
#endif
EOF
}
macros
cat $1 | sed -e 's/#include "support.h"//' | \
sed -e ':a' -e '$!N;s/\/\*\n \* DO NOT EDIT THIS FILE - it is generated by Glade\./DONOTEDITTHISFILE/;ta' -e 'P;D' | \
sed -e ':a' -e '$!N;s/DONOTEDITTHISFILE\n \*\///;ta' -e 'P;D' | \
sed -e 's/#ifdef HAVE_CONFIG_H//' | \
sed -e ':a' -e '$!N;s/# include <config.h>\n#endif//;ta' -e 'P;D' | \
sed -e ':a' -e '$!N;s/,\n[ \t]*\(.*$\)/, \1/;ta' -e 'P;D' | \
sed '/./,/^$/!d'

View File

@ -1,91 +0,0 @@
if [ ! -z $1 ]; then
if [ ! -e $1 ]; then
echo $0: error, file $1 doesn\'t exist
exit 1
fi
fi
macros () {
cat <<EOF
#include <gtk/gtk.h>
#if GTK_MINOR_VERSION >= 4
#define NEW_TOOLBAR_SEPARATOR(sep,toolbar) \\
sep = (GtkWidget*) gtk_separator_tool_item_new (); \\
gtk_widget_show (sep); \\
gtk_container_add (GTK_CONTAINER (toolbar), sep);
#define NEW_TOOLBAR_SEPARATOR_HIDDEN(sep,toolbar) \\
sep = (GtkWidget*) gtk_separator_tool_item_new (); \\
gtk_container_add (GTK_CONTAINER (toolbar), sep);
#define NEW_TOOL_ITEM_WITH_TOOLTIP(btn,img,label,toolbar,tip) \\
NEW_TOOL_ITEM(btn,img,label,toolbar) \\
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (btn), tooltips, _(tip), NULL);
#define NEW_TOOL_ITEM(btn,img,label,toolbar) \\
btn = (GtkWidget*) gtk_tool_button_new (img, _(label)); \\
gtk_widget_show (btn); \\
gtk_container_add (GTK_CONTAINER (toolbar), btn); \\
#define NEW_TOOL_ITEM_HIDDEN(btn,img,label,toolbar) \\
btn = (GtkWidget*) gtk_tool_button_new (img, _(label)); \\
gtk_container_add (GTK_CONTAINER (toolbar), btn); \\
#define NEW_TOOL_ITEM_HIDDEN_WITH_TOOLTIP(btn,img,label,toolbar,tip) \\
btn = (GtkWidget*) gtk_tool_button_new (img, _(label)); \\
gtk_container_add (GTK_CONTAINER (toolbar), btn); \\
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (btn), tooltips, _(tip), NULL);
#else /* GTK_MINOR_VERSION < 4 */
#define NEW_TOOLBAR_SEPARATOR(sep,toolbar) \\
sep = NULL; \\
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
#define NEW_TOOLBAR_SEPARATOR_HIDDEN(sep,toolbar) \\
sep = NULL;
#define NEW_TOOL_ITEM_WITH_TOOLTIP(btn,img,label,toolbar,tip) \\
btn = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), label, \\
tip, tip, img, NULL, NULL);
#define NEW_TOOL_ITEM_HIDDEN_WITH_TOOLTIP(btn,img,label,toolbar,tip) \\
btn = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), label, \\
tip, tip, img, NULL, NULL); \\
gtk_widget_hide (btn);
#define NEW_TOOL_ITEM(btn,img,label,toolbar) \\
btn = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), label, \\
NULL, NULL, img, NULL, NULL);
#define NEW_TOOL_ITEM_HIDDEN(btn,img,label,toolbar) \\
btn = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), label, \\
NULL, NULL, img, NULL, NULL); \\
gtk_widget_hide (btn);
#endif /* GTK_MINOR_VERSION < 4 */
EOF
}
replace () {
sed -e :a -e '$!N;s/\([a-zA-Z0-9_]*\) = (GtkWidget\*) gtk_separator_tool_item_new ();\n gtk_widget_show ([a-zA-Z0-9_]*);/TOOL_SEPARATOR \1/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/TOOL_SEPARATOR \([a-zA-Z0-9_]*\)\n gtk_container_add (GTK_CONTAINER (\([a-zA-Z0-9_]*\)), [a-zA-Z0-9_]*);/NEW_TOOLBAR_SEPARATOR (\1, \2)/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/\([a-zA-Z0-9_]*\) = (GtkWidget\*) gtk_separator_tool_item_new ();\n gtk_container_add (GTK_CONTAINER (\([a-zA-Z0-9_]*\)), [a-zA-Z0-9_]*);/NEW_TOOLBAR_SEPARATOR_HIDDEN (\1, \2)/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/\([a-zA-Z0-9_]*\) = (GtkWidget\*) gtk_tool_button_new (\([a-zA-Z0-9_]*\), _("\([a-zA-Z0-9_ +,.-]*\)"));\n gtk_widget_show ([a-zA-Z0-9_]*);/TOOL_ITEM \1 \2 "\3"/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/TOOL_ITEM \([a-zA-Z0-9_]*\) \([a-zA-Z0-9_]*\) "\([a-zA-Z0-9 _+,.-]*\)"\n gtk_container_add (GTK_CONTAINER (\([a-zA-Z0-9_]*\)), [a-zA-Z0-9_]*);/NEW_TOOL_ITEM (\1, \2, "\3", \4)/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/NEW_TOOL_ITEM (\([a-zA-Z0-9_]*\), \([a-zA-Z0-9_]*\), "\([a-zA-Z0-9 _+,.-]*\)", \([a-zA-Z0-9_]*\))\n gtk_tool_item_set_tooltip (GTK_TOOL_ITEM ([a-zA-Z0-9_]*), tooltips, _("\([a-zA-Z0-9 _+,.-]*\)"), NULL);/NEW_TOOL_ITEM_WITH_TOOLTIP (\1, \2, "\3", \4, "\5")/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/\([a-zA-Z0-9_]*\) = (GtkWidget\*) gtk_tool_button_new (\([a-zA-Z0-9_]*\), _("\([+,.a-zA-Z0-9 _-]*\)"));\n gtk_container_add (GTK_CONTAINER (\([a-zA-Z0-9_]*\)), [a-zA-Z0-9_]*);/NEW_TOOL_ITEM_HIDDEN (\1, \2, "\3", \4)/;ta' -e 'P;D' | \
sed -e :a -e '$!N;s/NEW_TOOL_ITEM_HIDDEN (\([a-zA-Z0-9_]*\), \([a-zA-Z0-9_]*\), "\([,.+a-zA-Z0-9 _-]*\)", \([a-zA-Z0-9_]*\))\n gtk_tool_item_set_tooltip (GTK_TOOL_ITEM ([a-zA-Z0-9_]*), tooltips, _("\([.,+a-zA-Z0-9_ -]*\)"), NULL);/NEW_TOOL_ITEM_HIDDEN_WITH_TOOLTIP (\1, \2, "\3", \4, "\5")/;ta' -e 'P;D'
}
if [ -z $1 ]; then
macros
replace
else
macros
cat $1 | replace
fi

View File

@ -149,7 +149,9 @@ ms_context_finalize (GObject *object)
{
MSContext *ctx = MS_CONTEXT (object);
moo_Py_DECREF (ctx->py_dict);
if (moo_python_running ())
moo_Py_DECREF (ctx->py_dict);
g_hash_table_destroy (ctx->vars);
g_free (ctx->error_msg);
@ -545,6 +547,7 @@ ms_context_assign_py_var (MSContext *ctx,
g_return_if_fail (var != NULL);
g_return_if_fail (obj != NULL);
g_return_if_fail (ctx->py_dict != NULL);
g_return_if_fail (moo_python_running ());
moo_py_dict_set_item (ctx->py_dict, var, obj);
}

View File

@ -16,6 +16,8 @@
#endif
#include "mooutils/mooutils-misc.h"
#include "mooutils/moologwindow-glade.h"
#include "mooutils/mooglade.h"
#include <gtk/gtk.h>
#include <unistd.h>
#include <string.h>
@ -786,7 +788,7 @@ moo_get_toplevel_window (void)
/***************************************************************************/
/* Custom log handlers
/* Log window
*/
typedef struct {
@ -807,42 +809,22 @@ static GtkWidget *moo_log_window_get_widget (void);
static MooLogWindow*
moo_log_window_new (void)
{
MooGladeXML *xml;
MooLogWindow *log;
GtkWidget *vbox, *scrolledwindow;
PangoFontDescription *font;
xml = moo_glade_xml_new_from_buf (MOO_LOG_WINDOW_GLADE_UI, -1, NULL, NULL);
log = g_new (MooLogWindow, 1);
log->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (log->window), "Log Window");
gtk_window_set_default_size (GTK_WINDOW (log->window), 400, 300);
vbox = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (log->window), vbox);
scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow);
gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0);
GTK_WIDGET_UNSET_FLAGS (scrolledwindow, GTK_CAN_FOCUS);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_SHADOW_ETCHED_IN);
log->textview = GTK_TEXT_VIEW (gtk_text_view_new ());
gtk_widget_show (GTK_WIDGET (log->textview));
gtk_container_add (GTK_CONTAINER (scrolledwindow), GTK_WIDGET (log->textview));
GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (log->textview), GTK_CAN_FOCUS);
gtk_text_view_set_editable (log->textview, FALSE);
gtk_text_view_set_wrap_mode (log->textview, GTK_WRAP_WORD);
log->window = moo_glade_xml_get_widget (xml, "window");
log->textview = moo_glade_xml_get_widget (xml, "textview");
g_signal_connect (log->window, "delete-event",
G_CALLBACK (gtk_widget_hide_on_delete), NULL);
log->buf = gtk_text_view_get_buffer (log->textview);
log->insert = gtk_text_buffer_get_insert (log->buf);
log->message_tag =
gtk_text_buffer_create_tag (log->buf, "message", "foreground", "blue", NULL);
log->warning_tag =
@ -851,7 +833,7 @@ moo_log_window_new (void)
gtk_text_buffer_create_tag (log->buf, "critical", "foreground", "red",
"weight", PANGO_WEIGHT_BOLD, NULL);
font = pango_font_description_from_string ("Courier New 9");
font = pango_font_description_from_string ("Monospace");
if (font)
{
@ -863,47 +845,17 @@ moo_log_window_new (void)
}
void
moo_log_window_write (const gchar *log_domain,
GLogLevelFlags flags,
const gchar *message)
{
char *text;
GtkTextTag *tag = NULL;
GtkTextIter end;
MooLogWindow *log = moo_log_window ();
#ifdef __WIN32__
if (flags & (G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION))
{
moo_show_fatal_error (log_domain, message);
return;
}
#endif /* __WIN32__ */
if (log_domain)
text = g_strdup_printf ("%s: %s\n", log_domain, message);
else
text = g_strdup_printf ("%s\n", message);
if (flags >= G_LOG_LEVEL_MESSAGE)
tag = log->message_tag;
else if (flags >= G_LOG_LEVEL_WARNING)
tag = log->warning_tag;
else
tag = log->critical_tag;
gtk_text_buffer_get_end_iter (log->buf, &end);
gtk_text_buffer_insert_with_tags (log->buf, &end, text, -1, tag, NULL);
gtk_text_view_scroll_mark_onscreen (log->textview, log->insert);
}
static MooLogWindow*
moo_log_window (void)
{
static MooLogWindow *log = NULL;
if (!log) log = moo_log_window_new ();
if (!log)
{
log = moo_log_window_new ();
g_object_add_weak_pointer (G_OBJECT (log->window), (gpointer*) &log);
}
return log;
}
@ -929,71 +881,203 @@ moo_log_window_hide (void)
}
/****************************************************************************/
static void
moo_log_window_insert (MooLogWindow *log,
const char *text,
GtkTextTag *tag)
{
GtkTextIter iter;
gtk_text_buffer_get_end_iter (log->buf, &iter);
gtk_text_buffer_insert_with_tags (log->buf, &iter, text, -1, tag, NULL);
gtk_text_view_scroll_mark_onscreen (log->textview, log->insert);
}
/******************************************************************************/
/* Custom g_log and g_print handlers
*/
static GLogFunc moo_log_func;
static GPrintFunc moo_print_func;
static GPrintFunc moo_printerr_func;
static char *moo_log_file;
static gboolean moo_log_file_written;
static gboolean moo_log_handlers_set;
static void
set_print_funcs (GLogFunc log_func,
GPrintFunc print_func,
GPrintFunc printerr_func)
{
moo_log_func = log_func;
moo_print_func = print_func;
moo_printerr_func = printerr_func;
moo_log_handlers_set = TRUE;
g_set_print_handler (print_func);
g_set_printerr_handler (printerr_func);
g_log_set_handler ("Glib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("Glib-GObject", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("GModule", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("GThread", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("Gtk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("Gdk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("Gdk-Pixbuf-CSource", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("GdkPixbuf", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("Pango", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler ("Moo", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL);
#if GLIB_CHECK_VERSION(2,6,0)
g_log_set_default_handler (log_func, NULL);
#endif /* GLIB_CHECK_VERSION(2,6,0) */
}
void
moo_reset_log_func (void)
{
if (moo_log_handlers_set)
set_print_funcs (moo_log_func, moo_print_func, moo_printerr_func);
}
void
moo_print (const char *string)
{
g_print ("%s", string);
}
void
moo_print_err (const char *string)
{
g_printerr ("%s", string);
}
/*
* Win32 message box for fatal errors
*/
#ifdef __WIN32__
#define PLEASE_REPORT \
"Please report it to emuntyan@sourceforge.net and provide "\
"steps needed to reproduce this error."
#ifdef __WIN32__
void
moo_show_fatal_error (const char *logdomain, const char *logmsg)
static void
show_fatal_error_win32 (const char *domain,
const char *logmsg)
{
char *msg = NULL;
if (logdomain)
if (domain)
msg = g_strdup_printf ("Fatal GGAP error:\n---\n%s: %s\n---\n"
PLEASE_REPORT, logdomain, logmsg);
PLEASE_REPORT, domain, logmsg);
else
msg = g_strdup_printf ("Fatal GGAP error:\n---\n%s\n---\n"
PLEASE_REPORT, logmsg);
MessageBox (NULL, msg, "Error", MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
MessageBox (NULL, msg, "Error",
MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
g_free (msg);
}
#endif /* __WIN32__ */
static void
log_func_file (const char *log_domain,
G_GNUC_UNUSED GLogLevelFlags flags,
const char *message,
gpointer filename)
{
static gboolean firsttime = TRUE;
static char *name = NULL;
FILE *logfile;
/*
* Display log messages in a window
*/
g_return_if_fail (filename != NULL);
static void
log_func_window (const gchar *log_domain,
GLogLevelFlags flags,
const gchar *message,
G_GNUC_UNUSED gpointer dummy)
{
char *text;
GtkTextTag *tag;
MooLogWindow *log;
#ifdef __WIN32__
if (flags & (G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION))
{
moo_show_fatal_error (log_domain, message);
show_fatal_error_win32 (log_domain, message);
return;
}
#endif /* __WIN32__ */
if (firsttime)
if (log_domain)
text = g_strdup_printf ("%s: %s\n", log_domain, message);
else
text = g_strdup_printf ("%s\n", message);
log = moo_log_window ();
if (flags >= G_LOG_LEVEL_MESSAGE)
tag = log->message_tag;
else if (flags >= G_LOG_LEVEL_WARNING)
tag = log->warning_tag;
else
tag = log->critical_tag;
moo_log_window_insert (log, text, tag);
g_free (text);
}
static void
print_func_window (const char *string)
{
MooLogWindow *log = moo_log_window ();
moo_log_window_insert (log, string, NULL);
}
static void
printerr_func_window (const char *string)
{
MooLogWindow *log = moo_log_window ();
moo_log_window_insert (log, string, log->warning_tag);
}
void
moo_set_log_func_window (gboolean show_now)
{
if (show_now)
gtk_widget_show (GTK_WIDGET (moo_log_window()->window));
set_print_funcs (log_func_window, print_func_window, printerr_func_window);
}
/*
* Write to a file
*/
static void
print_func_file (const char *string)
{
FILE *file;
g_return_if_fail (moo_log_file != NULL);
if (!moo_log_file_written)
{
name = g_strdup ((char*)filename);
logfile = fopen (name, "w+");
firsttime = FALSE;
file = fopen (moo_log_file, "w+");
moo_log_file_written = TRUE;
}
else
{
logfile = fopen (name, "a+");
file = fopen (moo_log_file, "a+");
}
if (logfile)
if (file)
{
if (log_domain)
fprintf (logfile, "%s: %s\r\n", log_domain, message);
else
fprintf (logfile, "%s\r\n", message);
fclose (logfile);
fprintf (file, "%s", string);
fclose (file);
}
else
{
@ -1002,6 +1086,51 @@ log_func_file (const char *log_domain,
}
static void
log_func_file (const char *log_domain,
G_GNUC_UNUSED GLogLevelFlags flags,
const char *message,
G_GNUC_UNUSED gpointer dummy)
{
char *string;
#ifdef __WIN32__
if (flags & (G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION))
{
show_fatal_error_win32 (log_domain, message);
return;
}
#endif /* __WIN32__ */
#ifdef __WIN32__
#define LT "\r\n"
#else
#define LT "\n"
#endif
if (log_domain)
string = g_strdup_printf ("%s: %s" LT, log_domain, message);
else
string = g_strdup_printf ("%s" LT, message);
#undef LT
print_func_file (string);
g_free (string);
}
void
moo_set_log_func_file (const char *log_file)
{
g_free (moo_log_file);
moo_log_file = g_strdup (log_file);
set_print_funcs (log_func_file, print_func_file, print_func_file);
}
/*
* Do nothing
*/
static void
log_func_silent (G_GNUC_UNUSED const gchar *log_domain,
G_GNUC_UNUSED GLogLevelFlags flags,
@ -1011,72 +1140,30 @@ log_func_silent (G_GNUC_UNUSED const gchar *log_domain,
#ifdef __WIN32__
if (flags & (G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION))
{
moo_show_fatal_error (log_domain, message);
show_fatal_error_win32 (log_domain, message);
return;
}
#endif /* __WIN32__ */
}
typedef void (*LogFunc) (const gchar *log_domain,
GLogLevelFlags flags,
const gchar *message,
gpointer data);
static void
set_handler (LogFunc func, gpointer data)
print_func_silent (G_GNUC_UNUSED const char *s)
{
#if !GLIB_CHECK_VERSION(2,6,0)
g_log_set_handler ("Glib",
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
func, data);
g_log_set_handler ("Gtk",
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
func, data);
g_log_set_handler ("Pango",
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
func, data);
g_log_set_handler ("Moo",
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
func, data);
g_log_set_handler (NULL,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
func, data);
#else /* GLIB_CHECK_VERSION(2,6,0) */
g_log_set_default_handler (func, data);
#endif /* GLIB_CHECK_VERSION(2,6,0) */
}
void
moo_set_log_func_window (int show)
{
if (show)
moo_log_window_show ();
set_handler ((LogFunc)moo_log_window_write, NULL);
}
void
moo_set_log_func_file (const char *log_file)
{
g_return_if_fail (log_file != NULL);
set_handler (log_func_file, (char*)log_file);
}
void
moo_set_log_func (int show_log)
moo_set_log_func_silent (void)
{
if (!show_log)
set_handler (log_func_silent, NULL);
#ifdef __WIN32__
else
moo_set_log_func_window (FALSE);
#endif /* __WIN32__ */
set_print_funcs ((GLogFunc) log_func_silent,
(GPrintFunc) print_func_silent,
(GPrintFunc) print_func_silent);
}
/***************************************************************************/
/* Very useful function
*/
void
moo_segfault (void)
{
@ -1085,6 +1172,10 @@ moo_segfault (void)
}
/***************************************************************************/
/* GtkSelection helpers
*/
void
moo_selection_data_set_pointer (GtkSelectionData *data,
GdkAtom type,
@ -1112,6 +1203,10 @@ moo_selection_data_get_pointer (GtkSelectionData *data,
}
/***************************************************************************/
/* Get currently pressed modifier keys
*/
GdkModifierType
moo_get_modifiers (GtkWidget *widget)
{
@ -1130,6 +1225,10 @@ moo_get_modifiers (GtkWidget *widget)
}
/***************************************************************************/
/* GtkAccelLabel helpers
*/
void
moo_menu_item_set_accel_label (GtkWidget *menu_item,
const char *label)

View File

@ -46,18 +46,13 @@ gboolean moo_window_set_icon_from_stock (GtkWindow *window,
void moo_log_window_show (void);
void moo_log_window_hide (void);
void moo_log_window_write (const char *log_domain,
GLogLevelFlags flags,
const char *message);
void moo_print (const char *string);
void moo_print_err (const char *string);
void moo_set_log_func_window (gboolean show);
void moo_set_log_func_window (gboolean show_now);
void moo_set_log_func_file (const char *log_file);
void moo_set_log_func (gboolean show_log);
#ifdef __WIN32__
void moo_show_fatal_error (const char *logdomain,
const char *logmsg);
#endif /* __WIN32__ */
void moo_set_log_func_silent (void);
void moo_reset_log_func (void);
void moo_segfault (void);

View File

@ -75,10 +75,8 @@ int _medit_parse_options (const char *const program_name,
/* Set to 1 if option --new-app (-n) has been specified. */
char _medit_opt_new_app;
#ifdef __WIN32__
/* Set to 1 if option --log (-l) has been specified. */
char _medit_opt_log;
#endif
/* Set to 1 if option --version has been specified. */
char _medit_opt_version;
@ -86,10 +84,8 @@ char _medit_opt_version;
/* Set to 1 if option --help (-h) has been specified. */
char _medit_opt_help;
#ifdef __WIN32__
/* Argument to option --log (-l), or a null pointer if no argument. */
const char *_medit_arg_log;
#endif
/* Parse command line options. Return index of first non-option argument,
or -1 if an error is encountered. */
@ -100,14 +96,10 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
static const char *const optstr__help = "help";
int i = 0;
_medit_opt_new_app = 0;
#ifdef __WIN32__
_medit_opt_log = 0;
#endif
_medit_opt_version = 0;
_medit_opt_help = 0;
#ifdef __WIN32__
_medit_arg_log = 0;
#endif
while (++i < argc)
{
const char *option = argv [i];
@ -143,14 +135,12 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
}
goto error_unknown_long_opt;
case 'l':
#ifdef __WIN32__
if (strncmp (option + 1, "og", option_len - 1) == 0)
{
_medit_arg_log = argument;
_medit_opt_log = 1;
break;
}
#endif
goto error_unknown_long_opt;
case 'n':
if (strncmp (option + 1, optstr__new_app + 1, option_len - 1) == 0)
@ -192,7 +182,6 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
case 'h':
_medit_opt_help = 1;
return i + 1;
#ifdef __WIN32__
case 'l':
if (option [1] != '\0')
{
@ -203,7 +192,6 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
_medit_arg_log = 0;
_medit_opt_log = 1;
break;
#endif
case 'n':
_medit_opt_new_app = 1;
break;
@ -225,9 +213,7 @@ static void usage (void)
g_print ("Options:\n");
g_print ("%s", STR_HELP_NEW_APP);
#ifdef __WIN32__
g_print ("%s", STR_HELP_LOG);
#endif
g_print ("%s", STR_HELP_VERSION);
g_print ("%s", STR_HELP_HELP);
}
@ -266,7 +252,6 @@ int main (int argc, char *argv[])
return 0;
}
#ifdef __WIN32__
if (_medit_opt_log)
{
if (_medit_arg_log)
@ -274,7 +259,6 @@ int main (int argc, char *argv[])
else
moo_set_log_func_window (TRUE);
}
#endif
app = g_object_new (MOO_TYPE_APP,
"argv", argv,

View File

@ -31,9 +31,7 @@ int _medit_parse_options (const char *const program_name,
*/
%%
n new-app "Run new instance of application"
#ifdef __WIN32__
l log "[=FILE] Show debug output or write it to FILE" optarg
#endif
version "Display version information and exit" return
h help "Display this help text and exit" return
%%
@ -47,9 +45,7 @@ static void usage (void)
g_print ("Options:\n");
g_print ("%s", STR_HELP_NEW_APP);
#ifdef __WIN32__
g_print ("%s", STR_HELP_LOG);
#endif
g_print ("%s", STR_HELP_VERSION);
g_print ("%s", STR_HELP_HELP);
}
@ -88,7 +84,6 @@ int main (int argc, char *argv[])
return 0;
}
#ifdef __WIN32__
if (_medit_opt_log)
{
if (_medit_arg_log)
@ -96,7 +91,6 @@ int main (int argc, char *argv[])
else
moo_set_log_func_window (TRUE);
}
#endif
app = g_object_new (MOO_TYPE_APP,
"argv", argv,
@ -105,10 +99,9 @@ int main (int argc, char *argv[])
"description", "medit is a text editor",
"open-files", argv + opt_remain,
"new-app", (gboolean) _medit_opt_new_app,
"default-ui", MEDIT_UI,
NULL);
moo_app_set_default_ui (app, MEDIT_UI);
if (!moo_app_init (app))
return 0;