Add a simple diff widget based on an incoming diff file.

Load that into edi if we load a diff or patch file
This commit is contained in:
Andy Williams 2014-11-22 22:36:57 +00:00
parent 586bbb41aa
commit ba42d32d5e
8 changed files with 200 additions and 52 deletions

View File

@ -59,61 +59,16 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
static Evas_Object *
_elm_code_test_diff_setup(Evas_Object *parent)
{
char *path = "elm_code/tests/testdiff.diff";
Evas_Object *diff;
Elm_Code_File *file;
Elm_Code *code;
Evas_Object *widget, *hbox;
hbox = elm_box_add(parent);
evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_homogeneous_set(hbox, EINA_TRUE);
elm_box_horizontal_set(hbox, EINA_TRUE);
evas_object_show(hbox);
// left side of diff
code = elm_code_create();
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
file = elm_code_file_open(code, path);
_append_line(code->file, "Some content to diff");
_append_line(code->file, "");
_append_line(code->file, "more");
_append_line(code->file, "removed");
_append_line(code->file, "will change");
_append_line(code->file, "unchanged");
elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_REMOVED);
elm_code_file_line_token_add(code->file, 4, 1, 7, ELM_CODE_TOKEN_TYPE_REMOVED);
elm_code_file_line_status_set(code->file, 5, ELM_CODE_STATUS_TYPE_CHANGED);
elm_code_file_line_token_add(code->file, 5, 1, 5, ELM_CODE_TOKEN_TYPE_REMOVED);
evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(widget);
elm_box_pack_end(hbox, widget);
// right side of diff
code = elm_code_create();
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
_append_line(code->file, "Some content to diff");
_append_line(code->file, "added");
_append_line(code->file, "more");
_append_line(code->file, "");
_append_line(code->file, "changed");
_append_line(code->file, "unchanged");
elm_code_file_line_status_set(code->file, 2, ELM_CODE_STATUS_TYPE_ADDED);
elm_code_file_line_token_add(code->file, 2, 1, 5, ELM_CODE_TOKEN_TYPE_ADDED);
elm_code_file_line_status_set(code->file, 5, ELM_CODE_STATUS_TYPE_CHANGED);
elm_code_file_line_token_add(code->file, 5, 7, 7, ELM_CODE_TOKEN_TYPE_ADDED);
evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(widget);
elm_box_pack_end(hbox, widget);
return hbox;
diff = elm_code_diff_widget_add(parent, code);
return diff;
}
static Evas_Object *

View File

@ -9,6 +9,7 @@
#include <elm_code_file.h>
#include <elm_code_parse.h>
#include <elm_code_widget.h>
#include <elm_code_diff_widget.h>
#ifdef EAPI
# undef EAPI

View File

@ -15,6 +15,7 @@ includes_HEADERS = \
elm_code_file.h \
elm_code_parse.h \
elm_code_widget.h \
elm_code_diff_widget.h \
Elm_Code.h
includesdir = $(includedir)/edi-@VMAJ@
@ -22,6 +23,7 @@ libelm_code_la_SOURCES = \
elm_code_file.c \
elm_code_parse.c \
elm_code_widget.c \
elm_code_diff_widget.c \
elm_code.c
libelm_code_la_LIBADD = @EFL_LIBS@ -lm
libelm_code_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@

View File

