Start of Targets dialog.
This commit is contained in:
parent
6ac1f11291
commit
2469ec2ca2
6 changed files with 261 additions and 51 deletions
|
@ -51,6 +51,8 @@ typedef struct HTTPS {
|
||||||
HTTPT *httpDownload(HTTPCallback callback, char *filename, char *url);
|
HTTPT *httpDownload(HTTPCallback callback, char *filename, char *url);
|
||||||
void httpShutdown(void);
|
void httpShutdown(void);
|
||||||
void httpStartup(void);
|
void httpStartup(void);
|
||||||
|
gboolean httpWaitForDownload(void);
|
||||||
|
void httpWaitForDownloadCallback(HTTPT *download);
|
||||||
|
|
||||||
|
|
||||||
#endif // HTTP_H
|
#endif // HTTP_H
|
||||||
|
|
|
@ -40,10 +40,12 @@
|
||||||
char *utilCreateString(char *format, ...);
|
char *utilCreateString(char *format, ...);
|
||||||
char *utilCreateStringVArgs(char *format, va_list args);
|
char *utilCreateStringVArgs(char *format, va_list args);
|
||||||
char *utilDeobfuscateASCII(char *obfuscated);
|
char *utilDeobfuscateASCII(char *obfuscated);
|
||||||
|
void utilDequote(char *string);
|
||||||
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
||||||
gboolean utilFileExists(char *filename);
|
gboolean utilFileExists(char *filename);
|
||||||
gboolean utilFileOpen(WindowDataT *self, char *extension, char *what);
|
gboolean utilFileOpen(WindowDataT *self, char *extension, char *what);
|
||||||
gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what);
|
gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what);
|
||||||
|
char *utilGetToken(char *input, char *delimit, char *openblock, char *closeblock);
|
||||||
WindowDataT *utilGetWindowData(GtkWidget *window);
|
WindowDataT *utilGetWindowData(GtkWidget *window);
|
||||||
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
|
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
|
||||||
gboolean utilMkDirP(const char *dir, const mode_t mode);
|
gboolean utilMkDirP(const char *dir, const mode_t mode);
|
||||||
|
|
25
src/http.c
25
src/http.c
|
@ -20,11 +20,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma ide diagnostic ignored "EndlessLoop"
|
||||||
|
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
|
||||||
static CURLM *_curlMulti = NULL;
|
static CURLM *_curlMulti = NULL;
|
||||||
static HTTPT **_activeHTTPs = NULL;
|
static HTTPT **_activeHTTPs = NULL;
|
||||||
|
static gboolean _httpTestComplete = FALSE;
|
||||||
|
static gboolean _httpTestSuccess = FALSE;
|
||||||
|
|
||||||
|
|
||||||
gboolean httpUpdate(gpointer userData); // Not static
|
gboolean httpUpdate(gpointer userData); // Not static
|
||||||
|
@ -150,6 +156,22 @@ gboolean httpUpdate(gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean httpWaitForDownload(void) {
|
||||||
|
_httpTestComplete = FALSE;
|
||||||
|
// This loop seriously breaks CLion's syntax highlighting for the rest of the function.
|
||||||
|
while (_httpTestComplete == FALSE) {
|
||||||
|
gtk_main_iteration();
|
||||||
|
}
|
||||||
|
return _httpTestSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void httpWaitForDownloadCallback(HTTPT *download) {
|
||||||
|
_httpTestComplete = TRUE;
|
||||||
|
_httpTestSuccess = download->success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t httpWrite(char *data, size_t num, size_t length, void *userp) {
|
static size_t httpWrite(char *data, size_t num, size_t length, void *userp) {
|
||||||
HTTPT *download = (HTTPT *)userp;
|
HTTPT *download = (HTTPT *)userp;
|
||||||
|
|
||||||
|
@ -171,3 +193,6 @@ static size_t httpWrite(char *data, size_t num, size_t length, void *userp) {
|
||||||
|
|
||||||
return num * length;
|
return num * length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
191
src/project.c
191
src/project.c
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
|
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
|
||||||
#pragma ide diagnostic ignored "EndlessLoop"
|
|
||||||
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -53,6 +52,17 @@ enum ProjectSectionTypeE {
|
||||||
typedef enum ProjectSectionTypeE ProjectSectionTypeT;
|
typedef enum ProjectSectionTypeE ProjectSectionTypeT;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ArchS {
|
||||||
|
char *name;
|
||||||
|
gboolean selected;
|
||||||
|
} ArchT;
|
||||||
|
|
||||||
|
typedef struct TargetS {
|
||||||
|
char *name;
|
||||||
|
char *longName;
|
||||||
|
ArchT **archs;
|
||||||
|
} TargetT;
|
||||||
|
|
||||||
typedef struct ProjectDataS {
|
typedef struct ProjectDataS {
|
||||||
WindowDataT windowData;
|
WindowDataT windowData;
|
||||||
GtkWidget *treeProject;
|
GtkWidget *treeProject;
|
||||||
|
@ -62,6 +72,7 @@ typedef struct ProjectDataS {
|
||||||
int buildSSHPort;
|
int buildSSHPort;
|
||||||
char *buildUser;
|
char *buildUser;
|
||||||
char *buildPassword;
|
char *buildPassword;
|
||||||
|
TargetT **targets;
|
||||||
} ProjectDataT;
|
} ProjectDataT;
|
||||||
|
|
||||||
typedef struct SectionDataS {
|
typedef struct SectionDataS {
|
||||||
|
@ -84,15 +95,10 @@ static SectionDataT _sectionData[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static gboolean _httpTestComplete = FALSE;
|
|
||||||
static gboolean _httpTestSuccess = FALSE;
|
|
||||||
|
|
||||||
|
|
||||||
#define BUILD_SETTINGS_RESPONSE_TEST 1
|
#define BUILD_SETTINGS_RESPONSE_TEST 1
|
||||||
|
|
||||||
|
|
||||||
static void addToTree(ProjectDataT *self, char *filename);
|
static void addToTree(ProjectDataT *self, char *filename);
|
||||||
static void httpTest(HTTPT *download);
|
|
||||||
static void loadConfig(ProjectDataT *self);
|
static void loadConfig(ProjectDataT *self);
|
||||||
static void loadProject(ProjectDataT *self);
|
static void loadProject(ProjectDataT *self);
|
||||||
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
|
||||||
|
@ -102,11 +108,12 @@ EVENT void menuProjectFileSaveAs(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectFileClose(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectFileClose(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData);
|
|
||||||
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData);
|
||||||
|
EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
|
||||||
static void saveConfig(ProjectDataT *self);
|
static void saveConfig(ProjectDataT *self);
|
||||||
|
static gboolean updateBuildOptions(ProjectDataT *self);
|
||||||
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
|
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
|
||||||
static void winProjectDelete(gpointer userData);
|
static void winProjectDelete(gpointer userData);
|
||||||
|
|
||||||
|
@ -142,12 +149,6 @@ static void addToTree(ProjectDataT *self, char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void httpTest(HTTPT *download) {
|
|
||||||
_httpTestComplete = TRUE;
|
|
||||||
_httpTestSuccess = download->success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void loadConfig(ProjectDataT *self) {
|
static void loadConfig(ProjectDataT *self) {
|
||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
|
@ -408,11 +409,6 @@ EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
||||||
ProjectDataT *self = (ProjectDataT *)userData;
|
ProjectDataT *self = (ProjectDataT *)userData;
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
|
@ -446,8 +442,6 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
||||||
&btnOkay
|
&btnOkay
|
||||||
};
|
};
|
||||||
char temp[6];
|
char temp[6];
|
||||||
char *name = NULL;
|
|
||||||
char *url = NULL;
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
SSHT *ssh = NULL;
|
SSHT *ssh = NULL;
|
||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
|
@ -481,19 +475,9 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
||||||
gtk_widget_set_sensitive(btnTest, FALSE);
|
gtk_widget_set_sensitive(btnTest, FALSE);
|
||||||
gtk_widget_set_sensitive(btnOkay, FALSE);
|
gtk_widget_set_sensitive(btnOkay, FALSE);
|
||||||
// Run server connection tests - HTTP.
|
// Run server connection tests - HTTP.
|
||||||
name = utilCreateString("%s%cjoeydev%cjoeydev.info", g_get_user_config_dir(), UTIL_PATH_CHAR, UTIL_PATH_CHAR);
|
if (updateBuildOptions(self) == FALSE) {
|
||||||
url = utilCreateString("http://%s:%d/joeydev.info", self->buildHost, self->buildHTTPPort);
|
|
||||||
_httpTestComplete = FALSE;
|
|
||||||
httpDownload(httpTest, name, url);
|
|
||||||
// This loop seriously breaks CLion's syntax highlighting.
|
|
||||||
while (_httpTestComplete == FALSE) {
|
|
||||||
gtk_main_iteration();
|
|
||||||
}
|
|
||||||
if (_httpTestSuccess == FALSE) {
|
|
||||||
error = utilCreateString("Unable to connect to HTTP port.");
|
error = utilCreateString("Unable to connect to HTTP port.");
|
||||||
}
|
}
|
||||||
DEL(url);
|
|
||||||
DEL(name);
|
|
||||||
// Run server connection tests - SSH.
|
// Run server connection tests - SSH.
|
||||||
ssh = sshConnect(self->buildHost, self->buildSSHPort, self->buildUser, self->buildPassword);
|
ssh = sshConnect(self->buildHost, self->buildSSHPort, self->buildUser, self->buildPassword);
|
||||||
if (ssh) {
|
if (ssh) {
|
||||||
|
@ -522,6 +506,8 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
||||||
gtk_widget_set_sensitive(btnTest, TRUE);
|
gtk_widget_set_sensitive(btnTest, TRUE);
|
||||||
gtk_widget_set_sensitive(btnOkay, TRUE);
|
gtk_widget_set_sensitive(btnOkay, TRUE);
|
||||||
} else {
|
} else {
|
||||||
|
// Try to load the build options in case they didn't click TEST.
|
||||||
|
updateBuildOptions(self);
|
||||||
// Close dialog on OKAY but not TEST.
|
// Close dialog on OKAY but not TEST.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -533,6 +519,62 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) {
|
||||||
|
ProjectDataT *self = (ProjectDataT *)userData;
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *contentArea;
|
||||||
|
GtkWidget *grid;
|
||||||
|
GtkWidget *widget;
|
||||||
|
TargetT *t;
|
||||||
|
ArchT *a;
|
||||||
|
char *temp;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
grid = gtk_grid_new();
|
||||||
|
gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE);
|
||||||
|
gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
|
||||||
|
gtk_grid_set_column_spacing(GTK_GRID(grid), 15);
|
||||||
|
gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
|
||||||
|
for (i=0; i<arrlen(self->targets); i++) {
|
||||||
|
t = self->targets[i];
|
||||||
|
temp = utilCreateString("%s:", t->longName);
|
||||||
|
widget = gtk_label_new(temp);
|
||||||
|
DEL(temp);
|
||||||
|
gtk_label_set_line_wrap(GTK_LABEL(widget), FALSE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(widget), 1.0);
|
||||||
|
gtk_grid_attach(GTK_GRID(grid), widget, 0, i, 1, 1);
|
||||||
|
for (j=0; j<arrlen(t->archs); j++) {
|
||||||
|
a = t->archs[j];
|
||||||
|
widget = gtk_check_button_new_with_label(a->name);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), a->selected);
|
||||||
|
gtk_grid_attach(GTK_GRID(grid), widget, j + 1, i, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog = gtk_dialog_new_with_buttons(
|
||||||
|
"Targets",
|
||||||
|
GTK_WINDOW(self->windowData.window),
|
||||||
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
"_Cancel",
|
||||||
|
GTK_RESPONSE_CANCEL,
|
||||||
|
"_OK",
|
||||||
|
GTK_RESPONSE_OK,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
contentArea = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||||
|
gtk_container_add(GTK_CONTAINER(contentArea), grid);
|
||||||
|
|
||||||
|
gtk_widget_show_all(dialog);
|
||||||
|
|
||||||
|
result = gtk_dialog_run(dialog);
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) {
|
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -574,6 +616,90 @@ static void saveConfig(ProjectDataT *self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean updateBuildOptions(ProjectDataT *self) {
|
||||||
|
char *test = NULL;
|
||||||
|
char *name = NULL;
|
||||||
|
char *url = NULL;
|
||||||
|
gboolean result = FALSE;
|
||||||
|
FILE *in = NULL;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
char *c = NULL;
|
||||||
|
TargetT *t = NULL;
|
||||||
|
ArchT *a = NULL;
|
||||||
|
|
||||||
|
// This updates the build options file without clobbering one if it already exists and we fail to get a new one.
|
||||||
|
|
||||||
|
test = utilCreateString("%s%cjoeydev%cjoeydev.temp", g_get_user_config_dir(), UTIL_PATH_CHAR, UTIL_PATH_CHAR);
|
||||||
|
name = utilCreateString("%s%cjoeydev%cjoeydev.info", g_get_user_config_dir(), UTIL_PATH_CHAR, UTIL_PATH_CHAR);
|
||||||
|
url = utilCreateString("http://%s:%d/joeydev.info", self->buildHost, self->buildHTTPPort);
|
||||||
|
|
||||||
|
httpDownload(httpWaitForDownloadCallback, test, url);
|
||||||
|
if (httpWaitForDownload() == TRUE) {
|
||||||
|
unlink(name);
|
||||||
|
rename(test, name);
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload current target listing.
|
||||||
|
while (arrlen(self->targets) > 0) {
|
||||||
|
t = self->targets[0];
|
||||||
|
while (arrlen(t->archs) > 0) {
|
||||||
|
a = t->archs[0];
|
||||||
|
DEL(a->name);
|
||||||
|
arrdel(t->archs, 0);
|
||||||
|
}
|
||||||
|
DEL(t->name);
|
||||||
|
DEL(t->longName);
|
||||||
|
arrdel(self->targets, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's a list of targets on the disk, load them.
|
||||||
|
if (utilFileExists(name) == TRUE) {
|
||||||
|
in = fopen(name, "rt");
|
||||||
|
if (in != NULL) {
|
||||||
|
while (getline(&line, &len, in) != -1) {
|
||||||
|
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
||||||
|
// Is this a 'target' line?
|
||||||
|
c = utilGetToken(line, " ", "\"", "\"");
|
||||||
|
utilDequote(c);
|
||||||
|
if (strcasecmp(c, "target") == 0) {
|
||||||
|
t = NEW(TargetT);
|
||||||
|
// Short name.
|
||||||
|
c = utilGetToken(NULL, " ", "\"", "\"");
|
||||||
|
utilDequote(c);
|
||||||
|
t->name = strdup(c);
|
||||||
|
// Long name.
|
||||||
|
c = utilGetToken(NULL, " ", "\"", "\"");
|
||||||
|
utilDequote(c);
|
||||||
|
t->longName = strdup(c);
|
||||||
|
// Architectures.
|
||||||
|
do {
|
||||||
|
c = utilGetToken(NULL, " ", "\"", "\"");
|
||||||
|
if (c != NULL) {
|
||||||
|
utilDequote(c);
|
||||||
|
a = NEW(ArchT);
|
||||||
|
a->name = strdup(c);
|
||||||
|
a->selected = TRUE;
|
||||||
|
arrput(t->archs, a);
|
||||||
|
}
|
||||||
|
} while (c != NULL);
|
||||||
|
arrput(self->targets, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(in);
|
||||||
|
DEL(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEL(url);
|
||||||
|
DEL(name);
|
||||||
|
DEL(test);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData) {
|
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData) {
|
||||||
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
|
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
|
||||||
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
|
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
|
||||||
|
@ -633,6 +759,9 @@ void winProjectCreate(void) {
|
||||||
utilWindowRegister(self);
|
utilWindowRegister(self);
|
||||||
gtk_widget_show_all(self->windowData.window);
|
gtk_widget_show_all(self->windowData.window);
|
||||||
|
|
||||||
|
// Attempt to load build settings from build server.
|
||||||
|
updateBuildOptions(self);
|
||||||
|
|
||||||
//***DEBUG***
|
//***DEBUG***
|
||||||
self->windowData.filename = strdup("/home/scott/code/joeydev/cmake-build-debug/test.joe");
|
self->windowData.filename = strdup("/home/scott/code/joeydev/cmake-build-debug/test.joe");
|
||||||
loadProject(self);
|
loadProject(self);
|
||||||
|
|
58
src/utils.c
58
src/utils.c
|
@ -97,6 +97,18 @@ char *utilDeobfuscateASCII(char *obfuscated) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void utilDequote(char *string) {
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if (string[0] == '"' || string[strlen(string) - 1] == '"') {
|
||||||
|
string[strlen(string) - 1] = 0;
|
||||||
|
for (x=1; x<strlen(string) + 1; x++) {
|
||||||
|
string[x - 1] = string[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted) {
|
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted) {
|
||||||
unsigned char *temp = NULL;
|
unsigned char *temp = NULL;
|
||||||
|
|
||||||
|
@ -206,6 +218,52 @@ gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
char *lead = NULL;
|
||||||
|
char *block = NULL;
|
||||||
|
int iBlock = 0;
|
||||||
|
int iBlockIndex = 0;
|
||||||
|
|
||||||
|
if (input != NULL) {
|
||||||
|
token = input;
|
||||||
|
lead = input;
|
||||||
|
} else {
|
||||||
|
lead = token;
|
||||||
|
if (*token == 0) lead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*token != 0) {
|
||||||
|
|
||||||
|
if (iBlock) {
|
||||||
|
if (closeblock[iBlockIndex] == *token) {
|
||||||
|
iBlock = 0;
|
||||||
|
}
|
||||||
|
token++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((block = strchr(openblock, *token)) != NULL) {
|
||||||
|
iBlock = 1;
|
||||||
|
iBlockIndex = block - openblock;
|
||||||
|
token++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr(delimit, *token) != NULL) {
|
||||||
|
*token = 0;
|
||||||
|
token++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
token++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WindowDataT *utilGetWindowData(GtkWidget *window) {
|
WindowDataT *utilGetWindowData(GtkWidget *window) {
|
||||||
return hmget(_windowList, window);
|
return hmget(_windowList, window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,21 +111,6 @@
|
||||||
<signal name="activate" handler="menuProjectProjectRemove" swapped="no"/>
|
<signal name="activate" handler="menuProjectProjectRemove" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkSeparatorMenuItem">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem" id="menuProjectProjectProperties">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Properties...</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<signal name="activate" handler="menuProjectProjectProperties" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -149,6 +134,15 @@
|
||||||
<signal name="activate" handler="menuProjectBuildSettings" swapped="no"/>
|
<signal name="activate" handler="menuProjectBuildSettings" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuProjectBuildTargets">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Targets...</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<signal name="activate" handler="menuProjectBuildTargets" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
Loading…
Add table
Reference in a new issue