Launching code editor from recipe dialog now working. Removed a mess of redundant path code.

This commit is contained in:
Scott Duensing 2023-04-26 17:54:06 -05:00
parent 870d2822e0
commit 5dead7d66c
6 changed files with 86 additions and 67 deletions

View file

@ -52,7 +52,8 @@ typedef struct WindowDataS {
gboolean (*closeWindow)(GtkWidget* widget, gpointer data);
gboolean isDirty;
char *title;
char *filename;
char *filename; // This typically is a full absolute path.
char *path; // This will be derived from the filename.
} WindowDataT;

View file

@ -50,6 +50,7 @@ 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);
GtkWidget *utilFindChildWidget(GtkWidget *parent, const gchar *name);
char *utilGetToken(char *input, char *delimit, char *openblock, char *closeblock);
WindowDataT *utilGetWindowData(GtkWidget *window);
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
@ -57,6 +58,7 @@ gboolean utilMkDirP(const char *dir, const mode_t mode);
char *utilObfuscateASCII(char *clearText);
gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question);
void utilSetDirty(WindowDataT *self, gboolean dirty);
void utilUpdatePath(WindowDataT *self);
void utilWindowRegister(gpointer windowData);
int utilWindowsCloseAll(void);
int utilWindowsOpen(void);

View file

