[gitg] Implemented better uri parsing and panel activating
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg] Implemented better uri parsing and panel activating
- Date: Sun, 6 Jun 2010 21:18:58 +0000 (UTC)
commit 89922aeb0378ef5b145a0d92d2df3945139c3e51
Author: Jesse van den Kieboom <jessevdk gnome org>
Date: Sun Jun 6 23:18:50 2010 +0200
Implemented better uri parsing and panel activating
gitg/Makefile.am | 4 +
gitg/gitg-activatable.c | 48 +++++++++
gitg/gitg-activatable.h | 33 +++++++
gitg/gitg-revision-changes-panel.c | 108 +++++++++++++++++++++-
gitg/gitg-revision-details-panel.c | 7 ++
gitg/gitg-revision-files-panel.c | 7 ++
gitg/gitg-revision-panel.c | 15 +++
gitg/gitg-revision-panel.h | 2 +
gitg/gitg-uri.c | 103 ++++++++++++++++++++
gitg/gitg-uri.h | 17 ++++
gitg/gitg-window.c | 185 +++++++++++++++++++++++-------------
gitg/gitg-window.h | 3 +
gitg/gitg.c | 34 +++++++-
13 files changed, 499 insertions(+), 67 deletions(-)
---
diff --git a/gitg/Makefile.am b/gitg/Makefile.am
index b063236..7ffb604 100644
--- a/gitg/Makefile.am
+++ b/gitg/Makefile.am
@@ -12,6 +12,7 @@ AM_CPPFLAGS = \
-DGITG_LOCALEDIR=\""$(datadir)/locale"\"
NOINST_H_FILES = \
+ gitg-activatable.h \
gitg-branch-actions.h \
gitg-cell-renderer-path.h \
gitg-commit-view.h \
@@ -30,6 +31,7 @@ NOINST_H_FILES = \
gitg-revision-changes-panel.h \
gitg-settings.h \
gitg-stat-view.h \
+ gitg-uri.h \
gitg-utils.h \
gitg-window.h \
gseal-gtk-compat.h
@@ -37,6 +39,7 @@ NOINST_H_FILES = \
gitg_SOURCES = \
$(BUILT_SOURCES) \
gitg.c \
+ gitg-activatable.c \
gitg-branch-actions.c \
gitg-cell-renderer-path.c \
gitg-commit-view.c \
@@ -55,6 +58,7 @@ gitg_SOURCES = \
gitg-revision-changes-panel.c \
gitg-settings.c \
gitg-stat-view.c \
+ gitg-uri.c \
gitg-utils.c \
gitg-window.c \
$(NOINST_H_FILES)
diff --git a/gitg/gitg-activatable.c b/gitg/gitg-activatable.c
new file mode 100644
index 0000000..644aaee
--- /dev/null
+++ b/gitg/gitg-activatable.c
@@ -0,0 +1,48 @@
+#include "gitg-activatable.h"
+
+G_DEFINE_INTERFACE (GitgActivatable, gitg_activatable, G_TYPE_INVALID)
+
+/* Default implementation */
+static gchar *
+gitg_activatable_get_id_default (GitgActivatable *panel)
+{
+ g_return_val_if_reached (NULL);
+}
+
+static gboolean
+gitg_activatable_activate_default (GitgActivatable *panel,
+ gchar const *cmd)
+{
+ return FALSE;
+}
+
+static void
+gitg_activatable_default_init (GitgActivatableInterface *iface)
+{
+ static gboolean initialized = FALSE;
+
+ iface->get_id = gitg_activatable_get_id_default;
+ iface->activate = gitg_activatable_activate_default;
+
+ if (!initialized)
+ {
+ initialized = TRUE;
+ }
+}
+
+gchar *
+gitg_activatable_get_id (GitgActivatable *panel)
+{
+ g_return_val_if_fail (GITG_IS_ACTIVATABLE (panel), NULL);
+
+ return GITG_ACTIVATABLE_GET_INTERFACE (panel)->get_id (panel);
+}
+
+gboolean
+gitg_activatable_activate (GitgActivatable *panel,
+ gchar const *action)
+{
+ g_return_val_if_fail (GITG_IS_ACTIVATABLE (panel), FALSE);
+
+ return GITG_ACTIVATABLE_GET_INTERFACE (panel)->activate (panel, action);
+}
diff --git a/gitg/gitg-activatable.h b/gitg/gitg-activatable.h
new file mode 100644
index 0000000..d5cd62a
--- /dev/null
+++ b/gitg/gitg-activatable.h
@@ -0,0 +1,33 @@
+#ifndef __GITG_ACTIVATABLE_H__
+#define __GITG_ACTIVATABLE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GITG_TYPE_ACTIVATABLE (gitg_activatable_get_type ())
+#define GITG_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_ACTIVATABLE, GitgActivatable))
+#define GITG_IS_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_ACTIVATABLE))
+#define GITG_ACTIVATABLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GITG_TYPE_ACTIVATABLE, GitgActivatableInterface))
+
+typedef struct _GitgActivatable GitgActivatable;
+typedef struct _GitgActivatableInterface GitgActivatableInterface;
+
+struct _GitgActivatableInterface
+{
+ GTypeInterface parent;
+
+ gchar *(*get_id) (GitgActivatable *panel);
+ gboolean (*activate) (GitgActivatable *panel,
+ gchar const *cmd);
+};
+
+GType gitg_activatable_get_type (void) G_GNUC_CONST;
+
+gchar *gitg_activatable_get_id (GitgActivatable *panel);
+gboolean gitg_activatable_activate (GitgActivatable *panel,
+ gchar const *action);
+
+G_END_DECLS
+
+#endif /* __GITG_ACTIVATABLE_H__ */
diff --git a/gitg/gitg-revision-changes-panel.c b/gitg/gitg-revision-changes-panel.c
index 681adaa..bf58635 100644
--- a/gitg/gitg-revision-changes-panel.c
+++ b/gitg/gitg-revision-changes-panel.c
@@ -13,6 +13,7 @@
#include <glib/gi18n.h>
#include "gitg-revision-panel.h"
+#include "gitg-activatable.h"
#define GITG_REVISION_CHANGES_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_REVISION_CHANGES_PANEL, GitgRevisionChangesPanelPrivate))
@@ -31,6 +32,8 @@ struct _GitgRevisionChangesPanelPrivate
GitgRepository *repository;
GitgRevision *revision;
GSList *cached_headers;
+
+ gchar *selection;
};
typedef enum
@@ -60,6 +63,8 @@ typedef struct
} DiffFile;
static void gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface);
+static void gitg_activatable_iface_init (GitgActivatableInterface *iface);
+
static void on_header_added (GitgDiffView *view, GitgDiffIter *iter, GitgRevisionChangesPanel *self);
static void on_diff_files_selection_changed (GtkTreeSelection *selection, GitgRevisionChangesPanel *self);
@@ -68,7 +73,9 @@ G_DEFINE_TYPE_EXTENDED (GitgRevisionChangesPanel,
G_TYPE_OBJECT,
0,
G_IMPLEMENT_INTERFACE (GITG_TYPE_REVISION_PANEL,
- gitg_revision_panel_iface_init));
+ gitg_revision_panel_iface_init);
+ G_IMPLEMENT_INTERFACE (GITG_TYPE_ACTIVATABLE,
+ gitg_activatable_iface_init));
static void set_revision (GitgRevisionChangesPanel *panel,
GitgRepository *repository,
@@ -271,6 +278,24 @@ gitg_revision_panel_get_label_impl (GitgRevisionPanel *panel)
return g_strdup (_("Changes"));
}
+static gchar *
+revision_panel_get_id (void)
+{
+ return g_strdup ("changes");
+}
+
+static gchar *
+gitg_revision_panel_get_id_impl (GitgRevisionPanel *panel)
+{
+ return revision_panel_get_id ();
+}
+
+static gchar *
+gitg_activatable_get_id_impl (GitgActivatable *activatable)
+{
+ return revision_panel_get_id ();
+}
+
static void
initialize_ui (GitgRevisionChangesPanel *changes_panel)
{
@@ -385,15 +410,81 @@ gitg_revision_panel_get_panel_impl (GitgRevisionPanel *panel)
return ret;
}
+static gboolean
+select_diff_file (GitgRevisionChangesPanel *changes_panel,
+ gchar const *filename)
+{
+ GtkTreeModel *store;
+ GtkTreeIter iter;
+
+ store = gtk_tree_view_get_model (changes_panel->priv->diff_files);
+
+ if (!gtk_tree_model_get_iter_first (store, &iter))
+ {
+ return FALSE;
+ }
+
+ do
+ {
+ DiffFile *file;
+
+ gtk_tree_model_get (store, &iter, 0, &file, -1);
+
+ if (g_strcmp0 (file->filename, filename) == 0)
+ {
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (changes_panel->priv->diff_files);
+
+ gtk_tree_selection_unselect_all (selection);
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ diff_file_unref (file);
+ return TRUE;
+ }
+
+ diff_file_unref (file);
+ } while (gtk_tree_model_iter_next (store, &iter));
+
+ return FALSE;
+}
+
+static gboolean
+gitg_activatable_activate_impl (GitgActivatable *activatable,
+ gchar const *action)
+{
+ GitgRevisionChangesPanel *changes_panel;
+
+ changes_panel = GITG_REVISION_CHANGES_PANEL (activatable);
+
+ if (select_diff_file (changes_panel, action))
+ {
+ return TRUE;
+ }
+
+ g_free (changes_panel->priv->selection);
+ changes_panel->priv->selection = g_strdup (action);
+
+ return TRUE;
+}
+
static void
gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface)
{
+ iface->get_id = gitg_revision_panel_get_id_impl;
iface->update = gitg_revision_panel_update_impl;
iface->get_label = gitg_revision_panel_get_label_impl;
iface->get_panel = gitg_revision_panel_get_panel_impl;
}
static void
+gitg_activatable_iface_init (GitgActivatableInterface *iface)
+{
+ iface->get_id = gitg_activatable_get_id_impl;
+ iface->activate = gitg_activatable_activate_impl;
+}
+
+static void
free_cached_header (gpointer header)
{
g_slice_free (CachedHeader, header);
@@ -444,6 +535,13 @@ gitg_revision_changes_panel_dispose (GObject *object)
if (changes_panel->priv->builder)
{
g_object_unref (changes_panel->priv->builder);
+ changes_panel->priv->builder = NULL;
+ }
+
+ if (changes_panel->priv->selection)
+ {
+ g_free (changes_panel->priv->selection);
+ changes_panel->priv->selection = NULL;
}
G_OBJECT_CLASS (gitg_revision_changes_panel_parent_class)->dispose (object);
@@ -611,6 +709,14 @@ on_diff_files_end_loading (GitgRunner *runner,
{
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET(self->priv->diff_files)),
NULL);
+
+ if (self->priv->selection)
+ {
+ select_diff_file (self, self->priv->selection);
+
+ g_free (self->priv->selection);
+ self->priv->selection = NULL;
+ }
}
static gboolean
diff --git a/gitg/gitg-revision-details-panel.c b/gitg/gitg-revision-details-panel.c
index 982d78e..0d0eb5f 100644
--- a/gitg/gitg-revision-details-panel.c
+++ b/gitg/gitg-revision-details-panel.c
@@ -101,6 +101,12 @@ gitg_revision_panel_update_impl (GitgRevisionPanel *panel,
}
static gchar *
+gitg_revision_panel_get_id_impl (GitgRevisionPanel *panel)
+{
+ return g_strdup ("details");
+}
+
+static gchar *
gitg_revision_panel_get_label_impl (GitgRevisionPanel *panel)
{
return g_strdup (_("Details"));
@@ -162,6 +168,7 @@ gitg_revision_panel_get_panel_impl (GitgRevisionPanel *panel)
static void
gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface)
{
+ iface->get_id = gitg_revision_panel_get_id_impl;
iface->update = gitg_revision_panel_update_impl;
iface->get_label = gitg_revision_panel_get_label_impl;
iface->get_panel = gitg_revision_panel_get_panel_impl;
diff --git a/gitg/gitg-revision-files-panel.c b/gitg/gitg-revision-files-panel.c
index e195214..985cd1c 100644
--- a/gitg/gitg-revision-files-panel.c
+++ b/gitg/gitg-revision-files-panel.c
@@ -589,6 +589,12 @@ gitg_revision_panel_update_impl (GitgRevisionPanel *panel,
}
static gchar *
+gitg_revision_panel_get_id_impl (GitgRevisionPanel *panel)
+{
+ return g_strdup ("files");
+}
+
+static gchar *
gitg_revision_panel_get_label_impl (GitgRevisionPanel *panel)
{
return g_strdup (_("Files"));
@@ -620,6 +626,7 @@ gitg_revision_panel_get_panel_impl (GitgRevisionPanel *panel)
static void
gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface)
{
+ iface->get_id = gitg_revision_panel_get_id_impl;
iface->update = gitg_revision_panel_update_impl;
iface->get_label = gitg_revision_panel_get_label_impl;
iface->get_panel = gitg_revision_panel_get_panel_impl;
diff --git a/gitg/gitg-revision-panel.c b/gitg/gitg-revision-panel.c
index e575be2..4a0a5a2 100644
--- a/gitg/gitg-revision-panel.c
+++ b/gitg/gitg-revision-panel.c
@@ -4,6 +4,12 @@ G_DEFINE_INTERFACE (GitgRevisionPanel, gitg_revision_panel, G_TYPE_INVALID)
/* Default implementation */
static gchar *
+gitg_revision_panel_get_id_default (GitgRevisionPanel *panel)
+{
+ g_return_val_if_reached (NULL);
+}
+
+static gchar *
gitg_revision_panel_get_label_default (GitgRevisionPanel *panel)
{
g_return_val_if_reached (NULL);
@@ -28,6 +34,7 @@ gitg_revision_panel_default_init (GitgRevisionPanelInterface *iface)
{
static gboolean initialized = FALSE;
+ iface->get_id = gitg_revision_panel_get_id_default;
iface->get_label = gitg_revision_panel_get_label_default;
iface->get_panel = gitg_revision_panel_get_panel_default;
iface->update = gitg_revision_panel_update_default;
@@ -39,6 +46,14 @@ gitg_revision_panel_default_init (GitgRevisionPanelInterface *iface)
}
gchar *
+gitg_revision_panel_get_id (GitgRevisionPanel *panel)
+{
+ g_return_val_if_fail (GITG_IS_REVISION_PANEL (panel), NULL);
+
+ return GITG_REVISION_PANEL_GET_INTERFACE (panel)->get_id (panel);
+}
+
+gchar *
gitg_revision_panel_get_label (GitgRevisionPanel *panel)
{
g_return_val_if_fail (GITG_IS_REVISION_PANEL (panel), NULL);
diff --git a/gitg/gitg-revision-panel.h b/gitg/gitg-revision-panel.h
index d0a7c10..5a100a2 100644
--- a/gitg/gitg-revision-panel.h
+++ b/gitg/gitg-revision-panel.h
@@ -23,12 +23,14 @@ struct _GitgRevisionPanelInterface
GitgRevision *revision);
gchar *(*get_label) (GitgRevisionPanel *panel);
+ gchar *(*get_id) (GitgRevisionPanel *panel);
GtkWidget *(*get_panel) (GitgRevisionPanel *panel);
};
GType gitg_revision_panel_get_type (void) G_GNUC_CONST;
GtkWidget *gitg_revision_panel_get_panel (GitgRevisionPanel *panel);
+gchar *gitg_revision_panel_get_id (GitgRevisionPanel *panel);
gchar *gitg_revision_panel_get_label (GitgRevisionPanel *panel);
void gitg_revision_panel_update (GitgRevisionPanel *panel,
GitgRepository *repository,
diff --git a/gitg/gitg-uri.c b/gitg/gitg-uri.c
new file mode 100644
index 0000000..74717c3
--- /dev/null
+++ b/gitg/gitg-uri.c
@@ -0,0 +1,103 @@
+#include "gitg-uri.h"
+
+#include <string.h>
+
+gboolean
+gitg_uri_parse (gchar const *uri,
+ gchar **work_tree,
+ gchar **selection,
+ gchar **activatable,
+ gchar **action)
+{
+ gchar *selection_sep;
+ gchar *activatable_sep;
+ gchar *action_sep;
+ gchar *dupped;
+
+ if (uri == NULL)
+ {
+ return FALSE;
+ }
+
+ if (!g_str_has_prefix (uri, "gitg://"))
+ {
+ return FALSE;
+ }
+
+ if (work_tree)
+ {
+ *work_tree = NULL;
+ }
+
+ if (selection)
+ {
+ *selection = NULL;
+ }
+
+ if (activatable)
+ {
+ *activatable = NULL;
+ }
+
+ if (action)
+ {
+ *action = NULL;
+ }
+
+ dupped = g_strdup (uri + 7);
+ selection_sep = strchr (dupped, ':');
+
+ if (selection_sep)
+ {
+ *selection_sep = '\0';
+ }
+
+ if (work_tree)
+ {
+ *work_tree = g_strdup (dupped);
+ }
+
+ if (!selection_sep)
+ {
+ g_free (dupped);
+ return TRUE;
+ }
+
+ activatable_sep = strchr (selection_sep + 1, '/');
+
+ if (activatable_sep)
+ {
+ *activatable_sep = '\0';
+ }
+
+ if (selection)
+ {
+ *selection = g_strdup (selection_sep + 1);
+ }
+
+ if (!activatable_sep)
+ {
+ g_free (dupped);
+ return TRUE;
+ }
+
+ action_sep = strchr (activatable_sep + 1, '/');
+
+ if (action_sep)
+ {
+ *action_sep = '\0';
+ }
+
+ if (activatable)
+ {
+ *activatable = g_strdup (activatable_sep + 1);
+ }
+
+ if (action_sep && action)
+ {
+ *action = g_strdup (action_sep + 1);
+ }
+
+ g_free (dupped);
+ return TRUE;
+}
diff --git a/gitg/gitg-uri.h b/gitg/gitg-uri.h
new file mode 100644
index 0000000..90001c3
--- /dev/null
+++ b/gitg/gitg-uri.h
@@ -0,0 +1,17 @@
+#ifndef __GITG_URI_H__
+#define __GITG_URI_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gboolean gitg_uri_parse (gchar const *uri,
+ gchar **work_tree,
+ gchar **selection,
+ gchar **activatable,
+ gchar **action);
+
+G_END_DECLS
+
+#endif /* __GITG_URI_H__ */
+
diff --git a/gitg/gitg-window.c b/gitg/gitg-window.c
index 855d94a..1ac3b19 100644
--- a/gitg/gitg-window.c
+++ b/gitg/gitg-window.c
@@ -47,6 +47,8 @@
#include "gitg-revision-details-panel.h"
#include "gitg-revision-changes-panel.h"
#include "gitg-revision-files-panel.h"
+#include "gitg-activatable.h"
+#include "gitg-uri.h"
#define DYNAMIC_ACTION_DATA_KEY "GitgDynamicActionDataKey"
#define DYNAMIC_ACTION_DATA_REMOTE_KEY "GitgDynamicActionDataRemoteKey"
@@ -105,6 +107,7 @@ struct _GitgWindowPrivate
GitgHash select_on_load;
GSList *revision_panels;
+ GSList *activatables;
};
static gboolean on_tree_view_motion (GtkTreeView *treeview,
@@ -251,6 +254,12 @@ add_revision_panel (GitgWindow *window,
window->priv->revision_panels = g_slist_append (window->priv->revision_panels,
panel);
+ if (GITG_IS_ACTIVATABLE (panel))
+ {
+ window->priv->activatables = g_slist_append (window->priv->activatables,
+ g_object_ref (panel));
+ }
+
label = gitg_revision_panel_get_label (panel);
label_widget = gtk_label_new (label);
gtk_widget_show (label_widget);
@@ -478,7 +487,7 @@ build_search_entry (GitgWindow *window,
gtk_window_add_accel_group (GTK_WINDOW(window), group);
}
-static void
+static gboolean
goto_hash (GitgWindow *window,
gchar const *hash)
{
@@ -486,7 +495,7 @@ goto_hash (GitgWindow *window,
if (!gitg_repository_find_by_hash (window->priv->repository, hash, &iter))
{
- return;
+ return FALSE;
}
gtk_tree_selection_select_iter (gtk_tree_view_get_selection (window->priv->tree_view),
@@ -503,6 +512,8 @@ goto_hash (GitgWindow *window,
0.5,
0);
gtk_tree_path_free (path);
+
+ return TRUE;
}
static void
@@ -1068,7 +1079,12 @@ gitg_window_destroy (GtkObject *object)
g_slist_foreach (window->priv->revision_panels, (GFunc)g_object_unref, NULL);
g_slist_free (window->priv->revision_panels);
+ g_slist_foreach (window->priv->activatables, (GFunc)g_object_unref, NULL);
+ g_slist_free (window->priv->activatables);
+
window->priv->revision_panels = NULL;
+ window->priv->activatables = NULL;
+
window->priv->destroy_has_run = TRUE;
}
@@ -1230,65 +1246,6 @@ gitg_window_set_select_on_load (GitgWindow *window,
}
static gboolean
-parse_gitg_uri (GFile *file,
- GFile **work_tree,
- gchar **selection)
-{
- if (selection)
- {
- *selection = NULL;
- }
-
- if (work_tree)
- {
- *work_tree = NULL;
- }
-
- if (!g_file_has_uri_scheme (file, "gitg"))
- {
- return FALSE;
- }
-
- /* Extract path and sha information */
- gchar *uri = g_file_get_uri (file);
- gchar *fd = strrchr (uri, ':');
- gchar *sel = NULL;
- gint pos = 0;
-
- if (fd)
- {
- sel = strchr (fd, '/');
-
- if (sel)
- {
- *sel = '\0';
- sel += 1;
- }
-
- pos = fd - uri;
- }
-
- if (pos > 5 && strlen (uri) - pos - 1 <= 40)
- {
- /* It has a sha */
- *fd = '\0';
-
- if (selection)
- {
- *selection = g_strdup (fd + 1);
- }
- }
-
- if (work_tree)
- {
- *work_tree = g_file_new_for_path (uri + 7);
- }
-
- g_free (uri);
- return TRUE;
-}
-
-static gboolean
convert_setting_to_inactive_max (GValue const *setting,
GValue *value,
gpointer userdata)
@@ -1770,6 +1727,22 @@ update_sensitivity (GitgWindow *window)
gtk_action_group_set_sensitive (window->priv->repository_group, sens);
}
+gboolean
+gitg_window_select (GitgWindow *window,
+ gchar const *selection)
+{
+ g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
+
+ gitg_window_set_select_on_load (window, selection);
+
+ if (!window->priv->repository)
+ {
+ return FALSE;
+ }
+
+ return goto_hash (window, window->priv->select_on_load);
+}
+
static gboolean
load_repository (GitgWindow *window,
GFile *git_dir,
@@ -1845,6 +1818,67 @@ load_repository (GitgWindow *window,
return window->priv->repository != NULL;
}
+static gboolean
+activate_activatable (GitgWindow *window,
+ GitgActivatable *activatable,
+ gchar const *action)
+{
+ if (!gitg_activatable_activate (activatable, action))
+ {
+ return FALSE;
+ }
+
+ if (GITG_IS_REVISION_PANEL (activatable))
+ {
+ GtkWidget *page;
+ GitgRevisionPanel *panel;
+ gint nth;
+
+ panel = GITG_REVISION_PANEL (activatable);
+ page = gitg_revision_panel_get_panel (panel);
+
+ nth = gtk_notebook_page_num (window->priv->notebook_revision,
+ page);
+
+ if (nth >= 0)
+ {
+ gtk_notebook_set_current_page (window->priv->notebook_revision,
+ nth);
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+gitg_window_activate (GitgWindow *window,
+ gchar const *activatable,
+ gchar const *action)
+{
+ GSList *item;
+
+ g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
+ g_return_val_if_fail (activatable != NULL, FALSE);
+
+ for (item = window->priv->activatables; item; item = g_slist_next (item))
+ {
+ GitgActivatable *act = item->data;
+ gchar *id;
+ gboolean match;
+
+ id = gitg_activatable_get_id (act);
+ match = g_strcmp0 (activatable, id) == 0;
+ g_free (id);
+
+ if (match)
+ {
+ return activate_activatable (window, act, action);
+ }
+ }
+
+ return FALSE;
+}
+
gboolean
gitg_window_load_repository (GitgWindow *window,
GFile *git_dir,
@@ -1907,13 +1941,27 @@ load_repository_for_command_line (GitgWindow *window,
if (argc > 0)
{
- GFile *first_arg = g_file_new_for_commandline_arg (argv[0]);
- gchar *sel;
+ GFile *first_arg;
+ gchar *uri;
+ gchar *sel = NULL;
+ gchar *work_tree_path = NULL;
+ gchar *activatable = NULL;
+ gchar *action = NULL;
+
+ first_arg = g_file_new_for_commandline_arg (argv[0]);
+ uri = g_file_get_uri (first_arg);
- if (!parse_gitg_uri (first_arg, &work_tree, &sel))
+ if (!gitg_uri_parse (uri, &work_tree_path, &sel, &activatable, &action))
{
git_dir = find_dot_git (first_arg);
}
+ else
+ {
+ work_tree = g_file_new_for_path (work_tree_path);
+ }
+
+ g_free (uri);
+ g_object_unref (first_arg);
if (git_dir || (work_tree && g_file_query_exists (work_tree, NULL)))
{
@@ -1923,10 +1971,17 @@ load_repository_for_command_line (GitgWindow *window,
argc - 1,
argv + 1,
selection ? selection : sel);
+
+ if (ret)
+ {
+ gitg_window_activate (window, activatable, action);
+ }
}
g_free (sel);
- g_object_unref (first_arg);
+ g_free (activatable);
+ g_free (action);
+ g_free (work_tree_path);
}
if (!ret)
diff --git a/gitg/gitg-window.h b/gitg/gitg-window.h
index 8ae26ef..648f38e 100644
--- a/gitg/gitg-window.h
+++ b/gitg/gitg-window.h
@@ -76,6 +76,9 @@ void gitg_window_set_select_on_load (GitgWindow *window, gchar const *selection)
gboolean gitg_window_add_branch_action (GitgWindow *window, GitgRunner *runner);
+gboolean gitg_window_select (GitgWindow *window, gchar const *selection);
+gboolean gitg_window_activate (GitgWindow *window, gchar const *activatable, gchar const *action);
+
G_END_DECLS
#endif /* __GITG_WINDOW_H__ */
diff --git a/gitg/gitg.c b/gitg/gitg.c
index 7070595..9b925ba 100644
--- a/gitg/gitg.c
+++ b/gitg/gitg.c
@@ -34,6 +34,7 @@
#include "gitg-settings.h"
#include "gitg-dirs.h"
#include "gitg-utils.h"
+#include "gitg-uri.h"
static gboolean commit_mode = FALSE;
static gchar *select_sha1 = NULL;
@@ -173,15 +174,46 @@ link_button_uri_hook (GtkLinkButton *button,
GitgWindow *window)
{
GFile *file;
+ GitgRepository *repository;
file = g_file_new_for_uri (link_);
+ repository = gitg_window_get_repository (window);
if (!g_file_has_uri_scheme (file, "gitg"))
{
original_link_button_hook (button, link_, NULL);
}
- else
+ else if (repository)
{
+ gchar *work_tree_path;
+ gchar *selection;
+ gchar *activatable;
+ gchar *action;
+
+ if (gitg_uri_parse (link_, &work_tree_path, &selection, &activatable, &action))
+ {
+ GFile *wt;
+ GFile *work_tree;
+ gboolean equal;
+
+ wt = gitg_repository_get_work_tree (repository);
+ work_tree = g_file_new_for_path (work_tree_path);
+ equal = g_file_equal (wt, work_tree);
+
+ g_object_unref (wt);
+ g_object_unref (work_tree);
+
+ if (equal)
+ {
+ gitg_window_select (window, selection);
+ gitg_window_activate (window, activatable, action);
+ }
+
+ g_free (work_tree_path);
+ g_free (selection);
+ g_free (activatable);
+ g_free (action);
+ }
}
g_object_unref (file);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]