Open/Save/SaveAs working.
This commit is contained in:
parent
db4c7a3204
commit
116d469f5c
6 changed files with 327 additions and 25 deletions
|
@ -27,6 +27,9 @@
|
|||
#include "common.h"
|
||||
|
||||
|
||||
char *utilCreateString(char *format, ...);
|
||||
char *utilCreateStringVArgs(char *format, va_list args);
|
||||
gboolean utilFileExists(char *filename);
|
||||
GdkPixbuf *utilGetPixbufFromMemory(char *data, unsigned int len);
|
||||
WindowDataT *utilGetWindowData(GtkWidget *window);
|
||||
gboolean utilGetWidgetsFromMemory(char *name[], GtkWidget **widgets[], char *data, unsigned int len, gpointer userData);
|
||||
|
|
|
@ -40,7 +40,6 @@ enum ParserKeywordE {
|
|||
PARSE_PALETTE,
|
||||
PARSE_PLOT,
|
||||
PARSE_RECTANGLE,
|
||||
PARSE_RESET,
|
||||
PARSE_RETURN,
|
||||
// After this are keywords for things that aren't commands but still need to emit bytecode.
|
||||
PARSE_MATH,
|
||||
|
|
42
src/utils.c
42
src/utils.c
|
@ -32,6 +32,48 @@ typedef struct WindowListS {
|
|||
static WindowListT *_windowList = NULL;
|
||||
|
||||
|
||||
char *utilCreateString(char *format, ...) {
|
||||
va_list args;
|
||||
char *string;
|
||||
|
||||
va_start(args, format);
|
||||
string = utilCreateStringVArgs(format, args);
|
||||
va_end(args);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
__attribute__((__format__(__printf__, 1, 0)))
|
||||
char *utilCreateStringVArgs(char *format, va_list args) {
|
||||
va_list argsCopy;
|
||||
int32_t size = 0;
|
||||
char *buffer = NULL;
|
||||
|
||||
va_copy(argsCopy, args);
|
||||
size = vsnprintf(NULL, 0, format, argsCopy) + 1;
|
||||
va_end(argsCopy);
|
||||
buffer = calloc(1, (size_t)size);
|
||||
if (buffer) {
|
||||
vsnprintf(buffer, (size_t)size, format, args);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
gboolean utilFileExists(char *filename) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
|
||||
if (f) {
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
GdkPixbuf *utilGetPixbufFromMemory(char *data, unsigned int len) {
|
||||
GdkPixbufLoader *loader;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
|
|
@ -318,7 +318,6 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
|
|||
{ "PALETTE", PARSE_PALETTE },
|
||||
{ "PLOT", PARSE_PLOT },
|
||||
{ "RECTANGLE", PARSE_RECTANGLE },
|
||||
{ "RESET", PARSE_RESET },
|
||||
{ "RETURN", PARSE_RETURN },
|
||||
{ NULL, PARSE_NONE }
|
||||
};
|
||||
|
@ -657,11 +656,6 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
|
|||
lineOkay = TRUE;
|
||||
break;
|
||||
|
||||
case PARSE_RESET:
|
||||
outputByte(bytecode, PARSE_RESET);
|
||||
lineOkay = TRUE;
|
||||
break;
|
||||
|
||||
case PARSE_RETURN:
|
||||
// Return
|
||||
outputByte(bytecode, PARSE_RETURN);
|
||||
|
|
291
src/vector.c
291
src/vector.c
|
@ -37,6 +37,8 @@
|
|||
#include "vecparse.h"
|
||||
|
||||
|
||||
#define VICTOR_VERSION "1.00"
|
||||
|
||||
#define SSM(m, w, l) scintilla_send_message(self->sci, m, w, l)
|
||||
#define MARGIN_SCRIPT_FOLD_INDEX 1
|
||||
#define MARKER_ERROR_ARROW 0
|
||||
|
@ -50,6 +52,7 @@ typedef struct VectorDataS {
|
|||
GtkWidget *drawVectorImage;
|
||||
GtkWidget *boxVectorForEditor;
|
||||
GtkWidget *editor;
|
||||
GtkWidget *fileVectorTraceImage;
|
||||
ScintillaObject *sci;
|
||||
void *pLexer;
|
||||
int id;
|
||||
|
@ -60,6 +63,9 @@ typedef struct VectorDataS {
|
|||
jlContextT *jlc;
|
||||
double traceImagePercent;
|
||||
float *variables;
|
||||
char *filename;
|
||||
char *title;
|
||||
char *tracename;
|
||||
} VectorDataT;
|
||||
|
||||
|
||||
|
@ -72,9 +78,20 @@ EVENT void drawVectorImageClick(GtkWidget *object, GdkEventButton *event, g
|
|||
EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotification *notifyData, gpointer userData);
|
||||
EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData);
|
||||
static int getWord(VecByteCodeT *bytecode, int *index);
|
||||
static void loadTraceImage(VectorDataT *self, char *filename);
|
||||
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorEditCut(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorEditDelete(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorEditPaste(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorFileClose(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorFileNew(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorFileSave(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorFileSaveAs(GtkWidget *object, gpointer userData);
|
||||
EVENT void menuVectorHelpVector(GtkWidget *object, gpointer userData);
|
||||
static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self);
|
||||
EVENT void scaleVectorTraceImageValueChanged(GtkWidget *object, gpointer userData);
|
||||
static void setDirty(VectorDataT *self, gboolean dirty);
|
||||
static float variable(VectorDataT *self, unsigned char byte);
|
||||
static int word(VectorDataT *self, unsigned short word);
|
||||
EVENT gboolean winVectorClose(GtkWidget *object, gpointer userData);
|
||||
|
@ -212,7 +229,7 @@ EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotifi
|
|||
// Release code.
|
||||
DEL(code);
|
||||
// Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable.
|
||||
self->windowData.isDirty = TRUE;
|
||||
setDirty(self, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -240,8 +257,19 @@ static int getWord(VecByteCodeT *bytecode, int *index) {
|
|||
|
||||
|
||||
EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
char *filename;
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
char *temp = NULL;
|
||||
|
||||
printf("fileVectorTraceImageFileSet fired\n");
|
||||
temp = (char *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(object));
|
||||
loadTraceImage(self, temp);
|
||||
DEL(temp);
|
||||
|
||||
setDirty(self, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void loadTraceImage(VectorDataT *self, char *filename) {
|
||||
int x;
|
||||
int y;
|
||||
int n;
|
||||
|
@ -251,9 +279,11 @@ EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
|
|||
cairo_surface_t *temp;
|
||||
cairo_t *cr;
|
||||
|
||||
filename = (char *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(object));
|
||||
image = stbi_load(filename, &x, &y, &n, 4); // Cairo is always 32 bit even with no alpha. Derp.
|
||||
DEL(filename);
|
||||
if (self->tracename != NULL) DEL(self->tracename);
|
||||
self->tracename = strdup(filename);
|
||||
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->fileVectorTraceImage), filename);
|
||||
|
||||
image = stbi_load(self->tracename, &x, &y, &n, 4); // Cairo is always 32 bit even with no alpha. Derp.
|
||||
|
||||
if (image != NULL) {
|
||||
// Create Cairo surface the same size as the loaded image.
|
||||
|
@ -296,6 +326,26 @@ EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
|
|||
}
|
||||
|
||||
|
||||
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorEditCut(GtkWidget *object, gpointer userData) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorEditDelete(GtkWidget *object, gpointer userData) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorEditPaste(GtkWidget *object, gpointer userData) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorFileClose(GtkWidget *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
|
||||
|
@ -305,6 +355,183 @@ EVENT void menuVectorFileClose(GtkWidget *object, gpointer userData) {
|
|||
}
|
||||
|
||||
|
||||
EVENT void menuVectorFileNew(GtkWidget *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
|
||||
(void)object;
|
||||
|
||||
if (self->windowData.isDirty == TRUE) {
|
||||
if (utilQuestionDialog(self->windowData.window, "New", "You have unsaved changes. Start new?")) {
|
||||
// Clear editor.
|
||||
SSM(SCI_CLEARALL, 0, 0);
|
||||
// Clear error markers.
|
||||
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0);
|
||||
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0);
|
||||
// Reset JoeyLib drawing state.
|
||||
jlPaletteDefault(self->jlc);
|
||||
jlDrawColorSet(self->jlc, 0);
|
||||
jlDrawClear(self->jlc);
|
||||
jlDrawColorSet(self->jlc, 15);
|
||||
// Destroy trace image, if any.
|
||||
if (self->trace != NULL) {
|
||||
cairo_surface_destroy(self->trace);
|
||||
self->trace = NULL;
|
||||
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(self->fileVectorTraceImage));
|
||||
}
|
||||
// Clear any filename.
|
||||
if (self->filename != NULL) DEL(self->filename);
|
||||
// Refresh widget.
|
||||
gtk_widget_queue_draw(self->drawVectorImage);
|
||||
// Mark clean.
|
||||
setDirty(self, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter;
|
||||
FILE *in;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
size_t count = 0;
|
||||
|
||||
if (self->windowData.isDirty) {
|
||||
if (!utilQuestionDialog(self->windowData.window, "Open", "You have unsaved changes. Open different file?")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new("Open",
|
||||
GTK_WINDOW(self->windowData.window),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Open", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
filter = gtk_file_filter_new();
|
||||
gtk_file_filter_add_pattern(filter, "*.vic");
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
|
||||
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
if (self->filename != NULL) DEL(self->filename);
|
||||
self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
|
||||
// Use our New code to reset the editor state before we load.
|
||||
setDirty(self, FALSE);
|
||||
menuVectorFileNew(object, userData);
|
||||
|
||||
in = fopen(self->filename, "rt");
|
||||
if (in != NULL) {
|
||||
while (getline(&line, &len, in) != -1) {
|
||||
switch (count) {
|
||||
case 0: // Version Number
|
||||
break;
|
||||
|
||||
case 1: // Trace image name
|
||||
line[strlen(line) - 1] = 0;
|
||||
if (utilFileExists(line)) {
|
||||
loadTraceImage(self, line);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Separator line
|
||||
break;
|
||||
|
||||
default: // Code for editor
|
||||
SSM(SCI_ADDTEXT, strlen(line), (sptr_t)line);
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
fclose(in);
|
||||
if (line != NULL) DEL(line);
|
||||
setDirty(self, FALSE); // Do again - loading text marks us dirty.
|
||||
} else {
|
||||
//***TODO*** Something bad happened.
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorFileSave(GtkWidget *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
int length = SSM(SCI_GETLENGTH, 0, 0);
|
||||
FILE *out = NULL;
|
||||
char *code = NULL;
|
||||
|
||||
// Do we need to save?
|
||||
if (self->windowData.isDirty == TRUE) {
|
||||
|
||||
// Do we have a filename? If not, kick 'em to SaveAs.
|
||||
if (self->filename == NULL) {
|
||||
menuVectorFileSaveAs(object, userData);
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate space to fetch code from editor.
|
||||
code = (char *)malloc(length + 1);
|
||||
if (!code) {
|
||||
//***TODO*** Something bad happened.
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch code.
|
||||
SSM(SCI_GETTEXT, length, (sptr_t)code);
|
||||
|
||||
out = fopen(self->filename, "wt");
|
||||
if (out != NULL) {
|
||||
// Save!
|
||||
fprintf(out, "%s\n", VICTOR_VERSION);
|
||||
fprintf(out, "%s\n", (self->tracename != NULL ? self->tracename : ""));
|
||||
fprintf(out, "------------------------------------------------------------------------------\n");
|
||||
fprintf(out, "%s\n", code);
|
||||
fclose(out);
|
||||
// Release code.
|
||||
DEL(code);
|
||||
// We're clean now.
|
||||
setDirty(self, FALSE);
|
||||
} else {
|
||||
// Release code.
|
||||
DEL(code);
|
||||
|
||||
//***TODO*** Something bad happened.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorFileSaveAs(GtkWidget *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new("Save As",
|
||||
GTK_WINDOW(self->windowData.window),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Save", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
if (self->filename != NULL) DEL(self->filename);
|
||||
self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
menuVectorFileSave(object, self);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
|
||||
EVENT void menuVectorHelpVector(GtkWidget *object, gpointer userData) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
||||
int x1;
|
||||
int y1;
|
||||
|
@ -324,6 +551,12 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
|
||||
self->variables = NULL;
|
||||
|
||||
// Reset JoeyLib draw state.
|
||||
jlPaletteDefault(self->jlc);
|
||||
jlDrawColorSet(self->jlc, 0);
|
||||
jlDrawClear(self->jlc);
|
||||
jlDrawColorSet(self->jlc, 15);
|
||||
|
||||
while (index < bytecode->length) {
|
||||
switch (bytecode->bytes[index++]) {
|
||||
|
||||
|
@ -575,14 +808,6 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
jlDrawBoxFilled(self->jlc, x1, y1, x2, y2);
|
||||
break;
|
||||
|
||||
case PARSE_RESET:
|
||||
printf("Reset\n");
|
||||
jlPaletteDefault(self->jlc);
|
||||
jlDrawColorSet(self->jlc, 0);
|
||||
jlDrawClear(self->jlc);
|
||||
jlDrawColorSet(self->jlc, 15);
|
||||
break;
|
||||
|
||||
case PARSE_RETURN:
|
||||
index = arrpop(stack);
|
||||
printf("Return %d\n", index);
|
||||
|
@ -618,6 +843,28 @@ EVENT void scaleVectorTraceImageValueChanged(GtkWidget *object, gpointer userDat
|
|||
}
|
||||
|
||||
|
||||
static void setDirty(VectorDataT *self, gboolean dirty) {
|
||||
char *title;
|
||||
|
||||
self->windowData.isDirty = dirty;
|
||||
if (dirty) {
|
||||
if (self->filename) {
|
||||
title = utilCreateString("%s - %s *", self->title, self->filename);
|
||||
} else {
|
||||
title = utilCreateString("%s - (no name) *", self->title);
|
||||
}
|
||||
} else {
|
||||
if (self->filename) {
|
||||
title = utilCreateString("%s - %s", self->title, self->filename);
|
||||
} else {
|
||||
title = utilCreateString("%s", self->title);
|
||||
}
|
||||
}
|
||||
gtk_window_set_title(GTK_WINDOW(self->windowData.window), title);
|
||||
DEL(title);
|
||||
}
|
||||
|
||||
|
||||
static float variable(VectorDataT *self, unsigned char byte) {
|
||||
int value;
|
||||
|
||||
|
@ -676,8 +923,8 @@ EVENT gboolean winVectorClose(GtkWidget *object, gpointer userData) {
|
|||
|
||||
void winVectorCreate(void) {
|
||||
VectorDataT *self;
|
||||
char *widgetNames[] = { "winVector", "boxVectorForEditor", "drawVectorImage", NULL };
|
||||
GtkWidget **widgets[] = { NULL, NULL, NULL };
|
||||
char *widgetNames[] = { "winVector", "boxVectorForEditor", "drawVectorImage", "fileVectorTraceImage", NULL };
|
||||
GtkWidget **widgets[] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
// Set up instance data.
|
||||
self = NEW(VectorDataT);
|
||||
|
@ -687,8 +934,12 @@ void winVectorCreate(void) {
|
|||
widgets[0] = &self->windowData.window;
|
||||
widgets[1] = &self->boxVectorForEditor;
|
||||
widgets[2] = &self->drawVectorImage;
|
||||
widgets[3] = &self->fileVectorTraceImage;
|
||||
utilGetWidgetsFromMemory(widgetNames, widgets, EMBEDDED(___ui_Vector_glade), self);
|
||||
|
||||
// Grab title.
|
||||
self->title = strdup(gtk_window_get_title(GTK_WINDOW(self->windowData.window)));
|
||||
|
||||
// Add missing event to drawVectorImage
|
||||
gtk_widget_add_events(self->drawVectorImage, GDK_BUTTON_PRESS_MASK);
|
||||
g_signal_connect(G_OBJECT(self->drawVectorImage), "button-press-event", G_CALLBACK(drawVectorImageClick), self);
|
||||
|
@ -748,8 +999,8 @@ void winVectorCreate(void) {
|
|||
SSM(SCI_MARKERSETBACK, MARKER_ERROR_HIGHLIGHT, 127 | (0 << 8) | (0 << 16)); // RGB
|
||||
|
||||
// Debug
|
||||
/*
|
||||
SSM(SCI_INSERTTEXT, 0, (sptr_t)
|
||||
"reset\n\n"
|
||||
"goto red\n\n"
|
||||
"yellow:\n"
|
||||
"\t%yellow = %red\n"
|
||||
|
@ -767,6 +1018,7 @@ void winVectorCreate(void) {
|
|||
"\tgoto yellow\n\n"
|
||||
"end:\n"
|
||||
);
|
||||
*/
|
||||
|
||||
// Connect editor to our code.
|
||||
g_signal_connect(G_OBJECT(self->editor), "sci-notify", G_CALLBACK(editorVectorNotify), self);
|
||||
|
@ -797,7 +1049,10 @@ static void winVectorDelete(gpointer userData) {
|
|||
cairo_surface_destroy(self->surface);
|
||||
cairo_surface_destroy(self->scaled);
|
||||
cairo_surface_destroy(self->target);
|
||||
if (self->trace != NULL) cairo_surface_destroy(self->trace);
|
||||
if (self->trace != NULL) cairo_surface_destroy(self->trace);
|
||||
if (self->filename != NULL) DEL(self->filename);
|
||||
if (self->title != NULL) DEL(self->title);
|
||||
if (self->tracename != NULL) DEL(self->tracename);
|
||||
|
||||
DEL(self);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorFileNew" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -66,6 +67,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Open...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorFileOpen" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -74,6 +76,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorFileSave" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -82,6 +85,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Save _As...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorFileSaveAs" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -119,6 +123,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Cut</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorEditCut" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -127,6 +132,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorEditCopy" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -135,6 +141,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Paste</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorEditPaste" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -143,6 +150,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorEditDelete" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -165,6 +173,7 @@
|
|||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Vector Editor...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorHelpVector" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
Loading…
Add table
Reference in a new issue