@ -81,7 +81,6 @@ typedef struct ProjectDataS {
char *buildPassword;
TargetT **targets;
GtkWidget *tempWidget; // Used to pass data around dialogs.
char *tempString; // Used to pass data around dialogs.
} ProjectDataT;
typedef struct SectionDataS {
@ -164,19 +163,16 @@ EVENT void buildTargetClicked(GtkButton *widget, gpointer userData) {
EVENT void btnEditRawClicked(GtkButton *widget, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
char *pathTemp = NULL;
char *filename = NULL;
int i;
GtkWidget *lblRaw = utilFindChildWidget(self->tempWidget, "lblRaw");
(void)widget;
pathTemp = strdup(self->windowData.filename);
cwk_path_get_dirname(pathTemp, (size_t *)&i); //***TODO*** Self is getting clobbered here. WTF?
if (i > 0) pathTemp[i] = 0;
gtk_dialog_response(GTK_DIALOG(self->tempWidget), GTK_RESPONSE_CANCEL);
//***TODO*** Be sure this is something we can edit as text.
filename = utilCreateString("%s%s", pathTemp, self->tempString);
filename = utilCreateString("%s%s", self->windowData.path, gtk_label_get_text(GTK_LABEL(lblRaw)));
winEditorCreate(filename);
DEL(filename);
}
@ -185,10 +181,13 @@ EVENT void btnEditRawClicked(GtkButton *widget, gpointer userData) {
EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
char *file = NULL;
GtkWidget *fileRecipe = utilFindChildWidget(self->tempWidget, "fileRecipe");
(void)widget;
file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(self->tempWidget));
gtk_dialog_response(GTK_DIALOG(self->tempWidget), GTK_RESPONSE_CANCEL);
file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileRecipe));
if (utilFileExists(file)) {
winEditorCreate(file);
}
@ -201,35 +200,27 @@ EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData) {
char *newFile = NULL;
char *fromTemp = NULL;
char *toTemp = NULL;
char *pathTemp = NULL;
int i;
(void)widget;
if (utilFileSaveOtherAs((WindowDataT *)userData, "*.c", "Recipe", &newFile)) {
pathTemp = strdup(self->windowData.filename);
cwk_path_get_dirname(pathTemp, (size_t *)&i);
if (i > 0) pathTemp[i] = 0;
fromTemp = utilCreateString("%s%s", __resourcePath, "recipe.c");
utilFileCopy(fromTemp, newFile);
DEL(fromTemp);
fromTemp = utilCreateString("%s%s", __resourcePath, "gitignore");
toTemp = utilCreateString("%s%s", pathTemp, ".gitignore");
toTemp = utilCreateString("%s%s", self->windowData.path, ".gitignore");
utilFileCopy(fromTemp, toTemp);
DEL(toTemp);
DEL(fromTemp);
fromTemp = utilCreateString("%s%s", __resourcePath, "gitattributes");
toTemp = utilCreateString("%s%s", pathTemp, ".gitattributes");
toTemp = utilCreateString("%s%s", self->windowData.path, ".gitattributes");
utilFileCopy(fromTemp, toTemp);
DEL(toTemp);
DEL(fromTemp);
DEL(pathTemp);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->tempWidget), newFile);
}
}
@ -255,10 +246,8 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
GtkWidget *btnOkay;
int original;
int result;
int i;
char *raw = NULL;
char *temp = NULL;
char *path = NULL;
char *widgetNames[] = {
"dialogCookSettings",
"lblRaw",
@ -282,13 +271,7 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
raw = utilFileBasename(filename);
gtk_label_set_text(GTK_LABEL(lblRaw), raw);
self->tempWidget = fileRecipe;
self->tempString = strdup(raw);
// Find path of project file.
path = strdup(self->windowData.filename);
cwk_path_get_dirname(path, (size_t *)&i);
if (i > 0) path[i] = 0;
self->tempWidget = dialogCookSettings;
original = findRecipeData(self, raw);
if (original >= 0) {
@ -301,7 +284,7 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileRecipe));
if (temp != NULL) {
// Convert to relative path.
cwk_path_get_relative(path, temp, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
cwk_path_get_relative(self->windowData.path, temp, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
if (__utilFilenameBuffer[0] != 0) {
DEL(temp);
temp = strdup(__utilFilenameBuffer);
@ -315,11 +298,9 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
}
}
DEL(path);
DEL(raw);
self->tempWidget = NULL;
DEL(self->tempString);
gtk_widget_destroy(dialogCookSettings);
}
@ -416,7 +397,6 @@ static void loadProject(ProjectDataT *self) {
TargetT *t = NULL;
int i;
int j;
char *path = NULL;
char *raw = NULL;
in = fopen(self->windowData.filename, "rt");
@ -427,10 +407,6 @@ static void loadProject(ProjectDataT *self) {
self->targets[i]->archs[j]->selected = FALSE;
}
}
// Find path of project file.
path = strdup(self->windowData.filename);
cwk_path_get_dirname(path, (size_t *)&i);
if (i > 0) path[i] = 0;
// Load project.
utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker.
while (getline(&line, &len, in) != -1) {
@ -442,7 +418,7 @@ static void loadProject(ProjectDataT *self) {
if (strcasecmp(c, "source") == 0) {
c = utilGetToken(NULL, " ", "\"", "\"");
utilDequote(c);
cwk_path_get_relative(path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
cwk_path_get_relative(self->windowData.path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
if (__utilFilenameBuffer[0] == 0) {
projectAddToTree(self, c);
} else {
@ -485,7 +461,7 @@ static void loadProject(ProjectDataT *self) {
raw = strdup(c);
c = utilGetToken(NULL, " ", "\"", "\"");
utilDequote(c);
cwk_path_get_relative(path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
cwk_path_get_relative(self->windowData.path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
if (__utilFilenameBuffer[0] == 0) {
addToRecipeData(self, raw, c);
} else {
@ -497,7 +473,6 @@ static void loadProject(ProjectDataT *self) {
}
fclose(in);
DEL(line);
DEL(path);
utilSetDirty((WindowDataT *)self, FALSE); // Do again - loading text marks us dirty.
} else {
//***TODO*** Something bad happened.
@ -543,6 +518,7 @@ EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData) {
// Nuke filename & mark clean.
DEL(self->windowData.filename);
DEL(self->windowData.path);
utilSetDirty(&self->windowData, FALSE);
}
@ -650,8 +626,6 @@ EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData) {
GtkFileFilter *filter;
ProjectSectionTypeT section;
char *temp = NULL;
char *path = NULL;
int x;
(void)object;
@ -664,10 +638,7 @@ EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData) {
);
if (self->windowData.filename != NULL) {
path = strdup(self->windowData.filename);
cwk_path_get_dirname(path, (size_t *)&x);
if (x > 0) path[x] = 0;
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),path);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),self->windowData.path);
}
for (section=0; section<SECTION_COUNT; section++) {
@ -685,8 +656,8 @@ EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData) {
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
if (path != NULL) {
cwk_path_get_relative(path,temp, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
if (self->windowData.path != NULL) {
cwk_path_get_relative(self->windowData.path,temp, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
DEL(temp);
temp = strdup(__utilFilenameBuffer);
}
@ -935,7 +906,6 @@ EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData) {
int i;
char *raw;
char *recipe;
char *path;
int result;
// Only one cook at a time. Should not be able to happen.
@ -947,11 +917,6 @@ EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData) {
// Remember who started the cook.
_cookingProjectData = self;
// Find path of project file.
path = strdup(self->windowData.filename);
cwk_path_get_dirname(path, (size_t *)&i);
if (i > 0) path[i] = 0;
for (i=0; i<arrlen(self->recipes); i++) {
// Build pathnames.
cwk_path_change_basename(self->windowData.filename, self->recipes[i]->key, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
@ -961,7 +926,7 @@ EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData) {
// Run it!
message(MSG_INFO, "Cooking %s", self->recipes[i]->key);
result = compilerRunRecipe(recipe, raw, path, self);
result = compilerRunRecipe(recipe, raw, self->windowData.path, self);
if (result != 0) {
//***TODO*** Not all negative returns are severe.
message(result > 0 ? MSG_ERROR : MSG_SEVERE, "Recipe %s returned %d", self->recipes[i]->value, result);
@ -969,7 +934,6 @@ EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData) {
message(MSG_INFO, "Finished Cooking");
}
DEL(path);
_cookingProjectData = NULL;
}
@ -1070,10 +1034,8 @@ EVENT void treeProjectRowActivated(GtkTreeView *treeView, GtkTreePath *path, Gtk
GtkTreeIter iter;
char *name = NULL;
char *pathString = NULL;
char *pathTemp = NULL;
char *filename = NULL;
int section;
int i;
pathString = gtk_tree_path_to_string(path);
if (strstr(pathString, ":") != NULL) {
@ -1084,15 +1046,10 @@ EVENT void treeProjectRowActivated(GtkTreeView *treeView, GtkTreePath *path, Gtk
debug("Double click! [%d] [%s] [%s]\n", section, pathString, name);
if (section == SECTION_CODE || section == SECTION_HEADER) {
//***TODO*** We find our path way too often. Do it once and keep it.
pathTemp = strdup(self->windowData.filename);
cwk_path_get_dirname(pathTemp, (size_t *)&i);
if (i > 0) pathTemp[i] = 0;
filename = utilCreateString("%s%s", pathTemp, name);
filename = utilCreateString("%s%s", self->windowData.path, name);
// Launch code editor.
winEditorCreate(filename);
DEL(filename);
DEL(pathTemp);
}
if (section == SECTION_RAW_DATA) {
@ -1323,6 +1280,7 @@ void winProjectCreate(void) {
//***DEBUG***
self->windowData.filename = strdup("/home/scott/joeyapps/warehouse/Warehouse.joe");
self->windowData.path = strdup("/home/scott/joeyapps/warehouse/");
loadProject(self);
}

View file

@ -253,7 +253,9 @@ gboolean utilFileOpen(WindowDataT *self, char *extension, char *what) {
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
utilSetDirty((WindowDataT *)self, FALSE);
DEL(self->filename);
DEL(self->path);
self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
utilUpdatePath(self);
} else {
result = FALSE;
}
@ -270,7 +272,7 @@ gboolean utilFileOpen(WindowDataT *self, char *extension, char *what) {
char *utilFileRemoveExtension(char *filename) {
int x = strlen(filename) - 1;
int x = (int)strlen(filename) - 1;
char c = 0;
char *newString = NULL;
@ -293,7 +295,12 @@ char *utilFileRemoveExtension(char *filename) {
gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) {
return utilFileSaveOtherAs(self, extension, what, &self->filename);
gboolean result;
result = utilFileSaveOtherAs(self, extension, what, &self->filename);
utilUpdatePath(self);
return result;
}
@ -339,6 +346,36 @@ gboolean utilFileSaveOtherAs(WindowDataT *self, char *extension, char *what, cha
}
GtkWidget *utilFindChildWidget(GtkWidget *parent, const gchar *name) {
GList *children = NULL;
GtkWidget *widget = NULL;
// This works on widgets with names. If a widget is referenced by
// utilGetWidgetsFromMemory, the name will be set to the ID of the
// widget. If not, you need to assign a name yourself.
if (g_strcmp0(gtk_widget_get_name(parent), name) == 0) {
return parent;
}
if (GTK_IS_CONTAINER(parent)) {
children = gtk_container_get_children(GTK_CONTAINER(parent));
}
while (children != NULL) {
widget = utilFindChildWidget(children->data, name);
if (widget != NULL) {
return widget;
}
children = children->next;
}
return NULL;
}
// 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;
@ -403,6 +440,8 @@ gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widg
x = 0;
while (name[x] != NULL) {
*widgets[x] = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, name[x]));
// Set the widget name property to the ID we used to find it.
gtk_widget_set_name(*widgets[x], name[x]);
x++;
}
@ -542,6 +581,20 @@ void utilSetDirty(WindowDataT *self, gboolean dirty) {
}
void utilUpdatePath(WindowDataT *self) {
int i;
if (self->filename) {
// Derive the path from the filename.
self->path = strdup(self->filename);
cwk_path_get_dirname(self->path, (size_t *)&i);
if (i > 0) self->path[i] = 0;
} else {
DEL(self->path);
}
}
void utilWindowRegister(gpointer windowData) {
WindowDataT *w = (WindowDataT *)windowData;

View file

@ -735,6 +735,7 @@ EVENT void menuVectorFileNew(GtkWidget *object, gpointer userData) {
// Clear any filename.
DEL(self->windowData.filename);
DEL(self->windowData.path);
// Refresh widget.
gtk_widget_queue_draw(self->drawVectorImage);
@ -1529,6 +1530,7 @@ void winVectorCreate(char *filename) {
if (filename != NULL) {
self->windowData.filename = strdup(filename);
utilUpdatePath((WindowDataT *)self);
loadVectorImage(self);
}
}

View file

@ -15,6 +15,9 @@
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">