Data cook dialog added. Doesn't save in project or work yet.
This commit is contained in:
parent
51b87b55be
commit
73ee8388de
5 changed files with 377 additions and 6 deletions
|
@ -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);
|
||||
|
|
115
src/project.c
115
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; i<arrlen(self->targets); i++) {
|
||||
for (j=0; j<arrlen(self->targets[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);
|
||||
}
|
||||
|
|
83
src/utils.c
83
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();
|
||||
}
|
||||
|
||||
|
|
181
ui/Cook.glade
Normal file
181
ui/Cook.glade
Normal file
|
@ -0,0 +1,181 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.40.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="dialogCookSettings">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="title" translatable="yes">Cook Data</property>
|
||||
<property name="default-width">400</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnCancel">
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnOkay">
|
||||
<property name="label" translatable="yes">OK</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<!-- n-columns=3 n-rows=3 -->
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="row-spacing">15</property>
|
||||
<property name="column-spacing">15</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Recipe:</property>
|
||||
<property name="justify">right</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="fileRecipe">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="filter">filefilterRecipe</property>
|
||||
<property name="preview-widget-active">False</property>
|
||||
<property name="title" translatable="yes">Open Recipe Program</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnNewRecipe">
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="btnNewRecipeClicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Raw:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lblRaw">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">lblRaw</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Cooked:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lblCooked">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">lblCooked</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">btnCancel</action-widget>
|
||||
<action-widget response="-5">btnOkay</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkFileFilter" id="filefilterRecipe">
|
||||
<patterns>
|
||||
<pattern>*.c</pattern>
|
||||
</patterns>
|
||||
</object>
|
||||
</interface>
|
|
@ -4,6 +4,7 @@
|
|||
<file preprocess="xml-stripblanks">JoeyDev.glade</file>
|
||||
<file preprocess="xml-stripblanks">Project.glade</file>
|
||||
<file preprocess="xml-stripblanks">BuildServer.glade</file>
|
||||
<file preprocess="xml-stripblanks">Cook.glade</file>
|
||||
<file preprocess="xml-stripblanks">Editor.glade</file>
|
||||
<file preprocess="xml-stripblanks">Vector.glade</file>
|
||||
<file>Logo.png</file>
|
||||
|
|
Loading…
Add table
Reference in a new issue