Build results starting to be displayed.
This commit is contained in:
parent
2fbeac943b
commit
b3dd4d6a08
13 changed files with 604 additions and 71 deletions
|
@ -56,6 +56,7 @@ set(SOURCE_FILES
|
||||||
src/editor.c
|
src/editor.c
|
||||||
src/compiler.c
|
src/compiler.c
|
||||||
src/messages.c
|
src/messages.c
|
||||||
|
src/results.c
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(include/config.h.in config.h)
|
configure_file(include/config.h.in config.h)
|
||||||
|
|
|
@ -44,7 +44,6 @@ typedef struct HTTPS {
|
||||||
curl_off_t length;
|
curl_off_t length;
|
||||||
curl_off_t progress;
|
curl_off_t progress;
|
||||||
HTTPCallback callback;
|
HTTPCallback callback;
|
||||||
GtkWidget *status;
|
|
||||||
} HTTPT;
|
} HTTPT;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef enum MessageTypesE MessageTypesT;
|
||||||
|
|
||||||
|
|
||||||
void message(MessageTypesT level, char *format, ...);
|
void message(MessageTypesT level, char *format, ...);
|
||||||
|
void messageShow(void);
|
||||||
void messageShutdown(void);
|
void messageShutdown(void);
|
||||||
void messageStartup(void);
|
void messageStartup(void);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,34 @@
|
||||||
#define PROJECT_H
|
#define PROJECT_H
|
||||||
|
|
||||||
|
|
||||||
struct ProjectDataS;
|
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;
|
||||||
|
StringHashT **recipes;
|
||||||
|
char *projectType;
|
||||||
|
char *projectName;
|
||||||
|
char *configName;
|
||||||
|
char *buildHost;
|
||||||
|
int buildHTTPPort;
|
||||||
|
int buildSSHPort;
|
||||||
|
char *buildUser;
|
||||||
|
char *buildPassword;
|
||||||
|
TargetT **targets;
|
||||||
|
void *buildResults; // Managed by results.c
|
||||||
|
GtkWidget *tempWidget; // Used to pass data around dialogs.
|
||||||
|
int tempInteger; // Used during recipe building.
|
||||||
|
} ProjectDataT;
|
||||||
|
|
||||||
|
|
||||||
gboolean projectAddToTree(struct ProjectDataS *self, char *filename);
|
gboolean projectAddToTree(struct ProjectDataS *self, char *filename);
|
||||||
|
|
33
include/results.h
Normal file
33
include/results.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RESULTS_H
|
||||||
|
#define RESULTS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "project.h"
|
||||||
|
|
||||||
|
|
||||||
|
void winBuildResultsCreate(ProjectDataT *project);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // RESULTS_H
|
|
@ -64,6 +64,8 @@ typedef struct ArchiveS {
|
||||||
extern char __utilFilenameBuffer[FILENAME_MAX];
|
extern char __utilFilenameBuffer[FILENAME_MAX];
|
||||||
|
|
||||||
|
|
||||||
|
void utilAddTextToListBox(GtkListBox *list, char *text);
|
||||||
|
void utilClearContainer(GtkContainer *container);
|
||||||
char *utilCreateString(char *format, ...);
|
char *utilCreateString(char *format, ...);
|
||||||
char *utilCreateStringVArgs(char *format, va_list args);
|
char *utilCreateStringVArgs(char *format, va_list args);
|
||||||
ArchiveT *utilDecompress(char *archive, char *outPath, archiveCallback callback, void *userData);
|
ArchiveT *utilDecompress(char *archive, char *outPath, archiveCallback callback, void *userData);
|
||||||
|
|
18
src/http.c
18
src/http.c
|
@ -75,7 +75,13 @@ HTTPT *httpDownload(HTTPCallback callback, char *filename, char *url) {
|
||||||
|
|
||||||
|
|
||||||
void httpShutdown(void) {
|
void httpShutdown(void) {
|
||||||
//***TODO*** Any active sessions?
|
// Free any active sessions.
|
||||||
|
while (arrlen(_activeHTTPs) > 0) {
|
||||||
|
DEL(_activeHTTPs[0]->filename);
|
||||||
|
DEL(_activeHTTPs[0]);
|
||||||
|
arrdel(_activeHTTPs, 0);
|
||||||
|
}
|
||||||
|
//ARRFREE(_activeHTTPs); // This is making Memwatch mad.
|
||||||
|
|
||||||
g_idle_remove_by_data(httpUpdate);
|
g_idle_remove_by_data(httpUpdate);
|
||||||
|
|
||||||
|
@ -112,13 +118,11 @@ gboolean httpUpdate(gpointer userData) {
|
||||||
// Try to get remote file size.
|
// Try to get remote file size.
|
||||||
if (dl->length == 0) {
|
if (dl->length == 0) {
|
||||||
curl_easy_getinfo(eh, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &dl->length);
|
curl_easy_getinfo(eh, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &dl->length);
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
debug("CURL Length %" CURL_FORMAT_CURL_OFF_T "\n", dl->length);
|
debug("CURL Length %" CURL_FORMAT_CURL_OFF_T "\n", dl->length);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (msg->msg == CURLMSG_DONE) {
|
if (msg->msg == CURLMSG_DONE) {
|
||||||
// HTTP Error?
|
// HTTP Error?
|
||||||
curl_easy_getinfo (eh, CURLINFO_RESPONSE_CODE, &httpCode);
|
curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, &httpCode);
|
||||||
// Finished. Tell CURL.
|
// Finished. Tell CURL.
|
||||||
curl_multi_remove_handle(_curlMulti, eh);
|
curl_multi_remove_handle(_curlMulti, eh);
|
||||||
curl_easy_cleanup(eh);
|
curl_easy_cleanup(eh);
|
||||||
|
@ -141,10 +145,8 @@ gboolean httpUpdate(gpointer userData) {
|
||||||
DEL(dl->filename);
|
DEL(dl->filename);
|
||||||
DEL(dl);
|
DEL(dl);
|
||||||
break;
|
break;
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
} else {
|
} else {
|
||||||
debug("CURL: %d\n", code);
|
debug("CURL: %d\n", code);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stillAlive) {
|
if (stillAlive) {
|
||||||
|
@ -157,6 +159,7 @@ gboolean httpUpdate(gpointer userData) {
|
||||||
|
|
||||||
|
|
||||||
gboolean httpWaitForDownload(void) {
|
gboolean httpWaitForDownload(void) {
|
||||||
|
//***TODO*** This whole thing is probably a bad idea.
|
||||||
_httpTestComplete = FALSE;
|
_httpTestComplete = FALSE;
|
||||||
// This loop seriously breaks CLion's syntax highlighting for the rest of the function.
|
// This loop seriously breaks CLion's syntax highlighting for the rest of the function.
|
||||||
while (_httpTestComplete == FALSE) {
|
while (_httpTestComplete == FALSE) {
|
||||||
|
@ -180,9 +183,8 @@ static size_t httpWrite(char *data, size_t num, size_t length, void *userp) {
|
||||||
|
|
||||||
// Update UI.
|
// Update UI.
|
||||||
download->progress += num * length;
|
download->progress += num * length;
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
debug("CURL Progress %" CURL_FORMAT_CURL_OFF_T " Length %" CURL_FORMAT_CURL_OFF_T "\n", download->progress, download->length);
|
debug("CURL Progress %" CURL_FORMAT_CURL_OFF_T " Length %" CURL_FORMAT_CURL_OFF_T "\n", download->progress, download->length);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Did the user request to cancel the transfer?
|
// Did the user request to cancel the transfer?
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
// The message window is a singleton so everything is global.
|
||||||
|
static WindowDataT *_self = NULL;
|
||||||
static GtkWidget *_lstMessages = NULL;
|
static GtkWidget *_lstMessages = NULL;
|
||||||
static char **_pendingMessages = NULL;
|
static char **_pendingMessages = NULL;
|
||||||
static pthread_mutex_t _mtxMessage;
|
static pthread_mutex_t _mtxMessage;
|
||||||
|
@ -95,6 +97,14 @@ static gboolean messageScroll(gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageShow(void) {
|
||||||
|
// Is the window open?
|
||||||
|
if (_lstMessages) {
|
||||||
|
gtk_window_present_with_time(GTK_WINDOW(_self->window), GDK_CURRENT_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void messageShutdown(void) {
|
void messageShutdown(void) {
|
||||||
g_idle_remove_by_data(messagesUpdate);
|
g_idle_remove_by_data(messagesUpdate);
|
||||||
pthread_mutex_destroy(&_mtxMessage);
|
pthread_mutex_destroy(&_mtxMessage);
|
||||||
|
@ -113,7 +123,6 @@ void messageStartup(void) {
|
||||||
|
|
||||||
|
|
||||||
static gboolean messagesUpdate(gpointer userData) {
|
static gboolean messagesUpdate(gpointer userData) {
|
||||||
WindowDataT *self = NULL;
|
|
||||||
char *widgetNames[] = {
|
char *widgetNames[] = {
|
||||||
"winMessages",
|
"winMessages",
|
||||||
"lstMessages",
|
"lstMessages",
|
||||||
|
@ -123,9 +132,6 @@ static gboolean messagesUpdate(gpointer userData) {
|
||||||
NULL,
|
NULL,
|
||||||
&_lstMessages
|
&_lstMessages
|
||||||
};
|
};
|
||||||
GtkWidget *row;
|
|
||||||
GtkWidget *box;
|
|
||||||
GtkWidget *label;
|
|
||||||
char *string = NULL;
|
char *string = NULL;
|
||||||
|
|
||||||
(void)userData;
|
(void)userData;
|
||||||
|
@ -144,31 +150,20 @@ static gboolean messagesUpdate(gpointer userData) {
|
||||||
// Do we need to open the message window?
|
// Do we need to open the message window?
|
||||||
if (!_lstMessages) {
|
if (!_lstMessages) {
|
||||||
// Set up instance data. We only need WindowDataT since this is a "singleton" window.
|
// Set up instance data. We only need WindowDataT since this is a "singleton" window.
|
||||||
self = NEW(WindowDataT);
|
_self = NEW(WindowDataT);
|
||||||
self->closeWindow = winMessagesClose;
|
_self->closeWindow = winMessagesClose;
|
||||||
|
|
||||||
widgets[0] = &self->window;
|
widgets[0] = &_self->window;
|
||||||
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Messages.glade", widgetNames, widgets, self);
|
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Messages.glade", widgetNames, widgets, _self);
|
||||||
|
|
||||||
// Register window.
|
// Register window.
|
||||||
utilWindowRegister(self);
|
utilWindowRegister(_self);
|
||||||
|
|
||||||
// Show window.
|
// Show window.
|
||||||
gtk_widget_show_all(self->window);
|
gtk_widget_show_all(_self->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new row with the message string.
|
utilAddTextToListBox(GTK_LIST_BOX(_lstMessages), string);
|
||||||
row = gtk_list_box_row_new();
|
|
||||||
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
|
|
||||||
gtk_widget_set_hexpand(box, TRUE);
|
|
||||||
label = gtk_label_new(string);
|
|
||||||
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
|
|
||||||
|
|
||||||
// Add new row to the message box.
|
|
||||||
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
|
||||||
gtk_container_add(GTK_CONTAINER(row), box);
|
|
||||||
gtk_list_box_insert(GTK_LIST_BOX(_lstMessages), row, -1);
|
|
||||||
gtk_widget_show_all(_lstMessages);
|
|
||||||
utilForceUpdate();
|
utilForceUpdate();
|
||||||
|
|
||||||
// Scroll to show new row.
|
// Scroll to show new row.
|
||||||
|
@ -182,17 +177,10 @@ static gboolean messagesUpdate(gpointer userData) {
|
||||||
|
|
||||||
|
|
||||||
EVENT void toolMessagesClearClicked(GtkWidget *widget, gpointer userData) {
|
EVENT void toolMessagesClearClicked(GtkWidget *widget, gpointer userData) {
|
||||||
GList *children;
|
|
||||||
GList *iter;
|
|
||||||
|
|
||||||
(void)widget;
|
(void)widget;
|
||||||
(void)userData;
|
(void)userData;
|
||||||
|
|
||||||
children = gtk_container_get_children(GTK_CONTAINER(_lstMessages));
|
utilClearContainer(GTK_CONTAINER(_lstMessages));
|
||||||
for (iter = children; iter != NULL; iter = g_list_next(iter)) {
|
|
||||||
gtk_widget_destroy(GTK_WIDGET(iter->data));
|
|
||||||
}
|
|
||||||
g_list_free(children);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
#include "results.h"
|
||||||
|
|
||||||
|
|
||||||
#define LOCAL_BUILD_RESULTS "build.tar.bz2"
|
#define LOCAL_BUILD_RESULTS "build.tar.bz2"
|
||||||
|
@ -62,34 +63,6 @@ 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 {
|
|
||||||
WindowDataT windowData;
|
|
||||||
GtkWidget *treeProject;
|
|
||||||
StringHashT **recipes;
|
|
||||||
char *projectType;
|
|
||||||
char *projectName;
|
|
||||||
char *configName;
|
|
||||||
char *buildHost;
|
|
||||||
int buildHTTPPort;
|
|
||||||
int buildSSHPort;
|
|
||||||
char *buildUser;
|
|
||||||
char *buildPassword;
|
|
||||||
TargetT **targets;
|
|
||||||
GtkWidget *tempWidget; // Used to pass data around dialogs.
|
|
||||||
int tempInteger; // Used during recipe building.
|
|
||||||
} ProjectDataT;
|
|
||||||
|
|
||||||
typedef struct SectionDataS {
|
typedef struct SectionDataS {
|
||||||
char *name;
|
char *name;
|
||||||
char *extension;
|
char *extension;
|
||||||
|
@ -301,8 +274,8 @@ static void decompressBuild(ArchiveT *archive) {
|
||||||
unlink(temp);
|
unlink(temp);
|
||||||
DEL(temp);
|
DEL(temp);
|
||||||
|
|
||||||
//***TODO*** Process build results.
|
|
||||||
message(MSG_INFO, "Processing build results");
|
message(MSG_INFO, "Processing build results");
|
||||||
|
winBuildResultsCreate(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1057,6 +1030,7 @@ EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData) {
|
||||||
|
|
||||||
// Are there recipes to cook?
|
// Are there recipes to cook?
|
||||||
if (arrlen(self->recipes) > 0) {
|
if (arrlen(self->recipes) > 0) {
|
||||||
|
messageShow();
|
||||||
self->tempInteger = -1; // Tell cookFinished() we're just starting.
|
self->tempInteger = -1; // Tell cookFinished() we're just starting.
|
||||||
ctx = compilerNewContext(cookFinished, self);
|
ctx = compilerNewContext(cookFinished, self);
|
||||||
cookFinished(&ctx);
|
cookFinished(&ctx);
|
||||||
|
@ -1080,6 +1054,8 @@ EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) {
|
||||||
gboolean archPrinted;
|
gboolean archPrinted;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
|
||||||
|
messageShow();
|
||||||
|
|
||||||
ssh = sshConnect(self->buildHost, self->buildSSHPort, self->buildUser, self->buildPassword);
|
ssh = sshConnect(self->buildHost, self->buildSSHPort, self->buildUser, self->buildPassword);
|
||||||
|
|
||||||
if (!ssh) {
|
if (!ssh) {
|
||||||
|
@ -1425,7 +1401,7 @@ static void sendSFTP(SFTPT *sftp) {
|
||||||
} else {
|
} else {
|
||||||
// Finished!
|
// Finished!
|
||||||
message(MSG_INFO, "Waiting for build to complete");
|
message(MSG_INFO, "Waiting for build to complete");
|
||||||
g_timeout_add_seconds(5, waitForBuild, sftp);
|
g_timeout_add_seconds(2, waitForBuild, sftp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1547,7 +1523,7 @@ void winProjectCreate(void) {
|
||||||
"winProject",
|
"winProject",
|
||||||
"treeProject",
|
"treeProject",
|
||||||
NULL
|
NULL
|
||||||
};
|
};static
|
||||||
GtkWidget **widgets[] = {
|
GtkWidget **widgets[] = {
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
|
|
285
src/results.c
Normal file
285
src/results.c
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "results.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ResultsDataS {
|
||||||
|
WindowDataT windowData;
|
||||||
|
ProjectDataT *project;
|
||||||
|
GtkWidget *gridResults;
|
||||||
|
GtkWidget *notebookResults;
|
||||||
|
GtkWidget *lstDebug;
|
||||||
|
GtkWidget *lstRelease;
|
||||||
|
GtkWidget *lstRaw;
|
||||||
|
int lastSelected;
|
||||||
|
} ResultsDataT;
|
||||||
|
|
||||||
|
|
||||||
|
static ResultsDataT **_resultWindows = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
EVENT void resultClicked(GtkButton *widget, gpointer userData);
|
||||||
|
static void resultShow(gboolean release, int target, int arch, ResultsDataT *self);
|
||||||
|
static void resultsUpdate(ResultsDataT *self);
|
||||||
|
EVENT gboolean winBuildResultsClose(GtkWidget *object, gpointer userData);
|
||||||
|
static void winBuildResultsDelete(gpointer userData);
|
||||||
|
|
||||||
|
|
||||||
|
EVENT void resultClicked(GtkButton *widget, gpointer userData) {
|
||||||
|
const char *name = gtk_widget_get_name(GTK_WIDGET(widget));
|
||||||
|
int t;
|
||||||
|
int a;
|
||||||
|
gboolean r;
|
||||||
|
|
||||||
|
// Extract button info from widget name.
|
||||||
|
r = (name[0] == 'r');
|
||||||
|
t = atoi(&name[1]);
|
||||||
|
a = atoi(strstr(name, "a") + 1);
|
||||||
|
|
||||||
|
resultShow(r, t, a, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void resultShow(gboolean release, int target, int arch, ResultsDataT *self) {
|
||||||
|
FILE *in;
|
||||||
|
char *temp;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
TargetT *t;
|
||||||
|
|
||||||
|
// Do we need to load new results?
|
||||||
|
if (target != self->lastSelected) {
|
||||||
|
|
||||||
|
self->lastSelected = target;
|
||||||
|
|
||||||
|
// Clear existing contents.
|
||||||
|
utilClearContainer(GTK_CONTAINER(self->lstDebug));
|
||||||
|
utilClearContainer(GTK_CONTAINER(self->lstRelease));
|
||||||
|
utilClearContainer(GTK_CONTAINER(self->lstRaw));
|
||||||
|
|
||||||
|
// Load raw results.
|
||||||
|
t = self->project->targets[target];
|
||||||
|
temp = utilCreateString("%sresults%cbuild.%s.%s.%s", self->project->windowData.path, UTIL_PATH_CHAR, t->name, t->archs[arch]->name, release ? "release" : "debug");
|
||||||
|
in = fopen(temp, "rt");
|
||||||
|
if (in) {
|
||||||
|
while (!feof(in)) {
|
||||||
|
utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker.
|
||||||
|
while (getline(&line, &len, in) != -1) {
|
||||||
|
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
||||||
|
utilAddTextToListBox(GTK_LIST_BOX(self->lstRaw), line);
|
||||||
|
//***TODO*** Parse these for the other tabs. And, oops, we need two RAW tabs!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(in);
|
||||||
|
DEL(line);
|
||||||
|
}
|
||||||
|
DEL(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display appropriate tab.
|
||||||
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(self->notebookResults), release ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void resultsUpdate(ResultsDataT *self) {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int x;
|
||||||
|
int gridLine = 0;
|
||||||
|
TargetT *t;
|
||||||
|
GtkWidget *w;
|
||||||
|
char *temp;
|
||||||
|
int firstSystem = -1;
|
||||||
|
gboolean debugFound;
|
||||||
|
gboolean releaseFound;
|
||||||
|
DIR *directory;
|
||||||
|
struct dirent *entry;
|
||||||
|
|
||||||
|
utilClearContainer(GTK_CONTAINER(self->gridResults));
|
||||||
|
|
||||||
|
// Iterate over target data and load results.
|
||||||
|
for (i=0; i<arrlen(self->project->targets); i++) {
|
||||||
|
t = self->project->targets[i];
|
||||||
|
for (j=0; j<arrlen(t->archs); j++) {
|
||||||
|
if (t->archs[j]->selected) {
|
||||||
|
|
||||||
|
if (firstSystem < 0) {
|
||||||
|
firstSystem = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to grid. Name.
|
||||||
|
w = gtk_label_new(t->longName);
|
||||||
|
gtk_label_set_line_wrap(GTK_LABEL(w), FALSE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(w), 1.0);
|
||||||
|
gtk_grid_attach(GTK_GRID(self->gridResults), w, 0, gridLine, 1, 1);
|
||||||
|
|
||||||
|
// Add to grid. Arch.
|
||||||
|
w = gtk_label_new(t->archs[j]->name);
|
||||||
|
gtk_label_set_line_wrap(GTK_LABEL(w), FALSE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(w), 1.0);
|
||||||
|
gtk_grid_attach(GTK_GRID(self->gridResults), w, 1, gridLine, 1, 1);
|
||||||
|
|
||||||
|
// See if we got binaries for debug and release.
|
||||||
|
debugFound = FALSE;
|
||||||
|
releaseFound = FALSE;
|
||||||
|
|
||||||
|
// This for loop is an ugly way to check both debug and release without making a function for the enclosed code.
|
||||||
|
for (x=0; x<2; x++) {
|
||||||
|
temp = utilCreateString("%sresults%c%s-%s%c%s", self->project->windowData.path, UTIL_PATH_CHAR, t->name, t->archs[j]->name, UTIL_PATH_CHAR, x == 0 ? "debug" : "release");
|
||||||
|
directory = opendir(temp);
|
||||||
|
DEL(temp);
|
||||||
|
if (directory) {
|
||||||
|
// Anything in here that's not a directory is a binary.
|
||||||
|
while ((entry = readdir(directory))) {
|
||||||
|
if (entry->d_type == DT_REG) {
|
||||||
|
if (x == 0) {
|
||||||
|
debugFound = TRUE;
|
||||||
|
} else {
|
||||||
|
releaseFound = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add debug button.
|
||||||
|
w = gtk_button_new_from_icon_name(debugFound ? "mail-mark-notjunk" : "mail-mark-junk", GTK_ICON_SIZE_BUTTON);
|
||||||
|
temp = utilCreateString("d%da%d", i, j); // We store data about this button in its name.
|
||||||
|
gtk_widget_set_name(w, temp);
|
||||||
|
DEL(temp);
|
||||||
|
gtk_grid_attach(GTK_GRID(self->gridResults), w, 2, gridLine, 1, 1);
|
||||||
|
g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(resultClicked), self);
|
||||||
|
|
||||||
|
// Add release button.
|
||||||
|
w = gtk_button_new_from_icon_name(releaseFound ? "mail-mark-notjunk" : "mail-mark-junk", GTK_ICON_SIZE_BUTTON);
|
||||||
|
temp = utilCreateString("r%da%d", i, j); // We store data about this button in its name.
|
||||||
|
gtk_widget_set_name(w, temp);
|
||||||
|
DEL(temp);
|
||||||
|
gtk_grid_attach(GTK_GRID(self->gridResults), w, 3, gridLine, 1, 1);
|
||||||
|
g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(resultClicked), self);
|
||||||
|
|
||||||
|
// Next result!
|
||||||
|
gridLine++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did we load anything?
|
||||||
|
if (gridLine > 0) {
|
||||||
|
resultShow(FALSE, firstSystem, 0, self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EVENT gboolean winBuildResultsClose(GtkWidget *object, gpointer userData) {
|
||||||
|
// userData is not reliable due to util indirectly calling us.
|
||||||
|
WindowDataT *self = (WindowDataT *)utilGetWindowData(object);
|
||||||
|
|
||||||
|
(void)userData;
|
||||||
|
|
||||||
|
winBuildResultsDelete(self);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void winBuildResultsCreate(ProjectDataT *project) {
|
||||||
|
int i;
|
||||||
|
ResultsDataT *self;
|
||||||
|
char *widgetNames[] = {
|
||||||
|
"winBuildResults",
|
||||||
|
"gridBuildResults",
|
||||||
|
"lstBuildMessagesDebug",
|
||||||
|
"lstBuildMessagesRelease",
|
||||||
|
"lstBuildMessagesRaw",
|
||||||
|
"notebookResults",
|
||||||
|
NULL
|
||||||
|
};static
|
||||||
|
GtkWidget **widgets[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Is there already a results window open for this project?
|
||||||
|
for (i=0; i<arrlen(_resultWindows); i++) {
|
||||||
|
if (_resultWindows[i]->project == project) {
|
||||||
|
// Focus the existing window.
|
||||||
|
gtk_window_present_with_time(GTK_WINDOW(_resultWindows[i]->windowData.window), GDK_CURRENT_TIME);
|
||||||
|
resultsUpdate(_resultWindows[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new window and associate it with the project.
|
||||||
|
self = NEW(ResultsDataT);
|
||||||
|
self->windowData.closeWindow = winBuildResultsClose;
|
||||||
|
self->project = project;
|
||||||
|
self->lastSelected = -1;
|
||||||
|
project->buildResults = self;
|
||||||
|
|
||||||
|
// Load widgets from XML.
|
||||||
|
widgets[0] = &self->windowData.window;
|
||||||
|
widgets[1] = &self->gridResults;
|
||||||
|
widgets[2] = &self->lstDebug;
|
||||||
|
widgets[3] = &self->lstRelease;
|
||||||
|
widgets[4] = &self->lstRaw;
|
||||||
|
widgets[5] = &self->notebookResults;
|
||||||
|
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/BuildResults.glade", widgetNames, widgets, self);
|
||||||
|
|
||||||
|
// Register window.
|
||||||
|
utilWindowRegister(self);
|
||||||
|
|
||||||
|
// Draw contents.
|
||||||
|
resultsUpdate(self);
|
||||||
|
|
||||||
|
// Show window.
|
||||||
|
gtk_widget_show_all(self->windowData.window);
|
||||||
|
|
||||||
|
// Remember window.
|
||||||
|
arrput(_resultWindows, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void winBuildResultsDelete(gpointer userData) {
|
||||||
|
ResultsDataT *self = (ResultsDataT *)userData;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Remove from open results window list.
|
||||||
|
for (i=0; i<arrlen(_resultWindows); i++) {
|
||||||
|
if (_resultWindows[i] == self) {
|
||||||
|
arrdel(_resultWindows, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
utilWindowUnRegister(userData);
|
||||||
|
|
||||||
|
DEL(userData);
|
||||||
|
}
|
31
src/utils.c
31
src/utils.c
|
@ -50,6 +50,37 @@ char __utilFilenameBuffer[FILENAME_MAX];
|
||||||
gboolean utilDecompressUpdate(gpointer userData); // Not static
|
gboolean utilDecompressUpdate(gpointer userData); // Not static
|
||||||
|
|
||||||
|
|
||||||
|
void utilAddTextToListBox(GtkListBox *list, char *text) {
|
||||||
|
GtkWidget *row;
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *label;
|
||||||
|
|
||||||
|
row = gtk_list_box_row_new();
|
||||||
|
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
|
||||||
|
gtk_widget_set_hexpand(box, TRUE);
|
||||||
|
label = gtk_label_new(text);
|
||||||
|
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
|
||||||
|
|
||||||
|
// Add new row to the message box.
|
||||||
|
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
||||||
|
gtk_container_add(GTK_CONTAINER(row), box);
|
||||||
|
gtk_list_box_insert(GTK_LIST_BOX(list), row, -1);
|
||||||
|
gtk_widget_show_all(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void utilClearContainer(GtkContainer *container) {
|
||||||
|
GList *children;
|
||||||
|
GList *iter;
|
||||||
|
|
||||||
|
children = gtk_container_get_children(GTK_CONTAINER(container));
|
||||||
|
for (iter = children; iter != NULL; iter = g_list_next(iter)) {
|
||||||
|
gtk_widget_destroy(GTK_WIDGET(iter->data));
|
||||||
|
}
|
||||||
|
g_list_free(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *utilCreateString(char *format, ...) {
|
char *utilCreateString(char *format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
char *string;
|
char *string;
|
||||||
|
|
187
ui/BuildResults.glade
Normal file
187
ui/BuildResults.glade
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.40.0 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkWindow" id="winBuildResults">
|
||||||
|
<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="margin-bottom">10</property>
|
||||||
|
<property name="title" translatable="yes">Build Results</property>
|
||||||
|
<property name="default-width">800</property>
|
||||||
|
<property name="icon-name">task-due</property>
|
||||||
|
<signal name="destroy" handler="winBuildResultsClose" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="spacing">10</property>
|
||||||
|
<child>
|
||||||
|
<!-- n-columns=4 n-rows=1 -->
|
||||||
|
<object class="GtkGrid" id="gridBuildResults">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="row-spacing">10</property>
|
||||||
|
<property name="column-spacing">10</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">System</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Arch</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Debug</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">2</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Release</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">3</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkNotebook" id="notebookResults">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="shadow-type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="lstBuildMessagesDebug">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="tab">
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Debug</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="tab-fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="shadow-type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="lstBuildMessagesRelease">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child type="tab">
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Release</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
<property name="tab-fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="shadow-type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="lstBuildMessagesRaw">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child type="tab">
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Raw</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">2</property>
|
||||||
|
<property name="tab-fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
|
@ -9,6 +9,7 @@
|
||||||
<file compressed="true" preprocess="xml-stripblanks">Editor.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Editor.glade</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">Vector.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Vector.glade</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">Messages.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Messages.glade</file>
|
||||||
|
<file compressed="true" preprocess="xml-stripblanks">BuildResults.glade</file>
|
||||||
<file>Logo.png</file>
|
<file>Logo.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/com/kangaroopunch/joeydev/icons/32x32/actions">
|
<gresource prefix="/com/kangaroopunch/joeydev/icons/32x32/actions">
|
||||||
|
|
Loading…
Add table
Reference in a new issue