diff --git a/src/bin/edi_build_main.c b/src/bin/edi_build_main.c index 7b09638..bd6066d 100644 --- a/src/bin/edi_build_main.c +++ b/src/bin/edi_build_main.c @@ -111,7 +111,8 @@ static void _edi_build_create_start(int argc, int arg0, char **argv) { elm_init(argc, argv); - edi_create_efl_project(argv[arg0+1], argv[arg0+2], argv[arg0+3], argv[arg0+4], argv[arg0+5], + edi_create_efl_project(argv[arg0 + 1], argv[arg0 + 2], argv[arg0 + 3], + argv[arg0 + 4], argv[arg0 + 5], argv[arg0 + 6], _edi_build_create_done_cb); } @@ -164,10 +165,11 @@ main(int argc, char **argv) if (!strncmp("create", build_type, 6)) { - if (argc - args != 6) + if (argc - args != 7) { - fprintf(stderr, "create requires 5 additional parameters:\n"); - fprintf(stderr, " parent_path, project_name, project_url, creator_name, creator_email\n"); + fprintf(stderr, "create requires 6 additional parameters:\n"); + fprintf(stderr, " skeleton, parent_path, project_name, " + "project_url, creator_name, creator_email\n"); goto end; } diff --git a/src/bin/edi_config.h b/src/bin/edi_config.h index af2030a..82ffae0 100644 --- a/src/bin/edi_config.h +++ b/src/bin/edi_config.h @@ -91,6 +91,7 @@ extern Edi_Project_Config *_edi_project_config; Eina_Bool _edi_config_init(void); Eina_Bool _edi_config_shutdown(void); +const char *_edi_config_dir_get(void); // Global configuration handling diff --git a/src/bin/screens/edi_welcome.c b/src/bin/screens/edi_welcome.c index ce3463c..a797e7b 100644 --- a/src/bin/screens/edi_welcome.c +++ b/src/bin/screens/edi_welcome.c @@ -14,11 +14,20 @@ #define _EDI_WELCOME_PROJECT_NEW_TABLE_WIDTH 4 +typedef struct _Edi_Skeleton +{ + const char *name; + const char *path; + // TODO: add more fields here (taken from skeleton metadata) +} Edi_Skeleton; + +static Eina_List *_available_skeletons = NULL; + static Evas_Object *_welcome_window, *_welcome_naviframe; static Evas_Object *_edi_new_popup; static Evas_Object *_edi_welcome_list; static Evas_Object *_edi_project_box; -static Evas_Object *_create_inputs[5]; +static Evas_Object *_create_inputs[6]; static Evas_Object *_edi_create_button, *_edi_open_button; @@ -208,20 +217,152 @@ _edi_welcome_project_new_create_done_cb(const char *path, Eina_Bool success) _edi_welcome_project_open(path, EINA_TRUE); } +static Edi_Skeleton * +_edi_skeleton_new(const char *zippath) +{ + Edi_Skeleton *skel; + char *name, *tarname; + + skel = malloc(sizeof(Edi_Skeleton)); + if (!skel) + return NULL; + + skel->path = eina_stringshare_add(zippath); + + tarname = ecore_file_strip_ext(ecore_file_file_get(zippath)); + name = ecore_file_strip_ext(tarname); + skel->name = eina_stringshare_add(name); + free(tarname); + free(name); + + // TODO: here we can search for an (optional) metadata file for the skeleton + // and present more info to the user + + return skel; +} + +static void +_edi_skeleton_free(Edi_Skeleton *skel) +{ + if (skel) + { + eina_stringshare_del(skel->name); + eina_stringshare_del(skel->path); + free(skel); + } +} + +static void +_edi_skeletons_discover(const char *path) +{ + Eina_List *file_list, *l; + char fullp[PATH_MAX], *p; + + file_list = ecore_file_ls(path); + EINA_LIST_FOREACH(file_list, l, p) + { + if (eina_str_has_extension(p, ".tar.gz")) + { + Edi_Skeleton *skel; + + snprintf(fullp, sizeof(fullp), "%s/%s", path, p); + skel = _edi_skeleton_new(fullp); + if (skel) + _available_skeletons = eina_list_append(_available_skeletons, skel); + } + free(p); + } + eina_list_free(file_list); +} + +static char * +_edi_skeleton_text_get_cb(void *data, Evas_Object *obj EINA_UNUSED, + const char *part EINA_UNUSED) +{ + Edi_Skeleton *skel = data; + + if (skel && skel->name && skel->name[0]) + return strdup(skel->name); + else + return NULL; +} + +static void +_edi_skeleton_pressed_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info) +{ + Edi_Skeleton *skel = elm_object_item_data_get(event_info); + + elm_object_text_set(obj, skel->name); + elm_combobox_hover_end(obj); + evas_object_data_set(obj, "selected_skeleton", skel); +} + +static void +_edi_welcome_project_new_skeleton_combobox_add(const char *text, int row, Evas_Object *parent) +{ + Evas_Object *label, *cmbbox; + Elm_Genlist_Item_Class *itc; + static char user_skeleton_dir[PATH_MAX]; + Edi_Skeleton *skel; + Eina_List *l; + + label = elm_label_add(parent); + elm_object_text_set(label, text); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_table_pack(parent, label, 0, row, 1, 1); + evas_object_show(label); + + cmbbox = elm_combobox_add(parent); + evas_object_size_hint_weight_set(cmbbox, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(cmbbox, EVAS_HINT_FILL, 0); + elm_object_part_text_set(cmbbox, "guide", "Select the project type"); + elm_object_text_set(cmbbox, "eflproject"); + elm_table_pack(parent, cmbbox, 1, row, _EDI_WELCOME_PROJECT_NEW_TABLE_WIDTH - 1, 1); + evas_object_smart_callback_add(cmbbox, "item,pressed", + _edi_skeleton_pressed_cb, NULL); + evas_object_show(cmbbox); + _create_inputs[row] = cmbbox; + + EINA_LIST_FREE(_available_skeletons, skel) + _edi_skeleton_free(skel); + + snprintf(user_skeleton_dir, sizeof(user_skeleton_dir), + "%s/skeleton", _edi_config_dir_get()); + _edi_skeletons_discover(PACKAGE_DATA_DIR "/skeleton"); + _edi_skeletons_discover(user_skeleton_dir); + + itc = elm_genlist_item_class_new(); + itc->item_style = "default"; + itc->func.text_get = _edi_skeleton_text_get_cb; + + EINA_LIST_FOREACH(_available_skeletons, l, skel) + elm_genlist_item_append(cmbbox, itc, skel, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + + elm_genlist_item_class_free(itc); +} + static void _edi_welcome_project_new_create_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *entry; const char *path, *name, *user, *email, *url; + Edi_Skeleton *skeleton; - entry = elm_layout_content_get(_create_inputs[0], "elm.swallow.entry"); + skeleton = evas_object_data_get(_create_inputs[0], "selected_skeleton"); + entry = elm_layout_content_get(_create_inputs[1], "elm.swallow.entry"); path = elm_object_text_get(entry); - name = elm_object_text_get(_create_inputs[1]); - url = elm_object_text_get(_create_inputs[2]); - user = elm_object_text_get(_create_inputs[3]); - email = elm_object_text_get(_create_inputs[4]); + name = elm_object_text_get(_create_inputs[2]); + url = elm_object_text_get(_create_inputs[3]); + user = elm_object_text_get(_create_inputs[4]); + email = elm_object_text_get(_create_inputs[5]); - edi_create_efl_project(path, name, url, user, email, _edi_welcome_project_new_create_done_cb); + if (skeleton && path && path[0] && name && name[0]) + edi_create_efl_project(skeleton->path, path, name, url, user, email, + _edi_welcome_project_new_create_done_cb); + // TODO show something to the user in case of missing fields } static int @@ -277,6 +418,7 @@ _edi_welcome_project_new_cb(void *data, Evas_Object *obj EINA_UNUSED, void *even username = getenv("USER"); if (!username) username = getenv("USERNAME"); + _edi_welcome_project_new_skeleton_combobox_add("Project Type", row++, content); _edi_welcome_project_new_directory_row_add("Parent Path", row++, content); _edi_welcome_project_new_input_row_add("Project Name", NULL, row++, content); _edi_welcome_project_new_input_row_add("Project URL", NULL, row++, content); diff --git a/src/lib/edi_create.c b/src/lib/edi_create.c index ec408e4..7ee9c3a 100644 --- a/src/lib/edi_create.c +++ b/src/lib/edi_create.c @@ -12,7 +12,7 @@ typedef struct _Edi_Create { - char *path, *temp, *name; + char *path, *temp, *name, *skelfile; char *url, *user, *email; Edi_Create_Cb callback; @@ -119,6 +119,7 @@ _edi_create_free_data() free(create->name); free(create->path); free(create->temp); + free(create->skelfile); free(create); } @@ -232,7 +233,8 @@ _edi_create_extract_done(void *data, int type EINA_UNUSED, void *event EINA_UNUS char tmpinner[PATH_MAX]; create = (Edi_Create *)data; - snprintf(tmpinner, sizeof(tmpinner), "%s/eflproject", create->temp); + snprintf(tmpinner, sizeof(tmpinner), "%s/%s", create->temp, create->skelfile); + tmpinner[strlen(tmpinner) - 7] = '\0'; // strip extensin ecore_event_handler_del(create->handler); @@ -247,25 +249,26 @@ _edi_create_extract_done(void *data, int type EINA_UNUSED, void *event EINA_UNUS } EAPI void -edi_create_efl_project(const char *parentdir, const char *name, const char *url, - const char *user, const char *email, Edi_Create_Cb func) +edi_create_efl_project(const char *skelpath, const char *parentdir, + const char *name, const char *url, const char *user, + const char *email, Edi_Create_Cb func) { - char *source, *cmd, *extract; + char *cmd, *extract; char tmp[PATH_MAX], dest[PATH_MAX]; Edi_Create *data; Ecore_Event_Handler *handler; - source = PACKAGE_DATA_DIR "/skeleton/eflproject.tar.gz"; extract = "tar zxf %s -C %s"; snprintf(tmp, sizeof(tmp), "%s/edi_%s", eina_environment_tmp_get(), name); snprintf(dest, sizeof(dest), "%s/%s", parentdir, name); INF("Creating project \"%s\" at path %s for %s<%s>\n", name, dest, user, email); - DBG("Extracting project files from %s\n", source); + DBG("Extracting project files from %s\n", skelpath); data = calloc(1, sizeof(Edi_Create)); data->path = strdup(dest); data->name = strdup(name); + data->skelfile = strdup(ecore_file_file_get(skelpath)); data->url = strdup(url); data->user = strdup(user); @@ -280,8 +283,8 @@ edi_create_efl_project(const char *parentdir, const char *name, const char *url, return; } - cmd = malloc(sizeof(char) * (strlen(extract) + strlen(source) + strlen(tmp) + 1)); - sprintf(cmd, extract, source, tmp); + cmd = malloc(sizeof(char) * (strlen(extract) + strlen(skelpath) + strlen(tmp) + 1)); + sprintf(cmd, extract, skelpath, tmp); data->temp = strdup(tmp); handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _edi_create_extract_done, data); diff --git a/src/lib/edi_create.h b/src/lib/edi_create.h index a7398d8..96ea7bc 100644 --- a/src/lib/edi_create.h +++ b/src/lib/edi_create.h @@ -28,8 +28,9 @@ typedef void (*Edi_Create_Cb)(const char *path, Eina_Bool success); * @ingroup Creation */ EAPI void -edi_create_efl_project(const char *parentdir, const char *name, const char *url, - const char *user, const char *email, Edi_Create_Cb func); +edi_create_efl_project(const char *skelpath, const char *parentdir, + const char *name, const char *url, const char *user, + const char *email, Edi_Create_Cb func); /** * @}