From 73ee8388de4bba01ffc1833b0b9c329f3e750714 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 18 Apr 2023 21:04:22 -0500 Subject: [PATCH] Data cook dialog added. Doesn't save in project or work yet. --- include/utils.h | 3 + src/project.c | 115 ++++++++++++++++++++++++- src/utils.c | 83 ++++++++++++++++-- ui/Cook.glade | 181 +++++++++++++++++++++++++++++++++++++++ ui/joeydev.gresource.xml | 1 + 5 files changed, 377 insertions(+), 6 deletions(-) create mode 100644 ui/Cook.glade diff --git a/include/utils.h b/include/utils.h index b709f53..eff4d5d 100644 --- a/include/utils.h +++ b/include/utils.h @@ -42,9 +42,12 @@ char *utilCreateStringVArgs(char *format, va_list args); char *utilDeobfuscateASCII(char *obfuscated); void utilDequote(char *string); void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted); +char *utilFileBasename(char *path); gboolean utilFileExists(char *filename); gboolean utilFileOpen(WindowDataT *self, char *extension, char *what); +char *utilFileRemoveExtension(char *filename); gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what); +gboolean utilFileSaveOtherAs(WindowDataT *self, char *extension, char *what, char **filename); char *utilGetToken(char *input, char *delimit, char *openblock, char *closeblock); WindowDataT *utilGetWindowData(GtkWidget *window); gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData); diff --git a/src/project.c b/src/project.c index c93eb91..4564d76 100644 --- a/src/project.c +++ b/src/project.c @@ -38,6 +38,7 @@ enum ProjectColumnsE { }; typedef enum ProjectColumnsE ProjectColumnsT; +// These have to match SectionDataT below. enum ProjectSectionTypeE { SECTION_HEADER = 0, SECTION_CODE, @@ -74,6 +75,7 @@ typedef struct ProjectDataS { char *buildUser; char *buildPassword; TargetT **targets; + GtkWidget *tempWidget; // Used to pass data around dialogs. } ProjectDataT; typedef struct SectionDataS { @@ -82,6 +84,7 @@ typedef struct SectionDataS { } SectionDataT; +// These have to match ProjectSectionTypeT above. static SectionDataT _sectionData[] = { { "Header", "*.h" }, { "Code", "*.c" }, @@ -101,6 +104,8 @@ static SectionDataT _sectionData[] = { static void addToTree(ProjectDataT *self, char *filename); EVENT void buildTargetClicked(GtkButton *widget, gpointer userData); +EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData); +static void dialogCookOptions(char *filename, ProjectDataT *self); static void loadConfig(ProjectDataT *self); static void loadProject(ProjectDataT *self); EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData); @@ -185,6 +190,84 @@ EVENT void buildTargetClicked(GtkButton *widget, gpointer userData) { } +EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData) { + ProjectDataT *self = (ProjectDataT *)userData; + char *newFile = NULL; + FILE *out = NULL; + + (void)widget; + + if (utilFileSaveOtherAs((WindowDataT *)userData, "*.c", "Recipe", &newFile)) { + out = fopen(newFile, "wt"); + fprintf(out, "" + "//\n" + "// JoeyBuild Recipe Program\n" + "//\n" + "\n" + "int recipe(char *fileIn, char *fileOut) {\n" + "\n" + "\treturn 0; // Return a non-zero value on failure.\n" + "}\n" + ); + fclose(out); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->tempWidget), newFile); + } +} + + +static void dialogCookOptions(char *filename, ProjectDataT *self) { + GtkWidget *dialogCookSettings; + GtkWidget *lblRaw; + GtkWidget *fileRecipe; + GtkWidget *btnNewRecipe; + GtkWidget *lblCooked; + GtkWidget *btnCancel; + GtkWidget *btnOkay; + int result = 0; + char *raw = NULL; + char *cooked = NULL; + char *widgetNames[] = { + "dialogCookSettings", + "lblRaw", + "fileRecipe", + "btnNewRecipe", + "lblCooked", + "btnCancel", + "btnOkay", + NULL + }; + GtkWidget **widgets[] = { + &dialogCookSettings, + &lblRaw, + &fileRecipe, + &btnNewRecipe, + &lblCooked, + &btnCancel, + &btnOkay + }; + + utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Cook.glade", widgetNames, widgets, self); + + raw = utilFileBasename(filename); + gtk_label_set_text(GTK_LABEL(lblRaw), raw); + cooked = utilFileRemoveExtension(raw); + strcat(cooked, ".dat"); + gtk_label_set_text(GTK_LABEL(lblCooked), cooked); + DEL(cooked); + DEL(raw); + + self->tempWidget = fileRecipe; + + result = gtk_dialog_run(GTK_DIALOG(dialogCookSettings)); + if (result == GTK_RESPONSE_OK) { + + } + + self->tempWidget = NULL; + gtk_widget_destroy(dialogCookSettings); +} + + static void loadConfig(ProjectDataT *self) { FILE *in = NULL; char *line = NULL; @@ -338,6 +421,13 @@ EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData) { (void)object; + // Is the project dirty? + if (self->windowData.isDirty) { + if (!utilQuestionDialog(self->windowData.window, "New Project", "You have unsaved changes. Create new project anyway?")) { + return; + } + } + // Reset project tree. gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), NULL); store = gtk_tree_store_new(1, G_TYPE_STRING); @@ -708,8 +798,19 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) { result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result != GTK_RESPONSE_OK) { + // Undo any changes. targetArrayDelete(&self->targets); self->targets = targetArrayCopy(backup); + } else { + // Did their selections change? + for (i=0; itargets); i++) { + for (j=0; jtargets[i]->archs); j++) { + if (backup[i]->archs[j]->selected != self->targets[i]->archs[j]->selected) { + utilSetDirty((WindowDataT *)self, TRUE); + break; // Try to speed it up just a bit. :-) + } + } + } } targetArrayDelete(&backup); @@ -765,13 +866,25 @@ EVENT void treeProjectRowActivated(GtkTreeView *treeView, GtkTreePath *path, Gtk GtkTreeIter iter; char *name = NULL; char *pathString = NULL; + int section; pathString = gtk_tree_path_to_string(path); if (strstr(pathString, ":") != NULL) { gtk_tree_model_get_iter_from_string(model, &iter, pathString); gtk_tree_model_get(model, &iter, COL_FILENAME, &name, -1); + section = atoi(pathString); - debug("Double click! [%s] [%s]\n", pathString, name); + debug("Double click! [%d] [%s] [%s]\n", section, pathString, name); + + if (section == SECTION_CODE || section == SECTION_HEADER) { + // Launch code editor. + //***TODO*** + } + + if (section == SECTION_RAW_DATA) { + // Display cook dialog. + dialogCookOptions(name, self); + } DEL(name); } diff --git a/src/utils.c b/src/utils.c index 2e86753..34b5b36 100644 --- a/src/utils.c +++ b/src/utils.c @@ -130,6 +130,18 @@ void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted) { } +char *utilFileBasename(char *path) { + const char *basename; + size_t length; + char *newString = NULL; + + cwk_path_get_basename(path, &basename, &length); + if (basename != NULL) newString = strdup(basename); + + return newString; +} + + gboolean utilFileExists(char *filename) { FILE *f = fopen(filename, "rb"); @@ -189,6 +201,29 @@ gboolean utilFileOpen(WindowDataT *self, char *extension, char *what) { } +char *utilFileRemoveExtension(char *filename) { + int x = strlen(filename) - 1; + char c = 0; + char *newString = NULL; + + while (x >= 0) { + if (filename[x] == '.') break; + x--; + } + + if (x >= 0) { + c = filename[x]; + filename[x] = 0; + newString = strdup(filename); + filename[x] = c; + } else { + newString = strdup(filename); + } + + return newString; +} + + gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) { GtkWidget *dialog; GtkFileFilter *filter; @@ -232,6 +267,48 @@ gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) { } +gboolean utilFileSaveOtherAs(WindowDataT *self, char *extension, char *what, char **filename) { + GtkWidget *dialog; + GtkFileFilter *filter; + gboolean result = FALSE; + char *files = utilCreateString("%s Files", what); + int x; + + dialog = gtk_file_chooser_dialog_new("Save As", + GTK_WINDOW(self->window), + GTK_FILE_CHOOSER_ACTION_SAVE, + "_Cancel", GTK_RESPONSE_CANCEL, + "_Save", GTK_RESPONSE_ACCEPT, + NULL); + + if (*filename != NULL) { + memcpy(__utilFilenameBuffer, *filename, strlen(*filename) + 1); + cwk_path_get_dirname(__utilFilenameBuffer, &x); + if (x > 0) __utilFilenameBuffer[x] = 0; + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),__utilFilenameBuffer); + } + + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); + + filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, files); + gtk_file_filter_add_pattern(filter, extension); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + DEL(*filename); + *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + result = TRUE; + } + + DEL(files); + + gtk_widget_destroy(dialog); + + return result; +} + + // https://stackoverflow.com/questions/26187037/in-c-split-char-on-spaces-with-strtok-function-except-if-between-quotes char *utilGetToken(char *input, char *delimit, char *openblock, char *closeblock) { static char *token = NULL; @@ -456,12 +533,8 @@ int utilWindowsCloseAll(void) { // User canceled closing. break; } - // Mark it clean and close it ourselves. - w->isDirty = FALSE; - gtk_window_close(GTK_WINDOW(w->window)); - // Unregister it. - utilWindowUnRegister(w); } + return utilWindowsOpen(); } diff --git a/ui/Cook.glade b/ui/Cook.glade new file mode 100644 index 0000000..6786bd0 --- /dev/null +++ b/ui/Cook.glade @@ -0,0 +1,181 @@ + + + + + + False + Cook Data + 400 + dialog + + + False + vertical + 2 + + + False + end + + + Cancel + True + True + True + + + True + True + 0 + + + + + OK + True + True + True + + + True + True + 1 + + + + + False + False + 0 + + + + + True + False + center + vertical + + + + True + False + 15 + 15 + + + True + False + end + Recipe: + right + + + 0 + 1 + + + + + True + False + True + filefilterRecipe + False + Open Recipe Program + + + 1 + 1 + + + + + New + True + True + True + + + + 2 + 1 + + + + + True + False + end + Raw: + + + 0 + 0 + + + + + True + False + start + lblRaw + + + 1 + 0 + 2 + + + + + True + False + end + Cooked: + + + 0 + 2 + + + + + True + False + start + lblCooked + + + 1 + 2 + 2 + + + + + False + True + 0 + + + + + True + True + 0 + + + + + + btnCancel + btnOkay + + + + + *.c + + + diff --git a/ui/joeydev.gresource.xml b/ui/joeydev.gresource.xml index e513d51..bd3d918 100644 --- a/ui/joeydev.gresource.xml +++ b/ui/joeydev.gresource.xml @@ -4,6 +4,7 @@ JoeyDev.glade Project.glade BuildServer.glade + Cook.glade Editor.glade Vector.glade Logo.png