From: <ro...@us...> - 2006-06-17 02:11:38
|
Revision: 16272 Author: roast Date: 2006-06-16 19:11:13 -0700 (Fri, 16 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16272&view=rev Log Message: ----------- merged with svn trunk, r16271 Modified Paths: -------------- branches/soc-2006-file-loggers/Makefile.mingw branches/soc-2006-file-loggers/config.h.mingw branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/gaim-installer.nsi branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO branches/soc-2006-file-loggers/plugins/tcl/Makefile.am branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw branches/soc-2006-file-loggers/plugins/tcl/tcl.c branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c branches/soc-2006-file-loggers/src/Makefile.am branches/soc-2006-file-loggers/src/Makefile.mingw branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/gtkdialogs.c branches/soc-2006-file-loggers/src/gtkutils.h branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.am branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/jabber/auth.c branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c branches/soc-2006-file-loggers/src/protocols/jabber/chat.c branches/soc-2006-file-loggers/src/protocols/jabber/disco.c branches/soc-2006-file-loggers/src/protocols/jabber/iq.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h branches/soc-2006-file-loggers/src/protocols/jabber/message.c branches/soc-2006-file-loggers/src/protocols/jabber/oob.c branches/soc-2006-file-loggers/src/protocols/jabber/parser.c branches/soc-2006-file-loggers/src/protocols/jabber/presence.c branches/soc-2006-file-loggers/src/protocols/jabber/roster.c branches/soc-2006-file-loggers/src/protocols/jabber/si.c branches/soc-2006-file-loggers/src/protocols/jabber/xdata.c branches/soc-2006-file-loggers/src/protocols/msn/userlist.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c branches/soc-2006-file-loggers/src/xmlnode.c branches/soc-2006-file-loggers/src/xmlnode.h Modified: branches/soc-2006-file-loggers/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272) @@ -12,6 +12,7 @@ GAIM_SOUNDS = ./sounds GAIM_INSTALL_DIR = ./win32-install-dir GTKSPELL_TOP = ../win32-dev/gtkspell-2.0.6/gtkspell +LIBXML2_DIR = ../win32-dev/libxml2 IDLETRACK_TOP = $(GAIM_SRC)/win32/IdleTracker GTKRC_TOP = ../win32-dev/gtkrc OSCAR = $(GAIM_PROTOS)/oscar @@ -33,7 +34,8 @@ VERSION := $(shell cat ./VERSION) NEEDED_DLLS = $(GTKSPELL_TOP)/libgtkspell.dll \ - $(IDLETRACK_TOP)/idletrack.dll + $(IDLETRACK_TOP)/idletrack.dll \ + $(LIBXML2_DIR)/bin/libxml2.dll SOUNDS = $(GAIM_SOUNDS)/alert.wav \ $(GAIM_SOUNDS)/login.wav \ Modified: branches/soc-2006-file-loggers/config.h.mingw =================================================================== --- branches/soc-2006-file-loggers/config.h.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/config.h.mingw 2006-06-17 02:11:13 UTC (rev 16272) @@ -635,6 +635,8 @@ <inttypes.h> don't define. */ /* #undef uintmax_t */ +#define HAVE_LIBXML 1 + /* * Following are added for Win32 version of Gaim */ Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/configure.ac 2006-06-17 02:11:13 UTC (rev 16272) @@ -171,6 +171,18 @@ AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for making sounds]) fi +dnl ################# +dnl # LibXML2 +dnl ################# +enable_libxml2=yes +PKG_CHECK_MODULES(LIBXML, libxml-2.0, ,enable_libxml2=no) +AC_SUBST(LIBXML_CFLAGS) +AC_SUBST(LIBXML_LIBS) +AC_ARG_ENABLE(libxml,[ --disable-libxml compile without libxml2 support],enable_libxml2=no) +if test "x$enable_libxml2" = "xyes"; then + AC_DEFINE(HAVE_LIBXML, 1, [Use libxml2 for xml parsing]) +fi + dnl ####################################################################### dnl # Check for Meanwhile headers (for Sametime) dnl ####################################################################### @@ -306,8 +318,8 @@ dnl ####################################################################### dnl # Check for Gadu-Gadu client includes and libraries dnl ####################################################################### -AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the GaduGadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"]) -AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the GaduGadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"]) +AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the Gadu-Gadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"]) +AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the Gadu-Gadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"]) GADU_CFLAGS="" GADU_LIBS="" if test -n "$with_gadu_includes" || test -n "$with_gadu_libs"; then @@ -1060,7 +1072,7 @@ dnl These two are inverses of each other <-- stolen from evolution! AC_ARG_ENABLE(gnutls, - [ --enable-gnutls=[yes,no] attempt to use GNUTLS for SSL support (preferred) [default=yes]], + [ --enable-gnutls=[yes,no] attempt to use GnuTLS for SSL support (preferred) [default=yes]], [enable_gnutls="$enableval"], [enable_gnutls="yes"]) @@ -1072,14 +1084,14 @@ msg_ssl="None (MSN will not work without SSL!)" dnl # -dnl # Check for GNUTLS if it's specified. +dnl # Check for GnuTLS if it's specified. dnl # if test "x$enable_gnutls" != "xno"; then enable_gnutls="no" prefix=`eval echo $prefix` AC_ARG_WITH(gnutls-includes, - [ --with-gnutls-includes=PREFIX location of GNUTLS includes.], + [ --with-gnutls-includes=PREFIX location of GnuTLS includes.], [ with_gnutls_includes="$withval" ], [ with_gnutls_includes="$prefix/include" ]) @@ -1088,7 +1100,7 @@ if test "x$with_gnutls_includes" != "xno"; then CPPFLAGS_save="$CPPFLAGS" - AC_MSG_CHECKING(for GNUTLS includes) + AC_MSG_CHECKING(for GnuTLS includes) AC_MSG_RESULT("") CPPFLAGS="$CPPFLAGS -I$with_gnutls_includes" @@ -1104,12 +1116,12 @@ GNUTLS_CFLAGS="" fi else - AC_MSG_CHECKING(for GNUTLS includes) + AC_MSG_CHECKING(for GnuTLS includes) AC_MSG_RESULT(no) fi AC_ARG_WITH(gnutls-libs, - [ --with-gnutls-libs=PREFIX location of GNUTLS libraries.], + [ --with-gnutls-libs=PREFIX location of GnuTLS libraries.], [ with_gnutls_libs="$withval" ]) if test "x$with_gnutls_libs" != "xno" -a \ @@ -1122,7 +1134,7 @@ *) with_gnutls_libs="-L$with_gnutls_libs" ;; esac - AC_CACHE_CHECK([for GNUTLS libraries], gnutls_libs, + AC_CACHE_CHECK([for GnuTLS libraries], gnutls_libs, [ LDFLAGS="$LDFLAGS $with_gnutls_libs -lgnutls -lgcrypt" AC_TRY_LINK_FUNC(gnutls_init, gnutls_libs="yes", gnutls_libs="no") @@ -1130,9 +1142,9 @@ ]) if test "x$gnutls_libs" != "xno"; then - AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GNUTLS]) + AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS]) AC_DEFINE(HAVE_SSL) - msg_gnutls="GNUTLS" + msg_gnutls="GnuTLS" GNUTLS_LIBS="$with_gnutls_libs -lgnutls -lgcrypt" enable_gnutls="yes" @@ -1141,7 +1153,7 @@ GNUTLS_LIBS="" fi else - AC_MSG_CHECKING(for GNUTLS libraries) + AC_MSG_CHECKING(for GnuTLS libraries) AC_MSG_RESULT(no) fi else @@ -1156,7 +1168,7 @@ dnl # -dnl # Check for NSS if it's specified, or if GNUTLS checks failed. +dnl # Check for NSS if it's specified, or if GnuTLS checks failed. dnl # if test "x$enable_nss" != "xno"; then @@ -1785,6 +1797,7 @@ eval echo DBUS servies directory........ : $DBUS_SERVICES_DIR fi echo Build with Cyrus SASL support. : $enable_cyrus_sasl +echo Build with libxml2 support.... : $enable_libxml2 echo Has you....................... : yes echo echo Modified: branches/soc-2006-file-loggers/gaim-installer.nsi =================================================================== --- branches/soc-2006-file-loggers/gaim-installer.nsi 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/gaim-installer.nsi 2006-06-17 02:11:13 UTC (rev 16272) @@ -744,6 +744,7 @@ Delete "$INSTDIR\idletrack.dll" Delete "$INSTDIR\libgtkspell.dll" Delete "$INSTDIR\libmeanwhile-1.dll" + Delete "$INSTDIR\libxml2.dll" Delete "$INSTDIR\nspr4.dll" Delete "$INSTDIR\nss3.dll" Delete "$INSTDIR\nssckbi.dll" Modified: branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO =================================================================== --- branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO 2006-06-17 02:11:13 UTC (rev 16272) @@ -4,10 +4,8 @@ Version 0.60 of Gaim brings up all themable smileys. In the preferences dialog, a user can choose from a selection of looks his smileys will take. This guide is to serve as a reference to those interested in creating third-party smiley themes. -(SME: I'm doing this at 6:30AM; I'm tired, but I can't sleep. Someone make sure I fix this up to make sure it all makes sense when I'm not tired anymore. Right now it's mostly just unassembled thoughts) +Your theme should be contained in a single directory. This directory will be installed in the Gaim smiley theme directory ($HOME/.gaim/smileys/). This directory will contain a file called `theme' that specifies the theme metadata and image files that are used by the theme. The format of the `theme' file is as follows. -Your theme should be contained in a single directory. This directory will be installed in the Gaim smiley theme directory (SME: There should probably be a $HOME/.gaim/smileys/ that the theme could go in too.). This directory will contain a file called `theme' that specifies the theme and image (SME: And possibly sound) files that are used by the theme. The format of the `theme' file is as follows. - The beginning of the file contains some metainformation about the theme in the format Key=Value @@ -19,10 +17,16 @@ Author - The author's name Following this meta-information are "sml" groups. A "sml" group is a group of smileys that will be shown together. For example, each protocol has its own "sml" group (MSN, Yahoo, Gadu-Gadu, etc.). The name of the group is surrounded in square brackets, and each line beneath it (until the next sml group or the end of the file) defines a smiley. -Each line of the group starts with a filename of the icon (SME: Or sound?) followed by a space-delimited list of the characters that represent it. +Each line of the group starts with a filename of the icon followed by a space-delimited list of the characters that represent it. Example: [AIM/ICQ] smiley.png :) :-) In the smiley selector UI, each icon will only be shown once, and the first string representing it will be used. To keep a smiley out of the selector altogether, make the first two characters of the line "! " followed by the filename and emoticons. + +As of 2.0.0beta2, spaces and backslashes in the "list of characters" (see above) must be escaped by prepending them with a backslash. For example, to define a smiley that is represented by ":-/" and ":-\", use: + +[AIM/ICQ] +think.png :-/ :-\\ + Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272) @@ -4,7 +4,8 @@ plugin_LTLIBRARIES = tcl.la -tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h +tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h \ + tcl_ref.c EXTRA_DIST = signal-test.tcl Makefile.mingw Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272) @@ -63,6 +63,7 @@ C_SRC = tcl.c \ tcl_cmds.c \ tcl_glib.c \ + tcl_ref.c \ tcl_signals.c Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -50,6 +50,15 @@ Tcl_Interp *interp; }; +GaimStringref *GaimTclRefAccount; +GaimStringref *GaimTclRefConnection; +GaimStringref *GaimTclRefConversation; +GaimStringref *GaimTclRefPointer; +GaimStringref *GaimTclRefPresence; +GaimStringref *GaimTclRefStatus; +GaimStringref *GaimTclRefStatusAttr; +GaimStringref *GaimTclRefStatusType; + static GHashTable *tcl_plugins = NULL; GaimPlugin *_tcl_plugin; @@ -123,8 +132,12 @@ Tcl_CreateObjCommand(interp, "::gaim::debug", tcl_cmd_debug, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::notify", tcl_cmd_notify, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::prefs", tcl_cmd_prefs, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::presence", tcl_cmd_presence, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::send_im", tcl_cmd_send_im, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::signal", tcl_cmd_signal, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_attr", tcl_cmd_status_attr, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_type", tcl_cmd_status_type, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::unload", tcl_cmd_unload, (ClientData)NULL, NULL); return 0; @@ -329,6 +342,17 @@ return FALSE; tcl_glib_init(); tcl_signal_init(); + gaim_tcl_ref_init(); + + GaimTclRefAccount = gaim_stringref_new("Account"); + GaimTclRefConnection = gaim_stringref_new("Connection"); + GaimTclRefConversation = gaim_stringref_new("Conversation"); + GaimTclRefPointer = gaim_stringref_new("Pointer"); + GaimTclRefPresence = gaim_stringref_new("Presence"); + GaimTclRefStatus = gaim_stringref_new("Status"); + GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); + GaimTclRefStatusType = gaim_stringref_new("StatusType"); + tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal); #ifdef HAVE_TK @@ -343,6 +367,15 @@ g_hash_table_destroy(tcl_plugins); tcl_plugins = NULL; + gaim_stringref_unref(GaimTclRefAccount); + gaim_stringref_unref(GaimTclRefConnection); + gaim_stringref_unref(GaimTclRefConversation); + gaim_stringref_unref(GaimTclRefPointer); + gaim_stringref_unref(GaimTclRefPresence); + gaim_stringref_unref(GaimTclRefStatus); + gaim_stringref_unref(GaimTclRefStatusAttr); + gaim_stringref_unref(GaimTclRefStatusType); + return TRUE; } Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -35,61 +35,91 @@ #include "tcl_gaim.h" -static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp); -static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp); -static gboolean tcl_validate_gc(GaimConnection *gc); +static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp); +static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp); +static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp); -static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp) +static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimAccount *account; GList *cur; + + account = gaim_tcl_ref_get(interp, obj, GaimTclRefAccount); + + if (account == NULL) + return NULL; + for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { if (account == cur->data) - return TRUE; + return account; } if (interp != NULL) Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); - return FALSE; + return NULL; } -static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp) +static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimConversation *convo; GList *cur; + convo = gaim_tcl_ref_get(interp, obj, GaimTclRefConversation); + + if (convo == NULL) + return NULL; + for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { if (convo == cur->data) - return TRUE; + return convo; } if (interp != NULL) Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); - return FALSE; + return NULL; } -static gboolean tcl_validate_gc(GaimConnection *gc) +static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimConnection *gc; GList *cur; + + gc = gaim_tcl_ref_get(interp, obj, GaimTclRefConnection); + + if (gc == NULL) + return NULL; + for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { if (gc == cur->data) - return TRUE; + return gc; } - return FALSE; + return NULL; } int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; - const char *cmds[] = { "alias", "connect", "connection", "disconnect", "find", - "handle", "isconnected", "list", - "protocol", "username", NULL }; - enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, - CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE, - CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, - CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd; + const char *cmds[] = { "alias", "connect", "connection", "disconnect", + "enabled", "find", "handle", "isconnected", + "list", "presence", "protocol", "status", + "status_type", "status_types", "username", + NULL }; + enum { CMD_ACCOUNT_ALIAS, + CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, + CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND, + CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, + CMD_ACCOUNT_PRESENCE, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS, + CMD_ACCOUNT_STATUS_TYPE, CMD_ACCOUNT_STATUS_TYPES, + CMD_ACCOUNT_USERNAME } cmd; const char *listopts[] = { "-all", "-online", NULL }; enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; const char *alias; - GList *cur; + const GList *cur; GaimAccount *account; + GaimStatus *status; + GaimStatusType *status_type; + GaimValue *value; + char *attr_id; int error; + int b, i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); @@ -105,8 +135,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; alias = gaim_account_get_alias(account); Tcl_SetStringObj(result, alias ? (char *)alias : "", -1); @@ -116,40 +145,61 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; if (!gaim_account_is_connected(account)) gaim_account_connect(account); - Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefConnection, + gaim_account_get_connection(account))); break; case CMD_ACCOUNT_CONNECTION: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; - Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefConnection, + gaim_account_get_connection(account))); break; case CMD_ACCOUNT_DISCONNECT: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; gaim_account_disconnect(account); break; + case CMD_ACCOUNT_ENABLED: + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetBooleanObj(result, + gaim_account_get_enabled(account, + gaim_core_get_ui())); + } else { + if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK) + return TCL_ERROR; + gaim_account_set_enabled(account, gaim_core_get_ui(), b); + } + break; case CMD_ACCOUNT_FIND: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); return TCL_ERROR; } - Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]), - Tcl_GetString(objv[3]))); + account = gaim_accounts_find(Tcl_GetString(objv[2]), + Tcl_GetString(objv[3])); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefAccount, account)); break; case CMD_ACCOUNT_HANDLE: if (objc != 2) { @@ -163,8 +213,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetBooleanObj(result, gaim_account_is_connected(account)); break; @@ -183,28 +232,140 @@ account = cur->data; if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account)) continue; - elem = Tcl_NewIntObj((int)account); + elem = gaim_tcl_ref_new(GaimTclRefAccount, account); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); break; + case CMD_ACCOUNT_PRESENCE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefPresence, + gaim_account_get_presence(account))); + break; case CMD_ACCOUNT_PROTOCOL: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1); break; + case CMD_ACCOUNT_STATUS: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?status_id name value ...?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_account_get_active_status(account))); + } else { + GList *l = NULL; + if (objc % 2) { + Tcl_SetStringObj(result, "name without value setting status", -1); + return TCL_ERROR; + } + status = gaim_account_get_status(account, Tcl_GetString(objv[3])); + if (status == NULL) { + Tcl_SetStringObj(result, "invalid status for account", -1); + return TCL_ERROR; + } + for (i = 4; i < objc; i += 2) { + attr_id = Tcl_GetString(objv[i]); + value = gaim_status_get_attr_value(status, attr_id); + if (value == NULL) { + Tcl_SetStringObj(result, "invalid attribute for account", -1); + return TCL_ERROR; + } + switch (gaim_value_get_type(value)) { + case GAIM_TYPE_BOOLEAN: + error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b); + if (error != TCL_OK) + return error; + l = g_list_append(l, attr_id); + l = g_list_append(l, GINT_TO_POINTER(b)); + break; + case GAIM_TYPE_INT: + error = Tcl_GetIntFromObj(interp, objv[i + 1], &b); + if (error != TCL_OK) + return error; + l = g_list_append(l, attr_id); + l = g_list_append(l, GINT_TO_POINTER(b)); + break; + case GAIM_TYPE_STRING: + l = g_list_append(l, attr_id); + l = g_list_append(l, Tcl_GetString(objv[i + 1])); + break; + default: + Tcl_SetStringObj(result, "unknown GaimValue type", -1); + return TCL_ERROR; + } + } + gaim_account_set_status_list(account, Tcl_GetString(objv[3]), TRUE, l); + g_list_free(l); + } + break; + case CMD_ACCOUNT_STATUS_TYPE: + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 4) { + status_type = gaim_account_get_status_type(account, + Tcl_GetString(objv[3])); + } else { + GaimStatusPrimitive primitive; + if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { + Tcl_SetStringObj(result, "bad option \"", -1); + Tcl_AppendObjToObj(result, objv[3]); + Tcl_AppendToObj(result, + "\": should be -primitive", -1); + return TCL_ERROR; + } + primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); + status_type = gaim_account_get_status_type_with_primitive(account, + primitive); + } + if (status_type == NULL) { + Tcl_SetStringObj(result, "status type not found", -1); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatusType, + status_type)); + break; + case CMD_ACCOUNT_STATUS_TYPES: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_account_get_status_types(account); cur != NULL; + cur = g_list_next(cur)) { + Tcl_ListObjAppendElement(interp, list, + gaim_tcl_ref_new(GaimTclRefStatusType, + cur->data)); + } + Tcl_SetObjResult(interp, list); + break; case CMD_ACCOUNT_USERNAME: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1); break; @@ -227,10 +388,8 @@ type = Tcl_GetString(elems[0]); name = Tcl_GetString(elems[1]); - if (Tcl_GetIntFromObj(interp, elems[2], (int *)&account) != TCL_OK) + if ((account = tcl_validate_account(elems[2], interp)) == NULL) return NULL; - if (!tcl_validate_account(account, interp)) - return NULL; if (!strcmp(type, "buddy")) { node = (GaimBlistNode *)gaim_find_buddy(account, name); @@ -301,15 +460,11 @@ Tcl_SetStringObj(result, "invalid buddy", -1); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, elems[2], (int *)&account)) != TCL_OK) + if ((account = tcl_validate_account(elems[2], interp)) == NULL) return TCL_ERROR; - if (!tcl_validate_account(account, interp)) - return TCL_ERROR; serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1])); } else { - if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3])); } @@ -351,7 +506,7 @@ tclbud = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1)); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1)); - Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)bud->account)); + Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, bud->account)); Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud); } if (count) { @@ -368,7 +523,7 @@ tclbud = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1)); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1)); - Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)cnode->account)); + Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, cnode->account)); Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud); break; default: @@ -409,23 +564,19 @@ Tcl_WrongNumArgs(interp, 2, objv, "gc"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); - if (error || !tcl_validate_gc(gc)) { - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) return TCL_ERROR; - } - Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefAccount, + gaim_connection_get_account(gc))); break; case CMD_CONN_DISPLAYNAME: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "gc"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); - if (error || !tcl_validate_gc(gc)) { - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) return TCL_ERROR; - } Tcl_SetStringObj(result, (char *)gaim_connection_get_display_name(gc), -1); break; case CMD_CONN_HANDLE: @@ -442,7 +593,7 @@ } list = Tcl_NewListObj(0, NULL); for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { - elem = Tcl_NewIntObj((int)cur->data); + elem = gaim_tcl_ref_new(GaimTclRefConnection, cur->data); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -483,15 +634,12 @@ return TCL_ERROR; } account = NULL; - if ((error = Tcl_GetIntFromObj(interp, objv[2], - (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, Tcl_GetString(objv[3]), account); - Tcl_SetIntObj(result, (int)convo); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo)); break; case CMD_CONV_HANDLE: if (objc != 2) { @@ -503,7 +651,7 @@ case CMD_CONV_LIST: list = Tcl_NewListObj(0, NULL); for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { - elem = Tcl_NewIntObj((int)cur->data); + elem = gaim_tcl_ref_new(GaimTclRefConversation, cur->data); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -538,24 +686,20 @@ Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[argsused++], (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL) return TCL_ERROR; convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused])); - Tcl_SetIntObj(result, (int)convo); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo)); break; case CMD_CONV_WRITE: if (objc != 6) { Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&convo)) != TCL_OK) - return error; + if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) + return TCL_ERROR; if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK) return error; - if (!tcl_validate_conversation(convo, interp)) - return TCL_ERROR; from = Tcl_GetString(objv[4]); what = Tcl_GetString(objv[5]); @@ -799,25 +943,224 @@ return TCL_OK; } +int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "account", "active_status", "available", + "chat_user", "context", "conversation", "idle", + "login", "online", "status", "statuses", NULL }; + enum { CMD_PRESENCE_ACCOUNT, CMD_PRESENCE_ACTIVE_STATUS, + CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_CHAT_USER, + CMD_PRESENCE_CONTEXT, CMD_PRESENCE_CONVERSATION, + CMD_PRESENCE_IDLE, CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE, + CMD_PRESENCE_STATUS, CMD_PRESENCE_STATUSES } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + Tcl_Obj *list, *elem; + GaimPresence *presence; + const GList *cur; + int error, idle, idle_time, login_time; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_PRESENCE_ACCOUNT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefAccount, + gaim_presence_get_account(presence))); + break; + case CMD_PRESENCE_ACTIVE_STATUS: + if (objc != 3 && objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "presence [?status_id? | ?-primitive primitive?]"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_presence_get_active_status(presence))); + } else if (objc == 4) { + Tcl_SetBooleanObj(result, + gaim_presence_is_status_active(presence, + Tcl_GetString(objv[3]))); + } else { + GaimStatusPrimitive primitive; + if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { + Tcl_SetStringObj(result, "bad option \"", -1); + Tcl_AppendObjToObj(result, objv[3]); + Tcl_AppendToObj(result, + "\": should be -primitive", -1); + return TCL_ERROR; + } + primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); + if (primitive == GAIM_STATUS_UNSET) { + Tcl_SetStringObj(result, "invalid primitive ", -1); + Tcl_AppendObjToObj(result, objv[4]); + return TCL_ERROR; + } + Tcl_SetBooleanObj(result, gaim_presence_is_status_primitive_active(presence, primitive)); + break; + } + break; + case CMD_PRESENCE_AVAILABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_presence_is_available(presence)); + break; + case CMD_PRESENCE_CHAT_USER: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_presence_get_chat_user(presence), -1); + break; + case CMD_PRESENCE_CONTEXT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + switch (gaim_presence_get_context(presence)) { + case GAIM_PRESENCE_CONTEXT_UNSET: + Tcl_SetStringObj(result, "unset", -1); + break; + case GAIM_PRESENCE_CONTEXT_ACCOUNT: + Tcl_SetStringObj(result, "account", -1); + break; + case GAIM_PRESENCE_CONTEXT_CONV: + Tcl_SetStringObj(result, "conversation", -1); + break; + case GAIM_PRESENCE_CONTEXT_BUDDY: + Tcl_SetStringObj(result, "buddy", -1); + break; + } + break; + case CMD_PRESENCE_CONVERSATION: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, + gaim_presence_get_conversation(presence))); + break; + case CMD_PRESENCE_IDLE: + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, "presence ?idle? ?time?"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + if (gaim_presence_is_idle(presence)) { + idle_time = gaim_presence_get_idle_time (presence); + Tcl_SetIntObj(result, idle_time); + } else { + result = Tcl_NewListObj(0, NULL); + Tcl_SetObjResult(interp, result); + } + break; + } + if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &idle)) != TCL_OK) + return TCL_ERROR; + if (objc == 4) { + gaim_presence_set_idle(presence, idle, time(NULL)); + } else if (objc == 5) { + if ((error = Tcl_GetIntFromObj(interp, + objv[4], + &idle_time)) != TCL_OK) + return TCL_ERROR; + gaim_presence_set_idle(presence, idle, idle_time); + } + break; + case CMD_PRESENCE_LOGIN: + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "presence ?time?"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetIntObj(result, gaim_presence_get_login_time(presence)); + } else { + if ((error == Tcl_GetIntFromObj(interp, + objv[3], + &login_time)) != TCL_OK) + return TCL_ERROR; + gaim_presence_set_login_time(presence, login_time); + } + break; + case CMD_PRESENCE_ONLINE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_presence_is_online(presence)); + break; + case CMD_PRESENCE_STATUS: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "presence status_id"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_presence_get_status(presence, + Tcl_GetString(objv[3])))); + break; + case CMD_PRESENCE_STATUSES: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_presence_get_statuses(presence); cur != NULL; + cur = g_list_next(cur)) { + elem = gaim_tcl_ref_new(GaimTclRefStatus, cur->data); + Tcl_ListObjAppendElement(interp, list, elem); + } + Tcl_SetObjResult(interp, list); + break; + } + + return TCL_OK; +} + int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { GaimConnection *gc; char *who, *text; - int error; - Tcl_Obj *result; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "gc who text"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK) - return error; - if (!tcl_validate_gc(gc)) { - result = Tcl_GetObjResult(interp); - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[1], interp)) == NULL) return TCL_ERROR; - } who = Tcl_GetString(objv[2]); text = Tcl_GetString(objv[3]); @@ -856,6 +1199,7 @@ return error; } handler->signal = objv[3]; + Tcl_IncrRefCount(handler->signal); handler->args = objv[4]; handler->proc = objv[5]; handler->interp = interp; @@ -868,7 +1212,7 @@ break; case CMD_SIGNAL_DISCONNECT: if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "signal"); + Tcl_WrongNumArgs(interp, 2, objv, "instance signal"); return TCL_ERROR; } if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK) @@ -880,6 +1224,265 @@ return TCL_OK; } +int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "attr", "type", NULL }; + enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatus *status; + GaimStatusType *status_type; + GaimValue *value; + const char *attr; + int error, v; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_ATTR: + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "status attr_id ?value?"); + return TCL_ERROR; + } + if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) + return TCL_ERROR; + attr = Tcl_GetString(objv[3]); + value = gaim_status_get_attr_value(status, attr); + if (value == NULL) { + Tcl_SetStringObj(result, "no such attribute", -1); + return TCL_ERROR; + } + switch (gaim_value_get_type(value)) { + case GAIM_TYPE_BOOLEAN: + if (objc == 4) { + Tcl_SetBooleanObj(result, gaim_value_get_boolean(value)); + } else { + if ((error = Tcl_GetBooleanFromObj(interp, objv[4], &v)) != TCL_OK) + return error; + gaim_status_set_attr_boolean(status, attr, v); + } + break; + case GAIM_TYPE_INT: + if (objc == 4) { + Tcl_SetIntObj(result, gaim_value_get_int(value)); + } else { + if ((error = Tcl_GetIntFromObj(interp, objv[4], &v)) != TCL_OK) + return error; + gaim_status_set_attr_int(status, attr, v ); + } + break; + case GAIM_TYPE_STRING: + if (objc == 4) + Tcl_SetStringObj(result, gaim_value_get_string(value), -1); + else + gaim_status_set_attr_string(status, attr, Tcl_GetString(objv[4])); + break; + default: + Tcl_SetStringObj(result, "attribute has unknown type", -1); + return TCL_ERROR; + } + break; + case CMD_STATUS_TYPE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "status"); + return TCL_ERROR; + } + if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) + return TCL_ERROR; + status_type = gaim_status_get_type(status); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefStatusType, + status_type)); + break; + } + + return TCL_OK; +} + +int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "id", "name", NULL }; + enum { CMD_STATUS_ATTR_ID, CMD_STATUS_ATTR_NAME } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatusAttr *attr; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_ATTR_ID: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "attr"); + return TCL_ERROR; + } + if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_attr_get_id(attr), -1); + break; + case CMD_STATUS_ATTR_NAME: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "attr"); + return TCL_ERROR; + } + if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_attr_get_name(attr), -1); + break; + } + + return TCL_OK; +} + +int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id", + "independent", "name", "primary_attr", + "primitive", "saveable", "user_settable", + NULL }; + enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS, + CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE, + CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT, + CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR, + CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE, + CMD_STATUS_TYPE_USER_SETTABLE } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatusType *status_type; + Tcl_Obj *list, *elem; + const GList *cur; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_TYPE_AVAILABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_available(status_type)); + break; + case CMD_STATUS_TYPE_ATTR: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype attr"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatusAttr, + gaim_status_type_get_attr(status_type, + Tcl_GetStringFromObj(objv[3], NULL)))); + break; + case CMD_STATUS_TYPE_ATTRS: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_status_type_get_attrs(status_type); + cur != NULL; cur = g_list_next(cur)) { + elem = gaim_tcl_ref_new(GaimTclRefStatusAttr, cur->data); + Tcl_ListObjAppendElement(interp, list, elem); + } + Tcl_SetObjResult(interp, list); + break; + case CMD_STATUS_TYPE_EXCLUSIVE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_exclusive(status_type)); + break; + case CMD_STATUS_TYPE_ID: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_id(status_type), -1); + break; + case CMD_STATUS_TYPE_INDEPENDENT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_independent(status_type)); + break; + case CMD_STATUS_TYPE_NAME: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_name(status_type), -1); + break; + case CMD_STATUS_TYPE_PRIMITIVE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_primitive_get_id_from_type(gaim_status_type_get_primitive(status_type)), -1); + break; + case CMD_STATUS_TYPE_PRIMARY_ATTR: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_primary_attr(status_type), -1); + break; + case CMD_STATUS_TYPE_SAVEABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_saveable(status_type)); + break; + case CMD_STATUS_TYPE_USER_SETTABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_user_settable(status_type)); + break; + } + + return TCL_OK; +} + static gboolean unload_self(gpointer data) { GaimPlugin *plugin = data; Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-17 02:11:13 UTC (rev 16272) @@ -28,6 +28,7 @@ #include "internal.h" #include "plugin.h" #include "value.h" +#include "stringref.h" struct tcl_signal_handler { Tcl_Obj *signal; @@ -46,6 +47,16 @@ extern GaimPlugin *_tcl_plugin; +/* Capitalized this way because these are "types" */ +extern GaimStringref *GaimTclRefAccount; +extern GaimStringref *GaimTclRefConnection; +extern GaimStringref *GaimTclRefConversation; +extern GaimStringref *GaimTclRefPointer; +extern GaimStringref *GaimTclRefPresence; +extern GaimStringref *GaimTclRefStatus; +extern GaimStringref *GaimTclRefStatusAttr; +extern GaimStringref *GaimTclRefStatusType; + GaimPlugin *tcl_interp_get_plugin(Tcl_Interp *interp); void tcl_signal_init(void); @@ -54,6 +65,10 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler); void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp); +void gaim_tcl_ref_init(void); +void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type); +Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value); + Tcl_ObjCmdProc tcl_cmd_account; Tcl_ObjCmdProc tcl_cmd_signal_connect; Tcl_ObjCmdProc tcl_cmd_buddy; @@ -63,8 +78,12 @@ Tcl_ObjCmdProc tcl_cmd_debug; Tcl_ObjCmdProc tcl_cmd_notify; Tcl_ObjCmdProc tcl_cmd_prefs; +Tcl_ObjCmdProc tcl_cmd_presence; Tcl_ObjCmdProc tcl_cmd_send_im; Tcl_ObjCmdProc tcl_cmd_signal; +Tcl_ObjCmdProc tcl_cmd_status; +Tcl_ObjCmdProc tcl_cmd_status_attr; +Tcl_ObjCmdProc tcl_cmd_status_type; Tcl_ObjCmdProc tcl_cmd_unload; #endif /* _GAIM_TCL_GAIM_H_ */ Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -1,7 +1,7 @@ /* * Tcl/Glib glue * - * Copyright (C) 2003, 2004 Ethan Blanton <ebl...@cs...> + * Copyright (C) 2003, 2004, 2006 Ethan Blanton <ebl...@cs...> * * This file is dual-licensed under the two sets of terms below. You may * use, redistribute, or modify it pursuant to either the set of conditions @@ -157,8 +157,8 @@ GIOChannel *channel; GIOCondition cond = 0; - if (g_hash_table_lookup(tcl_file_handlers, (gpointer)fd)) - tcl_delete_file_handler(fd); + if (g_hash_table_lookup(tcl_file_handlers, GINT_TO_POINTER(fd))) + tcl_delete_file_handler(fd); if (mask & TCL_READABLE) cond |= G_IO_IN; @@ -176,7 +176,7 @@ tfh->source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, tcl_file_callback, tfh, g_free); g_io_channel_unref(channel); - g_hash_table_insert(tcl_file_handlers, (gpointer)fd, tfh); + g_hash_table_insert(tcl_file_handlers, GINT_TO_POINTER(fd), tfh); Tcl_ServiceAll(); } @@ -189,7 +189,7 @@ return; g_source_remove(tfh->source); - g_hash_table_remove(tcl_file_handlers, (gpointer)fd); + g_hash_table_remove(tcl_file_handlers, GINT_TO_POINTER(fd)); Tcl_ServiceAll(); } @@ -241,7 +241,7 @@ return 0; } - tfh = g_hash_table_lookup(tcl_file_handlers, (gpointer)fev->fd); + tfh = g_hash_table_lookup(tcl_file_handlers, GINT_TO_POINTER(fev->fd)); if (tfh == NULL) return 1; Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -48,7 +48,8 @@ return; Tcl_DecrRefCount(handler->signal); - Tcl_DecrRefCount(handler->namespace); + if (handler->namespace) + Tcl_DecrRefCount(handler->namespace); g_free(handler); } @@ -86,7 +87,6 @@ (void *)handler)) return FALSE; - Tcl_IncrRefCount(handler->signal); handler->namespace = new_cb_namespace (); Tcl_IncrRefCount(handler->namespace); proc = g_string_new(""); @@ -134,6 +134,22 @@ tcl_callbacks = g_list_remove_all(tcl_callbacks, NULL); } +static GaimStringref *ref_type(GaimSubType type) +{ + switch (type) { + case GAIM_SUBTYPE_ACCOUNT: + return GaimTclRefAccount; + case GAIM_SUBTYPE_CONNECTION: + return GaimTclRefConnection; + case GAIM_SUBTYPE_CONVERSATION: + return GaimTclRefConversation; + case GAIM_SUBTYPE_STATUS: + return GaimTclRefStatus; + default: + return NULL; + } +} + static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handler) { GString *name, *val; @@ -170,14 +186,9 @@ case GAIM_TYPE_OBJECT: case GAIM_TYPE_BOXED: /* These are all "pointer" types to us */ - if (gaim_value_is_outgoing(handler->argtypes[i])) { - vals[i] = va_arg(args, void **); - Tcl_LinkVar(handler->interp, name->str, - vals[i], TCL_LINK_INT); - arg = Tcl_NewStringObj(name->str, -1); - } else { - arg = Tcl_NewIntObj((int)va_arg(args, void *)); - } + if (gaim_value_is_outgoing(handler->argtypes[i])) + gaim_debug_error("tcl", "pointer types do not currently support outgoing arguments\n"); + arg = gaim_tcl_ref_new(GaimTclRefPointer, va_arg(args, void *)); break; case GAIM_TYPE_BOOLEAN: if (gaim_value_is_outgoing(handler->argtypes[i])) { @@ -258,6 +269,11 @@ case GAIM_SUBTYPE_ACCOUNT: case GAIM_SUBTYPE_CONNECTION: case GAIM_SUBTYPE_CONVERSATION: + case GAIM_SUBTYPE_STATUS: + if (gaim_value_is_outgoing(handler->argtypes[i])) + gaim_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n"); + arg = gaim_tcl_ref_new(ref_type(gaim_value_get_subtype(handler->argtypes[i])), va_arg(args, void *)); + break; case GAIM_SUBTYPE_PLUGIN: case GAIM_SUBTYPE_XFER: /* pointers again */ @@ -281,24 +297,40 @@ node = va_arg(args, GaimBlistNode *); switch (node->type) { case GAIM_BLIST_GROUP_NODE: - g_string_printf(val, "group {%s}", ((GaimGroup *)node)->name); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("group", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimGroup *)node)->name, -1)); break; case GAIM_BLIST_CONTACT_NODE: /* g_string_printf(val, "contact {%s}", Contact Name? ); */ + arg = Tcl_NewStringObj("contact", -1); break; case GAIM_BLIST_BUDDY_NODE: - g_string_printf(val, "buddy {%s} %lu", ((GaimBuddy *)node)->name, - (unsigned long)((GaimBuddy *)node)->account); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("buddy", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimBuddy *)node)->name, -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + gaim_tcl_ref_new(GaimTclRefAccount, + ((GaimBuddy *)node)->account)); break; case GAIM_BLIST_CHAT_NODE: - g_string_printf(val, "chat {%s} %lu", ((GaimChat *)node)->alias, - (unsigned long)((GaimChat *)node)->account); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("chat", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimChat *)node)->alias, -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + gaim_tcl_ref_new(GaimTclRefAccount, + ((GaimChat *)node)->account)); break; case GAIM_BLIST_OTHER_NODE: - g_string_printf(val, "other"); + arg = Tcl_NewStringObj("other", -1); break; } - arg = Tcl_NewStringObj(val->str, -1); break; } } @@ -329,8 +361,10 @@ for (i = 0; i < handler->nargs; i++) { g_string_printf(name, "%s::arg%d", Tcl_GetString(handler->namespace), i); - if (gaim_value_is_outgoing(handler->argtypes[i])) + if (gaim_value_is_outgoing(handler->argtypes[i]) + && gaim_value_get_type(handler->argtypes[i]) != GAIM_TYPE_SUBTYPE) Tcl_UnlinkVar(handler->interp, name->str); + /* We basically only have to deal with strings on the * way out */ switch (gaim_value_get_type(handler->argtypes[i])) { Modified: branches/soc-2006-file-loggers/src/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/src/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/src/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272) @@ -347,7 +347,8 @@ $(SM_LIBS) \ $(INTLLIBS) \ $(GTKSPELL_LIBS) \ - $(STARTUP_NOTIFICATION_LIBS) + $(STARTUP_NOTIFICATION_LIBS) \ + $(LIBXML_LIBS) AM_CPPFLAGS = \ -DBR_PTHREADS=0 \ @@ -361,4 +362,5 @@ $(GTK_CFLAGS) \ $(DBUS_CFLAGS) \ $(GTKSPELL_CFLAGS) \ - $(STARTUP_NOTIFICATION_CFLAGS) + $(STARTUP_NOTIFICATION_CFLAGS) \ + $(LIBXML_CFLAGS) Modified: branches/soc-2006-file-loggers/src/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/src/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/sr... [truncated message content] |
From: <ro...@us...> - 2006-06-24 18:12:35
|
Revision: 16330 Author: roast Date: 2006-06-24 11:11:59 -0700 (Sat, 24 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16330&view=rev Log Message: ----------- merged with svn trunk, r16329 Modified Paths: -------------- branches/soc-2006-file-loggers/COPYRIGHT branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/doc/plugin-ids.dox branches/soc-2006-file-loggers/plugins/ChangeLog.API branches/soc-2006-file-loggers/plugins/idle.c branches/soc-2006-file-loggers/plugins/perl/common/Account.xs branches/soc-2006-file-loggers/plugins/perl/common/Conversation.xs branches/soc-2006-file-loggers/plugins/perl/common/Server.xs branches/soc-2006-file-loggers/plugins/tcl/Makefile.am branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw branches/soc-2006-file-loggers/plugins/tcl/tcl.c branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c branches/soc-2006-file-loggers/src/cmds.h branches/soc-2006-file-loggers/src/conversation.c branches/soc-2006-file-loggers/src/conversation.h branches/soc-2006-file-loggers/src/ft.c branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/gtkconv.c branches/soc-2006-file-loggers/src/gtkconv.h branches/soc-2006-file-loggers/src/gtkmain.c branches/soc-2006-file-loggers/src/gtkpounce.c branches/soc-2006-file-loggers/src/gtksavedstatuses.c branches/soc-2006-file-loggers/src/gtkstatusbox.c branches/soc-2006-file-loggers/src/pounce.c branches/soc-2006-file-loggers/src/pounce.h branches/soc-2006-file-loggers/src/protocols/irc/cmds.c branches/soc-2006-file-loggers/src/protocols/jabber/message.c branches/soc-2006-file-loggers/src/protocols/jabber/message.h branches/soc-2006-file-loggers/src/protocols/msn/msn.c branches/soc-2006-file-loggers/src/protocols/novell/novell.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/sametime/sametime.c branches/soc-2006-file-loggers/src/protocols/simple/simple.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.h branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_filexfer.c branches/soc-2006-file-loggers/src/protocols/zephyr/zephyr.c branches/soc-2006-file-loggers/src/prpl.h branches/soc-2006-file-loggers/src/server.c branches/soc-2006-file-loggers/src/server.h branches/soc-2006-file-loggers/src/xmlnode.c Modified: branches/soc-2006-file-loggers/COPYRIGHT =================================================================== --- branches/soc-2006-file-loggers/COPYRIGHT 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/COPYRIGHT 2006-06-24 18:11:59 UTC (rev 16330) @@ -51,6 +51,7 @@ Christophe Chapuis Ka-Hing Cheung Sadrul Habib Chowdhury +Brian Chu Arturo Cisneros, Jr. Vincas Ciziunas Jonathan Clark Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/configure.ac 2006-06-24 18:11:59 UTC (rev 16330) @@ -163,7 +163,11 @@ dnl # GStreamer dnl ####################################################################### enable_gst=yes -PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.10, ,enable_gst=no) +PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], , + [ + AC_MSG_RESULT(no) + enable_gst=no + ]) AC_SUBST(GSTREAMER_CFLAGS) AC_SUBST(GSTREAMER_LIBS) AC_ARG_ENABLE(gstreamer,[ --disable-gstreamer compile without GStreamer audio support],enable_gst=no) @@ -175,7 +179,11 @@ dnl # LibXML2 dnl ################# enable_libxml2=yes -PKG_CHECK_MODULES(LIBXML, libxml-2.0, ,enable_libxml2=no) +PKG_CHECK_MODULES(LIBXML, [libxml-2.0], , + [ + AC_MSG_RESULT(no) + enable_libxml2=no + ]) AC_SUBST(LIBXML_CFLAGS) AC_SUBST(LIBXML_LIBS) AC_ARG_ENABLE(libxml,[ --disable-libxml compile without libxml2 support],enable_libxml2=no) @@ -690,7 +698,7 @@ PYTHON=$withval) if test "x$enable_dbus" = "xyes" ; then - if test -z "$PYTHON" ; then + if test -z "$PYTHON" -o "x$PYTHON" = "xyes"; then AC_PATH_PROG([PYTHON], [python], [no]) fi Modified: branches/soc-2006-file-loggers/doc/plugin-ids.dox =================================================================== --- branches/soc-2006-file-loggers/doc/plugin-ids.dox 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/doc/plugin-ids.dox 2006-06-24 18:11:59 UTC (rev 16330) @@ -28,10 +28,7 @@ - qpe - Gaim for Qtopia plugin. The @em username must be a unique identifier for that person. It - @em should be your Gaim website user ID - (registered <a href="http://gaim.sourceforge.net/register.php">here</a>). - If for some reason you cannot register there (it shouldn't be a - problem!), you can use your SourceForge ID. Do @em not leave this field + @em should be your SourceForge ID. Do @em not leave this field blank. The @em pluginname is the name of your plugin. It can be whatever you like, Modified: branches/soc-2006-file-loggers/plugins/ChangeLog.API =================================================================== --- branches/soc-2006-file-loggers/plugins/ChangeLog.API 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/ChangeLog.API 2006-06-24 18:11:59 UTC (rev 16330) @@ -114,6 +114,7 @@ gaim_proxy_connect() and gaim_network_listen*(). * gaim_gtk_create_imhtml(): Added sw_ret() parameter * gaim_account_get_log(): Added create parameter + * GAIM_CMD_P_VERYHIGH is now GAIM_CMD_P_VERY_HIGH Removed: * gaim_gtk_sound_{get,set}_mute() (replaced by the /gaim/gtk/sound/mute @@ -173,6 +174,8 @@ * GAIM_MESSAGE_COLORIZE * user_data from gaim_notify_searchresults_new_rows and from notify_searchresults in GaimNotifyUiOps. + * gaim_conversation_get_send_history(), and send_history from + GaimConversation Added: * gaim_prefs_disconnect_by_handle() Modified: branches/soc-2006-file-loggers/plugins/idle.c =================================================================== --- branches/soc-2006-file-loggers/plugins/idle.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/idle.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -102,12 +102,13 @@ idle_all_action_ok(void *ignored, GaimRequestFields *fields) { GaimAccount *acct = NULL; - GList *l = gaim_accounts_get_all_active(); + GList *list, *iter; int tm = gaim_request_fields_get_integer(fields, "mins"); const char *prpl_id = NULL; - for(; l; l = l->next) { - acct = (GaimAccount *)(l->data); + list = gaim_accounts_get_all_active(); + for(iter = list; iter; iter = iter->next) { + acct = (GaimAccount *)(iter->data); if(acct) prpl_id = gaim_account_get_protocol_id(acct); @@ -122,6 +123,8 @@ idled_accts = g_list_append(idled_accts, acct); } } + + g_list_free(list); } static void Modified: branches/soc-2006-file-loggers/plugins/perl/common/Account.xs =================================================================== --- branches/soc-2006-file-loggers/plugins/perl/common/Account.xs 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/perl/common/Account.xs 2006-06-24 18:11:59 UTC (rev 16330) @@ -286,11 +286,13 @@ void gaim_accounts_get_all_active() PREINIT: - GList *l; + GList *list, *iter; PPCODE: - for (l = gaim_accounts_get_all_active(); l != NULL; l = l->next) { - XPUSHs(sv_2mortal(gaim_perl_bless_object(l->data, "Gaim::Account"))); + list = gaim_accounts_get_all_active(); + for (iter = gaim_accounts_get_all_active(); iter != NULL; iter = iter->next) { + XPUSHs(sv_2mortal(gaim_perl_bless_object(iter->data, "Gaim::Account"))); } + g_list_free(list); Gaim::Account gaim_accounts_find(name, protocol) Modified: branches/soc-2006-file-loggers/plugins/perl/common/Conversation.xs =================================================================== --- branches/soc-2006-file-loggers/plugins/perl/common/Conversation.xs 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/perl/common/Conversation.xs 2006-06-24 18:11:59 UTC (rev 16330) @@ -46,16 +46,6 @@ PROTOTYPES: ENABLE void -gaim_conversation_get_send_history(conv) - Gaim::Conversation conv -PREINIT: - GList *l; -PPCODE: - for (l = gaim_conversation_get_send_history(conv); l != NULL; l = l->next) { - XPUSHs(sv_2mortal(newSVpv(l->data, 0))); - } - -void gaim_conversation_destroy(conv) Gaim::Conversation conv @@ -189,15 +179,15 @@ Gaim::Conversation::IM im void -gaim_conv_im_start_type_again_timeout(im) +gaim_conv_im_start_send_typed_timeout(im) Gaim::Conversation::IM im void -gaim_conv_im_stop_type_again_timeout(im) +gaim_conv_im_stop_send_typed_timeout(im) Gaim::Conversation::IM im guint -gaim_conv_im_get_type_again_timeout(im) +gaim_conv_im_get_send_typed_timeout(im) Gaim::Conversation::IM im void Modified: branches/soc-2006-file-loggers/plugins/perl/common/Server.xs =================================================================== --- branches/soc-2006-file-loggers/plugins/perl/common/Server.xs 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/perl/common/Server.xs 2006-06-24 18:11:59 UTC (rev 16330) @@ -200,10 +200,10 @@ Gaim::MessageFlags flags int -serv_send_typing(con, a, b) +serv_send_typing(con, a, state) Gaim::Connection con const char * a - int b + Gaim::TypingState state void serv_set_buddyicon(gc, filename) Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-24 18:11:59 UTC (rev 16330) @@ -5,7 +5,7 @@ plugin_LTLIBRARIES = tcl.la tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h \ - tcl_ref.c + tcl_ref.c tcl_cmd.c EXTRA_DIST = signal-test.tcl Makefile.mingw Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-24 18:11:59 UTC (rev 16330) @@ -61,6 +61,7 @@ ## C_SRC = tcl.c \ + tcl_cmd.c \ tcl_cmds.c \ tcl_glib.c \ tcl_ref.c \ Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -126,6 +126,7 @@ Tcl_CreateObjCommand(interp, "::gaim::account", tcl_cmd_account, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::buddy", tcl_cmd_buddy, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::cmd", tcl_cmd_cmd, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::connection", tcl_cmd_connection, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::conversation", tcl_cmd_conversation, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::core", tcl_cmd_core, (ClientData)NULL, NULL); @@ -284,7 +285,9 @@ if (Tcl_EvalFile(interp, plugin->path) != TCL_OK) { result = Tcl_GetObjResult(interp); - gaim_debug(GAIM_DEBUG_ERROR, "tcl", "Error evaluating %s: %s\n", plugin->path, Tcl_GetString(result)); + gaim_debug(GAIM_DEBUG_ERROR, "tcl", + "Error evaluating %s: %s\n", plugin->path, + Tcl_GetString(result)); Tcl_DeleteInterp(interp); return FALSE; } @@ -313,6 +316,7 @@ if (data != NULL) { g_hash_table_remove(tcl_plugins, (gpointer)(data->interp)); gaim_signals_disconnect_by_handle(data->interp); + tcl_cmd_cleanup(data->interp); tcl_signal_cleanup(data->interp); Tcl_Release((ClientData)data->interp); Tcl_DeleteInterp(data->interp); @@ -341,6 +345,7 @@ if(!tcl_loaded) return FALSE; tcl_glib_init(); + tcl_cmd_init(); tcl_signal_init(); gaim_tcl_ref_init(); Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -73,7 +73,7 @@ return convo; } if (interp != NULL) - Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); + Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid conversation", -1); return NULL; } @@ -541,6 +541,70 @@ return TCL_OK; } +int tcl_cmd_cmd(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "register", "unregister", NULL }; + enum { CMD_CMD_REGISTER, CMD_CMD_UNREGISTER } cmd; + struct tcl_cmd_handler *handler; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimCmdId id; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_CMD_REGISTER: + if (objc != 9) { + Tcl_WrongNumArgs(interp, 2, objv, "cmd arglist priority flags prpl_id proc helpstr"); + return TCL_ERROR; + } + handler = g_new0(struct tcl_cmd_handler, 1); + handler->cmd = objv[2]; + handler->args = Tcl_GetString(objv[3]); + handler->nargs = strlen(handler->args); + if ((error = Tcl_GetIntFromObj(interp, objv[4], + &handler->priority)) != TCL_OK) { + g_free(handler); + return error; + } + if ((error = Tcl_GetIntFromObj(interp, objv[5], + &handler->flags)) != TCL_OK) { + g_free(handler); + return error; + } + handler->prpl_id = Tcl_GetString(objv[6]); + handler->proc = objv[7]; + handler->helpstr = Tcl_GetString(objv[8]); + handler->interp = interp; + if ((id = tcl_cmd_register(handler)) == 0) { + tcl_cmd_handler_free(handler); + Tcl_SetIntObj(result, 0); + } else { + handler->id = id; + Tcl_SetIntObj(result, id); + } + break; + case CMD_CMD_UNREGISTER: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "id"); + return TCL_ERROR; + } + if ((error = Tcl_GetIntFromObj(interp, objv[2], + (int *)&id)) != TCL_OK) + return error; + tcl_cmd_unregister(id, interp); + break; + } + + return TCL_OK; +} + int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-24 18:11:59 UTC (rev 16330) @@ -26,6 +26,7 @@ #include <tcl.h> #include "internal.h" +#include "cmds.h" #include "plugin.h" #include "value.h" #include "stringref.h" @@ -45,6 +46,23 @@ GaimValue **argtypes; }; +struct tcl_cmd_handler { + int id; + Tcl_Obj *cmd; + Tcl_Interp *interp; + + Tcl_Obj *namespace; + /* These are temporary during setup */ + const char *args; + int priority; + int flags; + const char *prpl_id; + Tcl_Obj *proc; + const char *helpstr; + + int nargs; +}; + extern GaimPlugin *_tcl_plugin; /* Capitalized this way because these are "types" */ @@ -65,6 +83,12 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler); void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp); +void tcl_cmd_init(void); +void tcl_cmd_handler_free(struct tcl_cmd_handler *handler); +void tcl_cmd_cleanup(Tcl_Interp *interp); +GaimCmdId tcl_cmd_register(struct tcl_cmd_handler *handler); +void tcl_cmd_unregister(GaimCmdId id, Tcl_Interp *interp); + void gaim_tcl_ref_init(void); void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type); Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value); @@ -72,6 +96,7 @@ Tcl_ObjCmdProc tcl_cmd_account; Tcl_ObjCmdProc tcl_cmd_signal_connect; Tcl_ObjCmdProc tcl_cmd_buddy; +Tcl_ObjCmdProc tcl_cmd_cmd; Tcl_ObjCmdProc tcl_cmd_connection; Tcl_ObjCmdProc tcl_cmd_conversation; Tcl_ObjCmdProc tcl_cmd_core; Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -387,7 +387,6 @@ g_string_free(val, TRUE); g_free(vals); g_free(strs); - return retval; } Modified: branches/soc-2006-file-loggers/src/cmds.h =================================================================== --- branches/soc-2006-file-loggers/src/cmds.h 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/cmds.h 2006-06-24 18:11:59 UTC (rev 16330) @@ -56,14 +56,14 @@ typedef guint GaimCmdId; enum _GaimCmdPriority { - GAIM_CMD_P_VERY_LOW = -1000, - GAIM_CMD_P_LOW = 0, - GAIM_CMD_P_DEFAULT = 1000, - GAIM_CMD_P_PRPL = 2000, - GAIM_CMD_P_PLUGIN = 3000, - GAIM_CMD_P_ALIAS = 4000, - GAIM_CMD_P_HIGH = 5000, - GAIM_CMD_P_VERYHIGH = 6000, + GAIM_CMD_P_VERY_LOW = -1000, + GAIM_CMD_P_LOW = 0, + GAIM_CMD_P_DEFAULT = 1000, + GAIM_CMD_P_PRPL = 2000, + GAIM_CMD_P_PLUGIN = 3000, + GAIM_CMD_P_ALIAS = 4000, + GAIM_CMD_P_HIGH = 5000, + GAIM_CMD_P_VERY_HIGH = 6000, }; enum _GaimCmdFlag { @@ -111,11 +111,11 @@ * @param f These are the flags. You need to at least pass one of GAIM_CMD_FLAG_IM or * GAIM_CMD_FLAG_CHAT (can may pass both) in order for the command to ever actually * be called. - * @param prpl_id This is the prpl's id string. This is only meaningful is the proper flag is set. + * @param prpl_id This is the prpl's id string. This is only meaningful if the proper flag is set. * @param func This is the function to call when someone enters this command. * @param helpstr This is a whitespace sensitive, UTF-8, HTML string describing how to use the command. * The preferred format of this string shall be the commands name, followed by a space - * and any arguments it accpets (if it takes any arguments, otherwise no space), follow + * and any arguments it accepts (if it takes any arguments, otherwise no space), followed * by a colon, two spaces, and a description of the command in sentence form. No slash * before the command name. * @param data User defined data to pass to the GaimCmdFunc Modified: branches/soc-2006-file-loggers/src/conversation.c =================================================================== --- branches/soc-2006-file-loggers/src/conversation.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/conversation.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -46,39 +46,44 @@ } static gboolean -reset_typing(gpointer data) +reset_typing_cb(gpointer data) { GaimConversation *c = (GaimConversation *)data; GaimConvIm *im; - if (!g_list_find(conversations, c)) - return FALSE; - im = GAIM_CONV_IM(c); gaim_conv_im_set_typing_state(im, GAIM_NOT_TYPING); gaim_conv_im_update_typing(im); gaim_conv_im_stop_typing_timeout(im); + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing-stopped", c->account, c->name); + return FALSE; } static gboolean -send_typed(gpointer data) +send_typed_cb(gpointer data) { GaimConversation *conv = (GaimConversation *)data; GaimConnection *gc; const char *name; g_return_val_if_fail(conv != NULL, FALSE); - + gc = gaim_conversation_get_gc(conv); name = gaim_conversation_get_name(conv); if (gc != NULL && name != NULL) { - gaim_conv_im_set_type_again(GAIM_CONV_IM(conv), TRUE); + /* We set this to 1 so that GAIM_TYPING will be sent + * if the Gaim user types anything else. + */ + gaim_conv_im_set_type_again(GAIM_CONV_IM(conv), 1); serv_send_typing(gc, name, GAIM_TYPED); + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typed", conv->account, conv->name); gaim_debug(GAIM_DEBUG_MISC, "conversation", "typed...\n"); } @@ -263,7 +268,6 @@ conv->account = account; conv->name = g_strdup(name); conv->title = g_strdup(name); - conv->send_history = g_list_append(NULL, NULL); conv->data = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); /* copy features from the connection. */ @@ -419,20 +423,9 @@ conv->name = NULL; conv->title = NULL; - for (node = g_list_first(conv->send_history); - node != NULL; - node = g_list_next(node)) { - - if (node->data != NULL) - g_free(node->data); - node->data = NULL; - } - - g_list_free(g_list_first(conv->send_history)); - if (conv->type == GAIM_CONV_TYPE_IM) { gaim_conv_im_stop_typing_timeout(conv->u.im); - gaim_conv_im_stop_type_again_timeout(conv->u.im); + gaim_conv_im_stop_send_typed_timeout(conv->u.im); if (conv->u.im->icon != NULL) gaim_buddy_icon_unref(conv->u.im->icon); @@ -708,14 +701,6 @@ conv->logs = NULL; } -GList * -gaim_conversation_get_send_history(const GaimConversation *conv) -{ - g_return_val_if_fail(conv != NULL, NULL); - - return conv->send_history; -} - GaimConvIm * gaim_conversation_get_im_data(const GaimConversation *conv) { @@ -1006,9 +991,14 @@ gaim_signal_emit(gaim_conversations_get_handle(), "buddy-typing", im->conv->account, im->conv->name); } - else + else if (state == GAIM_TYPED) { gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typed", im->conv->account, im->conv->name); + } + else if (state == GAIM_NOT_TYPING) + { + gaim_signal_emit(gaim_conversations_get_handle(), "buddy-typing-stopped", im->conv->account, im->conv->name); } } @@ -1036,7 +1026,7 @@ conv = gaim_conv_im_get_conversation(im); name = gaim_conversation_get_name(conv); - im->typing_timeout = gaim_timeout_add(timeout * 1000, reset_typing, conv); + im->typing_timeout = gaim_timeout_add(timeout * 1000, reset_typing_cb, conv); } void @@ -1060,11 +1050,14 @@ } void -gaim_conv_im_set_type_again(GaimConvIm *im, time_t val) +gaim_conv_im_set_type_again(GaimConvIm *im, unsigned int val) { g_return_if_fail(im != NULL); - im->type_again = val; + if (val == 0) + im->type_again = 0; + else + im->type_again = time(NULL) + val; } time_t @@ -1076,32 +1069,32 @@ } void -gaim_conv_im_start_type_again_timeout(GaimConvIm *im) +gaim_conv_im_start_send_typed_timeout(GaimConvIm *im) { g_return_if_fail(im != NULL); - im->type_again_timeout = gaim_timeout_add(SEND_TYPED_TIMEOUT, send_typed, + im->send_typed_timeout = gaim_timeout_add(SEND_TYPED_TIMEOUT, send_typed_cb, gaim_conv_im_get_conversation(im)); } void -gaim_conv_im_stop_type_again_timeout(GaimConvIm *im) +gaim_conv_im_stop_send_typed_timeout(GaimConvIm *im) { g_return_if_fail(im != NULL); - if (im->type_again_timeout == 0) + if (im->send_typed_timeout == 0) return; - gaim_timeout_remove(im->type_again_timeout); - im->type_again_timeout = 0; + gaim_timeout_remove(im->send_typed_timeout); + im->send_typed_timeout = 0; } guint -gaim_conv_im_get_type_again_timeout(const GaimConvIm *im) +gaim_conv_im_get_send_typed_timeout(const GaimConvIm *im) { g_return_val_if_fail(im != NULL, 0); - return im->type_again_timeout; + return im->send_typed_timeout; } void @@ -2110,6 +2103,12 @@ GAIM_SUBTYPE_ACCOUNT), gaim_value_new(GAIM_TYPE_STRING)); + gaim_signal_register(handle, "buddy-typed", + gaim_marshal_VOID__POINTER_POINTER, NULL, 2, + gaim_value_new(GAIM_TYPE_SUBTYPE, + GAIM_SUBTYPE_ACCOUNT), + gaim_value_new(GAIM_TYPE_STRING)); + gaim_signal_register(handle, "buddy-typing-stopped", gaim_marshal_VOID__POINTER_POINTER, NULL, 2, gaim_value_new(GAIM_TYPE_SUBTYPE, Modified: branches/soc-2006-file-loggers/src/conversation.h =================================================================== --- branches/soc-2006-file-loggers/src/conversation.h 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/conversation.h 2006-06-24 18:11:59 UTC (rev 16330) @@ -186,7 +186,7 @@ GaimTypingState typing_state; /**< The current typing state. */ guint typing_timeout; /**< The typing timer handle. */ time_t type_again; /**< The type again time. */ - guint type_again_timeout; /**< The type again timer handle. */ + guint send_typed_timeout; /**< The type again timer handle. */ GaimBuddyIcon *icon; /**< The buddy icon. */ }; @@ -236,8 +236,6 @@ GList *logs; /**< This conversation's logs */ - GList *send_history; /**< The send history. */ - union { GaimConvIm *im; /**< IM-specific data. */ @@ -441,15 +439,6 @@ void gaim_conversation_close_logs(GaimConversation *conv); /** - * Returns the specified conversation's send history. - * - * @param conv The conversation. - * - * @return The conversation's send history. - */ -GList *gaim_conversation_get_send_history(const GaimConversation *conv); - -/** * Returns the specified conversation's IM-specific data. * * If the conversation type is not GAIM_CONV_TYPE_IM, this will return @c NULL. @@ -677,19 +666,25 @@ guint gaim_conv_im_get_typing_timeout(const GaimConvIm *im); /** - * Sets the IM's time until it should send another typing notification. + * Sets the quiet-time when no GAIM_TYPING messages will be sent. + * Few protocols need this (maybe only MSN). If the user is still + * typing after this quiet-period, then another GAIM_TYPING message + * will be sent. * * @param im The IM. - * @param val The time. + * @param val The number of seconds to wait before allowing another + * GAIM_TYPING message to be sent to the user. Or 0 to + * not send another GAIM_TYPING message. */ -void gaim_conv_im_set_type_again(GaimConvIm *im, time_t val); +void gaim_conv_im_set_type_again(GaimConvIm *im, unsigned int val); /** - * Returns the IM's time until it should send another typing notification. + * Returns the time after which another GAIM_TYPING message should be sent. * * @param im The IM. * - * @return The time. + * @return The time in seconds since the epoch. Or 0 if no additional + * GAIM_TYPING message should be sent. */ time_t gaim_conv_im_get_type_again(const GaimConvIm *im); @@ -698,14 +693,14 @@ * * @param im The IM. */ -void gaim_conv_im_start_type_again_timeout(GaimConvIm *im); +void gaim_conv_im_start_send_typed_timeout(GaimConvIm *im); /** * Stops the IM's type again timeout. * * @param im The IM. */ -void gaim_conv_im_stop_type_again_timeout(GaimConvIm *im); +void gaim_conv_im_stop_send_typed_timeout(GaimConvIm *im); /** * Returns the IM's type again timeout interval. @@ -714,7 +709,7 @@ * * @return The type again timeout interval. */ -guint gaim_conv_im_get_type_again_timeout(const GaimConvIm *im); +guint gaim_conv_im_get_send_typed_timeout(const GaimConvIm *im); /** * Updates the visual typing notification for an IM conversation. Modified: branches/soc-2006-file-loggers/src/ft.c =================================================================== --- branches/soc-2006-file-loggers/src/ft.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/ft.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -388,8 +388,9 @@ gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_ACCEPTED) { gchar* message = NULL; + GaimBuddy *buddy = gaim_find_buddy(xfer->account, xfer->who); message = g_strdup_printf(_("%s is offering to send file %s"), - xfer->who, gaim_xfer_get_filename(xfer)); + buddy ? gaim_buddy_get_alias(buddy) : xfer->who, gaim_xfer_get_filename(xfer)); gaim_xfer_conversation_write(xfer, message, FALSE); g_free(message); /* Ask for a filename to save to if it's not already given by a plugin */ Modified: branches/soc-2006-file-loggers/src/gtkblist.c =================================================================== --- branches/soc-2006-file-loggers/src/gtkblist.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtkblist.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -1659,6 +1659,11 @@ static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, GtkSelectionData *sd, guint info, guint t) { + if (gtkblist->drag_timeout) { + g_source_remove(gtkblist->drag_timeout); + gtkblist->drag_timeout = 0; + } + if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE) && sd->data) { GaimBlistNode *n = NULL; GtkTreePath *path = NULL; Modified: branches/soc-2006-file-loggers/src/gtkconv.c =================================================================== --- branches/soc-2006-file-loggers/src/gtkconv.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtkconv.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -427,18 +427,14 @@ } static void -send_history_add(GaimConversation *conv, const char *message) +send_history_add(GaimGtkConversation *gtkconv, const char *message) { GList *first; - first = g_list_first(conv->send_history); - - if (first->data) - g_free(first->data); - + first = g_list_first(gtkconv->send_history); + g_free(first->data); first->data = g_strdup(message); - - conv->send_history = g_list_prepend(first, NULL); + gtkconv->send_history = g_list_prepend(first, NULL); } static gboolean @@ -462,7 +458,7 @@ GtkTextIter end; send_history = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry)); - send_history_add(conv, send_history); + send_history_add(gtkconv, send_history); g_free(send_history); cmdline = cmd + strlen(prefix); @@ -562,7 +558,7 @@ bufs = gtk_imhtml_get_markup_lines(GTK_IMHTML(gtkconv->entry)); for (i = 0; bufs[i]; i++) { - send_history_add(conv, bufs[i]); + send_history_add(gtkconv, bufs[i]); if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) gaim_conv_im_send_with_flags(GAIM_CONV_IM(conv), bufs[i], flags); else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) @@ -572,7 +568,7 @@ g_strfreev(bufs); } else { - send_history_add(conv, buf); + send_history_add(gtkconv, buf); if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) gaim_conv_im_send_with_flags(GAIM_CONV_IM(conv), buf, flags); else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) @@ -1787,29 +1783,28 @@ if (event->state & GDK_CONTROL_MASK) { switch (event->keyval) { case GDK_Up: - if (!conv->send_history) + if (!gtkconv->send_history) break; - if (!conv->send_history->prev) { + if (!gtkconv->send_history->prev) { GtkTextIter start, end; - if (conv->send_history->data) - g_free(conv->send_history->data); + g_free(gtkconv->send_history->data); gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &start); gtk_text_buffer_get_end_iter(gtkconv->entry_buffer, &end); - conv->send_history->data = + gtkconv->send_history->data = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry)); } - if (conv->send_history->next && conv->send_history->next->data) { + if (gtkconv->send_history->next && gtkconv->send_history->next->data) { GObject *object; GtkTextIter iter; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); - conv->send_history = conv->send_history->next; + gtkconv->send_history = gtkconv->send_history->next; /* Block the signal to prevent application of default formatting. */ object = g_object_ref(G_OBJECT(gtkconv->entry)); @@ -1824,7 +1819,7 @@ gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry)); gtk_imhtml_append_text_with_images( - GTK_IMHTML(gtkconv->entry), conv->send_history->data, + GTK_IMHTML(gtkconv->entry), gtkconv->send_history->data, 0, NULL); /* this is mainly just a hack so the formatting at the * cursor gets picked up. */ @@ -1836,15 +1831,15 @@ break; case GDK_Down: - if (!conv->send_history) + if (!gtkconv->send_history) break; - if (conv->send_history->prev && conv->send_history->prev->data) { + if (gtkconv->send_history->prev && gtkconv->send_history->prev->data) { GObject *object; GtkTextIter iter; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); - conv->send_history = conv->send_history->prev; + gtkconv->send_history = gtkconv->send_history->prev; /* Block the signal to prevent application of default formatting. */ object = g_object_ref(G_OBJECT(gtkconv->entry)); @@ -1859,11 +1854,11 @@ gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry)); gtk_imhtml_append_text_with_images( - GTK_IMHTML(gtkconv->entry), conv->send_history->data, + GTK_IMHTML(gtkconv->entry), gtkconv->send_history->data, 0, NULL); /* this is mainly just a hack so the formatting at the * cursor gets picked up. */ - if (*(char *)conv->send_history->data) { + if (*(char *)gtkconv->send_history->data) { gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_move_mark_by_name(buffer, "insert", &iter); } else { @@ -2173,8 +2168,7 @@ if (gtk_text_iter_is_start(start_pos) && gtk_text_iter_is_end(end_pos)) { /* We deleted all the text, so turn off typing. */ - if (gaim_conv_im_get_type_again_timeout(im)) - gaim_conv_im_stop_type_again_timeout(im); + gaim_conv_im_stop_send_typed_timeout(im); serv_send_typing(gaim_conversation_get_gc(conv), gaim_conversation_get_name(conv), @@ -2918,22 +2912,18 @@ im = GAIM_CONV_IM(conv); - if (gaim_conv_im_get_type_again_timeout(im)) - gaim_conv_im_stop_type_again_timeout(im); + gaim_conv_im_stop_send_typed_timeout(im); + gaim_conv_im_start_send_typed_timeout(im); - gaim_conv_im_start_type_again_timeout(im); - + /* Check if we need to send another GAIM_TYPING message */ if (first || (gaim_conv_im_get_type_again(im) != 0 && - time(NULL) > gaim_conv_im_get_type_again(im))) { - - int timeout = serv_send_typing(gaim_conversation_get_gc(conv), - (char *)gaim_conversation_get_name(conv), - GAIM_TYPING); - - if (timeout) - gaim_conv_im_set_type_again(im, time(NULL) + timeout); - else - gaim_conv_im_set_type_again(im, 0); + time(NULL) > gaim_conv_im_get_type_again(im))) + { + unsigned int timeout; + timeout = serv_send_typing(gaim_conversation_get_gc(conv), + gaim_conversation_get_name(conv), + GAIM_TYPING); + gaim_conv_im_set_type_again(im, timeout); } } @@ -4347,6 +4337,7 @@ conv->ui_data = gtkconv; gtkconv->active_conv = conv; gtkconv->convs = g_list_prepend(gtkconv->convs, conv); + gtkconv->send_history = g_list_append(NULL, NULL); /* Setup some initial variables. */ gtkconv->sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); @@ -4515,6 +4506,10 @@ gtk_object_sink(GTK_OBJECT(gtkconv->tooltips)); + gtkconv->send_history = g_list_first(gtkconv->send_history); + g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL); + g_list_free(gtkconv->send_history); + g_free(gtkconv); } Modified: branches/soc-2006-file-loggers/src/gtkconv.h =================================================================== --- branches/soc-2006-file-loggers/src/gtkconv.h 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtkconv.h 2006-06-24 18:11:59 UTC (rev 16330) @@ -114,6 +114,7 @@ { GaimConversation *active_conv; GList *convs; + GList *send_history; GaimGtkWindow *win; Modified: branches/soc-2006-file-loggers/src/gtkmain.c =================================================================== --- branches/soc-2006-file-loggers/src/gtkmain.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtkmain.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -432,6 +432,7 @@ char *opt_session_arg = NULL; int dologin_ret = -1; char *search_path; + GList *accounts; #ifdef HAVE_SIGNAL_H int sig_indx; /* for setting up signal catching */ sigset_t sigset; @@ -752,10 +753,14 @@ gaim_accounts_restore_current_statuses(); } - if (gaim_accounts_get_all_active() == NULL) + if ((accounts = gaim_accounts_get_all_active()) == NULL) { gaim_gtk_accounts_window_show(); } + else + { + g_list_free(accounts); + } #ifdef HAVE_STARTUP_NOTIFICATION startup_notification_complete(); Modified: branches/soc-2006-file-loggers/src/gtkpounce.c =================================================================== --- branches/soc-2006-file-loggers/src/gtkpounce.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtkpounce.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -81,6 +81,7 @@ GtkWidget *idle; GtkWidget *idle_return; GtkWidget *typing; + GtkWidget *typed; GtkWidget *stop_typing; GtkWidget *message_recv; @@ -278,6 +279,9 @@ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->typing))) events |= GAIM_POUNCE_TYPING; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->typed))) + events |= GAIM_POUNCE_TYPED; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->stop_typing))) events |= GAIM_POUNCE_TYPING_STOPPED; @@ -564,7 +568,7 @@ /* Create the "Pounce When Buddy..." frame. */ frame = gaim_gtk_make_frame(vbox2, _("Pounce When Buddy...")); - table = gtk_table_new(2, 4, FALSE); + table = gtk_table_new(5, 2, FALSE); gtk_container_add(GTK_CONTAINER(frame), table); gtk_table_set_col_spacings(GTK_TABLE(table), GAIM_HIG_BORDER); gtk_widget_show(table); @@ -583,29 +587,33 @@ gtk_check_button_new_with_mnemonic(_("Is no longer i_dle")); dialog->typing = gtk_check_button_new_with_mnemonic(_("Starts _typing")); + dialog->typed = + gtk_check_button_new_with_mnemonic(_("P_auses while typing")); dialog->stop_typing = gtk_check_button_new_with_mnemonic(_("Stops t_yping")); dialog->message_recv = gtk_check_button_new_with_mnemonic(_("Sends a _message")); - gtk_table_attach(GTK_TABLE(table), dialog->signon, 0, 1, 0, 1, + gtk_table_attach(GTK_TABLE(table), dialog->message_recv, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->signoff, 1, 2, 0, 1, + gtk_table_attach(GTK_TABLE(table), dialog->signon, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->away, 0, 1, 1, 2, + gtk_table_attach(GTK_TABLE(table), dialog->signoff, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->away_return, 1, 2, 1, 2, + gtk_table_attach(GTK_TABLE(table), dialog->away, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->idle, 0, 1, 2, 3, + gtk_table_attach(GTK_TABLE(table), dialog->away_return, 0, 1, 4, 5, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->idle_return, 1, 2, 2, 3, + gtk_table_attach(GTK_TABLE(table), dialog->idle, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->typing, 0, 1, 3, 4, + gtk_table_attach(GTK_TABLE(table), dialog->idle_return, 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->stop_typing, 1, 2, 3, 4, + gtk_table_attach(GTK_TABLE(table), dialog->typing, 1, 2, 2, 3, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->message_recv, 0, 1, 4, 5, + gtk_table_attach(GTK_TABLE(table), dialog->typed, 1, 2, 3, 4, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), dialog->stop_typing, 1, 2, 4, 5, + GTK_FILL, 0, 0, 0); gtk_widget_show(dialog->signon); gtk_widget_show(dialog->signoff); @@ -614,6 +622,7 @@ gtk_widget_show(dialog->idle); gtk_widget_show(dialog->idle_return); gtk_widget_show(dialog->typing); + gtk_widget_show(dialog->typed); gtk_widget_show(dialog->stop_typing); gtk_widget_show(dialog->message_recv); @@ -845,6 +854,8 @@ (events & GAIM_POUNCE_IDLE_RETURN)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->typing), (events & GAIM_POUNCE_TYPING)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->typed), + (events & GAIM_POUNCE_TYPED)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->stop_typing), (events & GAIM_POUNCE_TYPING_STOPPED)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->message_recv), @@ -1429,6 +1440,8 @@ tmp = g_strdup_printf( (events & GAIM_POUNCE_TYPING) ? _("%s has started typing to you (%s)") : + (events & GAIM_POUNCE_TYPED) ? + _("%s has paused while typing to you (%s)") : (events & GAIM_POUNCE_SIGNON) ? _("%s has signed on (%s)") : (events & GAIM_POUNCE_IDLE_RETURN) ? Modified: branches/soc-2006-file-loggers/src/gtksavedstatuses.c =================================================================== --- branches/soc-2006-file-loggers/src/gtksavedstatuses.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtksavedstatuses.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -760,6 +760,10 @@ type = gaim_account_get_status_type(account, id); gaim_savedstatus_set_substatus(saved_status, account, type, message); } + else + { + gaim_savedstatus_unset_substatus(saved_status, account); + } g_free(id); g_free(message); } while (gtk_tree_model_iter_next(model, &iter)); Modified: branches/soc-2006-file-loggers/src/gtkstatusbox.c =================================================================== --- branches/soc-2006-file-loggers/src/gtkstatusbox.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/gtkstatusbox.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -744,7 +744,11 @@ { g_source_remove(status_box->typing); status_box->typing = 0; - status_menu_refresh_iter(status_box); + if (status_box->account != NULL) + update_to_reflect_account_status(status_box, status_box->account, + gaim_account_get_active_status(status_box->account)); + else + status_menu_refresh_iter(status_box); return TRUE; } Modified: branches/soc-2006-file-loggers/src/pounce.c =================================================================== --- branches/soc-2006-file-loggers/src/pounce.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/pounce.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -206,6 +206,8 @@ add_event_to_xmlnode(child, "return-from-idle"); if (events & GAIM_POUNCE_TYPING) add_event_to_xmlnode(child, "start-typing"); + if (events & GAIM_POUNCE_TYPED) + add_event_to_xmlnode(child, "typed"); if (events & GAIM_POUNCE_TYPING_STOPPED) add_event_to_xmlnode(child, "stop-typing"); if (events & GAIM_POUNCE_MESSAGE_RECEIVED) @@ -411,7 +413,7 @@ else if (!strcmp(element_name, "option")) { if (!strcmp(data->option_type, "on-away")) data->options |= GAIM_POUNCE_OPTION_AWAY; - + g_free(data->option_type); data->option_type = NULL; } @@ -430,6 +432,8 @@ data->events |= GAIM_POUNCE_IDLE_RETURN; else if (!strcmp(data->event_type, "start-typing")) data->events |= GAIM_POUNCE_TYPING; + else if (!strcmp(data->event_type, "typed")) + data->events |= GAIM_POUNCE_TYPED; else if (!strcmp(data->event_type, "stop-typing")) data->events |= GAIM_POUNCE_TYPING_STOPPED; else if (!strcmp(data->event_type, "message-received")) @@ -1059,10 +1063,16 @@ conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, name, account); if (conv != NULL) { + GaimTypingState state; GaimPounceEvent event; - event = (gaim_conv_im_get_typing_state(GAIM_CONV_IM(conv)) == GAIM_TYPING - ? GAIM_POUNCE_TYPING : GAIM_POUNCE_TYPING_STOPPED); + state = gaim_conv_im_get_typing_state(GAIM_CONV_IM(conv)); + if (state == GAIM_TYPED) + event = GAIM_POUNCE_TYPED; + else if (state == GAIM_NOT_TYPING) + event = GAIM_POUNCE_TYPING_STOPPED; + else + event = GAIM_POUNCE_TYPING; gaim_pounce_execute(account, name, event); } @@ -1105,6 +1115,8 @@ gaim_signal_connect(conv_handle, "buddy-typing", handle, GAIM_CALLBACK(buddy_typing_cb), NULL); + gaim_signal_connect(conv_handle, "buddy-typed", + handle, GAIM_CALLBACK(buddy_typing_cb), NULL); gaim_signal_connect(conv_handle, "buddy-typing-stopped", handle, GAIM_CALLBACK(buddy_typing_cb), NULL); Modified: branches/soc-2006-file-loggers/src/pounce.h =================================================================== --- branches/soc-2006-file-loggers/src/pounce.h 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/pounce.h 2006-06-24 18:11:59 UTC (rev 16330) @@ -35,16 +35,17 @@ */ typedef enum { - GAIM_POUNCE_NONE = 0x00, /**< No events. */ - GAIM_POUNCE_SIGNON = 0x01, /**< The buddy signed on. */ - GAIM_POUNCE_SIGNOFF = 0x02, /**< The buddy signed off. */ - GAIM_POUNCE_AWAY = 0x04, /**< The buddy went away. */ - GAIM_POUNCE_AWAY_RETURN = 0x08, /**< The buddy returned from away. */ - GAIM_POUNCE_IDLE = 0x10, /**< The buddy became idle. */ - GAIM_POUNCE_IDLE_RETURN = 0x20, /**< The buddy is no longer idle. */ - GAIM_POUNCE_TYPING = 0x40, /**< The buddy started typing. */ - GAIM_POUNCE_TYPING_STOPPED = 0x80, /**< The buddy stopped typing. */ - GAIM_POUNCE_MESSAGE_RECEIVED = 0x100 /**< The buddy sent a message */ + GAIM_POUNCE_NONE = 0x000, /**< No events. */ + GAIM_POUNCE_SIGNON = 0x001, /**< The buddy signed on. */ + GAIM_POUNCE_SIGNOFF = 0x002, /**< The buddy signed off. */ + GAIM_POUNCE_AWAY = 0x004, /**< The buddy went away. */ + GAIM_POUNCE_AWAY_RETURN = 0x008, /**< The buddy returned from away. */ + GAIM_POUNCE_IDLE = 0x010, /**< The buddy became idle. */ + GAIM_POUNCE_IDLE_RETURN = 0x020, /**< The buddy is no longer idle. */ + GAIM_POUNCE_TYPING = 0x040, /**< The buddy started typing. */ + GAIM_POUNCE_TYPED = 0x080, /**< The buddy has entered text. */ + GAIM_POUNCE_TYPING_STOPPED = 0x100, /**< The buddy stopped typing. */ + GAIM_POUNCE_MESSAGE_RECEIVED = 0x200 /**< The buddy sent a message */ } GaimPounceEvent; Modified: branches/soc-2006-file-loggers/src/protocols/irc/cmds.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/irc/cmds.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/irc/cmds.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -372,6 +372,8 @@ g_free(buf); irc->quitting = TRUE; + + gaim_account_set_status(irc->account, "offline", TRUE, NULL); } return 0; Modified: branches/soc-2006-file-loggers/src/protocols/jabber/message.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/jabber/message.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/jabber/message.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -589,7 +589,7 @@ return 1; } -int jabber_send_typing(GaimConnection *gc, const char *who, int typing) +unsigned int jabber_send_typing(GaimConnection *gc, const char *who, GaimTypingState state) { JabberMessage *jm; JabberBuddy *jb; @@ -611,9 +611,9 @@ jm->to = g_strdup(who); jm->id = jabber_get_next_id(jm->js); - if(GAIM_TYPING == typing) + if(GAIM_TYPING == state) jm->chat_state = JM_STATE_COMPOSING; - else if(GAIM_TYPED == typing) + else if(GAIM_TYPED == state) jm->chat_state = JM_STATE_PAUSED; else jm->chat_state = JM_STATE_ACTIVE; Modified: branches/soc-2006-file-loggers/src/protocols/jabber/message.h =================================================================== --- branches/soc-2006-file-loggers/src/protocols/jabber/message.h 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/jabber/message.h 2006-06-24 18:11:59 UTC (rev 16330) @@ -71,7 +71,7 @@ GaimMessageFlags flags); int jabber_message_send_chat(GaimConnection *gc, int id, const char *message, GaimMessageFlags flags); -int jabber_send_typing(GaimConnection *gc, const char *who, int typing); +unsigned int jabber_send_typing(GaimConnection *gc, const char *who, GaimTypingState state); #endif /* _GAIM_JABBER_MESSAGE_H_ */ Modified: branches/soc-2006-file-loggers/src/protocols/msn/msn.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/msn/msn.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/msn/msn.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -836,8 +836,8 @@ return 1; } -static int -msn_send_typing(GaimConnection *gc, const char *who, int typing) +static unsigned int +msn_send_typing(GaimConnection *gc, const char *who, GaimTypingState state) { GaimAccount *account; MsnSession *session; @@ -847,7 +847,12 @@ account = gaim_connection_get_account(gc); session = gc->proto_data; - if (!typing) + /* + * TODO: I feel like this should be "if (state != GAIM_TYPING)" + * but this is how it was before, and I don't want to break + * anything. --KingAnt + */ + if (state == GAIM_NOT_TYPING) return 0; if (!g_ascii_strcasecmp(who, gaim_account_get_username(account))) Modified: branches/soc-2006-file-loggers/src/protocols/novell/novell.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/novell/novell.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/novell/novell.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -2303,8 +2303,8 @@ return 1; } -static int -novell_send_typing(GaimConnection * gc, const char *name, int typing) +static unsigned int +novell_send_typing(GaimConnection * gc, const char *name, GaimTypingState state) { NMConference *conf = NULL; NMUser *user; @@ -2312,11 +2312,11 @@ NMERR_T rc = NM_OK; if (gc == NULL || name == NULL) - return -1; + return 0; user = gc->proto_data; if (user == NULL) - return -1; + return 0; /* Need to get the DN for the buddy so we can look up the convo */ dn = nm_lookup_dn(user, name); @@ -2327,7 +2327,7 @@ if (conf) { rc = nm_send_typing(user, conf, - ((typing == GAIM_TYPING) ? TRUE : FALSE), NULL); + ((state == GAIM_TYPING) ? TRUE : FALSE), NULL); _check_for_disconnect(user, rc); } Modified: branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -1113,9 +1113,8 @@ od->iconconnecting = FALSE; - if (od->icontimer) - gaim_timeout_remove(od->icontimer); - od->icontimer = gaim_timeout_add(100, gaim_icon_timerfunc, gc); + if (od->icontimer == 0) + od->icontimer = gaim_timeout_add(100, gaim_icon_timerfunc, gc); } static int @@ -1815,9 +1814,8 @@ cur = cur->next; if (!cur) { od->requesticon = g_slist_append(od->requesticon, g_strdup(gaim_normalize(account, info->sn))); - if (od->icontimer) - gaim_timeout_remove(od->icontimer); - od->icontimer = gaim_timeout_add(500, gaim_icon_timerfunc, gc); + if (od->icontimer == 0) + od->icontimer = gaim_timeout_add(500, gaim_icon_timerfunc, gc); } } g_free(b16); @@ -3169,9 +3167,8 @@ od->requesticon = g_slist_remove(od->requesticon, sn); g_free(sn); - if (od->icontimer) - gaim_timeout_remove(od->icontimer); - od->icontimer = gaim_timeout_add(500, gaim_icon_timerfunc, gc); + if (od->icontimer == 0) + od->icontimer = gaim_timeout_add(500, gaim_icon_timerfunc, gc); return 1; } @@ -3221,9 +3218,8 @@ cur = cur->next; } - if (od->icontimer) - gaim_timeout_remove(od->icontimer); - od->icontimer = gaim_timeout_add(250, gaim_icon_timerfunc, gc); + if (od->icontimer == 0) + od->icontimer = gaim_timeout_add(250, gaim_icon_timerfunc, gc); return 1; } @@ -3234,6 +3230,8 @@ aim_userinfo_t *userinfo; FlapConnection *conn; + od->icontimer = 0; + conn = flap_connection_getbytype(od, SNAC_FAMILY_BART); if (!conn) { if (!od->iconconnecting) { @@ -3286,7 +3284,9 @@ g_free(sn); } - return TRUE; + od->icontimer = gaim_timeout_add(100, gaim_icon_timerfunc, gc); + + return FALSE; } /* @@ -3945,8 +3945,8 @@ flap_connection_send_keepalive(od, conn); } -static int -oscar_send_typing(GaimConnection *gc, const char *name, int typing) +static unsigned int +oscar_send_typing(GaimConnection *gc, const char *name, GaimTypingState state) { OscarData *od; PeerConnection *conn; @@ -3956,7 +3956,7 @@ if ((conn != NULL) && (conn->ready)) { - peer_odc_send_typing(conn, typing); + peer_odc_send_typing(conn, state); } else { /* Don't send if this turkey is in our deny list */ @@ -3965,9 +3965,9 @@ if (!list) { struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, name)); if (bi && bi->typingnot) { - if (typing == GAIM_TYPING) + if (state == GAIM_TYPING) aim_im_sendmtn(od, 0x0001, name, 0x0002); - else if (typing == GAIM_TYPED) + else if (state == GAIM_TYPED) aim_im_sendmtn(od, 0x0001, name, 0x0001); else aim_im_sendmtn(od, 0x0001, name, 0x0000); Modified: branches/soc-2006-file-loggers/src/protocols/sametime/sametime.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/sametime/sametime.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/sametime/sametime.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -3965,14 +3965,14 @@ } -static int mw_prpl_send_typing(GaimConnection *gc, const char *name, - int typing) { +static unsigned int mw_prpl_send_typing(GaimConnection *gc, const char *name, + GaimTypingState state) { struct mwGaimPluginData *pd; struct mwIdBlock who = { (char *) name, NULL }; struct mwConversation *conv; - gpointer t = GINT_TO_POINTER(!! typing); + gpointer t = GINT_TO_POINTER(!! state); g_return_val_if_fail(gc != NULL, 0); pd = gc->proto_data; @@ -3984,7 +3984,7 @@ if(mwConversation_isOpen(conv)) return ! mwConversation_send(conv, mwImSend_TYPING, t); - if(typing) { + if ((state == GAIM_TYPING) || (state == GAIM_TYPED)) { /* let's only open a channel for typing, not for not-typing. Otherwise two users in psychic mode will continually open conversations to each other, never able to get rid of them, as @@ -3996,6 +3996,11 @@ mwConversation_open(conv); } + /* + * TODO: This should probably be "0." When it's set to 1, the Gaim + * core will call serv_send_typing(gc, who, GAIM_TYPING) once + * every second until the Gaim user stops typing. --KingAnt + */ return 1; } Modified: branches/soc-2006-file-loggers/src/protocols/simple/simple.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/simple/simple.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/simple/simple.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -1053,7 +1053,7 @@ send_sip_response(sip->gc, msg, 200, "OK", NULL); } -static int simple_typing(GaimConnection *gc, const char *name, int typing) { +static unsigned int simple_typing(GaimConnection *gc, const char *name, GaimTypingState state) { struct simple_account_data *sip = gc->proto_data; gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" @@ -1065,16 +1065,22 @@ "<refresh>60</refresh>\n" "</isComposing>"; gchar *recv = g_strdup(name); - if(typing == GAIM_TYPING) { + if(state == GAIM_TYPING) { gchar *msg = g_strdup_printf(xml, "active"); simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); g_free(msg); - } else { + } else /* TODO: Only if (state == GAIM_TYPED) ? */ { gchar *msg = g_strdup_printf(xml, "idle"); simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); g_free(msg); } g_free(recv); + /* + * TODO: Is this right? It will cause the core to call + * serv_send_typing(gc, who, GAIM_TYPING) once every second + * until the user stops typing. If that's not desired, + * then return 0 instead. + */ return 1; } Modified: branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c =================================================================== --- branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c 2006-06-24 12:04:32 UTC (rev 16329) +++ branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c 2006-06-24 18:11:59 UTC (rev 16330) @@ -670,6 +670,7 @@ static void yahoo_process_message(GaimConnection *gc, struct yahoo_packet *pkt) { + struct yahoo_data *yd = gc->proto_data; GSList *l = pkt->hash; GSList *list = NULL; struct _yahoo_im *im = NULL; @@ -712,24 +713,29 @@ /** TODO: It seems that this check should be per IM, not global */ /* Check for the Doodle IMV */ - if(im != NULL && imv != NULL && !strcmp(imv, "doodle;11")) + if (im != NULL && imv!= NULL && im->from != NULL) { - GaimWhiteboard *wb; + g_hash_table_replace(yd->imvironments, g_strdup(im->from), g_strdup(imv)); - if (!yahoo_privacy_check(gc, im->from)) { - gaim_debug_info("yahoo", "Doodle request from %s dropped.\n", im->from); - return; - } + if (strcmp(imv, "doodle;11") == 0) + { + GaimWhiteboard *wb; - wb = gaim_whiteboard_get_session(gc->account, im->from); + if (!yahoo_privacy_check(gc, im->from)) { + gaim_debug_info("yahoo", "Doodle request from %s dropped.\n", im->from); + return; + } - /* If a Doodle session doesn't exist between this user */ - if(wb == NULL) - { - wb = gaim_whiteboard_create(gc->account, im->from, DOODLE_STATE_REQUESTED); + wb = gaim_whiteboard_get_session(gc->account, im->from); - yahoo_doodle_command_send_request(gc, im->from); - yahoo_doodle_command_send_ready(gc, im->from); + /* If a Doodle session doesn't exist between this user */ + if(wb == NULL) + { + wb = gaim_whiteboard_create(gc->account, im->from, DOODLE_STATE_REQUESTED); + + yahoo_doodle_command_send_request(gc, im->from); + yahoo_doodle_command_send_ready(gc, im->from); + } } } @@ -2576,6 +2582,7 @@ /* TODO: Is there a good grow size for the buffer? */ yd->txbuf = gaim_circ_buffer_new(0); yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); + yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); yd->confs = NULL; yd->conf_id = 2; @@ -2628,6 +2635,7 @@ yahoo_c_leave(gc, 1); /* 1 = YAHOO_CHAT_ID */ g_hash_table_destroy(yd->friends); + g_hash_table_destroy(yd->imvironments); g_free(yd->chat_name); g_free(yd->cookie_y); @@ -3101,14 +3109,30 @@ yahoo_packet_hash_str(pkt, 97, "1"); yahoo_packet_hash_str(pkt, 14, msg2); - /* If this message is to a user who is also Doodling with the local user, + /* + * IMVironment. + * + * If this message is to a user who is also Doodling with the local user, * format the chat packet with the correct IMV information (thanks Yahoo!) - */ - wb = gaim_whiteboard_get_session(gc->account, (char*)who); + * + * Otherwise attempt to use the same IMVironment as the remote user, + * just so that we don't inadvertantly reset their IMVironment back + * to nothing. + * + * If they have no set an IMVironment, then use the default.... [truncated message content] |
From: <ro...@us...> - 2006-06-25 23:09:14
|
Revision: 16337 Author: roast Date: 2006-06-25 16:08:49 -0700 (Sun, 25 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16337&view=rev Log Message: ----------- fixed botched up 16271:16329 merge Added Paths: ----------- branches/soc-2006-file-loggers/console/ branches/soc-2006-file-loggers/console/Makefile branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/gntblist.h branches/soc-2006-file-loggers/console/gntgaim.c branches/soc-2006-file-loggers/console/gntgaim.h branches/soc-2006-file-loggers/console/gntui.c branches/soc-2006-file-loggers/console/gntui.h branches/soc-2006-file-loggers/console/libgnt/ branches/soc-2006-file-loggers/console/libgnt/Makefile branches/soc-2006-file-loggers/console/libgnt/gnt-skel.c branches/soc-2006-file-loggers/console/libgnt/gnt-skel.h branches/soc-2006-file-loggers/console/libgnt/gnt.h branches/soc-2006-file-loggers/console/libgnt/gntbox.c branches/soc-2006-file-loggers/console/libgnt/gntbox.h branches/soc-2006-file-loggers/console/libgnt/gntbutton.c branches/soc-2006-file-loggers/console/libgnt/gntbutton.h branches/soc-2006-file-loggers/console/libgnt/gntcolors.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.h branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntentry.h branches/soc-2006-file-loggers/console/libgnt/gntkeys.h branches/soc-2006-file-loggers/console/libgnt/gntlabel.c branches/soc-2006-file-loggers/console/libgnt/gntlabel.h branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gnttree.h branches/soc-2006-file-loggers/console/libgnt/gntutils.c branches/soc-2006-file-loggers/console/libgnt/gntutils.h branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.h branches/soc-2006-file-loggers/console/libgnt/test.c branches/soc-2006-file-loggers/plugins/tcl/tcl_cmd.c branches/soc-2006-file-loggers/plugins/tcl/tcl_ref.c Added: branches/soc-2006-file-loggers/console/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/Makefile (rev 0) +++ branches/soc-2006-file-loggers/console/Makefile 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,27 @@ +CFLAGS=`pkg-config --cflags gaim gobject-2.0` -g -I./libgnt/ +LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0` -lncursesw -L./libgnt/ -lgnt + +GG_SOURCES = \ + gntblist.c \ + gntui.c + +GG_HEADERS = \ + gntblist.h \ + gntui.h + +GG_OBJECTS = \ + gntblist.o \ + gntui.o + +all: gntgaim + +gntgaim: gntgaim.o $(GG_OBJECTS) + $(CC) -o gntgaim gntgaim.o $(GG_OBJECTS) $(LDFLAGS) +gntblist.o: gntblist.c $(GG_HEADERS) +gntgaim.o: gntgaim.c gntgaim.h $(GG_HEADERS) +gntui.o: gntui.c $(GG_HEADERS) + +clean: + rm *.o + rm gntgaim + Property changes on: branches/soc-2006-file-loggers/console/Makefile ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,369 @@ +#include <gaim/account.h> +#include <gaim/blist.h> +#include <signal.h> +#include <gaim/util.h> +#include <gaim/server.h> + +#include "gntgaim.h" +#include "gntbox.h" +#include "gnttree.h" + +#include "gntblist.h" +#include <string.h> + +typedef struct +{ + GntWidget *window; + GntWidget *tree; + + GntWidget *tooltip; + GaimBlistNode *tnode; /* Who is the tooltip being displayed for? */ +} GGBlist; + +GGBlist *ggblist; + +static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist); +static void add_group(GaimGroup *group, GGBlist *ggblist); +static void draw_tooltip(GGBlist *ggblist); + +static void +new_node(GaimBlistNode *node) +{ +} + +static void +remove_tooltip(GGBlist *ggblist) +{ + gnt_widget_destroy(ggblist->tooltip); + ggblist->tooltip = NULL; + ggblist->tnode = NULL; +} + +static void +node_remove(GaimBuddyList *list, GaimBlistNode *node) +{ + GGBlist *ggblist = list->ui_data; + + if (node->ui_data == NULL) + return; + + gnt_tree_remove(GNT_TREE(ggblist->tree), node); + node->ui_data = NULL; + + /* XXX: Depending on the node, we may want to remove the group/contact node if necessary */ + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimGroup *group = gaim_buddy_get_group((GaimBuddy*)node); + if (gaim_blist_get_group_online_count(group) == 0) + node_remove(list, (GaimBlistNode*)group); + else if (ggblist->tnode == (GaimBlistNode *)group) /* Need to update the counts */ + draw_tooltip(ggblist); + } + + if (ggblist->tnode == node) + { + remove_tooltip(ggblist); + } +} + +static void +node_update(GaimBuddyList *list, GaimBlistNode *node) +{ + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy*)node; + if (gaim_presence_is_online(gaim_buddy_get_presence(buddy))) + add_buddy(buddy, list->ui_data); + else + node_remove(gaim_get_blist(), node); + } +} + +static void +new_list(GaimBuddyList *list) +{ +} + +static GaimBlistUiOps blist_ui_ops = +{ + new_list, + new_node, + NULL, + node_update, /* This doesn't do crap */ + node_remove, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static gpointer +gg_blist_get_handle() +{ + static int handle; + + return &handle; +} + +static void +add_group(GaimGroup *group, GGBlist *ggblist) +{ + GaimBlistNode *node = (GaimBlistNode *)group; + if (node->ui_data) + return; + node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), group, + group->name, NULL, NULL); +} + +static const char * +get_buddy_display_name(GaimBuddy *buddy) +{ + static char text[2096]; + char status[8]; + GaimStatusPrimitive prim; + GaimPresence *presence; + GaimStatus *now; + + presence = gaim_buddy_get_presence(buddy); + now = gaim_presence_get_active_status(presence); + + prim = gaim_status_type_get_primitive(gaim_status_get_type(now)); + + switch(prim) + { +#if 1 + case GAIM_STATUS_OFFLINE: + strncpy(status, "x", sizeof(status) - 1); + break; + case GAIM_STATUS_AVAILABLE: + strncpy(status, "o", sizeof(status) - 1); + break; + default: + strncpy(status, ".", sizeof(status) - 1); + break; +#else + /* XXX: Let's use these some time */ + case GAIM_STATUS_OFFLINE: + strncpy(status, "M-bM-^JM-^W", sizeof(status) - 1); + break; + case GAIM_STATUS_AVAILABLE: + /* XXX: Detect idleness */ + strncpy(status, "M-bM-^WM-/", sizeof(status) - 1); + break; + default: + strncpy(status, "M-bM-^JM-^V", sizeof(status) - 1); + break; +#endif + } + + snprintf(text, sizeof(text) - 1, "%s %s", status, gaim_buddy_get_alias(buddy)); + + return text; +} + +static void +add_buddy(GaimBuddy *buddy, GGBlist *ggblist) +{ + GaimGroup *group; + GaimBlistNode *node = (GaimBlistNode *)buddy; + if (node->ui_data) + return; + + group = gaim_buddy_get_group(buddy); + add_group(group, ggblist); + + node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy, + get_buddy_display_name(buddy), group, NULL); + + if (ggblist->tnode == (GaimBlistNode*)group) + draw_tooltip(ggblist); +} + +static void +buddy_signed_on(GaimBuddy *buddy, GGBlist *ggblist) +{ + add_buddy(buddy, ggblist); +} + +static void +buddy_signed_off(GaimBuddy *buddy, GGBlist *ggblist) +{ + node_remove(gaim_get_blist(), (GaimBlistNode*)buddy); +} + +GaimBlistUiOps *gg_blist_get_ui_ops() +{ + return &blist_ui_ops; +} + +static void +selection_activate(GntWidget *widget, GGBlist *ggblist) +{ + gnt_widget_set_focus(widget, FALSE); +} + +static void +draw_tooltip(GGBlist *ggblist) +{ + GaimBlistNode *node; + int x, y, top, width; + GString *str; + GaimPlugin *prpl; + GaimPluginProtocolInfo *prpl_info; + GaimAccount *account; + GntTree *tree; + GntWidget *widget, *box, *label; + char *title = NULL; + + widget = ggblist->tree; + tree = GNT_TREE(widget); + + if (ggblist->tooltip) + { + remove_tooltip(ggblist); + } + + node = gnt_tree_get_selection_data(tree); + if (!node) + return; + + str = g_string_new(""); + + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy *)node; + account = gaim_buddy_get_account(buddy); + + g_string_append_printf(str, _("Account: %s"), gaim_account_get_username(account)); + + prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info && prpl_info->tooltip_text) + { + GString *tip = g_string_new(""); + char *strip, *br; + prpl_info->tooltip_text(buddy, tip, TRUE); + + br = gaim_strreplace(tip->str, "\n", "<br>"); + strip = gaim_markup_strip_html(br); + g_string_append(str, strip); + g_string_free(tip, TRUE); + g_free(strip); + g_free(br); + } + + title = g_strdup(gaim_buddy_get_name(buddy)); + } + else if (GAIM_BLIST_NODE_IS_GROUP(node)) + { + GaimGroup *group = (GaimGroup *)node; + + g_string_append_printf(str, _("Online: %d\nTotal: %d"), + gaim_blist_get_group_online_count(group), + gaim_blist_get_group_size(group, FALSE)); + + title = g_strdup(group->name); + } + else + { + g_string_free(str, TRUE); + return; + } + + gnt_widget_get_position(widget, &x, &y); + gnt_widget_get_size(widget, &width, NULL); + top = gnt_tree_get_selection_visible_line(tree); + + x += width; + y += top - 1; + + box = gnt_box_new(FALSE, FALSE); + gnt_box_set_toplevel(GNT_BOX(box), TRUE); + GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW); + gnt_box_set_title(GNT_BOX(box), title); + + gnt_box_add_widget(GNT_BOX(box), GNT_WIDGET(gnt_label_new(str->str))); + + gnt_widget_set_position(box, x, y); + gnt_widget_draw(box); + + g_free(title); + g_string_free(str, TRUE); + ggblist->tooltip = box; + ggblist->tnode = node; +} + +static void +selection_changed(GntWidget *widget, gpointer old, gpointer current, GGBlist *ggblist) +{ + draw_tooltip(ggblist); +} + + +static gboolean +key_pressed(GntWidget *widget, const char *text, GGBlist *ggblist) +{ + if (text[0] == 27 && text[1] == 0) + { + /* Escape was pressed */ + if (ggblist->tooltip) + { + gnt_widget_destroy(ggblist->tooltip); + ggblist->tooltip = NULL; + return TRUE; + } + } + return FALSE; +} + +static void +buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist) +{ + gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, get_buddy_display_name(buddy)); + if (ggblist->tnode == (GaimBlistNode*)buddy) + draw_tooltip(ggblist); +} + +void gg_blist_init() +{ + ggblist = g_new0(GGBlist, 1); + + gaim_get_blist()->ui_data = ggblist; + + ggblist->window = gnt_box_new(FALSE, FALSE); + gnt_box_set_toplevel(GNT_BOX(ggblist->window), TRUE); + gnt_box_set_title(GNT_BOX(ggblist->window), _("Buddy List")); + gnt_box_set_pad(GNT_BOX(ggblist->window), 0); + + ggblist->tree = gnt_tree_new(); + GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); + gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 2); + + gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree); + gnt_widget_show(ggblist->window); + + gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(), + GAIM_CALLBACK(buddy_status_changed), ggblist); + +#if 0 + gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gg_blist_get_handle(), + GAIM_CALLBACK(buddy_signed_on), ggblist); + gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", gg_blist_get_handle(), + GAIM_CALLBACK(buddy_signed_off), ggblist); + + /* These I plan to use to indicate unread-messages etc. */ + gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", gg_blist_get_handle(), + GAIM_CALLBACK(received_im_msg), list); + gaim_signal_connect(gaim_conversations_get_handle(), "sent-im-msg", gg_blist_get_handle(), + GAIM_CALLBACK(sent_im_msg), NULL); + + gaim_signal_connect(gaim_conversations_get_handle(), "received-chat-msg", gg_blist_get_handle(), + GAIM_CALLBACK(received_chat_msg), list); +#endif + + g_signal_connect(G_OBJECT(ggblist->tree), "selection_changed", G_CALLBACK(selection_changed), ggblist); + g_signal_connect(G_OBJECT(ggblist->tree), "key_pressed", G_CALLBACK(key_pressed), ggblist); + g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist); +} + Property changes on: branches/soc-2006-file-loggers/console/gntblist.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/gntblist.h =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntblist.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,5 @@ +#include "blist.h" + +GaimBlistUiOps * gg_blist_get_ui_ops(); + +void gg_blist_init(); Property changes on: branches/soc-2006-file-loggers/console/gntblist.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/gntgaim.c =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntgaim.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,187 @@ +#include "account.h" +#include "conversation.h" +#include "core.h" +#include "debug.h" +#include "eventloop.h" +#include "ft.h" +#include "log.h" +#include "notify.h" +#include "prefs.h" +#include "prpl.h" +#include "pounce.h" +#include "savedstatuses.h" +#include "sound.h" +#include "status.h" +#include "util.h" +#include "whiteboard.h" + +#include "gntgaim.h" + +/* Anything IO-related is directly copied from gtkgaim's source tree */ + +static GaimCoreUiOps core_ops = +{ + NULL, /*gaim_gtk_prefs_init,*/ + NULL, /*debug_init,*/ + NULL, /*gaim_gtk_ui_init,*/ + NULL, /*gaim_gtk_quit*/ +}; + +static GaimCoreUiOps * +gnt_core_get_ui_ops() +{ + return &core_ops; +} + +#define GAIM_GTK_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) +#define GAIM_GTK_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) + +typedef struct _GaimGtkIOClosure { + GaimInputFunction function; + guint result; + gpointer data; + +} GaimGtkIOClosure; + +static void gaim_gtk_io_destroy(gpointer data) +{ + g_free(data); +} + +static gboolean gaim_gtk_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) +{ + GaimGtkIOClosure *closure = data; + GaimInputCondition gaim_cond = 0; + + if (condition & GAIM_GTK_READ_COND) + gaim_cond |= GAIM_INPUT_READ; + if (condition & GAIM_GTK_WRITE_COND) + gaim_cond |= GAIM_INPUT_WRITE; + +#if 0 + gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop", + "CLOSURE: callback for %d, fd is %d\n", + closure->result, g_io_channel_unix_get_fd(source)); +#endif + +#ifdef _WIN32 + if(! gaim_cond) { +#if DEBUG + gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop", + "CLOSURE received GIOCondition of 0x%x, which does not" + " match 0x%x (READ) or 0x%x (WRITE)\n", + condition, GAIM_GTK_READ_COND, GAIM_GTK_WRITE_COND); +#endif /* DEBUG */ + + return TRUE; + } +#endif /* _WIN32 */ + + closure->function(closure->data, g_io_channel_unix_get_fd(source), + gaim_cond); + + return TRUE; +} + +static guint gnt_input_add(gint fd, GaimInputCondition condition, GaimInputFunction function, + gpointer data) +{ + GaimGtkIOClosure *closure = g_new0(GaimGtkIOClosure, 1); + GIOChannel *channel; + GIOCondition cond = 0; + + closure->function = function; + closure->data = data; + + if (condition & GAIM_INPUT_READ) + cond |= GAIM_GTK_READ_COND; + if (condition & GAIM_INPUT_WRITE) + cond |= GAIM_GTK_WRITE_COND; + + channel = g_io_channel_unix_new(fd); + closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, + gaim_gtk_io_invoke, closure, gaim_gtk_io_destroy); + +#if 0 + gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop", + "CLOSURE: adding input watcher %d for fd %d\n", + closure->result, fd); +#endif + + g_io_channel_unref(channel); + return closure->result; +} + +static GaimEventLoopUiOps eventloop_ops = +{ + g_timeout_add, + (guint (*)(guint))g_source_remove, + gnt_input_add, + (guint (*)(guint))g_source_remove +}; + +GaimEventLoopUiOps * +gnt_eventloop_get_ui_ops(void) +{ + return &eventloop_ops; +} + +/* This is mostly copied from gtkgaim's source tree */ +static void +init_libgaim() +{ + char *path; + + gaim_debug_set_enabled(FALSE); + + gaim_core_set_ui_ops(gnt_core_get_ui_ops()); + gaim_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops()); + + gaim_util_set_user_dir("/tmp/tmp/"); /* XXX: */ + + path = g_build_filename(gaim_user_dir(), "plugins", NULL); + gaim_plugins_add_search_path(path); + g_free(path); + gaim_plugins_add_search_path("/usr/local/lib/gaim"); /* XXX: */ + + if (!gaim_core_init(GAIM_GNT_UI)) + { + fprintf(stderr, "OOPSSS!!\n"); + abort(); + } + + /* TODO: Move blist loading into gaim_blist_init() */ + gaim_set_blist(gaim_blist_new()); + gaim_blist_load(); + + /* TODO: Move prefs loading into gaim_prefs_init() */ + gaim_prefs_load(); + gaim_prefs_update_old(); + + /* load plugins we had when we quit */ + gaim_plugins_load_saved("/gaim/gtk/plugins/loaded"); + + /* TODO: Move pounces loading into gaim_pounces_init() */ + gaim_pounces_load(); + +} + +int main(int argc, char **argv) +{ + /* XXX: Don't puke */ + freopen("/dev/null", "w", stderr); + + /* Initialize the libgaim stuff */ + init_libgaim(); + + /* Enable the accounts and restore the status */ + gaim_accounts_restore_current_statuses(); + + /* Initialize the UI */ + init_gnt_ui(); + + gaim_core_quit(); + + return 0; +} + Property changes on: branches/soc-2006-file-loggers/console/gntgaim.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/gntgaim.h =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntgaim.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,5 @@ +#include <glib.h> + +#define GAIM_GNT_UI "gnt-gaim" + +#define _(x) x Property changes on: branches/soc-2006-file-loggers/console/gntgaim.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/gntui.c =================================================================== --- branches/soc-2006-file-loggers/console/gntui.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntui.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,17 @@ +#include "gntui.h" + +void init_gnt_ui() +{ + gnt_init(); + + wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + werase(stdscr); + wrefresh(stdscr); + + /* Initialize the buddy list */ + gg_blist_init(); + gaim_blist_set_ui_ops(gg_blist_get_ui_ops()); + + gnt_main(); +} + Property changes on: branches/soc-2006-file-loggers/console/gntui.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/gntui.h =================================================================== --- branches/soc-2006-file-loggers/console/gntui.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntui.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,3 @@ +#include "gnt.h" + +void init_gnt_ui(); Property changes on: branches/soc-2006-file-loggers/console/gntui.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/Makefile (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/Makefile 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,58 @@ +CFLAGS=`pkg-config --cflags gobject-2.0` -g +LDFLAGS=`pkg-config --libs gobject-2.0` -lncursesw + +HEADERS = \ + gntwidget.h \ + gntbox.h \ + gntbutton.h \ + gntcolors.h \ + gntentry.h \ + gntlabel.h \ + gnttree.h \ + gntutils.h \ + gnt.h + +SOURCES = \ + gntwidget.c \ + gntbox.c \ + gntbutton.c \ + gntcolors.c \ + gntentry.c \ + gntlabel.c \ + gnttree.c \ + gntutils.c \ + gntmain.c + +OBJECTS = \ + gntwidget.o \ + gntbox.o \ + gntbutton.o \ + gntcolors.o \ + gntentry.o \ + gntlabel.o \ + gnttree.o \ + gntutils.o \ + gntmain.o + +all: libgnt + +test2: $(OBJECTS) +key: $(OBJECTS) + +gntwidget.o: gntwidget.c $(HEADERS) +gntbox.o: gntbox.c $(HEADERS) +gntbutton.o: gntbutton.c $(HEADERS) +gntcolors.o: gntcolors.c $(HEADERS) +gntentry.o: gntentry.c $(HEADERS) +gntlabel.o: gntlabel.c $(HEADERS) +gnttree.o: gnttree.c $(HEADERS) +gntutils.o: gntutils.c $(HEADERS) +gntmain.o: gntmain.c $(HEADERS) + +libgnt: $(OBJECTS) + $(CC) --shared -o libgnt.so $(OBJECTS) + +clean: + rm *.o + rm libgnt.so + Property changes on: branches/soc-2006-file-loggers/console/libgnt/Makefile ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gnt-skel.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnt-skel.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gnt-skel.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,99 @@ +#include "gnt-skel.h" + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_skel_draw(GntWidget *widget) +{ + DEBUG; +} + +static void +gnt_skel_size_request(GntWidget *widget) +{ +} + +static void +gnt_skel_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_skel_key_pressed(GntWidget *widget, const char *text) +{ + return FALSE; +} + +static void +gnt_skel_destroy(GntWidget *widget) +{ +} + +static void +gnt_skel_class_init(GntSkelClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->destroy = gnt_skel_destroy; + parent_class->draw = gnt_skel_draw; + parent_class->map = gnt_skel_map; + parent_class->size_request = gnt_skel_size_request; + parent_class->key_pressed = gnt_skel_key_pressed; + + DEBUG; +} + +static void +gnt_skel_init(GTypeInstance *instance, gpointer class) +{ + DEBUG; +} + +/****************************************************************************** + * GntSkel API + *****************************************************************************/ +GType +gnt_skel_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntSkelClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_skel_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntSkel), + 0, /* n_preallocs */ + gnt_skel_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntSkel", + &info, 0); + } + + return type; +} + +GntWidget *gnt_skel_new() +{ + GntWidget *widget = g_object_new(GNT_TYPE_SKEL, NULL); + GntSkel *skel = GNT_SKEL(widget); + + return widget; +} + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gnt-skel.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gnt-skel.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnt-skel.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gnt-skel.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,47 @@ +#ifndef GNT_SKEL_H +#define GNT_SKEL_H + +#include "gntwidget.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_SKEL (gnt_skel_get_gtype()) +#define GNT_SKEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_SKEL, GntSkel)) +#define GNT_SKEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_SKEL, GntSkelClass)) +#define GNT_IS_SKEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_SKEL)) +#define GNT_IS_SKEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_SKEL)) +#define GNT_SKEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_SKEL, GntSkelClass)) + +#define GNT_SKEL_FLAGS(obj) (GNT_SKEL(obj)->priv.flags) +#define GNT_SKEL_SET_FLAGS(obj, flags) (GNT_SKEL_FLAGS(obj) |= flags) +#define GNT_SKEL_UNSET_FLAGS(obj, flags) (GNT_SKEL_FLAGS(obj) &= ~(flags)) + +typedef struct _GnSkel GntSkel; +typedef struct _GnSkelPriv GntSkelPriv; +typedef struct _GnSkelClass GntSkelClass; + +struct _GnSkel +{ + GntWidget parent; +}; + +struct _GnSkelClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_skel_get_gtype(void); + +GntWidget *gnt_skel_new(); + +G_END_DECLS + +#endif /* GNT_SKEL_H */ Property changes on: branches/soc-2006-file-loggers/console/libgnt/gnt-skel.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gnt.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnt.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gnt.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,17 @@ +#include <glib.h> +#include "gntwidget.h" +#include "gntcolors.h" +#include "gntkeys.h" + +/* XXX: Find a better place for this */ +#define SCROLL_HEIGHT 4096 +#define SCROLL_WIDTH 512 + +void gnt_init(); + +void gnt_main(); + +void gnt_screen_take_focus(GntWidget *widget); + +void gnt_screen_remove_widget(GntWidget *widget); + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gnt.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntbox.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbox.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntbox.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,362 @@ +#include "gntbox.h" + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_box_draw(GntWidget *widget) +{ + GntBox *box = GNT_BOX(widget); + GList *iter; + + for (iter = box->list; iter; iter = iter->next) + { + gnt_widget_draw(GNT_WIDGET(iter->data)); + } + + if (box->title) + { + gchar *title = g_strdup(box->title); + int pos = g_utf8_strlen(title, -1); + + if (pos >= widget->priv.width - 2) + { + g_utf8_strncpy(title, box->title, widget->priv.width - 2); + pos = 1; + } + else + { + /* XXX: Position of the title might be configurable */ + pos = (widget->priv.width - pos) / 2; + } + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE)); + mvwprintw(widget->window, 0, pos, title); + g_free(title); + } + wrefresh(widget->window); + + DEBUG; +} + +static void +reposition_children(GntWidget *widget) +{ + GList *iter; + GntBox *box = GNT_BOX(widget); + int w, h, curx, cury, max; + gboolean has_border = FALSE; + + w = h = 0; + max = -1; + curx = widget->priv.x; + cury = widget->priv.y; + if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) + { + has_border = TRUE; + curx += 1; + cury += 1; + } + + for (iter = box->list; iter; iter = iter->next) + { + gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury); + gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h); + if (box->vertical) + { + cury += h + box->pad; + if (max < w) + max = w; + } + else + { + curx += w + box->pad; + if (max < h) + max = h; + } + } + + if (has_border) + { + curx += 1; + cury += 1; + max += 2; + } + + if (box->vertical) + { + widget->priv.width = max; + widget->priv.height = cury - widget->priv.y; + } + else + { + widget->priv.width = curx - widget->priv.x; + widget->priv.height = max; + } +} + +static void +gnt_box_set_position(GntWidget *widget, int x, int y) +{ + gnt_widget_size_request(widget); + reposition_children(widget); +} + +static void +gnt_box_size_request(GntWidget *widget) +{ + GntBox *box = GNT_BOX(widget); + GList *iter; + + g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL); + + if (box->homogeneous) + { + int max = -1, w, h; + + /* XXX: should probably be changed based on vertical-ness */ + for (iter = box->list; iter; iter = iter->next) + { + gnt_widget_get_size(GNT_WIDGET(iter->data), &w, NULL); + if (max < w) + max = w; + } + + for (iter = box->list; iter; iter = iter->next) + { + gnt_widget_get_size(GNT_WIDGET(iter->data), NULL, &h); + gnt_widget_set_size(GNT_WIDGET(iter->data), max, h); + } + } + + reposition_children(widget); +} + +static void +gnt_box_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +/* Ensures that the current widget can take focus */ +static void +ensure_active(GntBox *box) +{ + int investigated = 0; + int total; + + if (box->active == NULL) + box->active = box->list; + + total = g_list_length(box->list); + + while (box->active && !GNT_WIDGET_IS_FLAG_SET(box->active->data, GNT_WIDGET_CAN_TAKE_FOCUS)) + { + box->active = box->active->next; + investigated++; + } + + /* Rotate if necessary */ + if (!box->active && investigated < total) + { + box->active = box->list; + while (investigated < total && !GNT_WIDGET_IS_FLAG_SET(box->active->data, GNT_WIDGET_CAN_TAKE_FOCUS)) + { + box->active = box->active->next; + investigated++; + } + } +} + +static gboolean +gnt_box_key_pressed(GntWidget *widget, const char *text) +{ + GntBox *box = GNT_BOX(widget); + + ensure_active(box); + if (box->active == NULL) + return FALSE; + + if (gnt_widget_key_pressed(box->active->data, text)) + return TRUE; + + if (text[0] == 27) + { + GList *now = NULL; + if (strcmp(text+1, GNT_KEY_LEFT) == 0) + { + now = box->active->prev; + if (now == NULL) + now = g_list_last(box->list); + } + else if (strcmp(text+1, GNT_KEY_RIGHT) == 0) + { + now = box->active->next; + if (now == NULL) + now = box->list; + } + + if (now) + { + gnt_widget_set_focus(box->active->data, FALSE); + box->active = now; + gnt_widget_set_focus(box->active->data, TRUE); + + return TRUE; + } + } + + return FALSE; +} + +static GntWidget *find_focused_widget(GntBox *box) +{ + GList *iter; + + for (iter = box->list; iter; iter = iter->next) + { + GntWidget *w = iter->data; + + if (GNT_IS_BOX(w)) + { + if ((w = find_focused_widget(GNT_BOX(w))) != NULL) + return w; + } + else + { + if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) && + GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS)) + return w; + } + } + return NULL; +} + +static void +gnt_box_lost_focus(GntWidget *widget) +{ + GntBox *box = GNT_BOX(widget); + GntWidget *p = widget; + + while (p->parent) + p = p->parent; + + p = find_focused_widget(GNT_BOX(p)); + if (p) + gnt_widget_set_focus(p, FALSE); +} + +static void +gnt_box_destroy(GntWidget *w) +{ + GntBox *box = GNT_BOX(w); + GList *iter; + + for (iter = box->list; iter; iter = iter->next) + { + gnt_widget_destroy(iter->data); + } + + g_list_free(box->list); +} + +static void +gnt_box_class_init(GntBoxClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->destroy = gnt_box_destroy; + parent_class->draw = gnt_box_draw; + parent_class->map = gnt_box_map; + parent_class->size_request = gnt_box_size_request; + parent_class->set_position = gnt_box_set_position; + parent_class->key_pressed = gnt_box_key_pressed; + parent_class->lost_focus = gnt_box_lost_focus; + + DEBUG; +} + +static void +gnt_box_init(GTypeInstance *instance, gpointer class) +{ + DEBUG; +} + +/****************************************************************************** + * GntBox API + *****************************************************************************/ +GType +gnt_box_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntBoxClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_box_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntBox), + 0, /* n_preallocs */ + gnt_box_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntBox", + &info, 0); + } + + return type; +} + +GntWidget *gnt_box_new(gboolean homo, gboolean vert) +{ + GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL); + GntBox *box = GNT_BOX(widget); + + box->homogeneous = homo; + box->vertical = vert; + box->pad = 1; + gnt_widget_set_take_focus(widget, TRUE); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + + return widget; +} + +void gnt_box_add_widget(GntBox *b, GntWidget *widget) +{ + b->list = g_list_append(b->list, widget); + widget->parent = GNT_WIDGET(b); +} + +void gnt_box_set_title(GntBox *b, const char *title) +{ + g_free(b->title); + b->title = g_strdup(title); +} + +void gnt_box_set_pad(GntBox *box, int pad) +{ + box->pad = pad; + /* XXX: Perhaps redraw if already showing? */ +} + +void gnt_box_set_toplevel(GntBox *box, gboolean set) +{ + GntWidget *widget = GNT_WIDGET(box); + if (set) + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + else + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); +} + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntbox.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntbox.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbox.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntbox.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,63 @@ +#ifndef GNT_BOX_H +#define GNT_BOX_H + +#include "gnt.h" +#include "gntwidget.h" + +#define GNT_TYPE_BOX (gnt_box_get_gtype()) +#define GNT_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BOX, GntBox)) +#define GNT_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BOX, GntBoxClass)) +#define GNT_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BOX)) +#define GNT_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BOX)) +#define GNT_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BOX, GntBoxClass)) + +typedef struct _GnBox GntBox; +typedef struct _GnBoxClass GntBoxClass; + +struct _GnBox +{ + GntWidget parent; + + gboolean vertical; + gboolean homogeneous; + GList *list; /* List of widgets */ + + GList *active; + int pad; /* Number of spaces to use between widgets */ + + char *title; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +struct _GnBoxClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_box_get_gtype(void); + +GntWidget *gnt_box_new(gboolean homo, gboolean vert); + +void gnt_box_add_widget(GntBox *box, GntWidget *widget); + +void gnt_box_set_title(GntBox *box, const char *title); + +void gnt_box_set_pad(GntBox *box, int pad); + +void gnt_box_set_toplevel(GntBox *box, gboolean set); + +G_END_DECLS + +#endif /* GNT_BOX_H */ + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntbox.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntbutton.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbutton.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntbutton.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,116 @@ +#include "gntbutton.h" + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_button_draw(GntWidget *widget) +{ + GntButton *button = GNT_BUTTON(widget); + GntColorType type; + + if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_HAS_FOCUS) + type = GNT_COLOR_HIGHLIGHT; + else + type = GNT_COLOR_NORMAL; + wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); + mvwprintw(widget->window, 1, 1, button->priv->text); + + wrefresh(widget->window); + + DEBUG; +} + +static void +gnt_button_size_request(GntWidget *widget) +{ + GntButton *button = GNT_BUTTON(widget); + widget->priv.width = g_utf8_strlen(button->priv->text, -1) + 2; + widget->priv.height = 3; +} + +static void +gnt_button_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_button_key_pressed(GntWidget *widget, const char *key) +{ + if (strcmp(key, GNT_KEY_ENTER) == 0) + { + gnt_widget_activate(widget); + return TRUE; + } + return FALSE; +} + +static void +gnt_button_class_init(GntWidgetClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->draw = gnt_button_draw; + parent_class->map = gnt_button_map; + parent_class->size_request = gnt_button_size_request; + parent_class->key_pressed = gnt_button_key_pressed; + + DEBUG; +} + +static void +gnt_button_init(GTypeInstance *instance, gpointer class) +{ + GntButton *button = GNT_BUTTON(instance); + button->priv = g_new0(GntButtonPriv, 1); + DEBUG; +} + +/****************************************************************************** + * GntButton API + *****************************************************************************/ +GType +gnt_button_get_gtype(void) { + static GType type = 0; + + if(type == 0) { + static const GTypeInfo info = { + sizeof(GntButtonClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_button_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntButton), + 0, /* n_preallocs */ + gnt_button_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntButton", + &info, 0); + } + + return type; +} + +GntWidget *gnt_button_new(const char *text) +{ + GntWidget *widget = g_object_new(GNT_TYPE_BUTTON, NULL); + GntButton *button = GNT_BUTTON(widget); + + button->priv->text = g_strdup(text); + gnt_widget_set_take_focus(widget, TRUE); + + return widget; +} + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntbutton.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntbutton.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbutton.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntbutton.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,55 @@ +#ifndef GNT_BUTTON_H +#define GNT_BUTTON_H + +#include <glib.h> +#include <glib-object.h> +#include "gnt.h" +#include "gntwidget.h" + +#define GNT_TYPE_BUTTON (gnt_button_get_gtype()) +#define GNT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BUTTON, GntButton)) +#define GNT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BUTTON, GntButtonClass)) +#define GNT_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BUTTON)) +#define GNT_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BUTTON)) +#define GNT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BUTTON, GntButtonClass)) + +typedef struct _GnButton GntButton; +typedef struct _GnButtonPriv GntButtonPriv; +typedef struct _GnButtonClass GntButtonClass; + +struct _GnButtonPriv +{ + char *text; +}; + +struct _GnButton +{ + GntWidget parent; + + GntButtonPriv *priv; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +struct _GnButtonClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_button_get_gtype(void); + +GntWidget *gnt_button_new(const char *text); + +G_END_DECLS + +#endif /* GNT_BUTTON_H */ Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntbutton.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntcolors.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcolors.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntcolors.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,33 @@ +#include <ncursesw/ncurses.h> +#include "gntcolors.h" + +void gnt_init_colors() +{ + if (can_change_color()) + { + /* XXX: Do some init_color()s */ + init_color(GNT_COLOR_BLACK, 0, 0, 0); + init_color(GNT_COLOR_RED, 1000, 0, 0); + init_color(GNT_COLOR_GREEN, 0, 1000, 0); + init_color(GNT_COLOR_BLUE, 0, 0, 1000); + init_color(GNT_COLOR_WHITE, 1000, 1000, 1000); + init_color(GNT_COLOR_GRAY, 799, 799, 799); + init_color(GNT_COLOR_DARK_GRAY, 256, 256, 256); + + /* Now some init_pair()s */ + init_pair(GNT_COLOR_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_WHITE); + init_pair(GNT_COLOR_HIGHLIGHT, GNT_COLOR_BLUE, GNT_COLOR_GRAY); + init_pair(GNT_COLOR_SHADOW, GNT_COLOR_BLACK, GNT_COLOR_DARK_GRAY); + init_pair(GNT_COLOR_TITLE, GNT_COLOR_WHITE, GNT_COLOR_DARK_GRAY); + init_pair(GNT_COLOR_TEXT_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_GRAY); + } + else + { + init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); + init_pair(GNT_COLOR_HIGHLIGHT, COLOR_CYAN, COLOR_BLACK); + init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK); + init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLACK); + init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_BLACK, COLOR_WHITE); + } +} + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntcolors.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntcolors.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcolors.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntcolors.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,34 @@ +#ifndef GNT_COLORS_H +#define GNT_COLORS_H + +typedef enum +{ + GNT_COLOR_NORMAL = 1, + GNT_COLOR_HIGHLIGHT, /* eg. when a button is selected */ + GNT_COLOR_DISABLED, /* eg. when a button is disabled */ + GNT_COLOR_HIGHLIGHT_D, /* eg. when a button is selected, but some other window is in focus */ + GNT_COLOR_TEXT_NORMAL, + GNT_COLOR_TEXT_INACTIVE, /* when the entry is out of focus */ + GNT_COLOR_MNEMONIC, + GNT_COLOR_MNEMONIC_D, + GNT_COLOR_SHADOW, + GNT_COLOR_TITLE, + GNT_COLORS +} GntColorType; + +enum +{ + GNT_COLOR_BLACK = 1, + GNT_COLOR_RED, + GNT_COLOR_GREEN, + GNT_COLOR_BLUE, + GNT_COLOR_WHITE, + GNT_COLOR_GRAY, + GNT_COLOR_DARK_GRAY, + GNT_TOTAL_COLORS +}; + +/* populate some default colors */ +void gnt_init_colors(); + +#endif Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntcolors.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntentry.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntentry.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntentry.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,251 @@ +#include <string.h> +#include "gntentry.h" + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_entry_draw(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + int stop; + + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TEXT_NORMAL)); + mvwprintw(widget->window, 0, 0, entry->scroll); + + stop = entry->end - entry->scroll; + if (stop < widget->priv.width) + mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop); + + wrefresh(widget->window); + + DEBUG; +} + +static void +gnt_entry_size_request(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + widget->priv.height = 1; + widget->priv.width = 20; +} + +static void +gnt_entry_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_entry_key_pressed(GntWidget *widget, const char *text) +{ + GntEntry *entry = GNT_ENTRY(widget); + + if (text[0] == 27) + { + if (strcmp(text + 1, GNT_KEY_DEL) == 0 && entry->cursor < entry->end) + { + memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor + 1); + entry->end--; + gnt_entry_draw(widget); + } + else if (strcmp(text + 1, GNT_KEY_LEFT) == 0 && entry->cursor > entry->start) + { + entry->cursor--; + if (entry->cursor < entry->scroll) + entry->scroll--; + gnt_entry_draw(widget); + } + else if (strcmp(text + 1, GNT_KEY_RIGHT) == 0 && entry->cursor < entry->end) + { + entry->cursor++; + if (entry->cursor - entry->scroll > widget->priv.width) + entry->scroll++; + gnt_entry_draw(widget); + } + /* XXX: handle other keys, like home/end, and ctrl+ goodness */ + } + else + { + if (!iscntrl(text[0])) + { + int i; + + for (i = 0; text[i]; i++) + { + /* Valid input? */ + if (ispunct(text[i]) && (entry->flag & GNT_ENTRY_FLAG_NO_PUNCT)) + continue; + if (isspace(text[i]) && (entry->flag & GNT_ENTRY_FLAG_NO_SPACE)) + continue; + if (isalpha(text[i]) && !(entry->flag & GNT_ENTRY_FLAG_ALPHA)) + continue; + if (isdigit(text[i]) && !(entry->flag & GNT_ENTRY_FLAG_INT)) + continue; + + /* Reached the max? */ + if (entry->max && entry->end - entry->start >= entry->max) + continue; + + if (entry->end - entry->start >= entry->buffer) + { + char *tmp = g_strdup_printf(entry->start); + gnt_entry_set_text(entry, tmp); + g_free(tmp); + } + + *(entry->cursor) = text[i]; + entry->cursor++; + + entry->end++; + if (entry->cursor - entry->scroll > widget->priv.width) + entry->scroll++; + } + gnt_entry_draw(widget); + } + else + { + /* Backspace is here */ + if (strcmp(text, GNT_KEY_BACKSPACE) == 0 && entry->cursor > entry->start) + { + entry->cursor--; + memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor); + entry->end--; + + if (entry->scroll > entry->start) + entry->scroll--; + + gnt_entry_draw(widget); + } + } + } + + return FALSE; +} + +static void +gnt_entry_destroy(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + g_free(entry->start); +} + +static void +gnt_entry_class_init(GntEntryClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->destroy = gnt_entry_destroy; + parent_class->draw = gnt_entry_draw; + parent_class->map = gnt_entry_map; + parent_class->size_request = gnt_entry_size_request; + parent_class->key_pressed = gnt_entry_key_pressed; + + DEBUG; +} + +static void +gnt_entry_init(GTypeInstance *instance, gpointer class) +{ + GntEntry *entry = GNT_ENTRY(instance); + + entry->flag = GNT_ENTRY_FLAG_ALL; + entry->max = 0; + + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), + GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS); + + DEBUG; +} + +/****************************************************************************** + * GntEntry API + *****************************************************************************/ +GType +gnt_entry_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntEntryClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_entry_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntEntry), + 0, /* n_preallocs */ + gnt_entry_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntEntry", + &info, 0); + } + + return type; +} + +GntWidget *gnt_entry_new(const char *text) +{ + GntWidget *widget = g_object_new(GNT_TYPE_ENTRY, NULL); + GntEntry *entry = GNT_ENTRY(widget); + + gnt_entry_set_text(entry, text); + + return widget; +} + +void gnt_entry_set_text(GntEntry *entry, const char *text) +{ + int len; + int scroll, cursor; + + g_free(entry->start); + + if (text && text[0]) + { + len = g_utf8_strlen(text, -1); + entry->buffer = len * 2; + } + else + { + entry->buffer = 128; + len = 0; + } + + scroll = entry->scroll - entry->start; + cursor = entry->end - entry->cursor; + + entry->start = g_new0(char, entry->buffer); + if (text) + snprintf(entry->start, len + 1, "%s", text); + entry->end = entry->start + len; + + entry->scroll = entry->start + scroll; + entry->cursor = entry->end - cursor; + + /* XXX: redraw if necessary? */ +} + +void gnt_entry_set_max(GntEntry *entry, int max) +{ + entry->max = max; +} + +void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag) +{ + entry->flag = flag; + /* XXX: Check the existing string to make sure the flags are respected? */ +} + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntentry.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntentry.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntentry.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntentry.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,78 @@ +#ifndef GNT_ENTRY_H +#define GNT_ENTRY_H + +#include "gntwidget.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_ENTRY (gnt_entry_get_gtype()) +#define GNT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_ENTRY, GntEntry)) +#define GNT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_ENTRY, GntEntryClass)) +#define GNT_IS_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_ENTRY)) +#define GNT_IS_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_ENTRY)) +#define GNT_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_ENTRY, GntEntryClass)) + +#define GNT_ENTRY_FLAGS(obj) (GNT_ENTRY(obj)->priv.flags) +#define GNT_ENTRY_SET_FLAGS(obj, flags) (GNT_ENTRY_FLAGS(obj) |= flags) +#define GNT_ENTRY_UNSET_FLAGS(obj, flags) (GNT_ENTRY_FLAGS(obj) &= ~(flags)) + +#define ENTRY_CHAR '_' /* The character to use to fill in the blank places */ + +typedef struct _GnEntry GntEntry; +typedef struct _GnEntryPriv GntEntryPriv; +typedef struct _GnEntryClass GntEntryClass; + +typedef enum +{ + GNT_ENTRY_FLAG_ALPHA = 1 << 0, /* Only alpha */ + GNT_ENTRY_FLAG_INT = 1 << 1, /* Only integer */ + GNT_ENTRY_FLAG_NO_SPACE = 1 << 2, /* No blank space is allowed */ + GNT_ENTRY_FLAG_NO_PUNCT = 1 << 3, /* No punctuations */ + GNT_ENTRY_FLAG_MASK = 1 << 4, /* Mask the inputs */ +} GntEntryFlag; + +#define GNT_ENTRY_FLAG_ALL (GNT_ENTRY_FLAG_ALPHA | GNT_ENTRY_FLAG_INT) + +struct _GnEntry +{ + GntWidget parent; + + GntEntryFlag flag; + + char *start; + char *end; + char *scroll; /* Current scrolling position */ + char *cursor; /* Cursor location */ + /* 0 <= cursor - scroll < widget-width */ + + size_t buffer; /* Size of the buffer */ + + int max; /* 0 means infinite */ +}; + +struct _GnEntryClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_entry_get_gtype(void); + +GntWidget *gnt_entry_new(const char *text); + +void gnt_entry_set_max(GntEntry *entry, int max); + +void gnt_entry_set_text(GntEntry *entry, const char *text); + +void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag); + +G_END_DECLS + +#endif /* GNT_ENTRY_H */ Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntentry.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntkeys.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntkeys.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntkeys.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,17 @@ +#ifndef GNT_KEYS_H +#define GNT_KEYS_H + +#define GNT_KEY_POPUP "[29~" + +/* Arrow keys */ +#define GNT_KEY_LEFT "[D" +#define GNT_KEY_RIGHT "[C" +#define GNT_KEY_UP "[A" +#define GNT_KEY_DOWN "[B" + +#define GNT_KEY_ENTER "\r" + +#define GNT_KEY_BACKSPACE "\177" +#define GNT_KEY_DEL "[3~" + +#endif Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntkeys.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntlabel.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntlabel.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntlabel.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,120 @@ +#include "gntlabel.h" + +#include <string.h> + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_label_destroy(GntWidget *widget) +{ + GntLabel *label = GNT_LABEL(widget); + g_free(label->text); +} + +static void +gnt_label_draw(GntWidget *widget) +{ + GntLabel *label = GNT_LABEL(widget); + + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + mvwprintw(widget->window, 0, 0, label->text); + wrefresh(widget->window); + + DEBUG; +} + +static void +gnt_label_size_request(GntWidget *widget) +{ + GntLabel *label = GNT_LABEL(widget); + char *s = label->text, *last = s; + int count = 1; + int max = 0; + + /* XXX: ew ... everyone look away */ + while (*s) + { + if (*s == '\n' || *s == '\r') + { + count++; + if (max < s - last + 1) + max = s - last + 1; + last = s + 1; + } + s++; + } + if (max < s - last + 1) + max = s - last + 1; + widget->priv.height = count; + + widget->priv.width = max; +} + +static void +gnt_label_class_init(GntLabelClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->destroy = gnt_label_destroy; + parent_class->draw = gnt_label_draw; + parent_class->map = NULL; + parent_class->size_request = gnt_label_size_request; + + DEBUG; +} + +static void +gnt_label_init(GTypeInstance *instance, gpointer class) +{ + DEBUG; +} + +/****************************************************************************** + * GntLabel API + *****************************************************************************/ +GType +gnt_label_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntLabelClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_label_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntLabel), + 0, /* n_preallocs */ + gnt_label_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntLabel", + &info, 0); + } + + return type; +} + +GntWidget *gnt_label_new(const char *text) +{ + GntWidget *widget = g_object_new(GNT_TYPE_LABEL, NULL); + GntLabel *label = GNT_LABEL(widget); + + label->text = g_strdup(text); + gnt_widget_set_take_focus(widget, FALSE); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + + return widget; +} + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntlabel.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntlabel.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntlabel.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntlabel.h 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,48 @@ +#ifndef GNT_LABEL_H +#define GNT_LABEL_H + +#include "gnt.h" +#include "gntwidget.h" + +#define GNT_TYPE_LABEL (gnt_label_get_gtype()) +#define GNT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_LABEL, GntLabel)) +#define GNT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_LABEL, GntLabelClass)) +#define GNT_IS_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_LABEL)) +#define GNT_IS_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LABEL)) +#define GNT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LABEL, GntLabelClass)) + +typedef struct _GnLabel GntLabel; +typedef struct _GnLabelClass GntLabelClass; + +struct _GnLabel +{ + GntWidget parent; + + char *text; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +struct _GnLabelClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_label_get_gtype(void); + +GntWidget *gnt_label_new(const char *text); + +G_END_DECLS + +#endif /* GNT_LABEL_H */ + Property changes on: branches/soc-2006-file-loggers/console/libgnt/gntlabel.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: branches/soc-2006-file-loggers/console/libgnt/gntmain.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntmain.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntmain.c 2006-06-25 23:08:49 UTC (rev 16337) @@ -0,0 +1,110 @@ +#include "gnt.h" +#include "gntkeys.h" +#include "gntcolors.h" +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> + +static GList *focus_list; +static int max_x; +static int max_y; + +void gnt_screen_take_focus(GntWidget *widget) +{ + focus_list = g_list_prepend(focus_list, widget); +} + +void gnt_screen_remove_widget(GntWidget *widget) +{ + focus_list = g_list_remove(focus_list, widget); + if (focus_list) + gnt_widge... [truncated message content] |
From: <ro...@us...> - 2006-07-02 16:05:50
|
Revision: 16396 Author: roast Date: 2006-07-02 09:02:29 -0700 (Sun, 02 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16396&view=rev Log Message: ----------- merged with svn trunk. 16338:16395. Modified Paths: -------------- branches/soc-2006-file-loggers/COPYRIGHT branches/soc-2006-file-loggers/ChangeLog branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/console/Makefile branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/gntgaim.c branches/soc-2006-file-loggers/console/gntui.c branches/soc-2006-file-loggers/console/libgnt/gnt.h branches/soc-2006-file-loggers/console/libgnt/gntbox.c branches/soc-2006-file-loggers/console/libgnt/gntbox.h branches/soc-2006-file-loggers/console/libgnt/gntbutton.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.h branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntentry.h branches/soc-2006-file-loggers/console/libgnt/gntkeys.h branches/soc-2006-file-loggers/console/libgnt/gntlabel.c branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.h branches/soc-2006-file-loggers/doc/C-HOWTO.dox branches/soc-2006-file-loggers/pixmaps/smileys/default/Makefile.am branches/soc-2006-file-loggers/pixmaps/smileys/default/theme branches/soc-2006-file-loggers/pixmaps/status/default/Makefile.am branches/soc-2006-file-loggers/src/blist.c branches/soc-2006-file-loggers/src/blist.h branches/soc-2006-file-loggers/src/buddyicon.c branches/soc-2006-file-loggers/src/dnssrv.c branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/protocols/Makefile.am branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.c branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.h branches/soc-2006-file-loggers/src/protocols/irc/cmds.c branches/soc-2006-file-loggers/src/protocols/irc/irc.h branches/soc-2006-file-loggers/src/protocols/irc/msgs.c branches/soc-2006-file-loggers/src/protocols/irc/parse.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/presence.c branches/soc-2006-file-loggers/src/protocols/msn/dialog.c branches/soc-2006-file-loggers/src/protocols/msn/session.c branches/soc-2006-file-loggers/src/protocols/oscar/family_feedbag.c branches/soc-2006-file-loggers/src/protocols/oscar/family_oservice.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.h branches/soc-2006-file-loggers/src/protocols/silc/silc.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c Added Paths: ----------- branches/soc-2006-file-loggers/console/gntconv.c branches/soc-2006-file-loggers/console/gntconv.h branches/soc-2006-file-loggers/console/libgnt/AUTHORS branches/soc-2006-file-loggers/console/libgnt/COPYING branches/soc-2006-file-loggers/console/libgnt/ChangeLog branches/soc-2006-file-loggers/console/libgnt/INSTALL branches/soc-2006-file-loggers/console/libgnt/Makefile.am branches/soc-2006-file-loggers/console/libgnt/NEWS branches/soc-2006-file-loggers/console/libgnt/README branches/soc-2006-file-loggers/console/libgnt/autogen.sh branches/soc-2006-file-loggers/console/libgnt/configure.ac branches/soc-2006-file-loggers/console/libgnt/gnt.pc.in branches/soc-2006-file-loggers/console/libgnt/gnttextview.c branches/soc-2006-file-loggers/console/libgnt/gnttextview.h branches/soc-2006-file-loggers/console/libgnt/test/ branches/soc-2006-file-loggers/console/libgnt/test/Makefile branches/soc-2006-file-loggers/console/libgnt/test/focus.c branches/soc-2006-file-loggers/console/libgnt/test/multiwin.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_0.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_1.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_10.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_11.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_12.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_13.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_14.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_15.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_16.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_17.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_18.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_19.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_2.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_20.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_21.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_22.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_23.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_24.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_25.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_26.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_27.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_28.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_29.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_3.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_30.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_31.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_32.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_33.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_34.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_35.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_36.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_37.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_38.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_39.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_4.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_40.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_41.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_42.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_43.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_44.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_45.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_46.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_47.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_48.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_49.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_5.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_50.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_51.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_52.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_53.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_54.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_55.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_56.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_57.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_58.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_59.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_6.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_60.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_61.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_62.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_63.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_64.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_65.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_66.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_67.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_68.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_69.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_7.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_70.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_71.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_72.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_73.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_74.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_75.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_76.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_77.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_78.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_79.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_8.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_80.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_81.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_82.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_83.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_84.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_85.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_86.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_87.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_88.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_89.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_9.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_90.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_91.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_92.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_93.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_94.gif branches/soc-2006-file-loggers/pixmaps/smileys/default/qq_smiley_95.gif branches/soc-2006-file-loggers/pixmaps/status/default/qq.png branches/soc-2006-file-loggers/src/protocols/qq/ branches/soc-2006-file-loggers/src/protocols/qq/Makefile.am branches/soc-2006-file-loggers/src/protocols/qq/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/qq/TODO branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.h branches/soc-2006-file-loggers/src/protocols/qq/char_conv.c branches/soc-2006-file-loggers/src/protocols/qq/char_conv.h branches/soc-2006-file-loggers/src/protocols/qq/crypt.c branches/soc-2006-file-loggers/src/protocols/qq/crypt.h branches/soc-2006-file-loggers/src/protocols/qq/file_trans.c branches/soc-2006-file-loggers/src/protocols/qq/file_trans.h branches/soc-2006-file-loggers/src/protocols/qq/group.c branches/soc-2006-file-loggers/src/protocols/qq/group.h branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.c branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.h branches/soc-2006-file-loggers/src/protocols/qq/group_conv.c branches/soc-2006-file-loggers/src/protocols/qq/group_conv.h branches/soc-2006-file-loggers/src/protocols/qq/group_find.c branches/soc-2006-file-loggers/src/protocols/qq/group_find.h branches/soc-2006-file-loggers/src/protocols/qq/group_free.c branches/soc-2006-file-loggers/src/protocols/qq/group_free.h branches/soc-2006-file-loggers/src/protocols/qq/group_hash.c branches/soc-2006-file-loggers/src/protocols/qq/group_hash.h branches/soc-2006-file-loggers/src/protocols/qq/group_im.c branches/soc-2006-file-loggers/src/protocols/qq/group_im.h branches/soc-2006-file-loggers/src/protocols/qq/group_info.c branches/soc-2006-file-loggers/src/protocols/qq/group_info.h branches/soc-2006-file-loggers/src/protocols/qq/group_join.c branches/soc-2006-file-loggers/src/protocols/qq/group_join.h branches/soc-2006-file-loggers/src/protocols/qq/group_misc.c branches/soc-2006-file-loggers/src/protocols/qq/group_misc.h branches/soc-2006-file-loggers/src/protocols/qq/group_network.c branches/soc-2006-file-loggers/src/protocols/qq/group_network.h branches/soc-2006-file-loggers/src/protocols/qq/group_opt.c branches/soc-2006-file-loggers/src/protocols/qq/group_opt.h branches/soc-2006-file-loggers/src/protocols/qq/group_search.c branches/soc-2006-file-loggers/src/protocols/qq/group_search.h branches/soc-2006-file-loggers/src/protocols/qq/header_info.c branches/soc-2006-file-loggers/src/protocols/qq/header_info.h branches/soc-2006-file-loggers/src/protocols/qq/im.c branches/soc-2006-file-loggers/src/protocols/qq/im.h branches/soc-2006-file-loggers/src/protocols/qq/infodlg.c branches/soc-2006-file-loggers/src/protocols/qq/infodlg.h branches/soc-2006-file-loggers/src/protocols/qq/ip_location.c branches/soc-2006-file-loggers/src/protocols/qq/ip_location.h branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.c branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.h branches/soc-2006-file-loggers/src/protocols/qq/login_logout.c branches/soc-2006-file-loggers/src/protocols/qq/login_logout.h branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.c branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.h branches/soc-2006-file-loggers/src/protocols/qq/qq.c branches/soc-2006-file-loggers/src/protocols/qq/qq.h branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.h branches/soc-2006-file-loggers/src/protocols/qq/recv_core.c branches/soc-2006-file-loggers/src/protocols/qq/recv_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_core.c branches/soc-2006-file-loggers/src/protocols/qq/send_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_file.c branches/soc-2006-file-loggers/src/protocols/qq/send_file.h branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.c branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.h branches/soc-2006-file-loggers/src/protocols/qq/show.c branches/soc-2006-file-loggers/src/protocols/qq/show.h branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.c branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.h branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.c branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.h branches/soc-2006-file-loggers/src/protocols/qq/utils.c branches/soc-2006-file-loggers/src/protocols/qq/utils.h Removed Paths: ------------- branches/soc-2006-file-loggers/console/libgnt/Makefile branches/soc-2006-file-loggers/console/libgnt/test/Makefile branches/soc-2006-file-loggers/console/libgnt/test/focus.c branches/soc-2006-file-loggers/console/libgnt/test/multiwin.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/src/protocols/qq/Makefile.am branches/soc-2006-file-loggers/src/protocols/qq/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/qq/TODO branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.h branches/soc-2006-file-loggers/src/protocols/qq/char_conv.c branches/soc-2006-file-loggers/src/protocols/qq/char_conv.h branches/soc-2006-file-loggers/src/protocols/qq/crypt.c branches/soc-2006-file-loggers/src/protocols/qq/crypt.h branches/soc-2006-file-loggers/src/protocols/qq/file_trans.c branches/soc-2006-file-loggers/src/protocols/qq/file_trans.h branches/soc-2006-file-loggers/src/protocols/qq/group.c branches/soc-2006-file-loggers/src/protocols/qq/group.h branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.c branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.h branches/soc-2006-file-loggers/src/protocols/qq/group_conv.c branches/soc-2006-file-loggers/src/protocols/qq/group_conv.h branches/soc-2006-file-loggers/src/protocols/qq/group_find.c branches/soc-2006-file-loggers/src/protocols/qq/group_find.h branches/soc-2006-file-loggers/src/protocols/qq/group_free.c branches/soc-2006-file-loggers/src/protocols/qq/group_free.h branches/soc-2006-file-loggers/src/protocols/qq/group_hash.c branches/soc-2006-file-loggers/src/protocols/qq/group_hash.h branches/soc-2006-file-loggers/src/protocols/qq/group_im.c branches/soc-2006-file-loggers/src/protocols/qq/group_im.h branches/soc-2006-file-loggers/src/protocols/qq/group_info.c branches/soc-2006-file-loggers/src/protocols/qq/group_info.h branches/soc-2006-file-loggers/src/protocols/qq/group_join.c branches/soc-2006-file-loggers/src/protocols/qq/group_join.h branches/soc-2006-file-loggers/src/protocols/qq/group_misc.c branches/soc-2006-file-loggers/src/protocols/qq/group_misc.h branches/soc-2006-file-loggers/src/protocols/qq/group_network.c branches/soc-2006-file-loggers/src/protocols/qq/group_network.h branches/soc-2006-file-loggers/src/protocols/qq/group_opt.c branches/soc-2006-file-loggers/src/protocols/qq/group_opt.h branches/soc-2006-file-loggers/src/protocols/qq/group_search.c branches/soc-2006-file-loggers/src/protocols/qq/group_search.h branches/soc-2006-file-loggers/src/protocols/qq/header_info.c branches/soc-2006-file-loggers/src/protocols/qq/header_info.h branches/soc-2006-file-loggers/src/protocols/qq/im.c branches/soc-2006-file-loggers/src/protocols/qq/im.h branches/soc-2006-file-loggers/src/protocols/qq/infodlg.c branches/soc-2006-file-loggers/src/protocols/qq/infodlg.h branches/soc-2006-file-loggers/src/protocols/qq/ip_location.c branches/soc-2006-file-loggers/src/protocols/qq/ip_location.h branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.c branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.h branches/soc-2006-file-loggers/src/protocols/qq/login_logout.c branches/soc-2006-file-loggers/src/protocols/qq/login_logout.h branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.c branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.h branches/soc-2006-file-loggers/src/protocols/qq/qq.c branches/soc-2006-file-loggers/src/protocols/qq/qq.h branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.h branches/soc-2006-file-loggers/src/protocols/qq/recv_core.c branches/soc-2006-file-loggers/src/protocols/qq/recv_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_core.c branches/soc-2006-file-loggers/src/protocols/qq/send_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_file.c branches/soc-2006-file-loggers/src/protocols/qq/send_file.h branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.c branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.h branches/soc-2006-file-loggers/src/protocols/qq/show.c branches/soc-2006-file-loggers/src/protocols/qq/show.h branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.c branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.h branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.c branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.h branches/soc-2006-file-loggers/src/protocols/qq/utils.c branches/soc-2006-file-loggers/src/protocols/qq/utils.h Modified: branches/soc-2006-file-loggers/COPYRIGHT =================================================================== --- branches/soc-2006-file-loggers/COPYRIGHT 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/COPYRIGHT 2006-07-02 16:02:29 UTC (rev 16396) @@ -59,6 +59,7 @@ Eoin Coffey Jason Cohen Todd Cohen +Jono Cole Nathan Conrad Felipe Contreras Alex Converse @@ -302,6 +303,7 @@ Wan Hing Wah Philip Walford Nathan Walp +Jonty Wareing Eric Warmenhoven Adam J. Warrington Andrew Wellington Modified: branches/soc-2006-file-loggers/ChangeLog =================================================================== --- branches/soc-2006-file-loggers/ChangeLog 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/ChangeLog 2006-07-02 16:02:29 UTC (rev 16396) @@ -130,6 +130,7 @@ channel or change your nick * Added /nickserv, /memoserv, /chanserv and /operserv commands (Joao Luís Marques Pinto) + * Added CTCP VERSION via /version (Andrej Krivulčík) Jabber Features: * Support for SRV lookups Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/configure.ac 2006-07-02 16:02:29 UTC (rev 16396) @@ -401,7 +401,7 @@ fi if test "x$STATIC_PRPLS" = "xall" ; then - STATIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr" + STATIC_PRPLS="bonjour gg irc jabber msn novell oscar qq sametime silc simple yahoo zephyr" fi if test "x$have_meanwhile" != "xyes" ; then STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'` @@ -436,6 +436,7 @@ msn) static_msn=yes ;; novell) static_novell=yes ;; oscar) static_oscar=yes ;; + qq) static_qq=yes ;; sametime) static_sametime=yes ;; silc) static_silc=yes ;; simple) static_simple=yes ;; @@ -452,6 +453,7 @@ AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes") AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes") AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes") +AM_CONDITIONAL(STATIC_QQ, test "x$static_qq" = "xyes") AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes") AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes") AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes") @@ -464,7 +466,7 @@ AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`]) if test "x$DYNAMIC_PRPLS" = "xall" ; then - DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr" + DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar qq sametime silc simple yahoo zephyr" fi if test "x$have_meanwhile" != "xyes"; then DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'` @@ -488,6 +490,7 @@ msn) dynamic_msn=yes ;; novell) dynamic_novell=yes ;; oscar) dynamic_oscar=yes ;; + qq) dynamic_qq=yes ;; sametime) dynamic_sametime=yes ;; silc) dynamic_silc=yes ;; simple) dynamic_simple=yes ;; @@ -504,6 +507,7 @@ AM_CONDITIONAL(DYNAMIC_MSN, test "x$dynamic_msn" = "xyes") AM_CONDITIONAL(DYNAMIC_NOVELL, test "x$dynamic_novell" = "xyes") AM_CONDITIONAL(DYNAMIC_OSCAR, test "x$dynamic_oscar" = "xyes") +AM_CONDITIONAL(DYNAMIC_QQ, test "x$dynamic_qq" = "xyes") AM_CONDITIONAL(DYNAMIC_SAMETIME, test "x$dynamic_sametime" = "xyes" -a "x$have_meanwhile" = "xyes") AM_CONDITIONAL(DYNAMIC_SILC, test "x$dynamic_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes") AM_CONDITIONAL(DYNAMIC_SIMPLE, test "x$dynamic_simple" = "xyes") @@ -1772,6 +1776,7 @@ src/protocols/napster/Makefile src/protocols/novell/Makefile src/protocols/oscar/Makefile + src/protocols/qq/Makefile src/protocols/sametime/Makefile src/protocols/silc/Makefile src/protocols/simple/Makefile Modified: branches/soc-2006-file-loggers/console/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/Makefile 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/Makefile 2006-07-02 16:02:29 UTC (rev 16396) @@ -1,30 +1,32 @@ -CFLAGS=`pkg-config --cflags gaim gobject-2.0` -g -I./libgnt/ -LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0` -lncursesw -L./libgnt/ -lgnt -pg +CC=gcc +CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall +LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg GG_SOURCES = \ gntblist.c \ + gntconv.c \ gntui.c GG_HEADERS = \ gntblist.h \ + gntconv.h \ gntui.h GG_OBJECTS = \ gntblist.o \ + gntconv.o \ gntui.o -all: - cd libgnt && make - make gntgaim +all: gntgaim gntgaim: gntgaim.o $(GG_OBJECTS) $(CC) -o gntgaim gntgaim.o $(GG_OBJECTS) $(LDFLAGS) gntblist.o: gntblist.c $(GG_HEADERS) +gntconv.o: gntconv.c $(GG_HEADERS) gntgaim.o: gntgaim.c gntgaim.h $(GG_HEADERS) gntui.o: gntui.c $(GG_HEADERS) clean: - cd libgnt && make clean - rm *.o - rm gntgaim + rm -f *.o + rm -f gntgaim Modified: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -1,11 +1,12 @@ -#include <gaim/account.h> -#include <gaim/blist.h> +#include <account.h> +#include <blist.h> +#include <server.h> #include <signal.h> -#include <gaim/util.h> -#include <gaim/server.h> +#include <util.h> #include "gntgaim.h" #include "gntbox.h" +#include "gntlabel.h" #include "gnttree.h" #include "gntblist.h" @@ -24,6 +25,7 @@ static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist); static void add_group(GaimGroup *group, GGBlist *ggblist); +static void add_chat(GaimChat *chat, GGBlist *ggblist); static void add_node(GaimBlistNode *node, GGBlist *ggblist); static void draw_tooltip(GGBlist *ggblist); @@ -38,6 +40,8 @@ add_buddy((GaimBuddy*)node, ggblist); else if (GAIM_BLIST_NODE_IS_GROUP(node)) add_group((GaimGroup*)node, ggblist); + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + add_chat((GaimChat *)node, ggblist); draw_tooltip(ggblist); } @@ -81,6 +85,10 @@ else node_remove(gaim_get_blist(), node); } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + add_chat((GaimChat *)node, list->ui_data); + } } static void @@ -121,52 +129,82 @@ } static const char * -get_buddy_display_name(GaimBuddy *buddy) +get_display_name(GaimBlistNode *node) { static char text[2096]; - char status[8]; - GaimStatusPrimitive prim; - GaimPresence *presence; - GaimStatus *now; + char status[8] = " "; + const char *name = NULL; - presence = gaim_buddy_get_presence(buddy); - now = gaim_presence_get_active_status(presence); + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy *)node; + GaimStatusPrimitive prim; + GaimPresence *presence; + GaimStatus *now; - prim = gaim_status_type_get_primitive(gaim_status_get_type(now)); + + presence = gaim_buddy_get_presence(buddy); + now = gaim_presence_get_active_status(presence); - switch(prim) - { + prim = gaim_status_type_get_primitive(gaim_status_get_type(now)); + + switch(prim) + { #if 1 - case GAIM_STATUS_OFFLINE: - strncpy(status, "x", sizeof(status) - 1); - break; - case GAIM_STATUS_AVAILABLE: - strncpy(status, "o", sizeof(status) - 1); - break; - default: - strncpy(status, ".", sizeof(status) - 1); - break; + case GAIM_STATUS_OFFLINE: + strncpy(status, "x", sizeof(status) - 1); + break; + case GAIM_STATUS_AVAILABLE: + strncpy(status, "o", sizeof(status) - 1); + break; + default: + strncpy(status, ".", sizeof(status) - 1); + break; #else - /* XXX: Let's use these some time */ - case GAIM_STATUS_OFFLINE: - strncpy(status, "⊗", sizeof(status) - 1); - break; - case GAIM_STATUS_AVAILABLE: - /* XXX: Detect idleness */ - strncpy(status, "◯", sizeof(status) - 1); - break; - default: - strncpy(status, "⊖", sizeof(status) - 1); - break; + /* XXX: Let's use these some time */ + case GAIM_STATUS_OFFLINE: + strncpy(status, "⊗", sizeof(status) - 1); + break; + case GAIM_STATUS_AVAILABLE: + /* XXX: Detect idleness */ + strncpy(status, "◯", sizeof(status) - 1); + break; + default: + strncpy(status, "⊖", sizeof(status) - 1); + break; #endif + } + name = gaim_buddy_get_alias(buddy); } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat*)node; + name = gaim_chat_get_name(chat); - snprintf(text, sizeof(text) - 1, "%s %s", status, gaim_buddy_get_alias(buddy)); + strncpy(status, "~", sizeof(status) - 1); + } + snprintf(text, sizeof(text) - 1, "%s %s", status, name); + return text; } static void +add_chat(GaimChat *chat, GGBlist *ggblist) +{ + GaimGroup *group; + GaimBlistNode *node = (GaimBlistNode *)chat; + if (node->ui_data) + return; + + group = gaim_chat_get_group(chat); + add_node((GaimBlistNode*)group, ggblist); + + node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), chat, + get_display_name(node), group, NULL); +} + +static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist) { GaimGroup *group; @@ -178,9 +216,10 @@ add_node((GaimBlistNode*)group, ggblist); node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy, - get_buddy_display_name(buddy), group, NULL); + get_display_name(node), group, NULL); } +#if 0 static void buddy_signed_on(GaimBuddy *buddy, GGBlist *ggblist) { @@ -192,6 +231,7 @@ { node_remove(gaim_get_blist(), (GaimBlistNode*)buddy); } +#endif GaimBlistUiOps *gg_blist_get_ui_ops() { @@ -201,7 +241,21 @@ static void selection_activate(GntWidget *widget, GGBlist *ggblist) { - gnt_widget_set_focus(widget, FALSE); + GntTree *tree = GNT_TREE(ggblist->tree); + GaimBlistNode *node = gnt_tree_get_selection_data(tree); + + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy *)node; + gaim_conversation_new(GAIM_CONV_TYPE_IM, + gaim_buddy_get_account(buddy), + gaim_buddy_get_name(buddy)); + } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat*)node; + serv_join_chat(chat->account->gc, chat->components); + } } static void @@ -214,12 +268,15 @@ GaimPluginProtocolInfo *prpl_info; GaimAccount *account; GntTree *tree; - GntWidget *widget, *box, *label; + GntWidget *widget, *box; char *title = NULL; widget = ggblist->tree; tree = GNT_TREE(widget); + if (!gnt_widget_has_focus(ggblist->tree)) + return; + if (ggblist->tooltip) { /* XXX: Once we can properly redraw on expose events, this can be removed at the end @@ -268,6 +325,15 @@ title = g_strdup(group->name); } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + GaimChat *chat = (GaimChat *)node; + GaimAccount *account = chat->account; + + g_string_append_printf(str, _("Account: %s"), gaim_account_get_username(account)); + + title = g_strdup(gaim_chat_get_name(chat)); + } else { g_string_free(str, TRUE); @@ -286,7 +352,7 @@ GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW); gnt_box_set_title(GNT_BOX(box), title); - gnt_box_add_widget(GNT_BOX(box), GNT_WIDGET(gnt_label_new(str->str))); + gnt_box_add_widget(GNT_BOX(box), gnt_label_new(str->str)); gnt_widget_set_position(box, x, y); gnt_widget_draw(box); @@ -319,13 +385,14 @@ return TRUE; } } + return FALSE; } static void buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist) { - gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, get_buddy_display_name(buddy)); + gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, get_display_name((GaimBlistNode*)buddy)); if (ggblist->tnode == (GaimBlistNode*)buddy) draw_tooltip(ggblist); } @@ -344,7 +411,7 @@ ggblist->tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); - gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 2); + gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 3); gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree); gnt_widget_show(ggblist->window); Copied: branches/soc-2006-file-loggers/console/gntconv.c (from rev 16395, trunk/console/gntconv.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntconv.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -0,0 +1,263 @@ +#include <string.h> +#include <util.h> + +#include "gntgaim.h" +#include "gntconv.h" + +#include "gnt.h" +#include "gntbox.h" +#include "gntentry.h" +#include "gnttextview.h" + +GHashTable *ggconvs; + +typedef struct _GGConv GGConv; +typedef struct _GGConvChat GGConvChat; +typedef struct _GGConvIm GGConvIm; + +struct _GGConv +{ + GaimConversation *conv; + + GntWidget *window; /* the container */ + GntWidget *entry; /* entry */ + GntWidget *tv; /* text-view */ + + union + { + GGConvChat *chat; + GGConvIm *im; + } u; +}; + +struct _GGConvChat +{ + GntWidget *userlist; /* the userlist */ +}; + +struct _GGConvIm +{ + void *nothing_for_now; +}; + +static gboolean +entry_key_pressed(GntWidget *w, const char *key, GGConv *ggconv) +{ + if (key[0] == '\r' && key[1] == 0) + { + const char *text = gnt_entry_get_text(GNT_ENTRY(ggconv->entry)); + switch (gaim_conversation_get_type(ggconv->conv)) + { + case GAIM_CONV_TYPE_IM: + gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), text, GAIM_MESSAGE_SEND); + break; + case GAIM_CONV_TYPE_CHAT: + gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), text); + break; + default: + g_return_val_if_reached(FALSE); + } + gnt_entry_clear(GNT_ENTRY(ggconv->entry)); + return TRUE; + } + else if (key[0] == 27) + { + if (strcmp(key+1, GNT_KEY_DOWN) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 1); + else if (strcmp(key+1, GNT_KEY_UP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -1); + else if (strcmp(key+1, GNT_KEY_PGDOWN) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), ggconv->tv->priv.height - 2); + else if (strcmp(key+1, GNT_KEY_PGUP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -(ggconv->tv->priv.height - 2)); + else + return FALSE; + return TRUE; + } + + return FALSE; +} + +static void +closing_window(GntWidget *window, GGConv *ggconv) +{ + ggconv->window = NULL; + gaim_conversation_destroy(ggconv->conv); +} + +static void +gg_create_conversation(GaimConversation *conv) +{ + GGConv *ggc = g_hash_table_lookup(ggconvs, conv); + char *title; + GaimConversationType type; + + if (ggc) + return; + + ggc = g_new0(GGConv, 1); + g_hash_table_insert(ggconvs, conv, ggc); + + ggc->conv = conv; + + type = gaim_conversation_get_type(conv); + title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); + ggc->window = gnt_box_new(FALSE, TRUE); + gnt_box_set_title(GNT_BOX(ggc->window), title); + gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); + gnt_widget_set_name(ggc->window, title); + + ggc->tv = gnt_text_view_new(); + gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv); + gnt_widget_set_name(ggc->tv, "conversation-window-textview"); + gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 40, getmaxy(stdscr) - 15); + + ggc->entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); + gnt_widget_set_name(ggc->entry, "conversation-window-entry"); + gnt_widget_set_size(ggc->entry, getmaxx(stdscr) - 40, 1); + + g_signal_connect(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); + g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); + + gnt_widget_set_position(ggc->window, 32, 0); + gnt_widget_show(ggc->window); + + g_free(title); +} + +static void +gg_destroy_conversation(GaimConversation *conv) +{ + g_hash_table_remove(ggconvs, conv); +} + +static void +gg_write_common(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); + char *strip; + GntTextViewFlags fl = 0; + + g_return_if_fail(ggconv != NULL); + + if (who && *who && (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV))) + { + char * name = g_strdup_printf("%s: ", who); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, GNT_TEXT_FLAG_BOLD); + g_free(name); + } + else + fl = GNT_TEXT_FLAG_DIM; + + if (flags & GAIM_MESSAGE_ERROR) + fl |= GNT_TEXT_FLAG_BOLD; + if (flags & GAIM_MESSAGE_NICK) + fl |= GNT_TEXT_FLAG_UNDERLINE; + + strip = gaim_markup_strip_html(message); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + strip, fl); + gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv)); + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); + + g_free(strip); + + gnt_widget_set_urgent(ggconv->tv); +} + +static void +gg_write_chat(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + gg_write_common(conv, who, message, flags, mtime); +} + +static void +gg_write_im(GaimConversation *conv, const char *who, const char *message, + GaimMessageFlags flags, time_t mtime) +{ + if (flags & GAIM_MESSAGE_SEND) + { + who = gaim_connection_get_display_name(conv->account->gc); + if (!who) + who = gaim_account_get_alias(conv->account); + if (!who) + who = gaim_account_get_username(conv->account); + } + else if (flags & GAIM_MESSAGE_RECV) + who = gaim_conversation_get_name(conv); + + gg_write_common(conv, who, message, flags, mtime); +} + +static void +gg_write_conv(GaimConversation *conv, const char *who, const char *alias, + const char *message, GaimMessageFlags flags, time_t mtime) +{ + const char *name; + if (alias && *alias) + name = alias; + else if (who && *who) + name = who; + else + name = NULL; + + gg_write_common(conv, name, message, flags, mtime); +} + +static void +gg_chat_add_users(GaimConversation *conv, GList *users, GList *flags, GList *aliases, gboolean new_arrivals) +{} + +static void +gg_chat_rename_user(GaimConversation *conv, const char *old, const char *new_n, const char *new_a) +{} + +static void +gg_chat_remove_user(GaimConversation *conv, GList *list) +{} + +static void +gg_chat_update_user(GaimConversation *conv, const char *user) +{} + +static GaimConversationUiOps conv_ui_ops = +{ + .create_conversation = gg_create_conversation, + .destroy_conversation = gg_destroy_conversation, + .write_chat = gg_write_chat, + .write_im = gg_write_im, + .write_conv = gg_write_conv, + .chat_add_users = gg_chat_add_users, + .chat_rename_user = gg_chat_rename_user, + .chat_remove_users = gg_chat_remove_user, + .chat_update_user = gg_chat_update_user, + .present = NULL, + .has_focus = NULL, + .custom_smiley_add = NULL, + .custom_smiley_write = NULL, + .custom_smiley_close = NULL +}; + +static void +destroy_ggconv(gpointer data) +{ + GGConv *conv = data; + gnt_widget_destroy(conv->window); + g_free(conv); +} + +GaimConversationUiOps *gg_conv_get_ui_ops() +{ + return &conv_ui_ops; +} + + +void gg_conversation_init() +{ + ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); +} + Copied: branches/soc-2006-file-loggers/console/gntconv.h (from rev 16395, trunk/console/gntconv.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntconv.h 2006-07-02 16:02:29 UTC (rev 16396) @@ -0,0 +1,5 @@ +#include "conversation.h" + +GaimConversationUiOps *gg_conv_get_ui_ops(); + +void gg_conversation_init(); Modified: branches/soc-2006-file-loggers/console/gntgaim.c =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -16,6 +16,7 @@ #include "whiteboard.h" #include "gntgaim.h" +#include "gntui.h" /* Anything IO-related is directly copied from gtkgaim's source tree */ Modified: branches/soc-2006-file-loggers/console/gntui.c =================================================================== --- branches/soc-2006-file-loggers/console/gntui.c 2006-07-02 15:49:54 UTC (rev 16395) +++ branches/soc-2006-file-loggers/console/gntui.c 2006-07-02 16:02:29 UTC (rev 16396) @@ -1,4 +1,6 @@ #include "gntui.h" +#include "gntblist.h" +#include "gntconv.h" void init_gnt_ui() { @@ -12,6 +14,10 @@ gg_blist_init(); gaim_blist_set_ui_ops(gg_blist_get_ui_ops()); + /* Now the conversations */ + gg_conversation_init(); + gaim_conversations_set_ui_ops(gg_conv_get_ui_ops()); + gnt_main(); } Copied: branches/soc-2006-file-loggers/console/libgnt/AUTHORS (from rev 16395, trunk/console/libgnt/AUTHORS) =================================================================== Copied: branches/soc-2006-file-loggers/console/libgnt/COPYING (from rev 16395, trunk/console/libgnt/COPYING) =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/COPYING (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/COPYING 2006-07-02 16:02:29 UTC (rev 16396) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show... [truncated message content] |
From: <ro...@us...> - 2006-07-08 22:43:58
|
Revision: 16465 Author: roast Date: 2006-07-08 15:43:22 -0700 (Sat, 08 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16465&view=rev Log Message: ----------- merged with svn trunk. 16395:16464. Modified Paths: -------------- branches/soc-2006-file-loggers/console/Makefile branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/gntblist.h branches/soc-2006-file-loggers/console/gntconv.c branches/soc-2006-file-loggers/console/gntconv.h branches/soc-2006-file-loggers/console/gntgaim.c branches/soc-2006-file-loggers/console/gntui.c branches/soc-2006-file-loggers/console/libgnt/Makefile.am branches/soc-2006-file-loggers/console/libgnt/configure.ac branches/soc-2006-file-loggers/console/libgnt/gnt.h branches/soc-2006-file-loggers/console/libgnt/gntbox.c branches/soc-2006-file-loggers/console/libgnt/gntbox.h branches/soc-2006-file-loggers/console/libgnt/gntbutton.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.c branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntlabel.c branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gnttextview.c branches/soc-2006-file-loggers/console/libgnt/gnttextview.h branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gnttree.h branches/soc-2006-file-loggers/console/libgnt/gntutils.c branches/soc-2006-file-loggers/console/libgnt/gntutils.h branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.h branches/soc-2006-file-loggers/console/libgnt/test/Makefile branches/soc-2006-file-loggers/console/libgnt/test/focus.c branches/soc-2006-file-loggers/console/libgnt/test/multiwin.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/gaim.spec.in branches/soc-2006-file-loggers/plugins/ssl/ssl-gnutls.c branches/soc-2006-file-loggers/src/connection.c branches/soc-2006-file-loggers/src/connection.h branches/soc-2006-file-loggers/src/conversation.c branches/soc-2006-file-loggers/src/debug.c branches/soc-2006-file-loggers/src/debug.h branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/gtkdebug.c branches/soc-2006-file-loggers/src/gtkprefs.c branches/soc-2006-file-loggers/src/protocols/bonjour/bonjour.c branches/soc-2006-file-loggers/src/protocols/bonjour/bonjour.h branches/soc-2006-file-loggers/src/protocols/bonjour/buddy.c branches/soc-2006-file-loggers/src/protocols/bonjour/dns_sd.c branches/soc-2006-file-loggers/src/protocols/bonjour/dns_sd.h branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.c branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.h branches/soc-2006-file-loggers/src/protocols/gg/lib/libgadu.c branches/soc-2006-file-loggers/src/protocols/irc/cmds.c branches/soc-2006-file-loggers/src/protocols/jabber/roster.c branches/soc-2006-file-loggers/src/protocols/msn/httpconn.c branches/soc-2006-file-loggers/src/protocols/msn/httpconn.h branches/soc-2006-file-loggers/src/protocols/msn/msn.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/proxy.c branches/soc-2006-file-loggers/src/server.c branches/soc-2006-file-loggers/src/util.c Added Paths: ----------- branches/soc-2006-file-loggers/console/gntaccount.c branches/soc-2006-file-loggers/console/gntaccount.h Property Changed: ---------------- branches/soc-2006-file-loggers/src/protocols/qq/ Modified: branches/soc-2006-file-loggers/console/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/Makefile 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/Makefile 2006-07-08 22:43:22 UTC (rev 16465) @@ -1,18 +1,22 @@ +VERSION=gntgaim-0.0.0dev CC=gcc -CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall +CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall -DVERSION=\"$(VERSION)\" LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg GG_SOURCES = \ + gntaccount.c \ gntblist.c \ gntconv.c \ gntui.c GG_HEADERS = \ + gntaccount.h \ gntblist.h \ gntconv.h \ gntui.h GG_OBJECTS = \ + gntaccount.o \ gntblist.o \ gntconv.o \ gntui.o @@ -21,6 +25,7 @@ gntgaim: gntgaim.o $(GG_OBJECTS) $(CC) -o gntgaim gntgaim.o $(GG_OBJECTS) $(LDFLAGS) +gntaccount.o: gntaccount.c $(GG_HEADERS) gntblist.o: gntblist.c $(GG_HEADERS) gntconv.o: gntconv.c $(GG_HEADERS) gntgaim.o: gntgaim.c gntgaim.h $(GG_HEADERS) Copied: branches/soc-2006-file-loggers/console/gntaccount.c (from rev 16464, trunk/console/gntaccount.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntaccount.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntaccount.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -0,0 +1,181 @@ +#include <gnt.h> +#include <gntbox.h> +#include <gntbutton.h> +#include <gntlabel.h> +#include <gnttree.h> + +#include <connection.h> +#include <notify.h> +#include <request.h> + +#include "gntaccount.h" +#include "gntgaim.h" + +typedef struct +{ + GntWidget *window; + GntWidget *tree; +} GGAccountList; + +static GGAccountList accounts; + +static void +account_toggled(GntWidget *widget, void *key, gpointer null) +{ + GaimAccount *account = key; + + gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key)); +} + +void gg_accounts_init() +{ + GList *iter; + GntWidget *box, *button; + + accounts.window = gnt_box_new(TRUE, TRUE); + gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE); + gnt_box_set_title(GNT_BOX(accounts.window), _("Accounts")); + gnt_box_set_pad(GNT_BOX(accounts.window), 0); + gnt_widget_set_name(accounts.window, "accounts"); + + gnt_box_add_widget(GNT_BOX(accounts.window), + gnt_label_new(_("You can enable/disable accounts from the following list."))); + + accounts.tree = gnt_tree_new(); + GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER); + + for (iter = gaim_accounts_get_all(); iter; iter = iter->next) + { + GaimAccount *account = iter->data; + char *str = g_strdup_printf("%s (%s)", + gaim_account_get_username(account), gaim_account_get_protocol_id(account)); + + gnt_tree_add_choice(GNT_TREE(accounts.tree), account, + str, NULL, NULL); + gnt_tree_set_choice(GNT_TREE(accounts.tree), account, + gaim_account_get_enabled(account, GAIM_GNT_UI)); + g_free(str); + } + + g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL); + + gnt_widget_set_size(accounts.tree, 40, 10); + gnt_box_add_widget(GNT_BOX(accounts.window), accounts.tree); + + box = gnt_box_new(FALSE, FALSE); + + button = gnt_button_new(_("Add")); + gnt_box_add_widget(GNT_BOX(box), button); + + button = gnt_button_new(_("Modify")); + gnt_box_add_widget(GNT_BOX(box), button); + + button = gnt_button_new(_("Delete")); + gnt_box_add_widget(GNT_BOX(box), button); + + gnt_box_add_widget(GNT_BOX(accounts.window), box); + + gnt_widget_show(accounts.window); +} + +void gg_accounts_uninit() +{ + gnt_widget_destroy(accounts.window); +} + +#if 0 +/* The following uiops stuff are copied from gtkaccount.c */ +/* Need to do some work on notify- and request-ui before this works */ +typedef struct +{ + GaimAccount *account; + char *username; + char *alias; +} AddUserData; + +static char * +make_info(GaimAccount *account, GaimConnection *gc, const char *remote_user, + const char *id, const char *alias, const char *msg) +{ + if (msg != NULL && *msg == '\0') + msg = NULL; + + return g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s"), + remote_user, + (alias != NULL ? " (" : ""), + (alias != NULL ? alias : ""), + (alias != NULL ? ")" : ""), + (id != NULL + ? id + : (gaim_connection_get_display_name(gc) != NULL + ? gaim_connection_get_display_name(gc) + : gaim_account_get_username(account))), + (msg != NULL ? ": " : "."), + (msg != NULL ? msg : "")); +} + +static void +notify_added(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + + gc = gaim_account_get_connection(account); + + buffer = make_info(account, gc, remote_user, id, alias, msg); + + gaim_notify_info(NULL, NULL, buffer, NULL); + + g_free(buffer); +} + +static void +request_add(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + AddUserData *data; + + gc = gaim_account_get_connection(account); + + data = g_new0(AddUserData, 1); + data->account = account; + data->username = g_strdup(remote_user); + data->alias = (alias != NULL ? g_strdup(alias) : NULL); + + buffer = make_info(account, gc, remote_user, id, alias, msg); +#if 0 + gaim_request_action(NULL, NULL, _("Add buddy to your list?"), + buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, + _("Add"), G_CALLBACK(add_user_cb), + _("Cancel"), G_CALLBACK(free_add_user_data)); +#endif + g_free(buffer); +} + +static GaimAccountUiOps ui_ops = +{ + .notify_added = notify_added, + .status_changed = NULL, + .request_add = request_add +}; +#else + +static GaimAccountUiOps ui_ops = +{ + .notify_added = NULL, + .status_changed = NULL, + .request_add = NULL +}; + +#endif + +GaimAccountUiOps *gg_accounts_get_ui_ops() +{ + return &ui_ops; +} + Copied: branches/soc-2006-file-loggers/console/gntaccount.h (from rev 16464, trunk/console/gntaccount.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntaccount.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntaccount.h 2006-07-08 22:43:22 UTC (rev 16465) @@ -0,0 +1,7 @@ +#include "account.h" + +GaimAccountUiOps *gg_accounts_get_ui_ops(); + +void gg_accounts_init(); + +void gg_accounts_uninit(); Modified: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -141,7 +141,7 @@ GaimStatusPrimitive prim; GaimPresence *presence; GaimStatus *now; - + gboolean ascii = gnt_ascii_only(); presence = gaim_buddy_get_presence(buddy); now = gaim_presence_get_active_status(presence); @@ -150,29 +150,15 @@ switch(prim) { -#if 1 case GAIM_STATUS_OFFLINE: - strncpy(status, "x", sizeof(status) - 1); + strncpy(status, ascii ? "x" : "⊗", sizeof(status) - 1); break; case GAIM_STATUS_AVAILABLE: - strncpy(status, "o", sizeof(status) - 1); + strncpy(status, ascii ? "o" : "◯", sizeof(status) - 1); break; default: - strncpy(status, ".", sizeof(status) - 1); + strncpy(status, ascii ? "." : "⊖", sizeof(status) - 1); break; -#else - /* XXX: Let's use these some time */ - case GAIM_STATUS_OFFLINE: - strncpy(status, "⊗", sizeof(status) - 1); - break; - case GAIM_STATUS_AVAILABLE: - /* XXX: Detect idleness */ - strncpy(status, "◯", sizeof(status) - 1); - break; - default: - strncpy(status, "⊖", sizeof(status) - 1); - break; -#endif } name = gaim_buddy_get_alias(buddy); } @@ -217,6 +203,10 @@ node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy, get_display_name(node), group, NULL); + if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) + gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, GNT_TEXT_FLAG_DIM); + else + gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, 0); } #if 0 @@ -355,6 +345,7 @@ gnt_box_add_widget(GNT_BOX(box), gnt_label_new(str->str)); gnt_widget_set_position(box, x, y); + GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_CAN_TAKE_FOCUS); gnt_widget_draw(box); g_free(title); @@ -371,7 +362,6 @@ draw_tooltip(ggblist); } - static gboolean key_pressed(GntWidget *widget, const char *text, GGBlist *ggblist) { @@ -390,13 +380,30 @@ } static void -buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist) +update_buddy_display(GaimBuddy *buddy, GGBlist *ggblist) { gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, get_display_name((GaimBlistNode*)buddy)); if (ggblist->tnode == (GaimBlistNode*)buddy) draw_tooltip(ggblist); + + if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) + gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, GNT_TEXT_FLAG_DIM); + else + gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, 0); } +static void +buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist) +{ + update_buddy_display(buddy, ggblist); +} + +static void +buddy_idle_changed(GaimBuddy *buddy, int old, int new, GGBlist *ggblist) +{ + update_buddy_display(buddy, ggblist); +} + void gg_blist_init() { ggblist = g_new0(GGBlist, 1); @@ -411,13 +418,15 @@ ggblist->tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); - gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 3); + gnt_widget_set_size(ggblist->tree, 25, getmaxy(stdscr) - 4); gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree); gnt_widget_show(ggblist->window); gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(), GAIM_CALLBACK(buddy_status_changed), ggblist); + gaim_signal_connect(gaim_blist_get_handle(), "buddy-idle-changed", gg_blist_get_handle(), + GAIM_CALLBACK(buddy_idle_changed), ggblist); #if 0 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gg_blist_get_handle(), @@ -438,5 +447,36 @@ g_signal_connect(G_OBJECT(ggblist->tree), "selection_changed", G_CALLBACK(selection_changed), ggblist); g_signal_connect(G_OBJECT(ggblist->tree), "key_pressed", G_CALLBACK(key_pressed), ggblist); g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist); + g_signal_connect_data(G_OBJECT(ggblist->tree), "gained-focus", G_CALLBACK(draw_tooltip), + ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED); + g_signal_connect_data(G_OBJECT(ggblist->tree), "lost-focus", G_CALLBACK(remove_tooltip), + ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED); } +void gg_blist_uninit() +{ + gnt_widget_destroy(ggblist->window); + g_free(ggblist); + ggblist = NULL; +} + +void gg_blist_get_position(int *x, int *y) +{ + gnt_widget_get_position(ggblist->window, x, y); +} + +void gg_blist_set_position(int x, int y) +{ + gnt_widget_set_position(ggblist->window, x, y); +} + +void gg_blist_get_size(int *width, int *height) +{ + gnt_widget_get_size(ggblist->window, width, height); +} + +void gg_blist_set_size(int width, int height) +{ + gnt_widget_set_size(ggblist->window, width, height); +} + Modified: branches/soc-2006-file-loggers/console/gntblist.h =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.h 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/gntblist.h 2006-07-08 22:43:22 UTC (rev 16465) @@ -3,3 +3,14 @@ GaimBlistUiOps * gg_blist_get_ui_ops(); void gg_blist_init(); + +void gg_blist_uninit(); + +void gg_blist_get_position(int *x, int *y); + +void gg_blist_set_position(int x, int y); + +void gg_blist_get_size(int *width, int *height); + +void gg_blist_set_size(int width, int height); + Modified: branches/soc-2006-file-loggers/console/gntconv.c =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/gntconv.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -2,6 +2,7 @@ #include <util.h> #include "gntgaim.h" +#include "gntblist.h" #include "gntconv.h" #include "gnt.h" @@ -91,10 +92,14 @@ GGConv *ggc = g_hash_table_lookup(ggconvs, conv); char *title; GaimConversationType type; + int x, width; if (ggc) return; + gg_blist_get_position(&x, NULL); + gg_blist_get_size(&width, NULL); + ggc = g_new0(GGConv, 1); g_hash_table_insert(ggconvs, conv, ggc); @@ -102,25 +107,28 @@ type = gaim_conversation_get_type(conv); title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); - ggc->window = gnt_box_new(FALSE, TRUE); + ggc->window = gnt_box_new(TRUE, TRUE); gnt_box_set_title(GNT_BOX(ggc->window), title); gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); + gnt_box_set_pad(GNT_BOX(ggc->window), 0); gnt_widget_set_name(ggc->window, title); ggc->tv = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv); gnt_widget_set_name(ggc->tv, "conversation-window-textview"); - gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 40, getmaxy(stdscr) - 15); + gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 3 - x - width, getmaxy(stdscr) - 5); ggc->entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); gnt_widget_set_name(ggc->entry, "conversation-window-entry"); - gnt_widget_set_size(ggc->entry, getmaxx(stdscr) - 40, 1); g_signal_connect(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); - gnt_widget_set_position(ggc->window, 32, 0); + /* XXX: I am assuming the buddylist is on the leftmost corner. + * That may not always be correct, since the windows can be moved. + * It might be an option to remember the position of conv. windows. */ + gnt_widget_set_position(ggc->window, x + width, 0); gnt_widget_show(ggc->window); g_free(title); @@ -138,7 +146,7 @@ { GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); char *strip; - GntTextViewFlags fl = 0; + GntTextFormatFlags fl = 0; g_return_if_fail(ggconv != NULL); @@ -165,7 +173,8 @@ g_free(strip); - gnt_widget_set_urgent(ggconv->tv); + if (flags & (GAIM_MESSAGE_RECV | GAIM_MESSAGE_NICK | GAIM_MESSAGE_ERROR)) + gnt_widget_set_urgent(ggconv->tv); } static void @@ -261,3 +270,9 @@ ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); } +void gg_conversation_uninit() +{ + g_hash_table_destroy(ggconvs); + ggconvs = NULL; +} + Modified: branches/soc-2006-file-loggers/console/gntconv.h =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.h 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/gntconv.h 2006-07-08 22:43:22 UTC (rev 16465) @@ -3,3 +3,5 @@ GaimConversationUiOps *gg_conv_get_ui_ops(); void gg_conversation_init(); + +void gg_conversation_uninit(); Modified: branches/soc-2006-file-loggers/console/gntgaim.c =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -18,6 +18,9 @@ #include "gntgaim.h" #include "gntui.h" +#define _GNU_SOURCE +#include <getopt.h> + /* Anything IO-related is directly copied from gtkgaim's source tree */ static GaimCoreUiOps core_ops = @@ -103,12 +106,6 @@ closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, gaim_gtk_io_invoke, closure, gaim_gtk_io_destroy); -#if 0 - gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop", - "CLOSURE: adding input watcher %d for fd %d\n", - closure->result, fd); -#endif - g_io_channel_unref(channel); return closure->result; } @@ -129,25 +126,124 @@ /* This is mostly copied from gtkgaim's source tree */ static void -init_libgaim() +show_usage(const char *name, gboolean terse) { + char *text; + + if (terse) { + text = g_strdup_printf(_("Gaim %s. Try `%s -h' for more information.\n"), VERSION, name); + } else { + text = g_strdup_printf(_("Gaim %s\n" + "Usage: %s [OPTION]...\n\n" + " -c, --config=DIR use DIR for config files\n" + " -d, --debug print debugging messages to stdout\n" + " -h, --help display this help and exit\n" + " -n, --nologin don't automatically login\n" + " -v, --version display the current version and exit\n"), VERSION, name); + } + + gaim_print_utf8_to_console(stdout, text); + g_free(text); +} + +static int +init_libgaim(int argc, char **argv) +{ char *path; + int opt; + gboolean opt_help = FALSE; + gboolean opt_nologin = FALSE; + gboolean opt_version = FALSE; + char *opt_config_dir_arg = NULL; + char *opt_session_arg = NULL; + gboolean debug_enabled = FALSE; - gaim_debug_set_enabled(FALSE); + struct option long_options[] = { + {"config", required_argument, NULL, 'c'}, + {"debug", no_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {"nologin", no_argument, NULL, 'n'}, + {"session", required_argument, NULL, 's'}, + {"version", no_argument, NULL, 'v'}, + {0, 0, 0, 0} + }; + /* scan command-line options */ + opterr = 1; + while ((opt = getopt_long(argc, argv, +#ifndef _WIN32 + "c:dhn::s:v", +#else + "c:dhn::v", +#endif + long_options, NULL)) != -1) { + switch (opt) { + case 'c': /* config dir */ + g_free(opt_config_dir_arg); + opt_config_dir_arg = g_strdup(optarg); + break; + case 'd': /* debug */ + debug_enabled = TRUE; + break; + case 'h': /* help */ + opt_help = TRUE; + break; + case 'n': /* no autologin */ + opt_nologin = TRUE; + break; + case 's': /* use existing session ID */ + g_free(opt_session_arg); + opt_session_arg = g_strdup(optarg); + break; + case 'v': /* version */ + opt_version = TRUE; + break; + case '?': /* show terse help */ + default: + show_usage(argv[0], TRUE); + return 0; + break; + } + } + + /* show help message */ + if (opt_help) { + show_usage(argv[0], FALSE); + return 0; + } + /* show version message */ + if (opt_version) { + printf("Gaim %s\n", VERSION); + return 0; + } + + /* set a user-specified config directory */ + if (opt_config_dir_arg != NULL) { + gaim_util_set_user_dir(opt_config_dir_arg); + } + + /* + * We're done piddling around with command line arguments. + * Fire up this baby. + */ + + /* Because we don't want debug-messages to show up and corrup the display */ + gaim_debug_set_enabled(debug_enabled); + gaim_core_set_ui_ops(gnt_core_get_ui_ops()); gaim_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops()); - gaim_util_set_user_dir("/tmp/tmp/"); /* XXX: */ - path = g_build_filename(gaim_user_dir(), "plugins", NULL); gaim_plugins_add_search_path(path); g_free(path); + gaim_plugins_add_search_path("/usr/local/lib/gaim"); /* XXX: */ if (!gaim_core_init(GAIM_GNT_UI)) { - fprintf(stderr, "OOPSSS!!\n"); + fprintf(stderr, + "Initialization of the Gaim core failed. Dumping core.\n" + "Please report this!\n"); abort(); } @@ -160,11 +256,36 @@ gaim_prefs_update_old(); /* load plugins we had when we quit */ - gaim_plugins_load_saved("/gaim/gtk/plugins/loaded"); + gaim_plugins_load_saved("/gaim/gnt/plugins/loaded"); /* TODO: Move pounces loading into gaim_pounces_init() */ gaim_pounces_load(); + if (opt_nologin) + { + /* Set all accounts to "offline" */ + GaimSavedStatus *saved_status; + + /* If we've used this type+message before, lookup the transient status */ + saved_status = gaim_savedstatus_find_transient_by_type_and_message( + GAIM_STATUS_OFFLINE, NULL); + + /* If this type+message is unique then create a new transient saved status */ + if (saved_status == NULL) + saved_status = gaim_savedstatus_new(NULL, GAIM_STATUS_OFFLINE); + + /* Set the status for each account */ + gaim_savedstatus_activate(saved_status); + } + else + { + /* Everything is good to go--sign on already */ + if (!gaim_prefs_get_bool("/core/savedstatus/startup_current_status")) + gaim_savedstatus_activate(gaim_savedstatus_get_startup()); + gaim_accounts_restore_current_statuses(); + } + + return 1; } int main(int argc, char **argv) @@ -173,12 +294,10 @@ freopen(".error", "w", stderr); /* Initialize the libgaim stuff */ - init_libgaim(); + if (!init_libgaim(argc, argv)) + return 0; - /* Enable the accounts and restore the status */ - gaim_accounts_restore_current_statuses(); - - /* Initialize the UI */ + /* Initialize and run the UI */ init_gnt_ui(); gaim_core_quit(); Modified: branches/soc-2006-file-loggers/console/gntui.c =================================================================== --- branches/soc-2006-file-loggers/console/gntui.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/gntui.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -1,4 +1,6 @@ #include "gntui.h" + +#include "gntaccount.h" #include "gntblist.h" #include "gntconv.h" @@ -6,9 +8,9 @@ { gnt_init(); - wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - werase(stdscr); - wrefresh(stdscr); + /* Accounts */ + gg_accounts_init(); + gaim_accounts_set_ui_ops(gg_accounts_get_ui_ops()); /* Initialize the buddy list */ gg_blist_init(); @@ -19,5 +21,16 @@ gaim_conversations_set_ui_ops(gg_conv_get_ui_ops()); gnt_main(); + + gaim_accounts_set_ui_ops(NULL); + gg_accounts_uninit(); + + gaim_blist_set_ui_ops(NULL); + gg_blist_uninit(); + + gaim_conversations_set_ui_ops(NULL); + gg_conversation_uninit(); + + gnt_quit(); } Modified: branches/soc-2006-file-loggers/console/libgnt/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/Makefile.am 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/Makefile.am 2006-07-08 22:43:22 UTC (rev 16465) @@ -37,7 +37,8 @@ libgnt_la_LIBADD = \ $(GLIB_LIBS) \ $(STATIC_LINK_LIBS) \ - -lncursesw + -lncursesw -lpanelw AM_CPPFLAGS = \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + -Wall Modified: branches/soc-2006-file-loggers/console/libgnt/configure.ac =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/configure.ac 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/configure.ac 2006-07-08 22:43:22 UTC (rev 16465) @@ -239,6 +239,8 @@ AC_CHECK_HEADERS(termios.h) #AC_VAR_TIMEZONE_EXTERNALS +AC_CHECK_LIB(ncursesw, initscr, , [AC_MSG_ERROR([ +*** You need ncursesw. ])]) AC_OUTPUT([Makefile gnt.pc Modified: branches/soc-2006-file-loggers/console/libgnt/gnt.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnt.h 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gnt.h 2006-07-08 22:43:22 UTC (rev 16465) @@ -7,6 +7,8 @@ void gnt_main(); +gboolean gnt_ascii_only(); + void gnt_screen_occupy(GntWidget *widget); void gnt_screen_release(GntWidget *widget); @@ -18,3 +20,6 @@ gboolean gnt_widget_has_focus(GntWidget *widget); void gnt_widget_set_urgent(GntWidget *widget); + +void gnt_quit(); + Modified: branches/soc-2006-file-loggers/console/libgnt/gntbox.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbox.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntbox.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -13,10 +13,25 @@ static GntWidget * find_focusable_widget(GntBox *box); static void +add_to_focus(gpointer value, gpointer data) +{ + GntBox *box = GNT_BOX(data); + GntWidget *w = GNT_WIDGET(value); + + if (GNT_IS_BOX(w)) + g_list_foreach(GNT_BOX(w)->list, add_to_focus, box); + else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS)) + box->focus = g_list_append(box->focus, w); +} + +static void gnt_box_draw(GntWidget *widget) { GntBox *box = GNT_BOX(widget); + if (box->focus == NULL && widget->parent == NULL) + g_list_foreach(box->list, add_to_focus, box); + g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL); gnt_box_sync_children(box); @@ -24,24 +39,29 @@ if (box->title) { gchar *title = g_strdup(box->title); - int pos = g_utf8_strlen(title, -1); + int pos = g_utf8_strlen(title, -1), right; - if (pos >= widget->priv.width - 2) + if (pos >= widget->priv.width - 4) { - g_utf8_strncpy(title, box->title, widget->priv.width - 2); - pos = 1; + g_utf8_strncpy(title, box->title, widget->priv.width - 4); + pos = 2; + right = pos + g_utf8_strlen(title, -1); } else { /* XXX: Position of the title might be configurable */ + right = pos; pos = (widget->priv.width - pos) / 2; + right += pos; } if (gnt_widget_has_focus(widget)) wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE)); else wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE_D)); + mvwaddch(widget->window, 0, pos-1, ACS_RTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); mvwprintw(widget->window, 0, pos, title); + mvwaddch(widget->window, 0, right, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); g_free(title); } @@ -152,102 +172,17 @@ DEBUG; } -static GntWidget * -find_next_focus(GntBox *box) -{ - GntWidget *w = box->active; - GList *iter; - - while (w && !(iter = g_list_find(box->list, w))) - w = w->parent; - - if (!w) - box->active = NULL; - else if (iter) - { - GntWidget *next = NULL; - - do - { - next = find_next_focus(iter->data); - box->active = next; - iter = iter->next; - } while (!next && iter); - } - - if (box->active == NULL && GNT_WIDGET(box)->parent == NULL) - { - box->active = find_focusable_widget(box); - } - - if (box->active) - GNT_WIDGET_SET_FLAGS(box->active, GNT_WIDGET_HAS_FOCUS); - - return box->active; -} - /* Ensures that the current widget can take focus */ static GntWidget * find_focusable_widget(GntBox *box) { - int investigated = 0; - int total; - GntWidget *w = NULL; - GList *iter; + if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL) + g_list_foreach(box->list, add_to_focus, box); - for (iter = box->list; iter; iter = iter->next) - { - w = iter->data; - if (GNT_IS_BOX(w)) - { - w = find_focusable_widget(GNT_BOX(w)); - if (w) - break; - } - else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS)) - break; - } + if (box->active == NULL && box->focus) + box->active = box->focus->data; - if (iter) - box->active = w; - else - box->active = NULL; - - if (box->active) - GNT_WIDGET_SET_FLAGS(box->active, GNT_WIDGET_HAS_FOCUS); - return box->active; - -#if 0 - if (box->active == NULL && box->list) - box->active = box->list->data; - else - w = box->active; - - total = g_list_length(box->list); - - while (box->active && !GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_CAN_TAKE_FOCUS)) - { - box->active = box->active->next; - investigated++; - } - - /* Rotate if necessary */ - if (!box->active && investigated < total) - { - box->active = box->list; - while (investigated < total && !GNT_WIDGET_IS_FLAG_SET(box->active->data, GNT_WIDGET_CAN_TAKE_FOCUS)) - { - box->active = box->active->next; - investigated++; - } - } - - if (box->active) - gnt_widget_set_focus(box->active->data, TRUE); - if (w && w != box->active->data) - gnt_widget_set_focus(w, FALSE); -#endif } static gboolean @@ -263,93 +198,60 @@ if (text[0] == 27) { -#if 0 - GList *now = NULL; + GntWidget *now = box->active; if (strcmp(text+1, GNT_KEY_LEFT) == 0) { - now = box->active->prev; - if (now == NULL) - now = g_list_last(box->list); + GList *iter = g_list_find(box->focus, box->active); + if ((!iter || !iter->prev) && box->focus) + { + box->active = box->focus->data; + } + else + { + box->active = iter->prev->data; + } } else if (strcmp(text+1, GNT_KEY_RIGHT) == 0) { - now = box->active->next; - if (now == NULL) - now = box->list; + GList *iter = g_list_find(box->focus, box->active); + if (iter && iter->next) + { + box->active = iter->next->data; + } + else if (box->focus) + { + box->active = box->focus->data; + } } if (now && now != box->active) { - gnt_widget_set_focus(box->active->data, FALSE); - box->active = now; - gnt_widget_set_focus(box->active->data, TRUE); - + gnt_widget_set_focus(now, FALSE); + gnt_widget_set_focus(box->active, TRUE); return TRUE; } -#endif } return FALSE; } -static GntWidget *find_focused_widget(GntBox *box) -{ - GList *iter; - - for (iter = box->list; iter; iter = iter->next) - { - GntWidget *w = iter->data; - - if (GNT_IS_BOX(w)) - { - if ((w = find_focused_widget(GNT_BOX(w))) != NULL) - return w; - } - else - { - if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) && - GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS)) - return w; - } - } - return NULL; -} - -#if 0 static void -gnt_box_set_focus(GntWidget *widget, gboolean set) +gnt_box_lost_focus(GntWidget *widget) { - GntWidget *p = widget; - - while (p->parent) - p = p->parent; - - p = find_focused_widget(GNT_BOX(p)); - if (p) - gnt_widget_set_focus(p, set); + GntWidget *w = GNT_BOX(widget)->active; + if (w) + gnt_widget_set_focus(w, FALSE); gnt_widget_draw(widget); } static void -gnt_box_lost_focus(GntWidget *widget) -{ - gnt_box_set_focus(widget, FALSE); -} - -static void gnt_box_gained_focus(GntWidget *widget) { - GntWidget *p; - - while (widget->parent) - widget = widget->parent; - - p = find_focused_widget(GNT_BOX(widget)); - GNT_BOX(widget)->active = g_list_find(GNT_BOX(widget)->list, p); - if (p) - gnt_widget_draw(p); + GntWidget *w = GNT_BOX(widget)->active; + if (w) + gnt_widget_set_focus(w, TRUE); + gnt_widget_draw(widget); } -#endif static void gnt_box_destroy(GntWidget *w) @@ -376,6 +278,33 @@ delwin(win); } +static gboolean +gnt_box_confirm_size(GntWidget *widget, int width, int height) +{ + GList *iter; + GntBox *box = GNT_BOX(widget); + int wchange, hchange; + + wchange = widget->priv.width - width; + hchange = widget->priv.height - height; + + /* XXX: Right now, I am trying to just apply all the changes to + * just one widget. It should be possible to distribute the + * changes to all the widgets in the box. */ + for (iter = box->list; iter; iter = iter->next) + { + GntWidget *wid = iter->data; + int w, h; + + gnt_widget_get_size(wid, &w, &h); + + if (gnt_widget_set_size(wid, w - wchange, h - hchange)) + return TRUE; + } + + return FALSE; +} + static void gnt_box_class_init(GntBoxClass *klass) { @@ -387,11 +316,9 @@ parent_class->size_request = gnt_box_size_request; parent_class->set_position = gnt_box_set_position; parent_class->key_pressed = gnt_box_key_pressed; -#if 0 - /* We are going to need this when there are multiple focusble widgets in a box */ parent_class->lost_focus = gnt_box_lost_focus; parent_class->gained_focus = gnt_box_gained_focus; -#endif + parent_class->confirm_size = gnt_box_confirm_size; DEBUG; } @@ -399,6 +326,9 @@ static void gnt_box_init(GTypeInstance *instance, gpointer class) { + /* Initially make both the height and width resizable. + * Update the flags as necessary when widgets are added to it. */ + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); DEBUG; } @@ -450,6 +380,17 @@ { b->list = g_list_append(b->list, widget); widget->parent = GNT_WIDGET(b); + + if (b->vertical) + { + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) + GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_X); + } + else + { + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y)) + GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_Y); + } } void gnt_box_set_title(GntBox *b, const char *title) @@ -468,9 +409,15 @@ { GntWidget *widget = GNT_WIDGET(box); if (set) + { GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); + } else + { GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); + } } void gnt_box_sync_children(GntBox *box) @@ -483,11 +430,18 @@ for (iter = box->list; iter; iter = iter->next) { GntWidget *w = GNT_WIDGET(iter->data); + int height, width; + + if (GNT_IS_BOX(w)) + gnt_box_sync_children(GNT_BOX(w)); + + gnt_widget_get_size(w, &width, &height); + copywin(w->window, widget->window, 0, 0, w->priv.y - widget->priv.y, w->priv.x - widget->priv.x, - w->priv.y - widget->priv.y + w->priv.height - 1, - w->priv.x - widget->priv.x + w->priv.width - 1, + w->priv.y - widget->priv.y + height - 1, + w->priv.x - widget->priv.x + width - 1, FALSE); } } Modified: branches/soc-2006-file-loggers/console/libgnt/gntbox.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbox.h 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntbox.h 2006-07-08 22:43:22 UTC (rev 16465) @@ -26,6 +26,7 @@ int pad; /* Number of spaces to use between widgets */ char *title; + GList *focus; /* List of widgets to cycle focus (only valid for parent boxes) */ void (*gnt_reserved1)(void); void (*gnt_reserved2)(void); Modified: branches/soc-2006-file-loggers/console/libgnt/gntbutton.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbutton.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntbutton.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -16,10 +16,11 @@ GntButton *button = GNT_BUTTON(widget); GntColorType type; - if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_HAS_FOCUS) + if (gnt_widget_has_focus(widget)) type = GNT_COLOR_HIGHLIGHT; else type = GNT_COLOR_NORMAL; + wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); mvwprintw(widget->window, 1, 1, button->priv->text); @@ -70,6 +71,8 @@ { GntButton *button = GNT_BUTTON(instance); button->priv = g_new0(GntButtonPriv, 1); + + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(button), GNT_WIDGET_GROW_X); /* Can be resized sideways */ DEBUG; } Modified: branches/soc-2006-file-loggers/console/libgnt/gntcolors.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcolors.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntcolors.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -29,10 +29,11 @@ else { init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); - init_pair(GNT_COLOR_HIGHLIGHT, COLOR_YELLOW, COLOR_BLACK); + init_pair(GNT_COLOR_HIGHLIGHT, COLOR_WHITE, COLOR_BLUE); init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK); - init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLACK); - init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_BLACK, COLOR_WHITE); + init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLUE); + init_pair(GNT_COLOR_TITLE_D, COLOR_WHITE, COLOR_BLACK); + init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_WHITE, COLOR_BLUE); init_pair(GNT_COLOR_HIGHLIGHT_D, COLOR_CYAN, COLOR_BLACK); init_pair(GNT_COLOR_DISABLED, COLOR_YELLOW, COLOR_WHITE); } Modified: branches/soc-2006-file-loggers/console/libgnt/gntentry.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntentry.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntentry.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -173,6 +173,7 @@ GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS); + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_GROW_X); DEBUG; } Modified: branches/soc-2006-file-loggers/console/libgnt/gntlabel.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntlabel.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntlabel.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -70,6 +70,7 @@ static void gnt_label_init(GTypeInstance *instance, gpointer class) { + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); DEBUG; } Modified: branches/soc-2006-file-loggers/console/libgnt/gntmain.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntmain.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gntmain.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -1,3 +1,5 @@ +#include <panel.h> + #include "gnt.h" #include "gntbox.h" #include "gntkeys.h" @@ -2,2 +4,3 @@ #include "gntcolors.h" +#include "gnttree.h" @@ -9,28 +12,60 @@ #include <unistd.h> #include <string.h> +static int lock_focus_list; static GList *focus_list; -static int max_x; -static int max_y; +static int X_MIN; +static int X_MAX; +static int Y_MIN; +static int Y_MAX; + +static gboolean ascii_only; + +static GMainLoop *loop; +static struct +{ + GntWidget *window; + GntWidget *tree; +} window_list; + typedef struct { GntWidget *me; - GList *below; /* List of widgets below me */ - GList *above; /* List of widgets above me */ + + PANEL *panel; } GntNode; +typedef enum +{ + GNT_KP_MODE_NORMAL, + GNT_KP_MODE_RESIZE, + GNT_KP_MODE_MOVE, + GNT_KP_MODE_MENU, + GNT_KP_MODE_WINDOW_LIST +} GntKeyPressMode; + static GHashTable *nodes; static void free_node(gpointer data); static void draw_taskbar(); +static void bring_on_top(GntWidget *widget); void gnt_screen_take_focus(GntWidget *widget) { GntWidget *w = NULL; + + if (lock_focus_list) + return; + if (focus_list) w = focus_list->data; - focus_list = g_list_prepend(focus_list, widget); + + /* XXX: ew */ + focus_list = g_list_first(focus_list); + focus_list = g_list_append(focus_list, widget); + focus_list = g_list_find(focus_list, widget); + gnt_widget_set_focus(widget, TRUE); if (w) gnt_widget_set_focus(w, FALSE); @@ -39,11 +74,24 @@ void gnt_screen_remove_widget(GntWidget *widget) { + int pos = g_list_index(g_list_first(focus_list), widget); + GList *next; + + if (lock_focus_list) + return; + + if (pos == -1) + return; + + focus_list = g_list_first(focus_list); focus_list = g_list_remove(focus_list, widget); + next = g_list_nth(focus_list, pos - 1); + if (next) + focus_list = next; + if (focus_list) { - gnt_widget_set_focus(focus_list->data, TRUE); - gnt_widget_draw(focus_list->data); + bring_on_top(focus_list->data); } draw_taskbar(); } @@ -52,29 +100,49 @@ bring_on_top(GntWidget *widget) { GntNode *node = g_hash_table_lookup(nodes, widget); - GList *iter; + g_return_if_fail(focus_list->data == widget); + if (!node) return; - for (iter = node->above; iter;) + gnt_widget_set_focus(focus_list->data, TRUE); + gnt_widget_draw(focus_list->data); + + top_panel(node->panel); + + if (window_list.window) { - GntNode *n = iter->data; - iter = iter->next; - n->below = g_list_remove(n->below, node); - n->above = g_list_prepend(n->above, node); - - node->above = g_list_remove(node->above, n); - node->below = g_list_prepend(node->below, n); + GntNode *nd = g_hash_table_lookup(nodes, window_list.window); + top_panel(nd->panel); } + update_panels(); + doupdate(); + draw_taskbar(); } static void +update_window_in_list(GntWidget *wid) +{ + GntTextFormatFlags flag = 0; + + if (window_list.window == NULL) + return; + + if (wid == focus_list->data) + flag |= GNT_TEXT_FLAG_DIM; + else if (GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_URGENT)) + flag |= GNT_TEXT_FLAG_BOLD; + + gnt_tree_set_row_flags(GNT_TREE(window_list.tree), wid, flag); +} + +static void draw_taskbar() { static WINDOW *taskbar = NULL; GList *iter; - int n, width; + int n, width = 0; int i; if (taskbar == NULL) @@ -82,6 +150,7 @@ taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0); } + wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); werase(taskbar); n = g_list_length(g_list_first(focus_list)); @@ -111,15 +180,106 @@ wbkgdset(taskbar, '\0' | COLOR_PAIR(color)); mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), width); mvwprintw(taskbar, 0, width * i, "%s", GNT_BOX(w)->title); + + update_window_in_list(w); } wrefresh(taskbar); } +static void +switch_window(int direction) +{ + GntWidget *w = NULL; + if (focus_list) + w = focus_list->data; + + if (direction == 1) + { + if (focus_list && focus_list->next) + focus_list = focus_list->next; + else + focus_list = g_list_first(focus_list); + } + else if (direction == -1) + { + if (focus_list && focus_list->prev) + focus_list = focus_list->prev; + else + focus_list = g_list_last(focus_list); + } + + if (focus_list) + { + bring_on_top(focus_list->data); + } + + if (w && (!focus_list || w != focus_list->data)) + { + gnt_widget_set_focus(w, FALSE); + } +} + +static void +window_list_activate(GntTree *tree, gpointer null) +{ + GntWidget *widget = gnt_tree_get_selection_data(GNT_TREE(tree)); + GntWidget *old = NULL; + + if (focus_list) + old = focus_list->data; + + focus_list = g_list_find(g_list_first(focus_list), widget); + bring_on_top(widget); + + if (old && (!focus_list || old != focus_list->data)) + { + gnt_widget_set_focus(old, FALSE); + } +} + +static void +show_window_list() +{ + GntWidget *tree, *win; + GList *iter; + + if (window_list.window) + return; + + win = window_list.window = gnt_box_new(FALSE, FALSE); + gnt_box_set_toplevel(GNT_BOX(win), TRUE); + gnt_box_set_title(GNT_BOX(win), "Window List"); + gnt_box_set_pad(GNT_BOX(win), 0); + + tree = window_list.tree = gnt_tree_new(); + + for (iter = g_list_first(focus_list); iter; iter = iter->next) + { + GntBox *box = GNT_BOX(iter->data); + + gnt_tree_add_row_after(GNT_TREE(tree), box, box->title, NULL, NULL); + update_window_in_list(GNT_WIDGET(box)); + } + + gnt_box_add_widget(GNT_BOX(win), tree); + + gnt_widget_set_size(tree, getmaxx(stdscr) / 3, getmaxy(stdscr) / 2); + gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4); + + lock_focus_list = 1; + gnt_widget_show(win); + lock_focus_list = 0; + + g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), NULL); +} + static gboolean io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) { char buffer[256]; + gboolean ret = FALSE; + static GntKeyPressMode mode = GNT_KP_MODE_NORMAL; int rd = read(0, buffer, sizeof(buffer) - 1); if (rd < 0) @@ -137,56 +297,197 @@ buffer[rd] = 0; - if (focus_list) + if (mode == GNT_KP_MODE_NORMAL) { - gboolean ret = FALSE; - ret = gnt_widget_key_pressed(focus_list->data, buffer); + if (focus_list) + { + ret = gnt_widget_key_pressed(focus_list->data, buffer); + } + + if (!ret) + { + if (buffer[0] == 27) + { + /* Some special key has been pressed */ + if (strcmp(buffer+1, GNT_KEY_POPUP) == 0) + {} + else if (strcmp(buffer + 1, "c") == 0) + { + /* Alt + c was pressed. I am going to use it to close a window. */ + if (focus_list) + { + gnt_widget_destroy(focus_list->data); + } + } + else if (strcmp(buffer + 1, "q") == 0) + { + /* I am going to use Alt + q to quit. */ + g_main_loop_quit(loop); + } + else if (strcmp(buffer + 1, "n") == 0) + { + /* Alt + n to go to the next window */ + switch_window(1); + } + else if (strcmp(buffer + 1, "p") == 0) + { + /* Alt + p to go to the previous window */ + switch_window(-1); + } + else if (strcmp(buffer + 1, "m") == 0 && focus_list) + { + /* Move a window */ + mode = GNT_KP_MODE_MOVE; + } + else if (strcmp(buffer + 1, "w") == 0 && focus_list) + { + /* Window list */ + mode = GNT_KP_MODE_WINDOW_LIST; + show_window_list(); + } + else if (strcmp(buffer + 1, "r") == 0 && focus_list) + { + /* Resize window */ + mode = GNT_KP_MODE_RESIZE; + } + } + } } - - if (buffer[0] == 27) + else if (mode == GNT_KP_MODE_MOVE && focus_list) { - /* Some special key has been pressed */ - if (strcmp(buffer+1, GNT_KEY_POPUP) == 0) - {} - else if (strcmp(buffer + 1, "c") == 0) + if (buffer[0] == 27) { - /* Alt + c was pressed. I am going to use it to close a window. */ - if (focus_list) + gboolean changed = FALSE; + int x, y, w, h; + GntWidget *widget = GNT_WIDGET(focus_list->data); + + gnt_widget_get_position(widget, &x, &y); + gnt_widget_get_size(widget, &w, &h); + + if (strcmp(buffer + 1, GNT_KEY_LEFT) == 0) { - gnt_widget_destroy(focus_list->data); - gnt_screen_remove_widget(focus_list->data); + if (x > X_MIN) + { + x--; + changed = TRUE; + } } + else if (strcmp(buffer + 1, GNT_KEY_RIGHT) == 0) + { + if (x + w < X_MAX) + { + x++; + changed = TRUE; + } + } + else if (strcmp(buffer + 1, GNT_KEY_UP) == 0) + { + if (y > Y_MIN) + { + y--; + changed = TRUE; + } + } + else if (strcmp(buffer + 1, GNT_KEY_DOWN) == 0) + { + if (y + h < Y_MAX) + { + y++; + changed = TRUE; + } + } + else if (buffer[1] == 0) + { + mode = GNT_KP_MODE_NORMAL; + changed = TRUE; + } + + if (changed) + { + GntNode *node = g_hash_table_lookup(nodes, widget); + gnt_widget_set_position(widget, x, y); + move_panel(node->panel, y, x); + update_panels(); + doupdate(); + } } - else if (strcmp(buffer + 1, "q") == 0) + else if (*buffer == '\r') { - /* I am going to use Alt + q to quit. */ - endwin(); - exit(1); + mode = GNT_KP_MODE_NORMAL; } - else if (strcmp(buffer + 1, "n") == 0) + } + else if (mode == GNT_KP_MODE_WINDOW_LIST && window_list.window) + { + gnt_widget_key_pressed(window_list.window, buffer); + + if (buffer[0] == '\r' || (buffer[0] == 27 && buffer[1] == 0)) { - /* Alt + n to go to the next window */ - GntWidget *w = NULL; - if (focus_list) - w = focus_list->data; + mode = GNT_KP_MODE_NORMAL; + lock_focus_list = 1; + gnt_widget_destroy(window_list.window); + window_list.window = NULL; + window_list.tree = NULL; + lock_focus_list = 0; + } + } + else if (mode == GNT_KP_MODE_RESIZE) + { + if (buffer[0] == '\r' || (buffer[0] == 27 && buffer[1] == 0)) + mode = GNT_KP_MODE_NORMAL; + else if (buffer[0] == 27) + { + GntWidget *widget = focus_list->data; + gboolean changed = FALSE; + int width, height; - if (focus_list && focus_list->next) - focus_list = focus_list->next; - else - focus_list = g_list_first(focus_list); - if (focus_list) + gnt_widget_get_size(widget, &width, &height); + + if (strcmp(buffer + 1, GNT_KEY_DOWN) == 0) { - gnt_widget_set_focus(focus_list->data, TRUE); - bring_on_top(focus_list->data); - gnt_widget_draw(focus_list->data); + if (widget->priv.y + height < Y_MAX) + { + height++; + changed = TRUE; + } } + else if (strcmp(buffer + 1, GNT_KEY_UP) == 0) + { + height--; + changed = TRUE; + } + else if (strcmp(buffer + 1, GNT_KEY_LEFT) == 0) + { + width--; + changed = TRUE; + } + else if (strcmp(buffer + 1, GNT_KEY_RIGHT) == 0) + { + if (widget->priv.x + width < X_MAX) + { + width++; + changed = TRUE; + } + } - if (w && w != focus_list->data) - gnt_widget_set_focus(w, FALSE); + if (changed) + { + GntNode *node = g_hash_table_lookup(nodes, widget); + int x, y; + + gnt_widget_get_position(widget, &x, &y); + + hide_panel(node->panel); + gnt_widget_set_size(widget, width, height); + gnt_widget_set_position(widget, x, y); + gnt_widget_draw(widget); + replace_panel(node->panel, widget->window); + show_panel(node->panel); + update_panels(); + doupdate(); + } } } - draw_taskbar(); refresh(); return TRUE; @@ -203,28 +504,41 @@ int result = g_io_add_watch(channel, (G_IO_IN | G_IO_HUP | G_IO_ERR), io_invoke, NULL); + const char *locale = setlocale(LC_ALL, ""); - setlocale(LC_ALL, ""); + if (locale && (strstr(locale, "UTF") || strstr(locale, "utf"))) + ascii_only = FALSE; + else + ascii_only = TRUE; + initscr(); start_color(); gnt_init_colors(); - max_x = getmaxx(stdscr); - max_y = getmaxy(stdscr); + X_MIN = 0; + Y_MIN = 0; + X_MAX = getmaxx(stdscr); + Y_MAX = getmaxy(stdscr) - 1; nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); noecho(); refresh(); +#if MAYBE_SOMEDAY mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL); +#endif + wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + werase(stdscr); + wrefresh(stdscr); + g_type_init(); } void gnt_main() { - GMainLoop *loop = g_main_new(FALSE); - g_main_run(loop); + loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(loop); } /********************************* @@ -235,45 +549,17 @@ free_node(gpointer data) { GntNode *node = data; - g_list_free(node->below); - g_list_free(node->above); + hide_panel(node->panel); + del_panel(node->panel); g_free(node); } -static void -check_intersection(gpointer key, gpointer value, gpointer data) -{ - GntNode *n = value; - GntNode *nu = data; - - if (value == NULL) - return; - if (n->me == nu->me) - return; - - if (n->me->priv.x + n->me->priv.width < nu->me->priv.x) - return; - if (nu->me->priv.x + nu->me->priv.width < n->me->priv.x) - return; - - if (n->me->priv.y + n->me->priv.height < nu->me->priv.y) - return; - if (nu->me->priv.y + nu->me->priv.height < n->me->priv.y) - return; - - n->above = g_list_prepend(n->above, nu); - nu->below = g_list_prepend(nu->below, n); -} - void gnt_screen_occupy(GntWidget *widget) { GntNode *node; - if (widget->parent) - { - while (widget->parent) - widget = widget->parent; - } + while (widget->parent) + widget = widget->parent; if (g_hash_table_lookup(nodes, widget)) return; /* XXX: perhaps _update instead? */ @@ -281,97 +567,64 @@ node = g_new0(GntNode, 1); node->me = widget; - g_hash_table_foreach(nodes, check_intersection, node); g_hash_table_replace(nodes, widget, node); + + if (window_list.window) + { + if ((GNT_IS_BOX(widget) && GNT_BOX(widget)->title) && window_list.window != widget + && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) + { + gnt_tree_add_row_after(GNT_TREE(window_list.tree), widget, + GNT_BOX(widget)->title, NULL, NULL); + update_window_in_list(widget); + } + } + + update_panels(); + doupdate(); } void gnt_screen_release(GntWidget *widget) { - WINDOW *win; - GList *iter; - GntNode *node = g_hash_table_lookup(nodes, widget); + GntNode *node; + + gnt_screen_remove_widget(widget); + node = g_hash_table_lookup(nodes, widget); + if (node == NULL) /* Yay! Nothing to do. */ return; - win = dupwin(widget->window); - werase(win); + g_hash_table_remove(nodes, widget); - /* XXX: This is not going to work. - * It will be necessary to build a topology and go from there. */ - for (iter = node->below; iter; iter = iter->next) + if (window_list.window) { - GntNode *n = iter->data; - GntWidget *w = n->me; - int left, right, top, bottom; - - left = MAX(widget->priv.x, w->priv.x) - w->priv.x; - right = MIN(widget->priv.x + widget->priv.width, w->priv.x + w->priv.width) - w->priv.x; - - top = MAX(widget->priv.y, w->priv.y) - w->priv.y; - bottom = MIN(widget->priv.y + widget->priv.height, w->priv.y + w->priv.height) - w->priv.y; - - copywin(w->window, win, top, left, - w->priv.y - widget->priv.y + top, - w->priv.x - widget->priv.x + left, - w->priv.y - widget->priv.y + bottom - 1, - w->priv.x - widget->priv.x + right - 1, FALSE); - n->above = g_list_remove(n->above, node); + gnt_tree_remove(GNT_TREE(window_list.tree), widget); } - for (iter = node->above; iter; iter = iter->next) - { - GntNode *n = iter->data; - n->below = g_list_remove(n->below, node); - } - - wrefresh(win); - delwin(win); - - g_hash_table_remove(nodes, widget); + update_panels(); + doupdate(); } void gnt_screen_update(GntWidget *widget) { - GList *iter; - WINDOW *win; GntNode *node; - if (widget->parent) - { - while (widget->parent) - widget = widget->parent; - } + while (widget->parent) + widget = widget->parent; gnt_box_sync_children(GNT_BOX(widget)); node = g_hash_table_lookup(nodes, widget); + if (node && !node->panel) + node->panel = new_panel(node->me->window); - win = dupwin(widget->window); - - if (node && node->above) + if (window_list.window) { - /* XXX: Same here: need to build a topology first. */ - for (iter = node->above; iter; iter = iter->next) - { - GntNode *n = iter->data; - GntWidget *w = n->me; - int left, right, top, bottom; - - left = MAX(widget->priv.x, w->priv.x) - w->priv.x; - right = MIN(widget->priv.x + widget->priv.width, w->priv.x + w->priv.width) - w->priv.x; - - top = MAX(widget->priv.y, w->priv.y) - w->priv.y; - bottom = MIN(widget->priv.y + widget->priv.height, w->priv.y + w->priv.height) - w->priv.y; - - copywin(w->window, win, top, left, - w->priv.y - widget->priv.y + top, - w->priv.x - widget->priv.x + left, - w->priv.y - widget->priv.y + bottom - 1, - w->priv.x - widget->priv.x + right - 1, FALSE); - } + GntNode *nd = g_hash_table_lookup(nodes, window_list.window); + top_panel(nd->panel); } - wrefresh(win); - delwin(win); + update_panels(); + doupdate(); } gboolean gnt_widget_has_focus(GntWidget *widget) @@ -383,17 +636,18 @@ w = widget; while (widget->parent) - { - fprintf(stderr, "%p %p\n", widget, widget->parent); widget = widget->parent; - } - fprintf(stderr, "%p %p\n", widget, widget->parent); - if (focus_list && focus_list->data == widget && - (!GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) || - GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS))) + if (widget == window_list.window) return TRUE; + if (focus_list && focus_list->data == widget) + { + if (GNT_IS_BOX(widget) && + (GNT_BOX(widget)->active == w || widget == w)) + return TRUE; + } + return FALSE; } @@ -409,3 +663,13 @@ draw_taskbar(); } +void gnt_quit() +{ + endwin(); +} + +gboolean gnt_ascii_only() +{ + return ascii_only; +} + Modified: branches/soc-2006-file-loggers/console/libgnt/gnttextview.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnttextview.c 2006-07-08 22:08:51 UTC (rev 16464) +++ branches/soc-2006-file-loggers/console/libgnt/gnttextview.c 2006-07-08 22:43:22 UTC (rev 16465) @@ -7,7 +7,7 @@ typedef struct { - GntTextViewFlags flags; + GntTextFormatFlags flags; char *text; } GntTextSegment; @@ -113,6 +113,9 @@ static void gnt_text_view_init(GTypeInstance *instance, gpointer class) { + /* XXX: For now, resizing the width is not permitted. This is because + * of the way I am handling wrapped lines. */ + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_Y); DEBUG; } @@ -152,14 +155,14 @@ GntTextView *view = GNT_TEXT_VIEW(widget); GntTextLine *line = g_new0(GntTextLine, 1); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER); + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); view->list = g_list_append(view->list, line); return widget; } -void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextViewFlags flags) +void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextFormatFlags flags) { GntWidget *widget = GNT_WIDGET(view); int fl = 0; @@ -198,7 +201,7 @@ { GntTextSegment *seg = g_new0(GntTextSegment, 1); seg->flags = fl; - seg->text = g_new0(char, len); /* XXX: MUST be improved */ + seg->text = g_new0(char, len + 1); /* XXX: MUST be improved */ g_utf8_strncpy(seg->text, iter, widget->priv.width - line->length - 1); line->segments = g_list_append(line->segments, seg); Modified: branches/soc-2006-file-loggers/console/libgnt/gnttextview.h ======================... [truncated message content] |
From: <ro...@us...> - 2006-07-29 21:39:13
|
Revision: 16598 Author: roast Date: 2006-07-29 14:38:18 -0700 (Sat, 29 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16598&view=rev Log Message: ----------- merged with svn trunk. 16534:16597. Modified Paths: -------------- branches/soc-2006-file-loggers/COPYRIGHT branches/soc-2006-file-loggers/config.h.mingw branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/console/Makefile branches/soc-2006-file-loggers/console/gntaccount.c branches/soc-2006-file-loggers/console/gntaccount.h branches/soc-2006-file-loggers/console/gntconv.c branches/soc-2006-file-loggers/console/gntgaim.c branches/soc-2006-file-loggers/console/gntnotify.c branches/soc-2006-file-loggers/console/gntui.c branches/soc-2006-file-loggers/console/libgnt/Makefile.am branches/soc-2006-file-loggers/console/libgnt/gntbox.c branches/soc-2006-file-loggers/console/libgnt/gntbutton.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.c branches/soc-2006-file-loggers/console/libgnt/gntcolors.h branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c branches/soc-2006-file-loggers/console/libgnt/gntcombobox.h branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntentry.h branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gnttree.h branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.h branches/soc-2006-file-loggers/console/libgnt/test/combo.c branches/soc-2006-file-loggers/doc/gtkconv-signals.dox branches/soc-2006-file-loggers/doc/log-signals.dox branches/soc-2006-file-loggers/plugins/ChangeLog.API branches/soc-2006-file-loggers/plugins/timestamp_format.c branches/soc-2006-file-loggers/src/conversation.c branches/soc-2006-file-loggers/src/gtkaccount.c branches/soc-2006-file-loggers/src/gtkconn.c branches/soc-2006-file-loggers/src/gtkconv.c branches/soc-2006-file-loggers/src/gtkconv.h branches/soc-2006-file-loggers/src/log.c branches/soc-2006-file-loggers/src/notify.c branches/soc-2006-file-loggers/src/protocols/gg/gg.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h branches/soc-2006-file-loggers/src/protocols/jabber/message.c branches/soc-2006-file-loggers/src/protocols/msn/servconn.c branches/soc-2006-file-loggers/src/protocols/oscar/flap_connection.c branches/soc-2006-file-loggers/src/protocols/oscar/odc.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.h branches/soc-2006-file-loggers/src/protocols/qq/Makefile.am branches/soc-2006-file-loggers/src/protocols/qq/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.h branches/soc-2006-file-loggers/src/protocols/qq/crypt.c branches/soc-2006-file-loggers/src/protocols/qq/group_opt.c branches/soc-2006-file-loggers/src/protocols/qq/qq.c branches/soc-2006-file-loggers/src/protocols/qq/qq.h branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.h branches/soc-2006-file-loggers/src/protocols/qq/utils.c branches/soc-2006-file-loggers/src/protocols/qq/utils.h branches/soc-2006-file-loggers/src/protocols/sametime/sametime.c branches/soc-2006-file-loggers/src/protocols/simple/simple.c branches/soc-2006-file-loggers/src/signals.c branches/soc-2006-file-loggers/src/signals.h branches/soc-2006-file-loggers/src/sslconn.c branches/soc-2006-file-loggers/src/value.h branches/soc-2006-file-loggers/src/win32/win32dep.c Added Paths: ----------- branches/soc-2006-file-loggers/console/gntdebug.c branches/soc-2006-file-loggers/console/gntdebug.h branches/soc-2006-file-loggers/console/gntprefs.c branches/soc-2006-file-loggers/console/gntprefs.h branches/soc-2006-file-loggers/console/gntrequest.c branches/soc-2006-file-loggers/console/gntrequest.h branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.c branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.h branches/soc-2006-file-loggers/console/libgnt/gntrc.sample branches/soc-2006-file-loggers/console/libgnt/gntstyle.c branches/soc-2006-file-loggers/console/libgnt/gntstyle.h Removed Paths: ------------- branches/soc-2006-file-loggers/src/protocols/qq/TODO branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.c branches/soc-2006-file-loggers/src/protocols/qq/group_admindlg.h branches/soc-2006-file-loggers/src/protocols/qq/infodlg.c branches/soc-2006-file-loggers/src/protocols/qq/infodlg.h branches/soc-2006-file-loggers/src/protocols/qq/show.c branches/soc-2006-file-loggers/src/protocols/qq/show.h Modified: branches/soc-2006-file-loggers/COPYRIGHT =================================================================== --- branches/soc-2006-file-loggers/COPYRIGHT 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/COPYRIGHT 2006-07-29 21:38:18 UTC (rev 16598) @@ -195,6 +195,7 @@ Richard Nelson Dennis Nezic Matthew A. Nicholson +Henning Norén Szilard Novaki Novell Padraig O'Briain Modified: branches/soc-2006-file-loggers/config.h.mingw =================================================================== --- branches/soc-2006-file-loggers/config.h.mingw 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/config.h.mingw 2006-07-29 21:38:18 UTC (rev 16598) @@ -641,3 +641,5 @@ * Following are added for Win32 version of Gaim */ #define HAVE_VSNPRINTF 1 + +#define SIZEOF_TIME_T 4 Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/configure.ac 2006-07-29 21:38:18 UTC (rev 16598) @@ -60,6 +60,9 @@ dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_STRUCT_TM +AC_CHECK_SIZEOF(time_t, ,[ +#include <stdio.h> +#include <time.h>]) AC_C_BIGENDIAN Modified: branches/soc-2006-file-loggers/console/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/Makefile 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/Makefile 2006-07-29 21:38:18 UTC (rev 16598) @@ -8,7 +8,10 @@ gntblist.c \ gntconn.c \ gntconv.c \ + gntdebug.c \ gntnotify.c \ + gntprefs.c \ + gntrequest.c \ gntui.c GG_HEADERS = \ @@ -16,7 +19,10 @@ gntblist.h \ gntconn.h \ gntconv.h \ + gntdebug.h \ gntnotify.h \ + gntprefs.h \ + gntrequest.h \ gntui.h GG_OBJECTS = \ @@ -24,7 +30,10 @@ gntblist.o \ gntconn.o \ gntconv.o \ + gntdebug.o \ gntnotify.o \ + gntprefs.o \ + gntrequest.o \ gntui.o all: gntgaim Modified: branches/soc-2006-file-loggers/console/gntaccount.c =================================================================== --- branches/soc-2006-file-loggers/console/gntaccount.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/gntaccount.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -1,6 +1,7 @@ #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> +#include <gntcheckbox.h> #include <gntcombobox.h> #include <gntentry.h> #include <gntlabel.h> @@ -17,6 +18,8 @@ #include "gntaccount.h" #include "gntgaim.h" +#include <string.h> + typedef struct { GntWidget *window; @@ -38,17 +41,157 @@ GntWidget *splits; GList *split_entries; + + GList *prpl_entries; + GntWidget *prpls; + + GntWidget *newmail; + GntWidget *remember; } AccountEditDialog; static void +account_add(GaimAccount *account) +{ + gnt_tree_add_choice(GNT_TREE(accounts.tree), account, + gnt_tree_create_row(GNT_TREE(accounts.tree), + gaim_account_get_username(account), + gaim_account_get_protocol_name(account)), + NULL, NULL); + gnt_tree_set_choice(GNT_TREE(accounts.tree), account, + gaim_account_get_enabled(account, GAIM_GNT_UI)); +} + +static void edit_dialog_destroy(AccountEditDialog *dialog) { + g_list_free(dialog->prpl_entries); + g_list_free(dialog->split_entries); g_free(dialog); } static void save_account_cb(AccountEditDialog *dialog) { + GaimAccount *account; + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + const char *value; + GString *username; + + /* XXX: Do some error checking first. */ + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + /* Screenname && user-splits */ + value = gnt_entry_get_text(GNT_ENTRY(dialog->screenname)); + + if (value == NULL || *value == '\0') + { + gaim_notify_error(NULL, _("Error"), _("Account was not added"), + _("Screenname of an account must be non-empty.")); + return; + } + + username = g_string_new(value); + + if (prplinfo != NULL) + { + GList *iter, *entries; + for (iter = prplinfo->user_splits, entries = dialog->split_entries; + iter && entries; iter = iter->next, entries = entries->next) + { + GaimAccountUserSplit *split = iter->data; + GntWidget *entry = entries->data; + + value = gnt_entry_get_text(GNT_ENTRY(entry)); + if (value == NULL || *value == '\0') + value = gaim_account_user_split_get_default_value(split); + g_string_append_printf(username, "%c%s", + gaim_account_user_split_get_separator(split), + value); + } + } + + if (dialog->account == NULL) + { + account = gaim_account_new(username->str, gaim_plugin_get_id(plugin)); + gaim_accounts_add(account); + } + else + { + account = dialog->account; + + /* Protocol */ + gaim_account_set_protocol_id(account, gaim_plugin_get_id(plugin)); + gaim_account_set_username(account, username->str); + } + g_string_free(username, TRUE); + + /* Alias */ + value = gnt_entry_get_text(GNT_ENTRY(dialog->alias)); + if (value && *value) + gaim_account_set_alias(account, value); + + /* Remember password and password */ + gaim_account_set_remember_password(account, + gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->remember))); + value = gnt_entry_get_text(GNT_ENTRY(dialog->password)); + if (value && *value && gaim_account_get_remember_password(account)) + gaim_account_set_password(account, value); + else + gaim_account_set_password(account, NULL); + + /* Mail notification */ + /* XXX: Only if the protocol has anything to do with emails */ + gaim_account_set_check_mail(account, + gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->newmail))); + + /* Protocol options */ + if (prplinfo) + { + GList *iter, *entries; + + for (iter = prplinfo->protocol_options, entries = dialog->prpl_entries; + iter && entries; iter = iter->next, entries = entries->next) + { + GaimAccountOption *option = iter->data; + GntWidget *entry = entries->data; + GaimPrefType type = gaim_account_option_get_type(option); + const char *setting = gaim_account_option_get_setting(option); + + if (type == GAIM_PREF_STRING) + { + const char *value = gnt_entry_get_text(GNT_ENTRY(entry)); + gaim_account_set_string(account, setting, value); + } + else if (type == GAIM_PREF_INT) + { + const char *str = gnt_entry_get_text(GNT_ENTRY(entry)); + int value = 0; + if (str) + value = atoi(str); + gaim_account_set_int(account, setting, value); + } + else if (type == GAIM_PREF_BOOLEAN) + { + gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(entry)); + gaim_account_set_bool(account, setting, value); + } + else if (type == GAIM_PREF_STRING_LIST) + { + /* TODO: */ + } + else + { + g_assert_not_reached(); + } + } + } + + /* XXX: Proxy options */ + + gnt_widget_destroy(dialog->window); } static void @@ -57,7 +200,7 @@ GntWidget *hbox; GaimPlugin *plugin; GaimPluginProtocolInfo *prplinfo; - GList *iter; + GList *iter, *entries; char *username = NULL; if (dialog->splits) @@ -99,20 +242,184 @@ g_free(buf); } - /* XXX: Add default/custom values to the splits */ + for (iter = g_list_last(prplinfo->user_splits), entries = g_list_last(dialog->split_entries); + iter && entries; iter = iter->prev, entries = entries->prev) + { + GntWidget *entry = entries->data; + GaimAccountUserSplit *split = iter->data; + const char *value = NULL; + char *s; + + if (dialog->account) + { + s = strrchr(username, gaim_account_user_split_get_separator(split)); + if (s != NULL) + { + *s = '\0'; + s++; + value = s; + } + } + if (value == NULL) + value = gaim_account_user_split_get_default_value(split); + + if (value != NULL) + gnt_entry_set_text(GNT_ENTRY(entry), value); + } + + if (username != NULL) + gnt_entry_set_text(GNT_ENTRY(dialog->screenname), username); + g_free(username); } static void +add_protocol_options(AccountEditDialog *dialog) +{ + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + GList *iter; + GntWidget *vbox, *box; + GaimAccount *account; + + if (dialog->prpls) + gnt_box_remove_all(GNT_BOX(dialog->prpls)); + else + { + dialog->prpls = vbox = gnt_vbox_new(FALSE); + gnt_box_set_pad(GNT_BOX(vbox), 0); + gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_LEFT); + gnt_box_set_fill(GNT_BOX(vbox), TRUE); + } + + if (dialog->prpl_entries) + { + g_list_free(dialog->prpl_entries); + dialog->prpl_entries = NULL; + } + + vbox = dialog->prpls; + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + if (!plugin) + return; + + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + account = dialog->account; + + for (iter = prplinfo->protocol_options; iter; iter = iter->next) + { + GaimAccountOption *option = iter->data; + GaimPrefType type = gaim_account_option_get_type(option); + + box = gnt_hbox_new(TRUE); + gnt_box_set_pad(GNT_BOX(box), 0); + gnt_box_add_widget(GNT_BOX(vbox), box); + + if (type == GAIM_PREF_BOOLEAN) + { + GntWidget *widget = gnt_check_box_new(gaim_account_option_get_text(option)); + gnt_box_add_widget(GNT_BOX(box), widget); + dialog->prpl_entries = g_list_append(dialog->prpl_entries, widget); + + if (account) + gnt_check_box_set_checked(GNT_CHECK_BOX(widget), + gaim_account_get_bool(account, + gaim_account_option_get_setting(option), + gaim_account_option_get_default_bool(option))); + else + gnt_check_box_set_checked(GNT_CHECK_BOX(widget), + gaim_account_option_get_default_bool(option)); + } + else + { + gnt_box_add_widget(GNT_BOX(box), + gnt_label_new(gaim_account_option_get_text(option))); + + if (type == GAIM_PREF_STRING_LIST) + { + /* TODO: Use a combobox */ + /* Don't forget to append the widget to prpl_entries */ + } + else + { + GntWidget *entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(box), entry); + dialog->prpl_entries = g_list_append(dialog->prpl_entries, entry); + + if (type == GAIM_PREF_STRING) + { + const char *dv = gaim_account_option_get_default_string(option); + + if (account) + gnt_entry_set_text(GNT_ENTRY(entry), + gaim_account_get_string(account, + gaim_account_option_get_setting(option), dv)); + else + gnt_entry_set_text(GNT_ENTRY(entry), dv); + } + else if (type == GAIM_PREF_INT) + { + char str[32]; + int value = gaim_account_option_get_default_int(option); + if (account) + value = gaim_account_get_int(account, + gaim_account_option_get_setting(option), value); + snprintf(str, sizeof(str), "%d", value); + gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT); + gnt_entry_set_text(GNT_ENTRY(entry), str); + } + else + { + g_assert_not_reached(); + } + } + } + } +} + +static void +update_user_options(AccountEditDialog *dialog) +{ + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + if (!plugin) + return; + + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + if (dialog->newmail == NULL) + dialog->newmail = gnt_check_box_new(_("New mail notifications")); + if (dialog->account) + gnt_check_box_set_checked(GNT_CHECK_BOX(dialog->newmail), + gaim_account_get_check_mail(dialog->account)); + if (!prplinfo || !(prplinfo->options & OPT_PROTO_MAIL_CHECK)) + gnt_widget_set_visible(dialog->newmail, FALSE); + else + gnt_widget_set_visible(dialog->newmail, TRUE); + + if (dialog->remember == NULL) + dialog->remember = gnt_check_box_new(_("Remember password")); + if (dialog->account) + gnt_check_box_set_checked(GNT_CHECK_BOX(dialog->remember), + gaim_account_get_remember_password(dialog->account)); +} + +static void prpl_changed_cb(GntWidget *combo, GaimPlugin *old, GaimPlugin *new, AccountEditDialog *dialog) { update_user_splits(dialog); + add_protocol_options(dialog); + update_user_options(dialog); /* This may not be necessary here */ gnt_box_readjust(GNT_BOX(dialog->window)); gnt_widget_draw(dialog->window); } static void -add_account(GntWidget *b, gpointer null) +edit_account(GaimAccount *account) { GntWidget *window, *hbox; GntWidget *combo, *button, *entry; @@ -122,8 +429,9 @@ dialog = g_new0(AccountEditDialog, 1); dialog->window = window = gnt_box_new(FALSE, TRUE); + dialog->account = account; gnt_box_set_toplevel(GNT_BOX(window), TRUE); - gnt_box_set_title(GNT_BOX(window), _("New Account")); + gnt_box_set_title(GNT_BOX(window), account ? _("Modify Account") : _("New Account")); gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); gnt_box_set_pad(GNT_BOX(window), 0); @@ -138,6 +446,12 @@ gnt_combo_box_add_data(GNT_COMBO_BOX(combo), iter->data, ((GaimPlugin*)iter->data)->info->name); } + if (account) + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), + gaim_plugins_find_with_id(gaim_account_get_protocol_id(account))); + else + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), list->data); + g_signal_connect(G_OBJECT(combo), "selection-changed", G_CALLBACK(prpl_changed_cb), dialog); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Protocol:"))); gnt_box_add_widget(GNT_BOX(hbox), combo); @@ -157,8 +471,11 @@ gnt_box_add_widget(GNT_BOX(window), hbox); dialog->password = entry = gnt_entry_new(NULL); + gnt_entry_set_masked(GNT_ENTRY(entry), TRUE); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Password:"))); gnt_box_add_widget(GNT_BOX(hbox), entry); + if (account) + gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_password(account)); hbox = gnt_box_new(TRUE, FALSE); gnt_box_add_widget(GNT_BOX(window), hbox); @@ -166,9 +483,23 @@ dialog->alias = entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Alias:"))); gnt_box_add_widget(GNT_BOX(hbox), entry); + if (account) + gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_alias(account)); + /* User options */ + update_user_options(dialog); + gnt_box_add_widget(GNT_BOX(window), dialog->remember); + gnt_box_add_widget(GNT_BOX(window), dialog->newmail); + gnt_box_add_widget(GNT_BOX(window), gnt_line_new(FALSE)); - + + /* The advanced box */ + add_protocol_options(dialog); + gnt_box_add_widget(GNT_BOX(window), dialog->prpls); + + /* TODO: Add proxy options */ + + /* The button box */ hbox = gnt_box_new(FALSE, FALSE); gnt_box_add_widget(GNT_BOX(window), hbox); @@ -183,9 +514,33 @@ g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(edit_dialog_destroy), dialog); gnt_widget_show(window); + gnt_box_readjust(GNT_BOX(window)); + gnt_widget_draw(window); } static void +add_account_cb(GntWidget *widget, gpointer null) +{ + edit_account(NULL); +} + +static void +modify_account_cb(GntWidget *widget, GntTree *tree) +{ + GaimAccount *account = gnt_tree_get_selection_data(tree); + if (!account) + return; + edit_account(account); +} + +static void +delete_account_cb(GntWidget *widget, GntTree *tree) +{ + /* XXX: After the request-api is complete */ + /* Note: remove the modify-dialog for the account */ +} + +static void account_toggled(GntWidget *widget, void *key, gpointer null) { GaimAccount *account = key; @@ -193,7 +548,7 @@ gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key)); } -void gg_accounts_init() +void gg_accounts_show_all() { GList *iter; GntWidget *box, *button; @@ -216,14 +571,7 @@ for (iter = gaim_accounts_get_all(); iter; iter = iter->next) { GaimAccount *account = iter->data; - - gnt_tree_add_choice(GNT_TREE(accounts.tree), account, - gnt_tree_create_row(GNT_TREE(accounts.tree), - gaim_account_get_username(account), - gaim_account_get_protocol_name(account)), - NULL, NULL); - gnt_tree_set_choice(GNT_TREE(accounts.tree), account, - gaim_account_get_enabled(account, GAIM_GNT_UI)); + account_add(account); } g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL); @@ -238,27 +586,65 @@ button = gnt_button_new(_("Add")); gnt_box_add_widget(GNT_BOX(box), button); - g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_account), NULL); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_account_cb), NULL); button = gnt_button_new(_("Modify")); gnt_box_add_widget(GNT_BOX(box), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(modify_account_cb), accounts.tree); button = gnt_button_new(_("Delete")); gnt_box_add_widget(GNT_BOX(box), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_account_cb), accounts.tree); gnt_box_add_widget(GNT_BOX(accounts.window), box); gnt_widget_show(accounts.window); } +static gpointer +gg_accounts_get_handle() +{ + static int handle; + + return &handle; +} + +static void +account_added_callback(GaimAccount *account) +{ + if (accounts.window == NULL) + return; + account_add(account); + gnt_widget_draw(accounts.tree); +} + +static void +account_removed_callback(GaimAccount *account) +{ + if (accounts.window == NULL) + return; + + gnt_tree_remove(GNT_TREE(accounts.tree), account); +} + +void gg_accounts_init() +{ + gaim_signal_connect(gaim_accounts_get_handle(), "account-added", + gg_accounts_get_handle(), GAIM_CALLBACK(account_added_callback), + NULL); + gaim_signal_connect(gaim_accounts_get_handle(), "account-removed", + gg_accounts_get_handle(), GAIM_CALLBACK(account_removed_callback), + NULL); + + gg_accounts_show_all(); +} + void gg_accounts_uninit() { gnt_widget_destroy(accounts.window); } -#if 0 /* The following uiops stuff are copied from gtkaccount.c */ -/* Need to do some work on notify- and request-ui before this works */ typedef struct { GaimAccount *account; @@ -305,6 +691,31 @@ } static void +free_add_user_data(AddUserData *data) +{ + g_free(data->username); + + if (data->alias != NULL) + g_free(data->alias); + + g_free(data); +} + +static void +add_user_cb(AddUserData *data) +{ + GaimConnection *gc = gaim_account_get_connection(data->account); + + if (g_list_find(gaim_connections_get_all(), gc)) + { + gaim_blist_request_add_buddy(data->account, data->username, + NULL, data->alias); + } + + free_add_user_data(data); +} + +static void request_add(GaimAccount *account, const char *remote_user, const char *id, const char *alias, const char *msg) @@ -321,12 +732,10 @@ data->alias = (alias != NULL ? g_strdup(alias) : NULL); buffer = make_info(account, gc, remote_user, id, alias, msg); -#if 0 gaim_request_action(NULL, NULL, _("Add buddy to your list?"), buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, _("Add"), G_CALLBACK(add_user_cb), _("Cancel"), G_CALLBACK(free_add_user_data)); -#endif g_free(buffer); } @@ -336,17 +745,7 @@ .status_changed = NULL, .request_add = request_add }; -#else -static GaimAccountUiOps ui_ops = -{ - .notify_added = NULL, - .status_changed = NULL, - .request_add = NULL -}; - -#endif - GaimAccountUiOps *gg_accounts_get_ui_ops() { return &ui_ops; Modified: branches/soc-2006-file-loggers/console/gntaccount.h =================================================================== --- branches/soc-2006-file-loggers/console/gntaccount.h 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/gntaccount.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -5,3 +5,6 @@ void gg_accounts_init(); void gg_accounts_uninit(); + +void gg_accounts_show_all(); + Modified: branches/soc-2006-file-loggers/console/gntconv.c =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/gntconv.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -159,9 +159,10 @@ g_hash_table_insert(ggconvs, conv, ggc); ggc->conv = conv; + conv->ui_data = ggc; type = gaim_conversation_get_type(conv); - title = g_strdup_printf(_("%s"), gaim_conversation_get_name(conv)); + title = g_strdup_printf(_("%s"), gaim_conversation_get_title(conv)); ggc->window = gnt_box_new(FALSE, TRUE); gnt_box_set_title(GNT_BOX(ggc->window), title); gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); @@ -199,7 +200,7 @@ gg_write_common(GaimConversation *conv, const char *who, const char *message, GaimMessageFlags flags, time_t mtime) { - GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); + GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); /* XXX: ggconv = conv->ui_data; should do */ char *strip; GntTextFormatFlags fl = 0; @@ -243,9 +244,9 @@ gg_write_im(GaimConversation *conv, const char *who, const char *message, GaimMessageFlags flags, time_t mtime) { + GaimAccount *account = gaim_conversation_get_account(conv); if (flags & GAIM_MESSAGE_SEND) { - GaimAccount *account = gaim_conversation_get_account(conv); who = gaim_connection_get_display_name(gaim_account_get_connection(account)); if (!who) who = gaim_account_get_alias(account); @@ -253,7 +254,13 @@ who = gaim_account_get_username(account); } else if (flags & GAIM_MESSAGE_RECV) + { + GaimBuddy *buddy; who = gaim_conversation_get_name(conv); + buddy = gaim_find_buddy(account, who); + if (buddy) + who = gaim_buddy_get_contact_alias(buddy); + } gg_write_common(conv, who, message, flags, mtime); } Copied: branches/soc-2006-file-loggers/console/gntdebug.c (from rev 16597, trunk/console/gntdebug.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntdebug.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntdebug.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,114 @@ +#include <gnt.h> +#include <gntbox.h> +#include <gnttextview.h> + +#include "gntdebug.h" +#include "gntgaim.h" + +#include <stdio.h> +#include <string.h> + +static struct +{ + GntWidget *window; + GntWidget *tview; +} debug; + +static gboolean +debug_window_kpress_cb(GntWidget *wid, const char *key, GntTextView *view) +{ + if (key[0] == 27) + { + /* XXX: This doesn't seem to always work */ + if (strcmp(key+1, GNT_KEY_DOWN) == 0) + gnt_text_view_scroll(view, 1); + else if (strcmp(key+1, GNT_KEY_UP) == 0) + gnt_text_view_scroll(view, -1); + else if (strcmp(key+1, GNT_KEY_PGDOWN) == 0) + gnt_text_view_scroll(view, wid->priv.height - 2); + else if (strcmp(key+1, GNT_KEY_PGUP) == 0) + gnt_text_view_scroll(view, -(wid->priv.height - 2)); + else + return FALSE; + return TRUE; + } + return FALSE; +} + +static void +gg_debug_print(GaimDebugLevel level, const char *category, + const char *args) +{ + if (debug.window == NULL) + fprintf(stderr, "%s: %s\n", category, args); + else + { + GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL; + + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), + category, GNT_TEXT_FLAG_BOLD); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), + ": ", GNT_TEXT_FLAG_BOLD); + + switch (level) + { + case GAIM_DEBUG_WARNING: + flag |= GNT_TEXT_FLAG_UNDERLINE; + case GAIM_DEBUG_ERROR: + case GAIM_DEBUG_FATAL: + flag |= GNT_TEXT_FLAG_BOLD; + break; + default: + break; + } + + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), args, flag); + gnt_text_view_next_line(GNT_TEXT_VIEW(debug.tview)); + gnt_text_view_scroll(GNT_TEXT_VIEW(debug.tview), 0); + + g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview); + } +} + +static GaimDebugUiOps uiops = +{ + gg_debug_print, +}; + +GaimDebugUiOps *gg_debug_get_ui_ops() +{ + return &uiops; +} + +static void +reset_debug_win(GntWidget *w, gpointer null) +{ + debug.window = debug.tview = NULL; +} + +void gg_debug_window_show() +{ + if (debug.window == NULL) + { + debug.window = gnt_vbox_new(FALSE); + gnt_box_set_toplevel(GNT_BOX(debug.window), TRUE); + gnt_box_set_title(GNT_BOX(debug.window), _("Debug Window")); + + debug.tview = gnt_text_view_new(); + gnt_box_add_widget(GNT_BOX(debug.window), debug.tview); + + g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL); + } + + gnt_widget_show(debug.window); +} + +void gg_debug_init() +{ + gg_debug_window_show(); +} + +void gg_debug_uninit() +{ +} + Copied: branches/soc-2006-file-loggers/console/gntdebug.h (from rev 16597, trunk/console/gntdebug.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntdebug.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntdebug.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,8 @@ +#include "debug.h" + +GaimDebugUiOps *gg_debug_get_ui_ops(); + +void gg_debug_init(); + +void gg_debug_uninit(); + Modified: branches/soc-2006-file-loggers/console/gntgaim.c =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/gntgaim.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -15,18 +15,25 @@ #include "util.h" #include "whiteboard.h" +#include "gntdebug.h" #include "gntgaim.h" +#include "gntprefs.h" #include "gntui.h" #define _GNU_SOURCE #include <getopt.h> -/* Anything IO-related is directly copied from gtkgaim's source tree */ +static void +debug_init() +{ + gg_debug_init(); + gaim_debug_set_ui_ops(gg_debug_get_ui_ops()); +} static GaimCoreUiOps core_ops = { - NULL, /*gaim_gtk_prefs_init,*/ - NULL, /*debug_init,*/ + gg_prefs_init, + debug_init, NULL, /*gaim_gtk_ui_init,*/ NULL, /*gaim_gtk_quit*/ }; @@ -37,6 +44,8 @@ return &core_ops; } +/* Anything IO-related is directly copied from gtkgaim's source tree */ + #define GAIM_GTK_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) #define GAIM_GTK_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) @@ -237,7 +246,11 @@ gaim_plugins_add_search_path(path); g_free(path); - gaim_plugins_add_search_path("/usr/local/lib/gaim"); /* XXX: */ +#ifdef LIBDIR + gaim_plugins_add_search_path(LIBDIR); +#else + gaim_plugins_add_search_path("/usr/local/lib/gaim"); /* XXX: Remove this after the restructure */ +#endif if (!gaim_core_init(GAIM_GNT_UI)) { @@ -293,6 +306,8 @@ /* XXX: Don't puke */ freopen(".error", "w", stderr); + gnt_init(); + /* Initialize the libgaim stuff */ if (!init_libgaim(argc, argv)) return 0; Modified: branches/soc-2006-file-loggers/console/gntnotify.c =================================================================== --- branches/soc-2006-file-loggers/console/gntnotify.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/gntnotify.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -15,6 +15,12 @@ GntWidget *tree; } emaildialog; +static void +notify_msg_window_destroy_cb(GntWidget *window, GaimNotifyMsgType type) +{ + gaim_notify_close(type, window); +} + static void * gg_notify_message(GaimNotifyMsgType type, const char *title, const char *primary, const char *secondary) @@ -48,7 +54,10 @@ button = gnt_button_new(_("OK")); gnt_box_add_widget(GNT_BOX(window), button); - g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), window); + g_signal_connect_swapped(G_OBJECT(button), "activate", + G_CALLBACK(gnt_widget_destroy), window); + g_signal_connect(G_OBJECT(window), "destroy", + G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(type)); gnt_widget_show(window); return window; @@ -57,7 +66,22 @@ /* handle is, in all/most occasions, a GntWidget * */ static void gg_close_notify(GaimNotifyType type, void *handle) { - gnt_widget_destroy(GNT_WIDGET(handle)); + GntWidget *widget = handle; + + if (!widget) + return; + + while (widget->parent) + widget = widget->parent; + + if (type == GAIM_NOTIFY_SEARCHRESULTS) + gaim_notify_searchresults_free(g_object_get_data(handle, "notify-results")); +#if 0 + /* This does not seem to be necessary */ + g_signal_handlers_disconnect_by_func(G_OBJECT(widget), + G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(type)); +#endif + gnt_widget_destroy(widget); } static void *gg_notify_formatted(const char *title, const char *primary, @@ -71,7 +95,7 @@ secondary ? "\n" : "", unformat ? unformat : ""); - void *ret = gg_notify_message(GAIM_NOTIFY_MSG_INFO, title, primary, t); + void *ret = gg_notify_message(GAIM_NOTIFY_FORMATTED, title, primary, t); g_free(t); g_free(unformat); @@ -151,7 +175,7 @@ return NULL; } - ret = gg_notify_message(GAIM_NOTIFY_MSG_INFO, _("New Mail"), _("You have mail!"), message->str); + ret = gg_notify_message(GAIM_NOTIFY_EMAIL, _("New Mail"), _("You have mail!"), message->str); g_string_free(message, TRUE); return ret; } @@ -180,6 +204,112 @@ return ui_handle; } +static void +notify_button_activated(GntWidget *widget, GaimNotifySearchButton *b) +{ + GList *list = NULL; + GaimAccount *account = g_object_get_data(G_OBJECT(widget), "notify-account"); + gpointer data = g_object_get_data(G_OBJECT(widget), "notify-data"); + + list = gnt_tree_get_selection_text_list(GNT_TREE(widget)); + + b->callback(gaim_account_get_connection(account), list, data); + g_list_foreach(list, (GFunc)g_free, NULL); + g_list_free(list); +} + +static void +gg_notify_sr_new_rows(GaimConnection *gc, + GaimNotifySearchResults *results, void *data) +{ + GntTree *tree = GNT_TREE(data); + GList *o; + + /* XXX: Do I need to empty the tree here? */ + + for (o = results->rows; o; o = o->next) + { + gnt_tree_add_row_after(GNT_TREE(tree), o->data, + gnt_tree_create_row_from_list(GNT_TREE(tree), o->data), + NULL, NULL); + } +} + +static void * +gg_notify_searchresults(GaimConnection *gc, const char *title, + const char *primary, const char *secondary, + GaimNotifySearchResults *results, gpointer data) +{ + GntWidget *window, *tree, *box, *button; + GList *iter; + + window = gnt_vbox_new(FALSE); + gnt_box_set_toplevel(GNT_BOX(window), TRUE); + gnt_box_set_title(GNT_BOX(window), title); + gnt_box_set_fill(GNT_BOX(window), FALSE); + gnt_box_set_pad(GNT_BOX(window), 0); + gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); + + gnt_box_add_widget(GNT_BOX(window), + gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD)); + gnt_box_add_widget(GNT_BOX(window), + gnt_label_new_with_format(secondary, GNT_TEXT_FLAG_NORMAL)); + + tree = gnt_tree_new_with_columns(g_list_length(results->columns)); + gnt_tree_set_show_title(GNT_TREE(tree), TRUE); + gnt_box_add_widget(GNT_BOX(window), tree); + + box = gnt_hbox_new(TRUE); + + for (iter = results->buttons; iter; iter = iter->next) + { + GaimNotifySearchButton *b = iter->data; + const char *text; + + switch (b->type) + { + case GAIM_NOTIFY_BUTTON_LABELED: + text = b->label; + break; + case GAIM_NOTIFY_BUTTON_CONTINUE: + text = _("Continue"); + break; + case GAIM_NOTIFY_BUTTON_ADD: + text = _("Add"); + break; + case GAIM_NOTIFY_BUTTON_INFO: + text = _("Info"); + break; + case GAIM_NOTIFY_BUTTON_IM: + text = _("IM"); + break; + case GAIM_NOTIFY_BUTTON_JOIN: + text = _("Join"); + break; + case GAIM_NOTIFY_BUTTON_INVITE: + text = _("Invite"); + break; + } + + button = gnt_button_new(text); + g_object_set_data(G_OBJECT(button), "notify-account", gaim_connection_get_account(gc)); + g_object_set_data(G_OBJECT(button), "notify-data", data); + g_signal_connect_swapped(G_OBJECT(button), "activate", + G_CALLBACK(notify_button_activated), b); + + gnt_box_add_widget(GNT_BOX(box), button); + } + + gnt_box_add_widget(GNT_BOX(window), box); + + gg_notify_sr_new_rows(gc, results, tree); + + gnt_widget_show(window); + g_object_set_data(G_OBJECT(window), "notify-results", results); + + return tree; +} + static GaimNotifyUiOps ops = { .notify_message = gg_notify_message, @@ -190,8 +320,8 @@ .notify_emails = gg_notify_emails, .notify_userinfo = gg_notify_userinfo, - .notify_searchresults = NULL, /* We are going to need multi-column GntTree's for this */ - .notify_searchresults_new_rows = NULL, + .notify_searchresults = gg_notify_searchresults, + .notify_searchresults_new_rows = gg_notify_sr_new_rows, .notify_uri = NULL /* This is of low-priority to me */ }; Copied: branches/soc-2006-file-loggers/console/gntprefs.c (from rev 16597, trunk/console/gntprefs.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntprefs.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntprefs.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,14 @@ +#include <prefs.h> + +#include "gntprefs.h" +#include "gntgaim.h" + +void gg_prefs_init() +{ + gaim_prefs_add_none("/gaim"); + gaim_prefs_add_none("/gaim/gnt"); + + gaim_prefs_add_none("/gaim/gnt/plugins"); + gaim_prefs_add_string_list("/gaim/gnt/plugins/loaded", NULL); +} + Copied: branches/soc-2006-file-loggers/console/gntprefs.h (from rev 16597, trunk/console/gntprefs.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntprefs.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntprefs.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,2 @@ +void gg_prefs_init(); + Copied: branches/soc-2006-file-loggers/console/gntrequest.c (from rev 16597, trunk/console/gntrequest.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntrequest.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntrequest.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,218 @@ +#include <gnt.h> +#include <gntbox.h> +#include <gntbutton.h> +#include <gntcombobox.h> +#include <gntentry.h> +#include <gntlabel.h> + +#include "gntrequest.h" + +static GntWidget * +setup_request_window(const char *title, const char *primary, + const char *secondary) +{ + GntWidget *window; + + window = gnt_vbox_new(FALSE); + gnt_box_set_toplevel(GNT_BOX(window), TRUE); + gnt_box_set_title(GNT_BOX(window), title); + gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); + + if (primary) + gnt_box_add_widget(GNT_BOX(window), + gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD)); + if (secondary) + gnt_box_add_widget(GNT_BOX(window), gnt_label_new(secondary)); + + return window; +} + +static GntWidget * +setup_button_box(gpointer userdata, gpointer cb, gpointer data, ...) +{ + GntWidget *box, *button; + va_list list; + const char *text; + gpointer callback; + + box = gnt_hbox_new(TRUE); + + va_start(list, data); + + while ((text = va_arg(list, const char *))) + { + callback = va_arg(list, gpointer); + button = gnt_button_new(text); + gnt_box_add_widget(GNT_BOX(box), button); + g_object_set_data(G_OBJECT(button), "activate-callback", callback); + g_object_set_data(G_OBJECT(button), "activate-userdata", userdata); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(cb), data); + } + + va_end(list); + return box; +} + +static void +notify_input_cb(GntWidget *button, GntWidget *entry) +{ + GaimRequestInputCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); + gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); + const char *text = gnt_entry_get_text(GNT_ENTRY(entry)); + + if (callback) + callback(data, text); + + while (button->parent) + button = button->parent; + + gaim_request_close(GAIM_REQUEST_INPUT, button); +} + +static void * +gg_request_input(const char *title, const char *primary, + const char *secondary, const char *default_value, + gboolean multiline, gboolean masked, gchar *hint, + const char *ok_text, GCallback ok_cb, + const char *cancel_text, GCallback cancel_cb, + void *user_data) +{ + GntWidget *window, *box, *entry; + + window = setup_request_window(title, primary, secondary); + + entry = gnt_entry_new(default_value); + if (masked) + gnt_entry_set_masked(GNT_ENTRY(entry), TRUE); + gnt_box_add_widget(GNT_BOX(window), entry); + + box = setup_button_box(user_data, notify_input_cb, entry, + ok_text, ok_cb, cancel_text, cancel_cb, NULL); + gnt_box_add_widget(GNT_BOX(window), box); + + gnt_widget_show(window); + + return window; +} + +static void +gg_close_request(GaimRequestType type, gpointer ui_handle) +{ + GntWidget *widget = GNT_WIDGET(ui_handle); + while (widget->parent) + widget = widget->parent; + gnt_widget_destroy(widget); +} + +static void +request_choice_cb(GntWidget *button, GntComboBox *combo) +{ + GaimRequestChoiceCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); + gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); + int choice = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))) - 1; + + if (callback) + callback(data, choice); + + while (button->parent) + button = button->parent; + + gaim_request_close(GAIM_REQUEST_INPUT, button); +} + +static void * +gg_request_choice(const char *title, const char *primary, + const char *secondary, unsigned int default_value, + const char *ok_text, GCallback ok_cb, + const char *cancel_text, GCallback cancel_cb, + void *user_data, va_list choices) +{ + GntWidget *window, *combo, *box; + const char *text; + int val; + + window = setup_request_window(title, primary, secondary); + + combo = gnt_combo_box_new(); + gnt_box_add_widget(GNT_BOX(window), combo); + while ((text = va_arg(choices, const char *))) + { + val = va_arg(choices, int); + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), GINT_TO_POINTER(val + 1), text); + } + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), GINT_TO_POINTER(default_value + 1)); + + box = setup_button_box(user_data, request_choice_cb, combo, + ok_text, ok_cb, cancel_text, cancel_cb, NULL); + gnt_box_add_widget(GNT_BOX(window), box); + + gnt_widget_show(window); + + return window; +} + +static void +request_action_cb(GntWidget *button, GntWidget *window) +{ + GaimRequestActionCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); + gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); + int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "activate-id")); + + callback(data, id); + + gaim_request_close(GAIM_REQUEST_ACTION, window); +} + +static void* +gg_request_action(const char *title, const char *primary, + const char *secondary, unsigned int default_value, + void *user_data, size_t actioncount, + va_list actions) +{ + GntWidget *window, *box, *button; + int i; + + window = setup_request_window(title, primary, secondary); + + box = gnt_hbox_new(TRUE); + gnt_box_add_widget(GNT_BOX(window), box); + for (i = 0; i < actioncount; i++) + { + const char *text = va_arg(actions, const char *); + GaimRequestActionCb callback = va_arg(actions, GaimRequestActionCb); + + button = gnt_button_new(text); + gnt_box_add_widget(GNT_BOX(box), button); + + g_object_set_data(G_OBJECT(button), "activate-callback", callback); + g_object_set_data(G_OBJECT(button), "activate-userdata", user_data); + g_object_set_data(G_OBJECT(button), "activate-id", GINT_TO_POINTER(i)); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(request_action_cb), window); + } + + gnt_widget_show(window); + + return window; +} + +static GaimRequestUiOps uiops = +{ + .request_input = gg_request_input, + .close_request = gg_close_request, + .request_choice = gg_request_choice, + .request_action = gg_request_action, +}; + +GaimRequestUiOps *gg_request_get_ui_ops() +{ + return &uiops; +} + +void gg_request_init() +{ +} + +void gg_request_uninit() +{ +} + Copied: branches/soc-2006-file-loggers/console/gntrequest.h (from rev 16597, trunk/console/gntrequest.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntrequest.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntrequest.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,8 @@ +#include "request.h" + +GaimRequestUiOps *gg_request_get_ui_ops(); + +void gg_request_init(); + +void gg_request_uninit(); + Modified: branches/soc-2006-file-loggers/console/gntui.c =================================================================== --- branches/soc-2006-file-loggers/console/gntui.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/gntui.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -5,6 +5,7 @@ #include "gntconn.h" #include "gntconv.h" #include "gntnotify.h" +#include "gntrequest.h" void init_gnt_ui() { @@ -31,6 +32,9 @@ gg_notify_init(); gaim_notify_set_ui_ops(gg_notify_get_ui_ops()); + gg_request_init(); + gaim_request_set_ui_ops(gg_request_get_ui_ops()); + #ifdef STANDALONE gnt_main(); @@ -49,6 +53,9 @@ gaim_notify_set_ui_ops(NULL); gg_notify_uninit(); + gaim_request_set_ui_ops(NULL); + gg_request_uninit(); + gnt_quit(); #endif } Modified: branches/soc-2006-file-loggers/console/libgnt/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/Makefile.am 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/Makefile.am 2006-07-29 21:38:18 UTC (rev 16598) @@ -7,12 +7,14 @@ gntwidget.c \ gntbox.c \ gntbutton.c \ + gntcheckbox.c \ gntcolors.c \ gntcombobox.c \ gntentry.c \ gntlabel.c \ gntline.c \ gntmarshal.c \ + gntstyle.c \ gnttextview.c \ gnttree.c \ gntmain.c @@ -21,6 +23,7 @@ gntwidget.h \ gntbox.h \ gntbutton.h \ + gntcheckbox.h \ gntcolors.h \ gntcombobox.h \ gntentry.h \ @@ -28,6 +31,7 @@ gntlabel.h \ gntline.h \ gntmarshal.h \ + gntstyle.h \ gnttextview.h \ gnttree.h \ gnt.h Modified: branches/soc-2006-file-loggers/console/libgnt/gntbox.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbox.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/gntbox.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -89,6 +89,8 @@ for (iter = box->list; iter; iter = iter->next) { + if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(iter->data), GNT_WIDGET_INVISIBLE)) + continue; gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury); gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h); if (box->vertical) @@ -217,6 +219,7 @@ static GntWidget * find_focusable_widget(GntBox *box) { + /* XXX: Make sure the widget is visible? */ if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL) g_list_foreach(box->list, add_to_focus, box); @@ -229,11 +232,17 @@ static void find_next_focus(GntBox *box) { - GList *iter = g_list_find(box->focus, box->active); - if (iter && iter->next) - box->active = iter->next->data; - else if (box->focus) - box->active = box->focus->data; + gpointer last = box->active; + do + { + GList *iter = g_list_find(box->focus, box->active); + if (iter && iter->next) + box->active = iter->next->data; + else if (box->focus) + box->active = box->focus->data; + if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE)) + break; + } while (box->active != last); } static gboolean @@ -564,6 +573,9 @@ int height, width; int x, y; + if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_INVISIBLE)) + continue; + if (GNT_IS_BOX(w)) gnt_box_sync_children(GNT_BOX(w)); Modified: branches/soc-2006-file-loggers/console/libgnt/gntbutton.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntbutton.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/gntbutton.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -22,7 +22,7 @@ type = GNT_COLOR_NORMAL; wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); - mvwprintw(widget->window, 1, 1, button->priv->text); + mvwprintw(widget->window, 1, 2, button->priv->text); DEBUG; } @@ -31,8 +31,10 @@ gnt_button_size_request(GntWidget *widget) { GntButton *button = GNT_BUTTON(widget); - widget->priv.width = g_utf8_strlen(button->priv->text, -1) + 2; - widget->priv.height = 3; + widget->priv.width = g_utf8_strlen(button->priv->text, -1) + 4; + widget->priv.height = 1; + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW)) + widget->priv.height += 2; } static void Copied: branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.c (from rev 16597, trunk/console/libgnt/gntcheckbox.c) =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,153 @@ +#include "gntcheckbox.h" + +enum +{ + SIG_TOGGLED = 1, + SIGS, +}; + +static GntButtonClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_check_box_draw(GntWidget *widget) +{ + GntCheckBox *cb = GNT_CHECK_BOX(widget); + GntColorType type; + char *text; + + if (gnt_widget_has_focus(widget)) + type = GNT_COLOR_HIGHLIGHT; + else + type = GNT_COLOR_NORMAL; + + wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); + + text = g_strdup_printf("[%c]", cb->checked ? 'X' : ' '); + mvwprintw(widget->window, 0, 0, text); + g_free(text); + + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + mvwprintw(widget->window, 0, 4, GNT_BUTTON(cb)->priv->text); + + DEBUG; +} + +static void +gnt_check_box_size_request(GntWidget *widget) +{ +} + +static void +gnt_check_box_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_check_box_key_pressed(GntWidget *widget, const char *text) +{ + if (text[0] == ' ' && text[1] == '\0') + { + GNT_CHECK_BOX(widget)->checked = !GNT_CHECK_BOX(widget)->checked; + g_signal_emit(widget, signals[SIG_TOGGLED], 0); + gnt_widget_draw(widget); + return TRUE; + } + + return FALSE; +} + +static void +gnt_check_box_destroy(GntWidget *widget) +{ +} + +static void +gnt_check_box_class_init(GntCheckBoxClass *klass) +{ + GntWidgetClass *wclass = GNT_WIDGET_CLASS(klass); + + parent_class = GNT_BUTTON_CLASS(klass); + /*parent_class->destroy = gnt_check_box_destroy;*/ + wclass->draw = gnt_check_box_draw; + /*parent_class->map = gnt_check_box_map;*/ + /*parent_class->size_request = gnt_check_box_size_request;*/ + wclass->key_pressed = gnt_check_box_key_pressed; + + signals[SIG_TOGGLED] = + g_signal_new("toggled", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntCheckBoxClass, toggled), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + DEBUG; +} + +static void +gnt_check_box_init(GTypeInstance *instance, gpointer class) +{ + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + DEBUG; +} + +/****************************************************************************** + * GntCheckBox API + *****************************************************************************/ +GType +gnt_check_box_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntCheckBoxClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_check_box_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntCheckBox), + 0, /* n_preallocs */ + gnt_check_box_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_BUTTON, + "GntCheckBox", + &info, 0); + } + + return type; +} + +GntWidget *gnt_check_box_new(const char *text) +{ + GntWidget *widget = g_object_new(GNT_TYPE_CHECK_BOX, NULL); + + GNT_BUTTON(widget)->priv->text = g_strdup(text); + gnt_widget_set_take_focus(widget, TRUE); + + return widget; +} + +void gnt_check_box_set_checked(GntCheckBox *box, gboolean set) +{ + if (set != box->checked) + { + box->checked = set; + g_signal_emit(box, signals[SIG_TOGGLED], 0); + } +} + +gboolean gnt_check_box_get_checked(GntCheckBox *box) +{ + return box->checked; +} + + + Copied: branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.h (from rev 16597, trunk/console/libgnt/gntcheckbox.h) =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.h (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntcheckbox.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -0,0 +1,54 @@ +#ifndef GNT_CHECK_BOX_H +#define GNT_CHECK_BOX_H + +#include "gntbutton.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_CHECK_BOX (gnt_check_box_get_gtype()) +#define GNT_CHECK_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_CHECK_BOX, GntCheckBox)) +#define GNT_CHECK_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_CHECK_BOX, GntCheckBoxClass)) +#define GNT_IS_CHECK_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_CHECK_BOX)) +#define GNT_IS_CHECK_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_CHECK_BOX)) +#define GNT_CHECK_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_CHECK_BOX, GntCheckBoxClass)) + +#define GNT_CHECK_BOX_FLAGS(obj) (GNT_CHECK_BOX(obj)->priv.flags) +#define GNT_CHECK_BOX_SET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) |= flags) +#define GNT_CHECK_BOX_UNSET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) &= ~(flags)) + +typedef struct _GnCheckBox GntCheckBox; +typedef struct _GnCheckBoxPriv GntCheckBoxPriv; +typedef struct _GnCheckBoxClass GntCheckBoxClass; + +struct _GnCheckBox +{ + GntButton parent; + gboolean checked; +}; + +struct _GnCheckBoxClass +{ + GntButtonClass parent; + + void (*toggled)(void); + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_check_box_get_gtype(void); + +GntWidget *gnt_check_box_new(const char *text); + +void gnt_check_box_set_checked(GntCheckBox *box, gboolean set); + +gboolean gnt_check_box_get_checked(GntCheckBox *box); + +G_END_DECLS + +#endif /* GNT_CHECK_BOX_H */ Modified: branches/soc-2006-file-loggers/console/libgnt/gntcolors.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcolors.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/gntcolors.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -1,6 +1,11 @@ #include <ncursesw/ncurses.h> #include "gntcolors.h" +#include <glib.h> + +#include <stdlib.h> +#include <string.h> + static struct { short r, g, b; @@ -75,3 +80,125 @@ restore_colors(); } +static int +get_color(char *key) +{ + int color; + + key = g_strstrip(key); + + if (strcmp(key, "black") == 0) + color = GNT_COLOR_BLACK; + else if (strcmp(key, "red") == 0) + color = GNT_COLOR_RED; + else if (strcmp(key, "green") == 0) + color = GNT_COLOR_GREEN; + else if (strcmp(key, "blue") == 0) + color = GNT_COLOR_BLUE; + else if (strcmp(key, "white") == 0) + color = GNT_COLOR_WHITE; + else if (strcmp(key, "gray") == 0) + color = GNT_COLOR_GRAY; + else if (strcmp(key, "darkgray") == 0) + color = GNT_COLOR_DARK_GRAY; + else + color = -1; + return color; +} + +void gnt_colors_parse(GKeyFile *kfile) +{ + GError *error = NULL; + gsize nkeys; + char **keys = g_key_file_get_keys(kfile, "colors", &nkeys, &error); + + if (error) + { + /* XXX: some error happened. */ + g_error_free(error); + } + else + { + while (nkeys--) + { + gsize len; + char *key = keys[nkeys]; + char **list = g_key_file_get_string_list(kfile, "colors", key, &len, NULL); + if (len == 3) + { + int r = atoi(list[0]); + int g = atoi(list[1]); + int b = atoi(list[2]); + int color = -1; + + g_ascii_strdown(key, -1); + color = get_color(key); + if (color == -1) + continue; + + init_color(color, r, g, b); + } + g_strfreev(list); + } + + g_strfreev(keys); + } + + gnt_color_pairs_parse(kfile); +} + +void gnt_color_pairs_parse(GKeyFile *kfile) +{ + GError *error = NULL; + gsize nkeys; + char **keys = g_key_file_get_keys(kfile, "colorpairs", &nkeys, &error); + + if (error) + { + /* XXX: some error happened. */ + g_error_free(error); + return; + } + + while (nkeys--) + { + gsize len; + char *key = keys[nkeys]; + char **list = g_key_file_get_string_list(kfile, "colorpairs", key, &len, NULL); + if (len == 2) + { + GntColorType type = 0; + int fg = get_color(g_ascii_strdown(list[0], -1)); + int bg = get_color(g_ascii_strdown(list[1], -1)); + if (fg == -1 || bg == -1) + continue; + + g_ascii_strdown(key, -1); + + if (strcmp(key, "normal") == 0) + type = GNT_COLOR_NORMAL; + else if (strcmp(key, "highlight") == 0) + type = GNT_COLOR_HIGHLIGHT; + else if (strcmp(key, "highlightd") == 0) + type = GNT_COLOR_HIGHLIGHT_D; + else if (strcmp(key, "shadow") == 0) + type = GNT_COLOR_SHADOW; + else if (strcmp(key, "title") == 0) + type = GNT_COLOR_TITLE; + else if (strcmp(key, "titled") == 0) + type = GNT_COLOR_TITLE_D; + else if (strcmp(key, "text") == 0) + type = GNT_COLOR_TEXT_NORMAL; + else if (strcmp(key, "disabled") == 0) + type = GNT_COLOR_DISABLED; + else + continue; + + init_pair(type, fg, bg); + } + g_strfreev(list); + } + + g_strfreev(keys); +} + Modified: branches/soc-2006-file-loggers/console/libgnt/gntcolors.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcolors.h 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/gntcolors.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -1,6 +1,8 @@ #ifndef GNT_COLORS_H #define GNT_COLORS_H +#include <glib.h> + typedef enum { GNT_COLOR_NORMAL = 1, @@ -34,4 +36,8 @@ void gnt_uninit_colors(); +void gnt_colors_parse(GKeyFile *kfile); + +void gnt_color_pairs_parse(GKeyFile *kfile); + #endif Modified: branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c 2006-07-29 21:38:18 UTC (rev 16598) @@ -20,10 +20,14 @@ { if (box->selected != key) { + /* XXX: make sure the key actually does exist */ gpointer old = box->selected; box->selected = key; g_signal_emit(box, signals[SIG_SELECTION_CHANGED], 0, old, key); - gnt_widget_draw(GNT_WIDGET(box)); + if (GNT_WIDGET(box)->window) + gnt_widget_draw(GNT_WIDGET(box)); + if (box->dropdown) + gnt_tree_set_selected(GNT_TREE(box->dropdown), key); } } @@ -246,3 +250,8 @@ return box->selected; } +void gnt_combo_box_set_selected(GntComboBox *box, gpointer key) +{ + set_selection(box, key); +} + Modified: branches/soc-2006-file-loggers/console/libgnt/gntcombobox.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcombobox.h 2006-07-29 20:26:50 UTC (rev 16597) +++ branches/soc-2006-file-loggers/console/libgnt/gntcombobox.h 2006-07-29 21:38:18 UTC (rev 16598) @@ -50,6 +50,8 @@ gpointer gnt_combo_box_get... [truncated message content] |
From: <ro...@us...> - 2006-08-09 04:52:51
|
Revision: 16677 Author: roast Date: 2006-08-08 21:49:19 -0700 (Tue, 08 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16677&view=rev Log Message: ----------- merged with svn trunk. 16597:16676. Modified Paths: -------------- branches/soc-2006-file-loggers/COPYRIGHT branches/soc-2006-file-loggers/ChangeLog branches/soc-2006-file-loggers/Makefile.mingw branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/console/Makefile branches/soc-2006-file-loggers/console/gntaccount.c branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/gntblist.h branches/soc-2006-file-loggers/console/gntconv.c branches/soc-2006-file-loggers/console/gntdebug.c branches/soc-2006-file-loggers/console/gntdebug.h branches/soc-2006-file-loggers/console/gntgaim.c branches/soc-2006-file-loggers/console/gntprefs.c branches/soc-2006-file-loggers/console/gntprefs.h branches/soc-2006-file-loggers/console/gntrequest.c branches/soc-2006-file-loggers/console/gntui.c branches/soc-2006-file-loggers/console/libgnt/Makefile.am branches/soc-2006-file-loggers/console/libgnt/gntbox.c branches/soc-2006-file-loggers/console/libgnt/gntbox.h branches/soc-2006-file-loggers/console/libgnt/gntbutton.c branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntlabel.c branches/soc-2006-file-loggers/console/libgnt/gntline.c branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gntstyle.c branches/soc-2006-file-loggers/console/libgnt/gntstyle.h branches/soc-2006-file-loggers/console/libgnt/gnttextview.c branches/soc-2006-file-loggers/console/libgnt/gnttextview.h branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gnttree.h branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.h branches/soc-2006-file-loggers/console/libgnt/test/combo.c branches/soc-2006-file-loggers/console/libgnt/test/multiwin.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/doc/Makefile.am branches/soc-2006-file-loggers/doc/gaim.1.in branches/soc-2006-file-loggers/doc/gaims_funniest_home_convos.txt branches/soc-2006-file-loggers/gaim.spec.in branches/soc-2006-file-loggers/pixmaps/status/default/Makefile.am branches/soc-2006-file-loggers/plugins/codeinline.c branches/soc-2006-file-loggers/plugins/contact_priority.c branches/soc-2006-file-loggers/plugins/dbus-example.c branches/soc-2006-file-loggers/plugins/history.c branches/soc-2006-file-loggers/plugins/log_reader.c branches/soc-2006-file-loggers/plugins/timestamp.c branches/soc-2006-file-loggers/po/POTFILES.in branches/soc-2006-file-loggers/src/account.c branches/soc-2006-file-loggers/src/accountopt.c branches/soc-2006-file-loggers/src/blist.c branches/soc-2006-file-loggers/src/buddyicon.c branches/soc-2006-file-loggers/src/cipher.c branches/soc-2006-file-loggers/src/cmds.c branches/soc-2006-file-loggers/src/connection.c branches/soc-2006-file-loggers/src/conversation.c branches/soc-2006-file-loggers/src/core.c branches/soc-2006-file-loggers/src/dbus-define-api.h branches/soc-2006-file-loggers/src/dbus-server.h branches/soc-2006-file-loggers/src/dbus-useful.c branches/soc-2006-file-loggers/src/dbus-useful.h branches/soc-2006-file-loggers/src/ft.c branches/soc-2006-file-loggers/src/gaim-client-example.c branches/soc-2006-file-loggers/src/gaim-client.c branches/soc-2006-file-loggers/src/gtkaccount.c branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/gtkconv.c branches/soc-2006-file-loggers/src/gtkdebug.c branches/soc-2006-file-loggers/src/gtkdialogs.c branches/soc-2006-file-loggers/src/gtkft.c branches/soc-2006-file-loggers/src/gtkimhtml.c branches/soc-2006-file-loggers/src/gtkimhtmltoolbar.c branches/soc-2006-file-loggers/src/gtklog.c branches/soc-2006-file-loggers/src/gtkpluginpref.c branches/soc-2006-file-loggers/src/gtkpounce.c branches/soc-2006-file-loggers/src/gtkprefs.c branches/soc-2006-file-loggers/src/gtkprivacy.c branches/soc-2006-file-loggers/src/gtkrequest.c branches/soc-2006-file-loggers/src/gtkroomlist.c branches/soc-2006-file-loggers/src/gtksound.c branches/soc-2006-file-loggers/src/gtkstatusbox.c branches/soc-2006-file-loggers/src/gtkthemes.c branches/soc-2006-file-loggers/src/gtkutils.c branches/soc-2006-file-loggers/src/imgstore.c branches/soc-2006-file-loggers/src/log.c branches/soc-2006-file-loggers/src/mime.c branches/soc-2006-file-loggers/src/mime.h branches/soc-2006-file-loggers/src/notify.c branches/soc-2006-file-loggers/src/plugin.c branches/soc-2006-file-loggers/src/pluginpref.c branches/soc-2006-file-loggers/src/pounce.c branches/soc-2006-file-loggers/src/prefs.c branches/soc-2006-file-loggers/src/protocols/Makefile.am branches/soc-2006-file-loggers/src/protocols/bonjour/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/msn/servconn.c branches/soc-2006-file-loggers/src/protocols/oscar/oft.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/qq/Makefile.am branches/soc-2006-file-loggers/src/protocols/qq/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_info.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_list.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_opt.h branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.c branches/soc-2006-file-loggers/src/protocols/qq/buddy_status.h branches/soc-2006-file-loggers/src/protocols/qq/char_conv.c branches/soc-2006-file-loggers/src/protocols/qq/char_conv.h branches/soc-2006-file-loggers/src/protocols/qq/crypt.c branches/soc-2006-file-loggers/src/protocols/qq/crypt.h branches/soc-2006-file-loggers/src/protocols/qq/file_trans.c branches/soc-2006-file-loggers/src/protocols/qq/file_trans.h branches/soc-2006-file-loggers/src/protocols/qq/group.c branches/soc-2006-file-loggers/src/protocols/qq/group.h branches/soc-2006-file-loggers/src/protocols/qq/group_conv.c branches/soc-2006-file-loggers/src/protocols/qq/group_conv.h branches/soc-2006-file-loggers/src/protocols/qq/group_find.c branches/soc-2006-file-loggers/src/protocols/qq/group_find.h branches/soc-2006-file-loggers/src/protocols/qq/group_free.c branches/soc-2006-file-loggers/src/protocols/qq/group_free.h branches/soc-2006-file-loggers/src/protocols/qq/group_hash.c branches/soc-2006-file-loggers/src/protocols/qq/group_hash.h branches/soc-2006-file-loggers/src/protocols/qq/group_im.c branches/soc-2006-file-loggers/src/protocols/qq/group_im.h branches/soc-2006-file-loggers/src/protocols/qq/group_info.c branches/soc-2006-file-loggers/src/protocols/qq/group_info.h branches/soc-2006-file-loggers/src/protocols/qq/group_join.c branches/soc-2006-file-loggers/src/protocols/qq/group_join.h branches/soc-2006-file-loggers/src/protocols/qq/group_misc.c branches/soc-2006-file-loggers/src/protocols/qq/group_misc.h branches/soc-2006-file-loggers/src/protocols/qq/group_network.c branches/soc-2006-file-loggers/src/protocols/qq/group_network.h branches/soc-2006-file-loggers/src/protocols/qq/group_opt.c branches/soc-2006-file-loggers/src/protocols/qq/group_opt.h branches/soc-2006-file-loggers/src/protocols/qq/group_search.c branches/soc-2006-file-loggers/src/protocols/qq/group_search.h branches/soc-2006-file-loggers/src/protocols/qq/header_info.c branches/soc-2006-file-loggers/src/protocols/qq/header_info.h branches/soc-2006-file-loggers/src/protocols/qq/im.c branches/soc-2006-file-loggers/src/protocols/qq/im.h branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.c branches/soc-2006-file-loggers/src/protocols/qq/keep_alive.h branches/soc-2006-file-loggers/src/protocols/qq/login_logout.c branches/soc-2006-file-loggers/src/protocols/qq/login_logout.h branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.c branches/soc-2006-file-loggers/src/protocols/qq/packet_parse.h branches/soc-2006-file-loggers/src/protocols/qq/qq.c branches/soc-2006-file-loggers/src/protocols/qq/qq.h branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.h branches/soc-2006-file-loggers/src/protocols/qq/recv_core.c branches/soc-2006-file-loggers/src/protocols/qq/recv_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_core.c branches/soc-2006-file-loggers/src/protocols/qq/send_core.h branches/soc-2006-file-loggers/src/protocols/qq/send_file.c branches/soc-2006-file-loggers/src/protocols/qq/send_file.h branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.c branches/soc-2006-file-loggers/src/protocols/qq/sendqueue.h branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.c branches/soc-2006-file-loggers/src/protocols/qq/sys_msg.h branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.c branches/soc-2006-file-loggers/src/protocols/qq/udp_proxy_s5.h branches/soc-2006-file-loggers/src/protocols/qq/utils.c branches/soc-2006-file-loggers/src/protocols/qq/utils.h branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.h branches/soc-2006-file-loggers/src/proxy.c branches/soc-2006-file-loggers/src/prpl.c branches/soc-2006-file-loggers/src/request.c branches/soc-2006-file-loggers/src/roomlist.c branches/soc-2006-file-loggers/src/server.c branches/soc-2006-file-loggers/src/signals.c branches/soc-2006-file-loggers/src/status.c branches/soc-2006-file-loggers/src/util.c branches/soc-2006-file-loggers/src/value.c branches/soc-2006-file-loggers/src/whiteboard.c branches/soc-2006-file-loggers/src/xmlnode.c Added Paths: ----------- branches/soc-2006-file-loggers/console/gntplugin.c branches/soc-2006-file-loggers/console/gntplugin.h branches/soc-2006-file-loggers/console/libgnt/gntutils.c branches/soc-2006-file-loggers/console/libgnt/gntutils.h branches/soc-2006-file-loggers/doc/gntgaim.1.in Removed Paths: ------------- branches/soc-2006-file-loggers/pixmaps/status/default/napster.png branches/soc-2006-file-loggers/src/gaim-socket.h branches/soc-2006-file-loggers/src/protocols/napster/ branches/soc-2006-file-loggers/src/protocols/qq/ip_location.c branches/soc-2006-file-loggers/src/protocols/qq/ip_location.h branches/soc-2006-file-loggers/src/socket.c Property Changed: ---------------- branches/soc-2006-file-loggers/doc/ branches/soc-2006-file-loggers/plugins/codeinline.c Modified: branches/soc-2006-file-loggers/COPYRIGHT =================================================================== --- branches/soc-2006-file-loggers/COPYRIGHT 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/COPYRIGHT 2006-08-09 04:49:19 UTC (rev 16677) @@ -86,6 +86,7 @@ Nelson Elhage Ignacio J. Elia Brian Enigma +Mattias Eriksson Stefan Esser Steffen Eschenbacher Marc Etcheverry Modified: branches/soc-2006-file-loggers/ChangeLog =================================================================== --- branches/soc-2006-file-loggers/ChangeLog 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/ChangeLog 2006-08-09 04:49:19 UTC (rev 16677) @@ -152,6 +152,7 @@ * SIP/SIMPLE support (Thomas Butter, Google Summer of Code) * Sametime protocol support Requires the meanwhile library: http://meanwhile.sourceforge.net + * Removed support for the napster and toc protocols Other Noteworthy Changes: * UPnP and NAT traversal support (Adam J. Warrington, Google Summer of Modified: branches/soc-2006-file-loggers/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/Makefile.mingw 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/Makefile.mingw 2006-08-09 04:49:19 UTC (rev 16677) @@ -21,7 +21,6 @@ TOC = $(GAIM_PROTOS)/toc IRC = $(GAIM_PROTOS)/irc JABBER = $(GAIM_PROTOS)/jabber -NAPSTER = $(GAIM_PROTOS)/napster GG = $(GAIM_PROTOS)/gg NOVELL = $(GAIM_PROTOS)/novell SILC = $(GAIM_PROTOS)/silc @@ -55,7 +54,6 @@ TOC_TYPE = PLUGIN IRC_TYPE = PLUGIN JABBER_TYPE = PLUGIN -NAPSTER_TYPE = PLUGIN GG_TYPE = PLUGIN NOVELL_TYPE = PLUGIN SILC_TYPE = PLUGIN @@ -69,7 +67,6 @@ $(MAKE) TYPE='$(MSN_TYPE)' -C $(MSN) -f Makefile.mingw $(MAKE) TYPE='$(IRC_TYPE)' -C $(IRC) -f Makefile.mingw $(MAKE) TYPE='$(JABBER_TYPE)' -C $(JABBER) -f Makefile.mingw - $(MAKE) TYPE='$(NAPSTER_TYPE)' -C $(NAPSTER) -f Makefile.mingw $(MAKE) TYPE='$(GG_TYPE)' -C $(GG) -f Makefile.mingw $(MAKE) TYPE='$(NOVELL_TYPE)' -C $(NOVELL) -f Makefile.mingw $(MAKE) TYPE='$(SILC_TYPE)' -C $(SILC) -f Makefile.mingw @@ -91,7 +88,6 @@ $(MAKE) TYPE='$(MSN_TYPE)' -C $(MSN) -f Makefile.mingw install $(MAKE) TYPE='$(IRC_TYPE)' -C $(IRC) -f Makefile.mingw install $(MAKE) TYPE='$(JABBER_TYPE)' -C $(JABBER) -f Makefile.mingw install - $(MAKE) TYPE='$(NAPSTER_TYPE)' -C $(NAPSTER) -f Makefile.mingw install $(MAKE) TYPE='$(GG_TYPE)' -C $(GG) -f Makefile.mingw install $(MAKE) TYPE='$(NOVELL_TYPE)' -C $(NOVELL) -f Makefile.mingw install $(MAKE) TYPE='$(SILC_TYPE)' -C $(SILC) -f Makefile.mingw install @@ -119,7 +115,6 @@ $(MAKE) -C $(MSN) -f Makefile.mingw clean $(MAKE) -C $(IRC) -f Makefile.mingw clean $(MAKE) -C $(JABBER) -f Makefile.mingw clean - $(MAKE) -C $(NAPSTER) -f Makefile.mingw clean $(MAKE) -C $(GG) -f Makefile.mingw clean $(MAKE) -C $(NOVELL) -f Makefile.mingw clean $(MAKE) -C $(SILC) -f Makefile.mingw clean Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/configure.ac 2006-08-09 04:49:19 UTC (rev 16677) @@ -1747,6 +1747,7 @@ gaim.service doc/Makefile doc/gaim.1 + doc/gntgaim.1 m4macros/Makefile pixmaps/Makefile pixmaps/smileys/Makefile @@ -1776,7 +1777,6 @@ src/protocols/irc/Makefile src/protocols/jabber/Makefile src/protocols/msn/Makefile - src/protocols/napster/Makefile src/protocols/novell/Makefile src/protocols/oscar/Makefile src/protocols/qq/Makefile Modified: branches/soc-2006-file-loggers/console/Makefile =================================================================== --- branches/soc-2006-file-loggers/console/Makefile 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/Makefile 2006-08-09 04:49:19 UTC (rev 16677) @@ -1,7 +1,7 @@ VERSION=gntgaim-0.0.0dev CC=gcc CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall -DVERSION=\"$(VERSION)\" -DSTANDALONE -LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg +LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg -lgaim GG_SOURCES = \ gntaccount.c \ @@ -10,6 +10,7 @@ gntconv.c \ gntdebug.c \ gntnotify.c \ + gntplugin.c \ gntprefs.c \ gntrequest.c \ gntui.c @@ -22,6 +23,7 @@ gntdebug.h \ gntnotify.h \ gntprefs.h \ + gntplugin.h \ gntrequest.h \ gntui.h @@ -32,6 +34,7 @@ gntconv.o \ gntdebug.o \ gntnotify.o \ + gntplugin.o \ gntprefs.o \ gntrequest.o \ gntui.o Modified: branches/soc-2006-file-loggers/console/gntaccount.c =================================================================== --- branches/soc-2006-file-loggers/console/gntaccount.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntaccount.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -49,6 +49,9 @@ GntWidget *remember; } AccountEditDialog; +/* This is necessary to close an edit-dialog when an account is deleted */ +static GList *accountdialogs; + static void account_add(GaimAccount *account) { @@ -64,6 +67,7 @@ static void edit_dialog_destroy(AccountEditDialog *dialog) { + accountdialogs = g_list_remove(accountdialogs, dialog); g_list_free(dialog->prpl_entries); g_list_free(dialog->split_entries); g_free(dialog); @@ -143,7 +147,6 @@ gaim_account_set_password(account, NULL); /* Mail notification */ - /* XXX: Only if the protocol has anything to do with emails */ gaim_account_set_check_mail(account, gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->newmail))); @@ -210,8 +213,9 @@ } else { - dialog->splits = gnt_box_new(FALSE, TRUE); + dialog->splits = gnt_vbox_new(FALSE); gnt_box_set_pad(GNT_BOX(dialog->splits), 0); + gnt_box_set_fill(GNT_BOX(dialog->splits), TRUE); } dialog->split_entries = NULL; @@ -229,7 +233,7 @@ GntWidget *entry; char *buf; - hbox = gnt_box_new(TRUE, FALSE); + hbox = gnt_hbox_new(TRUE); gnt_box_add_widget(GNT_BOX(dialog->splits), hbox); buf = g_strdup_printf("%s:", gaim_account_user_split_get_text(split)); @@ -426,18 +430,32 @@ GList *list, *iter; AccountEditDialog *dialog; + if (account) + { + GList *iter; + for (iter = accountdialogs; iter; iter = iter->next) + { + AccountEditDialog *dlg = iter->data; + if (dlg->account == account) + return; + } + } + dialog = g_new0(AccountEditDialog, 1); + accountdialogs = g_list_prepend(accountdialogs, dialog); - dialog->window = window = gnt_box_new(FALSE, TRUE); + dialog->window = window = gnt_vbox_new(FALSE); dialog->account = account; gnt_box_set_toplevel(GNT_BOX(window), TRUE); gnt_box_set_title(GNT_BOX(window), account ? _("Modify Account") : _("New Account")); gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); gnt_box_set_pad(GNT_BOX(window), 0); + gnt_widget_set_name(window, "edit-account"); + gnt_box_set_fill(GNT_BOX(window), TRUE); - hbox = gnt_box_new(TRUE, FALSE); + hbox = gnt_hbox_new(TRUE); + gnt_box_set_pad(GNT_BOX(hbox), 0); gnt_box_add_widget(GNT_BOX(window), hbox); - gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); dialog->protocol = combo = gnt_combo_box_new(); list = gaim_plugins_get_protocols(); @@ -446,6 +464,7 @@ gnt_combo_box_add_data(GNT_COMBO_BOX(combo), iter->data, ((GaimPlugin*)iter->data)->info->name); } + if (account) gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), gaim_plugins_find_with_id(gaim_account_get_protocol_id(account))); @@ -453,10 +472,12 @@ gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), list->data); g_signal_connect(G_OBJECT(combo), "selection-changed", G_CALLBACK(prpl_changed_cb), dialog); + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Protocol:"))); gnt_box_add_widget(GNT_BOX(hbox), combo); - hbox = gnt_box_new(TRUE, FALSE); + hbox = gnt_hbox_new(TRUE); + gnt_box_set_pad(GNT_BOX(hbox), 0); gnt_box_add_widget(GNT_BOX(window), hbox); dialog->screenname = entry = gnt_entry_new(NULL); @@ -467,7 +488,8 @@ update_user_splits(dialog); gnt_box_add_widget(GNT_BOX(window), dialog->splits); - hbox = gnt_box_new(TRUE, FALSE); + hbox = gnt_hbox_new(TRUE); + gnt_box_set_pad(GNT_BOX(hbox), 0); gnt_box_add_widget(GNT_BOX(window), hbox); dialog->password = entry = gnt_entry_new(NULL); @@ -477,7 +499,8 @@ if (account) gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_password(account)); - hbox = gnt_box_new(TRUE, FALSE); + hbox = gnt_hbox_new(TRUE); + gnt_box_set_pad(GNT_BOX(hbox), 0); gnt_box_add_widget(GNT_BOX(window), hbox); dialog->alias = entry = gnt_entry_new(NULL); @@ -500,8 +523,9 @@ /* TODO: Add proxy options */ /* The button box */ - hbox = gnt_box_new(FALSE, FALSE); + hbox = gnt_hbox_new(FALSE); gnt_box_add_widget(GNT_BOX(window), hbox); + gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); button = gnt_button_new(_("Cancel")); gnt_box_add_widget(GNT_BOX(hbox), button); @@ -534,10 +558,38 @@ } static void +really_delete_account(GaimAccount *account) +{ + GList *iter; + for (iter = accountdialogs; iter; iter = iter->next) + { + AccountEditDialog *dlg = iter->data; + if (dlg->account == account) + { + gnt_widget_destroy(dlg->window); + break; + } + } + gaim_accounts_delete(account); +} + +static void delete_account_cb(GntWidget *widget, GntTree *tree) { - /* XXX: After the request-api is complete */ - /* Note: remove the modify-dialog for the account */ + GaimAccount *account; + char *prompt; + + account = gnt_tree_get_selection_data(tree); + if (!account) + return; + + prompt = g_strdup_printf(_("Are you sure you want to delete %s?"), + gaim_account_get_username(account)); + + gaim_request_close_with_handle(account); /* Close any other opened delete window */ + gaim_request_action(account, _("Delete Account"), prompt, NULL, 0, account, 2, + _("Delete"), really_delete_account, _("Cancel"), NULL); + g_free(prompt); } static void @@ -548,12 +600,19 @@ gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key)); } +static void +reset_accounts_win(GntWidget *widget, gpointer null) +{ + accounts.window = NULL; + accounts.tree = NULL; +} + void gg_accounts_show_all() { GList *iter; GntWidget *box, *button; - accounts.window = gnt_box_new(FALSE, TRUE); + accounts.window = gnt_vbox_new(FALSE); gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE); gnt_box_set_title(GNT_BOX(accounts.window), _("Accounts")); gnt_box_set_pad(GNT_BOX(accounts.window), 0); @@ -582,7 +641,7 @@ gnt_box_add_widget(GNT_BOX(accounts.window), gnt_line_new(FALSE)); - box = gnt_box_new(FALSE, FALSE); + box = gnt_hbox_new(FALSE); button = gnt_button_new(_("Add")); gnt_box_add_widget(GNT_BOX(box), button); @@ -597,6 +656,8 @@ g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_account_cb), accounts.tree); gnt_box_add_widget(GNT_BOX(accounts.window), box); + + g_signal_connect(G_OBJECT(accounts.window), "destroy", G_CALLBACK(reset_accounts_win), NULL); gnt_widget_show(accounts.window); } @@ -641,7 +702,8 @@ void gg_accounts_uninit() { - gnt_widget_destroy(accounts.window); + if (accounts.window) + gnt_widget_destroy(accounts.window); } /* The following uiops stuff are copied from gtkaccount.c */ Modified: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -1,18 +1,26 @@ #include <account.h> #include <blist.h> #include <request.h> +#include <savedstatuses.h> #include <server.h> #include <signal.h> +#include <status.h> #include <util.h> #include "gntgaim.h" #include "gntbox.h" +#include "gntcombobox.h" +#include "gntentry.h" #include "gntlabel.h" +#include "gntline.h" #include "gnttree.h" #include "gntblist.h" #include <string.h> +#define PREF_ROOT "/gaim/gnt/blist" +#define TYPING_TIMEOUT 4000 + typedef struct { GntWidget *window; @@ -23,8 +31,29 @@ GntWidget *context; GaimBlistNode *cnode; + + /* XXX: I am KISSing */ + GntWidget *status; /* Dropdown with the statuses */ + GntWidget *statustext; /* Status message */ + int typing; } GGBlist; +typedef enum +{ + STATUS_PRIMITIVE = 0, + STATUS_SAVED +} StatusType; + +typedef struct +{ + StatusType type; + union + { + GaimStatusPrimitive prim; + GaimSavedStatus *saved; + } u; +} StatusBoxItem; + GGBlist *ggblist; static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist); @@ -32,7 +61,9 @@ static void add_chat(GaimChat *chat, GGBlist *ggblist); static void add_node(GaimBlistNode *node, GGBlist *ggblist); static void draw_tooltip(GGBlist *ggblist); +static gboolean remove_typing_cb(gpointer null); static void remove_peripherals(GGBlist *ggblist); +static const char * get_display_name(GaimBlistNode *node); static void new_node(GaimBlistNode *node) @@ -63,7 +94,7 @@ { GGBlist *ggblist = list->ui_data; - if (node->ui_data == NULL) + if (ggblist == NULL || node->ui_data == NULL) return; gnt_tree_remove(GNT_TREE(ggblist->tree), node); @@ -82,6 +113,15 @@ static void node_update(GaimBuddyList *list, GaimBlistNode *node) { + if (list->ui_data == NULL) + return; + + if (node->ui_data != NULL) + { + gnt_tree_change_text(GNT_TREE(ggblist->tree), node, + 0, get_display_name(node)); + } + if (GAIM_BLIST_NODE_IS_BUDDY(node)) { GaimBuddy *buddy = (GaimBuddy*)node; @@ -101,7 +141,7 @@ { } -static GaimBlistUiOps blist_ui_ops = +static GaimBlistUiOps blist_ui_ops = { new_list, new_node, @@ -131,7 +171,7 @@ return; gnt_tree_remove(GNT_TREE(ggblist->tree), group); node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), group, - gnt_tree_create_row(GNT_TREE(ggblist->tree), group->name), NULL, NULL); + gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)), NULL, NULL); } static const char * @@ -175,6 +215,8 @@ strncpy(status, "~", sizeof(status) - 1); } + else if (GAIM_BLIST_NODE_IS_GROUP(node)) + return ((GaimGroup*)node)->name; snprintf(text, sizeof(text) - 1, "%s %s", status, name); @@ -188,6 +230,8 @@ GaimBlistNode *node = (GaimBlistNode *)chat; if (node->ui_data) return; + if (!gaim_account_is_connected(chat->account)) + return; group = gaim_chat_get_group(chat); add_node((GaimBlistNode*)group, ggblist); @@ -274,7 +318,9 @@ gnt_append_menu_action(GntTree *tree, GaimMenuAction *action, gpointer parent) { GList *list; - + if (action == NULL) + return; + gnt_tree_add_row_after(tree, action, gnt_tree_create_row(tree, action->label), parent, NULL); for (list = action->children; list; list = list->next) @@ -351,7 +397,7 @@ add_custom_action(tree, _("View Log"), GAIM_CALLBACK(gg_blist_view_log_cb)), buddy); #endif - + /* Protocol actions */ append_proto_menu(tree, gaim_account_get_connection(gaim_buddy_get_account(buddy)), @@ -380,15 +426,54 @@ { void (*callback)(GaimBlistNode *, gpointer); callback = (void (*)(GaimBlistNode *, gpointer))action->callback; - callback(node, action->data); + if (callback) + callback(node, action->data); + else + return; } remove_context_menu(ggblist); } static void +rename_blist_node(GaimBlistNode *node, const char *newname) +{ + const char *name = newname; + if (name && !*name) + name = NULL; + + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + gaim_blist_alias_buddy((GaimBuddy*)node, name); + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + gaim_blist_alias_chat((GaimChat*)node, name); + else if (GAIM_BLIST_NODE_IS_GROUP(node)) + gaim_blist_rename_group((GaimGroup*)node, name); + else + g_return_if_reached(); +} + +static void gg_blist_rename_node_cb(GaimBlistNode *node, GaimBlistNode *null) { + const char *name = NULL; + char *prompt; + + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + name = gaim_buddy_get_contact_alias((GaimBuddy*)node); + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + name = gaim_chat_get_name((GaimChat*)node); + else if (GAIM_BLIST_NODE_IS_GROUP(node)) + name = ((GaimGroup*)node)->name; + else + g_return_if_reached(); + + prompt = g_strdup_printf(_("Please enter the new name for %s"), name); + + gaim_request_input(node, _("Rename"), prompt, _("Enter empty string to reset the name."), + name, FALSE, FALSE, NULL, _("Rename"), G_CALLBACK(rename_blist_node), + _("Cancel"), NULL, node); + + g_free(prompt); } /* XXX: This still doesn't do anything, because request doesn't have a ui yet */ @@ -472,7 +557,8 @@ window = gnt_vbox_new(FALSE); gnt_box_set_toplevel(GNT_BOX(window), TRUE); gnt_box_set_title(GNT_BOX(window), title); - + + gnt_widget_set_size(context, 0, g_list_length(GNT_TREE(context)->list)); gnt_box_add_widget(GNT_BOX(window), context); /* Set the position for the popup */ @@ -593,6 +679,7 @@ gnt_widget_set_position(box, x, y); GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_CAN_TAKE_FOCUS); + GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT); gnt_widget_draw(box); g_free(title); @@ -626,7 +713,7 @@ ret = gnt_widget_key_pressed(ggblist->context, text); stop = TRUE; } - + if (text[0] == 27) { if (strcmp(text + 1, GNT_KEY_POPUP) == 0) @@ -677,13 +764,243 @@ remove_context_menu(ggblist); } +static void +size_changed_cb(GntWidget *w, int width, int height) +{ + gaim_prefs_set_int(PREF_ROOT "/size/width", width); + gaim_prefs_set_int(PREF_ROOT "/size/height", height); +} + +static void +save_position_cb(GntWidget *w, int x, int y) +{ + gaim_prefs_set_int(PREF_ROOT "/position/x", x); + gaim_prefs_set_int(PREF_ROOT "/position/y", y); +} + +static void +reset_blist_window(GntWidget *window, gpointer null) +{ + GaimBlistNode *node; + gaim_signals_disconnect_by_handle(gg_blist_get_handle()); + gaim_get_blist()->ui_data = NULL; + + node = gaim_blist_get_root(); + while (node) + { + node->ui_data = NULL; + node = gaim_blist_node_next(node, TRUE); + } + + remove_typing_cb(NULL); + remove_peripherals(ggblist); + g_free(ggblist); + ggblist = NULL; +} + +static void +populate_buddylist() +{ + GaimBlistNode *node; + GaimBuddyList *list; + + list = gaim_get_blist(); + node = gaim_blist_get_root(); + while (node) + { + node_update(list, node); + node = gaim_blist_node_next(node, FALSE); + } +} + +static void +destroy_status_list(GList *list) +{ + g_list_foreach(list, (GFunc)g_free, NULL); + g_list_free(list); +} + +static void +populate_status_dropdown() +{ + int i; + GList *iter; + GList *items = NULL; + + /* First the primitives */ + GaimStatusPrimitive prims[] = {GAIM_STATUS_AVAILABLE, GAIM_STATUS_AWAY, + GAIM_STATUS_INVISIBLE, GAIM_STATUS_OFFLINE, GAIM_STATUS_UNSET}; + + for (i = 0; prims[i] != GAIM_STATUS_UNSET; i++) + { + StatusBoxItem *item = g_new0(StatusBoxItem, 1); + item->type = STATUS_PRIMITIVE; + item->u.prim = prims[i]; + items = g_list_prepend(items, item); + gnt_combo_box_add_data(GNT_COMBO_BOX(ggblist->status), item, + gaim_primitive_get_name_from_type(prims[i])); + } + + /* Now the popular statuses */ + for (iter = gaim_savedstatuses_get_popular(6); iter; iter = iter->next) + { + StatusBoxItem *item = g_new0(StatusBoxItem, 1); + item->type = STATUS_SAVED; + item->u.saved = iter->data; + items = g_list_prepend(items, item); + gnt_combo_box_add_data(GNT_COMBO_BOX(ggblist->status), item, + gaim_savedstatus_get_title(iter->data)); + } + + /* The keys for the combobox are created here, and never used + * anywhere else. So make sure the keys are freed when the widget + * is destroyed. */ + g_object_set_data_full(G_OBJECT(ggblist->status), "list of statuses", items, (GDestroyNotify)destroy_status_list); +} + void gg_blist_init() { + gaim_prefs_add_none(PREF_ROOT); + gaim_prefs_add_none(PREF_ROOT "/size"); + gaim_prefs_add_int(PREF_ROOT "/size/width", 20); + gaim_prefs_add_int(PREF_ROOT "/size/height", 20); + gaim_prefs_add_none(PREF_ROOT "/position"); + gaim_prefs_add_int(PREF_ROOT "/position/x", 0); + gaim_prefs_add_int(PREF_ROOT "/position/y", 0); + + gg_blist_show(); + + return; +} + +static gboolean +remove_typing_cb(gpointer null) +{ + GaimSavedStatus *current; + const char *message, *newmessage; + GaimStatusPrimitive prim, newprim; + StatusBoxItem *item; + + current = gaim_savedstatus_get_current(); + message = gaim_savedstatus_get_message(current); + prim = gaim_savedstatus_get_type(current); + + newmessage = gnt_entry_get_text(GNT_ENTRY(ggblist->statustext)); + item = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(ggblist->status)); + g_return_val_if_fail(item->type == STATUS_PRIMITIVE, FALSE); + newprim = item->u.prim; + + if (newprim != prim || ((message && !newmessage) || + (!message && newmessage) || + (message && newmessage && g_utf8_collate(message, newmessage) != 0))) + { + GaimSavedStatus *status = gaim_savedstatus_find_transient_by_type_and_message(newprim, newmessage); + /* Holy Crap! That's a LAWNG function name */ + if (status == NULL) + { + status = gaim_savedstatus_new(NULL, newprim); + gaim_savedstatus_set_message(status, newmessage); + } + + gaim_savedstatus_activate(status); + } + + gnt_box_give_focus_to_child(GNT_BOX(ggblist->window), ggblist->tree); + if (ggblist->typing) + g_source_remove(ggblist->typing); + ggblist->typing = 0; + return FALSE; +} + +static void +status_selection_changed(GntComboBox *box, StatusBoxItem *old, StatusBoxItem *now, gpointer null) +{ + gnt_entry_set_text(GNT_ENTRY(ggblist->statustext), NULL); + if (now->type == STATUS_SAVED) + { + /* Set the status immediately */ + gaim_savedstatus_activate(now->u.saved); + } + else if (now->type == STATUS_PRIMITIVE) + { + /* Move the focus to the entry box */ + /* XXX: Make sure the selected status can have a message */ + gnt_box_move_focus(GNT_BOX(ggblist->window), 1); + ggblist->typing = g_timeout_add(TYPING_TIMEOUT, (GSourceFunc)remove_typing_cb, NULL); + } + else + g_return_if_reached(); +} + +static gboolean +status_text_changed(GntEntry *entry, const char *text, gpointer null) +{ + if ((text[0] == 27 || (text[0] == '\t' && text[1] == '\0')) && ggblist->typing == 0) + return FALSE; + + if (ggblist->typing) + g_source_remove(ggblist->typing); + ggblist->typing = 0; + + if (text[0] == '\r' && text[1] == 0) + { + /* Set the status only after you press 'Enter' */ + remove_typing_cb(NULL); + return TRUE; + } + + ggblist->typing = g_timeout_add(TYPING_TIMEOUT, (GSourceFunc)remove_typing_cb, NULL); + return FALSE; +} + +static void +savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old) +{ + /* Block the signals we don't want to emit */ + GList *list; + GaimStatusPrimitive prim; + const char *message; + + if (!ggblist) + return; + + g_signal_handlers_block_matched(ggblist->status, G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, status_selection_changed, NULL); + g_signal_handlers_block_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, status_text_changed, NULL); + + prim = gaim_savedstatus_get_type(now); + message = gaim_savedstatus_get_message(now); + + list = g_object_get_data(G_OBJECT(ggblist->status), "list of statuses"); + for (; list; list = list->next) + { + StatusBoxItem *item = list->data; + if (item->type == STATUS_PRIMITIVE && item->u.prim == prim) + { + gnt_combo_box_set_selected(GNT_COMBO_BOX(ggblist->status), item); + gnt_entry_set_text(GNT_ENTRY(ggblist->statustext), message); + gnt_widget_draw(ggblist->status); + break; + } + } + + g_signal_handlers_unblock_matched(ggblist->status, G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, status_selection_changed, NULL); + g_signal_handlers_unblock_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, status_text_changed, NULL); +} + +void gg_blist_show() +{ + if (ggblist) + return; + ggblist = g_new0(GGBlist, 1); gaim_get_blist()->ui_data = ggblist; - ggblist->window = gnt_box_new(FALSE, FALSE); + ggblist->window = gnt_vbox_new(FALSE); gnt_widget_set_name(ggblist->window, "buddylist"); gnt_box_set_toplevel(GNT_BOX(ggblist->window), TRUE); gnt_box_set_title(GNT_BOX(ggblist->window), _("Buddy List")); @@ -692,16 +1009,29 @@ ggblist->tree = gnt_tree_new(); GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); gnt_tree_set_col_width(GNT_TREE(ggblist->tree), 0, 25); - gnt_widget_set_size(ggblist->tree, 0, getmaxy(stdscr) - 4); + gnt_widget_set_size(ggblist->tree, gaim_prefs_get_int(PREF_ROOT "/size/width"), + gaim_prefs_get_int(PREF_ROOT "/size/height")); + gnt_widget_set_position(ggblist->window, gaim_prefs_get_int(PREF_ROOT "/position/x"), + gaim_prefs_get_int(PREF_ROOT "/position/y")); gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree); + + gnt_box_add_widget(GNT_BOX(ggblist->window), gnt_hline_new()); + + ggblist->status = gnt_combo_box_new(); + gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->status); + ggblist->statustext = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->statustext); + + populate_status_dropdown(); + gnt_widget_show(ggblist->window); gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(), GAIM_CALLBACK(buddy_status_changed), ggblist); gaim_signal_connect(gaim_blist_get_handle(), "buddy-idle-changed", gg_blist_get_handle(), GAIM_CALLBACK(buddy_idle_changed), ggblist); - + #if 0 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gg_blist_get_handle(), GAIM_CALLBACK(buddy_signed_on), ggblist); @@ -725,10 +1055,28 @@ ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED); g_signal_connect_data(G_OBJECT(ggblist->tree), "lost-focus", G_CALLBACK(remove_peripherals), ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED); + g_signal_connect(G_OBJECT(ggblist->tree), "size_changed", G_CALLBACK(size_changed_cb), NULL); + g_signal_connect(G_OBJECT(ggblist->window), "position_set", G_CALLBACK(save_position_cb), NULL); + g_signal_connect(G_OBJECT(ggblist->window), "destroy", G_CALLBACK(reset_blist_window), NULL); + + /* Status signals */ + gaim_signal_connect(gaim_savedstatuses_get_handle(), "savedstatus-changed", gg_blist_get_handle(), + GAIM_CALLBACK(savedstatus_changed), NULL); + g_signal_connect(G_OBJECT(ggblist->status), "selection_changed", + G_CALLBACK(status_selection_changed), NULL); + g_signal_connect(G_OBJECT(ggblist->statustext), "key_pressed", + G_CALLBACK(status_text_changed), NULL); + + populate_buddylist(); + + savedstatus_changed(gaim_savedstatus_get_current(), NULL); } void gg_blist_uninit() { + if (ggblist == NULL) + return; + gnt_widget_destroy(ggblist->window); g_free(ggblist); ggblist = NULL; Modified: branches/soc-2006-file-loggers/console/gntblist.h =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.h 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntblist.h 2006-08-09 04:49:19 UTC (rev 16677) @@ -6,6 +6,8 @@ void gg_blist_uninit(); +void gg_blist_show(); + void gg_blist_get_position(int *x, int *y); void gg_blist_set_position(int x, int y); Modified: branches/soc-2006-file-loggers/console/gntconv.c =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntconv.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -1,17 +1,24 @@ #include <string.h> #include <cmds.h> +#include <prefs.h> #include <util.h> #include "gntgaim.h" +#include "gntaccount.h" #include "gntblist.h" #include "gntconv.h" +#include "gntdebug.h" +#include "gntplugin.h" +#include "gntprefs.h" #include "gnt.h" #include "gntbox.h" #include "gntentry.h" #include "gnttextview.h" +#define PREF_ROOT "/gaim/gnt/conversations" + GHashTable *ggconvs; typedef struct _GGConv GGConv; @@ -101,17 +108,20 @@ } else { + char *escape = g_markup_escape_text(text, -1); switch (gaim_conversation_get_type(ggconv->conv)) { case GAIM_CONV_TYPE_IM: - gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), text, GAIM_MESSAGE_SEND); + gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), escape, GAIM_MESSAGE_SEND); break; case GAIM_CONV_TYPE_CHAT: - gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), text); + gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), escape); break; default: + g_free(escape); g_return_val_if_reached(FALSE); } + g_free(escape); } gnt_entry_clear(GNT_ENTRY(ggconv->entry)); return TRUE; @@ -142,19 +152,29 @@ } static void +size_changed_cb(GntWidget *w, int width, int height) +{ + gaim_prefs_set_int(PREF_ROOT "/size/width", width); + gaim_prefs_set_int(PREF_ROOT "/size/height", height); +} + +static void +save_position_cb(GntWidget *w, int x, int y) +{ + gaim_prefs_set_int(PREF_ROOT "/position/x", x); + gaim_prefs_set_int(PREF_ROOT "/position/y", y); +} + +static void gg_create_conversation(GaimConversation *conv) { GGConv *ggc = g_hash_table_lookup(ggconvs, conv); char *title; GaimConversationType type; - int x, width; if (ggc) return; - gg_blist_get_position(&x, NULL); - gg_blist_get_size(&width, NULL); - ggc = g_new0(GGConv, 1); g_hash_table_insert(ggconvs, conv, ggc); @@ -172,7 +192,8 @@ ggc->tv = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv); gnt_widget_set_name(ggc->tv, "conversation-window-textview"); - gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 3 - x - width, getmaxy(stdscr) - 5); + gnt_widget_set_size(ggc->tv, gaim_prefs_get_int(PREF_ROOT "/size/width"), + gaim_prefs_get_int(PREF_ROOT "/size/height")); ggc->entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); @@ -181,12 +202,13 @@ g_signal_connect(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); - /* XXX: I am assuming the buddylist is on the leftmost corner. - * That may not always be correct, since the windows can be moved. - * It might be an option to remember the position of conv. windows. */ - gnt_widget_set_position(ggc->window, x + width, 0); + gnt_widget_set_position(ggc->window, gaim_prefs_get_int(PREF_ROOT "/position/x"), + gaim_prefs_get_int(PREF_ROOT "/position/y")); gnt_widget_show(ggc->window); + g_signal_connect(G_OBJECT(ggc->tv), "size_changed", G_CALLBACK(size_changed_cb), NULL); + g_signal_connect(G_OBJECT(ggc->window), "position_set", G_CALLBACK(save_position_cb), NULL); + g_free(title); } @@ -201,8 +223,9 @@ GaimMessageFlags flags, time_t mtime) { GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); /* XXX: ggconv = conv->ui_data; should do */ - char *strip; + char *strip, *newline; GntTextFormatFlags fl = 0; + int pos; g_return_if_fail(ggconv != NULL); @@ -221,12 +244,18 @@ if (flags & GAIM_MESSAGE_NICK) fl |= GNT_TEXT_FLAG_UNDERLINE; - strip = gaim_markup_strip_html(message); + pos = gnt_text_view_get_lines_below(GNT_TEXT_VIEW(ggconv->tv)); + + /* XXX: Remove this workaround when textview can parse messages. */ + newline = gaim_strdup_withhtml(message); + strip = gaim_markup_strip_html(newline); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), strip, fl); gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv)); - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); + if (pos <= 1) + gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0); + g_free(newline); g_free(strip); if (flags & (GAIM_MESSAGE_RECV | GAIM_MESSAGE_NICK | GAIM_MESSAGE_ERROR)) @@ -460,12 +489,27 @@ return GAIM_CMD_STATUS_OK; } +static GaimCmdRet +cmd_show_window(GaimConversation *conv, const char *cmd, char **args, char **error, gpointer data) +{ + void (*callback)() = data; + callback(); + return GAIM_CMD_STATUS_OK; +} void gg_conversation_init() { ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); - /* Xerox */ + gaim_prefs_add_none(PREF_ROOT); + gaim_prefs_add_none(PREF_ROOT "/size"); + gaim_prefs_add_int(PREF_ROOT "/size/width", 70); + gaim_prefs_add_int(PREF_ROOT "/size/height", 20); + gaim_prefs_add_none(PREF_ROOT "/position"); + gaim_prefs_add_int(PREF_ROOT "/position/x", 0); + gaim_prefs_add_int(PREF_ROOT "/position/y", 0); + + /* Xerox the commands */ gaim_cmd_register("say", "S", GAIM_CMD_P_DEFAULT, GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, say_command_cb, _("say <message>: Send a message normally as if you weren't using a command."), NULL); @@ -481,6 +525,23 @@ gaim_cmd_register("help", "w", GAIM_CMD_P_DEFAULT, GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, NULL, help_command_cb, _("help <command>: Help on a specific command."), NULL); + + /* Now some commands to bring up some other windows */ + gaim_cmd_register("plugins", "", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + cmd_show_window, _("plugins: Show the plugins window."), gg_plugins_show_all); + gaim_cmd_register("buddylist", "", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + cmd_show_window, _("buddylist: Show the buddylist."), gg_blist_show); + gaim_cmd_register("accounts", "", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + cmd_show_window, _("accounts: Show the accounts window."), gg_accounts_show_all); + gaim_cmd_register("debugwin", "", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + cmd_show_window, _("debugwin: Show the debug window."), gg_debug_window_show); + gaim_cmd_register("prefs", "", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + cmd_show_window, _("prefs: Show the preference window."), gg_prefs_show_all); } void gg_conversation_uninit() Modified: branches/soc-2006-file-loggers/console/gntdebug.c =================================================================== --- branches/soc-2006-file-loggers/console/gntdebug.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntdebug.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -19,7 +19,6 @@ { if (key[0] == 27) { - /* XXX: This doesn't seem to always work */ if (strcmp(key+1, GNT_KEY_DOWN) == 0) gnt_text_view_scroll(view, 1); else if (strcmp(key+1, GNT_KEY_UP) == 0) @@ -39,9 +38,7 @@ gg_debug_print(GaimDebugLevel level, const char *category, const char *args) { - if (debug.window == NULL) - fprintf(stderr, "%s: %s\n", category, args); - else + if (debug.window) { GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL; @@ -63,10 +60,7 @@ } gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), args, flag); - gnt_text_view_next_line(GNT_TEXT_VIEW(debug.tview)); gnt_text_view_scroll(GNT_TEXT_VIEW(debug.tview), 0); - - g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview); } } @@ -97,7 +91,10 @@ debug.tview = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(debug.window), debug.tview); + /* XXX: Add checkboxes/buttons for Clear, Pause, Timestamps */ + g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL); + g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview); } gnt_widget_show(debug.window); @@ -105,7 +102,8 @@ void gg_debug_init() { - gg_debug_window_show(); + if (gaim_debug_is_enabled()) + gg_debug_window_show(); } void gg_debug_uninit() Modified: branches/soc-2006-file-loggers/console/gntdebug.h =================================================================== --- branches/soc-2006-file-loggers/console/gntdebug.h 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntdebug.h 2006-08-09 04:49:19 UTC (rev 16677) @@ -6,3 +6,4 @@ void gg_debug_uninit(); +void gg_debug_window_show(); Modified: branches/soc-2006-file-loggers/console/gntgaim.c =================================================================== --- branches/soc-2006-file-loggers/console/gntgaim.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntgaim.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -140,9 +140,9 @@ char *text; if (terse) { - text = g_strdup_printf(_("Gaim %s. Try `%s -h' for more information.\n"), VERSION, name); + text = g_strdup_printf(_("%s. Try `%s -h' for more information.\n"), VERSION, name); } else { - text = g_strdup_printf(_("Gaim %s\n" + text = g_strdup_printf(_("%s\n" "Usage: %s [OPTION]...\n\n" " -c, --config=DIR use DIR for config files\n" " -d, --debug print debugging messages to stdout\n" @@ -151,6 +151,7 @@ " -v, --version display the current version and exit\n"), VERSION, name); } + gnt_quit(); gaim_print_utf8_to_console(stdout, text); g_free(text); } Copied: branches/soc-2006-file-loggers/console/gntplugin.c (from rev 16676, trunk/console/gntplugin.c) =================================================================== --- branches/soc-2006-file-loggers/console/gntplugin.c (rev 0) +++ branches/soc-2006-file-loggers/console/gntplugin.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -0,0 +1,135 @@ +#include <gnt.h> +#include <gntbox.h> +#include <gntlabel.h> +#include <gntline.h> +#include <gnttree.h> + +#include "notify.h" + +#include "gntgaim.h" +#include "gntplugin.h" + +static struct +{ + GntWidget *tree; + GntWidget *window; + GntWidget *aboot; +} plugins; + +static void +plugin_toggled_cb(GntWidget *tree, GaimPlugin *plugin, gpointer null) +{ + if (gnt_tree_get_choice(GNT_TREE(tree), plugin)) + { + if(!gaim_plugin_load(plugin)) + gaim_notify_error(NULL, "ERROR", "loading plugin failed", NULL); + } + else + { + if (!gaim_plugin_unload(plugin)) + gaim_notify_error(NULL, "ERROR", "unloading plugin failed", NULL); + } + gg_plugins_save_loaded(); +} + +/* Xerox */ +void +gg_plugins_save_loaded(void) +{ + GList *pl; + GList *files = NULL; + GaimPlugin *p; + + for (pl = gaim_plugins_get_loaded(); pl != NULL; pl = pl->next) { + p = pl->data; + + if (p->info->type != GAIM_PLUGIN_PROTOCOL && + p->info->type != GAIM_PLUGIN_LOADER) { + + files = g_list_append(files, p->path); + } + } + + gaim_prefs_set_string_list("/gaim/gnt/plugins/loaded", files); + g_list_free(files); +} + +static void +selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null) +{ + GaimPlugin *plugin = current; + char *text; + + /* XXX: Use formatting and stuff */ + gnt_text_view_clear(GNT_TEXT_VIEW(plugins.aboot)); + text = g_strdup_printf(_("Name: %s\nVersion: %s\nDescription: %s\nAuthor: %s\nWebsite: %s\nFilename: %s\n"), + plugin->info->name, plugin->info->version, plugin->info->description, + plugin->info->author, plugin->info->homepage, plugin->path); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(plugins.aboot), + text, GNT_TEXT_FLAG_NORMAL); + gnt_text_view_scroll(GNT_TEXT_VIEW(plugins.aboot), 0); +} + +static void +reset_plugin_window(GntWidget *window, gpointer null) +{ + plugins.window = NULL; + plugins.tree = NULL; + plugins.aboot = NULL; +} + +void gg_plugins_show_all() +{ + GntWidget *window, *tree, *box, *aboot; + GList *iter; + if (plugins.window) + return; + + gaim_plugins_probe(G_MODULE_SUFFIX); + + plugins.window = window = gnt_vbox_new(FALSE); + gnt_box_set_toplevel(GNT_BOX(window), TRUE); + gnt_box_set_title(GNT_BOX(window), _("Plugins")); + gnt_box_set_pad(GNT_BOX(window), 0); + + gnt_box_add_widget(GNT_BOX(window), + gnt_label_new(_("You can (un)load plugins from the following list."))); + gnt_box_add_widget(GNT_BOX(window), gnt_hline_new()); + + box = gnt_hbox_new(FALSE); + gnt_box_add_widget(GNT_BOX(window), box); + gnt_box_add_widget(GNT_BOX(window), gnt_hline_new()); + + gnt_box_set_pad(GNT_BOX(box), 0); + plugins.tree = tree = gnt_tree_new(); + GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); + gnt_box_add_widget(GNT_BOX(box), tree); + gnt_box_add_widget(GNT_BOX(box), gnt_vline_new()); + + plugins.aboot = aboot = gnt_text_view_new(); + gnt_widget_set_size(aboot, 40, 20); + gnt_box_add_widget(GNT_BOX(box), aboot); + + for (iter = gaim_plugins_get_all(); iter; iter = iter->next) + { + GaimPlugin *plug = iter->data; + + if (plug->info->type != GAIM_PLUGIN_STANDARD || + (plug->info->flags & GAIM_PLUGIN_FLAG_INVISIBLE) || + plug->error) + continue; + + gnt_tree_add_choice(GNT_TREE(tree), plug, + gnt_tree_create_row(GNT_TREE(tree), plug->info->name), NULL, NULL); + gnt_tree_set_choice(GNT_TREE(tree), plug, gaim_plugin_is_loaded(plug)); + } + gnt_tree_set_col_width(GNT_TREE(tree), 0, 30); + g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(plugin_toggled_cb), NULL); + g_signal_connect(G_OBJECT(tree), "selection_changed", G_CALLBACK(selection_changed), NULL); + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(reset_plugin_window), NULL); + + gnt_tree_set_selected(GNT_TREE(tree), gaim_plugins_get_all()->data); + + gnt_widget_show(window); +} + Copied: branches/soc-2006-file-loggers/console/gntplugin.h (from rev 16676, trunk/console/gntplugin.h) =================================================================== --- branches/soc-2006-file-loggers/console/gntplugin.h (rev 0) +++ branches/soc-2006-file-loggers/console/gntplugin.h 2006-08-09 04:49:19 UTC (rev 16677) @@ -0,0 +1,6 @@ +#include <plugin.h> + +void gg_plugins_show_all(); + +void gg_plugins_save_loaded(); + Modified: branches/soc-2006-file-loggers/console/gntprefs.c =================================================================== --- branches/soc-2006-file-loggers/console/gntprefs.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntprefs.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -1,8 +1,11 @@ #include <prefs.h> +#include "gntgaim.h" #include "gntprefs.h" -#include "gntgaim.h" +#include "gntrequest.h" +#include <string.h> + void gg_prefs_init() { gaim_prefs_add_none("/gaim"); @@ -10,5 +13,182 @@ gaim_prefs_add_none("/gaim/gnt/plugins"); gaim_prefs_add_string_list("/gaim/gnt/plugins/loaded", NULL); + + gaim_prefs_add_none("/gaim/gnt/conversations"); + gaim_prefs_add_bool("/gaim/gnt/conversations/timestamps", TRUE); + gaim_prefs_add_bool("/gaim/gnt/conversations/notify_typing", FALSE); } +typedef struct +{ + GaimPrefType type; + const char *pref; + const char *label; + GList *(*lv)(); /* If the value is to be selected from a number of choices */ +} Prefs; + +static GList * +get_log_options() +{ + return gaim_log_logger_get_options(); +} + +static GaimRequestField * +get_pref_field(Prefs *prefs) +{ + GaimRequestField *field = NULL; + + if (prefs->lv == NULL) + { + switch (prefs->type) + { + case GAIM_PREF_BOOLEAN: + field = gaim_request_field_bool_new(prefs->pref, prefs->label, + gaim_prefs_get_bool(prefs->pref)); + break; + case GAIM_PREF_INT: + field = gaim_request_field_int_new(prefs->pref, prefs->label, + gaim_prefs_get_int(prefs->pref)); + break; + case GAIM_PREF_STRING: + field = gaim_request_field_string_new(prefs->pref, prefs->label, + gaim_prefs_get_string(prefs->pref), FALSE); + break; + default: + break; + } + } + else + { + GList *list = prefs->lv(), *iter; + field = gaim_request_field_list_new(prefs->pref, prefs->label); + for (iter = list; iter; iter = iter->next) + { + gboolean select = FALSE; + const char *data = iter->data; + iter = iter->next; + switch (prefs->type) + { + case GAIM_PREF_BOOLEAN: + if (gaim_prefs_get_bool(prefs->pref) == GPOINTER_TO_INT(iter->data)) + select = TRUE; + break; + case GAIM_PREF_INT: + if (gaim_prefs_get_int(prefs->pref) == GPOINTER_TO_INT(iter->data)) + select = TRUE; + break; + case GAIM_PREF_STRING: + if (strcmp(gaim_prefs_get_string(prefs->pref), iter->data) == 0) + select = TRUE; + break; + default: + break; + } + gaim_request_field_list_add(field, data, iter->data); + if (select) + gaim_request_field_list_add_selected(field, data); + } + g_list_free(list); + } + return field; +} + +static Prefs convs[] = +{ + {GAIM_PREF_BOOLEAN, "/gaim/gnt/conversations/timestamps", _("Show Timestamps"), NULL}, + {GAIM_PREF_BOOLEAN, "/gaim/gnt/conversations/notify_typing", _("Notify buddies when you are typing"), NULL}, + {GAIM_PREF_NONE, NULL, NULL, NULL} +}; + +static Prefs logging[] = +{ + {GAIM_PREF_STRING, "/core/logging/format", _("Log format"), get_log_options}, + {GAIM_PREF_BOOLEAN, "/core/logging/log_ims", _("Log IMs"), NULL}, + {GAIM_PREF_BOOLEAN, "/core/logging/log_chats", _("Log chats"), NULL}, + {GAIM_PREF_BOOLEAN, "/core/logging/log_system", _("Log status change events"), NULL}, + {GAIM_PREF_NONE, NULL, NULL, NULL}, +}; + +static void +save_cb(void *data, GaimRequestFields *allfields) +{ + GList *list; + for (list = gaim_request_fields_get_groups(allfields); list; list = list->next) + { + GaimRequestFieldGroup *group = list->data; + GList *fields = gaim_request_field_group_get_fields(group); + + for (; fields ; fields = fields->next) + { + GaimRequestField *field = fields->data; + GaimRequestFieldType type = gaim_request_field_get_type(field); + GaimPrefType pt; + gpointer val = NULL; + const char *id = gaim_request_field_get_id(field); + + switch (type) + { + case GAIM_REQUEST_FIELD_LIST: + val = gaim_request_field_list_get_selected(field)->data; + break; + case GAIM_REQUEST_FIELD_BOOLEAN: + val = GINT_TO_POINTER(gaim_request_field_bool_get_value(field)); + break; + case GAIM_REQUEST_FIELD_INTEGER: + val = GINT_TO_POINTER(gaim_request_field_int_get_value(field)); + break; + case GAIM_REQUEST_FIELD_STRING: + val = (gpointer)gaim_request_field_string_get_value(field); + break; + default: + break; + } + + pt = gaim_prefs_get_type(id); + switch (pt) + { + case GAIM_PREF_INT: + gaim_prefs_set_int(id, GPOINTER_TO_INT(val)); + break; + case GAIM_PREF_BOOLEAN: + gaim_prefs_set_bool(id, GPOINTER_TO_INT(val)); + break; + case GAIM_PREF_STRING: + gaim_prefs_set_string(id, val); + break; + default: + break; + } + } + } +} + +void gg_prefs_show_all() +{ + GaimRequestFields *fields; + GaimRequestField *field; + GaimRequestFieldGroup *group; + int i; + + fields = gaim_request_fields_new(); + + group = gaim_request_field_group_new(_("Conversations")); + gaim_request_fields_add_group(fields, group); + for (i = 0; convs[i].pref; i++) + { + field = get_pref_field(convs + i); + gaim_request_field_group_add_field(group, field); + } + + group = gaim_request_field_group_new(_("Logging")); + gaim_request_fields_add_group(fields, group); + for (i = 0; logging[i].pref; i++) + { + field = get_pref_field(logging + i); + gaim_request_field_group_add_field(group, field); + } + + gaim_request_fields(NULL, _("Preferences"), NULL, NULL, fields, + _("Save"), G_CALLBACK(save_cb), _("Cancel"), NULL, NULL); +} + Modified: branches/soc-2006-file-loggers/console/gntprefs.h =================================================================== --- branches/soc-2006-file-loggers/console/gntprefs.h 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntprefs.h 2006-08-09 04:49:19 UTC (rev 16677) @@ -1,2 +1,4 @@ void gg_prefs_init(); +void gg_prefs_show_all(); + Modified: branches/soc-2006-file-loggers/console/gntrequest.c =================================================================== --- branches/soc-2006-file-loggers/console/gntrequest.c 2006-08-09 04:22:08 UTC (rev 16676) +++ branches/soc-2006-file-loggers/console/gntrequest.c 2006-08-09 04:49:19 UTC (rev 16677) @@ -1,15 +1,19 @@ #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> +#include <gntcheckbox.h> #include <gntcombobox.h> #include <gntentry.h> #include <gntlabel.h> +#include <gntline.h> +#include <gnttree.h> +#include "gntgaim.h" #include "gntrequest.h" static GntWidget * setup_request_window(const char *title, const char *primary, - const char *secondary) + const char *secondary, GaimRequestType type) { GntWidget *window; @@ -24,6 +28,9 @@ if (secondary) gnt_box_add_widget(GNT_BOX(window), gnt_label_new(secondary)); + g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gaim_request_close), + GINT_TO_POINTER(type)); + return window; } @@ -35,7 +42,7 @@ const char *text; gpointer callback; - box = gnt_hbox_new(TRUE); + box = gnt_hbox_new(FALSE); va_start(list, data); @@ -79,7 +86,7 @@ { GntWidget *window, *box, *entry; - window = setup_request_window(title, primary, secondary); + window = setup_request_window(title, primary, secondary, GAIM_REQUES... [truncated message content] |
From: <ro...@us...> - 2006-08-13 17:39:38
|
Revision: 16738 Author: roast Date: 2006-08-13 10:38:25 -0700 (Sun, 13 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16738&view=rev Log Message: ----------- merged with svn trunk. 16676:16737. Modified Paths: -------------- branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/console/gntblist.c branches/soc-2006-file-loggers/console/gntconv.c branches/soc-2006-file-loggers/console/gntprefs.c branches/soc-2006-file-loggers/console/gntrequest.c branches/soc-2006-file-loggers/console/libgnt/Makefile.am branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c branches/soc-2006-file-loggers/console/libgnt/gntentry.c branches/soc-2006-file-loggers/console/libgnt/gntentry.h branches/soc-2006-file-loggers/console/libgnt/gntkeys.h branches/soc-2006-file-loggers/console/libgnt/gntmain.c branches/soc-2006-file-loggers/console/libgnt/gnttree.c branches/soc-2006-file-loggers/console/libgnt/gnttree.h branches/soc-2006-file-loggers/console/libgnt/gntutils.c branches/soc-2006-file-loggers/console/libgnt/gntwidget.c branches/soc-2006-file-loggers/console/libgnt/test/tv.c branches/soc-2006-file-loggers/gaim.apspec.in branches/soc-2006-file-loggers/plugins/ChangeLog.API branches/soc-2006-file-loggers/plugins/log_reader.c branches/soc-2006-file-loggers/po/ChangeLog branches/soc-2006-file-loggers/po/de.po branches/soc-2006-file-loggers/po/fi.po branches/soc-2006-file-loggers/po/gl.po branches/soc-2006-file-loggers/po/gu.po branches/soc-2006-file-loggers/po/it.po branches/soc-2006-file-loggers/po/sl.po branches/soc-2006-file-loggers/po/zh_TW.po branches/soc-2006-file-loggers/src/account.c branches/soc-2006-file-loggers/src/ft.c branches/soc-2006-file-loggers/src/gtkaccount.c branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/gtkdialogs.c branches/soc-2006-file-loggers/src/plugin.c branches/soc-2006-file-loggers/src/protocols/irc/irc.c branches/soc-2006-file-loggers/src/protocols/jabber/JEPS branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/si.c branches/soc-2006-file-loggers/src/protocols/msn/directconn.c branches/soc-2006-file-loggers/src/protocols/msn/directconn.h branches/soc-2006-file-loggers/src/protocols/msn/httpconn.c branches/soc-2006-file-loggers/src/protocols/msn/nexus.c branches/soc-2006-file-loggers/src/protocols/msn/servconn.c branches/soc-2006-file-loggers/src/protocols/msn/slp.c branches/soc-2006-file-loggers/src/protocols/oscar/family_icbm.c branches/soc-2006-file-loggers/src/protocols/oscar/family_oservice.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/oscar/peer.c branches/soc-2006-file-loggers/src/protocols/oscar/peer.h branches/soc-2006-file-loggers/src/protocols/oscar/peer_proxy.c branches/soc-2006-file-loggers/src/protocols/qq/qq_proxy.c branches/soc-2006-file-loggers/src/protocols/sametime/sametime.c branches/soc-2006-file-loggers/src/protocols/silc/silc.c branches/soc-2006-file-loggers/src/protocols/silc/util.c branches/soc-2006-file-loggers/src/protocols/simple/simple.c branches/soc-2006-file-loggers/src/protocols/simple/simple.h branches/soc-2006-file-loggers/src/protocols/simple/sipmsg.c branches/soc-2006-file-loggers/src/protocols/simple/sipmsg.h branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_filexfer.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_picture.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoochat.c branches/soc-2006-file-loggers/src/protocols/yahoo/ycht.c branches/soc-2006-file-loggers/src/proxy.c branches/soc-2006-file-loggers/src/proxy.h branches/soc-2006-file-loggers/src/request.c branches/soc-2006-file-loggers/src/request.h branches/soc-2006-file-loggers/src/sslconn.c branches/soc-2006-file-loggers/src/upnp.c branches/soc-2006-file-loggers/src/util.c branches/soc-2006-file-loggers/src/xmlnode.h Added Paths: ----------- branches/soc-2006-file-loggers/console/libgnt/gntkeys.c branches/soc-2006-file-loggers/po/ne.po Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/configure.ac 2006-08-13 17:38:25 UTC (rev 16738) @@ -46,7 +46,7 @@ ;; esac -ALL_LINGUAS="am az bg bn bs ca ca@valencia cs da de el en_AU en_CA en_GB es et eu fa fi fr gl gu he hi hu it ja ka ko ku lt mk my_MM nb nl nn pa pl pt_BR pt ro ru sk sl sq sr sr@Latn sv ta te th tr uk vi xh zh_CN zh_TW" +ALL_LINGUAS="am az bg bn bs ca ca@valencia cs da de el en_AU en_CA en_GB es et eu fa fi fr gl gu he hi hu it ja ka ko ku lt mk my_MM nb ne nl nn pa pl pt_BR pt ro ru sk sl sq sr sr@Latn sv ta te th tr uk vi xh zh_CN zh_TW" AM_GLIB_GNU_GETTEXT dnl we don't use autobreak on cygwin!! @@ -546,7 +546,6 @@ if test "x$enable_debug" = "xyes" ; then AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.]) - enable_fatal_asserts="yes" fi if test "x$enable_fatal_asserts" = "xyes" ; then @@ -1822,9 +1821,10 @@ echo echo Use XScreenSaver Extension.... : $enable_xss echo Use X Session Management...... : $enable_sm -echo Use startup notification.......: $enable_startup_notification +echo Use startup notification...... : $enable_startup_notification echo echo Print debugging messages...... : $enable_debug +echo Assertions are fatal.......... : $enable_fatal_asserts echo eval eval echo Gaim will be installed in $bindir. if test "x$gaimpath" != "x" ; then Modified: branches/soc-2006-file-loggers/console/gntblist.c =================================================================== --- branches/soc-2006-file-loggers/console/gntblist.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/gntblist.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -1,5 +1,6 @@ #include <account.h> #include <blist.h> +#include <notify.h> #include <request.h> #include <savedstatuses.h> #include <server.h> @@ -100,7 +101,6 @@ gnt_tree_remove(GNT_TREE(ggblist->tree), node); node->ui_data = NULL; - /* XXX: Depending on the node, we may want to remove the group/contact node if necessary */ if (GAIM_BLIST_NODE_IS_BUDDY(node)) { GaimGroup *group = gaim_buddy_get_group((GaimBuddy*)node); @@ -141,6 +141,103 @@ { } +static void +add_buddy_cb(void *data, GaimRequestFields *allfields) +{ + const char *username = gaim_request_fields_get_string(allfields, "screenname"); + const char *alias = gaim_request_fields_get_string(allfields, "alias"); + const char *group = gaim_request_fields_get_string(allfields, "group"); + GaimAccount *account = gaim_request_fields_get_account(allfields, "account"); + const char *error = NULL; + GaimGroup *grp; + GaimBuddy *buddy; + + if (!username) + error = _("You must provide a screename for the buddy."); + else if (!group) + error = _("You must provide a group."); + else if (!account) + error = _("You must select an account."); + + if (error) + { + gaim_notify_error(NULL, _("Error"), _("Error adding buddy"), error); + return; + } + + grp = gaim_find_group(group); + if (!grp) + { + grp = gaim_group_new(group); + gaim_blist_add_group(grp, NULL); + } + + buddy = gaim_buddy_new(account, username, alias); + gaim_blist_add_buddy(buddy, NULL, grp, NULL); + gaim_account_add_buddy(account, buddy); +} + +static void +gg_request_add_buddy(GaimAccount *account, const char *username, const char *grp, const char *alias) +{ + GaimRequestFields *fields = gaim_request_fields_new(); + GaimRequestFieldGroup *group = gaim_request_field_group_new(NULL); + GaimRequestField *field; + + gaim_request_fields_add_group(fields, group); + + field = gaim_request_field_string_new("screenname", _("Screen Name"), username, FALSE); + gaim_request_field_group_add_field(group, field); + + field = gaim_request_field_string_new("alias", _("Alias"), alias, FALSE); + gaim_request_field_group_add_field(group, field); + + field = gaim_request_field_string_new("group", _("Group"), grp, FALSE); + gaim_request_field_group_add_field(group, field); + + field = gaim_request_field_account_new("account", _("Account"), NULL); + gaim_request_field_account_set_show_all(field, FALSE); + if (account) + gaim_request_field_account_set_value(field, account); + gaim_request_field_group_add_field(group, field); + + gaim_request_fields(NULL, _("Add Buddy"), NULL, _("Please enter buddy information."), + fields, _("Add"), G_CALLBACK(add_buddy_cb), _("Cancel"), NULL, NULL); +} + +static void +add_group_cb(gpointer null, const char *group) +{ + GaimGroup *grp; + + if (!group || !*group) + { + gaim_notify_error(NULL, _("Error"), _("Error adding group"), + _("You must give a name for the group to add.")); + return; + } + + grp = gaim_find_group(group); + if (!grp) + { + grp = gaim_group_new(group); + gaim_blist_add_group(grp, NULL); + } + else + { + gaim_notify_error(NULL, _("Error"), _("Error adding group"), + _("A group with the name already exists.")); + } +} + +static void +gg_request_add_group() +{ + gaim_request_input(NULL, _("Add Group"), NULL, _("Enter the name of the group"), + NULL, FALSE, FALSE, NULL, + _("Add"), G_CALLBACK(add_group_cb), _("Cancel"), NULL, NULL); +} + static GaimBlistUiOps blist_ui_ops = { new_list, @@ -150,9 +247,9 @@ node_remove, NULL, NULL, + .request_add_buddy = gg_request_add_buddy, NULL, - NULL, - NULL + .request_add_group = gg_request_add_group }; static gpointer @@ -360,8 +457,24 @@ } static void +gg_add_buddy(GaimGroup *grp, GaimBlistNode *node) +{ + gaim_blist_request_add_buddy(NULL, NULL, grp->name, NULL); +} + +static void +gg_add_group(GaimGroup *grp, GaimBlistNode *node) +{ + gaim_blist_request_add_group(); +} + +static void create_group_menu(GntTree *tree, GaimGroup *group) { + add_custom_action(tree, _("Add Buddy"), + GAIM_CALLBACK(gg_add_buddy), group); + add_custom_action(tree, _("Add Group"), + GAIM_CALLBACK(gg_add_group), group); } static void @@ -476,26 +589,91 @@ g_free(prompt); } -/* XXX: This still doesn't do anything, because request doesn't have a ui yet */ +/* Xeroxed from gtkdialogs.c:gaim_gtkdialogs_remove_group_cb*/ static void +remove_group(GaimGroup *group) +{ + GaimBlistNode *cnode, *bnode; + + cnode = ((GaimBlistNode*)group)->child; + + while (cnode) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + bnode = cnode->child; + cnode = cnode->next; + while (bnode) { + GaimBuddy *buddy; + if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { + buddy = (GaimBuddy*)bnode; + bnode = bnode->next; + if (gaim_account_is_connected(buddy->account)) { + gaim_account_remove_buddy(buddy->account, buddy, group); + gaim_blist_remove_buddy(buddy); + } + } else { + bnode = bnode->next; + } + } + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { + GaimChat *chat = (GaimChat *)cnode; + cnode = cnode->next; + if (gaim_account_is_connected(chat->account)) + gaim_blist_remove_chat(chat); + } else { + cnode = cnode->next; + } + } + + gaim_blist_remove_group(group); +} + +static void +gg_blist_remove_node(GaimBlistNode *node) +{ + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + { + GaimBuddy *buddy = (GaimBuddy*)node; + GaimGroup *group = gaim_buddy_get_group(buddy); + gaim_account_remove_buddy(gaim_buddy_get_account(buddy), buddy, group); + gaim_blist_remove_buddy(buddy); + } + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + { + gaim_blist_remove_chat((GaimChat*)node); + } + else if (GAIM_BLIST_NODE_IS_GROUP(node)) + { + remove_group((GaimGroup*)node); + } +} + +static void gg_blist_remove_node_cb(GaimBlistNode *node, GaimBlistNode *null) { - void (*callback)(gpointer); + char *primary, *sec = NULL; + const char *name; if (GAIM_BLIST_NODE_IS_BUDDY(node)) - callback = (void(*)(gpointer))gaim_blist_remove_buddy; + name = gaim_buddy_get_name((GaimBuddy*)node); else if (GAIM_BLIST_NODE_IS_CHAT(node)) - callback = (void(*)(gpointer))gaim_blist_remove_chat; + name = gaim_chat_get_name((GaimChat*)node); else if (GAIM_BLIST_NODE_IS_GROUP(node)) - callback = (void(*)(gpointer))gaim_blist_remove_group; + { + name = ((GaimGroup*)node)->name; + sec = _("Removing this group will also remove all the buddies in the group"); + } + else + return; + primary = g_strdup_printf(_("Are you sure you want to remove %s?"), name); + /* XXX: anything to do with the returned ui-handle? */ gaim_request_action(node, _("Confirm Remove"), - _("Are you sure you want to remove ..."), NULL, /* XXX: tidy up */ + primary, sec, 1, node, 2, - _("Remove"), callback, - _("No"), NULL); - + _("Remove"), gg_blist_remove_node, + _("Cancel"), NULL); + g_free(primary); } static void @@ -555,6 +733,7 @@ GAIM_CALLBACK(gg_blist_remove_node_cb), node); window = gnt_vbox_new(FALSE); + GNT_WIDGET_SET_FLAGS(window, GNT_WIDGET_TRANSIENT); gnt_box_set_toplevel(GNT_BOX(window), TRUE); gnt_box_set_title(GNT_BOX(window), title); @@ -634,6 +813,18 @@ g_free(br); } + if (gaim_prefs_get_bool("/gaim/gnt/blist/idletime")) + { + GaimPresence *pre = gaim_buddy_get_presence(buddy); + if (gaim_presence_is_idle(pre)) + { + time_t idle = gaim_presence_get_idle_time(pre); + char *st = gaim_str_seconds_to_string(time(NULL) - idle); + g_string_append_printf(str, _("\nIdle: %s"), st); + g_free(st); + } + } + title = g_strdup(gaim_buddy_get_name(buddy)); } else if (GAIM_BLIST_NODE_IS_GROUP(node)) Modified: branches/soc-2006-file-loggers/console/gntconv.c =================================================================== --- branches/soc-2006-file-loggers/console/gntconv.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/gntconv.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -123,6 +123,7 @@ } g_free(escape); } + gnt_entry_add_to_history(GNT_ENTRY(ggconv->entry), text); gnt_entry_clear(GNT_ENTRY(ggconv->entry)); return TRUE; } @@ -198,8 +199,11 @@ ggc->entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); gnt_widget_set_name(ggc->entry, "conversation-window-entry"); + gnt_entry_set_history_length(GNT_ENTRY(ggc->entry), -1); + gnt_entry_set_word_suggest(GNT_ENTRY(ggc->entry), TRUE); + gnt_entry_set_always_suggest(GNT_ENTRY(ggc->entry), FALSE); - g_signal_connect(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); + g_signal_connect_after(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); gnt_widget_set_position(ggc->window, gaim_prefs_get_int(PREF_ROOT "/position/x"), @@ -229,6 +233,9 @@ g_return_if_fail(ggconv != NULL); + if (gaim_prefs_get_bool("/gaim/gnt/conversations/timestamps")) + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + gaim_utf8_strftime("(%H:%M:%S) ", localtime(&mtime)), GNT_TEXT_FLAG_DIM); if (who && *who && (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV))) { char * name = g_strdup_printf("%s: ", who); @@ -312,6 +319,9 @@ static void gg_chat_add_users(GaimConversation *conv, GList *users, gboolean new_arrivals) { + GGConv *ggc = conv->ui_data; + GntEntry *entry = GNT_ENTRY(ggc->entry); + if (!new_arrivals) { /* Print the list of users in the room */ @@ -332,25 +342,39 @@ GAIM_MESSAGE_SYSTEM, time(NULL)); g_string_free(string, TRUE); } - /* XXX: Add the names for string completion */ + + for (; users; users = users->next) + { + GaimConvChatBuddy *cbuddy = users->data; + gnt_entry_add_suggest(entry, cbuddy->name); + gnt_entry_add_suggest(entry, cbuddy->alias); + } } static void gg_chat_rename_user(GaimConversation *conv, const char *old, const char *new_n, const char *new_a) { /* XXX: Update the name for string completion */ + GGConv *ggc = conv->ui_data; + GntEntry *entry = GNT_ENTRY(ggc->entry); + gnt_entry_remove_suggest(entry, old); + gnt_entry_add_suggest(entry, new_n); + gnt_entry_add_suggest(entry, new_a); } static void gg_chat_remove_user(GaimConversation *conv, GList *list) { /* XXX: Remove the name from string completion */ + GGConv *ggc = conv->ui_data; + GntEntry *entry = GNT_ENTRY(ggc->entry); + for (; list; list = list->next) + gnt_entry_remove_suggest(entry, list->data); } static void gg_chat_update_user(GaimConversation *conv, const char *user) { - /* XXX: This probably will not require updating the string completion */ } static GaimConversationUiOps conv_ui_ops = Modified: branches/soc-2006-file-loggers/console/gntprefs.c =================================================================== --- branches/soc-2006-file-loggers/console/gntprefs.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/gntprefs.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -14,9 +14,12 @@ gaim_prefs_add_none("/gaim/gnt/plugins"); gaim_prefs_add_string_list("/gaim/gnt/plugins/loaded", NULL); + gaim_prefs_add_none("/gaim/gnt/blist"); + gaim_prefs_add_bool("/gaim/gnt/blist/idletime", TRUE); + gaim_prefs_add_none("/gaim/gnt/conversations"); gaim_prefs_add_bool("/gaim/gnt/conversations/timestamps", TRUE); - gaim_prefs_add_bool("/gaim/gnt/conversations/notify_typing", FALSE); + gaim_prefs_add_bool("/gaim/gnt/conversations/notify_typing", FALSE); /* XXX: Not functional yet */ } typedef struct @@ -93,6 +96,12 @@ return field; } +static Prefs blist[] = +{ + {GAIM_PREF_BOOLEAN, "/gaim/gnt/blist/idletime", _("Show Idle Time"), NULL}, + {GAIM_PREF_NONE, NULL, NULL, NULL} +}; + static Prefs convs[] = { {GAIM_PREF_BOOLEAN, "/gaim/gnt/conversations/timestamps", _("Show Timestamps"), NULL}, @@ -163,31 +172,32 @@ } } -void gg_prefs_show_all() +static void +add_pref_group(GaimRequestFields *fields, const char *title, Prefs *prefs) { - GaimRequestFields *fields; GaimRequestField *field; GaimRequestFieldGroup *group; int i; - fields = gaim_request_fields_new(); - - group = gaim_request_field_group_new(_("Conversations")); + group = gaim_request_field_group_new(title); gaim_request_fields_add_group(fields, group); - for (i = 0; convs[i].pref; i++) + for (i = 0; prefs[i].pref; i++) { - field = get_pref_field(convs + i); + field = get_pref_field(prefs + i); gaim_request_field_group_add_field(group, field); } +} - group = gaim_request_field_group_new(_("Logging")); - gaim_request_fields_add_group(fields, group); - for (i = 0; logging[i].pref; i++) - { - field = get_pref_field(logging + i); - gaim_request_field_group_add_field(group, field); - } +void gg_prefs_show_all() +{ + GaimRequestFields *fields; + fields = gaim_request_fields_new(); + + add_pref_group(fields, _("Buddy List"), blist); + add_pref_group(fields, _("Conversations"), convs); + add_pref_group(fields, _("Logging"), logging); + gaim_request_fields(NULL, _("Preferences"), NULL, NULL, fields, _("Save"), G_CALLBACK(save_cb), _("Cancel"), NULL, NULL); } Modified: branches/soc-2006-file-loggers/console/gntrequest.c =================================================================== --- branches/soc-2006-file-loggers/console/gntrequest.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/gntrequest.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -182,7 +182,7 @@ window = setup_request_window(title, primary, secondary, GAIM_REQUEST_ACTION); - box = gnt_hbox_new(TRUE); + box = gnt_hbox_new(FALSE); gnt_box_add_widget(GNT_BOX(window), box); for (i = 0; i < actioncount; i++) { @@ -234,7 +234,8 @@ else if (type == GAIM_REQUEST_FIELD_STRING) { GntWidget *entry = field->ui_data; - gaim_request_field_string_set_value(field, gnt_entry_get_text(GNT_ENTRY(entry))); + const char *text = gnt_entry_get_text(GNT_ENTRY(entry)); + gaim_request_field_string_set_value(field, (text && *text) ? text : NULL); } else if (type == GAIM_REQUEST_FIELD_INTEGER) { @@ -278,6 +279,9 @@ } else if (type == GAIM_REQUEST_FIELD_ACCOUNT) { + GntWidget *combo = field->ui_data; + GaimAccount *acc = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)); + gaim_request_field_account_set_value(field, acc); } } } @@ -293,13 +297,13 @@ static void * gg_request_fields(const char *title, const char *primary, - const char *secondary, GaimRequestFields *fields, + const char *secondary, GaimRequestFields *allfields, const char *ok, GCallback ok_cb, const char *cancel, GCallback cancel_cb, void *userdata) { GntWidget *window, *box; - GList *list; + GList *grlist; window = setup_request_window(title, primary, secondary, GAIM_REQUEST_FIELDS); @@ -309,27 +313,28 @@ box = gnt_vbox_new(FALSE); gnt_box_set_pad(GNT_BOX(box), 0); gnt_box_set_fill(GNT_BOX(box), TRUE); - for (list = gaim_request_fields_get_groups(fields); list; list = list->next) + for (grlist = gaim_request_fields_get_groups(allfields); grlist; grlist = grlist->next) { - GaimRequestFieldGroup *group = list->data; + GaimRequestFieldGroup *group = grlist->data; GList *fields = gaim_request_field_group_get_fields(group); GntWidget *hbox; - - gnt_box_add_widget(GNT_BOX(box), - gnt_label_new_with_format(gaim_request_field_group_get_title(group), - GNT_TEXT_FLAG_BOLD)); + const char *title = gaim_request_field_group_get_title(group); + if (title) + gnt_box_add_widget(GNT_BOX(box), + gnt_label_new_with_format(title, GNT_TEXT_FLAG_BOLD)); + for (; fields ; fields = fields->next) { + /* XXX: Break each of the fields into a separate function? */ GaimRequestField *field = fields->data; GaimRequestFieldType type = gaim_request_field_get_type(field); const char *label = gaim_request_field_get_label(field); - hbox = gnt_hbox_new(FALSE); - gnt_box_set_pad(GNT_BOX(hbox), 0); + hbox = gnt_hbox_new(TRUE); /* hrm */ gnt_box_add_widget(GNT_BOX(box), hbox); - if (type != GAIM_REQUEST_FIELD_BOOLEAN) + if (type != GAIM_REQUEST_FIELD_BOOLEAN && label) { GntWidget *l = gnt_label_new(label); gnt_widget_set_size(l, 0, 1); @@ -417,12 +422,44 @@ } } } -#if 0 else if (type == GAIM_REQUEST_FIELD_ACCOUNT) { - /* XXX: remember to set the field->ui_data */ + gboolean all; + GaimAccount *def; + GList *list; + GntWidget *combo = gnt_combo_box_new(); + gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); + gnt_box_add_widget(GNT_BOX(hbox), combo); + field->ui_data = combo; + + all = gaim_request_field_account_get_show_all(field); + def = gaim_request_field_account_get_default_value(field); + + if (all) + list = gaim_accounts_get_all(); + else + list = gaim_connections_get_all(); + + for (; list; list = list->next) + { + GaimAccount *account; + char *text; + + if (all) + account = list->data; + else + account = gaim_connection_get_account(list->data); + + text = g_strdup_printf("%s (%s)", + gaim_account_get_username(account), + gaim_account_get_protocol_name(account)); + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), account, text); + g_free(text); + if (account == def) + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), account); + } + gnt_widget_set_size(combo, 20, 3); /* ew */ } -#endif else { gnt_box_add_widget(GNT_BOX(hbox), @@ -430,12 +467,12 @@ GNT_TEXT_FLAG_BOLD)); } } - if (list->next) + if (grlist->next) gnt_box_add_widget(GNT_BOX(box), gnt_hline_new()); } gnt_box_add_widget(GNT_BOX(window), box); - box = setup_button_box(userdata, request_fields_cb, fields, + box = setup_button_box(userdata, request_fields_cb, allfields, ok, ok_cb, cancel, cancel_cb, NULL); gnt_box_add_widget(GNT_BOX(window), box); Modified: branches/soc-2006-file-loggers/console/libgnt/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/Makefile.am 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/Makefile.am 2006-08-13 17:38:25 UTC (rev 16738) @@ -11,6 +11,7 @@ gntcolors.c \ gntcombobox.c \ gntentry.c \ + gntkeys.c \ gntlabel.c \ gntline.c \ gntmarshal.c \ Modified: branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntcombobox.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -74,8 +74,13 @@ static void gnt_combo_box_size_request(GntWidget *widget) { - widget->priv.height = 3; /* For now, a combobox will have border */ - widget->priv.width = 15; + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) + { + GntWidget *dd = GNT_COMBO_BOX(widget)->dropdown; + gnt_widget_size_request(dd); + widget->priv.height = 3; /* For now, a combobox will have border */ + widget->priv.width = MIN(10, dd->priv.width + 4); + } } static void Modified: branches/soc-2006-file-loggers/console/libgnt/gntentry.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntentry.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntentry.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -1,7 +1,9 @@ #include <ctype.h> #include <string.h> +#include "gntbox.h" #include "gntentry.h" +#include "gnttree.h" enum { @@ -12,6 +14,92 @@ static guint signals[SIGS] = { 0 }; static void +destroy_suggest(GntEntry *entry) +{ + if (entry->ddown) + { + gnt_widget_destroy(entry->ddown->parent); + entry->ddown = NULL; + } +} + +static char * +get_beginning_of_word(GntEntry *entry) +{ + char *s = entry->cursor; + while (s > entry->start) + { + char *t = g_utf8_find_prev_char(entry->start, s); + if ((*t < 'A' || *t > 'Z') && (*t < 'a' || *t > 'z')) + break; + s = t; + } + return s; +} + +static gboolean +show_suggest_dropdown(GntEntry *entry) +{ + char *suggest = NULL; + int len; + int offset = 0, x, y; + int count = 0; + GList *iter; + + if (entry->word) + { + char *s = get_beginning_of_word(entry); + suggest = g_strndup(s, entry->cursor - s); + if (entry->scroll < s) + offset = g_utf8_pointer_to_offset(entry->scroll, s); + } + else + suggest = g_strdup(entry->start); + len = strlen(suggest); /* Don't need to use the utf8-function here */ + + if (entry->ddown == NULL) + { + GntWidget *box = gnt_vbox_new(FALSE); + entry->ddown = gnt_tree_new(); + gnt_box_add_widget(GNT_BOX(box), entry->ddown); + + GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT); + + gnt_widget_get_position(GNT_WIDGET(entry), &x, &y); + x += offset; + y++; + if (y + 10 >= getmaxy(stdscr)) + y -= 11; + gnt_widget_set_position(box, x, y); + + gnt_widget_draw(box); + } + else + gnt_tree_remove_all(GNT_TREE(entry->ddown)); + + for (count = 0, iter = entry->suggests; iter; iter = iter->next) + { + const char *text = iter->data; + if (g_ascii_strncasecmp(suggest, text, len) == 0 && strlen(text) >= len) + { + gnt_tree_add_row_after(GNT_TREE(entry->ddown), (gpointer)text, + gnt_tree_create_row(GNT_TREE(entry->ddown), text), + NULL, NULL); + count++; + } + } + g_free(suggest); + + if (count == 0) + { + destroy_suggest(entry); + return FALSE; + } + + return TRUE; +} + +static void gnt_entry_draw(GntWidget *widget) { GntEntry *entry = GNT_ENTRY(widget); @@ -80,6 +168,11 @@ memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1); entry->end -= len; entry_redraw(widget); + + if (entry->ddown) + show_suggest_dropdown(entry); + + return TRUE; } else if (strcmp(text + 1, GNT_KEY_LEFT) == 0 && entry->cursor > entry->start) { @@ -87,6 +180,8 @@ if (entry->cursor < entry->scroll) entry->scroll = entry->cursor; entry_redraw(widget); + + return TRUE; } else if (strcmp(text + 1, GNT_KEY_RIGHT) == 0 && entry->cursor < entry->end) { @@ -94,15 +189,89 @@ if (g_utf8_pointer_to_offset(entry->scroll, entry->cursor) >= widget->priv.width) entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); entry_redraw(widget); + + return TRUE; } + else if (strcmp(text + 1, GNT_KEY_CTRL_DOWN) == 0 && entry->histlength) + { + if (entry->history->prev) + { + entry->history = entry->history->prev; + gnt_entry_set_text(entry, entry->history->data); + destroy_suggest(entry); + + return TRUE; + } + } + else if (strcmp(text + 1, GNT_KEY_UP) == 0 || + strcmp(text + 1, GNT_KEY_DOWN) == 0) + { + if (entry->ddown) + { + gnt_widget_key_pressed(entry->ddown, text); + return TRUE; + } + } + else if (strcmp(text + 1, GNT_KEY_CTRL_UP) == 0 && entry->histlength) + { + if (entry->history->next) + { + if (entry->history->prev == NULL) + { + /* Save the current contents */ + char *text = g_strdup(gnt_entry_get_text(entry)); + g_free(entry->history->data); + entry->history->data = text; + } + + entry->history = entry->history->next; + gnt_entry_set_text(entry, entry->history->data); + destroy_suggest(entry); + + return TRUE; + } + } /* XXX: handle other keys, like home/end, and ctrl+ goodness */ - else - return FALSE; + else if (text[1] == 0) + { + destroy_suggest(entry); + } - return TRUE; + return FALSE; } else { + if (text[0] == '\t') + { + if (entry->ddown) + destroy_suggest(entry); + else if (entry->suggests) + return show_suggest_dropdown(entry); + + return FALSE; + } + else if (text[0] == '\r' && entry->ddown) + { + char *text = g_strdup(gnt_tree_get_selection_data(GNT_TREE(entry->ddown))); + destroy_suggest(entry); + if (entry->word) + { + char *s = get_beginning_of_word(entry); + char *iter = text; + while (toupper(*s) == toupper(*iter)) + { + *s++ = *iter++; + } + gnt_entry_key_pressed(widget, iter); + } + else + { + gnt_entry_set_text(entry, text); + } + g_free(text); + return TRUE; + } + if (!iscntrl(text[0])) { const char *str, *next; @@ -143,6 +312,9 @@ while (g_utf8_pointer_to_offset(entry->scroll, entry->cursor) >= widget->priv.width) entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); + + if (entry->ddown) + show_suggest_dropdown(entry); } entry_redraw(widget); return TRUE; @@ -161,6 +333,8 @@ entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll); entry_redraw(widget); + if (entry->ddown) + show_suggest_dropdown(entry); return TRUE; } } @@ -174,9 +348,35 @@ { GntEntry *entry = GNT_ENTRY(widget); g_free(entry->start); + + if (entry->history) + { + entry->history = g_list_first(entry->history); + g_list_foreach(entry->history, (GFunc)g_free, NULL); + g_list_free(entry->history); + } + + if (entry->suggests) + { + g_list_foreach(entry->suggests, (GFunc)g_free, NULL); + g_list_free(entry->suggests); + } + + if (entry->ddown) + { + gnt_widget_destroy(entry->ddown->parent); + } } static void +gnt_entry_lost_focus(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + destroy_suggest(entry); + entry_redraw(widget); +} + +static void gnt_entry_class_init(GntEntryClass *klass) { parent_class = GNT_WIDGET_CLASS(klass); @@ -185,6 +385,7 @@ parent_class->map = gnt_entry_map; parent_class->size_request = gnt_entry_size_request; parent_class->key_pressed = gnt_entry_key_pressed; + parent_class->lost_focus = gnt_entry_lost_focus; DEBUG; } @@ -197,7 +398,14 @@ entry->flag = GNT_ENTRY_FLAG_ALL; entry->max = 0; + + entry->histlength = 0; + entry->history = NULL; + entry->word = TRUE; + entry->always = FALSE; + entry->suggests = NULL; + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS); GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_GROW_X); @@ -302,6 +510,7 @@ gnt_entry_set_text(entry, NULL); entry->scroll = entry->cursor = entry->end = entry->start; entry_redraw(GNT_WIDGET(entry)); + destroy_suggest(entry); } void gnt_entry_set_masked(GntEntry *entry, gboolean set) @@ -309,3 +518,90 @@ entry->masked = set; } +void gnt_entry_add_to_history(GntEntry *entry, const char *text) +{ + g_return_if_fail(entry->history != NULL); /* Need to set_history_length first */ + + if (g_list_length(entry->history) >= entry->histlength) + return; + + entry->history = g_list_first(entry->history); + g_free(entry->history->data); + entry->history->data = g_strdup(text); + entry->history = g_list_prepend(entry->history, NULL); +} + +void gnt_entry_set_history_length(GntEntry *entry, int num) +{ + if (num == 0) + { + entry->histlength = num; + if (entry->history) + { + entry->history = g_list_first(entry->history); + g_list_foreach(entry->history, (GFunc)g_free, NULL); + g_list_free(entry->history); + entry->history = NULL; + } + return; + } + + if (entry->histlength == 0) + { + entry->histlength = num; + entry->history = g_list_append(NULL, NULL); + return; + } + + if (num > 0 && num < entry->histlength) + { + GList *first, *iter; + int index = 0; + for (first = entry->history, index = 0; first->prev; first = first->prev, index++); + while ((iter = g_list_nth(first, num)) != NULL) + { + g_free(iter->data); + first = g_list_delete_link(first, iter); + } + entry->histlength = num; + if (index >= num) + entry->history = g_list_last(first); + return; + } + + entry->histlength = num; +} + +void gnt_entry_set_word_suggest(GntEntry *entry, gboolean word) +{ + entry->word = word; +} + +void gnt_entry_set_always_suggest(GntEntry *entry, gboolean always) +{ + entry->always = always; +} + +void gnt_entry_add_suggest(GntEntry *entry, const char *text) +{ + GList *find; + + if (!text || !*text) + return; + + find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate); + if (find) + return; + entry->suggests = g_list_append(entry->suggests, g_strdup(text)); +} + +void gnt_entry_remove_suggest(GntEntry *entry, const char *text) +{ + GList *find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate); + if (find) + { + g_free(find->data); + entry->suggests = g_list_delete_link(entry->suggests, find); + } +} + Modified: branches/soc-2006-file-loggers/console/libgnt/gntentry.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntentry.h 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntentry.h 2006-08-13 17:38:25 UTC (rev 16738) @@ -50,6 +50,14 @@ int max; /* 0 means infinite */ gboolean masked; + + GList *history; /* History of the strings. User can use this by pressing ctrl+up/down */ + int histlength; /* How long can the history be? */ + + GList *suggests; /* List of suggestions */ + gboolean word; /* Are the suggestions for only a word, or for the whole thing? */ + gboolean always; /* Should the list of suggestions show at all times, or only on tab-press? */ + GntWidget *ddown; /* The dropdown with the suggested list */ }; struct _GnEntryClass @@ -70,7 +78,6 @@ void gnt_entry_set_max(GntEntry *entry, int max); -/* XXX: For now, call gnt_entry_clear before calling this */ void gnt_entry_set_text(GntEntry *entry, const char *text); void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag); @@ -81,6 +88,18 @@ void gnt_entry_set_masked(GntEntry *entry, gboolean set); +void gnt_entry_add_to_history(GntEntry *entry, const char *text); + +void gnt_entry_set_history_length(GntEntry *entry, int num); + +void gnt_entry_set_word_suggest(GntEntry *entry, gboolean word); + +void gnt_entry_set_always_suggest(GntEntry *entry, gboolean always); + +void gnt_entry_add_suggest(GntEntry *entry, const char *text); + +void gnt_entry_remove_suggest(GntEntry *entry, const char *text); + G_END_DECLS #endif /* GNT_ENTRY_H */ Copied: branches/soc-2006-file-loggers/console/libgnt/gntkeys.c (from rev 16737, trunk/console/libgnt/gntkeys.c) =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntkeys.c (rev 0) +++ branches/soc-2006-file-loggers/console/libgnt/gntkeys.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -0,0 +1,29 @@ +#include "gntkeys.h" + +#include <string.h> + +void gnt_keys_refine(char *text) +{ + if (text[0] == 27) + { + /* These are for urxvt */ + if (strcmp(text + 1, "Oa") == 0) + { + strcpy(text + 1, GNT_KEY_CTRL_UP); + } + else if (strcmp(text + 1, "Ob") == 0) + { + strcpy(text + 1, GNT_KEY_CTRL_DOWN); + } + } + else if ((unsigned char)text[0] == 195) + { + /* These for xterm */ + if (text[2] == 0) + { + text[0] = 27; + text[1] -= 64; + } + } +} + Modified: branches/soc-2006-file-loggers/console/libgnt/gntkeys.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntkeys.h 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntkeys.h 2006-08-13 17:38:25 UTC (rev 16738) @@ -9,6 +9,11 @@ #define GNT_KEY_UP "[A" #define GNT_KEY_DOWN "[B" +#define GNT_KEY_CTRL_UP "[1;5A" +#define GNT_KEY_CTRL_DOWN "[1;5B" +#define GNT_KEY_CTRL_RIGHT "[1;5C" +#define GNT_KEY_CTRL_LEFT "[1;5D" + #define GNT_KEY_PGUP "[5~" #define GNT_KEY_PGDOWN "[6~" @@ -17,4 +22,9 @@ #define GNT_KEY_BACKSPACE "\177" #define GNT_KEY_DEL "[3~" +/** + * This will do stuff with the terminal settings and stuff. + */ +void gnt_keys_refine(char *text); + #endif Modified: branches/soc-2006-file-loggers/console/libgnt/gntmain.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntmain.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntmain.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -13,6 +13,11 @@ #include <unistd.h> #include <string.h> +/** + * Notes: Interesting functions to look at: + * scr_dump, scr_init, scr_restore: for workspaces + */ + static int lock_focus_list; static GList *focus_list; @@ -52,6 +57,14 @@ static void draw_taskbar(); static void bring_on_top(GntWidget *widget); +static gboolean +update_screen(gpointer null) +{ + update_panels(); + doupdate(); + return TRUE; +} + void gnt_screen_take_focus(GntWidget *widget) { GntWidget *w = NULL; @@ -119,8 +132,7 @@ GntNode *nd = g_hash_table_lookup(nodes, window_list.window); top_panel(nd->panel); } - update_panels(); - doupdate(); + update_screen(NULL); draw_taskbar(); } @@ -437,6 +449,8 @@ dump_screen(); } + gnt_keys_refine(buffer); + if (mode == GNT_KP_MODE_NORMAL) { if (focus_list) @@ -499,6 +513,14 @@ { shift_window(focus_list->data, 1); } + else if (strcmp(buffer + 1, "l") == 0) + { + touchwin(stdscr); + touchwin(newscr); + wrefresh(newscr); + update_screen(NULL); + draw_taskbar(); + } } } } @@ -557,8 +579,7 @@ GntNode *node = g_hash_table_lookup(nodes, widget); gnt_widget_set_position(widget, x, y); move_panel(node->panel, y, x); - update_panels(); - doupdate(); + update_screen(NULL); } } else if (*buffer == '\r') @@ -656,6 +677,10 @@ ascii_only = TRUE; initscr(); + typeahead(-1); + noecho(); + curs_set(0); + gnt_init_colors(); gnt_init_styles(); @@ -671,7 +696,6 @@ nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - noecho(); refresh(); #if 0 mousemask(NCURSES_BUTTON_PRESSED | NCURSES_BUTTON_RELEASED | REPORT_MOUSE_POSITION, NULL); @@ -729,8 +753,7 @@ } } - update_panels(); - doupdate(); + update_screen(NULL); } void gnt_screen_release(GntWidget *widget) @@ -750,8 +773,7 @@ gnt_tree_remove(GNT_TREE(window_list.tree), widget); } - update_panels(); - doupdate(); + update_screen(NULL); } void gnt_screen_update(GntWidget *widget) @@ -779,8 +801,7 @@ top_panel(nd->panel); } - update_panels(); - doupdate(); + update_screen(NULL); } gboolean gnt_widget_has_focus(GntWidget *widget) @@ -844,8 +865,7 @@ gnt_widget_draw(widget); replace_panel(node->panel, widget->window); show_panel(node->panel); - update_panels(); - doupdate(); + update_screen(NULL); } } Modified: branches/soc-2006-file-loggers/console/libgnt/gnttree.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnttree.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gnttree.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -770,6 +770,15 @@ } } +void gnt_tree_remove_all(GntTree *tree) +{ + tree->root = NULL; + g_hash_table_remove_all(tree->hash); + g_list_free(tree->list); + tree->list = NULL; + tree->current = tree->top = tree->bottom = NULL; +} + int gnt_tree_get_selection_visible_line(GntTree *tree) { return get_distance(tree->top, tree->current) + Modified: branches/soc-2006-file-loggers/console/libgnt/gnttree.h =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gnttree.h 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gnttree.h 2006-08-13 17:38:25 UTC (rev 16738) @@ -85,6 +85,8 @@ void gnt_tree_remove(GntTree *tree, gpointer key); +void gnt_tree_remove_all(GntTree *tree); + /* Returns the visible line number of the selected row */ int gnt_tree_get_selection_visible_line(GntTree *tree); Modified: branches/soc-2006-file-loggers/console/libgnt/gntutils.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntutils.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntutils.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -8,23 +8,26 @@ /* XXX: ew ... everyone look away */ last = s; - while (*s) + if (s) { - if (*s == '\n' || *s == '\r') + while (*s) { - count++; - len = g_utf8_pointer_to_offset(last, s); - if (max < len) - max = len; - last = s + 1; + if (*s == '\n' || *s == '\r') + { + count++; + len = g_utf8_pointer_to_offset(last, s); + if (max < len) + max = len; + last = s + 1; + } + s++; } - s++; + + len = g_utf8_pointer_to_offset(last, s); + if (max < len) + max = len; } - len = g_utf8_pointer_to_offset(last, s); - if (max < len) - max = len; - if (height) *height = count; if (width) Modified: branches/soc-2006-file-loggers/console/libgnt/gntwidget.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/gntwidget.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/gntwidget.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -80,6 +80,23 @@ return TRUE; } +static gboolean +gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + gboolean signal_handled; + + signal_handled = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_handled); + continue_emission = !signal_handled; + + return continue_emission; +} + + static void gnt_widget_class_init(GntWidgetClass *klass) { @@ -194,7 +211,7 @@ G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, key_pressed), - NULL, NULL, + gnt_boolean_handled_accumulator, NULL, gnt_closure_marshal_BOOLEAN__STRING, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); DEBUG; Modified: branches/soc-2006-file-loggers/console/libgnt/test/tv.c =================================================================== --- branches/soc-2006-file-loggers/console/libgnt/test/tv.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/console/libgnt/test/tv.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -14,19 +14,24 @@ gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), gnt_entry_get_text(GNT_ENTRY(w)), GNT_TEXT_FLAG_HIGHLIGHT); + gnt_entry_add_to_history(GNT_ENTRY(w), gnt_entry_get_text(GNT_ENTRY(w))); gnt_text_view_next_line(GNT_TEXT_VIEW(view)); gnt_entry_clear(GNT_ENTRY(w)); if (gnt_text_view_get_lines_below(GNT_TEXT_VIEW(view)) <= 1) gnt_text_view_scroll(GNT_TEXT_VIEW(view), 0); + gnt_entry_remove_suggest(GNT_ENTRY(w), "acb"); return TRUE; } else if (key[0] == 27) { - if (strcmp(key+1, GNT_KEY_UP)) + if (strcmp(key+1, GNT_KEY_UP) == 0) + gnt_text_view_scroll(GNT_TEXT_VIEW(view), -1); + else if (strcmp(key+1, GNT_KEY_DOWN) == 0) gnt_text_view_scroll(GNT_TEXT_VIEW(view), 1); - else if (strcmp(key+1, GNT_KEY_DOWN)) - gnt_text_view_scroll(GNT_TEXT_VIEW(view), -1); + else + return FALSE; + return TRUE; } return FALSE; @@ -53,6 +58,15 @@ gnt_widget_set_name(entry, "entry"); GNT_WIDGET_SET_FLAGS(entry, GNT_WIDGET_CAN_TAKE_FOCUS); + gnt_entry_set_word_suggest(GNT_ENTRY(entry), TRUE); + gnt_entry_set_always_suggest(GNT_ENTRY(entry), FALSE); + gnt_entry_add_suggest(GNT_ENTRY(entry), "a"); + gnt_entry_add_suggest(GNT_ENTRY(entry), "ab"); + gnt_entry_add_suggest(GNT_ENTRY(entry), "abc"); + gnt_entry_add_suggest(GNT_ENTRY(entry), "abcd"); + gnt_entry_add_suggest(GNT_ENTRY(entry), "abcde"); + gnt_entry_add_suggest(GNT_ENTRY(entry), "acb"); + view = gnt_text_view_new(); gnt_widget_set_name(view, "view"); @@ -65,7 +79,8 @@ gnt_widget_show(hbox); - g_signal_connect(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), view); + gnt_entry_set_history_length(GNT_ENTRY(entry), -1); + g_signal_connect_after(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), view); #ifdef STANDALONE gnt_main(); Modified: branches/soc-2006-file-loggers/gaim.apspec.in =================================================================== --- branches/soc-2006-file-loggers/gaim.apspec.in 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/gaim.apspec.in 2006-08-13 17:38:25 UTC (rev 16738) @@ -15,7 +15,7 @@ [Description] Gaim allows you to talk to anyone using a variety of messaging protocols, including AIM (Oscar and TOC), ICQ, IRC, Yahoo!, MSN Messenger, Jabber, -Gadu-Gadu, Napster, and Zephyr. These protocols are implemented using a +Gadu-Gadu, and Zephyr. These protocols are implemented using a modular, easy to use design. To use a protocol, just add an account using the account editor. Modified: branches/soc-2006-file-loggers/plugins/ChangeLog.API =================================================================== --- branches/soc-2006-file-loggers/plugins/ChangeLog.API 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/plugins/ChangeLog.API 2006-08-13 17:38:25 UTC (rev 16738) @@ -114,6 +114,9 @@ * All network activity has been updated to use non-blocking sockets. This means that plugins must be updated to expect such a socket from gaim_proxy_connect() and gaim_network_listen*(). + * gaim_proxy_connect(): changed to return NULL on error and a void * + handle on success, and changed parameters. It is now possible to + cancel connection attempts. * gaim_gtk_create_imhtml(): Added sw_ret() parameter * gaim_account_get_log(): Added create parameter * GAIM_CMD_P_VERYHIGH is now GAIM_CMD_P_VERY_HIGH Modified: branches/soc-2006-file-loggers/plugins/log_reader.c =================================================================== --- branches/soc-2006-file-loggers/plugins/log_reader.c 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/plugins/log_reader.c 2006-08-13 17:38:25 UTC (rev 16738) @@ -796,6 +796,7 @@ time_t time_unix; struct tm *tm_new; char *timestamp; + char *tmp; const char *style; new_session_id = xmlnode_get_attrib(message, "SessionID"); @@ -906,7 +907,7 @@ !isalnum(*(from_name + alias_length))); - to_name_matches = (gaim_str_has_prefix( + to_name_matches = to_name && (gaim_str_has_prefix( to_name, alias) && !isalnum(*(to_name + alias_length))); @@ -988,16 +989,18 @@ style = xmlnode_get_attrib(text_node, "Style"); + tmp = xmlnode_get_data(text_node); if (style && *style) { text = g_string_append(text, "<span style=\""); text = g_string_append(text, style); text = g_string_append(text, "\">"); - text = g_string_append(text, xmlnode_get_data(text_node)); + text = g_string_append(text, tmp); text = g_string_append(text, "</span>\n"); } else { - text = g_string_append(text, xmlnode_get_data(text_node)); + text = g_string_append(text, tmp); text = g_string_append(text, "\n"); } + g_free(tmp); } data->text = text; @@ -1493,7 +1496,7 @@ g_string_append(formatted, "<span style=\"color: #ff0000;\">"); - + if (gaim_str_has_prefix(line, "Your previous message has not been sent. " "Reason: Maximum length exceeded.")) { @@ -1713,10 +1716,11 @@ char buffer[1024] = ""; DWORD size = (sizeof(buffer) - 1); DWORD type; + gboolean found = FALSE; path = NULL; /* TODO: Test this after removing the trailing "\\". */ - if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "Trillian.SkinZip\\shell\\Add\\command\\", + if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "Trillian.SkinZip\\shell\\Add\\command\\", 0, KEY_QUERY_VALUE, &hKey)) { if(ERROR_SUCCESS == RegQueryValueEx(hKey, "", NULL, &type, (LPBYTE)buffer, &size)) { @@ -1751,20 +1755,18 @@ if (!path) { char *folder = wgaim_get_special_folder(CSIDL_PROGRAM_FILES); - if (folder) + if (folder) { path = g_build_filename(folder, "Trillian", "users", "default", "talk.ini", NULL); g_free(folder); } } - gboolean found = FALSE; - if (path) { /* Read talk.ini file to find the log directory. */ GError *error = NULL; -#if 0 && GTK_CHECK_VERSION(2,6,0) /* FIXME: Not tested yet. */ +#if 0 && GLIB_CHECK_VERSION(2,6,0) /* FIXME: Not tested yet. */ GKeyFile *key_file; gaim_debug(GAIM_DEBUG_INFO, "Trillian talk.ini read", @@ -1791,9 +1793,9 @@ g_key_file_free(key_file); } -#else /* !GTK_CHECK_VERSION(2,6,0) */ - GError *error = NULL; +#else /* !GLIB_CHECK_VERSION(2,6,0) */ gsize length; + gchar *contents = NULL; gaim_debug(GAIM_DEBUG_INFO, "Trillian talk.ini read", "Reading %s\n", path); Modified: branches/soc-2006-file-loggers/po/ChangeLog =================================================================== --- branches/soc-2006-file-loggers/po/ChangeLog 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/po/ChangeLog 2006-08-13 17:38:25 UTC (rev 16738) @@ -23,13 +23,16 @@ * German translation updated (Bjoern Voigt) * German win32 translation updated (Bjoern Voigt) * Greek translation added (Bouklis Panos) + * Gujarati translation updated (Ankit Patel) * Hebrew translation updated (Shalom Craimer) * Hungarian translation updated (Gabor Kelemen) + * Italian translation updated (Claudio Satriano) * Japanese translation updated (Takeshi Aihana) * Kurdish translation added (Erdal Ronahi and Amed Ç. Jiyan) * Kurdish win32 installer translation added (Erdal Ronahi) * Lithuanian translation updated (Andrius Štikonas, Laurynas Biveinis) * Lithuanian win32 translation added (Laurynas Biveinis) + * Nepali translation added (Shyam Krishna Bal) * Persian translation added (Elnaz Sarbar, Meelad Zakaria) * Polish translation updated (Emil Nowak) * Portuguese translation updated (Duarte Henriques) Modified: branches/soc-2006-file-loggers/po/de.po =================================================================== --- branches/soc-2006-file-loggers/po/de.po 2006-08-13 16:01:52 UTC (rev 16737) +++ branches/soc-2006-file-loggers/po/de.po 2006-08-13 17:38:25 UTC (rev 16738) @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: Gaim\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-04-29 23:34+0200\n" -"PO-Revision-Date: 2006-04-29 23:33+0200\n" +"POT-Creation-Date: 2006-06-20 10:30+0200\n" +"PO-Revision-Date: 2006-06-20 10:38+0200\n" "Last-Translator: Björn Voigt <bj...@cs...>\n" "Language-Team: de <de...@li...>\n" "MIME-Version: 1.0\n" @@ -196,7 +196,7 @@ msgid "Right-click for more unread messages...\n" msgstr "Rechtsklicken für weitere ungelesene Nachrichten...\n" -#: ../plugins/docklet/docklet.c:157 ../src/gtkblist.c:3230 +#: ../plugins/docklet/docklet.c:157 ../src/gtkblist.c:3246 #, c-format msgid "%d unread message from %s\n" msgid_plural "%d unread messages from %s\n" @@ -208,10 +208,10 @@ msgstr "Ändere Status" #: ../plugins/docklet/docklet.c:435 ../src/gtkstatusbox.c:673 -#: ../src/protocols/gg/gg.c:996 ../src/protocols/jabber/buddy.c:1104 +#: ../src/protocols/gg/gg.c:996 ../src/protocols/jabber/buddy.c:1363 #: ../src/protocols/msn/state.c:29 ../src/protocols/msn/state.c:30 #: ../src/protocols/msn/state.c:37 ../src/protocols/msn/state.c:38 -#: ../src/protocols/novell/novell.c:2845 ../src/protocols/yahoo/yahoo.c:2733 +#: ../src/protocols/novell/novell.c:2843 ../src/protocols/yahoo/yahoo.c:2731 #: ../src/status.c:155 msgid "Available" msgstr "Verfügbar" @@ -222,25 +222,25 @@ #: ../plugins/docklet/docklet.c:439 ../src/gtkprefs.c:1774 #: ../src/gtkstatusbox.c:674 ../src/protocols/gg/gg.c:999 #: ../src/protocols/irc/irc.c:520 ../src/protocols/irc/msgs.c:223 -#: ../src/protocols/jabber/buddy.c:1108 ../src/protocols/novell/novell.c:2848 -#: ../src/protocols/oscar/oscar.c:719 ../src/protocols/oscar/oscar.c:4391 -#: ../src/protocols/oscar/oscar.c:5434 ../src/protocols/silc/buddy.c:1469 -#: ../src/protocols/yahoo/yahoo.c:3187 ../src/protocols/yahoo/yahoo.c:3260 +#: ../src/protocols/jabber/buddy.c:1367 ../src/protocols/novell/novell.c:2846 +#: ../src/protocols/oscar/oscar.c:719 ../src/protocols/oscar/oscar.c:4397 +#: ../src/protocols/oscar/oscar.c:5440 ../src/protocols/silc/buddy.c:1469 +#: ../src/protocols/yahoo/yahoo.c:3185 ../src/protocols/yahoo/yahoo.c:3258 #: ../src/status.c:158 msgid "Away" msgstr "Abwesend" #: ../plugins/docklet/docklet.c:443 ../src/gtkstatusbox.c:675 -#: ../src/protocols/oscar/oscar.c:723 ../src/protocols/yahoo/yahoo.c:2727 +#: ../src/protocols/oscar/oscar.c:723 ../src/protocols/yahoo/yahoo.c:2725 #: ../src/status.c:157 msgid "Invisible" msgstr "Unsichtbar" -#: ../plugins/docklet/docklet.c:447 ../src/gtkblist.c:2960 +#: ../plugins/docklet/docklet.c:447 ../src/gtkblist.c:2976 #: ../src/gtkstatusbox.c:676 ../src/protocols/gg/gg.c:993 -#: ../src/protocols/jabber/buddy.c:1102 ../src/protocols/novell/novell.c:2857 -#: ../src/protocols/oscar/oscar.c:785 ../src/protocols/oscar/oscar.c:5406 -#: ../src/protocols/yahoo/yahoo.c:2731 ../src/status.c:154 +#: ../src/protocols/jabber/buddy.c:1361 ../src/protocols/novell/novell.c:2855 +#: ../src/protocols/oscar/oscar.c:785 ../src/protocols/oscar/oscar.c:5412 +#: ../src/protocols/yahoo/yahoo.c:2729 ../src/status.c:154 msgid "Offline" msgstr "Offline" @@ -256,7 +256,7 @@ msgid "Show Buddy List" msgstr "Buddy-Liste anzeigen" -#: ../plugins/docklet/docklet.c:489 ../src/gtkconv.c:5626 +#: ../plugins/docklet/docklet.c:489 ../src/gtkconv.c:5675 msgid "Unread Messages" msgstr "Ungelesene Nachrichten" @@ -296,7 +296,7 @@ msgstr "_Sofortnachrichten:" #: ../plugins/docklet/docklet.c:684 ../plugins/docklet/docklet.c:692 -#: ../plugins/win32/winprefs/winprefs.c:424 ../src/gtkprefs.c:823 +#: ../plugins/win32/winprefs/winprefs.c:462 ../src/gtkprefs.c:823 #: ../src/gtkprefs.c:1764 ../src/gtkprefs.c:1778 msgid "Never" msgstr "Niemals" @@ -307,7 +307,7 @@ #: ../plugins/docklet/docklet.c:686 ../plugins/docklet/docklet.c:694 #: ../plugins/timestamp_format.c:39 ../plugins/timestamp_format.c:48 -#: ../plugins/win32/winprefs/winprefs.c:425 ../src/gtkprefs.c:825 +#: ../plugins/win32/winprefs/winprefs.c:463 ../src/gtkprefs.c:825 msgid "Always" msgstr "Immer" @@ -617,7 +617,7 @@ #. Business #: ../plugins/gevolution/add_buddy_dialog.c:131 #: ../plugins/gevolution/assoc-buddy.c:119 ../src/gtkplugin.c:587 -#: ../src/gtkroomlist.c:604 ../src/protocols/jabber/jabber.c:755 +#: ../src/gtkroomlist.c:604 ../src/protocols/jabber/jabber.c:759 #: ../src/protocols/msn/msn.c:1532 ../src/protocols/msn/msn.c:1585 #: ../src/protocols/msn/msn.c:1606 msgid "Name" @@ -627,10 +627,10 @@ msgid "Instant Messaging" msgstr "Sofortnachrichten" -#: ../plugins/gevolution/add_buddy_dialog.c:442 ../src/gtkblist.c:4526 +#: ../plugins/gevolution/add_buddy_dialog.c:442 ../src/gtkblist.c:4532 #: ../src/protocols/silc/buddy.c:736 ../src/protocols/silc/buddy.c:1030 #: ../src/protocols/silc/buddy.c:1075 ../src/protocols/silc/buddy.c:1174 -#: ../src/protocols/yahoo/yahoo.c:2976 +#: ../src/protocols/yahoo/yahoo.c:2974 msgid "Add Buddy" msgstr "Buddy hinzufügen" @@ -644,14 +644,14 @@ #. "Search" #: ../plugins/gevolution/add_buddy_dialog.c:468 #: ../plugins/gevolution/assoc-buddy.c:353 -#: ../src/protocols/jabber/buddy.c:1460 ../src/protocols/oscar/oscar.c:6014 -#: ../src/protocols/sametime/sametime.c:5531 +#: ../src/protocols/jabber/buddy.c:1720 ../src/protocols/oscar/oscar.c:6020 +#: ../src/protocols/sametime/sametime.c:5529 msgid "Search" msgstr "Suchen" #: ../plugins/gevolution/add_buddy_dialog.c:549 -#: ../plugins/gevolution/new_person_dialog.c:307 ../src/gtkblist.c:4610 -#: ../src/gtkblist.c:4974 +#: ../plugins/gevolution/new_person_dialog.c:307 ../src/gtkblist.c:4616 +#: ../src/gtkblist.c:4980 msgid "Group:" msgstr "Gruppe:" @@ -687,13 +687,13 @@ msgstr "_Assoziiere den Buddy" #: ../plugins/gevolution/eds-utils.c:73 ../plugins/gevolution/eds-utils.c:86 -#: ../src/protocols/jabber/jabber.c:1122 +#: ../src/protocols/jabber/jabber.c:1125 msgid "None" msgstr "Kein" #: ../plugins/gevolution/gevo-util.c:64 ../plugins/gevolution/gevolution.c:96 #: ../src/blist.c:516 ../src/blist.c:1278 ../src/blist.c:1505 -#: ../src/gtkblist.c:4419 ../src/protocols/jabber/roster.c:65 +#: ../src/gtkblist.c:4425 ../src/protocols/jabber/roster.c:66 msgid "Buddies" msgstr "Buddys" @@ -730,8 +730,8 @@ "Wählen Sie alle Konten, zu denen Buddys automatisch hinzugefügt werden " "sollen." -#: ../plugins/gevolution/gevolution.c:450 ../plugins/idle.c:150 -#: ../plugins/idle.c:186 ../src/gtknotify.c:399 ../src/gtkpounce.c:1262 +#: ../plugins/gevolution/gevolution.c:450 ../plugins/idle.c:153 +#: ../plugins/idle.c:189 ../src/gtknotify.c:399 ../src/gtkpounce.c:1255 msgid "Account" msgstr "Konto" @@ -768,7 +768,7 @@ msgstr "Kontotyp:" #: ../plugins/gevolution/new_person_dialog.c:295 ../src/gtkaccount.c:784 -#: ../src/gtkblist.c:4572 +#: ../src/gtkblist.c:4578 msgid "Screen name:" msgstr "Benutzername:" @@ -870,50 +870,50 @@ msgid "Iconifies the buddy list and your conversations when you go away." msgstr "Minimiert die Buddy-Liste und die Gesprächsfenster, wenn Sie weggehen." -#: ../plugins/idle.c:155 ../plugins/idle.c:213 +#: ../plugins/idle.c:158 ../plugins/idle.c:216 msgid "Minutes" msgstr "Minuten" #. This is a cultural reference. Dy'er Mak'er is a song by Led Zeppelin. #. If that doesn't translate well into your language, drop the 's before translating. -#: ../plugins/idle.c:162 ../plugins/idle.c:195 ../plugins/idle.c:220 -#: ../plugins/idle.c:312 +#: ../plugins/idle.c:165 ../plugins/idle.c:198 ../plugins/idle.c:223 +#: ../plugins/idle.c:315 msgid "I'dle Mak'er" msgstr "Untätigkeitsmarker" -#: ../plugins/idle.c:163 ../plugins/idle.c:252 +#: ../plugins/idle.c:166 ../plugins/idle.c:255 msgid "Set Account Idle Time" msgstr "Setze Konto-Untätigkeitszeit" -#: ../plugins/idle.c:166 ../plugins/idle.c:224 +#: ../plugins/idle.c:169 ../plugins/idle.c:227 msgid "_Set" msgstr "_Setzen" -#: ../plugins/idle.c:167 ../plugins/idle.c:200 ../plugins/idle.c:225 +#: ../plugins/idle.c:170 ../plugins/idle.c:203 ../plugins/idle.c:228 msgid "_Cancel" msgstr "A_bbrechen" -#: ../plugins/idle.c:180 +#: ../plugins/idle.c:183 msgid "None of your accounts are idle." msgstr "Keine ihrer Konten sind untätig." -#: ../... [truncated message content] |