Initial porting to vala

This commit is contained in:
Jesse van den Kieboom 2012-04-14 13:46:39 +02:00
parent 79905400d7
commit a74c5661a6
152 changed files with 5163 additions and 36776 deletions

6
.gitmodules vendored Normal file
View File

@ -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

View File

@ -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 \

View File

@ -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)
AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = "yes"])
LIBGITG_EXT_CFLAGS="$LIBGITG_GTK_CFLAGS"
LIBGITG_EXT_LIBS="$LIBGITG_GTK_LIBS"
AC_SUBST(PACKAGE_CFLAGS)
AC_SUBST(PACKAGE_LIBS)
AC_SUBST(LIBGITG_EXT_CFLAGS)
AC_SUBST(LIBGITG_EXT_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}
"

View File

@ -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>

View File

@ -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

View File

@ -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);
}

View File

@ -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__ */

343
gitg/gitg-application.vala Normal file
View File

@ -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

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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 -->

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

64
gitg/gitg-dirs.vala Normal file
View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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>

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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>

62
gitg/gitg-resource.vala Normal file
View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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>

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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>

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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>

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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>

View File

@ -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 -->

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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>

457
gitg/gitg-window.vala Normal file
View File

@ -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

View File

@ -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;
}

25
gitg/gitg.vala Normal file
View File

@ -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

View File

@ -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 -->

View File

@ -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>

View File

@ -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: -->

View File

@ -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;
}

1
libgit2 Submodule

@ -0,0 +1 @@
Subproject commit 242a1cea8d66d9ec185044f345b22fec1940178f

1
libgit2-glib Submodule

@ -0,0 +1 @@
Subproject commit 1a17238b82e5d4ab65be78d90f356d2bf4aba912

38
libgitg-ext/GitgExt.py Normal file
View File

@ -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

100
libgitg-ext/Makefile.am Normal file
View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/gitg/ext">
</gresource>
</gresources>
<!-- ex: et ts=2 -->

View File

@ -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)
libgitg_1_0_la_LIBADD = $(LIBGITG_LIBS)
BUILT_SOURCES = \
gitg-enum-types.h \
gitg-enum-types.c
INST_H_FILES = \
libgitg.h
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
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
NOINST_H_FILES = \
gitg-convert.h \
gitg-debug.h \
gitg-i18n.h \
gitg-lanes.h \
gitg-smart-charset-converter.h \
gitg-encodings.h
Gitg-1.0.gir: libgitg-1.0.la
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
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
if ENABLE_DEBUG
C_FILES += gitg-debug.c
endif
# Ignore all warnings for vala code...
libgitg_1_0_la_CFLAGS = \
-w
ENUM_H_FILES = \
gitg-changed-file.h
libgitg_1_0_la_SOURCES = \
$(INST_H_FILES) \
$(NOINST_H_FILES) \
$(C_FILES)
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
%.typelib: %.gir
$(INTROSPECTION_COMPILER) $(INTROSPECTION_COMPILER_ARGS) --includedir=. -o $@ $<
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libgitg-1.0.pc
BUILT_SOURCES = \
$(gir_DATA) \
libgitg.h
EXTRA_DIST = $(pkgconfig_DATA)
CLEANFILES = $(VALA_FILES:.vala=.c)
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
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)) > $@
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)) > $@
-include $(top_srcdir)/git.mk

View File

@ -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;
}
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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__ */

85
libgitg/gitg-color.vala Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

90
libgitg/gitg-commit.vala Normal file
View File

@ -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

View File

@ -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);
}
}

View File

@ -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__ */

View File

@ -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, "?");
}

View File

@ -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__ */

View File

@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show More