From ba42d32d5e28b28fcea56c8109196ff76b729dc4 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 22 Nov 2014 22:36:57 +0000 Subject: [PATCH] Add a simple diff widget based on an incoming diff file. Load that into edi if we load a diff or patch file --- elm_code/bin/elm_code_test_main.c | 57 ++----------- elm_code/lib/Elm_Code.h | 1 + elm_code/lib/Makefile.am | 2 + elm_code/lib/elm_code_diff_widget.c | 122 ++++++++++++++++++++++++++++ elm_code/lib/elm_code_diff_widget.h | 39 +++++++++ elm_code/lib/elm_code_widget.h | 1 - elm_code/tests/testdiff.diff | 10 +++ src/bin/mainview/edi_mainview.c | 20 +++++ 8 files changed, 200 insertions(+), 52 deletions(-) create mode 100644 elm_code/lib/elm_code_diff_widget.c create mode 100644 elm_code/lib/elm_code_diff_widget.h create mode 100644 elm_code/tests/testdiff.diff diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index 69a3034..713598f 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -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 * diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index eadf59d..30f323a 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef EAPI # undef EAPI diff --git a/elm_code/lib/Makefile.am b/elm_code/lib/Makefile.am index 5339cc5..c2b4d99 100644 --- a/elm_code/lib/Makefile.am +++ b/elm_code/lib/Makefile.am @@ -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@ diff --git a/elm_code/lib/elm_code_diff_widget.c b/elm_code/lib/elm_code_diff_widget.c new file mode 100644 index 0000000..95eeb57 --- /dev/null +++ b/elm_code/lib/elm_code_diff_widget.c @@ -0,0 +1,122 @@ +#ifdef HAVE_CONFIG +# include "config.h" +#endif + +#include +#include + +#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); +} + diff --git a/elm_code/lib/elm_code_diff_widget.h b/elm_code/lib/elm_code_diff_widget.h new file mode 100644 index 0000000..ac9f6d4 --- /dev/null +++ b/elm_code/lib/elm_code_diff_widget.h @@ -0,0 +1,39 @@ +#ifndef ELM_CODE_DIFF_WIDGET_H_ +# define ELM_CODE_DIFF_WIDGET_H_ + +#include +#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_ */ diff --git a/elm_code/lib/elm_code_widget.h b/elm_code/lib/elm_code_widget.h index a9075ab..2302914 100644 --- a/elm_code/lib/elm_code_widget.h +++ b/elm_code/lib/elm_code_widget.h @@ -1,7 +1,6 @@ #ifndef ELM_CODE_WIDGET_H_ # define ELM_CODE_WIDGET_H_ -#include #include #include "elm_code_common.h" diff --git a/elm_code/tests/testdiff.diff b/elm_code/tests/testdiff.diff new file mode 100644 index 0000000..157cbb7 --- /dev/null +++ b/elm_code/tests/testdiff.diff @@ -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 diff --git a/src/bin/mainview/edi_mainview.c b/src/bin/mainview/edi_mainview.c index 4b513e5..fd68e9d 100644 --- a/src/bin/mainview/edi_mainview.c +++ b/src/bin/mainview/edi_mainview.c @@ -6,6 +6,7 @@ #include #include +#include #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);