@ -0,0 +1,122 @@
#ifdef HAVE_CONFIG
# include "config.h"
#endif
#include <Eo.h>
#include <Elementary.h>
#include "Elm_Code.h"
#include "elm_code_diff_widget.h"
#include "elm_code_private.h"
#define ELM_CODE_DIFF_WIDGET_LEFT "diffwidgetleft"
#define ELM_CODE_DIFF_WIDGET_RIGHT "diffwidgetright"
static void _elm_code_diff_widget_parse_diff_line(Elm_Code_Line *line, int number, Elm_Code_File *left, Elm_Code_File *right)
{
if (line->length < 1)
{
elm_code_file_line_append(left, "", 0);
elm_code_file_line_append(right, "", 0);
}
if (line->content[0] == '+')
{
elm_code_file_line_append(left, "", 0);
elm_code_file_line_append(right, line->content+1, line->length-1);
elm_code_file_line_status_set(right, number, ELM_CODE_STATUS_TYPE_ADDED);
}
else if (line->content[0] == '-')
{
elm_code_file_line_append(left, line->content+1, line->length-1);
elm_code_file_line_append(right, "", 0);
elm_code_file_line_status_set(left, number, ELM_CODE_STATUS_TYPE_REMOVED);
}
else
{
elm_code_file_line_append(left, line->content+1, line->length-1);
elm_code_file_line_append(right, line->content+1, line->length-1);
}
}
static void _elm_code_diff_widget_parse_diff(Elm_Code_File *diff, Elm_Code_File *left, Elm_Code_File *right)
{
Eina_List *item;
Elm_Code_Line *line;
int number;
number = 0;
EINA_LIST_FOREACH(diff->lines, item, line)
{
if (line->length > 0 && number < 2)
{
if (line->content[0] == 'd' || line->content[0] == 'i')
continue;
}
if (number == 0)
{
elm_code_file_line_append(left, line->content+4, line->length-4);
elm_code_file_line_status_set(left, 1, ELM_CODE_STATUS_TYPE_CHANGED);
}
else if (number == 1)
{
elm_code_file_line_append(right, line->content+4, line->length-4);
elm_code_file_line_status_set(right, 1, ELM_CODE_STATUS_TYPE_CHANGED);
}
else
_elm_code_diff_widget_parse_diff_line(line, number, left, right);
number++;
}
}
EAPI Evas_Object *elm_code_diff_widget_add(Evas_Object *parent, Elm_Code *code)
{
Elm_Code *wcode1, *wcode2;
Evas_Object *widget_left, *widget_right, *hbox;
hbox = elm_panes_add(parent);
evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_panes_horizontal_set(hbox, EINA_FALSE);
evas_object_show(hbox);
// left side of diff
wcode1 = elm_code_create();
elm_code_file_new(wcode1);
widget_left = elm_code_widget_add(parent, wcode1);
evas_object_size_hint_weight_set(widget_left, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget_left, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(widget_left);
evas_object_data_set(hbox, ELM_CODE_DIFF_WIDGET_LEFT, widget_left);
elm_object_part_content_set(hbox, "left", widget_left);
// right side of diff
wcode2 = elm_code_create();
elm_code_file_new(wcode2);
widget_right = elm_code_widget_add(parent, wcode2);
evas_object_size_hint_weight_set(widget_right, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget_right, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(widget_right);
evas_object_data_set(hbox, ELM_CODE_DIFF_WIDGET_RIGHT, widget_right);
elm_object_part_content_set(hbox, "right", widget_right);
_elm_code_diff_widget_parse_diff(code->file, wcode1->file, wcode2->file);
return hbox;
}
EAPI void elm_code_diff_widget_font_size_set(Evas_Object *widget, int size)
{
Evas_Object *child;
child = evas_object_data_get(widget, ELM_CODE_DIFF_WIDGET_LEFT);
elm_code_widget_font_size_set(child, size);
child = evas_object_data_get(widget, ELM_CODE_DIFF_WIDGET_RIGHT);
elm_code_widget_font_size_set(child, size);
}

View File

@ -0,0 +1,39 @@
#ifndef ELM_CODE_DIFF_WIDGET_H_
# define ELM_CODE_DIFF_WIDGET_H_
#include <Evas.h>
#include "elm_code_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* @brief These routines are used for rendering diff instances of Elm Code.
*/
/**
* @brief UI Loading functions.
* @defgroup Init Creating a diff widget to render an Elm Code backend
* when it's referencing a diff file
*
* @{
*
* Functions for Diff UI loading.
*
*/
EAPI Evas_Object *elm_code_diff_widget_add(Evas_Object *parent, Elm_Code *code);
EAPI void elm_code_diff_widget_font_size_set(Evas_Object *widget, int size);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ELM_CODE_DIFF_WIDGET_H_ */

View File

@ -1,7 +1,6 @@
#ifndef ELM_CODE_WIDGET_H_
# define ELM_CODE_WIDGET_H_
#include <Eina.h>
#include <Evas.h>
#include "elm_code_common.h"

View File

@ -0,0 +1,10 @@
--- testdiff1.txt 2014-11-22 21:16:16.279872989 +0000
+++ testdiff2.txt 2014-11-22 21:16:34.406052375 +0000
@@ -1,5 +1,5 @@
Some content to diff
+added
more
-removed
-will change
+changed
unchanged

View File

@ -6,6 +6,7 @@
#include <Eina.h>
#include <Eio.h>
#include <Elm_Code.h>
#include "mainview/edi_mainview_item.h"
#include "mainview/edi_mainview.h"
@ -159,6 +160,19 @@ _edi_mainview_content_image_create(Edi_Mainview_Item *item, Evas_Object *parent)
return scroll;
}
static Evas_Object *
_edi_mainview_content_diff_create(Edi_Mainview_Item *item, Evas_Object *parent)
{
Elm_Code *code;
Evas_Object *diff;
code = elm_code_create();
elm_code_file_open(code, item->path);
diff = elm_code_diff_widget_add(parent, code);
return diff;
}
static Evas_Object *
_edi_mainview_content_create(Edi_Mainview_Item *item, Evas_Object *parent)
{
@ -170,6 +184,10 @@ _edi_mainview_content_create(Edi_Mainview_Item *item, Evas_Object *parent)
{
return _edi_mainview_content_image_create(item, parent);
}
else if (!strcmp(item->editortype, "diff"))
{
return _edi_mainview_content_diff_create(item, parent);
}
return NULL;
}
@ -320,6 +338,8 @@ _edi_mainview_tab_stat_done(void *data, Eio_File *handler EINA_UNUSED, const Ein
options->type = "text"; // TODO make a code view
else if (!strncasecmp(mime, "image/", 6))
options->type = "image";
else if (!strcasecmp(mime, "text/x-diff") || !strcasecmp(mime, "text/x-patch"))
options->type = "diff";
else
{
_edi_mainview_choose_type(nf, options, _edi_mainview_choose_type_tab_cb);