[darcs-to-svn @ Save/restore window geometry]
authorXavier Claessens <xclaesse@src.gnome.org>
Thu, 26 Apr 2007 20:51:09 +0000 (20:51 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Thu, 26 Apr 2007 20:51:09 +0000 (20:51 +0000)
svn path=/trunk/; revision=6

libempathy-gtk/Makefile.am
libempathy-gtk/gossip-chat.c
libempathy-gtk/gossip-chat.h
libempathy-gtk/gossip-geometry.c [new file with mode: 0644]
libempathy-gtk/gossip-geometry.h [new file with mode: 0644]
libempathy/empathy-tp-chat.c
libempathy/empathy-tp-chat.h
libempathy/gossip-telepathy-group.c

index 1627156..dad681e 100644 (file)
@@ -24,6 +24,7 @@ libempathy_gtk_la_SOURCES =                                                   \
        gossip-chat-view.c                      gossip-chat-view.h              \
        gossip-chat-window.c                    gossip-chat-window.h            \
        gossip-private-chat.c                   gossip-private-chat.h           \
+       gossip-geometry.c                       gossip-geometry.h               \
        gossip-ui-utils.c                       gossip-ui-utils.h
 
 libempathy_gtk_la_LIBADD =                                                     \
index a60fc28..f67c029 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "gossip-chat.h"
 #include "gossip-chat-window.h"
-//#include "gossip-geometry.h"
+#include "gossip-geometry.h"
 #include "gossip-preferences.h"
 #include "gossip-spell.h"
 //#include "gossip-spell-dialog.h"
@@ -69,6 +69,7 @@ struct _GossipChatPriv {
        GtkTooltips      *tooltips;
        guint             composing_stop_timeout_id;
        gboolean          sensitive;
+       gchar            *id;
        /* Used to automatically shrink a window that has temporarily
         * grown due to long input. 
         */
@@ -1038,7 +1039,7 @@ gossip_chat_save_geometry (GossipChat *chat,
                           gint        w,
                           gint        h)
 {
-       //FIXME: gossip_geometry_save_for_chat (chat, x, y, w, h);
+       gossip_geometry_save (gossip_chat_get_id (chat), x, y, w, h);
 }
 
 void
@@ -1048,7 +1049,7 @@ gossip_chat_load_geometry (GossipChat *chat,
                           gint       *w,
                           gint       *h)
 {
-       //FIXME: gossip_geometry_load_for_chat (chat, x, y, w, h);
+       gossip_geometry_load (gossip_chat_get_id (chat), x, y, w, h);
 }
 
 void
@@ -1077,7 +1078,9 @@ gossip_chat_set_tp_chat (GossipChat    *chat,
                g_object_unref (priv->tp_chat);
        }
 
+       g_free (priv->id);
        priv->tp_chat = g_object_ref (tp_chat);
+       priv->id = g_strdup (empathy_tp_chat_get_id (tp_chat));
 
        g_signal_connect (tp_chat, "message-received",
                          G_CALLBACK (chat_message_received_cb),
@@ -1096,6 +1099,16 @@ gossip_chat_set_tp_chat (GossipChat    *chat,
        }
 }
 
+const gchar *
+gossip_chat_get_id (GossipChat *chat)
+{
+       GossipChatPriv *priv;
+
+       priv = GET_PRIV (chat);
+
+       return priv->id;
+}
+
 void
 gossip_chat_clear (GossipChat *chat)
 {
index cc0f584..3de788e 100644 (file)
@@ -126,6 +126,7 @@ void              gossip_chat_load_geometry         (GossipChat       *chat,
                                                     gint             *h);
 void              gossip_chat_set_tp_chat           (GossipChat       *chat,
                                                     EmpathyTpChat    *tp_chat);
+const gchar *     gossip_chat_get_id                (GossipChat       *chat);
 
 /* For spell checker dialog to correct the misspelled word. */
 gboolean          gossip_chat_get_is_command        (const gchar      *str);
diff --git a/libempathy-gtk/gossip-geometry.c b/libempathy-gtk/gossip-geometry.c
new file mode 100644 (file)
index 0000000..ad0bd8d
--- /dev/null
@@ -0,0 +1,186 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006-2007 Imendio AB
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Authors: Martyn Russell <martyn@imendio.com>
+ *          Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <gdk/gdk.h>
+
+#include <libempathy/gossip-debug.h>
+
+#include "gossip-geometry.h"
+
+#define DEBUG_DOMAIN "Geometry"
+
+#define GEOMETRY_DIR_CREATE_MODE  (S_IRUSR | S_IWUSR | S_IXUSR)
+#define GEOMETRY_FILE_CREATE_MODE (S_IRUSR | S_IWUSR)
+
+#define GEOMETRY_KEY_FILENAME     "geometry.ini"
+#define GEOMETRY_FORMAT           "%d,%d,%d,%d"
+#define GEOMETRY_GROUP_NAME       "geometry"
+
+static gchar *geometry_get_filename (void);
+
+static gchar *
+geometry_get_filename (void)
+{
+       gchar *dir;
+       gchar *filename;
+
+       dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
+       if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+               gossip_debug (DEBUG_DOMAIN, "Creating directory:'%s'", dir);
+               g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
+       }
+
+       filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
+       g_free (dir);
+
+       return filename;
+}
+
+void
+gossip_geometry_save (const gchar *name,
+                     gint         x,
+                     gint         y,
+                     gint         w,
+                     gint         h)
+{
+       GError      *error = NULL;
+       GKeyFile    *key_file;
+       gchar       *filename;
+       GdkScreen   *screen;
+       gint         max_width;
+       gint         max_height;
+       gchar       *content;
+       gsize        length;
+       gchar       *str;
+
+       gossip_debug (DEBUG_DOMAIN, "Saving window geometry: x:%d, y:%d, w:%d, h:%d\n",
+                     x, y, w, h);
+
+       screen = gdk_screen_get_default ();
+       max_width = gdk_screen_get_width (screen);
+       max_height = gdk_screen_get_height (screen);
+
+       w = CLAMP (w, 100, max_width);
+       h = CLAMP (h, 100, max_height);
+
+       x = CLAMP (x, 0, max_width - w);
+       y = CLAMP (y, 0, max_height - h);
+
+       str = g_strdup_printf (GEOMETRY_FORMAT, x, y, w, h);
+
+       key_file = g_key_file_new ();
+
+       filename = geometry_get_filename ();
+
+       g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
+       g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, name, str);
+
+       g_free (str);
+
+       content = g_key_file_to_data (key_file, &length, NULL);
+       if (!g_file_set_contents (filename, content, length, &error)) {
+               g_warning ("Couldn't save window geometry, error:%d->'%s'",
+                          error->code, error->message);
+               g_error_free (error);
+       }
+
+       g_free (content);
+       g_free (filename);
+       g_key_file_free (key_file);
+}
+
+void
+gossip_geometry_load (const gchar *name,
+                     gint        *x,
+                     gint        *y,
+                     gint        *w,
+                     gint        *h)
+{
+       GKeyFile    *key_file;
+       gchar       *filename;
+       gchar       *str = NULL;
+
+       if (x) {
+               *x = -1;
+       }
+
+       if (y) {
+               *y = -1;
+       }
+
+       if (w) {
+               *w = -1;
+       }
+
+       if (h) {
+               *h = -1;
+       }
+
+       key_file = g_key_file_new ();
+
+       filename = geometry_get_filename ();
+
+       if (g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL)) {
+               str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, name, NULL);
+       }
+
+       if (str) {
+               gint tmp_x, tmp_y, tmp_w, tmp_h;
+
+               sscanf (str, GEOMETRY_FORMAT, &tmp_x, &tmp_y, &tmp_w, &tmp_h);
+
+               if (x) {
+                       *x = tmp_x;
+               }
+
+               if (y) {
+                       *y = tmp_y;
+               }
+
+               if (w) {
+                       *w = tmp_w;
+               }
+
+               if (h) {
+                       *h = tmp_h;
+               }
+
+               g_free (str);
+       }
+
+       gossip_debug (DEBUG_DOMAIN, "Loading window geometry: x:%d, y:%d, w:%d, h:%d\n",
+                     x ? *x : -1,
+                     y ? *y : -1,
+                     w ? *w : -1,
+                     h ? *h : -1);
+
+       g_free (filename);
+       g_key_file_free (key_file);
+}
+
diff --git a/libempathy-gtk/gossip-geometry.h b/libempathy-gtk/gossip-geometry.h
new file mode 100644 (file)
index 0000000..24534fb
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006-2007 Imendio AB
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Authors: Martyn Russell <martyn@imendio.com>
+ *          Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __GOSSIP_GEOMETRY_H__
+#define __GOSSIP_GEOMETRY_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void gossip_geometry_save (const gchar *name,
+                          gint         x,
+                          gint         y,
+                          gint         w,
+                          gint         h);
+void gossip_geometry_load (const gchar *name,
+                          gint        *x,
+                          gint        *y,
+                          gint        *w,
+                          gint        *h);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_GEOMETRY_H__ */
index 9ddad86..36ac8a7 100644 (file)
@@ -25,6 +25,7 @@
 #include <libtelepathy/tp-helpers.h>
 #include <libtelepathy/tp-chan-type-text-gen.h>
 #include <libtelepathy/tp-chan-iface-chat-state-gen.h>
+#include <libtelepathy/tp-conn.h>
 
 #include "empathy-tp-chat.h"
 #include "empathy-contact-manager.h"
@@ -41,6 +42,9 @@
 
 struct _EmpathyTpChatPriv {
        EmpathyContactList *list;
+       McAccount          *account;
+       gchar              *id;
+
        TpChan             *tp_chan;
        DBusGProxy         *text_iface;
        DBusGProxy         *chat_state_iface;
@@ -160,6 +164,10 @@ tp_chat_finalize (GObject *object)
        if (priv->list) {
                g_object_unref (priv->list);
        }
+       if (priv->account) {
+               g_object_unref (priv->account);
+       }
+       g_free (priv->id);
 
        G_OBJECT_CLASS (empathy_tp_chat_parent_class)->finalize (object);
 }
@@ -181,6 +189,7 @@ empathy_tp_chat_new (McAccount *account,
        manager = empathy_session_get_contact_manager ();
        priv->list = empathy_contact_manager_get_list (manager, account);
        priv->tp_chan = g_object_ref (tp_chan);
+       priv->account = g_object_ref (account);
        g_object_ref (priv->list);
 
        priv->text_iface = tp_chan_get_interface (tp_chan,
@@ -360,6 +369,55 @@ empathy_tp_chat_send_state (EmpathyTpChat      *chat,
        }
 }
 
+const gchar *
+empathy_tp_chat_get_id (EmpathyTpChat *chat)
+{
+       EmpathyTpChatPriv  *priv;
+       MissionControl     *mc;
+       TpConn             *tp_conn;
+       GArray             *handles;
+       gchar             **names;
+       GError             *error = NULL;
+
+       g_return_val_if_fail (EMPATHY_IS_TP_CHAT (chat), NULL);
+
+       priv = GET_PRIV (chat);
+
+       if (priv->id) {
+               return priv->id;
+       }
+
+       mc = empathy_session_get_mission_control ();
+       tp_conn = mission_control_get_connection (mc, priv->account, NULL);
+       handles = g_array_new (FALSE, FALSE, sizeof (guint));
+       g_array_append_val (handles, priv->tp_chan->handle);
+
+       if (!tp_conn_inspect_handles (DBUS_G_PROXY (tp_conn),
+                                     priv->tp_chan->handle_type,
+                                     handles,
+                                     &names,
+                                     &error)) {
+               gossip_debug (DEBUG_DOMAIN, 
+                             "Couldn't get id: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+               g_array_free (handles, TRUE);
+               g_object_unref (tp_conn);
+               
+               return NULL;
+       }
+
+       /* A handle name is unique only for a specific account */
+       priv->id = g_strdup_printf ("%s/%s",
+                                   mc_account_get_unique_name (priv->account),
+                                   *names);
+
+       g_strfreev (names);
+       g_object_unref (tp_conn);
+
+       return priv->id;
+}
+
 static void
 tp_chat_destroy_cb (TpChan        *text_chan,
                    EmpathyTpChat *chat)
index 6a10561..5737fce 100644 (file)
@@ -71,6 +71,7 @@ void           empathy_tp_chat_send             (EmpathyTpChat      *chat,
                                                 GossipMessage      *message);
 void           empathy_tp_chat_send_state       (EmpathyTpChat      *chat,
                                                 EmpathyTpChatState  state);
+const gchar *  empathy_tp_chat_get_id           (EmpathyTpChat      *chat);
 
 G_END_DECLS
 
index 4b04ac4..3f9998c 100644 (file)
@@ -418,7 +418,7 @@ gossip_telepathy_group_get_name (GossipTelepathyGroup *group)
                return NULL;
        }
 
-       group_handles = g_array_new (FALSE, FALSE, sizeof (gint));
+       group_handles = g_array_new (FALSE, FALSE, sizeof (guint));
        g_array_append_val (group_handles, channel_handle);
        if (!tp_conn_inspect_handles (DBUS_G_PROXY (priv->tp_conn),
                                      handle_type,