mirror of
https://gitlab.gnome.org/GNOME/gitg
synced 2024-10-01 05:33:49 +00:00
Changed RvModel to proper Repository object
GitgRepository is now a custom GtkTreeModel instead of GtkListStore Added git path utility functions to gitg-utils
This commit is contained in:
parent
917413b931
commit
dda98d7a16
|
@ -12,13 +12,12 @@ INCLUDES = \
|
|||
-DGITG_UI_DIR=\""$(datadir)/gitg/ui/"\" \
|
||||
-DGITG_ICONDIR=\""$(datadir)/gitg/icons"\"
|
||||
|
||||
gitg_SOURCES = \
|
||||
gitg.c \
|
||||
gitg-revision.c \
|
||||
gitg-rv-model.c \
|
||||
gitg-loader.c \
|
||||
gitg-runner.c \
|
||||
gitg-utils.c \
|
||||
gitg_SOURCES = \
|
||||
gitg.c \
|
||||
gitg-revision.c \
|
||||
gitg-repository.c \
|
||||
gitg-runner.c \
|
||||
gitg-utils.c \
|
||||
sexy-icon-entry.c
|
||||
|
||||
gitg_LDADD = $(PACKAGE_LIBS)
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
#include "gitg-rv-model.h"
|
||||
#include "gitg-repository.h"
|
||||
#include "gitg-utils.h"
|
||||
#include <glib/gi18n.h>
|
||||
#include <time.h>
|
||||
|
||||
#define GITG_RV_MODEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GITG_TYPE_RV_MODEL, GitgRvModelPrivate))
|
||||
#define GITG_REPOSITORY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GITG_TYPE_REPOSITORY, GitgRepositoryPrivate))
|
||||
|
||||
static void gitg_rv_model_tree_model_iface_init(GtkTreeModelIface *iface);
|
||||
static void gitg_repository_tree_model_iface_init(GtkTreeModelIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (GitgRvModel, gitg_rv_model, GTK_TYPE_LIST_STORE, 0,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, gitg_rv_model_tree_model_iface_init));
|
||||
G_DEFINE_TYPE_EXTENDED(GitgRepository, gitg_repository, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL, gitg_repository_tree_model_iface_init));
|
||||
|
||||
struct _GitgRvModelPrivate
|
||||
{
|
||||
GHashTable *hashtable;
|
||||
/* Properties */
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_PATH,
|
||||
PROP_LOADER
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -22,54 +27,88 @@ enum
|
|||
N_COLUMNS
|
||||
};
|
||||
|
||||
static GtkTreeModelIface parent_iface = { 0, };
|
||||
|
||||
static int
|
||||
gitg_rv_model_get_n_columns (GtkTreeModel *self)
|
||||
struct _GitgRepositoryPrivate
|
||||
{
|
||||
/* validate our parameters */
|
||||
g_return_val_if_fail(GITG_RV_MODEL(self), 0);
|
||||
gchar *path;
|
||||
GitgRunner *loader;
|
||||
GHashTable *hashtable;
|
||||
gint stamp;
|
||||
GType column_types[N_COLUMNS];
|
||||
|
||||
GitgRevision **storage;
|
||||
gulong size;
|
||||
gulong allocated;
|
||||
gint grow_size;
|
||||
};
|
||||
|
||||
inline static gint
|
||||
gitg_repository_error_quark()
|
||||
{
|
||||
static GQuark quark = 0;
|
||||
|
||||
if (G_UNLIKELY(quark == 0))
|
||||
quark = g_quark_from_static_string("GitgRepositoryErrorQuark");
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
/* GtkTreeModel implementations */
|
||||
static GtkTreeModelFlags
|
||||
tree_model_get_flags(GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), 0);
|
||||
return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY;
|
||||
}
|
||||
|
||||
static gint
|
||||
tree_model_get_n_columns(GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), 0);
|
||||
return N_COLUMNS;
|
||||
}
|
||||
|
||||
static GType
|
||||
gitg_rv_model_get_column_type(GtkTreeModel *self, int column)
|
||||
static GType
|
||||
tree_model_get_column_type(GtkTreeModel *tree_model, gint index)
|
||||
{
|
||||
GType types[] = {
|
||||
GITG_TYPE_REVISION,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING
|
||||
};
|
||||
|
||||
/* validate our parameters */
|
||||
g_return_val_if_fail(GITG_IS_RV_MODEL(self), G_TYPE_INVALID);
|
||||
g_return_val_if_fail(column >= 0 && column < N_COLUMNS, G_TYPE_INVALID);
|
||||
|
||||
return types[column];
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), G_TYPE_INVALID);
|
||||
g_return_val_if_fail(index < N_COLUMNS && index >= 0, G_TYPE_INVALID);
|
||||
}
|
||||
|
||||
/* retreive an object from our parent's data storage,
|
||||
* unref the returned object when done */
|
||||
static GitgRevision *
|
||||
gitg_rv_model_get_object(GitgRvModel *self, GtkTreeIter *iter)
|
||||
static gboolean
|
||||
tree_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
|
||||
{
|
||||
GValue value = { 0, };
|
||||
GitgRevision *obj;
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), FALSE);
|
||||
|
||||
gint *indices;
|
||||
gint depth;
|
||||
|
||||
/* validate our parameters */
|
||||
g_return_val_if_fail(GITG_IS_RV_MODEL(self), NULL);
|
||||
g_return_val_if_fail(iter != NULL, NULL);
|
||||
indices = gtk_tree_path_get_indices(path);
|
||||
depth = gtk_tree_path_get_depth(path);
|
||||
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
|
||||
/* retreive the object using our parent's interface, take our own
|
||||
* reference to it */
|
||||
parent_iface.get_value(GTK_TREE_MODEL(self), iter, 0, &value);
|
||||
obj = GITG_REVISION(g_value_dup_object(&value));
|
||||
g_return_val_if_fail(depth == 1, FALSE);
|
||||
|
||||
if (indices[0] < 0 || indices[0] >= rp->priv->size)
|
||||
return FALSE;
|
||||
|
||||
iter->stamp = rp->priv->stamp;
|
||||
iter->user_data = GINT_TO_POINTER(indices[0]);
|
||||
iter->user_data2 = NULL;
|
||||
iter->user_data3 = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
|
||||
return obj;
|
||||
static GtkTreePath *
|
||||
tree_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), NULL);
|
||||
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
g_return_val_if_fail(iter->stamp == rp->priv->stamp, NULL);
|
||||
|
||||
return gtk_tree_path_new_from_indices(GPOINTER_TO_INT(iter->user_data), -1);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -78,74 +117,234 @@ timestamp_to_str(guint64 timestamp)
|
|||
struct tm *tms = localtime((time_t *)×tamp);
|
||||
char buf[255];
|
||||
|
||||
strftime(buf, 255, "%Y-%m-%d %H:%M:%S", tms);
|
||||
strftime(buf, 255, "%c", tms);
|
||||
return g_strdup(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_rv_model_get_value(GtkTreeModel *self, GtkTreeIter *iter, int column,
|
||||
GValue *value)
|
||||
static void
|
||||
tree_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
|
||||
{
|
||||
GitgRevision *obj;
|
||||
|
||||
/* validate our parameters */
|
||||
g_return_if_fail(GITG_IS_RV_MODEL(self));
|
||||
g_return_if_fail(iter != NULL);
|
||||
g_return_if_fail(GITG_IS_REPOSITORY(tree_model));
|
||||
g_return_if_fail(column >= 0 && column < N_COLUMNS);
|
||||
g_return_if_fail(value != NULL);
|
||||
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
g_return_if_fail(iter->stamp == rp->priv->stamp);
|
||||
|
||||
/* get the object from our parent's storage */
|
||||
obj = gitg_rv_model_get_object(GITG_RV_MODEL(self), iter);
|
||||
|
||||
/* initialise our GValue to the required type */
|
||||
g_value_init(value, gitg_rv_model_get_column_type(GTK_TREE_MODEL(self), column));
|
||||
gint index = GPOINTER_TO_INT(iter->user_data);
|
||||
|
||||
g_return_if_fail(index >= 0 && index < rp->priv->size);
|
||||
GitgRevision *rv = rp->priv->storage[index];
|
||||
|
||||
g_value_init(value, rp->priv->column_types[column]);
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case OBJECT_COLUMN:
|
||||
/* the object itself was requested */
|
||||
g_value_set_object(value, obj);
|
||||
break;
|
||||
case AUTHOR_COLUMN:
|
||||
g_value_set_string(value, gitg_revision_get_author(obj));
|
||||
break;
|
||||
g_value_set_object(value, rv);
|
||||
break;
|
||||
case SUBJECT_COLUMN:
|
||||
g_value_set_string(value, gitg_revision_get_subject(obj));
|
||||
break;
|
||||
g_value_set_string(value, gitg_revision_get_subject(rv));
|
||||
break;
|
||||
case AUTHOR_COLUMN:
|
||||
g_value_set_string(value, gitg_revision_get_author(rv));
|
||||
break;
|
||||
case DATE_COLUMN:
|
||||
g_value_take_string(value, timestamp_to_str(gitg_revision_get_timestamp(obj)));
|
||||
break;
|
||||
g_value_take_string(value, timestamp_to_str(gitg_revision_get_timestamp(rv)));
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
/* release the reference gained from gitg_rv_model _get_object() */
|
||||
g_object_unref(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_rv_model_tree_model_iface_init(GtkTreeModelIface *iface)
|
||||
static gboolean
|
||||
tree_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
parent_iface = *iface;
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), FALSE);
|
||||
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
g_return_val_if_fail(iter->stamp == rp->priv->stamp, FALSE);
|
||||
|
||||
iface->get_n_columns = gitg_rv_model_get_n_columns;
|
||||
iface->get_column_type = gitg_rv_model_get_column_type;
|
||||
iface->get_value = gitg_rv_model_get_value;
|
||||
gint next = GPOINTER_TO_INT(iter->user_data) + 1;
|
||||
|
||||
if (next >= rp->priv->size)
|
||||
return FALSE;
|
||||
|
||||
iter->user_data = GINT_TO_POINTER(next);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tree_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), FALSE);
|
||||
|
||||
// Only root has children, because it's a flat list
|
||||
if (parent != NULL)
|
||||
return FALSE;
|
||||
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
iter->stamp = rp->priv->stamp;
|
||||
iter->user_data = GINT_TO_POINTER(0);
|
||||
iter->user_data2 = NULL;
|
||||
iter->user_data3 = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tree_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), FALSE);
|
||||
|
||||
// Only root (NULL) has children
|
||||
return iter == NULL;
|
||||
}
|
||||
|
||||
static gint
|
||||
tree_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), 0);
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
|
||||
return iter ? 0 : rp->priv->size;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tree_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), FALSE);
|
||||
g_return_val_if_fail(n >= 0, FALSE);
|
||||
|
||||
if (parent)
|
||||
return FALSE;
|
||||
|
||||
GitgRepository *rp = GITG_REPOSITORY(tree_model);
|
||||
g_return_val_if_fail(n < rp->priv->size, FALSE);
|
||||
|
||||
iter->stamp = rp->priv->stamp;
|
||||
iter->user_data = GINT_TO_POINTER(n);
|
||||
iter->user_data2 = NULL;
|
||||
iter->user_data3 = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tree_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(tree_model), FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GType
|
||||
gitg_repository_get_column_type(GtkTreeModel *self, int column)
|
||||
{
|
||||
/* validate our parameters */
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(self), G_TYPE_INVALID);
|
||||
g_return_val_if_fail(column >= 0 && column < N_COLUMNS, G_TYPE_INVALID);
|
||||
|
||||
return GITG_REPOSITORY(self)->priv->column_types[column];
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_rv_model_finalize(GObject *object)
|
||||
gitg_repository_tree_model_iface_init(GtkTreeModelIface *iface)
|
||||
{
|
||||
G_OBJECT_CLASS (gitg_rv_model_parent_class)->finalize(object);
|
||||
iface->get_flags = tree_model_get_flags;
|
||||
iface->get_n_columns = tree_model_get_n_columns;
|
||||
iface->get_column_type = tree_model_get_column_type;
|
||||
iface->get_iter = tree_model_get_iter;
|
||||
iface->get_path = tree_model_get_path;
|
||||
iface->get_value = tree_model_get_value;
|
||||
iface->iter_next = tree_model_iter_next;
|
||||
iface->iter_children = tree_model_iter_children;
|
||||
iface->iter_has_child = tree_model_iter_has_child;
|
||||
iface->iter_n_children = tree_model_iter_n_children;
|
||||
iface->iter_nth_child = tree_model_iter_nth_child;
|
||||
iface->iter_parent = tree_model_iter_parent;
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_repository_finalize(GObject *object)
|
||||
{
|
||||
GitgRepository *rp = GITG_REPOSITORY(object);
|
||||
|
||||
// Make sure to cancel the loader
|
||||
gitg_runner_cancel(rp->priv->loader);
|
||||
g_object_unref(rp->priv->loader);
|
||||
|
||||
// Clear the model to remove all revision objects
|
||||
gitg_repository_clear(rp);
|
||||
|
||||
// Free the path
|
||||
g_free(rp->priv->path);
|
||||
|
||||
// Free the hash
|
||||
g_hash_table_destroy(rp->priv->hashtable);
|
||||
|
||||
G_OBJECT_CLASS (gitg_repository_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_repository_set_property(GObject *object, guint prop_id, GValue const *value, GParamSpec *pspec)
|
||||
{
|
||||
GitgRepository *self = GITG_REPOSITORY(object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_free(self->priv->path);
|
||||
self->priv->path = gitg_utils_find_git(g_value_get_string(value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_repository_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GitgRepository *self = GITG_REPOSITORY(object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_value_set_string(value, self->priv->path);
|
||||
break;
|
||||
case PROP_LOADER:
|
||||
g_value_set_object(value, self->priv->loader);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_rv_model_class_init(GitgRvModelClass *klass)
|
||||
gitg_repository_class_init(GitgRepositoryClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->finalize = gitg_rv_model_finalize;
|
||||
object_class->finalize = gitg_repository_finalize;
|
||||
|
||||
g_type_class_add_private(object_class, sizeof(GitgRvModelPrivate));
|
||||
object_class->set_property = gitg_repository_set_property;
|
||||
object_class->get_property = gitg_repository_get_property;
|
||||
|
||||
g_object_class_install_property(object_class, PROP_PATH,
|
||||
g_param_spec_string ("path",
|
||||
"PATH",
|
||||
"The repository path",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property(object_class, PROP_LOADER,
|
||||
g_param_spec_object ("loader",
|
||||
"LOADER",
|
||||
"The repository loader",
|
||||
GITG_TYPE_RUNNER,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private(object_class, sizeof(GitgRepositoryPrivate));
|
||||
}
|
||||
|
||||
static guint
|
||||
|
@ -169,46 +368,186 @@ hash_equal(gconstpointer a, gconstpointer b)
|
|||
}
|
||||
|
||||
static void
|
||||
gitg_rv_model_init(GitgRvModel *object)
|
||||
on_loader_update(GitgRunner *object, gchar **buffer, GitgRepository *self)
|
||||
{
|
||||
object->priv = GITG_RV_MODEL_GET_PRIVATE(object);
|
||||
gchar *line;
|
||||
|
||||
while ((line = *buffer++))
|
||||
{
|
||||
// New line is read
|
||||
gchar **components = g_strsplit(line, "\01", 0);
|
||||
|
||||
if (g_strv_length(components) < 5)
|
||||
{
|
||||
g_strfreev(components);
|
||||
continue;
|
||||
}
|
||||
|
||||
// components -> [hash, author, subject, parents ([1 2 3]), timestamp]
|
||||
gint64 timestamp = g_ascii_strtoll(components[4], NULL, 0);
|
||||
|
||||
GitgRevision *rv = gitg_revision_new(components[0], components[1], components[2], components[3], timestamp);
|
||||
gitg_repository_add(self, rv, NULL);
|
||||
|
||||
g_object_unref(rv);
|
||||
g_strfreev(components);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_repository_init(GitgRepository *object)
|
||||
{
|
||||
object->priv = GITG_REPOSITORY_GET_PRIVATE(object);
|
||||
object->priv->hashtable = g_hash_table_new_full(hash_hash, hash_equal, NULL, NULL);
|
||||
|
||||
GType types[] = { GITG_TYPE_REVISION };
|
||||
gtk_list_store_set_column_types(GTK_LIST_STORE(object), 1, types);
|
||||
object->priv->column_types[0] = GITG_TYPE_REVISION;
|
||||
object->priv->column_types[1] = G_TYPE_STRING;
|
||||
object->priv->column_types[2] = G_TYPE_STRING;
|
||||
object->priv->column_types[3] = G_TYPE_STRING;
|
||||
|
||||
object->priv->grow_size = 1000;
|
||||
object->priv->stamp = g_random_int();
|
||||
|
||||
object->priv->loader = gitg_runner_new(1000);
|
||||
g_signal_connect(object->priv->loader, "update", G_CALLBACK(on_loader_update), object);
|
||||
}
|
||||
|
||||
static void
|
||||
grow_storage(GitgRepository *repository, gint size)
|
||||
{
|
||||
if (repository->priv->size + size <= repository->priv->allocated)
|
||||
return;
|
||||
|
||||
gulong prevallocated = repository->priv->allocated;
|
||||
repository->priv->allocated += repository->priv->grow_size;
|
||||
GitgRevision **newstorage = g_slice_alloc(sizeof(GitgRevision *) * repository->priv->allocated);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < repository->priv->size; ++i)
|
||||
newstorage[i] = repository->priv->storage[i];
|
||||
|
||||
if (repository->priv->storage)
|
||||
g_slice_free1(sizeof(GitgRevision *) * prevallocated, repository->priv->storage);
|
||||
|
||||
repository->priv->storage = newstorage;
|
||||
}
|
||||
|
||||
GitgRepository *
|
||||
gitg_repository_new(gchar const *path)
|
||||
{
|
||||
return g_object_new(GITG_TYPE_REPOSITORY, "path", path, NULL);
|
||||
}
|
||||
|
||||
gchar const *
|
||||
gitg_repository_get_path(GitgRepository *self)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(self), NULL);
|
||||
|
||||
return self->priv->path;
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
gitg_repository_get_loader(GitgRepository *self)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(self), NULL);
|
||||
return GITG_RUNNER(g_object_ref(self->priv->loader));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_load(GitgRepository *self, GError **error)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(self), FALSE);
|
||||
|
||||
if (self->priv->path == NULL)
|
||||
{
|
||||
if (error)
|
||||
*error = g_error_new_literal(gitg_repository_error_quark(), GITG_REPOSITORY_ERROR_NOT_FOUND, _("Not a valid git repository"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gitg_runner_cancel(self->priv->loader);
|
||||
gitg_repository_clear(self);
|
||||
|
||||
gchar *argv[] = {
|
||||
"git",
|
||||
"--git-dir",
|
||||
gitg_utils_dot_git_path(self->priv->path),
|
||||
"log",
|
||||
"--encoding=UTF-8",
|
||||
"--topo-order",
|
||||
"--pretty=format:%H\01%an\01%s\01%P\01%at",
|
||||
"HEAD",
|
||||
NULL
|
||||
};
|
||||
|
||||
gboolean ret = gitg_runner_run(self->priv->loader, argv, error);
|
||||
g_free(argv[2]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
gitg_rv_model_add(GitgRvModel *self, GitgRevision *obj, GtkTreeIter *iter)
|
||||
gitg_repository_add(GitgRepository *self, GitgRevision *obj, GtkTreeIter *iter)
|
||||
{
|
||||
static guint num = 0;
|
||||
GtkTreeIter iter1;
|
||||
|
||||
/* validate our parameters */
|
||||
g_return_if_fail(GITG_IS_RV_MODEL(self));
|
||||
g_return_if_fail(GITG_IS_REPOSITORY(self));
|
||||
g_return_if_fail(GITG_IS_REVISION(obj));
|
||||
|
||||
grow_storage(self, 1);
|
||||
|
||||
/* put this object in our data storage */
|
||||
gtk_list_store_append(GTK_LIST_STORE(self), &iter1);
|
||||
gtk_list_store_set(GTK_LIST_STORE(self), &iter1, 0, obj, -1);
|
||||
self->priv->storage[self->priv->size++] = g_object_ref(obj);
|
||||
|
||||
g_hash_table_insert(self->priv->hashtable, (gpointer)gitg_revision_get_hash(obj), GUINT_TO_POINTER(num++));
|
||||
g_hash_table_insert(self->priv->hashtable, (gpointer)gitg_revision_get_hash(obj), GUINT_TO_POINTER(self->priv->size - 1));
|
||||
|
||||
iter1.stamp = self->priv->stamp;
|
||||
iter1.user_data = GINT_TO_POINTER(self->priv->size - 1);
|
||||
iter1.user_data2 = NULL;
|
||||
iter1.user_data3 = NULL;
|
||||
|
||||
GtkTreePath *path = gtk_tree_path_new_from_indices(self->priv->size - 1, -1);
|
||||
gtk_tree_model_row_inserted(GTK_TREE_MODEL(self), path, &iter1);
|
||||
gtk_tree_path_free(path);
|
||||
|
||||
/* return the iter if the user cares */
|
||||
if (iter)
|
||||
*iter = iter1;
|
||||
}
|
||||
|
||||
GitgRvModel *
|
||||
gitg_rv_model_new()
|
||||
void
|
||||
gitg_repository_clear(GitgRepository *repository)
|
||||
{
|
||||
return g_object_new(GITG_TYPE_RV_MODEL, NULL);
|
||||
int i;
|
||||
GtkTreePath *path = gtk_tree_path_new_from_indices(repository->priv->size - 1, -1);
|
||||
|
||||
|
||||
for (i = repository->priv->size - 1; i >= 0; --i)
|
||||
{
|
||||
GtkTreePath *dup = gtk_tree_path_copy(path);
|
||||
gtk_tree_model_row_deleted(GTK_TREE_MODEL(repository), dup);
|
||||
gtk_tree_path_free(dup);
|
||||
|
||||
gtk_tree_path_prev(path);
|
||||
g_object_unref(repository->priv->storage[i]);
|
||||
}
|
||||
|
||||
gtk_tree_path_free(path);
|
||||
|
||||
if (repository->priv->storage)
|
||||
g_slice_free1(sizeof(GitgRevision *) * repository->priv->size, repository->priv->storage);
|
||||
|
||||
repository->priv->storage = NULL;
|
||||
repository->priv->size = 0;
|
||||
repository->priv->allocated = 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_rv_model_find_by_hash(GitgRvModel *store, gchar const *hash, GtkTreeIter *iter)
|
||||
gitg_repository_find_by_hash(GitgRepository *store, gchar const *hash, GtkTreeIter *iter)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_RV_MODEL(store), FALSE);
|
||||
g_return_val_if_fail(GITG_IS_REPOSITORY(store), FALSE);
|
||||
|
||||
gpointer result = g_hash_table_lookup(store->priv->hashtable, hash);
|
||||
|
||||
|
@ -223,42 +562,10 @@ gitg_rv_model_find_by_hash(GitgRvModel *store, gchar const *hash, GtkTreeIter *i
|
|||
}
|
||||
|
||||
gboolean
|
||||
gitg_rv_model_find(GitgRvModel *store, GitgRevision *revision, GtkTreeIter *iter)
|
||||
gitg_repository_find(GitgRepository *store, GitgRevision *revision, GtkTreeIter *iter)
|
||||
{
|
||||
g_return_val_if_fail(GITG_IS_REVISION(revision), FALSE);
|
||||
|
||||
return gitg_rv_model_find_by_hash(store, gitg_revision_get_hash(revision), iter);
|
||||
return gitg_repository_find_by_hash(store, gitg_revision_get_hash(revision), iter);
|
||||
}
|
||||
|
||||
gint gitg_rv_model_compare(GitgRvModel *store, GtkTreeIter *a, GtkTreeIter *b, gint col)
|
||||
{
|
||||
GitgRevision *rv1;
|
||||
GitgRevision *rv2;
|
||||
|
||||
rv1 = gitg_rv_model_get_object(store, a);
|
||||
rv2 = gitg_rv_model_get_object(store, b);
|
||||
gint ret;
|
||||
int i1;
|
||||
int i2;
|
||||
|
||||
switch (col)
|
||||
{
|
||||
case SUBJECT_COLUMN:
|
||||
ret = g_utf8_collate(gitg_revision_get_subject(rv1), gitg_revision_get_subject(rv2));
|
||||
break;
|
||||
case AUTHOR_COLUMN:
|
||||
ret = g_utf8_collate(gitg_revision_get_author(rv1), gitg_revision_get_author(rv2));
|
||||
break;
|
||||
case DATE_COLUMN:
|
||||
i1 = gitg_revision_get_timestamp(rv1);
|
||||
i2 = gitg_revision_get_timestamp(rv2);
|
||||
|
||||
ret = i1 < i2 ? -1 : (i1 > i2 ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_unref(rv1);
|
||||
g_object_unref(rv2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,43 +1,56 @@
|
|||
#ifndef __GITG_RV_MODEL_H__
|
||||
#define __GITG_RV_MODEL_H__
|
||||
#ifndef __GITG_REPOSITORY_H__
|
||||
#define __GITG_REPOSITORY_H__
|
||||
|
||||
#include <gtk/gtkliststore.h>
|
||||
#include <gtk/gtktreemodel.h>
|
||||
|
||||
#include "gitg-revision.h"
|
||||
#include "gitg-runner.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_RV_MODEL (gitg_rv_model_get_type ())
|
||||
#define GITG_RV_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RV_MODEL, GitgRvModel))
|
||||
#define GITG_RV_MODEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RV_MODEL, GitgRvModel const))
|
||||
#define GITG_RV_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_RV_MODEL, GitgRvModelClass))
|
||||
#define GITG_IS_RV_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_RV_MODEL))
|
||||
#define GITG_IS_RV_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_RV_MODEL))
|
||||
#define GITG_RV_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_RV_MODEL, GitgRvModelClass))
|
||||
#define GITG_TYPE_REPOSITORY (gitg_repository_get_type ())
|
||||
#define GITG_REPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REPOSITORY, GitgRepository))
|
||||
#define GITG_REPOSITORY_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_REPOSITORY, GitgRepository const))
|
||||
#define GITG_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_REPOSITORY, GitgRepositoryClass))
|
||||
#define GITG_IS_REPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_REPOSITORY))
|
||||
#define GITG_IS_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_REPOSITORY))
|
||||
#define GITG_REPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_REPOSITORY, GitgRepositoryClass))
|
||||
|
||||
typedef struct _GitgRvModel GitgRvModel;
|
||||
typedef struct _GitgRvModelClass GitgRvModelClass;
|
||||
typedef struct _GitgRvModelPrivate GitgRvModelPrivate;
|
||||
typedef struct _GitgRepository GitgRepository;
|
||||
typedef struct _GitgRepositoryClass GitgRepositoryClass;
|
||||
typedef struct _GitgRepositoryPrivate GitgRepositoryPrivate;
|
||||
|
||||
struct _GitgRvModel {
|
||||
GtkListStore parent;
|
||||
typedef enum
|
||||
{
|
||||
GITG_REPOSITORY_NO_ERROR = 0,
|
||||
GITG_REPOSITORY_ERROR_NOT_FOUND
|
||||
} GitgRepositoryError;
|
||||
|
||||
struct _GitgRepository
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GitgRvModelPrivate *priv;
|
||||
GitgRepositoryPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GitgRvModelClass {
|
||||
GtkListStoreClass parent_class;
|
||||
struct _GitgRepositoryClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gitg_rv_model_get_type (void) G_GNUC_CONST;
|
||||
GitgRvModel *gitg_rv_model_new(void);
|
||||
GType gitg_repository_get_type (void) G_GNUC_CONST;
|
||||
GitgRepository *gitg_repository_new(gchar const *path);
|
||||
gchar const *gitg_repository_get_path(GitgRepository *repository);
|
||||
GitgRunner *gitg_repository_get_loader(GitgRepository *repository);
|
||||
|
||||
void gitg_rv_model_add(GitgRvModel *self, GitgRevision *obj, GtkTreeIter *iter);
|
||||
gboolean gitg_rv_model_find_by_hash(GitgRvModel *self, gchar const *hash, GtkTreeIter *iter);
|
||||
gboolean gitg_rv_model_find(GitgRvModel *store, GitgRevision *revision, GtkTreeIter *iter);
|
||||
gboolean gitg_repository_load(GitgRepository *repository, GError **error);
|
||||
|
||||
gint gitg_rv_model_compare(GitgRvModel *store, GtkTreeIter *a, GtkTreeIter *b, gint col);
|
||||
void gitg_repository_add(GitgRepository *repository, GitgRevision *revision, GtkTreeIter *iter);
|
||||
void gitg_repository_clear(GitgRepository *repository);
|
||||
|
||||
gboolean gitg_repository_find_by_hash(GitgRepository *self, gchar const *hash, GtkTreeIter *iter);
|
||||
gboolean gitg_repository_find(GitgRepository *store, GitgRevision *revision, GtkTreeIter *iter);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GITG_RV_MODEL_H__ */
|
||||
#endif /* __GITG_REPOSITORY_H__ */
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "gitg-utils.h"
|
||||
|
||||
inline static guint8
|
||||
|
@ -52,3 +55,51 @@ gitg_utils_sha1_to_hash_new(gchar const *sha1)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
find_dot_git(gchar *path)
|
||||
{
|
||||
while (strcmp(path, ".") != 0)
|
||||
{
|
||||
gchar *res = g_build_filename(path, ".git", NULL);
|
||||
|
||||
if (g_file_test(res, G_FILE_TEST_IS_DIR))
|
||||
{
|
||||
g_free(res);
|
||||
return path;
|
||||
}
|
||||
|
||||
gchar *tmp = g_path_get_dirname(path);
|
||||
g_free(path);
|
||||
path = tmp;
|
||||
|
||||
g_free(res);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gitg_utils_find_git(gchar const *path)
|
||||
{
|
||||
gchar const *find = G_DIR_SEPARATOR_S ".git";
|
||||
gchar *dir;
|
||||
|
||||
if (strstr(path, find) == path + strlen(path) - strlen(find))
|
||||
dir = g_strndup(path, strlen(path) - strlen(find));
|
||||
else
|
||||
dir = g_strdup(path);
|
||||
|
||||
return find_dot_git(dir);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gitg_utils_dot_git_path(gchar const *path)
|
||||
{
|
||||
gchar const *find = G_DIR_SEPARATOR_S ".git";
|
||||
|
||||
if (strstr(path, find) == path + strlen(path) - strlen(find))
|
||||
return g_strdup(path);
|
||||
else
|
||||
return g_build_filename(path, ".git", NULL);
|
||||
}
|
||||
|
|
|
@ -9,4 +9,7 @@ void gitg_utils_hash_to_sha1(gchar const *hash, gchar *sha);
|
|||
gchar *gitg_utils_sha1_to_hash_new(gchar const *sha);
|
||||
gchar *gitg_utils_hash_to_sha1_new(gchar const *hash);
|
||||
|
||||
gchar *gitg_utils_find_git(gchar const *path);
|
||||
gchar *gitg_utils_dot_git_path(gchar const *path);
|
||||
|
||||
#endif /* __GITG_UTILS_H__ */
|
||||
|
|
88
gitg/gitg.c
88
gitg/gitg.c
|
@ -7,9 +7,9 @@
|
|||
#include <gtksourceview/gtksourcelanguagemanager.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "gitg-rv-model.h"
|
||||
#include "gitg-repository.h"
|
||||
#include "gitg-utils.h"
|
||||
#include "gitg-loader.h"
|
||||
#include "gitg-runner.h"
|
||||
#include "sexy-icon-entry.h"
|
||||
#include "config.h"
|
||||
|
||||
|
@ -21,12 +21,12 @@ static GOptionEntry entries[] =
|
|||
static GtkWindow *window;
|
||||
static GtkBuilder *builder;
|
||||
static GtkTreeView *tree_view;
|
||||
static GitgRvModel *store;
|
||||
static GtkStatusbar *statusbar;
|
||||
static GitgRunner *diff_runner;
|
||||
static GtkSourceView *diff_view;
|
||||
static gchar *gitdir;
|
||||
static GtkWidget *search_popup;
|
||||
static GitgRepository *repository;
|
||||
|
||||
void
|
||||
parse_options(int *argc, char ***argv)
|
||||
|
@ -59,7 +59,7 @@ on_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer userdata)
|
|||
static gint
|
||||
string_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
|
||||
{
|
||||
return gitg_rv_model_compare(store, a, b, GPOINTER_TO_INT(userdata));
|
||||
return 0; //gitg_rv_model_compare(store, a, b, GPOINTER_TO_INT(userdata));
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -165,7 +165,7 @@ on_parent_clicked(GtkWidget *ev, GdkEventButton *event, gpointer userdata)
|
|||
return FALSE;
|
||||
|
||||
GtkTreeIter iter;
|
||||
if (gitg_rv_model_find_by_hash(store, (gchar *)userdata, &iter))
|
||||
if (gitg_repository_find_by_hash(repository, (gchar *)userdata, &iter))
|
||||
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(tree_view), &iter);
|
||||
|
||||
return TRUE;
|
||||
|
@ -254,7 +254,7 @@ on_update_diff(GtkTreeSelection *selection, GtkVBox *container)
|
|||
gchar *argv[] = {
|
||||
"git",
|
||||
"--git-dir",
|
||||
gitdir,
|
||||
gitg_utils_dot_git_path(gitg_repository_get_path(repository)),
|
||||
"show",
|
||||
"--pretty=format:%s%n%n%b",
|
||||
"--encoding=UTF-8",
|
||||
|
@ -265,13 +265,15 @@ on_update_diff(GtkTreeSelection *selection, GtkVBox *container)
|
|||
gitg_runner_run(diff_runner, argv, NULL);
|
||||
g_object_unref(rv);
|
||||
g_free(hash);
|
||||
g_free(argv[2]);
|
||||
}
|
||||
|
||||
static void
|
||||
build_tree_view()
|
||||
{
|
||||
tree_view = GTK_TREE_VIEW(gtk_builder_get_object(builder, "tree_view_rv"));
|
||||
store = gitg_rv_model_new();
|
||||
|
||||
gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(repository));
|
||||
|
||||
gtk_tree_view_insert_column_with_attributes(tree_view,
|
||||
0, _("Subject"), gtk_cell_renderer_text_new(), "text", 1, NULL);
|
||||
|
@ -295,7 +297,7 @@ build_tree_view()
|
|||
gtk_tree_view_column_set_fixed_width(column, cw[i]);
|
||||
|
||||
gtk_tree_view_column_set_sort_column_id(column, i + 1);
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), i + 1, string_compare, GINT_TO_POINTER(i + 1), NULL);
|
||||
//gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), i + 1, string_compare, GINT_TO_POINTER(i + 1), NULL);
|
||||
}
|
||||
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
|
||||
|
@ -520,7 +522,7 @@ on_diff_update(GitgRunner *runner, gchar **buffer, gpointer userdata)
|
|||
}
|
||||
|
||||
static void
|
||||
on_begin_loading(GitgLoader *loader, gpointer userdata)
|
||||
on_begin_loading(GitgRunner *loader, gpointer userdata)
|
||||
{
|
||||
GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
|
||||
gdk_window_set_cursor(GTK_WIDGET(tree_view)->window, cursor);
|
||||
|
@ -530,67 +532,32 @@ on_begin_loading(GitgLoader *loader, gpointer userdata)
|
|||
}
|
||||
|
||||
static void
|
||||
on_end_loading(GitgLoader *loader, gpointer userdata)
|
||||
on_end_loading(GitgRunner *loader, gpointer userdata)
|
||||
{
|
||||
gchar *msg = g_strdup_printf(_("Loaded %d revisions"), gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL));
|
||||
gchar *msg = g_strdup_printf(_("Loaded %d revisions"), gtk_tree_model_iter_n_children(GTK_TREE_MODEL(repository), NULL));
|
||||
|
||||
gtk_statusbar_push(statusbar, 0, msg);
|
||||
|
||||
g_free(msg);
|
||||
|
||||
gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(store));
|
||||
|
||||
gdk_window_set_cursor(GTK_WIDGET(tree_view)->window, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_update(GitgLoader *loader, GitgRevision **revisions)
|
||||
on_update(GitgRunner *loader, gchar **revisions, gpointer userdata)
|
||||
{
|
||||
GitgRevision *rv;
|
||||
|
||||
gtk_tree_view_set_model(tree_view, NULL);
|
||||
|
||||
while ((rv = *revisions++))
|
||||
gitg_rv_model_add(store, rv, NULL);
|
||||
|
||||
gchar *msg = g_strdup_printf(_("Loading %d revisions..."), gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL));
|
||||
gchar *msg = g_strdup_printf(_("Loading %d revisions..."), gtk_tree_model_iter_n_children(GTK_TREE_MODEL(repository), NULL));
|
||||
|
||||
gtk_statusbar_push(statusbar, 0, msg);
|
||||
g_free(msg);
|
||||
|
||||
//gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(store));
|
||||
}
|
||||
|
||||
static gchar *
|
||||
find_dot_git(gchar *path)
|
||||
{
|
||||
while (strcmp(path, ".") != 0)
|
||||
{
|
||||
gchar *res = g_build_filename(path, ".git", NULL);
|
||||
|
||||
if (g_file_test(res, G_FILE_TEST_IS_DIR))
|
||||
{
|
||||
g_free(path);
|
||||
return res;
|
||||
}
|
||||
|
||||
gchar *tmp = g_path_get_dirname(path);
|
||||
g_free(path);
|
||||
path = tmp;
|
||||
|
||||
g_free(res);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_no_gitdir(gpointer userdata)
|
||||
{
|
||||
if (gitdir)
|
||||
if (gitg_repository_get_path(repository))
|
||||
return FALSE;
|
||||
|
||||
GtkWidget *dlg = gtk_message_dialog_new(window, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("No .git directory found"));
|
||||
GtkWidget *dlg = gtk_message_dialog_new(window, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Gitg repository could not be found"));
|
||||
|
||||
gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
gtk_widget_destroy(dlg);
|
||||
|
@ -610,27 +577,28 @@ main(int argc, char **argv)
|
|||
gtk_init(&argc, &argv);
|
||||
parse_options(&argc, &argv);
|
||||
|
||||
gitdir = find_dot_git(argc > 1 ? g_strdup(argv[1]) : g_get_current_dir());
|
||||
gchar *gitdir = argc > 1 ? g_strdup(argv[1]) : g_get_current_dir();
|
||||
repository = gitg_repository_new(gitdir);
|
||||
g_free(gitdir);
|
||||
|
||||
build_ui();
|
||||
|
||||
GitgLoader *loader = gitg_loader_new(store);
|
||||
diff_runner = gitg_runner_new(2000);
|
||||
|
||||
g_signal_connect(diff_runner, "begin-loading", G_CALLBACK(on_diff_begin_loading), NULL);
|
||||
g_signal_connect(diff_runner, "update", G_CALLBACK(on_diff_update), NULL);
|
||||
g_signal_connect(diff_runner, "end-loading", G_CALLBACK(on_diff_end_loading), NULL);
|
||||
|
||||
g_signal_connect(loader, "begin-loading", G_CALLBACK(on_begin_loading), NULL);
|
||||
g_signal_connect(loader, "revisions-added", G_CALLBACK(on_update), NULL);
|
||||
g_signal_connect(loader, "end-loading", G_CALLBACK(on_end_loading), NULL);
|
||||
|
||||
if (gitdir != NULL)
|
||||
gitg_loader_load(loader, gitdir, NULL);
|
||||
GitgRunner *loader = gitg_repository_get_loader(repository);
|
||||
g_signal_connect(loader, "begin-loading", G_CALLBACK(on_begin_loading), NULL);
|
||||
g_signal_connect(loader, "end-loading", G_CALLBACK(on_end_loading), NULL);
|
||||
g_signal_connect(loader, "update", G_CALLBACK(on_update), NULL);
|
||||
g_object_unref(loader);
|
||||
|
||||
gitg_repository_load(repository, NULL);
|
||||
|
||||
g_idle_add(handle_no_gitdir, NULL);
|
||||
gtk_main();
|
||||
|
||||
g_free(gitdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue