summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse van den Kieboom <jesse.vandenkieboom@epfl.ch>2012-04-14 11:46:39 (GMT)
committerJesse van den Kieboom <jesse.vandenkieboom@epfl.ch>2012-04-14 11:46:39 (GMT)
commita74c5661a672712ddb96bd70d51fadea23dda933 (patch)
treeb2fe3015c0eaab2b5871865a7b96012d27fafb93
parent79905400d781f97ddb75055c4936737e2f228f20 (diff)
downloadgitg-a74c5661a672712ddb96bd70d51fadea23dda933.zip
gitg-a74c5661a672712ddb96bd70d51fadea23dda933.tar.xz
Initial porting to vala
-rw-r--r--.gitmodules6
-rw-r--r--Makefile.am6
-rw-r--r--configure.ac172
-rw-r--r--data/gitg-glade.xml7
-rw-r--r--gitg/Makefile.am116
-rw-r--r--gitg/gitg-activatable.c70
-rw-r--r--gitg/gitg-activatable.h55
-rw-r--r--gitg/gitg-application.vala343
-rw-r--r--gitg/gitg-avatar-cache.c416
-rw-r--r--gitg/gitg-avatar-cache.h73
-rw-r--r--gitg/gitg-blame-renderer.c454
-rw-r--r--gitg/gitg-blame-renderer.h61
-rw-r--r--gitg/gitg-branch-actions.c2108
-rw-r--r--gitg/gitg-branch-actions.h53
-rw-r--r--gitg/gitg-cell-renderer-path.c639
-rw-r--r--gitg/gitg-cell-renderer-path.h69
-rw-r--r--gitg/gitg-commit-menu.ui54
-rw-r--r--gitg/gitg-commit-view.c3216
-rw-r--r--gitg/gitg-commit-view.h61
-rw-r--r--gitg/gitg-diff-line-renderer.c379
-rw-r--r--gitg/gitg-diff-line-renderer.h60
-rw-r--r--gitg/gitg-diff-view.c1633
-rw-r--r--gitg/gitg-diff-view.h106
-rw-r--r--gitg/gitg-dirs.c78
-rw-r--r--gitg/gitg-dirs.h32
-rw-r--r--gitg/gitg-dirs.vala64
-rw-r--r--gitg/gitg-dnd.c1090
-rw-r--r--gitg/gitg-dnd.h45
-rw-r--r--gitg/gitg-label-renderer.c349
-rw-r--r--gitg/gitg-label-renderer.h52
-rw-r--r--gitg/gitg-menus.xml168
-rw-r--r--gitg/gitg-new-branch.ui106
-rw-r--r--gitg/gitg-plugins-engine.vala67
-rw-r--r--gitg/gitg-preferences-dialog.c431
-rw-r--r--gitg/gitg-preferences-dialog.h57
-rw-r--r--gitg/gitg-preferences.ui810
-rw-r--r--gitg/gitg-repository-dialog.c906
-rw-r--r--gitg/gitg-repository-dialog.h62
-rw-r--r--gitg/gitg-repository.ui320
-rw-r--r--gitg/gitg-resource.vala62
-rw-r--r--gitg/gitg-revision-changes-panel.c1048
-rw-r--r--gitg/gitg-revision-changes-panel.h34
-rw-r--r--gitg/gitg-revision-changes-panel.ui79
-rw-r--r--gitg/gitg-revision-details-panel.c936
-rw-r--r--gitg/gitg-revision-details-panel.h58
-rw-r--r--gitg/gitg-revision-details-panel.ui270
-rw-r--r--gitg/gitg-revision-files-panel.c1524
-rw-r--r--gitg/gitg-revision-files-panel.h61
-rw-r--r--gitg/gitg-revision-files-panel.ui96
-rw-r--r--gitg/gitg-revision-panel.c124
-rw-r--r--gitg/gitg-revision-panel.h70
-rw-r--r--gitg/gitg-stat-view.c500
-rw-r--r--gitg/gitg-stat-view.h37
-rw-r--r--gitg/gitg-tag.ui158
-rw-r--r--gitg/gitg-ui.xml136
-rw-r--r--gitg/gitg-uri.c103
-rw-r--r--gitg/gitg-uri.h17
-rw-r--r--gitg/gitg-utils.c466
-rw-r--r--gitg/gitg-utils.h61
-rw-r--r--gitg/gitg-window.c3584
-rw-r--r--gitg/gitg-window.h87
-rw-r--r--gitg/gitg-window.ui576
-rw-r--r--gitg/gitg-window.vala457
-rw-r--r--gitg/gitg.c207
-rw-r--r--gitg/gitg.vala25
-rw-r--r--gitg/resources/gitg-resources.xml10
-rw-r--r--gitg/resources/ui/gitg-menus.ui33
-rw-r--r--gitg/resources/ui/gitg-window.ui138
-rw-r--r--gitg/resources/ui/style.css56
m---------libgit20
m---------libgit2-glib0
-rw-r--r--libgitg-ext/GitgExt.py38
-rw-r--r--libgitg-ext/Makefile.am100
-rw-r--r--libgitg-ext/gitg-ext-application.vala19
-rw-r--r--libgitg-ext/gitg-ext-message-bus.vala294
-rw-r--r--libgitg-ext/gitg-ext-message-id.vala75
-rw-r--r--libgitg-ext/gitg-ext-message.vala40
-rw-r--r--libgitg-ext/gitg-ext-navigation-tree-view.vala476
-rw-r--r--libgitg-ext/gitg-ext-navigation.vala22
-rw-r--r--libgitg-ext/gitg-ext-panel.vala18
-rw-r--r--libgitg-ext/gitg-ext-view.vala112
-rw-r--r--libgitg-ext/libgitg-ext-1.0.pc.in11
-rw-r--r--libgitg-ext/resources/resources.xml7
-rw-r--r--libgitg/Makefile.am131
-rw-r--r--libgitg/gitg-changed-file.c343
-rw-r--r--libgitg/gitg-changed-file.h90
-rw-r--r--libgitg/gitg-color.c139
-rw-r--r--libgitg/gitg-color.h51
-rw-r--r--libgitg/gitg-color.vala85
-rw-r--r--libgitg/gitg-command.c513
-rw-r--r--libgitg/gitg-command.h98
-rw-r--r--libgitg/gitg-commit-model.vala246
-rw-r--r--libgitg/gitg-commit.c1484
-rw-r--r--libgitg/gitg-commit.h108
-rw-r--r--libgitg/gitg-commit.vala90
-rw-r--r--libgitg/gitg-config.c529
-rw-r--r--libgitg/gitg-config.h75
-rw-r--r--libgitg/gitg-convert.c118
-rw-r--r--libgitg/gitg-convert.h34
-rw-r--r--libgitg/gitg-debug.c74
-rw-r--r--libgitg/gitg-debug.h59
-rw-r--r--libgitg/gitg-encodings.c570
-rw-r--r--libgitg/gitg-encodings.h72
-rw-r--r--libgitg/gitg-enum-types.c.template40
-rw-r--r--libgitg/gitg-enum-types.h.template28
-rw-r--r--libgitg/gitg-hash.c147
-rw-r--r--libgitg/gitg-hash.h50
-rw-r--r--libgitg/gitg-i18n.c52
-rw-r--r--libgitg/gitg-i18n.h71
-rw-r--r--libgitg/gitg-init.vala20
-rw-r--r--libgitg/gitg-io.c507
-rw-r--r--libgitg/gitg-io.h106
-rw-r--r--libgitg/gitg-lane.c86
-rw-r--r--libgitg/gitg-lane.h69
-rw-r--r--libgitg/gitg-lane.vala63
-rw-r--r--libgitg/gitg-lanes.c750
-rw-r--r--libgitg/gitg-lanes.h64
-rw-r--r--libgitg/gitg-lanes.vala466
-rw-r--r--libgitg/gitg-line-parser.c479
-rw-r--r--libgitg/gitg-line-parser.h67
-rw-r--r--libgitg/gitg-ref.c248
-rw-r--r--libgitg/gitg-ref.h86
-rw-r--r--libgitg/gitg-ref.vala275
-rw-r--r--libgitg/gitg-repository.c2081
-rw-r--r--libgitg/gitg-repository.h113
-rw-r--r--libgitg/gitg-repository.vala38
-rw-r--r--libgitg/gitg-revision.c413
-rw-r--r--libgitg/gitg-revision.h88
-rw-r--r--libgitg/gitg-runner.c646
-rw-r--r--libgitg/gitg-runner.h76
-rw-r--r--libgitg/gitg-shell.c1045
-rw-r--r--libgitg/gitg-shell.h159
-rw-r--r--libgitg/gitg-smart-charset-converter.c438
-rw-r--r--libgitg/gitg-smart-charset-converter.h76
-rw-r--r--libgitg/libgitg-1.0.pc.in11
-rw-r--r--plugins/Makefile.am3
-rw-r--r--plugins/dash/Makefile.am52
-rw-r--r--plugins/dash/dash.plugin11
-rw-r--r--plugins/dash/gitg-dash-navigation.vala93
-rw-r--r--plugins/dash/gitg-dash.vala285
-rw-r--r--plugins/dash/resources/resources.xml10
-rw-r--r--plugins/dash/resources/view-create.ui91
-rw-r--r--plugins/dash/resources/view-open.ui91
-rw-r--r--plugins/dash/resources/view-recent.ui173
-rw-r--r--plugins/history/Makefile.am52
-rw-r--r--plugins/history/gitg-history-navigation.vala123
-rw-r--r--plugins/history/gitg-history.vala103
-rw-r--r--plugins/history/history.plugin11
-rw-r--r--plugins/history/resources/resources.xml8
-rw-r--r--plugins/history/resources/view-history.ui13
-rw-r--r--vapi/config.vapi13
-rw-r--r--vapi/gobject-introspection-1.0.vapi31
152 files changed, 5167 insertions, 36782 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4798a69
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "libgit2"]
+ path = libgit2
+ url = https://github.com/libgit2/libgit2.git
+[submodule "libgit2-glib"]
+ path = libgit2-glib
+ url = git@github.com:nacho/libgit2-glib.git
diff --git a/Makefile.am b/Makefile.am
index 8a1de3d..9ef7d1b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,9 +4,6 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = libgitg gitg data po tests tools
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libgitg-1.0.pc
-
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
@@ -17,8 +14,7 @@ EXTRA_DIST = \
MAINTAINERS \
intltool-extract.in \
intltool-merge.in \
- intltool-update.in \
- libgitg-1.0.pc.in
+ intltool-update.in
MAINTAINERCLEANFILES = \
aclocal.m4 \
diff --git a/configure.ac b/configure.ac
index 2235010..7762563 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,7 @@ AC_INIT([gitg],
[http://live.gnome.org/Gitg])
AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_SRCDIR([gitg/gitg.c])
+AC_CONFIG_SRCDIR([gitg/gitg.vala])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
@@ -36,11 +36,15 @@ AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PATH_PROG(GZIP, gzip)
+AM_PATH_PYTHON
+AM_PROG_VALAC
+
AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums)
+AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources)
# Initialize libtool
LT_PREREQ([2.2])
-LT_INIT
+LT_INIT(disable-static)
# i18n stuff
IT_PROG_INTLTOOL([0.40.0])
@@ -49,47 +53,64 @@ AM_GNU_GETTEXT_VERSION([0.17])
AM_GNU_GETTEXT([external])
GETTEXT_PACKAGE=gitg
+
+dnl adl_RECURSIVE_EVAL(VALUE, RESULT)
+dnl =================================
+dnl Interpolate the VALUE in loop until it doesn't change,
+dnl and set the result to $RESULT.
+dnl WARNING: It's easy to get an infinite loop with some unsane input.
+AC_DEFUN([adl_RECURSIVE_EVAL],
+[_lcl_receval="$1"
+$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ _lcl_receval_old=''
+ while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
+ _lcl_receval_old="[$]_lcl_receval"
+ eval _lcl_receval="\"[$]_lcl_receval\""
+ done
+ echo "[$]_lcl_receval")`])
+
+adl_RECURSIVE_EVAL("$datadir/gitg", [GITG_DATADIR])
+adl_RECURSIVE_EVAL("$datadir/locale", [GITG_LOCALEDIR])
+adl_RECURSIVE_EVAL("$libdir/gitg", [GITG_LIBDIR])
+
AC_SUBST(GETTEXT_PACKAGE)
+
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
+AC_DEFINE_UNQUOTED(GITG_DATADIR,"$GITG_DATADIR", [data dir])
+AC_DEFINE_UNQUOTED(GITG_LOCALEDIR,"$GITG_LOCALEDIR", [locale dir])
+AC_DEFINE_UNQUOTED(GITG_LIBDIR,"$GITG_LIBDIR", [lib dir])
AC_CHECK_LIB([m], [sinf])
GLIB_REQUIRED_VERSION=2.26
GTK_REQUIRED_VERSION=3.0.0
GTKSOURCEVIEW_REQUIRED_VERSION=3.1.3
+INTROSPECTION_REQUIRED=0.10.1
-PKG_CHECK_MODULES(GITG, [
- gtk+-3.0 >= $GTK_REQUIRED_VERSION
+PKG_CHECK_MODULES(LIBGITG, [
gthread-2.0 >= $GLIB_REQUIRED_VERSION
glib-2.0 >= $GLIB_REQUIRED_VERSION
gobject-2.0 >= $GLIB_REQUIRED_VERSION
gmodule-2.0 >= $GLIB_REQUIRED_VERSION
gio-2.0 >= $GLIB_REQUIRED_VERSION
gio-unix-2.0 >= $GLIB_REQUIRED_VERSION
+ gobject-introspection-1.0 >= $INTROSPECTION_REQUIRED
+ libgit2-glib-1.0
])
-PKG_CHECK_MODULES(PACKAGE, [
- gtksourceview-3.0 >= $GTKSOURCEVIEW_REQUIRED_VERSION
- gsettings-desktop-schemas
-])
-
-AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
-
-GNOME_COMPILE_WARNINGS([maximum])
-
-if test "x$USE_MAINTAINER_MODE" = "xyes"; then
-PACKAGE_CFLAGS="$PACKAGE_CFLAGS -Wall -Werror -Wuninitialized -Wmissing-declarations"
-enable_deprecations="yes"
-fi
-
-
AC_ARG_ENABLE(deprecations,
[AS_HELP_STRING([--enable-deprecations],
[warn about deprecated usages [default=no]])],
[enable_deprecations=$enableval])
+if test "x$USE_MAINTAINER_MODE" = "xyes"; then
+LIBGITG_CFLAGS="$LIBGITG_CFLAGS -Wall -Werror -Wuninitialized -Wmissing-declarations"
+enable_deprecations="yes"
+fi
+
if test "$enable_deprecations" = "yes"; then
- DISABLE_DEPRECATED_CFLAGS="\
+ LIBGITG_CFLAGS="$LIBGITG_CFLAGS \
-DG_DISABLE_DEPRECATED \
-DGDK_DISABLE_DEPRECATED \
-DGTK_DISABLE_DEPRECATED \
@@ -98,36 +119,56 @@ if test "$enable_deprecations" = "yes"; then
-DGSEAL_ENABLE"
fi
-PACKAGE_LIBS="$PACKAGE_LIBS -lm"
-
-
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--disable-debug],
[disable debug information [default=yes]])],
[enable_debug=$enableval], [enable_debug=yes])
if test "x$enable_debug" = "xyes"; then
- PACKAGE_CFLAGS="$PACKAGE_CFLAGS -g"
+ LIBGITG_CFLAGS="$LIBGITG_CFLAGS -g -O0"
AC_DEFINE([ENABLE_DEBUG],[1],[Whether debugging support is enabled])
fi
-AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = "yes"])
+AC_SUBST(LIBGITG_CFLAGS)
+AC_SUBST(LIBGITG_LIBS)
+PKG_CHECK_MODULES(LIBGITG_GTK, [
+ gtk+-3.0 >= $GTK_REQUIRED_VERSION
+])
-AC_ARG_ENABLE(debug,
- [AS_HELP_STRING([--disable-debug],
- [disable debug information [default=yes]])],
- [enable_debug=$enableval], [enable_debug=yes])
+LIBGITG_GTK_CFLAGS="$LIBGITG_CFLAGS $LIBGITG_GTK_CFLAGS"
+LIBGITG_GTK_LIBS="$LIBGITG_LIBS $LIBGITG_GTK_LIBS"
-if test "x$enable_debug" = "xyes"; then
- PACKAGE_CFLAGS="$PACKAGE_CFLAGS -g"
- AC_DEFINE([ENABLE_DEBUG],[1],[Whether debugging support is enabled])
-fi
+AC_SUBST(LIBGITG_GTK_CFLAGS)
+AC_SUBST(LIBGITG_GTK_LIBS)
+
+LIBGITG_EXT_CFLAGS="$LIBGITG_GTK_CFLAGS"
+LIBGITG_EXT_LIBS="$LIBGITG_GTK_LIBS"
-AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = "yes"])
+AC_SUBST(LIBGITG_EXT_CFLAGS)
+AC_SUBST(LIBGITG_EXT_LIBS)
-AC_SUBST(PACKAGE_CFLAGS)
-AC_SUBST(PACKAGE_LIBS)
+LIBPEAS_REQUIRED_VERSION=1.2.0
+LIBPEAS_GTK_REQUIRED_VERSION=1.2.0
+
+PKG_CHECK_MODULES(GITG, [
+ gtksourceview-3.0 >= $GTKSOURCEVIEW_REQUIRED_VERSION
+ gsettings-desktop-schemas
+ libpeas-1.0 >= $LIBPEAS_REQUIRED_VERSION
+ libpeas-gtk-1.0 >= $LIBPEAS_GTK_REQUIRED_VERSION
+ gee-1.0
+])
+
+GITG_CFLAGS="$LIBGITG_GTK_CFLAGS $GITG_CFLAGS"
+GITG_LIBS="$LIBGITG_GTK_LIBS $GITG_LIBS -lm"
+
+AC_SUBST(GITG_CFLAGS)
+AC_SUBST(GITG_LIBS)
+
+GOBJECT_INTROSPECTION_REQUIRE($INTROSPECTION_REQUIRED)
+AC_SUBST(INTROSPECTION_REQUIRED)
+
+GNOME_COMPILE_WARNINGS([maximum])
GLIB_GSETTINGS
@@ -148,10 +189,63 @@ AS_IF([ test "$glade_catalog" = "yes" ],
AC_MSG_RESULT([$GLADE_CATALOG_DIR])
AC_SUBST(GLADE_CATALOG_DIR)])
+GITG_PLUGIN_DATADIR="$datadir/gitg/plugins"
+AC_SUBST(GITG_PLUGIN_DATADIR)
+
+GITG_PLUGIN_LIBDIR="$libdir/gitg/plugins"
+AC_SUBST(GITG_PLUGIN_LIBDIR)
+
+GITG_PLUGIN_CFLAGS="$GITG_CFLAGS"
+GITG_PLUGIN_LIBS="$GITG_LIBS"
+
+AC_SUBST(GITG_PLUGIN_CFLAGS)
+AC_SUBST(GITG_PLUGIN_LIBS)
+
+GITG_PLUGIN_LIBTOOL_FLAGS="-module -avoid-version"
+AC_SUBST(GITG_PLUGIN_LIBTOOL_FLAGS)
+
+GITG_PLUGIN_VALAFLAGS="--pkg GitgExt-1.0 \
+ --pkg Ggit-1.0 \
+ --pkg Gitg-1.0 \
+ --pkg gio-2.0 \
+ --pkg gtk+-3.0 \
+ --pkg libpeas-1.0 \
+ --pkg gee-1.0 \
+ --vapidir \$(top_srcdir)/vapi \
+ --pkg config"
+
+AC_SUBST(GITG_PLUGIN_VALAFLAGS)
+
+dnl ===========================================================================
+dnl Check for python
+dnl ===========================================================================
+PYGOBJECT_REQUIRED=3.0.0
+
+AC_ARG_ENABLE([python],
+ AS_HELP_STRING([--enable-python[=@<:@no/auto/yes@:>@]],[Build with python support]),
+ [enable_python=$enableval],
+ [enable_python="auto"])
+
+if test "x$enable_python" = "xauto"; then
+ PKG_CHECK_EXISTS([pygobject-3.0 >= $PYGOBJECT_REQUIRED],
+ [enable_python=yes],[enable_python=no])
+fi
+
+if test "x$enable_python" = "xyes"; then
+ PKG_CHECK_MODULES(PYTHON, [pygobject-3.0 >= $PYGOBJECT_REQUIRED])
+
+ pyoverridesdir=`$PYTHON -c "import gi; print(gi._overridesdir)"`
+ AC_SUBST(pyoverridesdir)
+fi
+
+AM_CONDITIONAL(ENABLE_PYTHON, test x"$enable_python" = "xyes")
+
AC_CONFIG_FILES([
Makefile
-libgitg-1.0.pc
libgitg/Makefile
+libgitg/libgitg-1.0.pc
+libgitg-ext/Makefile
+libgitg-ext/libgitg-ext-1.0.pc
gitg/Makefile
data/Makefile
data/gitg.desktop.in
@@ -160,6 +254,9 @@ data/org.gnome.gitg.gschema.xml.in
po/Makefile.in
tests/Makefile
tools/Makefile
+plugins/Makefile
+plugins/dash/Makefile
+plugins/history/Makefile
])
AC_OUTPUT
@@ -172,4 +269,5 @@ Configuration:
Compiler: ${CC}
Glade catalog: ${glade_catalog}
Debug enabled: ${enable_debug}
+ Python support: ${enable_python}
"
diff --git a/data/gitg-glade.xml b/data/gitg-glade.xml
index 0b22393..66664ce 100644
--- a/data/gitg-glade.xml
+++ b/data/gitg-glade.xml
@@ -3,15 +3,8 @@
<glade-catalog name="gitg">
<glade-widget-classes>
<glade-widget-class name="GitgWindow" title="GitgWindow" generic-name="gitgwindow" parent="GtkWindow"/>
- <glade-widget-class name="GitgCommitView" title="GitgCommitView" generic-name="gitgcommitview" parent="GtkVPaned"/>
- <glade-widget-class name="GitgCellRendererPath" title="GitgCellRendererPath" generic-name="gitgcellrendererpath" parent="GtkCellRendererText"/>
- <glade-widget-class name="GitgDiffView" title="GitgDiffView" generic-name="gitgdiffview" parent="GtkSourceView"/>
</glade-widget-classes>
<glade-widget-group name="gitg" title="gitg">
- <glade-widget-class-ref name="GitgWindow" />
- <glade-widget-class-ref name="GitgCommitView" />
- <glade-widget-class-ref name="GitgCellRendererPath" />
- <glade-widget-class-ref name="GitgDiffView" />
</glade-widget-group>
</glade-catalog>
diff --git a/gitg/Makefile.am b/gitg/Makefile.am
index e74617f..1b06d97 100644
--- a/gitg/Makefile.am
+++ b/gitg/Makefile.am
@@ -4,85 +4,67 @@ AM_CPPFLAGS = \
-I$(top_srcdir) \
-I$(srcdir) \
$(GITG_CFLAGS) \
- $(PACKAGE_CFLAGS) \
$(WARN_CFLAGS) \
- $(DISABLE_DEPRECATED_CFLAGS) \
-DDATADIR=\""$(datadir)"\" \
-DGITG_DATADIR=\""$(datadir)/gitg"\" \
-DGITG_LOCALEDIR=\""$(datadir)/locale"\"
-NOINST_H_FILES = \
- gitg-activatable.h \
- gitg-avatar-cache.h \
- gitg-blame-renderer.h \
- gitg-branch-actions.h \
- gitg-cell-renderer-path.h \
- gitg-commit-view.h \
- gitg-diff-line-renderer.h \
- gitg-diff-view.h \
- gitg-dirs.h \
- gitg-dnd.h \
- gitg-label-renderer.h \
- gitg-preferences-dialog.h \
- gitg-repository-dialog.h \
- gitg-revision-panel.h \
- gitg-revision-details-panel.h \
- gitg-revision-files-panel.h \
- gitg-revision-changes-panel.h \
- gitg-stat-view.h \
- gitg-uri.h \
- gitg-utils.h \
- gitg-window.h
+VALAFLAGS = \
+ --vapidir $(top_srcdir)/vapi \
+ --pkg config \
+ --pkg Ggit-1.0 \
+ --pkg Gitg-1.0 \
+ --pkg GitgExt-1.0 \
+ --pkg gtk+-3.0 \
+ --pkg gio-2.0 \
+ --pkg libpeas-1.0 \
+ --pkg gobject-introspection-1.0
-gitg_SOURCES = \
- $(BUILT_SOURCES) \
- gitg.c \
- gitg-activatable.c \
- gitg-avatar-cache.c \
- gitg-blame-renderer.c \
- gitg-branch-actions.c \
- gitg-cell-renderer-path.c \
- gitg-commit-view.c \
- gitg-diff-line-renderer.c \
- gitg-diff-view.c \
- gitg-dirs.c \
- gitg-dnd.c \
- gitg-label-renderer.c \
- gitg-preferences-dialog.c \
- gitg-repository-dialog.c \
- gitg-revision-panel.c \
- gitg-revision-details-panel.c \
- gitg-revision-files-panel.c \
- gitg-revision-changes-panel.c \
- gitg-stat-view.c \
- gitg-uri.c \
- gitg-utils.c \
- gitg-window.c \
- $(NOINST_H_FILES)
+VALASOURCES = \
+ gitg.vala \
+ gitg-dirs.vala \
+ gitg-window.vala \
+ gitg-resource.vala \
+ gitg-application.vala \
+ gitg-plugins-engine.vala
-gitg_LDADD = \
- $(GITG_LIBS) \
- $(PACKAGE_LIBS) \
- $(top_builddir)/libgitg/libgitg-1.0.la
+BUILT_SOURCES = \
+ gitg-resources.c \
+ gitg-resources.h
+
+gitg_SOURCES = \
+ $(VALASOURCES) \
+ gitg-resources.c
+
+gitg_LDADD = \
+ $(GITG_LIBS) \
+ $(PACKAGE_LIBS) \
+ $(top_builddir)/libgitg/libgitg-1.0.la \
+ $(top_builddir)/libgitg-ext/libgitg-ext-1.0.la
gitg_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
-uidir = $(datadir)/gitg/ui/
-ui_DATA = \
- gitg-window.ui \
- gitg-commit-menu.ui \
- gitg-ui.xml \
- gitg-menus.xml \
- gitg-preferences.ui \
- gitg-new-branch.ui \
- gitg-tag.ui \
- gitg-repository.ui \
- gitg-revision-details-panel.ui \
- gitg-revision-changes-panel.ui \
- gitg-revision-files-panel.ui
+gitg-resources.c: resources/gitg-resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/gitg-resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-source \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+gitg-resources.h: resources/gitg-resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/gitg-resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-header \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+# Ignore all warnings for vala code...
+gitg_CFLAGS = \
+ -w
EXTRA_DIST = \
- $(ui_DATA)
+ resources/gitg-resources.xml \
+ $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/gitg-resources.xml)
+
+CLEANFILES = \
+ $(VALASOURCES:.vala=.c) \
+ $(BUILT_SOURCES)
-include $(top_srcdir)/git.mk
diff --git a/gitg/gitg-activatable.c b/gitg/gitg-activatable.c
deleted file mode 100644
index 07fb267..0000000
--- a/gitg/gitg-activatable.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * gitg-activatable.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-activatable.h"
-
-G_DEFINE_INTERFACE(GitgActivatable, gitg_activatable, G_TYPE_OBJECT)
-
-/* 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
deleted file mode 100644
index e83189b..0000000
--- a/gitg/gitg-activatable.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * gitg-activatable.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#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-application.vala b/gitg/gitg-application.vala
new file mode 100644
index 0000000..d5a57ef
--- /dev/null
+++ b/gitg/gitg-application.vala
@@ -0,0 +1,343 @@
+namespace Gitg
+{
+
+public class Application : Gtk.Application
+{
+ public Application()
+ {
+ Object(application_id: "org.gnome.gitg",
+ flags: ApplicationFlags.HANDLES_OPEN |
+ ApplicationFlags.HANDLES_COMMAND_LINE |
+ ApplicationFlags.SEND_ENVIRONMENT);
+ }
+
+ private struct Options
+ {
+ public static bool quit = false;
+ public static bool commit = false;
+ public static string? select = null;
+ public static bool startup = false;
+ public static bool no_wd = false;
+ public static ApplicationCommandLine command_line;
+
+ public static const OptionEntry[] entries = {
+ {"version", 'v', OptionFlags.NO_ARG, OptionArg.CALLBACK,
+ (void *)show_version_and_quit, N_("Show the application's version"), null},
+ {"commit", 'c', 0, OptionArg.NONE,
+ ref commit, N_("Start gitg in commit mode"), null},
+ {"select", 's', 0, OptionArg.STRING, ref select, N_("Select commit after loading the repository"), null},
+ {"no-wd", 0, 0, OptionArg.NONE,
+ ref no_wd, N_("Do not try to load a repository from the current working directory"), null},
+ {null}
+ };
+ }
+
+ private static Options options;
+
+ private static void show_version_and_quit()
+ {
+ stdout.printf("%s %s\n",
+ Environment.get_application_name(),
+ Config.VERSION);
+
+ options.quit = true;
+ }
+
+ private void parse_command_line(ref unowned string[] argv) throws OptionError
+ {
+ var ctx = new OptionContext(_("- git repository viewer"));
+
+ ctx.add_main_entries(options.entries, Config.GETTEXT_PACKAGE);
+ ctx.add_group(Gtk.get_option_group(true));
+
+ ctx.parse(ref argv);
+ }
+
+ protected override bool local_command_line ([CCode (array_length = false, array_null_terminated = true)] ref unowned string[] arguments, out int exit_status)
+ {
+ // Parse command line just for -v and -h
+ string[] cp = arguments;
+ unowned string[] argv = cp;
+
+ try
+ {
+ parse_command_line(ref argv);
+ }
+ catch (Error e)
+ {
+ exit_status = 1;
+ return true;
+ }
+
+ if (options.quit)
+ {
+ exit_status = 0;
+ return true;
+ }
+
+ return base.local_command_line(ref arguments, out exit_status);
+ }
+
+ protected override int command_line(ApplicationCommandLine cmd)
+ {
+ string[] arguments = cmd.get_arguments();
+ unowned string[] argv = arguments;
+
+ try
+ {
+ parse_command_line(ref argv);
+ }
+ catch (Error e)
+ {
+ cmd.printerr("option parsing failed: %s\n", e.message);
+ return 1;
+ }
+
+ if (options.quit)
+ {
+ return 0;
+ }
+
+ options.command_line = cmd;
+
+ if (options.startup)
+ {
+ app_init();
+ options.startup = false;
+ }
+
+ if (argv.length > 1)
+ {
+ File[] files = new File[argv.length - 1];
+ files.length = 0;
+
+ foreach (string arg in argv[1:argv.length])
+ {
+ files += File.new_for_commandline_arg(arg);
+ }
+
+ open(files, open_hint_from_options);
+ }
+ else
+ {
+ activate();
+ }
+
+ return 1;
+ }
+
+ private string open_hint_from_options
+ {
+ get { return options.commit ? "commit" : "history"; }
+ }
+
+ private void on_app_new_window_activated()
+ {
+ }
+
+ private void on_app_help_activated()
+ {
+
+ }
+
+ private void on_app_about_activated()
+ {
+
+ }
+
+ private void on_app_quit_activated()
+ {
+ foreach (var window in get_windows())
+ {
+ window.destroy();
+ }
+ }
+
+ private static const ActionEntry[] app_entries = {
+ {"new", on_app_new_window_activated},
+ {"help", on_app_help_activated},
+ {"about", on_app_about_activated},
+ {"quit", on_app_quit_activated}
+ };
+
+ private void setup_menus()
+ {
+ add_action_entries(app_entries, this);
+
+ MenuModel[] menus = Resource.load_objects<MenuModel>("ui/gitg-menus.ui", {"app-menu", "win-menu"});
+
+ set_app_menu(menus[0]);
+ set_menubar(menus[1]);
+ }
+
+ protected override void startup()
+ {
+ options.startup = true;
+ base.startup();
+
+ setup_menus();
+ }
+
+ protected override void activate()
+ {
+ /* Application gets activated when no command line arguments have
+ * been provided. However, gitg does something special in the case
+ * that it has been launched from the terminal. It will try to open
+ * the cwd as a repository. However, when not launched from the terminal
+ * this is undesired, and a --no-wd allows gitg to be launched without
+ * the implicit working directory opening of the repository. In the
+ * end, the following happens:
+ *
+ * 1) --no-wd: present the window
+ * 2) Get cwd from the commandline: open
+ */
+ if (options.no_wd)
+ {
+ present_window();
+ }
+ else
+ {
+ // Otherwise open repository from current dir
+ string? wd = options.command_line.get_cwd();
+
+ open(new File[] { File.new_for_path(wd) },
+ open_hint_from_options);
+ }
+
+ base.activate();
+ }
+
+ private Window? find_window_for_file(File file)
+ {
+ foreach (Gtk.Window window in get_windows())
+ {
+ Window wnd = window as Window;
+
+ if (wnd.repository == null)
+ {
+ continue;
+ }
+
+ if (wnd.repository.get_location().equal(file))
+ {
+ return wnd;
+ }
+ }
+
+ return null;
+ }
+
+ protected override void open(File[] files, string hint)
+ {
+ if (files.length == 0)
+ {
+ return;
+ }
+
+ bool opened = false;
+
+ // Set of files are potential git repositories
+ foreach (File f in files)
+ {
+ // See if the repository is already open somewhere
+ Window? window = find_window_for_file(f);
+
+ if (window != null)
+ {
+ // Present the window with this repository open
+ window.present_with_time(Gdk.CURRENT_TIME);
+ continue;
+ }
+
+ File? resolved;
+
+ // Try to open a repository at this location
+ try
+ {
+ resolved = Ggit.Repository.discover(f);
+ }
+ catch { continue; }
+
+ // Open the repository
+ Repository? repo;
+
+ try
+ {
+ repo = new Repository(resolved, null);
+ }
+ catch { continue; }
+
+ // Finally, create a window for the repository
+ new_window(repo, hint);
+ opened = true;
+ }
+
+ if (!opened)
+ {
+ // still open a window
+ present_window();
+ }
+ }
+
+ private void app_init()
+ {
+ PluginsEngine.initialize();
+
+ Gtk.CssProvider? provider = Resource.load_css("style.css");
+
+ if (provider != null)
+ {
+ Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ provider,
+ 600);
+ }
+ }
+
+ private GitgExt.ViewAction get_action_from_hint(string? hint)
+ {
+ if (hint == null)
+ {
+ return GitgExt.ViewAction.DEFAULT;
+ }
+
+ EnumClass klass = (EnumClass)typeof(GitgExt.ViewAction).class_ref();
+ EnumValue? val = klass.get_value_by_nick(hint);
+
+ if (val == null)
+ {
+ return GitgExt.ViewAction.DEFAULT;
+ }
+ else
+ {
+ return (GitgExt.ViewAction)val.value;
+ }
+ }
+
+ private void new_window(Repository? repo = null, string? hint = null)
+ {
+
+ add_window(Window.create_new(this, repo, get_action_from_hint(hint)));
+ present_window();
+ }
+
+ private void present_window()
+ {
+ /* Present the first window in the windows registered on the
+ * application. If there are no windows, then create a new empty
+ * window.
+ */
+ unowned List<Gtk.Window> windows = get_windows();
+
+ if (windows == null)
+ {
+ new_window();
+ return;
+ }
+
+ windows.data.present_with_time(Gdk.CURRENT_TIME);
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/gitg/gitg-avatar-cache.c b/gitg/gitg-avatar-cache.c
deleted file mode 100644
index 9317052..0000000
--- a/gitg/gitg-avatar-cache.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2009 Mathias Hasselmann
- *
- * 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.
- */
-
-#include "config.h"
-#include "gitg-avatar-cache.h"
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <string.h>
-
-#define AVATAR_SIZE 80
-
-typedef struct _GitgAvatarCacheLoader GitgAvatarCacheLoader;
-struct _GitgAvatarCacheLoader
-{
- gchar *uri;
- GitgAvatarCache *cache;
- GCancellable *cancellable;
- gchar buffer[8192];
- GdkPixbufLoader *pixbuf_loader;
- GdkPixbuf *pixbuf;
- GSimpleAsyncResult *result;
-};
-
-struct _GitgAvatarCachePrivate
-{
- GChecksum *checksum;
- GHashTable *pixbuf_table;
- GList *active_loaders;
-};
-
-G_DEFINE_TYPE (GitgAvatarCache, gitg_avatar_cache, G_TYPE_OBJECT)
-
-static void
-avatar_cache_loader_finish (GitgAvatarCacheLoader *loader,
- GError *error)
-{
- if (loader->cache)
- {
- g_object_remove_weak_pointer (G_OBJECT (loader->cache),
- (gpointer) &loader->cache);
- }
-
- if (loader->cancellable)
- {
- g_cancellable_cancel (loader->cancellable);
- g_object_unref (loader->cancellable);
- }
-
- if (loader->pixbuf_loader)
- {
- gdk_pixbuf_loader_close (loader->pixbuf_loader, NULL);
- g_object_unref (loader->pixbuf_loader);
- }
-
- if (loader->pixbuf)
- {
- g_simple_async_result_set_op_res_gpointer (loader->result,
- g_object_ref (loader->pixbuf),
- g_object_unref);
- }
- else
- {
- g_simple_async_result_set_from_error (loader->result, error);
- g_error_free (error);
- }
-
- g_simple_async_result_complete_in_idle (loader->result);
- g_object_unref (loader->result);
-
- g_slice_free (GitgAvatarCacheLoader, loader);
-}
-
-static void
-gitg_avatar_cache_init (GitgAvatarCache *cache)
-{
- cache->priv = G_TYPE_INSTANCE_GET_PRIVATE (cache,
- GITG_TYPE_AVATAR_CACHE,
- GitgAvatarCachePrivate);
-
-}
-
-static void
-cached_pixbuf_unref0 (gpointer pixbuf)
-{
- if (pixbuf != NULL)
- {
- g_object_unref (pixbuf);
- }
-}
-
-static void
-avatar_cache_insert (GitgAvatarCache *cache,
- const gchar *uri,
- GdkPixbuf *pixbuf)
-{
- GitgAvatarCachePrivate *priv = cache->priv;
-
- if (!priv->pixbuf_table)
- {
- priv->pixbuf_table = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- cached_pixbuf_unref0);
- }
-
- if (pixbuf != NULL)
- {
- g_object_ref (pixbuf);
- }
-
- g_hash_table_insert (priv->pixbuf_table, g_strdup (uri), pixbuf);
-}
-
-static void
-avatar_cache_close_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GitgAvatarCacheLoader *loader = user_data;
- GInputStream *stream = G_INPUT_STREAM (object);
- GError *error = NULL;
-
- if (g_input_stream_close_finish (stream, result, &error) &&
- gdk_pixbuf_loader_close (loader->pixbuf_loader, &error))
- {
- loader->pixbuf = gdk_pixbuf_loader_get_pixbuf (loader->pixbuf_loader);
- avatar_cache_insert (loader->cache, loader->uri, loader->pixbuf);
- g_object_unref (loader->pixbuf_loader);
- loader->pixbuf_loader = NULL;
- }
-
- if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning ("%s: %s", G_STRFUNC, error->message);
-
- avatar_cache_loader_finish (loader, error);
-}
-
-static void
-avatar_cache_read_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GitgAvatarCacheLoader *loader = user_data;
- GInputStream *stream = G_INPUT_STREAM (object);
- GError *error = NULL;
- gssize len;
-
- len = g_input_stream_read_finish (stream, result, &error);
-
- if (len > 0)
- {
- if (gdk_pixbuf_loader_write (loader->pixbuf_loader, (gpointer)
- loader->buffer, len, &error))
- {
- g_input_stream_read_async (stream, loader->buffer,
- sizeof (loader->buffer),
- G_PRIORITY_DEFAULT,
- loader->cancellable,
- avatar_cache_read_cb,
- loader);
- }
- else
- {
- len = -2;
- }
- }
-
- if (0 >= len)
- {
- g_input_stream_close_async (stream, G_PRIORITY_DEFAULT,
- loader->cancellable,
- avatar_cache_close_cb, loader);
- }
-
- if (error)
- {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning ("%s: %s", G_STRFUNC, error->message);
-
- g_error_free (error);
- }
-}
-
-static void
-avatar_cache_open_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GitgAvatarCacheLoader *loader = user_data;
- GError *error = NULL;
- GFileInputStream *stream;
-
- stream = g_file_read_finish (G_FILE (object), result, &error);
-
- if (stream)
- {
- g_input_stream_read_async (G_INPUT_STREAM (stream),
- loader->buffer, sizeof (loader->buffer),
- G_PRIORITY_DEFAULT, loader->cancellable,
- avatar_cache_read_cb, loader);
- }
- else
- {
- /* At the moment G_IO_ERROR_NOT_FOUND is not being returned
- * and instead an error code of 404 is. This is HTTP's
- * File Not Found error.
- */
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) ||
- (error != NULL && error->code == 404))
- {
- avatar_cache_insert (loader->cache, loader->uri, NULL);
- }
- else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- }
-
- avatar_cache_loader_finish (loader, error);
- }
-}
-
-static void
-avatar_cache_finalize (GObject *object)
-{
- GitgAvatarCachePrivate *priv = GITG_AVATAR_CACHE (object)->priv;
- GitgAvatarCacheLoader *loader;
- GList *l;
-
- if (priv->pixbuf_table)
- {
- g_hash_table_unref (priv->pixbuf_table);
- }
-
- if (priv->checksum)
- {
- g_checksum_free (priv->checksum);
- }
-
- for (l = priv->active_loaders; l; l = g_list_delete_link (l, l))
- {
- loader = priv->active_loaders->data;
- g_cancellable_cancel (loader->cancellable);
- }
-
- G_OBJECT_CLASS (gitg_avatar_cache_parent_class)->finalize (object);
-}
-
-static void
-gitg_avatar_cache_class_init (GitgAvatarCacheClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- object_class->finalize = avatar_cache_finalize;
-
- g_type_class_add_private (class, sizeof (GitgAvatarCachePrivate));
-}
-
-GitgAvatarCache *
-gitg_avatar_cache_new (void)
-{
- return g_object_new (GITG_TYPE_AVATAR_CACHE, NULL);
-}
-
-void
-gitg_avatar_cache_load_uri_async (GitgAvatarCache *cache,
- const gchar *uri,
- gint io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GitgAvatarCachePrivate *priv;
- gboolean found = FALSE;
- GdkPixbuf *pixbuf = NULL;
- GSimpleAsyncResult *result;
- GitgAvatarCacheLoader *loader;
- GFile *file;
-
- g_return_if_fail (GITG_IS_AVATAR_CACHE (cache));
- g_return_if_fail (NULL != callback);
- g_return_if_fail (NULL != uri);
-
- priv = cache->priv;
-
- result = g_simple_async_result_new (G_OBJECT (cache), callback, user_data,
- gitg_avatar_cache_load_uri_async);
-
- if (priv->pixbuf_table)
- {
- found = g_hash_table_lookup_extended (priv->pixbuf_table, uri,
- NULL, (gpointer *) &pixbuf);
- }
-
- if (found)
- {
- if (pixbuf == NULL)
- {
- g_simple_async_result_set_error (result, G_IO_ERROR,
- G_IO_ERROR_NOT_FOUND,
- "Not Found");
- }
- else
- {
- g_simple_async_result_set_op_res_gpointer (result,
- g_object_ref (pixbuf),
- g_object_unref);
- }
-
- g_simple_async_result_complete_in_idle (result);
- }
- else
- {
- if (cancellable)
- {
- g_object_ref (cancellable);
- }
- else
- {
- cancellable = g_cancellable_new ();
- }
-
- loader = g_slice_new0 (GitgAvatarCacheLoader);
- loader->pixbuf_loader = gdk_pixbuf_loader_new ();
- loader->result = g_object_ref (result);
- loader->cancellable = cancellable;
- loader->uri = g_strdup (uri);
- loader->cache = cache;
-
- g_object_add_weak_pointer (G_OBJECT (loader->cache),
- (gpointer) &loader->cache);
-
- file = g_file_new_for_uri (uri);
-
- g_file_read_async (file, G_PRIORITY_DEFAULT, loader->cancellable,
- avatar_cache_open_cb, loader);
-
- g_object_unref (file);
- }
-
- g_object_unref (result);
-}
-
-GdkPixbuf *
-gitg_avatar_cache_load_finish (GitgAvatarCache *cache,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- gpointer source_tag;
-
- g_return_val_if_fail (GITG_IS_AVATAR_CACHE (cache), NULL);
- g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- source_tag = g_simple_async_result_get_source_tag (simple);
-
- g_return_val_if_fail (source_tag == gitg_avatar_cache_load_uri_async, NULL);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- return g_simple_async_result_get_op_res_gpointer (simple);
-}
-
-gchar *
-gitg_avatar_cache_get_gravatar_uri (GitgAvatarCache *cache,
- const gchar *gravatar_id)
-{
- GitgAvatarCachePrivate *priv;
- gssize len;
- gchar *lowercase_id;
-
- g_return_val_if_fail (GITG_IS_AVATAR_CACHE (cache), NULL);
- g_return_val_if_fail (NULL != gravatar_id, NULL);
-
- priv = cache->priv;
-
- if (priv->checksum)
- {
- g_checksum_reset (priv->checksum);
- }
- else
- {
- priv->checksum = g_checksum_new (G_CHECKSUM_MD5);
- }
-
- len = strlen (gravatar_id);
- lowercase_id = g_ascii_strdown (gravatar_id, len);
-
- g_checksum_update (priv->checksum, (gpointer) lowercase_id, len);
-
- g_free (lowercase_id);
-
- /* d=404 will return a File Not Found if the avatar does not exist */
- return g_strdup_printf ("http://www.gravatar.com/avatar/%s?d=404&s=%d",
- g_checksum_get_string (priv->checksum),
- AVATAR_SIZE);
-}
diff --git a/gitg/gitg-avatar-cache.h b/gitg/gitg-avatar-cache.h
deleted file mode 100644
index dca9a34..0000000
--- a/gitg/gitg-avatar-cache.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2009 Mathias Hasselmann
- *
- * 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.
- */
-
-#ifndef __GITG_AVATAR_CACHE_H__
-#define __GITG_AVATAR_CACHE_H__
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_AVATAR_CACHE (gitg_avatar_cache_get_type ())
-#define GITG_AVATAR_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_AVATAR_CACHE, GitgAvatarCache))
-#define GITG_AVATAR_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_AVATAR_CACHE, GitgAvatarCacheClass))
-#define GITG_IS_AVATAR_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_AVATAR_CACHE))
-#define GITG_IS_AVATAR_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_AVATAR_CACHE))
-#define GITG_AVATAR_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_AVATAR_CACHE, GitgAvatarCacheClass))
-
-typedef struct _GitgAvatarCache GitgAvatarCache;
-typedef struct _GitgAvatarCachePrivate GitgAvatarCachePrivate;
-typedef struct _GitgAvatarCacheClass GitgAvatarCacheClass;
-
-struct _GitgAvatarCache
-{
- GObject parent_instance;
-
- GitgAvatarCachePrivate *priv;
-};
-
-struct _GitgAvatarCacheClass
-{
- GObjectClass parent_class;
-};
-
-GType gitg_avatar_cache_get_type (void) G_GNUC_CONST;
-
-GitgAvatarCache *gitg_avatar_cache_new (void);
-
-void gitg_avatar_cache_load_uri_async (GitgAvatarCache *cache,
- const gchar *uri,
- gint io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-GdkPixbuf *gitg_avatar_cache_load_finish (GitgAvatarCache *cache,
- GAsyncResult *result,
- GError **error);
-
-gchar *gitg_avatar_cache_get_gravatar_uri (GitgAvatarCache *cache,
- const gchar *gravatar_id);
-
-G_END_DECLS
-
-#endif /* __GITG_AVATAR_CACHE_H__ */
-
diff --git a/gitg/gitg-blame-renderer.c b/gitg/gitg-blame-renderer.c
deleted file mode 100644
index 630c284..0000000
--- a/gitg/gitg-blame-renderer.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * gitg-blame-renderer.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2011 - Ignacio Casal Quinteiro
- *
- * 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.
- */
-
-#include "gitg-blame-renderer.h"
-
-#include <libgitg/gitg-revision.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#define GITG_BLAME_RENDERER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_BLAME_RENDERER, GitgBlameRendererPrivate))
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_REVISION,
- PROP_SHOW,
- PROP_GROUP_START
-};
-
-struct _GitgBlameRendererPrivate
-{
- GitgRevision *revision;
- gint max_line;
- gboolean group_start;
- gboolean show;
-
- gchar *line_number;
-
- PangoLayout *cached_layout;
- PangoLayout *line_layout;
-};
-
-G_DEFINE_TYPE (GitgBlameRenderer, gitg_blame_renderer, GTK_SOURCE_TYPE_GUTTER_RENDERER)
-
-static void
-gitg_blame_renderer_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgBlameRenderer *self = GITG_BLAME_RENDERER (object);
-
- switch (prop_id)
- {
- case PROP_REVISION:
- self->priv->revision = g_value_get_boxed (value);
- break;
- case PROP_SHOW:
- self->priv->show = g_value_get_boolean (value);
- break;
- case PROP_GROUP_START:
- self->priv->group_start = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_blame_renderer_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgBlameRenderer *self = GITG_BLAME_RENDERER (object);
-
- switch (prop_id)
- {
- case PROP_REVISION:
- g_value_set_boxed (value, self->priv->revision);
- break;
- case PROP_SHOW:
- g_value_set_boolean (value, self->priv->show);
- break;
- case PROP_GROUP_START:
- g_value_set_boolean (value, self->priv->group_start);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_blame_renderer_finalize (GObject *object)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (object);
-
- g_free (br->priv->line_number);
-
- G_OBJECT_CLASS (gitg_blame_renderer_parent_class)->finalize (object);
-}
-
-static void
-gitg_blame_renderer_begin (GtkSourceGutterRenderer *renderer,
- cairo_t *cr,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkTextIter *start,
- GtkTextIter *end)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (renderer);
-
- br->priv->cached_layout = gtk_widget_create_pango_layout (GTK_WIDGET (gtk_source_gutter_renderer_get_view (renderer)),
- NULL);
- br->priv->line_layout = gtk_widget_create_pango_layout (GTK_WIDGET (gtk_source_gutter_renderer_get_view (renderer)),
- NULL);
-}
-
-static void
-render_blame (GtkSourceGutterRenderer *renderer,
- cairo_t *ctx,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState renderer_state)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (renderer);
- gchar *text;
- PangoLayout *layout;
- GtkWidget *widget;
- GtkStyleContext *style_context;
- gchar *sha1;
- gchar short_sha1[9];
-
- widget = GTK_WIDGET (gtk_source_gutter_renderer_get_view (renderer));
- layout = br->priv->cached_layout;
-
- pango_layout_set_width (layout, -1);
-
- sha1 = gitg_revision_get_sha1 (br->priv->revision);
- strncpy (short_sha1, sha1, 8);
- short_sha1[8] = '\0';
- g_free (sha1);
-
- text = g_strdup_printf ("<b>%s</b> %s", short_sha1,
- gitg_revision_get_author (br->priv->revision));
-
- pango_layout_set_markup (layout, text, -1);
- g_free (text);
- style_context = gtk_widget_get_style_context (widget);
-
- if (br->priv->group_start)
- {
- GdkRGBA bg_color;
-
- gtk_style_context_get_background_color (style_context, GTK_STATE_INSENSITIVE, &bg_color);
- gdk_cairo_set_source_rgba (ctx, &bg_color);
-
- cairo_save (ctx);
- cairo_move_to (ctx, background_area->x, background_area->y);
- cairo_line_to (ctx, background_area->x + background_area->width,
- cell_area->y);
- cairo_stroke (ctx);
- cairo_restore (ctx);
- }
-
- gtk_render_layout (style_context,
- ctx,
- cell_area->x,
- cell_area->y,
- layout);
-}
-
-static void
-render_line (GtkSourceGutterRenderer *renderer,
- cairo_t *ctx,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState renderer_state)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (renderer);
- PangoLayout *layout;
- GtkWidget *widget;
- GtkStyleContext *style_context;
- gint width, height;
-
- widget = GTK_WIDGET (gtk_source_gutter_renderer_get_view (renderer));
- layout = br->priv->line_layout;
-
- pango_layout_set_markup (layout, br->priv->line_number, -1);
- pango_layout_get_size (layout, &width, &height);
-
- style_context = gtk_widget_get_style_context (widget);
-
- width /= PANGO_SCALE;
-
- gtk_render_layout (style_context,
- ctx,
- cell_area->x + cell_area->width - width - 5,
- cell_area->y,
- layout);
-}
-
-static void
-gitg_blame_renderer_draw (GtkSourceGutterRenderer *renderer,
- cairo_t *ctx,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState renderer_state)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (renderer);
-
- /* Chain up to draw background */
- GTK_SOURCE_GUTTER_RENDERER_CLASS (
- gitg_blame_renderer_parent_class)->draw (renderer,
- ctx,
- background_area,
- cell_area,
- start,
- end,
- renderer_state);
-
- if (br->priv->show && br->priv->revision != NULL)
- {
- render_blame (renderer,
- ctx,
- background_area,
- cell_area,
- start,
- end,
- renderer_state);
- }
-
- render_line (renderer,
- ctx,
- background_area,
- cell_area,
- start,
- end,
- renderer_state);
-}
-
-static void
-gitg_blame_renderer_end (GtkSourceGutterRenderer *renderer)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (renderer);
-
- g_object_unref (br->priv->cached_layout);
- br->priv->cached_layout = NULL;
-
- g_object_unref (br->priv->line_layout);
- br->priv->line_layout = NULL;
-}
-
-static void
-gutter_renderer_query_data (GtkSourceGutterRenderer *renderer,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState state)
-{
- GitgBlameRenderer *br = GITG_BLAME_RENDERER (renderer);
- gchar *text;
- gint line;
- gboolean current_line;
-
- line = gtk_text_iter_get_line (start) + 1;
-
- current_line = (state & GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR) &&
- gtk_text_view_get_cursor_visible (gtk_source_gutter_renderer_get_view (renderer));
-
- if (current_line)
- {
- text = g_strdup_printf ("<b>%d</b>", line);
- }
- else
- {
- text = g_strdup_printf ("%d", line);
- }
-
- g_free (br->priv->line_number);
- br->priv->line_number = text;
-}
-
-static void
-measure_text (GitgBlameRenderer *br,
- const gchar *markup,
- gint *width)
-{
- PangoLayout *layout;
- gint w;
- gint h;
- GtkSourceGutterRenderer *r;
- GtkTextView *view;
-
- r = GTK_SOURCE_GUTTER_RENDERER (br);
- view = gtk_source_gutter_renderer_get_view (r);
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), NULL);
-
- pango_layout_set_markup (layout,
- markup,
- -1);
-
- pango_layout_get_size (layout, &w, &h);
-
- if (width)
- {
- *width = w / PANGO_SCALE;
- }
-
- g_object_unref (layout);
-}
-
-static GtkTextBuffer *
-get_buffer (GitgBlameRenderer *renderer)
-{
- GtkTextView *view;
-
- view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (renderer));
-
- return gtk_text_view_get_buffer (view);
-}
-
-static void
-recalculate_size (GitgBlameRenderer *br)
-{
- GtkTextBuffer *buffer;
- gchar *markup;
- gint size;
- gchar *text;
- gint num, num_digits, i;
-
- buffer = get_buffer (br);
-
- num = gtk_text_buffer_get_line_count (buffer);
- num_digits = 0;
-
- while (num > 0)
- {
- num /= 10;
- ++num_digits;
- }
-
- num_digits = MAX (num_digits, 2);
-
- text = g_new (gchar, br->priv->max_line + num_digits + 1);
- for (i = 0; i < br->priv->max_line + num_digits; i++)
- {
- text[i] = '0';
- }
- text[br->priv->max_line + num_digits] = '\0';
-
- markup = g_strdup_printf ("<b>%s</b>", text);
- g_free (text);
-
- measure_text (br, markup, &size);
- g_free (markup);
-
- gtk_source_gutter_renderer_set_size (GTK_SOURCE_GUTTER_RENDERER (br),
- size);
-}
-
-static void
-update_num_digits (GitgBlameRenderer *renderer,
- gint max_line)
-{
- max_line = MAX (max_line, 2);
-
- if (max_line != renderer->priv->max_line)
- {
- renderer->priv->max_line = max_line;
- recalculate_size (renderer);
- }
-}
-
-static void
-gitg_blame_renderer_class_init (GitgBlameRendererClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkSourceGutterRendererClass *renderer_class = GTK_SOURCE_GUTTER_RENDERER_CLASS (klass);
-
- renderer_class->begin = gitg_blame_renderer_begin;
- renderer_class->draw = gitg_blame_renderer_draw;
- renderer_class->end= gitg_blame_renderer_end;
- renderer_class->query_data = gutter_renderer_query_data;
-
- object_class->set_property = gitg_blame_renderer_set_property;
- object_class->get_property = gitg_blame_renderer_get_property;
- object_class->finalize = gitg_blame_renderer_finalize;
-
- g_object_class_install_property (object_class,
- PROP_REVISION,
- g_param_spec_boxed ("revision",
- "Revision",
- "Revision",
- GITG_TYPE_REVISION,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_SHOW,
- g_param_spec_boolean ("show",
- "Show",
- "Show",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_GROUP_START,
- g_param_spec_boolean ("group-start",
- "Group Start",
- "Group start",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_type_class_add_private (object_class, sizeof (GitgBlameRendererPrivate));
-}
-
-static void
-gitg_blame_renderer_init (GitgBlameRenderer *self)
-{
- self->priv = GITG_BLAME_RENDERER_GET_PRIVATE (self);
-}
-
-GitgBlameRenderer *
-gitg_blame_renderer_new (void)
-{
- return g_object_new (GITG_TYPE_BLAME_RENDERER, NULL);
-}
-
-void
-gitg_blame_renderer_set_max_line_count (GitgBlameRenderer *renderer,
- gint max_line)
-{
- g_return_if_fail (GITG_IS_BLAME_RENDERER (renderer));
-
- update_num_digits (renderer, max_line);
-}
diff --git a/gitg/gitg-blame-renderer.h b/gitg/gitg-blame-renderer.h
deleted file mode 100644
index 412ac90..0000000
--- a/gitg/gitg-blame-renderer.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * gitg-blame-renderer.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2011 - Ignacio Casal Quinteiro
- *
- * 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.
- */
-
-#ifndef __GITG_BLAME_RENDERER_H__
-#define __GITG_BLAME_RENDERER_H__
-
-#include <gtksourceview/gtksourceview.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_BLAME_RENDERER (gitg_blame_renderer_get_type ())
-#define GITG_BLAME_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_BLAME_RENDERER, GitgBlameRenderer))
-#define GITG_BLAME_RENDERER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_BLAME_RENDERER, GitgBlameRenderer const))
-#define GITG_BLAME_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_BLAME_RENDERER, GitgBlameRendererClass))
-#define GITG_IS_BLAME_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_BLAME_RENDERER))
-#define GITG_IS_BLAME_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_BLAME_RENDERER))
-#define GITG_BLAME_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_BLAME_RENDERER, GitgBlameRendererClass))
-
-typedef struct _GitgBlameRenderer GitgBlameRenderer;
-typedef struct _GitgBlameRendererClass GitgBlameRendererClass;
-typedef struct _GitgBlameRendererPrivate GitgBlameRendererPrivate;
-
-struct _GitgBlameRenderer {
- GtkSourceGutterRenderer parent;
-
- GitgBlameRendererPrivate *priv;
-};
-
-struct _GitgBlameRendererClass {
- GtkSourceGutterRendererClass parent_class;
-};
-
-GType gitg_blame_renderer_get_type (void) G_GNUC_CONST;
-
-GitgBlameRenderer *gitg_blame_renderer_new (void);
-
-void gitg_blame_renderer_set_max_line_count (GitgBlameRenderer *renderer,
- gint max_line_count);
-
-G_END_DECLS
-
-#endif /* __GITG_BLAME_RENDERER_H__ */
diff --git a/gitg/gitg-branch-actions.c b/gitg/gitg-branch-actions.c
deleted file mode 100644
index 4281602..0000000
--- a/gitg/gitg-branch-actions.c
+++ /dev/null
@@ -1,2108 +0,0 @@
-/*
- * gitg-branch-actions.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <glib/gi18n.h>
-#include <libgitg/gitg-hash.h>
-#include <unistd.h>
-
-#include "gitg-branch-actions.h"
-
-typedef enum
-{
- GITG_PROGRESS_SUCCESS,
- GITG_PROGRESS_ERROR,
- GITG_PROGRESS_CANCELLED
-} GitgProgress;
-
-typedef void (*ProgressCallback) (GitgWindow *window, GitgProgress progress, gpointer data);
-
-typedef struct
-{
- GitgWindow *window;
- GitgShell *shell;
-
- ProgressCallback callback;
- gpointer callback_data;
-
- guint timeout_id;
-
- GtkDialog *dialog;
- GtkProgressBar *progress;
-} ProgressInfo;
-
-static void
-free_progress_info (ProgressInfo *info)
-{
- if (info->timeout_id)
- {
- g_source_remove (info->timeout_id);
- }
-
- gtk_widget_destroy (GTK_WIDGET (info->dialog));
-
- g_object_unref (info->shell);
- g_slice_free (ProgressInfo, info);
-}
-
-static gchar const **
-parse_valist (va_list ap)
-{
- gchar const *a;
- gchar const **ret;
- guint num = 0;
-
- ret = g_new (gchar const *, 1);
-
- while ( (a = va_arg (ap, gchar const *)) != NULL)
- {
- ret = g_realloc (ret, sizeof (gchar const *) * (++num + 1));
- ret[num - 1] = a;
- }
-
- ret[num] = NULL;
- return ret;
-}
-
-static void
-on_progress_end (GitgShell *shell, gboolean cancelled, ProgressInfo *info)
-{
- GitgProgress progress;
-
- if (cancelled)
- {
- progress = GITG_PROGRESS_CANCELLED;
- }
- else if (gitg_io_get_exit_status (GITG_IO (shell)) != 0)
- {
- progress = GITG_PROGRESS_ERROR;
- }
- else
- {
- progress = GITG_PROGRESS_SUCCESS;
- }
-
- GitgWindow *window = info->window;
- ProgressCallback callback = info->callback;
- gpointer data = info->callback_data;
- free_progress_info (info);
-
- callback (window, progress, data);
-}
-
-static void
-on_progress_response (GtkDialog *dialog, GtkResponseType response, ProgressInfo *info)
-{
- gitg_io_cancel (GITG_IO (info->shell));
-}
-
-static gboolean
-on_progress_timeout (ProgressInfo *info)
-{
- gtk_progress_bar_pulse (info->progress);
- return TRUE;
-}
-
-static GitgShell *
-run_progress (GitgWindow *window,
- gchar const *title,
- gchar const *message,
- ProgressCallback callback,
- gpointer callback_data,
- ...)
-{
- va_list ap;
-
- va_start (ap, callback_data);
-
- GitgShell *shell = gitg_shell_new (1000);
- gchar const **argv = parse_valist (ap);
-
- GitgCommand *cmd = gitg_command_newv (gitg_window_get_repository (window),
- (gchar const * const *)argv);
-
- if (!gitg_shell_run (shell, cmd, NULL))
- {
- g_free (argv);
- g_object_unref (shell);
-
- callback (window, GITG_PROGRESS_ERROR, callback_data);
-
- return NULL;
- }
-
- g_free (argv);
-
- // Create dialog to show progress
- GtkDialogFlags flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
- GtkWidget *dlg;
-
- dlg = gtk_message_dialog_new (GTK_WINDOW (window),
- flags,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CANCEL,
- "%s",
- title);
-
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
- "%s",
- message);
-
- gtk_window_set_title (GTK_WINDOW (dlg), _ ("gitg"));
-
- // Add progress bar
- GtkWidget *area = gtk_dialog_get_content_area (GTK_DIALOG (dlg));
- GtkWidget *progress = gtk_progress_bar_new ();
- gtk_widget_show (progress);
-
- gtk_box_pack_start (GTK_BOX (area), progress, FALSE, FALSE, 0);
-
- gtk_widget_show (dlg);
-
- ProgressInfo *info = g_slice_new0 (ProgressInfo);
-
- info->dialog = GTK_DIALOG (dlg);
- info->progress = GTK_PROGRESS_BAR (progress);
- info->callback = callback;
- info->callback_data = callback_data;
- info->window = window;
- info->shell = g_object_ref (shell);
-
- info->timeout_id = g_timeout_add (100, (GSourceFunc)on_progress_timeout, info);
-
- g_signal_connect (dlg, "response", G_CALLBACK (on_progress_response), info);
- g_signal_connect (shell, "end", G_CALLBACK (on_progress_end), info);
-
- return shell;
-}
-
-static gint
-message_dialog (GitgWindow *window,
- GtkMessageType type,
- gchar const *primary,
- gchar const *secondary,
- gchar const *accept,
- ...)
-{
- GtkWidget *dlg;
- va_list ap;
-
- va_start (ap, accept);
- gchar *prim = g_strdup_vprintf (primary, ap);
- va_end (ap);
-
- GtkDialogFlags flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
- dlg = gtk_message_dialog_new (GTK_WINDOW (window),
- flags,
- type,
- GTK_BUTTONS_NONE,
- "%s",
- prim);
-
- g_free (prim);
-
- gtk_window_set_title (GTK_WINDOW (dlg), _ ("gitg"));
-
- if (secondary)
- {
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
- "%s",
- secondary);
- }
-
- GtkWidget *button;
-
- button = gtk_button_new_from_stock (accept ? GTK_STOCK_CANCEL : GTK_STOCK_OK);
- gtk_widget_show (button);
-
- gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
- button,
- accept ? GTK_RESPONSE_CANCEL : GTK_RESPONSE_ACCEPT);
-
- if (accept)
- {
- button = gtk_button_new_with_label (accept);
- gtk_widget_show (button);
-
- GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_OK,
- GTK_ICON_SIZE_BUTTON);
- gtk_widget_show (image);
-
- gtk_button_set_image (GTK_BUTTON (button), image);
- gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
- button,
- GTK_RESPONSE_ACCEPT);
- }
-
- gint ret = gtk_dialog_run (GTK_DIALOG (dlg));
- gtk_widget_destroy (dlg);
-
- return ret;
-}
-
-static GitgShell *
-remove_local_branch (GitgWindow *window,
- GitgRef *ref)
-{
- gchar const *name = gitg_ref_get_shortname (ref);
- GitgRepository *repository = gitg_window_get_repository (window);
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "branch",
- "-d",
- name,
- NULL),
- NULL))
- {
- gint ret = message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Branch <%s> could not be removed"),
- _ ("This usually means that the branch is not fully merged in HEAD. Do you want to forcefully remove the branch?"),
- _ ("Force remove"),
- name);
-
- if (ret == GTK_RESPONSE_ACCEPT)
- {
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "branch",
- "-D",
- name,
- NULL),
- NULL))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Branch <%s> could not be forcefully removed"),
- NULL,
- NULL,
- name);
-
- return NULL;
- }
- else
- {
- gitg_repository_reload (repository);
- return NULL;
- }
- }
- }
- else
- {
- gitg_repository_reload (repository);
-
- return NULL;
- }
-
- return NULL;
-}
-
-static void
-on_remove_remote_result (GitgWindow *window, GitgProgress progress, gpointer data)
-{
- GitgRef *ref = (GitgRef *)data;
-
- if (progress == GITG_PROGRESS_ERROR)
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to remove remote branch <%s>."),
- NULL,
- NULL,
- gitg_ref_get_shortname (ref));
- }
- else if (progress == GITG_PROGRESS_SUCCESS)
- {
- gitg_repository_reload (gitg_window_get_repository (window));
- }
-
- gitg_ref_free (ref);
-}
-
-static GitgShell *
-remove_remote_branch (GitgWindow *window,
- GitgRef *ref)
-{
- gchar const *name = gitg_ref_get_shortname (ref);
-
- gint r = message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Are you sure you want to remove the remote branch <%s>?"),
- _ ("This permanently removes the remote branch."),
- _ ("Remove remote branch"),
- name);
-
- if (r != GTK_RESPONSE_ACCEPT)
- {
- return NULL;
- }
-
- gchar const *local = gitg_ref_get_local_name (ref);
- gchar *rm = g_strconcat (":", local, NULL);
-
- GitgShell *ret;
- gchar *message = g_strdup_printf ("Removing remote branch `%s'", name);
-
- ret = run_progress (window,
- _ ("Remove branch"),
- message,
- on_remove_remote_result,
- gitg_ref_copy (ref),
- "push",
- gitg_ref_get_prefix (ref),
- rm,
- NULL);
- g_free (message);
-
- return ret;
-}
-
-static gchar *
-get_stash_refspec (GitgRepository *repository, GitgRef *stash)
-{
- gchar **out;
- gboolean retval;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (repository,
- "log",
- "--no-color",
- "--pretty=oneline",
- "-g",
- "refs/stash",
- NULL),
- FALSE,
- &out,
- NULL);
-
- gchar **ptr = out;
- gchar *sha1 = gitg_hash_hash_to_sha1_new (gitg_ref_get_hash (stash));
- gchar *ret = NULL;
-
- while (retval && ptr && *ptr)
- {
- if (g_str_has_prefix (*ptr, sha1))
- {
- gchar *start = *ptr + GITG_HASH_SHA_SIZE + 1;
- gchar *end = strchr (start, ':');
-
- if (end)
- {
- ret = g_strndup (start, end - start);
- }
- break;
- }
- ptr++;
- }
-
- g_strfreev (out);
- g_free (sha1);
-
- return ret;
-}
-
-static GitgShell *
-remove_stash (GitgWindow *window, GitgRef *ref)
-{
- gint r = message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Are you sure you want to remove this stash item?"),
- _ ("This permanently removes the stash item"),
- _ ("Remove stash"));
-
- if (r != GTK_RESPONSE_ACCEPT)
- {
- return NULL;
- }
-
- GitgRepository *repository = gitg_window_get_repository (window);
- gchar *spec = get_stash_refspec (repository, ref);
-
- if (!spec)
- {
- return NULL;
- }
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "reflog",
- "delete",
- "--updateref",
- "--rewrite",
- spec,
- NULL),
- NULL))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to remove stash"),
- _ ("The stash item could not be successfully removed"),
- NULL);
- }
- else
- {
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "rev-parse",
- "--verify",
- "refs/stash@{0}",
- NULL),
- NULL))
- {
- gitg_shell_run_sync (gitg_command_new (repository,
- "update-ref",
- "-d",
- "refs/stash",
- NULL),
- NULL);
- }
-
- gitg_repository_reload (repository);
- }
-
- g_free (spec);
- return NULL;
-}
-
-static GitgShell *
-remove_tag (GitgWindow *window, GitgRef *ref)
-{
- gchar const *name = gitg_ref_get_shortname (ref);
- gchar *message = g_strdup_printf (_ ("Are you sure you want to remove the tag <%s>?"),
- name);
- gint r = message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Remove tag"),
- message,
- _ ("Remove tag"));
- g_free (message);
-
- if (r != GTK_RESPONSE_ACCEPT)
- {
- return NULL;
- }
-
- GitgRepository *repository = gitg_window_get_repository (window);
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "tag",
- "-d",
- name,
- NULL),
- NULL))
- {
- message = g_strdup_printf (_ ("The tag <%s> could not be successfully removed"),
- name);
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to remove tag"),
- message,
- NULL);
- g_free (message);
- return NULL;
- }
- else
- {
- gitg_repository_reload (repository);
- return NULL;
- }
-}
-
-GitgShell *
-gitg_branch_actions_remove (GitgWindow *window,
- GitgRef *ref)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (ref != NULL, NULL);
-
- GitgRef *cp = gitg_ref_copy (ref);
- GitgShell *ret = NULL;
-
- switch (gitg_ref_get_ref_type (cp))
- {
- case GITG_REF_TYPE_BRANCH:
- ret = remove_local_branch (window, cp);
- break;
- case GITG_REF_TYPE_REMOTE:
- ret = remove_remote_branch (window, cp);
- break;
- case GITG_REF_TYPE_STASH:
- ret = remove_stash (window, cp);
- break;
- case GITG_REF_TYPE_TAG:
- ret = remove_tag (window, cp);
- break;
- default:
- break;
- }
-
- gitg_ref_free (cp);
- return ret;
-}
-
-static GitgShell *
-rename_branch (GitgWindow *window,
- GitgRef *ref,
- const gchar *newname)
-{
- gchar const *oldname = gitg_ref_get_shortname (ref);
- GitgRepository *repository = gitg_window_get_repository (window);
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "branch",
- "-m",
- oldname,
- newname,
- NULL),
- NULL))
- {
- gint ret = message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Branch <%s> could not be renamed to <%s>"),
- _ ("This usually means that a branch with that name already exists. Do you want to overwrite the branch?"),
- _ ("Force rename"),
- oldname, newname);
-
- if (ret == GTK_RESPONSE_ACCEPT)
- {
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "branch",
- "-M",
- oldname,
- newname,
- NULL),
- NULL))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Branch <%s> could not be forcefully renamed"),
- NULL,
- NULL,
- oldname);
-
- return NULL;
- }
- else
- {
- gitg_repository_reload (repository);
- return NULL;
- }
- }
- }
- else
- {
- gitg_repository_reload (repository);
-
- return NULL;
- }
-
- return NULL;
-}
-
-static gchar *
-rename_dialog (GitgWindow *window, const gchar *oldname)
-{
- GtkWidget *dlg;
-
- GtkDialogFlags flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
- dlg = gtk_dialog_new_with_buttons ("gitg",
- GTK_WINDOW (window),
- flags,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- "_Rename", GTK_RESPONSE_OK,
- NULL);
-
- gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
-
- GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- GtkWidget *label = gtk_label_new (_("Name:"));
- GtkWidget *entry = gtk_entry_new ();
-
- gtk_entry_set_text (GTK_ENTRY (entry), oldname);
- gtk_entry_set_width_chars (GTK_ENTRY (entry), 25);
- gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
-
- gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
- gtk_widget_show_all (box);
- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), box, TRUE, TRUE, 12);
- gint ret = gtk_dialog_run (GTK_DIALOG (dlg));
-
- gchar *newname = NULL;
- if (ret == GTK_RESPONSE_OK)
- {
- const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
- if (*text != '\0' && strcmp (text, oldname))
- {
- newname = g_strdup (text);
- }
- }
-
- gtk_widget_destroy (dlg);
-
- return newname;
-}
-
-GitgShell *
-gitg_branch_actions_rename (GitgWindow *window,
- GitgRef *ref)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (ref != NULL, NULL);
-
- if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH)
- {
- gchar *newname = rename_dialog (window, gitg_ref_get_shortname (ref));
-
- if (newname)
- {
- GitgRef *cp = gitg_ref_copy (ref);
- GitgShell *ret = NULL;
- ret = rename_branch (window, cp, newname);
- gitg_ref_free (cp);
- g_free (newname);
- return ret;
- }
- }
-
- return NULL;
-}
-
-static void
-reset_buffer (GitgShell *shell, GString *buffer)
-{
- g_string_erase (buffer, 0, -1);
-}
-
-static void
-update_buffer (GitgShell *shell, gchar **lines, GString *buffer)
-{
- gchar **ptr = lines;
-
- while (ptr && *ptr)
- {
- if (buffer->len != 0)
- {
- g_string_append_c (buffer, '\n');
- }
-
- g_string_append (buffer, *ptr);
- ++ptr;
- }
-}
-
-static gboolean
-no_changes (GitgRepository *repository)
-{
- return gitg_shell_run_sync (gitg_command_new (repository,
- "update-index",
- "--refresh",
- NULL),
- NULL) &&
- gitg_shell_run_sync (gitg_command_new (repository,
- "diff-files",
- "--no-ext-diff",
- "--quiet",
- NULL),
- NULL) &&
- gitg_shell_run_sync (gitg_command_new (repository,
- "diff-index",
- "--no-ext-diff",
- "--cached",
- "--quiet",
- "HEAD",
- "--",
- NULL),
- NULL);
-}
-
-static gboolean
-stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
-{
- GitgRepository *repository = gitg_window_get_repository (window);
- gboolean ret;
- gchar *tree = NULL;
- gchar *commit = NULL;
- gchar *head = NULL;
- gchar *msg = NULL;
- gboolean showerror = FALSE;
-
- GitgShell *shell = gitg_shell_new_synchronized (1000);
- GString *buffer = g_string_new ("");
-
- g_signal_connect (shell, "begin", G_CALLBACK (reset_buffer), buffer);
- g_signal_connect (shell, "update", G_CALLBACK (update_buffer), buffer);
-
- gchar const *secondary;
-
- if (storeref)
- {
- secondary = _ ("Do you want to temporarily stash these changes?");
- }
- else
- {
- secondary = _ ("Do you want to stash and reapply these changes?");
- }
-
- gint r = message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("You have uncommited changes in your current working tree"),
- secondary,
- _ ("Stash changes"));
-
- if (r != GTK_RESPONSE_ACCEPT)
- {
- ret = FALSE;
- goto cleanup;
- }
-
- gitg_shell_run (shell,
- gitg_command_new (repository,
- "log",
- "--no-color",
- "--abbrev-commit",
- "--pretty=oneline",
- "-n",
- "1",
- "HEAD",
- NULL),
- NULL);
-
- GitgRef *working = gitg_repository_get_current_working_ref (repository);
-
- if (working)
- {
- msg = g_strconcat (gitg_ref_get_shortname (working), ": ", buffer->str, NULL);
- }
- else
- {
- msg = g_strconcat (" (no branch): ", buffer->str, NULL);
- }
-
- // Create tree object of the current index
- gitg_shell_run (shell,
- gitg_command_new (repository,
- "write-tree",
- NULL),
- NULL);
-
- if (buffer->len == 0)
- {
- ret = FALSE;
- showerror = TRUE;
-
- goto cleanup;
- }
-
- tree = g_strndup (buffer->str, buffer->len);
- head = gitg_repository_parse_head (repository);
-
- gchar *idxmsg = g_strconcat ("index on ", msg, NULL);
-
- GInputStream *inp = g_memory_input_stream_new_from_data (idxmsg, -1, NULL);
- gitg_io_set_input (GITG_IO (shell), inp);
- g_object_unref (inp);
-
- gitg_shell_run (shell,
- gitg_command_new (repository,
- "commit-tree",
- tree,
- "-p",
- head,
- NULL),
- NULL);
-
- g_free (idxmsg);
- gitg_io_set_input (GITG_IO (shell), NULL);
-
- if (buffer->len == 0)
- {
- ret = FALSE;
- showerror = TRUE;
-
- goto cleanup;
- }
-
- commit = g_strndup (buffer->str, buffer->len);
-
- // Working tree
- gchar *tmpname = NULL;
- gint fd = g_file_open_tmp ("gitg-temp-index-XXXXXX", &tmpname, NULL);
-
- if (fd == -1)
- {
- ret = FALSE;
- showerror = TRUE;
-
- goto cleanup;
- }
-
- GFile *customindex = g_file_new_for_path (tmpname);
-
- close (fd);
-
- GFile *git_dir = gitg_repository_get_git_dir (repository);
- GFile *index_ = g_file_get_child (git_dir, "index");
-
- gboolean copied = g_file_copy (index_, customindex, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
-
- g_object_unref (index_);
- g_object_unref (git_dir);
-
- if (!copied)
- {
- g_object_unref (customindex);
-
- ret = FALSE;
- showerror = TRUE;
- goto cleanup;
- }
-
- tmpname = g_file_get_path (customindex);
-
- GitgCommand *cmd_read_tree = gitg_command_new (repository,
- "read-tree",
- "-m",
- tree,
- NULL);
-
- gitg_command_add_environment (cmd_read_tree,
- "GIT_INDEX_FILE",
- tmpname,
- NULL);
-
- GitgCommand *cmd_add = gitg_command_new (repository,
- "add",
- "-u",
- NULL);
-
- gitg_command_add_environment (cmd_add,
- "GIT_INDEX_FILE",
- tmpname,
- NULL);
-
- GitgCommand *cmd_write_tree = gitg_command_new (repository,
- "write-tree",
- NULL);
-
- gitg_command_add_environment (cmd_write_tree,
- "GIT_INDEX_FILE",
- tmpname,
- NULL);
-
- g_free (tmpname);
-
- gboolean writestash;
-
- writestash = gitg_shell_run (shell, cmd_read_tree, NULL) &&
- gitg_shell_run (shell, cmd_add, NULL) &&
- gitg_shell_run (shell, cmd_write_tree, NULL);
-
- g_file_delete (customindex, NULL, NULL);
- g_object_unref (customindex);
-
- if (!writestash)
- {
- ret = FALSE;
- showerror = TRUE;
-
- goto cleanup;
- }
-
- gchar *stashtree = g_strndup (buffer->str, buffer->len);
- gchar *reason = g_strconcat ("gitg auto stash: ", msg, NULL);
-
- inp = g_memory_input_stream_new_from_data (reason, -1, NULL);
- gitg_io_set_input (GITG_IO (shell), inp);
- g_object_unref (inp);
-
- gitg_shell_run (shell,
- gitg_command_new (repository,
- "commit-tree",
- stashtree,
- "-p",
- head,
- "-p",
- commit,
- NULL),
- NULL);
-
- gitg_io_set_input (GITG_IO (shell), NULL);
-
- g_free (stashtree);
-
- if (buffer->len == 0)
- {
- g_free (reason);
-
- ret = FALSE;
- showerror = TRUE;
-
- goto cleanup;
- }
-
- gchar *rref = g_strndup (buffer->str, buffer->len);
-
- if (ref)
- {
- *ref = g_strdup (rref);
- }
-
- git_dir = gitg_repository_get_git_dir (repository);
- gchar *git_path = g_file_get_path (git_dir);
-
- gchar *path = g_build_filename (git_path,
- "logs",
- "refs",
- "stash",
- NULL);
-
- g_object_unref (git_dir);
- g_free (git_path);
-
- GFile *reflog = g_file_new_for_path (path);
- GFileOutputStream *stream = g_file_create (reflog, G_FILE_CREATE_NONE, NULL, NULL);
-
- g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
-
- g_object_unref (stream);
- g_object_unref (reflog);
-
- g_free (path);
-
- gitg_shell_run (shell,
- gitg_command_new (repository,
- "update-ref",
- "-m",
- reason,
- "refs/stash",
- rref,
- NULL),
- NULL);
-
- g_free (rref);
-
- gitg_shell_run (shell,
- gitg_command_new (repository,
- "reset",
- "--hard",
- NULL),
- NULL);
-
- ret = TRUE;
-
-cleanup:
- g_string_free (buffer, TRUE);
- g_object_unref (shell);
- g_free (commit);
- g_free (tree);
- g_free (head);
- g_free (msg);
-
- if (showerror)
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to save current index state"),
- NULL,
- NULL);
- }
-
- return ret;
-}
-
-static gboolean
-stash_changes (GitgWindow *window, gchar **ref, gboolean storeref)
-{
- if (no_changes (gitg_window_get_repository (window)))
- {
- if (ref)
- {
- *ref = NULL;
- }
-
- return TRUE;
- }
-
- return stash_changes_real (window, ref, storeref);
-}
-
-static gboolean
-checkout_local_branch_real (GitgWindow *window, GitgRef *ref)
-{
- GitgRepository *repository = gitg_window_get_repository (window);
-
- return gitg_shell_run_sync (gitg_command_new (repository,
- "checkout",
- gitg_ref_get_shortname (ref),
- NULL),
- NULL);
-}
-
-static gboolean
-checkout_local_branch (GitgWindow *window,
- GitgRef *ref)
-{
- if (!stash_changes (window, NULL, TRUE))
- {
- return FALSE;
- }
-
- gchar const *name = gitg_ref_get_shortname (ref);
-
- if (!checkout_local_branch_real (window, ref))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout local branch <%s>"),
- NULL,
- NULL,
- name);
- return FALSE;
- }
- else
- {
- gitg_repository_load (gitg_window_get_repository (window), 1, (gchar const **)&name, NULL);
- return TRUE;
- }
-}
-
-static gboolean
-checkout_remote_branch (GitgWindow *window,
- GitgRef *ref)
-{
- if (!stash_changes (window, NULL, TRUE))
- {
- return FALSE;
- }
-
- GitgRepository *repository = gitg_window_get_repository (window);
- gchar const *name = gitg_ref_get_shortname (ref);
- gchar const *local = gitg_ref_get_local_name (ref);
- gboolean ret;
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "checkout",
- "--track",
- "-b",
- local,
- name,
- NULL),
- NULL))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout remote branch <%s> to local branch <%s>"),
- NULL,
- NULL,
- name,
- local);
- ret = FALSE;
- }
- else
- {
- gitg_repository_load (repository, 1, (gchar const **)&local, NULL);
- ret = TRUE;
- }
-
- return ret;
-}
-
-static gboolean
-checkout_tag (GitgWindow *window,
- GitgRef *ref)
-{
- if (!stash_changes (window, NULL, TRUE))
- {
- return FALSE;
- }
-
- GitgRepository *repository = gitg_window_get_repository (window);
- gchar const *name = gitg_ref_get_shortname (ref);
- gboolean ret;
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "checkout",
- "-b",
- name,
- name,
- NULL),
- NULL))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout tag <%s> to local branch <%s>"),
- NULL,
- NULL,
- name,
- name);
- ret = FALSE;
- }
- else
- {
- gitg_repository_load (repository, 1, (gchar const **)&name, NULL);
- ret = TRUE;
- }
-
- return ret;
-}
-
-gboolean
-gitg_branch_actions_checkout (GitgWindow *window,
- GitgRef *ref)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
-
- GitgRef *cp = gitg_ref_copy (ref);
- gboolean ret = FALSE;
-
- switch (gitg_ref_get_ref_type (cp))
- {
- case GITG_REF_TYPE_BRANCH:
- ret = checkout_local_branch (window, cp);
- break;
- case GITG_REF_TYPE_REMOTE:
- ret = checkout_remote_branch (window, cp);
- break;
- case GITG_REF_TYPE_TAG:
- ret = checkout_tag (window, cp);
- break;
- default:
- break;
- }
-
- gitg_ref_free (cp);
- return ret;
-}
-
-typedef struct
-{
- gboolean rebase;
-
- GitgRef *source;
- GitgRef *dest;
-
- gchar *stashcommit;
- GitgRef *head;
-} RefInfo;
-
-static RefInfo *
-ref_info_new (GitgRef *source, GitgRef *dest)
-{
- RefInfo *ret = g_slice_new0 (RefInfo);
-
- ret->source = gitg_ref_copy (source);
- ret->dest = gitg_ref_copy (dest);
-
- return ret;
-}
-
-static void
-ref_info_free (RefInfo *info)
-{
- gitg_ref_free (info->source);
- gitg_ref_free (info->dest);
-
- g_free (info->stashcommit);
- gitg_ref_free (info->head);
-
- g_slice_free (RefInfo, info);
-}
-
-static void
-on_merge_rebase_result (GitgWindow *window,
- GitgProgress progress,
- gpointer data)
-{
- RefInfo *info = (RefInfo *)data;
-
- if (progress == GITG_PROGRESS_ERROR)
- {
- gchar const *message;
-
- if (info->rebase)
- {
- message = _ ("Failed to rebase %s branch <%s> onto %s branch <%s>");
- }
- else
- {
- message = _ ("Failed to merge %s branch <%s> with %s branch <%s>");
- }
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- message,
- NULL,
- NULL,
- gitg_ref_get_ref_type (info->source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (info->source),
- gitg_ref_get_ref_type (info->dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (info->dest));
- }
- else if (progress == GITG_PROGRESS_SUCCESS)
- {
- GitgRepository *repository = gitg_window_get_repository (window);
-
- // Checkout head
- if (!checkout_local_branch_real (window, info->head))
- {
- gchar const *message = NULL;
-
- if (info->stashcommit)
- {
- gitg_shell_run_sync (gitg_command_new (repository,
- "update-ref",
- "-m",
- "gitg autosave stash",
- "refs/stash",
- info->stashcommit,
- NULL),
- NULL);
-
- message = _ ("The stashed changes have been stored to be reapplied manually");
- }
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout previously checked out branch"),
- message,
- NULL);
- }
- else if (info->stashcommit)
- {
- // Reapply stash
- if (!gitg_shell_run_sync (gitg_command_new (gitg_window_get_repository (window),
- "stash",
- "apply",
- "--index",
- info->stashcommit,
- NULL),
- NULL))
- {
- gitg_shell_run_sync (gitg_command_new (repository,
- "update-ref",
- "-m",
- "gitg autosave stash",
- "refs/stash",
- info->stashcommit,
- NULL),
- NULL);
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to reapply stash correctly"),
- _ ("There might be unresolved conflicts in the working tree or index which you need to resolve manually"),
- NULL);
- }
- }
-
- gitg_repository_reload (gitg_window_get_repository (window));
- }
-
- ref_info_free (info);
-}
-
-GitgShell *
-gitg_branch_actions_merge (GitgWindow *window,
- GitgRef *source,
- GitgRef *dest)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (dest != NULL, NULL);
- g_return_val_if_fail (source != NULL, NULL);
- g_return_val_if_fail (gitg_ref_get_ref_type (dest) != GITG_REF_TYPE_REMOTE, NULL);
-
- gchar *message = g_strdup_printf (_ ("Are you sure you want to merge %s branch <%s> onto %s branch <%s>?"),
- gitg_ref_get_ref_type (source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (dest));
-
- if (message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Merge"),
- message,
- _ ("Merge")) != GTK_RESPONSE_ACCEPT)
- {
- g_free (message);
- return NULL;
- }
-
- g_free (message);
- GitgRepository *repository = gitg_window_get_repository (window);
- gchar *stashcommit = NULL;
-
- if (!stash_changes (window, &stashcommit, FALSE))
- {
- return NULL;
- }
-
- GitgRef *head = gitg_repository_get_current_working_ref (repository);
-
- // First checkout the correct branch on which to merge, e.g. dest
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "checkout",
- gitg_ref_get_shortname (dest),
- NULL),
- NULL))
- {
- g_free (stashcommit);
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout local branch <%s>"),
- _ ("The branch on which to merge could not be checked out"),
- NULL,
- gitg_ref_get_shortname (dest));
- return NULL;
- }
-
- message = g_strdup_printf (_ ("Merging %s branch <%s> onto %s branch <%s>"),
- gitg_ref_get_ref_type (source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (dest));
-
- GitgShell *ret;
- RefInfo *info = ref_info_new (source, dest);
- info->stashcommit = stashcommit;
- info->head = gitg_ref_copy (head);
- info->rebase = FALSE;
-
- ret = run_progress (window,
- _ ("Merge"),
- message,
- on_merge_rebase_result,
- info,
- "merge",
- gitg_ref_get_shortname (source),
- NULL);
-
- g_free (message);
-
- return ret;
-}
-
-GitgShell *
-gitg_branch_actions_rebase (GitgWindow *window,
- GitgRef *source,
- GitgRef *dest)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (dest != NULL, NULL);
- g_return_val_if_fail (source != NULL, NULL);
- g_return_val_if_fail (gitg_ref_get_ref_type (source) != GITG_REF_TYPE_REMOTE, NULL);
-
- gchar *message = g_strdup_printf (_ ("Are you sure you want to rebase %s branch <%s> onto %s branch <%s>?"),
- gitg_ref_get_ref_type (source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (dest));
-
- if (message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Rebase"),
- message,
- _ ("Rebase")) != GTK_RESPONSE_ACCEPT)
- {
- g_free (message);
- return NULL;
- }
-
- g_free (message);
- GitgRepository *repository = gitg_window_get_repository (window);
- gchar *stashcommit = NULL;
-
- if (!no_changes (repository))
- {
- // Check if destination is current HEAD
- gchar *head = gitg_repository_parse_head (repository);
- GitgHash hash;
-
- gitg_hash_sha1_to_hash (head, hash);
- g_free (head);
-
- if (gitg_hash_hash_equal (hash, gitg_ref_get_hash (dest)))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Unable to rebase"),
- _ ("There are still uncommitted changes in your working tree and you are trying to rebase a branch onto the currently checked out branch. Either remove, stash or commit your changes first and try again"),
- NULL);
- return NULL;
- }
-
- if (!stash_changes_real (window, &stashcommit, FALSE))
- {
- return NULL;
- }
- }
-
- gchar *merge_head = gitg_hash_hash_to_sha1_new (gitg_ref_get_hash (dest));
-
- message = g_strdup_printf (_ ("Rebasing %s branch <%s> onto %s branch <%s>"),
- gitg_ref_get_ref_type (source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
- gitg_ref_get_shortname (dest));
-
- GitgShell *ret;
- RefInfo *info = ref_info_new (source, dest);
- info->stashcommit = stashcommit;
- info->head = gitg_ref_copy (gitg_repository_get_current_working_ref (repository));
- info->rebase = TRUE;
-
- ret = run_progress (window,
- _ ("Rebase"),
- message,
- on_merge_rebase_result,
- info,
- "rebase",
- merge_head,
- gitg_ref_get_shortname (source),
- NULL);
-
- g_free (message);
- g_free (merge_head);
-
- return ret;
-}
-
-static void
-on_push_result (GitgWindow *window,
- GitgProgress progress,
- gpointer data)
-{
- RefInfo *info = (RefInfo *)data;
-
- if (progress == GITG_PROGRESS_ERROR)
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to push local branch <%s> to remote <%s>"),
- _ ("This usually means that the remote branch could not be fast-forwarded. Try fetching the latest changes."),
- NULL,
- gitg_ref_get_shortname (info->source),
- gitg_ref_get_shortname (info->dest));
- }
- else if (progress == GITG_PROGRESS_SUCCESS)
- {
- gitg_repository_reload (gitg_window_get_repository (window));
- }
-
- ref_info_free (info);
-}
-
-GitgShell *
-gitg_branch_actions_push (GitgWindow *window,
- GitgRef *source,
- GitgRef *dest)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (dest != NULL, NULL);
- g_return_val_if_fail (source != NULL, NULL);
- g_return_val_if_fail (gitg_ref_get_ref_type (source) == GITG_REF_TYPE_BRANCH, NULL);
- g_return_val_if_fail (gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_REMOTE, NULL);
-
- gchar *message = g_strdup_printf (_ ("Are you sure you want to push <%s> to <%s>?"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_shortname (dest));
-
- if (message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Push"),
- message,
- _ ("Push")) != GTK_RESPONSE_ACCEPT)
- {
- g_free (message);
- return NULL;
- }
-
- g_free (message);
-
- gchar const *prefix = gitg_ref_get_prefix (dest);
- gchar const *local = gitg_ref_get_local_name (dest);
- gchar const *name = gitg_ref_get_shortname (source);
-
- gchar *spec = g_strconcat (name, ":", local, NULL);
- message = g_strdup_printf (_ ("Pushing local branch <%s> to remote branch <%s>"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_shortname (dest));
-
- GitgShell *ret;
- RefInfo *info = ref_info_new (source, dest);
-
- ret = run_progress (window,
- _ ("Push"),
- message,
- on_push_result,
- info,
- "push",
- prefix,
- spec,
- NULL);
-
- g_free (message);
- g_free (spec);
-
- return ret;
-}
-
-GitgShell *
-gitg_branch_actions_push_remote (GitgWindow *window,
- GitgRef *source,
- gchar const *remote,
- gchar const *branch)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (remote != NULL, NULL);
- g_return_val_if_fail (source != NULL, NULL);
- g_return_val_if_fail (gitg_ref_get_ref_type (source) == GITG_REF_TYPE_BRANCH, NULL);
-
- gchar *message = g_strdup_printf (_ ("Are you sure you want to push <%s> to remote <%s/%s>?"),
- gitg_ref_get_shortname (source),
- remote, branch);
-
- if (message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Push"),
- message,
- _ ("Push")) != GTK_RESPONSE_ACCEPT)
- {
- g_free (message);
- return NULL;
- }
-
- g_free (message);
-
- gchar const *name = gitg_ref_get_shortname (source);
- gchar *spec = g_strconcat (name, ":", branch, NULL);
- message = g_strdup_printf (_ ("Pushing local branch <%s> to remote branch <%s/%s>"),
- gitg_ref_get_shortname (source),
- remote, branch);
-
- GitgShell *ret;
- gchar *rr = g_strconcat ("refs/remotes/", remote, "/", branch, NULL);
- GitgRef *rmref = gitg_ref_new ("0000000000000000000000000000000000000000", rr);
- g_free (rr);
-
- RefInfo *info = ref_info_new (source, rmref);
- gitg_ref_free (rmref);
-
- ret = run_progress (window,
- _ ("Push"),
- message,
- on_push_result,
- info,
- "push",
- remote,
- spec,
- NULL);
-
- g_free (message);
- g_free (spec);
-
- return ret;
-}
-
-gboolean
-gitg_branch_actions_apply_stash (GitgWindow *window,
- GitgRef *stash,
- GitgRef *branch)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
- g_return_val_if_fail (gitg_ref_get_ref_type (stash) == GITG_REF_TYPE_STASH, FALSE);
- g_return_val_if_fail (gitg_ref_get_ref_type (branch) == GITG_REF_TYPE_BRANCH, FALSE);
-
- gchar *message = g_strdup_printf (_ ("Are you sure you want to apply the stash item to local branch <%s>?"),
- gitg_ref_get_shortname (branch));
-
- if (message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Apply stash"),
- message,
- _ ("Apply stash")) != GTK_RESPONSE_ACCEPT)
- {
- g_free (message);
- return FALSE;
- }
-
- GitgRepository *repository = gitg_window_get_repository (window);
- GitgRef *current = gitg_repository_get_current_working_ref (repository);
-
- if (!gitg_ref_equal (branch, current))
- {
- if (!stash_changes (window, NULL, TRUE))
- {
- return FALSE;
- }
-
- if (!checkout_local_branch_real (window, branch))
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout local branch <%s>"),
- NULL,
- NULL,
- gitg_ref_get_shortname (branch));
- return FALSE;
- }
- }
-
- gchar *sha1 = gitg_hash_hash_to_sha1_new (gitg_ref_get_hash (stash));
- gboolean ret;
-
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "stash",
- "apply",
- "--index",
- sha1,
- NULL),
- NULL))
- {
- message = g_strdup_printf (_ ("The stash could not be applied to local branch <%s>"),
- gitg_ref_get_shortname (branch));
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to apply stash"),
- message,
- NULL);
- g_free (message);
- ret = FALSE;
-
- if (!gitg_ref_equal (current, branch) && no_changes (repository))
- {
- checkout_local_branch_real (window, current);
- }
- }
- else
- {
- ret = TRUE;
- gitg_repository_reload (repository);
- }
-
- return ret;
-}
-
-gboolean
-gitg_branch_actions_create (GitgWindow *window, gchar const *sha1, gchar const *name)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
- g_return_val_if_fail (sha1 != NULL, FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- GitgRepository *repository;
- gboolean result = FALSE;
-
- repository = gitg_window_get_repository (window);
-
- result = gitg_shell_run_sync (gitg_command_new (repository,
- "branch",
- name,
- sha1,
- NULL),
- NULL);
-
- if (!result)
- {
- gchar const *message;
-
- message = _ ("The branch could not be successfully created");
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to create a branch"),
- message,
- NULL);
- return FALSE;
- }
- else
- {
- gitg_repository_reload (repository);
- return TRUE;
- }
-}
-
-gboolean
-gitg_branch_actions_tag (GitgWindow *window, gchar const *sha1, gchar const *name, gchar const *message, gboolean sign)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
- g_return_val_if_fail (sha1 != NULL, FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- GitgRepository *repository;
- gboolean result = FALSE;
-
- repository = gitg_window_get_repository (window);
-
- if (message != NULL && message[0] != '\0')
- {
- result = gitg_shell_run_sync (gitg_command_new (repository,
- "tag",
- "-m",
- message,
- sign ? "-s" : "-a",
- name,
- sha1,
- NULL),
- NULL);
- }
- else
- {
- result = gitg_shell_run_sync (gitg_command_new (repository,
- "tag",
- name,
- sha1,
- NULL),
- NULL);
- }
-
- if (!result)
- {
- gchar const *secondary;
-
- if (sign)
- {
- secondary = _ ("The tag object could not be successfully created. Please make sure you have a GPG key and the key is unlocked");
- }
- else
- {
- secondary = _ ("The tag object could not be successfully created");
- }
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to create tag"),
- secondary,
- NULL);
- return FALSE;
- }
- else
- {
- gitg_repository_reload (repository);
- return TRUE;
- }
-}
-
-typedef struct
-{
- GitgRevision *revision;
- GitgRef *dest;
-
- gchar *stashcommit;
- GitgRef *head;
-} CherryPickInfo;
-
-static CherryPickInfo *
-cherry_pick_info_new (GitgRevision *revision, GitgRef *dest)
-{
- CherryPickInfo *ret = g_slice_new0 (CherryPickInfo);
-
- ret->revision = gitg_revision_ref (revision);
- ret->dest = gitg_ref_copy (dest);
-
- return ret;
-}
-
-static void
-cherry_pick_info_free (CherryPickInfo *info)
-{
- gitg_revision_unref (info->revision);
- gitg_ref_free (info->dest);
-
- g_free (info->stashcommit);
- gitg_ref_free (info->head);
-
- g_slice_free (CherryPickInfo, info);
-}
-
-static void
-on_cherry_pick_result (GitgWindow *window,
- GitgProgress progress,
- gpointer data)
-{
- CherryPickInfo *info = (CherryPickInfo *)data;
-
- if (progress == GITG_PROGRESS_ERROR)
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to cherry-pick on <%s>"),
- NULL,
- NULL,
- gitg_ref_get_shortname (info->dest));
- }
- else if (progress == GITG_PROGRESS_SUCCESS)
- {
- GitgRepository *repository = gitg_window_get_repository (window);
-
- // Checkout head
- if (!checkout_local_branch_real (window, info->head))
- {
- gchar const *message = NULL;
-
- if (info->stashcommit)
- {
- gitg_shell_run_sync (gitg_command_new (repository,
- "update-ref",
- "-m",
- "gitg autosave stash",
- "refs/stash",
- info->stashcommit,
- NULL),
- NULL);
-
- message = _ ("The stashed changes have been stored to be reapplied manually");
- }
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout previously checked out branch"),
- message,
- NULL);
- }
- else if (info->stashcommit)
- {
- // Reapply stash
- if (!gitg_shell_run_sync (gitg_command_new (gitg_window_get_repository (window),
- "stash",
- "apply",
- "--index",
- info->stashcommit,
- NULL),
- NULL))
- {
- gitg_shell_run_sync (gitg_command_new (repository,
- "update-ref",
- "-m",
- "gitg autosave stash",
- "refs/stash",
- info->stashcommit,
- NULL),
- NULL);
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to reapply stash correctly"),
- _ ("There might be unresolved conflicts in the working tree or index which you need to resolve manually"),
- NULL);
- }
- }
-
- gitg_repository_reload (gitg_window_get_repository (window));
- }
-
- cherry_pick_info_free (info);
-}
-
-GitgShell *
-gitg_branch_actions_cherry_pick (GitgWindow *window,
- GitgRevision *revision,
- GitgRef *dest)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (revision != NULL, NULL);
- g_return_val_if_fail (dest != NULL, NULL);
-
- gchar *message = g_strdup_printf (_ ("Are you sure you want to cherry-pick that revision on <%s>?"),
- gitg_ref_get_shortname (dest));
-
- if (message_dialog (window,
- GTK_MESSAGE_QUESTION,
- _ ("Cherry-pick"),
- message,
- _ ("Cherry-pick")) != GTK_RESPONSE_ACCEPT)
- {
- g_free (message);
- return NULL;
- }
-
- gchar *stashcommit;
-
- if (!stash_changes (window, &stashcommit, FALSE))
- {
- return NULL;
- }
-
- GitgRepository *repository = gitg_window_get_repository (window);
- GitgRef *head = gitg_repository_get_current_working_ref (repository);
-
- // First checkout the correct branch on which to cherry-pick
- if (!gitg_shell_run_sync (gitg_command_new (repository,
- "checkout",
- gitg_ref_get_shortname (dest),
- NULL),
- NULL))
- {
- g_free (stashcommit);
-
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to checkout local branch <%s>"),
- _ ("The branch on which to cherry-pick could not be checked out"),
- NULL,
- gitg_ref_get_shortname (dest));
-
- return NULL;
- }
-
- message = g_strdup_printf (_ ("Cherry-picking on <%s>"),
- gitg_ref_get_shortname (dest));
-
- GitgShell *ret;
-
- CherryPickInfo *info = cherry_pick_info_new (revision, dest);
-
- info->stashcommit = stashcommit;
- info->head = gitg_ref_copy (head);
-
- gchar *sha1 = gitg_revision_get_sha1 (revision);
-
- ret = run_progress (window,
- _ ("Cherry-pick"),
- message,
- on_cherry_pick_result,
- info,
- "cherry-pick",
- sha1,
- NULL);
-
- g_free (message);
- g_free (sha1);
-
- return ret;
-}
-
-typedef struct
-{
- GitgRevision *revision;
- gchar *destination;
- GOutputStream *stream;
-} FormatPatchInfo;
-
-static FormatPatchInfo *
-format_patch_info_new (GitgRevision *revision, gchar const *destination, GOutputStream *stream)
-{
- FormatPatchInfo *ret = g_slice_new0 (FormatPatchInfo);
-
- ret->revision = gitg_revision_ref (revision);
- ret->destination = g_strdup (destination);
- ret->stream = stream;
-
- return ret;
-}
-
-static void
-format_patch_info_free (FormatPatchInfo *info)
-{
- gitg_revision_unref (info->revision);
- g_free (info->destination);
-
- g_object_unref (info->stream);
-
- g_slice_free (FormatPatchInfo, info);
-}
-
-static void
-on_format_patch_result (GitgWindow *window,
- GitgProgress progress,
- gpointer data)
-{
- FormatPatchInfo *info = (FormatPatchInfo *)data;
-
- if (progress == GITG_PROGRESS_ERROR)
- {
- message_dialog (window,
- GTK_MESSAGE_ERROR,
- _ ("Failed to generate format-patch"),
- NULL,
- NULL,
- NULL);
- }
-
- format_patch_info_free (info);
-}
-
-static void
-on_format_patch_update (GitgShell *shell,
- gchar **lines,
- FormatPatchInfo *info)
-{
- while (lines && *lines)
- {
- g_output_stream_write_all (info->stream, *lines, strlen (*lines), NULL, NULL, NULL);
- g_output_stream_write_all (info->stream, "\n", 1, NULL, NULL, NULL);
- ++lines;
- }
-}
-
-GitgShell *
-gitg_branch_actions_format_patch (GitgWindow *window,
- GitgRevision *revision,
- gchar const *destination)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
- g_return_val_if_fail (revision != NULL, NULL);
- g_return_val_if_fail (destination != NULL, NULL);
-
- GitgShell *ret;
-
- GFile *file = g_file_new_for_uri (destination);
- GFileOutputStream *stream = g_file_replace (file,
- NULL,
- FALSE,
- G_FILE_CREATE_REPLACE_DESTINATION,
- NULL,
- NULL);
- g_object_unref (file);
-
- if (!stream)
- {
- return NULL;
- }
-
- gchar *sha1 = gitg_revision_get_sha1 (revision);
- gchar *message;
-
- message = g_strdup_printf (_ ("Generating format-patch for <%s>"),
- gitg_revision_get_subject (revision));
-
- FormatPatchInfo *info = format_patch_info_new (revision,
- destination,
- G_OUTPUT_STREAM (stream));
-
- ret = run_progress (window,
- _ ("Format patch"),
- message,
- on_format_patch_result,
- info,
- "format-patch",
- "-1",
- "--stdout",
- sha1,
- NULL);
-
- if (ret)
- {
- g_signal_connect (ret, "update", G_CALLBACK (on_format_patch_update), info);
- }
-
- g_free (sha1);
- g_free (message);
-
- return ret;
-}
diff --git a/gitg/gitg-branch-actions.h b/gitg/gitg-branch-actions.h
deleted file mode 100644
index 88fac6a..0000000
--- a/gitg/gitg-branch-actions.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * gitg-branch-actions.h
- * This file is part of gitg
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_BRANCH_ACTIONS_H__
-#define __GITG_BRANCH_ACTIONS_H__
-
-#include <libgitg/gitg-ref.h>
-#include <gitg/gitg-window.h>
-
-G_BEGIN_DECLS
-
-gboolean gitg_branch_actions_create (GitgWindow *window, gchar const *sha1, gchar const *name);
-GitgShell *gitg_branch_actions_remove (GitgWindow *window, GitgRef *ref);
-GitgShell *gitg_branch_actions_rename (GitgWindow *window, GitgRef *ref);
-gboolean gitg_branch_actions_checkout (GitgWindow *window, GitgRef *ref);
-
-GitgShell *gitg_branch_actions_merge (GitgWindow *window, GitgRef *source, GitgRef *dest);
-GitgShell *gitg_branch_actions_rebase (GitgWindow *window, GitgRef *source, GitgRef *dest);
-
-GitgShell *gitg_branch_actions_push (GitgWindow *window, GitgRef *source, GitgRef *dest);
-GitgShell *gitg_branch_actions_push_remote (GitgWindow *window, GitgRef *source, gchar const *remote, gchar const *branch);
-
-gboolean gitg_branch_actions_apply_stash (GitgWindow *window, GitgRef *stash, GitgRef *branch);
-
-gboolean gitg_branch_actions_tag (GitgWindow *window, gchar const *sha1, gchar const *name, gchar const *message, gboolean sign);
-
-GitgShell *gitg_branch_actions_cherry_pick (GitgWindow *window, GitgRevision *revision, GitgRef *dest);
-
-GitgShell *gitg_branch_actions_format_patch (GitgWindow *window, GitgRevision *revision, gchar const *destination);
-
-G_END_DECLS
-
-#endif /* __GITG_BRANCH_ACTIONS_H__ */
-
diff --git a/gitg/gitg-cell-renderer-path.c b/gitg/gitg-cell-renderer-path.c
deleted file mode 100644
index 97902ee..0000000
--- a/gitg/gitg-cell-renderer-path.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * gitg-cell-renderer-path.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <math.h>
-#include <libgitg/gitg-lane.h>
-#include <libgitg/gitg-revision.h>
-
-#include "gitg-cell-renderer-path.h"
-#include "gitg-label-renderer.h"
-
-#define GITG_CELL_RENDERER_PATH_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_CELL_RENDERER_PATH, GitgCellRendererPathPrivate))
-
-#define DEFAULT_DOT_WIDTH 10
-#define DEFAULT_TRIANGLE_WIDTH 8
-
-#define DEFAULT_LANE_WIDTH (DEFAULT_DOT_WIDTH + 6)
-
-/* Properties */
-enum
-{
- PROP_0,
-
- PROP_REVISION,
- PROP_NEXT_REVISION,
- PROP_LANE_WIDTH,
- PROP_DOT_WIDTH,
- PROP_TRIANGLE_WIDTH,
- PROP_LABELS
-};
-
-struct _GitgCellRendererPathPrivate
-{
- GitgRevision *revision;
- GitgRevision *next_revision;
- GSList *labels;
- guint lane_width;
- guint triangle_width;
- guint dot_width;
-
- gint last_height;
-};
-
-static GtkCellRendererTextClass *parent_class = NULL;
-
-G_DEFINE_TYPE (GitgCellRendererPath, gitg_cell_renderer_path, GTK_TYPE_CELL_RENDERER_TEXT)
-
-static gint
-num_lanes (GitgCellRendererPath *self)
-{
- return g_slist_length (gitg_revision_get_lanes (self->priv->revision));
-}
-
-static gboolean
-is_dummy (GitgRevision *revision)
-{
- switch (gitg_revision_get_sign (revision))
- {
- case 's':
- case 't':
- case 'u':
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static gint
-total_width (GitgCellRendererPath *self,
- GtkWidget *widget)
-{
- PangoFontDescription *font;
- g_object_get (self, "font-desc", &font, NULL);
-
- gint offset = 0;
-
- if (is_dummy (self->priv->revision))
- {
- offset = self->priv->lane_width;
- }
-
- return num_lanes (self) * self->priv->lane_width +
- gitg_label_renderer_width (widget, font, self->priv->labels) +
- offset;
-}
-
-static void
-gitg_cell_renderer_path_finalize (GObject *object)
-{
- GitgCellRendererPath *self = GITG_CELL_RENDERER_PATH (object);
-
- gitg_revision_unref (self->priv->revision);
- gitg_revision_unref (self->priv->next_revision);
-
- g_slist_free (self->priv->labels);
-
- G_OBJECT_CLASS (gitg_cell_renderer_path_parent_class)->finalize (object);
-}
-
-static void
-renderer_get_size (GtkCellRenderer *renderer,
- GtkWidget *widget,
- const GdkRectangle *area,
- gint *xoffset,
- gint *yoffset,
- gint *width,
- gint *height)
-{
- GitgCellRendererPath *self = GITG_CELL_RENDERER_PATH (renderer);
-
- if (xoffset)
- {
- *xoffset = 0;
- }
-
- if (yoffset)
- {
- *yoffset = 0;
- }
-
- if (width)
- {
- *width = total_width (self, widget);
- }
-
- if (height)
- {
- *height = area ? area->height : 1;
- }
-}
-
-static void
-draw_arrow (GitgCellRendererPath *self,
- cairo_t *cr,
- const GdkRectangle *area,
- gint8 laneidx,
- gboolean top)
-{
- gdouble cw = self->priv->lane_width;
- gdouble xpos = area->x + laneidx * cw + cw / 2.0;
- gdouble df = (top ? -1 : 1) * 0.25 * area->height;
- gdouble ypos = area->y + area->height / 2.0 + df;
- gdouble q = cw / 4.0;
-
- cairo_move_to (cr, xpos - q, ypos + (top ? q : -q));
- cairo_line_to (cr, xpos, ypos);
- cairo_line_to (cr, xpos + q, ypos + (top ? q : -q));
- cairo_stroke (cr);
-
- cairo_move_to (cr, xpos, ypos);
- cairo_line_to (cr, xpos, ypos - df);
- cairo_stroke (cr);
-
- //cairo_move_to (cr, xpos, ypos);
- //cairo_line_to (cr, xpos, ypos + (top ? 1 : -1) * area->height / 2.0);
- //cairo_stroke (cr);
-}
-
-static void
-draw_paths_real (GitgCellRendererPath *self,
- cairo_t *cr,
- const GdkRectangle *area,
- GitgRevision *revision,
- gdouble yoffset)
-{
- if (!revision)
- {
- return;
- }
-
- GSList *lanes = gitg_revision_get_lanes (revision);
- gint8 to = 0;
- gdouble cw = self->priv->lane_width;
- gdouble ch = area->height / 2.0;
- GitgLane *lane;
-
- while (lanes)
- {
- GSList *item;
-
- lane = (GitgLane *) (lanes->data);
- gitg_color_set_cairo_source (lane->color, cr);
-
- for (item = lane->from; item; item = item->next)
- {
- gint8 from = (gint8)GPOINTER_TO_INT (item->data);
-
- cairo_move_to (cr, area->x + from * cw + cw / 2.0,
- area->y + yoffset * ch);
-
- cairo_curve_to (cr, area->x + from * cw + cw / 2.0,
- area->y + (yoffset + 1) * ch,
- area->x + to * cw + cw / 2.0, area->y + (yoffset + 1) * ch,
- area->x + to * cw + cw / 2.0, area->y + (yoffset + 2) * ch);
-
- cairo_stroke (cr);
- }
-
- ++to;
- lanes = lanes->next;
- }
-}
-
-static void
-draw_top_paths (GitgCellRendererPath *self,
- cairo_t *cr,
- const GdkRectangle *area)
-{
- draw_paths_real (self, cr, area, self->priv->revision, -1);
-}
-
-static void
-draw_bottom_paths (GitgCellRendererPath *self,
- cairo_t *cr,
- const GdkRectangle *area)
-{
- draw_paths_real (self, cr, area, self->priv->next_revision, 1);
-}
-
-static void
-draw_arrows (GitgCellRendererPath *self,
- cairo_t *cr,
- const GdkRectangle *area)
-{
- GSList *item;
- gint8 to = 0;
-
- for (item = gitg_revision_get_lanes (self->priv->revision); item; item = item->next)
- {
- GitgLane *lane = (GitgLane *)item->data;
- gitg_color_set_cairo_source (lane->color, cr);
-
- if (lane->type & GITG_LANE_TYPE_START)
- {
- draw_arrow (self, cr, area, to, TRUE);
- }
- else if (lane->type & GITG_LANE_TYPE_END)
- {
- draw_arrow (self, cr, area, to, FALSE);
- }
-
- ++to;
- }
-}
-
-static void
-draw_paths (GitgCellRendererPath *self,
- cairo_t *cr,
- const GdkRectangle *area)
-{
- cairo_set_line_width (cr, 2);
- //cairo_set_source_rgb (cr, 0.45, 0.6, 0.74);
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
-
- draw_top_paths (self, cr, area);
- draw_bottom_paths (self, cr, area);
- draw_arrows (self, cr, area);
-}
-
-static void
-draw_labels (GitgCellRendererPath *self,
- GtkWidget *widget,
- cairo_t *context,
- const GdkRectangle *area)
-{
- gint offset = num_lanes (self) * self->priv->lane_width;
- PangoFontDescription *font;
-
- if (is_dummy (self->priv->revision))
- {
- offset += self->priv->lane_width;
- }
-
- g_object_get (self, "font-desc", &font, NULL);
-
- cairo_translate (context, offset, 0.0);
- gitg_label_renderer_draw (widget, font, context, self->priv->labels, area);
-}
-
-static void
-draw_indicator_triangle (GitgCellRendererPath *self,
- GitgLane *lane,
- cairo_t *context,
- const GdkRectangle *area)
-{
- gdouble offset = gitg_revision_get_mylane (self->priv->revision) * self->priv->lane_width + (self->priv->lane_width - self->priv->triangle_width) / 2.0;
- gdouble radius = self->priv->triangle_width / 2.0;
- gdouble xs;
- int xd;
-
- if (lane->type & GITG_LANE_SIGN_LEFT)
- {
- xs = radius;
- xd = -1;
- }
- else
- {
- xs = -radius;
- xd = 1;
- }
-
- cairo_set_line_width (context, 2.0);
-
- cairo_move_to (context,
- area->x + offset + radius + xs,
- area->y + (area->height - self->priv->triangle_width) / 2);
-
- cairo_rel_line_to (context, 0, self->priv->triangle_width);
- cairo_rel_line_to (context,
- xd * self->priv->triangle_width,
- -self->priv->triangle_width / 2);
-
- cairo_close_path (context);
-
- cairo_set_source_rgb (context, 0, 0, 0);
- cairo_stroke_preserve (context);
-
- gitg_color_set_cairo_source (lane->color, context);
- cairo_fill (context);
-}
-
-static void
-draw_indicator_circle (GitgCellRendererPath *self,
- GitgLane *lane,
- cairo_t *context,
- const GdkRectangle *area)
-{
- gdouble offset = gitg_revision_get_mylane (self->priv->revision) * self->priv->lane_width + (self->priv->lane_width - self->priv->dot_width) / 2.0;
- gdouble radius = self->priv->dot_width / 2.0;
-
- if (is_dummy (self->priv->revision))
- {
- offset += self->priv->lane_width;
- }
-
- cairo_set_line_width (context, 2.0);
- cairo_arc (context, area->x + offset + radius, area->y + area->height / 2.0, radius, 0, 2 * M_PI);
- cairo_set_source_rgb (context, 0, 0, 0);
-
- if (is_dummy (self->priv->revision))
- {
- cairo_stroke (context);
- }
- else
- {
- cairo_stroke_preserve (context);
- gitg_color_set_cairo_source (lane->color, context);
-
- cairo_fill (context);
- }
-}
-
-static void
-draw_indicator (GitgCellRendererPath *self,
- cairo_t *context,
- const GdkRectangle *area)
-{
- GitgLane *lane = gitg_revision_get_lane (self->priv->revision);
-
- if (lane->type & GITG_LANE_SIGN_LEFT || lane->type & GITG_LANE_SIGN_RIGHT)
- {
- draw_indicator_triangle (self, lane, context, area);
- }
- else
- {
- draw_indicator_circle (self, lane, context, area);
- }
-}
-
-static void
-renderer_render (GtkCellRenderer *renderer,
- cairo_t *cr,
- GtkWidget *widget,
- const GdkRectangle *area,
- const GdkRectangle *cell_area,
- GtkCellRendererState flags)
-{
- GitgCellRendererPath *self;
- GdkRectangle narea;
- GdkRectangle ncell_area;
-
- self = GITG_CELL_RENDERER_PATH (renderer);
-
- self->priv->last_height = area->height;
-
- cairo_save (cr);
-
- gdk_cairo_rectangle (cr, area);
- cairo_clip (cr);
-
- draw_paths (self, cr, area);
-
- /* draw indicator */
- draw_indicator (self, cr, area);
-
- /* draw labels */
- draw_labels (self, widget, cr, area);
-
- narea = *area;
- ncell_area = *cell_area;
-
- narea.x += total_width (self, widget);
- ncell_area.x += total_width (self, widget);
-
- cairo_restore (cr);
-
- if (GTK_CELL_RENDERER_CLASS (parent_class)->render)
- {
- GTK_CELL_RENDERER_CLASS (parent_class)->render (renderer,
- cr,
- widget,
- &narea,
- &ncell_area,
- flags);
- }
-}
-
-static void
-gitg_cell_renderer_path_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgCellRendererPath *self = GITG_CELL_RENDERER_PATH (object);
-
- switch (prop_id)
- {
- case PROP_REVISION:
- g_value_set_boxed (value, self->priv->revision);
- break;
- case PROP_NEXT_REVISION:
- g_value_set_boxed (value, self->priv->next_revision);
- break;
- case PROP_LANE_WIDTH:
- g_value_set_uint (value, self->priv->lane_width);
- break;
- case PROP_DOT_WIDTH:
- g_value_set_uint (value, self->priv->dot_width);
- break;
- case PROP_TRIANGLE_WIDTH:
- g_value_set_uint (value, self->priv->triangle_width);
- break;
- case PROP_LABELS:
- g_value_set_pointer (value, self->priv->labels);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_cell_renderer_path_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgCellRendererPath *self = GITG_CELL_RENDERER_PATH (object);
-
- switch (prop_id)
- {
- case PROP_REVISION:
- gitg_revision_unref (self->priv->revision);
- self->priv->revision = g_value_dup_boxed (value);
- break;
- case PROP_NEXT_REVISION:
- gitg_revision_unref (self->priv->next_revision);
- self->priv->next_revision = g_value_dup_boxed (value);
- break;
- case PROP_LANE_WIDTH:
- self->priv->lane_width = g_value_get_uint (value);
- break;
- case PROP_DOT_WIDTH:
- self->priv->dot_width = g_value_get_uint (value);
- break;
- case PROP_TRIANGLE_WIDTH:
- self->priv->triangle_width = g_value_get_uint (value);
- break;
- case PROP_LABELS:
- g_slist_free (self->priv->labels);
- self->priv->labels = (GSList *)g_value_get_pointer (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_cell_renderer_path_class_init (GitgCellRendererPathClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkCellRendererClass *renderer_class = GTK_CELL_RENDERER_CLASS (klass);
-
- object_class->finalize = gitg_cell_renderer_path_finalize;
- object_class->get_property = gitg_cell_renderer_path_get_property;
- object_class->set_property = gitg_cell_renderer_path_set_property;
-
- renderer_class->get_size = renderer_get_size;
- renderer_class->render = renderer_render;
-
- parent_class = g_type_class_peek_parent (klass);
-
- g_object_class_install_property (object_class,
- PROP_REVISION,
- g_param_spec_boxed ("revision",
- "REVISION",
- "The revision",
- GITG_TYPE_REVISION,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_NEXT_REVISION,
- g_param_spec_boxed ("next-revision",
- "NEXT_REVISION",
- "The next revision",
- GITG_TYPE_REVISION,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_LANE_WIDTH,
- g_param_spec_uint ("lane-width",
- "LANE WIDTH",
- "The lane width",
- 0,
- G_MAXUINT,
- DEFAULT_LANE_WIDTH,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_DOT_WIDTH,
- g_param_spec_uint ("dot-width",
- "DOT WIDTH",
- "The dot width",
- 0,
- G_MAXUINT,
- DEFAULT_DOT_WIDTH,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_TRIANGLE_WIDTH,
- g_param_spec_uint ("triangle-width",
- "TRIANGLE WIDTH",
- "The triangle width",
- 0,
- G_MAXUINT,
- DEFAULT_TRIANGLE_WIDTH,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_LABELS,
- g_param_spec_pointer ("labels",
- "LABELS",
- "Labels",
- G_PARAM_READWRITE));
-
- g_type_class_add_private (object_class, sizeof (GitgCellRendererPathPrivate));
-}
-
-static void
-gitg_cell_renderer_path_init (GitgCellRendererPath *self)
-{
- self->priv = GITG_CELL_RENDERER_PATH_GET_PRIVATE (self);
-
- self->priv->lane_width = DEFAULT_LANE_WIDTH;
- self->priv->dot_width = DEFAULT_DOT_WIDTH;
- self->priv->triangle_width = DEFAULT_TRIANGLE_WIDTH;
-}
-
-GtkCellRenderer *
-gitg_cell_renderer_path_new ()
-{
- return GTK_CELL_RENDERER (g_object_new (GITG_TYPE_CELL_RENDERER_PATH, NULL));
-}
-
-GitgRef *
-gitg_cell_renderer_path_get_ref_at_pos (GtkWidget *widget,
- GitgCellRendererPath *renderer,
- gint x,
- gint *hot_x)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- g_return_val_if_fail (GITG_IS_CELL_RENDERER_PATH (renderer), NULL);
-
- PangoFontDescription *font;
- g_object_get (renderer, "font-desc", &font, NULL);
-
- gint offset = 0;
-
- if (is_dummy (renderer->priv->revision))
- {
- offset = renderer->priv->lane_width;
- }
-
- x -= num_lanes (renderer) * renderer->priv->lane_width + offset;
-
- return gitg_label_renderer_get_ref_at_pos (widget,
- font,
- renderer->priv->labels,
- x,
- hot_x);
-}
-
-GdkPixbuf *
-gitg_cell_renderer_path_render_ref (GtkWidget *widget,
- GitgCellRendererPath *renderer,
- GitgRef *ref,
- gint minwidth)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- g_return_val_if_fail (GITG_IS_CELL_RENDERER_PATH (renderer), NULL);
-
- PangoFontDescription *font;
- g_object_get (renderer, "font-desc", &font, NULL);
-
- return gitg_label_renderer_render_ref (widget,
- font,
- ref,
- renderer->priv->last_height,
- minwidth);
-}
diff --git a/gitg/gitg-cell-renderer-path.h b/gitg/gitg-cell-renderer-path.h
deleted file mode 100644
index 8ab7c99..0000000
--- a/gitg/gitg-cell-renderer-path.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * gitg-cell-renderer-path.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_CELL_RENDERER_PATH_H__
-#define __GITG_CELL_RENDERER_PATH_H__
-
-#include <gtk/gtk.h>
-#include <libgitg/gitg-ref.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_CELL_RENDERER_PATH (gitg_cell_renderer_path_get_type ())
-#define GITG_CELL_RENDERER_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CELL_RENDERER_PATH, GitgCellRendererPath))
-#define GITG_CELL_RENDERER_PATH_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CELL_RENDERER_PATH, GitgCellRendererPath const))
-#define GITG_CELL_RENDERER_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_CELL_RENDERER_PATH, GitgCellRendererPathClass))
-#define GITG_IS_CELL_RENDERER_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_CELL_RENDERER_PATH))
-#define GITG_IS_CELL_RENDERER_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_CELL_RENDERER_PATH))
-#define GITG_CELL_RENDERER_PATH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_CELL_RENDERER_PATH, GitgCellRendererPathClass))
-
-typedef struct _GitgCellRendererPath GitgCellRendererPath;
-typedef struct _GitgCellRendererPathClass GitgCellRendererPathClass;
-typedef struct _GitgCellRendererPathPrivate GitgCellRendererPathPrivate;
-
-struct _GitgCellRendererPath
-{
- GtkCellRendererText parent;
-
- GitgCellRendererPathPrivate *priv;
-};
-
-struct _GitgCellRendererPathClass
-{
- GtkCellRendererTextClass parent_class;
-};
-
-GType gitg_cell_renderer_path_get_type (void) G_GNUC_CONST;
-GtkCellRenderer *gitg_cell_renderer_path_new (void);
-
-GitgRef *gitg_cell_renderer_path_get_ref_at_pos (GtkWidget *widget,
- GitgCellRendererPath *renderer,
- gint x,
- gint *hot_x);
-GdkPixbuf *gitg_cell_renderer_path_render_ref (GtkWidget *widget,
- GitgCellRendererPath *renderer,
- GitgRef *ref,
- gint minwidth);
-
-G_END_DECLS
-
-#endif /* __GITG_CELL_RENDERER_PATH_H__ */
diff --git a/gitg/gitg-commit-menu.ui b/gitg/gitg-commit-menu.ui
deleted file mode 100644
index 90ad8e8..0000000
--- a/gitg/gitg-commit-menu.ui
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <object class="GtkUIManager" id="uiman">
- <child>
- <object class="GtkActionGroup" id="action_group_commit_context">
- <child>
- <object class="GtkAction" id="StageChangesAction">
- <property name="label" translatable="yes">Stage</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="UnstageChangesAction">
- <property name="label" translatable="yes">Unstage</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="RevertChangesAction">
- <property name="label" translatable="yes">Revert</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="IgnoreFileAction">
- <property name="label" translatable="yes">Ignore</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="EditFileAction">
- <property name="stock-id">gtk-edit</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="DeleteFileAction">
- <property name="stock-id">gtk-delete</property>
- </object>
- </child>
- </object>
- </child>
- <ui>
- <popup name="popup_commit_stage">
- <menuitem action="StageChangesAction"/>
- <menuitem action="RevertChangesAction"/>
- <menuitem action="IgnoreFileAction"/>
- <menuitem action="EditFileAction"/>
- <menuitem action="DeleteFileAction"/>
- </popup>
- <popup name="popup_commit_unstage">
- <menuitem action="UnstageChangesAction"/>
- <menuitem action="EditFileAction"/>
- </popup>
- </ui>
- </object>
-</interface>
-
-<!-- vi:ts=2:et -->
diff --git a/gitg/gitg-commit-view.c b/gitg/gitg-commit-view.c
deleted file mode 100644
index bda199e..0000000
--- a/gitg/gitg-commit-view.c
+++ /dev/null
@@ -1,3216 +0,0 @@
-/*
- * gitg-commit-view.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <gtksourceview/gtksourceview.h>
-#include <gtksourceview/gtksourcelanguagemanager.h>
-#include <gtksourceview/gtksourcestyleschememanager.h>
-#include <gtksourceview/gtksourcegutterrendererpixbuf.h>
-#include <glib/gi18n.h>
-#include <string.h>
-#include <libgitg/gitg-commit.h>
-#include <libgitg/gitg-shell.h>
-
-#include "gitg-commit-view.h"
-#include "gitg-diff-view.h"
-#include "gitg-utils.h"
-
-#define GITG_COMMIT_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GITG_TYPE_COMMIT_VIEW, GitgCommitViewPrivate))
-
-#define CATEGORY_UNSTAGE_HUNK "CategoryUnstageHunk"
-#define CATEGORY_STAGE_HUNK "CategoryStageHunk"
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_REPOSITORY,
- PROP_CONTEXT_SIZE
-};
-
-enum
-{
- COLUMN_NAME = 0,
- COLUMN_FILE,
- N_COLUMNS
-};
-
-typedef enum
-{
- CONTEXT_TYPE_FILE,
- CONTEXT_TYPE_HUNK
-} ContextType;
-
-struct _GitgCommitViewPrivate
-{
- GitgCommit *commit;
- GitgRepository *repository;
-
- GtkListStore *store_unstaged;
- GtkListStore *store_staged;
-
- GtkTreeView *tree_view_staged;
- GtkTreeView *tree_view_unstaged;
-
- GtkSourceView *changes_view;
- GtkTextView *comment_view;
- GtkSourceGutterRenderer *pixbuf_renderer;
- GtkCheckButton *check_button_signed_off_by;
- GtkCheckButton *check_button_amend;
-
- GtkHScale *hscale_context;
- gint context_size;
-
- GitgShell *shell;
- guint update_id;
- gboolean is_diff;
-
- GdkCursor *hand;
- GitgChangedFile *current_file;
- GitgChangedFileChanges current_changes;
-
- GtkUIManager *ui_manager;
- ContextType context_type;
- GtkTextIter context_iter;
-
- GtkActionGroup *group_context;
- GtkTextMark *highlight_mark;
- GtkTextTag *highlight_tag;
-
- GSettings *message_settings;
- GSettings *diff_settings;
-};
-
-static void gitg_commit_view_buildable_iface_init (GtkBuildableIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GitgCommitView, gitg_commit_view, GTK_TYPE_VPANED, 0,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gitg_commit_view_buildable_iface_init));
-
-static GtkBuildableIface parent_iface;
-
-static void on_commit_file_inserted (GitgCommit *commit,
- GitgChangedFile *file,
- GitgCommitView *view);
-static void on_commit_file_removed (GitgCommit *commit,
- GitgChangedFile *file,
- GitgCommitView *view);
-
-static void on_staged_button_press (GtkWidget *widget,
- GdkEventButton *event,
- GitgCommitView *view);
-static void on_unstaged_button_press (GtkWidget *widget,
- GdkEventButton *event,
- GitgCommitView *view);
-static gboolean on_staged_unstaged_button_press_before (GtkWidget *widget,
- GdkEventButton *event,
- GitgCommitView *view);
-static void on_unstaged_tree_view_row_activated (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GitgCommitView *view);
-static void on_staged_tree_view_row_activated (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GitgCommitView *view);
-
-static gboolean popup_unstaged_menu (GitgCommitView *view,
- GdkEventButton *event);
-static gboolean popup_staged_menu (GitgCommitView *view,
- GdkEventButton *event);
-
-static gboolean on_staged_popup_menu (GtkWidget *widget,
- GitgCommitView *view);
-static gboolean on_unstaged_popup_menu (GtkWidget *widget,
- GitgCommitView *view);
-
-static gboolean on_staged_motion (GtkWidget *widget,
- GdkEventMotion *event,
- GitgCommitView *view);
-static gboolean on_unstaged_motion (GtkWidget *widget,
- GdkEventMotion *event,
- GitgCommitView *view);
-
-static void on_commit_clicked (GtkButton *button,
- GitgCommitView *view);
-static void on_context_value_changed (GtkHScale *scale,
- GitgCommitView *view);
-
-static void on_changes_view_popup_menu (GtkTextView *textview,
- GtkMenu *menu,
- GitgCommitView *view);
-
-static void on_stage_changes (GtkAction *action,
- GitgCommitView *view);
-static void on_revert_changes (GtkAction *action,
- GitgCommitView *view);
-static void on_ignore_file (GtkAction *action,
- GitgCommitView *view);
-static void on_unstage_changes (GtkAction *action,
- GitgCommitView *view);
-static void on_edit_file (GtkAction *action,
- GitgCommitView *view);
-static void on_delete_file (GtkAction *action,
- GitgCommitView *view);
-
-static void on_check_button_amend_toggled (GtkToggleButton *button,
- GitgCommitView *view);
-
-static void pixbuf_renderer_query_data_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState state,
- GitgCommitView *view);
-static gboolean pixbuf_renderer_query_activatable_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *iter,
- GdkRectangle *area,
- GdkEvent *event,
- GitgCommitView *view);
-static void pixbuf_renderer_activate_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *iter,
- GdkRectangle *area,
- GdkEvent *event,
- GitgCommitView *view);
-
-static void
-gitg_commit_view_finalize (GObject *object)
-{
- GitgCommitView *view = GITG_COMMIT_VIEW (object);
-
- if (view->priv->update_id)
- {
- g_signal_handler_disconnect (view->priv->shell, view->priv->update_id);
- }
-
- gitg_io_cancel (GITG_IO (view->priv->shell));
- g_object_unref (view->priv->shell);
- g_object_unref (view->priv->ui_manager);
-
- g_object_unref (view->priv->hand);
-
- G_OBJECT_CLASS (gitg_commit_view_parent_class)->finalize (object);
-}
-
-static void
-icon_data_func (GtkTreeViewColumn *column,
- GtkCellRenderer *renderer,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GitgCommitView *view)
-{
- GitgChangedFile *file;
-
- gtk_tree_model_get (model, iter, COLUMN_FILE, &file, -1);
- GitgChangedFileStatus status = gitg_changed_file_get_status (file);
-
- gboolean staged = (model == GTK_TREE_MODEL (view->priv->store_staged));
-
- switch (status)
- {
- case GITG_CHANGED_FILE_STATUS_NEW:
- g_object_set (renderer,
- "stock-id",
- staged ? GTK_STOCK_ADD : GTK_STOCK_NEW,
- NULL);
- break;
- case GITG_CHANGED_FILE_STATUS_MODIFIED:
- g_object_set (renderer,
- "stock-id",
- staged ? GTK_STOCK_APPLY : GTK_STOCK_EDIT,
- NULL);
- break;
- case GITG_CHANGED_FILE_STATUS_DELETED:
- g_object_set (renderer,
- "stock-id",
- staged ? GTK_STOCK_REMOVE : GTK_STOCK_DELETE,
- NULL);
- break;
- default:
- break;
- }
-
- g_object_unref (file);
-}
-
-static void
-set_icon_data_func (GitgCommitView *view,
- GtkTreeView *treeview,
- GtkCellRenderer *renderer)
-{
- GtkTreeViewColumn *column = gtk_tree_view_get_column (treeview, 0);
-
- gtk_tree_view_column_set_cell_data_func (column,
- renderer,
- (GtkTreeCellDataFunc)icon_data_func,
- view,
- NULL);
-}
-
-static void
-set_language (GitgCommitView *view,
- GtkSourceLanguage *language)
-{
- GtkTextView *text_view;
- GtkSourceBuffer *buffer;
-
- text_view = GTK_TEXT_VIEW (view->priv->changes_view);
- buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (text_view));
-
- gtk_source_buffer_set_language (buffer, language);
- gitg_diff_view_set_diff_enabled (GITG_DIFF_VIEW (view->priv->changes_view),
- FALSE);
-}
-
-static void
-set_diff_language (GitgCommitView *view)
-{
- GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default ();
- GtkSourceLanguage *language = gtk_source_language_manager_get_language (manager, "gitgdiff");
-
- set_language (view, language);
- gitg_diff_view_set_diff_enabled (GITG_DIFF_VIEW (view->priv->changes_view), TRUE);
- gtk_widget_set_sensitive (GTK_WIDGET (view->priv->hscale_context), TRUE);
-}
-
-static void
-show_binary_information (GitgCommitView *view)
-{
- set_language (view, NULL);
-
- gtk_widget_set_sensitive (GTK_WIDGET (view->priv->hscale_context), FALSE);
-
- gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view->priv->changes_view)),
- _("Cannot display file content as text"),
- -1);
-}
-
-static void
-on_changes_update (GitgShell *shell,
- gchar **buffer,
- GitgCommitView *view)
-{
- gchar *line;
- GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view->priv->changes_view));
- GtkTextIter iter;
-
- gtk_text_buffer_get_end_iter (buf, &iter);
-
- while ((line = *(buffer++)))
- {
- if (view->priv->is_diff && g_str_has_prefix (line, "@@"))
- {
- if (view->priv->current_changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED)
- {
- gtk_source_buffer_create_source_mark (GTK_SOURCE_BUFFER (buf),
- NULL,
- CATEGORY_STAGE_HUNK,
- &iter);
- }
- else
- {
- gtk_source_buffer_create_source_mark (GTK_SOURCE_BUFFER (buf),
- NULL,
- CATEGORY_UNSTAGE_HUNK,
- &iter);
- }
- }
-
- gtk_text_buffer_insert (buf, &iter, line, -1);
- }
-
- if (gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buf)) == NULL)
- {
- gchar *content_type = gitg_utils_guess_content_type (GTK_TEXT_BUFFER (buf));
-
- if (content_type && !gitg_utils_can_display_content_type (content_type))
- {
- gitg_io_cancel (GITG_IO (shell));
- show_binary_information (view);
- }
- else if (content_type)
- {
- GtkSourceLanguage *language = gitg_utils_get_language (NULL, content_type);
- set_language (view, language);
- gtk_widget_set_sensitive (GTK_WIDGET (view->priv->hscale_context), FALSE);
- }
-
- g_free (content_type);
- }
-
- while (gtk_events_pending ())
- {
- gtk_main_iteration ();
- }
-}
-
-static void
-connect_update (GitgCommitView *view)
-{
- view->priv->update_id = g_signal_connect (view->priv->shell,
- "update",
- G_CALLBACK (on_changes_update),
- view);
-}
-
-static void
-set_current_file (GitgCommitView *view,
- GitgChangedFile *file,
- GitgChangedFileChanges changes)
-{
- if (view->priv->current_file != NULL)
- {
- g_object_unref (view->priv->current_file);
- }
-
- view->priv->current_file = file ? g_object_ref (file) : NULL;
- view->priv->current_changes = changes;
-}
-
-static gboolean
-get_selected_files (GtkTreeView *tree_view,
- GList **files,
- GList **paths,
- GitgChangedFileChanges *changes,
- GitgChangedFileStatus *status)
-{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
-
- if (files == NULL && changes == NULL && status == NULL && paths == NULL)
- {
- return gtk_tree_selection_count_selected_rows (selection) != 0;
- }
-
- GtkTreeModel *model;
- GList *items = gtk_tree_selection_get_selected_rows (selection, &model);
-
- if (files)
- {
- *files = NULL;
- }
-
- if (paths)
- {
- *paths = NULL;
- }
-
- if (!items)
- {
- return FALSE;
- }
-
- if (changes)
- {
- *changes = ~0;
- }
-
- if (status)
- {
- *status = -1;
- }
-
- GList *item;
- GitgChangedFile *file;
-
- for (item = items; item; item = g_list_next (item))
- {
- GtkTreeIter iter;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)item->data);
- gtk_tree_model_get (model, &iter, COLUMN_FILE, &file, -1);
-
- if (changes)
- {
- *changes &= gitg_changed_file_get_status (file);
- }
-
- GitgChangedFileStatus s = gitg_changed_file_get_status (file);
-
- if (status)
- {
- if (*status != -1 && *status != s)
- {
- *status = GITG_CHANGED_FILE_STATUS_NONE;
- }
- else
- *status = s;
- }
-
- if (files)
- {
- *files = g_list_prepend (*files, file);
- }
- else
- {
- g_object_unref (file);
- }
- }
-
- if (paths)
- {
- *paths = items;
- }
- else
- {
- g_list_free_full (items, (GDestroyNotify)gtk_tree_path_free);
- }
-
- if (files)
- {
- *files = g_list_reverse (*files);
- }
-
- return TRUE;
-}
-
-static gboolean
-check_selection (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- GitgCommitView *view)
-{
- if (view->priv->update_id)
- {
- g_signal_handler_disconnect (view->priv->shell, view->priv->update_id);
- }
-
- gitg_io_cancel (GITG_IO (view->priv->shell));
- view->priv->update_id = 0;
-
- GtkTextView *tv = GTK_TEXT_VIEW (view->priv->changes_view);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (tv);
- GtkTextIter start;
- GtkTextIter end;
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
-
- gtk_source_buffer_remove_source_marks (GTK_SOURCE_BUFFER (buffer),
- &start,
- &end,
- CATEGORY_UNSTAGE_HUNK);
-
- gtk_source_buffer_remove_source_marks (GTK_SOURCE_BUFFER (buffer),
- &start,
- &end,
- CATEGORY_STAGE_HUNK);
-
- gtk_text_buffer_set_text (gtk_text_view_get_buffer (tv), "", -1);
-
- GList *paths;
- gboolean ret;
- get_selected_files (tree_view, NULL, &paths, NULL, NULL);
-
- if (g_list_length (paths) != 1)
- {
- set_current_file (view, NULL, GITG_CHANGED_FILE_CHANGES_NONE);
- gtk_widget_set_sensitive (GTK_WIDGET (view->priv->hscale_context),
- FALSE);
- ret = FALSE;
- }
- else
- {
- if (iter)
- {
- gtk_tree_model_get_iter (gtk_tree_view_get_model (tree_view),
- iter,
- (GtkTreePath *)paths->data);
- }
-
- ret = TRUE;
- }
-
- g_list_free_full (paths, (GDestroyNotify)gtk_tree_path_free);
- return ret;
-}
-
-static void
-unselect_tree_view (GtkTreeView *view)
-{
- gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (view));
-}
-
-static void
-unstaged_selection_changed (GtkTreeSelection *selection,
- GitgCommitView *view)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if (!check_selection (view->priv->tree_view_unstaged, &iter, view))
- {
- return;
- }
-
- model = gtk_tree_view_get_model (view->priv->tree_view_unstaged);
- unselect_tree_view (view->priv->tree_view_staged);
-
- GitgChangedFile *file;
-
- gtk_tree_model_get (model, &iter, COLUMN_FILE, &file, -1);
- GitgChangedFileStatus status = gitg_changed_file_get_status (file);
- GFile *f = gitg_changed_file_get_file (file);
-
- if (status == GITG_CHANGED_FILE_STATUS_NEW)
- {
- gchar *content_type = gitg_utils_get_content_type (f);
-
- if (!gitg_utils_can_display_content_type (content_type))
- {
- show_binary_information (view);
- }
- else
- {
- GInputStream *stream = G_INPUT_STREAM (g_file_read (f, NULL, NULL));
-
- if (!stream)
- {
- show_binary_information (view);
- }
- else
- {
- gchar *basename = g_file_get_basename (f);
- GtkSourceLanguage *language;
-
- language = gitg_utils_get_language (basename,
- content_type);
- g_free (basename);
-
- set_language (view, language);
- gtk_widget_set_sensitive (GTK_WIDGET (view->priv->hscale_context),
- FALSE);
-
- view->priv->is_diff = FALSE;
- connect_update (view);
-
- gitg_shell_run_stream (view->priv->shell,
- stream,
- NULL);
-
- g_object_unref (stream);
- }
- }
-
- g_free (content_type);
- }
- else
- {
- gboolean allow_external;
-
- set_diff_language (view);
- view->priv->is_diff = TRUE;
- connect_update (view);
-
- gchar *path = gitg_repository_relative (view->priv->repository, f);
-
- gchar ct[10];
- g_snprintf (ct, sizeof (ct), "-U%d", view->priv->context_size);
-
- allow_external = g_settings_get_boolean (view->priv->diff_settings,
- "external");
-
- gitg_shell_run (view->priv->shell,
- gitg_command_new (view->priv->repository,
- "diff",
- allow_external ? "--ext-diff" : "--no-ext-diff",
- "--no-color",
- ct,
- "--",
- path,
- NULL),
- NULL);
-
- g_free (path);
- }
-
- set_current_file (view, file, GITG_CHANGED_FILE_CHANGES_UNSTAGED);
-
- g_object_unref (file);
- g_object_unref (f);
-}
-
-static void
-staged_selection_changed (GtkTreeSelection *selection,
- GitgCommitView *view)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if (!check_selection (view->priv->tree_view_staged, &iter, view))
- {
- return;
- }
-
- model = gtk_tree_view_get_model (view->priv->tree_view_staged);
- unselect_tree_view (view->priv->tree_view_unstaged);
-
- GitgChangedFile *file;
-
- gtk_tree_model_get (model, &iter, COLUMN_FILE, &file, -1);
- GitgChangedFileStatus status = gitg_changed_file_get_status (file);
-
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (view->priv->repository, f);
-
- if (status == GITG_CHANGED_FILE_STATUS_NEW)
- {
- view->priv->is_diff = FALSE;
-
- gchar *content_type = gitg_utils_get_content_type (f);
-
- if (!gitg_utils_can_display_content_type (content_type))
- {
- show_binary_information (view);
- }
- else
- {
- gtk_widget_set_sensitive (GTK_WIDGET (view->priv->hscale_context),
- FALSE);
-
- connect_update (view);
-
- gchar *indexpath = g_strconcat (":0:", path, NULL);
- gitg_shell_run (view->priv->shell,
- gitg_command_new (view->priv->repository,
- "show",
- "--encoding=UTF-8",
- "--no-color",
- indexpath,
- NULL),
- NULL);
-
- g_free (indexpath);
- }
-
- g_free (content_type);
- }
- else
- {
- gboolean allow_external;
-
- view->priv->is_diff = TRUE;
- set_diff_language (view);
- connect_update (view);
-
- gchar *head = gitg_repository_parse_head (view->priv->repository);
- gchar ct[10];
- g_snprintf (ct, sizeof (ct), "-U%d", view->priv->context_size);
-
- allow_external = g_settings_get_boolean (view->priv->diff_settings,
- "external");
-
- gitg_shell_run (view->priv->shell,
- gitg_command_new (view->priv->repository,
- "diff-index",
- allow_external ? "--ext-diff" : "--no-ext-diff",
- ct,
- "--cached",
- "--no-color",
- head,
- "--",
- path,
- NULL),
- NULL);
-
- g_free (head);
- }
-
- g_object_unref (f);
- g_free (path);
-
- set_current_file (view, file, GITG_CHANGED_FILE_CHANGES_CACHED);
- g_object_unref (file);
-}
-
-static gint
-compare_by_name (GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- gpointer userdata)
-{
- gchar *s1;
- gchar *s2;
-
- gtk_tree_model_get (model, a, COLUMN_NAME, &s1, -1);
- gtk_tree_model_get (model, b, COLUMN_NAME, &s2, -1);
-
- gint ret = gitg_utils_sort_names (s1, s2);
-
- g_free (s1);
- g_free (s2);
-
- return ret;
-}
-
-static void
-set_sort_func (GtkListStore *store)
-{
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
- 0,
- GTK_SORT_ASCENDING);
-
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
- 0,
- compare_by_name,
- NULL,
- NULL);
-}
-
-static gboolean
-has_hunk_mark (GtkSourceBuffer *buffer,
- GtkTextIter *iter)
-{
- GSList *m1;
- gboolean has_mark;
-
- m1 = gtk_source_buffer_get_source_marks_at_iter (buffer,
- iter,
- CATEGORY_UNSTAGE_HUNK);
-
- has_mark = (m1 != NULL);
- g_slist_free (m1);
-
- if (has_mark)
- {
- return TRUE;
- }
-
- m1 = gtk_source_buffer_get_source_marks_at_iter (buffer,
- iter,
- CATEGORY_STAGE_HUNK);
-
- has_mark = (m1 != NULL);
- g_slist_free (m1);
-
- return has_mark;
-}
-
-static gchar *
-get_patch_header (GitgCommitView *view,
- GtkTextBuffer *buffer,
- GtkTextIter const *iter)
-{
- GtkTextIter begin;
- GtkTextIter end;
- GitgDiffIter diff_iter;
-
- if (!gitg_diff_view_get_header_at_iter (GITG_DIFF_VIEW (view->priv->changes_view),
- iter,
- &diff_iter))
- {
- return NULL;
- }
-
- gitg_diff_iter_get_bounds (&diff_iter, &begin, &end);
-
- return gtk_text_buffer_get_text (buffer, &begin, &end, TRUE);
-}
-
-static gchar *
-get_patch_contents (GitgCommitView *view,
- GtkTextBuffer *buffer,
- GtkTextIter const *iter)
-{
- GtkTextIter begin;
- GtkTextIter end;
- GitgDiffIter diff_iter;
-
- if (!gitg_diff_view_get_hunk_at_iter (GITG_DIFF_VIEW (view->priv->changes_view),
- iter,
- &diff_iter))
- {
- return NULL;
- }
-
- gitg_diff_iter_get_bounds (&diff_iter, &begin, &end);
-
- return gtk_text_buffer_get_text (buffer, &begin, &end, FALSE);
-}
-
-static gchar *
-get_hunk_patch (GitgCommitView *view,
- GtkTextIter *iter)
-{
- /* Get patch header */
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view->priv->changes_view));
- gchar *header = get_patch_header (view, buffer, iter);
-
- if (!header)
- {
- return NULL;
- }
-
- /* Get patch contents */
- gchar *contents = get_patch_contents (view, buffer, iter);
-
- if (!contents)
- {
- g_free (header);
- return NULL;
- }
-
- return g_strconcat (header, contents, NULL);
-}
-
-static gchar *
-line_patch_contents (GitgCommitView *view,
- GtkTextIter const *iter,
- GitgDiffLineType old_type,
- GitgDiffLineType new_type)
-{
- GtkTextIter start;
- GtkTextIter end;
- GtkTextIter patch_iter = *iter;
- GitgDiffView *diff_view = GITG_DIFF_VIEW (view->priv->changes_view);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (diff_view));
- GitgDiffIter diff_iter;
-
- gtk_text_iter_set_line_offset (&patch_iter, 0);
-
- if (!gitg_diff_view_get_hunk_at_iter (diff_view, &patch_iter, &diff_iter))
- {
- return NULL;
- }
-
- gitg_diff_iter_get_bounds (&diff_iter, &start, &end);
- GtkTextIter begin = start;
-
- GString *patch = g_string_new ("");
- gchar *header = NULL;
- gint count_old = 0;
- gint count_new = 0;
-
- while (gtk_text_iter_compare (&start, &end) < 0)
- {
- GitgDiffLineType line_type;
- gboolean is_patch_line;
-
- line_type = gitg_diff_view_get_line_type (diff_view, &start);
-
- is_patch_line = gtk_text_iter_equal (&start, &patch_iter);
-
- gchar *text;
- GtkTextIter line_end = start;
- gtk_text_iter_forward_to_line_end (&line_end);
-
- if (gtk_text_iter_equal (&start, &begin))
- {
- header = gtk_text_buffer_get_text (buffer, &start, &line_end, TRUE);
- }
- else
- {
- if (line_type == old_type && !is_patch_line)
- {
- /* Take over like it was context */
- g_string_append_c (patch, ' ');
-
- if (!gtk_text_iter_ends_line (&start))
- {
- gtk_text_iter_forward_char (&start);
- }
- }
-
- if (line_type == GITG_DIFF_LINE_TYPE_NONE ||
- line_type == old_type || is_patch_line)
- {
- /* copy context */
- gtk_text_iter_forward_line (&line_end);
- text = gtk_text_buffer_get_text (buffer, &start, &line_end, TRUE);
-
- g_string_append (patch, text);
-
- if (!is_patch_line || line_type == GITG_DIFF_LINE_TYPE_REMOVE)
- {
- ++count_old;
- }
-
- if (!is_patch_line || line_type == GITG_DIFF_LINE_TYPE_ADD)
- {
- ++count_new;
- }
-
- g_free (text);
- }
- }
-
- if (!gtk_text_iter_forward_line (&start))
- {
- break;
- }
- }
-
- gchar *head = gitg_utils_rewrite_hunk_counters (header, count_old, count_new);
- g_free (header);
- gchar *ret = NULL;
-
- if (head)
- {
- gchar *contents = g_string_free (patch, FALSE);
- ret = g_strconcat (head, "\n", contents, NULL);
-
- g_free (contents);
- g_free (head);
- }
-
- return ret;
-}
-
-static gboolean
-stage_unstage_hunk (GitgCommitView *view,
- gchar const *hunk,
- GError **error)
-{
- gboolean ret;
- gboolean unstage = view->priv->current_changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED;
-
- if (unstage)
- {
- ret = gitg_commit_stage (view->priv->commit,
- view->priv->current_file,
- hunk,
- error);
- }
- else
- {
- ret = gitg_commit_unstage (view->priv->commit,
- view->priv->current_file,
- hunk,
- error);
- }
-
- return ret;
-}
-
-static gboolean
-handle_stage_unstage_line (GitgCommitView *view,
- GtkTextIter const *iter)
-{
- GitgDiffView *diff_view = GITG_DIFF_VIEW (view->priv->changes_view);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view->priv->changes_view));
- gchar *header = get_patch_header (view, buffer, iter);
- GitgDiffLineType old_type;
- GitgDiffLineType new_type;
-
- if (!header)
- {
- return FALSE;
- }
-
- GitgDiffIter diff_iter;
-
- if (!gitg_diff_view_get_header_at_iter (diff_view, iter, &diff_iter))
- {
- g_free (header);
- return FALSE;
- }
-
- if (view->priv->current_changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED)
- {
- old_type = GITG_DIFF_LINE_TYPE_REMOVE;
- new_type = GITG_DIFF_LINE_TYPE_ADD;
- }
- else
- {
- old_type = GITG_DIFF_LINE_TYPE_ADD;
- new_type = GITG_DIFF_LINE_TYPE_REMOVE;
- }
-
- gchar *contents = line_patch_contents (view, iter, old_type, new_type);
-
- if (!contents)
- {
- g_free (header);
- return FALSE;
- }
-
- gboolean ret;
- GitgChangedFile *file = g_object_ref (view->priv->current_file);
- GError *error = NULL;
- gchar *hunk = g_strconcat (header, contents, NULL);
-
- g_free (contents);
- g_free (header);
-
- ret = stage_unstage_hunk (view, hunk, &error);
-
- if (ret && file == view->priv->current_file)
- {
- gitg_diff_view_clear_line (GITG_DIFF_VIEW (view->priv->changes_view),
- iter,
- old_type,
- new_type);
- }
- else if (!ret)
- {
- g_warning ("Could not stage/unstage: %s", error->message);
- g_error_free (error);
- }
-
- g_free (hunk);
- g_object_unref (file);
-
- return ret;
-}
-
-static gboolean
-handle_stage_unstage (GitgCommitView *view,
- GtkTextIter *iter)
-{
- gchar *hunk = get_hunk_patch (view, iter);
-
- if (!hunk)
- {
- return FALSE;
- }
-
- gboolean ret;
- GitgChangedFile *file = g_object_ref (view->priv->current_file);
- GError *error = NULL;
-
- ret = stage_unstage_hunk (view, hunk, &error);
-
- if (ret && file == view->priv->current_file)
- {
- /* remove hunk from text view */
- gitg_diff_view_remove_hunk (GITG_DIFF_VIEW (view->priv->changes_view), iter);
- }
- else if (!ret)
- {
- g_warning ("Could not stage/unstage: %s", error->message);
- g_error_free (error);
- }
-
- g_object_unref (file);
- g_free (hunk);
-
- return ret;
-}
-
-static gboolean
-get_info_at_pointer (GitgCommitView *view,
- GtkTextIter *iter,
- gboolean *is_hunk,
- gchar **hunk,
- GitgDiffLineType *line_type)
-{
- GtkTextView *textview = GTK_TEXT_VIEW (view->priv->changes_view);
- gint x;
- gint y;
- gint width;
- gint height;
- gint buf_x;
- gint buf_y;
-
- /* Get where the pointer really is. */
- GdkWindow *win = gtk_text_view_get_window (textview, GTK_TEXT_WINDOW_TEXT);
-
- gdk_window_get_pointer (win, &x, &y, NULL);
-
- width = gdk_window_get_width (win);
- height = gdk_window_get_height (win);
-
- if (x < 0 || y < 0 || x > width || y > height)
- {
- return FALSE;
- }
-
- /* Get the iter where the cursor is at */
- gtk_text_view_window_to_buffer_coords (textview, GTK_TEXT_WINDOW_TEXT, x, y, &buf_x, &buf_y);
- gtk_text_view_get_iter_at_location (textview, iter, buf_x, buf_y);
-
- gtk_text_iter_set_line_offset (iter, 0);
-
- GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (textview));
-
- if (is_hunk)
- {
- *is_hunk = has_hunk_mark (buffer, iter);
-
- if (*is_hunk && hunk)
- {
- *hunk = get_hunk_patch (view, iter);
- }
- }
-
- if (line_type)
- {
- *line_type = gitg_diff_view_get_line_type (GITG_DIFF_VIEW (view->priv->changes_view),
- iter);
- }
-
- return TRUE;
-}
-
-static void
-unset_highlight (GitgCommitView *view)
-{
- if (!view->priv->highlight_mark)
- {
- return;
- }
-
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view->priv->changes_view));
- GtkTextIter start;
- GtkTextIter end;
-
- gtk_text_buffer_get_iter_at_mark (buffer, &start, view->priv->highlight_mark);
- end = start;
-
- gtk_text_iter_forward_to_line_end (&end);
-
- gtk_text_buffer_remove_tag (buffer, view->priv->highlight_tag, &start, &end);
-
- gtk_text_buffer_delete_mark (buffer, view->priv->highlight_mark);
- view->priv->highlight_mark = NULL;
-}
-
-static void
-set_highlight (GitgCommitView *view,
- GtkTextIter *iter)
-{
- if (!view->priv->highlight_tag)
- {
- return;
- }
-
- GtkTextIter start = *iter;
- GtkTextBuffer *buffer = gtk_text_iter_get_buffer (iter);
-
- gtk_text_iter_set_line_offset (&start, 0);
-
- if (view->priv->highlight_mark != NULL)
- {
- GtkTextIter mark_iter;
- gtk_text_buffer_get_iter_at_mark (buffer,
- &mark_iter,
- view->priv->highlight_mark);
-
- if (gtk_text_iter_equal (&start, &mark_iter))
- {
- return;
- }
-
- unset_highlight (view);
- }
-
- view->priv->highlight_mark = gtk_text_buffer_create_mark (buffer,
- NULL,
- &start,
- TRUE);
-
- GtkTextIter end = start;
- gtk_text_iter_forward_to_line_end (&end);
-
- gtk_text_buffer_apply_tag (buffer,
- view->priv->highlight_tag,
- &start,
- &end);
-}
-
-static gboolean
-gutter_event (GtkWidget *widget,
- GdkEventAny *event,
- GitgCommitView *view)
-{
- GtkTextView *textview = GTK_TEXT_VIEW (view->priv->changes_view);
- gint x;
- gint y;
- gint width;
- gint height;
- gint buf_x;
- gint buf_y;
- GtkTextIter iter;
- GitgDiffLineType line_type;
- GtkSourceGutter *gutter;
- GtkSourceGutterRenderer *renderer_at_pos;
-
- /* Get where the pointer really is. */
- GdkWindow *win = gtk_text_view_get_window (textview, GTK_TEXT_WINDOW_LEFT);
-
- gdk_window_get_pointer (win, &x, &y, NULL);
-
- width = gdk_window_get_width (win);
- height = gdk_window_get_height (win);
-
- if (x < 0 || y < 0 || x > width || y > height)
- {
- unset_highlight (view);
- gdk_window_set_cursor (event->window, NULL);
- return FALSE;
- }
-
- /* Get the iter where the cursor is at */
- gtk_text_view_window_to_buffer_coords (textview, GTK_TEXT_WINDOW_LEFT, x, y, &buf_x, &buf_y);
- gtk_text_view_get_iter_at_location (textview, &iter, buf_x, buf_y);
-
- gtk_text_iter_set_line_offset (&iter, 0);
-
- line_type = gitg_diff_view_get_line_type (GITG_DIFF_VIEW (view->priv->changes_view),
- &iter);
-
- gutter = gtk_source_view_get_gutter (view->priv->changes_view,
- GTK_TEXT_WINDOW_LEFT);
- renderer_at_pos = gtk_source_gutter_get_renderer_at_pos (gutter, x, y);
-
- if (renderer_at_pos == view->priv->pixbuf_renderer &&
- (line_type == GITG_DIFF_LINE_TYPE_ADD ||
- line_type == GITG_DIFF_LINE_TYPE_REMOVE))
- {
- set_highlight (view, &iter);
- gdk_window_set_cursor (event->window, view->priv->hand);
- }
- else
- {
- unset_highlight (view);
- gdk_window_set_cursor (event->window, NULL);
- }
-
- return FALSE;
-}
-
-static gboolean
-view_event (GtkWidget *widget,
- GdkEventAny *event,
- GitgCommitView *view)
-{
- GtkTextWindowType type;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- gboolean is_hunk = FALSE;
-
- type = gtk_text_view_get_window_type (GTK_TEXT_VIEW (widget), event->window);
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
-
- if (type == GTK_TEXT_WINDOW_LEFT)
- {
- return gutter_event (widget, event, view);
- }
-
- if (type == GTK_TEXT_WINDOW_TEXT && event->type == GDK_LEAVE_NOTIFY)
- {
- unset_highlight (view);
- gdk_window_set_cursor (event->window, NULL);
- return FALSE;
- }
-
- get_info_at_pointer (view, &iter, &is_hunk, NULL, NULL);
-
- if (event->type == GDK_LEAVE_NOTIFY ||
- event->type == GDK_MOTION_NOTIFY ||
- event->type == GDK_BUTTON_PRESS ||
- event->type == GDK_BUTTON_RELEASE ||
- event->type == GDK_ENTER_NOTIFY)
- {
- if (is_hunk)
- {
- set_highlight (view, &iter);
- gdk_window_set_cursor (event->window, view->priv->hand);
- }
- else
- {
- unset_highlight (view);
- gdk_window_set_cursor (event->window, NULL);
- }
- }
-
- if (type == GTK_TEXT_WINDOW_TEXT &&event->type == GDK_BUTTON_RELEASE &&
- ((GdkEventButton *) event)->button == 1 && is_hunk &&
- !gtk_text_buffer_get_has_selection (buffer))
- {
- if (handle_stage_unstage (view, &iter))
- {
- unset_highlight (view);
- gdk_window_set_cursor (event->window, NULL);
- }
- }
-
- return FALSE;
-}
-
-static GtkTextBuffer *
-initialize_buffer (GitgCommitView *view)
-{
- GtkTextBuffer *buffer = GTK_TEXT_BUFFER (gtk_source_buffer_new (NULL));
-
- GtkSourceStyleSchemeManager *manager = gtk_source_style_scheme_manager_get_default ();
- GtkSourceStyleScheme *scheme = gtk_source_style_scheme_manager_get_scheme (manager, "gitg");
- gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (buffer), scheme);
-
- return buffer;
-}
-
-static GtkTargetEntry dnd_entries[] = {
- {"text/uri-list", 0, 1}
-};
-
-static void
-on_tree_view_drag_data_get (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection,
- guint info,
- guint time,
- GitgCommitView *view)
-{
- GList *selected;
- GList *item;
- gchar **uris;
- guint i = 0;
-
- get_selected_files (GTK_TREE_VIEW (widget), &selected, NULL, NULL, NULL);
- uris = g_new (gchar *, g_list_length (selected) + 1);
-
- for (item = selected; item; item = g_list_next (item))
- {
- GitgChangedFile *file = GITG_CHANGED_FILE (item->data);
- GFile *gf = gitg_changed_file_get_file (file);
-
- uris[i++] = g_file_get_uri (gf);
- g_object_unref (gf);
- }
-
- uris[i] = NULL;
- gtk_selection_data_set_uris (selection, uris);
-
- g_strfreev (uris);
-
- g_list_free_full (selected, g_object_unref);
-}
-
-static void
-on_tree_view_staged_drag_data_received (GtkWidget *widget,
- GdkDragContext *drag_context,
- gint x,
- gint y,
- GtkSelectionData *data,
- guint info,
- guint time,
- GitgCommitView *view)
-{
- /* Stage all the files dropped on this */
- gchar **uris = gtk_selection_data_get_uris (data);
- gchar **uri;
-
- for (uri = uris; *uri; ++uri)
- {
- GFile *file = g_file_new_for_uri (*uri);
- GitgChangedFile *f;
-
- f = gitg_commit_find_changed_file (view->priv->commit, file);
-
- if (f && (gitg_changed_file_get_changes (f) & GITG_CHANGED_FILE_CHANGES_UNSTAGED))
- {
- gitg_commit_stage (view->priv->commit, f, NULL, NULL);
- }
-
- g_object_unref (f);
- g_object_unref (file);
- }
-}
-
-static void
-on_tree_view_unstaged_drag_data_received (GtkWidget *widget,
- GdkDragContext *drag_context,
- gint x,
- gint y,
- GtkSelectionData *data,
- guint info,
- guint time,
- GitgCommitView *view)
-{
- /* Unstage all the files dropped on this */
- gchar **uris = gtk_selection_data_get_uris (data);
- gchar **uri;
-
- for (uri = uris; *uri; ++uri)
- {
- GFile *file = g_file_new_for_uri (*uri);
- GitgChangedFile *f;
-
- f = gitg_commit_find_changed_file (view->priv->commit, file);
-
- if (f && (gitg_changed_file_get_changes (f) & GITG_CHANGED_FILE_CHANGES_CACHED))
- {
- gitg_commit_unstage (view->priv->commit, f, NULL, NULL);
- }
-
- g_object_unref (f);
- g_object_unref (file);
- }
-}
-
-static void
-initialize_dnd (GitgCommitView *view,
- GtkTreeView *tree_view,
- GCallback drag_data_received)
-{
- gtk_tree_view_enable_model_drag_dest (tree_view,
- dnd_entries,
- G_N_ELEMENTS (dnd_entries),
- GDK_ACTION_COPY);
-
- gtk_tree_view_enable_model_drag_source (tree_view,
- GDK_BUTTON1_MASK,
- dnd_entries,
- G_N_ELEMENTS (dnd_entries),
- GDK_ACTION_COPY);
-
- g_signal_connect (tree_view,
- "drag-data-get",
- G_CALLBACK (on_tree_view_drag_data_get),
- view);
-
- g_signal_connect (tree_view,
- "drag-data-received",
- G_CALLBACK (drag_data_received),
- view);
-}
-
-static void
-initialize_dnd_staged (GitgCommitView *view)
-{
- initialize_dnd (view,
- view->priv->tree_view_staged,
- G_CALLBACK (on_tree_view_staged_drag_data_received));
-}
-
-static void
-initialize_dnd_unstaged (GitgCommitView *view)
-{
- initialize_dnd (view,
- view->priv->tree_view_unstaged,
- G_CALLBACK (on_tree_view_unstaged_drag_data_received));
-}
-
-static void
-on_tag_added (GtkTextTagTable *table,
- GtkTextTag *tag,
- GitgCommitView *view)
-{
- gtk_text_tag_set_priority (view->priv->highlight_tag,
- gtk_text_tag_table_get_size (table) - 1);
-}
-
-/* Copied from GtkSourceView's gtksourceviewgutterrenderermarks.c */
-static int
-measure_line_height (GtkSourceView *view)
-{
- PangoLayout *layout;
- gint height = 12;
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), "QWERTY");
-
- if (layout)
- {
- pango_layout_get_pixel_size (layout, NULL, &height);
- g_object_unref (layout);
- }
-
- return height - 2;
-}
-
-static void
-gitg_commit_view_parser_finished (GtkBuildable *buildable,
- GtkBuilder *builder)
-{
- GtkSourceMarkAttributes *attrs;
- GtkSourceGutter *gutter;
-
- if (parent_iface.parser_finished)
- {
- parent_iface.parser_finished (buildable, builder);
- }
-
- /* Store widgets */
- GitgCommitView *self = GITG_COMMIT_VIEW (buildable);
-
- GtkBuilder *b = gitg_utils_new_builder ("gitg-commit-menu.ui");
- self->priv->ui_manager = g_object_ref (gtk_builder_get_object (b, "uiman"));
-
- g_signal_connect (gtk_builder_get_object (b, "StageChangesAction"),
- "activate",
- G_CALLBACK (on_stage_changes),
- self);
-
- g_signal_connect (gtk_builder_get_object (b, "RevertChangesAction"),
- "activate",
- G_CALLBACK (on_revert_changes),
- self);
-
- g_signal_connect (gtk_builder_get_object (b, "IgnoreFileAction"),
- "activate",
- G_CALLBACK (on_ignore_file),
- self);
-
- g_signal_connect (gtk_builder_get_object (b, "UnstageChangesAction"),
- "activate",
- G_CALLBACK (on_unstage_changes),
- self);
-
- g_signal_connect (gtk_builder_get_object (b, "EditFileAction"),
- "activate",
- G_CALLBACK (on_edit_file),
- self);
-
- g_signal_connect (gtk_builder_get_object (b, "DeleteFileAction"),
- "activate",
- G_CALLBACK (on_delete_file),
- self);
-
- self->priv->group_context = GTK_ACTION_GROUP (gtk_builder_get_object (b, "action_group_commit_context"));
-
- g_object_unref (b);
-
- self->priv->tree_view_unstaged = GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_unstaged"));
- self->priv->tree_view_staged = GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_staged"));
-
- self->priv->store_unstaged = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, GITG_TYPE_CHANGED_FILE);
- self->priv->store_staged = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, GITG_TYPE_CHANGED_FILE);
-
- set_sort_func (self->priv->store_unstaged);
- set_sort_func (self->priv->store_staged);
-
- self->priv->changes_view = GTK_SOURCE_VIEW (gtk_builder_get_object (builder, "source_view_changes"));
-
- gtk_widget_add_events (GTK_WIDGET (self->priv->changes_view),
- GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK);
-
- self->priv->comment_view = GTK_TEXT_VIEW (gtk_builder_get_object (builder, "text_view_comment"));
- self->priv->check_button_signed_off_by = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "check_button_signed_off_by"));
- self->priv->check_button_amend = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "check_button_amend"));
-
- g_settings_bind (self->priv->message_settings,
- "show-right-margin",
- self->priv->comment_view,
- "show-right-margin",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (self->priv->message_settings,
- "right-margin-at",
- self->priv->comment_view,
- "right-margin-position",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- self->priv->hscale_context = GTK_HSCALE (gtk_builder_get_object (builder, "hscale_context"));
- gtk_range_set_value (GTK_RANGE (self->priv->hscale_context), 3);
-
- initialize_dnd_staged (self);
- initialize_dnd_unstaged (self);
-
- GtkIconTheme *theme = gtk_icon_theme_get_default ();
- GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (theme, GTK_STOCK_ADD, 12, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-
- if (pixbuf)
- {
- attrs = gtk_source_mark_attributes_new ();
- gtk_source_mark_attributes_set_pixbuf (attrs, pixbuf);
-
- gtk_source_view_set_mark_attributes (self->priv->changes_view,
- CATEGORY_STAGE_HUNK,
- attrs, 1);
-
- g_object_unref (pixbuf);
- g_object_unref (attrs);
- }
-
- pixbuf = gtk_icon_theme_load_icon (theme, GTK_STOCK_REMOVE, 12, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-
- if (pixbuf)
- {
- attrs = gtk_source_mark_attributes_new ();
- gtk_source_mark_attributes_set_pixbuf (attrs, pixbuf);
-
- gtk_source_view_set_mark_attributes (self->priv->changes_view,
- CATEGORY_UNSTAGE_HUNK,
- attrs, 2);
-
- g_object_unref (pixbuf);
- g_object_unref (attrs);
- }
-
- gitg_utils_set_monospace_font (GTK_WIDGET (self->priv->changes_view));
-
- GtkTextBuffer *buffer = initialize_buffer (self);
- gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->priv->changes_view), buffer);
- g_signal_connect (self->priv->changes_view, "event", G_CALLBACK (view_event), self);
-
- gtk_tree_view_set_model (self->priv->tree_view_unstaged, GTK_TREE_MODEL (self->priv->store_unstaged));
- gtk_tree_view_set_model (self->priv->tree_view_staged, GTK_TREE_MODEL (self->priv->store_staged));
-
- set_icon_data_func (self, self->priv->tree_view_unstaged, GTK_CELL_RENDERER (gtk_builder_get_object (builder, "unstaged_cell_renderer_icon")));
- set_icon_data_func (self, self->priv->tree_view_staged, GTK_CELL_RENDERER (gtk_builder_get_object (builder, "staged_cell_renderer_icon")));
-
- GtkSourceStyleScheme *scheme;
- GtkSourceStyle *style;
-
- scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
- style = gtk_source_style_scheme_get_style (scheme, "current-line");
-
- gchar *background = NULL;
- gboolean background_set = FALSE;
-
- gchar *foreground = NULL;
- gboolean foreground_set = FALSE;
-
- if (style)
- {
- g_object_get (style,
- "line-background",
- &background,
- "line-background-set",
- &background_set,
- "foreground",
- &foreground,
- "foreground-set",
- &foreground_set,
- NULL);
-
- if (!background_set)
- {
- g_object_get (style,
- "background",
- &background,
- "background-set",
- &background_set,
- NULL);
- }
- }
-
- if (background_set)
- {
- self->priv->highlight_tag = gtk_text_buffer_create_tag (buffer,
- NULL,
- "paragraph-background",
- background,
- "foreground",
- foreground,
- "foreground-set",
- foreground_set,
- NULL);
-
- gtk_text_tag_set_priority (self->priv->highlight_tag,
- gtk_text_tag_table_get_size (gtk_text_buffer_get_tag_table (buffer)) - 1);
-
- g_signal_connect (gtk_text_buffer_get_tag_table (buffer),
- "tag-added",
- G_CALLBACK (on_tag_added),
- self);
- }
-
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (self->priv->tree_view_unstaged);
-
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (selection, "changed", G_CALLBACK (unstaged_selection_changed), self);
-
- selection = gtk_tree_view_get_selection (self->priv->tree_view_staged);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (selection, "changed", G_CALLBACK (staged_selection_changed), self);
-
- g_signal_connect (self->priv->tree_view_unstaged,
- "event-after",
- G_CALLBACK (on_unstaged_button_press),
- self);
-
- g_signal_connect (self->priv->tree_view_staged,
- "event-after",
- G_CALLBACK (on_staged_button_press),
- self);
-
- g_signal_connect (self->priv->tree_view_unstaged,
- "button-press-event",
- G_CALLBACK (on_staged_unstaged_button_press_before),
- self);
-
- g_signal_connect (self->priv->tree_view_staged,
- "button-press-event",
- G_CALLBACK (on_staged_unstaged_button_press_before),
- self);
-
- g_signal_connect (self->priv->tree_view_unstaged,
- "row-activated",
- G_CALLBACK (on_unstaged_tree_view_row_activated),
- self);
- g_signal_connect (self->priv->tree_view_staged,
- "row-activated",
- G_CALLBACK (on_staged_tree_view_row_activated),
- self);
-
- g_signal_connect (self->priv->tree_view_unstaged,
- "popup-menu",
- G_CALLBACK (on_unstaged_popup_menu),
- self);
-
- g_signal_connect (self->priv->tree_view_staged,
- "popup-menu",
- G_CALLBACK (on_staged_popup_menu),
- self);
-
- g_signal_connect (self->priv->changes_view,
- "populate-popup",
- G_CALLBACK (on_changes_view_popup_menu),
- self);
-
- g_signal_connect (self->priv->tree_view_unstaged,
- "motion-notify-event",
- G_CALLBACK (on_unstaged_motion),
- self);
-
- g_signal_connect (self->priv->tree_view_staged,
- "motion-notify-event",
- G_CALLBACK (on_staged_motion),
- self);
-
- g_signal_connect (gtk_builder_get_object (builder, "button_commit"),
- "clicked",
- G_CALLBACK (on_commit_clicked),
- self);
-
- g_signal_connect (self->priv->hscale_context,
- "value-changed",
- G_CALLBACK (on_context_value_changed),
- self);
-
- g_signal_connect (self->priv->check_button_amend,
- "toggled",
- G_CALLBACK (on_check_button_amend_toggled),
- self);
-
- gutter = gtk_source_view_get_gutter (self->priv->changes_view,
- GTK_TEXT_WINDOW_LEFT);
-
- self->priv->pixbuf_renderer = gtk_source_gutter_renderer_pixbuf_new ();
- g_object_set (self->priv->pixbuf_renderer, "xpad", 4, NULL);
-
- gtk_source_gutter_insert (gutter, self->priv->pixbuf_renderer, 1);
- gtk_source_gutter_renderer_set_size (self->priv->pixbuf_renderer,
- measure_line_height (GTK_SOURCE_VIEW (self->priv->changes_view)));
-
- g_signal_connect (self->priv->pixbuf_renderer,
- "query-data",
- G_CALLBACK (pixbuf_renderer_query_data_cb),
- self);
- g_signal_connect (self->priv->pixbuf_renderer,
- "query-activatable",
- G_CALLBACK (pixbuf_renderer_query_activatable_cb),
- self);
- g_signal_connect (self->priv->pixbuf_renderer,
- "activate",
- G_CALLBACK (pixbuf_renderer_activate_cb),
- self);
-}
-
-static void
-gitg_commit_view_buildable_iface_init (GtkBuildableIface *iface)
-{
- parent_iface = *iface;
-
- iface->parser_finished = gitg_commit_view_parser_finished;
-}
-
-static void
-gitg_commit_view_dispose (GObject *object)
-{
- GitgCommitView *self = GITG_COMMIT_VIEW (object);
-
- if (self->priv->message_settings)
- {
- g_object_unref (self->priv->message_settings);
- self->priv->message_settings = NULL;
- }
-
- if (self->priv->diff_settings)
- {
- g_object_unref (self->priv->diff_settings);
- self->priv->diff_settings = NULL;
- }
-
- if (self->priv->repository)
- {
- g_object_unref (self->priv->repository);
- self->priv->repository = NULL;
- }
-
- if (self->priv->commit)
- {
- g_signal_handlers_disconnect_by_func (self->priv->commit,
- on_commit_file_inserted,
- self);
-
- g_signal_handlers_disconnect_by_func (self->priv->commit,
- on_commit_file_removed,
- self);
-
- g_object_unref (self->priv->commit);
- self->priv->commit = NULL;
- }
-
- if (self->priv->pixbuf_renderer != NULL)
- {
- g_object_unref (self->priv->pixbuf_renderer);
- self->priv->pixbuf_renderer = NULL;
- }
-}
-
-static void
-gitg_commit_view_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgCommitView *self = GITG_COMMIT_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- g_value_set_object (value, self->priv->repository);
- break;
- case PROP_CONTEXT_SIZE:
- g_value_set_int (value, self->priv->context_size);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_commit_view_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgCommitView *self = GITG_COMMIT_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- self->priv->repository = g_value_dup_object (value);
- break;
- case PROP_CONTEXT_SIZE:
- self->priv->context_size = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-initialize_commit (GitgCommitView *self)
-{
- if (self->priv->commit)
- {
- return;
- }
-
- self->priv->commit = gitg_commit_new (self->priv->repository);
-
- g_signal_connect (self->priv->commit,
- "inserted",
- G_CALLBACK (on_commit_file_inserted),
- self);
-
- g_signal_connect (self->priv->commit,
- "removed",
- G_CALLBACK (on_commit_file_removed),
- self);
-
- gitg_commit_refresh (self->priv->commit);
-}
-
-static void
-gitg_commit_view_map (GtkWidget *widget)
-{
- GitgCommitView *self = GITG_COMMIT_VIEW (widget);
-
- GTK_WIDGET_CLASS (gitg_commit_view_parent_class)->map (widget);
-
- if (!self->priv->repository)
- {
- return;
- }
-
- initialize_commit (self);
-}
-
-static void
-gitg_commit_view_class_init (GitgCommitViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->finalize = gitg_commit_view_finalize;
- object_class->dispose = gitg_commit_view_dispose;
-
- widget_class->map = gitg_commit_view_map;
-
- object_class->set_property = gitg_commit_view_set_property;
- object_class->get_property = gitg_commit_view_get_property;
-
- g_object_class_install_property (object_class,
- PROP_REPOSITORY,
- g_param_spec_object ("repository",
- "REPOSITORY",
- "Repository",
- GITG_TYPE_REPOSITORY,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_CONTEXT_SIZE,
- g_param_spec_int ("context-size",
- "CONTEXT_SIZE",
- "Diff context size",
- 1,
- G_MAXINT,
- 3,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_type_class_add_private (object_class, sizeof (GitgCommitViewPrivate));
-}
-
-static void
-gitg_commit_view_init (GitgCommitView *self)
-{
- self->priv = GITG_COMMIT_VIEW_GET_PRIVATE (self);
-
- self->priv->message_settings =
- g_settings_new ("org.gnome.gitg.preferences.commit.message");
-
- self->priv->diff_settings =
- g_settings_new ("org.gnome.gitg.preferences.diff");
-
- self->priv->shell = gitg_shell_new (10000);
- gitg_shell_set_preserve_line_endings (self->priv->shell, TRUE);
-
- self->priv->hand = gdk_cursor_new (GDK_HAND1);
-}
-
-void
-gitg_commit_view_set_repository (GitgCommitView *view,
- GitgRepository *repository)
-{
- g_return_if_fail (GITG_IS_COMMIT_VIEW (view));
- g_return_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository));
-
- if (view->priv->repository)
- {
- g_object_unref (view->priv->repository);
- view->priv->repository = NULL;
- }
-
- if (view->priv->commit)
- {
- g_object_unref (view->priv->commit);
- view->priv->commit = NULL;
- }
-
- gtk_list_store_clear (view->priv->store_unstaged);
- gtk_list_store_clear (view->priv->store_staged);
-
- if (repository)
- {
- view->priv->repository = g_object_ref (repository);
- }
-
- if (gtk_widget_get_mapped (GTK_WIDGET (view)))
- {
- initialize_commit (view);
- }
-
- g_object_notify (G_OBJECT (view), "repository");
-}
-
-static void
-append_file (GtkListStore *store,
- GitgChangedFile *file,
- GitgCommitView *view)
-{
- GFile *f = gitg_changed_file_get_file (file);
- gchar *rel = gitg_repository_relative (view->priv->repository, f);
-
- GtkTreeIter iter;
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store,
- &iter,
- COLUMN_NAME,
- rel,
- COLUMN_FILE,
- file,
- -1);
-
- g_free (rel);
- g_object_unref (f);
-}
-
-/* Callbacks */
-static gboolean
-find_file_in_store (GtkListStore *store,
- GitgChangedFile *file,
- GtkTreeIter *iter)
-{
- GtkTreeModel *model = GTK_TREE_MODEL (store);
-
- if (!gtk_tree_model_get_iter_first (model, iter))
- {
- return FALSE;
- }
-
- do
- {
- GitgChangedFile *other;
- gtk_tree_model_get (model, iter, COLUMN_FILE, &other, -1);
- gboolean ret = (other == file);
-
- g_object_unref (other);
-
- if (ret)
- {
- return TRUE;
- }
- } while (gtk_tree_model_iter_next (model, iter));
-
- return FALSE;
-}
-
-static void
-model_row_changed (GtkListStore *store,
- GtkTreeIter *iter)
-{
- GtkTreePath *path;
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
-
- if (!path)
- {
- return;
- }
-
- gtk_tree_model_row_changed (GTK_TREE_MODEL (store), path, iter);
- gtk_tree_path_free (path);
-}
-
-static void
-on_commit_file_changed (GitgChangedFile *file,
- GParamSpec *spec,
- GitgCommitView *view)
-{
- GtkTreeIter staged;
- GtkTreeIter unstaged;
- gboolean isstaged;
- gboolean isunstaged;
-
- isstaged = find_file_in_store (view->priv->store_staged,
- file,
- &staged);
-
- isunstaged = find_file_in_store (view->priv->store_unstaged,
- file,
- &unstaged);
-
- if (isstaged)
- {
- model_row_changed (view->priv->store_staged, &staged);
- }
-
- if (isunstaged)
- {
- model_row_changed (view->priv->store_unstaged, &unstaged);
- }
-
- GitgChangedFileChanges changes = gitg_changed_file_get_changes (file);
-
- if (changes & GITG_CHANGED_FILE_CHANGES_CACHED)
- {
- if (!isstaged)
- {
- append_file (view->priv->store_staged, file, view);
- }
- }
- else
- {
- if (isstaged)
- {
- gtk_list_store_remove (view->priv->store_staged, &staged);
- }
- }
-
- if (changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED)
- {
- if (!isunstaged)
- {
- append_file (view->priv->store_unstaged, file, view);
- }
- }
- else
- {
- if (isunstaged)
- {
- gtk_list_store_remove (view->priv->store_unstaged,
- &unstaged);
- }
- }
-}
-
-static void
-on_commit_file_inserted (GitgCommit *commit,
- GitgChangedFile *file,
- GitgCommitView *view)
-{
- GitgChangedFileChanges changes;
-
- changes = gitg_changed_file_get_changes (file);
-
- if (changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED)
- {
- append_file (view->priv->store_unstaged, file, view);
- }
-
- if (changes & GITG_CHANGED_FILE_CHANGES_CACHED)
- {
- append_file (view->priv->store_staged, file, view);
- }
-
- g_signal_connect (file,
- "notify::changes",
- G_CALLBACK (on_commit_file_changed),
- view);
-
- g_signal_connect (file,
- "notify::status",
- G_CALLBACK (on_commit_file_changed),
- view);
-}
-
-static void
-on_commit_file_removed (GitgCommit *commit,
- GitgChangedFile *file,
- GitgCommitView *view)
-{
- GtkTreeIter iter;
-
- if (find_file_in_store (view->priv->store_staged, file, &iter))
- {
- gtk_list_store_remove (view->priv->store_staged, &iter);
- }
-
- if (find_file_in_store (view->priv->store_unstaged, file, &iter))
- {
- gtk_list_store_remove (view->priv->store_unstaged, &iter);
- }
-}
-
-static gboolean
-column_icon_test (GtkTreeView *view,
- gdouble ex,
- gdouble ey,
- GitgChangedFile **file)
-{
- GtkTreeViewColumn *column;
- gint x;
- gint y;
- GtkTreePath *path;
-
- gtk_tree_view_convert_widget_to_bin_window_coords (view,
- (gint)ex,
- (gint)ey,
- &x,
- &y);
-
- if (!gtk_tree_view_get_path_at_pos (view,
- x,
- y,
- &path,
- &column,
- NULL,
- NULL))
- {
- return FALSE;
- }
-
- if (column != gtk_tree_view_get_column (view, 0))
- {
- gtk_tree_path_free (path);
- return FALSE;
- }
-
- if (file)
- {
- GtkTreeModel *model = gtk_tree_view_get_model (view);
- GtkTreeIter iter;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, COLUMN_FILE, file, -1);
- }
-
- gtk_tree_path_free (path);
-
- return TRUE;
-}
-
-static gboolean
-on_staged_unstaged_button_press_before (GtkWidget *widget,
- GdkEventButton *event,
- GitgCommitView *view)
-{
- if (event->button == 1 &&
- column_icon_test (GTK_TREE_VIEW (widget),
- event->x,
- event->y,
- NULL))
- {
- /* Block selection by treeview when clicking on the icon */
- return TRUE;
- }
-
- if (event->button != 3)
- {
- return FALSE;
- }
-
- /* Check if it is important to keep the selection here */
- GtkTreeView *treeview = GTK_TREE_VIEW (widget);
- GtkTreePath *path;
-
- if (gtk_tree_view_get_path_at_pos (treeview,
- (gint)event->x,
- (gint)event->y,
- &path,
- NULL,
- NULL,
- NULL))
- {
- GtkTreeSelection *selection =
- gtk_tree_view_get_selection (treeview);
-
- if (gtk_tree_selection_path_is_selected (selection, path))
- {
- /* Block normal treeview behavior to unselect potential
- multiselection */
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-on_unstaged_tree_view_row_activated (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GitgCommitView *view)
-{
- GList *files = NULL;
-
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- gitg_commit_stage (view->priv->commit, files->data, NULL, NULL);
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
-}
-
-static void
-on_staged_tree_view_row_activated (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- GitgCommitView *view)
-{
- GList *files = NULL;
-
- get_selected_files (view->priv->tree_view_staged,
- &files,
- NULL,
- NULL,
- NULL);
-
- gitg_commit_unstage (view->priv->commit, files->data, NULL, NULL);
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
-}
-
-static void
-on_unstaged_button_press (GtkWidget *widget,
- GdkEventButton *event,
- GitgCommitView *view)
-{
- GitgChangedFile *file;
-
- if (event->type != GDK_BUTTON_PRESS)
- {
- return;
- }
-
- if (event->button == 1 &&
- column_icon_test (view->priv->tree_view_unstaged,
- event->x,
- event->y,
- &file))
- {
- GList *files = NULL;
-
- gitg_commit_stage (view->priv->commit, file, NULL, NULL);
-
- /* If the file is currently selected in the 'staged' tree,
- then refresh the diff */
- get_selected_files (view->priv->tree_view_staged,
- &files,
- NULL,
- NULL,
- NULL);
-
- if (files && !files->next)
- {
- GFile *f;
-
- f = gitg_changed_file_get_file (files->data);
-
- if (gitg_changed_file_equal (file, f))
- {
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (
- view->priv->tree_view_staged);
-
- staged_selection_changed (selection, view);
- }
-
- g_object_unref (f);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
- g_object_unref (file);
- }
- else if (event->button == 3)
- {
- view->priv->context_type = CONTEXT_TYPE_FILE;
- popup_unstaged_menu (view, event);
- }
-}
-
-static void
-on_staged_button_press (GtkWidget *widget,
- GdkEventButton *event,
- GitgCommitView *view)
-{
- GitgChangedFile *file;
-
- if (event->type != GDK_BUTTON_PRESS)
- {
- return;
- }
-
- if (event->button == 1 &&
- column_icon_test (view->priv->tree_view_staged,
- event->x,
- event->y,
- &file))
- {
- GList *files = NULL;
-
- gitg_commit_unstage (view->priv->commit, file, NULL, NULL);
-
- /* If the file is currently selected in the 'unstaged' tree,
- then refresh the diff */
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- if (files && !files->next)
- {
- GFile *f;
-
- f = gitg_changed_file_get_file (files->data);
-
- if (gitg_changed_file_equal (file, f))
- {
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (
- view->priv->tree_view_unstaged);
-
- unstaged_selection_changed (selection, view);
- }
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
- g_object_unref (file);
- }
- else if (event->button == 3)
- {
- view->priv->context_type = CONTEXT_TYPE_FILE;
- popup_staged_menu (view, event);
- }
-}
-
-static gboolean
-on_unstaged_motion (GtkWidget *widget,
- GdkEventMotion *event,
- GitgCommitView *view)
-{
- if (column_icon_test (view->priv->tree_view_unstaged,
- event->x,
- event->y,
- NULL))
- {
- gdk_window_set_cursor (gtk_widget_get_window (widget),
- view->priv->hand);
- }
- else
- {
- gdk_window_set_cursor (gtk_widget_get_window (widget), NULL);
- }
-
- return FALSE;
-}
-
-static gboolean
-on_staged_motion (GtkWidget *widget,
- GdkEventMotion *event,
- GitgCommitView *view)
-{
- if (column_icon_test (view->priv->tree_view_staged,
- event->x,
- event->y,
- NULL))
- {
- gdk_window_set_cursor (gtk_widget_get_window (widget),
- view->priv->hand);
- }
- else
- {
- gdk_window_set_cursor (gtk_widget_get_window (widget), NULL);
- }
-
- return FALSE;
-}
-
-static gchar *
-get_comment (GitgCommitView *view)
-{
- GtkTextBuffer *buffer;
- GtkTextIter start;
- GtkTextIter end;
-
- buffer = gtk_text_view_get_buffer (view->priv->comment_view);
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
- gchar *text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- gchar *ptr;
-
- for (ptr = text; *ptr; ptr = g_utf8_next_char (ptr))
- if (!g_unichar_isspace (g_utf8_get_char (ptr)))
- {
- return text;
- }
-
- g_free (text);
- return NULL;
-}
-
-static void
-show_error (GitgCommitView *view,
- gchar const *error)
-{
- GtkWidget *dlg;
-
- dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- "%s",
- error);
-
- gtk_dialog_run (GTK_DIALOG (dlg));
- gtk_widget_destroy (dlg);
-}
-
-static void
-on_commit_clicked (GtkButton *button,
- GitgCommitView *view)
-{
- gchar *comment;
- gboolean signoff;
- gboolean amend;
-
- if (!gitg_commit_has_changes (view->priv->commit))
- {
- show_error (view, _("You must first stage some changes before committing"));
- return;
- }
-
- comment = get_comment (view);
-
- if (!comment)
- {
- show_error (view, _("Please enter a commit message before committing"));
- return;
- }
-
- signoff = gtk_toggle_button_get_active (
- GTK_TOGGLE_BUTTON (view->priv->check_button_signed_off_by));
-
- amend = gtk_toggle_button_get_active (
- GTK_TOGGLE_BUTTON (view->priv->check_button_amend));
-
- GError *error = NULL;
-
- if (!gitg_commit_commit (view->priv->commit,
- comment,
- signoff,
- amend,
- &error))
- {
- if (error &&
- error->domain == GITG_COMMIT_ERROR &&
- error->code == GITG_COMMIT_ERROR_SIGNOFF)
- {
- show_error (view, _("Your user name or email could not be retrieved for use in the sign off message"));
- }
- else
- {
- gchar *msg;
-
- msg = g_strconcat (_("Something went wrong while trying to commit"),
- ":\n\n",
- error->message,
- NULL);
-
- show_error (view, msg);
- g_free (msg);
- }
-
- if (error)
- {
- g_error_free (error);
- }
- }
- else
- {
- gtk_text_buffer_set_text (
- gtk_text_view_get_buffer (view->priv->comment_view),
- "",
- -1);
-
- gtk_toggle_button_set_active (
- GTK_TOGGLE_BUTTON (view->priv->check_button_amend),
- FALSE);
-
- gtk_toggle_button_set_active (
- GTK_TOGGLE_BUTTON (view->priv->check_button_signed_off_by),
- FALSE);
- }
-
- g_free (comment);
-}
-
-static void
-on_context_value_changed (GtkHScale *scale,
- GitgCommitView *view)
-{
- view->priv->context_size = (gint)gtk_range_get_value (GTK_RANGE (scale));
-
- if (view->priv->current_changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED)
- {
- unstaged_selection_changed (
- gtk_tree_view_get_selection (view->priv->tree_view_unstaged),
- view);
- }
- else if (view->priv->current_changes & GITG_CHANGED_FILE_CHANGES_CACHED)
- {
- staged_selection_changed (
- gtk_tree_view_get_selection (view->priv->tree_view_staged),
- view);
- }
-}
-
-static gboolean
-set_unstaged_popup_status (GitgCommitView *view)
-{
- GitgChangedFileChanges changes;
- GitgChangedFileStatus status;
- GtkAction *revert;
- GtkAction *ignore;
- GtkAction *edit;
- GtkAction *delete;
-
- if (!get_selected_files (view->priv->tree_view_unstaged,
- NULL,
- NULL,
- &changes,
- &status))
- {
- return FALSE;
- }
-
- revert = gtk_ui_manager_get_action (view->priv->ui_manager,
- "/ui/popup_commit_stage/RevertChangesAction");
-
- ignore = gtk_ui_manager_get_action (view->priv->ui_manager,
- "/ui/popup_commit_stage/IgnoreFileAction");
-
- edit = gtk_ui_manager_get_action (view->priv->ui_manager,
- "/ui/popup_commit_stage/EditFileAction");
-
- delete = gtk_ui_manager_get_action (view->priv->ui_manager,
- "/ui/popup_commit_stage/DeleteFileAction");
-
- gtk_action_set_visible (revert, status == GITG_CHANGED_FILE_STATUS_MODIFIED ||
- status == GITG_CHANGED_FILE_STATUS_DELETED);
- gtk_action_set_visible (ignore, status == GITG_CHANGED_FILE_STATUS_NEW);
-
- gtk_action_set_visible (edit, status != GITG_CHANGED_FILE_STATUS_DELETED);
- gtk_action_set_visible (delete, status == GITG_CHANGED_FILE_STATUS_NEW);
-
- return TRUE;
-}
-
-static gboolean
-set_staged_popup_status (GitgCommitView *view)
-{
- GitgChangedFileStatus status;
- GtkAction *edit;
-
- if (!get_selected_files (view->priv->tree_view_staged,
- NULL,
- NULL,
- NULL,
- &status))
- {
- return FALSE;
- }
-
- edit = gtk_ui_manager_get_action (view->priv->ui_manager,
- "/ui/popup_commit_stage/EditFileAction");
-
- gtk_action_set_visible (edit, status != GITG_CHANGED_FILE_STATUS_DELETED);
-
- return TRUE;
-}
-
-static gboolean
-popup_unstaged_menu (GitgCommitView *view,
- GdkEventButton *event)
-{
- GtkWidget *wd;
-
- if (!set_unstaged_popup_status (view))
- {
- return FALSE;
- }
-
- wd = gtk_ui_manager_get_widget (view->priv->ui_manager,
- "/ui/popup_commit_stage");
-
- view->priv->context_type = CONTEXT_TYPE_FILE;
-
- if (event)
- {
- gtk_menu_popup (GTK_MENU (wd),
- NULL,
- NULL,
- NULL,
- NULL,
- event->button,
- event->time);
- }
- else
- {
- gtk_menu_popup (GTK_MENU (wd),
- NULL,
- NULL,
- gitg_utils_menu_position_under_tree_view,
- view->priv->tree_view_staged,
- 0,
- gtk_get_current_event_time ());
- }
-
- return TRUE;
-}
-
-static gboolean
-popup_staged_menu (GitgCommitView *view,
- GdkEventButton *event)
-{
- GtkWidget *wd;
-
- if (!set_staged_popup_status (view))
- {
- return FALSE;
- }
-
- wd = gtk_ui_manager_get_widget (view->priv->ui_manager,
- "/ui/popup_commit_unstage");
-
- view->priv->context_type = CONTEXT_TYPE_FILE;
-
- if (event)
- {
- gtk_menu_popup (GTK_MENU (wd),
- NULL,
- NULL,
- NULL,
- NULL,
- event->button,
- event->time);
- }
- else
- {
- gtk_menu_popup (GTK_MENU (wd),
- NULL,
- NULL,
- gitg_utils_menu_position_under_tree_view,
- view->priv->tree_view_unstaged,
- 0,
- gtk_get_current_event_time ());
- }
-
- return TRUE;
-}
-
-
-static gboolean
-on_unstaged_popup_menu (GtkWidget *widget,
- GitgCommitView *view)
-{
- return popup_unstaged_menu (view, NULL);
-}
-
-static gboolean
-on_staged_popup_menu (GtkWidget *widget,
- GitgCommitView *view)
-{
- return popup_staged_menu (view, NULL);
-}
-
-static void
-on_stage_changes (GtkAction *action,
- GitgCommitView *view)
-{
- if (view->priv->context_type == CONTEXT_TYPE_FILE)
- {
- GList *files = NULL;
- GList *item;
-
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- for (item = files; item; item = g_list_next (item))
- {
- gitg_commit_stage (view->priv->commit,
- GITG_CHANGED_FILE (item->data),
- NULL,
- NULL);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
- }
- else
- {
- handle_stage_unstage (view, &view->priv->context_iter);
- }
-}
-
-static void
-do_revert_changes (GitgCommitView *view)
-{
- gboolean ret = TRUE;
-
- if (view->priv->context_type == CONTEXT_TYPE_FILE)
- {
- GList *files = NULL;
- GList *item;
-
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- for (item = files; item; item = g_list_next (item))
- {
- ret &= gitg_commit_undo (view->priv->commit,
- GITG_CHANGED_FILE (item->data),
- NULL,
- NULL);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
- }
- else
- {
- GitgChangedFile *file;
- gchar *hunk;
-
- file = g_object_ref (view->priv->current_file);
-
- hunk = get_hunk_patch (view, &view->priv->context_iter);
-
- ret = gitg_commit_undo (view->priv->commit,
- view->priv->current_file,
- hunk,
- NULL);
-
- g_free (hunk);
-
- if (ret && view->priv->current_file == file)
- {
- gitg_diff_view_remove_hunk (GITG_DIFF_VIEW (view->priv->changes_view),
- &view->priv->context_iter);
- }
-
- g_object_unref (file);
- }
-
- if (!ret)
- {
- show_error (view, _("Revert fail"));
- }
-}
-
-static void
-on_revert_changes (GtkAction *action,
- GitgCommitView *view)
-{
- GtkWidget *dialog;
- gint response;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "%s",
- _("Are you sure you want to revert these changes?"));
-
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- "%s",
- _("Reverting changes is permanent and cannot be undone"));
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
-
- if (response == GTK_RESPONSE_YES)
- {
- do_revert_changes (view);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-on_edit_file (GtkAction *action,
- GitgCommitView *view)
-{
- GList *files = NULL;
- GList *item;
-
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- for (item = files; item; item = g_list_next (item))
- {
- GitgChangedFile *file = item->data;
-
- if (gitg_changed_file_get_status (file) ==
- GITG_CHANGED_FILE_STATUS_DELETED)
- {
- continue;
- }
-
- GFile *location = gitg_changed_file_get_file (file);
- gchar *uri = g_file_get_uri (location);
-
- gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (view)),
- uri,
- GDK_CURRENT_TIME,
- NULL);
-
- g_free (uri);
- g_object_unref (location);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
-}
-
-static void
-do_delete_file (GitgCommitView *view)
-{
- GList *files = NULL;
- GList *item;
- gboolean success = TRUE;
-
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- for (item = files; item; item = g_list_next (item))
- {
- GitgChangedFile *file = item->data;
- GFile *location = gitg_changed_file_get_file (file);
-
- success &= g_file_delete (location, NULL, NULL);
-
- g_object_unref (location);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
-
- gitg_commit_refresh (view->priv->commit);
-
- if (!success)
- {
- show_error (view, _("Delete Failed"));
- }
-}
-
-static void
-on_delete_file (GtkAction *action,
- GitgCommitView *view)
-{
- GtkWidget *toplevel;
- GtkWidget *dialog;
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "%s",
- _("Are you sure you want to delete these files?"));
-
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s",
- _("Deleting files is permanent "
- "and cannot be undone"));
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
- {
- do_delete_file (view);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-on_ignore_file (GtkAction *action,
- GitgCommitView *view)
-{
- GList *files = NULL;
- GList *item;
-
- get_selected_files (view->priv->tree_view_unstaged,
- &files,
- NULL,
- NULL,
- NULL);
-
- for (item = files; item; item = g_list_next (item))
- {
- gitg_commit_add_ignore (view->priv->commit,
- GITG_CHANGED_FILE (item->data),
- NULL);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
-}
-
-static void
-on_unstage_changes (GtkAction *action,
- GitgCommitView *view)
-{
- if (view->priv->context_type == CONTEXT_TYPE_FILE)
- {
- GList *files = NULL;
- GList *item;
-
- get_selected_files (view->priv->tree_view_staged,
- &files,
- NULL,
- NULL,
- NULL);
-
- for (item = files; item; item = g_list_next (item))
- {
- gitg_commit_unstage (view->priv->commit,
- GITG_CHANGED_FILE (item->data),
- NULL,
- NULL);
- }
-
- g_list_free_full (files, (GDestroyNotify)g_object_unref);
- }
- else
- {
- handle_stage_unstage (view, &view->priv->context_iter);
- }
-}
-
-static GtkWidget *
-create_context_menu_item (GitgCommitView *view,
- gchar const *action)
-{
- GtkAction *ac;
-
- ac = gtk_action_group_get_action (view->priv->group_context, action);
-
- return gtk_action_create_menu_item (ac);
-}
-
-static void
-on_changes_view_popup_menu (GtkTextView *textview,
- GtkMenu *menu,
- GitgCommitView *view)
-{
- gboolean is_hunk;
-
- get_info_at_pointer (view,
- &view->priv->context_iter,
- &is_hunk,
- NULL,
- NULL);
-
- if (!is_hunk)
- {
- return;
- }
-
- GtkWidget *separator = gtk_separator_menu_item_new ();
- gtk_widget_show (separator);
-
- view->priv->context_type = CONTEXT_TYPE_HUNK;
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), separator);
-
- if (view->priv->current_changes & GITG_CHANGED_FILE_CHANGES_CACHED)
- {
- GtkWidget *unstage;
-
- unstage = create_context_menu_item (view, "UnstageChangesAction");
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), unstage);
- }
- else
- {
- GtkWidget *stage;
- GtkWidget *revert;
-
- stage = create_context_menu_item (view, "StageChangesAction");
- revert = create_context_menu_item (view, "RevertChangesAction");
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), stage);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), revert);
- }
-}
-
-static void
-on_check_button_amend_toggled (GtkToggleButton *button,
- GitgCommitView *view)
-{
- gboolean active;
- GtkTextBuffer *buffer;
- GtkTextIter start;
- GtkTextIter end;
-
- active = gtk_toggle_button_get_active (button);
- buffer = gtk_text_view_get_buffer (view->priv->comment_view);
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
-
- if (active && gtk_text_iter_compare (&start, &end) == 0)
- {
- // Get last commit message
- gchar *message;
-
- message = gitg_commit_amend_message (view->priv->commit);
-
- if (message)
- {
- gtk_text_buffer_set_text (buffer, message, -1);
- }
-
- g_free (message);
- }
-}
-
-static void
-pixbuf_renderer_query_data_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState state,
- GitgCommitView *view)
-{
- GitgDiffView *diff_view;
- const gchar *stock_id;
-
- diff_view = GITG_DIFF_VIEW (view->priv->changes_view);
-
- switch (gitg_diff_view_get_line_type (diff_view, start))
- {
- case GITG_DIFF_LINE_TYPE_NONE:
- stock_id = GTK_STOCK_DISCARD;
- break;
- case GITG_DIFF_LINE_TYPE_ADD:
- stock_id = GTK_STOCK_ADD;
- break;
- case GITG_DIFF_LINE_TYPE_REMOVE:
- stock_id = GTK_STOCK_REMOVE;
- break;
- default:
- g_return_if_reached ();
- }
-
- g_object_set (renderer,
- "stock-id", stock_id,
- NULL);
-}
-
-static gboolean
-pixbuf_renderer_query_activatable_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *iter,
- GdkRectangle *area,
- GdkEvent *event,
- GitgCommitView *view)
-{
- GitgDiffView *diff_view = GITG_DIFF_VIEW (view->priv->changes_view);
- GitgDiffLineType line_type;
-
- line_type = gitg_diff_view_get_line_type (diff_view, iter);
-
- return line_type != GITG_DIFF_LINE_TYPE_NONE &&
- ((GdkEventButton *) event)->button == 1;
-}
-
-static void
-pixbuf_renderer_activate_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *iter,
- GdkRectangle *area,
- GdkEvent *event,
- GitgCommitView *view)
-{
- handle_stage_unstage_line (view, iter);
-}
diff --git a/gitg/gitg-commit-view.h b/gitg/gitg-commit-view.h
deleted file mode 100644
index a4cde9d..0000000
--- a/gitg/gitg-commit-view.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * gitg-commit-view.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_COMMIT_VIEW_H__
-#define __GITG_COMMIT_VIEW_H__
-
-#include <gtk/gtk.h>
-#include <libgitg/gitg-repository.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_COMMIT_VIEW (gitg_commit_view_get_type ())
-#define GITG_COMMIT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMIT_VIEW, GitgCommitView))
-#define GITG_COMMIT_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMIT_VIEW, GitgCommitView const))
-#define GITG_COMMIT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_COMMIT_VIEW, GitgCommitViewClass))
-#define GITG_IS_COMMIT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_COMMIT_VIEW))
-#define GITG_IS_COMMIT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_COMMIT_VIEW))
-#define GITG_COMMIT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_COMMIT_VIEW, GitgCommitViewClass))
-
-typedef struct _GitgCommitView GitgCommitView;
-typedef struct _GitgCommitViewClass GitgCommitViewClass;
-typedef struct _GitgCommitViewPrivate GitgCommitViewPrivate;
-
-struct _GitgCommitView
-{
- GtkVPaned parent;
-
- GitgCommitViewPrivate *priv;
-};
-
-struct _GitgCommitViewClass
-{
- GtkVPanedClass parent_class;
-};
-
-GType gitg_commit_view_get_type (void) G_GNUC_CONST;
-void gitg_commit_view_set_repository (GitgCommitView *view,
- GitgRepository *repository);
-
-G_END_DECLS
-
-#endif /* __GITG_COMMIT_VIEW_H__ */
diff --git a/gitg/gitg-diff-line-renderer.c b/gitg/gitg-diff-line-renderer.c
deleted file mode 100644
index e28eb8f..0000000
--- a/gitg/gitg-diff-line-renderer.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * gitg-diff-line-renderer.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-utils.h"
-#include "gitg-diff-line-renderer.h"
-
-#define GITG_DIFF_LINE_RENDERER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRendererPrivate))
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_LINE_OLD,
- PROP_LINE_NEW
-};
-
-struct _GitgDiffLineRendererPrivate
-{
- gint line_old;
- gint line_new;
- gint num_digits;
-
- PangoLayout *cached_layout;
- PangoAttribute *fg_attr;
- PangoAttrList *cached_attr_list;
-
- glong changed_handler_id;
-};
-
-G_DEFINE_TYPE (GitgDiffLineRenderer, gitg_diff_line_renderer, GTK_SOURCE_TYPE_GUTTER_RENDERER)
-
-static void
-gitg_diff_line_renderer_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgDiffLineRenderer *self = GITG_DIFF_LINE_RENDERER (object);
-
- switch (prop_id)
- {
- case PROP_LINE_OLD:
- self->priv->line_old = g_value_get_int (value);
- break;
- case PROP_LINE_NEW:
- self->priv->line_new = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_diff_line_renderer_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgDiffLineRenderer *self = GITG_DIFF_LINE_RENDERER (object);
-
- switch (prop_id)
- {
- case PROP_LINE_OLD:
- g_value_set_int (value, self->priv->line_old);
- break;
- case PROP_LINE_NEW:
- g_value_set_int (value, self->priv->line_new);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-create_layout (GitgDiffLineRenderer *renderer,
- GtkWidget *widget)
-{
- PangoLayout *layout;
- PangoAttribute *attr;
- GtkStyleContext *context;
- GdkRGBA color;
- PangoAttrList *attr_list;
-
- layout = gtk_widget_create_pango_layout (widget, NULL);
-
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-
- attr = pango_attr_foreground_new (color.red * 65535,
- color.green * 65535,
- color.blue * 65535);
-
- attr->start_index = 0;
- attr->end_index = G_MAXINT;
-
- attr_list = pango_attr_list_new ();
- pango_attr_list_insert (attr_list, attr);
-
- renderer->priv->fg_attr = attr;
- renderer->priv->cached_layout = layout;
- renderer->priv->cached_attr_list = attr_list;
-}
-
-static void
-gitg_diff_line_renderer_begin (GtkSourceGutterRenderer *renderer,
- cairo_t *cr,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkTextIter *start,
- GtkTextIter *end)
-{
- GitgDiffLineRenderer *lr = GITG_DIFF_LINE_RENDERER (renderer);
-
- create_layout (lr, GTK_WIDGET (gtk_source_gutter_renderer_get_view (renderer)));
-}
-
-static void
-gitg_diff_line_renderer_draw (GtkSourceGutterRenderer *renderer,
- cairo_t *ctx,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState renderer_state)
-{
- GitgDiffLineRenderer *lr = GITG_DIFF_LINE_RENDERER (renderer);
- gchar old_str[16];
- gchar new_str[16];
- PangoLayout *layout;
- GtkWidget *widget;
- GtkStyleContext *style_context;
- guint xpad = 0;
-
- /* Chain up to draw background */
- GTK_SOURCE_GUTTER_RENDERER_CLASS (
- gitg_diff_line_renderer_parent_class)->draw (renderer,
- ctx,
- background_area,
- cell_area,
- start,
- end,
- renderer_state);
-
- widget = GTK_WIDGET (gtk_source_gutter_renderer_get_view (renderer));
- layout = lr->priv->cached_layout;
-
- pango_layout_set_width (layout, cell_area->width / 2);
-
- pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
-
- if (lr->priv->line_old >= 0)
- {
- g_snprintf (old_str, sizeof (old_str), "%d", lr->priv->line_old);
- }
- else
- {
- *old_str = '\0';
- }
-
- if (lr->priv->line_new >= 0)
- {
- g_snprintf (new_str, sizeof (old_str), "%d", lr->priv->line_new);
- }
- else
- {
- *new_str = '\0';
- }
-
- g_object_get (renderer, "xpad", &xpad, NULL);
-
- pango_layout_set_text (layout, old_str, -1);
- style_context = gtk_widget_get_style_context (widget);
-
- gtk_render_layout (style_context,
- ctx,
- cell_area->x + cell_area->width / 2 - xpad,
- cell_area->y,
- layout);
-
- pango_layout_set_text (layout, new_str, -1);
- gtk_render_layout (style_context,
- ctx,
- cell_area->x + cell_area->width,
- cell_area->y,
- layout);
-
- gtk_render_line (style_context,
- ctx,
- background_area->x + background_area->width / 2,
- background_area->y - 1,
- background_area->x + background_area->width / 2,
- background_area->y + background_area->height);
-}
-
-static void
-gitg_diff_line_renderer_end (GtkSourceGutterRenderer *renderer)
-{
- GitgDiffLineRenderer *lr = GITG_DIFF_LINE_RENDERER (renderer);
-
- g_object_unref (lr->priv->cached_layout);
- lr->priv->cached_layout = NULL;
-
- pango_attr_list_unref (lr->priv->cached_attr_list);
- lr->priv->cached_attr_list = NULL;
-
- lr->priv->fg_attr = NULL;
-}
-
-static void
-measure_text (GitgDiffLineRenderer *lr,
- const gchar *markup,
- const gchar *text,
- gint *width,
- gint *height)
-{
- PangoLayout *layout;
- gint w;
- gint h;
- GtkSourceGutterRenderer *r;
- GtkTextView *view;
-
- r = GTK_SOURCE_GUTTER_RENDERER (lr);
- view = gtk_source_gutter_renderer_get_view (r);
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), NULL);
-
- if (markup)
- {
- pango_layout_set_markup (layout,
- markup,
- -1);
- }
- else
- {
- pango_layout_set_text (layout,
- text,
- -1);
- }
-
- pango_layout_get_size (layout, &w, &h);
-
- if (width)
- {
- *width = w / PANGO_SCALE;
- }
-
- if (height)
- {
- *height = h / PANGO_SCALE;
- }
-
- g_object_unref (layout);
-}
-
-static void
-recalculate_size (GitgDiffLineRenderer *lr)
-{
- gchar *markup;
- gint size;
- gint num = 1;
- gint i;
-
- for (i = 1; i < lr->priv->num_digits; ++i)
- {
- num *= 10;
- }
-
- markup = g_strdup_printf ("<b>%d %d</b>",
- num,
- num);
-
- measure_text (lr, markup, NULL, &size, NULL);
- g_free (markup);
-
- gtk_source_gutter_renderer_set_size (GTK_SOURCE_GUTTER_RENDERER (lr),
- size);
-}
-
-static void
-update_num_digits (GitgDiffLineRenderer *renderer,
- guint max_line_count)
-{
- /* Get size of this rendering */
- gint num_digits;
-
- num_digits = 0;
-
- while (max_line_count > 0)
- {
- max_line_count /= 10;
- ++num_digits;
- }
-
- num_digits = MAX (num_digits, 2);
-
- if (num_digits != renderer->priv->num_digits)
- {
- renderer->priv->num_digits = num_digits;
- recalculate_size (renderer);
- }
-}
-
-static void
-gitg_diff_line_renderer_class_init (GitgDiffLineRendererClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkSourceGutterRendererClass *renderer_class = GTK_SOURCE_GUTTER_RENDERER_CLASS (klass);
-
- renderer_class->begin = gitg_diff_line_renderer_begin;
- renderer_class->draw = gitg_diff_line_renderer_draw;
- renderer_class->end= gitg_diff_line_renderer_end;
-
- object_class->set_property = gitg_diff_line_renderer_set_property;
- object_class->get_property = gitg_diff_line_renderer_get_property;
-
- g_object_class_install_property (object_class,
- PROP_LINE_OLD,
- g_param_spec_int ("line-old",
- "Line Old",
- "Line Old",
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_LINE_NEW,
- g_param_spec_int ("line-new",
- "Line New",
- "Line New",
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_type_class_add_private (object_class, sizeof (GitgDiffLineRendererPrivate));
-}
-
-static void
-gitg_diff_line_renderer_init (GitgDiffLineRenderer *self)
-{
- self->priv = GITG_DIFF_LINE_RENDERER_GET_PRIVATE (self);
-}
-
-GitgDiffLineRenderer *
-gitg_diff_line_renderer_new ()
-{
- return g_object_new (GITG_TYPE_DIFF_LINE_RENDERER, NULL);
-}
-
-void
-gitg_diff_line_renderer_set_max_line_count (GitgDiffLineRenderer *renderer,
- guint max_line_count)
-{
- g_return_if_fail (GITG_IS_DIFF_LINE_RENDERER (renderer));
-
- update_num_digits (renderer, max_line_count);
-}
diff --git a/gitg/gitg-diff-line-renderer.h b/gitg/gitg-diff-line-renderer.h
deleted file mode 100644
index 1ffdad5..0000000
--- a/gitg/gitg-diff-line-renderer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * gitg-diff-line-renderer.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_DIFF_LINE_RENDERER_H__
-#define __GITG_DIFF_LINE_RENDERER_H__
-
-#include <gtksourceview/gtksourceview.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_DIFF_LINE_RENDERER (gitg_diff_line_renderer_get_type ())
-#define GITG_DIFF_LINE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRenderer))
-#define GITG_DIFF_LINE_RENDERER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRenderer const))
-#define GITG_DIFF_LINE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRendererClass))
-#define GITG_IS_DIFF_LINE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_DIFF_LINE_RENDERER))
-#define GITG_IS_DIFF_LINE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_DIFF_LINE_RENDERER))
-#define GITG_DIFF_LINE_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_DIFF_LINE_RENDERER, GitgDiffLineRendererClass))
-
-typedef struct _GitgDiffLineRenderer GitgDiffLineRenderer;
-typedef struct _GitgDiffLineRendererClass GitgDiffLineRendererClass;
-typedef struct _GitgDiffLineRendererPrivate GitgDiffLineRendererPrivate;
-
-struct _GitgDiffLineRenderer {
- GtkSourceGutterRenderer parent;
-
- GitgDiffLineRendererPrivate *priv;
-};
-
-struct _GitgDiffLineRendererClass {
- GtkSourceGutterRendererClass parent_class;
-};
-
-GType gitg_diff_line_renderer_get_type (void) G_GNUC_CONST;
-GitgDiffLineRenderer *gitg_diff_line_renderer_new (void);
-
-void gitg_diff_line_renderer_set_max_line_count (GitgDiffLineRenderer *renderer,
- guint max_line_count);
-
-G_END_DECLS
-
-#endif /* __GITG_DIFF_LINE_RENDERER_H__ */
diff --git a/gitg/gitg-diff-view.c b/gitg/gitg-diff-view.c
deleted file mode 100644
index 284a867..0000000
--- a/gitg/gitg-diff-view.c
+++ /dev/null
@@ -1,1633 +0,0 @@
-/*
- * gitg-diff-view.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-diff-view.h"
-#include "gitg-diff-line-renderer.h"
-#include "gitg-utils.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#define GITG_DIFF_VIEW_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_DIFF_VIEW, GitgDiffViewPrivate))
-
-#ifndef MAX
-#define MAX(a, b) (a > b ? a : b)
-#endif
-
-#ifndef MIN
-#define MIN(a, b) (a < b ? a : b)
-#endif
-
-#define IDLE_SCAN_COUNT 30
-
-#define GITG_DIFF_ITER_GET_VIEW(iter) ((GitgDiffView *) ((iter)->userdata))
-#define GITG_DIFF_ITER_GET_REGION(iter) ((Region *) ((iter)->userdata2))
-
-#define GITG_DIFF_ITER_SET_REGION(iter, region) ((iter)->userdata2 = region)
-#define GITG_DIFF_ITER_SET_VIEW(iter, view) ((iter)->userdata = view)
-
-static void on_buffer_insert_text (GtkTextBuffer *buffer,
- GtkTextIter *iter,
- gchar const *text,
- gint len,
- GitgDiffView *view);
-
-static void on_buffer_delete_range (GtkTextBuffer *buffer,
- GtkTextIter *start,
- GtkTextIter *end,
- GitgDiffView *view);
-
-/*static void
-line_renderer_size_func (GtkSourceGutter *gutter,
- GtkCellRenderer *cell,
- GitgDiffView *view);
-*/
-static void line_renderer_query_data_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState state,
- GitgDiffView *view);
-static void disable_diff_view (GitgDiffView *view);
-static void enable_diff_view (GitgDiffView *view);
-
-static gboolean on_idle_scan (GitgDiffView *view);
-
-/* Signals */
-enum
-{
- HEADER_ADDED,
- HUNK_ADDED,
- NUM_SIGNALS
-};
-
-/* Properties */
-enum
-{
- PROP_0,
-
- PROP_DIFF_ENABLED
-};
-
-typedef struct _Region Region;
-
-struct _Region
-{
- GitgDiffIterType type;
- Region *next;
- Region *prev;
-
- guint line;
- gboolean visible;
-};
-
-typedef struct
-{
- Region region;
-
- gchar index_from[GITG_HASH_SHA_SIZE + 1];
- gchar index_to[GITG_HASH_SHA_SIZE + 1];
-} Header;
-
-typedef struct
-{
- Region region;
- guint old;
- guint new;
-} Hunk;
-
-struct _GitgDiffViewPrivate
-{
- guint last_scan_line;
-
- guint max_line_count;
- Region *regions;
- Region *last_region;
- GSequence *regions_index;
-
- guint scan_id;
- gboolean diff_enabled;
- GtkTextBuffer *current_buffer;
- GtkTextTag *invisible_tag;
- GtkTextTag *subheader_tag;
-
- GitgDiffLineRenderer *line_renderer;
-
- Region *lines_current_region;
- gint lines_previous_line;
- guint lines_counters[2];
-
- gboolean ignore_changes;
-};
-
-G_DEFINE_TYPE (GitgDiffView, gitg_diff_view, GTK_SOURCE_TYPE_VIEW)
-
-static gboolean gitg_diff_view_draw (GtkWidget *widget, cairo_t *cr);
-static guint diff_view_signals[NUM_SIGNALS] = {0,};
-
-static void
-region_free (Region *region,
- gboolean all)
-{
- if (!region)
- {
- return;
- }
-
- if (all)
- {
- region_free (region->next, all);
- }
- else
- {
- if (region->next)
- {
- region->next->prev = region->prev;
- }
-
- if (region->prev)
- {
- region->prev->next = region->next;
- }
- }
-
- if (region->type == GITG_DIFF_ITER_TYPE_HEADER)
- {
- g_slice_free (Header, (Header *)region);
- }
- else
- {
- g_slice_free (Hunk, (Hunk *)region);
- }
-}
-
-static void
-set_max_line_count (GitgDiffView *view,
- guint max_line_count)
-{
- view->priv->max_line_count = max_line_count;
-
- if (view->priv->line_renderer)
- {
- gitg_diff_line_renderer_set_max_line_count (view->priv->line_renderer,
- max_line_count);
- }
-}
-
-static void
-regions_free (GitgDiffView *view)
-{
- region_free (view->priv->regions, TRUE);
-
- g_sequence_remove_range (g_sequence_get_begin_iter (view->priv->regions_index),
- g_sequence_get_end_iter (view->priv->regions_index));
-
- view->priv->regions = NULL;
- view->priv->last_region = NULL;
- view->priv->last_scan_line = 0;
-
- set_max_line_count (view, 99);
-}
-
-static void
-gitg_diff_view_finalize (GObject *object)
-{
- GitgDiffView *view = GITG_DIFF_VIEW (object);
-
- regions_free (view);
- g_sequence_free (view->priv->regions_index);
-
- G_OBJECT_CLASS (gitg_diff_view_parent_class)->finalize (object);
-}
-
-static void
-gitg_diff_view_dispose (GObject *object)
-{
- GitgDiffView *view = GITG_DIFF_VIEW (object);
-
- disable_diff_view (view);
-
- if (view->priv->line_renderer)
- {
- g_object_unref (view->priv->line_renderer);
- view->priv->line_renderer = NULL;
- }
-
- G_OBJECT_CLASS (gitg_diff_view_parent_class)->dispose (object);
-}
-
-static void
-set_diff_enabled (GitgDiffView *view,
- gboolean enabled)
-{
- if (enabled == view->priv->diff_enabled)
- {
- return;
- }
-
- if (enabled)
- {
- enable_diff_view (view);
- }
- else
- {
- disable_diff_view (view);
- }
-
- gtk_widget_queue_draw (GTK_WIDGET (view));
-}
-
-static void
-gitg_diff_view_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgDiffView *self = GITG_DIFF_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_DIFF_ENABLED:
- set_diff_enabled (self, g_value_get_boolean (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_diff_view_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgDiffView *self = GITG_DIFF_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_DIFF_ENABLED:
- g_value_set_boolean (value, self->priv->diff_enabled);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_diff_view_constructed (GObject *object)
-{
- g_object_set (object, "show-line-numbers", FALSE, NULL);
-
- G_OBJECT_CLASS (gitg_diff_view_parent_class)->constructed (object);
-}
-
-static void
-gitg_diff_view_class_init (GitgDiffViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->finalize = gitg_diff_view_finalize;
- object_class->dispose = gitg_diff_view_dispose;
- object_class->set_property = gitg_diff_view_set_property;
- object_class->get_property = gitg_diff_view_get_property;
-
- object_class->constructed = gitg_diff_view_constructed;
-
- widget_class->draw = gitg_diff_view_draw;
-
- diff_view_signals[HEADER_ADDED] =
- g_signal_new ("header-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgDiffViewClass, header_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE,
- 1,
- G_TYPE_POINTER);
-
- diff_view_signals[HUNK_ADDED] =
- g_signal_new ("hunk-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgDiffViewClass, hunk_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE,
- 1,
- G_TYPE_POINTER);
-
- g_object_class_install_property (object_class, PROP_DIFF_ENABLED,
- g_param_spec_boolean ("diff-enabled",
- "DIFF_ENABLED",
- "Enables diff view",
- FALSE,
- G_PARAM_READWRITE));
-
- g_type_class_add_private (object_class, sizeof (GitgDiffViewPrivate));
-}
-
-static void
-disable_diff_view (GitgDiffView *view)
-{
- if (!view->priv->diff_enabled)
- {
- return;
- }
-
- regions_free (view);
-
- if (view->priv->scan_id)
- {
- g_source_remove (view->priv->scan_id);
- view->priv->scan_id = 0;
- }
-
- if (view->priv->current_buffer)
- {
- GtkTextTagTable *table;
- GtkSourceGutter *gutter;
-
- table = gtk_text_buffer_get_tag_table (view->priv->current_buffer);
-
- g_signal_handlers_disconnect_by_func (view->priv->current_buffer,
- G_CALLBACK (on_buffer_insert_text),
- view);
-
- g_signal_handlers_disconnect_by_func (view->priv->current_buffer,
- G_CALLBACK (on_buffer_delete_range),
- view);
-
- gtk_text_tag_table_remove (table, view->priv->invisible_tag);
- gtk_text_tag_table_remove (table, view->priv->subheader_tag);
-
- g_object_unref (view->priv->current_buffer);
-
- view->priv->current_buffer = NULL;
- view->priv->invisible_tag = NULL;
- view->priv->subheader_tag = NULL;
-
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (view),
- GTK_TEXT_WINDOW_LEFT);
-
- gtk_source_gutter_remove (gutter,
- GTK_SOURCE_GUTTER_RENDERER (view->priv->line_renderer));
- }
-
- view->priv->diff_enabled = FALSE;
-}
-
-static void
-enable_diff_view (GitgDiffView *view)
-{
- GtkTextBuffer *buffer;
- GtkTextTagTable *table;
- GtkSourceGutter *gutter;
-
- if (view->priv->diff_enabled)
- {
- disable_diff_view (view);
- }
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- view->priv->current_buffer = g_object_ref (buffer);
-
- g_signal_connect_after (buffer,
- "insert-text",
- G_CALLBACK (on_buffer_insert_text),
- view);
-
- g_signal_connect_after (buffer,
- "delete-range",
- G_CALLBACK (on_buffer_delete_range),
- view);
-
- view->priv->scan_id = g_idle_add ( (GSourceFunc)on_idle_scan, view);
-
- view->priv->invisible_tag = gtk_text_buffer_create_tag (view->priv->current_buffer,
- "GitgHunkInvisible",
- "invisible",
- TRUE,
- NULL);
-
- view->priv->subheader_tag = gtk_text_buffer_create_tag (view->priv->current_buffer,
- "GitgHunkSubHeader",
- "invisible",
- TRUE,
- NULL);
-
- table = gtk_text_buffer_get_tag_table (view->priv->current_buffer);
-
- gtk_text_tag_set_priority (view->priv->subheader_tag,
- gtk_text_tag_table_get_size (table) - 1);
-
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (view),
- GTK_TEXT_WINDOW_LEFT);
-
- gtk_source_gutter_insert (gutter,
- GTK_SOURCE_GUTTER_RENDERER (view->priv->line_renderer),
- 0);
-
- g_signal_connect (view->priv->line_renderer,
- "query-data",
- (GCallback) line_renderer_query_data_cb,
- view);
-
- view->priv->diff_enabled = TRUE;
-}
-
-static void
-on_buffer_set (GitgDiffView *self, GParamSpec *spec, gpointer userdata)
-{
- if (self->priv->diff_enabled)
- {
- enable_diff_view (self);
- }
-}
-
-static void
-gitg_diff_view_init (GitgDiffView *self)
-{
- self->priv = GITG_DIFF_VIEW_GET_PRIVATE (self);
-
- self->priv->regions_index = g_sequence_new (NULL);
- self->priv->line_renderer = gitg_diff_line_renderer_new ();
-
- g_object_ref (self->priv->line_renderer);
- g_object_set (self->priv->line_renderer, "xpad", 2, NULL);
-
- g_signal_connect (self, "notify::buffer", G_CALLBACK (on_buffer_set), NULL);
-}
-
-GitgDiffView *
-gitg_diff_view_new ()
-{
- return g_object_new (GITG_TYPE_DIFF_VIEW, NULL);
-}
-
-static gint
-index_compare (gconstpointer a, gconstpointer b, gpointer userdata)
-{
- guint la = ( (Region *)a)->line;
- guint lb = ( (Region *)b)->line;
-
- return la < lb ? -1 : (la > lb ? 1 : 0);
-}
-
-static void
-ensure_max_line (GitgDiffView *view, Hunk *hunk)
-{
- guint num = hunk->region.next ? hunk->region.next->line - hunk->region.line : 0;
- guint m = MAX (hunk->new + num, hunk->old + num);
-
- if (m > view->priv->max_line_count)
- {
- set_max_line_count (view, m);
-
- gtk_source_gutter_queue_draw (gtk_source_view_get_gutter (GTK_SOURCE_VIEW (view), GTK_TEXT_WINDOW_LEFT));
- }
-}
-
-static void
-hide_header_details (GitgDiffView *view,
- Region *region)
-{
- /* Just hide the lines 2->n lines from region to region->next */
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- GtkTextIter startiter;
- GtkTextIter enditer;
-
- gint line = region->line + 2;
-
- gtk_text_buffer_get_iter_at_line (buffer, &startiter, line);
-
- enditer = startiter;
-
- if (region->next)
- {
- gtk_text_iter_forward_lines (&enditer, region->next->line - line);
- }
- else
- {
- gtk_text_iter_forward_line (&enditer);
- }
-
- gtk_text_buffer_apply_tag (buffer, view->priv->subheader_tag, &startiter, &enditer);
-}
-
-static void
-region_to_iter (GitgDiffView *view, Region *region, GitgDiffIter *iter)
-{
- GITG_DIFF_ITER_SET_VIEW (iter, view);
- GITG_DIFF_ITER_SET_REGION (iter, region);
-}
-
-static void
-add_region (GitgDiffView *view, Region *region)
-{
- if (view->priv->last_region)
- {
- view->priv->last_region->next = region;
- region->prev = view->priv->last_region;
-
- if (view->priv->last_region->type == GITG_DIFF_ITER_TYPE_HUNK)
- {
- ensure_max_line (view, (Hunk *)view->priv->last_region);
- }
- }
- else
- {
- view->priv->regions = region;
- region->prev = NULL;
- }
-
- view->priv->last_region = region;
-
- if (region->prev && region->prev->type == GITG_DIFF_ITER_TYPE_HEADER)
- {
- /* Hide header details if first hunk is scanned */
- hide_header_details (view, region->prev);
- }
-
- g_sequence_insert_sorted (view->priv->regions_index, region, index_compare, NULL);
-
- GitgDiffIter iter;
- region_to_iter (view, region, &iter);
-
- if (region->type == GITG_DIFF_ITER_TYPE_HEADER)
- {
- g_signal_emit (view, diff_view_signals[HEADER_ADDED], 0, &iter);
- }
- else if (region->type == GITG_DIFF_ITER_TYPE_HUNK)
- {
- g_signal_emit (view, diff_view_signals[HUNK_ADDED], 0, &iter);
- }
-}
-
-static void
-parse_hunk_info (Hunk *hunk, GtkTextIter *iter)
-{
- GtkTextIter end = *iter;
-
- gtk_text_iter_forward_to_line_end (&end);
- gchar *text = gtk_text_iter_get_text (iter, &end);
-
- hunk->old = 0;
- hunk->new = 0;
-
- gchar *old = g_utf8_strchr (text, -1, '-');
- gchar *new = g_utf8_strchr (text, -1, '+');
-
- if (!old || !new)
- {
- return;
- }
-
- hunk->old = atoi (old + 1);
- hunk->new = atoi (new + 1);
-
- g_free (text);
-}
-
-static void
-ensure_scan (GitgDiffView *view, guint last_line)
-{
- /* Scan from last_scan_line, making regions */
- GtkTextIter iter;
- GtkTextBuffer *buffer = view->priv->current_buffer;
- gtk_text_buffer_get_iter_at_line (buffer, &iter, view->priv->last_scan_line);
-
- while (view->priv->last_scan_line <= last_line)
- {
- GtkTextIter start = iter;
- GtkTextIter end = iter;
-
- if (!gtk_text_iter_forward_line (&iter))
- {
- break;
- }
-
- ++view->priv->last_scan_line;
-
- if (!gtk_text_iter_forward_chars (&end, 3))
- {
- continue;
- }
-
- gchar *text = gtk_text_iter_get_text (&start, &end);
-
- if (g_str_has_prefix (text, "@@ ") || g_str_has_prefix (text, "@@@"))
- {
- /* start new hunk region */
- Hunk *hunk = g_slice_new (Hunk);
- hunk->region.type = GITG_DIFF_ITER_TYPE_HUNK;
- hunk->region.line = view->priv->last_scan_line - 1;
- hunk->region.visible = TRUE;
-
- parse_hunk_info (hunk, &start);
-
- add_region (view, (Region *)hunk);
-
- g_free (text);
- continue;
- }
-
- g_free (text);
-
- if (!gtk_text_iter_forward_chars (&end, 7))
- {
- continue;
- }
-
- text = gtk_text_iter_get_text (&start, &end);
-
- if (g_str_has_prefix (text, "diff --git") || g_str_has_prefix (text, "diff --cc"))
- {
- /* start new header region */
- Header *header = g_slice_new (Header);
- header->region.type = GITG_DIFF_ITER_TYPE_HEADER;
- header->region.line = view->priv->last_scan_line - 1;
- header->region.visible = TRUE;
-
- header->index_to[0] = '\0';
- header->index_from[0] = '\0';
-
- add_region (view, (Region *)header);
- }
-
- g_free (text);
- }
-
- if (view->priv->last_region && view->priv->last_region->type == GITG_DIFF_ITER_TYPE_HUNK)
- {
- ensure_max_line (view, (Hunk *)view->priv->last_region);
- }
-}
-
-static Region *
-find_current_region (GitgDiffView *view, guint line)
-{
- GSequenceIter *iter;
- Region tmp = {0, NULL, NULL, line};
-
- iter = g_sequence_search (view->priv->regions_index, &tmp, index_compare, NULL);
-
- if (!iter || g_sequence_iter_is_begin (iter))
- {
- return NULL;
- }
-
- if (!g_sequence_iter_is_end (iter))
- {
- Region *ret = (Region *)g_sequence_get (iter);
-
- if (ret->line == line)
- {
- return ret->visible ? ret : NULL;
- }
- }
-
- Region *ret = (Region *)g_sequence_get (g_sequence_iter_prev (iter));
- return ret->visible ? ret : NULL;
-}
-
-static gboolean
-line_has_prefix (GitgDiffView *view, guint line, gchar const *prefix)
-{
- GtkTextIter iter;
-
- gtk_text_buffer_get_iter_at_line (view->priv->current_buffer, &iter, line);
-
- GtkTextIter end = iter;
-
- if (!gtk_text_iter_forward_chars (&end, g_utf8_strlen (prefix, -1)))
- {
- return FALSE;
- }
-
- gchar *text = gtk_text_iter_get_text (&iter, &end);
- gboolean ret = g_str_has_prefix (text, prefix);
- g_free (text);
-
- return ret;
-}
-
-static gboolean
-draw_old (GitgDiffView *view, guint line)
-{
- return !line_has_prefix (view, line, "+");
-}
-
-static gboolean
-draw_new (GitgDiffView *view, guint line)
-{
- return !line_has_prefix (view, line, "-");
-}
-
-static void
-get_initial_counters (GitgDiffView *view, Region *region, guint line, guint counters[2])
-{
- guint i;
-
- counters[0] = counters[1] = 0;
-
- for (i = region->line + 1; i < line; ++i)
- {
- if (draw_old (view, i))
- ++counters[0];
-
- if (draw_new (view, i))
- ++counters[1];
- }
-}
-
-static void
-line_renderer_query_data_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState state,
- GitgDiffView *view)
-{
- gint line_old = -1;
- gint line_new = -1;
- gint line_number;
- Region **current = &view->priv->lines_current_region;
-
- line_number = gtk_text_iter_get_line (start) + 1;
-
- ensure_scan (view, line_number);
-
- if (!*current || view->priv->lines_previous_line + 1 != line_number)
- {
- *current = find_current_region (view, line_number);
-
- if (*current)
- {
- get_initial_counters (view,
- *current,
- line_number,
- view->priv->lines_counters);
- }
- }
-
- view->priv->lines_previous_line = line_number;
-
- if (*current &&
- (*current)->type == GITG_DIFF_ITER_TYPE_HUNK &&
- line_number != (*current)->line)
- {
- Hunk *hunk = (Hunk *)*current;
-
- if (draw_old (view, line_number))
- {
- line_old = hunk->old + view->priv->lines_counters[0]++;
- }
-
- if (draw_new (view, line_number))
- {
- line_new = hunk->new + view->priv->lines_counters[1]++;
- }
- }
-
- g_object_set (renderer, "line_old", line_old, "line_new", line_new, NULL);
-
- if (*current && (*current)->next && line_number == (*current)->next->line - 1)
- {
- view->priv->lines_counters[0] = view->priv->lines_counters[1] = 0;
- *current = (*current)->next->visible ? (*current)->next : NULL;
- }
-}
-
-static gint
-gitg_diff_view_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- GitgDiffView *view = GITG_DIFF_VIEW (widget);
-
- /* Prepare for new round of draw on the line renderer */
- view->priv->lines_current_region = NULL;
- view->priv->lines_previous_line = -1;
- view->priv->lines_counters[0] = 0;
- view->priv->lines_counters[1] = 0;
-
- if (GTK_WIDGET_CLASS (gitg_diff_view_parent_class)->draw)
- {
- return GTK_WIDGET_CLASS (gitg_diff_view_parent_class)->draw (widget, cr);
- }
- else
- {
- return FALSE;
- }
-}
-
-void
-gitg_diff_view_set_diff_enabled (GitgDiffView *view, gboolean enabled)
-{
- g_return_if_fail (GITG_IS_DIFF_VIEW (view));
-
- set_diff_enabled (view, enabled);
-
- g_object_notify (G_OBJECT (view), "diff-enabled");
-}
-
-static void
-offset_regions (Region *region,
- gint offset)
-{
- while (region)
- {
- region->line += offset;
- region = region->next;
- }
-}
-
-static gint
-compare_regions (Region *first,
- Region *second,
- gpointer user_data)
-{
- return first->line < second->line ? -1 : (first->line > second->line ? 1 : 0);
-}
-
-static GSequenceIter *
-region_get_iter (GitgDiffView *view, Region *region)
-{
- GSequenceIter *iter;
-
- iter = g_sequence_search (view->priv->regions_index,
- region,
- (GCompareDataFunc)compare_regions,
- NULL);
-
- if (g_sequence_iter_is_end (iter))
- {
- return g_sequence_iter_prev (iter);
- }
- else
- {
- Region *reg = g_sequence_get (iter);
-
- if (reg->line != region->line)
- {
- return g_sequence_iter_prev (iter);
- }
- else
- {
- return iter;
- }
- }
-}
-
-static void
-remove_regions_sequence (GitgDiffView *view,
- Region *from,
- Region *to)
-{
- GSequenceIter *start;
- GSequenceIter *end;
-
- start = region_get_iter (view, from);
-
- if (to)
- {
- end = g_sequence_iter_prev (region_get_iter (view, to));
- }
- else
- {
- end = g_sequence_get_end_iter (view->priv->regions_index);
- }
-
- g_sequence_remove_range (start, end);
-}
-
-static void
-remove_regions (GitgDiffView *view, Region *from, Region *to)
-{
- GtkTextBuffer *buffer;
- GtkTextIter start;
- GtkTextIter end;
- gint offset;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
- if (from->prev)
- {
- if (to)
- {
- from->prev->next = to;
- to->prev = from->prev;
- }
- else
- {
- from->prev->next = NULL;
- }
- }
- else
- {
- if (to)
- {
- view->priv->regions = to;
- to->prev = NULL;
- }
- else
- {
- view->priv->regions = NULL;
- }
- }
-
- if (!to)
- {
- view->priv->last_region = from->prev;
- }
-
- remove_regions_sequence (view, from, to);
-
- gtk_text_buffer_get_iter_at_line (buffer, &start, from->line);
-
- if (to)
- {
- gtk_text_buffer_get_iter_at_line (buffer, &end, to->line);
- }
- else
- {
- gtk_text_buffer_get_end_iter (buffer, &end);
- }
-
- /* Remove and free from sequence */
- while (from && from != to)
- {
- Region *next = from->next;
-
- //region_free (from);
- from = next;
- }
-
- offset = gtk_text_iter_get_line (&start) - gtk_text_iter_get_line (&end);
-
- offset_regions (to, offset);
-
- view->priv->ignore_changes = TRUE;
- gtk_text_buffer_begin_user_action (buffer);
- gtk_text_buffer_delete (buffer, &start, &end);
- gtk_text_buffer_end_user_action (buffer);
- view->priv->ignore_changes = FALSE;
-}
-
-void
-gitg_diff_view_remove_hunk (GitgDiffView *view, GtkTextIter *iter)
-{
- g_return_if_fail (GITG_IS_DIFF_VIEW (view));
- g_return_if_fail (iter != NULL);
-
- /* removes hunk at iter and if it was the last hunk of a file, also removes
- the file header */
- Region *region = find_current_region (view,
- gtk_text_iter_get_line (iter));
-
- if (!region)
- {
- return;
- }
-
- Region *from = region;
- Region *to = region->next;
-
- if (region->prev && region->prev->type == GITG_DIFF_ITER_TYPE_HEADER &&
- (!to || to->type == GITG_DIFF_ITER_TYPE_HEADER))
- {
- /* also remove the header in this case */
- from = region->prev;
- }
-
- remove_regions (view, from, to);
-}
-
-gboolean
-gitg_diff_view_get_start_iter (GitgDiffView *view, GitgDiffIter *iter)
-{
- g_return_val_if_fail (GITG_IS_DIFF_VIEW (view), FALSE);
- g_return_val_if_fail (iter != NULL, FALSE);
-
- if (!view->priv->diff_enabled)
- {
- return FALSE;
- }
-
- region_to_iter (view, view->priv->regions, iter);
- return GITG_DIFF_ITER_GET_REGION (iter) != NULL;
-}
-
-gboolean
-gitg_diff_iter_forward (GitgDiffIter *iter)
-{
- g_return_val_if_fail (iter != NULL, FALSE);
-
- if (!GITG_DIFF_ITER_GET_REGION (iter))
- {
- return FALSE;
- }
-
- GITG_DIFF_ITER_SET_REGION (iter, GITG_DIFF_ITER_GET_REGION (iter)->next);
-
- return GITG_DIFF_ITER_GET_REGION (iter) != NULL;
-}
-
-gboolean
-gitg_diff_view_get_end_iter (GitgDiffView *view, GitgDiffIter *iter)
-{
- g_return_val_if_fail (GITG_IS_DIFF_VIEW (view), FALSE);
- g_return_val_if_fail (iter != NULL, FALSE);
-
- region_to_iter (view, view->priv->last_region, iter);
-
- return GITG_DIFF_ITER_GET_REGION (iter) != NULL;
-}
-
-gboolean
-gitg_diff_iter_backward (GitgDiffIter *iter)
-{
- g_return_val_if_fail (iter != NULL, FALSE);
-
- if (!GITG_DIFF_ITER_GET_REGION (iter))
- {
- return FALSE;
- }
-
- GITG_DIFF_ITER_SET_REGION (iter, GITG_DIFF_ITER_GET_REGION (iter)->prev);
-
- return GITG_DIFF_ITER_GET_REGION (iter) != NULL;
-
-}
-
-GitgDiffIterType
-gitg_diff_iter_get_type (GitgDiffIter *iter)
-{
- g_return_val_if_fail (iter != NULL, 0);
- g_return_val_if_fail (GITG_IS_DIFF_VIEW (GITG_DIFF_ITER_GET_VIEW (iter)), 0);
- g_return_val_if_fail (GITG_DIFF_ITER_GET_REGION (iter) != NULL, 0);
-
- return GITG_DIFF_ITER_GET_REGION (iter)->type;
-}
-
-static void
-region_iter_range (GitgDiffView *view, Region *region, GtkTextIter *start, GtkTextIter *end)
-{
- gtk_text_buffer_get_iter_at_line (view->priv->current_buffer, start, region->line);
-
- Region *next = region->next;
-
- while (next && next->type != region->type)
- next = next->next;
-
- if (next)
- gtk_text_buffer_get_iter_at_line (view->priv->current_buffer, end, next->line);
- else
- gtk_text_buffer_get_end_iter (view->priv->current_buffer, end);
-}
-
-void
-gitg_diff_iter_set_visible (GitgDiffIter *iter, gboolean visible)
-{
- g_return_if_fail (iter != NULL);
- g_return_if_fail (GITG_IS_DIFF_VIEW (GITG_DIFF_ITER_GET_VIEW (iter)));
- g_return_if_fail (GITG_DIFF_ITER_GET_REGION (iter) != NULL);
-
- GitgDiffView *view = GITG_DIFF_ITER_GET_VIEW (iter);
- Region *region = GITG_DIFF_ITER_GET_REGION (iter);
-
- if (region->visible == visible)
- return;
-
- GtkTextIter start;
- GtkTextIter end;
-
- region_iter_range (view, region, &start, &end);
- region->visible = visible;
-
- /* Propagate visibility to hunks */
- if (region->type == GITG_DIFF_ITER_TYPE_HEADER)
- {
- Region *next = region->next;
-
- while (next && next->type != GITG_DIFF_ITER_TYPE_HEADER)
- {
- next->visible = visible;
- next = next->next;
- }
- }
-
- if (visible)
- {
- gtk_text_buffer_remove_tag (view->priv->current_buffer, view->priv->invisible_tag, &start, &end);
-
- if (region->type == GITG_DIFF_ITER_TYPE_HEADER)
- {
- hide_header_details (view, region);
- }
- }
- else
- {
- if (region->type == GITG_DIFF_ITER_TYPE_HEADER)
- {
- gtk_text_buffer_remove_tag (view->priv->current_buffer, view->priv->subheader_tag, &start, &end);
- }
-
- gtk_text_buffer_apply_tag (view->priv->current_buffer, view->priv->invisible_tag, &start, &end);
- }
-}
-
-static gboolean
-header_parse_index (GitgDiffView *view, Header *header)
-{
- GtkTextIter iter;
- GtkTextBuffer *buffer = view->priv->current_buffer;
- guint num;
- guint i;
-
- if (header->region.next)
- num = header->region.next->line - header->region.line;
- else
- num = gtk_text_buffer_get_line_count (buffer) - header->region.line;
-
- gtk_text_buffer_get_iter_at_line (buffer, &iter, header->region.line);
-
- for (i = 0; i < num; ++i)
- {
- if (!gtk_text_iter_forward_line (&iter))
- return FALSE;
-
- GtkTextIter end = iter;
- gtk_text_iter_forward_to_line_end (&end);
-
- /* get line contents */
- gchar *line = gtk_text_iter_get_text (&iter, &end);
- gchar match[] = "index ";
-
- if (g_str_has_prefix (line, match))
- {
- gchar *start = line + strlen (match);
- gchar *sep = strstr (start, "..");
- gboolean ret;
-
- if (sep)
- {
- gchar *last = strstr (sep, " ");
- gchar *bet = strstr (start, ",");
-
- if (!last)
- last = line + strlen (line);
-
- strncpy (header->index_from, start, (bet ? bet : sep) - start);
- strncpy (header->index_to, sep + 2, last - (sep + 2));
-
- header->index_from[ (bet ? bet : sep) - start] = '\0';
- header->index_to[last - (sep + 2)] = '\0';
-
- ret = TRUE;
- }
- else
- {
- ret = FALSE;
- }
-
- g_free (line);
- return ret;
- }
-
- g_free (line);
- }
-
- return FALSE;
-}
-
-gboolean
-gitg_diff_iter_get_index (GitgDiffIter *iter,
- gchar **from,
- gchar **to)
-{
- Region *region = GITG_DIFF_ITER_GET_REGION (iter);
-
- while (region && region->type != GITG_DIFF_ITER_TYPE_HEADER)
- {
- region = region->prev;
- }
-
- if (!region)
- {
- return FALSE;
- }
-
- Header *header = (Header *)region;
- gboolean ret = TRUE;
-
- if (!* (header->index_to))
- {
- ret = header_parse_index (GITG_DIFF_ITER_GET_VIEW (iter), header);
- }
-
- if (!ret)
- {
- return FALSE;
- }
-
- *from = header->index_from;
- *to = header->index_to;
-
- return TRUE;
-}
-
-static gboolean
-iter_in_view (GitgDiffView *view,
- GtkTextIter *iter)
-{
- GtkTextIter start;
- GtkTextIter end;
- GdkRectangle rect;
- GtkTextView *textview = GTK_TEXT_VIEW (view);
-
- gtk_text_view_get_visible_rect (textview, &rect);
- gtk_text_view_get_iter_at_location (textview, &start, rect.x, rect.y);
- gtk_text_view_get_iter_at_location (textview, &end, rect.x + rect.width, rect.y + rect.height);
-
- return gtk_text_iter_in_range (iter, &start, &end) || gtk_text_iter_equal (iter, &end);
-}
-
-static gboolean
-try_scan (GitgDiffView *view)
-{
- gint lines = gtk_text_buffer_get_line_count (view->priv->current_buffer);
-
- if (view->priv->last_scan_line > lines)
- {
- return FALSE;
- }
-
- guint num = MIN (lines - view->priv->last_scan_line, IDLE_SCAN_COUNT);
-
- if (num == 0)
- {
- return FALSE;
- }
-
- gchar str[8];
- g_snprintf (str, sizeof (str), "%u", view->priv->max_line_count);
- guint max_line = strlen (str);
-
- guint last = view->priv->last_scan_line;
- ensure_scan (view, view->priv->last_scan_line + num);
- g_snprintf (str, sizeof (str), "%u", view->priv->max_line_count);
-
- if (strlen (str) > max_line)
- {
- gtk_widget_queue_draw (GTK_WIDGET (view));
- }
-
- return last != view->priv->last_scan_line;
-}
-
-static void
-on_buffer_delete_range (GtkTextBuffer *buffer,
- GtkTextIter *start,
- GtkTextIter *end,
- GitgDiffView *view)
-{
- if (view->priv->ignore_changes)
- {
- return;
- }
-
- regions_free (view);
-
- if (iter_in_view (view, start) || iter_in_view (view, end))
- {
- try_scan (view);
- }
-
- if (!view->priv->scan_id)
- {
- view->priv->scan_id = g_idle_add ( (GSourceFunc)on_idle_scan,
- view);
- }
-}
-
-static void
-on_buffer_insert_text (GtkTextBuffer *buffer,
- GtkTextIter *iter,
- gchar const *text,
- gint len,
- GitgDiffView *view)
-{
- if (view->priv->ignore_changes)
- {
- return;
- }
-
- /* if region is in current view and not scanned, issue scan now */
- if (iter_in_view (view, iter))
- {
- try_scan (view);
- }
-
- if (!view->priv->scan_id)
- {
- view->priv->scan_id = g_idle_add ( (GSourceFunc)on_idle_scan, view);
- }
-}
-
-static gboolean
-on_idle_scan (GitgDiffView *view)
-{
- if (try_scan (view))
- {
- return TRUE;
- }
-
- view->priv->scan_id = 0;
- return FALSE;
-}
-
-gboolean
-gitg_diff_view_get_header_at_iter (GitgDiffView *view,
- GtkTextIter const *iter,
- GitgDiffIter *diff_iter)
-{
- g_return_val_if_fail (GITG_IS_DIFF_VIEW (view), FALSE);
- g_return_val_if_fail (iter != NULL, FALSE);
- g_return_val_if_fail (diff_iter != NULL, FALSE);
-
- if (!view->priv->diff_enabled)
- {
- return FALSE;
- }
-
- ensure_scan (view, gtk_text_iter_get_line (iter));
-
- Region *region = find_current_region (view, gtk_text_iter_get_line (iter));
-
- while (region && region->type == GITG_DIFF_ITER_TYPE_HUNK)
- {
- region = region->prev;
- }
-
- region_to_iter (view, region, diff_iter);
- return region != NULL && region->type == GITG_DIFF_ITER_TYPE_HEADER;
-}
-
-gboolean
-gitg_diff_view_get_hunk_at_iter (GitgDiffView *view,
- GtkTextIter const *iter,
- GitgDiffIter *diff_iter)
-{
- g_return_val_if_fail (GITG_IS_DIFF_VIEW (view), FALSE);
- g_return_val_if_fail (iter != NULL, FALSE);
- g_return_val_if_fail (diff_iter != NULL, FALSE);
-
- if (!view->priv->diff_enabled)
- {
- return FALSE;
- }
-
- ensure_scan (view, gtk_text_iter_get_line (iter));
-
- Region *region = find_current_region (view, gtk_text_iter_get_line (iter));
-
- if (region == NULL || region->type != GITG_DIFF_ITER_TYPE_HUNK)
- {
- return FALSE;
- }
-
- region_to_iter (view, region, diff_iter);
- return TRUE;
-}
-
-static void
-region_get_bounds (GitgDiffView *view,
- Region *region,
- GtkTextIter *start,
- GtkTextIter *end)
-{
- gtk_text_buffer_get_iter_at_line (view->priv->current_buffer,
- start,
- region->line);
-
- if (region->next != NULL)
- {
- gtk_text_buffer_get_iter_at_line (view->priv->current_buffer,
- end,
- region->next->line);
- }
- else
- {
- gtk_text_buffer_get_end_iter (view->priv->current_buffer,
- end);
- }
-}
-
-void
-gitg_diff_iter_get_bounds (GitgDiffIter const *iter,
- GtkTextIter *start,
- GtkTextIter *end)
-{
- g_return_if_fail (iter != NULL);
- g_return_if_fail (GITG_IS_DIFF_VIEW (GITG_DIFF_ITER_GET_VIEW (iter)));
- g_return_if_fail (GITG_DIFF_ITER_GET_REGION (iter) != NULL);
- g_return_if_fail (start != NULL);
- g_return_if_fail (end != NULL);
-
- GitgDiffView *view = GITG_DIFF_ITER_GET_VIEW (iter);
- Region *region = GITG_DIFF_ITER_GET_REGION (iter);
-
- region_get_bounds (view, region, start, end);
-}
-
-GitgDiffLineType
-gitg_diff_view_get_line_type (GitgDiffView *view, GtkTextIter const *iter)
-{
- g_return_val_if_fail (GITG_IS_DIFF_VIEW (view), GITG_DIFF_LINE_TYPE_NONE);
- g_return_val_if_fail (iter != NULL, GITG_DIFF_LINE_TYPE_NONE);
-
- if (!view->priv->diff_enabled)
- {
- return GITG_DIFF_LINE_TYPE_NONE;
- }
-
- GitgDiffIter diff_iter;
-
- if (!gitg_diff_view_get_hunk_at_iter (view, iter, &diff_iter))
- {
- return GITG_DIFF_LINE_TYPE_NONE;
- }
-
- GtkTextIter start = *iter;
- gtk_text_iter_set_line_offset (&start, 0);
-
- gunichar ch = gtk_text_iter_get_char (&start);
-
- switch (ch)
- {
- case '+':
- return GITG_DIFF_LINE_TYPE_ADD;
- case '-':
- return GITG_DIFF_LINE_TYPE_REMOVE;
- default:
- return GITG_DIFF_LINE_TYPE_NONE;
- }
-}
-
-static void
-calculate_hunk_header_counters (GitgDiffView *view,
- Region *region)
-{
- GtkTextIter start;
- GtkTextIter end;
- GtkTextIter begin;
-
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
- region_get_bounds (view, region, &start, &end);
-
- begin = start;
-
- guint new_count = 0;
- guint old_count = 0;
-
- gboolean isempty = TRUE;
-
- if (gtk_text_iter_forward_line (&start))
- {
- while (gtk_text_iter_compare (&start, &end) < 0)
- {
- GitgDiffLineType line_type;
- GtkTextIter line_end = start;
-
- gtk_text_iter_forward_to_line_end (&line_end);
-
- line_type = gitg_diff_view_get_line_type (view, &start);
-
- if (line_type == GITG_DIFF_LINE_TYPE_NONE ||
- line_type == GITG_DIFF_LINE_TYPE_ADD)
- {
- ++new_count;
- }
-
- if (line_type == GITG_DIFF_LINE_TYPE_NONE ||
- line_type == GITG_DIFF_LINE_TYPE_REMOVE)
- {
- ++old_count;
- }
-
- if (line_type != GITG_DIFF_LINE_TYPE_NONE)
- {
- isempty = FALSE;
- }
-
- if (!gtk_text_iter_forward_line (&start))
- {
- break;
- }
- }
- }
-
- if (isempty)
- {
- gitg_diff_view_remove_hunk (view, &begin);
- }
- else
- {
- end = begin;
- gtk_text_iter_forward_to_line_end (&end);
-
- gchar *header = gtk_text_buffer_get_text (buffer, &begin, &end, TRUE);
- gchar *ret;
-
- ret = gitg_utils_rewrite_hunk_counters (header, old_count, new_count);
- g_free (header);
-
- gtk_text_buffer_delete (buffer, &begin, &end);
- gtk_text_buffer_insert (buffer, &begin, ret, -1);
-
- g_free (ret);
- }
-}
-
-void
-gitg_diff_view_clear_line (GitgDiffView *view,
- GtkTextIter const *iter,
- GitgDiffLineType old_type,
- GitgDiffLineType new_type)
-{
- g_return_if_fail (GITG_IS_DIFF_VIEW (view));
- g_return_if_fail (iter != NULL);
-
- GitgDiffLineType line_type;
- GitgDiffIter diff_iter;
-
- line_type = gitg_diff_view_get_line_type (view, iter);
-
- if (line_type == GITG_DIFF_LINE_TYPE_NONE)
- {
- return;
- }
-
- gitg_diff_view_get_hunk_at_iter (view, iter, &diff_iter);
-
- GtkTextIter start = *iter;
- GtkTextIter end;
- GtkTextBuffer *buffer;
- Region *region;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
- gtk_text_iter_set_line_offset (&start, 0);
- end = start;
-
- gtk_text_buffer_begin_user_action (buffer);
- view->priv->ignore_changes = TRUE;
-
- region = GITG_DIFF_ITER_GET_REGION (&diff_iter);
-
- if (line_type == new_type)
- {
- /* means the line now just becomes context */
- gtk_text_iter_forward_char (&end);
- gtk_text_buffer_delete (buffer, &start, &end);
- gtk_text_buffer_insert (buffer, &start, " ", 1);
- }
- else
- {
- /* means the line should be removed */
- if (!gtk_text_iter_forward_line (&end))
- {
- gtk_text_iter_forward_to_line_end (&end);
- }
-
- gtk_text_buffer_delete (buffer, &start, &end);
- offset_regions (region->next, -1);
- }
-
- calculate_hunk_header_counters (view, region);
-
- view->priv->ignore_changes = FALSE;
- gtk_text_buffer_end_user_action (buffer);
-}
diff --git a/gitg/gitg-diff-view.h b/gitg/gitg-diff-view.h
deleted file mode 100644
index f714b53..0000000
--- a/gitg/gitg-diff-view.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * gitg-diff-view.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_DIFF_VIEW_H__
-#define __GITG_DIFF_VIEW_H__
-
-#include <gtksourceview/gtksourceview.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_DIFF_VIEW (gitg_diff_view_get_type ())
-#define GITG_DIFF_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_DIFF_VIEW, GitgDiffView))
-#define GITG_DIFF_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_DIFF_VIEW, GitgDiffView const))
-#define GITG_DIFF_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_DIFF_VIEW, GitgDiffViewClass))
-#define GITG_IS_DIFF_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_DIFF_VIEW))
-#define GITG_IS_DIFF_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_DIFF_VIEW))
-#define GITG_DIFF_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_DIFF_VIEW, GitgDiffViewClass))
-
-typedef struct _GitgDiffView GitgDiffView;
-typedef struct _GitgDiffViewClass GitgDiffViewClass;
-typedef struct _GitgDiffViewPrivate GitgDiffViewPrivate;
-
-typedef struct _GitgDiffIter GitgDiffIter;
-
-struct _GitgDiffIter
-{
- gpointer userdata;
- gpointer userdata2;
- gpointer userdata3;
-};
-
-typedef enum
-{
- GITG_DIFF_ITER_TYPE_HEADER = 1,
- GITG_DIFF_ITER_TYPE_HUNK
-} GitgDiffIterType;
-
-typedef enum
-{
- GITG_DIFF_LINE_TYPE_NONE,
- GITG_DIFF_LINE_TYPE_ADD,
- GITG_DIFF_LINE_TYPE_REMOVE,
-} GitgDiffLineType;
-
-struct _GitgDiffView
-{
- GtkSourceView parent;
-
- GitgDiffViewPrivate *priv;
-};
-
-struct _GitgDiffViewClass
-{
- GtkSourceViewClass parent_class;
-
- void (*header_added)(GitgDiffView *view, GitgDiffIter *iter);
- void (*hunk_added)(GitgDiffView *view, GitgDiffIter *iter);
-};
-
-GType gitg_diff_view_get_type(void) G_GNUC_CONST;
-GitgDiffView *gitg_diff_view_new(void);
-
-void gitg_diff_view_remove_hunk(GitgDiffView *view, GtkTextIter *iter);
-void gitg_diff_view_set_diff_enabled(GitgDiffView *view, gboolean enabled);
-
-/* Iterator functions */
-gboolean gitg_diff_view_get_start_iter(GitgDiffView *view, GitgDiffIter *iter);
-gboolean gitg_diff_iter_forward(GitgDiffIter *iter);
-
-gboolean gitg_diff_view_get_end_iter(GitgDiffView *view, GitgDiffIter *iter);
-gboolean gitg_diff_iter_backward(GitgDiffIter *iter);
-
-GitgDiffIterType gitg_diff_iter_get_type(GitgDiffIter *iter);
-void gitg_diff_iter_set_visible(GitgDiffIter *iter, gboolean visible);
-gboolean gitg_diff_iter_get_index(GitgDiffIter *iter, gchar **from, gchar **to);
-
-gboolean gitg_diff_view_get_header_at_iter (GitgDiffView *view, GtkTextIter const *iter, GitgDiffIter *diff_iter);
-gboolean gitg_diff_view_get_hunk_at_iter (GitgDiffView *view, GtkTextIter const *iter, GitgDiffIter *diff_iter);
-
-void gitg_diff_iter_get_bounds (GitgDiffIter const *iter, GtkTextIter *start, GtkTextIter *end);
-
-GitgDiffLineType gitg_diff_view_get_line_type (GitgDiffView *view, GtkTextIter const *iter);
-void gitg_diff_view_clear_line (GitgDiffView *view, GtkTextIter const *iter, GitgDiffLineType old_type, GitgDiffLineType new_type);
-
-G_END_DECLS
-
-#endif /* __GITG_DIFF_VIEW_H__ */
diff --git a/gitg/gitg-dirs.c b/gitg/gitg-dirs.c
deleted file mode 100644
index b0e9640..0000000
--- a/gitg/gitg-dirs.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * gitg-dirs.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include "gitg-dirs.h"
-#include "config.h"
-
-gchar const *
-gitg_dirs_get_data_dir (void)
-{
- static gchar *datadir = NULL;
-
- if (!datadir)
- {
- datadir = g_strdup (GITG_DATADIR);
- }
-
- return datadir;
-}
-
-gchar *
-gitg_dirs_get_data_filename(gchar const *first, ...)
-{
- gchar const *datadir = gitg_dirs_get_data_dir();
- gchar *ret;
-
- ret = g_build_filename(datadir, first, NULL);
- gchar const *item;
-
- va_list ap;
- va_start(ap, first);
-
- while ((item = va_arg(ap, gchar const *)))
- {
- gchar *tmp = ret;
- ret = g_build_filename(ret, item, NULL);
- g_free(tmp);
- }
-
- va_end(ap);
- return ret;
-}
-
-void
-gitg_dirs_initialize(int argc, char **argv)
-{
- gchar *path = g_path_get_dirname(argv[0]);
-
- if (!g_path_is_absolute(path))
- {
- gchar *tmp = path;
- gchar *cwd = g_get_current_dir();
-
- path = g_build_filename(cwd, tmp, NULL);
- g_free(tmp);
- g_free(cwd);
- }
-
- g_free(path);
-}
diff --git a/gitg/gitg-dirs.h b/gitg/gitg-dirs.h
deleted file mode 100644
index a6a2755..0000000
--- a/gitg/gitg-dirs.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * gitg-dirs.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_DIRS_H__
-#define __GITG_DIRS_H__
-
-#include <glib.h>
-
-gchar const *gitg_dirs_get_data_dir (void);
-gchar *gitg_dirs_get_data_filename (gchar const *first, ...) G_GNUC_NULL_TERMINATED;
-void gitg_dirs_initialize (int argc, char **argv);
-
-#endif /* __GITG_DIRS_H__ */
diff --git a/gitg/gitg-dirs.vala b/gitg/gitg-dirs.vala
new file mode 100644
index 0000000..bc345e2
--- /dev/null
+++ b/gitg/gitg-dirs.vala
@@ -0,0 +1,64 @@
+namespace Gitg
+{
+
+public class Dirs
+{
+ public static string data_dir
+ {
+ get { return Config.GITG_DATADIR; }
+ }
+
+ public static string locale_dir
+ {
+ get { return Config.GITG_LOCALEDIR; }
+ }
+
+ public static string lib_dir
+ {
+ get { return Config.GITG_LIBDIR; }
+ }
+
+ public static string plugins_dir
+ {
+ owned get { return Path.build_filename(lib_dir, "plugins"); }
+ }
+
+ public static string plugins_data_dir
+ {
+ owned get { return Path.build_filename(data_dir, "plugins"); }
+ }
+
+ public static string user_plugins_dir
+ {
+ owned get { return Path.build_filename(Environment.get_user_data_dir(), "gitg", "plugins"); }
+ }
+
+ public static string user_plugins_data_dir
+ {
+ owned get { return user_plugins_dir; }
+ }
+
+ public static string build_data_file(string part, ...)
+ {
+ var l = va_list();
+ var ret = Path.build_filename(data_dir, part, null);
+
+ while (true)
+ {
+ string? s = l.arg();
+
+ if (s == null)
+ {
+ break;
+ }
+
+ ret = Path.build_filename(ret, s);
+ }
+
+ return ret;
+ }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/gitg/gitg-dnd.c b/gitg/gitg-dnd.c
deleted file mode 100644
index 2b6b91b..0000000
--- a/gitg/gitg-dnd.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * gitg-dnd.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <gtk/gtk.h>
-
-#include "gitg-dnd.h"
-#include "gitg-cell-renderer-path.h"
-#include "gitg-window.h"
-#include "gitg-branch-actions.h"
-#include "gitg-utils.h"
-
-#include <string.h>
-
-enum
-{
- DRAG_TARGET_REF = 1,
- DRAG_TARGET_TREEISH,
- DRAG_TARGET_REVISION,
- DRAG_TARGET_TEXT,
- DRAG_TARGET_URI,
- DRAG_TARGET_DIRECT_SAVE
-};
-
-#define XDS_ATOM gdk_atom_intern ("XdndDirectSave0", FALSE)
-#define TEXT_ATOM gdk_atom_intern ("text/plain", FALSE)
-
-#define MAX_XDS_ATOM_VAL_LEN 4096
-
-static GtkTargetEntry target_dest_entries[] = {
- {"gitg-ref", GTK_TARGET_SAME_WIDGET, DRAG_TARGET_REF}
-};
-
-static GtkTargetEntry target_source_entries[] = {
- {"x-gitg/treeish-list", GTK_TARGET_OTHER_APP, DRAG_TARGET_TREEISH},
- {"XdndDirectSave0", GTK_TARGET_OTHER_APP, DRAG_TARGET_DIRECT_SAVE}
-};
-
-typedef struct
-{
- GtkTreeView *tree_view;
- GitgRef *ref;
- GitgRef *target;
- GitgRef *cursor_ref;
-
- GitgDndCallback callback;
- GitgDndRevisionCallback revision_callback;
- gpointer callback_data;
-
- gdouble x;
- gdouble y;
-
- gboolean is_drag;
- GtkTargetList *target_list;
- GtkTargetList *revision_target_list;
- GitgRevision *revision;
-
- guint scroll_timeout;
- gchar *xds_destination;
- gchar *xds_filename;
-} GitgDndData;
-
-#define GITG_DND_DATA_KEY "GitgDndDataKey"
-
-#define GITG_DND_GET_DATA(widget) ((GitgDndData *)g_object_get_data(G_OBJECT(widget), GITG_DND_DATA_KEY))
-
-static void
-remove_scroll_timeout (GitgDndData *data)
-{
- if (data->scroll_timeout != 0)
- {
- g_source_remove (data->scroll_timeout);
- data->scroll_timeout = 0;
- }
-}
-
-
-static GitgDndData *
-gitg_dnd_data_new ()
-{
- GitgDndData *data = g_slice_new0 (GitgDndData);
-
- data->target_list = gtk_target_list_new (target_dest_entries,
- G_N_ELEMENTS (target_dest_entries));
-
- data->revision_target_list = gtk_target_list_new (target_source_entries,
- G_N_ELEMENTS (target_source_entries));
-
- gtk_target_list_add_text_targets (data->revision_target_list, DRAG_TARGET_TEXT);
- gtk_target_list_add_uri_targets (data->revision_target_list, DRAG_TARGET_URI);
-
- return data;
-}
-
-static void
-gitg_dnd_data_free (GitgDndData *data)
-{
- gtk_target_list_unref (data->target_list);
- gtk_target_list_unref (data->revision_target_list);
-
- remove_scroll_timeout (data);
-
- g_slice_free (GitgDndData, data);
-}
-
-static GitgRef *
-get_ref_at_pos (GtkTreeView *tree_view,
- gint x,
- gint y,
- gint *hot_x,
- gint *hot_y,
- GitgCellRendererPath **renderer,
- GtkTreePath **tp)
-{
- gint cell_x;
- gint cell_y;
- GtkTreePath *path;
- GtkTreeViewColumn *column;
-
- if (!gtk_tree_view_get_path_at_pos (tree_view,
- x,
- y,
- &path,
- &column,
- &cell_x,
- &cell_y))
- {
- return NULL;
- }
-
- if (hot_y)
- {
- *hot_y = cell_y;
- }
-
- GtkCellRenderer *cell = gitg_utils_find_cell_at_pos (tree_view, column, path, cell_x);
-
- if (!cell || !GITG_IS_CELL_RENDERER_PATH (cell))
- {
- return NULL;
- }
-
- if (renderer)
- {
- *renderer = GITG_CELL_RENDERER_PATH (cell);
- }
-
- GitgRef *ref = gitg_cell_renderer_path_get_ref_at_pos (GTK_WIDGET (tree_view),
- GITG_CELL_RENDERER_PATH (cell),
- cell_x,
- hot_x);
-
- if (tp)
- {
- *tp = path;
- }
- else
- {
- gtk_tree_path_free (path);
- }
-
- return ref;
-}
-
-static GitgRevision *
-get_revision_at_pos (GtkTreeView *tree_view,
- gint x,
- gint y,
- GtkTreePath **tp)
-{
- gint cell_x;
- gint cell_y;
- GtkTreePath *path;
- GtkTreeViewColumn *column;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GitgRevision *revision;
-
- if (!gtk_tree_view_get_path_at_pos (tree_view,
- x,
- y,
- &path,
- &column,
- &cell_x,
- &cell_y))
- {
- return NULL;
- }
-
- model = gtk_tree_view_get_model (tree_view);
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- {
- return NULL;
- }
-
- gtk_tree_model_get (model, &iter, 0, &revision, -1);
-
- if (revision && tp)
- {
- *tp = path;
- }
- else
- {
- gtk_tree_path_free (path);
- }
-
- return revision;
-}
-
-static gboolean
-can_drag (GitgRef *ref)
-{
- GitgRefType type = gitg_ref_get_ref_type (ref);
-
- switch (type)
- {
- case GITG_REF_TYPE_BRANCH:
- case GITG_REF_TYPE_REMOTE:
- case GITG_REF_TYPE_STASH:
- return TRUE;
- break;
- default:
- return FALSE;
- break;
- }
-}
-
-static gboolean
-can_drop (GitgRef *source, GitgRef *dest)
-{
- if (gitg_ref_equal (source, dest))
- {
- return FALSE;
- }
-
- GitgRefType source_type = gitg_ref_get_ref_type (source);
- GitgRefType dest_type = gitg_ref_get_ref_type (dest);
-
- if (source_type == GITG_REF_TYPE_BRANCH)
- {
- return dest_type == GITG_REF_TYPE_BRANCH || dest_type == GITG_REF_TYPE_REMOTE;
- }
- else if (source_type == GITG_REF_TYPE_REMOTE)
- {
- return dest_type == GITG_REF_TYPE_BRANCH;
- }
- else if (source_type == GITG_REF_TYPE_STASH)
- {
- return dest_type == GITG_REF_TYPE_BRANCH;
- }
-
- return FALSE;
-}
-
-/* Copied from gitg-label-renderer
- * TODO: refactor
- */
-static inline guint8
-convert_color_channel (guint8 src,
- guint8 alpha)
-{
- return alpha ? src / (alpha / 255.0) : 0;
-}
-
-static void
-convert_bgra_to_rgba (guint8 const *src,
- guint8 *dst,
- gint width,
- gint height)
-{
- guint8 const *src_pixel = src;
- guint8 * dst_pixel = dst;
- int y;
-
- for (y = 0; y < height; y++)
- {
- int x;
-
- for (x = 0; x < width; x++)
- {
- dst_pixel[0] = convert_color_channel (src_pixel[2],
- src_pixel[3]);
- dst_pixel[1] = convert_color_channel (src_pixel[1],
- src_pixel[3]);
- dst_pixel[2] = convert_color_channel (src_pixel[0],
- src_pixel[3]);
- dst_pixel[3] = src_pixel[3];
-
- dst_pixel += 4;
- src_pixel += 4;
- }
- }
-}
-
-static GdkPixbuf *
-create_revision_drag_icon (GtkTreeView *tree_view,
- GitgRevision *revision)
-{
- gchar const *subject = gitg_revision_get_subject (revision);
- gchar *sha1 = gitg_revision_get_sha1 (revision);
-
- /* Only take first 8 characters */
- sha1[8] = '\0';
-
- gchar *text = g_strdup_printf ("%s: %s", sha1, subject);
-
- PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (tree_view), text);
- gint width;
- gint height;
-
- pango_layout_get_pixel_size (layout, &width, &height);
-
- cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width + 4, height + 4);
- cairo_t *context = cairo_create (surface);
-
- cairo_rectangle (context, 0, 0, width + 4, height + 4);
- cairo_set_source_rgb (context, 1, 1, 1);
- cairo_fill (context);
-
- cairo_translate (context, 2, 2);
- cairo_set_source_rgb (context, 0, 0, 0);
- pango_cairo_show_layout (context, layout);
-
- guint8 *data = cairo_image_surface_get_data (surface);
- GdkPixbuf *ret = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width + 4, height + 4);
- guint8 *pixdata = gdk_pixbuf_get_pixels (ret);
-
- convert_bgra_to_rgba (data, pixdata, width + 4, height + 4);
-
- cairo_destroy (context);
- cairo_surface_destroy (surface);
-
- g_object_unref (layout);
-
- g_free (text);
- g_free (sha1);
-
- return ret;
-}
-
-static gchar *
-generate_format_patch_filename (GitgRevision *revision)
-{
- gchar *name = gitg_revision_get_format_patch_name (revision);
- gchar *filename = g_strdup_printf ("0001-%s.patch", name);
-
- g_free (name);
- return filename;
-}
-
-static void
-begin_drag (GtkWidget *widget,
- GdkEvent *event,
- GitgDndData *data)
-{
-
- GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
- gint hot_x;
- gint hot_y;
- GitgCellRendererPath *cell;
- GitgRef *ref = get_ref_at_pos (tree_view,
- (gint)data->x,
- (gint)data->y,
- &hot_x,
- &hot_y,
- &cell,
- NULL);
-
- if (ref && !can_drag (ref))
- {
- return;
- }
- else if (ref)
- {
- /* This is a DND operation on a ref */
- data->ref = ref;
- gitg_ref_set_state (ref, GITG_REF_STATE_NONE);
-
- GdkDragContext *context = gtk_drag_begin (widget,
- data->target_list,
- GDK_ACTION_MOVE,
- 1,
- event);
-
- guint minwidth;
- guint h;
- gdk_display_get_maximal_cursor_size (gtk_widget_get_display (widget), &minwidth, &h);
-
- GdkPixbuf *pixbuf = gitg_cell_renderer_path_render_ref (GTK_WIDGET (tree_view),
- cell,
- ref,
- minwidth + 1);
-
- if (pixbuf)
- {
- gtk_drag_set_icon_pixbuf (context, pixbuf, hot_x, hot_y);
- g_object_unref (pixbuf);
- }
- }
- else
- {
- /* This is a normal DND operation which is just possibly just about
- a SHA */
- GitgRevision *revision;
- GtkTreePath *path = NULL;
-
- revision = get_revision_at_pos (tree_view,
- (gint)data->x,
- (gint)data->y,
- &path);
-
- if (revision && !gitg_revision_get_sign (revision))
- {
- /* Make a DND for the revision */
- data->revision = revision;
-
- GdkDragContext *context = gtk_drag_begin (widget,
- data->revision_target_list,
- GDK_ACTION_COPY,
- 1,
- event);
- GdkPixbuf *icon;
- gchar *filename;
-
- filename = generate_format_patch_filename (revision);
-
- gdk_property_change (gtk_widget_get_window (widget),
- XDS_ATOM, TEXT_ATOM,
- 8, GDK_PROP_MODE_REPLACE,
- (guchar *) filename,
- strlen (filename));
-
- data->xds_filename = filename;
-
- icon = create_revision_drag_icon (tree_view, revision);
-
- if (icon)
- {
- gtk_drag_set_icon_pixbuf (context, icon, 0, 0);
- g_object_unref (icon);
- }
-
- gtk_tree_path_free (path);
- }
-
- if (revision)
- {
- gitg_revision_unref (revision);
- }
- }
-}
-
-static void
-update_highlight (GitgDndData *data, gint x, gint y)
-{
- GitgRef *ref = get_ref_at_pos (data->tree_view,
- x,
- y,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (ref != data->cursor_ref)
- {
- if (data->cursor_ref)
- {
- gitg_ref_set_state (data->cursor_ref, GITG_REF_STATE_NONE);
- }
-
- if (ref && gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_NONE)
- {
- gitg_ref_set_state (ref, GITG_REF_STATE_PRELIGHT);
-
- gdk_window_set_cursor (gtk_tree_view_get_bin_window (data->tree_view),
- gdk_cursor_new (GDK_HAND2));
- }
- else
- {
- gdk_window_set_cursor (gtk_tree_view_get_bin_window (data->tree_view),
- NULL);
- }
-
- data->cursor_ref = ref;
- gtk_widget_queue_draw (GTK_WIDGET (data->tree_view));
- }
-}
-
-static gboolean
-vertical_autoscroll (GitgDndData *data)
-{
- GdkRectangle visible_rect;
- gint y;
- gint offset;
- gfloat value;
-
- gdk_window_get_pointer (gtk_tree_view_get_bin_window (data->tree_view), NULL, &y, NULL);
- gtk_tree_view_convert_bin_window_to_tree_coords (data->tree_view, 0, y, NULL, &y);
-
- gtk_tree_view_get_visible_rect (data->tree_view, &visible_rect);
-
- /* see if we are near the edge. */
- offset = y - (visible_rect.y + 2 * 15);
-
- if (offset > 0)
- {
- offset = y - (visible_rect.y + visible_rect.height - 2 * 15);
-
- if (offset < 0)
- {
- return TRUE;
- }
- }
-
- GtkAdjustment *adj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (data->tree_view));
-
- value = CLAMP (gtk_adjustment_get_value (adj) + offset, 0.0,
- gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
-
- gtk_adjustment_set_value (adj, value);
- return TRUE;
-}
-
-static void
-add_scroll_timeout (GitgDndData *data)
-{
- if (data->scroll_timeout == 0)
- {
- data->scroll_timeout = g_timeout_add (50,
- (GSourceFunc)vertical_autoscroll,
- data);
- }
-}
-
-
-static gboolean
-gitg_drag_source_event_cb (GtkWidget *widget,
- GdkEvent *event,
- GitgDndData *data)
-{
- gboolean retval = FALSE;
-
- if (event->any.window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget)))
- {
- return FALSE;
- }
-
- switch (event->type)
- {
- case GDK_BUTTON_PRESS:
- if (event->button.button == 1)
- {
- data->x = event->button.x;
- data->y = event->button.y;
-
- data->is_drag = TRUE;
- data->ref = NULL;
- data->target = NULL;
- }
- break;
- case GDK_BUTTON_RELEASE:
- if (event->button.button == 1)
- {
- data->is_drag = FALSE;
-
- if (data->target)
- {
- gitg_ref_set_state (data->target, GITG_REF_STATE_NONE);
- }
-
- remove_scroll_timeout (data);
- }
- break;
- case GDK_MOTION_NOTIFY:
- if (data->is_drag && (event->motion.state & GDK_BUTTON1_MASK))
- {
- if (gtk_drag_check_threshold (widget, data->x, data->y, event->motion.x, event->motion.y))
- {
- data->is_drag = FALSE;
- begin_drag (widget, event, data);
-
- retval = TRUE;
- }
- }
- else if (!data->is_drag && !(event->motion.state & GDK_BUTTON1_MASK))
- {
- update_highlight (data, (gint)event->motion.x, (gint)event->motion.y);
- }
- break;
- default:
- break;
- }
-
- return retval;
-}
-
-static gboolean
-gitg_drag_source_motion_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time,
- GitgDndData *data)
-{
- if (!data->ref && !data->revision)
- {
- return FALSE;
- }
-
- GitgRef *ref;
- gint dx;
- gint dy;
-
- gtk_tree_view_convert_widget_to_bin_window_coords (data->tree_view,
- x,
- y,
- &dx,
- &dy);
-
- ref = get_ref_at_pos (GTK_TREE_VIEW (widget),
- dx,
- dy,
- NULL,
- NULL,
- NULL,
- NULL);
-
- gboolean ret = FALSE;
-
- if (ref != data->target)
- {
- if (data->target)
- {
- gitg_ref_set_state (data->target, GITG_REF_STATE_NONE);
- gtk_widget_queue_draw (widget);
- }
-
- if (data->ref && data->callback)
- {
- data->callback (data->ref, ref, FALSE, data->callback_data);
- }
- else if (data->revision && data->revision_callback)
- {
- data->revision_callback (data->revision, ref, FALSE, data->callback_data);
- }
- }
-
- if ((data->ref && ref && can_drop (data->ref, ref)) ||
- (data->revision && ref && gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH))
- {
- if (ref != data->target)
- {
- gitg_ref_set_state (ref, GITG_REF_STATE_SELECTED);
- data->target = ref;
-
- gtk_widget_queue_draw (widget);
- }
-
- gdk_drag_status (context, GDK_ACTION_MOVE, time);
- ret = TRUE;
- }
- else
- {
- if (data->target)
- {
- data->target = NULL;
- gtk_widget_queue_draw (widget);
- }
- }
-
- if (data->ref)
- {
- add_scroll_timeout (data);
- }
-
- return ret;
-}
-
-static gboolean
-gitg_drag_source_drop_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time,
- GitgDndData *data)
-{
- if (!(data->ref || data->revision) || !data->target)
- {
- return FALSE;
- }
-
- gboolean ret = FALSE;
-
- if (data->ref && data->callback)
- {
- ret = data->callback (data->ref, data->target, TRUE, data->callback_data);
- }
- else if (data->revision && data->revision_callback)
- {
- ret = data->revision_callback (data->revision, data->target, TRUE, data->callback_data);
- }
-
- gtk_drag_finish (context, ret, FALSE, time);
- return ret;
-}
-
-static gboolean
-gitg_drag_source_leave_cb (GtkWidget *widget,
- GdkDragContext *context,
- guint time,
- GitgDndData *data)
-{
- remove_scroll_timeout (data);
- return FALSE;
-}
-
-static void
-remove_trailing_newlines (gchar **lines)
-{
- gint lastnewline = -1;
- gchar **ptr = lines;
- gint i = 0;
-
- while (ptr && *ptr)
- {
- if (lastnewline == -1 && **ptr == '\0')
- {
- lastnewline = i;
- }
- else if (lastnewline != -1 && **ptr != '\0')
- {
- lastnewline = -1;
- }
-
- ++i;
- ++ptr;
- }
-
- if (lastnewline == -1)
- {
- return;
- }
-
- while (lines[lastnewline])
- {
- g_free (lines[lastnewline]);
- lines[lastnewline] = NULL;
-
- ++lastnewline;
- }
-}
-
-static gchar *
-revision_to_text (GitgRepository *repository,
- GitgRevision *revision)
-{
- gchar **lines;
- gchar *sha1 = gitg_revision_get_sha1 (revision);
-
- gitg_shell_run_sync_with_output (gitg_command_new (repository,
- "log",
- "-1",
- "--pretty=format:%h: %s%n%n%b",
- sha1,
- NULL),
- FALSE,
- &lines,
- NULL);
-
- remove_trailing_newlines (lines);
- gchar *ret = g_strjoinv ("\n", lines);
-
- g_strfreev (lines);
- g_free (sha1);
-
- return ret;
-}
-
-static gchar *
-revision_to_uri (GitgRepository *repository,
- GitgRevision *revision)
-{
- GFile *work_tree = gitg_repository_get_work_tree (repository);
- gchar *sha1 = gitg_revision_get_sha1 (revision);
-
- gchar *path = g_file_get_path (work_tree);
- gchar *ret = g_strdup_printf ("gitg://%s:%s", path, sha1);
-
- g_free (sha1);
- g_free (path);
- g_object_unref (work_tree);
-
- return ret;
-}
-
-static gchar *
-revision_to_treeish (GitgRepository *repository,
- GitgRevision *revision)
-{
- GFile *work_tree = gitg_repository_get_work_tree (repository);
- gchar *sha1 = gitg_revision_get_sha1 (revision);
- gchar *path = g_file_get_path (work_tree);
-
- gchar *ret = g_strdup_printf ("%s\n%s", path, sha1);
-
- g_free (sha1);
- g_free (path);
- g_object_unref (work_tree);
-
- return ret;
-}
-
-static gchar *
-get_xds_filename (GtkWidget *widget,
- GdkDragContext *context)
-{
- if (context == NULL || widget == NULL)
- {
- return NULL;
- }
-
- gint len;
- gchar *ret = NULL;
-
- if (gdk_property_get (gtk_widget_get_window (widget),
- XDS_ATOM, TEXT_ATOM,
- 0, MAX_XDS_ATOM_VAL_LEN,
- FALSE, NULL, NULL, &len,
- (unsigned char **) &ret))
- {
- gchar *dupped = g_strndup (ret, len);
- g_free (ret);
-
- return dupped;
- }
-
- return NULL;
-}
-
-static gboolean
-has_direct_save (GitgDndData *data,
- GtkWidget *widget,
- GdkDragContext *context)
-{
- gboolean ret;
-
- if (!g_list_find (gdk_drag_context_list_targets (context), XDS_ATOM))
- {
- return FALSE;
- }
-
- gchar *filename = get_xds_filename (widget, context);
- ret = filename && *filename && g_strcmp0 (data->xds_filename, filename) != 0;
- g_free (filename);
-
- return ret;
-}
-
-static void
-gitg_drag_source_data_get_cb (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection,
- guint info,
- guint time,
- GitgDndData *data)
-{
- if (!data->revision)
- {
- return;
- }
-
- GitgRepository *repository = GITG_REPOSITORY (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
-
- if (has_direct_save (data, widget, context))
- {
- gchar *destination = get_xds_filename (widget, context);
-
- if (destination && *destination)
- {
- data->xds_destination = g_strdup (destination);
-
- gtk_selection_data_set (selection,
- gtk_selection_data_get_target (selection),
- 8,
- (guchar const *)"S",
- 1);
- }
- else
- {
- gtk_selection_data_set (selection,
- gtk_selection_data_get_target (selection),
- 8,
- (guchar const *)"E",
- 1);
- }
-
- g_free (destination);
- return;
- }
-
- switch (info)
- {
- case DRAG_TARGET_TEXT:
- {
- gchar *text = revision_to_text (repository, data->revision);
- gtk_selection_data_set_text (selection, text, -1);
- g_free (text);
- }
- break;
- case DRAG_TARGET_TREEISH:
- {
- gchar *treeish = revision_to_treeish (repository,
- data->revision);
-
- gtk_selection_data_set (selection,
- gtk_selection_data_get_target (selection),
- 8,
- (guchar const *)treeish,
- strlen (treeish));
-
- g_free (treeish);
- }
- break;
- case DRAG_TARGET_URI:
- {
- gchar *uri = revision_to_uri (repository, data->revision);
- gchar *uris[] = {uri, NULL};
-
- gtk_selection_data_set_uris (selection, uris);
- g_free (uri);
- }
- break;
- }
-}
-
-static void
-gitg_drag_source_end_cb (GtkTreeView *tree_view,
- GdkDragContext *context,
- GitgDndData *data)
-{
- if (data->revision)
- {
- gdk_property_delete (gtk_widget_get_window (GTK_WIDGET (tree_view)), XDS_ATOM);
-
- if (data->xds_destination != NULL)
- {
- /* Do extract it there then */
- GitgWindow *window = GITG_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (data->tree_view)));
- gitg_window_add_branch_action (window,
- gitg_branch_actions_format_patch (window,
- data->revision,
- data->xds_destination));
-
- g_free (data->xds_destination);
- data->xds_destination = NULL;
- }
-
- if (data->xds_filename != NULL)
- {
- g_free (data->xds_filename);
- data->xds_filename = NULL;
- }
- }
-}
-
-static void
-gitg_drag_source_data_delete_cb (GtkTreeView *tree_view,
- GdkDragContext *context,
- GitgDndData *data)
-{
- g_signal_stop_emission_by_name (tree_view, "drag-data-delete");
-}
-
-void
-gitg_dnd_enable (GtkTreeView *tree_view,
- GitgDndCallback callback,
- GitgDndRevisionCallback revision_callback,
- gpointer callback_data)
-{
- if (GITG_DND_GET_DATA (tree_view))
- {
- return;
- }
-
- GitgDndData *data = gitg_dnd_data_new ();
-
- data->tree_view = tree_view;
- data->callback = callback;
- data->revision_callback = revision_callback;
- data->callback_data = callback_data;
-
- g_object_set_data_full (G_OBJECT (tree_view),
- GITG_DND_DATA_KEY,
- data,
- (GDestroyNotify)gitg_dnd_data_free);
-
- gtk_widget_add_events (GTK_WIDGET (tree_view),
- gtk_widget_get_events (GTK_WIDGET (tree_view)) |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON_MOTION_MASK);
-
- gtk_drag_dest_set (GTK_WIDGET (tree_view),
- 0,
- target_dest_entries,
- G_N_ELEMENTS (target_dest_entries),
- GDK_ACTION_MOVE);
-
- g_signal_connect (tree_view,
- "drag-data-get",
- G_CALLBACK (gitg_drag_source_data_get_cb),
- data);
-
- g_signal_connect (tree_view,
- "button-press-event",
- G_CALLBACK (gitg_drag_source_event_cb),
- data);
-
- g_signal_connect (tree_view,
- "button-release-event",
- G_CALLBACK (gitg_drag_source_event_cb),
- data);
-
- g_signal_connect (tree_view,
- "motion-notify-event",
- G_CALLBACK (gitg_drag_source_event_cb),
- data);
-
- g_signal_connect (tree_view,
- "drag-motion",
- G_CALLBACK (gitg_drag_source_motion_cb),
- data);
-
- g_signal_connect (tree_view,
- "drag-drop",
- G_CALLBACK (gitg_drag_source_drop_cb),
- data);
-
- g_signal_connect (tree_view,
- "drag-leave",
- G_CALLBACK (gitg_drag_source_leave_cb),
- data);
-
- g_signal_connect (tree_view,
- "drag-end",
- G_CALLBACK (gitg_drag_source_end_cb),
- data);
-
- g_signal_connect (tree_view,
- "drag-data-delete",
- G_CALLBACK (gitg_drag_source_data_delete_cb),
- data);
-}
-
-void
-gitg_dnd_disable (GtkTreeView *tree_view)
-{
- GitgDndData *data = GITG_DND_GET_DATA (tree_view);
-
- if (data)
- {
- g_signal_handlers_disconnect_by_func (tree_view, gitg_drag_source_event_cb, data);
- g_signal_handlers_disconnect_by_func (tree_view, gitg_drag_source_motion_cb, data);
- g_signal_handlers_disconnect_by_func (tree_view, gitg_drag_source_drop_cb, data);
- g_signal_handlers_disconnect_by_func (tree_view, gitg_drag_source_leave_cb, data);
- g_signal_handlers_disconnect_by_func (tree_view, gitg_drag_source_data_get_cb, data);
- g_signal_handlers_disconnect_by_func (tree_view, gitg_drag_source_end_cb, data);
-
- g_object_set_data (G_OBJECT (tree_view), GITG_DND_DATA_KEY, NULL);
- }
-}
diff --git a/gitg/gitg-dnd.h b/gitg/gitg-dnd.h
deleted file mode 100644
index 560dbea..0000000
--- a/gitg/gitg-dnd.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * gitg-dnd.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_DND_H__
-#define __GITG_DND_H__
-
-#include <gtk/gtk.h>
-#include <libgitg/gitg-ref.h>
-#include <libgitg/gitg-revision.h>
-
-G_BEGIN_DECLS
-
-typedef gboolean (*GitgDndCallback)(GitgRef *source, GitgRef *dest, gboolean dropped, gpointer callback_data);
-typedef gboolean (*GitgDndRevisionCallback)(GitgRevision *source, GitgRef *dest, gboolean dropped, gpointer callback_data);
-
-void gitg_dnd_enable (GtkTreeView *tree_view,
- GitgDndCallback callback,
- GitgDndRevisionCallback revision_callback,
- gpointer callback_data);
-
-void gitg_dnd_disable (GtkTreeView *tree_view);
-
-G_END_DECLS
-
-#endif /* __GITG_DND_H__ */
-
diff --git a/gitg/gitg-label-renderer.c b/gitg/gitg-label-renderer.c
deleted file mode 100644
index ba98e83..0000000
--- a/gitg/gitg-label-renderer.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * gitg-label-renderer.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-label-renderer.h"
-#include "gitg-utils.h"
-
-#include <libgitg/gitg-ref.h>
-#include <math.h>
-
-#define PADDING 4
-#define MARGIN 3
-
-static gint
-get_label_width (PangoLayout *layout,
- GitgRef *ref)
-{
- gint w;
- gchar *smaller = g_strdup_printf ("<span size='smaller'>%s</span>",
- gitg_ref_get_shortname (ref));
-
- pango_layout_set_markup (layout, smaller, -1);
-
- pango_layout_get_pixel_size (layout, &w, NULL);
- g_free (smaller);
-
- return w + PADDING * 2;
-}
-
-gint
-gitg_label_renderer_width (GtkWidget *widget,
- PangoFontDescription *description,
- GSList *labels)
-{
- gint width = 0;
- GSList *item;
-
- if (labels == NULL)
- return 0;
-
- PangoContext *ctx = gtk_widget_get_pango_context (widget);
- PangoLayout *layout = pango_layout_new (ctx);
- pango_layout_set_font_description (layout, description);
-
- for (item = labels; item; item = item->next)
- {
- width += get_label_width (layout, GITG_REF (item->data)) + MARGIN;
- }
-
- g_object_unref (layout);
-
- return width + MARGIN;
-}
-
-static void
-get_type_color (GitgRefType type,
- gdouble *r,
- gdouble *g,
- gdouble *b)
-{
- switch (type)
- {
- case GITG_REF_TYPE_NONE:
- *r = 1;
- *g = 1;
- *b = 0.8;
- break;
- case GITG_REF_TYPE_BRANCH:
- *r = 0.8;
- *g = 1;
- *b = 0.5;
- break;
- case GITG_REF_TYPE_REMOTE:
- *r = 0.5;
- *g = 0.8;
- *b = 1;
- break;
- case GITG_REF_TYPE_TAG:
- *r = 1;
- *g = 1;
- *b = 0;
- break;
- case GITG_REF_TYPE_STASH:
- *r = 1;
- *g = 0.8;
- *b = 0.5;
- break;
- default:
- *r = 1;
- *g = 1;
- *b = 1;
- break;
- }
-}
-
-static void
-get_ref_color (GitgRef *ref,
- gdouble *r,
- gdouble *g,
- gdouble *b)
-{
- if (gitg_ref_get_working (ref))
- {
- /* Orange */
- *r = 1;
- *g = 0.7;
- *b = 0;
- }
- else
- {
- get_type_color (gitg_ref_get_ref_type (ref), r, g, b);
- }
-}
-
-static void
-set_source_for_ref_type (cairo_t *context,
- GitgRef *ref,
- gboolean use_state)
-{
- if (use_state)
- {
- GitgRefState state = gitg_ref_get_state (ref);
-
- if (state == GITG_REF_STATE_SELECTED)
- {
- cairo_set_source_rgb (context, 1, 1, 1);
- return;
- }
- else if (state == GITG_REF_STATE_PRELIGHT)
- {
- gdouble r, g, b;
- get_ref_color (ref, &r, &g, &b);
-
- cairo_set_source_rgba (context, r, g, b, 0.3);
- return;
- }
- }
-
- gdouble r, g, b;
- get_ref_color (ref, &r, &g, &b);
-
- cairo_set_source_rgb (context, r, g, b);
-}
-
-static gint
-render_label (cairo_t *context,
- PangoLayout *layout,
- GitgRef *ref,
- gint x,
- gint y,
- gint height,
- gboolean use_state)
-{
- gint w;
- gint h;
- gchar *smaller = g_strdup_printf ("<span size='smaller'>%s</span>",
- gitg_ref_get_shortname (ref));
-
- pango_layout_set_markup (layout, smaller, -1);
- pango_layout_get_pixel_size (layout, &w, &h);
-
- // draw rounded rectangle
- gitg_utils_rounded_rectangle (context, x + 0.5,
- y + MARGIN + 0.5,
- w + PADDING * 2,
- height - MARGIN * 2,
- 5);
-
- set_source_for_ref_type (context, ref, use_state);
- cairo_fill_preserve (context);
-
- cairo_set_source_rgb (context, 0, 0, 0);
- cairo_stroke (context);
-
- cairo_save (context);
- cairo_translate (context, x + PADDING, y + (height - h) / 2.0 + 0.5);
- pango_cairo_show_layout (context, layout);
- cairo_restore (context);
-
- g_free (smaller);
- return w;
-}
-
-void
-gitg_label_renderer_draw (GtkWidget *widget,
- PangoFontDescription *description,
- cairo_t *context,
- GSList *labels,
- const GdkRectangle *area)
-{
- GSList *item;
- double pos = MARGIN + 0.5;
-
- cairo_save (context);
- cairo_set_line_width (context, 1.0);
-
- PangoContext *ctx = gtk_widget_get_pango_context (widget);
- PangoLayout *layout = pango_layout_new (ctx);
- pango_layout_set_font_description (layout, description);
-
- for (item = labels; item; item = item->next)
- {
- gint w = render_label (context,
- layout,
- GITG_REF (item->data),
- pos,
- area->y,
- area->height,
- TRUE);
-
- pos += w + PADDING * 2 + MARGIN;
- }
-
- g_object_unref (layout);
- cairo_restore (context);
-}
-
-
-GitgRef *
-gitg_label_renderer_get_ref_at_pos (GtkWidget *widget,
- PangoFontDescription *font,
- GSList *labels,
- gint x,
- gint *hot_x)
-{
- if (!labels)
- {
- return NULL;
- }
-
- PangoContext *ctx = gtk_widget_get_pango_context (widget);
- PangoLayout *layout = pango_layout_new (ctx);
- pango_layout_set_font_description (layout, font);
-
- gint start = MARGIN;
- GitgRef *ret = NULL;
- GSList *item;
-
- for (item = labels; item; item = item->next)
- {
- gint width = get_label_width (layout, GITG_REF (item->data));
-
- if (x >= start && x <= start + width)
- {
- ret = GITG_REF (item->data);
-
- if (hot_x)
- {
- *hot_x = x - start;
- }
-
- break;
- }
-
- start += width + MARGIN;
- }
-
- g_object_unref (layout);
- return ret;
-}
-
-static inline guint8
-convert_color_channel (guint8 src,
- guint8 alpha)
-{
- return alpha ? src / (alpha / 255.0) : 0;
-}
-
-static void
-convert_bgra_to_rgba (guint8 const *src,
- guint8 *dst,
- gint width,
- gint height)
-{
- guint8 const *src_pixel = src;
- guint8 * dst_pixel = dst;
- int y;
-
- for (y = 0; y < height; y++)
- {
- int x;
-
- for (x = 0; x < width; x++)
- {
- dst_pixel[0] = convert_color_channel (src_pixel[2],
- src_pixel[3]);
- dst_pixel[1] = convert_color_channel (src_pixel[1],
- src_pixel[3]);
- dst_pixel[2] = convert_color_channel (src_pixel[0],
- src_pixel[3]);
- dst_pixel[3] = src_pixel[3];
-
- dst_pixel += 4;
- src_pixel += 4;
- }
- }
-}
-
-GdkPixbuf *
-gitg_label_renderer_render_ref (GtkWidget *widget,
- PangoFontDescription *description,
- GitgRef *ref,
- gint height,
- gint minwidth)
-{
- PangoContext *ctx = gtk_widget_get_pango_context (widget);
- PangoLayout *layout = pango_layout_new (ctx);
- pango_layout_set_font_description (layout, description);
-
- gint width = MAX (get_label_width (layout, ref), minwidth);
-
- cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width + 2, height + 2);
- cairo_t *context = cairo_create (surface);
-
- cairo_set_line_width (context, 1);
-
- render_label (context, layout, ref, 1, 1, height, FALSE);
-
- guint8 *data = cairo_image_surface_get_data (surface);
- GdkPixbuf *ret = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width + 2, height + 2);
- guint8 *pixdata = gdk_pixbuf_get_pixels (ret);
-
- convert_bgra_to_rgba (data, pixdata, width + 2, height + 2);
-
- cairo_destroy (context);
- cairo_surface_destroy (surface);
-
- g_object_unref (layout);
-
- return ret;
-}
diff --git a/gitg/gitg-label-renderer.h b/gitg/gitg-label-renderer.h
deleted file mode 100644
index e593d6f..0000000
--- a/gitg/gitg-label-renderer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * gitg-label-renderer.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_LABEL_RENDERER_H__
-#define __GITG_LABEL_RENDERER_H__
-
-#include <gtk/gtk.h>
-#include <pango/pango.h>
-#include <libgitg/gitg-ref.h>
-
-gint gitg_label_renderer_width (GtkWidget *widget,
- PangoFontDescription *description,
- GSList *labels);
-void gitg_label_renderer_draw (GtkWidget *widget,
- PangoFontDescription *description,
- cairo_t *context,
- GSList *labels,
- const GdkRectangle *area);
-
-GitgRef *gitg_label_renderer_get_ref_at_pos (GtkWidget *widget,
- PangoFontDescription *description,
- GSList *labels,
- gint x,
- gint *hot_x);
-
-GdkPixbuf *gitg_label_renderer_render_ref (GtkWidget *widget,
- PangoFontDescription *description,
- GitgRef *ref,
- gint height,
- gint minwidth);
-
-#endif /* __GITG_LABEL_RENDERER_H__ */
-
diff --git a/gitg/gitg-menus.xml b/gitg/gitg-menus.xml
deleted file mode 100644
index 062fc92..0000000
--- a/gitg/gitg-menus.xml
+++ /dev/null
@@ -1,168 +0,0 @@
-<?xml version="1.0"?>
-<!--Generated with glade3 3.4.5 on Tue Jun 24 00:13:41 2008 -->
-<interface>
- <object class="GtkUIManager" id="uiman">
- <child>
- <object class="GtkActionGroup" id="actiongroup">
- <child>
- <object class="GtkRadioAction" id="subject">
- <property name="label" translatable="yes">_Subject</property>
- <property name="active">true</property>
- <signal after="true" handler="on_subject_activate" name="activate"/>
- </object>
- </child>
- <child>
- <object class="GtkRadioAction" id="author">
- <property name="label" translatable="yes">_Author</property>
- <property name="group">subject</property>
- <signal after="true" handler="on_author_activate" name="activate"/>
- </object>
- </child>
- <child>
- <object class="GtkRadioAction" id="date">
- <property name="label" translatable="yes">_Date</property>
- <property name="group">subject</property>
- <signal after="true" handler="on_date_activate" name="activate"/>
- </object>
- </child>
- <child>
- <object class="GtkRadioAction" id="hash">
- <property name="label" translatable="yes">_Hash</property>
- <property name="group">subject</property>
- <signal after="true" handler="on_hash_activate" name="activate"/>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_ref">
- <child>
- <object class="GtkAction" id="CheckoutAction">
- <property name="label" translatable="yes">Checkout branch</property>
- <signal name="activate" handler="on_checkout_branch_action_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="RemoveAction">
- <property name="label" translatable="yes">Remove branch</property>
- <signal name="activate" handler="on_remove_branch_action_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="RenameAction">
- <property name="label" translatable="yes">Rename branch</property>
- <signal name="activate" handler="on_rename_branch_action_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="RebaseAction">
- <property name="label" translatable="yes">Rebase branch onto...</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="MergeAction">
- <property name="label" translatable="yes">Merge branch with...</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="PushAction">
- <property name="label" translatable="yes">Push branch to...</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="StashAction">
- <property name="label" translatable="yes">Apply stash to...</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_dnd">
- <child>
- <object class="GtkAction" id="MergeDndAction">
- <property name="label" translatable="yes">Merge</property>
- <signal name="activate" handler="on_merge_branch_action_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="RebaseDndAction">
- <property name="label" translatable="yes">Rebase</property>
- <signal name="activate" handler="on_rebase_branch_action_activate"/>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_revision">
- <child>
- <object class="GtkAction" id="NewBranchAction">
- <property name="label" translatable="yes">Create branch</property>
- <signal name="activate" handler="on_revision_new_branch_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="TagAction">
- <property name="label" translatable="yes">Create tag</property>
- <signal name="activate" handler="on_revision_tag_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="CherryPickAction">
- <property name="label" translatable="yes">Cherry-pick on...</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="FormatPatchAction">
- <property name="label" translatable="yes">Format patch</property>
- <signal name="activate" handler="on_revision_format_patch_activate"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="SquashAction">
- <property name="label">Squash revisions</property>
- <signal name="activate" handler="on_revision_squash_activate"/>
- </object>
- </child>
- </object>
- </child>
- <ui>
- <popup name="search_popup">
- <menuitem action="subject"/>
- <menuitem action="author"/>
- <menuitem action="date"/>
- <menuitem action="hash"/>
- </popup>
- <popup name="ref_popup">
- <menuitem action="CheckoutAction"/>
- <menuitem action="RemoveAction"/>
- <menuitem action="RenameAction"/>
- <separator/>
- <menu name="Rebase" action="RebaseAction">
- <placeholder name="Placeholder"/>
- </menu>
- <menu name="Merge" action="MergeAction">
- <placeholder name="Placeholder"/>
- </menu>
- <menu name="Push" action="PushAction">
- <placeholder name="Placeholder"/>
- </menu>
- <menu name="Stash" action="StashAction">
- <placeholder name="Placeholder"/>
- </menu>
- </popup>
- <popup name="dnd_popup">
- <menuitem action="RebaseDndAction"/>
- <menuitem action="MergeDndAction"/>
- </popup>
- <popup name="revision_popup">
- <menuitem action="NewBranchAction"/>
- <menuitem action="TagAction"/>
- <menu name="CherryPick" action="CherryPickAction">
- <placeholder name="Placeholder"/>
- </menu>
- <menuitem action="FormatPatchAction"/>
- <menuitem action="SquashAction"/>
- </popup>
- </ui>
- </object>
-</interface>
diff --git a/gitg/gitg-new-branch.ui b/gitg/gitg-new-branch.ui
deleted file mode 100644
index ae26a80..0000000
--- a/gitg/gitg-new-branch.ui
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkDialog" id="dialog_branch">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Create branch</property>
- <property name="window_position">center-always</property>
- <property name="destroy_with_parent">True</property>
- <property name="type_hint">normal</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog_vbox_main">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkTable" id="table_main">
- <property name="visible">True</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_name">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Name:</property>
- </object>
- <packing>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- <property name="y_options">GTK_SHRINK</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="activates_default">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog_action_area">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="button_cancel">
- <property name="label">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_branch">
- <property name="label" translatable="yes">Create branch</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="is_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="image">image_tag</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="-6">button_cancel</action-widget>
- <action-widget response="-3">button_branch</action-widget>
- </action-widgets>
- </object>
- <object class="GtkImage" id="image_tag">
- <property name="visible">True</property>
- <property name="stock">gtk-apply</property>
- </object>
-</interface>
diff --git a/gitg/gitg-plugins-engine.vala b/gitg/gitg-plugins-engine.vala
new file mode 100644
index 0000000..925686e
--- /dev/null
+++ b/gitg/gitg-plugins-engine.vala
@@ -0,0 +1,67 @@
+namespace Gitg
+{
+
+public class PluginsEngine : Peas.Engine
+{
+ private static PluginsEngine s_instance;
+
+ construct
+ {
+ enable_loader("python");
+
+ var repo = Introspection.Repository.get_default();
+
+ try
+ {
+ repo.require("Peas", "1.0", 0);
+ repo.require("PeasGtk", "1.0", 0);
+ }
+ catch (Error e)
+ {
+ warning("Could not load repository: %s", e.message);
+ return;
+ }
+
+ add_search_path(Dirs.user_plugins_dir,
+ Dirs.user_plugins_data_dir);
+
+ add_search_path(Dirs.plugins_dir,
+ Dirs.plugins_data_dir);
+
+ Peas.PluginInfo[] builtins = new Peas.PluginInfo[20];
+ builtins.length = 0;
+
+ foreach (var info in get_plugin_list())
+ {
+ if (info.is_builtin())
+ {
+ builtins += info;
+ }
+ }
+
+ foreach (var info in builtins)
+ {
+ load_plugin(info);
+ }
+ }
+
+ public new static PluginsEngine get_default()
+ {
+ if (s_instance == null)
+ {
+ s_instance = new PluginsEngine();
+ s_instance.add_weak_pointer(&s_instance);
+ }
+
+ return s_instance;
+ }
+
+ public static void initialize()
+ {
+ get_default();
+ }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/gitg/gitg-preferences-dialog.c b/gitg/gitg-preferences-dialog.c
deleted file mode 100644
index 60b0376..0000000
--- a/gitg/gitg-preferences-dialog.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * gitg-preferences-dialog.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-preferences-dialog.h"
-
-#include "gitg-utils.h"
-
-#include <libgitg/gitg-config.h>
-#include <stdlib.h>
-#include <glib/gi18n.h>
-
-enum
-{
- COLUMN_NAME,
- COLUMN_PROPERTY,
- N_COLUMNS
-};
-
-void on_collapse_inactive_lanes_changed (GtkAdjustment *adjustment,
- GParamSpec *spec,
- GitgPreferencesDialog *dialog);
-
-gboolean on_entry_configuration_user_name_focus_out_event (GtkEntry *entry,
- GdkEventFocus *event,
- GitgPreferencesDialog *dialog);
-
-gboolean on_entry_configuration_user_email_focus_out_event (GtkEntry *entry,
- GdkEventFocus *event,
- GitgPreferencesDialog *dialog);
-
-#define GITG_PREFERENCES_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_PREFERENCES_DIALOG, GitgPreferencesDialogPrivate))
-
-static GitgPreferencesDialog *preferences_dialog;
-
-struct _GitgPreferencesDialogPrivate
-{
- GitgConfig *config;
-
- GtkCheckButton *history_search_filter;
- GtkAdjustment *collapse_inactive_lanes;
- GtkCheckButton *history_show_virtual_stash;
- GtkCheckButton *history_show_virtual_staged;
- GtkCheckButton *history_show_virtual_unstaged;
- GtkCheckButton *history_topo_order;
- GtkCheckButton *check_button_collapse_inactive;
- GtkCheckButton *main_layout_vertical;
-
- GtkCheckButton *check_button_show_right_margin;
- GtkLabel *label_right_margin;
- GtkSpinButton *spin_button_right_margin;
-
- GtkCheckButton *check_button_external_diff;
-
- GtkEntry *entry_configuration_user_name;
- GtkEntry *entry_configuration_user_email;
-
- GtkWidget *table;
-
- gint prev_value;
-
- GSettings *history_settings;
- GSettings *message_settings;
- GSettings *view_settings;
- GSettings *diff_settings;
-};
-
-G_DEFINE_TYPE(GitgPreferencesDialog, gitg_preferences_dialog, GTK_TYPE_DIALOG)
-
-static gint
-round_val(gdouble val)
-{
- gint ival = (gint)val;
-
- return ival + (val - ival > 0.5);
-}
-
-static void
-gitg_preferences_dialog_dispose (GObject *object)
-{
- GitgPreferencesDialog *dialog = GITG_PREFERENCES_DIALOG (object);
-
- if (dialog->priv->message_settings)
- {
- g_object_unref (dialog->priv->message_settings);
- dialog->priv->message_settings = NULL;
- }
-
- if (dialog->priv->view_settings)
- {
- g_object_unref (dialog->priv->view_settings);
- dialog->priv->view_settings = NULL;
- }
-
- if (dialog->priv->diff_settings)
- {
- g_object_unref (dialog->priv->diff_settings);
- dialog->priv->diff_settings = NULL;
- }
-
- G_OBJECT_CLASS (gitg_preferences_dialog_parent_class)->dispose (object);
-}
-
-static void
-gitg_preferences_dialog_finalize (GObject *object)
-{
- GitgPreferencesDialog *dialog = GITG_PREFERENCES_DIALOG (object);
-
- g_object_unref (dialog->priv->config);
-
- G_OBJECT_CLASS (gitg_preferences_dialog_parent_class)->finalize (object);
-}
-
-static void
-gitg_preferences_dialog_class_init(GitgPreferencesDialogClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- object_class->dispose = gitg_preferences_dialog_dispose;
- object_class->finalize = gitg_preferences_dialog_finalize;
-
- g_type_class_add_private(object_class, sizeof(GitgPreferencesDialogPrivate));
-}
-
-static void
-gitg_preferences_dialog_init(GitgPreferencesDialog *self)
-{
- self->priv = GITG_PREFERENCES_DIALOG_GET_PRIVATE(self);
-
- self->priv->config = gitg_config_new (NULL);
- self->priv->history_settings = g_settings_new ("org.gnome.gitg.preferences.view.history");
- self->priv->message_settings = g_settings_new ("org.gnome.gitg.preferences.commit.message");
- self->priv->view_settings = g_settings_new ("org.gnome.gitg.preferences.view.main");
- self->priv->diff_settings = g_settings_new ("org.gnome.gitg.preferences.diff");
-}
-
-static void
-on_response(GtkWidget *dialog, gint response, gpointer data)
-{
- gtk_widget_destroy(dialog);
-}
-
-static GVariant *
-convert_collapsed (const GValue *value,
- const GVariantType *expected_type,
- gpointer userdata)
-{
- GitgPreferencesDialog *dialog = GITG_PREFERENCES_DIALOG (userdata);
- gint val = round_val (g_value_get_double (value));
-
- if (val == dialog->priv->prev_value)
- return NULL;
-
- dialog->priv->prev_value = val;
-
- return g_variant_new_int32 (val);
-}
-
-static void
-on_collapse_inactive_toggled(GtkToggleButton *button, GitgPreferencesDialog *dialog)
-{
- gboolean active = gtk_toggle_button_get_active (button);
- gtk_widget_set_sensitive(dialog->priv->table, active);
-}
-
-static void
-on_check_button_show_right_margin_toggled(GtkToggleButton *button, GitgPreferencesDialog *dialog)
-{
- gboolean active = gtk_toggle_button_get_active (button);
-
- gtk_widget_set_sensitive(GTK_WIDGET(dialog->priv->label_right_margin), active);
- gtk_widget_set_sensitive(GTK_WIDGET(dialog->priv->spin_button_right_margin), active);
-}
-
-static gboolean
-orientation_to_layout_vertical (GValue *value,
- GVariant *variant,
- gpointer user_data)
-{
- const gchar *orientation;
- gboolean val;
-
- orientation = g_variant_get_string (variant, NULL);
-
- if (strcmp (orientation, "vertical") == 0)
- {
- val = TRUE;
- }
- else
- {
- val = FALSE;
- }
-
- g_value_set_boolean (value, val);
-
- return TRUE;
-}
-
-static GVariant *
-layout_vertical_to_orientation (const GValue *value,
- const GVariantType *expected_type,
- gpointer user_data)
-{
- GVariant *orientation;
-
- if (g_value_get_boolean (value))
- {
- orientation = g_variant_new_string ("vertical");
- }
- else
- {
- orientation = g_variant_new_string ("horizontal");
- }
-
- return orientation;
-}
-
-static void
-initialize_view(GitgPreferencesDialog *dialog)
-{
- g_signal_connect (dialog->priv->check_button_collapse_inactive,
- "toggled",
- G_CALLBACK (on_collapse_inactive_toggled),
- dialog);
-
- g_signal_connect (dialog->priv->check_button_show_right_margin,
- "toggled",
- G_CALLBACK (on_check_button_show_right_margin_toggled),
- dialog);
-
- g_settings_bind (dialog->priv->history_settings,
- "search-filter",
- dialog->priv->history_search_filter,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind_with_mapping (dialog->priv->history_settings,
- "collapse-inactive-lanes",
- dialog->priv->collapse_inactive_lanes,
- "value",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET,
- NULL,
- convert_collapsed,
- dialog,
- NULL);
-
- g_settings_bind (dialog->priv->history_settings,
- "collapse-inactive-lanes-active",
- dialog->priv->check_button_collapse_inactive,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (dialog->priv->history_settings,
- "topo-order",
- dialog->priv->history_topo_order,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (dialog->priv->history_settings,
- "show-virtual-stash",
- dialog->priv->history_show_virtual_stash,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (dialog->priv->history_settings,
- "show-virtual-staged",
- dialog->priv->history_show_virtual_staged,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (dialog->priv->history_settings,
- "show-virtual-unstaged",
- dialog->priv->history_show_virtual_unstaged,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (dialog->priv->message_settings,
- "show-right-margin",
- dialog->priv->check_button_show_right_margin,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (dialog->priv->message_settings,
- "right-margin-at",
- dialog->priv->spin_button_right_margin,
- "value",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind_with_mapping (dialog->priv->view_settings,
- "layout-vertical",
- dialog->priv->main_layout_vertical,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET,
- orientation_to_layout_vertical,
- layout_vertical_to_orientation,
- NULL,
- NULL);
-
- g_settings_bind (dialog->priv->diff_settings,
- "external",
- dialog->priv->check_button_external_diff,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-}
-
-static void
-create_preferences_dialog()
-{
- GtkBuilder *b = gitg_utils_new_builder("gitg-preferences.ui");
-
- preferences_dialog = GITG_PREFERENCES_DIALOG(gtk_builder_get_object(b, "dialog_preferences"));
- g_object_add_weak_pointer(G_OBJECT(preferences_dialog), (gpointer *)&preferences_dialog);
-
- GitgPreferencesDialogPrivate *priv = preferences_dialog->priv;
-
- priv->history_search_filter = GTK_CHECK_BUTTON(gtk_builder_get_object(b, "check_button_history_search_filter"));
- priv->collapse_inactive_lanes = GTK_ADJUSTMENT(gtk_builder_get_object(b, "adjustment_collapse_inactive_lanes"));
-
- priv->history_show_virtual_stash = GTK_CHECK_BUTTON(gtk_builder_get_object(b, "check_button_history_show_virtual_stash"));
- priv->history_show_virtual_staged = GTK_CHECK_BUTTON(gtk_builder_get_object(b, "check_button_history_show_virtual_staged"));
- priv->history_show_virtual_unstaged = GTK_CHECK_BUTTON(gtk_builder_get_object(b, "check_button_history_show_virtual_unstaged"));
- priv->history_topo_order = GTK_CHECK_BUTTON (gtk_builder_get_object (b, "check_button_history_topo_order"));
-
- priv->main_layout_vertical = GTK_CHECK_BUTTON (gtk_builder_get_object (b, "check_button_main_layout_vertical"));
-
- priv->check_button_collapse_inactive = GTK_CHECK_BUTTON(gtk_builder_get_object(b, "check_button_collapse_inactive"));
- priv->table = GTK_WIDGET(gtk_builder_get_object(b, "table_collapse_inactive_lanes"));
-
- priv->check_button_show_right_margin = GTK_CHECK_BUTTON(gtk_builder_get_object(b, "check_button_show_right_margin"));
- priv->label_right_margin = GTK_LABEL(gtk_builder_get_object(b, "label_right_margin"));
- priv->spin_button_right_margin = GTK_SPIN_BUTTON(gtk_builder_get_object(b, "spin_button_right_margin"));
-
- priv->check_button_external_diff = GTK_CHECK_BUTTON (gtk_builder_get_object (b, "check_button_external_diff"));
-
- priv->prev_value = (gint)gtk_adjustment_get_value(priv->collapse_inactive_lanes);
- g_signal_connect(preferences_dialog, "response", G_CALLBACK(on_response), NULL);
-
- initialize_view(preferences_dialog);
-
- priv->entry_configuration_user_name = GTK_ENTRY(gtk_builder_get_object(b, "entry_configuration_user_name"));
- priv->entry_configuration_user_email = GTK_ENTRY(gtk_builder_get_object(b, "entry_configuration_user_email"));
-
- gtk_builder_connect_signals(b, preferences_dialog);
- g_object_unref(b);
-
- gchar *val;
-
- val = gitg_config_get_value (priv->config, "user.name");
- gtk_entry_set_text (priv->entry_configuration_user_name, val ? val : "");
- g_free (val);
-
- val = gitg_config_get_value (priv->config, "user.email");
- gtk_entry_set_text (priv->entry_configuration_user_email, val ? val : "");
- g_free (val);
-}
-
-GitgPreferencesDialog *
-gitg_preferences_dialog_present(GtkWindow *window)
-{
- if (!preferences_dialog)
- create_preferences_dialog();
-
- gtk_window_set_transient_for(GTK_WINDOW(preferences_dialog), window);
- gtk_window_present(GTK_WINDOW(preferences_dialog));
-
- return preferences_dialog;
-}
-
-void
-on_collapse_inactive_lanes_changed (GtkAdjustment *adjustment,
- GParamSpec *spec,
- GitgPreferencesDialog *dialog)
-{
- gint val = round_val(gtk_adjustment_get_value(adjustment));
-
- if (val > 0)
- {
- g_signal_handlers_block_by_func (adjustment,
- on_collapse_inactive_lanes_changed,
- dialog);
-
- gtk_adjustment_set_value (adjustment, val);
-
- g_signal_handlers_unblock_by_func (adjustment,
- on_collapse_inactive_lanes_changed,
- dialog);
- }
-}
-
-gboolean
-on_entry_configuration_user_name_focus_out_event (GtkEntry *entry,
- GdkEventFocus *event,
- GitgPreferencesDialog *dialog)
-{
- gitg_config_set_value (dialog->priv->config,
- "user.name",
- gtk_entry_get_text (entry));
-
- return FALSE;
-}
-
-gboolean
-on_entry_configuration_user_email_focus_out_event (GtkEntry *entry,
- GdkEventFocus *event,
- GitgPreferencesDialog *dialog)
-{
- gitg_config_set_value (dialog->priv->config,
- "user.email",
- gtk_entry_get_text (entry));
-
- return FALSE;
-}
-
diff --git a/gitg/gitg-preferences-dialog.h b/gitg/gitg-preferences-dialog.h
deleted file mode 100644
index c1142cb..0000000
--- a/gitg/gitg-preferences-dialog.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * gitg-preferences-dialog.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_PREFERENCES_DIALOG_H__
-#define __GITG_PREFERENCES_DIALOG_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_PREFERENCES_DIALOG (gitg_preferences_dialog_get_type ())
-#define GITG_PREFERENCES_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_PREFERENCES_DIALOG, GitgPreferencesDialog))
-#define GITG_PREFERENCES_DIALOG_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_PREFERENCES_DIALOG, GitgPreferencesDialog const))
-#define GITG_PREFERENCES_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_PREFERENCES_DIALOG, GitgPreferencesDialogClass))
-#define GITG_IS_PREFERENCES_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_PREFERENCES_DIALOG))
-#define GITG_IS_PREFERENCES_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_PREFERENCES_DIALOG))
-#define GITG_PREFERENCES_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_PREFERENCES_DIALOG, GitgPreferencesDialogClass))
-
-typedef struct _GitgPreferencesDialog GitgPreferencesDialog;
-typedef struct _GitgPreferencesDialogClass GitgPreferencesDialogClass;
-typedef struct _GitgPreferencesDialogPrivate GitgPreferencesDialogPrivate;
-
-struct _GitgPreferencesDialog {
- GtkDialog parent;
-
- GitgPreferencesDialogPrivate *priv;
-};
-
-struct _GitgPreferencesDialogClass {
- GtkDialogClass parent_class;
-};
-
-GType gitg_preferences_dialog_get_type(void) G_GNUC_CONST;
-GitgPreferencesDialog *gitg_preferences_dialog_present(GtkWindow *window);
-
-G_END_DECLS
-
-#endif /* __GITG_PREFERENCES_DIALOG_H__ */
diff --git a/gitg/gitg-preferences.ui b/gitg/gitg-preferences.ui
deleted file mode 100644
index abf4ffc..0000000
--- a/gitg/gitg-preferences.ui
+++ /dev/null
@@ -1,810 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <object class="GtkAdjustment" id="adjustment_collapse_inactive_lanes">
- <property name="upper">5</property>
- <property name="value">2</property>
- <property name="step_increment">1</property>
- <property name="page_increment">1</property>
- <property name="page_size">1</property>
- </object>
- <object class="GitgPreferencesDialog" id="dialog_preferences">
- <property name="can_focus">False</property>
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Preferences</property>
- <property name="default_width">400</property>
- <property name="default_height">500</property>
- <property name="type_hint">normal</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog_vbox_main">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox" id="dialog_action_area">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="button_close">
- <property name="label">gtk-close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkNotebook" id="notebook1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="vexpand">True</property>
- <child>
- <object class="GtkBox" id="vbox_history">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">18</property>
- <child>
- <object class="GtkBox" id="vbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label130">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;Interface&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox23">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkLabel" id="label22">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label"> </property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox54">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="check_button_main_layout_vertical">
- <property name="label" translatable="yes">Use vertical layout</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;Revisions&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox5">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label"> </property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox5">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="check_button_history_search_filter">
- <property name="label" translatable="yes">Search filters revisions in the history view</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_collapse_inactive">
- <property name="label" translatable="yes">Collapse inactive lanes</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="table_collapse_inactive_lanes">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">3</property>
- <property name="row_spacing">3</property>
- <child>
- <object class="GtkHScale" id="hscale_collapse_inactive_lanes">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="adjustment">adjustment_collapse_inactive_lanes</property>
- <property name="digits">0</property>
- <property name="draw_value">False</property>
- </object>
- <packing>
- <property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label15">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Early</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label17">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label18">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Late</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_history_show_virtual_stash">
- <property name="label" translatable="yes">Show stash in history</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_history_show_virtual_staged">
- <property name="label" translatable="yes">Show staged changes in history</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_history_show_virtual_unstaged">
- <property name="label" translatable="yes">Show unstaged changes in history</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">5</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_history_topo_order">
- <property name="label" translatable="yes">Show history in topological order</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">6</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_view">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Preferences that apply to the history view</property>
- <property name="label" translatable="yes">History</property>
- </object>
- <packing>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_commit">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">18</property>
- <child>
- <object class="GtkBox" id="vbox11">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;Commit Message&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox9">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label"> </property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_commit_message">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="check_button_show_right_margin">
- <property name="label" translatable="yes">Display right _margin</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox_right_margin">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_right_margin">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Right margin at column:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="spin_button_right_margin">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="adjustment">spin_button_right_margin_adjustment</property>
- <property name="climb_rate">1</property>
- <property name="snap_to_ticks">True</property>
- <property name="numeric">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_commit">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Preferences that apply to the commit view</property>
- <property name="label" translatable="yes">Commit</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_commit1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">18</property>
- <child>
- <object class="GtkBox" id="vbox2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_diff_program">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;Diff Program&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label"> </property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_diff_program">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="check_button_external_diff">
- <property name="label" translatable="yes">Allow external diff program</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_diff">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Diff</property>
- </object>
- <packing>
- <property name="position">2</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_configure">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">18</property>
- <child>
- <object class="GtkBox" id="vbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;User&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label"> </property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_configuration_user_name">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Name:</property>
- </object>
- <packing>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_configuration_user_email">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">E-mail:</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_configuration_user_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hexpand">True</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <signal name="focus-out-event" handler="on_entry_configuration_user_name_focus_out_event" swapped="no"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_configuration_user_email">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hexpand">True</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <signal name="focus-out-event" handler="on_entry_configuration_user_email_focus_out_event" swapped="no"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_configuration">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Configure global git settings. This corresponds to the settings as stored in ~/.gitconfig. Repository specific settings can be configured at the repository properties.</property>
- <property name="label" translatable="yes">Configuration</property>
- </object>
- <packing>
- <property name="position">3</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="-7">button_close</action-widget>
- </action-widgets>
- </object>
- <object class="GtkImage" id="image_bold">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-bold</property>
- <property name="icon-size">1</property>
- </object>
- <object class="GtkImage" id="image_italic">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-italic</property>
- <property name="icon-size">1</property>
- </object>
- <object class="GtkImage" id="image_underline">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-underline</property>
- <property name="icon-size">1</property>
- </object>
- <object class="GtkAdjustment" id="spin_button_right_margin_adjustment">
- <property name="lower">1</property>
- <property name="upper">160</property>
- <property name="value">72</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
-</interface>
diff --git a/gitg/gitg-repository-dialog.c b/gitg/gitg-repository-dialog.c
deleted file mode 100644
index b84b46d..0000000
--- a/gitg/gitg-repository-dialog.c
+++ /dev/null
@@ -1,906 +0,0 @@
-/*
- * gitg-repository-dialog.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <glib/gi18n.h>
-
-#include <stdlib.h>
-#include <libgitg/gitg-config.h>
-#include <libgitg/gitg-shell.h>
-
-#include "gitg-repository-dialog.h"
-#include "gitg-utils.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-void on_button_fetch_remote_clicked (GtkButton *button,
- GitgRepositoryDialog *dialog);
-
-void on_button_remove_remote_clicked (GtkButton *button,
- GitgRepositoryDialog *dialog);
-
-void on_button_add_remote_clicked (GtkButton *button,
- GitgRepositoryDialog *dialog);
-
-gboolean on_entry_repository_user_name_focus_out_event (GtkEntry *entry,
- GdkEventFocus *focus,
- GitgRepositoryDialog *dialog);
-
-gboolean on_entry_repository_user_email_focus_out_event (GtkEntry *entry,
- GdkEventFocus *focus,
- GitgRepositoryDialog *dialog);
-
-void on_remote_name_edited (GtkCellRendererText *renderer,
- gchar *path,
- gchar *new_text,
- GitgRepositoryDialog *dialog);
-
-void on_remote_url_edited (GtkCellRendererText *renderer,
- gchar *path,
- gchar *new_text,
- GitgRepositoryDialog *dialog);
-
-#define GITG_REPOSITORY_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_REPOSITORY_DIALOG, GitgRepositoryDialogPrivate))
-
-static GitgRepositoryDialog *repository_dialog = NULL;
-
-enum
-{
- COLUMN_NAME,
- COLUMN_URL,
- COLUMN_FETCH,
- COLUMN_PULSE,
- COLUMN_SPINNER
-};
-
-struct _GitgRepositoryDialogPrivate
-{
- GitgRepository *repository;
- GitgConfig *config;
-
- GtkEntry *entry_repository_user_name;
- GtkEntry *entry_repository_user_email;
-
- GtkTreeView *tree_view_remotes;
- GtkListStore *list_store_remotes;
-
- GtkButton *button_remove_remote;
- GtkButton *button_fetch_remote;
- GtkImage *image_fetch_remote;
-
- GList *fetchers;
- gboolean show_fetch;
-};
-
-G_DEFINE_TYPE (GitgRepositoryDialog, gitg_repository_dialog, GTK_TYPE_DIALOG)
-
-typedef struct
-{
- GitgRepositoryDialog *dialog;
- GitgShell *shell;
- GtkTreeRowReference *reference;
-
- guint pulse_id;
-} FetchInfo;
-
-static void
-fetch_cleanup (FetchInfo *info)
-{
- info->dialog->priv->fetchers = g_list_remove (info->dialog->priv->fetchers, info);
-
- if (gtk_tree_row_reference_valid (info->reference))
- {
- GtkTreeIter iter;
- GtkTreePath *path = gtk_tree_row_reference_get_path (info->reference);
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (info->dialog->priv->list_store_remotes),
- &iter,
- path);
-
- gtk_list_store_set (info->dialog->priv->list_store_remotes,
- &iter,
- COLUMN_FETCH, FALSE,
- -1);
-
- gtk_tree_path_free (path);
- }
-
- g_source_remove (info->pulse_id);
-
- gtk_tree_row_reference_free (info->reference);
- g_object_unref (info->shell);
-
- g_slice_free (FetchInfo, info);
-}
-
-static void
-gitg_repository_dialog_finalize (GObject *object)
-{
- GitgRepositoryDialog *dialog = GITG_REPOSITORY_DIALOG (object);
-
- if (dialog->priv->repository)
- {
- g_object_unref (dialog->priv->repository);
- }
-
- if (dialog->priv->config)
- {
- g_object_unref (dialog->priv->config);
- }
-
- GList *copy = g_list_copy (dialog->priv->fetchers);
- GList *item;
-
- for (item = copy; item; item = g_list_next (item))
- {
- gitg_io_cancel (GITG_IO (((FetchInfo *)item->data)->shell));
- }
-
- g_list_free (copy);
- g_list_free (dialog->priv->fetchers);
-
- G_OBJECT_CLASS (gitg_repository_dialog_parent_class)->finalize (object);
-}
-
-static void
-gitg_repository_dialog_class_init (GitgRepositoryDialogClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_repository_dialog_finalize;
-
- g_type_class_add_private (object_class, sizeof(GitgRepositoryDialogPrivate));
-}
-
-static void
-gitg_repository_dialog_init (GitgRepositoryDialog *self)
-{
- self->priv = GITG_REPOSITORY_DIALOG_GET_PRIVATE (self);
-}
-
-static void
-on_response(GtkWidget *dialog, gint response, gpointer data)
-{
- gtk_widget_destroy(dialog);
-}
-
-static void
-update_fetch (GitgRepositoryDialog *dialog)
-{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (dialog->priv->tree_view_remotes);
- GList *rows;
- GtkTreeModel *model;
-
- rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- GList *item;
- gboolean show_fetch = FALSE;
-
- for (item = rows; item; item = g_list_next (item))
- {
- GtkTreePath *path = (GtkTreePath *)item->data;
- GtkTreeIter iter;
-
- gtk_tree_model_get_iter (model, &iter, path);
-
- gboolean fetch;
- gtk_tree_model_get (model, &iter, COLUMN_FETCH, &fetch, -1);
-
- if (!fetch)
- {
- show_fetch = TRUE;
- }
- }
-
- if (!rows)
- {
- show_fetch = TRUE;
- }
-
- if (show_fetch)
- {
- gtk_image_set_from_stock (dialog->priv->image_fetch_remote, GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON);
- gtk_button_set_label (dialog->priv->button_fetch_remote, _("Fetch"));
- }
- else
- {
- gtk_image_set_from_stock (dialog->priv->image_fetch_remote, GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON);
- gtk_button_set_label (dialog->priv->button_fetch_remote, _("Cancel"));
- }
-
- dialog->priv->show_fetch = show_fetch;
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-}
-
-static void
-update_sensitivity (GitgRepositoryDialog *dialog)
-{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (dialog->priv->tree_view_remotes);
- GList *rows;
- GtkTreeModel *model;
-
- rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->button_remove_remote), rows != NULL);
- gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->button_fetch_remote), rows != NULL);
-
- update_fetch (dialog);
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-}
-
-static void
-add_remote (GitgRepositoryDialog *dialog, gchar const *name, gchar const *url, GtkTreeIter *iter)
-{
- GtkTreeIter it;
-
- gtk_list_store_append (dialog->priv->list_store_remotes, iter ? iter : &it);
- gtk_list_store_set (dialog->priv->list_store_remotes,
- iter ? iter : &it,
- COLUMN_NAME, name,
- COLUMN_URL, url,
- COLUMN_FETCH, FALSE,
- COLUMN_PULSE, 0,
- COLUMN_SPINNER, NULL,
- -1);
-}
-
-static gboolean
-pulse_row (FetchInfo *info)
-{
- gint pulse;
- gboolean fetch;
- GtkTreeIter iter;
- GtkTreePath *path = gtk_tree_row_reference_get_path (info->reference);
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (info->dialog->priv->list_store_remotes),
- &iter,
- path);
-
- gtk_tree_model_get (GTK_TREE_MODEL (info->dialog->priv->list_store_remotes),
- &iter,
- COLUMN_FETCH, &fetch,
- COLUMN_PULSE, &pulse,
- -1);
-
- if (fetch)
- {
- gtk_list_store_set (info->dialog->priv->list_store_remotes,
- &iter,
- COLUMN_PULSE, pulse + 1,
- -1);
- }
-
- gtk_tree_path_free (path);
-
- return fetch;
-}
-
-static void
-on_fetch_begin_loading (GitgShell *shell, FetchInfo *info)
-{
- GtkTreeIter iter;
- GtkTreePath *path = gtk_tree_row_reference_get_path (info->reference);
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (info->dialog->priv->list_store_remotes),
- &iter,
- path);
-
- gtk_list_store_set (info->dialog->priv->list_store_remotes,
- &iter,
- COLUMN_FETCH, TRUE,
- -1);
-
- /* We can't tell how often we are supposed to pulse so just pulse
- * at the interval of the default engine. Yes this is annoying but,
- * mclasen said to "blame the engine."
- */
- info->pulse_id = g_timeout_add (750 / 12,
- (GSourceFunc)pulse_row,
- info);
-
- gtk_tree_path_free (path);
- update_fetch (info->dialog);
-}
-
-static void
-on_fetch_end_loading (GitgShell *shell, gboolean cancelled, FetchInfo *info)
-{
- if (cancelled || !gtk_tree_row_reference_valid (info->reference))
- {
- fetch_cleanup (info);
- return;
- }
-
- GitgRepositoryDialog *dialog = info->dialog;
-
- fetch_cleanup (info);
-
- update_fetch (dialog);
- gitg_repository_reload (dialog->priv->repository);
-}
-
-static void
-fetch_remote (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
-{
- GitgShell *shell = gitg_shell_new (1000);
- FetchInfo *info = g_slice_new0 (FetchInfo);
- GtkTreeModel *model = GTK_TREE_MODEL (dialog->priv->list_store_remotes);
-
- GtkTreePath *path = gtk_tree_model_get_path (model, iter);
-
- info->dialog = dialog;
- info->reference = gtk_tree_row_reference_new (model, path);
- info->shell = shell;
-
- gtk_tree_path_free (path);
-
- g_signal_connect (shell,
- "begin",
- G_CALLBACK (on_fetch_begin_loading),
- info);
-
- g_signal_connect (shell,
- "end",
- G_CALLBACK (on_fetch_end_loading),
- info);
-
- dialog->priv->fetchers = g_list_prepend (dialog->priv->fetchers, info);
-
- gchar *name;
- gtk_tree_model_get (model, iter, COLUMN_NAME, &name, -1);
-
- gitg_shell_run (shell,
- gitg_command_new (dialog->priv->repository,
- "fetch",
- name,
- NULL),
- NULL);
-
- g_free (name);
-}
-
-static void
-on_selection_changed (GtkTreeSelection *selection, GitgRepositoryDialog *dialog)
-{
- update_sensitivity (dialog);
-}
-
-static void
-init_remotes(GitgRepositoryDialog *dialog)
-{
- gchar *ret = gitg_config_get_value_regex (dialog->priv->config,
- "remote\\..*\\.url",
- NULL);
-
- if (!ret)
- {
- update_sensitivity (dialog);
- return;
- }
-
- gchar **lines = g_strsplit(ret, "\n", -1);
- gchar **ptr = lines;
-
- GRegex *regex = g_regex_new ("remote\\.(.+?)\\.url\\s+(.*)", 0, 0, NULL);
-
- while (*ptr)
- {
- GMatchInfo *info = NULL;
-
- if (g_regex_match (regex, *ptr, 0, &info))
- {
- gchar *name = g_match_info_fetch (info, 1);
- gchar *url = g_match_info_fetch (info, 2);
-
- add_remote (dialog, name, url, NULL);
-
- g_free (name);
- g_free (url);
- }
-
- g_match_info_free (info);
- ++ptr;
- }
-
- g_regex_unref (regex);
- g_strfreev (lines);
- g_free (ret);
-
- GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection (dialog->priv->tree_view_remotes);
-
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (selection, "changed", G_CALLBACK (on_selection_changed), dialog);
-
- update_sensitivity (dialog);
-}
-
-static void
-init_properties(GitgRepositoryDialog *dialog)
-{
- gchar *val;
-
- val = gitg_config_get_value (dialog->priv->config, "user.name");
- gtk_entry_set_text (dialog->priv->entry_repository_user_name, val ? val : "");
- g_free (val);
-
- val = gitg_config_get_value (dialog->priv->config, "user.email");
- gtk_entry_set_text (dialog->priv->entry_repository_user_email, val ? val : "");
- g_free (val);
-
- init_remotes(dialog);
-}
-
-static void
-fetch_data_spinner_cb (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GitgRepositoryDialog *dialog)
-{
- gboolean fetch;
- guint pulse;
-
- gtk_tree_model_get (model, iter,
- COLUMN_FETCH, &fetch,
- COLUMN_PULSE, &pulse,
- -1);
-
- g_object_set (G_OBJECT (cell),
- "active", fetch,
- "visible", fetch,
- "pulse", pulse,
- NULL);
-}
-
-static void
-fetch_data_icon_cb (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GitgRepositoryDialog *dialog)
-{
- gboolean fetch;
-
- gtk_tree_model_get (model, iter, COLUMN_FETCH, &fetch, -1);
-
- g_object_set (G_OBJECT (cell),
- "visible", !fetch,
- NULL);
-}
-
-
-static void
-create_repository_dialog (GitgWindow *window)
-{
- GitgRepository *repository = gitg_window_get_repository (window);
-
- if (!repository)
- {
- return;
- }
-
- GtkBuilder *b = gitg_utils_new_builder("gitg-repository.ui");
-
- repository_dialog = GITG_REPOSITORY_DIALOG(gtk_builder_get_object(b, "dialog_repository"));
- g_object_add_weak_pointer(G_OBJECT(repository_dialog), (gpointer *)&repository_dialog);
-
- repository_dialog->priv->repository = g_object_ref (repository);
- repository_dialog->priv->config = gitg_config_new (repository);
-
- repository_dialog->priv->entry_repository_user_name = GTK_ENTRY(gtk_builder_get_object(b, "entry_repository_user_name"));
- repository_dialog->priv->entry_repository_user_email = GTK_ENTRY(gtk_builder_get_object(b, "entry_repository_user_email"));
-
- repository_dialog->priv->tree_view_remotes = GTK_TREE_VIEW(gtk_builder_get_object(b, "tree_view_remotes"));
- repository_dialog->priv->list_store_remotes = GTK_LIST_STORE(gtk_builder_get_object(b, "list_store_remotes"));
-
- repository_dialog->priv->button_remove_remote = GTK_BUTTON(gtk_builder_get_object(b, "button_remove_remote"));
- repository_dialog->priv->button_fetch_remote = GTK_BUTTON(gtk_builder_get_object(b, "button_fetch_remote"));
- repository_dialog->priv->image_fetch_remote = GTK_IMAGE(gtk_builder_get_object(b, "image_fetch_remote"));
-
- GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (b, "tree_view_remotes_column_name"));
-
- GtkCellRenderer *spinner_renderer = gtk_cell_renderer_spinner_new ();
- g_object_set (spinner_renderer, "visible", FALSE, NULL);
-
- gtk_tree_view_column_pack_start (column, spinner_renderer, FALSE);
- gtk_cell_layout_reorder (GTK_CELL_LAYOUT (column), spinner_renderer, 1);
-
- gtk_tree_view_column_set_cell_data_func (column,
- spinner_renderer,
- (GtkTreeCellDataFunc)fetch_data_spinner_cb,
- repository_dialog,
- NULL);
-
- GtkCellRenderer *icon_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (b, "tree_view_remotes_renderer_icon"));
- gtk_tree_view_column_set_cell_data_func (column,
- icon_renderer,
- (GtkTreeCellDataFunc)fetch_data_icon_cb,
- repository_dialog,
- NULL);
-
- gtk_builder_connect_signals(b, repository_dialog);
- g_object_unref (b);
-
- GFile *work_tree = gitg_repository_get_work_tree (repository);
- gchar *basename = g_file_get_basename (work_tree);
- g_object_unref (work_tree);
-
- gchar *title = g_strdup_printf("%s - %s", _("Properties"), basename);
- gtk_window_set_title(GTK_WINDOW(repository_dialog), title);
-
- g_free (title);
- g_free (basename);
-
- g_signal_connect(repository_dialog, "response", G_CALLBACK(on_response), NULL);
-
- init_properties(repository_dialog);
-}
-
-GitgRepositoryDialog *
-gitg_repository_dialog_present (GitgWindow *window)
-{
- if (!repository_dialog)
- {
- create_repository_dialog(window);
- }
-
- gtk_window_set_transient_for(GTK_WINDOW(repository_dialog), GTK_WINDOW (window));
- gtk_window_present(GTK_WINDOW(repository_dialog));
-
- return repository_dialog;
-}
-
-void
-gitg_repository_dialog_close (void)
-{
- if (repository_dialog)
- {
- gtk_widget_destroy (GTK_WIDGET (repository_dialog));
- }
-}
-
-static void
-fetch_remote_cancel (GitgRepositoryDialog *dialog,
- GtkTreeIter *iter)
-{
- GList *item;
- GtkTreePath *orig;
- GtkTreeModel *model = GTK_TREE_MODEL (dialog->priv->list_store_remotes);
-
- orig = gtk_tree_model_get_path (model, iter);
-
- for (item = dialog->priv->fetchers; item; item = g_list_next (item))
- {
- FetchInfo *info = (FetchInfo *)item->data;
- GtkTreePath *ref = gtk_tree_row_reference_get_path (info->reference);
- gboolean equal = gtk_tree_path_compare (orig, ref) == 0;
-
- gtk_tree_path_free (ref);
-
- if (equal)
- {
- gitg_io_cancel (GITG_IO (info->shell));
- break;
- }
- }
-
- gtk_tree_path_free (orig);
-}
-
-void
-on_button_fetch_remote_clicked (GtkButton *button,
- GitgRepositoryDialog *dialog)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (dialog->priv->tree_view_remotes);
-
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
- GList *item;
-
- for (item = rows; item; item = g_list_next (item))
- {
- GtkTreePath *path = (GtkTreePath *)item->data;
- GtkTreeIter iter;
- gboolean fetch;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, COLUMN_FETCH, &fetch, -1);
-
- if (!fetch && dialog->priv->show_fetch)
- {
- fetch_remote (dialog, &iter);
- }
- else if (fetch && !dialog->priv->show_fetch)
- {
- fetch_remote_cancel (dialog, &iter);
- }
-
- gtk_tree_path_free (path);
- }
-
- if (rows)
- {
- update_fetch (dialog);
- }
-
- g_list_free (rows);
-}
-
-static gboolean
-remove_remote (GitgRepositoryDialog *dialog, gchar const *name)
-{
- return gitg_shell_run_sync (gitg_command_new (dialog->priv->repository,
- "remote",
- "rm",
- name,
- NULL),
- NULL);
-}
-
-void
-on_button_remove_remote_clicked (GtkButton *button,
- GitgRepositoryDialog *dialog)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (dialog->priv->tree_view_remotes);
-
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
- GList *refs = NULL;
- GList *item;
-
- for (item = rows; item; item = g_list_next (item))
- {
- GtkTreeRowReference *ref;
- GtkTreePath *path = (GtkTreePath *)item->data;
-
- ref = gtk_tree_row_reference_new (model, path);
- refs = g_list_prepend (refs, ref);
-
- gtk_tree_path_free (path);
- }
-
- refs = g_list_reverse (refs);
- g_list_free (rows);
-
- for (item = refs; item; item = g_list_next (item))
- {
- GtkTreeRowReference *ref = (GtkTreeRowReference *)item->data;
- GtkTreePath *path = gtk_tree_row_reference_get_path (ref);
- GtkTreeIter iter;
- gchar *name;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, COLUMN_NAME, &name, -1);
-
- gboolean ret = remove_remote (dialog, name);
-
- if (ret)
- {
- gtk_list_store_remove (dialog->priv->list_store_remotes, &iter);
- }
-
- gtk_tree_row_reference_free (ref);
- gtk_tree_path_free (path);
- }
-
- g_list_free (refs);
-}
-
-void
-on_button_add_remote_clicked (GtkButton *button,
- GitgRepositoryDialog *dialog)
-{
- GtkTreeModel *model = GTK_TREE_MODEL (dialog->priv->list_store_remotes);
- GtkTreeIter iter;
-
- gint num = 0;
-
- if (gtk_tree_model_get_iter_first (model, &iter))
- {
- do
- {
- gchar *name;
- gtk_tree_model_get (model, &iter, COLUMN_NAME, &name, -1);
-
- if (g_str_has_prefix (name, "remote"))
- {
- gint n = atoi (name + 6);
-
- if (n > num)
- {
- num = n;
- }
- }
-
- g_free (name);
- } while (gtk_tree_model_iter_next (model, &iter));
- }
-
- gchar *name = g_strdup_printf ("remote%d", num + 1);
- gchar const url[] = "git://example.com/repository.git";
-
- if (gitg_shell_run_sync (gitg_command_new (dialog->priv->repository,
- "remote",
- "add",
- name,
- url,
- NULL),
- NULL))
- {
- GtkTreeIter iter;
- GtkTreePath *path;
-
- add_remote (dialog, name, url, &iter);
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (dialog->priv->list_store_remotes), &iter);
-
- gtk_tree_view_set_cursor (dialog->priv->tree_view_remotes,
- path,
- gtk_tree_view_get_column (dialog->priv->tree_view_remotes, COLUMN_NAME),
- TRUE);
-
- gtk_tree_path_free (path);
- }
-
- g_free (name);
-}
-
-gboolean
-on_entry_repository_user_name_focus_out_event (GtkEntry *entry,
- GdkEventFocus *focus,
- GitgRepositoryDialog *dialog)
-{
- gchar const *text;
-
- text = gtk_entry_get_text (entry);
- gitg_config_set_value (dialog->priv->config, "user.name", *text ? text : NULL);
-
- return FALSE;
-}
-
-gboolean
-on_entry_repository_user_email_focus_out_event (GtkEntry *entry,
- GdkEventFocus *focus,
- GitgRepositoryDialog *dialog)
-{
- gchar const *text;
-
- text = gtk_entry_get_text (entry);
- gitg_config_set_value (dialog->priv->config, "user.email", *text ? text : NULL);
-
- return FALSE;
-}
-
-void
-on_remote_name_edited (GtkCellRendererText *renderer,
- gchar *path,
- gchar *new_text,
- GitgRepositoryDialog *dialog)
-{
- if (!*new_text)
- {
- return;
- }
-
- GtkTreePath *tp = gtk_tree_path_new_from_string (path);
- GtkTreeIter iter;
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->list_store_remotes),
- &iter,
- tp);
-
- gchar *oldname;
- gchar *url;
-
- gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->list_store_remotes),
- &iter,
- COLUMN_NAME, &oldname,
- COLUMN_URL, &url,
- -1);
-
- if (gitg_shell_run_sync (gitg_command_new (dialog->priv->repository,
- "remote",
- "add",
- new_text,
- url,
- NULL),
- NULL))
- {
- remove_remote (dialog, oldname);
-
- gtk_list_store_set (dialog->priv->list_store_remotes,
- &iter,
- COLUMN_NAME, new_text,
- -1);
-
- fetch_remote (dialog, &iter);
- }
-
- g_free (oldname);
- g_free (url);
-
- gtk_tree_path_free (tp);
-}
-
-void
-on_remote_url_edited (GtkCellRendererText *renderer,
- gchar *path,
- gchar *new_text,
- GitgRepositoryDialog *dialog)
-{
- if (!*new_text)
- {
- return;
- }
-
- GtkTreePath *tp = gtk_tree_path_new_from_string (path);
- GtkTreeIter iter;
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->list_store_remotes),
- &iter,
- tp);
-
- gchar *name;
- gchar *url;
-
- gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->list_store_remotes),
- &iter,
- COLUMN_NAME, &name,
- COLUMN_URL, &url,
- -1);
-
- if (g_strcmp0 (url, new_text) == 0)
- {
- g_free (name);
- g_free (url);
-
- gtk_tree_path_free (tp);
-
- return;
- }
-
- g_free (url);
-
- gchar *key = g_strconcat ("remote.", name, ".url", NULL);
- g_free (name);
-
- if (gitg_config_set_value (dialog->priv->config, key, new_text))
- {
- gtk_list_store_set (dialog->priv->list_store_remotes,
- &iter,
- COLUMN_URL, new_text,
- -1);
-
- fetch_remote (dialog, &iter);
- }
-
- g_free (key);
- gtk_tree_path_free (tp);
-}
diff --git a/gitg/gitg-repository-dialog.h b/gitg/gitg-repository-dialog.h
deleted file mode 100644
index e712edb..0000000
--- a/gitg/gitg-repository-dialog.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * gitg-repository-dialog.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REPOSITORY_DIALOG_H__
-#define __GITG_REPOSITORY_DIALOG_H__
-
-#include <gtk/gtk.h>
-#include "gitg-window.h"
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REPOSITORY_DIALOG (gitg_repository_dialog_get_type ())
-#define GITG_REPOSITORY_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REPOSITORY_DIALOG, GitgRepositoryDialog))
-#define GITG_REPOSITORY_DIALOG_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REPOSITORY_DIALOG, GitgRepositoryDialog const))
-#define GITG_REPOSITORY_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_REPOSITORY_DIALOG, GitgRepositoryDialogClass))
-#define GITG_IS_REPOSITORY_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REPOSITORY_DIALOG))
-#define GITG_IS_REPOSITORY_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_REPOSITORY_DIALOG))
-#define GITG_REPOSITORY_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_REPOSITORY_DIALOG, GitgRepositoryDialogClass))
-
-typedef struct _GitgRepositoryDialog GitgRepositoryDialog;
-typedef struct _GitgRepositoryDialogClass GitgRepositoryDialogClass;
-typedef struct _GitgRepositoryDialogPrivate GitgRepositoryDialogPrivate;
-
-struct _GitgRepositoryDialog
-{
- GtkDialog parent;
-
- GitgRepositoryDialogPrivate *priv;
-};
-
-struct _GitgRepositoryDialogClass
-{
- GtkDialogClass parent_class;
-};
-
-GType gitg_repository_dialog_get_type (void) G_GNUC_CONST;
-GitgRepositoryDialog *gitg_repository_dialog_present(GitgWindow *window);
-
-void gitg_repository_dialog_close (void);
-
-G_END_DECLS
-
-#endif /* __GITG_REPOSITORY_DIALOG_H__ */
diff --git a/gitg/gitg-repository.ui b/gitg/gitg-repository.ui
deleted file mode 100644
index f6012e5..0000000
--- a/gitg/gitg-repository.ui
+++ /dev/null
@@ -1,320 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.18"/>
- <!-- interface-requires gitg 0.2 -->
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkListStore" id="list_store_remotes">
- <columns>
- <!-- column-name name -->
- <column type="gchararray"/>
- <!-- column-name url -->
- <column type="gchararray"/>
- <!-- column-name fetching -->
- <column type="gboolean"/>
- <!-- column-name pulse -->
- <column type="gint"/>
- <!-- column-name spinner -->
- <column type="GdkPixbuf"/>
- </columns>
- </object>
- <object class="GitgRepositoryDialog" id="dialog_repository">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Properties</property>
- <property name="default_width">500</property>
- <property name="default_height">300</property>
- <property name="type_hint">normal</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog_vbox_main">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkNotebook" id="notebook_main">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkBox" id="vbox_remotes_intern">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_remotes">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTreeView" id="tree_view_remotes">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="model">list_store_remotes</property>
- <property name="rules_hint">True</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkTreeViewColumn" id="tree_view_remotes_column_name">
- <property name="title" translatable="yes">Name</property>
- <child>
- <object class="GtkCellRendererPixbuf" id="tree_view_remotes_renderer_icon">
- <property name="stock-id">gtk-network</property>
- </object>
- </child>
- <child>
- <object class="GtkCellRendererText" id="tree_view_remotes_renderer_name">
- <property name="editable">True</property>
- <signal name="edited" handler="on_remote_name_edited"/>
- </object>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="tree_view_remotes_column_url">
- <property name="title" translatable="yes">URL</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkCellRendererText" id="tree_view_remotes_renderer_url">
- <property name="editable">True</property>
- <signal name="edited" handler="on_remote_url_edited"/>
- </object>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox1">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkButton" id="button_fetch_remote">
- <property name="label" translatable="yes">Fetch</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image_fetch_remote</property>
- <signal name="clicked" handler="on_button_fetch_remote_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_add_remote">
- <property name="label">gtk-add</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_button_add_remote_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_remove_remote">
- <property name="label">gtk-remove</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_button_remove_remote_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_remotes">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Remotes</property>
- </object>
- <packing>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_configuration_intern">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_user">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;User&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox_configuration_message">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkLabel" id="label_spacer">
- <property name="visible">True</property>
- <property name="label"> </property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <property name="hexpand">True</property>
- <property name="vexpand">False</property>
- <child>
- <object class="GtkLabel" id="label_configuration_user_name">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Name:</property>
- </object>
- <packing>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_configuration_user_email">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">E-mail:</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_repository_user_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x25CF;</property>
- <signal name="focus_out_event" handler="on_entry_repository_user_name_focus_out_event"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_repository_user_email">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x25CF;</property>
- <signal name="focus_out_event" handler="on_entry_repository_user_email_focus_out_event"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_configuration">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Configuration</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog_action_area">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="button_close">
- <property name="label">gtk-close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="-7">button_close</action-widget>
- </action-widgets>
- </object>
- <object class="GtkImage" id="image_fetch_remote">
- <property name="visible">True</property>
- <property name="stock">gtk-refresh</property>
- </object>
-</interface>
diff --git a/gitg/gitg-resource.vala b/gitg/gitg-resource.vala
new file mode 100644
index 0000000..4af3c42
--- /dev/null
+++ b/gitg/gitg-resource.vala
@@ -0,0 +1,62 @@
+namespace Gitg
+{
+ class Resource
+ {
+ public static T[]? load_objects<T>(string id, string[] objects)
+ {
+ var builder = new Gtk.Builder();
+
+ try
+ {
+ builder.add_from_resource("/org/gnome/gitg/" + id);
+ }
+ catch (Error e)
+ {
+ warning("Error while loading resource: %s", e.message);
+ return null;
+ }
+
+ T[] ret = new T[objects.length];
+ ret.length = 0;
+
+ foreach (string obj in objects)
+ {
+ ret += (T)builder.get_object(obj);
+ }
+
+ return ret;
+ }
+
+ public static T? load_object<T>(string id, string object)
+ {
+ T[]? ret = load_objects<T>(id, new string[] {object});
+
+ if (ret == null)
+ {
+ return null;
+ }
+
+ return ret[0];
+ }
+
+ public static Gtk.CssProvider? load_css(string id)
+ {
+ var provider = new Gtk.CssProvider();
+ var f = File.new_for_uri("resource:///org/gnome/gitg/ui/" + id);
+
+ try
+ {
+ provider.load_from_file(f);
+ }
+ catch (Error e)
+ {
+ warning("Error while loading resource: %s", e.message);
+ return null;
+ }
+
+ return provider;
+ }
+ }
+}
+
+// ex: ts=4 noet
diff --git a/gitg/gitg-revision-changes-panel.c b/gitg/gitg-revision-changes-panel.c
deleted file mode 100644
index 8706e57..0000000
--- a/gitg/gitg-revision-changes-panel.c
+++ /dev/null
@@ -1,1048 +0,0 @@
-#include "gitg-revision-changes-panel.h"
-
-#include <gtksourceview/gtksourceview.h>
-#include <gtksourceview/gtksourcelanguagemanager.h>
-#include <gtksourceview/gtksourcestyleschememanager.h>
-#include <string.h>
-#include <libgitg/gitg-repository.h>
-#include <libgitg/gitg-revision.h>
-#include <libgitg/gitg-shell.h>
-#include <libgitg/gitg-hash.h>
-#include "gitg-diff-view.h"
-#include "gitg-utils.h"
-#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))
-
-struct _GitgRevisionChangesPanelPrivate
-{
- GtkWidget *panel_widget;
- GtkBuilder *builder;
-
- GtkSourceView *diff;
- GtkTreeView *diff_files;
- GtkListStore *list_store_diff_files;
-
- GitgShell *diff_shell;
- GitgShell *diff_files_shell;
-
- GitgRepository *repository;
- GitgRevision *revision;
- GSList *cached_headers;
-
- gchar *selection;
-
- GSettings *diff_settings;
-};
-
-typedef enum
-{
- DIFF_FILE_STATUS_NONE,
- DIFF_FILE_STATUS_NEW,
- DIFF_FILE_STATUS_MODIFIED,
- DIFF_FILE_STATUS_DELETED
-} DiffFileStatus;
-
-typedef struct
-{
- GitgDiffIter iter;
-} CachedHeader;
-
-typedef struct
-{
- gint refcount;
-
- gchar index_from[GITG_HASH_SHA_SIZE + 1];
- gchar index_to[GITG_HASH_SHA_SIZE + 1];
- DiffFileStatus status;
- gchar *filename;
-
- gboolean visible;
- GitgDiffIter iter;
-} 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);
-
-static GType diff_file_get_type (void) G_GNUC_CONST;
-
-G_DEFINE_TYPE_EXTENDED (GitgRevisionChangesPanel,
- gitg_revision_changes_panel,
- G_TYPE_OBJECT,
- 0,
- G_IMPLEMENT_INTERFACE (GITG_TYPE_REVISION_PANEL,
- gitg_revision_panel_iface_init);
- G_IMPLEMENT_INTERFACE (GITG_TYPE_ACTIVATABLE,
- gitg_activatable_iface_init));
-
-static void set_revision (GitgRevisionChangesPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision);
-
-static DiffFile *
-diff_file_new (gchar const *from,
- gchar *to,
- gchar const *status,
- gchar const *filename)
-{
- DiffFile *f = g_slice_new (DiffFile);
-
- strncpy (f->index_from, from, GITG_HASH_SHA_SIZE);
- strncpy (f->index_to, to, GITG_HASH_SHA_SIZE);
-
- f->index_from[GITG_HASH_SHA_SIZE] = '\0';
- f->index_to[GITG_HASH_SHA_SIZE] = '\0';
- f->visible = FALSE;
-
- DiffFileStatus st;
-
- switch (*status)
- {
- case 'A':
- st = DIFF_FILE_STATUS_NEW;
- break;
- case 'D':
- st = DIFF_FILE_STATUS_DELETED;
- break;
- default:
- st = DIFF_FILE_STATUS_MODIFIED;
- break;
- }
-
- f->status = st;
- f->filename = g_strdup (filename);
- f->refcount = 1;
-
- return f;
-}
-
-static DiffFile *
-diff_file_copy (DiffFile *f)
-{
- g_atomic_int_inc (&f->refcount);
- return f;
-}
-
-static void
-diff_file_unref (DiffFile *f)
-{
- if (!g_atomic_int_dec_and_test (&f->refcount))
- {
- return;
- }
-
- g_free (f->filename);
- g_slice_free (DiffFile, f);
-}
-
-G_DEFINE_BOXED_TYPE (DiffFile, diff_file, diff_file_copy, diff_file_unref)
-
-static void
-revision_files_icon (GtkTreeViewColumn *column,
- GtkCellRenderer *renderer,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GitgRevisionChangesPanel *self)
-{
- DiffFile *f;
- gtk_tree_model_get (model, iter, 0, &f, -1);
-
- gchar const *id = NULL;
-
- switch (f->status)
- {
- case DIFF_FILE_STATUS_NEW:
- id = GTK_STOCK_NEW;
- break;
- case DIFF_FILE_STATUS_MODIFIED:
- id = GTK_STOCK_EDIT;
- break;
- case DIFF_FILE_STATUS_DELETED:
- id = GTK_STOCK_DELETE;
- break;
- default:
- break;
- }
-
- g_object_set (G_OBJECT(renderer), "stock-id", id, NULL);
- diff_file_unref (f);
-}
-
-static void
-revision_files_name (GtkTreeViewColumn *column,
- GtkCellRenderer *renderer,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GitgRevisionChangesPanel *self)
-{
- DiffFile *f;
- gtk_tree_model_get (model, iter, 0, &f, -1);
-
- g_object_set (G_OBJECT(renderer), "text", f->filename, NULL);
-
- diff_file_unref (f);
-}
-
-static gboolean
-diff_file_visible (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer data)
-{
- DiffFile *f;
- gtk_tree_model_get (model, iter, 0, &f, -1);
-
- if (!f)
- {
- return FALSE;
- }
-
- gboolean ret = f->visible;
- diff_file_unref (f);
-
- return ret;
-}
-
-static gboolean
-on_diff_files_button_press (GtkTreeView *treeview,
- GdkEventButton *event,
- GitgRevisionChangesPanel *view)
-{
- if (event->button != 1)
- {
- return FALSE;
- }
-
- if (event->window != gtk_tree_view_get_bin_window (treeview))
- {
- return FALSE;
- }
-
- GtkTreePath *path;
-
- if (!gtk_tree_view_get_path_at_pos (treeview,
- event->x,
- event->y,
- &path,
- NULL,
- NULL,
- NULL))
- {
- return FALSE;
- }
-
- GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
- gboolean ret = FALSE;
-
- if (gtk_tree_selection_path_is_selected (selection, path) &&
- gtk_tree_selection_count_selected_rows (selection) == 1)
- {
- /* deselect */
- gtk_tree_selection_unselect_path (selection, path);
- ret = TRUE;
- }
-
- gtk_tree_path_free (path);
- return ret;
-}
-
-static void
-gitg_revision_panel_update_impl (GitgRevisionPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- GitgRevisionChangesPanel *changes_panel;
-
- changes_panel = GITG_REVISION_CHANGES_PANEL (panel);
-
- set_revision (changes_panel, repository, revision);
-}
-
-static gchar *
-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)
-{
- GitgRevisionChangesPanelPrivate *priv = changes_panel->priv;
-
- priv->diff = GTK_SOURCE_VIEW (gtk_builder_get_object (priv->builder,
- "revision_diff"));
-
- priv->diff_files = GTK_TREE_VIEW (gtk_builder_get_object (priv->builder,
- "tree_view_revision_files"));
-
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (priv->diff_files);
-
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
-
- g_signal_connect (selection,
- "changed",
- G_CALLBACK (on_diff_files_selection_changed),
- changes_panel);
-
- g_signal_connect (priv->diff_files,
- "button-press-event",
- G_CALLBACK (on_diff_files_button_press),
- changes_panel);
-
- priv->list_store_diff_files = gtk_list_store_new (1, diff_file_get_type ());
-
- GtkTreeModel *filter;
-
- filter = gtk_tree_model_filter_new (GTK_TREE_MODEL(priv->list_store_diff_files),
- NULL);
- gtk_tree_view_set_model (priv->diff_files, filter);
-
- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
- diff_file_visible,
- NULL,
- NULL);
-
- GtkTreeViewColumn *column;
-
- column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (priv->builder,
- "revision_files_column_icon"));
-
- gtk_tree_view_column_set_cell_data_func (column,
- GTK_CELL_RENDERER (gtk_builder_get_object (priv->builder,
- "revision_files_cell_renderer_icon")),
- (GtkTreeCellDataFunc)revision_files_icon,
- changes_panel,
- NULL);
-
- column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (priv->builder,
- "revision_files_column_name"));
- gtk_tree_view_column_set_cell_data_func (column,
- GTK_CELL_RENDERER (gtk_builder_get_object (priv->builder,
- "revision_files_cell_renderer_name")),
- (GtkTreeCellDataFunc)revision_files_name,
- changes_panel,
- NULL);
-
- GtkSourceLanguageManager *manager;
- GtkSourceLanguage *language;
- GtkSourceBuffer *buffer;
-
- manager = gtk_source_language_manager_get_default ();
- language = gtk_source_language_manager_get_language (manager, "gitgdiff");
- buffer = gtk_source_buffer_new_with_language (language);
-
- g_object_unref (language);
-
- GtkSourceStyleSchemeManager *scheme_manager;
- GtkSourceStyleScheme *scheme;
-
- scheme_manager = gtk_source_style_scheme_manager_get_default ();
- scheme = gtk_source_style_scheme_manager_get_scheme (scheme_manager,
- "gitg");
- gtk_source_buffer_set_style_scheme (buffer, scheme);
-
- gitg_utils_set_monospace_font (GTK_WIDGET (priv->diff));
- gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->diff),
- GTK_TEXT_BUFFER (buffer));
-
- g_signal_connect (priv->diff,
- "header-added",
- G_CALLBACK (on_header_added),
- changes_panel);
-}
-
-static GtkWidget *
-gitg_revision_panel_get_panel_impl (GitgRevisionPanel *panel)
-{
- GtkBuilder *builder;
- GtkWidget *ret;
- GitgRevisionChangesPanel *changes_panel;
-
- changes_panel = GITG_REVISION_CHANGES_PANEL (panel);
-
- if (changes_panel->priv->panel_widget)
- {
- return changes_panel->priv->panel_widget;
- }
-
- builder = gitg_utils_new_builder ("gitg-revision-changes-panel.ui");
- changes_panel->priv->builder = builder;
-
- ret = GTK_WIDGET (gtk_builder_get_object (builder, "revision_changes_page"));
- changes_panel->priv->panel_widget = ret;
-
- initialize_ui (changes_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);
-}
-
-static void
-free_cached_headers (GitgRevisionChangesPanel *changes_panel)
-{
- g_slist_free_full (changes_panel->priv->cached_headers, free_cached_header);
-
- changes_panel->priv->cached_headers = NULL;
-}
-
-static void
-gitg_revision_changes_panel_finalize (GObject *object)
-{
- free_cached_headers (GITG_REVISION_CHANGES_PANEL (object));
-
- G_OBJECT_CLASS (gitg_revision_changes_panel_parent_class)->finalize (object);
-}
-
-static void
-gitg_revision_changes_panel_dispose (GObject *object)
-{
- GitgRevisionChangesPanel *changes_panel;
-
- changes_panel = GITG_REVISION_CHANGES_PANEL (object);
-
- set_revision (changes_panel, NULL, NULL);
-
- if (changes_panel->priv->diff_settings)
- {
- g_object_unref (changes_panel->priv->diff_settings);
- changes_panel->priv->diff_settings = NULL;
- }
-
- if (changes_panel->priv->diff_files_shell)
- {
- g_object_unref (changes_panel->priv->diff_files_shell);
- changes_panel->priv->diff_files_shell = NULL;
- }
-
- if (changes_panel->priv->diff_files_shell)
- {
- g_object_unref (changes_panel->priv->diff_shell);
- changes_panel->priv->diff_shell = NULL;
- }
-
- 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);
-}
-
-static void
-gitg_revision_changes_panel_class_init (GitgRevisionChangesPanelClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_revision_changes_panel_finalize;
- object_class->dispose = gitg_revision_changes_panel_dispose;
-
- g_type_class_add_private (object_class, sizeof(GitgRevisionChangesPanelPrivate));
-}
-
-static void
-reload_diff (GitgRevisionChangesPanel *changes_panel)
-{
- GtkTreeSelection *selection;
-
- // First cancel a possibly still running diff
- gitg_io_cancel (GITG_IO (changes_panel->priv->diff_shell));
- gitg_io_cancel (GITG_IO (changes_panel->priv->diff_files_shell));
-
- free_cached_headers (changes_panel);
-
- // Clear the buffer
- GtkTextBuffer *buffer;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (changes_panel->priv->diff));
- gtk_text_buffer_set_text (buffer, "", 0);
-
- selection = gtk_tree_view_get_selection (changes_panel->priv->diff_files);
- g_signal_handlers_block_by_func (selection,
- G_CALLBACK (on_diff_files_selection_changed),
- changes_panel);
-
- gtk_list_store_clear (changes_panel->priv->list_store_diff_files);
-
- g_signal_handlers_unblock_by_func (selection,
- G_CALLBACK (on_diff_files_selection_changed),
- changes_panel);
-
- if (!changes_panel->priv->revision)
- {
- return;
- }
-
- gchar sign = gitg_revision_get_sign (changes_panel->priv->revision);
- gboolean allow_external;
-
- allow_external = g_settings_get_boolean (changes_panel->priv->diff_settings,
- "external");
-
- switch (sign)
- {
- case 't':
- gitg_shell_run (changes_panel->priv->diff_shell,
- gitg_command_new (changes_panel->priv->repository,
- "diff",
- allow_external ? "--ext-diff" : "--no-ext-diff",
- "--cached",
- "-M",
- "--pretty=format:",
- "--encoding=UTF-8",
- "--no-color",
- NULL),
- NULL);
- break;
- case 'u':
- gitg_shell_run (changes_panel->priv->diff_shell,
- gitg_command_new (changes_panel->priv->repository,
- "diff",
- allow_external ? "--ext-diff" : "--no-ext-diff",
- "-M",
- "--pretty=format:",
- "--encoding=UTF-8",
- "--no-color",
- NULL),
- NULL);
- break;
- default:
- {
- gchar *hash = gitg_revision_get_sha1 (changes_panel->priv->revision);
-
- gitg_shell_run (changes_panel->priv->diff_shell,
- gitg_command_new (changes_panel->priv->repository,
- "show",
- "-M",
- "--pretty=format:",
- "--encoding=UTF-8",
- "--no-color",
- hash,
- NULL),
- NULL);
-
- g_free (hash);
- }
- break;
- }
-}
-
-static void
-set_revision (GitgRevisionChangesPanel *changes_panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- if (changes_panel->priv->repository == repository &&
- changes_panel->priv->revision == revision)
- {
- return;
- }
-
- if (changes_panel->priv->diff_shell)
- {
- gitg_io_cancel (GITG_IO (changes_panel->priv->diff_shell));
- }
-
- if (changes_panel->priv->diff_files_shell)
- {
- gitg_io_cancel (GITG_IO (changes_panel->priv->diff_files_shell));
- }
-
- if (changes_panel->priv->repository)
- {
- g_object_unref (changes_panel->priv->repository);
- }
-
- if (changes_panel->priv->revision)
- {
- gitg_revision_unref (changes_panel->priv->revision);
- }
-
- if (repository)
- {
- changes_panel->priv->repository = g_object_ref (repository);
- }
- else
- {
- changes_panel->priv->repository = NULL;
- }
-
- if (revision)
- {
- changes_panel->priv->revision = gitg_revision_ref (revision);
- }
- else
- {
- changes_panel->priv->revision = NULL;
- }
-
- reload_diff (changes_panel);
-}
-
-static void
-on_diff_files_begin_loading (GitgShell *shell,
- GitgRevisionChangesPanel *self)
-{
- GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
-
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (self->priv->diff_files)),
- cursor);
-
- g_object_unref (cursor);
-}
-
-static void
-on_diff_files_end_loading (GitgShell *shell,
- gboolean cancelled,
- GitgRevisionChangesPanel *self)
-{
- 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
-match_indices (DiffFile *f,
- gchar const *from,
- gchar const *to)
-{
- return g_str_has_prefix (f->index_from, from) &&
- (g_str_has_prefix (f->index_to, to) ||
- g_str_has_prefix (f->index_to, "0000000"));
-}
-
-static void
-visible_from_cached_headers (GitgRevisionChangesPanel *view,
- DiffFile *f)
-{
- GSList *item;
-
- for (item = view->priv->cached_headers; item; item = g_slist_next (item))
- {
- CachedHeader *header = (CachedHeader *)item->data;
- gchar *from;
- gchar *to;
-
- gitg_diff_iter_get_index (&header->iter, &from, &to);
-
- if (gitg_diff_iter_get_index (&header->iter, &from, &to) && match_indices (f, from, to))
- {
- f->visible = TRUE;
- f->iter = header->iter;
-
- return;
- }
- }
-}
-
-static void
-add_diff_file (GitgRevisionChangesPanel *view,
- DiffFile *f)
-{
- GtkTreeIter iter;
- gtk_list_store_append (view->priv->list_store_diff_files, &iter);
-
- /* see if it is in the cached headers */
- visible_from_cached_headers (view, f);
- gtk_list_store_set (view->priv->list_store_diff_files, &iter, 0, f, -1);
-}
-
-static void
-on_diff_files_update (GitgShell *shell,
- gchar **buffer,
- GitgRevisionChangesPanel *self)
-{
- gchar **line;
-
- while (*(line = buffer++))
- {
- if (**line == '\0')
- {
- continue;
- }
-
- // Count parents
- gint parents = 0;
- gchar *ptr = *line;
-
- while (*(ptr++) == ':')
- {
- ++parents;
- }
-
- gint numparts = 3 + 2 * parents;
- gchar **parts = g_strsplit (ptr, " ", numparts);
-
- if (g_strv_length (parts) == numparts)
- {
- gchar **files = g_strsplit (parts[numparts - 1], "\t", -1);
-
- DiffFile *f = diff_file_new (parts[parents + 1], parts[numparts - 2], files[0], files[1]);
-
- add_diff_file (self, f);
- diff_file_unref (f);
-
- g_strfreev (files);
- }
-
- g_strfreev (parts);
- }
-}
-
-static void
-on_diff_begin_loading (GitgShell *shell,
- GitgRevisionChangesPanel *self)
-{
- GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET(self->priv->diff)),
- cursor);
- g_object_unref (cursor);
-}
-
-static void
-on_diff_end_loading (GitgShell *shell,
- gboolean cancelled,
- GitgRevisionChangesPanel *self)
-{
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET(self->priv->diff)),
- NULL);
-
- if (cancelled)
- {
- return;
- }
-
- gchar sign = gitg_revision_get_sign (self->priv->revision);
- gboolean allow_external;
-
- allow_external = g_settings_get_boolean (self->priv->diff_settings,
- "external");
-
- if (sign == 't' || sign == 'u')
- {
- gchar *head = gitg_repository_parse_head (self->priv->repository);
- const gchar *cached = NULL;
-
- if (sign == 't')
- cached = "--cached";
-
- gitg_shell_run (self->priv->diff_files_shell,
- gitg_command_new (self->priv->repository,
- "diff-index",
- allow_external ? "--ext-diff" : "--no-ext-diff",
- "--raw",
- "-M",
- "--abbrev=40",
- head,
- cached,
- NULL),
- NULL);
- g_free (head);
- }
- else
- {
- gchar *sha = gitg_revision_get_sha1 (self->priv->revision);
- gitg_shell_run (self->priv->diff_files_shell,
- gitg_command_new (self->priv->repository,
- "show",
- "--encoding=UTF-8",
- "--raw",
- "-M",
- "--pretty=format:",
- "--abbrev=40",
- sha,
- NULL),
- NULL);
- g_free (sha);
- }
-}
-
-static void
-on_diff_update (GitgShell *shell,
- gchar **buffer,
- GitgRevisionChangesPanel *self)
-{
- gchar *line;
- GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(self->priv->diff));
- GtkTextIter iter;
-
- gtk_text_buffer_get_end_iter (buf, &iter);
-
- while ((line = *buffer++))
- {
- gtk_text_buffer_insert (buf, &iter, line, -1);
- gtk_text_buffer_insert (buf, &iter, "\n", -1);
- }
-}
-
-static void
-gitg_revision_changes_panel_init (GitgRevisionChangesPanel *self)
-{
- self->priv = GITG_REVISION_CHANGES_PANEL_GET_PRIVATE (self);
-
- self->priv->diff_settings = g_settings_new ("org.gnome.gitg.preferences.diff");
- self->priv->diff_shell = gitg_shell_new (2000);
-
- g_signal_connect (self->priv->diff_shell,
- "begin",
- G_CALLBACK (on_diff_begin_loading),
- self);
-
- g_signal_connect (self->priv->diff_shell,
- "update",
- G_CALLBACK (on_diff_update),
- self);
-
- g_signal_connect (self->priv->diff_shell,
- "end",
- G_CALLBACK (on_diff_end_loading),
- self);
-
- self->priv->diff_files_shell = gitg_shell_new (2000);
-
- g_signal_connect (self->priv->diff_files_shell,
- "begin",
- G_CALLBACK(on_diff_files_begin_loading),
- self);
-
- g_signal_connect (self->priv->diff_files_shell,
- "update",
- G_CALLBACK(on_diff_files_update),
- self);
-
- g_signal_connect (self->priv->diff_files_shell,
- "end",
- G_CALLBACK(on_diff_files_end_loading),
- self);
-}
-
-static gboolean
-find_diff_file (GitgRevisionChangesPanel *view,
- GitgDiffIter *iter,
- GtkTreeIter *it,
- DiffFile **f)
-{
- gchar *from;
- gchar *to;
-
- if (!gitg_diff_iter_get_index (iter, &from, &to))
- {
- return FALSE;
- }
-
- GtkTreeModel *model = GTK_TREE_MODEL (view->priv->list_store_diff_files);
-
- if (!gtk_tree_model_get_iter_first (model, it))
- {
- return FALSE;
- }
-
- do
- {
- gtk_tree_model_get (model, it, 0, f, -1);
-
- if (match_indices (*f, from, to))
- {
- return TRUE;
- }
-
- diff_file_unref (*f);
- } while (gtk_tree_model_iter_next (model, it));
-
- return FALSE;
-}
-
-static void
-on_header_added (GitgDiffView *view,
- GitgDiffIter *iter,
- GitgRevisionChangesPanel *self)
-{
- GtkTreeIter it;
- DiffFile *f;
-
- if (find_diff_file (self, iter, &it, &f))
- {
- if (!f->visible)
- {
- f->visible = TRUE;
- f->iter = *iter;
-
- diff_file_unref (f);
-
- GtkTreeModel *model = GTK_TREE_MODEL (self->priv->list_store_diff_files);
- GtkTreePath *path = gtk_tree_model_get_path (model, &it);
-
- gtk_tree_model_row_changed (model, path, &it);
- gtk_tree_path_free (path);
- }
- }
- else
- {
- /* Insert in cached headers */
- CachedHeader *header = g_slice_new (CachedHeader);
- header->iter = *iter;
-
- self->priv->cached_headers = g_slist_prepend (self->priv->cached_headers, header);
- }
-}
-
-typedef struct
-{
- gint numselected;
- GtkTreeSelection *selection;
-} ForeachSelectionData;
-
-static gboolean
-foreach_selection_changed (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- ForeachSelectionData *data)
-{
- gboolean visible = data->numselected == 0 ||
- gtk_tree_selection_path_is_selected (data->selection,
- path);
-
- DiffFile *f = NULL;
- gtk_tree_model_get (model, iter, 0, &f, -1);
-
- if (f->visible)
- {
- gitg_diff_iter_set_visible (&f->iter, visible);
- }
-
- diff_file_unref (f);
- return FALSE;
-}
-
-static void
-on_diff_files_selection_changed (GtkTreeSelection *selection,
- GitgRevisionChangesPanel *self)
-{
- ForeachSelectionData data = {
- gtk_tree_selection_count_selected_rows (selection),
- selection
- };
-
- gtk_tree_model_foreach (gtk_tree_view_get_model (self->priv->diff_files),
- (GtkTreeModelForeachFunc)foreach_selection_changed,
- &data);
-}
-
diff --git a/gitg/gitg-revision-changes-panel.h b/gitg/gitg-revision-changes-panel.h
deleted file mode 100644
index 0741d00..0000000
--- a/gitg/gitg-revision-changes-panel.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __GITG_REVISION_CHANGES_PANEL_H__
-#define __GITG_REVISION_CHANGES_PANEL_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REVISION_CHANGES_PANEL (gitg_revision_changes_panel_get_type ())
-#define GITG_REVISION_CHANGES_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_CHANGES_PANEL, GitgRevisionChangesPanel))
-#define GITG_REVISION_CHANGES_PANEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_CHANGES_PANEL, GitgRevisionChangesPanel const))
-#define GITG_REVISION_CHANGES_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_REVISION_CHANGES_PANEL, GitgRevisionChangesPanelClass))
-#define GITG_IS_REVISION_CHANGES_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REVISION_CHANGES_PANEL))
-#define GITG_IS_REVISION_CHANGES_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_REVISION_CHANGES_PANEL))
-#define GITG_REVISION_CHANGES_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_REVISION_CHANGES_PANEL, GitgRevisionChangesPanelClass))
-
-typedef struct _GitgRevisionChangesPanel GitgRevisionChangesPanel;
-typedef struct _GitgRevisionChangesPanelClass GitgRevisionChangesPanelClass;
-typedef struct _GitgRevisionChangesPanelPrivate GitgRevisionChangesPanelPrivate;
-
-struct _GitgRevisionChangesPanel {
- GObject parent;
-
- GitgRevisionChangesPanelPrivate *priv;
-};
-
-struct _GitgRevisionChangesPanelClass {
- GObjectClass parent_class;
-};
-
-GType gitg_revision_changes_panel_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* __GITG_REVISION_CHANGES_PANEL_H__ */
diff --git a/gitg/gitg-revision-changes-panel.ui b/gitg/gitg-revision-changes-panel.ui
deleted file mode 100644
index aab03bf..0000000
--- a/gitg/gitg-revision-changes-panel.ui
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <object class="GtkBox" id="revision_changes_page">
- <property name="visible">True</property>
- <property name="spacing">3</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkHPaned" id="hpaned_revision_view">
- <property name="visible">True</property>
- <property name="position">200</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_revision_files">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTreeView" id="tree_view_revision_files">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkTreeViewColumn" id="revision_files_column_icon">
- <property name="sizing">fixed</property>
- <property name="fixed_width">20</property>
- <property name="title">Icon</property>
- <child>
- <object class="GtkCellRendererPixbuf" id="revision_files_cell_renderer_icon"/>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="revision_files_column_name">
- <property name="title">Filename</property>
- <child>
- <object class="GtkCellRendererText" id="revision_files_cell_renderer_name"/>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_details">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GitgDiffView" id="revision_diff">
- <property name="editable">False</property>
- <property name="cursor_visible">False</property>
- <property name="show_line_numbers">False</property>
- <property name="tab_width">4</property>
- <property name="diff_enabled">True</property>
- <property name="expand">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
-</interface>
diff --git a/gitg/gitg-revision-details-panel.c b/gitg/gitg-revision-details-panel.c
deleted file mode 100644
index f45aeac..0000000
--- a/gitg/gitg-revision-details-panel.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * gitg-revision-details-panel.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-
-#include "gitg-revision-details-panel.h"
-#include "gitg-utils.h"
-#include "gitg-revision-panel.h"
-#include "gitg-stat-view.h"
-#include "gitg-uri.h"
-#include "gitg-avatar-cache.h"
-
-#include <glib/gi18n.h>
-#include <stdlib.h>
-
-#define GITG_REVISION_DETAILS_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_REVISION_DETAILS_PANEL, GitgRevisionDetailsPanelPrivate))
-
-typedef struct
-{
- gchar *file;
- guint added;
- guint removed;
-} StatInfo;
-
-struct _GitgRevisionDetailsPanelPrivate
-{
- GtkLabel *sha;
- GtkLabel *author;
- GtkLabel *committer;
- GtkLabel *subject;
- GtkTable *parents;
- GtkImage *avatar;
-
- GtkWidget *panel_widget;
- GtkTextView *text_view;
-
- GtkBuilder *builder;
-
- GitgRepository *repository;
- GitgRevision *revision;
-
- GitgShell *shell;
- gboolean in_stat;
-
- GSList *stats;
- GitgWindow *window;
-
- GitgAvatarCache *cache;
-};
-
-static void gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface);
-
-static void set_revision (GitgRevisionDetailsPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision);
-
-G_DEFINE_TYPE_EXTENDED (GitgRevisionDetailsPanel,
- gitg_revision_details_panel,
- G_TYPE_OBJECT,
- 0,
- G_IMPLEMENT_INTERFACE (GITG_TYPE_REVISION_PANEL,
- gitg_revision_panel_iface_init));
-
-static void
-update_markup (GObject *object)
-{
- GtkLabel *label = GTK_LABEL(object);
- gchar const *text = gtk_label_get_text (label);
-
- gchar *newtext = g_strconcat ("<span weight='bold' foreground='#777'>",
- text,
- "</span>",
- NULL);
-
- gtk_label_set_markup (label, newtext);
- g_free (newtext);
-}
-
-static void
-gitg_revision_panel_update_impl (GitgRevisionPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- GitgRevisionDetailsPanel *details_panel;
-
- details_panel = GITG_REVISION_DETAILS_PANEL (panel);
-
- set_revision (details_panel, repository, revision);
-}
-
-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"));
-}
-
-static void
-initialize_ui (GitgRevisionDetailsPanel *panel)
-{
- GitgRevisionDetailsPanelPrivate *priv = panel->priv;
-
- priv->sha = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_sha"));
- priv->author = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_author"));
- priv->committer = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_committer"));
- priv->subject = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_subject"));
- priv->parents = GTK_TABLE (gtk_builder_get_object (priv->builder, "table_parents"));
- priv->text_view = GTK_TEXT_VIEW (gtk_builder_get_object (priv->builder, "text_view_details"));
- priv->avatar = GTK_IMAGE (gtk_builder_get_object (priv->builder, "image_avatar"));
-
- gchar const *lbls[] = {
- "label_subject_lbl",
- "label_author_lbl",
- "label_committer_lbl",
- "label_sha_lbl",
- "label_parent_lbl"
- };
-
- gint i;
-
- for (i = 0; i < sizeof (lbls) / sizeof (gchar *); ++i)
- {
- update_markup (gtk_builder_get_object (priv->builder, lbls[i]));
- }
-}
-
-static GtkWidget *
-gitg_revision_panel_get_panel_impl (GitgRevisionPanel *panel)
-{
- GtkBuilder *builder;
- GtkWidget *ret;
- GitgRevisionDetailsPanel *details_panel;
-
- details_panel = GITG_REVISION_DETAILS_PANEL (panel);
-
- if (details_panel->priv->panel_widget)
- {
- return details_panel->priv->panel_widget;
- }
-
- builder = gitg_utils_new_builder ("gitg-revision-details-panel.ui");
- details_panel->priv->builder = builder;
-
- ret = GTK_WIDGET (gtk_builder_get_object (builder, "revision_details_page"));
- details_panel->priv->panel_widget = ret;
-
- initialize_ui (details_panel);
-
- return ret;
-}
-
-static void
-gitg_revision_panel_initialize_impl (GitgRevisionPanel *panel,
- GitgWindow *window)
-{
- GITG_REVISION_DETAILS_PANEL (panel)->priv->window = window;
-}
-
-static void
-gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface)
-{
- iface->initialize = gitg_revision_panel_initialize_impl;
- 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_revision_details_panel_finalize (GObject *object)
-{
- G_OBJECT_CLASS (gitg_revision_details_panel_parent_class)->finalize (object);
-}
-
-static void
-gitg_revision_details_panel_dispose (GObject *object)
-{
- GitgRevisionDetailsPanel *panel = GITG_REVISION_DETAILS_PANEL (object);
-
- set_revision (panel, NULL, NULL);
-
- if (panel->priv->builder)
- {
- g_object_unref (panel->priv->builder);
- panel->priv->builder = NULL;
- }
-
- if (panel->priv->shell)
- {
- gitg_io_cancel (GITG_IO (panel->priv->shell));
- g_object_unref (panel->priv->shell);
-
- panel->priv->shell = NULL;
- }
-
- if (panel->priv->cache)
- {
- g_object_unref (panel->priv->cache);
- panel->priv->cache = NULL;
- }
-
- G_OBJECT_CLASS (gitg_revision_details_panel_parent_class)->dispose (object);
-}
-static void
-gitg_revision_details_panel_class_init (GitgRevisionDetailsPanelClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- object_class->finalize = gitg_revision_details_panel_finalize;
- object_class->dispose = gitg_revision_details_panel_dispose;
-
- g_type_class_add_private (object_class, sizeof (GitgRevisionDetailsPanelPrivate));
-}
-
-static void
-on_shell_begin (GitgShell *shell,
- GitgRevisionDetailsPanel *panel)
-{
- GdkCursor *cursor;
-
- cursor = gdk_cursor_new (GDK_WATCH);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (panel->priv->text_view)),
- cursor);
-
- panel->priv->in_stat = FALSE;
-
- g_object_unref (cursor);
-}
-
-static gboolean
-link_button_activate_link_cb (GtkLinkButton *button,
- GitgWindow *window)
-{
- const gchar *uri;
- GFile *file;
- GitgRepository *repository;
- gchar *work_tree_path;
- gchar *selection;
- gchar *activatable;
- gchar *action;
-
- uri = gtk_link_button_get_uri (button);
- file = g_file_new_for_uri (uri);
- repository = gitg_window_get_repository (window);
-
- if (g_file_has_uri_scheme (file, "gitg") &&
- gitg_uri_parse (uri, &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);
-
- return TRUE;
- }
-
- g_object_unref (file);
-
- return FALSE;
-}
-
-static void
-make_stats_table (GitgRevisionDetailsPanel *panel)
-{
- guint num;
- GtkTable *table;
- GSList *item;
- guint i;
- guint max_lines = 0;
- GtkTextChildAnchor *anchor;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- gchar *path;
- gchar *repo_uri;
- gchar *sha1;
- GFile *work_tree;
-
- if (!panel->priv->stats)
- {
- return;
- }
-
- num = g_slist_length (panel->priv->stats);
- table = GTK_TABLE (gtk_table_new (num, 3, FALSE));
- gtk_table_set_row_spacings (table, 3);
- gtk_table_set_col_spacings (table, 6);
-
- for (item = panel->priv->stats; item; item = g_slist_next (item))
- {
- StatInfo *info = item->data;
- guint total = info->added + info->removed;
-
- if (total > max_lines)
- {
- max_lines = total;
- }
- }
-
- item = panel->priv->stats;
- work_tree = gitg_repository_get_work_tree (panel->priv->repository);
- path = g_file_get_path (work_tree);
- sha1 = gitg_revision_get_sha1 (panel->priv->revision);
-
- g_object_unref (work_tree);
-
- repo_uri = g_strdup_printf ("gitg://%s:%s", path, sha1);
-
- g_free (sha1);
- g_free (path);
-
- for (i = 0; i < num; ++i)
- {
- StatInfo *info = item->data;
- GtkWidget *view;
- GtkWidget *file;
- GtkWidget *total;
- GtkWidget *align;
- gchar *total_str;
- gchar *uri;
-
- view = gitg_stat_view_new (info->added,
- info->removed,
- max_lines);
-
- align = gtk_alignment_new (0, 0.5, 1, 0);
- gtk_widget_set_size_request (view, 300, 18);
-
- gtk_container_add (GTK_CONTAINER (align), view);
-
- uri = g_strdup_printf ("%s/changes/%s", repo_uri, info->file);
-
- file = gtk_link_button_new_with_label (uri,
- info->file);
-
- g_free (uri);
-
- gtk_button_set_alignment (GTK_BUTTON (file),
- 0,
- 0.5);
- g_signal_connect (file,
- "activate-link",
- G_CALLBACK (link_button_activate_link_cb),
- panel->priv->window);
-
- total_str = g_strdup_printf ("%d", info->added + info->removed);
- total = gtk_label_new (total_str);
- g_free (total_str);
-
- g_free (info->file);
- g_slice_free (StatInfo, info);
-
- gtk_table_attach (table, file,
- 0, 1, i, i + 1,
- GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
- 0, 0);
-
- gtk_table_attach (table, align,
- 1, 2, i, i + 1,
- GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL,
- 0, 0);
-
- gtk_table_attach (table, total,
- 2, 3, i, i + 1,
- GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
- 0, 0);
-
- gtk_widget_show (view);
- gtk_widget_show (file);
- gtk_widget_show (total);
- gtk_widget_show (align);
-
- item = g_slist_next (item);
- }
-
- gtk_widget_show (GTK_WIDGET (table));
-
- buffer = gtk_text_view_get_buffer (panel->priv->text_view);
-
- gtk_text_buffer_get_end_iter (buffer, &iter);
- gtk_text_buffer_insert (buffer, &iter, "\n\n", 2);
-
- anchor = gtk_text_buffer_create_child_anchor (buffer,
- &iter);
-
- gtk_text_view_add_child_at_anchor (panel->priv->text_view,
- GTK_WIDGET (table),
- anchor);
-}
-
-static void
-on_shell_end (GitgShell *shell,
- gboolean cancelled,
- GitgRevisionDetailsPanel *panel)
-{
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (panel->priv->text_view)),
- NULL);
-
- panel->priv->stats = g_slist_reverse (panel->priv->stats);
-
- make_stats_table (panel);
-
- g_slist_free (panel->priv->stats);
- panel->priv->stats = NULL;
-}
-
-static void
-strip_trailing_newlines (GtkTextBuffer *buffer)
-{
- GtkTextIter iter;
- GtkTextIter end;
-
- gtk_text_buffer_get_end_iter (buffer, &iter);
-
- if (!gtk_text_iter_starts_line (&iter))
- {
- return;
- }
-
- while (!gtk_text_iter_is_start (&iter) &&
- gtk_text_iter_ends_line (&iter))
- {
- if (!gtk_text_iter_backward_line (&iter))
- {
- break;
- }
- }
-
- gtk_text_iter_forward_to_line_end (&iter);
-
- gtk_text_buffer_get_end_iter (buffer, &end);
- gtk_text_buffer_delete (buffer, &iter, &end);
-}
-
-static void
-add_stat (GitgRevisionDetailsPanel *panel,
- gchar const *line)
-{
- gchar **parts;
-
- parts = g_strsplit_set (line, "\t ", -1);
-
- if (g_strv_length (parts) == 3)
- {
- StatInfo *stat;
-
- stat = g_slice_new (StatInfo);
-
- stat->added = (guint)atoi (parts[0]);
- stat->removed = (guint)atoi (parts[1]);
- stat->file = g_strdup (parts[2]);
-
- panel->priv->stats = g_slist_prepend (panel->priv->stats,
- stat);
- }
-
- g_strfreev (parts);
-}
-
-static void
-on_shell_update (GitgShell *shell,
- gchar **lines,
- GitgRevisionDetailsPanel *panel)
-{
- GtkTextBuffer *buffer;
- GtkTextIter end;
-
- buffer = gtk_text_view_get_buffer (panel->priv->text_view);
- gtk_text_buffer_get_end_iter (buffer, &end);
-
- while (lines && *lines)
- {
- gchar const *line = *lines;
- ++lines;
-
- if (panel->priv->in_stat)
- {
- add_stat (panel, line);
- }
- else
- {
- if (!gtk_text_iter_is_start (&end))
- {
- gtk_text_buffer_insert (buffer, &end, "\n", 1);
- }
-
- if (line[0] == '\x01' && !line[1])
- {
- panel->priv->in_stat = TRUE;
- strip_trailing_newlines (buffer);
- }
- else
- {
- gtk_text_buffer_insert (buffer, &end, line, -1);
- }
- }
- }
-}
-
-static void
-gitg_revision_details_panel_init (GitgRevisionDetailsPanel *self)
-{
- self->priv = GITG_REVISION_DETAILS_PANEL_GET_PRIVATE(self);
-
- self->priv->shell = gitg_shell_new (1000);
-
- g_signal_connect (self->priv->shell,
- "begin",
- G_CALLBACK (on_shell_begin),
- self);
-
- g_signal_connect (self->priv->shell,
- "end",
- G_CALLBACK (on_shell_end),
- self);
-
- g_signal_connect (self->priv->shell,
- "update",
- G_CALLBACK (on_shell_update),
- self);
-
- self->priv->cache = gitg_avatar_cache_new ();
-}
-
-#define HASH_KEY "GitgRevisionDetailsPanelHashKey"
-
-static gboolean
-on_parent_clicked (GtkWidget *ev,
- GdkEventButton *event,
- gpointer userdata)
-{
- GitgRevisionDetailsPanel *panel;
- gchar *hash;
-
- if (event->button != 1)
- {
- return FALSE;
- }
-
- panel = GITG_REVISION_DETAILS_PANEL (userdata);
- hash = (gchar *)g_object_get_data (G_OBJECT (ev), HASH_KEY);
-
- gitg_window_select (panel->priv->window, hash);
- return FALSE;
-}
-
-static GtkWidget *
-make_parent_label (GitgRevisionDetailsPanel *self,
- gchar const *sha1)
-{
- GtkWidget *ev = gtk_event_box_new ();
- GtkWidget *lbl = gtk_label_new (NULL);
-
- gchar *markup = g_strconcat ("<span underline='single' foreground='#00f'>",
- sha1,
- "</span>",
- NULL);
-
- gtk_label_set_markup (GTK_LABEL(lbl), markup);
- g_free (markup);
-
- gtk_widget_set_halign (lbl, GTK_ALIGN_START);
- gtk_container_add (GTK_CONTAINER(ev), lbl);
-
- gtk_widget_show (ev);
- gtk_widget_show (lbl);
-
- g_object_set_data_full (G_OBJECT(ev),
- HASH_KEY,
- g_strdup (sha1),
- (GDestroyNotify)g_free);
-
- g_signal_connect (ev,
- "button-release-event",
- G_CALLBACK(on_parent_clicked),
- self);
-
- return ev;
-}
-
-static void
-update_parents (GitgRevisionDetailsPanel *self)
-{
- GList *children;
- GList *item;
-
- children = gtk_container_get_children (GTK_CONTAINER (self->priv->parents));
-
- for (item = children; item; item = g_list_next (item))
- {
- gtk_container_remove (GTK_CONTAINER (self->priv->parents),
- GTK_WIDGET (item->data));
- }
-
- g_list_free (children);
-
- if (!self->priv->revision)
- {
- return;
- }
-
- gchar **parents = gitg_revision_get_parents (self->priv->revision);
- gint num = g_strv_length (parents);
- gint i;
-
- gtk_table_resize (self->priv->parents, num ? num : num + 1, 2);
- GdkCursor *cursor = gdk_cursor_new (GDK_HAND1);
- GitgHash hash;
-
- for (i = 0; i < num; ++i)
- {
- GtkWidget *widget = make_parent_label (self, parents[i]);
- gtk_table_attach (self->priv->parents,
- widget,
- 0,
- 1,
- i,
- i + 1,
- GTK_FILL | GTK_SHRINK,
- GTK_FILL | GTK_SHRINK,
- 0,
- 0);
-
- gtk_widget_realize (widget);
- gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
-
- /* find subject */
- gitg_hash_sha1_to_hash (parents[i], hash);
-
- GitgRevision *revision;
-
- revision = gitg_repository_lookup (self->priv->repository, hash);
-
- if (revision)
- {
- GtkWidget *subject = gtk_label_new (NULL);
-
- gchar *text;
-
- text = g_markup_printf_escaped (": <i>%s</i>",
- gitg_revision_get_subject (revision));
-
- gtk_label_set_markup (GTK_LABEL(subject), text);
-
- g_free (text);
-
- gtk_widget_show (subject);
-
- gtk_widget_set_halign (subject, GTK_ALIGN_START);
- gtk_label_set_ellipsize (GTK_LABEL(subject), PANGO_ELLIPSIZE_END);
- gtk_label_set_single_line_mode (GTK_LABEL(subject), TRUE);
-
- gtk_table_attach (self->priv->parents,
- subject,
- 1,
- 2,
- i,
- i + 1,
- GTK_FILL | GTK_EXPAND,
- GTK_FILL | GTK_SHRINK,
- 0,
- 0);
- }
- }
-
- g_object_unref (cursor);
- g_strfreev (parents);
-}
-
-static void
-update_details (GitgRevisionDetailsPanel *panel)
-{
- gchar *sha1;
-
- gitg_io_cancel (GITG_IO (panel->priv->shell));
-
- gtk_text_buffer_set_text (gtk_text_view_get_buffer (panel->priv->text_view),
- "",
- 0);
-
- if (!panel->priv->revision)
- {
- return;
- }
-
- sha1 = gitg_revision_get_sha1 (panel->priv->revision);
-
- gitg_shell_run (panel->priv->shell,
- gitg_command_new (panel->priv->repository,
- "show",
- "--numstat",
- "--pretty=format:%s%n%n%b%n\x01",
- sha1,
- NULL),
- NULL);
-
- g_free (sha1);
-}
-
-static void
-update_author (GitgRevisionDetailsPanel *panel)
-{
- gchar const *author;
- gchar const *author_email;
-
- author = gitg_revision_get_author (panel->priv->revision);
- author_email = gitg_revision_get_author_email (panel->priv->revision);
-
- if (author == NULL || author_email == NULL ||
- *author == '\0' || *author_email == '\0')
- {
- gtk_label_set_text (panel->priv->author, "");
- }
- else
- {
- gchar *tmp;
- gchar *date;
-
- date = gitg_revision_get_author_date_for_display (panel->priv->revision);
- tmp = g_markup_printf_escaped ("<a href='mailto:%s'>%s &lt;%s&gt;</a> (%s)",
- author_email,
- author,
- author_email,
- date);
-
- gtk_label_set_markup (panel->priv->author, tmp);
-
- g_free (tmp);
- g_free (date);
- }
-}
-
-static void
-update_committer (GitgRevisionDetailsPanel *panel)
-{
- gchar const *committer;
- gchar const *committer_email;
-
- committer = gitg_revision_get_committer (panel->priv->revision);
- committer_email = gitg_revision_get_committer_email (panel->priv->revision);
-
- if (committer == NULL || committer_email == NULL ||
- *committer == '\0' || *committer_email == '\0')
- {
- gtk_label_set_text (panel->priv->committer, "");
- }
- else
- {
- gchar *tmp;
- gchar *date;
-
- date = gitg_revision_get_committer_date_for_display (panel->priv->revision);
- tmp = g_markup_printf_escaped ("<a href='mailto:%s'>%s &lt;%s&gt;</a> (%s)",
- committer_email,
- committer,
- committer_email,
- date);
-
- gtk_label_set_markup (panel->priv->committer, tmp);
-
- g_free (tmp);
- g_free (date);
- }
-}
-
-static void
-avatar_ready (GObject *source_object,
- GAsyncResult *res,
- GitgRevisionDetailsPanel *panel)
-{
- GdkPixbuf *pixbuf;
- GError *error = NULL;
-
- pixbuf = gitg_avatar_cache_load_finish (panel->priv->cache,
- res,
- &error);
-
- gtk_widget_set_visible (GTK_WIDGET (panel->priv->avatar),
- error == NULL);
-
- if (error == NULL)
- {
- gtk_image_set_from_pixbuf (panel->priv->avatar, pixbuf);
- }
-}
-
-static void
-set_avatar (GitgRevisionDetailsPanel *panel,
- const gchar *email)
-{
- if (email == NULL || *email == '\0')
- {
- gtk_widget_hide (GTK_WIDGET (panel->priv->avatar));
- }
- else
- {
- gchar *uri;
-
- uri = gitg_avatar_cache_get_gravatar_uri (panel->priv->cache,
- email);
- gitg_avatar_cache_load_uri_async (panel->priv->cache,
- uri,
- G_PRIORITY_DEFAULT,
- NULL,
- (GAsyncReadyCallback)avatar_ready,
- panel);
- g_free (uri);
- }
-}
-
-static void
-reload (GitgRevisionDetailsPanel *panel)
-{
- GtkClipboard *cb;
-
- // Update labels
- if (panel->priv->revision)
- {
- gchar *tmp;
-
- update_author (panel);
- update_committer (panel);
-
- tmp = g_markup_printf_escaped ("<b>%s</b>",
- gitg_revision_get_subject (panel->priv->revision));
-
- gtk_label_set_markup (panel->priv->subject, tmp);
-
- g_free (tmp);
-
- tmp = gitg_revision_get_sha1 (panel->priv->revision);
- gtk_label_set_text (panel->priv->sha, tmp);
-
- cb = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
- gtk_clipboard_set_text (cb, tmp, -1);
-
- g_free (tmp);
-
- set_avatar (panel, gitg_revision_get_author_email (panel->priv->revision));
- }
- else
- {
- gtk_label_set_text (panel->priv->author, "");
- gtk_label_set_text (panel->priv->committer, "");
- gtk_label_set_text (panel->priv->subject, "");
- gtk_label_set_text (panel->priv->sha, "");
- set_avatar (panel, NULL);
- }
-
- // Update parents
- update_parents (panel);
- update_details (panel);
-}
-
-static void
-set_revision (GitgRevisionDetailsPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- if (panel->priv->repository == repository &&
- panel->priv->revision == revision)
- {
- return;
- }
-
- if (panel->priv->repository)
- {
- g_object_unref (panel->priv->repository);
- }
-
- if (panel->priv->revision)
- {
- gitg_revision_unref (panel->priv->revision);
- }
-
- if (repository)
- {
- panel->priv->repository = g_object_ref (repository);
- }
- else
- {
- panel->priv->repository = NULL;
- }
-
- if (revision)
- {
- panel->priv->revision = gitg_revision_ref (revision);
- }
- else
- {
- panel->priv->revision = NULL;
- }
-
- reload (panel);
-}
diff --git a/gitg/gitg-revision-details-panel.h b/gitg/gitg-revision-details-panel.h
deleted file mode 100644
index 772f6e1..0000000
--- a/gitg/gitg-revision-details-panel.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * gitg-revision-details-panel.h
- * This file is part of gitg - git repository details_paneler
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REVISION_DETAILS_PANEL_H__
-#define __GITG_REVISION_DETAILS_PANEL_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REVISION_DETAILS_PANEL (gitg_revision_details_panel_get_type ())
-#define GITG_REVISION_DETAILS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_DETAILS_PANEL, GitgRevisionDetailsPanel))
-#define GITG_REVISION_DETAILS_PANEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_DETAILS_PANEL, GitgRevisionDetailsPanel const))
-#define GITG_REVISION_DETAILS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_REVISION_DETAILS_PANEL, GitgRevisionDetailsPanelClass))
-#define GITG_IS_REVISION_DETAILS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REVISION_DETAILS_PANEL))
-#define GITG_IS_REVISION_DETAILS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_REVISION_DETAILS_PANEL))
-#define GITG_REVISION_DETAILS_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_REVISION_DETAILS_PANEL, GitgRevisionDetailsClass))
-
-typedef struct _GitgRevisionDetailsPanel GitgRevisionDetailsPanel;
-typedef struct _GitgRevisionDetailsPanelClass GitgRevisionDetailsPanelClass;
-typedef struct _GitgRevisionDetailsPanelPrivate GitgRevisionDetailsPanelPrivate;
-
-struct _GitgRevisionDetailsPanel
-{
- GObject parent;
-
- GitgRevisionDetailsPanelPrivate *priv;
-};
-
-struct _GitgRevisionDetailsPanelClass
-{
- GObjectClass parent_class;
-};
-
-GType gitg_revision_details_panel_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* __GITG_REVISION_DETAILS_PANEL_H__ */
diff --git a/gitg/gitg-revision-details-panel.ui b/gitg/gitg-revision-details-panel.ui
deleted file mode 100644
index 85a988e..0000000
--- a/gitg/gitg-revision-details-panel.ui
+++ /dev/null
@@ -1,270 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <!-- interface-requires gtk+ 2.12 -->
- <object class="GtkBox" id="revision_details_page">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkGrid" id="grid1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkGrid" id="grid2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_sha_lbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">SHA:</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_author_lbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Author:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_committer_lbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Committer:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_subject_lbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Subject:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_parent_lbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Parent:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="table_parents">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">3</property>
- <property name="row_spacing">2</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_subject">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- <property name="selectable">True</property>
- <property name="ellipsize">end</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_committer">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_author">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_sha">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="box1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image_avatar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-missing-image</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_details">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="vexpand">True</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTextView" id="text_view_details">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="wrap_mode">word-char</property>
- <property name="cursor_visible">False</property>
- <property name="accepts_tab">False</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
-</interface>
diff --git a/gitg/gitg-revision-files-panel.c b/gitg/gitg-revision-files-panel.c
deleted file mode 100644
index 700362f..0000000
--- a/gitg/gitg-revision-files-panel.c
+++ /dev/null
@@ -1,1524 +0,0 @@
-/*
- * gitg-revision-files-panel.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <gtksourceview/gtksourceview.h>
-#include <gtksourceview/gtksourcelanguagemanager.h>
-#include <string.h>
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-#include <stdlib.h>
-#include <libgitg/gitg-revision.h>
-#include <libgitg/gitg-shell.h>
-
-#include "gitg-revision-files-panel.h"
-#include "gitg-utils.h"
-#include "gitg-revision-panel.h"
-#include "gitg-dirs.h"
-#include "gitg-blame-renderer.h"
-
-#define GITG_REVISION_FILES_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_REVISION_FILES_VIEW, GitgRevisionFilesViewPrivate))
-
-#define GITG_REVISION_FILES_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_REVISION_FILES_PANEL, GitgRevisionFilesPanelPrivate))
-
-#define BLAME_DATA "GitgRevisionFilesPanelBlame"
-
-enum
-{
- ICON_COLUMN,
- NAME_COLUMN,
- CONTENT_TYPE_COLUMN,
- N_COLUMNS
-};
-
-typedef struct _GitgRevisionFilesView GitgRevisionFilesView;
-typedef struct _GitgRevisionFilesViewClass GitgRevisionFilesViewClass;
-typedef struct _GitgRevisionFilesViewPrivate GitgRevisionFilesViewPrivate;
-
-struct _GitgRevisionFilesViewPrivate
-{
- GSettings *settings;
-
- GtkTreeView *tree_view;
-
- GtkSourceView *contents;
- GitgShell *content_shell;
- GtkTreeStore *store;
-
- GtkToggleButton *blame_checkbutton;
- GHashTable *blames; /* hash : tag */
- GitgBlameRenderer *blame_renderer;
- gint blame_offset;
- GtkTextTag *active_tag;
-
- glong query_data_id;
- glong query_tooltip_id;
-
- GtkWidget *active_view;
-
- gchar *drag_dir;
- gchar **drag_files;
-
- GitgRepository *repository;
- GitgRevision *revision;
- GitgShell *loader;
- GtkTreePath *load_path;
-
- gboolean skipped_blank_line;
- gboolean disposed;
-};
-
-struct _GitgRevisionFilesView
-{
- GtkHPaned parent;
-
- GitgRevisionFilesViewPrivate *priv;
-};
-
-struct _GitgRevisionFilesViewClass
-{
- GtkHPanedClass parent_class;
-};
-
-struct _GitgRevisionFilesPanelPrivate
-{
- GitgRevisionFilesView *panel;
-};
-
-#define GITG_TYPE_REVISION_FILES_VIEW (gitg_revision_files_view_get_type ())
-#define GITG_REVISION_FILES_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_FILES_VIEW, GitgRevisionFilesView))
-
-static void gitg_revision_files_view_buildable_iface_init (GtkBuildableIface *iface);
-static void gitg_revision_panel_iface_init (GitgRevisionPanelInterface *iface);
-
-static void load_node (GitgRevisionFilesView *view, GtkTreeIter *parent);
-static gchar *node_identity (GitgRevisionFilesView *view, GtkTreeIter *iter);
-
-G_DEFINE_TYPE_EXTENDED (GitgRevisionFilesPanel,
- gitg_revision_files_panel,
- G_TYPE_OBJECT,
- 0,
- G_IMPLEMENT_INTERFACE (GITG_TYPE_REVISION_PANEL,
- gitg_revision_panel_iface_init));
-
-G_DEFINE_TYPE_EXTENDED (GitgRevisionFilesView,
- gitg_revision_files_view,
- GTK_TYPE_HPANED,
- 0,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
- gitg_revision_files_view_buildable_iface_init));
-
-static GtkBuildableIface parent_iface;
-
-static void
-gitg_revision_files_view_finalize (GObject *object)
-{
- GitgRevisionFilesView *self = GITG_REVISION_FILES_VIEW (object);
-
- if (self->priv->load_path)
- {
- gtk_tree_path_free (self->priv->load_path);
- }
-
- g_free (self->priv->drag_dir);
-
- if (self->priv->drag_files)
- {
- g_strfreev (self->priv->drag_files);
- }
-
- gitg_io_cancel (GITG_IO (self->priv->loader));
- g_object_unref (self->priv->loader);
-
- gitg_io_cancel (GITG_IO (self->priv->content_shell));
- g_object_unref (self->priv->content_shell);
-
- g_hash_table_unref (self->priv->blames);
-
- G_OBJECT_CLASS (gitg_revision_files_view_parent_class)->finalize (object);
-}
-
-static void
-load_tree (GitgRevisionFilesView *files_view)
-{
- load_node (files_view, NULL);
-}
-
-static void
-set_revision (GitgRevisionFilesView *files_view,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- if (files_view->priv->repository == repository &&
- files_view->priv->revision == revision)
- {
- return;
- }
-
- gitg_io_cancel (GITG_IO (files_view->priv->loader));
- gtk_tree_store_clear (files_view->priv->store);
-
- if (files_view->priv->repository)
- {
- g_object_unref (files_view->priv->repository);
- }
-
- if (files_view->priv->revision)
- {
- gitg_revision_unref (files_view->priv->revision);
- }
-
- if (repository)
- {
- files_view->priv->repository = g_object_ref (repository);
- }
- else
- {
- files_view->priv->repository = NULL;
- }
-
- if (revision)
- {
- files_view->priv->revision = gitg_revision_ref (revision);
- }
- else
- {
- files_view->priv->revision = NULL;
- }
-
- if (files_view->priv->repository && files_view->priv->revision)
- {
- load_tree (files_view);
- }
-}
-
-static GtkTextTag *
-get_blame_tag_from_iter (GitgRevisionFilesView *files_view,
- GtkTextIter *iter)
-{
- GtkTextTag *tag = NULL;
- GSList *tags, *l;
-
- tags = gtk_text_iter_get_tags (iter);
-
- for (l = tags; l != NULL; l = g_slist_next (l))
- {
- if (g_object_get_data (l->data, BLAME_DATA) != NULL)
- {
- tag = l->data;
- break;
- }
- }
-
- g_slist_free (tags);
-
- return tag;
-}
-
-static void
-blame_renderer_query_data_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *start,
- GtkTextIter *end,
- GtkSourceGutterRendererState state,
- GitgRevisionFilesView *files_view)
-{
- GtkTextTag *tag;
- GitgRevision *rev;
- GtkTextIter iter;
-
- iter = *start;
- gtk_text_iter_set_line_offset (&iter, 0);
-
- tag = get_blame_tag_from_iter (files_view, &iter);
-
- if (tag == NULL)
- return;
-
- rev = g_object_get_data (G_OBJECT (tag), BLAME_DATA);
-
- if (gtk_text_iter_begins_tag (&iter, tag))
- {
- gboolean group_start = FALSE;
-
- if (!gtk_text_iter_is_start (&iter))
- {
- group_start = TRUE;
- }
-
- g_object_set (renderer,
- "revision", rev,
- "show", TRUE,
- "group-start", group_start,
- NULL);
- }
- else
- {
- g_object_set (renderer,
- "revision", rev,
- "show", FALSE,
- "group-start", FALSE,
- NULL);
- }
-}
-
-static gboolean
-blame_renderer_query_tooltip_cb (GtkSourceGutterRenderer *renderer,
- GtkTextIter *iter,
- GdkRectangle *area,
- gint x,
- gint y,
- GtkTooltip *tooltip,
- GitgRevisionFilesView *tree)
-{
- GtkTextTag *tag;
- GitgRevision *rev;
- const gchar *author;
- const gchar *committer;
- const gchar *subject;
- gchar *text;
- gchar *sha1;
- gchar *author_date;
- gchar *committer_date;
-
- tag = get_blame_tag_from_iter (tree, iter);
-
- if (tag == NULL)
- return FALSE;
-
- rev = g_object_get_data (G_OBJECT (tag), BLAME_DATA);
-
- if (rev == NULL)
- return FALSE;
-
- sha1 = gitg_revision_get_sha1 (rev);
- author_date = gitg_revision_get_author_date_for_display (rev);
- committer_date = gitg_revision_get_committer_date_for_display (rev);
-
- author = _("Author");
- committer = _("Committer");
- subject = _("Subject");
-
- text = g_markup_printf_escaped ("<b>SHA:</b> %s\n"
- "<b>%s:</b> %s &lt;%s&gt; (%s)\n"
- "<b>%s:</b> %s &lt;%s&gt; (%s)\n"
- "<b>%s:</b> <i>%s</i>",
- sha1,
- author, gitg_revision_get_author (rev),
- gitg_revision_get_author_email (rev),
- author_date,
- committer, gitg_revision_get_committer (rev),
- gitg_revision_get_committer_email (rev),
- committer_date,
- subject, gitg_revision_get_subject (rev));
-
- g_free (sha1);
- g_free (author_date);
- g_free (committer_date);
- gtk_tooltip_set_markup (tooltip, text);
- g_free (text);
-
- return TRUE;
-}
-
-static void
-remove_blames (GitgRevisionFilesView *tree)
-{
- GtkTextBuffer *buffer;
- GList *tags, *tag;
- GtkTextTagTable *table;
- gboolean blame_mode;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tree->priv->contents));
- table = gtk_text_buffer_get_tag_table (buffer);
-
- if (tree->priv->query_data_id != 0)
- {
- g_signal_handler_disconnect (tree->priv->blame_renderer,
- tree->priv->query_data_id);
- tree->priv->query_data_id = 0;
- }
-
- if (tree->priv->query_tooltip_id != 0)
- {
- g_signal_handler_disconnect (tree->priv->blame_renderer,
- tree->priv->query_tooltip_id);
- tree->priv->query_tooltip_id = 0;
- }
-
- tags = g_hash_table_get_values (tree->priv->blames);
-
- for (tag = tags; tag != NULL; tag = g_list_next (tag))
- {
- g_object_set_data (tag->data, BLAME_DATA, NULL);
- gtk_text_tag_table_remove (table, tag->data);
- }
-
- g_hash_table_remove_all (tree->priv->blames);
-
- g_list_free (tags);
-
- tree->priv->blame_offset = 0;
- tree->priv->active_tag = NULL;
-
- g_object_set (tree->priv->blame_renderer,
- "revision", NULL,
- "show", FALSE,
- "group-start", FALSE,
- NULL);
-
- blame_mode = gtk_toggle_button_get_active (tree->priv->blame_checkbutton);
-
- if (blame_mode)
- {
- gitg_blame_renderer_set_max_line_count (tree->priv->blame_renderer, 0);
- }
-}
-
-static void
-gitg_revision_files_view_dispose (GObject *object)
-{
- GitgRevisionFilesView* files_view = GITG_REVISION_FILES_VIEW (object);
-
- if (!files_view->priv->disposed)
- {
- set_revision (files_view, NULL, NULL);
- remove_blames (files_view);
-
- files_view->priv->disposed = TRUE;
- }
-
- if (files_view->priv->blame_renderer != NULL)
- {
- g_object_unref (files_view->priv->blame_renderer);
- files_view->priv->blame_renderer = NULL;
- }
-
- if (files_view->priv->settings != NULL)
- {
- g_object_unref (files_view->priv->settings);
- files_view->priv->settings = NULL;
- }
-
- G_OBJECT_CLASS (gitg_revision_files_view_parent_class)->dispose (object);
-}
-
-static gboolean
-loaded (GitgRevisionFilesView *view,
- GtkTreeIter *iter)
-{
- gint num;
-
- num = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(view->priv->store),
- iter);
-
- if (num != 1)
- {
- return TRUE;
- }
-
- gchar *content_type = NULL;
- GtkTreeIter child;
-
- if (!gtk_tree_model_iter_children (GTK_TREE_MODEL(view->priv->store),
- &child,
- iter))
- {
- return FALSE;
- }
-
- gtk_tree_model_get (GTK_TREE_MODEL(view->priv->store),
- &child,
- CONTENT_TYPE_COLUMN,
- &content_type,
- -1);
-
- gboolean ret = content_type != NULL;
- g_free (content_type);
-
- return ret;
-}
-
-static void
-on_row_expanded (GtkTreeView *files_view,
- GtkTreeIter *iter,
- GtkTreePath *path,
- GitgRevisionFilesView *view)
-{
- if (loaded (view, iter))
- {
- return;
- }
-
- load_node (view, iter);
-}
-
-static void
-show_binary_information (GitgRevisionFilesView *tree,
- GtkTextBuffer *buffer)
-{
- gtk_text_buffer_set_text (buffer,
- _("Cannot display file content as text"),
- -1);
-
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), NULL);
-}
-
-static void
-on_selection_changed (GtkTreeSelection *selection,
- GitgRevisionFilesView *tree)
-{
- GtkTextBuffer *buffer;
- gboolean blame_mode;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path = NULL;
- GList *rows;
- gchar *name;
- gchar *content_type;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tree->priv->contents));
- gitg_io_cancel (GITG_IO (tree->priv->content_shell));
-
- blame_mode = gtk_toggle_button_get_active (tree->priv->blame_checkbutton);
-
- remove_blames (tree);
-
- gtk_text_buffer_set_text (buffer, "", -1);
-
- if (!tree->priv->revision)
- {
- return;
- }
-
- rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- if (g_list_length (rows) == 1)
- {
- path = gtk_tree_path_copy ((GtkTreePath *)rows->data);
- }
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-
- if (!path)
- {
- return;
- }
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
- gtk_tree_model_get (model,
- &iter,
- NAME_COLUMN,
- &name,
- CONTENT_TYPE_COLUMN,
- &content_type,
- -1);
-
- if (!content_type)
- {
- g_free (name);
- return;
- }
-
- if (!gitg_utils_can_display_content_type (content_type))
- {
- show_binary_information (tree, buffer);
- }
- else
- {
- GtkSourceLanguage *language;
- gchar *id;
-
- language = gitg_utils_get_language (name, content_type);
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer),
- language);
-
- id = node_identity (tree, &iter);
-
- if (!blame_mode)
- {
- gitg_shell_run (tree->priv->content_shell,
- gitg_command_new (tree->priv->repository,
- "show",
- "--encoding=UTF-8",
- id,
- NULL),
- NULL);
- }
- else
- {
- gchar **hash_name;
-
- gitg_blame_renderer_set_max_line_count (tree->priv->blame_renderer, 0);
-
- hash_name = g_strsplit (id, ":", 2);
- gitg_shell_run (tree->priv->content_shell,
- gitg_command_new (tree->priv->repository,
- "blame",
- "--encoding=UTF-8",
- "--root",
- "-l",
- hash_name[0],
- "--",
- hash_name[1],
- NULL),
- NULL);
-
- g_strfreev (hash_name);
- }
-
- g_free (id);
- }
-
- g_free (name);
- g_free (content_type);
-}
-
-static gchar *
-node_path (GtkTreeModel *model,
- GtkTreeIter *parent)
-{
- if (!parent)
- {
- return NULL;
- }
-
- gchar *name;
- gtk_tree_model_get (model,
- parent,
- NAME_COLUMN,
- &name,
- -1);
-
- GtkTreeIter parent_iter;
- gchar *ret;
-
- if (gtk_tree_model_iter_parent (model, &parent_iter, parent))
- {
- gchar *path = node_path (model, &parent_iter);
- ret = g_build_filename (path, name, NULL);
- g_free (path);
- g_free (name);
- }
- else
- {
- ret = name;
- }
-
- return ret;
-}
-
-static void
-export_drag_files (GitgRevisionFilesView *files_view)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (files_view->priv->tree_view);
-
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
- gint num = g_list_length (rows);
-
- if (num == 0)
- {
- g_list_free (rows);
- return;
- }
-
- GList *item;
-
- files_view->priv->drag_files = g_new (gchar *, num + 1);
- gchar **ptr = files_view->priv->drag_files;
-
- for (item = rows; item; item = item->next)
- {
- GtkTreePath *path = (GtkTreePath *)item->data;
- GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, path);
-
- *ptr++ = node_path (model, &iter);
- gtk_tree_path_free (path);
- }
-
- *ptr = NULL;
- g_list_free (rows);
-
- // Prepend temporary directory in uri list
- g_free (files_view->priv->drag_dir);
- gchar const *tmp = g_get_tmp_dir ();
- files_view->priv->drag_dir = g_build_filename (tmp,
- "gitg-export-XXXXXX",
- NULL);
-
- if (!mkdtemp (files_view->priv->drag_dir))
- {
- g_warning ("Could not create temporary directory for export");
- return;
- }
-
- // Do the export
- gitg_utils_export_files (files_view->priv->repository,
- files_view->priv->revision,
- files_view->priv->drag_dir,
- files_view->priv->drag_files);
-
- ptr = files_view->priv->drag_files;
-
- while (*ptr)
- {
- gchar *tmp = g_build_filename (files_view->priv->drag_dir, *ptr, NULL);
- g_free (*ptr);
-
- GFile *file = g_file_new_for_path (tmp);
- *ptr++ = g_file_get_uri (file);
-
- g_free (tmp);
- }
-}
-
-static void
-on_drag_data_get (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection,
- guint info,
- guint time,
- GitgRevisionFilesView *files_view)
-{
- if (!files_view->priv->drag_files)
- {
- export_drag_files (files_view);
- }
-
- gtk_selection_data_set_uris (selection, files_view->priv->drag_files);
-}
-
-static gboolean
-test_selection (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer data)
-{
- if (path_currently_selected)
- {
- return TRUE;
- }
-
- // Test for (Empty)
- GtkTreeIter iter;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- {
- return FALSE;
- }
-
- gchar *content_type;
- gtk_tree_model_get (model,
- &iter,
- CONTENT_TYPE_COLUMN,
- &content_type,
- -1);
-
- if (!content_type)
- {
- return FALSE;
- }
-
- g_free (content_type);
- return TRUE;
-}
-
-static void
-on_drag_end (GtkWidget *widget,
- GdkDragContext *context,
- GitgRevisionFilesView *files_view)
-{
- if (files_view->priv->drag_files != NULL)
- {
- g_strfreev (files_view->priv->drag_files);
- files_view->priv->drag_files = NULL;
-
- g_free (files_view->priv->drag_dir);
- files_view->priv->drag_dir = NULL;
- }
-}
-
-static void
-blame_mode_set_active (GitgRevisionFilesView *tree,
- gboolean active)
-{
- GtkSourceGutter *gutter;
-
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (tree->priv->contents),
- GTK_TEXT_WINDOW_LEFT);
-
- gtk_source_view_set_show_line_numbers (tree->priv->contents, !active);
-
- if (active)
- {
- gtk_source_gutter_insert (gutter,
- GTK_SOURCE_GUTTER_RENDERER (tree->priv->blame_renderer),
- 0);
- }
- else
- {
- gtk_source_gutter_remove (gutter,
- GTK_SOURCE_GUTTER_RENDERER (tree->priv->blame_renderer));
- }
-}
-
-static void
-gitg_revision_files_view_parser_finished (GtkBuildable *buildable,
- GtkBuilder *builder)
-{
- GitgRevisionFilesView *files_view = GITG_REVISION_FILES_VIEW (buildable);
- GtkTreeSelection *selection;
-
- if (parent_iface.parser_finished)
- {
- parent_iface.parser_finished (buildable, builder);
- }
-
- // Store widgets
- files_view->priv->tree_view = GTK_TREE_VIEW (gtk_builder_get_object (builder,
- "revision_files"));
- files_view->priv->contents = GTK_SOURCE_VIEW (gtk_builder_get_object (builder,
- "revision_files_contents"));
- files_view->priv->blame_checkbutton = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
- "blame_mode_checkbutton"));
- files_view->priv->blame_renderer = gitg_blame_renderer_new ();
- g_object_ref (files_view->priv->blame_renderer);
-
- gitg_utils_set_monospace_font (GTK_WIDGET(files_view->priv->contents));
- gtk_tree_view_set_model (files_view->priv->tree_view,
- GTK_TREE_MODEL(files_view->priv->store));
-
- selection = gtk_tree_view_get_selection (files_view->priv->tree_view);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- gtk_tree_selection_set_select_function (selection,
- test_selection,
- NULL,
- NULL);
-
- // Setup drag source
- GtkTargetEntry targets[] = {
- {"text/uri-list", GTK_TARGET_OTHER_APP, 0}
- };
-
- // Set tree view as a drag source
- gtk_drag_source_set (GTK_WIDGET(files_view->priv->tree_view),
- GDK_BUTTON1_MASK,
- targets,
- 1,
- GDK_ACTION_DEFAULT | GDK_ACTION_COPY);
-
- // Connect signals
- g_signal_connect_after (files_view->priv->tree_view,
- "row-expanded",
- G_CALLBACK(on_row_expanded),
- files_view);
-
- g_signal_connect (files_view->priv->tree_view,
- "drag-data-get",
- G_CALLBACK(on_drag_data_get),
- files_view);
-
- g_signal_connect (files_view->priv->tree_view,
- "drag-end",
- G_CALLBACK(on_drag_end),
- files_view);
-
- g_signal_connect (selection,
- "changed",
- G_CALLBACK(on_selection_changed),
- files_view);
-
- g_settings_bind (files_view->priv->settings,
- "blame-mode",
- files_view->priv->blame_checkbutton,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
- blame_mode_set_active (files_view,
- gtk_toggle_button_get_active (files_view->priv->blame_checkbutton));
-}
-
-static void
-gitg_revision_panel_update_impl (GitgRevisionPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- GitgRevisionFilesPanel *files_view_panel;
-
- files_view_panel = GITG_REVISION_FILES_PANEL (panel);
-
- set_revision (files_view_panel->priv->panel, repository, revision);
-}
-
-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"));
-}
-
-static GtkWidget *
-gitg_revision_panel_get_panel_impl (GitgRevisionPanel *panel)
-{
- GtkBuilder *builder;
- GtkWidget *ret;
- GitgRevisionFilesPanel *files_view_panel;
-
- files_view_panel = GITG_REVISION_FILES_PANEL (panel);
-
- if (files_view_panel->priv->panel)
- {
- return GTK_WIDGET (files_view_panel->priv->panel);
- }
-
- builder = gitg_utils_new_builder ("gitg-revision-files-panel.ui");
- ret = GTK_WIDGET (gtk_builder_get_object (builder, "revision_files_view"));
- files_view_panel->priv->panel = g_object_ref (ret);
-
- g_object_unref (builder);
-
- return ret;
-}
-
-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_revision_files_view_buildable_iface_init (GtkBuildableIface *iface)
-{
- parent_iface = *iface;
-
- iface->parser_finished = gitg_revision_files_view_parser_finished;
-}
-
-static void
-gitg_revision_files_view_class_init (GitgRevisionFilesViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- object_class->finalize = gitg_revision_files_view_finalize;
- object_class->dispose = gitg_revision_files_view_dispose;
-
- g_type_class_add_private (object_class, sizeof (GitgRevisionFilesViewPrivate));
-}
-
-static void
-gitg_revision_files_panel_dispose (GObject *object)
-{
- GitgRevisionFilesPanel *panel;
-
- panel = GITG_REVISION_FILES_PANEL (object);
-
- if (panel->priv->panel)
- {
- g_object_unref (panel->priv->panel);
- panel->priv->panel = NULL;
- }
-
- G_OBJECT_CLASS (gitg_revision_files_panel_parent_class)->dispose (object);
-}
-
-static void
-gitg_revision_files_panel_class_init (GitgRevisionFilesPanelClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = gitg_revision_files_panel_dispose;
-
- g_type_class_add_private (object_class, sizeof (GitgRevisionFilesPanelPrivate));
-}
-
-static gchar *
-get_content_type (gchar *name,
- gboolean dir)
-{
- if (dir)
- {
- return g_strdup ("inode/directory");
- }
- else
- {
- return g_content_type_guess (name, NULL, 0, NULL);
- }
-}
-
-static void
-remove_dummy (GitgRevisionFilesView *tree)
-{
- if (!tree->priv->load_path)
- {
- return;
- }
-
- GtkTreeIter parent;
- GtkTreeModel *model = GTK_TREE_MODEL(tree->priv->store);
- gtk_tree_model_get_iter (model, &parent, tree->priv->load_path);
-
- if (gtk_tree_model_iter_n_children (model, &parent) != 2)
- {
- return;
- }
-
- GtkTreeIter child;
- gtk_tree_model_iter_children (model, &child, &parent);
-
- do
- {
- gchar *content_type;
- gtk_tree_model_get (model,
- &child,
- CONTENT_TYPE_COLUMN,
- &content_type,
- -1);
-
- if (!content_type)
- {
- gtk_tree_store_remove (tree->priv->store, &child);
- break;
- }
- g_free (content_type);
- } while (gtk_tree_model_iter_next (model, &child));
-}
-
-static void
-append_node (GitgRevisionFilesView *tree,
- gchar *line)
-{
- GtkTreeIter parent;
- GtkTreeIter iter;
-
- if (tree->priv->load_path)
- {
- gtk_tree_model_get_iter (GTK_TREE_MODEL(tree->priv->store),
- &parent,
- tree->priv->load_path);
- gtk_tree_store_append (tree->priv->store, &iter, &parent);
- }
- else
- {
- gtk_tree_store_append (tree->priv->store, &iter, NULL);
- }
-
- int len = strlen (line);
- gboolean isdir = FALSE;
-
- if (line[len - 1] == '/')
- {
- isdir = TRUE;
- line[len - 1] = '\0';
- }
-
- GIcon *icon;
-
- if (isdir)
- {
- GtkTreeIter empty;
- gtk_tree_store_append (tree->priv->store, &empty, &iter);
- gtk_tree_store_set (tree->priv->store,
- &empty,
- NAME_COLUMN,
- _ ("(Empty)"),
- -1);
-
- gchar *content_type = get_content_type (line, TRUE);
- gtk_tree_store_set (tree->priv->store,
- &iter,
- CONTENT_TYPE_COLUMN,
- content_type,
- -1);
- icon = g_content_type_get_icon (content_type);
- g_free (content_type);
-
- if (icon && G_IS_THEMED_ICON(icon))
- {
- g_themed_icon_append_name (G_THEMED_ICON(icon), "folder");
- }
- }
- else
- {
- gchar *content_type = get_content_type (line, FALSE);
- icon = g_content_type_get_icon (content_type);
- gtk_tree_store_set (tree->priv->store,
- &iter,
- CONTENT_TYPE_COLUMN,
- content_type,
- -1);
- g_free (content_type);
-
- if (icon && G_IS_THEMED_ICON(icon))
- {
- g_themed_icon_append_name (G_THEMED_ICON(icon),
- "text-x-generic");
- }
- }
-
- if (G_IS_THEMED_ICON(icon))
- {
- GtkIconTheme *theme = gtk_icon_theme_get_default ();
-
- gchar **names;
- g_object_get (icon, "names", &names, NULL);
-
- GtkIconInfo *info;
-
- info = gtk_icon_theme_choose_icon (theme,
- (gchar const **)names,
- 16,
- 0);
-
- if (info)
- {
- GError *error = NULL;
- GdkPixbuf *pixbuf = gtk_icon_info_load_icon (info, &error);
-
- if (!pixbuf)
- {
- g_warning ("Error loading icon: %s", error->message);
- g_error_free (error);
- }
-
- gtk_tree_store_set (tree->priv->store,
- &iter,
- ICON_COLUMN,
- pixbuf,
- -1);
-
- if (pixbuf)
- {
- g_object_unref (pixbuf);
- }
-
- gtk_icon_info_free (info);
- }
-
- g_strfreev (names);
- }
-
- if (icon)
- {
- g_object_unref (icon);
- }
-
- gtk_tree_store_set (tree->priv->store,
- &iter,
- NAME_COLUMN,
- line,
- -1);
- remove_dummy (tree);
-}
-
-static void
-on_update (GitgShell *shell,
- gchar **buffer,
- GitgRevisionFilesView *tree)
-{
- gchar *line;
-
- while ((line = *buffer++))
- {
- if (!tree->priv->skipped_blank_line)
- {
- if (*line == '\0')
- {
- tree->priv->skipped_blank_line = TRUE;
- }
-
- continue;
- }
-
- append_node (tree, line);
- }
-}
-
-static gint
-compare_func (GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- GitgRevisionFilesView *self)
-{
- // First sort directories before files
- gboolean da = gtk_tree_model_iter_has_child (model, a) != 0;
- gboolean db = gtk_tree_model_iter_has_child (model, b) != 0;
-
- if (da != db)
- {
- return da ? -1 : 1;
- }
-
- // Then sort on name
- gchar *s1;
- gchar *s2;
-
- gtk_tree_model_get (model,
- a,
- NAME_COLUMN,
- &s1,
- -1);
-
- gtk_tree_model_get (model,
- b,
- NAME_COLUMN,
- &s2,
- -1);
-
- int ret = gitg_utils_sort_names (s1, s2);
-
- g_free (s1);
- g_free (s2);
-
- return ret;
-}
-
-/**
- * parse_blame:
- * @line: the line to be parsed
- * @real_line: the real connect to be inserted in the text buffer
- * @sha: the sha get from @line
- * @size: the size for the gutter
- */
-static void
-parse_blame (const gchar *line,
- const gchar **real_line,
- gchar **sha,
- gint *size)
-{
- gunichar c;
- const gchar *name_end;
-
- *sha = g_strndup (line, GITG_HASH_SHA_SIZE);
- line += GITG_HASH_SHA_SIZE;
- *real_line = strstr (line, ") ");
- *real_line += 2;
-
- line = strstr (line, " (");
- line += 2;
- name_end = line;
- c = g_utf8_get_char (name_end);
-
- while (!g_unichar_isdigit (c))
- {
- name_end = g_utf8_next_char (name_end);
- c = g_utf8_get_char (name_end);
- }
- name_end--;
-
- *size = name_end - line + 15; /* hash name + extra space */
-}
-
-static GtkTextTag *
-get_tag_for_sha (GitgRevisionFilesView *tree,
- GtkTextBuffer *buffer,
- const gchar *sha)
-{
- GtkTextTag *tag;
-
- tag = g_hash_table_lookup (tree->priv->blames, sha);
-
- if (tag == NULL)
- {
- GitgHash hash;
- GitgRevision *revision;
-
- tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
-
- gitg_hash_sha1_to_hash (sha, hash);
- revision = gitg_repository_lookup (tree->priv->repository,
- hash);
- g_object_set_data (G_OBJECT (tag), BLAME_DATA, revision);
-
- g_hash_table_insert (tree->priv->blames, g_strdup (sha),
- g_object_ref (tag));
- }
-
- return tag;
-}
-
-static void
-apply_active_blame_tag (GitgRevisionFilesView *tree,
- GtkTextBuffer *buffer,
- GtkTextIter *end)
-{
- GtkTextIter start;
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start,
- tree->priv->blame_offset);
- gtk_text_buffer_apply_tag (buffer, tree->priv->active_tag,
- &start, end);
-
- tree->priv->blame_offset = gtk_text_iter_get_offset (end);
-}
-
-static void
-insert_blame_line (GitgRevisionFilesView *tree,
- GtkTextBuffer *buffer,
- const gchar *line,
- GtkTextIter *iter)
-{
- GtkTextTag *tag;
- const gchar *real_line;
- gint size;
- gchar *sha;
-
- parse_blame (line, &real_line, &sha, &size);
- gitg_blame_renderer_set_max_line_count (tree->priv->blame_renderer, size);
-
- tag = get_tag_for_sha (tree, buffer, sha);
-
- if (tag != tree->priv->active_tag)
- {
- if (tree->priv->active_tag != NULL)
- {
- apply_active_blame_tag (tree, buffer, iter);
- }
-
- tree->priv->active_tag = tag;
- }
-
- g_free (sha);
-
- gtk_text_buffer_insert (buffer, iter, real_line, -1);
- gtk_text_buffer_insert (buffer, iter, "\n", -1);
-}
-
-static void
-on_contents_update (GitgShell *shell,
- gchar **buffer,
- GitgRevisionFilesView *tree)
-{
- GtkTextBuffer *buf;
- GtkTextIter end;
- gchar *line;
- gboolean blame_mode;
-
- buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tree->priv->contents));
- gtk_text_buffer_get_end_iter (buf, &end);
- blame_mode = gtk_toggle_button_get_active (tree->priv->blame_checkbutton);
-
- if (blame_mode)
- {
- while ((line = *buffer++))
- {
- insert_blame_line (tree, buf, line, &end);
- }
-
- if (tree->priv->active_tag != NULL)
- {
- apply_active_blame_tag (tree, buf, &end);
- }
- }
- else
- {
- while ((line = *buffer++))
- {
- gtk_text_buffer_insert (buf, &end, line, -1);
- gtk_text_buffer_insert (buf, &end, "\n", -1);
- }
- }
-
- if (gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buf)) == NULL)
- {
- gchar *content_type = gitg_utils_guess_content_type (buf);
-
- if (content_type && !gitg_utils_can_display_content_type (content_type))
- {
- gitg_io_cancel (GITG_IO (shell));
- show_binary_information (tree, buf);
- }
- else
- {
- GtkSourceLanguage *language;
-
- language = gitg_utils_get_language (NULL, content_type);
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buf),
- language);
- }
-
- g_free (content_type);
- }
-}
-
-static void
-on_contents_end (GitgShell *shell,
- GError *error,
- GitgRevisionFilesView *tree)
-{
- gboolean blame_mode;
-
- blame_mode = gtk_toggle_button_get_active (tree->priv->blame_checkbutton);
-
- if (blame_mode)
- {
- GtkSourceGutter *gutter;
-
- tree->priv->query_data_id =
- g_signal_connect (tree->priv->blame_renderer,
- "query-data",
- G_CALLBACK (blame_renderer_query_data_cb),
- tree);
-
- tree->priv->query_tooltip_id =
- g_signal_connect (tree->priv->blame_renderer,
- "query-tooltip",
- G_CALLBACK (blame_renderer_query_tooltip_cb),
- tree);
-
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (tree->priv->contents),
- GTK_TEXT_WINDOW_LEFT);
- gtk_source_gutter_queue_draw (gutter);
- }
-}
-
-static void
-on_blame_mode_changed (GSettings *settings,
- const gchar *key,
- GitgRevisionFilesView *files_view)
-{
- GtkTreeSelection *selection;
-
- blame_mode_set_active (files_view, g_settings_get_boolean (settings, key));
-
- selection = gtk_tree_view_get_selection (files_view->priv->tree_view);
- on_selection_changed (selection, files_view);
-}
-
-static void
-gitg_revision_files_view_init (GitgRevisionFilesView *self)
-{
- self->priv = GITG_REVISION_FILES_VIEW_GET_PRIVATE (self);
-
- self->priv->settings = g_settings_new ("org.gnome.gitg.preferences.view.files");
-
- g_signal_connect (self->priv->settings,
- "changed::blame-mode",
- G_CALLBACK (on_blame_mode_changed),
- self);
-
- self->priv->store = gtk_tree_store_new (N_COLUMNS,
- GDK_TYPE_PIXBUF,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self->priv->store),
- 1,
- (GtkTreeIterCompareFunc)compare_func,
- self,
- NULL);
-
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->priv->store),
- NAME_COLUMN,
- GTK_SORT_ASCENDING);
-
- self->priv->loader = gitg_shell_new (1000);
- g_signal_connect (self->priv->loader,
- "update",
- G_CALLBACK (on_update),
- self);
-
- self->priv->content_shell = gitg_shell_new (5000);
- g_signal_connect (self->priv->content_shell,
- "update",
- G_CALLBACK (on_contents_update),
- self);
- g_signal_connect (self->priv->content_shell,
- "end",
- G_CALLBACK (on_contents_end),
- self);
-
- self->priv->blames = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
-}
-
-static void
-gitg_revision_files_panel_init (GitgRevisionFilesPanel *self)
-{
- self->priv = GITG_REVISION_FILES_PANEL_GET_PRIVATE (self);
-}
-
-static gchar *
-node_identity (GitgRevisionFilesView *tree,
- GtkTreeIter *parent)
-{
- gchar *sha = gitg_revision_get_sha1 (tree->priv->revision);
-
- // Path consists of the SHA1 of the revision and the actual file path
- // from parent
- gchar *par = node_path (GTK_TREE_MODEL (tree->priv->store), parent);
- gchar *path = g_strconcat (sha, ":", par, NULL);
- g_free (sha);
- g_free (par);
-
- return path;
-}
-
-static void
-load_node (GitgRevisionFilesView *tree,
- GtkTreeIter *parent)
-{
- if (gitg_io_get_running (GITG_IO (tree->priv->loader)))
- {
- return;
- }
-
- if (tree->priv->load_path)
- {
- gtk_tree_path_free (tree->priv->load_path);
- }
-
- gchar *id = node_identity (tree, parent);
-
- if (parent)
- {
- tree->priv->load_path =
- gtk_tree_model_get_path (GTK_TREE_MODEL (tree->priv->store),
- parent);
- }
- else
- {
- tree->priv->load_path = NULL;
- }
-
- tree->priv->skipped_blank_line = FALSE;
- gitg_shell_run (tree->priv->loader,
- gitg_command_new (tree->priv->repository,
- "show",
- "--encoding=UTF-8",
- id,
- NULL),
- NULL);
- g_free (id);
-}
diff --git a/gitg/gitg-revision-files-panel.h b/gitg/gitg-revision-files-panel.h
deleted file mode 100644
index 220aa21..0000000
--- a/gitg/gitg-revision-files-panel.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * gitg-revision-files-panel.h
- * This file is part of gitg - git repository view_paneler
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REVISION_FILES_PANEL__H__
-#define __GITG_REVISION_FILES_PANEL__H__
-
-#include <gtk/gtk.h>
-#include <libgitg/gitg-repository.h>
-#include <libgitg/gitg-revision.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REVISION_FILES_PANEL (gitg_revision_files_panel_get_type ())
-#define GITG_REVISION_FILES_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_FILES_PANEL, GitgRevisionFilesPanel))
-#define GITG_REVISION_FILES_PANEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_FILES_PANEL, GitgRevisionFilesPanel const))
-#define GITG_REVISION_FILES_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_REVISION_FILES_PANEL, GitgRevisionFilesPanelClass))
-#define GITG_IS_REVISION_FILES_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REVISION_FILES_PANEL))
-#define GITG_IS_REVISION_FILES_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_REVISION_FILES_PANEL))
-#define GITG_REVISION_FILES_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_REVISION_FILES_PANEL, GitgRevisionFilesViewPanelClass))
-
-typedef struct _GitgRevisionFilesPanel GitgRevisionFilesPanel;
-typedef struct _GitgRevisionFilesPanelClass GitgRevisionFilesPanelClass;
-typedef struct _GitgRevisionFilesPanelPrivate GitgRevisionFilesPanelPrivate;
-
-struct _GitgRevisionFilesPanel
-{
- GObject parent;
-
- GitgRevisionFilesPanelPrivate *priv;
-};
-
-struct _GitgRevisionFilesPanelClass
-{
- GObjectClass parent_class;
-};
-
-GType gitg_revision_files_panel_get_type (void) G_GNUC_CONST;
-GType gitg_revision_files_view_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* __GITG_REVISION_FILES_PANEL__H__ */
diff --git a/gitg/gitg-revision-files-panel.ui b/gitg/gitg-revision-files-panel.ui
deleted file mode 100644
index 5f172eb..0000000
--- a/gitg/gitg-revision-files-panel.ui
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <object class="GtkSourceBuffer" id="source_buffer"></object>
- <object class="GitgRevisionFilesView" id="revision_files_view">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="position">200</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_revision_files">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTreeView" id="revision_files">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <child>
- <object class="GtkTreeViewColumn" id="revision_files_column">
- <property name="title">Filename</property>
- <child>
- <object class="GtkCellRendererPixbuf" id="renderer_icon"/>
- <attributes>
- <attribute name="pixbuf">0</attribute>
- </attributes>
- </child>
- <child>
- <object class="GtkCellRendererText" id="renderer_date"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="sourcebox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkBox" id="hbox_top">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkCheckButton" id="blame_mode_checkbutton">
- <property name="label" translatable="yes">Switch to Blame mode</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_files_contents">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkSourceView" id="revision_files_contents">
- <property name="buffer">source_buffer</property>
- <property name="editable">False</property>
- <property name="show_line_numbers">False</property>
- <property name="expand">True</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- </object>
-</interface>
diff --git a/gitg/gitg-revision-panel.c b/gitg/gitg-revision-panel.c
deleted file mode 100644
index 979969e..0000000
--- a/gitg/gitg-revision-panel.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * gitg-revision-panel.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-revision-panel.h"
-
-G_DEFINE_INTERFACE(GitgRevisionPanel, gitg_revision_panel, G_TYPE_OBJECT)
-
-/* Default implementation */
-static void
-gitg_revision_panel_initialize_default (GitgRevisionPanel *panel,
- GitgWindow *window)
-{
- /* No 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);
-}
-
-static GtkWidget *
-gitg_revision_panel_get_panel_default (GitgRevisionPanel *panel)
-{
- g_return_val_if_reached (NULL);
-}
-
-static void
-gitg_revision_panel_update_default (GitgRevisionPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- /* No default implementation */
-}
-
-static void
-gitg_revision_panel_default_init (GitgRevisionPanelInterface *iface)
-{
- static gboolean initialized = FALSE;
-
- iface->initialize = gitg_revision_panel_initialize_default;
- 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;
-
- if (!initialized)
- {
- initialized = TRUE;
- }
-}
-
-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);
-
- return GITG_REVISION_PANEL_GET_INTERFACE (panel)->get_label (panel);
-}
-
-GtkWidget *
-gitg_revision_panel_get_panel (GitgRevisionPanel *panel)
-{
- g_return_val_if_fail (GITG_IS_REVISION_PANEL (panel), NULL);
-
- return GITG_REVISION_PANEL_GET_INTERFACE (panel)->get_panel (panel);
-}
-
-void
-gitg_revision_panel_update (GitgRevisionPanel *panel,
- GitgRepository *repository,
- GitgRevision *revision)
-{
- g_return_if_fail (GITG_IS_REVISION_PANEL (panel));
-
- GITG_REVISION_PANEL_GET_INTERFACE (panel)->update (panel,
- repository,
- revision);
-}
-
-void
-gitg_revision_panel_initialize (GitgRevisionPanel *panel,
- GitgWindow *window)
-{
- g_return_if_fail (GITG_IS_REVISION_PANEL (panel));
- g_return_if_fail (GITG_IS_WINDOW (window));
-
- GITG_REVISION_PANEL_GET_INTERFACE (panel)->initialize (panel,
- window);
-}
-
diff --git a/gitg/gitg-revision-panel.h b/gitg/gitg-revision-panel.h
deleted file mode 100644
index 29cd604..0000000
--- a/gitg/gitg-revision-panel.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * gitg-revision-panel.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REVISION_PANEL_H__
-#define __GITG_REVISION_PANEL_H__
-
-#include <gtk/gtk.h>
-#include <libgitg/gitg-repository.h>
-#include "gitg-window.h"
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REVISION_PANEL (gitg_revision_panel_get_type ())
-#define GITG_REVISION_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REVISION_PANEL, GitgRevisionPanel))
-#define GITG_IS_REVISION_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REVISION_PANEL))
-#define GITG_REVISION_PANEL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GITG_TYPE_REVISION_PANEL, GitgRevisionPanelInterface))
-
-typedef struct _GitgRevisionPanel GitgRevisionPanel;
-typedef struct _GitgRevisionPanelInterface GitgRevisionPanelInterface;
-
-struct _GitgRevisionPanelInterface
-{
- GTypeInterface parent;
-
- void (*initialize) (GitgRevisionPanel *panel,
- GitgWindow *window);
-
- void (*update) (GitgRevisionPanel *panel,
- GitgRepository *repository,
- 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;
-
-void gitg_revision_panel_initialize (GitgRevisionPanel *panel,
- GitgWindow *window);
-
-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,
- GitgRevision *revision);
-
-G_END_DECLS
-
-#endif /* __GITG_REVISION_PANEL_H__ */
diff --git a/gitg/gitg-stat-view.c b/gitg/gitg-stat-view.c
deleted file mode 100644
index d22573d..0000000
--- a/gitg/gitg-stat-view.c
+++ /dev/null
@@ -1,500 +0,0 @@
-#include "gitg-stat-view.h"
-
-#include "gitg-utils.h"
-#include <math.h>
-#include <cairo.h>
-
-#define GITG_STAT_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_STAT_VIEW, GitgStatViewPrivate))
-
-enum
-{
- PROP_0,
- PROP_LINES_ADDED,
- PROP_LINES_REMOVED,
- PROP_MAX_LINES
-};
-
-struct _GitgStatViewPrivate
-{
- gdouble color_added[3];
- gdouble color_removed[3];
-
- cairo_pattern_t *gradient_added;
- cairo_pattern_t *gradient_removed;
-
- guint lines_added;
- guint lines_removed;
- guint max_lines;
-
- guint radius;
- guint stat_padding;
- gboolean show_lines;
- guint lines_spacing;
-};
-
-G_DEFINE_TYPE (GitgStatView, gitg_stat_view, GTK_TYPE_DRAWING_AREA)
-
-static void
-clear_gradients (GitgStatView *view)
-{
- if (view->priv->gradient_added)
- {
- cairo_pattern_destroy (view->priv->gradient_added);
- view->priv->gradient_added = NULL;
- }
-
- if (view->priv->gradient_removed)
- {
- cairo_pattern_destroy (view->priv->gradient_removed);
- view->priv->gradient_removed = NULL;
- }
-}
-
-static void
-gitg_stat_view_finalize (GObject *object)
-{
- GitgStatView *view = GITG_STAT_VIEW (object);
-
- clear_gradients (view);
-
- G_OBJECT_CLASS (gitg_stat_view_parent_class)->finalize (object);
-}
-
-static void
-update_colors (GitgStatView *view)
-{
- GtkStyleContext *style_context;
- GtkStateFlags state;
- GdkRGBA bg_color;
- gdouble hue, sat, val;
-
- if (!gtk_widget_get_realized (GTK_WIDGET (view)))
- {
- return;
- }
-
- style_context = gtk_widget_get_style_context (GTK_WIDGET (view));
- state = gtk_widget_get_state (GTK_WIDGET (view));
- gtk_style_context_get_background_color (style_context, state, &bg_color);
-
- gtk_rgb_to_hsv (bg_color.red, bg_color.green, bg_color.blue, &hue, &sat, &val);
-
- sat = MIN(sat * 0.5 + 0.5, 1);
- val = MIN((pow(val + 1, 3) - 1) / 7 * 0.6 + 0.2, 1);
-
- gtk_hsv_to_rgb (0,
- sat,
- val,
- &(view->priv->color_removed[0]),
- &(view->priv->color_removed[1]),
- &(view->priv->color_removed[2]));
-
- gtk_hsv_to_rgb (0.3,
- sat,
- val,
- &(view->priv->color_added[0]),
- &(view->priv->color_added[1]),
- &(view->priv->color_added[2]));
-
- clear_gradients (view);
-}
-
-static void
-gitg_stat_view_realize (GtkWidget *widget)
-{
- if (GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->realize)
- {
- GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->realize (widget);
- }
-
- update_colors (GITG_STAT_VIEW (widget));
-}
-
-static void
-update_styles (GitgStatView *view)
-{
- gtk_style_context_get_style (gtk_widget_get_style_context (GTK_WIDGET (view)),
- gtk_widget_get_state (GTK_WIDGET (view)),
- "radius", &view->priv->radius,
- "stat-padding", &view->priv->stat_padding,
- "show-lines", &view->priv->show_lines,
- "lines-spacing", &view->priv->lines_spacing,
- NULL);
-}
-
-static void
-gitg_stat_view_style_updated (GtkWidget *widget)
-{
- if (GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->style_updated)
- {
- GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->style_updated (widget);
- }
-
- update_colors (GITG_STAT_VIEW (widget));
- update_styles (GITG_STAT_VIEW (widget));
-}
-
-static void
-multiply_color (gdouble *color, gdouble factor, gdouble *ret)
-{
- guint i;
-
- for (i = 0; i < 3; ++i)
- {
- ret[i] = color[i] * factor;
- }
-}
-
-static cairo_pattern_t *
-create_gradient (gdouble *base_color,
- gint y,
- gint height)
-{
- cairo_pattern_t *gradient;
- gdouble ret[3];
-
- gradient = cairo_pattern_create_linear (0, y, 0, height);
-
- cairo_pattern_add_color_stop_rgb (gradient,
- 0,
- base_color[0],
- base_color[1],
- base_color[2]);
-
- multiply_color (base_color, 1.3, ret);
-
- cairo_pattern_add_color_stop_rgb (gradient,
- 1,
- ret[0],
- ret[1],
- ret[2]);
-
- return gradient;
-}
-
-static void
-update_gradients (GitgStatView *view,
- GdkRectangle *alloc)
-{
- if (view->priv->gradient_added == NULL)
- {
- view->priv->gradient_added = create_gradient (view->priv->color_added,
- 0,
- alloc->height);
- }
-
- if (view->priv->gradient_removed == NULL)
- {
- view->priv->gradient_removed = create_gradient (view->priv->color_removed,
- 0,
- alloc->height);
- }
-}
-
-static void
-draw_stat (GitgStatView *view,
- cairo_t *ctx,
- gdouble *color,
- cairo_pattern_t *gradient,
- gint x,
- gint y,
- gint width,
- gint height)
-{
- gdouble darker[3];
- gdouble xoff;
- cairo_matrix_t mat;
-
- x += 0.5;
- y += 0.5;
- width -= 1;
- height -= 1;
-
- gitg_utils_rounded_rectangle (ctx,
- x,
- y,
- width,
- height,
- view->priv->radius);
-
- cairo_set_source (ctx, gradient);
- cairo_fill_preserve (ctx);
-
- multiply_color (color, 0.4, darker);
-
- cairo_set_line_width (ctx, 1);
-
- cairo_set_source_rgb (ctx, darker[0], darker[1], darker[2]);
- cairo_stroke (ctx);
-
- if (view->priv->show_lines)
- {
- xoff = x + view->priv->lines_spacing;
-
- cairo_matrix_init_rotate (&mat, M_PI);
- cairo_pattern_set_matrix (gradient, &mat);
-
- cairo_set_source (ctx, gradient);
-
- while (xoff < x + width - view->priv->lines_spacing / 2)
- {
- cairo_move_to (ctx, xoff, y + 2);
- cairo_line_to (ctx, xoff, y + height - 2);
- cairo_stroke (ctx);
-
- xoff += view->priv->lines_spacing;
- }
-
- cairo_matrix_init_identity (&mat);
- cairo_pattern_set_matrix (gradient, &mat);
- }
-}
-
-static gboolean
-gitg_stat_view_draw (GtkWidget *widget,
- cairo_t *ctx)
-{
- GdkRectangle alloc;
- guint added_width;
- guint removed_width;
- gdouble unit;
- GitgStatView *view;
- guint padding;
-
- if (GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->draw)
- {
- GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->draw (widget, ctx);
- }
-
- view = GITG_STAT_VIEW (widget);
-
- if (view->priv->max_lines == 0 ||
- (view->priv->lines_added == 0 && view->priv->lines_removed == 0))
- {
- return TRUE;
- }
-
- if (view->priv->lines_added == 0 || view->priv->lines_removed == 0)
- {
- padding = 0;
- }
- else
- {
- padding = 2;
- }
-
- gtk_widget_get_allocation (widget, &alloc);
-
- update_gradients (view, &alloc);
-
- unit = (alloc.width - padding) / (gdouble)view->priv->max_lines;
-
- added_width = MAX(view->priv->radius * 2 + 1, (guint)(unit * view->priv->lines_added));
- removed_width = MAX(view->priv->radius * 2 + 1, (guint)(unit * view->priv->lines_removed));
-
- if (view->priv->lines_added > 0)
- {
- draw_stat (view,
- ctx,
- view->priv->color_added,
- view->priv->gradient_added,
- 0,
- 0,
- added_width,
- alloc.height);
- }
- else
- {
- added_width = 0;
- }
-
- if (view->priv->lines_removed > 0)
- {
- draw_stat (view,
- ctx,
- view->priv->color_removed,
- view->priv->gradient_removed,
- added_width + padding,
- 0,
- removed_width,
- alloc.height);
- }
-
- return TRUE;
-}
-
-static void
-gitg_stat_view_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgStatView *self = GITG_STAT_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_LINES_ADDED:
- self->priv->lines_added = g_value_get_uint (value);
- gtk_widget_queue_draw (GTK_WIDGET (self));
- break;
- case PROP_LINES_REMOVED:
- self->priv->lines_removed = g_value_get_uint (value);
- gtk_widget_queue_draw (GTK_WIDGET (self));
- break;
- case PROP_MAX_LINES:
- self->priv->max_lines = g_value_get_uint (value);
- gtk_widget_queue_draw (GTK_WIDGET (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_stat_view_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgStatView *self = GITG_STAT_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_LINES_ADDED:
- g_value_set_uint (value, self->priv->lines_added);
- break;
- case PROP_LINES_REMOVED:
- g_value_set_uint (value, self->priv->lines_removed);
- break;
- case PROP_MAX_LINES:
- g_value_set_uint (value, self->priv->max_lines);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-gitg_stat_view_configure (GtkWidget *widget,
- GdkEventConfigure *event)
-{
- gboolean ret;
-
- if (GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->configure_event)
- {
- ret = GTK_WIDGET_CLASS (gitg_stat_view_parent_class)->configure_event (widget, event);
- }
- else
- {
- ret = FALSE;
- }
-
- clear_gradients (GITG_STAT_VIEW (widget));
-
- return ret;
-}
-
-static void
-gitg_stat_view_class_init (GitgStatViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- widget_class->draw = gitg_stat_view_draw;
- widget_class->style_updated = gitg_stat_view_style_updated;
- widget_class->realize = gitg_stat_view_realize;
- widget_class->configure_event = gitg_stat_view_configure;
-
- object_class->finalize = gitg_stat_view_finalize;
- object_class->set_property = gitg_stat_view_set_property;
- object_class->get_property = gitg_stat_view_get_property;
-
- g_object_class_install_property (object_class,
- PROP_LINES_ADDED,
- g_param_spec_uint ("lines-added",
- "Lines Added",
- "Lines added",
- 0,
- G_MAXUINT,
- 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_LINES_REMOVED,
- g_param_spec_uint ("lines-removed",
- "Lines Removed",
- "Lines removed",
- 0,
- G_MAXUINT,
- 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_MAX_LINES,
- g_param_spec_uint ("max-lines",
- "Max Lines",
- "Max lines",
- 0,
- G_MAXUINT,
- 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_uint ("radius",
- "Radius",
- "Radius",
- 0,
- G_MAXUINT,
- 4,
- G_PARAM_READWRITE));
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_uint ("stat-padding",
- "Stat padding",
- "Stat padding",
- 0,
- G_MAXUINT,
- 2,
- G_PARAM_READWRITE));
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_boolean ("show-lines",
- "Show lines",
- "Show lines",
- TRUE,
- G_PARAM_READWRITE));
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_uint ("lines-spacing",
- "Lines spacing",
- "Lines spacing",
- 1,
- G_MAXUINT,
- 10,
- G_PARAM_READWRITE));
-
- g_type_class_add_private (object_class, sizeof(GitgStatViewPrivate));
-}
-
-static void
-gitg_stat_view_init (GitgStatView *self)
-{
- self->priv = GITG_STAT_VIEW_GET_PRIVATE (self);
-}
-
-GtkWidget *
-gitg_stat_view_new (guint lines_added,
- guint lines_removed,
- guint max_lines)
-{
- return g_object_new (GITG_TYPE_STAT_VIEW,
- "lines-added",
- lines_added,
- "lines-removed",
- lines_removed,
- "max-lines",
- max_lines,
- NULL);
-}
diff --git a/gitg/gitg-stat-view.h b/gitg/gitg-stat-view.h
deleted file mode 100644
index e78a636..0000000
--- a/gitg/gitg-stat-view.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __GITG_STAT_VIEW_H__
-#define __GITG_STAT_VIEW_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_STAT_VIEW (gitg_stat_view_get_type ())
-#define GITG_STAT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_STAT_VIEW, GitgStatView))
-#define GITG_STAT_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_STAT_VIEW, GitgStatView const))
-#define GITG_STAT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_STAT_VIEW, GitgStatViewClass))
-#define GITG_IS_STAT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_STAT_VIEW))
-#define GITG_IS_STAT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_STAT_VIEW))
-#define GITG_STAT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_STAT_VIEW, GitgStatViewClass))
-
-typedef struct _GitgStatView GitgStatView;
-typedef struct _GitgStatViewClass GitgStatViewClass;
-typedef struct _GitgStatViewPrivate GitgStatViewPrivate;
-
-struct _GitgStatView {
- GtkDrawingArea parent;
-
- GitgStatViewPrivate *priv;
-};
-
-struct _GitgStatViewClass {
- GtkDrawingAreaClass parent_class;
-};
-
-GType gitg_stat_view_get_type (void) G_GNUC_CONST;
-GtkWidget *gitg_stat_view_new (guint lines_added,
- guint lines_removed,
- guint max_lines);
-
-G_END_DECLS
-
-#endif /* __GITG_STAT_VIEW_H__ */
diff --git a/gitg/gitg-tag.ui b/gitg/gitg-tag.ui
deleted file mode 100644
index 03758d7..0000000
--- a/gitg/gitg-tag.ui
+++ /dev/null
@@ -1,158 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <!-- interface-requires gtk+ 2.16 -->
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkDialog" id="dialog_tag">
- <property name="border_width">5</property>
- <property name="title" translatable="yes">Properties</property>
- <property name="window_position">center-always</property>
- <property name="default_width">400</property>
- <property name="default_height">200</property>
- <property name="destroy_with_parent">True</property>
- <property name="type_hint">normal</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog_vbox_main">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkTable" id="table_main">
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_name">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Name:</property>
- </object>
- <packing>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- <property name="y_options">GTK_SHRINK</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_message">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Message:</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_SHRINK | GTK_FILL</property>
- <property name="y_options">GTK_SHRINK | GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x25CF;</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_message">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTextView" id="text_view_message">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_sign">
- <property name="label" translatable="yes">Create signed tag object</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog_action_area">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="button_cancel">
- <property name="label">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_tag">
- <property name="label" translatable="yes">Create tag</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="is_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="image">image_tag</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="-6">button_cancel</action-widget>
- <action-widget response="-3">button_tag</action-widget>
- </action-widgets>
- </object>
- <object class="GtkImage" id="image_tag">
- <property name="visible">True</property>
- <property name="stock">gtk-apply</property>
- </object>
-</interface>
diff --git a/gitg/gitg-ui.xml b/gitg/gitg-ui.xml
deleted file mode 100644
index b65e59c..0000000
--- a/gitg/gitg-ui.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <object class="GtkUIManager" id="uiman">
- <child>
- <object class="GtkActionGroup" id="action_group_menu">
- <child>
- <object class="GtkAction" id="FileAction">
- <property name="label" translatable="yes">_File</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="EditAction">
- <property name="label" translatable="yes">_Edit</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="ViewAction">
- <property name="label" translatable="yes">_View</property>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="HelpAction">
- <property name="label" translatable="yes">_Help</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_menu_file">
- <child>
- <object class="GtkAction" id="FileOpenAction">
- <property name="stock-id">gtk-open</property>
- <property name="label" translatable="yes">_Open...</property>
- <signal name="activate" handler="on_file_open"/>
- </object>
- </child>
- <child>
- <object class="GtkRecentAction" id="RecentOpenAction">
- <property name="label" translatable="yes">R_ecently Opened</property>
- <signal name="item-activated" handler="on_recent_open"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="FileQuitAction">
- <property name="stock-id">gtk-quit</property>
- <signal name="activate" handler="on_file_quit"/>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_menu_edit">
- <child>
- <object class="GtkAction" id="EditCutAction">
- <property name="stock-id">gtk-cut</property>
- <signal name="activate" handler="on_edit_cut"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="EditCopyAction">
- <property name="stock-id">gtk-copy</property>
- <signal name="activate" handler="on_edit_copy"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="EditPasteAction">
- <property name="stock-id">gtk-paste</property>
- <signal name="activate" handler="on_edit_paste"/>
- </object>
- </child>
- <child>
- <object class="GtkAction" id="EditPreferencesAction">
- <property name="stock-id">gtk-preferences</property>
- <signal name="activate" handler="on_edit_preferences"/>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_menu_repository">
- <child>
- <object class="GtkAction" id="RepositoryPropertiesAction">
- <property name="stock-id">gtk-properties</property>
- <property name="label">_Repository Properties</property>
- <signal name="activate" handler="on_repository_properties"/>
- </object>
- <accelerator key="R" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>
- </child>
- <child>
- <object class="GtkAction" id="ViewRefreshAction">
- <property name="stock-id">gtk-refresh</property>
- <signal name="activate" handler="on_view_refresh"/>
- </object>
- <accelerator key="R" modifiers="GDK_CONTROL_MASK"/>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkActionGroup" id="action_group_menu_help">
- <child>
- <object class="GtkAction" id="HelpAboutAction">
- <property name="stock-id">gtk-about</property>
- <signal name="activate" handler="on_help_about"/>
- </object>
- </child>
- </object>
- </child>
- <ui>
- <menubar name="menubar_main">
- <menu action="FileAction">
- <menuitem action="FileOpenAction"/>
- <menuitem action="RecentOpenAction"/>
- <separator/>
- <menuitem action="RepositoryPropertiesAction"/>
- <separator/>
- <menuitem action="FileQuitAction"/>
- </menu>
- <menu action="EditAction">
- <menuitem action="EditCutAction"/>
- <menuitem action="EditCopyAction"/>
- <menuitem action="EditPasteAction"/>
- <separator/>
- <menuitem action="EditPreferencesAction"/>
- </menu>
- <menu action="ViewAction">
- <menuitem action="ViewRefreshAction"/>
- </menu>
- <menu action="HelpAction">
- <menuitem action="HelpAboutAction"/>
- </menu>
- </menubar>
- </ui>
- </object>
-</interface>
-
-<!-- vi:ts=2:et -->
diff --git a/gitg/gitg-uri.c b/gitg/gitg-uri.c
deleted file mode 100644
index 74717c3..0000000
--- a/gitg/gitg-uri.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#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
deleted file mode 100644
index 90001c3..0000000
--- a/gitg/gitg-uri.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#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-utils.c b/gitg/gitg-utils.c
deleted file mode 100644
index ad748b0..0000000
--- a/gitg/gitg-utils.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * gitg-utils.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-dirs.h"
-#include "gitg-utils.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-gchar *
-gitg_utils_get_content_type(GFile *file)
-{
- GFileInfo *info = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL);
-
- if (!info || !g_file_info_has_attribute(info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
- return NULL;
-
- gchar *content_type = g_strdup(g_file_info_get_content_type(info));
- g_object_unref(info);
-
- return content_type;
-}
-
-gboolean
-gitg_utils_can_display_content_type (gchar const *content_type)
-{
- return g_content_type_is_a (content_type, "text/plain") ||
- g_content_type_equals (content_type, "application/octet-stream");
-}
-
-gchar *
-gitg_utils_guess_content_type(GtkTextBuffer *buffer)
-{
- GtkTextIter start;
- GtkTextIter end;
-
- gtk_text_buffer_get_start_iter(buffer, &start);
- end = start;
-
- gtk_text_iter_forward_chars(&end, 256);
- gchar *data = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
-
- gchar *content_type = g_content_type_guess(NULL, (guchar *)data, strlen(data), NULL);
- g_free(data);
-
- return content_type;
-}
-
-static void
-append_escape (GString *gstr, gchar const *item)
-{
- gchar *escape = g_shell_quote (item);
-
- g_string_append_printf (gstr, " %s", escape);
- g_free (escape);
-}
-
-gboolean
-gitg_utils_export_files (GitgRepository *repository,
- GitgRevision *revision,
- gchar const *todir,
- gchar * const *paths)
-{
- GString *gstr = g_string_new("sh -c \"git --git-dir");
-
- GFile *git_dir = gitg_repository_get_git_dir (repository);
- gchar *git_path = g_file_get_path (git_dir);
-
- append_escape (gstr, git_path);
-
- g_free (git_path);
- g_object_unref (git_dir);
-
- // Append the revision
- gchar *sha = gitg_revision_get_sha1 (revision);
- g_string_append_printf (gstr, " archive --format=tar %s", sha);
- g_free(sha);
-
- // Append the files
- while (*paths)
- {
- append_escape (gstr, *paths);
- paths++;
- }
-
- g_string_append (gstr, " | tar -xC");
- append_escape (gstr, todir);
- g_string_append (gstr, "\"");
-
- GError *error = NULL;
- gint status;
-
- gboolean ret = g_spawn_command_line_sync (gstr->str, NULL, NULL, &status, &error);
-
- if (!ret)
- {
- g_warning ("Export failed:\n%s\n%s", gstr->str, error->message);
- g_error_free (error);
- }
-
- g_string_free (gstr, TRUE);
- return ret;
-}
-
-GtkSourceLanguage *
-gitg_utils_get_language(gchar const *filename, gchar const *content_type)
-{
- if (!gitg_utils_can_display_content_type(content_type))
- return NULL;
-
- GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default();
- return gtk_source_language_manager_guess_language(manager, filename, content_type);
-}
-
-gchar *
-gitg_utils_get_monospace_font_name(void)
-{
- GSettings *interface;
- gchar *name;
-
- interface = g_settings_new ("org.gnome.desktop.interface");
- name = g_settings_get_string (interface, "monospace-font-name");
-
- g_object_unref (interface);
-
- return name;
-}
-
-void
-gitg_utils_set_monospace_font(GtkWidget *widget)
-{
- gchar *name = gitg_utils_get_monospace_font_name();
-
- if (name)
- {
- PangoFontDescription *description = pango_font_description_from_string(name);
-
- if (description)
- {
- gtk_widget_override_font(widget, description);
- pango_font_description_free(description);
- }
- }
-
- g_free(name);
-}
-
-GtkBuilder *
-gitg_utils_new_builder (gchar const *filename)
-{
- GtkBuilder *b = gtk_builder_new ();
- GError *error = NULL;
-
- gchar *path = gitg_dirs_get_data_filename ("ui", filename, NULL);
-
- if (!gtk_builder_add_from_file (b, path, &error))
- {
- g_critical ("Could not open UI file: %s (%s)", path, error->message);
- g_error_free (error);
-
- g_free (path);
- exit (1);
- }
-
- g_free (path);
- return b;
-}
-
-gint
-gitg_utils_sort_names(gchar const *s1, gchar const *s2)
-{
- if (s1 == NULL)
- return -1;
-
- if (s2 == NULL)
- return 1;
-
- gchar *c1 = s1 ? g_utf8_casefold(s1, -1) : NULL;
- gchar *c2 = s2 ? g_utf8_casefold(s2, -1) : NULL;
-
- gint ret = g_utf8_collate(c1, c2);
-
- g_free(c1);
- g_free(c2);
-
- return ret;
-}
-
-/* Copied from gedit-utils.c */
-void
-gitg_utils_menu_position_under_widget (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
-{
- GtkWidget *w = GTK_WIDGET (user_data);
- GtkRequisition requisition;
-
- gdk_window_get_origin (gtk_widget_get_window (w), x, y);
- gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
-
- GtkAllocation alloc;
- gtk_widget_get_allocation (w, &alloc);
-
- if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL)
- {
- *x += alloc.x + alloc.width - requisition.width;
- }
- else
- {
- *x += alloc.x;
- }
-
- *y += alloc.y + alloc.height;
- *push_in = TRUE;
-}
-
-void
-gitg_utils_menu_position_under_tree_view (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
-{
- GtkTreeView *tree = GTK_TREE_VIEW (user_data);
- GtkTreeModel *model;
- GtkTreeSelection *selection;
- GtkTreeIter iter;
-
- model = gtk_tree_view_get_model (tree);
- g_return_if_fail (model != NULL);
-
- selection = gtk_tree_view_get_selection (tree);
- g_return_if_fail (selection != NULL);
-
- if (gtk_tree_selection_get_selected (selection, NULL, &iter))
- {
- GtkTreePath *path;
- GdkRectangle rect;
-
- gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (tree)), x, y);
-
- path = gtk_tree_model_get_path (model, &iter);
- gtk_tree_view_get_cell_area (tree, path,
- gtk_tree_view_get_column (tree, 0), /* FIXME 0 for RTL ? */
- &rect);
- gtk_tree_path_free (path);
-
- *x += rect.x;
- *y += rect.y + rect.height;
-
- if (gtk_widget_get_direction (GTK_WIDGET (tree)) == GTK_TEXT_DIR_RTL)
- {
- GtkRequisition requisition;
- gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
- *x += rect.width - requisition.width;
- }
- }
- else
- {
- /* no selection -> regular "under widget" positioning */
- gitg_utils_menu_position_under_widget (menu,
- x, y, push_in,
- tree);
- }
-}
-
-gchar *
-gitg_utils_rewrite_hunk_counters (gchar const *header,
- guint old_count,
- guint new_count)
-{
- if (!header)
- {
- return NULL;
- }
-
- gchar *copy = g_strdup (header);
- gchar *ptr1 = g_utf8_strchr (copy, -1, ',');
-
- if (!ptr1)
- {
- g_free (copy);
- return NULL;
- }
-
- gchar *ptrs1 = g_utf8_strchr (ptr1 + 1, -1, ' ');
-
- if (!ptrs1)
- {
- g_free (copy);
- return NULL;
- }
-
- gchar *ptr2 = g_utf8_strchr (ptrs1 + 1, -1, ',');
-
- if (!ptr2)
- {
- g_free (copy);
- return NULL;
- }
-
- gchar *ptrs2 = g_utf8_strchr (ptr2 + 1, -1, ' ');
-
- if (!ptrs2)
- {
- g_free (copy);
- return NULL;
- }
-
- *ptr1 = *ptr2 = '\0';
-
- gchar *ret;
-
- ret = g_strdup_printf ("%s,%d%s,%d%s",
- copy,
- old_count,
- ptrs1,
- new_count,
- ptrs2);
-
- g_free (copy);
- return ret;
-}
-
-GtkCellRenderer *
-gitg_utils_find_cell_at_pos (GtkTreeView *tree_view, GtkTreeViewColumn *column, GtkTreePath *path, gint x)
-{
- GList *cells;
- GList *item;
- GtkTreeIter iter;
- GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
-
- gtk_tree_model_get_iter (model, &iter, path);
-
- gtk_tree_view_column_cell_set_cell_data (column, model, &iter, FALSE, FALSE);
-
- cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
- GtkCellRenderer *ret = NULL;
-
- for (item = cells; item; item = g_list_next (item))
- {
- GtkCellRenderer *renderer = GTK_CELL_RENDERER (item->data);
- gint start;
- gint width;
-
- if (!gtk_tree_view_column_cell_get_position (column, renderer, &start, &width))
- {
- continue;
- }
-
- gtk_cell_renderer_get_preferred_width (renderer, GTK_WIDGET (tree_view), &width, NULL);
-
- if (x >= start && x <= start + width)
- {
- ret = renderer;
- break;
- }
- }
-
- g_list_free (cells);
- return ret;
-}
-
-typedef struct
-{
- gint position;
- gboolean reversed;
-} PanedRestoreInfo;
-
-static void
-free_paned_restore_info (PanedRestoreInfo *info)
-{
- g_slice_free (PanedRestoreInfo, info);
-}
-
-static void
-paned_set_position (GtkPaned *paned, gint position, gboolean reversed)
-{
- if (position == -1)
- {
- return;
- }
-
- if (!reversed)
- {
- gtk_paned_set_position (paned, position);
- }
- else
- {
- GtkAllocation alloc;
- gtk_widget_get_allocation (GTK_WIDGET (paned), &alloc);
-
- gtk_paned_set_position (paned, alloc.width - position);
- }
-}
-
-static void
-on_paned_mapped (GtkPaned *paned, PanedRestoreInfo *info)
-{
- paned_set_position (paned, info->position, info->reversed);
-
- g_signal_handlers_disconnect_by_func (paned, on_paned_mapped, info);
-}
-
-void
-gitg_utils_restore_pane_position (GtkPaned *paned, gint position, gboolean reversed)
-{
- g_return_if_fail (GTK_IS_PANED (paned));
-
- if (gtk_widget_get_mapped (GTK_WIDGET (paned)))
- {
- paned_set_position (paned, position, reversed);
-
- return;
- }
-
- PanedRestoreInfo *info = g_slice_new (PanedRestoreInfo);
- info->position = position;
- info->reversed = reversed;
-
- g_signal_connect_data (paned,
- "map",
- G_CALLBACK (on_paned_mapped),
- info,
- (GClosureNotify)free_paned_restore_info,
- G_CONNECT_AFTER);
-}
-
-void
-gitg_utils_rounded_rectangle(cairo_t *ctx, gdouble x, gdouble y, gdouble width, gdouble height, gdouble radius)
-{
- cairo_move_to (ctx, x + radius, y);
- cairo_rel_line_to (ctx, width - 2 * radius, 0);
- cairo_arc (ctx, x + width - radius, y + radius, radius, 1.5 * M_PI, 0.0);
-
- cairo_rel_line_to (ctx, 0, height - 2 * radius);
- cairo_arc (ctx, x + width - radius, y + height - radius, radius, 0.0, 0.5 * M_PI);
-
- cairo_rel_line_to (ctx, -(width - radius * 2), 0);
- cairo_arc (ctx, x + radius, y + height - radius, radius, 0.5 * M_PI, M_PI);
-
- cairo_rel_line_to (ctx, 0, -(height - radius * 2));
- cairo_arc (ctx, x + radius, y + radius, radius, M_PI, 1.5 * M_PI);
-}
diff --git a/gitg/gitg-utils.h b/gitg/gitg-utils.h
deleted file mode 100644
index f202fb7..0000000
--- a/gitg/gitg-utils.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * gitg-utils.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_UTILS_H__
-#define __GITG_UTILS_H__
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <gtksourceview/gtksourcelanguagemanager.h>
-#include <gtksourceview/gtksourcelanguage.h>
-
-#include <libgitg/gitg-repository.h>
-#include <libgitg/gitg-revision.h>
-
-gchar *gitg_utils_get_content_type(GFile *file);
-gboolean gitg_utils_can_display_content_type(gchar const *content_type);
-gchar *gitg_utils_guess_content_type(GtkTextBuffer *buffer);
-
-gboolean gitg_utils_export_files(GitgRepository *repository, GitgRevision *revision,
-gchar const *todir, gchar * const *paths);
-
-GtkSourceLanguage *gitg_utils_get_language(gchar const *filename, gchar const *content_type);
-
-gchar *gitg_utils_get_monospace_font_name(void);
-void gitg_utils_set_monospace_font(GtkWidget *widget);
-
-GtkBuilder *gitg_utils_new_builder (gchar const *filename);
-
-gint gitg_utils_sort_names(gchar const *s1, gchar const *s2);
-
-void gitg_utils_menu_position_under_widget(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data);
-void gitg_utils_menu_position_under_tree_view(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data);
-
-gchar *gitg_utils_rewrite_hunk_counters (gchar const *hunk, guint old_count, guint new_count);
-
-GtkCellRenderer *gitg_utils_find_cell_at_pos (GtkTreeView *tree_view, GtkTreeViewColumn *column, GtkTreePath *path, gint x);
-
-void gitg_utils_restore_pane_position (GtkPaned *paned, gint position, gboolean reversed);
-
-void gitg_utils_rounded_rectangle (cairo_t *ctx, gdouble x, gdouble y, gdouble width, gdouble height, gdouble radius);
-
-#endif /* __GITG_UTILS_H__ */
diff --git a/gitg/gitg-window.c b/gitg/gitg-window.c
deleted file mode 100644
index fa30e52..0000000
--- a/gitg/gitg-window.c
+++ /dev/null
@@ -1,3584 +0,0 @@
-/*
- * gitg-window.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <gdk/gdkkeysyms.h>
-#include <string.h>
-#include <stdlib.h>
-#include <glib/gi18n.h>
-#include <libgitg/gitg-config.h>
-#include <libgitg/gitg-ref.h>
-#include <libgitg/gitg-hash.h>
-
-#include "config.h"
-
-#include "gitg-dirs.h"
-#include "gitg-window.h"
-#include "gitg-cell-renderer-path.h"
-#include "gitg-commit-view.h"
-#include "gitg-preferences-dialog.h"
-#include "gitg-repository-dialog.h"
-#include "gitg-dnd.h"
-#include "gitg-branch-actions.h"
-#include "gitg-utils.h"
-#include "gitg-revision-panel.h"
-#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"
-#define DYNAMIC_ACTION_DATA_BRANCH_KEY "GitgDynamicActionDataBranchKey"
-
-#define GITG_WINDOW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_WINDOW, GitgWindowPrivate))
-
-enum
-{
- COLUMN_BRANCHES_NAME,
- COLUMN_BRANCHES_REF,
- COLUMN_BRANCHES_ICON,
- COLUMN_BRANCHES_SELECTION
-};
-
-struct _GitgWindowPrivate
-{
- GitgRepository *repository;
-
- GtkTreeStore *branches_store;
-
- /* Widget placeholders */
- GtkNotebook *notebook_main;
- GtkTreeView *tree_view;
- GtkStatusbar *statusbar;
- GitgCommitView *commit_view;
- GtkWidget *search_popup;
- GtkComboBox *combo_branches;
-
- GtkUIManager *menus_ui_manager;
-
- GtkWidget *vpaned_main;
- GtkWidget *hpaned_commit1;
- GtkWidget *hpaned_commit2;
- GtkWidget *vpaned_commit;
- GtkNotebook *notebook_revision;
-
- GtkActionGroup *edit_group;
- GtkActionGroup *repository_group;
- GtkWidget *open_dialog;
-
- GitgCellRendererPath *renderer_path;
-
- GTimer *load_timer;
- GdkCursor *hand;
-
- gboolean destroy_has_run;
- guint merge_rebase_uid;
- GtkActionGroup *merge_rebase_action_group;
-
- guint cherry_pick_uid;
- GtkActionGroup *cherry_pick_action_group;
- GitgRef *popup_refs[2];
-
- GList *branch_actions;
- GitgHash select_on_load;
-
- GSList *revision_panels;
- GSList *activatables;
-
- GSettings *state_settings;
- GSettings *view_settings;
- GSettings *history_settings;
- GSettings *hidden_settings;
-};
-
-static gboolean on_tree_view_motion (GtkTreeView *treeview,
- GdkEventMotion *event,
- GitgWindow *window);
-
-static gboolean on_tree_view_button_release (GtkTreeView *treeview,
- GdkEventButton *event,
- GitgWindow *window);
-
-static void gitg_window_buildable_iface_init (GtkBuildableIface *iface);
-
-void on_subject_activate (GtkAction *action, GitgWindow *window);
-void on_author_activate (GtkAction *action, GitgWindow *window);
-void on_date_activate (GtkAction *action, GitgWindow *window);
-void on_hash_activate (GtkAction *action, GitgWindow *window);
-void on_file_quit (GtkAction *action, GitgWindow *window);
-void on_file_open (GtkAction *action, GitgWindow *window);
-void on_edit_cut (GtkAction *action, GitgWindow *window);
-void on_edit_copy (GtkAction *action, GitgWindow *window);
-void on_edit_paste (GtkAction *action, GitgWindow *window);
-void on_view_refresh (GtkAction *action, GitgWindow *window);
-void on_recent_open (GtkRecentChooser *chooser, GitgWindow *window);
-void on_help_about (GtkAction *action, GitgWindow *window);
-void on_edit_preferences (GtkAction *action, GitgWindow *window);
-void on_repository_properties (GtkAction *action, GitgWindow *window);
-
-void on_tree_view_rv_button_press_event (GtkWidget *widget,
- GdkEvent *event,
- GitgWindow *window);
-
-void on_checkout_branch_action_activate (GtkAction *action, GitgWindow *window);
-void on_remove_branch_action_activate (GtkAction *action, GitgWindow *window);
-void on_rename_branch_action_activate (GtkAction *action, GitgWindow *window);
-void on_rebase_branch_action_activate (GtkAction *action, GitgWindow *window);
-void on_merge_branch_action_activate (GtkAction *action, GitgWindow *window);
-void on_revision_format_patch_activate (GtkAction *action, GitgWindow *window);
-void on_revision_new_branch_activate (GtkAction *action, GitgWindow *window);
-void on_revision_tag_activate (GtkAction *action, GitgWindow *window);
-void on_revision_squash_activate (GtkAction *action, GitgWindow *window);
-
-G_DEFINE_TYPE_EXTENDED(GitgWindow, gitg_window, GTK_TYPE_WINDOW, 0,
- G_IMPLEMENT_INTERFACE(GTK_TYPE_BUILDABLE, gitg_window_buildable_iface_init));
-
-static GtkBuildableIface parent_iface;
-static GtkWindowClass *parent_class = NULL;
-
-static void
-on_branch_action_shell_end (GitgShell *shell,
- gboolean cancelled,
- GitgWindow *window)
-{
- window->priv->branch_actions = g_list_remove (window->priv->branch_actions, shell);
- g_object_unref (shell);
-}
-
-gboolean
-gitg_window_add_branch_action (GitgWindow *window,
- GitgShell *shell)
-{
- if (shell != NULL && gitg_io_get_running (GITG_IO (shell)))
- {
- window->priv->branch_actions = g_list_prepend (window->priv->branch_actions, shell);
-
- g_signal_connect (shell, "end", G_CALLBACK (on_branch_action_shell_end), window);
- }
- else if (shell)
- {
- g_object_unref (shell);
- shell = NULL;
- }
-
- return shell != NULL;
-}
-
-static void
-gitg_window_finalize (GObject *object)
-{
- GitgWindow *self = GITG_WINDOW(object);
-
- g_timer_destroy (self->priv->load_timer);
- g_object_unref (self->priv->hand);
-
- GList *copy = g_list_copy (self->priv->branch_actions);
- GList *item;
-
- for (item = copy; item; item = g_list_next (item))
- {
- gitg_io_cancel (item->data);
- }
-
- g_list_free (copy);
-
- G_OBJECT_CLASS (gitg_window_parent_class)->finalize (object);
-}
-
-static void
-gitg_window_dispose (GObject *object)
-{
- GitgWindow *self = GITG_WINDOW (object);
-
- if (self->priv->state_settings)
- {
- g_object_unref (self->priv->state_settings);
- self->priv->state_settings = NULL;
- }
-
- if (self->priv->view_settings)
- {
- g_object_unref (self->priv->view_settings);
- self->priv->view_settings = NULL;
- }
-
- if (self->priv->history_settings)
- {
- g_object_unref (self->priv->history_settings);
- self->priv->history_settings = NULL;
- }
-
- if (self->priv->hidden_settings)
- {
- g_object_unref (self->priv->hidden_settings);
- self->priv->hidden_settings = NULL;
- }
-
- G_OBJECT_CLASS (gitg_window_parent_class)->dispose (object);
-}
-
-static void
-on_revision_panel_mapped (GtkWidget *page,
- GitgWindow *window)
-{
- gint nth;
- GitgRevisionPanel *panel;
- GitgRevision *revision = NULL;
- GtkTreeModel *model;
- GtkTreeSelection *selection;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (window->priv->tree_view);
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &revision, -1);
- }
-
- if (!revision)
- {
- return;
- }
-
- nth = gtk_notebook_page_num (window->priv->notebook_revision,
- page);
-
- panel = g_slist_nth_data (window->priv->revision_panels, nth);
-
- gitg_revision_panel_update (panel,
- window->priv->repository,
- revision);
-
- gitg_revision_unref (revision);
-}
-
-static void
-add_revision_panel (GitgWindow *window,
- GType panel_type)
-{
- GitgRevisionPanel *panel;
- gchar *label;
- GtkWidget *label_widget;
- GtkWidget *page;
-
- g_return_if_fail (g_type_is_a (panel_type, GITG_TYPE_REVISION_PANEL));
-
- panel = g_object_new (panel_type, NULL);
- gitg_revision_panel_initialize (panel, 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);
-
- g_free (label);
-
- page = gitg_revision_panel_get_panel (panel);
- gtk_widget_show (page);
-
- g_signal_connect (page,
- "map",
- G_CALLBACK (on_revision_panel_mapped),
- window);
-
- gtk_notebook_append_page (window->priv->notebook_revision,
- page,
- label_widget);
-}
-
-static void
-on_selection_changed (GtkTreeSelection *selection,
- GitgWindow *window)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GitgRevision *revision = NULL;
- GSList *item;
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- gtk_tree_model_get (GTK_TREE_MODEL(model), &iter, 0, &revision, -1);
- }
-
- gint i = 0;
-
- for (item = window->priv->revision_panels; item; item = g_slist_next (item))
- {
- GtkWidget *page;
-
- page = gtk_notebook_get_nth_page (window->priv->notebook_revision,
- i++);
-
- if (gtk_widget_get_mapped (page) || !revision)
- {
- gitg_revision_panel_update (item->data,
- window->priv->repository,
- revision);
- }
- }
-
- if (revision)
- {
- if (gitg_repository_get_loaded (window->priv->repository))
- {
- memcpy (window->priv->select_on_load,
- gitg_revision_get_hash (revision),
- GITG_HASH_BINARY_SIZE);
- }
-
- gitg_revision_unref (revision);
- }
- else
- {
- if (gitg_repository_get_loaded (window->priv->repository))
- {
- memset (window->priv->select_on_load, 0, GITG_HASH_BINARY_SIZE);
- }
- }
-}
-
-static void
-on_search_icon_release (GtkEntry *entry,
- GtkEntryIconPosition icon_pos,
- int button,
- GitgWindow *window)
-{
- gtk_menu_popup (GTK_MENU(window->priv->search_popup),
- NULL,
- NULL,
- NULL,
- NULL,
- button,
- gtk_get_current_event_time ());
-}
-
-static void
-search_column_activate (GtkAction *action,
- gint column,
- GtkTreeView *tree_view)
-{
- if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action)))
- {
- return;
- }
-
- gtk_tree_view_set_search_column (tree_view, column);
-}
-
-void
-on_subject_activate (GtkAction *action,
- GitgWindow *window)
-{
- search_column_activate (action, 1, window->priv->tree_view);
-}
-
-void
-on_author_activate (GtkAction *action,
- GitgWindow *window)
-{
- search_column_activate (action, 2, window->priv->tree_view);
-}
-
-void
-on_date_activate (GtkAction *action,
- GitgWindow *window)
-{
- search_column_activate (action, 3, window->priv->tree_view);
-}
-
-void
-on_hash_activate (GtkAction *action,
- GitgWindow *window)
-{
- search_column_activate (action, 4, window->priv->tree_view);
-}
-
-static gboolean
-search_hash_equal_func (GtkTreeModel *model,
- gchar const *key,
- GtkTreeIter *iter)
-{
- GitgRevision *rv;
- gtk_tree_model_get (model, iter, 0, &rv, -1);
-
- gchar *sha = gitg_revision_get_sha1 (rv);
-
- gboolean ret = !g_str_has_prefix (sha, key);
-
- g_free (sha);
- gitg_revision_unref (rv);
-
- return ret;
-}
-
-static gboolean
-search_equal_func (GtkTreeModel *model,
- gint column,
- gchar const *key,
- GtkTreeIter *iter,
- gpointer userdata)
-{
- if (column == 4)
- {
- return search_hash_equal_func (model, key, iter);
- }
-
- gchar *cmp;
- gtk_tree_model_get (model, iter, column, &cmp, -1);
-
- gchar *s1 = g_utf8_casefold (key, -1);
- gchar *s2 = g_utf8_casefold (cmp, -1);
-
- gboolean ret = strstr (s2, s1) == NULL;
-
- g_free (s1);
- g_free (s2);
-
- g_free (cmp);
-
- return ret;
-}
-
-static void
-focus_search (GtkAccelGroup *group,
- GObject *acceleratable,
- guint keyval,
- GdkModifierType modifier,
- gpointer userdata)
-{
- gtk_widget_grab_focus (GTK_WIDGET(userdata));
-}
-
-static void
-build_search_entry (GitgWindow *window,
- GtkBuilder *builder)
-{
- GtkWidget *box;
- GtkWidget *entry;
- GtkWidget *popup;
-
- box = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_top"));
- entry = gtk_entry_new ();
-
- gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
- GTK_ENTRY_ICON_PRIMARY,
- GTK_STOCK_FIND);
-
- gtk_tree_view_set_search_entry (window->priv->tree_view, GTK_ENTRY(entry));
- gtk_widget_show (entry);
- gtk_box_pack_end (GTK_BOX(box), entry, FALSE, FALSE, 0);
-
- popup = gtk_ui_manager_get_widget (window->priv->menus_ui_manager,
- "/ui/search_popup");
-
- window->priv->search_popup = popup;
- g_object_ref (popup);
-
- g_signal_connect (entry,
- "icon-release",
- G_CALLBACK(on_search_icon_release),
- window);
-
- gtk_tree_view_set_search_column (window->priv->tree_view, 1);
-
- gtk_tree_view_set_search_equal_func (window->priv->tree_view,
- search_equal_func,
- window,
- NULL);
-
- GtkAccelGroup *group = gtk_accel_group_new ();
-
- GClosure *closure = g_cclosure_new (G_CALLBACK (focus_search), entry, NULL);
-
- gtk_accel_group_connect (group, GDK_KEY_f, GDK_CONTROL_MASK, 0, closure);
- gtk_window_add_accel_group (GTK_WINDOW(window), group);
-}
-
-static gboolean
-goto_hash (GitgWindow *window,
- gchar const *hash)
-{
- GtkTreeIter iter;
-
- if (!gitg_repository_find_by_hash (window->priv->repository, hash, &iter))
- {
- return FALSE;
- }
-
- gtk_tree_selection_select_iter (gtk_tree_view_get_selection (window->priv->tree_view),
- &iter);
- GtkTreePath *path;
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL(window->priv->repository),
- &iter);
-
- gtk_tree_view_scroll_to_cell (window->priv->tree_view,
- path,
- NULL,
- TRUE,
- 0.5,
- 0);
- gtk_tree_path_free (path);
-
- return TRUE;
-}
-
-static void
-on_renderer_path (GtkTreeViewColumn *column,
- GitgCellRendererPath *renderer,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GitgWindow *window)
-{
- GitgRevision *rv;
-
- gtk_tree_model_get (model, iter, 0, &rv, -1);
- GtkTreeIter iter1 = *iter;
-
- GitgRevision *next_revision = NULL;
-
- if (gtk_tree_model_iter_next (model, &iter1))
- {
- gtk_tree_model_get (model, &iter1, 0, &next_revision, -1);
- }
-
- GSList *labels;
- const gchar *lbl = NULL;
-
- switch (gitg_revision_get_sign (rv))
- {
- case 't':
- lbl = "staged";
- break;
- case 'u':
- lbl = "unstaged";
- break;
- default:
- break;
- }
-
- if (lbl != NULL)
- {
- g_object_set (renderer, "style", PANGO_STYLE_ITALIC, NULL);
- labels = g_slist_append (NULL,
- gitg_ref_new (gitg_revision_get_hash (rv),
- lbl));
- }
- else
- {
- g_object_set (renderer, "style", PANGO_STYLE_NORMAL, NULL);
- labels = gitg_repository_get_refs_for_hash (GITG_REPOSITORY(model),
- gitg_revision_get_hash (rv));
- }
-
- g_object_set (renderer,
- "revision", rv,
- "next_revision", next_revision,
- "labels", labels,
- NULL);
-
- gitg_revision_unref (next_revision);
- gitg_revision_unref (rv);
-}
-
-static gboolean
-branches_separator_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer data)
-{
- gchar *name;
- GitgRef *ref;
-
- gtk_tree_model_get (model,
- iter,
- COLUMN_BRANCHES_NAME, &name,
- COLUMN_BRANCHES_REF, &ref,
- -1);
-
- gboolean ret = (name == NULL && ref == NULL);
-
- g_free (name);
- gitg_ref_free (ref);
-
- return ret;
-}
-
-static void
-on_branches_combo_changed (GtkComboBox *combo,
- GitgWindow *window)
-{
- if (gtk_combo_box_get_active (combo) < 2)
- {
- return;
- }
-
- GtkTreeIter iter;
- gchar **selection;
-
- gtk_combo_box_get_active_iter (combo, &iter);
-
- gtk_tree_model_get (gtk_combo_box_get_model (combo),
- &iter,
- COLUMN_BRANCHES_SELECTION, &selection,
- -1);
-
- if (selection != NULL)
- {
- gitg_repository_load (window->priv->repository, 1, (gchar const **)selection, NULL);
- g_strfreev (selection);
- }
-}
-
-static void
-build_branches_combo (GitgWindow *window,
- GtkBuilder *builder)
-{
- GtkComboBox *combo;
- window->priv->branches_store = gtk_tree_store_new (4,
- G_TYPE_STRING,
- GITG_TYPE_REF,
- G_TYPE_STRING,
- G_TYPE_STRV);
-
- combo = GTK_COMBO_BOX (gtk_builder_get_object (builder,
- "combo_box_branches"));
-
- window->priv->combo_branches = combo;
-
- GtkTreeIter iter;
- gtk_tree_store_append (window->priv->branches_store, &iter, NULL);
- gtk_tree_store_set (window->priv->branches_store,
- &iter,
- COLUMN_BRANCHES_NAME, _ ("Select branch"),
- COLUMN_BRANCHES_REF, NULL,
- COLUMN_BRANCHES_SELECTION, NULL,
- -1);
-
- gtk_combo_box_set_model (combo, GTK_TREE_MODEL(window->priv->branches_store));
- gtk_combo_box_set_active (combo, 0);
-
- gtk_combo_box_set_row_separator_func (combo,
- branches_separator_func,
- window,
- NULL);
-
- g_signal_connect (combo,
- "changed",
- G_CALLBACK(on_branches_combo_changed),
- window);
-}
-
-static void
-restore_state (GitgWindow *window)
-{
- gint width;
- gint height;
-
- g_settings_get (window->priv->state_settings, "size", "(ii)", &width, &height);
-
- gtk_window_set_default_size (GTK_WINDOW(window),
- width, height);
-
- gitg_utils_restore_pane_position (GTK_PANED(window->priv->vpaned_main),
- g_settings_get_int (window->priv->state_settings,
- "vpaned-main-position"),
- FALSE);
-
- gitg_utils_restore_pane_position (GTK_PANED(window->priv->vpaned_commit),
- g_settings_get_int (window->priv->state_settings,
- "vpaned-commit-position"),
- FALSE);
-
- gitg_utils_restore_pane_position (GTK_PANED(window->priv->hpaned_commit1),
- g_settings_get_int (window->priv->state_settings,
- "hpaned-commit1-position"),
- FALSE);
-
- gitg_utils_restore_pane_position (GTK_PANED(window->priv->hpaned_commit2),
- g_settings_get_int (window->priv->state_settings,
- "hpaned-commit2-position"),
- TRUE);
-}
-
-static void
-update_dnd_status (GitgWindow *window,
- GitgRef *source,
- GitgRef *dest)
-{
- if (!dest)
- {
- gtk_statusbar_push (window->priv->statusbar, 0, "");
- }
- else
- {
- gchar *message = NULL;
- GitgRefType source_type = gitg_ref_get_ref_type (source);
- GitgRefType dest_type = gitg_ref_get_ref_type (dest);
-
- if (source_type == GITG_REF_TYPE_BRANCH &&
- dest_type== GITG_REF_TYPE_REMOTE)
- {
- message = g_strdup_printf (_ ("Push local branch <%s> to remote branch <%s>"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_shortname (dest));
- }
- else if (source_type == GITG_REF_TYPE_BRANCH &&
- dest_type == GITG_REF_TYPE_BRANCH)
- {
- message = g_strdup_printf (_ ("Merge/rebase local branch <%s> with/on local branch <%s>"),
- gitg_ref_get_shortname (source),
- gitg_ref_get_shortname (dest));
- }
- else if (source_type == GITG_REF_TYPE_REMOTE &&
- dest_type == GITG_REF_TYPE_BRANCH)
- {
- message = g_strdup_printf (_ ("Merge/rebase local branch <%s> with/on remote branch <%s>"),
- gitg_ref_get_shortname (dest),
- gitg_ref_get_shortname (source));
- }
- else if (source_type == GITG_REF_TYPE_STASH &&
- dest_type == GITG_REF_TYPE_BRANCH)
- {
- message = g_strdup_printf (_ ("Apply stash to local branch <%s>"),
- gitg_ref_get_shortname (dest));
- }
-
- if (message)
- {
- gtk_statusbar_push (window->priv->statusbar, 0, message);
- }
-
- g_free (message);
- }
-}
-
-static gboolean
-on_refs_dnd (GitgRef *source,
- GitgRef *dest,
- gboolean dropped,
- GitgWindow *window)
-{
- if (!dropped)
- {
- update_dnd_status (window, source, dest);
- return FALSE;
- }
-
- gboolean ret = FALSE;
- GitgRefType source_type = gitg_ref_get_ref_type (source);
- GitgRefType dest_type = gitg_ref_get_ref_type (dest);
-
- if (source_type == GITG_REF_TYPE_BRANCH &&
- dest_type == GITG_REF_TYPE_REMOTE)
- {
- ret = gitg_window_add_branch_action (window,
- gitg_branch_actions_push (window,
- source,
- dest));
- }
- else if (source_type == GITG_REF_TYPE_STASH)
- {
- if (dest_type == GITG_REF_TYPE_BRANCH)
- {
- ret = gitg_branch_actions_apply_stash (window,
- source,
- dest);
- }
- }
- else if (dest_type == GITG_REF_TYPE_BRANCH)
- {
- GtkWidget *popup;
-
- popup = gtk_ui_manager_get_widget (window->priv->menus_ui_manager,
- "/ui/dnd_popup");
-
- window->priv->popup_refs[0] = source;
- window->priv->popup_refs[1] = dest;
-
- gtk_menu_popup (GTK_MENU (popup),
- NULL,
- NULL,
- NULL,
- NULL,
- 1,
- gtk_get_current_event_time ());
- }
-
- gtk_statusbar_push (window->priv->statusbar, 0, "");
- return ret;
-}
-
-static void
-update_revision_dnd_status (GitgWindow *window,
- GitgRevision *source,
- GitgRef *dest)
-{
- if (!dest)
- {
- gtk_statusbar_push (window->priv->statusbar, 0, "");
- }
- else
- {
- gchar *message = g_strdup_printf (_ ("Cherry-pick revision on <%s>"),
- gitg_ref_get_shortname (dest));
-
- gtk_statusbar_push (window->priv->statusbar, 0, message);
- g_free (message);
- }
-}
-
-static gboolean
-on_revision_dnd (GitgRevision *source,
- GitgRef *dest,
- gboolean dropped,
- GitgWindow *window)
-{
- if (!dropped)
- {
- update_revision_dnd_status (window, source, dest);
- return FALSE;
- }
-
- if (gitg_ref_get_ref_type (dest) != GITG_REF_TYPE_BRANCH)
- {
- return FALSE;
- }
-
- return gitg_window_add_branch_action (window,
- gitg_branch_actions_cherry_pick (window, source, dest));
-}
-
-static void
-init_tree_view (GitgWindow *window,
- GtkBuilder *builder)
-{
- GtkTreeViewColumn *col;
-
- col = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (builder,
- "rv_column_subject"));
-
- window->priv->renderer_path = GITG_CELL_RENDERER_PATH (gtk_builder_get_object (builder,
- "rv_renderer_subject"));
-
- gtk_tree_view_column_set_cell_data_func (col,
- GTK_CELL_RENDERER (window->priv->renderer_path),
- (GtkTreeCellDataFunc)on_renderer_path,
- window,
- NULL);
-
- gitg_dnd_enable (window->priv->tree_view,
- (GitgDndCallback)on_refs_dnd,
- (GitgDndRevisionCallback)on_revision_dnd,
- window);
-}
-
-static void
-gitg_window_parser_finished (GtkBuildable *buildable,
- GtkBuilder *builder)
-{
- if (parent_iface.parser_finished)
- parent_iface.parser_finished (buildable, builder);
-
- // Store widgets
- GitgWindow *window = GITG_WINDOW(buildable);
-
- // Insert menu from second ui file
- GtkBuilder *b = gitg_utils_new_builder ("gitg-ui.xml");
- GtkUIManager *uiman = GTK_UI_MANAGER (gtk_builder_get_object (b, "uiman"));
-
- GtkRecentChooser *chooser = GTK_RECENT_CHOOSER(gtk_builder_get_object (b, "RecentOpenAction"));
- GtkRecentFilter *filter = gtk_recent_filter_new ();
- gtk_recent_filter_add_group (filter, "gitg");
-
- gtk_recent_chooser_add_filter (chooser, filter);
- gtk_recent_chooser_set_show_tips (chooser, TRUE);
- gtk_recent_chooser_set_sort_type (chooser, GTK_RECENT_SORT_MRU);
-
- GtkWidget *menu = gtk_ui_manager_get_widget (uiman, "/ui/menubar_main");
- GtkWidget *vbox = GTK_WIDGET(gtk_builder_get_object (builder, "vbox_main"));
-
- gtk_box_pack_start (GTK_BOX(vbox), menu, FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX(vbox), menu, 0);
-
- gtk_window_add_accel_group (GTK_WINDOW (window), gtk_ui_manager_get_accel_group (uiman));
-
- window->priv->edit_group = GTK_ACTION_GROUP(gtk_builder_get_object (b, "action_group_menu_edit"));
- window->priv->repository_group = GTK_ACTION_GROUP(gtk_builder_get_object (b, "action_group_menu_repository"));
-
- gtk_builder_connect_signals (b, window);
- g_object_unref (b);
-
- window->priv->vpaned_main = GTK_WIDGET (gtk_builder_get_object (builder,
- "vpaned_main"));
-
- g_settings_bind (window->priv->view_settings,
- "layout-vertical",
- window->priv->vpaned_main,
- "orientation",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- window->priv->hpaned_commit1 = GTK_WIDGET (gtk_builder_get_object (builder,
- "hpaned_commit1"));
-
- window->priv->hpaned_commit2 = GTK_WIDGET (gtk_builder_get_object (builder,
- "hpaned_commit2"));
-
- window->priv->vpaned_commit = GTK_WIDGET (gtk_builder_get_object (builder,
- "vpaned_commit"));
-
- window->priv->notebook_main = GTK_NOTEBOOK (gtk_builder_get_object (builder,
- "notebook_main"));
-
- window->priv->notebook_revision = GTK_NOTEBOOK (gtk_builder_get_object (builder,
- "notebook_revision"));
-
- window->priv->tree_view = GTK_TREE_VIEW (gtk_builder_get_object (builder,
- "tree_view_rv"));
-
- window->priv->statusbar = GTK_STATUSBAR (gtk_builder_get_object (builder,
- "statusbar"));
-
- window->priv->commit_view = GITG_COMMIT_VIEW (gtk_builder_get_object (builder,
- "vpaned_commit"));
-
- restore_state (window);
-
- init_tree_view (window, builder);
-
- // Intialize branches
- build_branches_combo (window, builder);
-
- // Get menus ui
- b = gitg_utils_new_builder ("gitg-menus.xml");
- window->priv->menus_ui_manager = GTK_UI_MANAGER (g_object_ref (gtk_builder_get_object (b,
- "uiman")));
-
- gtk_builder_connect_signals (b, window);
- g_object_unref (b);
-
- // Create search entry
- build_search_entry (window, builder);
-
- gtk_builder_connect_signals (builder, window);
-
- // Initialize revision panels
- add_revision_panel (window, GITG_TYPE_REVISION_DETAILS_PANEL);
- add_revision_panel (window, GITG_TYPE_REVISION_CHANGES_PANEL);
- add_revision_panel (window, GITG_TYPE_REVISION_FILES_PANEL);
-
- // Connect signals
- GtkTreeSelection *selection = gtk_tree_view_get_selection (window->priv->tree_view);
- g_signal_connect (selection,
- "changed",
- G_CALLBACK(on_selection_changed),
- window);
-
- g_signal_connect (window->priv->tree_view,
- "motion-notify-event",
- G_CALLBACK(on_tree_view_motion),
- window);
-
- g_signal_connect (window->priv->tree_view,
- "button-release-event",
- G_CALLBACK(on_tree_view_button_release),
- window);
-}
-
-static void
-gitg_window_buildable_iface_init (GtkBuildableIface *iface)
-{
- parent_iface = *iface;
-
- iface->parser_finished = gitg_window_parser_finished;
-}
-
-static void
-save_state (GitgWindow *window)
-{
- GtkAllocation allocation;
- gint position;
-
- gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
-
- g_settings_set (window->priv->state_settings, "size", "(ii)",
- allocation.width, allocation.height);
-
- if (gtk_widget_get_mapped (window->priv->vpaned_main))
- {
- position = gtk_paned_get_position (GTK_PANED (window->priv->vpaned_main));
- g_settings_set_int (window->priv->state_settings, "vpaned-main-position",
- position);
- }
-
- if (gtk_widget_get_mapped (window->priv->vpaned_commit))
- {
- position = gtk_paned_get_position (GTK_PANED (window->priv->vpaned_commit));
- g_settings_set_int (window->priv->state_settings, "vpaned-commit-position",
- position);
- }
-
- if (gtk_widget_get_mapped (window->priv->hpaned_commit1))
- {
- position = gtk_paned_get_position (GTK_PANED (window->priv->hpaned_commit1));
- g_settings_set_int (window->priv->state_settings, "hpaned-commit1-position",
- position);
- }
-
- if (gtk_widget_get_mapped (window->priv->hpaned_commit2))
- {
- GtkAllocation alloc;
-
- gtk_widget_get_allocation (GTK_WIDGET (window->priv->hpaned_commit2),
- &alloc);
-
- position = gtk_paned_get_position (GTK_PANED (window->priv->hpaned_commit2));
- g_settings_set_int (window->priv->state_settings, "hpaned-commit2-position",
- alloc.width - position);
- }
-}
-
-static gboolean
-gitg_window_delete_event (GtkWidget *widget,
- GdkEventAny *event)
-{
- save_state (GITG_WINDOW (widget));
-
- if (GTK_WIDGET_CLASS (parent_class)->delete_event)
- {
- return GTK_WIDGET_CLASS (parent_class)->delete_event (widget, event);
- }
- else
- {
- gtk_widget_destroy (widget);
- return TRUE;
- }
-}
-
-static void
-gitg_window_destroy (GtkWidget *widget)
-{
- GitgWindow *window = GITG_WINDOW(widget);
-
- if (!window->priv->destroy_has_run)
- {
- gtk_tree_view_set_model (window->priv->tree_view, NULL);
-
- g_slist_free_full (window->priv->revision_panels, g_object_unref);
- g_slist_free_full (window->priv->activatables, g_object_unref);
-
- window->priv->revision_panels = NULL;
- window->priv->activatables = NULL;
-
- window->priv->destroy_has_run = TRUE;
- }
-
- if (GTK_WIDGET_CLASS(parent_class)->destroy)
- {
- GTK_WIDGET_CLASS(parent_class)->destroy (widget);
- }
-}
-
-static gboolean
-gitg_window_window_state_event (GtkWidget *widget,
- GdkEventWindowState *event)
-{
- GitgWindow *window = GITG_WINDOW(widget);
-
- if (event->changed_mask &
- (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN))
- {
- gboolean show;
-
- show = !(event->new_window_state &
- (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN));
-
- gtk_window_set_has_resize_grip (GTK_WINDOW (window), show);
- }
-
- /* Save the window state */
- g_settings_set_int (window->priv->state_settings, "state", event->new_window_state);
-
- return FALSE;
-}
-
-static void
-gitg_window_set_focus (GtkWindow *wnd,
- GtkWidget *widget)
-{
- GitgWindow *window;
-
- if (GTK_WINDOW_CLASS (gitg_window_parent_class)->set_focus)
- {
- GTK_WINDOW_CLASS (gitg_window_parent_class)->set_focus (wnd, widget);
- }
-
- if (widget == NULL)
- {
- return;
- }
-
- window = GITG_WINDOW (wnd);
-
- gboolean cancopy = g_signal_lookup ("copy-clipboard",
- G_OBJECT_TYPE(widget)) != 0;
- gboolean selection = FALSE;
- gboolean editable = FALSE;
-
- if (GTK_IS_EDITABLE (widget))
- {
- selection = gtk_editable_get_selection_bounds (GTK_EDITABLE (widget),
- NULL,
- NULL);
- editable = gtk_editable_get_editable (GTK_EDITABLE(widget));
- cancopy = cancopy && selection;
- }
-
- gtk_action_set_sensitive (gtk_action_group_get_action (window->priv->edit_group,
- "EditPasteAction"),
- editable);
-
- gtk_action_set_sensitive (gtk_action_group_get_action (window->priv->edit_group,
- "EditCutAction"),
- editable && selection);
- gtk_action_set_sensitive (gtk_action_group_get_action (window->priv->edit_group,
- "EditCopyAction"),
- cancopy);
-}
-
-static void
-gitg_window_class_init (GitgWindowClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GtkWindowClass *window_class = GTK_WINDOW_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->finalize = gitg_window_finalize;
- object_class->dispose = gitg_window_dispose;
-
- widget_class->destroy = gitg_window_destroy;
- widget_class->delete_event = gitg_window_delete_event;
- widget_class->window_state_event = gitg_window_window_state_event;
- window_class->set_focus = gitg_window_set_focus;
-
- g_type_class_add_private (object_class, sizeof (GitgWindowPrivate));
-}
-
-static void
-gitg_window_init (GitgWindow *self)
-{
- self->priv = GITG_WINDOW_GET_PRIVATE(self);
-
- self->priv->load_timer = g_timer_new ();
- self->priv->hand = gdk_cursor_new (GDK_HAND1);
- self->priv->state_settings = g_settings_new ("org.gnome.gitg.state.window");
- self->priv->view_settings = g_settings_new ("org.gnome.gitg.preferences.view.main");
- self->priv->history_settings = g_settings_new ("org.gnome.gitg.preferences.view.history");
- self->priv->hidden_settings = g_settings_new ("org.gnome.gitg.preferences.hidden");
-}
-
-static void
-on_repository_loaded (GitgRepository *repository,
- GitgWindow *window)
-{
- gchar *msg = g_strdup_printf (_ ("Loaded %d revisions in %.2fs"),
- gtk_tree_model_iter_n_children (GTK_TREE_MODEL(window->priv->repository), NULL),
- g_timer_elapsed (window->priv->load_timer, NULL));
-
- gtk_statusbar_push (window->priv->statusbar, 0, msg);
-
- g_free (msg);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window->priv->tree_view)), NULL);
-
- gtk_tree_view_set_model (window->priv->tree_view,
- GTK_TREE_MODEL (window->priv->repository));
-
- GitgHash hash = {0,};
-
- if (memcmp (window->priv->select_on_load, hash, GITG_HASH_BINARY_SIZE) != 0)
- {
- goto_hash (window, window->priv->select_on_load);
- }
-}
-
-static void
-on_update (GitgShell *loader,
- gchar **revisions,
- GitgWindow *window)
-{
- gchar *msg = g_strdup_printf (_ ("Loading %d revisions..."),
- gtk_tree_model_iter_n_children (GTK_TREE_MODEL(window->priv->repository), NULL));
-
- gtk_statusbar_push (window->priv->statusbar, 0, msg);
- g_free (msg);
-}
-
-void
-gitg_window_set_select_on_load (GitgWindow *window,
- gchar const *selection)
-{
- if (!selection || !window->priv->repository)
- {
- return;
- }
-
- gchar *resolved;
-
- resolved = gitg_repository_parse_ref (window->priv->repository,
- selection);
-
- if (resolved && strlen (resolved) == GITG_HASH_SHA_SIZE)
- {
- gitg_hash_sha1_to_hash (resolved, window->priv->select_on_load);
- }
-
- g_free (resolved);
-}
-
-static gboolean
-convert_setting_to_inactive_max (GValue *value,
- GVariant *variant,
- gpointer userdata)
-{
- gint s = g_variant_get_int32 (variant);
- g_value_set_int (value, 2 + s * 8);
-
- return TRUE;
-}
-
-static gboolean
-convert_setting_to_inactive_collapse (GValue *value,
- GVariant *variant,
- gpointer userdata)
-{
- gint s = g_variant_get_int32 (variant);
- g_value_set_int (value, 1 + s * 3);
-
- return TRUE;
-}
-
-static gboolean
-convert_setting_to_inactive_gap (GValue *value,
- GVariant *variant,
- gpointer userdata)
-{
- g_value_set_int (value, 10);
-
- return TRUE;
-}
-
-static void
-bind_repository (GitgWindow *window)
-{
- if (window->priv->repository == NULL)
- return;
-
- g_settings_bind_with_mapping (window->priv->history_settings,
- "collapse-inactive-lanes",
- window->priv->repository,
- "inactive-max",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET,
- convert_setting_to_inactive_max,
- NULL,
- window,
- NULL);
-
- g_settings_bind (window->priv->history_settings,
- "show-virtual-stash",
- window->priv->repository,
- "show-stash",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (window->priv->history_settings,
- "show-virtual-staged",
- window->priv->repository,
- "show-staged",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (window->priv->history_settings,
- "show-virtual-unstaged",
- window->priv->repository,
- "show-unstaged",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind (window->priv->history_settings,
- "topo-order",
- window->priv->repository,
- "topo-order",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-
- g_settings_bind_with_mapping (window->priv->history_settings,
- "collapse-inactive-lanes",
- window->priv->repository,
- "inactive-collapse",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET,
- convert_setting_to_inactive_collapse,
- NULL,
- window,
- NULL);
-
- g_settings_bind_with_mapping (window->priv->history_settings,
- "collapse-inactive-lanes",
- window->priv->repository,
- "inactive-gap",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET,
- convert_setting_to_inactive_gap,
- NULL,
- window,
- NULL);
-
- g_settings_bind (window->priv->history_settings,
- "collapse-inactive-lanes-active",
- window->priv->repository,
- "inactive-enabled",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-}
-
-static gboolean
-create_repository (GitgWindow *window,
- GFile *git_dir,
- GFile *work_tree,
- gchar const *selection)
-{
- window->priv->repository = gitg_repository_new (git_dir, work_tree);
-
- if (!gitg_repository_exists (window->priv->repository))
- {
- g_object_unref (window->priv->repository);
- window->priv->repository = NULL;
- }
- else if (selection)
- {
- gitg_window_set_select_on_load (window, selection);
- }
-
- bind_repository (window);
-
- return window->priv->repository != NULL;
-}
-
-static int
-sort_by_ref_type (GitgRef *a,
- GitgRef *b)
-{
- if (gitg_ref_get_ref_type (a) == gitg_ref_get_ref_type (b))
- {
- if (g_ascii_strcasecmp (gitg_ref_get_shortname (a), "master") == 0)
- {
- return -1;
- }
- else if (g_ascii_strcasecmp (gitg_ref_get_shortname (b), "master") == 0)
- {
- return 1;
- }
- else
- {
- return g_ascii_strcasecmp (gitg_ref_get_shortname (a),
- gitg_ref_get_shortname (b));
- }
- }
- else
- {
- return gitg_ref_get_ref_type (a) - gitg_ref_get_ref_type (b);
- }
-}
-
-static void
-clear_branches_combo (GitgWindow *window)
-{
- GtkTreeIter iter;
-
- if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(window->priv->branches_store), &iter, NULL, 1))
- {
- while (gtk_tree_store_remove (window->priv->branches_store, &iter))
- ;
- }
-
- gtk_combo_box_set_active (window->priv->combo_branches, 0);
-}
-
-static gboolean
-equal_selection (gchar const **s1,
- gchar const **s2)
-{
- if (!s1 || !s2)
- {
- return s1 == s2;
- }
-
- gint i = 0;
-
- while (s1[i] && s2[i])
- {
- if (strcmp (s1[i], s2[i]) != 0)
- {
- return FALSE;
- }
-
- ++i;
- }
-
- return !s1[i] && !s2[i];
-}
-
-static void
-fill_branches_combo (GitgWindow *window)
-{
- if (!window->priv->repository)
- {
- return;
- }
-
- guint children;
-
- children = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (window->priv->branches_store),
- NULL);
-
- if (children > 1)
- {
- return;
- }
-
- GSList *refs = gitg_repository_get_refs (window->priv->repository);
-
- refs = g_slist_sort (refs, (GCompareFunc)sort_by_ref_type);
- GSList *item;
-
- GitgRefType prevtype = GITG_REF_TYPE_NONE;
- GtkTreeIter iter;
- GtkTreeIter parent;
- GitgRef *parentref = NULL;
- GtkTreeStore *store = window->priv->branches_store;
-
- GitgRef *current_ref;
- GitgRef *working_ref;
-
- current_ref = gitg_repository_get_current_ref (window->priv->repository);
- working_ref = gitg_repository_get_current_working_ref (window->priv->repository);
-
- gchar const **current_selection = gitg_repository_get_current_selection (window->priv->repository);
-
- GtkTreeRowReference *active_from_current_ref = NULL;
- GtkTreeRowReference *active_from_selection = NULL;
-
- for (item = refs; item; item = item->next)
- {
- GitgRef *ref = (GitgRef *)item->data;
-
- if (!(gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_REMOTE ||
- gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH))
- {
- continue;
- }
-
- if (gitg_ref_get_ref_type (ref) != prevtype)
- {
- /* Insert separator */
- gtk_tree_store_append (store, &iter, NULL);
- gtk_tree_store_set (store,
- &iter,
- COLUMN_BRANCHES_NAME, NULL,
- COLUMN_BRANCHES_REF, NULL,
- COLUMN_BRANCHES_SELECTION, NULL,
- -1);
-
- prevtype = gitg_ref_get_ref_type (ref);
- }
-
- if (gitg_ref_get_prefix (ref))
- {
- if (!parentref || !gitg_ref_equal_prefix (parentref, ref))
- {
- parentref = ref;
-
- /* Add parent item */
- gtk_tree_store_append (store, &parent, NULL);
- gtk_tree_store_set (store,
- &parent,
- COLUMN_BRANCHES_NAME, gitg_ref_get_prefix (ref),
- COLUMN_BRANCHES_REF, NULL,
- -1);
-
- if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_REMOTE)
- {
- /* Add remote icon */
- gtk_tree_store_set (store,
- &parent,
- COLUMN_BRANCHES_ICON, g_strdup (GTK_STOCK_NETWORK),
- -1);
- }
- }
-
- gtk_tree_store_append (store, &iter, &parent);
- }
- else
- {
- gtk_tree_store_append (store, &iter, NULL);
- }
-
- gchar const *selection[] = {
- gitg_ref_get_name (ref),
- NULL
- };
-
- gtk_tree_store_set (store,
- &iter,
- COLUMN_BRANCHES_NAME, gitg_ref_get_shortname (ref),
- COLUMN_BRANCHES_REF, ref,
- COLUMN_BRANCHES_SELECTION, selection,
- -1);
-
- if (!active_from_current_ref && gitg_ref_equal (current_ref, ref))
- {
- GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
- &iter);
-
- active_from_current_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
- path);
- gtk_tree_path_free (path);
- }
-
- if (!active_from_selection &&
- ((current_selection && equal_selection (selection, current_selection)) ||
- (!current_selection && gitg_ref_equal (ref, working_ref))))
- {
- GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
- &iter);
-
- active_from_selection = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
- path);
- gtk_tree_path_free (path);
- }
- }
-
- /* Separator */
- gtk_tree_store_append (store, &iter, NULL);
- gtk_tree_store_set (store,
- &iter,
- COLUMN_BRANCHES_NAME, NULL,
- COLUMN_BRANCHES_REF, NULL,
- COLUMN_BRANCHES_SELECTION, NULL,
- -1);
-
- gchar const *selection[] = {
- "--branches",
- NULL
- };
-
- gtk_tree_store_append (store, &iter, NULL);
- gtk_tree_store_set (store,
- &iter,
- COLUMN_BRANCHES_NAME, _ ("Local branches"),
- COLUMN_BRANCHES_REF, NULL,
- COLUMN_BRANCHES_SELECTION, selection,
- -1);
-
- if (!active_from_selection &&
- current_selection && equal_selection (selection, current_selection))
- {
- GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
- &iter);
-
- active_from_selection = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
- path);
- gtk_tree_path_free (path);
- }
-
- selection[0] = "--all";
-
- gtk_tree_store_append (store, &iter, NULL);
- gtk_tree_store_set (store,
- &iter,
- COLUMN_BRANCHES_NAME, _ ("All branches"),
- COLUMN_BRANCHES_REF, NULL,
- COLUMN_BRANCHES_SELECTION, selection,
- -1);
-
- if (!active_from_selection &&
- current_selection && equal_selection (selection, current_selection))
- {
- GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
- &iter);
-
- active_from_selection = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
- path);
- gtk_tree_path_free (path);
- }
-
- if (active_from_selection != NULL || active_from_current_ref != NULL)
- {
- GtkTreePath *path;
- GtkTreeIter active;
-
- path = gtk_tree_row_reference_get_path (active_from_selection ? active_from_selection : active_from_current_ref);
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &active, path);
- gtk_combo_box_set_active_iter (window->priv->combo_branches, &active);
- }
-
- g_slist_free_full (refs, (GDestroyNotify)gitg_ref_free);
-
- if (active_from_selection)
- {
- gtk_tree_row_reference_free (active_from_selection);
- }
-
- if (active_from_current_ref)
- {
- gtk_tree_row_reference_free (active_from_current_ref);
- }
-}
-
-static void
-update_window_title (GitgWindow *window)
-{
- if (!window->priv->repository)
- {
- gtk_window_set_title (GTK_WINDOW (window), _ ("gitg"));
- return;
- }
-
- GitgRef *ref = gitg_repository_get_current_working_ref (window->priv->repository);
- gchar *refname = NULL;
-
- if (ref)
- {
- refname = g_strconcat (" (", gitg_ref_get_shortname (ref), ")", NULL);
- }
-
- GFile *work_tree = gitg_repository_get_work_tree (window->priv->repository);
- gchar *basename = g_file_get_basename (work_tree);
- gchar *title = g_strconcat (_ ("gitg"), " - ", basename, refname, NULL);
-
- gtk_window_set_title (GTK_WINDOW (window), title);
-
- g_object_unref (work_tree);
- g_free (basename);
- g_free (title);
- g_free (refname);
-}
-
-static void
-on_repository_load (GitgRepository *repository,
- GitgWindow *window)
-{
- GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window->priv->tree_view)), cursor);
- g_object_unref (cursor);
-
- gtk_statusbar_push (window->priv->statusbar, 0, _ ("Begin loading repository"));
-
- g_timer_reset (window->priv->load_timer);
- g_timer_start (window->priv->load_timer);
-
- g_signal_handlers_block_by_func (window->priv->combo_branches,
- on_branches_combo_changed,
- window);
-
- clear_branches_combo (window);
- fill_branches_combo (window);
-
- g_signal_handlers_unblock_by_func (window->priv->combo_branches,
- on_branches_combo_changed,
- window);
-
- gtk_tree_view_set_model (window->priv->tree_view, NULL);
-
- update_window_title (window);
-}
-
-static void
-add_recent_item (GitgWindow *window)
-{
- GtkRecentManager *manager = gtk_recent_manager_get_default ();
- GtkRecentData data = { 0 };
- gchar *groups[] = {"gitg", NULL};
- GFile *work_tree = gitg_repository_get_work_tree (window->priv->repository);
- gchar *basename = g_file_get_basename (work_tree);
-
- data.display_name = basename;
- data.app_name = "gitg";
- data.mime_type = "inode/directory";
- data.app_exec = "gitg %f";
- data.groups = groups;
-
- gchar *uri = g_file_get_uri (work_tree);
- gtk_recent_manager_add_full (manager, uri, &data);
-
- g_free (basename);
- g_free (uri);
- g_object_unref (work_tree);
-}
-
-static void
-update_sensitivity (GitgWindow *window)
-{
- gboolean sens = window->priv->repository != NULL;
-
- gtk_widget_set_sensitive (GTK_WIDGET (window->priv->notebook_main), sens);
- 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,
- GFile *work_tree,
- gint argc,
- gchar const **argv,
- gchar const *selection)
-{
- if (window->priv->repository)
- {
- gtk_tree_view_set_model (window->priv->tree_view, NULL);
-
- g_signal_handlers_disconnect_by_func (window->priv->repository,
- G_CALLBACK (on_repository_load),
- window);
-
- g_signal_handlers_disconnect_by_func (window->priv->repository,
- G_CALLBACK (on_repository_loaded),
- window);
-
- g_object_unref (window->priv->repository);
- window->priv->repository = NULL;
-
- gitg_repository_dialog_close ();
-
- memset (window->priv->select_on_load, 0, GITG_HASH_BINARY_SIZE);
- }
-
- if ((git_dir || work_tree) &&
- create_repository (window, git_dir, work_tree, selection))
- {
- GitgShell *loader = gitg_repository_get_loader (window->priv->repository);
-
- gitg_window_set_select_on_load (window, selection);
-
- g_signal_connect (loader, "update", G_CALLBACK (on_update), window);
- g_object_unref (loader);
-
- g_signal_connect (window->priv->repository,
- "load",
- G_CALLBACK (on_repository_load),
- window);
-
- g_signal_connect (window->priv->repository,
- "loaded",
- G_CALLBACK (on_repository_loaded),
- window);
-
- clear_branches_combo (window);
-
- gitg_repository_load (window->priv->repository, argc, argv, NULL);
-
- gitg_commit_view_set_repository (window->priv->commit_view,
- window->priv->repository);
-
- add_recent_item (window);
- }
- else
- {
- clear_branches_combo (window);
-
- gitg_commit_view_set_repository (window->priv->commit_view,
- NULL);
-
- update_window_title (window);
- }
-
- update_sensitivity (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,
- GFile *work_tree,
- gint argc,
- gchar const **argv,
- gchar const *selection)
-{
- g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
-
- return load_repository (window,
- git_dir,
- work_tree,
- argc,
- argv,
- selection);
-}
-
-static GFile *
-find_dot_git (GFile *location,
- gboolean *from_first)
-{
- location = g_file_dup (location);
-
- if (from_first)
- {
- *from_first = TRUE;
- }
-
- do
- {
- GFile *tmp;
- gboolean exists;
-
- tmp = g_file_get_child (location, ".git");
- exists = g_file_query_exists (tmp, NULL);
-
- if (exists)
- {
- g_object_unref (location);
- location = tmp;
-
- break;
- }
-
- if (from_first)
- {
- *from_first = FALSE;
- }
-
- g_object_unref (tmp);
-
- tmp = g_file_get_parent (location);
-
- g_object_unref (location);
- location = tmp;
- } while (location != NULL);
-
- return location;
-}
-
-static gboolean
-load_repository_for_command_line (GitgWindow *window,
- gint argc,
- gchar const **argv,
- gchar const *selection)
-{
- gboolean ret = FALSE;
- GFile *git_dir = NULL;
- GFile *work_tree = NULL;
-
- if (argc > 0)
- {
- GFile *first_arg;
- gchar *uri;
- gchar *sel = NULL;
- gchar *work_tree_path = NULL;
- gchar *activatable = NULL;
- gchar *action = NULL;
- gboolean from_first;
-
- first_arg = g_file_new_for_commandline_arg (argv[0]);
- uri = g_file_get_uri (first_arg);
-
- if (!gitg_uri_parse (uri, &work_tree_path, &sel, &activatable, &action))
- {
- git_dir = find_dot_git (first_arg, &from_first);
- }
- else
- {
- work_tree = g_file_new_for_path (work_tree_path);
- }
-
- g_free (uri);
-
- if (git_dir || (work_tree && g_file_query_exists (work_tree, NULL)))
- {
- gint offset;
-
- if (git_dir && !from_first)
- {
- offset = 0;
- }
- else
- {
- offset = 1;
- }
-
- ret = load_repository (window,
- git_dir,
- work_tree,
- argc - offset,
- argv + offset,
- selection ? selection : sel);
-
- if (ret && activatable)
- {
- gitg_window_activate (window, activatable, action);
- }
- }
-
- g_free (sel);
- g_free (activatable);
- g_free (action);
- g_free (work_tree_path);
-
- g_object_unref (first_arg);
- }
-
- if (!ret)
- {
- gchar *cwd = g_get_current_dir ();
-
- GFile *file = g_file_new_for_path (cwd);
- git_dir = find_dot_git (file, NULL);
-
- g_free (cwd);
- g_object_unref (file);
-
- ret = load_repository (window,
- git_dir,
- NULL,
- argc,
- argv,
- selection);
- }
-
- if (git_dir)
- {
- g_object_unref (git_dir);
- }
-
- if (work_tree)
- {
- g_object_unref (work_tree);
- }
-
- return ret;
-}
-
-gboolean
-gitg_window_load_repository_for_command_line (GitgWindow *window,
- gint argc,
- gchar const **argv,
- gchar const *selection)
-{
- gboolean ret;
-
- g_return_val_if_fail (GITG_IS_WINDOW (window), FALSE);
-
- gchar const *git_dir_path = g_getenv ("GIT_DIR");
- gchar const *work_tree_path = g_getenv ("GIT_WORK_TREE");
-
- if (!git_dir_path && !work_tree_path)
- {
- return load_repository_for_command_line (window, argc, argv, selection);
- }
-
- GFile *git_dir = NULL;
- GFile *work_tree = NULL;
-
- if (git_dir_path)
- {
- git_dir = g_file_new_for_commandline_arg (git_dir_path);
- }
-
- if (work_tree_path)
- {
- work_tree = g_file_new_for_commandline_arg (work_tree_path);
- }
-
- ret = gitg_window_load_repository (window,
- git_dir,
- work_tree,
- argc,
- argv,
- selection);
-
- if (git_dir)
- {
- g_object_unref (git_dir);
- }
-
- if (work_tree)
- {
- g_object_unref (work_tree);
- }
-
- return ret;
-}
-
-void
-gitg_window_show_commit (GitgWindow *window)
-{
- g_return_if_fail (GITG_IS_WINDOW(window));
-
- gtk_notebook_set_current_page (window->priv->notebook_main, 1);
-}
-
-GitgRepository *
-gitg_window_get_repository (GitgWindow *window)
-{
- g_return_val_if_fail (GITG_IS_WINDOW(window), NULL);
-
- return window->priv->repository;
-}
-
-void
-on_file_quit (GtkAction *action,
- GitgWindow *window)
-{
- gtk_main_quit ();
-}
-
-static void
-on_open_dialog_response (GtkFileChooser *dialog,
- gint response,
- GitgWindow *window)
-{
- if (response != GTK_RESPONSE_ACCEPT)
- {
- gtk_widget_destroy (GTK_WIDGET(dialog));
-
- return;
- }
-
- GFile *file = gtk_file_chooser_get_file (dialog);
- gtk_widget_destroy (GTK_WIDGET(dialog));
-
- load_repository (window, NULL, file, 0, NULL, NULL);
- g_object_unref (file);
-}
-
-void
-on_file_open (GtkAction *action,
- GitgWindow *window)
-{
- if (window->priv->open_dialog)
- {
- gtk_window_present (GTK_WINDOW(window->priv->open_dialog));
- return;
- }
-
- window->priv->open_dialog = gtk_file_chooser_dialog_new (_ ("Open git repository"),
- GTK_WINDOW (window),
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN,
- GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(window->priv->open_dialog), TRUE);
- g_object_add_weak_pointer (G_OBJECT(window->priv->open_dialog), (gpointer *)&(window->priv->open_dialog));
- gtk_window_present (GTK_WINDOW(window->priv->open_dialog));
-
- g_signal_connect (window->priv->open_dialog, "response", G_CALLBACK(on_open_dialog_response), window);
-}
-
-void
-on_edit_copy (GtkAction *action,
- GitgWindow *window)
-{
- GtkWidget *focus = gtk_window_get_focus (GTK_WINDOW (window));
-
- g_signal_emit_by_name (focus, "copy-clipboard", 0);
-}
-
-void
-on_edit_cut (GtkAction *action,
- GitgWindow *window)
-{
- GtkWidget *focus = gtk_window_get_focus (GTK_WINDOW (window));
-
- g_signal_emit_by_name (focus, "cut-clipboard", 0);
-}
-
-void
-on_edit_paste (GtkAction *action,
- GitgWindow *window)
-{
- GtkWidget *focus = gtk_window_get_focus (GTK_WINDOW (window));
-
- g_signal_emit_by_name (focus, "paste-clipboard", 0);
-}
-
-void
-on_view_refresh (GtkAction *action,
- GitgWindow *window)
-{
- if (window->priv->repository &&
- gitg_repository_exists (window->priv->repository))
- {
- gitg_repository_reload (window->priv->repository);
- }
-}
-
-void
-on_recent_open (GtkRecentChooser *chooser,
- GitgWindow *window)
-{
- gchar *uri = gtk_recent_chooser_get_current_uri (chooser);
- GFile *work_tree = g_file_new_for_uri (uri);
- g_free (uri);
-
- load_repository (window, NULL, work_tree, 0, NULL, NULL);
-
- g_object_unref (work_tree);
-}
-
-void
-on_help_about (GtkAction *action,
- GitgWindow *window)
-{
- static gchar const copyright[] = "Copyright \xc2\xa9 2009 Jesse van den Kieboom";
- static gchar const *authors[] = {"Jesse van den Kieboom <jessevdk@gnome.org>", NULL};
- static gchar const *comments = N_ ("gitg is a git repository viewer for gtk+/GNOME");
-
-
- gchar *path = gitg_dirs_get_data_filename ("icons", "gitg.svg", NULL);
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (path, NULL);
- g_free (path);
-
- if (!pixbuf)
- {
- path = gitg_dirs_get_data_filename ("icons", "gitg128x128.png", NULL);
- pixbuf = gdk_pixbuf_new_from_file (path, NULL);
- g_free (path);
- }
-
- gtk_show_about_dialog (GTK_WINDOW(window),
- "authors", authors,
- "copyright", copyright,
- "comments", _ (comments),
- "version", VERSION,
- "website", PACKAGE_URL,
- "website-label", "gitg homepage",
- "logo", pixbuf,
- "license-type", GTK_LICENSE_GPL_2_0,
- NULL);
-
- if (pixbuf)
- {
- g_object_unref (pixbuf);
- }
-}
-
-static gboolean
-find_lane_boundary (GitgWindow *window,
- GtkTreePath *path,
- gint cell_x,
- gchar const **hash)
-{
- GtkTreeModel *model = GTK_TREE_MODEL(window->priv->repository);
- GtkTreeIter iter;
- guint width;
- GitgRevision *revision;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, 0, &revision, -1);
-
- /* Determine lane at cell_x */
- g_object_get (window->priv->renderer_path, "lane-width", &width, NULL);
- guint laneidx = cell_x / width;
-
- GSList *lanes = gitg_revision_get_lanes (revision);
- GitgLane *lane = (GitgLane *)g_slist_nth_data (lanes, laneidx);
- gboolean ret;
-
- if (lane && GITG_IS_LANE_BOUNDARY(lane))
- {
- if (hash)
- *hash = ((GitgLaneBoundary *)lane)->hash;
-
- ret = TRUE;
- }
- else
- {
- ret = FALSE;
- }
-
- gitg_revision_unref (revision);
- return ret;
-}
-
-static gboolean
-is_boundary_from_event (GitgWindow *window,
- GdkEventAny *event,
- gint x,
- gint y,
- gchar const **hash)
-{
- GtkTreePath *path;
- GtkTreeViewColumn *column;
- gint cell_x;
- gint cell_y;
-
- if (event->window != gtk_tree_view_get_bin_window (window->priv->tree_view))
- return FALSE;
-
- gtk_tree_view_get_path_at_pos (window->priv->tree_view,
- x,
- y,
- &path,
- &column,
- &cell_x,
- &cell_y);
-
- if (!path)
- return FALSE;
-
- /* First check on correct column */
- if (gtk_tree_view_get_column (window->priv->tree_view, 0) != column)
- {
- if (path)
- gtk_tree_path_free (path);
-
- return FALSE;
- }
-
- /* Check for lanes that have TYPE_END or TYPE_START and where the mouse
- is actually placed */
- gboolean ret = find_lane_boundary (window, path, cell_x, hash);
- gtk_tree_path_free (path);
-
- return ret;
-}
-
-static gboolean
-on_tree_view_motion (GtkTreeView *treeview,
- GdkEventMotion *event,
- GitgWindow *window)
-{
- GdkWindow *win;
-
- win = gtk_widget_get_window (GTK_WIDGET (treeview));
-
- if (is_boundary_from_event (window, (GdkEventAny *)event, event->x, event->y, NULL))
- {
- gdk_window_set_cursor (win, window->priv->hand);
- }
- else
- {
- gdk_window_set_cursor (win, NULL);
- }
-
- return FALSE;
-}
-
-static gboolean
-on_tree_view_button_release (GtkTreeView *treeview,
- GdkEventButton *event,
- GitgWindow *window)
-{
- if (event->button != 1)
- {
- return FALSE;
- }
-
- gchar const *hash;
-
- if (!is_boundary_from_event (window,
- (GdkEventAny *)event,
- event->x,
- event->y,
- &hash))
- {
- return FALSE;
- }
-
- goto_hash (window, hash);
- return TRUE;
-}
-
-void
-on_edit_preferences (GtkAction *action,
- GitgWindow *window)
-{
- gitg_preferences_dialog_present (GTK_WINDOW(window));
-}
-
-void
-on_repository_properties (GtkAction *action,
- GitgWindow *window)
-{
- gitg_repository_dialog_present (window);
-}
-
-static void
-on_push_activated (GtkAction *action,
- GitgWindow *window)
-{
- gchar const *remote = g_object_get_data (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_REMOTE_KEY);
- gchar const *branch = g_object_get_data (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_BRANCH_KEY);
-
- gitg_window_add_branch_action (window,
- gitg_branch_actions_push_remote (window, window->priv->popup_refs[0], remote, branch));
-}
-
-static void
-on_rebase_activated (GtkAction *action,
- GitgWindow *window)
-{
- GitgRef *dest = g_object_get_data (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_KEY);
-
- gitg_window_add_branch_action (window,
- gitg_branch_actions_rebase (window,
- window->priv->popup_refs[0],
- dest));
-}
-
-static void
-on_merge_activated (GtkAction *action,
- GitgWindow *window)
-{
- GitgRef *dest = g_object_get_data (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_KEY);
-
- gitg_window_add_branch_action (window,
- gitg_branch_actions_merge (window,
- dest,
- window->priv->popup_refs[0]));
-}
-
-static void
-on_stash_activated (GtkAction *action,
- GitgWindow *window)
-{
- GitgRef *dest = g_object_get_data (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_KEY);
-
- gitg_branch_actions_apply_stash (window, window->priv->popup_refs[0], dest);
-}
-
-static void
-get_tracked_ref (GitgWindow *window,
- GitgRef *branch,
- gchar **retremote,
- gchar **retbranch)
-{
- GitgConfig *config = gitg_config_new (window->priv->repository);
- gchar *merge;
- gchar *var;
-
- var = g_strconcat ("branch.", gitg_ref_get_shortname (branch), ".remote", NULL);
- *retremote = gitg_config_get_value (config, var);
- g_free (var);
-
- if (!*retremote || !**retremote)
- {
- g_free (*retremote);
- *retremote = NULL;
-
- g_object_unref (config);
-
- return;
- }
-
- var = g_strconcat ("branch.", gitg_ref_get_shortname (branch), ".merge", NULL);
- merge = gitg_config_get_value (config, var);
- g_free (var);
-
- g_object_unref (config);
-
- if (merge && g_str_has_prefix (merge, "refs/heads"))
- {
- *retbranch = g_strdup (merge + 11);
- }
- else
- {
- *retbranch = NULL;
- }
-
- g_free (merge);
-}
-
-static gboolean
-repository_has_ref (GitgWindow *window,
- gchar const *remote,
- gchar const *branch)
-{
- GSList *refs = gitg_repository_get_refs (window->priv->repository);
- gchar *combined = g_strconcat (remote, "/", branch, NULL);
-
- while (refs)
- {
- GitgRef *r = (GitgRef *)refs->data;
-
- if (gitg_ref_get_ref_type (r) == GITG_REF_TYPE_REMOTE &&
- strcmp (gitg_ref_get_shortname (r), combined) == 0)
- {
- g_free (combined);
- return TRUE;
- }
-
- refs = g_slist_next (refs);
- }
-
- g_free (combined);
- return FALSE;
-}
-
-static void
-add_push_action (GitgWindow *window,
- GtkActionGroup *group,
- gchar const *remote,
- gchar const *branch)
-{
- gchar *acname = g_strconcat ("Push", remote, branch, "Action", NULL);
- gchar *name;
-
- if (gtk_action_group_get_action (group, acname) != NULL)
- {
- /* No need for twice the same */
- g_free (acname);
- return;
- }
-
- if (repository_has_ref (window, remote, branch))
- {
- name = g_strconcat (remote, "/", branch, NULL);
- }
- else
- {
- name = g_strconcat (remote, "/", branch, " (", _ ("new"), ")", NULL);
- }
-
- GtkAction *pushac = gtk_action_new (acname, name, NULL, NULL);
- gtk_action_group_add_action (group, pushac);
-
- gchar *nm = g_strconcat ("Push", remote, branch, NULL);
- gtk_ui_manager_add_ui (window->priv->menus_ui_manager,
- window->priv->merge_rebase_uid,
- "/ui/ref_popup/Push/Placeholder",
- nm,
- acname,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
-
- g_object_set_data_full (G_OBJECT (pushac),
- DYNAMIC_ACTION_DATA_REMOTE_KEY,
- g_strdup (remote),
- (GDestroyNotify)g_free);
-
- g_object_set_data_full (G_OBJECT (pushac),
- DYNAMIC_ACTION_DATA_BRANCH_KEY,
- g_strdup (branch),
- (GDestroyNotify)g_free);
-
- g_signal_connect (pushac,
- "activate",
- G_CALLBACK (on_push_activated),
- window);
-
- g_free (acname);
- g_free (name);
- g_free (nm);
-}
-
-static void
-update_merge_rebase (GitgWindow *window,
- GitgRef *ref)
-{
- if (window->priv->merge_rebase_uid != 0)
- {
- gtk_ui_manager_remove_ui (window->priv->menus_ui_manager,
- window->priv->merge_rebase_uid);
- }
-
- GtkActionGroup *ac = window->priv->merge_rebase_action_group;
-
- if (ac)
- {
- GList *actions = gtk_action_group_list_actions (ac);
- GList *item;
-
- for (item = actions; item; item = g_list_next (item))
- {
- gtk_action_group_remove_action (ac, (GtkAction *)item->data);
- }
-
- g_list_free (actions);
- }
-
- if (gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_BRANCH &&
- gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_STASH)
- {
- return;
- }
-
- if (window->priv->merge_rebase_uid == 0)
- {
- window->priv->merge_rebase_uid = gtk_ui_manager_new_merge_id (window->priv->menus_ui_manager);
- }
-
- if (ac == NULL)
- {
- ac = gtk_action_group_new ("GitgMergeRebaseActions");
- window->priv->merge_rebase_action_group = ac;
- gtk_ui_manager_insert_action_group (window->priv->menus_ui_manager,
- ac,
- 0);
- }
-
- GSList *refs = gitg_repository_get_refs (window->priv->repository);
- GSList *item;
-
- for (item = refs; item; item = g_slist_next (item))
- {
- GitgRef *r = GITG_REF (item->data);
-
- if (gitg_ref_get_ref_type (r) == GITG_REF_TYPE_BRANCH && !gitg_ref_equal (r, ref))
- {
- gchar const *rname = gitg_ref_get_shortname (r);
-
- if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH)
- {
- gchar *rebase = g_strconcat ("Rebase", rname, "Action", NULL);
- gchar *merge = g_strconcat ("Merge", rname, "Action", NULL);
-
- GtkAction *rebaseac = gtk_action_new (rebase, rname, NULL, NULL);
- GtkAction *mergeac = gtk_action_new (merge, rname, NULL, NULL);
-
- g_object_set_data_full (G_OBJECT (rebaseac),
- DYNAMIC_ACTION_DATA_KEY,
- gitg_ref_copy (r),
- (GDestroyNotify)gitg_ref_free);
- g_object_set_data_full (G_OBJECT (mergeac),
- DYNAMIC_ACTION_DATA_KEY,
- gitg_ref_copy (r),
- (GDestroyNotify)gitg_ref_free);
-
- g_signal_connect (rebaseac,
- "activate",
- G_CALLBACK (on_rebase_activated),
- window);
- g_signal_connect (mergeac,
- "activate",
- G_CALLBACK (on_merge_activated),
- window);
-
- gtk_action_group_add_action (ac, rebaseac);
- gtk_action_group_add_action (ac, mergeac);
-
- gchar *name = g_strconcat ("Rebase", rname, NULL);
-
- gtk_ui_manager_add_ui (window->priv->menus_ui_manager,
- window->priv->merge_rebase_uid,
- "/ui/ref_popup/Rebase/Placeholder",
- name,
- rebase,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
- g_free (name);
-
- name = g_strconcat ("Merge", rname, NULL);
-
- gtk_ui_manager_add_ui (window->priv->menus_ui_manager,
- window->priv->merge_rebase_uid,
- "/ui/ref_popup/Merge/Placeholder",
- name,
- merge,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
- g_free (name);
-
- g_object_unref (rebaseac);
- g_object_unref (mergeac);
-
- g_free (rebase);
- g_free (merge);
- }
- else
- {
- gchar *stash = g_strconcat ("Stash", rname, "Action", NULL);
-
- GtkAction *stashac = gtk_action_new (stash, rname, NULL, NULL);
-
- g_object_set_data_full (G_OBJECT (stashac),
- DYNAMIC_ACTION_DATA_KEY,
- gitg_ref_copy (r),
- (GDestroyNotify)gitg_ref_free);
-
- g_signal_connect (stashac,
- "activate",
- G_CALLBACK (on_stash_activated),
- window);
-
- gtk_action_group_add_action (ac, stashac);
-
- gchar *name = g_strconcat ("Stash", rname, NULL);
-
- gtk_ui_manager_add_ui (window->priv->menus_ui_manager,
- window->priv->merge_rebase_uid,
- "/ui/ref_popup/Stash/Placeholder",
- name,
- stash,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
- g_free (name);
-
- g_object_unref (stashac);
- }
- }
- }
-
- g_slist_free_full (refs, (GDestroyNotify)gitg_ref_free);
-
- if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH)
- {
- /* Get the tracked remote of this ref (if any) */
- gchar *remote = NULL;
- gchar *branch = NULL;
-
- get_tracked_ref (window, ref, &remote, &branch);
-
- if (remote)
- {
- add_push_action (window,
- ac,
- remote,
- branch ? branch : gitg_ref_get_shortname (ref));
-
- g_free (remote);
- g_free (branch);
- }
-
- GSList const *ref_pushes = gitg_repository_get_ref_pushes (window->priv->repository,
- ref);
-
- /* Get configured ref pushes */
- while (ref_pushes)
- {
- GitgRef *push_ref = ref_pushes->data;
-
- add_push_action (window,
- ac,
- gitg_ref_get_prefix (push_ref),
- gitg_ref_get_local_name (push_ref));
-
- ref_pushes = g_slist_next (ref_pushes);
- }
-
- gchar **remotes = gitg_repository_get_remotes (window->priv->repository);
- gchar **ptr = remotes;
-
- while (*ptr)
- {
- add_push_action (window,
- ac,
- *ptr,
- gitg_ref_get_shortname (ref));
-
- ++ptr;
- }
-
- g_strfreev (remotes);
- }
-
- gtk_ui_manager_ensure_update (window->priv->menus_ui_manager);
-}
-
-static gboolean
-has_local_ref (GitgWindow *window,
- gchar const *name)
-{
- GSList *refs = gitg_repository_get_refs (window->priv->repository);
- GSList *item;
- gboolean ret = FALSE;
-
- for (item = refs; item; item = g_slist_next (item))
- {
- GitgRef *ref = GITG_REF (item->data);
-
- if (gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_BRANCH)
- {
- continue;
- }
-
- gchar const *nm = gitg_ref_get_shortname (ref);
-
- if (g_strcmp0 (name, nm) == 0)
- {
- ret = TRUE;
- break;
- }
- }
-
- g_slist_free_full (refs, (GDestroyNotify)gitg_ref_free);
-
- return ret;
-}
-
-static gboolean
-popup_ref (GitgWindow *window,
- GdkEventButton *event)
-{
- gint cell_x;
- gint cell_y;
- GtkTreePath *path;
- GtkTreeViewColumn *column;
-
- GtkTreeView *tree_view = window->priv->tree_view;
-
- if (!gtk_tree_view_get_path_at_pos (tree_view,
- (gint)event->x,
- (gint)event->y,
- &path,
- &column,
- &cell_x,
- &cell_y))
- {
- return FALSE;
- }
-
- GtkCellRenderer *cell = gitg_utils_find_cell_at_pos (tree_view, column, path, cell_x);
-
- if (!cell || !GITG_IS_CELL_RENDERER_PATH (cell))
- {
- return FALSE;
- }
-
- GitgRef *ref = gitg_cell_renderer_path_get_ref_at_pos (GTK_WIDGET (tree_view),
- GITG_CELL_RENDERER_PATH (cell),
- cell_x,
- NULL);
- gtk_tree_path_free (path);
-
- if (!ref || (gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_BRANCH &&
- gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_REMOTE &&
- gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_STASH &&
- gitg_ref_get_ref_type (ref) != GITG_REF_TYPE_TAG))
- {
- return FALSE;
- }
-
- GtkWidget *popup = gtk_ui_manager_get_widget (window->priv->menus_ui_manager,
- "/ui/ref_popup");
-
- GtkAction *checkout = gtk_ui_manager_get_action (window->priv->menus_ui_manager,
- "/ui/ref_popup/CheckoutAction");
- GtkAction *remove = gtk_ui_manager_get_action (window->priv->menus_ui_manager,
- "/ui/ref_popup/RemoveAction");
- GtkAction *rename = gtk_ui_manager_get_action (window->priv->menus_ui_manager,
- "/ui/ref_popup/RenameAction");
-
- if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_REMOTE)
- {
- gchar const *local = gitg_ref_get_local_name (ref);
-
- if (!has_local_ref (window, local))
- {
- gchar *label = g_strdup_printf (_ ("New local branch <%s>"), local);
-
- g_object_set (checkout, "label", label, NULL);
- gtk_action_set_visible (checkout, TRUE);
- g_free (label);
- }
- else
- {
- gtk_action_set_visible (checkout, FALSE);
- }
-
- g_object_set (remove, "label", _ ("Remove remote branch"), NULL);
- gtk_action_set_visible (rename, FALSE);
- }
- else if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH)
- {
- g_object_set (checkout, "label", _ ("Checkout working copy"), NULL);
- g_object_set (remove, "label", _ ("Remove local branch"), NULL);
- gtk_action_set_visible (rename, TRUE);
- g_object_set (rename, "label", _ ("Rename local branch"), NULL);
-
- GitgRef *working = gitg_repository_get_current_working_ref (window->priv->repository);
-
- gtk_action_set_visible (checkout, !gitg_ref_equal (working, ref));
- }
- else if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_STASH)
- {
- g_object_set (remove, "label", _ ("Remove stash"), NULL);
- gtk_action_set_visible (rename, FALSE);
- gtk_action_set_visible (checkout, FALSE);
- }
- else if (gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_TAG)
- {
- g_object_set (remove, "label", _ ("Remove tag"), NULL);
- gtk_action_set_visible (rename, FALSE);
-
- if (!has_local_ref (window, gitg_ref_get_shortname (ref)))
- {
- gchar *label = g_strdup_printf (_ ("New local branch <%s>"), gitg_ref_get_shortname (ref));
-
- g_object_set (checkout, "label", label, NULL);
- gtk_action_set_visible (checkout, TRUE);
- g_free (label);
- }
- else
- {
- gtk_action_set_visible (checkout, FALSE);
- }
- }
-
- update_merge_rebase (window, ref);
- window->priv->popup_refs[0] = ref;
-
- gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, window, event->button, event->time);
- return TRUE;
-}
-
-static gboolean
-consecutive_revisions (GitgWindow *window,
- GList *rows)
-{
- return FALSE;
-}
-
-static void
-on_cherry_pick_activated (GtkAction *action,
- GitgWindow *window)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (window->priv->tree_view);
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- if (!rows || rows->next)
- {
- return;
- }
-
- GtkTreeIter iter;
- GitgRevision *rev;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
- gtk_tree_model_get (model, &iter, 0, &rev, -1);
-
- GitgRef *ref = g_object_get_data (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_KEY);
-
- gitg_window_add_branch_action (window,
- gitg_branch_actions_cherry_pick (window,
- rev,
- ref));
-
- gitg_revision_unref (rev);
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-}
-
-static void
-update_cherry_pick (GitgWindow *window)
-{
- if (window->priv->cherry_pick_uid != 0)
- {
- gtk_ui_manager_remove_ui (window->priv->menus_ui_manager,
- window->priv->cherry_pick_uid);
- }
-
- GtkActionGroup *ac = window->priv->cherry_pick_action_group;
-
- if (ac)
- {
- GList *actions = gtk_action_group_list_actions (ac);
- GList *item;
-
- for (item = actions; item; item = g_list_next (item))
- {
- gtk_action_group_remove_action (ac, (GtkAction *)item->data);
- }
-
- g_list_free (actions);
- }
-
- if (window->priv->cherry_pick_uid == 0)
- {
- window->priv->cherry_pick_uid = gtk_ui_manager_new_merge_id (window->priv->menus_ui_manager);
- }
-
- if (ac == NULL)
- {
- ac = gtk_action_group_new ("GitgCherryPickActions");
-
- window->priv->cherry_pick_action_group = ac;
-
- gtk_ui_manager_insert_action_group (window->priv->menus_ui_manager,
- ac,
- 0);
- }
-
- GSList *refs = gitg_repository_get_refs (window->priv->repository);
- GSList *item;
-
- for (item = refs; item; item = g_slist_next (item))
- {
- GitgRef *r = GITG_REF (item->data);
-
- if (gitg_ref_get_ref_type (r) == GITG_REF_TYPE_BRANCH)
- {
- gchar const *rname = gitg_ref_get_shortname (r);
- gchar *acname = g_strconcat ("CherryPick", rname, "Action", NULL);
-
- GtkAction *action = gtk_action_new (acname, rname, NULL, NULL);
-
- g_object_set_data_full (G_OBJECT (action),
- DYNAMIC_ACTION_DATA_KEY,
- gitg_ref_copy (r),
- (GDestroyNotify)gitg_ref_free);
-
- g_signal_connect (action,
- "activate",
- G_CALLBACK (on_cherry_pick_activated),
- window);
-
- gtk_action_group_add_action (ac, action);
-
- gchar *name = g_strconcat ("CherryPick", rname, NULL);
-
- gtk_ui_manager_add_ui (window->priv->menus_ui_manager,
- window->priv->cherry_pick_uid,
- "/ui/revision_popup/CherryPick/Placeholder",
- name,
- acname,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
- g_free (name);
-
- g_object_unref (action);
- g_free (acname);
- }
- }
-
- g_slist_free_full (refs, (GDestroyNotify)gitg_ref_free);
-}
-
-static gboolean
-popup_revision (GitgWindow *window,
- GdkEventButton *event)
-{
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (window->priv->tree_view);
- GList *rows = gtk_tree_selection_get_selected_rows (selection, NULL);
-
- if (!rows)
- {
- return FALSE;
- }
-
- gboolean show = FALSE;
-
- update_cherry_pick (window);
-
- GtkAction *tag;
-
- tag = gtk_ui_manager_get_action (window->priv->menus_ui_manager,
- "/ui/revision_popup/TagAction");
-
- GtkAction *squash;
-
- squash = gtk_ui_manager_get_action (window->priv->menus_ui_manager,
- "/ui/revision_popup/SquashAction");
-
- if (!rows->next)
- {
- GtkTreeModel *model;
- GtkTreeIter iter;
- GitgRevision *rev;
- gchar sign;
-
- model = GTK_TREE_MODEL (window->priv->repository);
- gtk_tree_model_get_iter (model, &iter, rows->data);
-
- gtk_tree_model_get (model, &iter, 0, &rev, -1);
-
- sign = gitg_revision_get_sign (rev);
- gitg_revision_unref (rev);
-
- if (sign)
- {
- show = FALSE;
- }
- else
- {
- show = TRUE;
-
- gtk_action_set_visible (squash, FALSE);
- gtk_action_set_visible (tag, TRUE);
- }
- }
- else if (consecutive_revisions (window, rows))
- {
- show = TRUE;
-
- gtk_action_set_visible (squash, TRUE);
- gtk_action_set_visible (tag, FALSE);
- }
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-
- if (!show)
- {
- return FALSE;
- }
-
- gtk_menu_popup (GTK_MENU (gtk_ui_manager_get_widget (window->priv->menus_ui_manager, "/ui/revision_popup")),
- NULL,
- NULL,
- NULL,
- window,
- event->button,
- event->time);
-
- return TRUE;
-}
-
-void
-on_tree_view_rv_button_press_event (GtkWidget *widget,
- GdkEvent *event,
- GitgWindow *window)
-{
- if (event->type == GDK_BUTTON_PRESS)
- {
- GdkEventButton *button = (GdkEventButton *)event;
-
- if (button->button == 3)
- {
- if (!popup_ref (window, button))
- {
- popup_revision (window, button);
- }
- }
- }
-}
-
-void
-on_checkout_branch_action_activate (GtkAction *action,
- GitgWindow *window)
-{
- if (gitg_branch_actions_checkout (window, window->priv->popup_refs[0]))
- {
- update_window_title (window);
- }
-}
-
-void
-on_remove_branch_action_activate (GtkAction *action,
- GitgWindow *window)
-{
- gitg_branch_actions_remove (window, window->priv->popup_refs[0]);
-}
-
-void
-on_rename_branch_action_activate (GtkAction *action,
- GitgWindow *window)
-{
- gitg_branch_actions_rename (window, window->priv->popup_refs[0]);
-}
-
-void
-on_rebase_branch_action_activate (GtkAction *action,
- GitgWindow *window)
-{
- gint source;
-
- if (gitg_ref_get_ref_type (window->priv->popup_refs[0]) == GITG_REF_TYPE_REMOTE)
- {
- source = 1;
- }
- else
- {
- source = 0;
- }
-
- gitg_window_add_branch_action (window,
- gitg_branch_actions_rebase (window,
- window->priv->popup_refs[source],
- window->priv->popup_refs[!source]));
-}
-
-void
-on_merge_branch_action_activate (GtkAction *action,
- GitgWindow *window)
-{
- gitg_window_add_branch_action (window,
- gitg_branch_actions_merge (window,
- window->priv->popup_refs[0],
- window->priv->popup_refs[1]));
-}
-
-typedef struct
-{
- GtkBuilder *builder;
- GitgWindow *window;
- GitgRevision *revision;
-} TagInfo;
-
-static void
-free_tag_info (TagInfo *info)
-{
- g_object_unref (info->builder);
- gitg_revision_unref (info->revision);
-
- g_slice_free (TagInfo, info);
-}
-
-static void
-on_new_branch_dialog_response (GtkWidget *dialog,
- gint response,
- TagInfo *info)
-{
- gboolean destroy = TRUE;
-
- if (response == GTK_RESPONSE_ACCEPT)
- {
- gchar const *name = gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (info->builder, "entry_name")));
-
- if (*name)
- {
- gchar *sha1 = gitg_revision_get_sha1 (info->revision);
-
- if (!gitg_branch_actions_create (info->window, sha1, name))
- {
- destroy = FALSE;
- }
-
- g_free (sha1);
- }
- else
- {
- GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (dialog),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _ ("Not all fields are correctly filled in"));
-
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
- "%s",
- _("Please make sure to fill in the branch name"));
-
- g_signal_connect (dlg, "response", G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_widget_show (dlg);
-
- destroy = FALSE;
- }
- }
-
- if (destroy)
- {
- free_tag_info (info);
- gtk_widget_destroy (dialog);
- }
-}
-
-static void
-on_tag_dialog_response (GtkWidget *dialog,
- gint response,
- TagInfo *info)
-{
- gboolean destroy = TRUE;
-
- if (response == GTK_RESPONSE_ACCEPT)
- {
- gchar const *name = gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (info->builder, "entry_name")));
- gboolean sign = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (info->builder, "check_button_sign")));
-
- GtkTextView *view = GTK_TEXT_VIEW (gtk_builder_get_object (info->builder, "text_view_message"));
- GtkTextIter start;
- GtkTextIter end;
-
- gtk_text_buffer_get_bounds (gtk_text_view_get_buffer (view), &start, &end);
- gchar *message = gtk_text_iter_get_text (&start, &end);
-
- const gchar *secondary_text = NULL;
-
- if (sign && (!*name || !*message))
- {
- secondary_text = _ ("Please make sure to fill in both the tag name and the commit message");
- }
- else if (!sign && !*name)
- {
- secondary_text = _ ("Please make sure to fill in the tag name");
- }
-
- if (secondary_text)
- {
- GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (dialog),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _ ("Not all fields are correctly filled in"));
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
- "%s",
- secondary_text);
-
- g_signal_connect (dlg, "response", G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_widget_show (dlg);
-
- destroy = FALSE;
- }
- else
- {
- gchar *sha1 = gitg_revision_get_sha1 (info->revision);
- if (!gitg_branch_actions_tag (info->window,
- sha1,
- name,
- message,
- sign))
- {
- destroy = FALSE;
- }
-
- g_free (sha1);
-
- g_settings_set_boolean (info->window->priv->hidden_settings,
- "sign-tag", sign);
- }
-
- g_free (message);
- }
-
- if (destroy)
- {
- free_tag_info (info);
- gtk_widget_destroy (dialog);
- }
-}
-
-typedef struct
-{
- GitgWindow *window;
- GList *revisions;
-} FormatPatchInfo;
-
-static void
-on_format_patch_response (GtkDialog *dialog,
- gint response,
- FormatPatchInfo *info)
-{
- if (response == GTK_RESPONSE_ACCEPT)
- {
- if (!info->revisions->next)
- {
- gchar *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
- gboolean ret;
-
- ret = gitg_window_add_branch_action (info->window,
- gitg_branch_actions_format_patch (info->window,
- info->revisions->data,
- uri));
- g_free (uri);
-
- if (!ret)
- {
- GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (dialog),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _ ("Format patch failed for unknown reason"));
-
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
- "%s",
- _("Please check if you have the right permissions to write the file"));
-
- g_signal_connect (dlg, "response", G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_widget_show (dlg);
- }
- }
- else
- {
- /* TODO: implement once multiple selection is realized */
- }
- }
-
- g_list_free_full (info->revisions, (GDestroyNotify)gitg_revision_unref);
- g_slice_free (FormatPatchInfo, info);
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-void
-on_revision_format_patch_activate (GtkAction *action,
- GitgWindow *window)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (window->priv->tree_view);
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- GtkWidget *dialog = NULL;
-
- if (!rows->next)
- {
- GtkTreeIter iter;
- GitgRevision *revision;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
- gtk_tree_model_get (model, &iter, 0, &revision, -1);
-
- /* Single one, pick filename */
- dialog = gtk_file_chooser_dialog_new (_ ("Save format patch"),
- GTK_WINDOW (window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
- TRUE);
-
- gchar *name = gitg_revision_get_format_patch_name (revision);
- gchar *filename = g_strdup_printf ("0001-%s.patch", name);
-
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
- g_free (filename);
- g_free (name);
-
- gitg_revision_unref (revision);
- }
- else
- {
- /* TODO: Implement selecting folder once multiple selection is realized */
- }
-
- GFile *work_tree = gitg_repository_get_work_tree (window->priv->repository);
-
- gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog),
- work_tree,
- NULL);
-
- g_object_unref (work_tree);
-
- FormatPatchInfo *info = g_slice_new (FormatPatchInfo);
- info->window = window;
- info->revisions = NULL;
-
- GList *item;
-
- for (item = rows; item; item = g_list_next (item))
- {
- GtkTreeIter iter;
- GitgRevision *revision;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
- gtk_tree_model_get (model, &iter, 0, &revision, -1);
-
- info->revisions = g_list_prepend (info->revisions, revision);
- }
-
- info->revisions = g_list_reverse (info->revisions);
-
- g_signal_connect (dialog,
- "response",
- G_CALLBACK (on_format_patch_response),
- info);
-
- gtk_widget_show (dialog);
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-}
-
-void
-on_revision_new_branch_activate (GtkAction *action,
- GitgWindow *window)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (window->priv->tree_view);
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- if (rows && !rows->next)
- {
- GtkBuilder *builder = gitg_utils_new_builder ("gitg-new-branch.ui");
- GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_branch"));
-
- gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (window));
-
- GtkTreeIter iter;
- GitgRevision *rev;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
- gtk_tree_model_get (model, &iter, 0, &rev, -1);
-
- TagInfo *info = g_slice_new (TagInfo);
-
- info->revision = gitg_revision_ref (rev);
- info->window = window;
- info->builder = builder;
-
- g_signal_connect (widget,
- "response",
- G_CALLBACK (on_new_branch_dialog_response),
- info);
-
- gtk_widget_show (widget);
-
- gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "entry_name")));
- gitg_revision_unref (rev);
- }
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-}
-
-void
-on_revision_tag_activate (GtkAction *action,
- GitgWindow *window)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
-
- selection = gtk_tree_view_get_selection (window->priv->tree_view);
- GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
-
- if (rows && !rows->next)
- {
- GtkBuilder *builder = gitg_utils_new_builder ("gitg-tag.ui");
- GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_tag"));
-
- GtkToggleButton *toggle = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "check_button_sign"));
-
- gboolean active;
-
- active = g_settings_get_boolean (window->priv->hidden_settings,
- "sign-tag");
- gtk_toggle_button_set_active (toggle, active);
-
- gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (window));
-
- GtkTreeIter iter;
- GitgRevision *rev;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)rows->data);
- gtk_tree_model_get (model, &iter, 0, &rev, -1);
-
- TagInfo *info = g_slice_new (TagInfo);
-
- info->revision = gitg_revision_ref (rev);
- info->window = window;
- info->builder = builder;
-
- g_signal_connect (widget,
- "response",
- G_CALLBACK (on_tag_dialog_response),
- info);
-
- gtk_widget_show (widget);
-
- gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "entry_name")));
- gitg_revision_unref (rev);
- }
-
- g_list_free_full (rows, (GDestroyNotify)gtk_tree_path_free);
-}
-
-void
-on_revision_squash_activate (GtkAction *action,
- GitgWindow *window)
-{
-
-}
diff --git a/gitg/gitg-window.h b/gitg/gitg-window.h
deleted file mode 100644
index 3245013..0000000
--- a/gitg/gitg-window.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * gitg-window.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_WINDOW_H__
-#define __GITG_WINDOW_H__
-
-#include <gtk/gtk.h>
-#include <libgitg/gitg-repository.h>
-#include <libgitg/gitg-shell.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_WINDOW (gitg_window_get_type ())
-#define GITG_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_WINDOW, GitgWindow))
-#define GITG_WINDOW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_WINDOW, GitgWindow const))
-#define GITG_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_WINDOW, GitgWindowClass))
-#define GITG_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_WINDOW))
-#define GITG_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_WINDOW))
-#define GITG_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_WINDOW, GitgWindowClass))
-
-typedef struct _GitgWindow GitgWindow;
-typedef struct _GitgWindowClass GitgWindowClass;
-typedef struct _GitgWindowPrivate GitgWindowPrivate;
-
-struct _GitgWindow
-{
- GtkWindow parent;
-
- GitgWindowPrivate *priv;
-};
-
-struct _GitgWindowClass
-{
- GtkWindowClass parent_class;
-};
-
-GType gitg_window_get_type (void) G_GNUC_CONST;
-
-gboolean gitg_window_load_repository (GitgWindow *window,
- GFile *git_dir,
- GFile *work_tree,
- gint argc,
- gchar const **argv,
- gchar const *selection);
-
-gboolean gitg_window_load_repository_for_command_line (GitgWindow *window,
- gint argc,
- gchar const **argv,
- gchar const *selection);
-
-gboolean gitg_window_load_repository_from_environment (GitgWindow *window,
- gint argc,
- gchar const **argv,
- gchar const *selection);
-
-void gitg_window_show_commit (GitgWindow *window);
-
-GitgRepository *gitg_window_get_repository (GitgWindow *window);
-void gitg_window_set_select_on_load (GitgWindow *window, gchar const *selection);
-
-gboolean gitg_window_add_branch_action (GitgWindow *window, GitgShell *shell);
-
-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-window.ui b/gitg/gitg-window.ui
deleted file mode 100644
index 46bc353..0000000
--- a/gitg/gitg-window.ui
+++ /dev/null
@@ -1,576 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <!-- interface-requires gtk+ 2.18 -->
- <!-- interface-requires gitg 0.0.6 -->
- <!-- interface-requires sourceview -->
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkAdjustment" id="adjustment_context">
- <property name="value">3</property>
- <property name="lower">1</property>
- <property name="upper">10</property>
- <property name="step_increment">1</property>
- <property name="page_increment">1</property>
- <property name="page_size">1</property>
- </object>
- <object class="GitgWindow" id="window">
- <property name="title" translatable="yes">gitg</property>
- <property name="default_width">800</property>
- <property name="default_height">800</property>
- <child>
- <object class="GtkBox" id="vbox_main">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkNotebook" id="notebook_main">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <child>
- <object class="GtkBox" id="vbox_history">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkVPaned" id="vpaned_main">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="position">350</property>
- <child>
- <object class="GtkBox" id="vbox2">
- <property name="visible">True</property>
- <property name="border_width">6</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkBox" id="hbox_top">
- <property name="visible">True</property>
- <property name="spacing">3</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkLabel" id="label_branches">
- <property name="label" translatable="yes">Branch:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="combo_box_branches">
- <child>
- <object class="GtkCellRendererPixbuf" id="branches_renderer_icon"/>
- <attributes>
- <attribute name="stock-id">2</attribute>
- </attributes>
- </child>
- <child>
- <object class="GtkCellRendererText" id="branches_renderer"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="padding">3</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTreeView" id="tree_view_rv">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="rules_hint">True</property>
- <property name="search_column">1</property>
- <property name="fixed_height_mode">True</property>
- <property name="expand">True</property>
- <signal name="event_after" handler="on_tree_view_rv_button_press_event"/>
- <child>
- <object class="GtkTreeViewColumn" id="rv_column_subject">
- <property name="resizable">True</property>
- <property name="sizing">fixed</property>
- <property name="fixed_width">400</property>
- <property name="title" translatable="yes">Subject</property>
- <property name="expand">True</property>
- <child>
- <object class="GitgCellRendererPath" id="rv_renderer_subject"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="rv_column2">
- <property name="resizable">True</property>
- <property name="sizing">fixed</property>
- <property name="fixed_width">200</property>
- <property name="title" translatable="yes">Author</property>
- <child>
- <object class="GtkCellRendererText" id="rv_renderer_author"/>
- <attributes>
- <attribute name="text">2</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="rv_column3">
- <property name="resizable">True</property>
- <property name="sizing">fixed</property>
- <property name="fixed_width">200</property>
- <property name="title" translatable="yes">Date</property>
- <child>
- <object class="GtkCellRendererText" id="rv_renderer_date"/>
- <attributes>
- <attribute name="text">3</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkNotebook" id="notebook_revision">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">6</property>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_history">
- <property name="visible">True</property>
- <property name="label" translatable="yes">History</property>
- </object>
- <packing>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GitgCommitView" id="vpaned_commit">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">6</property>
- <property name="orientation">vertical</property>
- <property name="position">450</property>
- <property name="position_set">True</property>
- <child>
- <object class="GtkBox" id="vbox_changes">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkBox" id="hbox_changes">
- <property name="visible">True</property>
- <property name="spacing">3</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkLabel" id="label_changes">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">1</property>
- <property name="label" translatable="yes">Changes</property>
- <property name="mnemonic_widget">source_view_changes</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_context">
- <property name="label" translatable="yes">Context:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkHScale" id="hscale_context">
- <property name="width_request">200</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="adjustment">adjustment_context</property>
- <property name="digits">0</property>
- <property name="value_pos">right</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_changes">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GitgDiffView" id="source_view_changes">
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="left_margin">2</property>
- <property name="right_margin">2</property>
- <property name="cursor_visible">False</property>
- <property name="show_line_numbers">False</property>
- <property name="tab_width">4</property>
- <property name="expand">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkHPaned" id="hpaned_commit1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <child>
- <object class="GtkBox" id="vbox_unstaged">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkLabel" id="label_unstaged">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">1</property>
- <property name="label" translatable="yes">_Unstaged</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">tree_view_unstaged</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_unstaged">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTreeView" id="tree_view_unstaged">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="headers_clickable">False</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkTreeViewColumn" id="unstaged_column_icon">
- <property name="sizing">fixed</property>
- <property name="fixed_width">20</property>
- <child>
- <object class="GtkCellRendererPixbuf" id="unstaged_cell_renderer_icon"/>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="unstaged_column_name">
- <property name="resizable">True</property>
- <property name="title" translatable="yes">Unstaged</property>
- <child>
- <object class="GtkCellRendererText" id="unstaged_cell_renderer"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkHPaned" id="hpaned_commit2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <child>
- <object class="GtkBox" id="vbox_comment">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkLabel" id="label_comment">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">1</property>
- <property name="label" translatable="yes">Co_mmit message</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">text_view_comment</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_comment">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkSourceView" id="text_view_comment">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="left_margin">2</property>
- <property name="right_margin">2</property>
- <property name="expand">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox_commit">
- <property name="visible">True</property>
- <property name="spacing">3</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkBox" id="vbox1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkCheckButton" id="check_button_amend">
- <property name="label" translatable="yes">Amend</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="check_button_signed_off_by">
- <property name="label" translatable="yes">Add signed-off-by</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="yalign">1</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkButton" id="button_commit">
- <property name="label" translatable="yes">_Commit</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image_commit</property>
- <property name="use_underline">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="vbox_staged">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkLabel" id="label_staged">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Staged</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">tree_view_staged</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolled_window_staged">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">etched-in</property>
- <child>
- <object class="GtkTreeView" id="tree_view_staged">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="headers_clickable">False</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkTreeViewColumn" id="staged_column_icon">
- <property name="sizing">fixed</property>
- <property name="fixed_width">20</property>
- <child>
- <object class="GtkCellRendererPixbuf" id="staged_cell_renderer_icon"/>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="staged_column_name">
- <property name="resizable">True</property>
- <child>
- <object class="GtkCellRendererText" id="staged_cell_renderer_name"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label_commit">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Commit</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkStatusbar" id="statusbar">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkImage" id="image_commit">
- <property name="visible">True</property>
- <property name="stock">gtk-apply</property>
- </object>
-</interface>
diff --git a/gitg/gitg-window.vala b/gitg/gitg-window.vala
new file mode 100644
index 0000000..80d176b
--- /dev/null
+++ b/gitg/gitg-window.vala
@@ -0,0 +1,457 @@
+namespace Gitg
+{
+
+public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable, Gtk.Buildable
+{
+ private class ActiveView
+ {
+ public GitgExt.View view;
+ public Gtk.RadioToolButton? navigation_button;
+
+ public ActiveView(GitgExt.View v)
+ {
+ view = v;
+ }
+ }
+
+ private Repository? d_repository;
+ private GitgExt.MessageBus d_message_bus;
+ private Peas.ExtensionSet d_extensions_view;
+ private Peas.ExtensionSet d_extensions_navigation;
+ private GitgExt.View? d_current_view;
+ private HashTable<string, GitgExt.View> d_view_map;
+ private GitgExt.ViewAction d_action;
+
+ private HashTable<string, ActiveView> d_active_views;
+
+ // Widgets
+ private Gtk.Toolbar d_topnav;
+ private Gtk.Toolbar d_subnav;
+ private Gtk.Paned d_paned;
+ private Gtk.Paned d_panels;
+ private Gtk.Notebook d_notebook_panels;
+ private GitgExt.NavigationTreeView d_navigation;
+ private Gtk.Frame d_main_frame;
+
+ public GitgExt.View? current_view
+ {
+ owned get { return d_current_view; }
+ }
+
+ public GitgExt.MessageBus message_bus
+ {
+ owned get { return d_message_bus; }
+ }
+
+ public Repository? repository
+ {
+ owned get { return d_repository; }
+ }
+
+ private Gtk.RadioToolButton? create_topnav_button(GitgExt.View v)
+ {
+ Icon? icon = v.icon;
+
+ if (icon == null)
+ {
+ return null;
+ }
+
+ var img = new Gtk.Image.from_gicon(icon, d_topnav.get_icon_size());
+ img.show();
+
+ Gtk.RadioToolButton button;
+
+ if (d_topnav.get_n_items() != 0)
+ {
+ var ic = d_topnav.get_nth_item(0);
+ button = new Gtk.RadioToolButton.from_widget(ic as Gtk.RadioToolButton);
+ }
+ else
+ {
+ button = new Gtk.RadioToolButton(null);
+ }
+
+ button.set_icon_widget(img);
+ button.set_label(v.display_name);
+
+ button.show();
+
+ return button;
+ }
+
+ private void add_view(GitgExt.View v)
+ {
+ // Add a navigation button if needed
+ Gtk.RadioToolButton? button = create_topnav_button(v);
+ ActiveView av = new ActiveView(v);
+
+ av.navigation_button = button;
+
+ if (button != null)
+ {
+ d_topnav.add(button);
+ }
+
+ button.toggled.connect((b) => {
+ if (b.active)
+ {
+ set_view(v);
+ }
+ });
+
+ d_active_views.insert(v.id, av);
+ }
+
+ private void set_view(GitgExt.View v)
+ {
+ /* This function updates the view to @v. The following steps are
+ * involved:
+ *
+ * 1) Clear navigation tree
+ * 2) Remove all panels and panel navigation widgets
+ * 3) Remove main view widget
+ * 3) Hide panels and panel navigation
+ * 4) Set the current view to @v
+ * 5) Fill the navigation model with navigation from @v (if needed)
+ * 6) Query nagivation extensions to fill the navigation model
+ */
+
+ if (d_current_view == v)
+ {
+ return;
+ }
+
+ d_navigation.model.clear();
+
+ // Remove panel widgets
+ while (d_notebook_panels.get_n_pages() > 0)
+ {
+ d_notebook_panels.remove_page(0);
+ }
+
+ // Remove panel navigation buttons
+ while (d_subnav.get_n_items() > 0)
+ {
+ d_subnav.remove(d_subnav.get_nth_item(0));
+ }
+
+ var child = d_main_frame.get_child();
+ if (child != null)
+ {
+ d_main_frame.remove(child);
+ }
+
+ // Hide panel note book and panel navigation toolbar
+ d_notebook_panels.hide();
+ d_subnav.hide();
+
+ if (d_current_view != null)
+ {
+ var av = d_active_views.lookup(d_current_view.id);
+
+ if (av != null)
+ {
+ av.navigation_button.set_active(false);
+ }
+ }
+
+ // Set the current view
+ d_current_view = v;
+
+ // Populate navigation from the view first
+ GitgExt.Navigation? nav = v.navigation;
+
+ if (nav != null)
+ {
+ d_navigation.model.populate(nav);
+ }
+
+ // Populate navigation from the extensions
+ d_extensions_navigation.foreach((s, info, obj) => {
+ nav = obj as GitgExt.Navigation;
+
+ if (nav.available)
+ {
+ d_navigation.model.populate(nav);
+ }
+ });
+
+ // Expand all the navigation by default
+ d_navigation.expand_all();
+
+ // Select the first item of the navigation list
+ d_navigation.select_first();
+
+ // Set the main widget
+ var widget = v.widget;
+
+ if (widget != null)
+ {
+ widget.show();
+ d_main_frame.add(widget);
+ }
+
+ var av = d_active_views.lookup(v.id);
+
+ if (av.navigation_button != null)
+ {
+
+ av.navigation_button.set_active(true);
+ }
+ }
+
+ private void remove_view(GitgExt.View v, bool update_current)
+ {
+ ActiveView av;
+
+ if (d_active_views.lookup_extended(v.id, null, out av))
+ {
+ av.navigation_button.destroy();
+
+ d_view_map.remove(v.id);
+ d_active_views.remove(v.id);
+
+ if (av.view == d_current_view)
+ {
+ d_current_view = null;
+
+ if (update_current)
+ {
+ activate_default_view();
+ }
+ }
+ }
+ }
+
+ private void extension_view_added(Peas.ExtensionSet s,
+ Peas.PluginInfo info,
+ Object obj)
+ {
+ GitgExt.View v = obj as GitgExt.View;
+
+ d_view_map.insert(v.id, v);
+
+ if (v.is_available())
+ {
+ add_view(v);
+ }
+ }
+
+ private void extension_view_removed(Peas.ExtensionSet s,
+ Peas.PluginInfo info,
+ Object obj)
+ {
+ remove_view(obj as GitgExt.View, true);
+ }
+
+ private void update_nav_visibility(Gtk.Toolbar tb)
+ {
+ tb.visible = (tb.get_n_items() > 1);
+ }
+
+ private void parser_finished(Gtk.Builder builder)
+ {
+ d_topnav = builder.get_object("toolbar_topnav") as Gtk.Toolbar;
+ d_subnav = builder.get_object("toolbar_subnav") as Gtk.Toolbar;
+ d_paned = builder.get_object("paned_main") as Gtk.Paned;
+ d_panels = builder.get_object("paned_panel") as Gtk.Paned;
+ d_main_frame = builder.get_object("frame_main") as Gtk.Frame;
+
+ d_navigation = builder.get_object("tree_view_navigation") as GitgExt.NavigationTreeView;
+ d_notebook_panels = builder.get_object("notebook_panels") as Gtk.Notebook;
+
+ d_topnav.add.connect((t, widget) => {
+ update_nav_visibility(d_topnav);
+ });
+
+ d_topnav.remove.connect((t, widget) => {
+ update_nav_visibility(d_topnav);
+ });
+
+ d_subnav.add.connect((t, widget) => {
+ update_nav_visibility(d_subnav);
+ });
+
+ d_subnav.remove.connect((t, widget) => {
+ update_nav_visibility(d_subnav);
+ });
+
+ base.parser_finished(builder);
+ }
+
+ private bool init(Cancellable? cancellable)
+ {
+ // Setup message bus
+ d_message_bus = new GitgExt.MessageBus();
+
+ // Initialize peas extensions set for views
+ var engine = PluginsEngine.get_default();
+
+ d_extensions_view = new Peas.ExtensionSet(engine,
+ typeof(GitgExt.View),
+ "application",
+ this);
+
+ d_extensions_navigation = new Peas.ExtensionSet(engine,
+ typeof(GitgExt.Navigation),
+ "application",
+ this);
+
+ d_view_map = new HashTable<string, GitgExt.View>(str_hash, str_equal);
+ d_active_views = new HashTable<string, ActiveView>(str_hash, str_equal);
+
+ // Add all the extensions
+ d_extensions_view.foreach(extension_view_added);
+
+ d_extensions_view.extension_added.connect(extension_view_added);
+ d_extensions_view.extension_removed.connect(extension_view_removed);
+
+ activate_default_view();
+
+ return true;
+ }
+
+ public static Window? create_new(Gtk.Application app,
+ Repository repository,
+ GitgExt.ViewAction action)
+ {
+ Window? ret = Resource.load_object<Window>("ui/gitg-window.ui", "window");
+
+ if (ret != null)
+ {
+ ret.d_repository = repository;
+ ret.d_action = action;
+ }
+
+ try
+ {
+ ((Initable)ret).init(null);
+ } catch {}
+
+ return ret;
+ }
+
+ private void activate_default_view()
+ {
+ GitgExt.View? def = null;
+
+ // Activate the default view
+ d_extensions_view.foreach((s, info, obj) => {
+ GitgExt.View v = obj as GitgExt.View;
+
+ if (d_active_views.lookup_extended(v.id, null, null))
+ {
+ if (v.is_default_for(d_action))
+ {
+ set_view(v);
+ def = null;
+ return;
+ }
+ else if (def == null)
+ {
+ def = v;
+ }
+ }
+ });
+
+ if (def != null)
+ {
+ set_view(def);
+ }
+ }
+
+ private void update_views()
+ {
+ /* This method is called after some state has changed and thus a new
+ * set of views needs to be computed. Currently the only state change
+ * is opening or closing a repository.
+ */
+
+ // Now see if new views became available
+ d_extensions_view.foreach((s, info, obj) => {
+ GitgExt.View v = obj as GitgExt.View;
+
+ bool isavail = v.is_available();
+ bool isactive = d_active_views.lookup_extended(v.id, null, null);
+
+ if (isavail == isactive)
+ {
+ return;
+ }
+
+ if (isactive)
+ {
+ // should be inactive
+ remove_view(v, false);
+ }
+ else
+ {
+ add_view(v);
+ }
+ });
+
+ activate_default_view();
+ }
+
+ /* public API implementation of GitgExt.Application */
+ public GitgExt.View? view(string id)
+ {
+ GitgExt.View v;
+
+ if (d_view_map.lookup_extended(id, null, out v))
+ {
+ set_view(v);
+ }
+
+ return null;
+ }
+
+ public void open(File path)
+ {
+ File repo;
+
+ if (d_repository != null &&
+ d_repository.get_location().equal(path))
+ {
+ return;
+ }
+
+ try
+ {
+ repo = Ggit.Repository.discover(path);
+ }
+ catch
+ {
+ // TODO
+ return;
+ }
+
+ if (d_repository != null)
+ {
+ close();
+ }
+
+ try
+ {
+ d_repository = new Gitg.Repository(repo, null);
+ }
+ catch {}
+
+ update_views();
+ }
+
+ public void create(File path)
+ {
+ // TODO
+ }
+
+ public void close()
+ {
+ // TODO
+ }
+}
+
+}
+
+// ex:ts=4 noet
diff --git a/gitg/gitg.c b/gitg/gitg.c
deleted file mode 100644
index 0355b69..0000000
--- a/gitg/gitg.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * gitg.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <gtk/gtk.h>
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gtksourceview/gtksourcelanguagemanager.h>
-#include <gtksourceview/gtksourcestyleschememanager.h>
-#include <libgitg/gitg-debug.h>
-
-#include "gitg-window.h"
-#include "config.h"
-#include "gitg-dirs.h"
-#include "gitg-utils.h"
-#include "gitg-uri.h"
-
-static gboolean commit_mode = FALSE;
-static gchar *select_sha1 = NULL;
-
-static void
-show_version_and_quit (void)
-{
- g_print ("%s - Version %s\n", g_get_application_name (), VERSION);
-
- exit (0);
-}
-
-static GOptionEntry entries[] =
-{
- { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- show_version_and_quit, N_("Show the application's version"), NULL },
- { "commit", 'c', 0, G_OPTION_ARG_NONE, &commit_mode, N_("Start gitg in commit mode") },
- { "select", 's', 0, G_OPTION_ARG_STRING, &select_sha1, N_("Select commit after loading the repository") },
- { NULL }
-};
-
-static void
-parse_options (int *argc, char ***argv)
-{
- GError *error = NULL;
- GOptionContext *context;
-
- context = g_option_context_new (_("- git repository viewer"));
-
- // Ignore unknown options so we can pass them to git
- g_option_context_set_ignore_unknown_options (context, TRUE);
- g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
-
- if (!g_option_context_parse (context, argc, argv, &error))
- {
- g_print ("option parsing failed: %s\n", error->message);
- g_error_free (error);
- exit (1);
- }
-
- g_option_context_free(context);
-}
-
-static gboolean
-on_window_delete_event (GtkWidget *widget, gpointer userdata)
-{
- gtk_main_quit ();
- return FALSE;
-}
-
-static GitgWindow *
-build_ui ()
-{
- GtkBuilder *builder = gitg_utils_new_builder ("gitg-window.ui");
-
- GtkWidget *window = GTK_WIDGET (gtk_builder_get_object(builder, "window"));
- gtk_widget_show_all (window);
-
- g_signal_connect_after (window, "destroy", G_CALLBACK (on_window_delete_event), NULL);
- g_object_unref (builder);
-
- return GITG_WINDOW (window);
-}
-
-static void
-set_language_search_path ()
-{
- GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default ();
- gchar const * const *orig = gtk_source_language_manager_get_search_path (manager);
- gchar const **dirs = g_new0 (gchar const *, g_strv_length ((gchar **)orig) + 2);
- guint i = 0;
-
- while (orig[i])
- {
- dirs[i + 1] = orig[i];
- ++i;
- }
-
- gchar *path = gitg_dirs_get_data_filename ("language-specs", NULL);
- dirs[0] = path;
- gtk_source_language_manager_set_search_path (manager, (gchar **)dirs);
- g_free (path);
-
- g_free (dirs);
-}
-
-static void
-set_style_scheme_search_path ()
-{
- GtkSourceStyleSchemeManager *manager = gtk_source_style_scheme_manager_get_default ();
-
- gchar *path = gitg_dirs_get_data_filename ("styles", NULL);
- gtk_source_style_scheme_manager_prepend_search_path (manager, path);
- g_free (path);
-}
-
-static void
-set_icons ()
-{
- static gchar const *icon_infos[] = {
- "gitg16x16.png",
- "gitg22x22.png",
- "gitg24x24.png",
- "gitg32x32.png",
- "gitg48x48.png",
- "gitg64x64.png",
- "gitg128x128.png",
- NULL
- };
-
- int i;
- GList *icons = NULL;
-
- for (i = 0; icon_infos[i]; ++i)
- {
- gchar *filename = gitg_dirs_get_data_filename ("icons", icon_infos[i], NULL);
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
- g_free (filename);
-
- if (pixbuf)
- {
- icons = g_list_prepend (icons, pixbuf);
- }
- }
-
- gtk_window_set_default_icon_list (icons);
-
- g_list_free_full (icons, g_object_unref);
-}
-
-int
-main (int argc, char **argv)
-{
- gboolean ret;
-
- gitg_debug_init ();
-
- bindtextdomain (GETTEXT_PACKAGE, GITG_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- g_set_prgname ("gitg");
-
- /* Translators: this is the application name as in g_set_application_name */
- g_set_application_name (_("gitg"));
-
- gitg_dirs_initialize (argc, argv);
- gtk_init (&argc, &argv);
- parse_options (&argc, &argv);
-
- set_language_search_path ();
- set_style_scheme_search_path ();
- set_icons ();
-
- GitgWindow *window = build_ui ();
-
- ret = gitg_window_load_repository_for_command_line (window,
- argc - 1,
- (gchar const **)argv + 1,
- select_sha1);
-
- if (commit_mode && ret)
- {
- gitg_window_show_commit (window);
- }
-
- gtk_main ();
-
- return 0;
-}
diff --git a/gitg/gitg.vala b/gitg/gitg.vala
new file mode 100644
index 0000000..19d2428
--- /dev/null
+++ b/gitg/gitg.vala
@@ -0,0 +1,25 @@
+namespace Gitg
+{
+
+private const string version = Config.VERSION;
+
+public class Main
+{
+ public static int main(string[] args)
+ {
+ Intl.bindtextdomain(Config.GETTEXT_PACKAGE, Config.GITG_LOCALEDIR);
+ Intl.textdomain(Config.GETTEXT_PACKAGE);
+
+ Environment.set_prgname("gitg");
+ Environment.set_application_name(_("gitg"));
+
+ Gitg.init();
+
+ Application app = new Application();
+ return app.run(args);
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/gitg/resources/gitg-resources.xml b/gitg/resources/gitg-resources.xml
new file mode 100644
index 0000000..4700c6b
--- /dev/null
+++ b/gitg/resources/gitg-resources.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/gitg">
+ <file>ui/gitg-window.ui</file>
+ <file>ui/gitg-menus.ui</file>
+ <file>ui/style.css</file>
+ </gresource>
+</gresources>
+
+<!-- ex: et ts=2 -->
diff --git a/gitg/resources/ui/gitg-menus.ui b/gitg/resources/ui/gitg-menus.ui
new file mode 100644
index 0000000..cab1805
--- /dev/null
+++ b/gitg/resources/ui/gitg-menus.ui
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <menu id="app-menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_New Window</attribute>
+ <attribute name="action">app.new</attribute>
+ <attribute name="accel">&lt;Primary&gt;n</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Help</attribute>
+ <attribute name="action">app.help</attribute>
+ <attribute name="accel">F1</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_About</attribute>
+ <attribute name="action">app.about</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Quit</attribute>
+ <attribute name="action">app.quit</attribute>
+ <attribute name="accel">&lt;Primary&gt;q</attribute>
+ </item>
+ </section>
+ </menu>
+ <menu id="win-menu">
+ </menu>
+</interface>
diff --git a/gitg/resources/ui/gitg-window.ui b/gitg/resources/ui/gitg-window.ui
new file mode 100644
index 0000000..cddb1dc
--- /dev/null
+++ b/gitg/resources/ui/gitg-window.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.3 -->
+ <!-- interface-requires gitg 0.2 -->
+ <object class="GitgWindow" id="window">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">gitg</property>
+ <property name="default_width">800</property>
+ <property name="default_height">600</property>
+ <child>
+ <object class="GtkPaned" id="paned_main">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">200</property>
+ <property name="vexpand">True</property>
+ <property name="name">paned_main</property>
+ <child>
+ <object class="GtkEventBox" id="navigation_background">
+ <property name="visible">True</property>
+ <property name="name">navigation_background</property>
+ <child>
+ <object class="GtkGrid" id="grid_navigation">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="name">grid_navigation</property>
+ <property name="hexpand">True</property>
+ <property name="halign">fill</property>
+ <child>
+ <object class="GtkToolbar" id="toolbar_topnav">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="toolbar_style">icons</property>
+ <property name="icon-size">1</property>
+ <property name="hexpand">True</property>
+ <property name="halign">fill</property>
+ <property name="name">toolbar_topnav</property>
+ <property name="show-arrow">False</property>
+ <style>
+ <class name="inline-toolbar"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled_window_navigation">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vexpand">true</property>
+ <property name="hexpand">true</property>
+ <property name="shadow-type">none</property>
+ <property name="name">scrolled_window_navigation</property>
+ <child>
+ <object class="GitgExtNavigationTreeView" id="tree_view_navigation">
+ <property name="visible">True</property>
+ <property name="headers-visible">False</property>
+ <property name="name">tree_view_navigation</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="toolbar_subnav">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="toolbar_style">icons</property>
+ <property name="hexpand">True</property>
+ <property name="icon-size">2</property>
+ <property name="name">toolbar_subnav</property>
+ <style>
+ <class name="inline-toolbar"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkPaned" id="paned_panels">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkEventBox" id="frame_background">
+ <property name="visible">True</property>
+ <property name="name">frame_background</property>
+ <child>
+ <object class="GtkFrame" id="frame_main">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">in</property>
+ <property name="name">frame_main</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="notebook_panels">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
+
+<!-- ex:set ts=2 et: -->
diff --git a/gitg/resources/ui/style.css b/gitg/resources/ui/style.css
new file mode 100644
index 0000000..5d934b1
--- /dev/null
+++ b/gitg/resources/ui/style.css
@@ -0,0 +1,56 @@
+GtkToolbar#toolbar_topnav, GtkToolbar#toolbar_subnav {
+ border-left: 0px;
+ border-right: 0px;
+}
+
+GtkToolbar#toolbar_subnav {
+ border-bottom: 0px;
+}
+
+#navigation_background {
+ background-color: shade(@theme_bg_color, 0.85);
+ background-image: none;
+}
+
+#tree_view_navigation {
+ background-color: inherit;
+ background-image: none;
+ color: inherit;
+ background-color: shade(@theme_bg_color, 0.9);
+}
+
+#paned_main {
+ border-style: solid;
+ border-color: @borders;
+ border-width: 0px 0px 0px 1px;
+ padding: 0px;
+ border-radius: 0px;
+ background-color: inherit;
+}
+
+#tree_view_navigation.view:selected {
+ background-color: @theme_selected_bg_color;
+ color: @theme_selected_fg_color;
+}
+
+#frame_main {
+ padding: 0px 6px 6px 6px;
+}
+
+GtkLabel.title {
+ font-weight: bold;
+ font-size: 16;
+ color: @insensitive_fg_color;
+ text-shadow: 1 1 @theme_base_color;
+}
+
+GtkLabel.description {
+ padding-bottom: 12px;
+ color: @insensitive_fg_color;
+}
+
+GtkLabel.grid_title {
+ font-weight: bold;
+
+ text-shadow: 1 1 @theme_base_color;
+}
diff --git a/libgit2 b/libgit2
new file mode 160000
+Subproject 242a1cea8d66d9ec185044f345b22fec1940178
diff --git a/libgit2-glib b/libgit2-glib
new file mode 160000
+Subproject 1a17238b82e5d4ab65be78d90f356d2bf4aba91
diff --git a/libgitg-ext/GitgExt.py b/libgitg-ext/GitgExt.py
new file mode 100644
index 0000000..976a445
--- /dev/null
+++ b/libgitg-ext/GitgExt.py
@@ -0,0 +1,38 @@
+from gi.repository import GObject
+from ..overrides import override
+from ..importer import modules
+
+GitgExt = modules['GitgExt']._introspection_module
+__all__ = []
+
+class MessageBus(GitgExt.MessageBus):
+ def create(self, msgid, **kwargs):
+ tp = self.lookup(msgid)
+
+ if not tp.is_a(GitgExt.Message.__gtype__):
+ return None
+
+ kwargs['id'] = msgid
+
+ return GObject.new(tp, **kwargs)
+
+ def send(self, msgid, **kwargs):
+ msg = self.create(msgid, **kwargs)
+ self.send_message(msg)
+
+ return msg
+
+MessageBus = override(MessageBus)
+__all__.append('MessageBus')
+
+class Message(Gedit.Message):
+ def __getattribute__(self, name):
+ try:
+ return Gedit.Message.__getattribute__(self, name)
+ except:
+ return getattr(self.props, name)
+
+Message = override(Message)
+__all__.append('Message')
+
+# vi:ex:ts=4:et
diff --git a/libgitg-ext/Makefile.am b/libgitg-ext/Makefile.am
new file mode 100644
index 0000000..37cad6c
--- /dev/null
+++ b/libgitg-ext/Makefile.am
@@ -0,0 +1,100 @@
+lib_LTLIBRARIES = libgitg-ext-1.0.la
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(srcdir) \
+ $(LIBGITG_EXT_CFLAGS) \
+ $(WARN_CFLAGS) \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(libdir)"\"
+
+VALAFLAGS = \
+ --pkg Ggit-1.0 \
+ --pkg Gitg-1.0 \
+ --pkg gio-2.0 \
+ --pkg gtk+-3.0 \
+ --header libgitg-ext.h \
+ --includedir libgitg-ext \
+ --basedir $(top_srcdir) \
+ --gir GitgExt-1.0.gir \
+ --library libgitg-ext-1.0
+
+libgitg_ext_1_0_la_LDFLAGS = \
+ -export-dynamic -no-undefined -export-symbols-regex "^[^_].*"
+
+libgitg_ext_1_0_la_LIBADD = $(LIBGITG_EXT_LIBS)
+
+INST_H_FILES = \
+ libgitg-ext.h
+
+VALA_FILES = \
+ gitg-ext-application.vala \
+ gitg-ext-panel.vala \
+ gitg-ext-view.vala \
+ gitg-ext-navigation.vala \
+ gitg-ext-navigation-tree-view.vala \
+ gitg-ext-message-id.vala \
+ gitg-ext-message.vala \
+ gitg-ext-message-bus.vala
+
+libgitg_ext_1_0_la_SOURCES = \
+ $(VALA_FILES) \
+ gitg-ext-resources.c
+
+headerdir = $(prefix)/include/libgitg-ext-1.0/libgitg-ext
+header_DATA = $(INST_H_FILES)
+
+GitgExt-1.0.gir: libgitg-ext-1.0.la
+
+# Ignore all warnings for vala code...
+libgitg_ext_1_0_la_CFLAGS = \
+ -w
+
+girdir = $(INTROSPECTION_GIRDIR)
+gir_DATA = GitgExt-1.0.gir
+
+typelibdir = $(INTROSPECTION_TYPELIBDIR)
+typelib_DATA = GitgExt-1.0.typelib
+
+%.typelib: %.gir
+ $(INTROSPECTION_COMPILER) $(INTROSPECTION_COMPILER_ARGS) --includedir=. -o $@ $<
+
+if ENABLE_PYTHON
+overridesdir = $(pyoverridesdir)
+overrides_PYTHON = \
+ GitgExt.py
+endif
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgitg-ext-1.0.pc
+
+gitg-ext-resources.c: resources/resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-source \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+gitg-ext-resources.h: resources/resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-header \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+BUILT_SOURCES = \
+ $(gir_DATA) \
+ libgitg-ext.h \
+ gitg-ext-resources.c \
+ gitg-ext-resources.h
+
+EXTRA_DIST = \
+ $(pkgconfig_DATA) \
+ resources/resources.xml \
+ $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+
+CLEANFILES = \
+ $(VALA_FILES:.vala=.c) \
+ GitgExt-1.0.gir \
+ GitgExt-1.0.typelib
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/libgitg-ext/gitg-ext-application.vala b/libgitg-ext/gitg-ext-application.vala
new file mode 100644
index 0000000..8f0671e
--- /dev/null
+++ b/libgitg-ext/gitg-ext-application.vala
@@ -0,0 +1,19 @@
+namespace GitgExt
+{
+
+public interface Application : Object
+{
+ public abstract Gitg.Repository? repository { owned get; }
+ public abstract GitgExt.MessageBus message_bus { owned get; }
+ public abstract GitgExt.View? current_view { owned get; }
+
+ public abstract GitgExt.View? view(string id);
+
+ public abstract void open(File repository);
+ public abstract void create(File repository);
+ public abstract void close();
+}
+
+}
+
+// ex:set ts=4 noet:
diff --git a/libgitg-ext/gitg-ext-message-bus.vala b/libgitg-ext/gitg-ext-message-bus.vala
new file mode 100644
index 0000000..a15daa9
--- /dev/null
+++ b/libgitg-ext/gitg-ext-message-bus.vala
@@ -0,0 +1,294 @@
+namespace GitgExt
+{
+
+public delegate void MessageCallback(GitgExt.Message message);
+
+public class MessageBus : Object
+{
+ class Listener
+ {
+ public uint id;
+ public bool blocked;
+
+ public MessageCallback callback;
+
+ public Listener(uint id, owned MessageCallback callback)
+ {
+ this.id = id;
+
+ // TODO: destroy notify is lost...
+ this.callback = (owned)callback;
+ this.blocked = false;
+ }
+ }
+
+ class Message
+ {
+ public MessageId id;
+ public List<Listener> listeners;
+
+ public Message(MessageId id)
+ {
+ this.id = id.copy();
+ this.listeners = new List<Listener>();
+ }
+ }
+
+ class IdMap
+ {
+ public Message message;
+ public unowned List<Listener> listener;
+
+ public IdMap(Message message)
+ {
+ this.message = message;
+ }
+ }
+
+ private HashTable<MessageId, Message> d_messages;
+ private HashTable<uint, IdMap> d_idmap;
+ private HashTable<MessageId, Type> d_types;
+ private static MessageBus? s_instance;
+ private static uint s_next_id;
+
+ public signal void registered(MessageId id);
+ public signal void unregistered(MessageId id);
+
+ public virtual signal void dispatch(GitgExt.Message message)
+ {
+ Message? msg = lookup_message(message.id, false);
+
+ if (msg != null)
+ {
+ dispatch_message_real(msg, message);
+ }
+ }
+
+ public MessageBus()
+ {
+ d_messages = new HashTable<MessageId, Message>(MessageId.hash, MessageId.equal);
+ d_idmap = new HashTable<uint, IdMap>(direct_hash, direct_equal);
+ d_types = new HashTable<MessageId, Type>(MessageId.hash, MessageId.equal);
+ }
+
+ public static MessageBus get_default()
+ {
+ if (s_instance == null)
+ {
+ s_instance = new MessageBus();
+ s_instance.add_weak_pointer(&s_instance);
+ }
+
+ return s_instance;
+ }
+
+ private void dispatch_message_real(Message msg, GitgExt.Message message)
+ {
+ foreach (Listener l in msg.listeners)
+ {
+ if (!l.blocked)
+ {
+ l.callback(message);
+ }
+ }
+ }
+
+ public Type lookup(MessageId id)
+ {
+ Type ret;
+
+ if (!d_types.lookup_extended(id, null, out ret))
+ {
+ return Type.INVALID;
+ }
+ else
+ {
+ return ret;
+ }
+ }
+
+ public void register(Type message_type, MessageId id)
+ {
+ if (is_registered(id))
+ {
+ warning("Message type for `%s' is already registered", id.id);
+ return;
+ }
+
+ var cp = id.copy();
+
+ d_types.insert(cp, message_type);
+
+ registered(cp);
+ }
+
+ private void unregister_real(MessageId id, bool remove_from_store)
+ {
+ var cp = id;
+
+ if (!remove_from_store || d_types.remove(cp))
+ {
+ unregistered(cp);
+ }
+ }
+
+ public void unregister(MessageId id)
+ {
+ unregister_real(id, true);
+ }
+
+ public void unregister_all(string object_path)
+ {
+ d_types.foreach_remove((key, val) => {
+ if (key.object_path == object_path)
+ {
+ unregister_real(key, true);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ });
+ }
+
+ public bool is_registered(MessageId id)
+ {
+ return d_types.lookup_extended(id, null, null);
+ }
+
+ private Message new_message(MessageId id)
+ {
+ var ret = new Message(id);
+
+ d_messages.insert(id, ret);
+ return ret;
+ }
+
+ private Message? lookup_message(MessageId id, bool create)
+ {
+ var message = d_messages.lookup(id);
+
+ if (message == null && !create)
+ {
+ return null;
+ }
+
+ if (message == null)
+ {
+ message = new_message(id);
+ }
+
+ return message;
+ }
+
+ private uint add_listener(Message message, owned MessageCallback callback)
+ {
+ var listener = new Listener(++s_next_id, (owned)callback);
+
+ message.listeners.append(listener);
+
+ var idmap = new IdMap(message);
+ idmap.listener = message.listeners.last();
+
+ d_idmap.insert(listener.id, idmap);
+ return listener.id;
+ }
+
+ private void remove_listener(Message message, List<Listener> listener)
+ {
+ unowned Listener lst = listener.data;
+
+ d_idmap.remove(lst.id);
+
+ message.listeners.delete_link(listener);
+
+ if (message.listeners == null)
+ {
+ d_messages.remove(message.id);
+ }
+ }
+
+ private void block_listener(Message message, List<Listener> listener)
+ {
+ listener.data.blocked = true;
+ }
+
+ private void unblock_listener(Message message, List<Listener> listener)
+ {
+ listener.data.blocked = false;
+ }
+
+ public new uint connect(MessageId id, owned MessageCallback callback)
+ {
+ var message = lookup_message(id, true);
+
+ return add_listener(message, (owned)callback);
+ }
+
+ private delegate void MatchCallback(Message message, List<Listener> listeners);
+
+ private void process_by_id(uint id, MatchCallback processor)
+ {
+ IdMap? idmap = d_idmap.lookup(id);
+
+ if (idmap == null)
+ {
+ return;
+ }
+
+ processor(idmap.message, idmap.listener);
+ }
+
+ public new void disconnect(uint id)
+ {
+ process_by_id(id, remove_listener);
+ }
+
+ public void block(uint id)
+ {
+ process_by_id(id, block_listener);
+ }
+
+ public void unblock(uint id)
+ {
+ process_by_id(id, unblock_listener);
+ }
+
+ private void dispatch_message(GitgExt.Message message)
+ {
+ dispatch(message);
+ }
+
+ public GitgExt.Message send_message(GitgExt.Message message)
+ {
+ dispatch_message(message);
+ return message;
+ }
+
+ public GitgExt.Message? send(MessageId id, string? firstprop, ...)
+ {
+ Type type = lookup(id);
+
+ if (type == Type.INVALID)
+ {
+ warning("Could not find message type for `%s'", id.id);
+ return null;
+ }
+
+ GitgExt.Message? msg = (GitgExt.Message?)Object.new_valist(type, firstprop, va_list());
+
+ if (msg != null)
+ {
+ msg.id = id;
+ }
+
+ dispatch_message(msg);
+
+ return msg;
+ }
+}
+
+}
+
+// ex:set ts=4 noet:
diff --git a/libgitg-ext/gitg-ext-message-id.vala b/libgitg-ext/gitg-ext-message-id.vala
new file mode 100644
index 0000000..584da75
--- /dev/null
+++ b/libgitg-ext/gitg-ext-message-id.vala
@@ -0,0 +1,75 @@
+namespace GitgExt
+{
+
+public class MessageId : Object
+{
+ public string object_path { construct set; get; }
+ public string method { construct set; get; }
+
+ public string id
+ {
+ owned get { return object_path + "." + method; }
+ }
+
+ public uint hash()
+ {
+ return id.hash();
+ }
+
+ public bool equal(MessageId other)
+ {
+ return id == other.id;
+ }
+
+ public MessageId(string object_path, string method)
+ {
+ Object(object_path: object_path, method: method);
+ }
+
+ public MessageId copy()
+ {
+ return new MessageId(object_path, method);
+ }
+
+ public static bool valid_object_path(string path)
+ {
+ if (path == null)
+ {
+ return false;
+ }
+
+ if (path[0] != '/')
+ {
+ return false;
+ }
+
+ int i = 0;
+
+ while (i < path.length)
+ {
+ var c = path[i];
+
+ if (c == '/')
+ {
+ ++i;
+
+ if (i == path.length || !(c.isalpha() || c == '_'))
+ {
+ return false;
+ }
+ }
+ else if (!(c.isalnum() || c == '_'))
+ {
+ return false;
+ }
+
+ ++i;
+ }
+
+ return true;
+ }
+}
+
+}
+
+// ex:set ts=4 noet:
diff --git a/libgitg-ext/gitg-ext-message.vala b/libgitg-ext/gitg-ext-message.vala
new file mode 100644
index 0000000..a7f216d
--- /dev/null
+++ b/libgitg-ext/gitg-ext-message.vala
@@ -0,0 +1,40 @@
+namespace GitgExt
+{
+
+public abstract class Message : Object
+{
+ private MessageId d_id;
+
+ public MessageId id
+ {
+ construct set
+ {
+ d_id = value.copy();
+ }
+ get
+ {
+ return d_id;
+ }
+ }
+
+ public bool has(string propname)
+ {
+ return get_class().find_property(propname) != null;
+ }
+
+ public static bool type_has(Type type, string propname)
+ {
+ return ((ObjectClass)type.class_ref()).find_property(propname) != null;
+ }
+
+ public static bool type_check(Type type, string propname, Type value_type)
+ {
+ ParamSpec? spec = ((ObjectClass)type.class_ref()).find_property(propname);
+
+ return (spec != null && spec.value_type == value_type);
+ }
+}
+
+}
+
+// ex:set ts=4 noet:
diff --git a/libgitg-ext/gitg-ext-navigation-tree-view.vala b/libgitg-ext/gitg-ext-navigation-tree-view.vala
new file mode 100644
index 0000000..84b59cb
--- /dev/null
+++ b/libgitg-ext/gitg-ext-navigation-tree-view.vala
@@ -0,0 +1,476 @@
+namespace GitgExt
+{
+
+private enum Column
+{
+ ICON_NAME,
+ TEXT,
+ HINT,
+ SECTION,
+ OID
+}
+
+private enum Hint
+{
+ NONE,
+ HEADER,
+ DEFAULT
+}
+
+public delegate void NavigationActivated(int numclick);
+
+public class NavigationTreeModel : Gtk.TreeStore
+{
+ private class Activated : Object
+ {
+ private NavigationActivated d_activated;
+
+ public Activated(owned NavigationActivated? activated)
+ {
+ d_activated = (owned)activated;
+ }
+
+ public void activate(int numclick)
+ {
+ if (d_activated != null)
+ {
+ d_activated(numclick);
+ }
+ }
+ }
+ private SList<Gtk.TreeIter?> d_parents;
+ private uint d_sections;
+ private uint d_oid;
+ private Activated[] d_callbacks;
+
+ construct
+ {
+ set_column_types({typeof(string), typeof(string), typeof(uint), typeof(uint), typeof(uint)});
+
+ d_callbacks = new Activated[100];
+ d_callbacks.length = 0;
+ }
+
+ public uint begin_section()
+ {
+ d_parents = null;
+ return d_sections;
+ }
+
+ public void end_section()
+ {
+ ++d_sections;
+ }
+
+ private void append_one(string text,
+ string? icon_name,
+ uint hint,
+ owned NavigationActivated? callback,
+ out Gtk.TreeIter iter)
+ {
+ if (d_parents != null)
+ {
+ base.append(out iter, d_parents.data);
+ }
+ else
+ {
+ base.append(out iter, null);
+ }
+
+ @set(iter,
+ Column.ICON_NAME, icon_name,
+ Column.TEXT, text,
+ Column.HINT, hint,
+ Column.SECTION, d_sections,
+ Column.OID, d_oid);
+
+ d_callbacks += new Activated((owned)callback);
+ ++d_oid;
+ }
+
+ public NavigationTreeModel begin_header(string text,
+ string? icon_name)
+ {
+ Gtk.TreeIter iter;
+
+ append_one(text, icon_name, Hint.HEADER, null, out iter);
+ d_parents.prepend(iter);
+
+ return this;
+ }
+
+ public NavigationTreeModel end_header()
+ {
+ if (d_parents != null)
+ {
+ d_parents.remove_link(d_parents);
+ }
+
+ return this;
+ }
+
+ public new NavigationTreeModel append_default(string text,
+ string? icon_name,
+ owned NavigationActivated? callback)
+ {
+ Gtk.TreeIter iter;
+ append_one(text, icon_name, Hint.DEFAULT, (owned)callback, out iter);
+
+ return this;
+ }
+
+ public new NavigationTreeModel append(string text,
+ string? icon_name,
+ owned NavigationActivated? callback)
+ {
+ Gtk.TreeIter iter;
+ append_one(text, icon_name, Hint.NONE, (owned)callback, out iter);
+
+ return this;
+ }
+
+ public uint populate(GitgExt.Navigation nav)
+ {
+ uint ret = begin_section();
+
+ nav.populate(this);
+
+ end_section();
+ return ret;
+ }
+
+ public void remove_section(uint section)
+ {
+ Gtk.TreeIter iter;
+
+ if (!get_iter_first(out iter))
+ {
+ return;
+ }
+
+ while (true)
+ {
+ uint s;
+
+ @get(iter, Column.SECTION, out s);
+
+ if (s == section)
+ {
+ if (!base.remove(ref iter))
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (!iter_next(ref iter))
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ public new void clear()
+ {
+ base.clear();
+
+ d_sections = 0;
+ d_oid = 0;
+
+ d_callbacks.length = 0;
+ }
+
+ public void activate(Gtk.TreeIter iter, int numclick)
+ {
+ uint oid;
+
+ @get(iter, Column.OID, out oid);
+
+ if (d_callbacks[oid] != null)
+ {
+ d_callbacks[oid].activate(numclick);
+ }
+ }
+}
+
+public class NavigationRendererText : Gtk.CellRendererText
+{
+ private string d_icon_name;
+ private Gdk.Pixbuf d_pixbuf;
+ private Gtk.StateFlags d_state;
+
+ public string? icon_name
+ {
+ get { return d_icon_name;}
+ set
+ {
+ if (d_icon_name != value)
+ {
+ d_icon_name = value;
+ reset_pixbuf();
+ }
+ }
+ }
+
+ public uint hint { get; set; }
+
+ construct
+ {
+ ellipsize = Pango.EllipsizeMode.MIDDLE;
+ }
+
+ private void reset_pixbuf()
+ {
+ d_pixbuf = null;
+ }
+
+ private void ensure_pixbuf(Gtk.StyleContext ctx)
+ {
+ if (d_icon_name == null || (d_pixbuf != null && d_state == ctx.get_state()))
+ {
+ return;
+ }
+
+ d_pixbuf = null;
+
+ d_state = ctx.get_state();
+ var screen = ctx.get_screen();
+ var settings = Gtk.Settings.get_for_screen(screen);
+
+ int w = 16;
+ int h = 16;
+
+ Gtk.icon_size_lookup_for_settings(settings, Gtk.IconSize.MENU, out w, out h);
+
+ Gtk.IconInfo? info = Gtk.IconTheme.get_default().lookup_icon(d_icon_name,
+ int.min(w, h),
+ Gtk.IconLookupFlags.USE_BUILTIN);
+
+ if (info == null)
+ {
+ return;
+ }
+
+ bool symbolic = false;
+
+ try
+ {
+ d_pixbuf = info.load_symbolic_for_context(ctx, out symbolic);
+ } catch {};
+
+ if (d_pixbuf != null)
+ {
+ var source = new Gtk.IconSource();
+ source.set_pixbuf(d_pixbuf);
+
+ source.set_size(Gtk.IconSize.SMALL_TOOLBAR);
+ source.set_size_wildcarded(false);
+
+ d_pixbuf = ctx.render_icon_pixbuf(source, Gtk.IconSize.SMALL_TOOLBAR);
+ }
+ }
+
+ protected override void get_preferred_width(Gtk.Widget widget,
+ out int minimum_width,
+ out int minimum_height)
+ {
+ ensure_pixbuf(widget.get_style_context());
+
+ // Size of text
+ base.get_preferred_width(widget, out minimum_width, out minimum_height);
+
+ if (d_pixbuf != null)
+ {
+ minimum_width += d_pixbuf.get_width() + 3;
+ minimum_height += d_pixbuf.get_height();
+ }
+ }
+
+ protected override void get_preferred_height_for_width(Gtk.Widget widget,
+ int width,
+ out int minimum_height,
+ out int natural_height)
+ {
+ base.get_preferred_height_for_width(widget, width,
+ out minimum_height,
+ out natural_height);
+
+ ensure_pixbuf(widget.get_style_context());
+
+ if (d_pixbuf != null)
+ {
+ minimum_height = int.max(minimum_height, d_pixbuf.height);
+ natural_height = int.max(natural_height, d_pixbuf.height);
+ }
+ }
+
+ protected override void render(Cairo.Context ctx,
+ Gtk.Widget widget,
+ Gdk.Rectangle background_area,
+ Gdk.Rectangle cell_area,
+ Gtk.CellRendererState state)
+ {
+ var stx = widget.get_style_context();
+ ensure_pixbuf(stx);
+
+ int xpad = 3;
+
+ if (hint != Hint.HEADER)
+ {
+ cell_area.x -= 15;
+ }
+
+ if (d_pixbuf == null)
+ {
+ base.render(ctx, widget, background_area, cell_area, state);
+ }
+ else
+ {
+ // render the text with an additional padding
+ Gdk.Rectangle area = cell_area;
+ area.x += d_pixbuf.width + xpad;
+
+ base.render(ctx, widget, background_area, area, state);
+
+ // render the pixbuf
+ int ypad = (cell_area.height - d_pixbuf.height) / 2;
+
+ stx.render_icon(ctx, d_pixbuf, cell_area.x, cell_area.y + ypad);
+ }
+ }
+}
+
+public class NavigationTreeView : Gtk.TreeView
+{
+ private Gdk.RGBA d_header_bg;
+ private Gdk.RGBA d_header_fg;
+
+ construct
+ {
+ var model = new NavigationTreeModel();
+ set_model(model);
+
+ var cell = new NavigationRendererText();
+ var col = new Gtk.TreeViewColumn.with_attributes("text",
+ cell,
+ "icon_name", Column.ICON_NAME,
+ "text", Column.TEXT,
+ "hint", Column.HINT);
+
+ col.set_cell_data_func(cell, (col, cell, model, iter) => {
+ uint hint;
+
+ model.get(iter, Column.HINT, out hint);
+
+ Gtk.CellRendererText t = cell as Gtk.CellRendererText;
+
+ if (hint == Hint.HEADER)
+ {
+ t.weight = Pango.Weight.BOLD;
+ t.background_rgba = d_header_bg;
+ t.foreground_rgba = d_header_fg;
+ }
+ else
+ {
+ t.weight = Pango.Weight.NORMAL;
+ t.background_set = false;
+ t.foreground_set = false;
+ }
+ });
+
+ append_column(col);
+
+ get_selection().set_select_function((sel, model, path, cursel) => {
+ Gtk.TreeIter iter;
+ model.get_iter(out iter, path);
+
+ uint hint;
+
+ model.get(iter, Column.HINT, out hint);
+
+ return hint != Hint.HEADER;
+ });
+
+ update_header_colors();
+
+ get_selection().changed.connect((sel) => {
+ Gtk.TreeIter iter;
+
+ if (sel.get_selected(null, out iter))
+ {
+ model.activate(iter, 1);
+ }
+ });
+ }
+
+ protected override void style_updated()
+ {
+ base.style_updated();
+ update_header_colors();
+ }
+
+ private void update_header_colors()
+ {
+ get_style_context().lookup_color("insensitive_bg_color", out d_header_bg);
+ get_style_context().lookup_color("insensitive_fg_color", out d_header_fg);
+ }
+
+ public new NavigationTreeModel model
+ {
+ get { return base.get_model() as NavigationTreeModel; }
+ }
+
+ private bool select_first_in(Gtk.TreeIter? parent, bool seldef)
+ {
+ Gtk.TreeIter iter;
+
+ if (!model.iter_children(out iter, parent))
+ {
+ return false;
+ }
+
+ while (true)
+ {
+ uint hint;
+ model.get(iter, Column.HINT, out hint);
+
+ if (hint == Hint.HEADER)
+ {
+ if (select_first_in(iter, seldef))
+ {
+ return true;
+ }
+ }
+
+ if (!seldef || hint == Hint.DEFAULT)
+ {
+ get_selection().select_iter(iter);
+
+ return true;
+ }
+
+ if (!model.iter_next(ref iter))
+ {
+ return false;
+ }
+ }
+ }
+
+ public void select_first()
+ {
+ select_first_in(null, true) || select_first_in(null, false);
+ }
+
+ protected override void row_activated(Gtk.TreePath path, Gtk.TreeViewColumn col)
+ {
+ Gtk.TreeIter iter;
+
+ model.get_iter(out iter, path);
+ model.activate(iter, 2);
+ }
+}
+
+}
+
+// ex:set ts=4 noet:
diff --git a/libgitg-ext/gitg-ext-navigation.vala b/libgitg-ext/gitg-ext-navigation.vala
new file mode 100644
index 0000000..cee9941
--- /dev/null
+++ b/libgitg-ext/gitg-ext-navigation.vala
@@ -0,0 +1,22 @@
+namespace GitgExt
+{
+
+public enum NavigationSide
+{
+ LEFT = 0,
+ TOP = 1
+}
+
+public interface Navigation : Object
+{
+ public abstract Application? application { owned get; construct; }
+
+ public abstract void populate(GitgExt.NavigationTreeModel model);
+ public abstract bool available { get; }
+
+ public abstract NavigationSide navigation_side { get; }
+}
+
+}
+
+// ex:set ts=4 noet:
diff --git a/libgitg-ext/gitg-ext-panel.vala b/libgitg-ext/gitg-ext-panel.vala
new file mode 100644
index 0000000..1d6d105
--- /dev/null
+++ b/libgitg-ext/gitg-ext-panel.vala
@@ -0,0 +1,18 @@
+namespace GitgExt
+{
+
+public interface Panel : Object
+{
+ public abstract Application? application { owned get; construct; }
+
+ public abstract string id { owned get; }
+ public abstract string display_name { owned get; }
+ public abstract Icon? icon { owned get; }
+
+ public abstract bool supported { get; }
+ public abstract Gtk.Widget? widget { owned get; }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/libgitg-ext/gitg-ext-view.vala b/libgitg-ext/gitg-ext-view.vala
new file mode 100644
index 0000000..b362597
--- /dev/null
+++ b/libgitg-ext/gitg-ext-view.vala
@@ -0,0 +1,112 @@
+namespace GitgExt
+{
+
+/**
+ * A view action.
+ *
+ * A view action indicates a user preference to open gitg in a particular view.
+ */
+public enum ViewAction
+{
+ /**
+ * Open gitg in the History view.
+ */
+ HISTORY,
+
+ /**
+ * Open gitg in the Commit view.
+ */
+ COMMIT,
+
+ /**
+ * Open gitg in the default view.
+ */
+ DEFAULT = HISTORY
+}
+
+/**
+ * gitg View interface.
+ *
+ * The GitgExtView interface can be implemented to provide a main view in
+ * gitg. An example of such views are the builtin Dashboard, History and
+ * Commit views.
+ *
+ * Implementations of the GitgExtView interface will be integrated
+ * automatically in the gitg interface according to the various interface
+ * methods and properties that need to be implemented.
+ *
+ * == Default View Navigation ==
+ * To provide a default navigation when the view is active, the
+ * #GitgExtView::navigation property should be implemented and should return a
+ * non-null #GitgExtNavigation. This navigation section will always be present
+ * at the top of the navigation menu. Note that you should normally ''not''
+ * export this type to Peas because you will end up having the navigation
+ * shown twice in the UI.
+ */
+public interface View : Object
+{
+ /**
+ * The main gitg application interface. This property is a "construct"
+ * property and will be automatically set when an instance of the view
+ * object is created.
+ */
+ public abstract GitgExt.Application? application { owned get; construct; }
+
+ /**
+ * A unique id for the view. Ids in gitg are normally of the form
+ * /org/gnome/gitg/...
+ */
+ public abstract string id { owned get; }
+
+ /**
+ * The display name of the view. This should result in a string which can
+ * be displayed in the gitg UI to identify the view.
+ */
+ public abstract string display_name { owned get; }
+
+ /**
+ * The view icon. If provided, the icon will be used in the top navigation
+ * toolbar so that users can easily switch to the view. If not provider,
+ * the only way to activate the view will be through the menu.
+ */
+ public abstract Icon? icon { owned get; }
+
+ /**
+ * The view widget. This widget will be embedded in the main gitg UI when
+ * the view is activated.
+ */
+ public abstract Gtk.Widget? widget { owned get; }
+
+ /**
+ * Main navigation for the view. When provided, the corresponding navigation
+ * section will be added in the navigation panel when the view is activated.
+ */
+ public abstract Navigation? navigation { owned get; }
+
+ /**
+ * This method is used by gitg to verify whether or not a particular view
+ * is available in the current state of #GitgExtView::application.
+ * Implementations usually at least verify whether there is a repository
+ * currently open, but other constraints for when a view should be
+ * available can also be implemented.
+ *
+ * @return %TRUE if the view is available, %FALSE otherwise.
+ */
+ public abstract bool is_available();
+
+ /**
+ * @param action the action
+ *
+ * Implement this method when a view should be the preferred default view
+ * for a particular action. The first available view indicating to be
+ * a default view will be used as the default activated view when launching
+ * gitg (or when opening a repository).
+ *
+ * @return %TRUE if the view is a default for @action, %FALSE otherwise.
+ */
+ public abstract bool is_default_for(ViewAction action);
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/libgitg-ext/libgitg-ext-1.0.pc.in b/libgitg-ext/libgitg-ext-1.0.pc.in
new file mode 100644
index 0000000..d851288
--- /dev/null
+++ b/libgitg-ext/libgitg-ext-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libgitg-ext
+Description: gitg extensions library
+Version: @PACKAGE_VERSION@
+Requires: libgit2-glib-1.0 libgitg-1.0 gtk+-3.0 glib-2.0 gobject-2.0 gmodule-2.0 gio-2.0 gio-unix-2.0 gthread-2.0
+Libs: -L${libdir} -lgitg-ext-1.0
+Cflags: -I${includedir}/libgitg-ext-1.0
diff --git a/libgitg-ext/resources/resources.xml b/libgitg-ext/resources/resources.xml
new file mode 100644
index 0000000..a2e738f
--- /dev/null
+++ b/libgitg-ext/resources/resources.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/gitg/ext">
+ </gresource>
+</gresources>
+
+<!-- ex: et ts=2 -->
diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am
index e6e6973..7dec0e8 100644
--- a/libgitg/Makefile.am
+++ b/libgitg/Makefile.am
@@ -3,97 +3,70 @@ lib_LTLIBRARIES = libgitg-1.0.la
INCLUDES = \
-I$(top_srcdir) \
-I$(srcdir) \
- $(GITG_CFLAGS) \
+ $(LIBGITG_CFLAGS) \
$(WARN_CFLAGS) \
- $(DISABLE_DEPRECATED_CFLAGS) \
-DDATADIR=\""$(datadir)"\" \
- -DLIBDIR=\""$(libdir)"\" \
- -DGITG_LOCALEDIR=\""$(datadir)/locale"\"
+ -DLIBDIR=\""$(libdir)"\"
-libgitg_1_0_la_LDFLAGS = \
+libgitg_1_0_la_LDFLAGS = \
-export-dynamic -no-undefined -export-symbols-regex "^[^_].*"
-libgitg_1_0_la_LIBADD = $(GITG_LIBS)
-
-BUILT_SOURCES = \
- gitg-enum-types.h \
- gitg-enum-types.c
-
-INST_H_FILES = \
- $(BUILT_H_FILES) \
- gitg-changed-file.h \
- gitg-color.h \
- gitg-commit.h \
- gitg-config.h \
- gitg-hash.h \
- gitg-lane.h \
- gitg-ref.h \
- gitg-repository.h \
- gitg-revision.h \
- gitg-runner.h \
- gitg-command.h \
- gitg-shell.h \
- gitg-io.h \
- gitg-line-parser.h
-
-NOINST_H_FILES = \
- gitg-convert.h \
- gitg-debug.h \
- gitg-i18n.h \
- gitg-lanes.h \
- gitg-smart-charset-converter.h \
- gitg-encodings.h
-
-C_FILES = \
- $(BUILT_SOURCES) \
- gitg-changed-file.c \
- gitg-color.c \
- gitg-commit.c \
- gitg-config.c \
- gitg-convert.c \
- gitg-hash.c \
- gitg-i18n.c \
- gitg-lane.c \
- gitg-lanes.c \
- gitg-ref.c \
- gitg-repository.c \
- gitg-revision.c \
- gitg-runner.c \
- gitg-smart-charset-converter.c \
- gitg-encodings.c \
- gitg-command.c \
- gitg-io.c \
- gitg-shell.c \
- gitg-line-parser.c
-
-if ENABLE_DEBUG
-C_FILES += gitg-debug.c
-endif
-
-ENUM_H_FILES = \
- gitg-changed-file.h
-
-libgitg_1_0_la_SOURCES = \
- $(INST_H_FILES) \
- $(NOINST_H_FILES) \
- $(C_FILES)
+libgitg_1_0_la_LIBADD = $(LIBGITG_LIBS)
+
+INST_H_FILES = \
+ libgitg.h
+
+VALAFLAGS = \
+ --pkg Ggit-1.0 \
+ --pkg gio-2.0 \
+ --header libgitg.h \
+ --includedir libgitg \
+ --basedir $(top_srcdir) \
+ --gir Gitg-1.0.gir \
+ --library libgitg-1.0
+
+Gitg-1.0.gir: libgitg-1.0.la
+
+VALA_FILES = \
+ gitg-repository.vala \
+ gitg-ref.vala \
+ gitg-lane.vala \
+ gitg-lanes.vala \
+ gitg-color.vala \
+ gitg-init.vala \
+ gitg-commit.vala \
+ gitg-commit-model.vala
+
+# Ignore all warnings for vala code...
+libgitg_1_0_la_CFLAGS = \
+ -w
+
+libgitg_1_0_la_SOURCES = \
+ $(VALA_FILES)
headerdir = $(prefix)/include/libgitg-1.0/libgitg
header_DATA = $(INST_H_FILES)
-EXTRA_DIST = \
- gitg-enum-types.h.template \
- gitg-enum-types.c.template
+girdir = $(INTROSPECTION_GIRDIR)
+gir_DATA = Gitg-1.0.gir
-CLEANFILES = $(BUILT_SOURCES)
+typelibdir = $(INTROSPECTION_TYPELIBDIR)
+typelib_DATA = Gitg-1.0.typelib
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
+%.typelib: %.gir
+ $(INTROSPECTION_COMPILER) $(INTROSPECTION_COMPILER_ARGS) --includedir=. -o $@ $<
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgitg-1.0.pc
-gitg-enum-types.h: gitg-enum-types.h.template $(ENUM_H_FILES) $(GLIB_MKENUMS)
- $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template gitg-enum-types.h.template $(ENUM_H_FILES)) > $@
+BUILT_SOURCES = \
+ $(gir_DATA) \
+ libgitg.h
-gitg-enum-types.c: gitg-enum-types.c.template $(ENUM_H_FILES) $(GLIB_MKENUMS)
- $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template gitg-enum-types.c.template $(ENUM_H_FILES)) > $@
+EXTRA_DIST = $(pkgconfig_DATA)
+CLEANFILES = $(VALA_FILES:.vala=.c)
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
-include $(top_srcdir)/git.mk
diff --git a/libgitg/gitg-changed-file.c b/libgitg/gitg-changed-file.c
deleted file mode 100644
index 59883b7..0000000
--- a/libgitg/gitg-changed-file.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * gitg-changed-file.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-changed-file.h"
-#include "gitg-enum-types.h"
-
-#define GITG_CHANGED_FILE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_CHANGED_FILE, GitgChangedFilePrivate))
-
-struct _GitgChangedFilePrivate
-{
- GFile *file;
-
- GitgChangedFileStatus status;
- GitgChangedFileChanges changes;
-
- gchar *sha;
- gchar *mode;
-
- GFileMonitor *monitor;
-};
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_FILE,
- PROP_STATUS,
- PROP_CHANGES,
- PROP_SHA,
- PROP_MODE
-};
-
-/* Signals */
-enum
-{
- CHANGED,
- NUM_SIGNALS
-};
-
-static guint changed_file_signals[NUM_SIGNALS] = {0,};
-
-G_DEFINE_TYPE(GitgChangedFile, gitg_changed_file, G_TYPE_OBJECT)
-
-static void on_file_monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event, GitgChangedFile *self);
-
-static void
-gitg_changed_file_finalize(GObject *object)
-{
- GitgChangedFile *self = GITG_CHANGED_FILE(object);
-
- g_free(self->priv->sha);
- g_free(self->priv->mode);
- g_object_unref(self->priv->file);
-
- if (self->priv->monitor)
- {
- g_file_monitor_cancel(self->priv->monitor);
- g_object_unref(self->priv->monitor);
- }
-
- G_OBJECT_CLASS(gitg_changed_file_parent_class)->finalize(object);
-}
-
-static void
-gitg_changed_file_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- GitgChangedFile *self = GITG_CHANGED_FILE(object);
-
- switch (prop_id)
- {
- case PROP_FILE:
- g_value_set_object(value, self->priv->file);
- break;
- case PROP_STATUS:
- g_value_set_enum(value, self->priv->status);
- break;
- case PROP_CHANGES:
- g_value_set_flags(value, self->priv->changes);
- break;
- case PROP_SHA:
- g_value_set_string(value, self->priv->sha);
- break;
- case PROP_MODE:
- g_value_set_string(value, self->priv->mode);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-set_sha_real(GitgChangedFile *self, gchar const *sha)
-{
- g_free(self->priv->sha);
- self->priv->sha = g_strdup(sha);
-}
-
-static void
-set_mode_real(GitgChangedFile *self, gchar const *mode)
-{
- g_free(self->priv->mode);
- self->priv->mode = g_strdup(mode);
-}
-
-static void
-update_monitor(GitgChangedFile *file)
-{
- gboolean ismodified = (file->priv->status == GITG_CHANGED_FILE_STATUS_MODIFIED);
- gboolean iscached = (file->priv->changes & GITG_CHANGED_FILE_CHANGES_CACHED);
-
- gboolean needmonitor = ismodified || iscached;
-
- if (needmonitor && !file->priv->monitor)
- {
- file->priv->monitor = g_file_monitor_file(file->priv->file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_file_monitor_set_rate_limit(file->priv->monitor, 1000);
- g_signal_connect(file->priv->monitor, "changed", G_CALLBACK(on_file_monitor_changed), file);
- }
- else if (!needmonitor && file->priv->monitor)
- {
- g_file_monitor_cancel(file->priv->monitor);
- g_object_unref(file->priv->monitor);
- file->priv->monitor = NULL;
- }
-}
-
-static void
-gitg_changed_file_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- GitgChangedFile *self = GITG_CHANGED_FILE(object);
-
- switch (prop_id)
- {
- case PROP_FILE:
- self->priv->file = g_value_dup_object(value);
- break;
- case PROP_STATUS:
- self->priv->status = g_value_get_enum(value);
- update_monitor(self);
- break;
- case PROP_CHANGES:
- self->priv->changes = g_value_get_flags(value);
- update_monitor(self);
- break;
- case PROP_SHA:
- set_sha_real(self, g_value_get_string(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_changed_file_class_init(GitgChangedFileClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_changed_file_finalize;
- object_class->set_property = gitg_changed_file_set_property;
- object_class->get_property = gitg_changed_file_get_property;
-
- g_object_class_install_property(object_class, PROP_FILE,
- g_param_spec_object("file",
- "FILE",
- "File",
- G_TYPE_OBJECT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property(object_class, PROP_STATUS,
- g_param_spec_enum("status",
- "STATUS",
- "Status",
- GITG_TYPE_CHANGED_FILE_STATUS,
- GITG_CHANGED_FILE_STATUS_NEW,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_CHANGES,
- g_param_spec_flags("changes",
- "CHANGES",
- "Changes",
- GITG_TYPE_CHANGED_FILE_CHANGES,
- GITG_CHANGED_FILE_CHANGES_NONE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_SHA,
- g_param_spec_string("sha",
- "SHA",
- "Sha",
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_MODE,
- g_param_spec_string("mode",
- "MODE",
- "Mode",
- NULL,
- G_PARAM_READWRITE));
-
- changed_file_signals[CHANGED] =
- g_signal_new ("changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgChangedFileClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- g_type_class_add_private(object_class, sizeof(GitgChangedFilePrivate));
-}
-
-static void
-gitg_changed_file_init(GitgChangedFile *self)
-{
- self->priv = GITG_CHANGED_FILE_GET_PRIVATE (self);
-}
-
-GitgChangedFile*
-gitg_changed_file_new(GFile *file)
-{
- return g_object_new(GITG_TYPE_CHANGED_FILE, "file", file, NULL);
-}
-
-GFile *
-gitg_changed_file_get_file(GitgChangedFile *file)
-{
- g_return_val_if_fail(GITG_IS_CHANGED_FILE(file), NULL);
-
- return g_object_ref(file->priv->file);
-}
-
-gchar const *
-gitg_changed_file_get_sha(GitgChangedFile *file)
-{
- g_return_val_if_fail(GITG_IS_CHANGED_FILE(file), NULL);
-
- return file->priv->sha;
-}
-
-gchar const *
-gitg_changed_file_get_mode(GitgChangedFile *file)
-{
- g_return_val_if_fail(GITG_IS_CHANGED_FILE(file), NULL);
-
- return file->priv->mode;
-}
-
-void
-gitg_changed_file_set_sha(GitgChangedFile *file, gchar const *sha)
-{
- g_return_if_fail(GITG_IS_CHANGED_FILE(file));
-
- set_sha_real(file, sha);
- g_object_notify(G_OBJECT(file), "sha");
-}
-
-void
-gitg_changed_file_set_mode(GitgChangedFile *file, gchar const *mode)
-{
- g_return_if_fail(GITG_IS_CHANGED_FILE(file));
-
- set_mode_real(file, mode);
- g_object_notify(G_OBJECT(file), "mode");
-}
-
-GitgChangedFileStatus gitg_changed_file_get_status(GitgChangedFile *file)
-{
- g_return_val_if_fail(GITG_IS_CHANGED_FILE(file), GITG_CHANGED_FILE_STATUS_NONE);
-
- return file->priv->status;
-}
-
-GitgChangedFileChanges gitg_changed_file_get_changes(GitgChangedFile *file)
-{
- g_return_val_if_fail(GITG_IS_CHANGED_FILE(file), GITG_CHANGED_FILE_CHANGES_NONE);
-
- return file->priv->changes;
-}
-
-void gitg_changed_file_set_status(GitgChangedFile *file, GitgChangedFileStatus status)
-{
- g_return_if_fail(GITG_IS_CHANGED_FILE(file));
-
- if (status == file->priv->status)
- return;
-
- g_object_set(file, "status", status, NULL);
-}
-
-void
-gitg_changed_file_set_changes(GitgChangedFile *file, GitgChangedFileChanges changes)
-{
- g_return_if_fail(GITG_IS_CHANGED_FILE(file));
-
- if (changes == file->priv->changes)
- return;
-
- g_object_set(file, "changes", changes, NULL);
-}
-
-gboolean
-gitg_changed_file_equal(GitgChangedFile *file, GFile *other)
-{
- g_return_val_if_fail(GITG_IS_CHANGED_FILE(file), FALSE);
-
- return g_file_equal(file->priv->file, other);
-}
-
-static void
-on_file_monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event, GitgChangedFile *self)
-{
- switch (event)
- {
- case G_FILE_MONITOR_EVENT_DELETED:
- case G_FILE_MONITOR_EVENT_CREATED:
- case G_FILE_MONITOR_EVENT_CHANGED:
- g_signal_emit(self, changed_file_signals[CHANGED], 0);
- break;
- default:
- break;
- }
-}
diff --git a/libgitg/gitg-changed-file.h b/libgitg/gitg-changed-file.h
deleted file mode 100644
index 9800cf3..0000000
--- a/libgitg/gitg-changed-file.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * gitg-changed-file.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_CHANGED_FILE_H__
-#define __GITG_CHANGED_FILE_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_CHANGED_FILE (gitg_changed_file_get_type ())
-#define GITG_CHANGED_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CHANGED_FILE, GitgChangedFile))
-#define GITG_CHANGED_FILE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CHANGED_FILE, GitgChangedFile const))
-#define GITG_CHANGED_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_CHANGED_FILE, GitgChangedFileClass))
-#define GITG_IS_CHANGED_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_CHANGED_FILE))
-#define GITG_IS_CHANGED_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_CHANGED_FILE))
-#define GITG_CHANGED_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_CHANGED_FILE, GitgChangedFileClass))
-
-typedef struct _GitgChangedFile GitgChangedFile;
-typedef struct _GitgChangedFileClass GitgChangedFileClass;
-typedef struct _GitgChangedFilePrivate GitgChangedFilePrivate;
-
-typedef enum
-{
- GITG_CHANGED_FILE_STATUS_NONE = 0,
- GITG_CHANGED_FILE_STATUS_NEW,
- GITG_CHANGED_FILE_STATUS_MODIFIED,
- GITG_CHANGED_FILE_STATUS_DELETED
-} GitgChangedFileStatus;
-
-typedef enum
-{
- GITG_CHANGED_FILE_CHANGES_NONE = 0,
- GITG_CHANGED_FILE_CHANGES_CACHED = 1 << 0,
- GITG_CHANGED_FILE_CHANGES_UNSTAGED = 1 << 1
-} GitgChangedFileChanges;
-
-struct _GitgChangedFile {
- GObject parent;
-
- GitgChangedFilePrivate *priv;
-};
-
-struct _GitgChangedFileClass {
- GObjectClass parent_class;
-
- void (*changed)(GitgChangedFile *file);
-};
-
-GType gitg_changed_file_get_type (void) G_GNUC_CONST;
-GitgChangedFile *gitg_changed_file_new(GFile *file);
-
-GFile *gitg_changed_file_get_file(GitgChangedFile *file);
-gboolean gitg_changed_file_equal(GitgChangedFile *file, GFile *other);
-
-gchar const *gitg_changed_file_get_sha(GitgChangedFile *file);
-gchar const *gitg_changed_file_get_mode(GitgChangedFile *file);
-
-void gitg_changed_file_set_sha(GitgChangedFile *file, gchar const *sha);
-void gitg_changed_file_set_mode(GitgChangedFile *file, gchar const *mode);
-
-GitgChangedFileStatus gitg_changed_file_get_status(GitgChangedFile *file);
-GitgChangedFileChanges gitg_changed_file_get_changes(GitgChangedFile *file);
-
-void gitg_changed_file_set_status(GitgChangedFile *file, GitgChangedFileStatus status);
-void gitg_changed_file_set_changes(GitgChangedFile *file, GitgChangedFileChanges changes);
-
-G_END_DECLS
-
-#endif /* __GITG_CHANGED_FILE_H__ */
diff --git a/libgitg/gitg-color.c b/libgitg/gitg-color.c
deleted file mode 100644
index d5eeb85..0000000
--- a/libgitg/gitg-color.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * gitg-color.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-color.h"
-#include <gdk/gdk.h>
-
-static gint8 current_index = 0;
-
-static gchar const *palette[] = {
- "#c4a000",
- "#4e9a06",
- "#ce5c00",
- "#204a87",
- "#2e3436",
- "#6c3566",
- "#a40000",
-
- "#8ae234",
- "#fcaf3e",
- "#729fcf",
- "#fce94f",
- "#888a85",
- "#ad7fa8",
- "#e9b96e",
- "#ef2929"
-};
-
-void
-gitg_color_reset (void)
-{
- current_index = 0;
-}
-
-void
-gitg_color_get (GitgColor *color, gdouble *r, gdouble *g, gdouble *b)
-{
- gchar const *spec = palette[color->index];
- GdkColor c;
-
- gdk_color_parse(spec, &c);
-
- *r = c.red / 65535.0;
- *g = c.green / 65535.0;
- *b = c.blue / 65535.0;
-}
-
-void
-gitg_color_set_cairo_source (GitgColor *color, cairo_t *cr)
-{
- gdouble r, g, b;
-
- gitg_color_get(color, &r, &g, &b);
- cairo_set_source_rgb(cr, r, g, b);
-}
-
-static gint8
-next_index ()
-{
- gint8 next = current_index++;
-
- if (current_index == sizeof(palette) / sizeof(gchar const *))
- current_index = 0;
-
- return next;
-}
-
-GitgColor *
-gitg_color_next (void)
-{
- GitgColor *res = g_new(GitgColor, 1);
- res->ref_count = 1;
- res->index = next_index();
-
- return res;
-}
-
-GitgColor *
-gitg_color_next_index (GitgColor *color)
-{
- color->index = next_index();
- return color;
-}
-
-GitgColor *
-gitg_color_copy (GitgColor *color)
-{
- GitgColor *copy = g_new(GitgColor, 1);
- copy->ref_count = 1;
- copy->index = color->index;
-
- return copy;
-}
-
-GitgColor *
-gitg_color_ref (GitgColor *color)
-{
- if (!color)
- return NULL;
-
- ++color->ref_count;
- return color;
-}
-
-GitgColor *
-gitg_color_unref (GitgColor *color)
-{
- if (!color)
- return NULL;
-
- --color->ref_count;
-
- if (color->ref_count == 0)
- {
- g_free(color);
- return NULL;
- }
-
- return color;
-}
-
diff --git a/libgitg/gitg-color.h b/libgitg/gitg-color.h
deleted file mode 100644
index c3c9bd3..0000000
--- a/libgitg/gitg-color.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * gitg-color.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_COLOR_H__
-#define __GITG_COLOR_H__
-
-#include <glib.h>
-#include <cairo.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GitgColor GitgColor;
-
-struct _GitgColor
-{
- gulong ref_count;
- gint8 index;
-};
-
-void gitg_color_reset (void);
-void gitg_color_get (GitgColor *color, gdouble *r, gdouble *g, gdouble *b);
-void gitg_color_set_cairo_source (GitgColor *color, cairo_t *cr);
-
-GitgColor *gitg_color_next (void);
-GitgColor *gitg_color_next_index (GitgColor *color);
-GitgColor *gitg_color_ref (GitgColor *color);
-GitgColor *gitg_color_copy (GitgColor *color);
-GitgColor *gitg_color_unref (GitgColor *color);
-
-G_END_DECLS
-
-#endif /* __GITG_COLOR_H__ */
diff --git a/libgitg/gitg-color.vala b/libgitg/gitg-color.vala
new file mode 100644
index 0000000..5dc4077
--- /dev/null
+++ b/libgitg/gitg-color.vala
@@ -0,0 +1,85 @@
+namespace Gitg
+{
+
+public class Color : Object
+{
+ private struct Rgb
+ {
+ ushort r;
+ ushort g;
+ ushort b;
+ }
+
+ private static const Rgb[] palette = {
+ {196, 160, 0},
+ {78, 154, 6},
+ {206, 92, 0},
+ {32, 74, 135},
+ {46, 52, 54},
+ {108, 53, 102},
+ {164, 0, 0},
+
+ {138, 226, 52},
+ {252, 175, 62},
+ {114, 159, 207},
+ {252, 233, 79},
+ {136, 138, 133},
+ {173, 127, 168},
+ {233, 185, 110},
+ {239, 41, 41}
+ };
+
+ private static uint current_index;
+
+ public uint idx = 0;
+
+ public static void reset()
+ {
+ current_index = 0;
+ }
+
+ public void components(out double r, out double g, out double b)
+ {
+ r = palette[idx].r / 255.0;
+ g = palette[idx].g / 255.0;
+ b = palette[idx].b / 255.0;
+ }
+
+ private static uint inc_index()
+ {
+ uint next = current_index++;
+
+ if (current_index == palette.length)
+ {
+ current_index = 0;
+ }
+
+ return next;
+ }
+
+ public static Color next()
+ {
+ Color ret = new Color();
+ ret.idx = inc_index();
+
+ return ret;
+ }
+
+ public Color next_index()
+ {
+ this.idx = inc_index();
+ return this;
+ }
+
+ public Color copy()
+ {
+ Color ret = new Color();
+ ret.idx = idx;
+
+ return ret;
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-command.c b/libgitg/gitg-command.c
deleted file mode 100644
index f6ef51e..0000000
--- a/libgitg/gitg-command.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * gitg-command.c
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * gitg 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.
- *
- * gitg 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 gitg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include "gitg-command.h"
-
-#define GITG_COMMAND_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_COMMAND, GitgCommandPrivate))
-
-#define CONST_CONST(x) ((gchar const * const *)x)
-
-struct _GitgCommandPrivate
-{
- GitgRepository *repository;
- gchar **arguments;
- gchar **environment;
- GFile *working_directory;
-};
-
-G_DEFINE_TYPE (GitgCommand, gitg_command, G_TYPE_INITIALLY_UNOWNED)
-
-enum
-{
- PROP_0,
- PROP_REPOSITORY,
- PROP_ARGUMENTS,
- PROP_ENVIRONMENT,
- PROP_WORKING_DIRECTORY
-};
-
-static void
-gitg_command_finalize (GObject *object)
-{
- GitgCommand *command;
-
- command = GITG_COMMAND (object);
-
- g_strfreev (command->priv->arguments);
- g_strfreev (command->priv->environment);
-
- G_OBJECT_CLASS (gitg_command_parent_class)->finalize (object);
-}
-
-static void
-gitg_command_dispose (GObject *object)
-{
- GitgCommand *command;
-
- command = GITG_COMMAND (object);
-
- if (command->priv->repository != NULL)
- {
- g_object_unref (command->priv->repository);
- command->priv->repository = NULL;
- }
-
- G_OBJECT_CLASS (gitg_command_parent_class)->dispose (object);
-}
-
-static void
-gitg_command_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgCommand *self = GITG_COMMAND (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- self->priv->repository = g_value_dup_object (value);
- break;
- case PROP_ARGUMENTS:
- gitg_command_set_argumentsv (self,
- g_value_get_boxed (value));
- break;
- case PROP_ENVIRONMENT:
- gitg_command_set_environmentv (self,
- g_value_get_boxed (value));
- break;
- case PROP_WORKING_DIRECTORY:
- gitg_command_set_working_directory (self,
- g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_command_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgCommand *self = GITG_COMMAND (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- g_value_set_object (value, self->priv->repository);
- break;
- case PROP_ARGUMENTS:
- g_value_set_boxed (value, self->priv->arguments);
- break;
- case PROP_ENVIRONMENT:
- g_value_set_boxed (value, self->priv->environment);
- break;
- case PROP_WORKING_DIRECTORY:
- g_value_take_object (value, gitg_command_get_working_directory (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_command_class_init (GitgCommandClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_command_finalize;
- object_class->dispose = gitg_command_dispose;
-
- object_class->get_property = gitg_command_get_property;
- object_class->set_property = gitg_command_set_property;
-
- g_type_class_add_private (object_class, sizeof(GitgCommandPrivate));
-
- g_object_class_install_property (object_class,
- PROP_REPOSITORY,
- g_param_spec_object ("repository",
- "Repository",
- "Repository",
- GITG_TYPE_REPOSITORY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_ARGUMENTS,
- g_param_spec_boxed ("arguments",
- "Arguments",
- "Arguments",
- G_TYPE_STRV,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_ENVIRONMENT,
- g_param_spec_boxed ("environment",
- "Environment",
- "Environment",
- G_TYPE_STRV,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_WORKING_DIRECTORY,
- g_param_spec_object ("working-directory",
- "Working Directory",
- "Working directory",
- G_TYPE_FILE,
- G_PARAM_READWRITE));
-}
-
-static void
-gitg_command_init (GitgCommand *self)
-{
- self->priv = GITG_COMMAND_GET_PRIVATE (self);
-}
-
-static gchar **
-collect_arguments (va_list ap)
-{
- GPtrArray *arguments;
- gchar const *arg;
-
- arguments = g_ptr_array_new ();
-
- while ((arg = va_arg (ap, gchar const *)) != NULL)
- {
- g_ptr_array_add (arguments, g_strdup (arg));
- }
-
- g_ptr_array_add (arguments, NULL);
-
- return (gchar **)g_ptr_array_free (arguments, FALSE);
-}
-
-static gchar **
-combine_environment (gchar const * const *environment)
-{
- GPtrArray *ret;
-
- ret = g_ptr_array_new ();
-
- while (*environment)
- {
- gchar const *key = *environment++;
- gchar const *value = *environment++;
-
- gchar *combined = g_strconcat (key, "=", value, NULL);
-
- g_ptr_array_add (ret, combined);
- }
-
- g_ptr_array_add (ret, NULL);
-
- return (gchar **)g_ptr_array_free (ret, FALSE);
-}
-
-GitgCommand *
-gitg_command_newv (GitgRepository *repository,
- gchar const * const *arguments)
-{
- g_return_val_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository), NULL);
-
- return g_object_new (GITG_TYPE_COMMAND,
- "repository", repository,
- "arguments", arguments,
- NULL);
-}
-
-GitgCommand *
-gitg_command_new (GitgRepository *repository,
- ...)
-{
- va_list ap;
- GitgCommand *ret;
- gchar **arguments;
-
- g_return_val_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository), NULL);
-
- va_start (ap, repository);
-
- arguments = collect_arguments (ap);
- ret = gitg_command_newv (repository, CONST_CONST (arguments));
-
- g_strfreev (arguments);
- va_end (ap);
-
- return ret;
-}
-
-GitgRepository *
-gitg_command_get_repository (GitgCommand *command)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
-
- return command->priv->repository;
-}
-
-void
-gitg_command_set_argumentsv (GitgCommand *command,
- gchar const * const *arguments)
-{
- GPtrArray *ret;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- ret = g_ptr_array_new ();
-
- if (command->priv->repository)
- {
- GFile *git_dir;
- GFile *work_tree;
-
- gchar *git_dir_path;
- gchar *work_tree_path;
-
- git_dir = gitg_repository_get_git_dir (command->priv->repository);
- work_tree = gitg_repository_get_work_tree (command->priv->repository);
-
- git_dir_path = g_file_get_path (git_dir);
- work_tree_path = g_file_get_path (work_tree);
-
- g_object_unref (git_dir);
- g_object_unref (work_tree);
-
- g_ptr_array_add (ret, g_strdup ("git"));
- g_ptr_array_add (ret, g_strdup ("--git-dir"));
- g_ptr_array_add (ret, git_dir_path);
- g_ptr_array_add (ret, g_strdup ("--work-tree"));
- g_ptr_array_add (ret, work_tree_path);
- }
-
- while (*arguments)
- {
- g_ptr_array_add (ret, g_strdup (*arguments++));
- }
-
- g_ptr_array_add (ret, NULL);
-
- g_strfreev (command->priv->arguments);
- command->priv->arguments = (gchar **)g_ptr_array_free (ret, FALSE);
-
- g_object_notify (G_OBJECT (command), "arguments");
-}
-
-void
-gitg_command_set_arguments (GitgCommand *command,
- ...)
-{
- va_list ap;
- gchar **arguments;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- va_start (ap, command);
- arguments = collect_arguments (ap);
- va_end (ap);
-
- gitg_command_set_argumentsv (command, CONST_CONST (arguments));
-
- g_strfreev (arguments);
-}
-
-void
-gitg_command_add_argumentsv (GitgCommand *command,
- gchar const * const *arguments)
-{
- GPtrArray *args;
- gchar **ptr;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- args = g_ptr_array_new ();
-
- for (ptr = command->priv->arguments; ptr && *ptr; ++ptr)
- {
- g_ptr_array_add (args, *ptr);
- }
-
- while (arguments && *arguments)
- {
- g_ptr_array_add (args, g_strdup (*arguments++));
- }
-
- g_free (command->priv->arguments);
-
- g_ptr_array_add (args, NULL);
- command->priv->arguments = (gchar **)g_ptr_array_free (args, FALSE);
-
- g_object_notify (G_OBJECT (command), "arguments");
-}
-
-void
-gitg_command_add_arguments (GitgCommand *command,
- ...)
-{
- va_list ap;
- gchar **arguments;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- va_start (ap, command);
- arguments = collect_arguments (ap);
- va_end (ap);
-
- gitg_command_add_argumentsv (command, CONST_CONST (arguments));
-
- g_strfreev (arguments);
-}
-
-gchar const * const *
-gitg_command_get_arguments (GitgCommand *command)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
- return CONST_CONST (command->priv->arguments);
-}
-
-void
-gitg_command_set_environmentv (GitgCommand *command,
- gchar const * const *environment)
-{
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- g_strfreev (command->priv->environment);
- command->priv->environment = combine_environment (environment);
-
- g_object_notify (G_OBJECT (command), "environment");
-}
-
-void
-gitg_command_set_environment (GitgCommand *command,
- ...)
-{
- va_list ap;
- gchar **environment;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- va_start (ap, command);
- environment = collect_arguments (ap);
- va_end (ap);
-
- gitg_command_set_environmentv (command, CONST_CONST (environment));
-
- g_strfreev (environment);
-}
-
-void
-gitg_command_add_environmentv (GitgCommand *command,
- gchar const * const *environment)
-{
- GPtrArray *args;
- gchar **combined;
- gchar **ptr;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- args = g_ptr_array_new ();
-
- for (ptr = command->priv->environment; ptr && *ptr; ++ptr)
- {
- g_ptr_array_add (args, *ptr);
- }
-
- combined = combine_environment (environment);
-
- for (ptr = combined; ptr && *ptr; ++ptr)
- {
- g_ptr_array_add (args, *ptr);
- }
-
- g_free (combined);
- g_free (command->priv->environment);
-
- g_ptr_array_add (args, NULL);
-
- command->priv->environment = (gchar **)g_ptr_array_free (args, FALSE);
-
- g_object_notify (G_OBJECT (command), "arguments");
-}
-
-void
-gitg_command_add_environment (GitgCommand *command,
- ...)
-{
- va_list ap;
- gchar **environment;
-
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- va_start (ap, command);
- environment = collect_arguments (ap);
- va_end (ap);
-
- gitg_command_add_environmentv (command, CONST_CONST (environment));
- g_strfreev (environment);
-}
-
-gchar const * const *
-gitg_command_get_environment (GitgCommand *command)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
-
- return CONST_CONST (command->priv->environment);
-}
-
-void
-gitg_command_set_working_directory (GitgCommand *command,
- GFile *working_directory)
-{
- g_return_if_fail (GITG_IS_COMMAND (command));
- g_return_if_fail (working_directory == NULL || G_IS_FILE (working_directory));
-
- if (command->priv->working_directory)
- {
- g_object_unref (command->priv->working_directory);
- command->priv->working_directory = NULL;
- }
-
- if (working_directory)
- {
- command->priv->working_directory = g_file_dup (working_directory);
- }
-
- g_object_notify (G_OBJECT (command), "working-directory");
-}
-
-GFile *
-gitg_command_get_working_directory (GitgCommand *command)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
-
- if (command->priv->working_directory)
- {
- return g_file_dup (command->priv->working_directory);
- }
- else if (command->priv->repository)
- {
- return gitg_repository_get_work_tree (command->priv->repository);
- }
-
- return NULL;
-}
diff --git a/libgitg/gitg-command.h b/libgitg/gitg-command.h
deleted file mode 100644
index 4fe5924..0000000
--- a/libgitg/gitg-command.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * gitg-command.h
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * gitg 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.
- *
- * gitg 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 gitg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_COMMAND_H__
-#define __GITG_COMMAND_H__
-
-#include <glib-object.h>
-#include <libgitg/gitg-repository.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_COMMAND (gitg_command_get_type ())
-#define GITG_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMAND, GitgCommand))
-#define GITG_COMMAND_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMAND, GitgCommand const))
-#define GITG_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_COMMAND, GitgCommandClass))
-#define GITG_IS_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_COMMAND))
-#define GITG_IS_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_COMMAND))
-#define GITG_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_COMMAND, GitgCommandClass))
-
-typedef struct _GitgCommand GitgCommand;
-typedef struct _GitgCommandClass GitgCommandClass;
-typedef struct _GitgCommandPrivate GitgCommandPrivate;
-
-struct _GitgCommand
-{
- /*< private >*/
- GInitiallyUnowned parent;
-
- GitgCommandPrivate *priv;
-
- /*< public >*/
-};
-
-struct _GitgCommandClass
-{
- /*< private >*/
- GInitiallyUnownedClass parent_class;
-
- /*< public >*/
-};
-
-GType gitg_command_get_type (void) G_GNUC_CONST;
-
-GitgCommand *gitg_command_new (GitgRepository *repository,
- ...) G_GNUC_NULL_TERMINATED;
-GitgCommand *gitg_command_newv (GitgRepository *repository,
- gchar const * const *arguments);
-
-GitgRepository *gitg_command_get_repository (GitgCommand *command);
-
-GFile *gitg_command_get_working_directory (GitgCommand *command);
-void gitg_command_set_working_directory (GitgCommand *command,
- GFile *file);
-
-void gitg_command_set_arguments (GitgCommand *command,
- ...) G_GNUC_NULL_TERMINATED;
-void gitg_command_set_argumentsv (GitgCommand *command,
- gchar const * const *arguments);
-void gitg_command_add_arguments (GitgCommand *command,
- ...) G_GNUC_NULL_TERMINATED;
-void gitg_command_add_argumentsv (GitgCommand *command,
- gchar const * const *arguments);
-
-gchar const * const *gitg_command_get_arguments (GitgCommand *command);
-
-void gitg_command_set_environment (GitgCommand *command,
- ...) G_GNUC_NULL_TERMINATED;
-void gitg_command_set_environmentv (GitgCommand *command,
- gchar const * const *environment);
-void gitg_command_add_environment (GitgCommand *command,
- ...) G_GNUC_NULL_TERMINATED;
-void gitg_command_add_environmentv (GitgCommand *command,
- gchar const * const *environment);
-
-gchar const * const *gitg_command_get_environment (GitgCommand *command);
-
-G_END_DECLS
-
-#endif /* __GITG_COMMAND_H__ */
diff --git a/libgitg/gitg-commit-model.vala b/libgitg/gitg-commit-model.vala
new file mode 100644
index 0000000..87aca7b
--- /dev/null
+++ b/libgitg/gitg-commit-model.vala
@@ -0,0 +1,246 @@
+namespace Gitg
+{
+
+public class CommitModel : Object
+{
+ private Repository d_repository;
+ private Cancellable? d_cancellable;
+ private Gitg.Commit[] d_ids;
+ private unowned Thread<void*>? d_thread;
+ private Ggit.RevisionWalker? d_walker;
+ private uint d_advertized_size;
+ private uint d_idleid;
+
+ public uint limit { get; set; }
+
+ private Ggit.OId[] include { get; set; }
+ private Ggit.OId[] exclude { get; set; }
+
+ public signal void started();
+ public signal void update(uint added);
+ public signal void finished();
+
+ public CommitModel(Repository repository)
+ {
+ d_repository = repository;
+ }
+
+ ~CommitModel()
+ {
+ cancel();
+ }
+
+ private void cancel()
+ {
+ if (d_cancellable == null)
+ {
+ return;
+ }
+
+ d_cancellable.cancel();
+ d_thread.join();
+
+ if (d_idleid != 0)
+ {
+ Source.remove(d_idleid);
+ d_idleid = 0;
+ }
+
+ d_thread = null;
+ d_cancellable = null;
+
+ d_ids = new Gitg.Commit[0];
+ d_advertized_size = 0;
+
+ started();
+ finished();
+ }
+
+ public void reload()
+ {
+ cancel();
+ walk();
+ }
+
+ public uint size()
+ {
+ return d_advertized_size;
+ }
+
+ public new Gitg.Commit? @get(uint idx)
+ {
+ Gitg.Commit? ret;
+
+ if (idx >= d_advertized_size)
+ {
+ return null;
+ }
+
+ lock(d_ids)
+ {
+ ret = d_ids[idx];
+ }
+
+ return ret;
+ }
+
+ private void notify_batch(bool isend)
+ {
+ lock(d_idleid)
+ {
+ if (d_idleid != 0)
+ {
+ Source.remove(d_idleid);
+ d_idleid = 0;
+ }
+ }
+
+ uint newsize = d_ids.length;
+
+ d_idleid = Idle.add(() => {
+ lock(d_idleid)
+ {
+ if (d_idleid == 0)
+ {
+ return false;
+ }
+
+ d_idleid = 0;
+
+ uint added = newsize - d_advertized_size;
+ d_advertized_size = newsize;
+
+ update(added);
+
+ if (isend)
+ {
+ d_thread.join();
+ d_thread = null;
+ d_cancellable = null;
+
+ finished();
+ }
+ }
+
+ return false;
+ });
+ }
+
+ private void walk()
+ {
+ Ggit.OId[] included = include;
+ Ggit.OId[] excluded = exclude;
+
+ d_cancellable = new Cancellable();
+ uint limit = this.limit;
+
+ ThreadFunc<void*> run = () => {
+ if (d_walker == null)
+ {
+ try
+ {
+ d_walker = new Ggit.RevisionWalker(d_repository);
+ }
+ catch
+ {
+ notify_batch(true);
+ return null;
+ }
+ }
+
+ d_walker.reset();
+
+ foreach (Ggit.OId oid in included)
+ {
+ try
+ {
+ d_walker.push(oid);
+ } catch {};
+ }
+
+ foreach (Ggit.OId oid in excluded)
+ {
+ try
+ {
+ d_walker.hide(oid);
+ } catch {};
+ }
+
+ d_walker.set_sort_mode(Ggit.SortMode.TOPOLOGICAL |
+ Ggit.SortMode.TIME);
+
+ uint size;
+
+ // Pre-allocate array to store commits
+ lock(d_ids)
+ {
+ d_ids = new Gitg.Commit[1000];
+
+ size = d_ids.length;
+
+ d_ids.length = 0;
+ d_advertized_size = 0;
+ }
+
+ Timer timer = new Timer();
+
+ while (true)
+ {
+ Ggit.OId? id;
+ Gitg.Commit? commit;
+
+ if (d_cancellable.is_cancelled())
+ {
+ break;
+ }
+
+ try
+ {
+ id = d_walker.next();
+ commit = d_repository.lookup(id, typeof(Gitg.Commit)) as Gitg.Commit;
+ } catch { break; }
+
+ // Add the id
+ if (d_ids.length == size)
+ {
+ lock(d_ids)
+ {
+ size *= 2;
+
+ d_ids.resize((int)size);
+ }
+ }
+
+ d_ids += commit;
+
+ if (timer.elapsed() >= 200)
+ {
+ notify_batch(false);
+ timer.start();
+ }
+
+ if (limit > 0 && d_ids.length == limit)
+ {
+ break;
+ }
+ }
+
+ notify_batch(true);
+ return null;
+ };
+
+ try
+ {
+ d_thread = Thread.create<void*>(run, true);
+ }
+ catch
+ {
+ finished();
+ d_cancellable = null;
+ }
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-commit.c b/libgitg/gitg-commit.c
deleted file mode 100644
index 6b734f1..0000000
--- a/libgitg/gitg-commit.c
+++ /dev/null
@@ -1,1484 +0,0 @@
-/*
- * gitg-commit.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-commit.h"
-#include "gitg-shell.h"
-#include "gitg-changed-file.h"
-#include "gitg-config.h"
-
-#include <string.h>
-
-#define GITG_COMMIT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GITG_TYPE_COMMIT, GitgCommitPrivate))
-
-#define CAN_DELETE_KEY "CanDeleteKey"
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_REPOSITORY
-};
-
-/* Signals */
-enum
-{
- INSERTED,
- REMOVED,
- LAST_SIGNAL
-};
-
-struct _GitgCommitPrivate
-{
- GitgRepository *repository;
- GitgShell *shell;
-
- guint update_id;
- guint end_id;
-
- GHashTable *files;
-};
-
-static guint commit_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (GitgCommit, gitg_commit, G_TYPE_OBJECT)
-
-static void on_changed_file_changed (GitgChangedFile *file, GitgCommit *commit);
-
-GQuark
-gitg_commit_error_quark ()
-{
- static GQuark quark = 0;
-
- if (G_UNLIKELY (quark == 0))
- quark = g_quark_from_string ("gitg_commit_error");
-
- return quark;
-}
-
-static void
-shell_cancel (GitgCommit *commit)
-{
- if (commit->priv->update_id)
- {
- g_signal_handler_disconnect (commit->priv->shell,
- commit->priv->update_id);
- commit->priv->update_id = 0;
- }
-
- if (commit->priv->end_id)
- {
- g_signal_handler_disconnect (commit->priv->shell,
- commit->priv->end_id);
- commit->priv->end_id = 0;
- }
-
- gitg_io_cancel (GITG_IO (commit->priv->shell));
-}
-
-static void
-gitg_commit_finalize (GObject *object)
-{
- GitgCommit *commit = GITG_COMMIT (object);
-
- shell_cancel (commit);
- g_object_unref (commit->priv->shell);
-
- g_hash_table_destroy (commit->priv->files);
-
- G_OBJECT_CLASS (gitg_commit_parent_class)->finalize (object);
-}
-
-static void
-gitg_commit_dispose (GObject *object)
-{
- GitgCommit *self = GITG_COMMIT (object);
-
- if (self->priv->repository)
- {
- g_signal_handlers_disconnect_by_func (self->priv->repository,
- G_CALLBACK (gitg_commit_refresh),
- self);
-
- g_object_unref (self->priv->repository);
- self->priv->repository = NULL;
- }
-}
-
-static void
-gitg_commit_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgCommit *self = GITG_COMMIT (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- g_value_set_object (value, self->priv->repository);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_commit_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgCommit *self = GITG_COMMIT (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- {
- if (self->priv->repository)
- {
- g_object_unref (self->priv->repository);
- }
-
- self->priv->repository = g_value_dup_object (value);
-
- g_signal_connect_swapped (self->priv->repository,
- "load",
- G_CALLBACK (gitg_commit_refresh),
- self);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_commit_class_init (GitgCommitClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = gitg_commit_dispose;
- object_class->finalize = gitg_commit_finalize;
-
- object_class->set_property = gitg_commit_set_property;
- object_class->get_property = gitg_commit_get_property;
-
- g_object_class_install_property (object_class,
- PROP_REPOSITORY,
- g_param_spec_object ("repository",
- "REPOSITORY",
- "Repository",
- GITG_TYPE_REPOSITORY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- commit_signals[INSERTED] =
- g_signal_new ("inserted",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgCommitClass,
- inserted),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- GITG_TYPE_CHANGED_FILE);
-
- commit_signals[REMOVED] =
- g_signal_new ("removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgCommitClass,
- removed),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- GITG_TYPE_CHANGED_FILE);
-
- g_type_class_add_private (object_class, sizeof (GitgCommitPrivate));
-}
-
-static void
-gitg_commit_init (GitgCommit *self)
-{
- self->priv = GITG_COMMIT_GET_PRIVATE (self);
-
- self->priv->shell = gitg_shell_new (10000);
- self->priv->files = g_hash_table_new_full (g_file_hash,
- (GEqualFunc)g_file_equal,
- (GDestroyNotify)g_object_unref,
- (GDestroyNotify)g_object_unref);
-}
-
-GitgCommit *
-gitg_commit_new (GitgRepository *repository)
-{
- return g_object_new (GITG_TYPE_COMMIT, "repository", repository, NULL);
-}
-
-static void
-shell_connect (GitgCommit *commit,
- GCallback updatefunc,
- GCallback endfunc)
-{
- if (commit->priv->update_id)
- {
- g_signal_handler_disconnect (commit->priv->shell,
- commit->priv->update_id);
- commit->priv->update_id = 0;
- }
-
- if (commit->priv->end_id)
- {
- g_signal_handler_disconnect (commit->priv->shell,
- commit->priv->end_id);
- commit->priv->end_id = 0;
- }
-
- if (updatefunc)
- {
- commit->priv->update_id = g_signal_connect (commit->priv->shell,
- "update",
- updatefunc,
- commit);
- }
-
- if (endfunc)
- {
- commit->priv->end_id = g_signal_connect (commit->priv->shell,
- "end",
- endfunc,
- commit);
- }
-}
-
-static void
-update_changed_file_status (GitgChangedFile *file,
- char const *action,
- gchar const *mode)
-{
- GitgChangedFileStatus status;
-
- if (strcmp (action, "D") == 0)
- {
- status = GITG_CHANGED_FILE_STATUS_DELETED;
- }
- else if (strcmp (mode, "000000") == 0)
- {
- status = GITG_CHANGED_FILE_STATUS_NEW;
- }
- else
- {
- status = GITG_CHANGED_FILE_STATUS_MODIFIED;
- }
-
- gitg_changed_file_set_status (file, status);
-}
-
-static void
-add_files (GitgCommit *commit,
- gchar **buffer,
- gboolean cached)
-{
- gchar *line;
-
- while ((line = *buffer++) != NULL)
- {
- gchar **parts = g_strsplit (line, " ", 5);
- guint len = g_strv_length (parts);
-
- gchar **subparts = NULL;
-
- if (len > 4)
- {
- subparts = g_strsplit (parts[4], "\t", 2);
- }
-
- guint sublen = g_strv_length (subparts);
-
- if (len < 5 || sublen < 2)
- {
- g_warning ("Invalid line: %s (%d)", line, len);
- g_strfreev (parts);
- g_strfreev (subparts);
- continue;
- }
-
- /* Also split status and file path now */
-
- gchar const *mode = parts[0] + 1;
- gchar const *sha = parts[2];
-
- GFile *work_tree = gitg_repository_get_work_tree (commit->priv->repository);
- GFile *file = g_file_get_child (work_tree, subparts[1]);
-
- g_object_unref (work_tree);
-
- GitgChangedFile *f = GITG_CHANGED_FILE (g_hash_table_lookup (commit->priv->files,
- file));
-
- if (f)
- {
- GitgChangedFileChanges changes = gitg_changed_file_get_changes (f);
-
- g_object_set_data (G_OBJECT (f), CAN_DELETE_KEY, NULL);
- update_changed_file_status (f, subparts[0], mode);
-
- if (cached)
- {
- gitg_changed_file_set_sha (f, sha);
- gitg_changed_file_set_mode (f, mode);
-
- changes |= GITG_CHANGED_FILE_CHANGES_CACHED;
- }
- else
- {
- changes |= GITG_CHANGED_FILE_CHANGES_UNSTAGED;
- }
-
- gitg_changed_file_set_changes (f, changes);
-
- if ((changes & GITG_CHANGED_FILE_CHANGES_CACHED) &&
- (changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED))
- {
- gitg_changed_file_set_status (f, GITG_CHANGED_FILE_STATUS_MODIFIED);
- }
-
- g_object_unref (file);
- g_strfreev (parts);
- g_strfreev (subparts);
-
- continue;
- }
-
- f = gitg_changed_file_new (file);
- update_changed_file_status (f, subparts[0], mode);
-
- gitg_changed_file_set_sha (f, sha);
- gitg_changed_file_set_mode (f, mode);
-
- GitgChangedFileChanges changes;
-
- changes = cached ? GITG_CHANGED_FILE_CHANGES_CACHED : GITG_CHANGED_FILE_CHANGES_UNSTAGED;
- gitg_changed_file_set_changes (f, changes);
-
- g_hash_table_insert (commit->priv->files, file, f);
-
- g_signal_connect (f, "changed", G_CALLBACK (on_changed_file_changed), commit);
- g_signal_emit (commit, commit_signals[INSERTED], 0, f);
-
- g_strfreev (parts);
- g_strfreev (subparts);
- }
-}
-
-static void
-read_cached_files_update (GitgShell *shell,
- gchar **buffer,
- GitgCommit *commit)
-{
- add_files (commit, buffer, TRUE);
-}
-
-static gboolean
-delete_file (GFile *key,
- GitgChangedFile *value,
- GitgCommit *commit)
-{
- if (!g_object_get_data (G_OBJECT (value), CAN_DELETE_KEY))
- {
- return FALSE;
- }
-
- g_signal_emit (commit, commit_signals[REMOVED], 0, value);
- return TRUE;
-}
-
-static void
-refresh_done (GitgShell *shell,
- gboolean cancelled,
- GitgCommit *commit)
-{
- g_hash_table_foreach_remove (commit->priv->files,
- (GHRFunc)delete_file,
- commit);
-}
-
-static void
-read_unstaged_files_end (GitgShell *shell,
- gboolean cancelled,
- GitgCommit *commit)
-{
- gchar *head = gitg_repository_parse_head (commit->priv->repository);
- gitg_io_cancel (GITG_IO (shell));
-
- shell_connect (commit,
- G_CALLBACK (read_cached_files_update),
- G_CALLBACK (refresh_done));
-
- gitg_shell_run (commit->priv->shell,
- gitg_command_new (commit->priv->repository,
- "diff-index",
- "--no-ext-diff",
- "--cached",
- head,
- NULL),
- NULL);
-
- g_free (head);
-}
-
-static void
-read_unstaged_files_update (GitgShell *shell,
- gchar **buffer,
- GitgCommit *commit)
-{
- add_files (commit, buffer, FALSE);
-}
-
-static void
-read_other_files_end (GitgShell *shell,
- gboolean cancelled,
- GitgCommit *commit)
-{
- gitg_io_cancel (GITG_IO (shell));
-
- shell_connect (commit,
- G_CALLBACK (read_unstaged_files_update),
- G_CALLBACK (read_unstaged_files_end));
-
- gitg_shell_run (commit->priv->shell,
- gitg_command_new (commit->priv->repository,
- "diff-files",
- "--no-ext-diff",
- NULL),
- NULL);
-}
-
-static void
-changed_file_new (GitgChangedFile *f)
-{
- gitg_changed_file_set_status (f, GITG_CHANGED_FILE_STATUS_NEW);
- gitg_changed_file_set_changes (f, GITG_CHANGED_FILE_CHANGES_UNSTAGED);
-
- g_object_set_data (G_OBJECT (f), CAN_DELETE_KEY, NULL);
-}
-
-static void
-read_other_files_update (GitgShell *shell,
- gchar **buffer,
- GitgCommit *commit)
-{
- gchar *line;
-
- while ((line = *buffer++) != NULL)
- {
- /* Skip empty lines */
- if (!*line)
- {
- continue;
- }
-
- /* Check if file is already in our index */
- GFile *work_tree = gitg_repository_get_work_tree (commit->priv->repository);
- GFile *file = g_file_get_child (work_tree, line);
-
- g_object_unref (work_tree);
-
- GitgChangedFile *f = g_hash_table_lookup (commit->priv->files, file);
-
- if (f)
- {
- changed_file_new (f);
- g_object_unref (file);
- continue;
- }
-
- f = gitg_changed_file_new (file);
-
- changed_file_new (f);
- g_hash_table_insert (commit->priv->files, file, f);
-
- g_signal_emit (commit, commit_signals[INSERTED], 0, f);
- }
-}
-
-static void
-update_index_end (GitgShell *shell,
- gboolean cancelled,
- GitgCommit *commit)
-{
- gitg_io_cancel (GITG_IO (shell));
-
- shell_connect (commit,
- G_CALLBACK (read_other_files_update),
- G_CALLBACK (read_other_files_end));
-
- gitg_shell_run (commit->priv->shell,
- gitg_command_new (commit->priv->repository,
- "ls-files",
- "--others",
- "--exclude-standard",
- NULL),
- NULL);
-}
-
-static void
-update_index (GitgCommit *commit)
-{
- shell_connect (commit,
- NULL,
- G_CALLBACK (update_index_end));
-
- gitg_shell_run (commit->priv->shell,
- gitg_command_new (commit->priv->repository,
- "update-index",
- "-q",
- "--unmerged",
- "--ignore-missing",
- "--refresh",
- NULL),
- NULL);
-}
-
-static void
-set_can_delete (GFile *key,
- GitgChangedFile *value,
- GitgCommit *commit)
-{
- g_object_set_data (G_OBJECT (value),
- CAN_DELETE_KEY,
- GINT_TO_POINTER (TRUE));
-
- gitg_changed_file_set_changes (value, GITG_CHANGED_FILE_CHANGES_NONE);
-}
-
-void
-gitg_commit_refresh (GitgCommit *commit)
-{
- g_return_if_fail (GITG_IS_COMMIT (commit));
-
- shell_cancel (commit);
-
- g_hash_table_foreach (commit->priv->files, (GHFunc)set_can_delete, commit);
-
- /* Read other files */
- if (commit->priv->repository)
- {
- update_index (commit);
- }
- else
- {
- refresh_done (commit->priv->shell, FALSE, commit);
- }
-}
-
-static void
-update_index_staged (GitgCommit *commit,
- GitgChangedFile *file)
-{
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
- gchar *head = gitg_repository_parse_head (commit->priv->repository);
- gboolean retval;
- gchar **ret;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "diff-index",
- "--no-ext-diff",
- "--cached",
- head,
- "--",
- path,
- NULL),
- FALSE,
- &ret,
- NULL);
-
- g_free (path);
- g_free (head);
- g_object_unref (f);
-
- if (!retval)
- {
- g_strfreev (ret);
- return;
- }
-
- gchar **parts = *ret ? g_strsplit_set (*ret, " \t", 0) : NULL;
- g_strfreev (ret);
-
- if (parts && g_strv_length (parts) > 2)
- {
- gitg_changed_file_set_mode (file, parts[0] + 1);
- gitg_changed_file_set_sha (file, parts[2]);
-
- gitg_changed_file_set_changes (file,
- gitg_changed_file_get_changes (file) |
- GITG_CHANGED_FILE_CHANGES_CACHED);
-
- update_changed_file_status (file, parts[4], parts[0] + 1);
- }
- else
- {
- gitg_changed_file_set_changes (file,
- gitg_changed_file_get_changes (file) &
- ~GITG_CHANGED_FILE_CHANGES_CACHED);
- }
-
- if (parts)
- {
- g_strfreev (parts);
- }
-}
-
-static void
-update_index_unstaged (GitgCommit *commit,
- GitgChangedFile *file)
-{
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
- gboolean retval;
- gchar **ret;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "diff-files",
- "--no-ext-diff",
- "--",
- path,
- NULL),
- FALSE,
- &ret,
- NULL);
-
- g_free (path);
- g_object_unref (f);
-
- if (retval && ret && *ret)
- {
- gitg_changed_file_set_changes (file,
- gitg_changed_file_get_changes (file) |
- GITG_CHANGED_FILE_CHANGES_UNSTAGED);
- }
- else
- {
- gitg_changed_file_set_changes (file,
- gitg_changed_file_get_changes (file) &
- ~GITG_CHANGED_FILE_CHANGES_UNSTAGED);
- }
-
- g_strfreev (ret);
-}
-
-static void
-update_index_file (GitgCommit *commit,
- GitgChangedFile *file)
-{
- /* update the index */
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
- g_object_unref (f);
-
- gitg_shell_run_sync (gitg_command_new (commit->priv->repository,
- "update-index",
- "-q",
- "--unmerged",
- "--ignore-missing",
- "--refresh",
- NULL),
- NULL);
-
- g_free (path);
-}
-
-static void
-refresh_changes (GitgCommit *commit, GitgChangedFile *file)
-{
- /* update the index */
- update_index_file (commit, file);
-
- /* Determine if it still has staged/unstaged changes */
- update_index_staged (commit, file);
- update_index_unstaged (commit, file);
-
- GitgChangedFileChanges changes = gitg_changed_file_get_changes (file);
- GitgChangedFileStatus status = gitg_changed_file_get_status (file);
-
- if (changes == GITG_CHANGED_FILE_CHANGES_NONE &&
- status == GITG_CHANGED_FILE_STATUS_NONE)
- {
- gitg_changed_file_set_status (file,
- GITG_CHANGED_FILE_STATUS_NEW);
- }
- else if ((changes & GITG_CHANGED_FILE_CHANGES_CACHED) &&
- (changes & GITG_CHANGED_FILE_CHANGES_UNSTAGED))
- {
- gitg_changed_file_set_status (file,
- GITG_CHANGED_FILE_STATUS_MODIFIED);
- }
-
- if (status == GITG_CHANGED_FILE_STATUS_NEW &&
- !(changes & GITG_CHANGED_FILE_CHANGES_CACHED))
- {
- gitg_changed_file_set_changes (file,
- GITG_CHANGED_FILE_CHANGES_UNSTAGED);
- }
-}
-
-static gboolean
-apply_hunk (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- gboolean reverse,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMIT (commit), FALSE);
- g_return_val_if_fail (GITG_IS_CHANGED_FILE (file), FALSE);
-
- g_return_val_if_fail (hunk != NULL, FALSE);
-
- gboolean ret = gitg_shell_run_sync_with_input (gitg_command_new (commit->priv->repository,
- "apply",
- "--cached",
- reverse ? "--reverse" : NULL,
- NULL),
- hunk,
- error);
-
- if (ret)
- {
- refresh_changes (commit, file);
- }
-
- return ret;
-}
-
-gboolean
-gitg_commit_stage (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- GError **error)
-{
- if (hunk)
- {
- return apply_hunk (commit, file, hunk, FALSE, error);
- }
-
- /* Otherwise, stage whole file */
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
- g_object_unref (f);
-
- gboolean ret = gitg_shell_run_sync (gitg_command_new (commit->priv->repository,
- "update-index",
- "--add",
- "--remove",
- "--",
- path,
- NULL),
- error);
- g_free (path);
-
- if (ret)
- {
- refresh_changes (commit, file);
- }
- else
- {
- g_error ("Update index for stage failed");
- }
-
- return ret;
-}
-
-gboolean
-gitg_commit_unstage (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- GError **error)
-{
- if (hunk)
- {
- return apply_hunk (commit, file, hunk, TRUE, error);
- }
-
- /* Otherwise, unstage whole file */
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
- g_object_unref (f);
-
- gchar *input = g_strdup_printf ("%s %s\t%s\n",
- gitg_changed_file_get_mode (file),
- gitg_changed_file_get_sha (file),
- path);
-
- gboolean ret = gitg_shell_run_sync_with_input (gitg_command_new (commit->priv->repository,
- "update-index",
- "--index-info",
- NULL),
- input,
- error);
-
- g_free (input);
-
- if (ret)
- {
- refresh_changes (commit, file);
- }
- else
- {
- g_error ("Update index for unstage failed");
- }
-
- return ret;
-}
-
-static void
-find_staged (GFile *key,
- GitgChangedFile *value,
- gboolean *result)
-{
- if (*result)
- {
- return;
- }
-
- *result = (gitg_changed_file_get_changes (value) &
- GITG_CHANGED_FILE_CHANGES_CACHED);
-}
-
-gboolean
-gitg_commit_has_changes (GitgCommit *commit)
-{
- g_return_val_if_fail (GITG_IS_COMMIT (commit), FALSE);
- gboolean result = FALSE;
-
- g_hash_table_foreach (commit->priv->files, (GHFunc)find_staged, &result);
- return result;
-}
-
-static gchar *
-comment_parse_subject (gchar const *comment)
-{
- gchar *ptr;
- gchar *subject;
-
- if ((ptr = g_utf8_strchr (comment, g_utf8_strlen (comment, -1), '\n')) != NULL)
- {
- subject = g_strndup (comment, ptr - comment);
- }
- else
- {
- subject = g_strdup (comment);
- }
-
- gchar *commit = g_strconcat ("commit:", subject, NULL);
- g_free (subject);
-
- return commit;
-}
-
-static gboolean
-write_tree (GitgCommit *commit, gchar **tree, GError **error)
-{
- gchar **lines;
- gboolean retval;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "write-tree",
- NULL),
- FALSE,
- &lines,
- error);
-
- if (!retval || !lines || strlen (*lines) != GITG_HASH_SHA_SIZE)
- {
- g_strfreev (lines);
- return FALSE;
- }
-
- *tree = g_strdup (*lines);
- g_strfreev (lines);
-
- return TRUE;
-}
-
-static gchar *
-get_signed_off_line (GitgCommit *commit)
-{
- gchar **user;
- gboolean retval;
- gchar **email;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "config",
- "--get",
- "user.name",
- NULL),
- FALSE,
- &user,
- NULL);
-
- if (!retval || !user)
- {
- return NULL;
- }
-
- if (!*user || !**user)
- {
- g_strfreev (user);
- return NULL;
- }
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "config",
- "--get",
- "user.email",
- NULL),
- FALSE,
- &email,
- NULL);
-
- if (!retval || !email)
- {
- g_strfreev (user);
- return NULL;
- }
-
- if (!*email || !**email)
- {
- g_strfreev (user);
- g_strfreev (email);
-
- return NULL;
- }
-
- gchar *ret = g_strdup_printf ("Signed-off-by: %s <%s>", *user, *email);
- g_strfreev (user);
- g_strfreev (email);
-
- return ret;
-}
-
-static void
-set_amend_environment (GitgCommit *commit,
- GitgCommand *command)
-{
- gchar **out;
- gboolean retval;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "cat-file",
- "commit",
- "HEAD",
- NULL),
- FALSE,
- &out,
- NULL);
-
- if (!retval)
- {
- g_strfreev (out);
- return;
- }
-
- // Parse author
- GRegex *r = g_regex_new ("^author (.*) < ([^>]*)> ([0-9]+.*)$",
- G_REGEX_CASELESS,
- 0,
- NULL);
-
- GMatchInfo *info = NULL;
- gchar **ptr = out;
-
- while (ptr && *ptr)
- {
- if (g_regex_match (r, *ptr, 0, &info))
- {
- gchar *name = g_match_info_fetch (info, 1);
- gchar *email = g_match_info_fetch (info, 2);
- gchar *date = g_match_info_fetch (info, 3);
-
- gitg_command_add_environment (command, "GIT_AUTHOR_NAME", name, NULL);
- gitg_command_add_environment (command, "GIT_AUTHOR_EMAIL", email, NULL);
- gitg_command_add_environment (command, "GIT_AUTHOR_DATE", date, NULL);
-
- g_free (name);
- g_free (email);
- g_free (date);
-
- break;
- }
-
- ++ptr;
- }
-
- g_strfreev (out);
-}
-
-static gchar *
-convert_commit_encoding (GitgCommit *commit,
- gchar const *s)
-{
- GitgConfig *config;
- gchar *encoding;
- gchar *ret;
-
- config = gitg_config_new (commit->priv->repository);
- encoding = gitg_config_get_value (config, "i18n.commitencoding");
-
- if (!encoding || !*encoding)
- {
- g_object_unref (config);
- g_free (encoding);
-
- config = gitg_config_new (NULL);
-
- encoding = gitg_config_get_value (config, "i18n.commitencoding");
- }
-
- g_object_unref (config);
-
- if (!encoding || !*encoding || g_ascii_strcasecmp (encoding, "UTF-8") == 0)
- {
- g_free (encoding);
- return g_strdup (s);
- }
-
- // Try to convert from UTF-8 to 'encoding'
- ret = g_convert (s, -1, encoding, "UTF-8", NULL, NULL, NULL);
-
- if (!ret)
- {
- // Just use 's' then, even if it is UTF-8...
- ret = g_strdup (s);
- }
-
- g_free (encoding);
- return ret;
-}
-
-static gboolean
-commit_tree (GitgCommit *commit,
- gchar const *tree,
- gchar const *comment,
- gboolean signoff,
- gboolean amend,
- gchar **ref,
- GError **error)
-{
- gchar *fullcomment;
- gboolean retval;
-
- if (signoff)
- {
- gchar *line = get_signed_off_line (commit);
-
- if (!line)
- {
- if (error)
- {
- g_set_error (error,
- GITG_COMMIT_ERROR,
- GITG_COMMIT_ERROR_SIGNOFF,
- "Could not retrieve user name or email for signoff message");
- }
-
- return FALSE;
- }
-
- fullcomment = g_strconcat (comment, "\n\n", line, NULL);
- }
- else
- {
- fullcomment = g_strdup (comment);
- }
-
- gchar *head;
-
- if (amend)
- {
- head = gitg_repository_parse_ref (commit->priv->repository,
- "HEAD^");
- }
- else
- {
- head = gitg_repository_parse_ref (commit->priv->repository,
- "HEAD");
- }
-
- GitgCommand *command;
- gchar **buffer;
-
- command = gitg_command_new (commit->priv->repository,
- "commit-tree",
- tree,
- head ? "-p" : NULL,
- head,
- NULL);
-
- if (amend)
- {
- set_amend_environment (commit, command);
- }
-
- gchar *converted = convert_commit_encoding (commit, fullcomment);
-
- retval = gitg_shell_run_sync_with_input_and_output (command,
- FALSE,
- converted,
- &buffer,
- error);
-
- g_free (head);
- g_free (fullcomment);
- g_free (converted);
- g_object_unref (command);
-
- if (!retval || !buffer || !*buffer || strlen (*buffer) != GITG_HASH_SHA_SIZE)
- {
- g_strfreev (buffer);
- return FALSE;
- }
-
- *ref = g_strdup (*buffer);
- g_strfreev (buffer);
-
- return TRUE;
-}
-
-static gboolean
-update_ref (GitgCommit *commit,
- gchar const *ref,
- gchar const *subject,
- GError **error)
-{
- gchar *converted = convert_commit_encoding (commit, subject);
-
- gboolean ret = gitg_shell_run_sync (gitg_command_new (commit->priv->repository,
- "update-ref",
- "-m",
- converted,
- "HEAD",
- ref,
- NULL),
- error);
- g_free (converted);
-
- return ret;
-}
-
-gboolean
-gitg_commit_commit (GitgCommit *commit,
- gchar const *comment,
- gboolean signoff,
- gboolean amend,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMIT (commit), FALSE);
-
- gchar *tree;
-
- if (!gitg_repository_run_hook (commit->priv->repository,
- "pre-commit",
- error,
- NULL))
- {
- return FALSE;
- }
-
- if (!write_tree (commit, &tree, error))
- {
- return FALSE;
- }
-
- GFile *git_dir = gitg_repository_get_git_dir (commit->priv->repository);
- GFile *child = g_file_get_child (git_dir, "COMMIT_EDITMSG");
- gchar *path = g_file_get_path (child);
-
- g_object_unref (git_dir);
- g_object_unref (child);
-
- g_file_set_contents (path, comment, -1, NULL);
-
- if (!gitg_repository_run_hook (commit->priv->repository,
- "commit-msg",
- error,
- path,
- NULL))
- {
- g_free (path);
- return FALSE;
- }
-
- g_free (path);
-
- gchar *ref;
- gboolean ret = commit_tree (commit, tree, comment, signoff, amend, &ref, error);
- g_free (tree);
-
- if (!ret)
- {
- return FALSE;
- }
-
- gchar *subject = comment_parse_subject (comment);
- ret = update_ref (commit, ref, subject, error);
- g_free (subject);
-
- if (!ret)
- {
- return FALSE;
- }
-
- gitg_repository_run_hook (commit->priv->repository,
- "post-commit",
- NULL,
- NULL);
-
- gitg_repository_reload (commit->priv->repository);
- return TRUE;
-}
-
-static void
-remove_file (GitgCommit *commit,
- GitgChangedFile *file)
-{
- GFile *f = gitg_changed_file_get_file (file);
-
- g_hash_table_remove (commit->priv->files, f);
- g_object_unref (f);
-
- g_signal_emit (commit, commit_signals[REMOVED], 0, file);
-}
-
-gboolean
-gitg_commit_revert (GitgCommit *commit,
- GitgRevision *from,
- GitgRevision *to,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMIT (commit), FALSE);
- g_return_val_if_fail (from != NULL, FALSE);
- g_return_val_if_fail (to != NULL, FALSE);
-
- return FALSE;
-
- // TODO
- /*gchar *sha1from = gitg_revision_get_sha1 (from);
- gchar *sha1to = gitg_revision_get_sha1 (to);
-
- gitg_repository_command_with_outputv (commit->priv->repository,
- error,
- "diff",
- "--full-index",
- "--binary",
- "--no-color",
- sha1to,
- sha1from,
- NULL)
- git diff --full-index --binary --no-color to from*/
-}
-
-gboolean
-gitg_commit_undo (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- GError **error)
-{
- gboolean ret;
-
- if (!hunk)
- {
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
-
- ret = gitg_shell_run_sync_with_input (gitg_command_new (commit->priv->repository,
- "checkout-index",
- "--index",
- "--quiet",
- "--force",
- "--stdin",
- NULL),
- path,
- error);
-
- g_free (path);
-
- update_index_file (commit, file);
- update_index_unstaged (commit, file);
- g_object_unref (f);
- }
- else
- {
- ret = gitg_shell_run_sync_with_input (gitg_command_new (commit->priv->repository,
- "apply",
- "-R",
- "-",
- NULL),
- hunk,
- error);
-
- update_index_file (commit, file);
- update_index_unstaged (commit, file);
- }
-
- return ret;
-}
-
-gboolean
-gitg_commit_add_ignore (GitgCommit *commit,
- GitgChangedFile *file,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMIT (commit), FALSE);
- g_return_val_if_fail (GITG_IS_CHANGED_FILE (file), FALSE);
-
- GFile *f = gitg_changed_file_get_file (file);
- gchar *path = gitg_repository_relative (commit->priv->repository, f);
-
- GFile *git_dir = gitg_repository_get_work_tree (commit->priv->repository);
- GFile *ignore = g_file_get_child (git_dir, ".gitignore");
-
- GFileOutputStream *stream = g_file_append_to (ignore,
- G_FILE_CREATE_NONE,
- NULL,
- error);
- gboolean ret = FALSE;
-
- g_object_unref (git_dir);
- g_object_unref (ignore);
-
- if (stream)
- {
- gchar *line = g_strdup_printf ("/%s\n", path);
-
- ret = g_output_stream_write_all (G_OUTPUT_STREAM (stream),
- line,
- strlen (line),
- NULL,
- NULL,
- error);
-
- g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
-
- g_object_unref (stream);
- g_free (line);
- }
-
- if (ret)
- {
- remove_file (commit, file);
- }
-
- g_object_unref (f);
- g_free (path);
-
- return ret;
-}
-
-static void
-on_changed_file_changed (GitgChangedFile *file,
- GitgCommit *commit)
-{
- refresh_changes (commit, file);
-}
-
-GitgChangedFile *
-gitg_commit_find_changed_file (GitgCommit *commit,
- GFile *file)
-{
- g_return_val_if_fail (GITG_IS_COMMIT (commit), NULL);
- g_return_val_if_fail (G_IS_FILE (file), NULL);
-
- GitgChangedFile *f = g_hash_table_lookup (commit->priv->files, file);
-
- if (f != NULL)
- {
- return g_object_ref (f);
- }
- else
- {
- return NULL;
- }
-}
-
-gchar *
-gitg_commit_amend_message (GitgCommit *commit)
-{
- gchar **out;
- gboolean retval;
-
- g_return_val_if_fail (GITG_IS_COMMIT (commit), NULL);
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
- "cat-file",
- "commit",
- "HEAD",
- NULL),
- FALSE,
- &out,
- NULL);
-
- gchar *ret = NULL;
-
- if (retval && out)
- {
- gchar **ptr = out;
-
- while (*ptr)
- {
- if (!**ptr)
- {
- ++ptr;
- break;
- }
-
- ++ptr;
- }
-
- if (*ptr && **ptr)
- {
- GString *buffer = g_string_new ("");
-
- while (*ptr)
- {
- if (buffer->len != 0)
- {
- g_string_append_c (buffer, '\n');
- }
-
- g_string_append (buffer, *ptr);
- ++ptr;
- }
-
- ret = g_string_free (buffer, FALSE);
- }
- }
-
- g_strfreev (out);
- return ret;
-}
diff --git a/libgitg/gitg-commit.h b/libgitg/gitg-commit.h
deleted file mode 100644
index 66a62d1..0000000
--- a/libgitg/gitg-commit.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * gitg-commit.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_COMMIT_H__
-#define __GITG_COMMIT_H__
-
-#include <glib-object.h>
-#include <libgitg/gitg-repository.h>
-#include <libgitg/gitg-changed-file.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_COMMIT (gitg_commit_get_type ())
-#define GITG_COMMIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMIT, GitgCommit))
-#define GITG_COMMIT_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMIT, GitgCommit const))
-#define GITG_COMMIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_COMMIT, GitgCommitClass))
-#define GITG_IS_COMMIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_COMMIT))
-#define GITG_IS_COMMIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_COMMIT))
-#define GITG_COMMIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_COMMIT, GitgCommitClass))
-
-#define GITG_COMMIT_ERROR (gitg_commit_error_quark())
-
-typedef struct _GitgCommit GitgCommit;
-typedef struct _GitgCommitClass GitgCommitClass;
-typedef struct _GitgCommitPrivate GitgCommitPrivate;
-
-typedef enum
-{
- GITG_COMMIT_ERROR_NONE = 0,
- GITG_COMMIT_ERROR_SIGNOFF,
- GITG_COMMIT_ERROR_MERGE
-} GitgCommitError;
-
-struct _GitgCommit {
- GObject parent;
-
- GitgCommitPrivate *priv;
-};
-
-struct _GitgCommitClass {
- GObjectClass parent_class;
-
- void (*inserted) (GitgCommit *commit, GitgChangedFile *file);
- void (*removed) (GitgCommit *commit, GitgChangedFile *file);
-};
-
-GQuark gitg_commit_error_quark (void);
-
-GType gitg_commit_get_type (void) G_GNUC_CONST;
-GitgCommit *gitg_commit_new (GitgRepository *repository);
-
-void gitg_commit_refresh (GitgCommit *commit);
-gboolean gitg_commit_stage (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- GError **error);
-gboolean gitg_commit_unstage (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- GError **error);
-gboolean gitg_commit_has_changes (GitgCommit *commit);
-gboolean gitg_commit_commit (GitgCommit *commit,
- gchar const *comment,
- gboolean signoff,
- gboolean amend,
- GError **error);
-
-gboolean gitg_commit_revert (GitgCommit *commit,
- GitgRevision *from,
- GitgRevision *to,
- GError **error);
-
-gboolean gitg_commit_undo (GitgCommit *commit,
- GitgChangedFile *file,
- gchar const *hunk,
- GError **error);
-
-gboolean gitg_commit_add_ignore (GitgCommit *commit,
- GitgChangedFile *file,
- GError **error);
-
-GitgChangedFile *gitg_commit_find_changed_file (GitgCommit *commit,
- GFile *file);
-
-gchar *gitg_commit_amend_message (GitgCommit *commit);
-
-G_END_DECLS
-
-#endif /* __GITG_COMMIT_H__ */
diff --git a/libgitg/gitg-commit.vala b/libgitg/gitg-commit.vala
new file mode 100644
index 0000000..ff67a22
--- /dev/null
+++ b/libgitg/gitg-commit.vala
@@ -0,0 +1,90 @@
+namespace Gitg
+{
+
+public class Commit : Ggit.Commit
+{
+ public Lane.Tag tag { get; set; }
+ public unowned SList<Lane> lanes { get; set; }
+
+ private ushort d_mylane;
+
+ public ushort mylane
+ {
+ get { return d_mylane; }
+ set
+ {
+ d_mylane = value;
+ update_lane_tag();
+ }
+ }
+
+ public unowned Lane lane
+ {
+ get { return lanes.nth_data(d_mylane); }
+ }
+
+ public unowned SList<Lane> remove_lane(Lane lane)
+ {
+ lanes.remove(lane);
+ return lanes;
+ }
+
+ private void update_lane_tag()
+ {
+ unowned Lane? lane = lanes.nth_data(d_mylane);
+
+ if (lane == null)
+ {
+ return;
+ }
+
+ lane.tag &= ~(Lane.Tag.SIGN_STASH |
+ Lane.Tag.SIGN_STAGED |
+ Lane.Tag.SIGN_UNSTAGED) | tag;
+ }
+
+ public void update_lanes(SList<Lane> lanes, int mylane)
+ {
+ this.lanes = lanes;
+
+ if (mylane >= 0)
+ {
+ d_mylane = (ushort)mylane;
+ }
+
+ update_lane_tag();
+ }
+
+ public string format_patch_name
+ {
+ owned get
+ {
+ return get_subject().replace(" ", "-").replace("/", "-");;
+ }
+ }
+
+ private string date_for_display(DateTime dt)
+ {
+ return dt.format("%c");
+ }
+
+ public string committer_date_for_display
+ {
+ owned get
+ {
+ return date_for_display(get_committer().get_time());
+ }
+ }
+
+ public string author_date_for_display
+ {
+ owned get
+ {
+ return date_for_display(get_author().get_time());
+ }
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-config.c b/libgitg/gitg-config.c
deleted file mode 100644
index 56d2f32..0000000
--- a/libgitg/gitg-config.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * gitg-config.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-config.h"
-#include "gitg-shell.h"
-#include "gitg-debug.h"
-
-#define GITG_CONFIG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_CONFIG, GitgConfigPrivate))
-
-enum
-{
- PROP_0,
- PROP_REPOSITORY
-};
-
-struct _GitgConfigPrivate
-{
- GitgRepository *repository;
- GitgShell *shell;
-
- GString *accumulated;
-};
-
-G_DEFINE_TYPE (GitgConfig, gitg_config, G_TYPE_OBJECT)
-
-static void
-gitg_config_finalize (GObject *object)
-{
- GitgConfig *config = GITG_CONFIG (object);
-
- if (config->priv->repository)
- {
- g_object_unref(config->priv->repository);
- }
-
- g_string_free (config->priv->accumulated, TRUE);
-
- G_OBJECT_CLASS (gitg_config_parent_class)->finalize (object);
-}
-
-static void
-gitg_config_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- GitgConfig *self = GITG_CONFIG (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- if (self->priv->repository)
- {
- g_object_unref(self->priv->repository);
- }
-
- self->priv->repository = GITG_REPOSITORY (g_value_dup_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_config_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- GitgConfig *self = GITG_CONFIG (object);
-
- switch (prop_id)
- {
- case PROP_REPOSITORY:
- g_value_set_object (value, self->priv->repository);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_config_class_init (GitgConfigClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_config_finalize;
- object_class->get_property = gitg_config_get_property;
- object_class->set_property = gitg_config_set_property;
-
- g_object_class_install_property(object_class, PROP_REPOSITORY,
- g_param_spec_object("repository",
- "REPOSITORY",
- "The repository",
- GITG_TYPE_REPOSITORY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_type_class_add_private (object_class, sizeof(GitgConfigPrivate));
-}
-
-static void
-gitg_config_accumulate (GitgShell *shell,
- gchar **buffer,
- GitgConfig *config)
-{
- gchar **ptr = buffer;
-
- while (*ptr)
- {
- g_string_append (config->priv->accumulated, *ptr);
- ++ptr;
- }
-}
-
-static void
-gitg_config_begin (GitgShell *shell,
- GitgConfig *config)
-{
- g_string_erase (config->priv->accumulated, 0, -1);
-}
-
-static void
-gitg_config_init (GitgConfig *self)
-{
- self->priv = GITG_CONFIG_GET_PRIVATE (self);
-
- self->priv->shell = gitg_shell_new_synchronized (1000);
- gitg_shell_set_preserve_line_endings (self->priv->shell, TRUE);
-
- self->priv->accumulated = g_string_new ("");
-
- g_signal_connect (self->priv->shell,
- "update",
- G_CALLBACK (gitg_config_accumulate),
- self);
-
- g_signal_connect (self->priv->shell,
- "begin",
- G_CALLBACK (gitg_config_begin),
- self);
-}
-
-GitgConfig *
-gitg_config_new (GitgRepository *repository)
-{
- return g_object_new (GITG_TYPE_CONFIG, "repository", repository, NULL);
-}
-
-static gchar *
-get_value_process (GitgConfig *config, gboolean ret)
-{
- gchar *res;
-
- if (ret)
- {
- res = g_strndup (config->priv->accumulated->str,
- config->priv->accumulated->len);
- }
- else
- {
- res = NULL;
- }
-
- return res;
-}
-
-static gchar *
-get_value_global (GitgConfig *config, gchar const *key)
-{
- GError *error = NULL;
-
- gboolean ret;
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (NULL,
- "git",
- "config",
- "--global",
- key,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to get config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- return get_value_process (config, ret);
-}
-
-static gchar *
-get_value_global_regex (GitgConfig *config,
- gchar const *regex,
- gchar const *value_regex)
-{
- GError *error = NULL;
-
- gboolean ret;
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (NULL,
- "git",
- "config",
- "--global",
- "--get-regexp",
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to get config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- return get_value_process (config, ret);
-}
-
-static gchar *
-get_value_local (GitgConfig *config, gchar const *key)
-{
- gboolean ret;
- GFile *git_dir;
- GFile *cfg_file;
- gchar *cfg;
- GError *error = NULL;
-
- git_dir = gitg_repository_get_git_dir (config->priv->repository);
-
- cfg_file = g_file_get_child (git_dir, "config");
- cfg = g_file_get_path (cfg_file);
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (config->priv->repository,
- "config",
- "--file",
- cfg,
- key,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to get config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- g_free (cfg);
-
- g_object_unref (cfg_file);
- g_object_unref (git_dir);
-
- return get_value_process (config, ret);
-}
-
-static gchar *
-get_value_local_regex (GitgConfig *config,
- gchar const *regex,
- gchar const *value_regex)
-{
- gboolean ret;
- GFile *git_dir;
- GFile *cfg_file;
- gchar *cfg;
- GError *error = NULL;
-
- git_dir = gitg_repository_get_git_dir (config->priv->repository);
-
- cfg_file = g_file_get_child (git_dir, "config");
- cfg = g_file_get_path (cfg_file);
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (config->priv->repository,
- "config",
- "--file",
- cfg,
- "--get-regexp",
- regex,
- value_regex,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to get config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- g_free (cfg);
-
- g_object_unref (cfg_file);
- g_object_unref (git_dir);
-
- return get_value_process (config, ret);
-}
-
-static gboolean
-set_value_global (GitgConfig *config, gchar const *key, gchar const *value)
-{
- GError *error = NULL;
- gboolean ret;
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (NULL,
- "git",
- "config",
- "--global",
- value == NULL ? "--unset" : key,
- value == NULL ? key : value,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to get config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- return ret;
-}
-
-static gboolean
-set_value_local (GitgConfig *config, gchar const *key, gchar const *value)
-{
- gboolean ret;
- GFile *git_dir;
- GFile *cfg_file;
- gchar *cfg;
- GError *error = NULL;
-
- git_dir = gitg_repository_get_git_dir (config->priv->repository);
-
- cfg_file = g_file_get_child (git_dir, "config");
- cfg = g_file_get_path (cfg_file);
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (config->priv->repository,
- "config",
- "--file",
- cfg,
- value == NULL ? "--unset" : key,
- value == NULL ? key : value,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to set config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- g_free (cfg);
-
- g_object_unref (cfg_file);
- g_object_unref (git_dir);
-
- return ret;
-}
-
-static gboolean
-rename_global (GitgConfig *config, gchar const *old, gchar const *nw)
-{
- gboolean ret;
- GError *error = NULL;
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (NULL,
- "git",
- "config",
- "--global",
- "--rename-section",
- old,
- nw,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to rename config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- return ret;
-}
-
-static gboolean
-rename_local (GitgConfig *config, gchar const *old, gchar const *nw)
-{
- gboolean ret;
- GFile *git_dir;
- GFile *cfg_file;
- gchar *cfg;
- GError *error = NULL;
-
- git_dir = gitg_repository_get_git_dir (config->priv->repository);
-
- cfg_file = g_file_get_child (git_dir, "config");
- cfg = g_file_get_path (cfg_file);
-
- ret = gitg_shell_run (config->priv->shell,
- gitg_command_new (config->priv->repository,
- "config",
- "--file",
- cfg,
- "--rename-section",
- old,
- nw,
- NULL),
- &error);
-
- if (error)
- {
- gitg_debug (GITG_DEBUG_CONFIG,
- "Failed to rename config: %s",
- error->message);
-
- g_error_free (error);
- }
-
- g_free (cfg);
-
- g_object_unref (cfg_file);
- g_object_unref (git_dir);
-
- return ret;
-}
-
-gchar *
-gitg_config_get_value (GitgConfig *config, gchar const *key)
-{
- g_return_val_if_fail (GITG_IS_CONFIG (config), NULL);
- g_return_val_if_fail (key != NULL, NULL);
-
- if (config->priv->repository != NULL)
- {
- return get_value_local (config, key);
- }
- else
- {
- return get_value_global (config, key);
- }
-}
-
-gchar *
-gitg_config_get_value_regex (GitgConfig *config,
- gchar const *regex,
- gchar const *value_regex)
-{
- g_return_val_if_fail (GITG_IS_CONFIG (config), NULL);
- g_return_val_if_fail (regex != NULL, NULL);
-
- if (config->priv->repository != NULL)
- {
- return get_value_local_regex (config, regex, value_regex);
- }
- else
- {
- return get_value_global_regex (config, regex, value_regex);
- }
-}
-
-gboolean
-gitg_config_set_value (GitgConfig *config, gchar const *key, gchar const *value)
-{
- g_return_val_if_fail (GITG_IS_CONFIG (config), FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
-
- if (config->priv->repository != NULL)
- {
- return set_value_local (config, key, value);
- }
- else
- {
- return set_value_global (config, key, value);
- }
-}
-
-gboolean
-gitg_config_rename (GitgConfig *config, gchar const *old, gchar const *nw)
-{
- g_return_val_if_fail (GITG_IS_CONFIG (config), FALSE);
- g_return_val_if_fail (old != NULL, FALSE);
- g_return_val_if_fail (nw != NULL, FALSE);
-
- if (config->priv->repository != NULL)
- {
- return rename_local (config, old, nw);
- }
- else
- {
- return rename_global (config, old, nw);
- }
-}
diff --git a/libgitg/gitg-config.h b/libgitg/gitg-config.h
deleted file mode 100644
index a68363e..0000000
--- a/libgitg/gitg-config.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * gitg-config.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_CONFIG_H__
-#define __GITG_CONFIG_H__
-
-#include <glib-object.h>
-#include <libgitg/gitg-repository.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_CONFIG (gitg_config_get_type ())
-#define GITG_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CONFIG, GitgConfig))
-#define GITG_CONFIG_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CONFIG, GitgConfig const))
-#define GITG_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_CONFIG, GitgConfigClass))
-#define GITG_IS_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_CONFIG))
-#define GITG_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_CONFIG))
-#define GITG_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_CONFIG, GitgConfigClass))
-
-typedef struct _GitgConfig GitgConfig;
-typedef struct _GitgConfigClass GitgConfigClass;
-typedef struct _GitgConfigPrivate GitgConfigPrivate;
-
-struct _GitgConfig
-{
- GObject parent;
-
- GitgConfigPrivate *priv;
-};
-
-struct _GitgConfigClass
-{
- GObjectClass parent_class;
-};
-
-GType gitg_config_get_type (void) G_GNUC_CONST;
-GitgConfig *gitg_config_new (GitgRepository *repository);
-
-gchar *gitg_config_get_value (GitgConfig *config,
- gchar const *key);
-
-gchar *gitg_config_get_value_regex (GitgConfig *config,
- gchar const *regex,
- gchar const *value_regex);
-
-gboolean gitg_config_rename (GitgConfig *config,
- gchar const *old,
- gchar const *nw);
-
-gboolean gitg_config_set_value (GitgConfig *config,
- gchar const *key,
- gchar const *value);
-
-G_END_DECLS
-
-#endif /* __GITG_CONFIG_H__ */
diff --git a/libgitg/gitg-convert.c b/libgitg/gitg-convert.c
deleted file mode 100644
index 4978410..0000000
--- a/libgitg/gitg-convert.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * gitg-convert.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-convert.h"
-
-#include <string.h>
-
-static void
-utf8_validate_fallback (gchar *text,
- gssize size)
-{
- gchar const *end;
-
- while (!g_utf8_validate (text, size, &end))
- {
- *((gchar *)end) = '?';
- }
-}
-
-static gchar *
-convert_fallback (gchar const *text,
- gssize size,
- gchar const *fallback)
-{
- gchar *res;
- gsize read, written;
- GString *str = g_string_new ("");
-
- while ((res = g_convert(text,
- size,
- "UTF-8",
- "ASCII",
- &read,
- &written,
- NULL)) == NULL)
- {
- res = g_convert (text, read, "UTF-8", "ASCII", NULL, NULL, NULL);
- str = g_string_append (str, res);
-
- str = g_string_append (str, fallback);
- text = text + read + 1;
- size = size - read;
- }
-
- str = g_string_append (str, res);
- g_free (res);
-
- utf8_validate_fallback (str->str, str->len);
- return g_string_free (str, FALSE);
-}
-
-gchar *
-gitg_convert_utf8 (gchar const *str, gssize size)
-{
- static gchar *encodings[] = {
- "ISO-8859-15",
- "ASCII"
- };
-
- if (str == NULL)
- {
- return NULL;
- }
-
- if (size == -1)
- {
- size = strlen (str);
- }
-
- if (g_utf8_validate (str, size, NULL))
- {
- return g_strndup (str, size);
- }
-
- int i;
- for (i = 0; i < sizeof (encodings) / sizeof (gchar *); ++i)
- {
- gsize read;
- gsize written;
-
- gchar *ret = g_convert (str,
- size,
- "UTF-8",
- encodings[i],
- &read,
- &written,
- NULL);
-
- if (ret && read == size)
- {
- utf8_validate_fallback (ret, written);
- return ret;
- }
-
- g_free (ret);
- }
-
- return convert_fallback (str, size, "?");
-}
diff --git a/libgitg/gitg-convert.h b/libgitg/gitg-convert.h
deleted file mode 100644
index 614d26b..0000000
--- a/libgitg/gitg-convert.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * gitg-convert.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_CONVERT_H__
-#define __GITG_CONVERT_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-gchar *gitg_convert_utf8 (gchar const *str, gssize size);
-
-G_END_DECLS
-
-#endif /* __GITG_CONVERT_H__ */
diff --git a/libgitg/gitg-debug.c b/libgitg/gitg-debug.c
deleted file mode 100644
index 6530e7a..0000000
--- a/libgitg/gitg-debug.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * gitg-debug.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-debug.h"
-#include <glib.h>
-#include <stdio.h>
-
-static guint debug_enabled = GITG_DEBUG_NONE;
-
-#define DEBUG_FROM_ENV(name) \
- { \
- if (g_getenv(#name)) \
- { \
- debug_enabled |= name; \
- } \
- }
-
-void
-gitg_debug_init (void)
-{
- DEBUG_FROM_ENV (GITG_DEBUG_SHELL);
- DEBUG_FROM_ENV (GITG_DEBUG_SHELL_OUTPUT);
- DEBUG_FROM_ENV (GITG_DEBUG_CHARSET_CONVERSION);
- DEBUG_FROM_ENV (GITG_DEBUG_CONFIG);
-}
-
-gboolean
-gitg_debug_enabled (guint debug)
-{
- return debug_enabled & debug;
-}
-
-void
-gitg_debug_message (guint level,
- gchar const *file,
- gint line,
- gchar const *function,
- gchar const *format,
- ...)
-{
- if (G_UNLIKELY (debug_enabled & level))
- {
- va_list ap;
- gchar *msg;
-
- va_start (ap, format);
- msg = g_strdup_vprintf (format, ap);
- va_end (ap);
-
- g_print ("%s:%d (%s) %s\n", file, line, function, msg);
- fflush (stdout);
-
- g_free (msg);
- }
-}
diff --git a/libgitg/gitg-debug.h b/libgitg/gitg-debug.h
deleted file mode 100644
index 81183b6..0000000
--- a/libgitg/gitg-debug.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * gitg-debug.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_DEBUG_H__
-#define __GITG_DEBUG_H__
-
-#include <glib.h>
-#include <config.h>
-
-enum
-{
- GITG_DEBUG_NONE = 0,
- GITG_DEBUG_SHELL = 1 << 0,
- GITG_DEBUG_SHELL_OUTPUT = 1 << 1,
- GITG_DEBUG_CHARSET_CONVERSION = 1 << 2,
- GITG_DEBUG_CONFIG = 1 << 3
-};
-
-#if ENABLE_DEBUG
-void gitg_debug_init (void);
-gboolean gitg_debug_enabled (guint debug);
-
-void gitg_debug_message (guint level,
- gchar const *file,
- gint line,
- gchar const *function,
- gchar const *format,
- ...);
-
-#define gitg_debug(level,args...) gitg_debug_message (level, __FILE__, __LINE__, G_STRFUNC, args)
-#else
-
-#define gitg_debug_init(args...) ;
-#define gitg_debug_enabled(x) FALSE
-#define gitg_debug(level,args...) ;
-
-#endif
-
-#endif /* __GITG_DEBUG_H__ */
-
diff --git a/libgitg/gitg-encodings.c b/libgitg/gitg-encodings.c
deleted file mode 100644
index 7c3411f..0000000
--- a/libgitg/gitg-encodings.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * This file was copied from gedit-encodings.c
- *
- * gedit-encodings.c
- * This file is part of gedit
- *
- * Copyright (C) 2002-2005 Paolo Maggi
- *
- * 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.
- */
-
-/*
- * Modified by the gedit Team, 2002-2005. See the AUTHORS file for a
- * list of people on the gedit Team.
- * See the ChangeLog files for a list of changes.
- *
- * $Id$
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <glib/gi18n.h>
-
-#include "gitg-encodings.h"
-
-
-struct _GitgEncoding
-{
- gint index;
- const gchar *charset;
- const gchar *name;
-};
-
-G_DEFINE_BOXED_TYPE (GitgEncoding, gitg_encoding,
- gitg_encoding_copy,
- gitg_encoding_free)
-
-/*
- * The original versions of the following tables are taken from profterm
- *
- * Copyright (C) 2002 Red Hat, Inc.
- */
-
-typedef enum
-{
-
- GITG_ENCODING_ISO_8859_1,
- GITG_ENCODING_ISO_8859_2,
- GITG_ENCODING_ISO_8859_3,
- GITG_ENCODING_ISO_8859_4,
- GITG_ENCODING_ISO_8859_5,
- GITG_ENCODING_ISO_8859_6,
- GITG_ENCODING_ISO_8859_7,
- GITG_ENCODING_ISO_8859_8,
- GITG_ENCODING_ISO_8859_9,
- GITG_ENCODING_ISO_8859_10,
- GITG_ENCODING_ISO_8859_13,
- GITG_ENCODING_ISO_8859_14,
- GITG_ENCODING_ISO_8859_15,
- GITG_ENCODING_ISO_8859_16,
-
- GITG_ENCODING_UTF_7,
- GITG_ENCODING_UTF_16,
- GITG_ENCODING_UTF_16_BE,
- GITG_ENCODING_UTF_16_LE,
- GITG_ENCODING_UTF_32,
- GITG_ENCODING_UCS_2,
- GITG_ENCODING_UCS_4,
-
- GITG_ENCODING_ARMSCII_8,
- GITG_ENCODING_BIG5,
- GITG_ENCODING_BIG5_HKSCS,
- GITG_ENCODING_CP_866,
-
- GITG_ENCODING_EUC_JP,
- GITG_ENCODING_EUC_JP_MS,
- GITG_ENCODING_CP932,
- GITG_ENCODING_EUC_KR,
- GITG_ENCODING_EUC_TW,
-
- GITG_ENCODING_GB18030,
- GITG_ENCODING_GB2312,
- GITG_ENCODING_GBK,
- GITG_ENCODING_GEOSTD8,
-
- GITG_ENCODING_IBM_850,
- GITG_ENCODING_IBM_852,
- GITG_ENCODING_IBM_855,
- GITG_ENCODING_IBM_857,
- GITG_ENCODING_IBM_862,
- GITG_ENCODING_IBM_864,
-
- GITG_ENCODING_ISO_2022_JP,
- GITG_ENCODING_ISO_2022_KR,
- GITG_ENCODING_ISO_IR_111,
- GITG_ENCODING_JOHAB,
- GITG_ENCODING_KOI8_R,
- GITG_ENCODING_KOI8__R,
- GITG_ENCODING_KOI8_U,
-
- GITG_ENCODING_SHIFT_JIS,
- GITG_ENCODING_TCVN,
- GITG_ENCODING_TIS_620,
- GITG_ENCODING_UHC,
- GITG_ENCODING_VISCII,
-
- GITG_ENCODING_WINDOWS_1250,
- GITG_ENCODING_WINDOWS_1251,
- GITG_ENCODING_WINDOWS_1252,
- GITG_ENCODING_WINDOWS_1253,
- GITG_ENCODING_WINDOWS_1254,
- GITG_ENCODING_WINDOWS_1255,
- GITG_ENCODING_WINDOWS_1256,
- GITG_ENCODING_WINDOWS_1257,
- GITG_ENCODING_WINDOWS_1258,
-
- GITG_ENCODING_LAST,
-
- GITG_ENCODING_UTF_8,
- GITG_ENCODING_UNKNOWN
-
-} GitgEncodingIndex;
-
-static const GitgEncoding utf8_encoding = {
- GITG_ENCODING_UTF_8,
- "UTF-8",
- N_("Unicode")
-};
-
-/* initialized in gitg_encoding_lazy_init() */
-static GitgEncoding unknown_encoding = {
- GITG_ENCODING_UNKNOWN,
- NULL,
- NULL
-};
-
-static const GitgEncoding encodings [] = {
-
- { GITG_ENCODING_ISO_8859_1,
- "ISO-8859-1", N_("Western") },
- { GITG_ENCODING_ISO_8859_2,
- "ISO-8859-2", N_("Central European") },
- { GITG_ENCODING_ISO_8859_3,
- "ISO-8859-3", N_("South European") },
- { GITG_ENCODING_ISO_8859_4,
- "ISO-8859-4", N_("Baltic") },
- { GITG_ENCODING_ISO_8859_5,
- "ISO-8859-5", N_("Cyrillic") },
- { GITG_ENCODING_ISO_8859_6,
- "ISO-8859-6", N_("Arabic") },
- { GITG_ENCODING_ISO_8859_7,
- "ISO-8859-7", N_("Greek") },
- { GITG_ENCODING_ISO_8859_8,
- "ISO-8859-8", N_("Hebrew Visual") },
- { GITG_ENCODING_ISO_8859_9,
- "ISO-8859-9", N_("Turkish") },
- { GITG_ENCODING_ISO_8859_10,
- "ISO-8859-10", N_("Nordic") },
- { GITG_ENCODING_ISO_8859_13,
- "ISO-8859-13", N_("Baltic") },
- { GITG_ENCODING_ISO_8859_14,
- "ISO-8859-14", N_("Celtic") },
- { GITG_ENCODING_ISO_8859_15,
- "ISO-8859-15", N_("Western") },
- { GITG_ENCODING_ISO_8859_16,
- "ISO-8859-16", N_("Romanian") },
-
- { GITG_ENCODING_UTF_7,
- "UTF-7", N_("Unicode") },
- { GITG_ENCODING_UTF_16,
- "UTF-16", N_("Unicode") },
- { GITG_ENCODING_UTF_16_BE,
- "UTF-16BE", N_("Unicode") },
- { GITG_ENCODING_UTF_16_LE,
- "UTF-16LE", N_("Unicode") },
- { GITG_ENCODING_UTF_32,
- "UTF-32", N_("Unicode") },
- { GITG_ENCODING_UCS_2,
- "UCS-2", N_("Unicode") },
- { GITG_ENCODING_UCS_4,
- "UCS-4", N_("Unicode") },
-
- { GITG_ENCODING_ARMSCII_8,
- "ARMSCII-8", N_("Armenian") },
- { GITG_ENCODING_BIG5,
- "BIG5", N_("Chinese Traditional") },
- { GITG_ENCODING_BIG5_HKSCS,
- "BIG5-HKSCS", N_("Chinese Traditional") },
- { GITG_ENCODING_CP_866,
- "CP866", N_("Cyrillic/Russian") },
-
- { GITG_ENCODING_EUC_JP,
- "EUC-JP", N_("Japanese") },
- { GITG_ENCODING_EUC_JP_MS,
- "EUC-JP-MS", N_("Japanese") },
- { GITG_ENCODING_CP932,
- "CP932", N_("Japanese") },
-
- { GITG_ENCODING_EUC_KR,
- "EUC-KR", N_("Korean") },
- { GITG_ENCODING_EUC_TW,
- "EUC-TW", N_("Chinese Traditional") },
-
- { GITG_ENCODING_GB18030,
- "GB18030", N_("Chinese Simplified") },
- { GITG_ENCODING_GB2312,
- "GB2312", N_("Chinese Simplified") },
- { GITG_ENCODING_GBK,
- "GBK", N_("Chinese Simplified") },
- { GITG_ENCODING_GEOSTD8,
- "GEORGIAN-ACADEMY", N_("Georgian") }, /* FIXME GEOSTD8 ? */
-
- { GITG_ENCODING_IBM_850,
- "IBM850", N_("Western") },
- { GITG_ENCODING_IBM_852,
- "IBM852", N_("Central European") },
- { GITG_ENCODING_IBM_855,
- "IBM855", N_("Cyrillic") },
- { GITG_ENCODING_IBM_857,
- "IBM857", N_("Turkish") },
- { GITG_ENCODING_IBM_862,
- "IBM862", N_("Hebrew") },
- { GITG_ENCODING_IBM_864,
- "IBM864", N_("Arabic") },
-
- { GITG_ENCODING_ISO_2022_JP,
- "ISO-2022-JP", N_("Japanese") },
- { GITG_ENCODING_ISO_2022_KR,
- "ISO-2022-KR", N_("Korean") },
- { GITG_ENCODING_ISO_IR_111,
- "ISO-IR-111", N_("Cyrillic") },
- { GITG_ENCODING_JOHAB,
- "JOHAB", N_("Korean") },
- { GITG_ENCODING_KOI8_R,
- "KOI8R", N_("Cyrillic") },
- { GITG_ENCODING_KOI8__R,
- "KOI8-R", N_("Cyrillic") },
- { GITG_ENCODING_KOI8_U,
- "KOI8U", N_("Cyrillic/Ukrainian") },
-
- { GITG_ENCODING_SHIFT_JIS,
- "SHIFT_JIS", N_("Japanese") },
- { GITG_ENCODING_TCVN,
- "TCVN", N_("Vietnamese") },
- { GITG_ENCODING_TIS_620,
- "TIS-620", N_("Thai") },
- { GITG_ENCODING_UHC,
- "UHC", N_("Korean") },
- { GITG_ENCODING_VISCII,
- "VISCII", N_("Vietnamese") },
-
- { GITG_ENCODING_WINDOWS_1250,
- "WINDOWS-1250", N_("Central European") },
- { GITG_ENCODING_WINDOWS_1251,
- "WINDOWS-1251", N_("Cyrillic") },
- { GITG_ENCODING_WINDOWS_1252,
- "WINDOWS-1252", N_("Western") },
- { GITG_ENCODING_WINDOWS_1253,
- "WINDOWS-1253", N_("Greek") },
- { GITG_ENCODING_WINDOWS_1254,
- "WINDOWS-1254", N_("Turkish") },
- { GITG_ENCODING_WINDOWS_1255,
- "WINDOWS-1255", N_("Hebrew") },
- { GITG_ENCODING_WINDOWS_1256,
- "WINDOWS-1256", N_("Arabic") },
- { GITG_ENCODING_WINDOWS_1257,
- "WINDOWS-1257", N_("Baltic") },
- { GITG_ENCODING_WINDOWS_1258,
- "WINDOWS-1258", N_("Vietnamese") }
-};
-
-static void
-gitg_encoding_lazy_init (void)
-{
- static gboolean initialized = FALSE;
- const gchar *locale_charset;
-
- if (initialized)
- {
- return;
- }
-
- if (g_get_charset (&locale_charset) == FALSE)
- {
- unknown_encoding.charset = g_strdup (locale_charset);
- }
-
- initialized = TRUE;
-}
-
-const GitgEncoding *
-gitg_encoding_get_from_charset (const gchar *charset)
-{
- gint i;
-
- g_return_val_if_fail (charset != NULL, NULL);
-
- gitg_encoding_lazy_init ();
-
- if (charset == NULL)
- {
- return NULL;
- }
-
- if (g_ascii_strcasecmp (charset, "UTF-8") == 0)
- {
- return gitg_encoding_get_utf8 ();
- }
-
- i = 0;
-
- while (i < GITG_ENCODING_LAST)
- {
- if (g_ascii_strcasecmp (charset, encodings[i].charset) == 0)
- {
- return &encodings[i];
- }
-
- ++i;
- }
-
- if (unknown_encoding.charset != NULL)
- {
- if (g_ascii_strcasecmp (charset, unknown_encoding.charset) == 0)
- {
- return &unknown_encoding;
- }
- }
-
- return NULL;
-}
-
-GSList *
-gitg_encoding_get_candidates (void)
-{
- static GSList *ret = NULL;
-
- if (ret == NULL)
- {
- ret = g_slist_prepend (ret,
- (gpointer)gitg_encoding_get_from_index (GITG_ENCODING_WINDOWS_1250));
-
- ret = g_slist_prepend (ret,
- (gpointer)gitg_encoding_get_from_index (GITG_ENCODING_ISO_8859_1));
-
- ret = g_slist_prepend (ret,
- (gpointer)gitg_encoding_get_current ());
-
- ret = g_slist_prepend (ret,
- (gpointer)gitg_encoding_get_utf8 ());
- }
-
- return ret;
-}
-
-const GitgEncoding *
-gitg_encoding_get_from_index (gint idx)
-{
- g_return_val_if_fail (idx >= 0, NULL);
-
- if (idx >= GITG_ENCODING_LAST)
- {
- return NULL;
- }
-
- gitg_encoding_lazy_init ();
-
- return &encodings[idx];
-}
-
-const GitgEncoding *
-gitg_encoding_get_utf8 (void)
-{
- gitg_encoding_lazy_init ();
-
- return &utf8_encoding;
-}
-
-const GitgEncoding *
-gitg_encoding_get_current (void)
-{
- static gboolean initialized = FALSE;
- static const GitgEncoding *locale_encoding = NULL;
-
- const gchar *locale_charset;
-
- gitg_encoding_lazy_init ();
-
- if (initialized != FALSE)
- {
- return locale_encoding;
- }
-
- if (g_get_charset (&locale_charset) == FALSE)
- {
- g_return_val_if_fail (locale_charset != NULL, &utf8_encoding);
-
- locale_encoding = gitg_encoding_get_from_charset (locale_charset);
- }
- else
- {
- locale_encoding = &utf8_encoding;
- }
-
- if (locale_encoding == NULL)
- {
- locale_encoding = &unknown_encoding;
- }
-
- g_return_val_if_fail (locale_encoding != NULL, NULL);
-
- initialized = TRUE;
-
- return locale_encoding;
-}
-
-gchar *
-gitg_encoding_to_string (const GitgEncoding* enc)
-{
- g_return_val_if_fail (enc != NULL, NULL);
-
- gitg_encoding_lazy_init ();
-
- g_return_val_if_fail (enc->charset != NULL, NULL);
-
- if (enc->name != NULL)
- {
- return g_strdup_printf ("%s (%s)", _(enc->name), enc->charset);
- }
- else
- {
- if (g_ascii_strcasecmp (enc->charset, "ANSI_X3.4-1968") == 0)
- {
- return g_strdup_printf ("US-ASCII (%s)", enc->charset);
- }
- else
- {
- return g_strdup (enc->charset);
- }
- }
-}
-
-const gchar *
-gitg_encoding_get_charset (const GitgEncoding* enc)
-{
- g_return_val_if_fail (enc != NULL, NULL);
-
- gitg_encoding_lazy_init ();
-
- g_return_val_if_fail (enc->charset != NULL, NULL);
-
- return enc->charset;
-}
-
-const gchar *
-gitg_encoding_get_name (const GitgEncoding* enc)
-{
- g_return_val_if_fail (enc != NULL, NULL);
-
- gitg_encoding_lazy_init ();
-
- return (enc->name == NULL) ? _("Unknown") : _(enc->name);
-}
-
-/* These are to make language bindings happy. Since Encodings are
- * const, copy() just returns the same pointer and fres() doesn't
- * do nothing */
-
-GitgEncoding *
-gitg_encoding_copy (const GitgEncoding *enc)
-{
- g_return_val_if_fail (enc != NULL, NULL);
-
- return (GitgEncoding *) enc;
-}
-
-void
-gitg_encoding_free (GitgEncoding *enc)
-{
- g_return_if_fail (enc != NULL);
-}
-
-static gboolean
-data_exists (GSList *list,
- const gpointer data)
-{
- while (list != NULL)
- {
- if (list->data == data)
- return TRUE;
-
- list = g_slist_next (list);
- }
-
- return FALSE;
-}
-
-GSList *
-_gitg_encoding_strv_to_list (const gchar * const *enc_str)
-{
- GSList *res = NULL;
- gchar **p;
- const GitgEncoding *enc;
-
- for (p = (gchar **)enc_str; p != NULL && *p != NULL; p++)
- {
- const gchar *charset = *p;
-
- if (strcmp (charset, "CURRENT") == 0)
- g_get_charset (&charset);
-
- g_return_val_if_fail (charset != NULL, NULL);
- enc = gitg_encoding_get_from_charset (charset);
-
- if (enc != NULL)
- {
- if (!data_exists (res, (gpointer)enc))
- {
- res = g_slist_prepend (res, (gpointer)enc);
- }
- }
- }
-
- return g_slist_reverse (res);
-}
-
-gchar **
-_gitg_encoding_list_to_strv (const GSList *enc_list)
-{
- GSList *l;
- GPtrArray *array;
-
- array = g_ptr_array_sized_new (g_slist_length ((GSList *)enc_list) + 1);
-
- for (l = (GSList *)enc_list; l != NULL; l = g_slist_next (l))
- {
- const GitgEncoding *enc;
- const gchar *charset;
-
- enc = (const GitgEncoding *)l->data;
-
- charset = gitg_encoding_get_charset (enc);
- g_return_val_if_fail (charset != NULL, NULL);
-
- g_ptr_array_add (array, g_strdup (charset));
- }
-
- g_ptr_array_add (array, NULL);
-
- return (gchar **)g_ptr_array_free (array, FALSE);
-}
-
-/* ex:ts=8:noet: */
diff --git a/libgitg/gitg-encodings.h b/libgitg/gitg-encodings.h
deleted file mode 100644
index 1c7070e..0000000
--- a/libgitg/gitg-encodings.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copied from gedit-encodings.h
- *
- *
- * gedit-encodings.h
- * This file is part of gedit
- *
- * Copyright (C) 2002-2005 Paolo Maggi
- *
- * 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.
- */
-
-/*
- * Modified by the gedit Team, 2002-2005. See the AUTHORS file for a
- * list of people on the gedit Team.
- * See the ChangeLog files for a list of changes.
- *
- * $Id$
- */
-
-#ifndef __GITG_ENCODINGS_H__
-#define __GITG_ENCODINGS_H__
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GitgEncoding GitgEncoding;
-
-#define GITG_TYPE_ENCODING (gitg_encoding_get_type ())
-
-GType gitg_encoding_get_type (void) G_GNUC_CONST;
-
-const GitgEncoding *gitg_encoding_get_from_charset (const gchar *charset);
-const GitgEncoding *gitg_encoding_get_from_index (gint index);
-
-gchar *gitg_encoding_to_string (const GitgEncoding *enc);
-
-const gchar *gitg_encoding_get_name (const GitgEncoding *enc);
-const gchar *gitg_encoding_get_charset (const GitgEncoding *enc);
-
-const GitgEncoding *gitg_encoding_get_utf8 (void);
-const GitgEncoding *gitg_encoding_get_current (void);
-
-GSList *gitg_encoding_get_candidates (void);
-
-/* These should not be used, they are just to make python bindings happy */
-GitgEncoding *gitg_encoding_copy (const GitgEncoding *enc);
-void gitg_encoding_free (GitgEncoding *enc);
-
-GSList *_gitg_encoding_strv_to_list (const gchar * const *enc_str);
-gchar **_gitg_encoding_list_to_strv (const GSList *enc);
-
-G_END_DECLS
-
-#endif /* __GITG_ENCODINGS_H__ */
-
-/* ex:ts=8:noet: */
diff --git a/libgitg/gitg-enum-types.c.template b/libgitg/gitg-enum-types.c.template
deleted file mode 100644
index 69dd81d..0000000
--- a/libgitg/gitg-enum-types.c.template
+++ /dev/null
@@ -1,40 +0,0 @@
-/*** BEGIN file-header ***/
-#include "gitg-enum-types.h"
-
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-/* enumerations from "@filename@" */
-#include "@filename@"
-
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType
-@enum_name@_get_type (void)
-{
- static GType the_type = 0;
-
- if (the_type == 0)
- {
- static const G@Type@Value values[] = {
-/*** END value-header ***/
-
-/*** BEGIN value-production ***/
- { @VALUENAME@,
- "@VALUENAME@",
- "@valuenick@" },
-/*** END value-production ***/
-
-/*** BEGIN value-tail ***/
- { 0, NULL, NULL }
- };
- the_type = g_@type@_register_static (
- g_intern_static_string ("@EnumName@"),
- values);
- }
- return the_type;
-}
-
-/*** END value-tail ***/
-
diff --git a/libgitg/gitg-enum-types.h.template b/libgitg/gitg-enum-types.h.template
deleted file mode 100644
index 7808c8d..0000000
--- a/libgitg/gitg-enum-types.h.template
+++ /dev/null
@@ -1,28 +0,0 @@
-/*** BEGIN file-header ***/
-#ifndef __GITG_ENUM_TYPES_H__
-#define __GITG_ENUM_TYPES_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-/* Enumerations from "@filename@" */
-
-/*** END file-production ***/
-
-/*** BEGIN enumeration-production ***/
-#define GITG_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
-GType @enum_name@_get_type (void) G_GNUC_CONST;
-
-/*** END enumeration-production ***/
-
-/*** BEGIN file-tail ***/
-G_END_DECLS
-
-#endif /* __GITG_ENUM_TYPES_H__ */
-/*** END file-tail ***/
-
-
diff --git a/libgitg/gitg-hash.c b/libgitg/gitg-hash.c
deleted file mode 100644
index 9bb4e06..0000000
--- a/libgitg/gitg-hash.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * gitg-hash.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include <string.h>
-#include <glib.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "gitg-hash.h"
-
-inline static guint8
-atoh (gchar c)
-{
- if (c >= 'a')
- {
- return c - 'a' + 10;
- }
-
- if (c >= 'A')
- {
- return c - 'A' + 10;
- }
-
- return c - '0';
-}
-
-void
-gitg_hash_partial_sha1_to_hash (gchar const *sha,
- gint length,
- gchar *hash)
-{
- if (length % 2 == 1)
- {
- --length;
- }
-
- int i;
-
- for (i = 0; i < length / 2; ++i)
- {
- gchar h = atoh (*(sha++)) << 4;
- hash[i] = h | atoh (*(sha++));
- }
-}
-
-void
-gitg_hash_sha1_to_hash (gchar const *sha,
- gchar *hash)
-{
- gitg_hash_partial_sha1_to_hash (sha, GITG_HASH_SHA_SIZE, hash);
-}
-
-void
-gitg_hash_hash_to_sha1 (gchar const *hash,
- gchar *sha)
-{
- char const *repr = "0123456789abcdef";
- int i;
- int pos = 0;
-
- for (i = 0; i < GITG_HASH_BINARY_SIZE; ++i)
- {
- sha[pos++] = repr[(hash[i] >> 4) & 0x0f];
- sha[pos++] = repr[(hash[i] & 0x0f)];
- }
-}
-
-gchar *
-gitg_hash_hash_to_sha1_new (gchar const *hash)
-{
- gchar *ret = g_new (gchar, GITG_HASH_SHA_SIZE + 1);
- gitg_hash_hash_to_sha1 (hash, ret);
-
- ret[GITG_HASH_SHA_SIZE] = '\0';
- return ret;
-}
-
-gchar *
-gitg_hash_partial_sha1_to_hash_new (gchar const *sha,
- gint length,
- gint *retlen)
-{
- if (length == -1)
- {
- length = strlen (sha);
- }
-
- if (length % 2 != 0)
- {
- --length;
- }
-
- *retlen = length / 2;
- gchar *ret = g_new (gchar, *retlen);
-
- gitg_hash_partial_sha1_to_hash (sha, length, ret);
-
- return ret;
-}
-
-gchar *
-gitg_hash_sha1_to_hash_new (gchar const *sha1)
-{
- gchar *ret = g_new (gchar, GITG_HASH_BINARY_SIZE);
- gitg_hash_sha1_to_hash (sha1, ret);
-
- return ret;
-}
-
-guint
-gitg_hash_hash (gconstpointer v)
-{
- /* 31 bit hash function, copied from g_str_hash */
- const signed char *p = v;
- guint32 h = *p;
- int i;
-
- for (i = 1; i < GITG_HASH_BINARY_SIZE; ++i)
- h = (h << 5) - h + p[i];
-
- return h;
-}
-
-gboolean
-gitg_hash_hash_equal (gconstpointer a, gconstpointer b)
-{
- return memcmp (a, b, GITG_HASH_BINARY_SIZE) == 0;
-}
diff --git a/libgitg/gitg-hash.h b/libgitg/gitg-hash.h
deleted file mode 100644
index 28238bc..0000000
--- a/libgitg/gitg-hash.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * gitg-hash.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_HASH_H__
-#define __GITG_HASH_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-#define GITG_HASH_BINARY_SIZE 20
-#define GITG_HASH_SHA_SIZE 40
-
-typedef gchar GitgHash[GITG_HASH_BINARY_SIZE];
-
-void gitg_hash_sha1_to_hash(gchar const *sha, gchar *hash);
-void gitg_hash_hash_to_sha1(gchar const *hash, gchar *sha);
-
-void gitg_hash_partial_sha1_to_hash (gchar const *sha, gint length, gchar *hash);
-
-gchar *gitg_hash_sha1_to_hash_new(gchar const *sha);
-gchar *gitg_hash_hash_to_sha1_new(gchar const *hash);
-
-gchar *gitg_hash_partial_sha1_to_hash_new (gchar const *sha, gint length, gint *retlen);
-
-guint gitg_hash_hash(gconstpointer v);
-gboolean gitg_hash_hash_equal(gconstpointer a, gconstpointer b);
-
-G_END_DECLS
-
-#endif /* __GITG_HASH_H__ */
diff --git a/libgitg/gitg-i18n.c b/libgitg/gitg-i18n.c
deleted file mode 100644
index 359c2f2..0000000
--- a/libgitg/gitg-i18n.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
- * All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
-
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "gitg-i18n.h"
-
-/**
- * _gitg_gettext:
- * @msgid: The string to be translated
- *
- * Returns the translated string from the libgitg translations.
- * This is an internal function and should only be used by
- * the internals of libgitg
- *
- * Returns: the transation of @msgid to the current locale
- */
-const gchar *
-_gitg_gettext (const gchar *msgid)
-{
- static gboolean initialized = FALSE;
-
- if (G_UNLIKELY (!initialized))
- {
- bindtextdomain (GETTEXT_PACKAGE, GITG_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- initialized = TRUE;
- }
-
- return g_dgettext (GETTEXT_PACKAGE, msgid);
-}
diff --git a/libgitg/gitg-i18n.h b/libgitg/gitg-i18n.h
deleted file mode 100644
index 7b47ff6..0000000
--- a/libgitg/gitg-i18n.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
- * All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
-
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-/*
- * Handles all of the internationalization configuration options.
- * Author: Tom Tromey <tromey@creche.cygnus.com>
- *
- * This is a modified version of gtksourceview-i18n.h
- */
-
-#ifndef __GITG_18N_H__
-#define __GITG_18N_H__
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-#ifdef ENABLE_NLS
-# include <libintl.h>
-# undef _
-# define _(String) _gitg_gettext (String)
-# undef N_
-# ifdef gettext_noop
-# define N_(String) gettext_noop (String)
-# else
-# define N_(String) (String)
-# endif
-#else
-/* Stubs that do something close enough. */
-# undef textdomain
-# define textdomain(String) (String)
-# undef gettext
-# define gettext(String) (String)
-# undef dgettext
-# define dgettext(Domain,Message) (Message)
-# undef dcgettext
-# define dcgettext(Domain,Message,Type) (Message)
-# undef bindtextdomain
-# define bindtextdomain(Domain,Directory) (Domain)
-# undef bind_textdomain_codeset
-# define bind_textdomain_codeset(Domain,CodeSet) (Domain)
-# undef _
-# define _(String) (String)
-# undef N_
-# define N_(String) (String)
-#endif
-
-const gchar *_gitg_gettext (const char *msgid) G_GNUC_FORMAT(1);
-
-G_END_DECLS
-
-#endif /* __GITG_I18N_H__ */
diff --git a/libgitg/gitg-init.vala b/libgitg/gitg-init.vala
new file mode 100644
index 0000000..841a3fe
--- /dev/null
+++ b/libgitg/gitg-init.vala
@@ -0,0 +1,20 @@
+namespace Gitg
+{
+
+public void init()
+{
+ var factory = Ggit.ObjectFactory.get_default();
+
+ factory.register(typeof(Ggit.Repository),
+ typeof(Gitg.Repository));
+
+ factory.register(typeof(Ggit.Ref),
+ typeof(Gitg.Ref));
+
+ factory.register(typeof(Ggit.Commit),
+ typeof(Gitg.Commit));
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-io.c b/libgitg/gitg-io.c
deleted file mode 100644
index 955020a..0000000
--- a/libgitg/gitg-io.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * gitg-io.c
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include "gitg-io.h"
-
-#define GITG_IO_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_IO, GitgIOPrivate))
-
-struct _GitgIOPrivate
-{
- GInputStream *input;
- GOutputStream *output;
-
- gint exit_status;
-
- guint cancelled : 1;
- guint running : 1;
- guint auto_utf8 : 1;
- guint stderr_to_stdout : 1;
-};
-
-enum
-{
- PROP_0,
-
- PROP_INPUT,
- PROP_OUTPUT,
- PROP_CANCELLED,
- PROP_EXIT_STATUS,
- PROP_RUNNING,
- PROP_AUTO_UTF8,
- PROP_STDERR_TO_STDOUT
-};
-
-enum
-{
- BEGIN,
- END,
- NUM_SIGNALS
-};
-
-G_DEFINE_TYPE (GitgIO, gitg_io, G_TYPE_OBJECT)
-
-static guint signals[NUM_SIGNALS] = {0,};
-
-static void
-gitg_io_finalize (GObject *object)
-{
- G_OBJECT_CLASS (gitg_io_parent_class)->finalize (object);
-}
-
-static void
-gitg_io_dispose (GObject *object)
-{
- GitgIO *io;
-
- io = GITG_IO (object);
-
- gitg_io_close (io);
-
- G_OBJECT_CLASS (gitg_io_parent_class)->dispose (object);
-}
-
-static void
-gitg_io_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgIO *self = GITG_IO (object);
-
- switch (prop_id)
- {
- case PROP_INPUT:
- gitg_io_set_input (self, g_value_get_object (value));
- break;
- case PROP_OUTPUT:
- gitg_io_set_output (self, g_value_get_object (value));
- break;
- case PROP_CANCELLED:
- gitg_io_set_cancelled (self, g_value_get_boolean (value));
- break;
- case PROP_EXIT_STATUS:
- gitg_io_set_exit_status (self, g_value_get_int (value));
- break;
- case PROP_RUNNING:
- gitg_io_set_running (self, g_value_get_boolean (value));
- break;
- case PROP_AUTO_UTF8:
- gitg_io_set_auto_utf8 (self, g_value_get_boolean (value));
- break;
- case PROP_STDERR_TO_STDOUT:
- gitg_io_set_stderr_to_stdout (self, g_value_get_boolean (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_io_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgIO *self = GITG_IO (object);
-
- switch (prop_id)
- {
- case PROP_INPUT:
- g_value_set_object (value, self->priv->input);
- break;
- case PROP_OUTPUT:
- g_value_set_object (value, self->priv->output);
- break;
- case PROP_CANCELLED:
- g_value_set_boolean (value, self->priv->cancelled);
- break;
- case PROP_EXIT_STATUS:
- g_value_set_int (value, self->priv->exit_status);
- break;
- case PROP_RUNNING:
- g_value_set_boolean (value, self->priv->running);
- break;
- case PROP_AUTO_UTF8:
- g_value_set_boolean (value, self->priv->auto_utf8);
- break;
- case PROP_STDERR_TO_STDOUT:
- g_value_set_boolean (value, self->priv->stderr_to_stdout);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_io_cancel_impl (GitgIO *io)
-{
- io->priv->cancelled = TRUE;
-}
-
-static void
-gitg_io_begin_impl (GitgIO *io)
-{
- gitg_io_set_running (io, TRUE);
-}
-
-static void
-gitg_io_end_impl (GitgIO *io,
- GError *error)
-{
- gitg_io_set_running (io, FALSE);
-}
-
-static void
-gitg_io_class_init (GitgIOClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_io_finalize;
- object_class->dispose = gitg_io_dispose;
-
- object_class->get_property = gitg_io_get_property;
- object_class->set_property = gitg_io_set_property;
-
- klass->cancel = gitg_io_cancel_impl;
- klass->begin = gitg_io_begin_impl;
- klass->end = gitg_io_end_impl;
-
- g_object_class_install_property (object_class,
- PROP_INPUT,
- g_param_spec_object ("input",
- "Input",
- "Input",
- G_TYPE_INPUT_STREAM,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_OUTPUT,
- g_param_spec_object ("output",
- "Output",
- "Output",
- G_TYPE_OUTPUT_STREAM,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_CANCELLED,
- g_param_spec_boolean ("cancelled",
- "Cancelled",
- "Cancelled",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_EXIT_STATUS,
- g_param_spec_int ("exit-status",
- "Exit status",
- "Exit Status",
- G_MININT,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_RUNNING,
- g_param_spec_boolean ("running",
- "Running",
- "Running",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_STDERR_TO_STDOUT,
- g_param_spec_boolean ("stderr-to-stdout",
- "stderr to stdout",
- "Redirect stderr to stdout",
- FALSE,
- G_PARAM_READWRITE));
-
- signals[BEGIN] =
- g_signal_new ("begin",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GitgIOClass, begin),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[END] =
- g_signal_new ("end",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GitgIOClass, end),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE,
- 1,
- G_TYPE_ERROR);
-
- g_type_class_add_private (object_class, sizeof (GitgIOPrivate));
-
- g_object_class_install_property (object_class,
- PROP_AUTO_UTF8,
- g_param_spec_boolean ("auto-utf8",
- "Auto Utf8",
- "Auto utf8",
- TRUE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-}
-
-static void
-gitg_io_init (GitgIO *self)
-{
- self->priv = GITG_IO_GET_PRIVATE (self);
-}
-
-GitgIO *
-gitg_io_new ()
-{
- return g_object_new (GITG_TYPE_IO, NULL);
-}
-
-void
-gitg_io_begin (GitgIO *io)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (!io->priv->running)
- {
- g_signal_emit (io, signals[BEGIN], 0);
- }
-}
-
-void
-gitg_io_end (GitgIO *io,
- GError *error)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->running)
- {
- g_signal_emit (io, signals[END], 0, error);
- }
-}
-
-void
-gitg_io_cancel (GitgIO *io)
-{
- if (GITG_IO_GET_CLASS (io)->cancel)
- {
- GITG_IO_GET_CLASS (io)->cancel (io);
- }
-}
-
-gboolean
-gitg_io_get_cancelled (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), FALSE);
-
- return io->priv->cancelled;
-}
-
-void
-gitg_io_set_cancelled (GitgIO *io,
- gboolean cancelled)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->cancelled != cancelled)
- {
- io->priv->cancelled = cancelled;
- g_object_notify (G_OBJECT (io), "cancelled");
- }
-}
-
-void
-gitg_io_set_output (GitgIO *io,
- GOutputStream *stream)
-{
- g_return_if_fail (GITG_IS_IO (io));
- g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
-
- if (io->priv->output)
- {
- g_object_unref (io->priv->output);
- io->priv->output = NULL;
- }
-
- if (stream)
- {
- io->priv->output = g_object_ref (stream);
- }
-}
-
-void
-gitg_io_set_input (GitgIO *io,
- GInputStream *stream)
-{
- g_return_if_fail (GITG_IS_IO (io));
- g_return_if_fail (G_IS_INPUT_STREAM (stream));
-
- if (io->priv->input)
- {
- g_object_unref (io->priv->input);
- io->priv->input = NULL;
- }
-
- if (stream)
- {
- io->priv->input = g_object_ref (stream);
- }
-}
-
-GInputStream *
-gitg_io_get_input (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), NULL);
- return io->priv->input;
-}
-
-GOutputStream *
-gitg_io_get_output (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), NULL);
- return io->priv->output;
-}
-
-void
-gitg_io_close (GitgIO *io)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->input)
- {
- g_input_stream_close (io->priv->input, NULL, NULL);
-
- g_object_unref (io->priv->input);
- io->priv->input = NULL;
- }
-
- if (io->priv->output)
- {
- g_output_stream_close (io->priv->output, NULL, NULL);
-
- g_object_unref (io->priv->output);
- io->priv->output = NULL;
- }
-}
-
-gint
-gitg_io_get_exit_status (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), 0);
-
- return io->priv->exit_status;
-}
-
-void
-gitg_io_set_exit_status (GitgIO *io,
- gint exit_status)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->exit_status != exit_status)
- {
- io->priv->exit_status = exit_status;
- g_object_notify (G_OBJECT (io), "exit-status");
- }
-}
-
-gboolean
-gitg_io_get_running (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), FALSE);
-
- return io->priv->running;
-}
-
-void
-gitg_io_set_running (GitgIO *io,
- gboolean running)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->running != running)
- {
- io->priv->running = running;
-
- if (running)
- {
- io->priv->cancelled = FALSE;
- }
-
- g_object_notify (G_OBJECT (io), "running");
- }
-}
-
-void
-gitg_io_set_auto_utf8 (GitgIO *io,
- gboolean auto_utf8)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->auto_utf8 == auto_utf8)
- {
- return;
- }
-
- io->priv->auto_utf8 = auto_utf8;
-
- g_object_notify (G_OBJECT (io), "auto-utf8");
-}
-
-gboolean
-gitg_io_get_auto_utf8 (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), FALSE);
-
- return io->priv->auto_utf8;
-}
-
-void
-gitg_io_set_stderr_to_stdout (GitgIO *io,
- gboolean redirect)
-{
- g_return_if_fail (GITG_IS_IO (io));
-
- if (io->priv->stderr_to_stdout == redirect)
- {
- return;
- }
-
- io->priv->stderr_to_stdout = redirect;
-
- g_object_notify (G_OBJECT (io), "stderr-to-stdout");
-}
-
-gboolean
-gitg_io_get_stderr_to_stdout (GitgIO *io)
-{
- g_return_val_if_fail (GITG_IS_IO (io), FALSE);
-
- return io->priv->stderr_to_stdout;
-}
diff --git a/libgitg/gitg-io.h b/libgitg/gitg-io.h
deleted file mode 100644
index 153ae87..0000000
--- a/libgitg/gitg-io.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * gitg-io.h
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_IO_H__
-#define __GITG_IO_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_IO (gitg_io_get_type ())
-#define GITG_IO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_IO, GitgIO))
-#define GITG_IO_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_IO, GitgIO const))
-#define GITG_IO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_IO, GitgIOClass))
-#define GITG_IS_IO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_IO))
-#define GITG_IS_IO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_IO))
-#define GITG_IO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_IO, GitgIOClass))
-
-typedef struct _GitgIO GitgIO;
-typedef struct _GitgIOClass GitgIOClass;
-typedef struct _GitgIOPrivate GitgIOPrivate;
-
-struct _GitgIO
-{
- /*< private >*/
- GObject parent;
-
- GitgIOPrivate *priv;
-
- /*< public >*/
-};
-
-struct _GitgIOClass
-{
- /*< private >*/
- GObjectClass parent_class;
-
- /*< public >*/
- void (*cancel) (GitgIO *io);
-
- /* Signals */
- void (*begin) (GitgIO *io);
- void (*end) (GitgIO *io, GError *error);
-};
-
-GType gitg_io_get_type (void) G_GNUC_CONST;
-GitgIO *gitg_io_new (void);
-
-void gitg_io_begin (GitgIO *io);
-void gitg_io_end (GitgIO *io,
- GError *error);
-
-void gitg_io_set_input (GitgIO *io,
- GInputStream *stream);
-void gitg_io_set_output (GitgIO *io,
- GOutputStream *stream);
-
-GInputStream *gitg_io_get_input (GitgIO *io);
-GOutputStream *gitg_io_get_output (GitgIO *io);
-
-void gitg_io_close (GitgIO *io);
-void gitg_io_cancel (GitgIO *io);
-
-gboolean gitg_io_get_cancelled (GitgIO *io);
-void gitg_io_set_cancelled (GitgIO *io,
- gboolean cancelled);
-
-gint gitg_io_get_exit_status (GitgIO *io);
-void gitg_io_set_exit_status (GitgIO *io,
- gint status);
-
-gboolean gitg_io_get_running (GitgIO *io);
-void gitg_io_set_running (GitgIO *io,
- gboolean running);
-
-void gitg_io_set_auto_utf8 (GitgIO *io,
- gboolean auto_utf8);
-gboolean gitg_io_get_auto_utf8 (GitgIO *io);
-
-gboolean gitg_io_get_stderr_to_stdout (GitgIO *io);
-void gitg_io_set_stderr_to_stdout (GitgIO *io,
- gboolean redirect);
-
-G_END_DECLS
-
-#endif /* __GITG_IO_H__ */
diff --git a/libgitg/gitg-lane.c b/libgitg/gitg-lane.c
deleted file mode 100644
index f03e143..0000000
--- a/libgitg/gitg-lane.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * gitg-lane.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-lane.h"
-
-/* GitgLane functions */
-GitgLane *
-gitg_lane_copy (GitgLane *lane)
-{
- GitgLane *copy = g_slice_new(GitgLane);
- copy->color = gitg_color_ref(lane->color);
- copy->from = g_slist_copy(lane->from);
- copy->type = lane->type;
-
- return copy;
-}
-
-GitgLane *
-gitg_lane_dup (GitgLane *lane)
-{
- GitgLane *dup = g_slice_new(GitgLane);
- dup->color = gitg_color_copy(lane->color);
- dup->from = g_slist_copy(lane->from);
- dup->type = lane->type;
-
- return dup;
-}
-
-void
-gitg_lane_free (GitgLane *lane)
-{
- gitg_color_unref(lane->color);
- g_slist_free(lane->from);
-
- if (GITG_IS_LANE_BOUNDARY(lane))
- g_slice_free(GitgLaneBoundary, (GitgLaneBoundary *)lane);
- else
- g_slice_free(GitgLane, lane);
-}
-
-GitgLane *
-gitg_lane_new (void)
-{
- return gitg_lane_new_with_color(NULL);
-}
-
-GitgLane *
-gitg_lane_new_with_color (GitgColor *color)
-{
- GitgLane *lane = g_slice_new0(GitgLane);
- lane->color = color ? gitg_color_ref(color) : gitg_color_next();
-
- return lane;
-}
-
-GitgLaneBoundary *
-gitg_lane_convert_boundary (GitgLane *lane, GitgLaneType type)
-{
- GitgLaneBoundary *boundary = g_slice_new(GitgLaneBoundary);
-
- boundary->lane = *lane;
- boundary->lane.type |= type;
-
- g_slice_free(GitgLane, lane);
-
- return boundary;
-}
diff --git a/libgitg/gitg-lane.h b/libgitg/gitg-lane.h
deleted file mode 100644
index 61664db..0000000
--- a/libgitg/gitg-lane.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * gitg-lane.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_LANE_H__
-#define __GITG_LANE_H__
-
-#include <glib.h>
-#include <libgitg/gitg-color.h>
-#include <libgitg/gitg-hash.h>
-
-G_BEGIN_DECLS
-
-#define GITG_IS_LANE_BOUNDARY(lane) (lane->type & GITG_LANE_TYPE_START || lane->type & GITG_LANE_TYPE_END)
-
-typedef enum
-{
- GITG_LANE_TYPE_NONE,
- GITG_LANE_TYPE_START = 1 << 0,
- GITG_LANE_TYPE_END = 1 << 1,
- GITG_LANE_SIGN_LEFT = 1 << 2,
- GITG_LANE_SIGN_RIGHT = 1 << 3,
- GITG_LANE_SIGN_STASH = 1 << 4,
- GITG_LANE_SIGN_STAGED = 1 << 5,
- GITG_LANE_SIGN_UNSTAGED = 1 << 6,
-} GitgLaneType;
-
-typedef struct
-{
- GitgColor *color; /** Pointer to color */
- GSList *from; /** List of lanes merging on this lane */
- gint8 type;
-} GitgLane;
-
-typedef struct
-{
- GitgLane lane;
- GitgHash hash;
-} GitgLaneBoundary;
-
-GitgLane *gitg_lane_new (void);
-GitgLane *gitg_lane_new_with_color (GitgColor *color);
-GitgLane *gitg_lane_copy (GitgLane *lane);
-GitgLane *gitg_lane_dup (GitgLane *lane);
-
-void gitg_lane_free (GitgLane *lane);
-GitgLaneBoundary *gitg_lane_convert_boundary (GitgLane *lane, GitgLaneType type);
-
-G_END_DECLS
-
-#endif /* __GITG_LANE_H__ */
diff --git a/libgitg/gitg-lane.vala b/libgitg/gitg-lane.vala
new file mode 100644
index 0000000..e62dbdb
--- /dev/null
+++ b/libgitg/gitg-lane.vala
@@ -0,0 +1,63 @@
+namespace Gitg
+{
+
+[Compact]
+public class Lane
+{
+ [Flags]
+ public enum Tag
+ {
+ NONE = 0,
+ START = 1 << 0,
+ END = 1 << 1,
+ SIGN_STASH = 1 << 2,
+ SIGN_STAGED = 1 << 3,
+ SIGN_UNSTAGED = 1 << 4
+ }
+
+ public Color color;
+ public SList<int> from;
+ public Tag tag;
+ public Ggit.OId? boundary_id;
+
+ public Lane()
+ {
+ this.with_color(null);
+ }
+
+ public Lane.with_color(Color? color)
+ {
+ if (color != null)
+ {
+ this.color = color;
+ }
+ else
+ {
+ this.color = Color.next();
+ }
+ }
+
+ public Lane copy()
+ {
+ Lane ret = new Lane.with_color(color);
+ ret.from = from.copy();
+ ret.tag = tag;
+ ret.boundary_id = boundary_id;
+
+ return ret;
+ }
+
+ public Lane dup()
+ {
+ Lane ret = new Lane.with_color(color.copy());
+ ret.from = from.copy();
+ ret.tag = tag;
+ ret.boundary_id = boundary_id;
+
+ return ret;
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-lanes.c b/libgitg/gitg-lanes.c
deleted file mode 100644
index 41b8650..0000000
--- a/libgitg/gitg-lanes.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * gitg-lanes.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-lanes.h"
-#include "gitg-hash.h"
-#include <string.h>
-
-#define GITG_LANES_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_LANES, GitgLanesPrivate))
-
-enum
-{
- PROP_0,
- PROP_INACTIVE_MAX,
- PROP_INACTIVE_COLLAPSE,
- PROP_INACTIVE_GAP,
- PROP_INACTIVE_ENABLED
-};
-
-typedef struct
-{
- GitgLane *lane;
- guint8 inactive;
- gchar const *from;
- gchar const *to;
-} LaneContainer;
-
-typedef struct
-{
- GitgColor *color;
- gint8 index;
- gchar const *from;
- gchar const *to;
-} CollapsedLane;
-
-struct _GitgLanesPrivate
-{
- /* list of last N GitgRevisions used to backtrack in case of lane
- collapse/reactivation */
- GSList *previous;
-
- /* list of LaneContainer resembling the current lanes state for the
- next revision */
- GSList *lanes;
-
- /* hash table of rev hash -> CollapsedLane where rev hash is the hash
- to be expected on the lane */
- GHashTable *collapsed;
-
- gint inactive_max;
- gint inactive_collapse;
- gint inactive_gap;
- gboolean inactive_enabled;
-};
-
-G_DEFINE_TYPE (GitgLanes, gitg_lanes, G_TYPE_OBJECT)
-
-static void
-lane_container_free (LaneContainer *container)
-{
- gitg_lane_free (container->lane);
- g_slice_free (LaneContainer, container);
-}
-
-static void
-collapsed_lane_free (CollapsedLane *lane)
-{
- gitg_color_unref (lane->color);
- g_slice_free (CollapsedLane, lane);
-}
-
-static CollapsedLane *
-collapsed_lane_new (LaneContainer *container)
-{
- CollapsedLane *collapsed = g_slice_new (CollapsedLane);
- collapsed->color = gitg_color_ref (container->lane->color);
- collapsed->from = container->from;
- collapsed->to = container->to;
-
- return collapsed;
-}
-
-static void
-free_lanes (GitgLanes *lanes)
-{
- g_slist_free_full (lanes->priv->lanes, (GDestroyNotify)lane_container_free);
-
- lanes->priv->lanes = NULL;
-}
-
-static LaneContainer *
-find_lane_by_hash (GitgLanes *lanes,
- gchar const *hash,
- gint8 *pos)
-{
- GSList *item;
- gint8 p = 0;
-
- if (!hash)
- {
- return NULL;
- }
-
- for (item = lanes->priv->lanes; item; item = g_slist_next (item))
- {
- LaneContainer *container = (LaneContainer *)(item->data);
-
- if (container && container->to && gitg_hash_hash_equal (container->to, hash))
- {
- if (pos)
- {
- *pos = p;
- }
-
- return container;
- }
-
- ++p;
- }
-
- return NULL;
-}
-
-/* GitgLanes functions */
-static void
-gitg_lanes_finalize (GObject *object)
-{
- GitgLanes *self = GITG_LANES (object);
-
- gitg_lanes_reset (self);
- g_hash_table_destroy (self->priv->collapsed);
-
- G_OBJECT_CLASS (gitg_lanes_parent_class)->finalize (object);
-}
-
-static void
-gitg_lanes_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgLanes *self = GITG_LANES (object);
-
- switch (prop_id)
- {
- case PROP_INACTIVE_MAX:
- self->priv->inactive_max = g_value_get_int (value);
- break;
- case PROP_INACTIVE_COLLAPSE:
- self->priv->inactive_collapse = g_value_get_int (value);
- break;
- case PROP_INACTIVE_GAP:
- self->priv->inactive_gap = g_value_get_int (value);
- break;
- case PROP_INACTIVE_ENABLED:
- self->priv->inactive_enabled = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_lanes_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgLanes *self = GITG_LANES(object);
-
- switch (prop_id)
- {
- case PROP_INACTIVE_MAX:
- g_value_set_int (value, self->priv->inactive_max);
- break;
- case PROP_INACTIVE_COLLAPSE:
- g_value_set_int (value, self->priv->inactive_collapse);
- break;
- case PROP_INACTIVE_GAP:
- g_value_set_int (value, self->priv->inactive_gap);
- break;
- case PROP_INACTIVE_ENABLED:
- g_value_set_boolean (value, self->priv->inactive_enabled);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_lanes_class_init(GitgLanesClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- object_class->finalize = gitg_lanes_finalize;
- object_class->set_property = gitg_lanes_set_property;
- object_class->get_property = gitg_lanes_get_property;
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_MAX,
- g_param_spec_int ("inactive-max",
- "INACTIVE_MAX",
- "Maximum inactivity on a lane before collapsing",
- 1,
- G_MAXINT,
- 30,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_COLLAPSE,
- g_param_spec_int ("inactive-collapse",
- "INACTIVE_COLLAPSE",
- "Number of revisions to collapse",
- 1,
- G_MAXINT,
- 10,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_GAP,
- g_param_spec_int ("inactive-gap",
- "INACTIVE_GAP",
- "Minimum of revisions to leave between collapse and expand",
- 1,
- G_MAXINT,
- 10,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_ENABLED,
- g_param_spec_boolean ("inactive-enabled",
- "INACTIVE_ENABLED",
- "Lane collapsing enabled",
- TRUE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_type_class_add_private (object_class, sizeof (GitgLanesPrivate));
-}
-
-static void
-gitg_lanes_init (GitgLanes *self)
-{
- self->priv = GITG_LANES_GET_PRIVATE (self);
- self->priv->collapsed = g_hash_table_new_full (gitg_hash_hash,
- gitg_hash_hash_equal,
- NULL,
- (GDestroyNotify)collapsed_lane_free);
-}
-
-GitgLanes *
-gitg_lanes_new ()
-{
- return GITG_LANES (g_object_new (GITG_TYPE_LANES, NULL));
-}
-
-static LaneContainer *
-lane_container_new_with_color (gchar const *from,
- gchar const *to,
- GitgColor *color)
-{
- LaneContainer *ret = g_slice_new (LaneContainer);
-
- ret->from = from;
- ret->to = to;
- ret->lane = gitg_lane_new_with_color (color);
- ret->inactive = 0;
-
- return ret;
-}
-
-static LaneContainer *
-lane_container_new (gchar const *from,
- gchar const *to)
-{
- return lane_container_new_with_color (from, to, NULL);
-}
-
-static GSList *
-lanes_list (GitgLanes *lanes)
-{
- GSList *lns = NULL;
- GSList *item;
-
- for (item = lanes->priv->lanes; item; item = item->next)
- {
- lns = g_slist_prepend (lns, gitg_lane_copy (((LaneContainer*)item->data)->lane));
- }
-
- return g_slist_reverse (lns);
-}
-
-void
-gitg_lanes_reset (GitgLanes *lanes)
-{
- free_lanes (lanes);
- gitg_color_reset ();
-
- g_slist_free_full (lanes->priv->previous, (GDestroyNotify)gitg_revision_unref);
-
- lanes->priv->previous = NULL;
-
- g_hash_table_remove_all (lanes->priv->collapsed);
-}
-
-static void
-lane_container_next (LaneContainer *container,
- gint index)
-{
- GitgLane *lane = gitg_lane_copy(container->lane);
-
- lane->type = GITG_LANE_TYPE_NONE;
- g_slist_free (lane->from);
-
- gitg_lane_free (container->lane);
-
- container->lane = lane;
- container->lane->from = g_slist_prepend (NULL, GINT_TO_POINTER ((gint)(index)));
-
- if (container->to)
- {
- ++container->inactive;
- }
-}
-
-static void
-update_lane_merge_indices (GSList *from,
- gint8 index,
- gint direction)
-{
- GSList *item;
-
- for (item = from; item; item = g_slist_next (item))
- {
- gint8 idx = GPOINTER_TO_INT (item->data);
-
- if ((direction < 0 && idx > index) || (direction > 0 && idx >= index))
- {
- item->data = GINT_TO_POINTER (idx + direction);
- }
- }
-}
-
-static void
-update_merge_indices (GSList *lanes,
- gint8 index,
- gint direction)
-{
- GSList *item;
-
- for (item = lanes; item; item = g_slist_next (item))
- {
- GitgLane *lane = (GitgLane *)item->data;
-
- update_lane_merge_indices (lane->from, index, direction);
- }
-}
-
-static void
-add_collapsed (GitgLanes *lanes,
- LaneContainer *container,
- gint8 index)
-{
- CollapsedLane *collapsed = collapsed_lane_new (container);
- collapsed->index = index;
-
- g_hash_table_insert (lanes->priv->collapsed, (gpointer)container->to, collapsed);
-}
-
-static void
-collapse_lane (GitgLanes *lanes,
- LaneContainer *container,
- gint8 index)
-{
- /* backtrack for inactive-collapse revisions and remove this container from
- those revisions, appropriately updating merge indices etc */
- GSList *item;
-
- add_collapsed(lanes, container, index);
-
- for (item = lanes->priv->previous; item; item = g_slist_next(item))
- {
- GitgRevision *revision = GITG_REVISION(item->data);
- GSList *lns = gitg_revision_get_lanes(revision);
-
- /* remove lane at 'index' and update merge indices for the lanes
- after 'index' in the list */
- if (item->next)
- {
- GSList *collapsed = g_slist_nth(lns, index);
- GitgLane *lane = (GitgLane *)collapsed->data;
-
- gint8 newindex = GPOINTER_TO_INT(lane->from->data);
-
- lns = gitg_revision_remove_lane(revision, lane);
-
- if (item->next->next)
- {
- update_merge_indices(lns, newindex, -1);
- }
-
- gint mylane = gitg_revision_get_mylane(revision);
-
- if (mylane > index)
- {
- gitg_revision_set_mylane(revision, mylane - 1);
- }
-
- index = newindex;
- }
- else
- {
- /* the last item we keep, and set the style of the lane to END */
- GSList *lstlane = g_slist_nth(lns, index);
- GitgLaneBoundary *boundary;
-
- boundary = gitg_lane_convert_boundary ((GitgLane *)lstlane->data,
- GITG_LANE_TYPE_END);
-
- /* copy parent hash over */
- memcpy (boundary->hash, container->to, GITG_HASH_BINARY_SIZE);
- lstlane->data = boundary;
- }
- }
-}
-
-static void
-update_current_lanes_merge_indices (GitgLanes *lanes,
- gint8 index,
- gint8 direction)
-{
- GSList *item;
-
- for (item = lanes->priv->lanes; item; item = g_slist_next (item))
- {
- update_lane_merge_indices (((LaneContainer *)item->data)->lane->from,
- index,
- direction);
- }
-}
-
-static void
-collapse_lanes (GitgLanes *lanes)
-{
- GSList *item = lanes->priv->lanes;
- gint8 index = 0;
-
- while (item)
- {
- LaneContainer *container = (LaneContainer *)item->data;
-
- if (container->inactive != lanes->priv->inactive_max + lanes->priv->inactive_gap)
- {
- item = g_slist_next (item);
- ++index;
- continue;
- }
-
- collapse_lane (lanes,
- container,
- GPOINTER_TO_INT (container->lane->from->data));
-
- update_current_lanes_merge_indices (lanes, index, -1);
-
- GSList *next = g_slist_next (item);
-
- lane_container_free (container);
-
- lanes->priv->lanes = g_slist_remove_link (lanes->priv->lanes, item);
- item = next;
- }
-}
-
-static gint8
-ensure_correct_index (GitgRevision *revision,
- gint8 index)
-{
- guint len = g_slist_length (gitg_revision_get_lanes (revision));
-
- if (index > len)
- {
- index = len;
- }
-
- return index;
-}
-
-static void
-expand_lane (GitgLanes *lanes,
- CollapsedLane *lane)
-{
- GSList *item;
- gint8 index = lane->index;
-
- GitgLane *ln = gitg_lane_new_with_color (lane->color);
- guint len = g_slist_length (lanes->priv->lanes);
- gint8 next;
-
- if (index > len)
- {
- index = len;
- }
-
- next = ensure_correct_index ((GitgRevision *)lanes->priv->previous->data,
- index);
-
- LaneContainer *container = lane_container_new_with_color (lane->from,
- lane->to,
- lane->color);
-
- update_current_lanes_merge_indices (lanes, index, 1);
-
- container->lane->from = g_slist_prepend (NULL, GINT_TO_POINTER ((gint)next));
- lanes->priv->lanes = g_slist_insert (lanes->priv->lanes, container, index);
-
- index = next;
- guint cnt = 0;
-
- for (item = lanes->priv->previous; item; item = g_slist_next (item))
- {
- GitgRevision *revision = item->data;
-
- if (cnt == lanes->priv->inactive_collapse)
- {
- break;
- }
-
- /* insert new lane at the index */
- GitgLane *copy = gitg_lane_copy (ln);
- GSList *lns = gitg_revision_get_lanes (revision);
-
- if (!item->next || cnt + 1 == lanes->priv->inactive_collapse)
- {
- GitgLaneBoundary *boundary = gitg_lane_convert_boundary (copy, GITG_LANE_TYPE_START);
-
- /* copy child hash in boundary */
- memcpy (boundary->hash, lane->from, GITG_HASH_BINARY_SIZE);
- copy = (GitgLane *)boundary;
- }
- else
- {
- next = ensure_correct_index (GITG_REVISION (item->next->data), index);
- copy->from = g_slist_prepend (NULL, GINT_TO_POINTER ((gint)next));
-
- /* update merge indices */
- update_merge_indices (lns, index, 1);
- }
-
- lns = gitg_revision_insert_lane (revision, copy, index);
- gint mylane = gitg_revision_get_mylane (revision);
-
- if (mylane >= index)
- {
- gitg_revision_set_mylane (revision, mylane + 1);
- }
-
- index = next;
- ++cnt;
- }
-
- gitg_lane_free (ln);
-}
-
-static void
-expand_lane_from_hash (GitgLanes *lanes, gchar const *hash)
-{
- CollapsedLane *collapsed = (CollapsedLane *)g_hash_table_lookup (lanes->priv->collapsed, hash);
-
- if (!collapsed)
- {
- return;
- }
-
- expand_lane (lanes, collapsed);
- g_hash_table_remove (lanes->priv->collapsed, hash);
-}
-
-static void
-expand_lanes (GitgLanes *lanes, GitgRevision *revision)
-{
- /* expand any lanes that revision needs (own lane and parents lanes) */
- expand_lane_from_hash (lanes, gitg_revision_get_hash (revision));
-
- guint num;
- guint i;
- GitgHash *parents = gitg_revision_get_parents_hash (revision, &num);
-
- for (i = 0; i < num; ++i)
- {
- expand_lane_from_hash (lanes, parents[i]);
- }
-}
-
-static void
-init_next_layer (GitgLanes *lanes)
-{
- GSList *item = lanes->priv->lanes;
- gint8 index = 0;
-
- /* Initialize new set of lanes based on 'lanes'. It copies the lane (refs
- the color) and adds the lane index as a merge (so it basicly represents
- a passthrough) */
- for (item = lanes->priv->lanes; item; item = g_slist_next (item))
- {
- LaneContainer *container = (LaneContainer *)item->data;
-
- lane_container_next (container, index++);
- }
-}
-
-static void
-prepare_lanes (GitgLanes *lanes, GitgRevision *next, gint8 *pos)
-{
- LaneContainer *mylane;
- guint num;
- GitgHash *parents;
- guint i;
- gchar const *myhash;
-
- parents = gitg_revision_get_parents_hash (next, &num);
- myhash = gitg_revision_get_hash (next);
-
- /* prepare the next layer */
- init_next_layer (lanes);
-
- mylane = (LaneContainer *)g_slist_nth_data (lanes->priv->lanes, *pos);
-
- /* Iterate over all parents and find them a lane */
- for (i = 0; i < num; ++i)
- {
- gint8 lnpos;
- LaneContainer *container = find_lane_by_hash (lanes, parents[i], &lnpos);
-
- if (container)
- {
- /* There already is a lane for this parent. This means that we add
- mypos as a merge for the lane, also this means the color of
- this lane incluis the merge should change to one color */
- container->lane->from = g_slist_append (container->lane->from, GINT_TO_POINTER ((gint)*pos));
- gitg_color_next_index (container->lane->color);
- container->inactive = 0;
- container->from = gitg_revision_get_hash (next);
-
- continue;
- }
- else if (mylane && mylane->to == NULL)
- {
- /* There is no parent yet which can proceed on the current
- revision lane, so set it now */
- mylane->to = (gchar const *)parents[i];
-
- /* If there is more than one parent, then also change the color
- since this revision is a merge */
- if (num > 1)
- {
- gitg_color_unref (mylane->lane->color);
- mylane->lane->color = gitg_color_next ();
- }
- else
- {
- GitgColor *nc = gitg_color_copy (mylane->lane->color);
- gitg_color_unref (mylane->lane->color);
- mylane->lane->color = nc;
- }
- }
- else
- {
- /* Generate a new lane for this parent */
- LaneContainer *newlane = lane_container_new (myhash, parents[i]);
- newlane->lane->from = g_slist_prepend (NULL, GINT_TO_POINTER ((gint)*pos));
- lanes->priv->lanes = g_slist_append (lanes->priv->lanes, newlane);
- }
- }
-
- /* Remove the current lane if it is no longer needed */
- if (mylane && mylane->to == NULL)
- {
- lanes->priv->lanes = g_slist_remove (lanes->priv->lanes, mylane);
- }
-
- /* Store new revision in our track list */
- if (g_slist_length (lanes->priv->previous) == lanes->priv->inactive_collapse + lanes->priv->inactive_gap + 1)
- {
- GSList *last = g_slist_last (lanes->priv->previous);
- gitg_revision_unref (GITG_REVISION (last->data));
-
- lanes->priv->previous = g_slist_remove_link (lanes->priv->previous, last);
- }
-
- lanes->priv->previous = g_slist_prepend (lanes->priv->previous, gitg_revision_ref (next));
-}
-
-GSList *
-gitg_lanes_next (GitgLanes *lanes, GitgRevision *next, gint8 *nextpos)
-{
- LaneContainer *mylane;
- GSList *res;
- gchar const *myhash = gitg_revision_get_hash (next);
-
- if (lanes->priv->inactive_enabled)
- {
- collapse_lanes (lanes);
- expand_lanes (lanes, next);
- }
-
- mylane = find_lane_by_hash (lanes, myhash, nextpos);
-
- if (!mylane)
- {
- /* apparently, there is no lane reserved for this revision, we
- add a new one */
- lanes->priv->lanes = g_slist_append (lanes->priv->lanes, lane_container_new (myhash, NULL));
- *nextpos = g_slist_length (lanes->priv->lanes) - 1;
- }
- else
- {
- /* copy the color here because this represents a new stop */
- GitgColor *nc = gitg_color_copy (mylane->lane->color);
- gitg_color_unref (mylane->lane->color);
-
- mylane->lane->color = nc;
- mylane->to = NULL;
- mylane->from = gitg_revision_get_hash (next);
- mylane->inactive = 0;
- }
-
- res = lanes_list (lanes);
- prepare_lanes (lanes, next, nextpos);
-
- return res;
-}
diff --git a/libgitg/gitg-lanes.h b/libgitg/gitg-lanes.h
deleted file mode 100644
index ae71757..0000000
--- a/libgitg/gitg-lanes.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * gitg-lanes.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_LANES_H__
-#define __GITG_LANES_H__
-
-#include <glib-object.h>
-#include "gitg-revision.h"
-#include "gitg-lane.h"
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_LANES (gitg_lanes_get_type ())
-#define GITG_LANES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_LANES, GitgLanes))
-#define GITG_LANES_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_LANES, GitgLanes const))
-#define GITG_LANES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_LANES, GitgLanesClass))
-#define GITG_IS_LANES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_LANES))
-#define GITG_IS_LANES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_LANES))
-#define GITG_LANES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_LANES, GitgLanesClass))
-
-typedef struct _GitgLanes GitgLanes;
-typedef struct _GitgLanesClass GitgLanesClass;
-typedef struct _GitgLanesPrivate GitgLanesPrivate;
-
-struct _GitgLanes {
- GObject parent;
-
- GitgLanesPrivate *priv;
-};
-
-struct _GitgLanesClass {
- GObjectClass parent_class;
-};
-
-GType gitg_lanes_get_type (void) G_GNUC_CONST;
-
-GitgLanes *gitg_lanes_new(void);
-void gitg_lanes_reset(GitgLanes *lanes);
-GSList *gitg_lanes_next(GitgLanes *lanes, GitgRevision *next, gint8 *mylane);
-
-G_END_DECLS
-
-
-#endif /* __GITG_LANES_H__ */
-
diff --git a/libgitg/gitg-lanes.vala b/libgitg/gitg-lanes.vala
new file mode 100644
index 0000000..24e6fbc
--- /dev/null
+++ b/libgitg/gitg-lanes.vala
@@ -0,0 +1,466 @@
+namespace Gitg
+{
+
+public class Lanes : Object
+{
+ public int inactive_max { get; set; }
+ public int inactive_collapse { get; set; }
+ public int inactive_gap { get; set; }
+ public bool inactive_enabled { get; set; }
+
+ private SList<Commit> d_previous;
+ private SList<LaneContainer> d_lanes;
+ private HashTable<Ggit.OId, CollapsedLane> d_collapsed;
+
+ [Compact]
+ class LaneContainer
+ {
+ public Lane lane;
+ public uint inactive;
+ public Ggit.OId? from;
+ public Ggit.OId? to;
+
+ public LaneContainer.with_color(Ggit.OId from,
+ Ggit.OId to,
+ Color? color)
+ {
+ this.from = from;
+ this.to = to;
+ this.lane = new Lane.with_color(color);
+ this.inactive = 0;
+ }
+
+ public LaneContainer(Ggit.OId? from,
+ Ggit.OId? to)
+ {
+ this.with_color(from, to, null);
+ }
+
+ public void next(int index)
+ {
+ lane = lane.copy();
+
+ lane.tag = Lane.Tag.NONE;
+ lane.from = new SList<int>();
+ lane.from.prepend(index);
+
+ if (to != null)
+ {
+ ++inactive;
+ }
+ }
+ }
+
+ [Compact]
+ class CollapsedLane
+ {
+ public Color color;
+ public uint index;
+ public Ggit.OId? from;
+ public Ggit.OId? to;
+
+ public CollapsedLane(LaneContainer container)
+ {
+ color = container.lane.color;
+ from = container.from;
+ to = container.to;
+ }
+ }
+
+ public Lanes()
+ {
+ d_collapsed = new HashTable<Ggit.OId, CollapsedLane>(Ggit.OId.hash,
+ Ggit.OId.equal);
+
+ reset();
+ }
+
+ public void reset()
+ {
+ d_previous = new SList<Commit>();
+ d_lanes = new SList<LaneContainer>();
+
+ Color.reset();
+
+ d_collapsed.remove_all();
+ }
+
+ public SList<Lane> next(Commit next,
+ out int nextpos)
+ {
+ var myoid = next.get_id();
+
+ if (inactive_enabled)
+ {
+ collapse_lanes();
+ expand_lanes(next);
+ }
+
+ unowned LaneContainer? mylane = find_lane_by_oid(myoid, out nextpos);
+
+ if (mylane == null)
+ {
+ // there is no lane reserver for this comit, add a new lane
+ d_lanes.append(new LaneContainer(myoid, null));
+ nextpos = (int)d_lanes.length() - 1;
+ }
+ else
+ {
+ // copy the color here because the commit is a new stop
+ mylane.lane.color = mylane.lane.color.copy();
+
+ mylane.to = null;
+ mylane.from = next.get_id();
+ mylane.inactive = 0;
+ }
+
+ var res = lanes_list();
+ prepare_lanes(next, nextpos);
+
+ return res;
+ }
+
+ private void prepare_lanes(Commit next, int pos)
+ {
+ var parents = next.get_parents();
+ var myoid = next.get_id();
+
+ init_next_layer();
+ unowned LaneContainer mylane = d_lanes.nth_data(pos);
+
+ for (uint i = 0; i < parents.size(); ++i)
+ {
+ int lnpos;
+ var poid = parents.get_id(i);
+
+ unowned LaneContainer? container = find_lane_by_oid(poid, out lnpos);
+
+ if (container != null)
+ {
+ // there is already a lane for this parent. This means that
+ // we add pos as a merge for the lane, also this means the
+ // color of this lane incluis the merge should change to
+ // one color
+ container.lane.from.append(pos);
+ container.lane.color.next_index();
+
+ container.inactive = 0;
+ container.from = myoid;
+
+ continue;
+ }
+ else if (mylane != null && mylane.to == null)
+ {
+ // there is no parent yet which can proceed on the current
+ // commit lane, so set it now
+ mylane.to = poid;
+
+ if (parents.size() > 1)
+ {
+ mylane.lane.color = Color.next();
+ }
+ else
+ {
+ mylane.lane.color = mylane.lane.color.copy();
+ }
+ }
+ else
+ {
+ // generate a new lane for this parent
+ LaneContainer newlane = new LaneContainer(myoid, poid);
+
+ newlane.lane.from.prepend(pos);
+ d_lanes.append((owned)newlane);
+ }
+ }
+
+ if (mylane != null && mylane.to == null)
+ {
+ // remove current lane if no longer needed (i.e. merged)
+ d_lanes.remove(mylane);
+ }
+
+ // store new commit in track list
+ if (d_previous.length() == inactive_collapse + inactive_gap + 1)
+ {
+ d_previous.delete_link(d_previous.last());
+ }
+
+ d_previous.prepend(next);
+ }
+
+ private void add_collapsed(LaneContainer container,
+ int index)
+ {
+ var collapsed = new CollapsedLane(container);
+ collapsed.index = index;
+
+ d_collapsed.insert(container.to, (owned)collapsed);
+ }
+
+ private void collapse_lane(LaneContainer container,
+ int index)
+ {
+ add_collapsed(container, index);
+
+ unowned SList<Commit> item = d_previous;
+
+ while (item != null)
+ {
+ var commit = item.data;
+ unowned SList<Lane> lns = commit.lanes;
+ unowned SList<Lane> lstlane = lns.nth(index);
+ unowned Lane lane = lstlane.data;
+
+ if (item.next != null)
+ {
+ var newindex = lane.from.data;
+
+ lns = commit.remove_lane(lane);
+
+ if (item.next.next != null)
+ {
+ update_merge_indices(lns, newindex, -1);
+ }
+
+ var mylane = commit.mylane;
+
+ if (mylane > index)
+ {
+ --commit.mylane;
+ }
+
+ index = newindex;
+ }
+ else
+ {
+ lane.tag |= Lane.Tag.END;
+ lane.boundary_id = container.to;
+ }
+
+ item = item.next;
+ }
+ }
+
+ private void collapse_lanes()
+ {
+ int index = 0;
+ unowned SList<LaneContainer> item = d_lanes;
+
+ while (item != null)
+ {
+ unowned LaneContainer container = item.data;
+
+ if (container.inactive != inactive_max + inactive_gap)
+ {
+ item = item.next;
+ ++index;
+ continue;
+ }
+
+ collapse_lane(container, container.lane.from.data);
+ update_current_lane_merge_indices(index, -1);
+
+ unowned SList<LaneContainer> next = item.next;
+ d_lanes.remove_link(item);
+ item = next;
+ }
+ }
+
+ private int ensure_correct_index(Commit commit,
+ int index)
+ {
+ var len = commit.lanes.length();
+
+ if (index > len)
+ {
+ return (int)len;
+ }
+ else
+ {
+ return index;
+ }
+ }
+
+ private void update_lane_merge_indices(SList<int> from,
+ int index,
+ int direction)
+ {
+ while (from != null)
+ {
+ int idx = from.data;
+
+ if (idx > index || (direction > 0 && idx == index))
+ {
+ from.data = idx + direction;
+ }
+
+ from = from.next;
+ }
+ }
+
+ private void update_merge_indices(SList<Lane> lanes,
+ int index,
+ int direction)
+ {
+ foreach (unowned Lane lane in lanes)
+ {
+ update_lane_merge_indices(lane.from, index, direction);
+ }
+ }
+ private void update_current_lane_merge_indices(int index,
+ int direction)
+ {
+ foreach (unowned LaneContainer container in d_lanes)
+ {
+ update_lane_merge_indices(container.lane.from,
+ index,
+ direction);
+ }
+ }
+
+ private void expand_lane(CollapsedLane lane)
+ {
+ var index = lane.index;
+ var ln = new Lane.with_color(lane.color);
+ var len = d_lanes.length();
+
+ if (index > len)
+ {
+ index = len;
+ }
+
+ var next = ensure_correct_index(d_previous.data, (int)index);
+
+ var container = new LaneContainer.with_color(lane.from,
+ lane.to,
+ lane.color);
+
+ update_current_lane_merge_indices((int)index, 1);
+
+ container.lane.from.prepend(next);
+ d_lanes.insert((owned)container, (int)index);
+
+ index = next;
+ uint cnt = 0;
+
+ unowned SList<Commit> ptr = d_previous;
+
+ while (ptr != null)
+ {
+ var commit = ptr.data;
+
+ if (cnt == inactive_collapse)
+ {
+ break;
+ }
+
+ // Insert new lane at the index
+ Lane copy = ln.copy();
+ unowned SList<Lane> lns = commit.lanes;
+
+ if (ptr.next == null || cnt + 1 == inactive_collapse)
+ {
+ copy.boundary_id = lane.from;
+ copy.tag |= Lane.Tag.START;
+ }
+ else
+ {
+ next = ensure_correct_index(ptr.next.data, (int)index);
+ copy.from.prepend(next);
+
+ update_merge_indices(lns, (int)index, 1);
+ }
+
+ commit.lanes.insert((owned)copy, (int)index);
+ lns = commit.lanes;
+
+ var mylane = commit.mylane;
+
+ if (mylane >= index)
+ {
+ ++commit.mylane;
+ }
+
+ index = next;
+ ++cnt;
+
+ ptr = ptr.next;
+ }
+ }
+
+ private void expand_lane_from_oid(Ggit.OId id)
+ {
+ unowned CollapsedLane? collapsed = d_collapsed.lookup(id);
+
+ if (collapsed != null)
+ {
+ expand_lane(collapsed);
+ d_collapsed.remove(id);
+ }
+ }
+
+ private void expand_lanes(Commit commit)
+ {
+ expand_lane_from_oid(commit.get_id());
+
+ var parents = commit.get_parents();
+
+ for (uint i = 0; i < parents.size(); ++i)
+ {
+ expand_lane_from_oid(parents.get_id(i));
+ }
+ }
+
+ private void init_next_layer()
+ {
+ int index = 0;
+
+ foreach (unowned LaneContainer container in d_lanes)
+ {
+ container.next(index++);
+ }
+ }
+
+ private unowned LaneContainer? find_lane_by_oid(Ggit.OId id,
+ out int pos)
+ {
+ int p = 0;
+ unowned SList<LaneContainer> ptr = d_lanes;
+
+ while (ptr != null)
+ {
+ unowned LaneContainer? container = ptr.data;
+
+ if (container != null &&
+ id.equal(container.to))
+ {
+ pos = p;
+ return container;
+ }
+
+ ++p;
+ ptr = ptr.next;
+ }
+
+ pos = -1;
+ return null;
+ }
+
+ private SList<Lane> lanes_list()
+ {
+ var ret = new SList<Lane>();
+
+ foreach (unowned LaneContainer container in d_lanes)
+ {
+ ret.prepend(container.lane.copy());
+ }
+
+ ret.reverse();
+ return ret;
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-line-parser.c b/libgitg/gitg-line-parser.c
deleted file mode 100644
index e3fee83..0000000
--- a/libgitg/gitg-line-parser.c
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * gitg-line-parser.c
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * gitg 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.
- *
- * gitg 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 gitg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include "gitg-line-parser.h"
-#include <libgitg/gitg-debug.h>
-
-#define GITG_LINE_PARSER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_LINE_PARSER, GitgLineParserPrivate))
-
-struct _GitgLineParserPrivate
-{
- gchar *rest_buffer;
- gsize rest_buffer_size;
-
- gchar **lines;
- guint buffer_size;
-
- gchar *read_buffer;
-
- gboolean preserve_line_endings;
-};
-
-enum
-{
- LINES,
- DONE,
- NUM_SIGNALS
-};
-
-G_DEFINE_TYPE (GitgLineParser, gitg_line_parser, G_TYPE_OBJECT)
-
-enum
-{
- PROP_0,
- PROP_BUFFER_SIZE,
- PROP_PRESERVE_LINE_ENDINGS
-};
-
-static guint signals[NUM_SIGNALS] = {0,};
-
-typedef struct
-{
- GitgLineParser *parser;
- GInputStream *stream;
- GCancellable *cancellable;
-} AsyncData;
-
-static AsyncData *
-async_data_new (GitgLineParser *parser,
- GInputStream *stream,
- GCancellable *cancellable)
-{
- AsyncData *data;
-
- data = g_slice_new (AsyncData);
- data->parser = g_object_ref (parser);
- data->stream = stream;
- data->cancellable = g_object_ref (cancellable);
-
- return data;
-}
-
-static void
-async_data_free (AsyncData *data)
-{
- g_object_unref (data->parser);
- g_object_unref (data->cancellable);
- g_slice_free (AsyncData, data);
-}
-
-static void
-free_lines (GitgLineParser *stream)
-{
- gint i = 0;
-
- while (stream->priv->lines[i])
- {
- g_free (stream->priv->lines[i++]);
- }
-
- stream->priv->lines[0] = NULL;
-}
-
-static void
-gitg_line_parser_finalize (GObject *object)
-{
- GitgLineParser *stream;
-
- stream = GITG_LINE_PARSER (object);
-
- free_lines (stream);
-
- g_slice_free1 (sizeof (gchar *) * (stream->priv->buffer_size + 1), stream->priv->lines);
- g_slice_free1 (sizeof (gchar) * (stream->priv->buffer_size + 1), stream->priv->read_buffer);
-
- G_OBJECT_CLASS (gitg_line_parser_parent_class)->finalize (object);
-}
-
-static const gchar *
-find_newline (const gchar *ptr,
- const gchar *end,
- const gchar **line_end)
-{
-
- while (ptr < end)
- {
- gunichar c;
-
- c = g_utf8_get_char (ptr);
-
- if (c == '\n')
- {
- /* That's it */
- *line_end = g_utf8_next_char (ptr);
- return ptr;
- }
- else if (c == '\r')
- {
- gchar *next;
-
- next = g_utf8_next_char (ptr);
-
- if (next < end)
- {
- gunichar n = g_utf8_get_char (next);
-
- if (n == '\n')
- {
- /* Consume both! */
- *line_end = g_utf8_next_char (next);
- return ptr;
- }
- else
- {
- /* That's it! */
- *line_end = next;
- return ptr;
- }
- }
- else
- {
- /* Need to save it, it might come later... */
- break;
- }
- }
-
- ptr = g_utf8_next_char (ptr);
- }
-
- return NULL;
-}
-
-static void
-parse_lines (GitgLineParser *stream,
- const gchar *buffer,
- gssize size)
-{
- gchar const *ptr;
- gchar const *newline = NULL;
- gint i = 0;
- gchar *all = NULL;
- gchar const *end;
-
- if (stream->priv->rest_buffer_size > 0)
- {
- GString *str = g_string_sized_new (stream->priv->rest_buffer_size + size);
-
- g_string_append_len (str, stream->priv->rest_buffer, stream->priv->rest_buffer_size);
- g_string_append_len (str, buffer, size);
-
- all = g_string_free (str, FALSE);
- size += stream->priv->rest_buffer_size;
-
- g_free (stream->priv->rest_buffer);
- stream->priv->rest_buffer = NULL;
- stream->priv->rest_buffer_size = 0;
-
- ptr = all;
- }
- else
- {
- ptr = buffer;
- }
-
- const gchar *line_end;
- end = ptr + size;
-
- while ((newline = find_newline (ptr, end, &line_end)))
- {
- if (stream->priv->preserve_line_endings)
- {
- stream->priv->lines[i++] = g_strndup (ptr, line_end - ptr);
- }
- else
- {
- stream->priv->lines[i++] = g_strndup (ptr, newline - ptr);
- }
-
- gitg_debug (GITG_DEBUG_SHELL_OUTPUT, "%s", stream->priv->lines[i - 1]);
-
- ptr = line_end;
-
- if (i == stream->priv->buffer_size)
- {
- break;
- }
- }
-
- if (ptr < end)
- {
- stream->priv->rest_buffer_size = end - ptr;
- stream->priv->rest_buffer = g_strndup (ptr, stream->priv->rest_buffer_size);
- }
-
- stream->priv->lines[i] = NULL;
-
- g_signal_emit (stream, signals[LINES], 0, stream->priv->lines);
-
- g_free (all);
-}
-
-static void
-emit_rest (GitgLineParser *stream)
-{
- if (stream->priv->rest_buffer_size > 0)
- {
- if (!stream->priv->preserve_line_endings &&
- stream->priv->rest_buffer[stream->priv->rest_buffer_size - 1] == '\r')
- {
- stream->priv->rest_buffer[stream->priv->rest_buffer_size - 1] = '\0';
- }
-
- gchar *b[] = {stream->priv->rest_buffer, NULL};
-
- g_signal_emit (stream, signals[LINES], 0, b);
-
- g_free (stream->priv->rest_buffer);
- stream->priv->rest_buffer = NULL;
- stream->priv->rest_buffer_size = 0;
- }
-}
-
-static void
-parser_done (AsyncData *data,
- GError *error)
-{
- if (!error)
- {
- emit_rest (data->parser);
- }
-
- g_signal_emit (data->parser, signals[DONE], 0, error);
-
- async_data_free (data);
-}
-
-static void
-gitg_line_parser_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgLineParser *self = GITG_LINE_PARSER (object);
-
- switch (prop_id)
- {
- case PROP_BUFFER_SIZE:
- self->priv->buffer_size = g_value_get_uint (value);
- break;
- case PROP_PRESERVE_LINE_ENDINGS:
- self->priv->preserve_line_endings = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_line_parser_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgLineParser *self = GITG_LINE_PARSER (object);
-
- switch (prop_id)
- {
- case PROP_BUFFER_SIZE:
- g_value_set_uint (value, self->priv->buffer_size);
- break;
- case PROP_PRESERVE_LINE_ENDINGS:
- g_value_set_boolean (value, self->priv->preserve_line_endings);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_line_parser_constructed (GObject *object)
-{
- GitgLineParser *stream;
-
- stream = GITG_LINE_PARSER (object);
-
- stream->priv->lines = g_slice_alloc (sizeof (gchar *) * (stream->priv->buffer_size + 1));
- stream->priv->lines[0] = NULL;
-
- stream->priv->read_buffer = g_slice_alloc (sizeof (gchar) * (stream->priv->buffer_size + 1));
-
- G_OBJECT_CLASS (gitg_line_parser_parent_class)->constructed (object);
-}
-
-static void start_read_lines (AsyncData *data);
-
-static void
-read_ready (GInputStream *stream,
- GAsyncResult *result,
- AsyncData *data)
-{
- gssize read;
- GError *error = NULL;
-
- read = g_input_stream_read_finish (stream, result, &error);
-
- if (g_cancellable_is_cancelled (data->cancellable))
- {
- if (error)
- {
- g_error_free (error);
- }
-
- async_data_free (data);
- return;
- }
-
- if (read == -1)
- {
- parser_done (data, error);
-
- if (error)
- {
- g_error_free (error);
- }
- }
- else if (read == 0)
- {
- parser_done (data, NULL);
- }
- else
- {
- data->parser->priv->read_buffer[read] = '\0';
-
- parse_lines (data->parser,
- data->parser->priv->read_buffer,
- read);
-
- start_read_lines (data);
- }
-}
-
-static void
-start_read_lines (AsyncData *data)
-{
- g_input_stream_read_async (data->stream,
- data->parser->priv->read_buffer,
- data->parser->priv->buffer_size,
- G_PRIORITY_DEFAULT,
- data->cancellable,
- (GAsyncReadyCallback)read_ready,
- data);
-}
-
-static void
-gitg_line_parser_class_init (GitgLineParserClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_line_parser_finalize;
- object_class->constructed = gitg_line_parser_constructed;
-
- object_class->get_property = gitg_line_parser_get_property;
- object_class->set_property = gitg_line_parser_set_property;
-
- g_type_class_add_private (object_class, sizeof(GitgLineParserPrivate));
-
- signals[LINES] =
- g_signal_new ("lines",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE,
- 1,
- G_TYPE_POINTER);
-
- signals[DONE] =
- g_signal_new ("done",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE,
- 1,
- G_TYPE_ERROR);
-
- g_object_class_install_property (object_class,
- PROP_BUFFER_SIZE,
- g_param_spec_uint ("buffer-size",
- "Buffer size",
- "Buffer Size",
- 1,
- G_MAXUINT,
- 100,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_PRESERVE_LINE_ENDINGS,
- g_param_spec_boolean ("preserve-line-endings",
- "Preserve line endings",
- "Preserve Line Endings",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-gitg_line_parser_init (GitgLineParser *self)
-{
- self->priv = GITG_LINE_PARSER_GET_PRIVATE (self);
-}
-
-GitgLineParser *
-gitg_line_parser_new (guint buffer_size,
- gboolean preserve_line_endings)
-{
- return g_object_new (GITG_TYPE_LINE_PARSER,
- "buffer-size", buffer_size,
- "preserve-line-endings", preserve_line_endings,
- NULL);
-}
-
-void
-gitg_line_parser_parse (GitgLineParser *parser,
- GInputStream *stream,
- GCancellable *cancellable)
-{
- AsyncData *data;
-
- g_return_if_fail (GITG_IS_LINE_PARSER (parser));
- g_return_if_fail (G_IS_INPUT_STREAM (stream));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- data = async_data_new (parser, stream, cancellable);
- start_read_lines (data);
-}
diff --git a/libgitg/gitg-line-parser.h b/libgitg/gitg-line-parser.h
deleted file mode 100644
index e492def..0000000
--- a/libgitg/gitg-line-parser.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * gitg-line-parser.h
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * gitg 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.
- *
- * gitg 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 gitg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_LINE_PARSER_H__
-#define __GITG_LINE_PARSER_H__
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_LINE_PARSER (gitg_line_parser_get_type ())
-#define GITG_LINE_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_LINE_PARSER, GitgLineParser))
-#define GITG_LINE_PARSER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_LINE_PARSER, GitgLineParser const))
-#define GITG_LINE_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_LINE_PARSER, GitgLineParserClass))
-#define GITG_IS_LINE_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_LINE_PARSER))
-#define GITG_IS_LINE_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_LINE_PARSER))
-#define GITG_LINE_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_LINE_PARSER, GitgLineParserClass))
-
-typedef struct _GitgLineParser GitgLineParser;
-typedef struct _GitgLineParserClass GitgLineParserClass;
-typedef struct _GitgLineParserPrivate GitgLineParserPrivate;
-
-struct _GitgLineParser
-{
- /*< private >*/
- GObject parent;
-
- GitgLineParserPrivate *priv;
-};
-
-struct _GitgLineParserClass
-{
- /*< private >*/
- GObjectClass parent_class;
-};
-
-GType gitg_line_parser_get_type (void) G_GNUC_CONST;
-
-GitgLineParser *gitg_line_parser_new (guint buffer_size,
- gboolean preserve_line_endings);
-
-void gitg_line_parser_parse (GitgLineParser *parser,
- GInputStream *stream,
- GCancellable *cancellable);
-
-G_END_DECLS
-
-#endif /* __GITG_LINE_PARSER_H__ */
diff --git a/libgitg/gitg-ref.c b/libgitg/gitg-ref.c
deleted file mode 100644
index bc99c0f..0000000
--- a/libgitg/gitg-ref.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * gitg-ref.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-ref.h"
-#include "gitg-hash.h"
-#include <string.h>
-
-typedef struct
-{
- gchar const *prefix;
- GitgRefType type;
-} PrefixTypeMap;
-
-struct _GitgRef
-{
- GitgHash hash;
- GitgRefType type;
-
- gchar *name;
- gchar *shortname;
-
- gchar *prefix;
- GitgRefState state;
-
- gboolean working;
-};
-
-G_DEFINE_BOXED_TYPE (GitgRef, gitg_ref, gitg_ref_copy, gitg_ref_free)
-
-GitgRef *
-gitg_ref_new (gchar const *hash, gchar const *name)
-{
- GitgRef *inst = g_slice_new0 (GitgRef);
-
- gitg_hash_sha1_to_hash (hash, inst->hash);
- inst->name = g_strdup (name);
-
- PrefixTypeMap map[] = {
- {"refs/heads/", GITG_REF_TYPE_BRANCH},
- {"refs/remotes/", GITG_REF_TYPE_REMOTE},
- {"refs/tags/", GITG_REF_TYPE_TAG},
- {"refs/stash", GITG_REF_TYPE_STASH}
- };
-
- inst->prefix = NULL;
-
- // set type from name
- int i;
- for (i = 0; i < sizeof (map) / sizeof (PrefixTypeMap); ++i)
- {
- gchar *pos;
-
- if (!g_str_has_prefix (name, map[i].prefix))
- {
- continue;
- }
-
- inst->type = map[i].type;
-
- if (inst->type == GITG_REF_TYPE_STASH)
- {
- inst->shortname = g_strdup ("stash");
- }
- else
- {
- inst->shortname = g_strdup (name + strlen (map[i].prefix));
- }
-
- if (map[i].type == GITG_REF_TYPE_REMOTE && (pos = strchr (inst->shortname, '/')))
- {
- inst->prefix = g_strndup (inst->shortname, pos - inst->shortname);
- }
-
- break;
- }
-
- if (inst->shortname == NULL)
- {
- inst->type = GITG_REF_TYPE_NONE;
- inst->shortname = g_strdup (name);
- }
-
- return inst;
-}
-
-GitgRef *
-gitg_ref_copy (GitgRef *ref)
-{
- if (ref == NULL)
- {
- return NULL;
- }
-
- GitgRef *ret = g_slice_new0 (GitgRef);
-
- ret->type = ref->type;
- ret->name = g_strdup (ref->name);
- ret->shortname = g_strdup (ref->shortname);
- ret->prefix = g_strdup (ref->prefix);
- ret->working = ref->working;
-
- gint i;
-
- for (i = 0; i < GITG_HASH_BINARY_SIZE; ++i)
- {
- ret->hash[i] = ref->hash[i];
- }
-
- return ret;
-}
-
-void
-gitg_ref_free (GitgRef *ref)
-{
- if (!ref)
- {
- return;
- }
-
- g_free (ref->name);
- g_free (ref->shortname);
- g_free (ref->prefix);
-
- g_slice_free (GitgRef, ref);
-}
-
-gboolean
-gitg_ref_equal (GitgRef *ref, GitgRef *other)
-{
- if (ref == NULL && other == NULL)
- {
- return TRUE;
- }
-
- if (ref == NULL || other == NULL)
- {
- return FALSE;
- }
-
- return strcmp (ref->name, other->name) == 0;
-}
-
-gboolean
-gitg_ref_equal_prefix (GitgRef *ref, GitgRef *other)
-{
- if (ref == NULL && other == NULL)
- {
- return TRUE;
- }
-
- if (ref == NULL || other == NULL)
- {
- return FALSE;
- }
-
- return strcmp (ref->prefix, other->prefix) == 0;
-}
-
-gchar const *
-gitg_ref_get_hash (GitgRef *ref)
-{
- return ref->hash;
-}
-
-GitgRefType
-gitg_ref_get_ref_type (GitgRef *ref)
-{
- return ref->type;
-}
-
-gchar const *
-gitg_ref_get_name (GitgRef *ref)
-{
- return ref->name;
-}
-
-gchar const *
-gitg_ref_get_shortname (GitgRef *ref)
-{
- return ref->shortname;
-}
-
-gchar const *
-gitg_ref_get_prefix (GitgRef *ref)
-{
- return ref->prefix;
-}
-
-GitgRefState
-gitg_ref_get_state (GitgRef *ref)
-{
- return ref->state;
-}
-
-void
-gitg_ref_set_state (GitgRef *ref,
- GitgRefState state)
-{
- ref->state = state;
-}
-
-gchar const *
-gitg_ref_get_local_name (GitgRef *ref)
-{
- gchar const *shortname = gitg_ref_get_shortname (ref);
- gchar const *prefix = gitg_ref_get_prefix (ref);
-
- if (prefix && g_str_has_prefix (shortname, prefix))
- {
- return shortname + strlen (prefix) + 1;
- }
- else
- {
- return shortname;
- }
-}
-
-void
-gitg_ref_set_working (GitgRef *ref,
- gboolean working)
-{
- ref->working = working;
-}
-
-gboolean
-gitg_ref_get_working (GitgRef *ref)
-{
- return ref->working;
-}
diff --git a/libgitg/gitg-ref.h b/libgitg/gitg-ref.h
deleted file mode 100644
index 3fba9ba..0000000
--- a/libgitg/gitg-ref.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * gitg-ref.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REF_H__
-#define __GITG_REF_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REF (gitg_ref_get_type ())
-#define GITG_REF(obj) ((GitgRef *)obj)
-#define GITG_REF_CONST(obj) ((GitgRef const *)obj)
-
-typedef enum
-{
- GITG_REF_TYPE_NONE = 0,
- GITG_REF_TYPE_BRANCH,
- GITG_REF_TYPE_REMOTE,
- GITG_REF_TYPE_TAG,
- GITG_REF_TYPE_STASH
-} GitgRefType;
-
-typedef enum
-{
- GITG_REF_STATE_NONE = 0,
- GITG_REF_STATE_SELECTED,
- GITG_REF_STATE_PRELIGHT
-} GitgRefState;
-
-typedef struct _GitgRef GitgRef;
-
-GType gitg_ref_get_type (void) G_GNUC_CONST;
-
-GitgRef *gitg_ref_new (gchar const *hash,
- gchar const *name);
-
-gchar const *gitg_ref_get_hash (GitgRef *ref);
-GitgRefType gitg_ref_get_ref_type (GitgRef *ref);
-gchar const *gitg_ref_get_name (GitgRef *ref);
-
-gchar const *gitg_ref_get_shortname (GitgRef *ref);
-gchar const *gitg_ref_get_prefix (GitgRef *ref);
-
-gchar const *gitg_ref_get_local_name (GitgRef *ref);
-
-GitgRefState gitg_ref_get_state (GitgRef *ref);
-void gitg_ref_set_state (GitgRef *ref,
- GitgRefState state);
-
-void gitg_ref_set_working (GitgRef *ref,
- gboolean working);
-gboolean gitg_ref_get_working (GitgRef *ref);
-
-GitgRef *gitg_ref_copy (GitgRef *ref);
-void gitg_ref_free (GitgRef *ref);
-
-gboolean gitg_ref_equal (GitgRef *ref,
- GitgRef *other);
-
-gboolean gitg_ref_equal_prefix (GitgRef *ref,
- GitgRef *other);
-
-G_END_DECLS
-
-#endif /* __GITG_REF_H__ */
-
diff --git a/libgitg/gitg-ref.vala b/libgitg/gitg-ref.vala
new file mode 100644
index 0000000..3914b07
--- /dev/null
+++ b/libgitg/gitg-ref.vala
@@ -0,0 +1,275 @@
+namespace Gitg
+{
+
+public enum RefType
+{
+ BRANCH,
+ REMOTE,
+ TAG,
+ STASH
+}
+
+/**
+ * Parse ref name into components.
+ *
+ * This class parses a refname and splits it into several components.
+ *
+ */
+public class ParsedRefName : Object
+{
+ private string d_shortname;
+ private string d_name;
+ private string d_remote_name;
+ private string d_remote_branch;
+
+ /**
+ * The type of ref.
+ */
+ public RefType rtype { get; private set; }
+
+ /**
+ * The full name of the ref.
+ */
+ public string name
+ {
+ owned get { return d_name; }
+ }
+
+ /**
+ * The short name of the ref. This represents the name of the ref
+ * without the information of the type of ref.
+ */
+ public string shortname
+ {
+ owned get { return d_shortname; }
+ }
+
+ /**
+ * The remote name of the ref (only for remote refs)
+ */
+ public string? remote_name
+ {
+ owned get { return d_remote_name; }
+ }
+
+ /**
+ * The remote branch name of the ref (only for remote refs)
+ */
+ public string? remote_branch
+ {
+ owned get { return d_remote_branch; }
+ }
+
+ public ParsedRefName(string name)
+ {
+ parse_name(name);
+ }
+
+ private void parse_name(string name)
+ {
+ d_name = name;
+
+ string[] prefixes = {
+ "refs/heads/",
+ "refs/remotes/",
+ "refs/tags/",
+ "refs/stash"
+ };
+
+ d_shortname = name;
+
+ for (var i = 0; i < prefixes.length; ++i)
+ {
+ if (!d_name.has_prefix(prefixes[i]))
+ {
+ continue;
+ }
+
+ rtype = (RefType)i;
+
+ if (rtype == RefType.STASH)
+ {
+ d_shortname = "stash";
+ }
+ else
+ {
+ d_shortname = d_name[prefixes[i].length:d_name.length];
+ }
+
+ if (rtype == RefType.REMOTE)
+ {
+ var pos = d_shortname.index_of_char('/');
+
+ if (pos != -1)
+ {
+ d_remote_name = d_shortname.substring(0, pos);
+ d_remote_branch = d_shortname.substring(pos + 1);
+ }
+ else
+ {
+ d_remote_name = d_shortname;
+ }
+ }
+ }
+ }
+}
+
+public class Ref : Ggit.Ref
+{
+ private List<Ref>? d_pushes;
+
+ private static Regex? s_remote_key_regex;
+ private ParsedRefName d_parsed_name;
+
+ public ParsedRefName parsed_name
+ {
+ owned get
+ {
+ if (d_parsed_name == null)
+ {
+ d_parsed_name = new ParsedRefName(get_name());
+ }
+
+ return d_parsed_name;
+ }
+ }
+
+ public new Gitg.Repository get_owner()
+ {
+ return (Gitg.Repository)base.get_owner();
+ }
+
+ private void add_push_ref(string spec)
+ {
+ Gitg.Ref rf;
+
+ try
+ {
+ rf = get_owner().lookup_reference(spec);
+ } catch { return; }
+
+ if (d_pushes.find_custom(rf, (a, b) => {
+ return a.get_name().ascii_casecmp(b.get_name());
+ }) == null)
+ {
+ d_pushes.append(rf);
+ }
+ }
+
+ private void add_branch_configured_push(Ggit.Config cfg)
+ {
+ string remote;
+ string merge;
+
+ try
+ {
+ remote = cfg.get_string(@"branch.$(parsed_name.shortname).remote");
+ merge = cfg.get_string(@"branch.$(parsed_name.shortname).merge");
+ } catch { return; }
+
+ var nm = new ParsedRefName(merge);
+
+ add_push_ref(@"refs/remotes/$remote/$(nm.shortname)");
+ }
+
+ private void add_remote_configured_push(Ggit.Config cfg)
+ {
+ Regex valregex;
+
+ try
+ {
+ valregex = new Regex("^%s:(.*)".printf(Regex.escape_string(get_name())));
+
+ if (s_remote_key_regex == null)
+ {
+ s_remote_key_regex = new Regex("remote\\.(.*)\\.push");
+ }
+
+ cfg.match_foreach(s_remote_key_regex, (info, val) => {
+ MatchInfo vinfo;
+
+ if (!valregex.match(val, 0, out vinfo))
+ {
+ return 0;
+ }
+
+ var rname = info.fetch(1);
+ var pref = vinfo.fetch(1);
+
+ add_push_ref(@"refs/remotes/$rname/$pref");
+ return 0;
+ });
+
+ } catch { return; }
+ }
+
+ private void add_branch_same_name_push(Ggit.Config cfg)
+ {
+ string remote;
+
+ try
+ {
+ remote = cfg.get_string(@"branch.$(parsed_name.shortname).remote");
+ } catch { return; }
+
+ add_push_ref(@"refs/remotes/$remote/$(parsed_name.shortname)");
+ }
+
+ private void compose_pushes()
+ {
+ d_pushes = new List<Ref>();
+
+ Ggit.Config cfg;
+
+ try
+ {
+ cfg = get_owner().get_config();
+ } catch { return; }
+
+ /* The possible refspecs of a local $ref (branch) are resolved in the
+ * following order (duplicates are removed automatically):
+ *
+ * 1) Branch configured remote and merge (git push):
+ *
+ * Remote: branch.<name>.remote
+ * Spec: branch.<name>.merge
+ *
+ * 2) Remote configured matching push refspec:
+ * For each remote.<name>.push matching ${ref.name}:<spec>
+ *
+ * Remote: <name>
+ * Spec: <spec>
+ *
+ * 3) Remote branch with the same name
+ *
+ * Remote: branch.<name>.remote
+ * Spec: ${ref.name}
+ */
+
+ // Branch configured remote and merge
+ add_branch_configured_push(cfg);
+
+ // Remote configured push spec
+ add_remote_configured_push(cfg);
+
+ // Same name push
+ add_branch_same_name_push(cfg);
+ }
+
+ public List<Ref> pushes
+ {
+ get
+ {
+ if (d_pushes == null)
+ {
+ compose_pushes();
+ }
+
+ return d_pushes;
+ }
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-repository.c b/libgitg/gitg-repository.c
deleted file mode 100644
index f1d1b18..0000000
--- a/libgitg/gitg-repository.c
+++ /dev/null
@@ -1,2081 +0,0 @@
-/*
- * gitg-repository.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-repository.h"
-#include "gitg-hash.h"
-#include "gitg-i18n.h"
-#include "gitg-lanes.h"
-#include "gitg-ref.h"
-#include "gitg-config.h"
-#include "gitg-shell.h"
-
-#include <gio/gio.h>
-#include <sys/time.h>
-#include <time.h>
-#include <string.h>
-
-#define GITG_REPOSITORY_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_REPOSITORY, GitgRepositoryPrivate))
-
-static void gitg_repository_tree_model_iface_init (GtkTreeModelIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GitgRepository, gitg_repository, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, gitg_repository_tree_model_iface_init));
-
-/* Properties */
-enum
-{
- PROP_0,
- PROP_WORK_TREE,
- PROP_GIT_DIR,
- PROP_PATH,
- PROP_LOADER,
- PROP_SHOW_STAGED,
- PROP_SHOW_UNSTAGED,
- PROP_SHOW_STASH,
- PROP_TOPO_ORDER,
- PROP_INACTIVE_MAX,
- PROP_INACTIVE_COLLAPSE,
- PROP_INACTIVE_GAP,
- PROP_INACTIVE_ENABLED
-};
-
-/* Signals */
-enum
-{
- LOAD,
- LOADED,
- LAST_SIGNAL
-};
-
-static guint repository_signals[LAST_SIGNAL] = { 0 };
-
-enum
-{
- OBJECT_COLUMN,
- SUBJECT_COLUMN,
- AUTHOR_COLUMN,
- DATE_COLUMN,
- N_COLUMNS
-};
-
-typedef enum
-{
- LOAD_STAGE_NONE = 0,
- LOAD_STAGE_STASH,
- LOAD_STAGE_STAGED,
- LOAD_STAGE_UNSTAGED,
- LOAD_STAGE_COMMITS,
- LOAD_STAGE_LAST
-} LoadStage;
-
-struct _GitgRepositoryPrivate
-{
- GFile *git_dir;
- GFile *work_tree;
-
- GitgShell *loader;
- GHashTable *hashtable;
- gint stamp;
- GType column_types[N_COLUMNS];
-
- GHashTable *ref_pushes;
- GHashTable *ref_names;
-
- GitgRevision **storage;
- GitgLanes *lanes;
- GHashTable *refs;
- GitgRef *current_ref;
- GitgRef *working_ref;
-
- gulong size;
- gulong allocated;
- gint grow_size;
-
- gchar **last_args;
- gchar **selection;
-
- guint idle_relane_id;
-
- LoadStage load_stage;
-
- GFileMonitor *monitor;
-
- guint show_staged : 1;
- guint show_unstaged : 1;
- guint show_stash : 1;
- guint topoorder : 1;
-};
-
-static gboolean repository_relane (GitgRepository *repository);
-static void build_log_args (GitgRepository *self,
- gint argc,
- gchar const **av);
-
-inline static gint
-gitg_repository_error_quark ()
-{
- static GQuark quark = 0;
-
- if (G_UNLIKELY (quark == 0))
- {
- quark = g_quark_from_static_string ("GitgRepositoryErrorQuark");
- }
-
- return quark;
-}
-
-/* GtkTreeModel implementations */
-static GtkTreeModelFlags
-tree_model_get_flags (GtkTreeModel *tree_model)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), 0);
- return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY;
-}
-
-static gint
-tree_model_get_n_columns (GtkTreeModel *tree_model)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), 0);
- return N_COLUMNS;
-}
-
-static GType
-tree_model_get_column_type (GtkTreeModel *tree_model,
- gint index)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), G_TYPE_INVALID);
- g_return_val_if_fail (index < N_COLUMNS && index >= 0, G_TYPE_INVALID);
-
- return GITG_REPOSITORY (tree_model)->priv->column_types[index];
-}
-
-static void
-fill_iter (GitgRepository *repository,
- gint index,
- GtkTreeIter *iter)
-{
- iter->stamp = repository->priv->stamp;
- iter->user_data = GINT_TO_POINTER (index);
-}
-
-static gboolean
-tree_model_get_iter (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreePath *path)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), FALSE);
-
- gint *indices;
- gint depth;
-
- indices = gtk_tree_path_get_indices (path);
- depth = gtk_tree_path_get_depth (path);
-
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
-
- g_return_val_if_fail (depth == 1, FALSE);
-
- if (indices[0] < 0 || indices[0] >= rp->priv->size)
- return FALSE;
-
- fill_iter (rp, indices[0], iter);
-
- return TRUE;
-}
-
-static GtkTreePath *
-tree_model_get_path (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), NULL);
-
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
- g_return_val_if_fail (iter->stamp == rp->priv->stamp, NULL);
-
- return gtk_tree_path_new_from_indices (GPOINTER_TO_INT (iter->user_data), -1);
-}
-
-static void
-tree_model_get_value (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint column,
- GValue *value)
-{
- g_return_if_fail (GITG_IS_REPOSITORY (tree_model));
- g_return_if_fail (column >= 0 && column < N_COLUMNS);
-
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
- g_return_if_fail (iter->stamp == rp->priv->stamp);
-
- gint index = GPOINTER_TO_INT (iter->user_data);
-
- g_return_if_fail (index >= 0 && index < rp->priv->size);
- GitgRevision *rv = rp->priv->storage[index];
-
- g_value_init (value, rp->priv->column_types[column]);
-
- switch (column)
- {
- case OBJECT_COLUMN:
- g_value_set_boxed (value, rv);
- break;
- case SUBJECT_COLUMN:
- g_value_set_string (value, gitg_revision_get_subject (rv));
- break;
- case AUTHOR_COLUMN:
- g_value_set_string (value, gitg_revision_get_author (rv));
- break;
- case DATE_COLUMN:
- g_value_take_string (value, gitg_revision_get_author_date_for_display (rv));
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-}
-
-static gboolean
-tree_model_iter_next (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), FALSE);
-
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
- g_return_val_if_fail (iter->stamp == rp->priv->stamp, FALSE);
-
- gint next = GPOINTER_TO_INT (iter->user_data) + 1;
-
- if (next >= rp->priv->size)
- return FALSE;
-
- iter->user_data = GINT_TO_POINTER (next);
- return TRUE;
-}
-
-static gboolean
-tree_model_iter_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), FALSE);
-
- // Only root has children, because it's a flat list
- if (parent != NULL)
- {
- return FALSE;
- }
-
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
- fill_iter (rp, 0, iter);
-
- return TRUE;
-}
-
-static gboolean
-tree_model_iter_has_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), FALSE);
-
- // Only root (NULL) has children
- return iter == NULL;
-}
-
-static gint
-tree_model_iter_n_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), 0);
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
-
- return iter ? 0 : rp->priv->size;
-}
-
-static gboolean
-tree_model_iter_nth_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), FALSE);
- g_return_val_if_fail (n >= 0, FALSE);
-
- if (parent)
- {
- return FALSE;
- }
-
- GitgRepository *rp = GITG_REPOSITORY (tree_model);
- g_return_val_if_fail (n < rp->priv->size, FALSE);
-
- fill_iter (rp, n, iter);
-
- return TRUE;
-}
-
-static gboolean
-tree_model_iter_parent (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *child)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (tree_model), FALSE);
- return FALSE;
-}
-
-static void
-gitg_repository_tree_model_iface_init (GtkTreeModelIface *iface)
-{
- iface->get_flags = tree_model_get_flags;
- iface->get_n_columns = tree_model_get_n_columns;
- iface->get_column_type = tree_model_get_column_type;
- iface->get_iter = tree_model_get_iter;
- iface->get_path = tree_model_get_path;
- iface->get_value = tree_model_get_value;
- iface->iter_next = tree_model_iter_next;
- iface->iter_children = tree_model_iter_children;
- iface->iter_has_child = tree_model_iter_has_child;
- iface->iter_n_children = tree_model_iter_n_children;
- iface->iter_nth_child = tree_model_iter_nth_child;
- iface->iter_parent = tree_model_iter_parent;
-}
-
-static void
-do_clear (GitgRepository *repository,
- gboolean emit)
-{
- gint i;
- GtkTreePath *path = gtk_tree_path_new_from_indices (repository->priv->size - 1, -1);
-
- for (i = repository->priv->size - 1; i >= 0; --i)
- {
- if (emit)
- {
- GtkTreePath *dup = gtk_tree_path_copy (path);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (repository), dup);
- gtk_tree_path_free (dup);
- }
-
- gtk_tree_path_prev (path);
- gitg_revision_unref (repository->priv->storage[i]);
- }
-
- gtk_tree_path_free (path);
-
- if (repository->priv->storage)
- {
- g_slice_free1 (sizeof (GitgRevision *) * repository->priv->size,
- repository->priv->storage);
- }
-
- repository->priv->storage = NULL;
- repository->priv->size = 0;
- repository->priv->allocated = 0;
-
- gitg_ref_free (repository->priv->current_ref);
- repository->priv->current_ref = NULL;
-
- /* clear hash tables */
- g_hash_table_remove_all (repository->priv->hashtable);
- g_hash_table_remove_all (repository->priv->refs);
- g_hash_table_remove_all (repository->priv->ref_names);
- g_hash_table_remove_all (repository->priv->ref_pushes);
-
- gitg_color_reset ();
-}
-
-static void
-prepare_relane (GitgRepository *repository)
-{
- if (!repository->priv->idle_relane_id)
- {
- repository->priv->idle_relane_id = g_idle_add ((GSourceFunc)repository_relane, repository);
- }
-}
-
-static void
-gitg_repository_finalize (GObject *object)
-{
- GitgRepository *rp = GITG_REPOSITORY (object);
-
- /* Make sure to cancel the loader */
- gitg_io_cancel (GITG_IO (rp->priv->loader));
- g_object_unref (rp->priv->loader);
-
- g_object_unref (rp->priv->lanes);
-
- /* Clear the model to remove all revision objects */
- do_clear (rp, FALSE);
-
- if (rp->priv->work_tree)
- {
- g_object_unref (rp->priv->work_tree);
- }
-
- if (rp->priv->git_dir)
- {
- g_object_unref (rp->priv->git_dir);
- }
-
- /* Free the hash */
- g_hash_table_destroy (rp->priv->hashtable);
- g_hash_table_destroy (rp->priv->refs);
- g_hash_table_destroy (rp->priv->ref_names);
- g_hash_table_destroy (rp->priv->ref_pushes);
-
- /* Free cached args */
- g_strfreev (rp->priv->last_args);
- g_strfreev (rp->priv->selection);
-
- if (rp->priv->idle_relane_id)
- {
- g_source_remove (rp->priv->idle_relane_id);
- }
-
- if (rp->priv->current_ref)
- {
- gitg_ref_free (rp->priv->current_ref);
- }
-
- if (rp->priv->working_ref)
- {
- gitg_ref_free (rp->priv->working_ref);
- }
-
- if (rp->priv->monitor)
- {
- g_file_monitor_cancel (rp->priv->monitor);
- g_object_unref (rp->priv->monitor);
- }
-
- G_OBJECT_CLASS (gitg_repository_parent_class)->finalize (object);
-}
-
-static void
-gitg_repository_set_property (GObject *object,
- guint prop_id,
- GValue const *value,
- GParamSpec *pspec)
-{
- GitgRepository *self = GITG_REPOSITORY (object);
-
- switch (prop_id)
- {
- case PROP_WORK_TREE:
- if (self->priv->work_tree)
- {
- g_object_unref (self->priv->work_tree);
- }
-
- self->priv->work_tree = g_value_dup_object (value);
- break;
- case PROP_GIT_DIR:
- if (self->priv->git_dir)
- {
- g_object_unref (self->priv->git_dir);
- }
-
- self->priv->git_dir = g_value_dup_object (value);
- break;
- case PROP_SHOW_STAGED:
- self->priv->show_staged = g_value_get_boolean (value);
- gitg_repository_reload (self);
- break;
- case PROP_SHOW_UNSTAGED:
- self->priv->show_unstaged = g_value_get_boolean (value);
- gitg_repository_reload (self);
- break;
- case PROP_SHOW_STASH:
- self->priv->show_stash = g_value_get_boolean (value);
- gitg_repository_reload (self);
- break;
- case PROP_TOPO_ORDER:
- self->priv->topoorder = g_value_get_boolean (value);
-
- if (self->priv->selection != NULL)
- {
- build_log_args (self,
- g_strv_length (self->priv->selection),
- (gchar const **)self->priv->selection);
- }
-
- gitg_repository_reload (self);
- break;
- case PROP_INACTIVE_MAX:
- g_object_set_property (G_OBJECT (self->priv->lanes),
- "inactive-max",
- value);
- prepare_relane (self);
- break;
- case PROP_INACTIVE_COLLAPSE:
- g_object_set_property (G_OBJECT (self->priv->lanes),
- "inactive-collapse",
- value);
- prepare_relane (self);
- break;
- case PROP_INACTIVE_GAP:
- g_object_set_property (G_OBJECT (self->priv->lanes),
- "inactive-gap",
- value);
- prepare_relane (self);
- break;
- case PROP_INACTIVE_ENABLED:
- g_object_set_property (G_OBJECT (self->priv->lanes),
- "inactive-enabled",
- value);
- prepare_relane (self);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_repository_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgRepository *self = GITG_REPOSITORY (object);
-
- switch (prop_id)
- {
- case PROP_WORK_TREE:
- g_value_set_object (value, self->priv->work_tree);
- break;
- case PROP_GIT_DIR:
- g_value_set_object (value, self->priv->git_dir);
- break;
- case PROP_LOADER:
- g_value_set_object (value, self->priv->loader);
- break;
- case PROP_SHOW_STAGED:
- g_value_set_boolean (value, self->priv->show_staged);
- break;
- case PROP_SHOW_UNSTAGED:
- g_value_set_boolean (value, self->priv->show_unstaged);
- break;
- case PROP_SHOW_STASH:
- g_value_set_boolean (value, self->priv->show_stash);
- break;
- case PROP_TOPO_ORDER:
- g_value_set_boolean (value, self->priv->topoorder);
- break;
- case PROP_INACTIVE_MAX:
- g_object_get_property (G_OBJECT (self->priv->lanes),
- "inactive-max",
- value);
- break;
- case PROP_INACTIVE_COLLAPSE:
- g_object_get_property (G_OBJECT (self->priv->lanes),
- "inactive-collapse",
- value);
- break;
- case PROP_INACTIVE_GAP:
- g_object_get_property (G_OBJECT (self->priv->lanes),
- "inactive-gap",
- value);
- break;
- case PROP_INACTIVE_ENABLED:
- g_object_get_property (G_OBJECT (self->priv->lanes),
- "inactive-enabled",
- value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gchar *
-parse_ref_intern (GitgRepository *repository,
- gchar const *ref,
- gboolean symbolic)
-{
- gchar **ret;
- gboolean retval;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (repository,
- "rev-parse",
- "--verify",
- symbolic ? "--symbolic-full-name" : ref,
- symbolic ? ref : NULL,
- NULL),
- FALSE,
- &ret,
- NULL);
-
- if (!retval || !ret)
- {
- g_strfreev (ret);
- return NULL;
- }
-
- gchar *r = g_strdup (*ret);
- g_strfreev (ret);
-
- return r;
-}
-
-static GitgRef *
-get_current_working_ref (GitgRepository *repository)
-{
- GitgRef *ret = NULL;
-
- gchar *hash = parse_ref_intern (repository, "HEAD", FALSE);
- gchar *name = parse_ref_intern (repository, "HEAD", TRUE);
-
- if (hash && name)
- {
- ret = gitg_ref_new (hash, name);
- gitg_ref_set_working (ret, TRUE);
- }
-
- g_free (hash);
- g_free (name);
-
- return ret;
-}
-
-static void
-on_head_changed (GFileMonitor *monitor,
- GFile *file,
- GFile *otherfile,
- GFileMonitorEvent event,
- GitgRepository *repository)
-{
- switch (event)
- {
- case G_FILE_MONITOR_EVENT_CHANGED:
- case G_FILE_MONITOR_EVENT_CREATED:
- {
- GitgRef *current = get_current_working_ref (repository);
-
- if (!gitg_ref_equal (current, repository->priv->working_ref))
- {
- gitg_repository_reload (repository);
- }
-
- gitg_ref_free (current);
- }
- break;
- default:
- break;
- }
-}
-
-static void
-install_head_monitor (GitgRepository *repository)
-{
- GFile *file = g_file_get_child (repository->priv->git_dir, "HEAD");
-
- repository->priv->monitor = g_file_monitor_file (file,
- G_FILE_MONITOR_NONE,
- NULL,
- NULL);
-
- g_signal_connect (repository->priv->monitor,
- "changed",
- G_CALLBACK (on_head_changed),
- repository);
-
- g_object_unref (file);
-}
-
-static void
-gitg_repository_constructed (GObject *object)
-{
- GitgRepository *repository = GITG_REPOSITORY (object);
-
- if (repository->priv->git_dir == NULL &&
- repository->priv->work_tree == NULL)
- {
- return;
- }
-
- if (repository->priv->git_dir == NULL)
- {
- repository->priv->git_dir = g_file_get_child (repository->priv->work_tree,
- ".git");
- }
- else if (repository->priv->work_tree == NULL)
- {
- repository->priv->work_tree = g_file_get_parent (repository->priv->git_dir);
- }
-
- install_head_monitor (repository);
-
- G_OBJECT_CLASS (gitg_repository_parent_class)->constructed (object);
-}
-
-static void
-gitg_repository_class_init (GitgRepositoryClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = gitg_repository_finalize;
-
- object_class->set_property = gitg_repository_set_property;
- object_class->get_property = gitg_repository_get_property;
-
- object_class->constructed = gitg_repository_constructed;
-
- g_object_class_install_property (object_class,
- PROP_GIT_DIR,
- g_param_spec_object ("git-dir",
- "GIT_DIR",
- "The repository .git directory",
- G_TYPE_FILE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_WORK_TREE,
- g_param_spec_object ("work-tree",
- "WORK_TREE",
- "The work tree directory",
- G_TYPE_FILE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class,
- PROP_LOADER,
- g_param_spec_object ("loader",
- "LOADER",
- "The repository loader",
- GITG_TYPE_SHELL,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_SHOW_STAGED,
- g_param_spec_boolean ("show-staged",
- "Show Staged",
- "Show staged",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_SHOW_UNSTAGED,
- g_param_spec_boolean ("show-unstaged",
- "Show Unstaged",
- "Show unstaged",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_SHOW_STASH,
- g_param_spec_boolean ("show-stash",
- "Show Stash",
- "Show stash",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_TOPO_ORDER,
- g_param_spec_boolean ("topo-order",
- "Topo order",
- "Show in topological order",
- FALSE,
- G_PARAM_READWRITE));
-
- /* FIXME: gitg-lanes shouldn't be an object? */
- g_object_class_install_property (object_class,
- PROP_INACTIVE_MAX,
- g_param_spec_int ("inactive-max",
- "INACTIVE_MAX",
- "Maximum inactivity on a lane before collapsing",
- 1,
- G_MAXINT,
- 30,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_COLLAPSE,
- g_param_spec_int ("inactive-collapse",
- "INACTIVE_COLLAPSE",
- "Number of revisions to collapse",
- 1,
- G_MAXINT,
- 10,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_GAP,
- g_param_spec_int ("inactive-gap",
- "INACTIVE_GAP",
- "Minimum of revisions to leave between collapse and expand",
- 1,
- G_MAXINT,
- 10,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_INACTIVE_ENABLED,
- g_param_spec_boolean ("inactive-enabled",
- "INACTIVE_ENABLED",
- "Lane collapsing enabled",
- TRUE,
- G_PARAM_READWRITE));
-
- repository_signals[LOAD] =
- g_signal_new ("load",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgRepositoryClass,
- load),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- repository_signals[LOADED] =
- g_signal_new ("loaded",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgRepositoryClass,
- loaded),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- g_type_class_add_private (object_class, sizeof (GitgRepositoryPrivate));
-}
-
-static void
-append_revision (GitgRepository *repository,
- GitgRevision *rv)
-{
- GSList *lanes;
- gint8 mylane = 0;
-
- if (repository->priv->size == 0)
- {
- gitg_lanes_reset (repository->priv->lanes);
- }
-
- lanes = gitg_lanes_next (repository->priv->lanes, rv, &mylane);
- gitg_revision_set_lanes (rv, lanes, mylane);
-
- gitg_repository_add (repository, rv, NULL);
- gitg_revision_unref (rv);
-}
-
-static void
-add_dummy_commit (GitgRepository *repository,
- gboolean staged)
-{
- GitgRevision *revision;
- gchar const *subject;
- struct timeval tv;
-
- gettimeofday (&tv, NULL);
-
- if (staged)
- {
- subject = _ ("Staged changes");
- }
- else
- {
- subject = _ ("Unstaged changes");
- }
-
- revision = gitg_revision_new ("0000000000000000000000000000000000000000",
- "",
- "",
- tv.tv_sec,
- "",
- "",
- -1,
- subject,
- NULL);
- gitg_revision_set_sign (revision, staged ? 't' : 'u');
-
- append_revision (repository, revision);
-}
-
-static void
-on_loader_end_loading (GitgShell *object,
- GError *error,
- GitgRepository *repository)
-{
- if (gitg_io_get_cancelled (GITG_IO (object)))
- {
- g_signal_emit (repository, repository_signals[LOADED], 0);
- return;
- }
-
- LoadStage current = repository->priv->load_stage++;
- gboolean show_unstaged;
- gboolean show_staged;
-
- show_unstaged = repository->priv->show_unstaged;
- show_staged = repository->priv->show_staged;
-
- switch (current)
- {
- case LOAD_STAGE_STASH:
- case LOAD_STAGE_STAGED:
- {
- /* Check if there are staged changes */
- gchar *head = gitg_repository_parse_head (repository);
- const gchar *cached = NULL;
-
- if (current == LOAD_STAGE_STAGED)
- {
- /* Check if there are unstaged changes */
- if (show_staged && gitg_io_get_exit_status (GITG_IO (object)) != 0)
- {
- add_dummy_commit (repository, TRUE);
- }
- }
- else
- {
- cached = "--cached";
- }
-
- gitg_shell_run (object,
- gitg_command_new (repository,
- "diff-index",
- "--no-ext-diff",
- "--quiet",
- head,
- cached,
- NULL),
- NULL);
-
- g_free (head);
- }
- break;
- case LOAD_STAGE_UNSTAGED:
- if (show_unstaged && gitg_io_get_exit_status (GITG_IO (object)) != 0)
- {
- add_dummy_commit (repository, FALSE);
- }
-
- gitg_shell_run (object,
- gitg_command_newv (repository,
- (gchar const * const *)repository->priv->last_args),
- NULL);
- break;
- default:
- break;
- }
-
- if (repository->priv->load_stage == LOAD_STAGE_LAST)
- {
- g_signal_emit (repository, repository_signals[LOADED], 0);
- }
-}
-
-static gint
-find_ref_custom (GitgRef *first,
- GitgRef *second)
-{
- return gitg_ref_equal (first, second) ? 0 : 1;
-}
-
-static GitgRef *
-add_ref (GitgRepository *self,
- gchar const *sha1,
- gchar const *name)
-{
- GitgRef *ref = gitg_ref_new (sha1, name);
- GSList *refs = (GSList *)g_hash_table_lookup (self->priv->refs,
- gitg_ref_get_hash (ref));
-
- g_hash_table_insert (self->priv->ref_names,
- (gpointer)gitg_ref_get_name (ref),
- ref);
-
- if (refs == NULL)
- {
- g_hash_table_insert (self->priv->refs,
- (gpointer)gitg_ref_get_hash (ref),
- g_slist_append (NULL, ref));
- }
- else
- {
- if (!g_slist_find_custom (refs, ref, (GCompareFunc)find_ref_custom))
- {
- refs = g_slist_append (refs, ref);
- }
- else
- {
- gitg_ref_free (ref);
- }
- }
-
- return ref;
-}
-
-static void
-loader_update_stash (GitgRepository *repository,
- gchar **buffer)
-{
- gchar *line;
- gboolean show_stash;
-
- show_stash = repository->priv->show_stash;
-
- if (!show_stash)
- {
- return;
- }
-
- while ((line = *buffer++) != NULL)
- {
- gchar **components = g_strsplit (line, "\01", 0);
- guint len = g_strv_length (components);
-
- if (len < 5)
- {
- g_strfreev (components);
- continue;
- }
-
- /* components -> [hash, author, author email, author date,
- committer, committer email, committer date,
- subject, parents, left-right] */
- gint64 author_date = g_ascii_strtoll (components[3], NULL, 0);
-
- GitgRevision *rv = gitg_revision_new (components[0],
- components[1],
- components[2],
- author_date,
- NULL,
- NULL,
- -1,
- components[4],
- NULL);
-
- add_ref (repository, components[0], "refs/stash");
-
- gitg_revision_set_sign (rv, 's');
- append_revision (repository, rv);
- g_strfreev (components);
- }
-}
-
-static void
-loader_update_commits (GitgRepository *self,
- gchar **buffer)
-{
- gchar *line;
-
- while ( (line = *buffer++) != NULL)
- {
- /* new line is read */
- gchar **components = g_strsplit (line, "\01", 0);
- guint len = g_strv_length (components);
-
- if (len < 9)
- {
- g_strfreev (components);
- continue;
- }
-
- /* components -> [hash, author, subject, parents ([1 2 3]), timestamp[, leftright]] */
- gint64 author_date = g_ascii_strtoll (components[3], NULL, 0);
- gint64 committer_date = g_ascii_strtoll (components[6], NULL, 0);
-
- GitgRevision *rv = gitg_revision_new (components[0],
- components[1],
- components[2],
- author_date,
- components[4],
- components[5],
- committer_date,
- components[7],
- components[8]);
-
- if (len > 9 && strlen (components[9]) == 1 && strchr ("<>-^", *components[9]) != NULL)
- {
- gitg_revision_set_sign (rv, *components[9]);
- }
-
- append_revision (self, rv);
- g_strfreev (components);
- }
-}
-
-static void
-on_loader_update (GitgShell *object,
- gchar **buffer,
- GitgRepository *repository)
-{
- switch (repository->priv->load_stage)
- {
- case LOAD_STAGE_STASH:
- loader_update_stash (repository, buffer);
- break;
- case LOAD_STAGE_STAGED:
- break;
- case LOAD_STAGE_UNSTAGED:
- break;
- case LOAD_STAGE_COMMITS:
- loader_update_commits (repository, buffer);
- break;
- default:
- break;
- }
-}
-
-static void
-free_refs (GSList *refs)
-{
- g_slist_free_full (refs, (GDestroyNotify)gitg_ref_free);
-}
-
-static gboolean
-repository_relane (GitgRepository *repository)
-{
- repository->priv->idle_relane_id = 0;
-
- gitg_lanes_reset (repository->priv->lanes);
-
- guint i;
- GtkTreeIter iter;
- GtkTreePath *path = gtk_tree_path_new_first ();
-
- for (i = 0; i < repository->priv->size; ++i)
- {
- gint8 mylane;
- GitgRevision *revision = repository->priv->storage[i];
-
- GSList *lanes = gitg_lanes_next (repository->priv->lanes,
- revision,
- &mylane);
- gitg_revision_set_lanes (revision,
- lanes,
- mylane);
-
- fill_iter (repository, i, &iter);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (repository),
- path,
- &iter);
-
- gtk_tree_path_next (path);
- }
-
- gtk_tree_path_free (path);
-
- return FALSE;
-}
-
-static gchar **
-copy_strv (gchar const **ptr,
- gint argc)
-{
- GPtrArray *ret = g_ptr_array_new ();
- gint i = 0;
-
- while (ptr && ( (argc >= 0 && i < argc) || (argc < 0 && ptr[i])))
- {
- g_ptr_array_add (ret, g_strdup (ptr[i]));
- ++i;
- }
-
- g_ptr_array_add (ret, NULL);
- return (gchar **)g_ptr_array_free (ret, FALSE);
-}
-
-static gboolean
-has_left_right (gchar const **av,
- int argc)
-{
- int i;
-
- for (i = 0; i < argc; ++i)
- {
- if (strcmp (av[i], "--left-right") == 0)
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-build_log_args (GitgRepository *self,
- gint argc,
- gchar const **av)
-{
- gboolean topoorder;
-
- topoorder = self->priv->topoorder;
-
- gchar **argv = g_new0 (gchar *, 6 + topoorder + (argc > 0 ? argc - 1 : 0));
-
- argv[0] = g_strdup ("log");
-
- if (has_left_right (av, argc))
- {
- argv[1] = g_strdup ("--pretty=format:%H\x01%an\x01%ae\x01%at\x01%cn\x01%ce\x01%ct\x01%s\x01%P\x01%m");
- }
- else
- {
- argv[1] = g_strdup ("--pretty=format:%H\x01%an\x01%ae\x01%at\x01%cn\x01%ce\x01%ct\x01%s\x01%P");
- }
-
- argv[2] = g_strdup ("--encoding=UTF-8");
- gint start = 3;
-
- if (topoorder)
- {
- argv[3] = g_strdup ("--topo-order");
- ++start;
- }
-
- gchar *head = NULL;
-
- if (argc <= 0)
- {
- head = gitg_repository_parse_ref (self, "HEAD");
-
- if (head)
- {
- argv[start] = g_strdup ("HEAD");
- }
-
- g_free (head);
- }
- else
- {
- int i;
-
- for (i = 0; i < argc; ++i)
- {
- argv[start + i] = g_strdup (av[i]);
- }
- }
-
- g_strfreev (self->priv->last_args);
- self->priv->last_args = argv;
-
- gchar **newselection = copy_strv (av, argc);
-
- g_strfreev (self->priv->selection);
- self->priv->selection = newselection;
-}
-
-static void
-gitg_repository_init (GitgRepository *object)
-{
- object->priv = GITG_REPOSITORY_GET_PRIVATE (object);
-
- object->priv->hashtable = g_hash_table_new (gitg_hash_hash,
- gitg_hash_hash_equal);
-
- object->priv->ref_pushes = g_hash_table_new (gitg_hash_hash,
- gitg_hash_hash_equal);
-
- object->priv->ref_names = g_hash_table_new (g_str_hash, g_str_equal);
-
- object->priv->column_types[0] = GITG_TYPE_REVISION;
- object->priv->column_types[1] = G_TYPE_STRING;
- object->priv->column_types[2] = G_TYPE_STRING;
- object->priv->column_types[3] = G_TYPE_STRING;
-
- object->priv->lanes = gitg_lanes_new ();
- object->priv->grow_size = 1000;
- object->priv->stamp = g_random_int ();
-
- object->priv->refs = g_hash_table_new_full (gitg_hash_hash,
- gitg_hash_hash_equal,
- NULL,
- (GDestroyNotify)free_refs);
-
- object->priv->loader = gitg_shell_new (10000);
- gitg_io_set_auto_utf8 (GITG_IO (object->priv->loader), FALSE);
-
- g_signal_connect (object->priv->loader,
- "update",
- G_CALLBACK (on_loader_update),
- object);
-
- g_signal_connect (object->priv->loader,
- "end",
- G_CALLBACK (on_loader_end_loading),
- object);
-}
-
-static void
-grow_storage (GitgRepository *repository,
- gint size)
-{
- if (repository->priv->size + size <= repository->priv->allocated)
- {
- return;
- }
-
- gulong prevallocated = repository->priv->allocated;
- repository->priv->allocated += repository->priv->grow_size;
- GitgRevision **newstorage = g_slice_alloc (sizeof (GitgRevision *) * repository->priv->allocated);
-
- gint i;
- for (i = 0; i < repository->priv->size; ++i)
- {
- newstorage[i] = repository->priv->storage[i];
- }
-
- if (repository->priv->storage)
- {
- g_slice_free1 (sizeof (GitgRevision *) * prevallocated,
- repository->priv->storage);
- }
-
- repository->priv->storage = newstorage;
-}
-
-GitgRepository *
-gitg_repository_new (GFile *git_dir,
- GFile *work_tree)
-{
- return g_object_new (GITG_TYPE_REPOSITORY,
- "git-dir", git_dir,
- "work-tree", work_tree,
- NULL);
-}
-
-GFile *
-gitg_repository_get_work_tree (GitgRepository *self)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (self), NULL);
-
- return g_file_dup (self->priv->work_tree);
-}
-
-GFile *
-gitg_repository_get_git_dir (GitgRepository *self)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (self), NULL);
-
- return g_file_dup (self->priv->git_dir);
-}
-
-GitgShell *
-gitg_repository_get_loader (GitgRepository *self)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (self), NULL);
- return GITG_SHELL (g_object_ref (self->priv->loader));
-}
-
-static gboolean
-reload_revisions (GitgRepository *repository,
- GError **error)
-{
- if (repository->priv->working_ref)
- {
- gitg_ref_free (repository->priv->working_ref);
- repository->priv->working_ref = NULL;
- }
-
- g_signal_emit (repository, repository_signals[LOAD], 0);
-
- repository->priv->load_stage = LOAD_STAGE_STASH;
-
- return gitg_shell_run (repository->priv->loader,
- gitg_command_new (repository,
- "log",
- "--pretty=format:%H\x01%an\x01%ae\x01%at\x01%s",
- "--encoding=UTF-8",
- "-g",
- "refs/stash",
- NULL),
- error);
-}
-
-static gchar *
-load_current_ref (GitgRepository *self)
-{
- gchar **out;
- gchar *ret = NULL;
- gint i;
- gint numargs;
- gboolean retval;
-
- if (self->priv->last_args == NULL)
- {
- return NULL;
- }
-
- numargs = g_strv_length (self->priv->last_args);
-
- gchar const **argv = g_new0 (gchar const *, numargs + 3);
-
- argv[0] = "rev-parse";
- argv[1] = "--no-flags";
- argv[2] = "--symbolic-full-name";
-
- for (i = 1; i < numargs; ++i)
- {
- argv[2 + i] = self->priv->last_args[i];
- }
-
- retval = gitg_shell_run_sync_with_output (gitg_command_newv (self, argv),
- FALSE,
- &out,
- NULL);
-
- if (!retval || !out)
- {
- g_strfreev (out);
- return NULL;
- }
-
- if (*out && !*(out + 1))
- {
- ret = g_strdup (*out);
- }
-
- g_strfreev (out);
- return ret;
-}
-
-static void
-load_refs (GitgRepository *self)
-{
- gchar **refs;
- gboolean retval;
-
- retval = gitg_shell_run_sync_with_output (gitg_command_new (self,
- "for-each-ref",
- "--format=%(refname) %(objectname) %(*objectname)",
- "refs",
- NULL),
- FALSE,
- &refs,
- NULL);
-
- if (!retval || !refs)
- {
- g_strfreev (refs);
- return;
- }
-
- gchar **buffer = refs;
- gchar *buf;
- gchar *current = load_current_ref (self);
-
- GitgRef *working = gitg_repository_get_current_working_ref (self);
-
- while (buffer != NULL && (buf = *buffer++) != NULL)
- {
- // each line will look like <name> <hash>
- gchar **components = g_strsplit (buf, " ", 3);
- guint len = g_strv_length (components);
-
- if (len == 2 || len == 3)
- {
- gchar const *obj = len == 3 && *components[2] ? components[2] : components[1];
- GitgRef *ref = add_ref (self, obj, components[0]);
-
- if (current != NULL && strcmp (gitg_ref_get_name (ref), current) == 0)
- {
- self->priv->current_ref = gitg_ref_copy (ref);
- }
-
- if (working != NULL && gitg_ref_equal (working, ref))
- {
- gitg_ref_set_working (ref, TRUE);
- }
- }
-
- g_strfreev (components);
- }
-
- g_strfreev (refs);
- g_free (current);
-}
-
-void
-gitg_repository_reload (GitgRepository *repository)
-{
- g_return_if_fail (GITG_IS_REPOSITORY (repository));
- g_return_if_fail (repository->priv->git_dir != NULL);
-
- gitg_io_cancel (GITG_IO (repository->priv->loader));
-
- repository->priv->load_stage = LOAD_STAGE_NONE;
- gitg_repository_clear (repository);
-
- load_refs (repository);
- reload_revisions (repository, NULL);
-}
-
-gboolean
-gitg_repository_load (GitgRepository *self,
- int argc,
- gchar const **av,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (self), FALSE);
-
- if (self->priv->git_dir == NULL)
- {
- if (error)
- {
- *error = g_error_new_literal (gitg_repository_error_quark (),
- GITG_REPOSITORY_ERROR_NOT_FOUND,
- _ ("Not a valid git repository"));
- }
-
- return FALSE;
- }
-
- gitg_io_cancel (GITG_IO (self->priv->loader));
- gitg_repository_clear (self);
-
- build_log_args (self, argc, av);
-
- /* first get the refs */
- load_refs (self);
-
- /* request log (all the revision) */
- return reload_revisions (self, error);
-}
-
-void
-gitg_repository_add (GitgRepository *self,
- GitgRevision *obj,
- GtkTreeIter *iter)
-{
- GtkTreeIter iter1;
-
- /* validate our parameters */
- g_return_if_fail (GITG_IS_REPOSITORY (self));
-
- grow_storage (self, 1);
-
- /* put this object in our data storage */
- self->priv->storage[self->priv->size++] = gitg_revision_ref (obj);
-
- g_hash_table_insert (self->priv->hashtable,
- (gpointer)gitg_revision_get_hash (obj),
- GUINT_TO_POINTER (self->priv->size - 1));
-
- iter1.stamp = self->priv->stamp;
- iter1.user_data = GINT_TO_POINTER (self->priv->size - 1);
- iter1.user_data2 = NULL;
- iter1.user_data3 = NULL;
-
- GtkTreePath *path = gtk_tree_path_new_from_indices (self->priv->size - 1, -1);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (self), path, &iter1);
- gtk_tree_path_free (path);
-
- /* return the iter if the user cares */
- if (iter)
- {
- *iter = iter1;
- }
-}
-
-void
-gitg_repository_clear (GitgRepository *repository)
-{
- g_return_if_fail (GITG_IS_REPOSITORY (repository));
- do_clear (repository, TRUE);
-}
-
-GitgRevision *
-gitg_repository_lookup (GitgRepository *store,
- gchar const *hash)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (store), NULL);
-
- gpointer result = g_hash_table_lookup (store->priv->hashtable, hash);
-
- if (!result)
- {
- return NULL;
- }
-
- return store->priv->storage[GPOINTER_TO_UINT (result)];
-}
-
-gboolean
-gitg_repository_find_by_hash (GitgRepository *store,
- gchar const *hash,
- GtkTreeIter *iter)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (store), FALSE);
-
- gpointer result = g_hash_table_lookup (store->priv->hashtable, hash);
-
- if (!result)
- {
- return FALSE;
- }
-
- GtkTreePath *path = gtk_tree_path_new_from_indices (GPOINTER_TO_UINT (result),
- -1);
- gtk_tree_model_get_iter (GTK_TREE_MODEL (store), iter, path);
- gtk_tree_path_free (path);
-
- return TRUE;
-}
-
-gboolean
-gitg_repository_find (GitgRepository *store,
- GitgRevision *revision,
- GtkTreeIter *iter)
-{
- return gitg_repository_find_by_hash (store,
- gitg_revision_get_hash (revision),
- iter);
-}
-
-static gint
-ref_compare (GitgRef *a,
- GitgRef *b)
-{
- GitgRefType t1 = gitg_ref_get_ref_type (a);
- GitgRefType t2 = gitg_ref_get_ref_type (b);
-
- if (t1 != t2)
- {
- return t1 < t2 ? -1 : 1;
- }
- else
- {
- return g_strcmp0 (gitg_ref_get_shortname (a),
- gitg_ref_get_shortname (b));
- }
-}
-
-GSList *
-gitg_repository_get_refs (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- GList *values = g_hash_table_get_values (repository->priv->refs);
- GSList *ret = NULL;
- GList *item;
-
- for (item = values; item; item = item->next)
- {
- GSList *val;
-
- for (val = item->data; val; val = val->next)
- {
- ret = g_slist_insert_sorted (ret,
- gitg_ref_copy (val->data),
- (GCompareFunc)ref_compare);
- }
- }
-
- g_list_free (values);
-
- return ret;
-}
-
-GSList *
-gitg_repository_get_refs_for_hash (GitgRepository *repository,
- gchar const *hash)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
- return g_slist_copy ( (GSList *)g_hash_table_lookup (repository->priv->refs, hash));
-}
-
-GitgRef *
-gitg_repository_get_current_ref (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- return repository->priv->current_ref;
-}
-
-gchar *
-gitg_repository_relative (GitgRepository *repository,
- GFile *file)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
- g_return_val_if_fail (repository->priv->work_tree != NULL, NULL);
-
- return g_file_get_relative_path (repository->priv->work_tree, file);
-}
-
-gchar *
-gitg_repository_parse_ref (GitgRepository *repository,
- gchar const *ref)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- return parse_ref_intern (repository, ref, FALSE);
-}
-
-gchar *
-gitg_repository_parse_head (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- gchar *ret = gitg_repository_parse_ref (repository, "HEAD");
-
- if (!ret)
- {
- ret = g_strdup ("4b825dc642cb6eb9a060e54bf8d69288fbee4904");
- }
-
- return ret;
-}
-
-GitgRef *
-gitg_repository_get_current_working_ref (GitgRepository *repository)
-{
- if (repository->priv->working_ref)
- {
- return repository->priv->working_ref;
- }
-
- repository->priv->working_ref = get_current_working_ref (repository);
- return repository->priv->working_ref;
-}
-
-gchar **
-gitg_repository_get_remotes (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- GitgConfig *config = gitg_config_new (repository);
- gchar *ret = gitg_config_get_value_regex (config, "remote\\..*\\.url", NULL);
-
- GPtrArray *remotes = g_ptr_array_new ();
-
- if (!ret)
- {
- g_ptr_array_add (remotes, NULL);
- g_object_unref (config);
-
- return (gchar **)g_ptr_array_free (remotes, FALSE);
- }
-
- gchar **lines = g_strsplit (ret, "\n", -1);
- gchar **ptr = lines;
-
- g_free (ret);
-
- GRegex *regex = g_regex_new ("remote\\.(.+?)\\.url\\s+(.*)", 0, 0, NULL);
-
- while (*ptr)
- {
- GMatchInfo *info = NULL;
-
- if (g_regex_match (regex, *ptr, 0, &info))
- {
- gchar *name = g_match_info_fetch (info, 1);
-
- g_ptr_array_add (remotes, name);
- }
-
- g_match_info_free (info);
- ++ptr;
- }
-
- /* NULL terminate */
- g_ptr_array_add (remotes, NULL);
- g_object_unref (config);
- g_strfreev (lines);
-
- return (gchar **)g_ptr_array_free (remotes, FALSE);
-}
-
-GSList const *
-gitg_repository_get_ref_pushes (GitgRepository *repository, GitgRef *ref)
-
-{
- gpointer ret;
- GitgRef *my_ref;
-
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- my_ref = g_hash_table_lookup (repository->priv->ref_names,
- gitg_ref_get_name (ref));
-
- if (!my_ref)
- {
- return NULL;
- }
-
- if (g_hash_table_lookup_extended (repository->priv->ref_pushes,
- my_ref,
- NULL,
- &ret))
- {
- return ret;
- }
-
- GitgConfig *config = gitg_config_new (repository);
- gchar *escaped = g_regex_escape_string (gitg_ref_get_name (my_ref), -1);
- gchar *value_regex = g_strdup_printf ("^%s:", escaped);
-
- gchar *pushes = gitg_config_get_value_regex (config,
- "remote\\..*\\.push",
- value_regex);
-
- g_free (escaped);
- g_free (value_regex);
-
- if (!pushes || !*pushes)
- {
- g_object_unref (config);
- g_free (pushes);
-
- g_hash_table_insert (repository->priv->ref_pushes,
- my_ref,
- NULL);
-
- return NULL;
- }
-
- gchar **lines = g_strsplit (pushes, "\n", -1);
- gchar **ptr = lines;
-
- g_free (pushes);
-
- GRegex *regex = g_regex_new ("remote\\(.+?)\\.push\\s+.*:refs/heads/(.*)", 0, 0, NULL);
- GSList *refs = NULL;
-
- while (*ptr)
- {
- GMatchInfo *info = NULL;
-
- if (g_regex_match (regex, *ptr, 0, &info))
- {
- gchar *remote = g_match_info_fetch (info, 1);
- gchar *branch = g_match_info_fetch (info, 2);
-
- gchar *rr = g_strconcat ("refs/remotes/", remote, "/", branch, NULL);
-
- GitgRef *remref = g_hash_table_lookup (repository->priv->ref_names,
- rr);
-
- g_free (rr);
- g_free (remote);
- g_free (branch);
-
- if (remref)
- {
- refs = g_slist_prepend (refs, remref);
- }
- }
-
- g_match_info_free (info);
- ++ptr;
- }
-
- g_object_unref (config);
- g_strfreev (lines);
-
- refs = g_slist_reverse (refs);
-
- g_hash_table_insert (repository->priv->ref_pushes,
- my_ref,
- refs);
-
- return refs;
-}
-
-gboolean
-gitg_repository_get_loaded (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
-
- return repository->priv->load_stage == LOAD_STAGE_LAST &&
- !gitg_io_get_running (GITG_IO (repository->priv->loader));
-}
-
-gchar const **
-gitg_repository_get_current_selection (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
-
- return (gchar const **)repository->priv->selection;
-}
-
-gboolean
-gitg_repository_exists (GitgRepository *repository)
-{
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
-
- if (repository->priv->git_dir == NULL)
- {
- return FALSE;
- }
-
- return g_file_query_exists (repository->priv->git_dir, NULL) &&
- g_file_query_exists (repository->priv->work_tree, NULL);
-}
-
-static void
-collect_update (GitgShell *shell,
- gchar const * const *lines,
- GPtrArray *ret)
-{
- while (lines && *lines)
- {
- g_ptr_array_add (ret, g_strdup (*lines++));
- }
-}
-
-gboolean
-gitg_repository_run_hook (GitgRepository *repository,
- gchar const *name,
- GError **error,
- ...)
-{
- GFile *hooksdir;
- GFile *hookfile;
- GitgCommand *command;
- gchar *path;
- GPtrArray *args;
- gchar **argsv;
- gchar **ret;
- va_list ap;
- gchar const *arg;
- GFileInfo *info;
- gboolean canexec;
- gboolean retval;
- GitgShell *shell;
- GPtrArray *ptrar;
- GFile *index_file;
-
- g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
-
- if (repository->priv->git_dir == NULL)
- {
- return FALSE;
- }
-
- hooksdir = g_file_get_child (repository->priv->git_dir, "hooks");
- hookfile = g_file_get_child (hooksdir, name);
- g_object_unref (hooksdir);
-
- info = g_file_query_info (hookfile,
- G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
- G_FILE_QUERY_INFO_NONE,
- NULL,
- NULL);
-
- canexec = info &&
- g_file_info_get_attribute_boolean (info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
-
- if (info)
- {
- g_object_unref (info);
- }
-
- if (!canexec)
- {
- /* It's considered a success if the hook cannot be executed */
- g_object_unref (hookfile);
- return TRUE;
- }
-
- path = g_file_get_path (hookfile);
- g_object_unref (hookfile);
-
- args = g_ptr_array_new ();
- g_ptr_array_add (args, path);
-
- va_start (ap, error);
-
- while ((arg = va_arg (ap, gchar const *)) != NULL)
- {
- g_ptr_array_add (args, g_strdup (arg));
- }
-
- va_end (ap);
-
- g_ptr_array_add (args, NULL);
- argsv = (gchar **)g_ptr_array_free (args, FALSE);
-
- command = gitg_command_newv (NULL,
- (gchar const * const *)argsv);
-
- gitg_command_set_working_directory (command, repository->priv->work_tree);
-
- path = g_file_get_path (repository->priv->git_dir);
- gitg_command_add_environment (command, "GIT_DIR", path, NULL);
- g_free (path);
-
- index_file = g_file_get_child (repository->priv->git_dir, "index");
- path = g_file_get_path (index_file);
- g_object_unref (index_file);
-
- gitg_command_add_environment (command, "GIT_INDEX_FILE", path, NULL);
- g_free (path);
-
- g_strfreev (argsv);
-
- shell = gitg_shell_new_synchronized (1000);
-
- gitg_io_set_stderr_to_stdout (GITG_IO (shell), TRUE);
- gitg_shell_set_preserve_line_endings (shell, TRUE);
-
- ptrar = g_ptr_array_sized_new (100);
-
- g_signal_connect (shell,
- "update",
- G_CALLBACK (collect_update),
- ptrar);
-
- retval = gitg_shell_run (shell, command, error) &&
- gitg_io_get_exit_status (GITG_IO (shell)) == 0;
-
- g_ptr_array_add (ptrar, NULL);
- ret = (gchar **)g_ptr_array_free (ptrar, FALSE);
-
- if (!retval)
- {
- if (error)
- {
- gchar *joined;
-
- joined = g_strjoinv ("", ret);
-
- if (*error)
- {
- g_prefix_error (error,
- "Hook `%s' failed: %s",
- name,
- joined);
- }
- else
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Hook `%s' failed: %s",
- name,
- joined);
- }
-
- g_free (joined);
- }
- }
-
- g_strfreev (ret);
-
- return retval;
-}
diff --git a/libgitg/gitg-repository.h b/libgitg/gitg-repository.h
deleted file mode 100644
index aebe815..0000000
--- a/libgitg/gitg-repository.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * gitg-repository.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REPOSITORY_H__
-#define __GITG_REPOSITORY_H__
-
-#include <gtk/gtk.h>
-
-#include <libgitg/gitg-revision.h>
-#include <libgitg/gitg-ref.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REPOSITORY (gitg_repository_get_type ())
-#define GITG_REPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REPOSITORY, GitgRepository))
-#define GITG_REPOSITORY_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REPOSITORY, GitgRepository const))
-#define GITG_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_REPOSITORY, GitgRepositoryClass))
-#define GITG_IS_REPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REPOSITORY))
-#define GITG_IS_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_REPOSITORY))
-#define GITG_REPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_REPOSITORY, GitgRepositoryClass))
-
-typedef struct _GitgRepository GitgRepository;
-typedef struct _GitgRepositoryClass GitgRepositoryClass;
-typedef struct _GitgRepositoryPrivate GitgRepositoryPrivate;
-
-struct _GitgShell;
-
-typedef enum
-{
- GITG_REPOSITORY_NO_ERROR = 0,
- GITG_REPOSITORY_ERROR_NOT_FOUND
-} GitgRepositoryError;
-
-struct _GitgRepository
-{
- GObject parent;
-
- GitgRepositoryPrivate *priv;
-};
-
-struct _GitgRepositoryClass
-{
- GObjectClass parent_class;
-
- void (*load) (GitgRepository *repository);
- void (*loaded) (GitgRepository *repository);
-};
-
-GType gitg_repository_get_type (void) G_GNUC_CONST;
-
-GitgRepository *gitg_repository_new (GFile *git_dir,
- GFile *work_tree);
-
-GFile *gitg_repository_get_work_tree (GitgRepository *repository);
-GFile *gitg_repository_get_git_dir (GitgRepository *repository);
-
-gboolean gitg_repository_exists (GitgRepository *repository);
-
-gboolean gitg_repository_load(GitgRepository *repository, int argc, gchar const **argv, GError **error);
-gboolean gitg_repository_get_loaded(GitgRepository *repository);
-
-void gitg_repository_add(GitgRepository *repository, GitgRevision *revision, GtkTreeIter *iter);
-void gitg_repository_clear(GitgRepository *repository);
-
-gboolean gitg_repository_find_by_hash(GitgRepository *self, gchar const *hash, GtkTreeIter *iter);
-gboolean gitg_repository_find(GitgRepository *store, GitgRevision *revision, GtkTreeIter *iter);
-GitgRevision *gitg_repository_lookup(GitgRepository *store, gchar const *hash);
-
-GSList *gitg_repository_get_refs(GitgRepository *repository);
-GSList *gitg_repository_get_refs_for_hash(GitgRepository *repository, gchar const *hash);
-GitgRef *gitg_repository_get_current_ref(GitgRepository *repository);
-GitgRef *gitg_repository_get_current_working_ref(GitgRepository *repository);
-
-gchar *gitg_repository_relative(GitgRepository *repository, GFile *file);
-
-gchar *gitg_repository_parse_ref(GitgRepository *repository, gchar const *ref);
-gchar *gitg_repository_parse_head(GitgRepository *repository);
-
-void gitg_repository_reload(GitgRepository *repository);
-
-struct _GitgShell *gitg_repository_get_loader (GitgRepository *repository);
-
-gchar **gitg_repository_get_remotes (GitgRepository *repository);
-GSList const *gitg_repository_get_ref_pushes (GitgRepository *repository, GitgRef *ref);
-gchar const **gitg_repository_get_current_selection (GitgRepository *repository);
-
-gboolean gitg_repository_run_hook (GitgRepository *repository,
- gchar const *name,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-G_END_DECLS
-
-#endif /* __GITG_REPOSITORY_H__ */
diff --git a/libgitg/gitg-repository.vala b/libgitg/gitg-repository.vala
new file mode 100644
index 0000000..927f878
--- /dev/null
+++ b/libgitg/gitg-repository.vala
@@ -0,0 +1,38 @@
+namespace Gitg
+{
+
+public class Repository : Ggit.Repository
+{
+ public Repository(File location, File? workdir) throws Error
+ {
+ Object(location: location,
+ workdir: workdir);
+
+ ((Initable)this).init(null);
+ }
+
+ // Wrappers for Gitg.Ref
+ public new Ref lookup_reference(string name) throws Error
+ {
+ return base.lookup_reference(name) as Ref;
+ }
+
+ public new Ref create_reference(string name, Ggit.OId oid) throws Error
+ {
+ return base.create_reference(name, oid) as Ref;
+ }
+
+ public new Ref create_symbolic_reference(string name, string target) throws Error
+ {
+ return base.create_symbolic_reference(name, target) as Ref;
+ }
+
+ public new Gitg.Ref get_head() throws Error
+ {
+ return base.get_head() as Ref;
+ }
+}
+
+}
+
+// ex:set ts=4 noet
diff --git a/libgitg/gitg-revision.c b/libgitg/gitg-revision.c
deleted file mode 100644
index 579c878..0000000
--- a/libgitg/gitg-revision.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * gitg-revision.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-convert.h"
-#include "gitg-revision.h"
-#include "gitg-hash.h"
-
-struct _GitgRevision
-{
- gint refcount;
-
- GitgHash hash;
-
- gchar *author;
- gchar *author_email;
- gint64 author_date;
-
- gchar *committer;
- gchar *committer_email;
- gint64 committer_date;
-
- gchar *subject;
-
- GitgHash *parents;
- guint num_parents;
- char sign;
-
- GSList *lanes;
- gint8 mylane;
-};
-
-G_DEFINE_BOXED_TYPE (GitgRevision, gitg_revision, gitg_revision_ref, gitg_revision_unref)
-
-static void
-free_lanes (GitgRevision *rv)
-{
- g_slist_free_full (rv->lanes, (GDestroyNotify)gitg_lane_free);
- rv->lanes = NULL;
-}
-
-static void
-gitg_revision_finalize (GitgRevision *revision)
-{
- g_free (revision->author);
- g_free (revision->author_email);
-
- g_free (revision->committer);
- g_free (revision->committer_email);
-
- g_free (revision->subject);
- g_free (revision->parents);
-
- free_lanes (revision);
-
- g_slice_free (GitgRevision, revision);
-}
-
-GitgRevision *
-gitg_revision_ref (GitgRevision *revision)
-{
- if (revision == NULL)
- {
- return NULL;
- }
-
- g_atomic_int_inc (&revision->refcount);
- return revision;
-}
-
-void
-gitg_revision_unref (GitgRevision *revision)
-{
- if (revision == NULL)
- {
- return;
- }
-
- if (!g_atomic_int_dec_and_test (&revision->refcount))
- {
- return;
- }
-
- gitg_revision_finalize (revision);
-}
-
-GitgRevision *
-gitg_revision_new (gchar const *sha,
- gchar const *author,
- gchar const *author_email,
- gint64 author_date,
- gchar const *committer,
- gchar const *committer_email,
- gint64 committer_date,
- gchar const *subject,
- gchar const *parents)
-{
- GitgRevision *rv = g_slice_new0 (GitgRevision);
-
- rv->refcount = 1;
-
- gitg_hash_sha1_to_hash (sha, rv->hash);
-
- rv->author = g_strdup (author);
- rv->author_email = g_strdup (author_email);
- rv->author_date = author_date;
-
- rv->committer = g_strdup (committer);
- rv->committer_email = g_strdup (committer_email);
- rv->committer_date = committer_date;
-
- rv->subject = g_strdup (subject);
-
- if (parents)
- {
- gchar **shas = g_strsplit (parents, " ", 0);
- gint num = g_strv_length (shas);
- rv->parents = g_new (GitgHash, num + 1);
-
- gint i;
-
- for (i = 0; i < num; ++i)
- {
- gitg_hash_sha1_to_hash (shas[i], rv->parents[i]);
- }
-
- g_strfreev (shas);
- rv->num_parents = num;
- }
-
- return rv;
-}
-
-gchar const *
-gitg_revision_get_author (GitgRevision *revision)
-{
- return revision->author;
-}
-
-gchar const *
-gitg_revision_get_author_email (GitgRevision *revision)
-{
- return revision->author_email;
-}
-
-gint64
-gitg_revision_get_author_date (GitgRevision *revision)
-{
- return revision->author_date;
-}
-
-gchar const *
-gitg_revision_get_committer (GitgRevision *revision)
-{
- return revision->committer;
-}
-
-gchar const *
-gitg_revision_get_committer_email (GitgRevision *revision)
-{
- return revision->committer_email;
-}
-
-gint64
-gitg_revision_get_committer_date (GitgRevision *revision)
-{
- return revision->committer_date;
-}
-
-gchar const *
-gitg_revision_get_subject (GitgRevision *revision)
-{
- return revision->subject;
-}
-
-gchar const *
-gitg_revision_get_hash (GitgRevision *revision)
-{
- return revision->hash;
-}
-
-gchar *
-gitg_revision_get_sha1 (GitgRevision *revision)
-{
- char res[GITG_HASH_SHA_SIZE];
- gitg_hash_hash_to_sha1 (revision->hash, res);
-
- return g_strndup (res, GITG_HASH_SHA_SIZE);
-}
-
-GitgHash *
-gitg_revision_get_parents_hash (GitgRevision *revision,
- guint *num_parents)
-{
- if (num_parents)
- {
- *num_parents = revision->num_parents;
- }
-
- return revision->parents;
-}
-
-gchar **
-gitg_revision_get_parents (GitgRevision *revision)
-{
- gchar **ret = g_new (gchar *, revision->num_parents + 1);
-
- gint i;
-
- for (i = 0; i < revision->num_parents; ++i)
- {
- ret[i] = g_new (gchar, GITG_HASH_SHA_SIZE + 1);
- gitg_hash_hash_to_sha1 (revision->parents[i], ret[i]);
-
- ret[i][GITG_HASH_SHA_SIZE] = '\0';
- }
-
- ret[revision->num_parents] = NULL;
-
- return ret;
-}
-
-GSList *
-gitg_revision_get_lanes (GitgRevision *revision)
-{
- return revision->lanes;
-}
-
-GSList *
-gitg_revision_remove_lane (GitgRevision *revision,
- GitgLane *lane)
-{
- revision->lanes = g_slist_remove (revision->lanes, lane);
- gitg_lane_free (lane);
-
- return revision->lanes;
-}
-
-GSList *
-gitg_revision_insert_lane (GitgRevision *revision,
- GitgLane *lane,
- gint index)
-{
- revision->lanes = g_slist_insert (revision->lanes, lane, index);
-
- return revision->lanes;
-}
-
-static void
-update_lane_type (GitgRevision *revision)
-{
- GitgLane *lane = (GitgLane *)g_slist_nth_data (revision->lanes, revision->mylane);
-
- if (lane == NULL)
- {
- return;
- }
-
- lane->type &= ~ (GITG_LANE_SIGN_LEFT |
- GITG_LANE_SIGN_RIGHT |
- GITG_LANE_SIGN_STASH |
- GITG_LANE_SIGN_STAGED |
- GITG_LANE_SIGN_UNSTAGED);
-
- switch (revision->sign)
- {
- case '<':
- lane->type |= GITG_LANE_SIGN_LEFT;
- break;
- case '>':
- lane->type |= GITG_LANE_SIGN_RIGHT;
- break;
- case 's':
- lane->type |= GITG_LANE_SIGN_STASH;
- break;
- case 't':
- lane->type |= GITG_LANE_SIGN_STAGED;
- break;
- case 'u':
- lane->type |= GITG_LANE_SIGN_UNSTAGED;
- break;
- }
-}
-
-void
-gitg_revision_set_lanes (GitgRevision *revision,
- GSList *lanes,
- gint8 mylane)
-{
- free_lanes (revision);
- revision->lanes = lanes;
-
- if (mylane >= 0)
- {
- revision->mylane = mylane;
- }
-
- update_lane_type (revision);
-}
-
-gint8
-gitg_revision_get_mylane (GitgRevision *revision)
-{
- return revision->mylane;
-}
-
-void
-gitg_revision_set_mylane (GitgRevision *revision,
- gint8 mylane)
-{
- g_return_if_fail (mylane >= 0);
-
- revision->mylane = mylane;
- update_lane_type (revision);
-}
-
-void
-gitg_revision_set_sign (GitgRevision *revision,
- char sign)
-{
- revision->sign = sign;
-}
-
-char
-gitg_revision_get_sign (GitgRevision *revision)
-{
- return revision->sign;
-}
-
-GitgLane *
-gitg_revision_get_lane (GitgRevision *revision)
-{
- return (GitgLane *)g_slist_nth_data (revision->lanes, revision->mylane);
-}
-
-gchar *
-gitg_revision_get_format_patch_name (GitgRevision *revision)
-{
- GString *ret;
- gboolean lastisspace = FALSE;
- gchar const *ptr;
-
- ret = g_string_new ("");
- ptr = revision->subject;
-
- do
- {
- gunichar c;
-
- c = g_utf8_get_char (ptr);
-
- if (c == ' ' || c == '/')
- {
- if (!lastisspace)
- {
- g_string_append_c (ret, '-');
- lastisspace = TRUE;
- }
- }
- else
- {
- g_string_append_unichar (ret, c);
- }
- } while (*(ptr = g_utf8_next_char (ptr)));
-
- return g_string_free (ret, FALSE);
-}
-
-static gchar *
-date_for_display (gint64 date)
-{
- if (date < 0)
- {
- return g_strdup ("");
- }
-
- time_t t = date;
- struct tm *tms = localtime (&t);
- gchar buf[255];
-
- strftime (buf, 254, "%c", tms);
- return gitg_convert_utf8 (buf, -1);
-}
-
-gchar *
-gitg_revision_get_author_date_for_display (GitgRevision *revision)
-{
- return date_for_display (gitg_revision_get_author_date (revision));
-}
-
-gchar *
-gitg_revision_get_committer_date_for_display (GitgRevision *revision)
-{
- return date_for_display (gitg_revision_get_committer_date (revision));
-}
diff --git a/libgitg/gitg-revision.h b/libgitg/gitg-revision.h
deleted file mode 100644
index e01a141..0000000
--- a/libgitg/gitg-revision.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * gitg-revision.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_REVISION_H__
-#define __GITG_REVISION_H__
-
-#include <glib-object.h>
-#include <libgitg/gitg-lane.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_REVISION (gitg_revision_get_type ())
-#define GITG_REVISION(obj) ((GitgRevision *)obj)
-#define GITG_REVISION_CONST(obj) ((GitgRevision const *)obj)
-
-typedef struct _GitgRevision GitgRevision;
-
-GType gitg_revision_get_type (void) G_GNUC_CONST;
-
-GitgRevision *gitg_revision_new (gchar const *hash,
- gchar const *author,
- gchar const *author_email,
- gint64 author_date,
- gchar const *committer,
- gchar const *committer_email,
- gint64 committer_date,
- gchar const *subject,
- gchar const *parents);
-
-inline gchar const *gitg_revision_get_author (GitgRevision *revision);
-inline gchar const *gitg_revision_get_author_email (GitgRevision *revision);
-inline gint64 gitg_revision_get_author_date (GitgRevision *revision);
-
-inline gchar const *gitg_revision_get_committer (GitgRevision *revision);
-inline gchar const *gitg_revision_get_committer_email (GitgRevision *revision);
-inline gint64 gitg_revision_get_committer_date (GitgRevision *revision);
-
-inline gchar const *gitg_revision_get_subject (GitgRevision *revision);
-
-inline gchar const *gitg_revision_get_hash (GitgRevision *revision);
-inline GitgHash *gitg_revision_get_parents_hash (GitgRevision *revision, guint *num_parents);
-
-gchar *gitg_revision_get_sha1 (GitgRevision *revision);
-gchar **gitg_revision_get_parents (GitgRevision *revision);
-
-GSList *gitg_revision_get_lanes (GitgRevision *revision);
-GitgLane *gitg_revision_get_lane (GitgRevision *revision);
-void gitg_revision_set_lanes (GitgRevision *revision, GSList *lanes, gint8 mylane);
-
-GSList *gitg_revision_remove_lane (GitgRevision *revision, GitgLane *lane);
-GSList *gitg_revision_insert_lane (GitgRevision *revision, GitgLane *lane, gint index);
-
-gint8 gitg_revision_get_mylane (GitgRevision *revision);
-void gitg_revision_set_mylane (GitgRevision *revision, gint8 mylane);
-
-void gitg_revision_set_sign(GitgRevision *revision, char sign);
-char gitg_revision_get_sign(GitgRevision *revision);
-
-GitgRevision *gitg_revision_ref (GitgRevision *revision);
-void gitg_revision_unref (GitgRevision *revision);
-
-gchar *gitg_revision_get_format_patch_name (GitgRevision *revision);
-
-gchar *gitg_revision_get_author_date_for_display (GitgRevision *revision);
-gchar *gitg_revision_get_committer_date_for_display (GitgRevision *revision);
-
-G_END_DECLS
-
-#endif /* __GITG_REVISION_H__ */
diff --git a/libgitg/gitg-runner.c b/libgitg/gitg-runner.c
deleted file mode 100644
index 1800415..0000000
--- a/libgitg/gitg-runner.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * gitg-runner.c
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * gitg 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.
- *
- * gitg 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 gitg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <gio/gunixoutputstream.h>
-#include <gio/gunixinputstream.h>
-
-#include "gitg-runner.h"
-#include "gitg-debug.h"
-
-#include "gitg-smart-charset-converter.h"
-
-#define GITG_RUNNER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_RUNNER, GitgRunnerPrivate))
-
-struct _GitgRunnerPrivate
-{
- GitgCommand *command;
-
- GInputStream *g_stdout;
- GOutputStream *g_stdin;
-
- GCancellable *cancellable;
- gboolean cancelled;
-
- GPid pid;
- guint watch_id;
-};
-
-G_DEFINE_TYPE (GitgRunner, gitg_runner, GITG_TYPE_IO)
-
-enum
-{
- PROP_0,
- PROP_COMMAND
-};
-
-typedef struct
-{
- GitgRunner *runner;
- GCancellable *cancellable;
-} AsyncData;
-
-static AsyncData *
-async_data_new (GitgRunner *runner)
-{
- AsyncData *data;
-
- data = g_slice_new (AsyncData);
-
- data->runner = runner;
- data->cancellable = g_object_ref (runner->priv->cancellable);
-
- return data;
-}
-
-static void
-async_data_free (AsyncData *data)
-{
- g_object_unref (data->cancellable);
- g_slice_free (AsyncData, data);
-}
-
-static void
-gitg_runner_finalize (GObject *object)
-{
- G_OBJECT_CLASS (gitg_runner_parent_class)->finalize (object);
-}
-
-static void
-close_streams (GitgRunner *runner)
-{
- if (runner->priv->cancellable)
- {
- g_cancellable_cancel (runner->priv->cancellable);
- }
-
- if (runner->priv->g_stdin != NULL)
- {
- g_output_stream_close (runner->priv->g_stdin, NULL, NULL);
- g_object_unref (runner->priv->g_stdin);
-
- runner->priv->g_stdin = NULL;
- }
-
- if (runner->priv->g_stdout != NULL)
- {
- g_input_stream_close (runner->priv->g_stdout, NULL, NULL);
- g_object_unref (runner->priv->g_stdout);
-
- runner->priv->g_stdout = NULL;
- }
-
- gitg_io_close (GITG_IO (runner));
-}
-
-static void
-gitg_runner_dispose (GObject *object)
-{
- GitgRunner *runner;
-
- runner = GITG_RUNNER (object);
-
- if (runner->priv->command != NULL)
- {
- g_object_unref (runner->priv->command);
- runner->priv->command = NULL;
- }
-
- gitg_io_cancel (GITG_IO (runner));
-
- close_streams (runner);
-
- G_OBJECT_CLASS (gitg_runner_parent_class)->dispose (object);
-}
-
-static void
-gitg_runner_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgRunner *self = GITG_RUNNER (object);
-
- switch (prop_id)
- {
- case PROP_COMMAND:
- gitg_runner_set_command (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_runner_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgRunner *self = GITG_RUNNER (object);
-
- switch (prop_id)
- {
- case PROP_COMMAND:
- g_value_set_object (value, self->priv->command);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-dummy_cb (GPid pid,
- gint status,
- gpointer data)
-{
-}
-
-static void
-kill_process (GitgRunner *runner)
-{
- if (runner->priv->pid == 0)
- {
- return;
- }
-
- /* We remove our handler for the process here and install a dummy
- handler later so it will still be properly reaped */
- g_source_remove (runner->priv->watch_id);
- kill (runner->priv->pid, SIGTERM);
-
- g_child_watch_add (runner->priv->pid, dummy_cb, NULL);
-
- runner->priv->pid = 0;
-
- gitg_io_set_exit_status (GITG_IO (runner), EXIT_FAILURE);
-}
-
-static void
-runner_done (GitgRunner *runner,
- GError *error)
-{
- close_streams (runner);
- kill_process (runner);
-
- if (!error && gitg_io_get_exit_status (GITG_IO (runner)) != 0)
- {
- GError *err;
-
- err = g_error_new (G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Process exited with non-zero exit code: %d",
- gitg_io_get_exit_status (GITG_IO (runner)));
-
- gitg_io_end (GITG_IO (runner), err);
- g_error_free (err);
- }
- else
- {
- gitg_io_end (GITG_IO (runner), error);
- }
-}
-
-static void
-gitg_runner_cancel (GitgIO *io)
-{
- gboolean was_running;
- GitgRunner *runner;
-
- runner = GITG_RUNNER (io);
-
- if (runner->priv->cancellable)
- {
- g_cancellable_cancel (runner->priv->cancellable);
-
- g_object_unref (runner->priv->cancellable);
- runner->priv->cancellable = NULL;
- }
-
- was_running = gitg_io_get_running (GITG_IO (runner));
-
- GITG_IO_CLASS (gitg_runner_parent_class)->cancel (GITG_IO (runner));
-
- if (was_running)
- {
- runner_done (runner, NULL);
- }
-}
-
-static void
-gitg_runner_class_init (GitgRunnerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GitgIOClass *io_class = GITG_IO_CLASS (klass);
-
- object_class->finalize = gitg_runner_finalize;
- object_class->dispose = gitg_runner_dispose;
-
- object_class->get_property = gitg_runner_get_property;
- object_class->set_property = gitg_runner_set_property;
-
- io_class->cancel = gitg_runner_cancel;
-
- g_type_class_add_private (object_class, sizeof(GitgRunnerPrivate));
-
- g_object_class_install_property (object_class,
- PROP_COMMAND,
- g_param_spec_object ("command",
- "Command",
- "Command",
- GITG_TYPE_COMMAND,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-}
-
-static void
-gitg_runner_init (GitgRunner *self)
-{
- self->priv = GITG_RUNNER_GET_PRIVATE (self);
-}
-
-GitgRunner *
-gitg_runner_new (GitgCommand *command)
-{
- return g_object_new (GITG_TYPE_RUNNER,
- "command", command,
- NULL);
-}
-
-static void
-splice_input_ready_cb (GOutputStream *source,
- GAsyncResult *result,
- AsyncData *data)
-{
- GError *error = NULL;
- gboolean ret;
-
- ret = g_output_stream_splice_finish (source, result, &error);
-
- if (g_cancellable_is_cancelled (data->cancellable))
- {
- if (error)
- {
- g_error_free (error);
- }
-
- async_data_free (data);
- return;
- }
-
- if (!ret)
- {
- runner_done (data->runner, error);
- }
-
- if (error)
- {
- g_error_free (error);
- }
-
- async_data_free (data);
-}
-
-static void
-splice_output_ready_cb (GOutputStream *source,
- GAsyncResult *result,
- AsyncData *data)
-{
- GError *error = NULL;
- gboolean ret;
-
- ret = g_output_stream_splice_finish (source, result, &error);
-
- if (g_cancellable_is_cancelled (data->cancellable))
- {
- if (error)
- {
- g_error_free (error);
- }
-
- async_data_free (data);
- return;
- }
-
- if (!ret)
- {
- runner_done (data->runner, error);
- }
- else if (data->runner->priv->pid == 0)
- {
- runner_done (data->runner, NULL);
- }
-
- if (error)
- {
- g_error_free (error);
- }
-
- async_data_free (data);
-}
-
-void
-gitg_runner_stream_close (GitgRunner *runner,
- GError *error)
-{
- g_return_if_fail (GITG_IS_RUNNER (runner));
-
- if (runner->priv->pid == 0 || error)
- {
- runner_done (runner, error);
- }
- else
- {
- g_input_stream_close (runner->priv->g_stdout, NULL, NULL);
- }
-}
-
-static void
-process_watch_cb (GPid pid,
- gint status,
- GitgRunner *runner)
-{
- runner->priv->pid = 0;
-
- if (WIFEXITED (status))
- {
- gitg_io_set_exit_status (GITG_IO (runner), WEXITSTATUS (status));
- }
- else
- {
- gitg_io_set_exit_status (GITG_IO (runner), 0);
- }
-
- /* Note that we don't emit 'done' here because the streams might not
- yet be ready with all their writing/reading */
- if (runner->priv->cancellable)
- {
- g_object_unref (runner->priv->cancellable);
- runner->priv->cancellable = NULL;
- }
-
- runner->priv->watch_id = 0;
-
- if (runner->priv->g_stdout == NULL || g_input_stream_is_closed (runner->priv->g_stdout))
- {
- runner_done (runner, NULL);
- }
-}
-
-static void
-debug_runner_command (GitgRunner *runner)
-{
- gchar *argstr;
- gchar const * const *envs;
- GFile *wd;
-
- argstr = g_strjoinv (" ", (gchar **)gitg_command_get_arguments (runner->priv->command));
-
- gitg_debug (GITG_DEBUG_SHELL,
- "Running command: %s", argstr);
-
- g_free (argstr);
-
- envs = gitg_command_get_environment (runner->priv->command);
-
- if (envs)
- {
- gchar *environment;
- environment = g_strjoinv (", ", (gchar **)envs);
-
- gitg_debug (GITG_DEBUG_SHELL,
- "Environment: %s", environment);
-
- g_free (environment);
- }
- else
- {
- gitg_debug (GITG_DEBUG_SHELL,
- "Environment: None");
- }
-
- wd = gitg_command_get_working_directory (runner->priv->command);
-
- if (wd)
- {
- gchar *path;
-
- path = g_file_get_path (wd);
-
- gitg_debug (GITG_DEBUG_SHELL, "CWD: %s", path);
-
- g_free (path);
- g_object_unref (wd);
- }
- else
- {
- gitg_debug (GITG_DEBUG_SHELL, "CWD: None\n");
- }
-}
-
-static void
-setup_dup_stderr_to_stdout ()
-{
- dup2 (1, 2);
-}
-
-void
-gitg_runner_run (GitgRunner *runner)
-{
- gboolean ret;
- gint stdinf;
- gint g_stdoutf;
- GFile *working_directory;
- gchar *wd_path = NULL;
- GInputStream *start_input;
- GOutputStream *end_output;
- GInputStream *output;
- GitgSmartCharsetConverter *smart;
- GError *error = NULL;
- GSpawnFlags flags = 0;
- gboolean redirect_stderr;
- GSpawnChildSetupFunc setup_func = NULL;
-
- g_return_if_fail (GITG_IS_RUNNER (runner));
-
- gitg_io_cancel (GITG_IO (runner));
-
- runner->priv->cancelled = FALSE;
-
- working_directory = gitg_command_get_working_directory (runner->priv->command);
-
- if (working_directory)
- {
- wd_path = g_file_get_path (working_directory);
- g_object_unref (working_directory);
- }
-
- start_input = gitg_io_get_input (GITG_IO (runner));
-
- if (gitg_debug_enabled (GITG_DEBUG_SHELL))
- {
- debug_runner_command (runner);
- }
-
- redirect_stderr = gitg_io_get_stderr_to_stdout (GITG_IO (runner));
-
- if (!redirect_stderr && !gitg_debug_enabled (GITG_DEBUG_SHELL))
- {
- flags = G_SPAWN_STDERR_TO_DEV_NULL;
- }
-
- if (redirect_stderr)
- {
- setup_func = (GSpawnChildSetupFunc)setup_dup_stderr_to_stdout;
- }
-
- ret = g_spawn_async_with_pipes (wd_path,
- (gchar **)gitg_command_get_arguments (runner->priv->command),
- (gchar **)gitg_command_get_environment (runner->priv->command),
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD |
- flags,
- setup_func,
- NULL,
- &(runner->priv->pid),
- start_input ? &stdinf : NULL,
- &g_stdoutf,
- NULL,
- &error);
-
- g_free (wd_path);
-
- gitg_io_begin (GITG_IO (runner));
-
- if (!ret)
- {
- runner_done (runner, error);
- g_error_free (error);
- return;
- }
-
- runner->priv->watch_id = g_child_watch_add (runner->priv->pid,
- (GChildWatchFunc)process_watch_cb,
- runner);
-
- if (start_input)
- {
- AsyncData *data;
-
- runner->priv->cancellable = g_cancellable_new ();
-
- runner->priv->g_stdin =
- G_OUTPUT_STREAM (g_unix_output_stream_new (stdinf,
- TRUE));
-
- data = async_data_new (runner);
-
- /* Splice the supplied input to g_stdin of the process */
- g_output_stream_splice_async (runner->priv->g_stdin,
- start_input,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
- G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- G_PRIORITY_DEFAULT,
- runner->priv->cancellable,
- (GAsyncReadyCallback)splice_input_ready_cb,
- data);
- }
-
- output = G_INPUT_STREAM (g_unix_input_stream_new (g_stdoutf,
- TRUE));
-
- if (gitg_io_get_auto_utf8 (GITG_IO (runner)))
- {
- smart = gitg_smart_charset_converter_new (gitg_encoding_get_candidates ());
-
- runner->priv->g_stdout = g_converter_input_stream_new (output,
- G_CONVERTER (smart));
-
- g_object_unref (smart);
- g_object_unref (output);
- }
- else
- {
- runner->priv->g_stdout = output;
- }
-
- end_output = gitg_io_get_output (GITG_IO (runner));
-
- if (end_output)
- {
- AsyncData *data;
-
- if (runner->priv->cancellable == NULL)
- {
- runner->priv->cancellable = g_cancellable_new ();
- }
-
- data = async_data_new (runner);
-
- /* Splice output of the process into the provided stream */
- g_output_stream_splice_async (end_output,
- runner->priv->g_stdout,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
- G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- G_PRIORITY_DEFAULT,
- runner->priv->cancellable,
- (GAsyncReadyCallback)splice_output_ready_cb,
- data);
- }
-}
-
-GInputStream *
-gitg_runner_get_stream (GitgRunner *runner)
-{
- g_return_val_if_fail (GITG_IS_RUNNER (runner), NULL);
-
- return runner->priv->g_stdout;
-}
-
-void
-gitg_runner_set_command (GitgRunner *runner, GitgCommand *command)
-{
- g_return_if_fail (GITG_IS_RUNNER (runner));
- g_return_if_fail (GITG_IS_COMMAND (command));
-
- if (runner->priv->command)
- {
- g_object_unref (runner->priv->command);
- }
-
- runner->priv->command = g_object_ref_sink (command);
- g_object_notify (G_OBJECT (runner), "command");
-}
-
-GitgCommand *
-gitg_runner_get_command (GitgRunner *runner)
-{
- g_return_val_if_fail (GITG_IS_RUNNER (runner), NULL);
-
- return runner->priv->command;
-}
diff --git a/libgitg/gitg-runner.h b/libgitg/gitg-runner.h
deleted file mode 100644
index d6ba1d3..0000000
--- a/libgitg/gitg-runner.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * gitg-runner.h
- * This file is part of gitg
- *
- * Copyright (C) 2010 - Jesse van den Kieboom
- *
- * gitg 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.
- *
- * gitg 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 gitg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_RUNNER_H__
-#define __GITG_RUNNER_H__
-
-#include <glib-object.h>
-#include <libgitg/gitg-command.h>
-#include <libgitg/gitg-io.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_RUNNER (gitg_runner_get_type ())
-#define GITG_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RUNNER, GitgRunner))
-#define GITG_RUNNER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RUNNER, GitgRunner const))
-#define GITG_RUNNER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_RUNNER, GitgRunnerClass))
-#define GITG_IS_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_RUNNER))
-#define GITG_IS_RUNNER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_RUNNER))
-#define GITG_RUNNER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_RUNNER, GitgRunnerClass))
-
-typedef struct _GitgRunner GitgRunner;
-typedef struct _GitgRunnerClass GitgRunnerClass;
-typedef struct _GitgRunnerPrivate GitgRunnerPrivate;
-
-struct _GitgRunner
-{
- /*< private >*/
- GitgIO parent;
-
- GitgRunnerPrivate *priv;
-
- /*< public >*/
-};
-
-struct _GitgRunnerClass
-{
- /*< private >*/
- GitgIOClass parent_class;
-
- /*< public >*/
-};
-
-GType gitg_runner_get_type (void) G_GNUC_CONST;
-GitgRunner *gitg_runner_new (GitgCommand *command);
-
-void gitg_runner_run (GitgRunner *runner);
-
-GitgCommand *gitg_runner_get_command (GitgRunner *runner);
-void gitg_runner_set_command (GitgRunner *runner, GitgCommand *command);
-
-GInputStream *gitg_runner_get_stream (GitgRunner *runner);
-void gitg_runner_stream_close (GitgRunner *runner, GError *error);
-
-G_END_DECLS
-
-#endif /* __GITG_RUNNER_H__ */
diff --git a/libgitg/gitg-shell.c b/libgitg/gitg-shell.c
deleted file mode 100644
index 56a31e6..0000000
--- a/libgitg/gitg-shell.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * gitg-shell.c
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#include "gitg-convert.h"
-#include "gitg-debug.h"
-#include "gitg-shell.h"
-#include "gitg-smart-charset-converter.h"
-#include "gitg-runner.h"
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <gio/gio.h>
-#include <gio/gunixoutputstream.h>
-#include <gio/gunixinputstream.h>
-
-#include "gitg-line-parser.h"
-
-#define GITG_SHELL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_SHELL, GitgShellPrivate))
-
-/* Signals */
-enum
-{
- UPDATE,
- LAST_SIGNAL
-};
-
-static guint shell_signals[LAST_SIGNAL] = { 0 };
-
-/* Properties */
-enum
-{
- PROP_0,
-
- PROP_BUFFER_SIZE,
- PROP_SYNCHRONIZED,
- PROP_PRESERVE_LINE_ENDINGS
-};
-
-struct _GitgShellPrivate
-{
- GSList *runners;
-
- GCancellable *cancellable;
- GError *error;
-
- GMainLoop *main_loop;
- GitgRunner *last_runner;
-
- guint buffer_size;
- GitgLineParser *line_parser;
-
- guint synchronized : 1;
- guint preserve_line_endings : 1;
- guint cancelled : 1;
- guint read_done : 1;
-};
-
-static void shell_done (GitgShell *shell, GError *error);
-
-G_DEFINE_TYPE (GitgShell, gitg_shell, GITG_TYPE_IO)
-
-static void
-runner_end (GitgRunner *runner,
- GError *error,
- GitgShell *shell)
-{
- if (!shell->priv->runners)
- {
- return;
- }
-
- if ((runner == shell->priv->last_runner && shell->priv->read_done) || error)
- {
- shell_done (shell, error);
- }
-}
-
-static void
-close_runners (GitgShell *shell)
-{
- GSList *item;
-
- for (item = shell->priv->runners; item; item = g_slist_next (item))
- {
- GitgRunner *runner = item->data;
-
- g_signal_handlers_disconnect_by_func (runner,
- runner_end,
- shell);
-
- gitg_io_close (GITG_IO (runner));
- g_object_unref (runner);
- }
-
- g_slist_free (shell->priv->runners);
- shell->priv->runners = NULL;
-
- if (shell->priv->line_parser)
- {
- g_object_unref (shell->priv->line_parser);
- shell->priv->line_parser = NULL;
- }
-
- shell->priv->last_runner = NULL;
-}
-
-static void
-gitg_shell_finalize (GObject *object)
-{
- GitgShell *shell = GITG_SHELL (object);
-
- /* Cancel possible running */
- gitg_io_cancel (GITG_IO (shell));
-
- if (shell->priv->cancellable)
- {
- g_object_unref (shell->priv->cancellable);
- }
-
- G_OBJECT_CLASS (gitg_shell_parent_class)->finalize (object);
-}
-
-static void
-gitg_shell_dispose (GObject *object)
-{
- GitgShell *shell;
-
- shell = GITG_SHELL (object);
-
- close_runners (shell);
-}
-
-static void
-gitg_shell_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GitgShell *shell = GITG_SHELL (object);
-
- switch (prop_id)
- {
- case PROP_BUFFER_SIZE:
- g_value_set_uint (value, shell->priv->buffer_size);
- break;
- case PROP_SYNCHRONIZED:
- g_value_set_boolean (value, shell->priv->synchronized);
- break;
- case PROP_PRESERVE_LINE_ENDINGS:
- g_value_set_boolean (value, shell->priv->preserve_line_endings);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_shell_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GitgShell *shell = GITG_SHELL (object);
-
- switch (prop_id)
- {
- case PROP_BUFFER_SIZE:
- shell->priv->buffer_size = g_value_get_uint (value);
- break;
- case PROP_SYNCHRONIZED:
- shell->priv->synchronized = g_value_get_boolean (value);
- break;
- case PROP_PRESERVE_LINE_ENDINGS:
- shell->priv->preserve_line_endings = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gitg_shell_cancel (GitgIO *io)
-{
- gboolean was_running;
- GitgShell *shell;
-
- shell = GITG_SHELL (io);
-
- if (shell->priv->line_parser)
- {
- g_object_unref (shell->priv->line_parser);
- shell->priv->line_parser = NULL;
- }
-
- was_running = gitg_io_get_running (io);
-
- GITG_IO_CLASS (gitg_shell_parent_class)->cancel (io);
-
- if (was_running)
- {
- shell_done (GITG_SHELL (io), NULL);
- }
-}
-
-static void
-gitg_shell_class_init (GitgShellClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GitgIOClass *io_class = GITG_IO_CLASS (klass);
-
- object_class->finalize = gitg_shell_finalize;
- object_class->dispose = gitg_shell_dispose;
-
- object_class->get_property = gitg_shell_get_property;
- object_class->set_property = gitg_shell_set_property;
-
- io_class->cancel = gitg_shell_cancel;
-
- g_object_class_install_property (object_class, PROP_BUFFER_SIZE,
- g_param_spec_uint ("buffer_size",
- "BUFFER SIZE",
- "The shells buffer size",
- 1,
- G_MAXUINT,
- 1,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class, PROP_SYNCHRONIZED,
- g_param_spec_boolean ("synchronized",
- "SYNCHRONIZED",
- "Whether the command is ran synchronized",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_PRESERVE_LINE_ENDINGS,
- g_param_spec_boolean ("preserve-line-endings",
- "Preserve Line Endings",
- "preserve line endings",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- shell_signals[UPDATE] =
- g_signal_new ("update",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GitgShellClass, update),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE,
- 1,
- G_TYPE_POINTER);
-
- g_type_class_add_private (object_class, sizeof (GitgShellPrivate));
-}
-
-static void
-gitg_shell_init (GitgShell *self)
-{
- self->priv = GITG_SHELL_GET_PRIVATE (self);
-
- self->priv->cancellable = g_cancellable_new ();
-}
-
-GitgShell *
-gitg_shell_new (guint buffer_size)
-{
- g_assert (buffer_size > 0);
-
- return GITG_SHELL (g_object_new (GITG_TYPE_SHELL,
- "buffer_size",
- buffer_size,
- "synchronized",
- FALSE,
- NULL));
-}
-
-GitgShell *
-gitg_shell_new_synchronized (guint buffer_size)
-{
- g_assert (buffer_size > 0);
-
- return GITG_SHELL (g_object_new (GITG_TYPE_SHELL,
- "buffer_size",
- buffer_size,
- "synchronized",
- TRUE,
- NULL));
-}
-
-void
-gitg_shell_set_preserve_line_endings (GitgShell *shell,
- gboolean preserve_line_endings)
-{
- g_return_if_fail (GITG_IS_SHELL (shell));
-
- shell->priv->preserve_line_endings = preserve_line_endings;
- g_object_notify (G_OBJECT (shell), "preserve-line-endings");
-}
-
-gboolean
-gitg_shell_get_preserve_line_endings (GitgShell *shell)
-{
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
-
- return shell->priv->preserve_line_endings;
-}
-
-static void
-shell_done (GitgShell *shell,
- GError *error)
-{
- if (shell->priv->error)
- {
- g_error_free (shell->priv->error);
- shell->priv->error = NULL;
- }
-
- if (error)
- {
- shell->priv->error = g_error_copy (error);
- gitg_io_set_exit_status (GITG_IO (shell), EXIT_FAILURE);
- }
-
- if (shell->priv->main_loop)
- {
- g_main_loop_quit (shell->priv->main_loop);
- g_main_loop_unref (shell->priv->main_loop);
-
- shell->priv->main_loop = NULL;
- }
-
- if (shell->priv->runners == NULL)
- {
- return;
- }
-
- if (shell->priv->cancellable)
- {
- g_cancellable_cancel (shell->priv->cancellable);
- g_object_unref (shell->priv->cancellable);
-
- shell->priv->cancellable = NULL;
- }
-
- /* Take over the exit code of the last runner */
- if (!error)
- {
- gitg_io_set_exit_status (GITG_IO (shell),
- gitg_io_get_exit_status (GITG_IO (shell->priv->last_runner)));
- }
-
- close_runners (shell);
- gitg_io_close (GITG_IO (shell));
-
- gitg_io_end (GITG_IO (shell), error);
-}
-
-static gboolean
-run_sync (GitgShell *shell,
- GError **error)
-{
- g_main_loop_run (shell->priv->main_loop);
-
- if (shell->priv->error)
- {
- g_propagate_error (error, shell->priv->error);
- shell->priv->error = NULL;
-
- return FALSE;
- }
-
- return gitg_io_get_exit_status (GITG_IO (shell)) == 0;
-}
-
-static void
-on_lines_done_cb (GitgLineParser *parser,
- GError *error,
- GitgShell *shell)
-{
- if (!shell->priv->read_done)
- {
- shell->priv->read_done = TRUE;
-
- if (shell->priv->last_runner == NULL)
- {
- shell_done (shell, error);
- }
- else
- {
- gitg_runner_stream_close (shell->priv->last_runner, NULL);
- }
- }
-}
-
-static void
-on_lines_cb (GitgLineParser *parser,
- gchar **lines,
- GitgShell *shell)
-{
- g_signal_emit (shell, shell_signals[UPDATE], 0, lines);
-}
-
-static void
-run_stream (GitgShell *shell,
- GInputStream *stream)
-{
- shell->priv->cancellable = g_cancellable_new ();
-
- shell->priv->read_done = FALSE;
-
- shell->priv->line_parser = gitg_line_parser_new (shell->priv->buffer_size,
- shell->priv->preserve_line_endings);
-
- g_signal_connect (shell->priv->line_parser,
- "lines",
- G_CALLBACK (on_lines_cb),
- shell);
-
- g_signal_connect (shell->priv->line_parser,
- "done",
- G_CALLBACK (on_lines_done_cb),
- shell);
-
- gitg_line_parser_parse (shell->priv->line_parser,
- stream,
- shell->priv->cancellable);
-}
-
-static gboolean
-run_commands (GitgShell *shell,
- GitgCommand **commands,
- GError **error)
-{
- GitgIO *io;
- GitgRunner *prev = NULL;
- GOutputStream *output;
- gboolean ret = TRUE;
- GitgCommand **ptr;
-
- io = GITG_IO (shell);
- output = gitg_io_get_output (io);
-
- shell->priv->read_done = TRUE;
-
- gitg_io_cancel (GITG_IO (shell));
-
- gitg_io_begin (GITG_IO (shell));
-
- /* Ref sink all commands */
- for (ptr = commands; *ptr; ++ptr)
- {
- g_object_ref_sink (*ptr);
- }
-
- if (shell->priv->synchronized)
- {
- shell->priv->main_loop = g_main_loop_new (NULL, FALSE);
- }
-
- /* Setup runners */
- for (ptr = commands; *ptr; ++ptr)
- {
- GitgRunner *runner;
-
- runner = gitg_runner_new (*ptr);
-
- if (gitg_io_get_stderr_to_stdout (GITG_IO (shell)))
- {
- gitg_io_set_stderr_to_stdout (GITG_IO (runner), TRUE);
- }
-
- g_signal_connect (runner,
- "end",
- G_CALLBACK (runner_end),
- shell);
-
- if (ptr == commands)
- {
- /* Copy input set on the shell to the first runner */
- GInputStream *input;
-
- input = gitg_io_get_input (io);
-
- if (input != NULL)
- {
- gitg_io_set_input (GITG_IO (runner), input);
- }
- }
- else
- {
- /* Set output of the previous runner to the input of
- this runner */
- gitg_io_set_input (GITG_IO (runner),
- gitg_runner_get_stream (prev));
- }
-
- if (!*(ptr + 1))
- {
- shell->priv->last_runner = runner;
-
- /* Copy output set on the shell to the last runner */
- if (output != NULL)
- {
- gitg_io_set_output (GITG_IO (runner), output);
- }
- }
-
- shell->priv->runners = g_slist_append (shell->priv->runners,
- runner);
-
- /* Start the runner */
- gitg_runner_run (runner);
-
- if (shell->priv->runners == NULL)
- {
- /* This means it there was an error */
- if (error && shell->priv->error)
- {
- *error = g_error_copy (shell->priv->error);
- }
-
- if (shell->priv->error)
- {
- g_error_free (shell->priv->error);
- shell->priv->error = NULL;
- }
-
- ret = FALSE;
- goto cleanup;
- }
-
- prev = runner;
- }
-
- /* Setup line reader if necessary in async mode */
- if (output == NULL)
- {
- run_stream (shell, gitg_runner_get_stream (shell->priv->last_runner));
- }
-
- if (shell->priv->synchronized)
- {
- return run_sync (shell, error);
- }
-
-cleanup:
- for (ptr = commands; *ptr; ++ptr)
- {
- g_object_unref (*ptr);
- }
-
- if (shell->priv->main_loop)
- {
- g_main_loop_unref (shell->priv->main_loop);
- shell->priv->main_loop = NULL;
- }
-
- return ret;
-}
-
-gboolean
-gitg_shell_run (GitgShell *shell,
- GitgCommand *command,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
- g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
-
- return gitg_shell_runv (shell, error, command, NULL);
-}
-
-gboolean
-gitg_shell_run_list (GitgShell *shell,
- GitgCommand **commands,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
-
- return run_commands (shell, commands, error);
-}
-
-gboolean
-gitg_shell_runva (GitgShell *shell,
- va_list ap,
- GError **error)
-{
- GPtrArray *ptr;
- GitgCommand **commands;
- GitgCommand *command;
- gboolean ret;
- guint num = 0;
-
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
-
- ptr = g_ptr_array_new ();
-
- while ((command = va_arg (ap, GitgCommand *)) != NULL)
- {
- g_ptr_array_add (ptr, command);
- ++num;
- }
-
- if (num == 0)
- {
- g_ptr_array_free (ptr, TRUE);
- return FALSE;
- }
-
- g_ptr_array_add (ptr, NULL);
-
- commands = (GitgCommand **)g_ptr_array_free (ptr, FALSE);
-
- ret = gitg_shell_run_list (shell, commands, error);
-
- g_free (commands);
-
- return ret;
-}
-
-gboolean
-gitg_shell_runv (GitgShell *shell,
- GError **error,
- ...)
-{
- va_list ap;
- gboolean ret;
-
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
-
- va_start (ap, error);
- ret = gitg_shell_runva (shell, ap, error);
- va_end (ap);
-
- return ret;
-}
-
-guint
-gitg_shell_get_buffer_size (GitgShell *shell)
-{
- g_return_val_if_fail (GITG_IS_SHELL (shell), 0);
- return shell->priv->buffer_size;
-}
-
-gboolean
-gitg_shell_run_sync_with_output (GitgCommand *command,
- gboolean preserve_line_endings,
- gchar ***output,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
-
- return gitg_shell_run_sync_with_outputv (preserve_line_endings,
- output,
- error,
- command,
- NULL);
-}
-
-static void
-collect_update (GitgShell *shell,
- gchar const * const *lines,
- GPtrArray *ret)
-{
- while (lines && *lines)
- {
- g_ptr_array_add (ret, g_strdup (*lines++));
- }
-}
-
-gboolean
-gitg_shell_run_sync_with_input_and_output_list (GitgCommand **commands,
- gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- GError **error)
-{
- GitgShell *shell;
- GPtrArray *ret;
- gboolean res;
- gchar **out;
-
- if (output)
- {
- *output = NULL;
- }
-
- shell = gitg_shell_new_synchronized (1000);
-
- gitg_shell_set_preserve_line_endings (shell, preserve_line_endings);
-
- ret = g_ptr_array_sized_new (100);
-
- g_signal_connect (shell,
- "update",
- G_CALLBACK (collect_update),
- ret);
-
- if (input)
- {
- GInputStream *stream;
-
- stream = g_memory_input_stream_new_from_data (g_strdup (input),
- -1,
- (GDestroyNotify)g_free);
-
- gitg_io_set_input (GITG_IO (shell), stream);
- g_object_unref (stream);
- }
-
- res = gitg_shell_run_list (shell, commands, error);
- g_ptr_array_add (ret, NULL);
- out = (gchar **)g_ptr_array_free (ret, FALSE);
-
- if (output)
- {
- *output = out;
- }
- else
- {
- g_strfreev (out);
- }
-
- if (!res || gitg_io_get_exit_status (GITG_IO (shell)) != 0)
- {
- g_object_unref (shell);
-
- return FALSE;
- }
-
- g_object_unref (shell);
-
- return TRUE;
-}
-
-static gboolean
-gitg_shell_run_sync_with_input_and_outputva (gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- va_list ap,
- GError **error)
-{
- GPtrArray *commands;
- GitgCommand *cmd;
- GitgCommand **cmds;
- gboolean ret;
-
- commands = g_ptr_array_new ();
-
- while ((cmd = va_arg (ap, GitgCommand *)))
- {
- g_ptr_array_add (commands, cmd);
- }
-
- g_ptr_array_add (commands, NULL);
- cmds = (GitgCommand **)g_ptr_array_free (commands, FALSE);
-
- ret = gitg_shell_run_sync_with_input_and_output_list (cmds,
- preserve_line_endings,
- input,
- output,
- error);
-
- g_free (cmds);
- return ret;
-}
-
-static gboolean
-gitg_shell_run_sync_with_outputva (gboolean preserve_line_endings,
- gchar ***output,
- va_list ap,
- GError **error)
-{
- return gitg_shell_run_sync_with_input_and_outputva (preserve_line_endings,
- NULL,
- output,
- ap,
- error);
-}
-
-gboolean
-gitg_shell_run_sync_with_output_list (GitgCommand **commands,
- gboolean preserve_line_endings,
- gchar ***output,
- GError **error)
-{
- return gitg_shell_run_sync_with_input_and_output_list (commands,
- preserve_line_endings,
- NULL,
- output,
- error);
-}
-
-gboolean
-gitg_shell_run_sync_with_outputv (gboolean preserve_line_endings,
- gchar ***output,
- GError **error,
- ...)
-{
- va_list ap;
- gboolean ret;
-
- va_start (ap, error);
- ret = gitg_shell_run_sync_with_outputva (preserve_line_endings,
- output,
- ap,
- error);
- va_end (ap);
-
- return ret;
-}
-
-gboolean
-gitg_shell_run_sync (GitgCommand *command,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
-
- return gitg_shell_run_syncv (error, command, NULL);
-}
-
-gboolean
-gitg_shell_run_sync_list (GitgCommand **commands,
- GError **error)
-{
- return gitg_shell_run_sync_with_output_list (commands, FALSE, NULL, error);
-}
-
-gboolean
-gitg_shell_run_syncv (GError **error,
- ...)
-{
- va_list ap;
- gboolean res;
-
- va_start (ap, error);
- res = gitg_shell_run_sync_with_outputva (FALSE, NULL, ap, error);
- va_end (ap);
-
- return res;
-}
-
-gboolean
-gitg_shell_run_sync_with_input (GitgCommand *command,
- const gchar *input,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
-
- return gitg_shell_run_sync_with_inputv (input, error, command, NULL);
-}
-
-gboolean
-gitg_shell_run_sync_with_input_list (GitgCommand **commands,
- const gchar *input,
- GError **error)
-{
- return gitg_shell_run_sync_with_input_and_output_list (commands,
- FALSE,
- input,
- NULL,
- error);
-}
-
-gboolean
-gitg_shell_run_sync_with_inputv (const gchar *input,
- GError **error,
- ...)
-{
- va_list ap;
- gboolean ret;
-
- va_start (ap, error);
- ret = gitg_shell_run_sync_with_input_and_outputva (FALSE,
- input,
- NULL,
- ap,
- error);
- va_end (ap);
-
- return ret;
-}
-
-gboolean
-gitg_shell_run_sync_with_input_and_output (GitgCommand *command,
- gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
-
- return gitg_shell_run_sync_with_input_and_outputv (preserve_line_endings,
- input,
- output,
- error,
- command,
- NULL);
-}
-
-gboolean
-gitg_shell_run_sync_with_input_and_outputv (gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- GError **error,
- ...)
-{
- va_list ap;
- gboolean ret;
-
- va_start (ap, error);
- ret = gitg_shell_run_sync_with_input_and_outputva (preserve_line_endings,
- input,
- output,
- ap,
- error);
- va_end (ap);
-
- return ret;
-}
-
-GitgCommand **
-gitg_shell_parse_commands (GitgRepository *repository,
- const gchar *cmdstr,
- GError **error)
-{
- gint argc;
- gchar **argv;
- GitgCommand *cmd = NULL;
- gint i;
- GPtrArray *commands;
- gboolean canenv = TRUE;
- guint num = 0;
-
- g_return_val_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository), NULL);
- g_return_val_if_fail (cmdstr != NULL, NULL);
-
- if (!g_shell_parse_argv (cmdstr, &argc, &argv, error))
- {
- return FALSE;
- }
-
- commands = g_ptr_array_new ();
-
- for (i = 0; i < argc; ++i)
- {
- gchar *pos;
-
- if (cmd == NULL)
- {
- cmd = gitg_command_new (repository, NULL);
- g_ptr_array_add (commands, cmd);
-
- canenv = TRUE;
- ++num;
- }
-
- if (strcmp (argv[i], "|") == 0)
- {
- cmd = NULL;
- }
- else if (canenv && (pos = g_utf8_strchr (argv[i], -1, '=')))
- {
- *pos = '\0';
- gitg_command_add_environment (cmd, argv[i], pos + 1, NULL);
- }
- else
- {
- canenv = FALSE;
- gitg_command_add_arguments (cmd, argv[i], NULL);
- }
- }
-
- g_strfreev (argv);
- g_ptr_array_add (commands, NULL);
-
- return (GitgCommand **)g_ptr_array_free (commands, FALSE);
-}
-
-gboolean
-gitg_shell_run_parse (GitgShell *shell,
- GitgRepository *repository,
- const gchar *cmdstr,
- GError **error)
-
-{
- gboolean ret;
- GitgCommand **commands;
-
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
- g_return_val_if_fail (cmdstr != NULL, FALSE);
- g_return_val_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository), FALSE);
-
- commands = gitg_shell_parse_commands (repository, cmdstr, error);
-
- if (!commands)
- {
- return FALSE;
- }
-
- ret = run_commands (shell, commands, error);
- g_free (commands);
-
- return ret;
-}
-
-gboolean
-gitg_shell_run_stream (GitgShell *shell,
- GInputStream *stream,
- GError **error)
-{
- g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE);
- g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
-
- gitg_io_cancel (GITG_IO (shell));
-
- run_stream (shell, stream);
- return TRUE;
-}
diff --git a/libgitg/gitg-shell.h b/libgitg/gitg-shell.h
deleted file mode 100644
index 2412ff3..0000000
--- a/libgitg/gitg-shell.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * gitg-shell.h
- * This file is part of gitg - git repository viewer
- *
- * Copyright (C) 2009 - Jesse van den Kieboom
- *
- * 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.
- */
-
-#ifndef __GITG_SHELL_H__
-#define __GITG_SHELL_H__
-
-#include <glib-object.h>
-#include <libgitg/gitg-io.h>
-#include <libgitg/gitg-command.h>
-#include <libgitg/gitg-repository.h>
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_SHELL (gitg_shell_get_type ())
-#define GITG_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_SHELL, GitgShell))
-#define GITG_SHELL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_SHELL, GitgShell const))
-#define GITG_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_SHELL, GitgShellClass))
-#define GITG_IS_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_SHELL))
-#define GITG_IS_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_SHELL))
-#define GITG_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_SHELL, GitgShellClass))
-
-#define GITG_SHELL_ERROR (gitg_shell_error_quark())
-
-typedef struct _GitgShell GitgShell;
-typedef struct _GitgShellClass GitgShellClass;
-typedef struct _GitgShellPrivate GitgShellPrivate;
-
-struct _GitgShell
-{
- GitgIO parent;
-
- GitgShellPrivate *priv;
-};
-
-struct _GitgShellClass
-{
- GitgIOClass parent_class;
-
- /* signals */
- void (* update) (GitgShell *shell,
- gchar const * const *buffer);
-};
-
-GType gitg_shell_get_type (void) G_GNUC_CONST;
-
-GitgShell *gitg_shell_new (guint buffer_size);
-GitgShell *gitg_shell_new_synchronized (guint buffer_size);
-
-void gitg_shell_set_preserve_line_endings (GitgShell *shell,
- gboolean preserve_line_endings);
-gboolean gitg_shell_get_preserve_line_endings (GitgShell *shell);
-
-guint gitg_shell_get_buffer_size (GitgShell *shell);
-
-GitgCommand **gitg_shell_parse_commands (GitgRepository *repository,
- const gchar *cmdstr,
- GError **error);
-
-gboolean gitg_shell_run_parse (GitgShell *shell,
- GitgRepository *repository,
- const gchar *cmd,
- GError **error);
-
-gboolean gitg_shell_runva (GitgShell *shell,
- va_list ap,
- GError **error);
-
-gboolean gitg_shell_run_stream (GitgShell *shell,
- GInputStream *stream,
- GError **error);
-
-gboolean gitg_shell_run (GitgShell *shell,
- GitgCommand *command,
- GError **error);
-
-gboolean gitg_shell_run_list (GitgShell *shell,
- GitgCommand **commands,
- GError **error);
-
-gboolean gitg_shell_runv (GitgShell *shell,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-gboolean gitg_shell_run_sync_with_output (GitgCommand *command,
- gboolean preserve_line_endings,
- gchar ***output,
- GError **error);
-
-gboolean gitg_shell_run_sync_with_output_list (GitgCommand **commands,
- gboolean preserve_line_endings,
- gchar ***output,
- GError **error);
-
-gboolean gitg_shell_run_sync_with_outputv (gboolean preserve_line_endings,
- gchar ***output,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-gboolean gitg_shell_run_sync (GitgCommand *command,
- GError **error);
-
-gboolean gitg_shell_run_sync_list (GitgCommand **commands,
- GError **error);
-
-gboolean gitg_shell_run_syncv (GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-gboolean gitg_shell_run_sync_with_input (GitgCommand *command,
- const gchar *input,
- GError **error);
-
-gboolean gitg_shell_run_sync_with_input_list (GitgCommand **commands,
- const gchar *input,
- GError **error);
-
-gboolean gitg_shell_run_sync_with_inputv (const gchar *input,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-gboolean gitg_shell_run_sync_with_input_and_output (GitgCommand *command,
- gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- GError **error);
-
-gboolean gitg_shell_run_sync_with_input_and_output_list (GitgCommand **commands,
- gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- GError **error);
-
-gboolean gitg_shell_run_sync_with_input_and_outputv (gboolean preserve_line_endings,
- const gchar *input,
- gchar ***output,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-G_END_DECLS
-
-#endif /* __GITG_SHELL_H__ */
diff --git a/libgitg/gitg-smart-charset-converter.c b/libgitg/gitg-smart-charset-converter.c
deleted file mode 100644
index dc07c25..0000000
--- a/libgitg/gitg-smart-charset-converter.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * gedit-smart-charset-converter.c
- * This file is part of gedit
- *
- * Copyright (C) 2009 - Ignacio Casal Quinteiro
- *
- * gedit 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.
- *
- * gedit 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 gedit; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include "gitg-smart-charset-converter.h"
-#include "gitg-debug.h"
-
-#include <gio/gio.h>
-#include <glib/gi18n.h>
-
-#define GITG_SMART_CHARSET_CONVERTER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_SMART_CHARSET_CONVERTER, GitgSmartCharsetConverterPrivate))
-
-struct _GitgSmartCharsetConverterPrivate
-{
- GCharsetConverter *charset_conv;
-
- GSList *encodings;
- GSList *current_encoding;
-
- guint is_utf8 : 1;
- guint use_first : 1;
-};
-
-static void gitg_smart_charset_converter_iface_init (GConverterIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GitgSmartCharsetConverter, gitg_smart_charset_converter,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
- gitg_smart_charset_converter_iface_init))
-
-GQuark
-gitg_charset_conversion_error_quark (void)
-{
- static GQuark ret = 0;
-
- if (G_UNLIKELY (ret == 0))
- {
- ret = g_quark_from_static_string ("GitgCharsetConversionError");
- }
-
- return ret;
-}
-
-static void
-gitg_smart_charset_converter_finalize (GObject *object)
-{
- GitgSmartCharsetConverter *smart = GITG_SMART_CHARSET_CONVERTER (object);
-
- g_slist_free (smart->priv->encodings);
-
- G_OBJECT_CLASS (gitg_smart_charset_converter_parent_class)->finalize (object);
-}
-
-static void
-gitg_smart_charset_converter_dispose (GObject *object)
-{
- GitgSmartCharsetConverter *smart = GITG_SMART_CHARSET_CONVERTER (object);
-
- if (smart->priv->charset_conv != NULL)
- {
- g_object_unref (smart->priv->charset_conv);
- smart->priv->charset_conv = NULL;
- }
-
- G_OBJECT_CLASS (gitg_smart_charset_converter_parent_class)->dispose (object);
-}
-
-static void
-gitg_smart_charset_converter_class_init (GitgSmartCharsetConverterClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gitg_smart_charset_converter_finalize;
- object_class->dispose = gitg_smart_charset_converter_dispose;
-
- g_type_class_add_private (object_class, sizeof (GitgSmartCharsetConverterPrivate));
-}
-
-static void
-gitg_smart_charset_converter_init (GitgSmartCharsetConverter *smart)
-{
- smart->priv = GITG_SMART_CHARSET_CONVERTER_GET_PRIVATE (smart);
-
- smart->priv->charset_conv = NULL;
- smart->priv->encodings = NULL;
- smart->priv->current_encoding = NULL;
- smart->priv->is_utf8 = FALSE;
- smart->priv->use_first = FALSE;
-}
-
-static const GitgEncoding *
-get_encoding (GitgSmartCharsetConverter *smart)
-{
- if (smart->priv->current_encoding == NULL)
- {
- smart->priv->current_encoding = smart->priv->encodings;
- }
- else
- {
- smart->priv->current_encoding = g_slist_next (smart->priv->current_encoding);
- }
-
- if (smart->priv->current_encoding != NULL)
- return (const GitgEncoding *)smart->priv->current_encoding->data;
-
-#if 0
- FIXME: uncomment this when using fallback
- /* If we tried all encodings, we return the first encoding */
- smart->priv->use_first = TRUE;
- smart->priv->current_encoding = smart->priv->encodings;
-
- return (const GitgEncoding *)smart->priv->current_encoding->data;
-#endif
- return NULL;
-}
-
-static gboolean
-try_convert (GCharsetConverter *converter,
- const void *inbuf,
- gsize inbuf_size)
-{
- GError *err;
- gsize bytes_read, nread;
- gsize bytes_written, nwritten;
- GConverterResult res;
- gchar *out;
- gboolean ret;
- gsize out_size;
-
- if (inbuf == NULL || inbuf_size == 0)
- {
- return FALSE;
- }
-
- err = NULL;
- nread = 0;
- nwritten = 0;
- out_size = inbuf_size * 4;
- out = g_malloc (out_size);
-
- do
- {
- res = g_converter_convert (G_CONVERTER (converter),
- (gchar *)inbuf + nread,
- inbuf_size - nread,
- (gchar *)out + nwritten,
- out_size - nwritten,
- G_CONVERTER_INPUT_AT_END,
- &bytes_read,
- &bytes_written,
- &err);
-
- nread += bytes_read;
- nwritten += bytes_written;
- } while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR && err == NULL);
-
- if (err != NULL)
- {
- if (err->code == G_CONVERT_ERROR_PARTIAL_INPUT)
- {
- /* FIXME We can get partial input while guessing the
- encoding because we just take some amount of text
- to guess from. */
- ret = TRUE;
- }
- else
- {
- ret = FALSE;
- }
-
- g_error_free (err);
- }
- else
- {
- ret = TRUE;
- }
-
- /* FIXME: Check the remainder? */
- if (ret == TRUE && !g_utf8_validate (out, nwritten, NULL))
- {
- ret = FALSE;
- }
-
- g_free (out);
-
- return ret;
-}
-
-static GCharsetConverter *
-guess_encoding (GitgSmartCharsetConverter *smart,
- const void *inbuf,
- gsize inbuf_size)
-{
- GCharsetConverter *conv = NULL;
-
- if (inbuf == NULL || inbuf_size == 0)
- {
- smart->priv->is_utf8 = TRUE;
- return NULL;
- }
-
- if (smart->priv->encodings != NULL &&
- smart->priv->encodings->next == NULL)
- {
- smart->priv->use_first = TRUE;
- }
-
- /* We just check the first block */
- while (TRUE)
- {
- const GitgEncoding *enc;
-
- if (conv != NULL)
- {
- g_object_unref (conv);
- conv = NULL;
- }
-
- /* We get an encoding from the list */
- enc = get_encoding (smart);
-
- /* if it is NULL we didn't guess anything */
- if (enc == NULL)
- {
- break;
- }
-
- if (enc == gitg_encoding_get_utf8 ())
- {
- gsize remainder;
- const gchar *end;
-
- if (g_utf8_validate (inbuf, inbuf_size, &end) ||
- smart->priv->use_first)
- {
- smart->priv->is_utf8 = TRUE;
- break;
- }
-
- /* Check if the end is less than one char */
- remainder = inbuf_size - (end - (gchar *)inbuf);
- if (remainder < 6)
- {
- smart->priv->is_utf8 = TRUE;
- break;
- }
-
- continue;
- }
-
- conv = g_charset_converter_new ("UTF-8",
- gitg_encoding_get_charset (enc),
- NULL);
-
- /* If we tried all encodings we use the first one */
- if (smart->priv->use_first)
- {
- break;
- }
-
- /* Try to convert */
- if (try_convert (conv, inbuf, inbuf_size))
- {
- gitg_debug (GITG_DEBUG_CHARSET_CONVERSION,
- "Guessed %s conversion",
- gitg_encoding_get_charset (enc));
- break;
- }
- }
-
- if (smart->priv->is_utf8)
- {
- gitg_debug (GITG_DEBUG_CHARSET_CONVERSION, "Guessed UTF8 conversion");
- }
-
- if (conv != NULL)
- {
- g_converter_reset (G_CONVERTER (conv));
-
- /* FIXME: uncomment this when we want to use the fallback
- g_charset_converter_set_use_fallback (conv, TRUE);*/
- }
-
- return conv;
-}
-
-static GConverterResult
-gitg_smart_charset_converter_convert (GConverter *converter,
- const void *inbuf,
- gsize inbuf_size,
- void *outbuf,
- gsize outbuf_size,
- GConverterFlags flags,
- gsize *bytes_read,
- gsize *bytes_written,
- GError **error)
-{
- GitgSmartCharsetConverter *smart = GITG_SMART_CHARSET_CONVERTER (converter);
-
- /* Guess the encoding if we didn't make it yet */
- if (smart->priv->charset_conv == NULL && !smart->priv->is_utf8)
- {
- smart->priv->charset_conv = guess_encoding (smart, inbuf, inbuf_size);
-
- /* If we still have the previous case is that we didn't guess
- anything */
- if (smart->priv->charset_conv == NULL && !smart->priv->is_utf8)
- {
- g_set_error_literal (error, GITG_CHARSET_CONVERSION_ERROR,
- GITG_CHARSET_CONVERSION_ERROR_ENCODING_AUTO_DETECTION_FAILED,
- _("It is not possible to detect the encoding automatically"));
-
- return G_CONVERTER_ERROR;
- }
- }
-
- /* Now if the encoding is utf8 just redirect the input to the output */
- if (smart->priv->is_utf8)
- {
- gsize size;
- GConverterResult ret;
-
- size = MIN (inbuf_size, outbuf_size);
-
- memcpy (outbuf, inbuf, size);
- *bytes_read = size;
- *bytes_written = size;
-
- ret = G_CONVERTER_CONVERTED;
-
- if (flags & G_CONVERTER_INPUT_AT_END)
- {
- ret = G_CONVERTER_FINISHED;
- }
- else if (flags & G_CONVERTER_FLUSH)
- {
- ret = G_CONVERTER_FLUSHED;
- }
-
- return ret;
- }
-
- /* If we reached here is because we need to convert the text so, we
- convert it with the charset converter */
- return g_converter_convert (G_CONVERTER (smart->priv->charset_conv),
- inbuf,
- inbuf_size,
- outbuf,
- outbuf_size,
- flags,
- bytes_read,
- bytes_written,
- error);
-}
-
-static void
-gitg_smart_charset_converter_reset (GConverter *converter)
-{
- GitgSmartCharsetConverter *smart = GITG_SMART_CHARSET_CONVERTER (converter);
-
- smart->priv->current_encoding = NULL;
- smart->priv->is_utf8 = FALSE;
-
- if (smart->priv->charset_conv != NULL)
- {
- g_object_unref (smart->priv->charset_conv);
- smart->priv->charset_conv = NULL;
- }
-}
-
-static void
-gitg_smart_charset_converter_iface_init (GConverterIface *iface)
-{
- iface->convert = gitg_smart_charset_converter_convert;
- iface->reset = gitg_smart_charset_converter_reset;
-}
-
-GitgSmartCharsetConverter *
-gitg_smart_charset_converter_new (GSList *candidate_encodings)
-{
- GitgSmartCharsetConverter *smart;
-
- g_return_val_if_fail (candidate_encodings != NULL, NULL);
-
- smart = g_object_new (GITG_TYPE_SMART_CHARSET_CONVERTER, NULL);
-
- smart->priv->encodings = g_slist_copy (candidate_encodings);
-
- return smart;
-}
-
-const GitgEncoding *
-gitg_smart_charset_converter_get_guessed (GitgSmartCharsetConverter *smart)
-{
- g_return_val_if_fail (GITG_IS_SMART_CHARSET_CONVERTER (smart), NULL);
-
- if (smart->priv->current_encoding != NULL)
- {
- return (const GitgEncoding *)smart->priv->current_encoding->data;
- }
- else if (smart->priv->is_utf8)
- {
- return gitg_encoding_get_utf8 ();
- }
-
- return NULL;
-}
-
-guint
-gitg_smart_charset_converter_get_num_fallbacks (GitgSmartCharsetConverter *smart)
-{
- g_return_val_if_fail (GITG_IS_SMART_CHARSET_CONVERTER (smart), FALSE);
-
- if (smart->priv->charset_conv == NULL)
- return FALSE;
-
- return g_charset_converter_get_num_fallbacks (smart->priv->charset_conv) != 0;
-}
-
-/* ex:ts=8:noet: */
diff --git a/libgitg/gitg-smart-charset-converter.h b/libgitg/gitg-smart-charset-converter.h
deleted file mode 100644
index 64d7aff..0000000
--- a/libgitg/gitg-smart-charset-converter.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * gedit-smart-charset-converter.h
- * This file is part of gedit
- *
- * Copyright (C) 2009 - Ignacio Casal Quinteiro
- *
- * gedit 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.
- *
- * gedit 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 gedit; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#ifndef __GITG_SMART_CHARSET_CONVERTER_H__
-#define __GITG_SMART_CHARSET_CONVERTER_H__
-
-#include <glib-object.h>
-
-#include "gitg-encodings.h"
-
-G_BEGIN_DECLS
-
-#define GITG_TYPE_SMART_CHARSET_CONVERTER (gitg_smart_charset_converter_get_type ())
-#define GITG_SMART_CHARSET_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_SMART_CHARSET_CONVERTER, GitgSmartCharsetConverter))
-#define GITG_SMART_CHARSET_CONVERTER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_SMART_CHARSET_CONVERTER, GitgSmartCharsetConverter const))
-#define GITG_SMART_CHARSET_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_SMART_CHARSET_CONVERTER, GitgSmartCharsetConverterClass))
-#define GITG_IS_SMART_CHARSET_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_SMART_CHARSET_CONVERTER))
-#define GITG_IS_SMART_CHARSET_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_SMART_CHARSET_CONVERTER))
-#define GITG_SMART_CHARSET_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_SMART_CHARSET_CONVERTER, GitgSmartCharsetConverterClass))
-
-typedef struct _GitgSmartCharsetConverter GitgSmartCharsetConverter;
-typedef struct _GitgSmartCharsetConverterClass GitgSmartCharsetConverterClass;
-typedef struct _GitgSmartCharsetConverterPrivate GitgSmartCharsetConverterPrivate;
-
-#define GITG_CHARSET_CONVERSION_ERROR (gitg_charset_conversion_error_quark ())
-
-typedef enum
-{
- GITG_CHARSET_CONVERSION_ERROR_ENCODING_AUTO_DETECTION_FAILED
-} GitgCharserConversionError;
-
-struct _GitgSmartCharsetConverter
-{
- GObject parent;
-
- GitgSmartCharsetConverterPrivate *priv;
-};
-
-struct _GitgSmartCharsetConverterClass
-{
- GObjectClass parent_class;
-};
-
-GType gitg_smart_charset_converter_get_type (void) G_GNUC_CONST;
-GQuark gitg_charset_conversion_error_quark (void);
-
-GitgSmartCharsetConverter *gitg_smart_charset_converter_new (GSList *candidate_encodings);
-
-const GitgEncoding *gitg_smart_charset_converter_get_guessed (GitgSmartCharsetConverter *smart);
-
-guint gitg_smart_charset_converter_get_num_fallbacks(GitgSmartCharsetConverter *smart);
-
-G_END_DECLS
-
-#endif /* __GITG_SMART_CHARSET_CONVERTER_H__ */
-
-/* ex:ts=8:noet: */
diff --git a/libgitg/libgitg-1.0.pc.in b/libgitg/libgitg-1.0.pc.in
new file mode 100644
index 0000000..59ff1fe
--- /dev/null
+++ b/libgitg/libgitg-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Description: gitg library
+Version: @PACKAGE_VERSION@
+Requires: libgit2-glib-1.0 glib-2.0 gobject-2.0 gmodule-2.0 gio-2.0 gio-unix-2.0 gthread-2.0
+Libs: -L${libdir} -lgitg-1.0
+Cflags: -I${includedir}/libgitg-1.0
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
new file mode 100644
index 0000000..32e0a3a
--- /dev/null
+++ b/plugins/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = dash history
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/dash/Makefile.am b/plugins/dash/Makefile.am
new file mode 100644
index 0000000..3351847
--- /dev/null
+++ b/plugins/dash/Makefile.am
@@ -0,0 +1,52 @@
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(srcdir) \
+ $(GITG_PLUGIN_CFLAGS) \
+ $(WARN_CFLAGS) \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(libdir)"\"
+
+plugindir = $(GITG_PLUGIN_LIBDIR)
+plugin_LTLIBRARIES = libdash.la
+plugin_DATA = dash.plugin
+
+VALAFLAGS = $(GITG_PLUGIN_VALAFLAGS)
+VALA_SOURCES = \
+ gitg-dash.vala \
+ gitg-dash-navigation.vala
+
+libdash_la_LDFLAGS = $(GITG_PLUGIN_LIBTOOL_FLAGS)
+
+libdash_la_LIBADD = $(GITG_PLUGIN_LIBS)
+libdash_la_CFLAGS = -w
+
+libdash_la_SOURCES = \
+ $(VALA_SOURCES) \
+ gitg-dash-resources.c
+
+BUILT_SOURCES = \
+ gitg-dash-resources.c \
+ gitg-dash-resources.h
+
+gitg-dash-resources.c: resources/resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-source \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+gitg-dash-resources.h: resources/resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-header \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+EXTRA_DIST = $(plugin_DATA) \
+ resources/resources.xml \
+ $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+
+CLEANFILES = \
+ $(VALA_SOURCES:.vala=.c) \
+ $(BUILT_SOURCES)
+
+install-data-hook:
+ rm -f $(GITG_PLUGIN_LIBDIR)/libdash.la
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/dash/dash.plugin b/plugins/dash/dash.plugin
new file mode 100644
index 0000000..dad39a6
--- /dev/null
+++ b/plugins/dash/dash.plugin
@@ -0,0 +1,11 @@
+[Plugin]
+Loader=C
+Module=dash
+Name=Dash
+Description=gitg Dash
+Authors=Jesse van den Kieboom <jessevdk@gnome.org>
+Copyright=Copyright © 2012 Jesse van den Kieboom
+Website=
+Hidden=1
+Builtin=1
+Version=1.0
diff --git a/plugins/dash/gitg-dash-navigation.vala b/plugins/dash/gitg-dash-navigation.vala
new file mode 100644
index 0000000..e74049d
--- /dev/null
+++ b/plugins/dash/gitg-dash-navigation.vala
@@ -0,0 +1,93 @@
+namespace GitgDash
+{
+ private class Navigation : Object, GitgExt.Navigation
+ {
+ public GitgExt.Application? application { owned get; construct; }
+
+ public signal void show_open();
+ public signal void show_create();
+ public signal void show_recent(string uri);
+ public signal void activate_recent(string uri);
+
+ public Navigation(GitgExt.Application app)
+ {
+ Object(application: app);
+ }
+
+ public void populate(GitgExt.NavigationTreeModel model)
+ {
+ model.begin_header("Repository", null)
+ .append_default("Open", "document-open-symbolic", (c) => { show_open(); })
+ .append("Create", "list-add-symbolic", (c) => { show_create(); })
+ .end_header();
+
+ model.begin_header("Recent", null);
+
+ var manager = Gtk.RecentManager.get_default();
+ var list = new List<Gtk.RecentInfo>();
+
+ Gee.HashSet<string> uris = new Gee.HashSet<string>();
+
+ foreach (var item in manager.get_items())
+ {
+ if (!item.has_application("gitg") ||
+ !item.exists())
+ {
+ continue;
+ }
+
+ if (uris.add(item.get_uri()))
+ {
+ list.prepend(item);
+ }
+ }
+
+ list.sort((a, b) => {
+ if (a.get_visited() < b.get_visited())
+ {
+ return 1;
+ }
+ else if (a.get_visited() > b.get_visited())
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ });
+
+ foreach (var item in list)
+ {
+ string uri = item.get_uri();
+
+ model.append(item.get_display_name(),
+ null,
+ (c) => {
+ if (c == 1)
+ {
+ show_recent(uri);
+ }
+ else
+ {
+ activate_recent(uri);
+ }
+ });
+ }
+
+ model.end_header();
+ }
+
+ public GitgExt.NavigationSide navigation_side
+ {
+ get { return GitgExt.NavigationSide.LEFT; }
+ }
+
+ public bool available
+ {
+ get { return true; }
+ }
+ }
+}
+
+// ex: ts=4 noet
diff --git a/plugins/dash/gitg-dash.vala b/plugins/dash/gitg-dash.vala
new file mode 100644
index 0000000..668a776
--- /dev/null
+++ b/plugins/dash/gitg-dash.vala
@@ -0,0 +1,285 @@
+namespace GitgDash
+{
+ // Do this to pull in config.h before glib.h (for gettext...)
+ private const string version = Gitg.Config.VERSION;
+
+ public class View : Object, GitgExt.View
+ {
+ public GitgExt.Application? application { owned get; construct; }
+ private Gtk.Notebook d_main;
+
+ private Gtk.Widget? d_open;
+ private int d_openidx;
+
+ private Gtk.Widget? d_create;
+ private int d_createidx;
+
+ private Gtk.Widget? d_recent;
+ private Gtk.Label? d_recent_path;
+ private Gtk.Label? d_recent_last_used;
+ private Gtk.Label? d_recent_current_branch;
+ private File? d_recent_current_file;
+ private int d_recentidx;
+
+ private HashTable<File, Gitg.Repository> d_repos;
+
+ private File? d_open_folder;
+
+ construct
+ {
+ d_main = new Gtk.Notebook();
+ d_main.set_show_tabs(false);
+ d_main.show();
+
+ d_repos = new HashTable<File, Gitg.Repository>(File.hash, File.equal);
+ }
+
+ public string id
+ {
+ owned get { return "/org/gnome/gitg/Views/Dash"; }
+ }
+
+ public bool is_available()
+ {
+ // The dash is always available
+ return true;
+ }
+
+ public string display_name
+ {
+ owned get { return "Dashboard"; }
+ }
+
+ public Icon? icon
+ {
+ owned get
+ {
+ return new ThemedIcon("document-open-recent-symbolic");
+ }
+ }
+
+ public Gtk.Widget? widget
+ {
+ owned get
+ {
+ return d_main;
+ }
+ }
+
+ public GitgExt.Navigation? navigation
+ {
+ owned get
+ {
+ var ret = new Navigation(application);
+
+ ret.show_open.connect(show_open);
+ ret.show_create.connect(show_create);
+ ret.show_recent.connect(show_recent);
+ ret.activate_recent.connect(activate_recent);
+
+ return ret;
+ }
+ }
+
+ public bool is_default_for(GitgExt.ViewAction action)
+ {
+ return application.repository == null;
+ }
+
+ private Gee.HashMap<string, Object>? from_builder(string path, string[] ids)
+ {
+ var builder = new Gtk.Builder();
+
+ try
+ {
+ builder.add_from_resource("/org/gnome/gitg/dash/" + path);
+ }
+ catch (Error e)
+ {
+ warning("Failed to load ui: %s", e.message);
+ return null;
+ }
+
+ Gee.HashMap<string, Object> ret = new Gee.HashMap<string, Object>();
+
+ foreach (string id in ids)
+ {
+ ret[id] = builder.get_object(id);
+ }
+
+ return ret;
+ }
+
+ private void connect_chooser_folder(Gtk.FileChooser ch)
+ {
+ if (d_open_folder == null)
+ {
+ var path = Environment.get_home_dir();
+ d_open_folder = File.new_for_path(path);
+ }
+
+ ch.unmap.connect((w) => {
+ d_open_folder = ch.get_current_folder_file();
+ });
+
+ ch.map.connect((w) => {
+ if (d_open_folder != null)
+ {
+ try
+ {
+ ch.set_current_folder_file(d_open_folder);
+ } catch {};
+ }
+ });
+ }
+
+ public void show_open()
+ {
+ if (d_open == null)
+ {
+ var ret = from_builder("view-open.ui", {"view",
+ "file_chooser",
+ "button_open"});
+
+ d_open = ret["view"] as Gtk.Widget;
+
+ var ch = ret["file_chooser"] as Gtk.FileChooser;
+ connect_chooser_folder(ch);
+
+ (ret["button_open"] as Gtk.Button).clicked.connect((b) => {
+ application.open(ch.get_current_folder_file());
+ });
+
+ d_openidx = d_main.append_page(d_open, null);
+ }
+
+ d_main.set_current_page(d_openidx);
+ }
+
+ public void show_create()
+ {
+ if (d_create == null)
+ {
+ var ret = from_builder("view-create.ui", {"view",
+ "file_chooser",
+ "button_create"});
+
+ d_create = ret["view"] as Gtk.Widget;
+
+ var ch = ret["file_chooser"] as Gtk.FileChooser;
+ connect_chooser_folder(ch);
+
+ (ret["button_create"] as Gtk.Button).clicked.connect((b) => {
+ application.create(ch.get_current_folder_file());
+ });
+
+ d_createidx = d_main.append_page(d_create, null);
+ }
+
+ d_main.set_current_page(d_createidx);
+ }
+
+ public void show_recent(string uri)
+ {
+ var manager = Gtk.RecentManager.get_default();
+ Gtk.RecentInfo? info = null;
+
+ foreach (var item in manager.get_items())
+ {
+ if (item.get_uri() == uri &&
+ item.has_application("gitg") && item.exists())
+ {
+ info = item;
+ break;
+ }
+ }
+
+ if (info == null)
+ {
+ return;
+ }
+
+ File f = File.new_for_uri(info.get_uri());
+ Gitg.Repository? repo;
+
+ if (!d_repos.lookup_extended(f, null, out repo))
+ {
+ // Try to open the repo
+ try
+ {
+ repo = new Gitg.Repository(f, null);
+
+ d_repos.insert(f, repo);
+ }
+ catch
+ {
+ return;
+ }
+ }
+
+ if (repo == null)
+ {
+ return;
+ }
+
+ if (d_recent == null)
+ {
+ var ret = from_builder("view-recent.ui", {"view",
+ "label_path_i",
+ "label_last_used_i",
+ "label_current_branch_i",
+ "button_open"});
+
+ d_recent = ret["view"] as Gtk.Widget;
+ d_recent_path = ret["label_path_i"] as Gtk.Label;
+ d_recent_last_used = ret["label_last_used_i"] as Gtk.Label;
+ d_recent_current_branch = ret["label_current_branch_i"] as Gtk.Label;
+
+ (ret["button_open"] as Gtk.Button).clicked.connect((b) => {
+ application.open(d_recent_current_file);
+ });
+
+ d_recentidx = d_main.append_page(d_recent, null);
+ }
+
+ d_recent_path.label = Filename.display_name(f.get_path());
+ d_recent_current_file = f;
+
+ var dt = new DateTime.from_unix_utc(info.get_visited());
+ d_recent_last_used.label = dt.format("%c");
+
+ d_recent_current_branch.label = _("(no branch)");
+
+ try
+ {
+ var r = repo.get_head();
+
+ if (r != null)
+ {
+ d_recent_current_branch.label = r.parsed_name.shortname;
+ }
+ }
+ catch {}
+
+ d_main.set_current_page(d_recentidx);
+ }
+
+ public void activate_recent(string uri)
+ {
+ File f = File.new_for_uri(uri);
+
+ application.open(f);
+ }
+ }
+}
+
+[ModuleInit]
+public void peas_register_types(TypeModule module)
+{
+ Peas.ObjectModule mod = module as Peas.ObjectModule;
+
+ mod.register_extension_type(typeof(GitgExt.View),
+ typeof(GitgDash.View));
+}
+
+// ex: ts=4 noet
diff --git a/plugins/dash/resources/resources.xml b/plugins/dash/resources/resources.xml
new file mode 100644
index 0000000..6139db8
--- /dev/null
+++ b/plugins/dash/resources/resources.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/gitg/dash">
+ <file>view-open.ui</file>
+ <file>view-create.ui</file>
+ <file>view-recent.ui</file>
+ </gresource>
+</gresources>
+
+<!-- ex: et ts=2 -->
diff --git a/plugins/dash/resources/view-create.ui b/plugins/dash/resources/view-create.ui
new file mode 100644
index 0000000..c68addb
--- /dev/null
+++ b/plugins/dash/resources/view-create.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.3 -->
+ <!-- interface-requires gitg 0.2 -->
+ <object class="GtkGrid" id="view">
+ <property name="visible">True</property>
+ <property name="row-spacing">6</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label_title">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Create repository</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_description">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Select a folder in which you want to create a new git repository.</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="description"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserWidget" id="file_chooser">
+ <property name="visible">True</property>
+ <property name="local-only">True</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand">True</property>
+ <property name="action">select-folder</property>
+ <property name="create-folders">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="buttons">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="halign">end</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkButton" id="button_create">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Create</property>
+ <property name="use-stock">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
+
+<!-- ex:set ts=2 et: -->
diff --git a/plugins/dash/resources/view-open.ui b/plugins/dash/resources/view-open.ui
new file mode 100644
index 0000000..199b9c3
--- /dev/null
+++ b/plugins/dash/resources/view-open.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.3 -->
+ <!-- interface-requires gitg 0.2 -->
+ <object class="GtkGrid" id="view">
+ <property name="visible">True</property>
+ <property name="row-spacing">6</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label_title">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Open repository</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_description">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Select a folder to open the corresponding git repository.</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="description"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserWidget" id="file_chooser">
+ <property name="visible">True</property>
+ <property name="local-only">True</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand">True</property>
+ <property name="action">select-folder</property>
+ <property name="create-folders">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="buttons">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="halign">end</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkButton" id="button_open">
+ <property name="visible">True</property>
+ <property name="label">gtk-open</property>
+ <property name="use-stock">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
+
+<!-- ex:set ts=2 et: -->
diff --git a/plugins/dash/resources/view-recent.ui b/plugins/dash/resources/view-recent.ui
new file mode 100644
index 0000000..80e824b
--- /dev/null
+++ b/plugins/dash/resources/view-recent.ui
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.3 -->
+ <object class="GtkGrid" id="view">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Recent repository</property>
+ <style>
+ <class name="title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Open a recently used repository.</property>
+ <style>
+ <class name="description"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_path">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Path:</property>
+ <style>
+ <class name="grid_title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_path_i">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label"></property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_last_used">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Last used:</property>
+ <style>
+ <class name="grid_title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_last_used_i">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label"></property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_current_branch">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Current branch:</property>
+ <style>
+ <class name="grid_title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_current_branch_i">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label"></property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="buttons">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="halign">end</property>
+ <property name="valign">end</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkButton" id="button_open">
+ <property name="visible">True</property>
+ <property name="label">gtk-open</property>
+ <property name="use-stock">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/plugins/history/Makefile.am b/plugins/history/Makefile.am
new file mode 100644
index 0000000..099c165
--- /dev/null
+++ b/plugins/history/Makefile.am
@@ -0,0 +1,52 @@
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(srcdir) \
+ $(GITG_PLUGIN_CFLAGS) \
+ $(WARN_CFLAGS) \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(libdir)"\"
+
+plugindir = $(GITG_PLUGIN_LIBDIR)
+plugin_LTLIBRARIES = libhistory.la
+plugin_DATA = history.plugin
+
+VALAFLAGS = $(GITG_PLUGIN_VALAFLAGS)
+VALA_SOURCES = \
+ gitg-history.vala \
+ gitg-history-navigation.vala
+
+libhistory_la_LDFLAGS = $(GITG_PLUGIN_LIBTOOL_FLAGS)
+
+libhistory_la_LIBADD = $(GITG_PLUGIN_LIBS)
+libhistory_la_CFLAGS = -w
+
+libhistory_la_SOURCES = \
+ $(VALA_SOURCES) \
+ gitg-history-resources.c
+
+BUILT_SOURCES = \
+ gitg-history-resources.c \
+ gitg-history-resources.h
+
+gitg-history-resources.c: resources/resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-source \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+gitg-history-resources.h: resources/resources.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+ $(GLIB_COMPILE_RESOURCES) --generate-header \
+ --sourcedir $(srcdir)/resources \
+ --target "$@" "$<"
+
+EXTRA_DIST = $(plugin_DATA) \
+ resources/resources.xml \
+ $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir)/resources resources/resources.xml)
+
+CLEANFILES = \
+ $(VALA_SOURCES:.vala=.c) \
+ $(BUILT_SOURCES)
+
+install-data-hook:
+ rm -f $(GITG_PLUGIN_LIBDIR)/libhistory.la
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/history/gitg-history-navigation.vala b/plugins/history/gitg-history-navigation.vala
new file mode 100644
index 0000000..b18753c
--- /dev/null
+++ b/plugins/history/gitg-history-navigation.vala
@@ -0,0 +1,123 @@
+namespace GitgHistory
+{
+ private class Navigation : Object, GitgExt.Navigation
+ {
+ public GitgExt.Application? application { owned get; construct; }
+
+ public Navigation(GitgExt.Application app)
+ {
+ Object(application: app);
+ }
+
+ private static int sort_refs(Gitg.Ref a, Gitg.Ref b)
+ {
+ return a.parsed_name.shortname.ascii_casecmp(b.parsed_name.shortname);
+ }
+
+ public void populate(GitgExt.NavigationTreeModel model)
+ {
+ var repo = application.repository;
+
+ List<Gitg.Ref> branches = new List<Gitg.Ref>();
+ HashTable<string, List<Gitg.Ref>> remotes;
+ List<string> remotenames = new List<string>();
+
+ remotes = new HashTable<string, List<Gitg.Ref>>(str_hash, str_equal);
+
+ try
+ {
+ repo.references_foreach(Ggit.RefType.LISTALL, (nm) => {
+ Gitg.Ref? r;
+
+ try
+ {
+ r = repo.lookup_reference(nm);
+ } catch { return 0; }
+
+ if (r.parsed_name.rtype == Gitg.RefType.BRANCH)
+ {
+ branches.insert_sorted(r, sort_refs);
+ }
+ else if (r.parsed_name.rtype == Gitg.RefType.REMOTE)
+ {
+ unowned List<Gitg.Ref> lst;
+
+ string rname = r.parsed_name.remote_name;
+
+ if (!remotes.lookup_extended(rname, null, out lst))
+ {
+ List<Gitg.Ref> nlst = new List<Gitg.Ref>();
+ nlst.prepend(r);
+
+ remotes.insert(rname, (owned)nlst);
+ remotenames.insert_sorted(rname, (a, b) => a.ascii_casecmp(b));
+ }
+ else
+ {
+ /*unowned List<Gitg.Ref> start = lst;
+
+ lst.insert_sorted(r, sort_refs);
+
+ if (lst != start)
+ {
+ remotes.insert(rname, lst.copy());
+ }*/
+ }
+ }
+
+ return 0;
+ });
+ } catch {}
+
+ Gitg.Ref? head = null;
+
+ try
+ {
+ head = repo.get_head();
+ } catch {}
+
+ // Branches
+ model.begin_header("Branches", null);
+
+ foreach (var item in branches)
+ {
+ if (head != null && item.get_id().equal(head.get_id()))
+ {
+ model.append_default(item.parsed_name.shortname,
+ "object-select-symbolic",
+ null);
+ }
+ else
+ {
+ model.append(item.parsed_name.shortname, null, null);
+ }
+ }
+
+ model.end_header();
+
+ // Remotes
+ model.begin_header("Remotes", "network-server-symbolic");
+
+ foreach (var rname in remotenames)
+ {
+ //model.append(item.parsed_name.remote_branch, null, null);
+ }
+
+ model.end_header();
+
+ // Tags
+ }
+
+ public GitgExt.NavigationSide navigation_side
+ {
+ get { return GitgExt.NavigationSide.LEFT; }
+ }
+
+ public bool available
+ {
+ get { return true; }
+ }
+ }
+}
+
+// ex: ts=4 noet
diff --git a/plugins/history/gitg-history.vala b/plugins/history/gitg-history.vala
new file mode 100644
index 0000000..8a03455
--- /dev/null
+++ b/plugins/history/gitg-history.vala
@@ -0,0 +1,103 @@
+namespace GitgHistory
+{
+ // Do this to pull in config.h before glib.h (for gettext...)
+ private const string version = Gitg.Config.VERSION;
+
+ public class View : Object, GitgExt.View
+ {
+ public GitgExt.Application? application { owned get; construct; }
+
+ private Gtk.Widget d_main;
+
+ public string id
+ {
+ owned get { return "/org/gnome/gitg/Views/History"; }
+ }
+
+ public bool is_available()
+ {
+ // The history view is available only when there is a repository
+ return application.repository != null;
+ }
+
+ public string display_name
+ {
+ owned get { return "History"; }
+ }
+
+ public Icon? icon
+ {
+ owned get { return new ThemedIcon("view-list-symbolic"); }
+ }
+
+ public Gtk.Widget? widget
+ {
+ owned get
+ {
+ if (d_main == null)
+ {
+ build_ui();
+ }
+
+ return d_main;
+ }
+ }
+
+ public GitgExt.Navigation? navigation
+ {
+ owned get
+ {
+ var ret = new Navigation(application);
+
+ return ret;
+ }
+ }
+
+ public bool is_default_for(GitgExt.ViewAction action)
+ {
+ return application.repository != null && action == GitgExt.ViewAction.HISTORY;
+ }
+
+ private void build_ui()
+ {
+ var ret = from_builder("view-history.ui", {"view"});
+
+ d_main = ret["view"] as Gtk.Widget;
+ }
+
+ private Gee.HashMap<string, Object>? from_builder(string path, string[] ids)
+ {
+ var builder = new Gtk.Builder();
+
+ try
+ {
+ builder.add_from_resource("/org/gnome/gitg/history/" + path);
+ }
+ catch (Error e)
+ {
+ warning("Failed to load ui: %s", e.message);
+ return null;
+ }
+
+ Gee.HashMap<string, Object> ret = new Gee.HashMap<string, Object>();
+
+ foreach (string id in ids)
+ {
+ ret[id] = builder.get_object(id);
+ }
+
+ return ret;
+ }
+ }
+}
+
+[ModuleInit]
+public void peas_register_types(TypeModule module)
+{
+ Peas.ObjectModule mod = module as Peas.ObjectModule;
+
+ mod.register_extension_type(typeof(GitgExt.View),
+ typeof(GitgHistory.View));
+}
+
+// ex: ts=4 noet
diff --git a/plugins/history/history.plugin b/plugins/history/history.plugin
new file mode 100644
index 0000000..33d800a
--- /dev/null
+++ b/plugins/history/history.plugin
@@ -0,0 +1,11 @@
+[Plugin]
+Loader=C
+Module=history
+Name=History
+Description=gitg History
+Authors=Jesse van den Kieboom <jessevdk@gnome.org>
+Copyright=Copyright © 2012 Jesse van den Kieboom
+Website=
+Hidden=1
+Builtin=1
+Version=1.0
diff --git a/plugins/history/resources/resources.xml b/plugins/history/resources/resources.xml
new file mode 100644
index 0000000..802c861
--- /dev/null
+++ b/plugins/history/resources/resources.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/gitg/history">
+ <file>view-history.ui</file>
+ </gresource>
+</gresources>
+
+<!-- ex: et ts=2 -->
diff --git a/plugins/history/resources/view-history.ui b/plugins/history/resources/view-history.ui
new file mode 100644
index 0000000..c725a0d
--- /dev/null
+++ b/plugins/history/resources/view-history.ui
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.3 -->
+ <object class="GtkGrid" id="view">
+ <property name="visible">True</property>
+ <property name="row-spacing">6</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ </object>
+</interface>
+
+<!-- ex:set ts=2 et: -->
diff --git a/vapi/config.vapi b/vapi/config.vapi
new file mode 100644
index 0000000..cee9f22
--- /dev/null
+++ b/vapi/config.vapi
@@ -0,0 +1,13 @@
+[CCode(cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
+namespace Gitg.Config
+{
+ public const string GETTEXT_PACKAGE;
+ public const string PACKAGE_NAME;
+ public const string PACKAGE_VERSION;
+ public const string GITG_DATADIR;
+ public const string GITG_LOCALEDIR;
+ public const string GITG_LIBDIR;
+ public const string VERSION;
+}
+
+// ex:ts=4 noet
diff --git a/vapi/gobject-introspection-1.0.vapi b/vapi/gobject-introspection-1.0.vapi
new file mode 100644
index 0000000..28f7c49
--- /dev/null
+++ b/vapi/gobject-introspection-1.0.vapi
@@ -0,0 +1,31 @@
+[CCode (cprefix = "GI", lower_case_cprefix = "g_i", cheader_filename = "girepository.h")]
+namespace Introspection
+{
+ [CCode (cprefix = "G_IREPOSITORY_ERROR_")]
+ public errordomain RepositoryError {
+ TYPELIB_NOT_FOUND,
+ NAMESPACE_MISMATCH,
+ NAMESPACE_VERSION_CONFLICT,
+ LIBRARY_NOT_FOUND
+ }
+
+ [CCode (cname="int", cprefix = "G_IREPOSITORY_LOAD_FLAG_")]
+ public enum RepositoryLoadFlags {
+ LAZY = 1
+ }
+
+ [CCode (ref_function = "", unref_function = "")]
+ public class Repository {
+ public static unowned Repository get_default();
+ public static void prepend_search_path(string directory);
+ public static unowned GLib.SList<string> get_search_path();
+
+ public unowned Typelib? require(string namespace_, string? version = null, RepositoryLoadFlags flags = 0) throws RepositoryError;
+ }
+
+ [Compact]
+ [CCode (cname = "GTypelib", cprefix = "g_typelib_", free_function = "g_typelib_free")]
+ public class Typelib {
+ public unowned string get_namespace();
+ }
+}