Handle Fluid project settings better (#556)

Fix allocation bug in Fl_String
This commit is contained in:
Matthias Melcher 2022-11-26 01:35:50 +01:00 committed by GitHub
parent c1a7c4af04
commit 6e5c472cf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 295 additions and 253 deletions

View File

@ -267,7 +267,7 @@ void CodeEditor::textsize(Fl_Fontsize s) {
A widget derived from CodeEditor with highlighting for code blocks.
This widget is used by the SourceView system to show the design's
source an header code. The secondary highlighting show the text
source and header code. The secondary highlighting show the text
part that corresponds to the selected widget(s).
*/

View File

@ -288,12 +288,12 @@ const char* ExternalCodeEditor::create_tmpdir() {
\return NULL if can't, posts dialog explaining why.
*/
const char* ExternalCodeEditor::tmp_filename() {
static char path[512];
static char path[FL_PATH_MAX+1];
const char *tmpdir = create_tmpdir();
if ( !tmpdir ) return 0;
const char *ext = code_file_name; // e.g. ".cxx"
snprintf(path, sizeof(path), "%s/%p%s", tmpdir, (void*)this, ext);
path[sizeof(path)-1] = 0;
const char *ext = P.code_file_name; // e.g. ".cxx"
snprintf(path, FL_PATH_MAX, "%s/%p%s", tmpdir, (void*)this, ext);
path[FL_PATH_MAX] = 0;
return path;
}

View File

@ -22,6 +22,7 @@
#include <FL/fl_string_functions.h> // fl_strdup()
#include "ExternalCodeEditor_WIN32.h"
#include "fluid.h"
#include <stdio.h> // snprintf()
#include <stdlib.h>
@ -358,8 +359,7 @@ const char* ExternalCodeEditor::tmp_filename() {
static char path[512];
const char *tmpdir = create_tmpdir();
if ( !tmpdir ) return 0;
extern const char *code_file_name; // fluid's global
const char *ext = code_file_name; // e.g. ".cxx"
const char *ext = P.code_file_name; // e.g. ".cxx"
_snprintf(path, sizeof(path), "%s\\%p%s", tmpdir, (void*)this, ext);
path[sizeof(path)-1] = 0;
return path;

View File

@ -24,6 +24,7 @@
#include "file.h"
#include "code.h"
#include "widget_browser.h"
#include "undo.h"
#include <FL/Fl.H>
#include <FL/Fl_Group.H>
@ -79,6 +80,8 @@ void group_cb(Fl_Widget *, void *) {
fl_message("Please select widgets to group");
return;
}
undo_checkpoint();
undo_suspend();
Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
force_parent = 1;
Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make(kAddAsLastChild));
@ -93,6 +96,8 @@ void group_cb(Fl_Widget *, void *) {
}
fix_group_size(n);
widget_browser->rebuild();
undo_resume();
set_modflag(1);
}
void ungroup_cb(Fl_Widget *, void *) {
@ -111,6 +116,8 @@ void ungroup_cb(Fl_Widget *, void *) {
return;
}
}
undo_checkpoint();
undo_suspend();
for (n = q->next; n && n->level > q->level;) {
Fl_Type *nxt = n->remove();
n->insert(q);
@ -118,6 +125,8 @@ void ungroup_cb(Fl_Widget *, void *) {
}
delete q;
widget_browser->rebuild();
undo_resume();
set_modflag(1);
}
////////////////////////////////////////////////////////////////

View File

@ -378,10 +378,10 @@ void Fl_Menu_Item_Type::write_item() {
write_comment_inline_c(" ");
write_c(" {");
if (label() && label()[0])
switch (i18n_type) {
switch (P.i18n_type) {
case 1:
// we will call i18n when the menu is instantiated for the first time
write_c("%s(", i18n_static_function);
write_c("%s(", P.i18n_static_function.value());
write_cstring(label());
write_c(")");
break;
@ -394,7 +394,7 @@ void Fl_Menu_Item_Type::write_item() {
write_c("\"\"");
if (((Fl_Button*)o)->shortcut()) {
int s = ((Fl_Button*)o)->shortcut();
if (use_FL_COMMAND && (s & (FL_CTRL|FL_META))) {
if (P.use_FL_COMMAND && (s & (FL_CTRL|FL_META))) {
write_c(", FL_COMMAND|0x%x, ", s & ~(FL_CTRL|FL_META));
} else {
write_c(", 0x%x, ", s);
@ -474,15 +474,15 @@ void Fl_Menu_Item_Type::write_code1() {
write_c("%sml->labela = (char*)", indent());
image->write_inline();
write_c(";\n");
if (i18n_type==0) {
if (P.i18n_type==0) {
write_c("%sml->labelb = o->label();\n", indent());
} else if (i18n_type==1) {
} else if (P.i18n_type==1) {
write_c("%sml->labelb = %s(o->label());\n",
indent(), i18n_function);
} else if (i18n_type==2) {
indent(), P.i18n_function.value());
} else if (P.i18n_type==2) {
write_c("%sml->labelb = catgets(%s,%s,i+%d,o->label());\n",
indent(), i18n_file[0] ? i18n_file : "_catalog",
i18n_set, msgnum());
indent(), P.i18n_file[0] ? P.i18n_file.value() : "_catalog",
P.i18n_set.value(), msgnum());
}
write_c("%sml->typea = FL_IMAGE_LABEL;\n", indent());
write_c("%sml->typeb = FL_NORMAL_LABEL;\n", indent());
@ -491,20 +491,20 @@ void Fl_Menu_Item_Type::write_code1() {
image->write_code("o");
}
}
if (i18n_type && label() && label()[0]) {
if (P.i18n_type && label() && label()[0]) {
Fl_Labeltype t = o->labeltype();
if (image) {
// label was already copied a few lines up
} else if ( t==FL_NORMAL_LABEL || t==FL_SHADOW_LABEL
|| t==FL_ENGRAVED_LABEL || t==FL_EMBOSSED_LABEL) {
start_menu_initialiser(menuItemInitialized, mname, i);
if (i18n_type==1) {
if (P.i18n_type==1) {
write_c("%so->label(%s(o->label()));\n",
indent(), i18n_function);
} else if (i18n_type==2) {
indent(), P.i18n_function.value());
} else if (P.i18n_type==2) {
write_c("%so->label(catgets(%s,%s,i+%d,o->label()));\n",
indent(), i18n_file[0] ? i18n_file : "_catalog",
i18n_set, msgnum());
indent(), P.i18n_file[0] ? P.i18n_file.value() : "_catalog",
P.i18n_set.value(), msgnum());
}
}
}

View File

@ -124,6 +124,7 @@ void earlier_cb(Fl_Widget*,void*) {
Fl_Type* g;
for (g = f->prev; g && g->level > f->level; g = g->prev) {/*empty*/}
if (g && g->level == f->level && !g->selected) {
if (!mod) undo_checkpoint();
f->move_before(g);
mod = 1;
}
@ -147,6 +148,7 @@ void later_cb(Fl_Widget*,void*) {
Fl_Type* g;
for (g = f->next; g && g->level > f->level; g = g->next) {/*empty*/}
if (g && g->level == f->level && !g->selected) {
if (!mod) undo_checkpoint();
g->move_before(f);
mod = 1;
}
@ -179,11 +181,6 @@ void delete_all(int selected_only) {
} else f = f->next;
}
if(!selected_only) {
// FIXME: undo/redo uses this function, resetting the following preferences randomly
include_H_from_C=1;
use_FL_COMMAND=0;
utf8_in_src = 0;
avoid_early_includes = 0;
// reset the setting for the external shell command
shell_prefs_get();
shell_settings_write();

View File

@ -2631,18 +2631,18 @@ void Fl_Widget_Type::write_code1() {
}
if (label() && *label()) {
write_c(", ");
switch (i18n_type) {
switch (P.i18n_type) {
case 0 : /* None */
write_cstring(label());
break;
case 1 : /* GNU gettext */
write_c("%s(", i18n_function);
write_c("%s(", P.i18n_function.value());
write_cstring(label());
write_c(")");
break;
case 2 : /* POSIX catgets */
write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
i18n_set, msgnum());
write_c("catgets(%s,%s,%d,", P.i18n_file[0] ? P.i18n_file.value() : "_catalog",
P.i18n_set.value(), msgnum());
write_cstring(label());
write_c(")");
break;
@ -2704,18 +2704,18 @@ void Fl_Widget_Type::write_widget_code() {
if (tooltip() && *tooltip()) {
write_c("%s%s->tooltip(",indent(), var);
switch (i18n_type) {
switch (P.i18n_type) {
case 0 : /* None */
write_cstring(tooltip());
break;
case 1 : /* GNU gettext */
write_c("%s(", i18n_function);
write_c("%s(", P.i18n_function.value());
write_cstring(tooltip());
write_c(")");
break;
case 2 : /* POSIX catgets */
write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
i18n_set, msgnum() + 1);
write_c("catgets(%s,%s,%d,", P.i18n_file[0] ? P.i18n_file.value() : "_catalog",
P.i18n_set.value(), msgnum() + 1);
write_cstring(tooltip());
write_c(")");
break;
@ -2737,7 +2737,7 @@ void Fl_Widget_Type::write_widget_code() {
else if (is_value_input()) shortcut = ((Fl_Value_Input*)o)->shortcut();
else if (is_text_display()) shortcut = ((Fl_Text_Display*)o)->shortcut();
if (shortcut) {
if (use_FL_COMMAND && (shortcut & (FL_CTRL|FL_META))) {
if (P.use_FL_COMMAND && (shortcut & (FL_CTRL|FL_META))) {
write_c("%s%s->shortcut(FL_COMMAND|0x%x);\n", indent(), var, shortcut & ~(FL_CTRL|FL_META));
} else {
write_c("%s%s->shortcut(0x%x);\n", indent(), var, shortcut);

View File

@ -43,11 +43,6 @@
#include <stdlib.h>
#include <stdio.h>
int include_H_from_C = 1;
int use_FL_COMMAND = 0;
int utf8_in_src = 0;
int avoid_early_includes = 0;
extern Fl_Preferences fluid_prefs;
inline int fl_min(int a, int b) { return (a < b ? a : b); }
@ -122,7 +117,7 @@ void default_widget_size_cb(Fl_Round_Button *b, long size) {
void i18n_type_cb(Fl_Choice *c, void *) {
undo_checkpoint();
switch (i18n_type = c->value()) {
switch (P.i18n_type = c->value()) {
case 0 : /* None */
i18n_include_input->hide();
i18n_conditional_input->hide();
@ -133,13 +128,13 @@ void i18n_type_cb(Fl_Choice *c, void *) {
break;
case 1 : /* GNU gettext */
i18n_include_input->value("<libintl.h>");
i18n_include = i18n_include_input->value();
P.i18n_include = i18n_include_input->value();
i18n_conditional_input->value("");
i18n_conditional = i18n_conditional_input->value();
P.i18n_conditional = i18n_conditional_input->value();
i18n_function_input->value("gettext");
i18n_function = i18n_function_input->value();
P.i18n_function = i18n_function_input->value();
i18n_static_function_input->value("gettext_noop");
i18n_static_function = i18n_static_function_input->value();
P.i18n_static_function = i18n_static_function_input->value();
i18n_include_input->show();
i18n_conditional_input->show();
i18n_file_input->hide();
@ -149,13 +144,13 @@ void i18n_type_cb(Fl_Choice *c, void *) {
break;
case 2 : /* POSIX cat */
i18n_include_input->value("<nl_types.h>");
i18n_include = i18n_include_input->value();
P.i18n_include = i18n_include_input->value();
i18n_conditional_input->value("");
i18n_conditional = i18n_conditional_input->value();
P.i18n_conditional = i18n_conditional_input->value();
i18n_file_input->value("");
i18n_file = i18n_file_input->value();
P.i18n_file = i18n_file_input->value();
i18n_set_input->value("1");
i18n_set = i18n_set_input->value();
P.i18n_set = i18n_set_input->value();
i18n_include_input->show();
i18n_conditional_input->show();
i18n_file_input->show();
@ -172,15 +167,15 @@ void i18n_text_cb(Fl_Input *i, void *) {
undo_checkpoint();
if (i == i18n_function_input)
i18n_function = i->value();
P.i18n_function = i->value();
else if (i == i18n_static_function_input)
i18n_static_function = i->value();
P.i18n_static_function = i->value();
else if (i == i18n_file_input)
i18n_file = i->value();
P.i18n_file = i->value();
else if (i == i18n_include_input)
i18n_include = i->value();
P.i18n_include = i->value();
else if (i == i18n_conditional_input)
i18n_conditional = i->value();
P.i18n_conditional = i->value();
set_modflag(1);
}
@ -189,27 +184,27 @@ void i18n_int_cb(Fl_Int_Input *i, void *) {
undo_checkpoint();
if (i == i18n_set_input)
i18n_set = i->value();
P.i18n_set = i->value();
set_modflag(1);
}
void show_project_cb(Fl_Widget *, void *) {
if(project_window==0) make_project_window();
include_H_from_C_button->value(include_H_from_C);
use_FL_COMMAND_button->value(use_FL_COMMAND);
utf8_in_src_button->value(utf8_in_src);
avoid_early_includes_button->value(avoid_early_includes);
header_file_input->value(header_file_name);
code_file_input->value(code_file_name);
i18n_type_chooser->value(i18n_type);
i18n_function_input->value(i18n_function);
i18n_static_function_input->value(i18n_static_function);
i18n_file_input->value(i18n_file);
i18n_set_input->value(i18n_set);
i18n_include_input->value(i18n_include);
i18n_conditional_input->value(i18n_conditional);
switch (i18n_type) {
include_H_from_C_button->value(P.include_H_from_C);
use_FL_COMMAND_button->value(P.use_FL_COMMAND);
utf8_in_src_button->value(P.utf8_in_src);
avoid_early_includes_button->value(P.avoid_early_includes);
header_file_input->value(P.header_file_name);
code_file_input->value(P.code_file_name);
i18n_type_chooser->value(P.i18n_type);
i18n_function_input->value(P.i18n_function);
i18n_static_function_input->value(P.i18n_static_function);
i18n_file_input->value(P.i18n_file);
i18n_set_input->value(P.i18n_set);
i18n_include_input->value(P.i18n_include);
i18n_conditional_input->value(P.i18n_conditional);
switch (P.i18n_type) {
case 0 : /* None */
i18n_include_input->hide();
i18n_conditional_input->hide();
@ -267,41 +262,41 @@ void show_global_settings_cb(Fl_Widget *, void *) {
}
void header_input_cb(Fl_Input* i, void*) {
if (header_file_name && strcmp(header_file_name, i->value()))
if (strcmp(P.header_file_name, i->value()))
set_modflag(1);
header_file_name = i->value();
P.header_file_name = i->value();
}
void code_input_cb(Fl_Input* i, void*) {
if (code_file_name && strcmp(code_file_name, i->value()))
if (strcmp(P.code_file_name, i->value()))
set_modflag(1);
code_file_name = i->value();
P.code_file_name = i->value();
}
void include_H_from_C_button_cb(Fl_Check_Button* b, void*) {
if (include_H_from_C != b->value()) {
if (P.include_H_from_C != b->value()) {
set_modflag(1);
include_H_from_C = b->value();
P.include_H_from_C = b->value();
}
}
void use_FL_COMMAND_button_cb(Fl_Check_Button* b, void*) {
if (use_FL_COMMAND != b->value()) {
if (P.use_FL_COMMAND != b->value()) {
set_modflag(1);
use_FL_COMMAND = b->value();
P.use_FL_COMMAND = b->value();
}
}
void utf8_in_src_cb(Fl_Check_Button *b, void*) {
if (utf8_in_src != b->value()) {
if (P.utf8_in_src != b->value()) {
set_modflag(1);
utf8_in_src = b->value();
P.utf8_in_src = b->value();
}
}
void avoid_early_includes_cb(Fl_Check_Button *b, void*) {
if (avoid_early_includes != b->value()) {
if (P.avoid_early_includes != b->value()) {
set_modflag(1);
avoid_early_includes = b->value();
P.avoid_early_includes = b->value();
}
}

View File

@ -25,11 +25,6 @@
class Fl_Widget_Class_Type;
extern int include_H_from_C;
extern int use_FL_COMMAND;
extern int utf8_in_src;
extern int avoid_early_includes;
extern Fl_Menu_Item window_type_menu[];
extern Fl_Widget_Class_Type *current_widget_class;
void toggle_overlays(Fl_Widget *,void *);

View File

@ -44,7 +44,7 @@ void Shortcut_Button::draw() {
if (value()) draw_box(FL_DOWN_BOX, (Fl_Color)9);
else draw_box(FL_UP_BOX, FL_WHITE);
fl_font(FL_HELVETICA,14); fl_color(FL_FOREGROUND_COLOR);
if (use_FL_COMMAND && (svalue & (FL_CTRL|FL_META))) {
if (P.use_FL_COMMAND && (svalue & (FL_CTRL|FL_META))) {
char buf[1024];
fl_snprintf(buf, 1023, "Command+%s", fl_shortcut_label(svalue&~(FL_CTRL|FL_META)));
fl_draw(buf,x()+6,y(),w(),h(),FL_ALIGN_LEFT);

View File

@ -56,10 +56,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -93,10 +91,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -127,10 +123,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -160,10 +154,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -197,10 +189,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -231,10 +221,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -272,10 +260,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -315,10 +301,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -352,10 +336,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -385,10 +367,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -420,10 +400,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
if (o->next && o->next->level > o->level && !o->next->selected &&
!o->is_menu_button()) {
@ -444,10 +422,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
int center2;
@ -473,10 +449,8 @@ void align_widget_cb(Fl_Widget*, long how)
{
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
int center2;
@ -498,6 +472,8 @@ void align_widget_cb(Fl_Widget*, long how)
}
break;
}
if (changed)
set_modflag(1);
}
@ -509,7 +485,6 @@ void widget_size_cb(Fl_Widget *, long size) {
if (o->selected && o->is_widget()) {
if (!changed) {
changed = 1;
set_modflag(1);
undo_checkpoint();
}
@ -525,4 +500,6 @@ void widget_size_cb(Fl_Widget *, long size) {
if (w->window()) w->window()->redraw();
}
}
if (changed)
set_modflag(1);
}

View File

@ -270,7 +270,7 @@ void write_cstring(const char *s, int length) {
break;
}
// if the UTF-8 option is checked, write unicode characters verbatim
if (utf8_in_src && (c&0x80)) {
if (P.utf8_in_src && (c&0x80)) {
if ((c&0x40)) {
// This is the first character in a utf-8 sequence (0b11......).
// A line break would be ok here. Do not put linebreak in front of
@ -584,47 +584,47 @@ int write_code(const char *s, const char *t) {
fprintf(header_file, "#define %s\n", define_name);
}
if (avoid_early_includes==0) {
if (P.avoid_early_includes==0) {
write_declare("#include <FL/Fl.H>");
}
if (t && include_H_from_C) {
if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) {
if (t && P.include_H_from_C) {
if (P.header_file_name[0] == '.' && strchr(P.header_file_name, '/') == NULL) {
write_c("#include \"%s\"\n", fl_filename_name(t));
} else {
write_c("#include \"%s\"\n", t);
}
}
if (i18n_type && i18n_include[0]) {
int conditional = (i18n_conditional[0]!=0);
if (P.i18n_type && P.i18n_include[0]) {
int conditional = (P.i18n_conditional[0]!=0);
if (conditional) {
write_c("#ifdef %s\n", i18n_conditional);
write_c("#ifdef %s\n", P.i18n_conditional.value());
indentation++;
}
if (i18n_include[0] != '<' &&
i18n_include[0] != '\"')
write_c("#%sinclude \"%s\"\n", indent(), i18n_include);
if (P.i18n_include[0] != '<' &&
P.i18n_include[0] != '\"')
write_c("#%sinclude \"%s\"\n", indent(), P.i18n_include.value());
else
write_c("#%sinclude %s\n", indent(), i18n_include);
if (i18n_type == 2) {
if (i18n_file[0]) write_c("extern nl_catd %s;\n", i18n_file);
else {
write_c("#%sinclude %s\n", indent(), P.i18n_include.value());
if (P.i18n_type == 2) {
if (P.i18n_file[0]) {
write_c("extern nl_catd %s;\n", P.i18n_file.value());
} else {
write_c("// Initialize I18N stuff now for menus...\n");
write_c("#%sinclude <locale.h>\n", indent());
write_c("static char *_locale = setlocale(LC_MESSAGES, \"\");\n");
write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n",
i18n_program);
write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n", P.i18n_program);
}
}
if (conditional) {
write_c("#else\n");
if (i18n_type == 1) {
if (i18n_function[0]) {
write_c("#%sifndef %s\n", indent(), i18n_function);
write_c("#%sdefine %s(text) text\n", indent_plus(1), i18n_function);
if (P.i18n_type == 1) {
if (P.i18n_function[0]) {
write_c("#%sifndef %s\n", indent(), P.i18n_function.value());
write_c("#%sdefine %s(text) text\n", indent_plus(1), P.i18n_function.value());
write_c("#%sendif\n", indent());
}
}
if (i18n_type == 2) {
if (P.i18n_type == 2) {
write_c("#%sifndef catgets\n", indent());
write_c("#%sdefine catgets(catalog, set, msgid, text) text\n", indent_plus(1));
write_c("#%sendif\n", indent());
@ -632,9 +632,9 @@ int write_code(const char *s, const char *t) {
indentation--;
write_c("#endif\n");
}
if (i18n_type == 1 && i18n_static_function[0]) {
write_c("#ifndef %s\n", i18n_static_function);
write_c("#%sdefine %s(text) text\n", indent_plus(1), i18n_static_function);
if (P.i18n_type == 1 && P.i18n_static_function[0]) {
write_c("#ifndef %s\n", P.i18n_static_function.value());
write_c("#%sdefine %s(text) text\n", indent_plus(1), P.i18n_static_function.value());
write_c("#endif\n");
}
}
@ -692,7 +692,7 @@ int write_strings(const char *sfile) {
if (!fp) return 1;
switch (i18n_type) {
switch (P.i18n_type) {
case 0 : /* None, just put static text out */
fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
@ -772,7 +772,7 @@ int write_strings(const char *sfile) {
case 2 : /* POSIX catgets, put a .msg file out */
fprintf(fp, "$ generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
fprintf(fp, "$set %s\n", i18n_set);
fprintf(fp, "$set %s\n", P.i18n_set.value());
fputs("$quote \"\n", fp);
for (i = 1, p = Fl_Type::first; p; p = p->next) {

View File

@ -64,7 +64,7 @@ double read_version;
// BASIC FILE WRITING:
/**
Open teh .fl design file for writing.
Open the .fl design file for writing.
If the filename is NULL, associate stdout instead.
\param[in] s the filename or NULL for stdout
\return 1 if successful. 0 if the operation failed
@ -377,36 +377,36 @@ int write_file(const char *filename, int selected_only) {
if (!open_write(filename)) return 0;
write_string("# data file for the Fltk User Interface Designer (fluid)\n"
"version %.4f",FL_VERSION);
if(!include_H_from_C)
if(!P.include_H_from_C)
write_string("\ndo_not_include_H_from_C");
if(use_FL_COMMAND)
if(P.use_FL_COMMAND)
write_string("\nuse_FL_COMMAND");
if (utf8_in_src)
if (P.utf8_in_src)
write_string("\nutf8_in_src");
if (avoid_early_includes)
if (P.avoid_early_includes)
write_string("\navoid_early_includes");
if (i18n_type) {
write_string("\ni18n_type %d", i18n_type);
write_string("\ni18n_include"); write_word(i18n_include);
write_string("\ni18n_conditional"); write_word(i18n_conditional);
switch (i18n_type) {
if (P.i18n_type) {
write_string("\ni18n_type %d", P.i18n_type);
write_string("\ni18n_include"); write_word(P.i18n_include);
write_string("\ni18n_conditional"); write_word(P.i18n_conditional);
switch (P.i18n_type) {
case 1 : /* GNU gettext */
write_string("\ni18n_function"); write_word(i18n_function);
write_string("\ni18n_static_function"); write_word(i18n_static_function);
write_string("\ni18n_function"); write_word(P.i18n_function);
write_string("\ni18n_static_function"); write_word(P.i18n_static_function);
break;
case 2 : /* POSIX catgets */
if (i18n_file[0]) {
if (P.i18n_file[0]) {
write_string("\ni18n_file");
write_word(i18n_file);
write_word(P.i18n_file);
}
write_string("\ni18n_set"); write_word(i18n_set);
write_string("\ni18n_set"); write_word(P.i18n_set);
break;
}
}
if (!selected_only) {
write_string("\nheader_name"); write_word(header_file_name);
write_string("\ncode_name"); write_word(code_file_name);
write_string("\nheader_name"); write_word(P.header_file_name);
write_string("\ncode_name"); write_word(P.code_file_name);
#if 0
// https://github.com/fltk/fltk/issues/328
@ -495,62 +495,62 @@ static void read_children(Fl_Type *p, int paste, Strategy strategy, char skip_op
}
if (!strcmp(c,"do_not_include_H_from_C")) {
include_H_from_C=0;
P.include_H_from_C=0;
goto CONTINUE;
}
if (!strcmp(c,"use_FL_COMMAND")) {
use_FL_COMMAND=1;
P.use_FL_COMMAND=1;
goto CONTINUE;
}
if (!strcmp(c,"utf8_in_src")) {
utf8_in_src=1;
P.utf8_in_src=1;
goto CONTINUE;
}
if (!strcmp(c,"avoid_early_includes")) {
avoid_early_includes=1;
P.avoid_early_includes=1;
goto CONTINUE;
}
if (!strcmp(c,"i18n_type")) {
i18n_type = atoi(read_word());
P.i18n_type = atoi(read_word());
goto CONTINUE;
}
if (!strcmp(c,"i18n_function")) {
i18n_function = fl_strdup(read_word());
P.i18n_function = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_static_function")) {
i18n_static_function = fl_strdup(read_word());
P.i18n_static_function = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_file")) {
i18n_file = fl_strdup(read_word());
P.i18n_file = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_set")) {
i18n_set = fl_strdup(read_word());
P.i18n_set = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_include")) {
i18n_include = fl_strdup(read_word());
P.i18n_include = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_conditional")) {
i18n_conditional = fl_strdup(read_word());
P.i18n_conditional = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_type"))
{
i18n_type = atoi(read_word());
P.i18n_type = atoi(read_word());
goto CONTINUE;
}
if (!strcmp(c,"header_name")) {
if (!header_file_set) header_file_name = fl_strdup(read_word());
if (!P.header_file_set) P.header_file_name = read_word();
else read_word();
goto CONTINUE;
}
if (!strcmp(c,"code_name")) {
if (!code_file_set) code_file_name = fl_strdup(read_word());
if (!P.code_file_set) P.code_file_name = read_word();
else read_word();
goto CONTINUE;
}
@ -649,7 +649,7 @@ int read_file(const char *filename, int merge, Strategy strategy) {
if (merge)
deselect();
else
delete_all();
P.reset();
read_children(Fl_Type::current, merge, strategy);
Fl_Type::current = 0;
// Force menu items to be rebuilt...

View File

@ -163,24 +163,28 @@ int compile_strings = 0; // fluic -cs
/// Set, if Fluid runs in batch mode, and no user interface is activated.
int batch_mode = 0; // if set (-c, -u) don't open display
/// If set, commandline overrides header file name in .fl file.
int header_file_set = 0;
/** \var int Project::header_file_set
If set, commandline overrides header file name in .fl file.
*/
/// If set, commandline overrides source code file name in .fl file.
int code_file_set = 0;
/** \var int Project::code_file_set
If set, commandline overrides source code file name in .fl file.
*/
/// Hold the default extension for header files, or the entire filename if set via command line.
const char* header_file_name = ".h";
/** \var int Project::header_file_name
Hold the default extension for header files, or the entire filename if set via command line.
*/
/// Hold the default extension for source code files, or the entire filename if set via command line.
const char* code_file_name = ".cxx";
/** \var int Project::code_file_name
Hold the default extension for source code files, or the entire filename if set via command line.
*/
/** \var int Project::i18n_type
Saved in the .fl design file.
\todo document me
*/
/// Saved in the .fl design file.
/// \todo document me
int i18n_type = 0;
/**
/** \var int Project::i18n_include
For either type of translation, write a #include statement into the
source file.
@ -193,22 +197,22 @@ int i18n_type = 0;
Saved in the .fl design file.
*/
const char* i18n_include = "";
const char* i18n_conditional = "";
/** \var int Project::i18n_conditional
Saved in the .fl design file.
\todo document me
*/
/**
/** \var int Project::i18n_function
For the gettext/intl.h options, this is the function that translates text
at runtime.
This is usually "gettext" or "_".
This should not be empty.
Saved in the .fl design file.
*/
const char* i18n_function = "";
/**
/** \var int Project::i18n_static_function
For the gettext/intl.h options, this is the function that marks the
translation of text at initialisation time.
@ -219,18 +223,20 @@ const char* i18n_function = "";
Saved in the .fl design file.
*/
const char* i18n_static_function = "";
/// Saved in the .fl design file.
/// \todo document me
const char* i18n_file = "";
/** \var int Project::i18n_file
Saved in the .fl design file.
\todo document me
*/
/// Saved in the .fl design file.
/// \todo document me
const char* i18n_set = "";
/** \var int Project::i18n_set
Saved in the .fl design file.
\todo document me
*/
/// \todo document me
char i18n_program[FL_PATH_MAX] = "";
/** \var int Project::i18n_program
\todo document me
*/
/// Offset in pixels when adding widgets from an .fl file.
int pasteoffset = 0;
@ -238,6 +244,46 @@ int pasteoffset = 0;
/// Paste offset incrementing at every paste command.
static int ipasteoffset = 0;
// ---- project settings
Project P;
Project::Project() :
i18n_type(0),
i18n_program(""),
include_H_from_C(1),
use_FL_COMMAND(0),
utf8_in_src(0),
avoid_early_includes(0),
header_file_set(0),
code_file_set(0),
header_file_name(".h"),
code_file_name(".cxx")
{ }
Project::~Project() {
}
void Project::reset() {
::delete_all();
i18n_type = 0;
i18n_include = "";
i18n_conditional = "";
i18n_function = "";
i18n_static_function = "";
i18n_file = "";
i18n_set = "";
i18n_program[0] = 0;
include_H_from_C = 1;
use_FL_COMMAND = 0;
utf8_in_src = 0;
avoid_early_includes = 0;
header_file_set = 0;
code_file_set = 0;
header_file_name = ".h";
code_file_name = ".cxx";
}
// ---- Sourceview definition
@ -636,7 +682,7 @@ void exit_cb(Fl_Widget *,void *) {
// Destroy tree
// Doing so causes dtors to automatically close all external editors
// and cleans up editor tmp files. Then remove fluid tmpdir /last/.
delete_all();
P.reset();
ExternalCodeEditor::tmpdir_clear();
exit(0);
@ -803,7 +849,7 @@ void new_cb(Fl_Widget *, void *v) {
}
// Clear the current data...
delete_all();
P.reset();
set_filename(NULL);
set_modflag(0, 0);
widget_browser->rebuild();
@ -932,27 +978,27 @@ int write_code_files() {
save_cb(0,0);
if (!filename) return 1;
}
char cname[FL_PATH_MAX];
char hname[FL_PATH_MAX];
strlcpy(i18n_program, fl_filename_name(filename), sizeof(i18n_program));
fl_filename_setext(i18n_program, sizeof(i18n_program), "");
if (*code_file_name == '.' && strchr(code_file_name, '/') == NULL) {
strlcpy(cname, fl_filename_name(filename), sizeof(cname));
fl_filename_setext(cname, sizeof(cname), code_file_name);
char cname[FL_PATH_MAX+1];
char hname[FL_PATH_MAX+1];
strlcpy(P.i18n_program, fl_filename_name(filename), FL_PATH_MAX);
fl_filename_setext(P.i18n_program, FL_PATH_MAX, "");
if (P.code_file_name[0] == '.' && strchr(P.code_file_name, '/') == NULL) {
strlcpy(cname, fl_filename_name(filename), FL_PATH_MAX);
fl_filename_setext(cname, FL_PATH_MAX, P.code_file_name);
} else {
strlcpy(cname, code_file_name, sizeof(cname));
strlcpy(cname, P.code_file_name, FL_PATH_MAX);
}
if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) {
strlcpy(hname, fl_filename_name(filename), sizeof(hname));
fl_filename_setext(hname, sizeof(hname), header_file_name);
if (P.header_file_name[0] == '.' && strchr(P.header_file_name, '/') == NULL) {
strlcpy(hname, fl_filename_name(filename), FL_PATH_MAX);
fl_filename_setext(hname, FL_PATH_MAX, P.header_file_name);
} else {
strlcpy(hname, header_file_name, sizeof(hname));
strlcpy(hname, P.header_file_name, FL_PATH_MAX);
}
if (!batch_mode) enter_project_dir();
int x = write_code(cname,hname);
if (!batch_mode) leave_project_dir();
strlcat(cname, " and ", sizeof(cname));
strlcat(cname, hname, sizeof(cname));
strlcat(cname, " and ", FL_PATH_MAX);
strlcat(cname, hname, FL_PATH_MAX);
if (batch_mode) {
if (!x) {fprintf(stderr,"%s : %s\n",cname,strerror(errno)); exit(1);}
} else {
@ -986,7 +1032,7 @@ void write_strings_cb(Fl_Widget *, void *) {
}
char sname[FL_PATH_MAX];
strlcpy(sname, fl_filename_name(filename), sizeof(sname));
fl_filename_setext(sname, sizeof(sname), exts[i18n_type]);
fl_filename_setext(sname, sizeof(sname), exts[P.i18n_type]);
if (!batch_mode) enter_project_dir();
int x = write_strings(sname);
if (!batch_mode) leave_project_dir();
@ -1128,8 +1174,10 @@ void duplicate_cb(Fl_Widget*, void*) {
User wants to sort selected widgets by y coordinate.
*/
static void sort_cb(Fl_Widget *,void *) {
undo_checkpoint();
sort((Fl_Type*)NULL);
widget_browser->rebuild();
set_modflag(1);
}
/**
@ -1687,16 +1735,12 @@ void set_modflag(int mf, int mfc) {
#endif // _WIN32
else basename = filename;
if (code_file_name)
code_ext = fl_filename_ext(code_file_name);
else
code_ext = ".cxx";
code_ext = fl_filename_ext(P.code_file_name);
char mod_star = modflag ? '*' : ' ';
char mod_c_star = modflag_c ? '*' : ' ';
snprintf(title, sizeof(title), "%s%c %s%c",
basename, mod_star, code_ext, mod_c_star);
main_window->label(title);
main_window->copy_label(title);
}
// if the UI was modified in any way, update the Source View panel
if (sourceview_panel && sourceview_panel->visible() && sv_autorefresh->value())
@ -1806,18 +1850,18 @@ void update_sourceview_cb(Fl_Button*, void*)
static const char *exts[] = { ".txt", ".po", ".msg" };
char fn[FL_PATH_MAX];
fluid_prefs.getUserdataPath(fn, FL_PATH_MAX);
fl_filename_setext(fn, FL_PATH_MAX, exts[i18n_type]);
fl_filename_setext(fn, FL_PATH_MAX, exts[P.i18n_type]);
write_strings(fn);
int top = sv_strings->top_line();
sv_strings->buffer()->loadfile(fn);
sv_strings->scroll(top, 0);
} else if (sv_source->visible_r() || sv_header->visible_r()) {
strlcpy(i18n_program, fl_filename_name(sv_source_filename), sizeof(i18n_program));
fl_filename_setext(i18n_program, sizeof(i18n_program), "");
const char *code_file_name_bak = code_file_name;
code_file_name = sv_source_filename;
const char *header_file_name_bak = header_file_name;
header_file_name = sv_header_filename;
strlcpy(P.i18n_program, fl_filename_name(sv_source_filename), FL_PATH_MAX);
fl_filename_setext(P.i18n_program, FL_PATH_MAX, "");
Fd_String code_file_name_bak = P.code_file_name;
P.code_file_name = sv_source_filename;
Fd_String header_file_name_bak = P.header_file_name;
P.header_file_name = sv_header_filename;
// generate the code and load the files
write_sourceview = 1;
@ -1837,8 +1881,8 @@ void update_sourceview_cb(Fl_Button*, void*)
}
write_sourceview = 0;
code_file_name = code_file_name_bak;
header_file_name = header_file_name_bak;
P.code_file_name = code_file_name_bak;
P.header_file_name = header_file_name_bak;
}
}
@ -1867,16 +1911,16 @@ static int arg(int argc, char** argv, int& i) {
if (argv[i][1] == 'c' && !argv[i][2]) {compile_file++; batch_mode++; i++; return 1;}
if (argv[i][1] == 'c' && argv[i][2] == 's' && !argv[i][3]) {compile_file++; compile_strings++; batch_mode++; i++; return 1;}
if (argv[i][1] == 'o' && !argv[i][2] && i+1 < argc) {
code_file_name = argv[i+1];
code_file_set = 1;
P.code_file_name = argv[i+1];
P.code_file_set = 1;
batch_mode++;
i += 2;
return 2;
}
if (argv[i][1] == 'h' && !argv[i][2]) {
if (i+1 < argc) {
header_file_name = argv[i+1];
header_file_set = 1;
P.header_file_name = argv[i+1];
P.header_file_set = 1;
batch_mode++;
i += 2;
return 2;

View File

@ -20,6 +20,7 @@
#include <FL/filename.H>
#include <FL/Fl_Preferences.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_String.H>
#define BROWSERWIDTH 300
#define BROWSERHEIGHT 500
@ -75,22 +76,48 @@ extern int compile_file; // fluid -c
extern int compile_strings; // fluic -cs
extern int batch_mode;
extern int header_file_set;
extern int code_file_set;
extern const char* header_file_name;
extern const char* code_file_name;
extern int i18n_type;
extern const char* i18n_include;
extern const char* i18n_conditional;
extern const char* i18n_function;
extern const char* i18n_static_function;
extern const char* i18n_file;
extern const char* i18n_set;;
extern char i18n_program[FL_PATH_MAX];
extern int pasteoffset;
// ---- string handling
class Fd_String : public Fl_String
{
public:
Fd_String() : Fl_String("") { }
Fd_String(const char* s) : Fl_String(s) { }
int empty() { return size()==0; }
void operator=(const char* s) { value(s); }
operator const char* () const { return value(); }
};
// ---- project settings
class Project {
public:
Project();
~Project();
void reset();
int i18n_type;
Fd_String i18n_include;
Fd_String i18n_conditional;
Fd_String i18n_function;
Fd_String i18n_static_function;
Fd_String i18n_file;
Fd_String i18n_set;
char i18n_program[FL_PATH_MAX+1];
int include_H_from_C;
int use_FL_COMMAND;
int utf8_in_src;
int avoid_early_includes;
int header_file_set = 0;
int code_file_set = 0;
Fd_String header_file_name;
Fd_String code_file_name;
};
extern Project P;
// ---- public functions
extern void set_filename(const char *c);

View File

@ -86,8 +86,6 @@ void Fl_String::alloc_buf(int size) {
return;
if (size > 0 && size <= capacity_)
return;
if (capacity_ > 0)
return;
int new_size = (size + 1 + 15) & (~15); // round upwards
char *new_value = new char[new_size];