Start of Targets dialog.
This commit is contained in:
parent
6ac1f11291
commit
2469ec2ca2
6 changed files with 261 additions and 51 deletions
|
@ -48,9 +48,11 @@ typedef struct HTTPS {
|
|||
} HTTPT;
|
||||
|
||||
|
||||
HTTPT *httpDownload(HTTPCallback callback, char *filename, char *url);
|
||||
void httpShutdown(void);
|
||||
void httpStartup(void);
|
||||
HTTPT *httpDownload(HTTPCallback callback, char *filename, char *url);
|
||||
void httpShutdown(void);
|
||||
void httpStartup(void);
|
||||
gboolean httpWaitForDownload(void);
|
||||
void httpWaitForDownloadCallback(HTTPT *download);
|
||||
|
||||
|
||||
#endif // HTTP_H
|
||||
|
|
|
@ -40,10 +40,12 @@
|
|||
char *utilCreateString(char *format, ...);
|
||||
char *utilCreateStringVArgs(char *format, va_list args);
|
||||
char *utilDeobfuscateASCII(char *obfuscated);
|
||||
void utilDequote(char *string);
|
||||
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
||||
gboolean utilFileExists(char *filename);
|
||||
gboolean utilFileOpen(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);
|
||||
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
|
||||
gboolean utilMkDirP(const char *dir, const mode_t mode);
|
||||
|
|
29
src/http.c
29
src/http.c
|
@ -20,11 +20,17 @@
|
|||
*/
|
||||
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "EndlessLoop"
|
||||
|
||||
|
||||
#include "http.h"
|
||||
|
||||
|
||||
static CURLM *_curlMulti = NULL;
|
||||
static HTTPT **_activeHTTPs = NULL;
|
||||
static CURLM *_curlMulti = NULL;
|
||||
static HTTPT **_activeHTTPs = NULL;
|
||||
static gboolean _httpTestComplete = FALSE;
|
||||
static gboolean _httpTestSuccess = FALSE;
|
||||
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
|
191
src/project.c
191
src/project.c
|
@ -22,7 +22,6 @@
|
|||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
|
||||
#pragma ide diagnostic ignored "EndlessLoop"
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
@ -53,6 +52,17 @@ enum ProjectSectionTypeE {
|
|||
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 {
|
||||
WindowDataT windowData;
|
||||
GtkWidget *treeProject;
|
||||
|
@ -62,6 +72,7 @@ typedef struct ProjectDataS {
|
|||
int buildSSHPort;
|
||||
char *buildUser;
|
||||
char *buildPassword;
|
||||
TargetT **targets;
|
||||
} ProjectDataT;
|
||||
|
||||
typedef struct SectionDataS {
|
||||
|
@ -84,15 +95,10 @@ static SectionDataT _sectionData[] = {
|
|||
};
|
||||
|
||||
|
||||
static gboolean _httpTestComplete = FALSE;
|
||||
static gboolean _httpTestSuccess = FALSE;
|
||||
|
||||
|
||||
#define BUILD_SETTINGS_RESPONSE_TEST 1
|
||||
|
||||
|
||||
static void addToTree(ProjectDataT *self, char *filename);
|
||||
static void httpTest(HTTPT *download);
|
||||
static void loadConfig(ProjectDataT *self);
|
||||
static void loadProject(ProjectDataT *self);
|
||||
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 menuProjectProjectAdd(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 menuProjectBuildTargets(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
|
||||
static void saveConfig(ProjectDataT *self);
|
||||
static gboolean updateBuildOptions(ProjectDataT *self);
|
||||
EVENT gboolean winProjectClose(GtkWidget *object, 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) {
|
||||
FILE *in = 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) {
|
||||
ProjectDataT *self = (ProjectDataT *)userData;
|
||||
GtkWidget *dialog;
|
||||
|
@ -446,8 +442,6 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
|||
&btnOkay
|
||||
};
|
||||
char temp[6];
|
||||
char *name = NULL;
|
||||
char *url = NULL;
|
||||
int result = 0;
|
||||
SSHT *ssh = 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(btnOkay, FALSE);
|
||||
// Run server connection tests - HTTP.
|
||||
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);
|
||||
_httpTestComplete = FALSE;
|
||||
httpDownload(httpTest, name, url);
|
||||
// This loop seriously breaks CLion's syntax highlighting.
|
||||
while (_httpTestComplete == FALSE) {
|
||||
gtk_main_iteration();
|
||||
}
|
||||
if (_httpTestSuccess == FALSE) {
|
||||
if (updateBuildOptions(self) == FALSE) {
|
||||
error = utilCreateString("Unable to connect to HTTP port.");
|
||||
}
|
||||
DEL(url);
|
||||
DEL(name);
|
||||
// Run server connection tests - SSH.
|
||||
ssh = sshConnect(self->buildHost, self->buildSSHPort, self->buildUser, self->buildPassword);
|
||||
if (ssh) {
|
||||
|
@ -522,6 +506,8 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
|
|||
gtk_widget_set_sensitive(btnTest, TRUE);
|
||||
gtk_widget_set_sensitive(btnOkay, TRUE);
|
||||
} else {
|
||||
// Try to load the build options in case they didn't click TEST.
|
||||
updateBuildOptions(self);
|
||||
// Close dialog on OKAY but not TEST.
|
||||
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) {
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
|
||||
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
|
||||
|
@ -633,6 +759,9 @@ void winProjectCreate(void) {
|
|||
utilWindowRegister(self);
|
||||
gtk_widget_show_all(self->windowData.window);
|
||||
|
||||
// Attempt to load build settings from build server.
|
||||
updateBuildOptions(self);
|
||||
|
||||
//***DEBUG***
|
||||
self->windowData.filename = strdup("/home/scott/code/joeydev/cmake-build-debug/test.joe");
|
||||
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) {
|
||||
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) {
|
||||
return hmget(_windowList, window);
|
||||
}
|
||||
|
|
|
@ -111,21 +111,6 @@
|
|||
<signal name="activate" handler="menuProjectProjectRemove" swapped="no"/>
|
||||
</object>
|
||||
</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>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -149,6 +134,15 @@
|
|||
<signal name="activate" handler="menuProjectBuildSettings" swapped="no"/>
|
||||
</object>
|
||||
</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>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
|
|
Loading…
Add table
Reference in a new issue