FLUID: comments, typos, formatting

This commit is contained in:
Matthias Melcher 2024-03-02 22:58:52 +01:00
parent 7fea97c7a7
commit ec9430e744
17 changed files with 228 additions and 195 deletions

View File

@ -17,7 +17,8 @@
# Targets that will be built: fluid and fluid-cmd (Windows)
set(TARGETS fluid)
# Source files for 'fluid-lib' = all source files except the main file (fluid.cxx)
# Source files for 'fluid-lib' = all source files except the main files
# (fluid.cxx and fluid.h)
# Note: macOS (Xcode) needs at least one source file (fluid.cxx) to link the main
# program fluid properly
@ -116,7 +117,7 @@ if(APPLE AND NOT FLTK_BACKEND_X11)
set(ICON_NAME fluid.icns)
set(ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/icons/${ICON_NAME}")
add_executable(fluid MACOSX_BUNDLE fluid.cxx ${ICON_PATH})
add_executable(fluid MACOSX_BUNDLE fluid.cxx fluid.h ${ICON_PATH})
# create macOS bundle wrapper script
@ -133,7 +134,7 @@ if(APPLE AND NOT FLTK_BACKEND_X11)
else()
# Option 'WIN32' builds a Windows GUI program, ignored on other platforms
add_executable(fluid WIN32 fluid.cxx)
add_executable(fluid WIN32 fluid.cxx fluid.h)
endif()
@ -144,7 +145,7 @@ target_link_libraries(fluid PRIVATE fluid-lib)
if(WIN32)
list(APPEND TARGETS fluid-cmd)
add_executable(fluid-cmd fluid.cxx)
add_executable(fluid-cmd fluid.cxx fluid.h)
target_link_libraries(fluid-cmd PRIVATE fluid-lib)
set(FLTK_FLUID_EXECUTABLE fltk::fluid-cmd)
else()

View File

@ -2,7 +2,7 @@
// Code editor widget for the Fast Light Tool Kit (FLTK).
// Syntax highlighting rewritten by erco@seriss.com 09/15/20.
//
// Copyright 1998-2023 by Bill Spitzak and others.
// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -28,13 +28,6 @@
// ---- CodeEditor implementation
/** \class CodeEditor
A widget derived from Fl_Text_Editor that implements C++ code highlighting.
CodeEditor is used in Fluid whenever the user can edit C++ source
code or header text.
*/
/**
Lookup table for all supported styles.
Every table entry describes a rendering style for the corresponding text.
@ -263,14 +256,6 @@ void CodeEditor::textsize(Fl_Fontsize s) {
// ---- CodeViewer implementation
/** \class CodeViewer
A widget derived from CodeEditor with highlighting for code blocks.
This widget is used by the SourceView system to show the design's
source and header code. The secondary highlighting show the text
part that corresponds to the selected widget(s).
*/
/**
Create a CodeViewer widget.
\param[in] X, Y, W, H position and size of the widget

View File

@ -2,7 +2,7 @@
// Code editor widget for the Fast Light Tool Kit (FLTK).
// Syntax highlighting rewritten by erco@seriss.com 09/15/20.
//
// Copyright 1998-2022 by Bill Spitzak and others.
// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -35,6 +35,12 @@
// ---- CodeEditor declaration
/**
A widget derived from Fl_Text_Editor that implements C++ code highlighting.
CodeEditor is used in Fluid whenever the user can edit C++ source
code or header text.
*/
class CodeEditor : public Fl_Text_Editor {
friend class StyleParse;
@ -49,31 +55,51 @@ class CodeEditor : public Fl_Text_Editor {
public:
CodeEditor(int X, int Y, int W, int H, const char *L=0);
~CodeEditor();
int top_line() { return get_absolute_top_line_number(); }
void textsize(Fl_Fontsize s);
/// access to protected member get_absolute_top_line_number()
int top_line() { return get_absolute_top_line_number(); }
/// access to protected member mTopLineNum
int scroll_row() { return mTopLineNum; }
/// access to protected member mHorizOffset
int scroll_col() { return mHorizOffset; }
};
// ---- CodeViewer declaration
/**
A widget derived from CodeEditor with highlighting for code blocks.
This widget is used by the SourceView system to show the design's
source and header code. The secondary highlighting show the text
part that corresponds to the selected widget(s).
*/
class CodeViewer : public CodeEditor {
public:
CodeViewer(int X, int Y, int W, int H, const char *L=0);
protected:
int handle(int ev) FL_OVERRIDE{ return Fl_Text_Display::handle(ev); }
void draw() FL_OVERRIDE;
/// Limit event handling to viewing, not editing
int handle(int ev) FL_OVERRIDE { return Fl_Text_Display::handle(ev); }
};
// ---- Project File Text Viewe declaration
// ---- Project File Text Viewer declaration
/**
A text viewer with an additional highlighting color scheme.
*/
class TextViewer : public Fl_Text_Display {
public:
TextViewer(int X, int Y, int W, int H, const char *L=0);
~TextViewer();
int top_line() { return get_absolute_top_line_number(); }
void draw() FL_OVERRIDE;
/// access to protected member get_absolute_top_line_number()
int top_line() { return get_absolute_top_line_number(); }
};
#endif // !CodeEditor_h

View File

@ -30,7 +30,7 @@
// TODO: warning if the user wants to change builtin layouts
// TODO: move panel to global settings panel (move load & save to main pulldown, or to toolbox?)
// INFO: how about a small tool box for quick preset selection and disabeling of individual snaps?
// INFO: how about a small tool box for quick preset selection and disabling of individual snaps?
void select_layout_suite_cb(Fl_Widget *, void *user_data);

View File

@ -38,7 +38,6 @@ public:
void write_properties(Fd_Project_Writer &f) FL_OVERRIDE;
void read_property(Fd_Project_Reader &f, const char *) FL_OVERRIDE;
void copy_properties() FL_OVERRIDE;
};
extern Fl_Button_Type Fl_Button_type;

View File

@ -162,7 +162,7 @@ const char *_c_check(const char * & c, int type) {
\note This function checks every conceivable line of code, which is not
always wanted. It can't differentiate characters in comments, and the
user may well intend to leave a curly bracket open
(i.e. namesapece { ... } ). We should make this option user selectable.
(i.e. namespace { ... } ). We should make this option user selectable.
*/
const char *c_check(const char *c, int type) {
return _c_check(c,type);
@ -779,7 +779,7 @@ void Fl_CodeBlock_Type::write_properties(Fd_Project_Writer &f) {
}
/**
Read the node specifc properties.
Read the node specific properties.
*/
void Fl_CodeBlock_Type::read_property(Fd_Project_Reader &f, const char *c) {
if (!strcmp(c,"after")) {
@ -1441,7 +1441,7 @@ int Fl_DeclBlock_Type::is_public() const {return public_;}
/**
Create a new declaration block.
\param[in] strategy add after current or as last child
\return new Declaration Blocknode
\return new Declaration Block node
*/
Fl_Type *Fl_DeclBlock_Type::make(Strategy strategy) {
Fl_Type *p = Fl_Type::current;

View File

@ -381,14 +381,14 @@ void Fl_Menu_Item_Type::write_item(Fd_Code_Writer& f) {
f.write_c(" {");
if (label() && label()[0])
switch (g_project.i18n_type) {
case 1:
case FD_I18N_GNU:
// we will call i18n when the menu is instantiated for the first time
f.write_c("%s(", g_project.i18n_gnu_static_function.c_str());
f.write_cstring(label());
f.write_c(")");
break;
case 2:
// fall through: strings can't be translated before a catalog is choosen
case FD_I18N_POSIX:
// fall through: strings can't be translated before a catalog is chosen
default:
f.write_cstring(label());
}
@ -486,14 +486,15 @@ void Fl_Menu_Item_Type::write_code1(Fd_Code_Writer& f) {
f.write_c("%sml->labela = (char*)", f.indent());
image->write_inline(f);
f.write_c(";\n");
if (g_project.i18n_type==0) {
if (g_project.i18n_type==FD_I18N_NONE) {
f.write_c("%sml->labelb = o->label();\n", f.indent());
} else if (g_project.i18n_type==1) {
} else if (g_project.i18n_type==FD_I18N_GNU) {
f.write_c("%sml->labelb = %s(o->label());\n",
f.indent(), g_project.i18n_gnu_function.c_str());
} else if (g_project.i18n_type==2) {
} else if (g_project.i18n_type==FD_I18N_POSIX) {
f.write_c("%sml->labelb = catgets(%s,%s,i+%d,o->label());\n",
f.indent(), g_project.i18n_pos_file[0] ? g_project.i18n_pos_file.c_str() : "_catalog",
f.indent(),
g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
g_project.i18n_pos_set.c_str(), msgnum());
}
f.write_c("%sml->typea = FL_IMAGE_LABEL;\n", f.indent());
@ -510,12 +511,13 @@ void Fl_Menu_Item_Type::write_code1(Fd_Code_Writer& f) {
} else if ( t==FL_NORMAL_LABEL || t==FL_SHADOW_LABEL
|| t==FL_ENGRAVED_LABEL || t==FL_EMBOSSED_LABEL) {
start_menu_initialiser(f, menuItemInitialized, mname, i);
if (g_project.i18n_type==1) {
if (g_project.i18n_type==FD_I18N_GNU) {
f.write_c("%so->label(%s(o->label()));\n",
f.indent(), g_project.i18n_gnu_function.c_str());
} else if (g_project.i18n_type==2) {
} else if (g_project.i18n_type==FD_I18N_POSIX) {
f.write_c("%so->label(catgets(%s,%s,i+%d,o->label()));\n",
f.indent(), g_project.i18n_pos_file[0] ? g_project.i18n_pos_file.c_str() : "_catalog",
f.indent(),
g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
g_project.i18n_pos_set.c_str(), msgnum());
}
}

View File

@ -1,7 +1,7 @@
//
// Widget type header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2023 by Bill Spitzak and others.
// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -130,7 +130,7 @@ public: // things that should not be public:
Fl_Type *parent;
/** This type is rendered "selected" in the tree browser. */
char new_selected; // browser highlight
/** Backup storage for selection if an error accured during some operation
/** Backup storage for selection if an error occurred during some operation
(see `haderror`). It seems that this is often confused with new_selected
which seems to hold the true and visible selection state. */
char selected; // copied here by selection_changed()
@ -225,9 +225,9 @@ public:
void write_comment_inline_c(Fd_Code_Writer& f, const char *ind=0L); // write the commentary text
// live mode
virtual Fl_Widget *enter_live_mode(int top=0); // build wdgets needed for live mode
virtual Fl_Widget *enter_live_mode(int top=0); // build widgets needed for live mode
virtual void leave_live_mode(); // free allocated resources
virtual void copy_properties(); // copy properties from this type into a potetial live object
virtual void copy_properties(); // copy properties from this type into a potential live object
// get message number for I18N
int msgnum();

View File

@ -2997,16 +2997,17 @@ void Fl_Widget_Type::write_code1(Fd_Code_Writer& f) {
if (label() && *label()) {
f.write_c(", ");
switch (g_project.i18n_type) {
case 0 : /* None */
case FD_I18N_NONE : /* None */
f.write_cstring(label());
break;
case 1 : /* GNU gettext */
case FD_I18N_GNU : /* GNU gettext */
f.write_c("%s(", g_project.i18n_gnu_function.c_str());
f.write_cstring(label());
f.write_c(")");
break;
case 2 : /* POSIX catgets */
f.write_c("catgets(%s,%s,%d,", g_project.i18n_pos_file[0] ? g_project.i18n_pos_file.c_str() : "_catalog",
case FD_I18N_POSIX : /* POSIX catgets */
f.write_c("catgets(%s,%s,%d,",
g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
g_project.i18n_pos_set.c_str(), msgnum());
f.write_cstring(label());
f.write_c(")");
@ -3070,17 +3071,19 @@ void Fl_Widget_Type::write_widget_code(Fd_Code_Writer& f) {
if (tooltip() && *tooltip()) {
f.write_c("%s%s->tooltip(",f.indent(), var);
switch (g_project.i18n_type) {
case 0 : /* None */
case FD_I18N_NONE : /* None */
f.write_cstring(tooltip());
break;
case 1 : /* GNU gettext */
case FD_I18N_GNU : /* GNU gettext */
f.write_c("%s(", g_project.i18n_gnu_function.c_str());
f.write_cstring(tooltip());
f.write_c(")");
break;
case 2 : /* POSIX catgets */
f.write_c("catgets(%s,%s,%d,", g_project.i18n_pos_file[0] ? g_project.i18n_pos_file.c_str() : "_catalog",
g_project.i18n_pos_set.c_str(), msgnum() + 1);
case FD_I18N_POSIX : /* POSIX catgets */
f.write_c("catgets(%s,%s,%d,",
g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
g_project.i18n_pos_set.c_str(),
msgnum() + 1);
f.write_cstring(tooltip());
f.write_c(")");
break;

View File

@ -57,7 +57,7 @@ protected:
/// This variable is set for visible windows in batch mode.
/// We can't open a window in batch mode, even if we want the "visible" flags
/// set, so we need a second place to store this information while also
/// disabeling the output of the "hide" property by the Widget Type.
/// disabling the output of the "hide" property by the Widget Type.
uchar override_visible_;
void write_static(Fd_Code_Writer& f) FL_OVERRIDE;

View File

@ -73,19 +73,19 @@ void i18n_type_cb(Fl_Choice *c, void *v) {
c->value(g_project.i18n_type);
} else {
undo_checkpoint();
g_project.i18n_type = c->value();
g_project.i18n_type = static_cast<Fd_I18n_Type>(c->value());
set_modflag(1);
}
switch (g_project.i18n_type) {
case 0 : /* None */
case FD_I18N_NONE : /* None */
i18n_gnu_group->hide();
i18n_posix_group->hide();
break;
case 1 : /* GNU gettext */
case FD_I18N_GNU : /* GNU gettext */
i18n_gnu_group->show();
i18n_posix_group->hide();
break;
case 2 : /* POSIX cat */
case FD_I18N_POSIX : /* POSIX cat */
i18n_gnu_group->hide();
i18n_posix_group->show();
break;

View File

@ -1,5 +1,5 @@
//
// Widget type header file for the Fast Light Tool Kit (FLTK).
// Window type header file for the Fast Light Tool Kit (FLTK).
//
// Type for creating all subclasses of Fl_Widget
// This should have the widget pointer in it, but it is still in the

View File

@ -94,7 +94,7 @@ int write_strings(const Fl_String &filename) {
if (!fp) return 1;
switch (g_project.i18n_type) {
case 0 : /* None, just put static text out */
case FD_I18N_NONE : /* None, just put static text out */
fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
for (p = Fl_Type::first; p; p = p->next) {
@ -113,7 +113,7 @@ int write_strings(const Fl_String &filename) {
}
}
break;
case 1 : /* GNU gettext, put a .po file out */
case FD_I18N_GNU : /* GNU gettext, put a .po file out */
fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
for (p = Fl_Type::first; p; p = p->next) {
@ -142,7 +142,7 @@ int write_strings(const Fl_String &filename) {
}
}
break;
case 2 : /* POSIX catgets, put a .msg file out */
case FD_I18N_POSIX : /* 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", g_project.i18n_pos_set.c_str());
@ -844,7 +844,7 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview)
}
}
Fl_String loc_include, loc_conditional;
if (g_project.i18n_type==1) {
if (g_project.i18n_type==FD_I18N_GNU) {
loc_include = g_project.i18n_gnu_include;
loc_conditional = g_project.i18n_gnu_conditional;
} else {
@ -861,7 +861,7 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview)
write_c("#%sinclude \"%s\"\n", indent(), loc_include.c_str());
else
write_c("#%sinclude %s\n", indent(), loc_include.c_str());
if (g_project.i18n_type == 2) {
if (g_project.i18n_type == FD_I18N_POSIX) {
if (!g_project.i18n_pos_file.empty()) {
write_c("extern nl_catd %s;\n", g_project.i18n_pos_file.c_str());
} else {
@ -873,14 +873,14 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview)
}
if (conditional) {
write_c("#else\n");
if (g_project.i18n_type == 1) {
if (g_project.i18n_type == FD_I18N_GNU) {
if (!g_project.i18n_gnu_function.empty()) {
write_c("#%sifndef %s\n", indent(), g_project.i18n_gnu_function.c_str());
write_c("#%sdefine %s(text) text\n", indent_plus(1), g_project.i18n_gnu_function.c_str());
write_c("#%sendif\n", indent());
}
}
if (g_project.i18n_type == 2) {
if (g_project.i18n_type == FD_I18N_POSIX) {
write_c("#%sifndef catgets\n", indent());
write_c("#%sdefine catgets(catalog, set, msgid, text) text\n", indent_plus(1));
write_c("#%sendif\n", indent());
@ -888,7 +888,7 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview)
indentation--;
write_c("#endif\n");
}
if (g_project.i18n_type == 1 && g_project.i18n_gnu_static_function[0]) {
if (g_project.i18n_type == FD_I18N_GNU && g_project.i18n_gnu_static_function[0]) {
write_c("#ifndef %s\n", g_project.i18n_gnu_static_function.c_str());
write_c("#%sdefine %s(text) text\n", indent_plus(1), g_project.i18n_gnu_static_function.c_str());
write_c("#endif\n");

View File

@ -283,7 +283,7 @@ Fl_Type *Fd_Project_Reader::read_children(Fl_Type *p, int merge, Strategy strate
goto CONTINUE;
}
if (!strcmp(c,"i18n_type")) {
g_project.i18n_type = atoi(read_word());
g_project.i18n_type = static_cast<Fd_I18n_Type>(atoi(read_word()));
goto CONTINUE;
}
if (!strcmp(c,"i18n_gnu_function")) {
@ -303,16 +303,16 @@ Fl_Type *Fd_Project_Reader::read_children(Fl_Type *p, int merge, Strategy strate
goto CONTINUE;
}
if (!strcmp(c,"i18n_include")) {
if (g_project.i18n_type == 1)
if (g_project.i18n_type == FD_I18N_GNU)
g_project.i18n_gnu_include = read_word();
else if (g_project.i18n_type == 2)
else if (g_project.i18n_type == FD_I18N_POSIX)
g_project.i18n_pos_include = read_word();
goto CONTINUE;
}
if (!strcmp(c,"i18n_conditional")) {
if (g_project.i18n_type == 1)
if (g_project.i18n_type == FD_I18N_GNU)
g_project.i18n_gnu_conditional = read_word();
else if (g_project.i18n_type == 2)
else if (g_project.i18n_type == FD_I18N_POSIX)
g_project.i18n_pos_conditional = read_word();
goto CONTINUE;
}
@ -847,13 +847,15 @@ int Fd_Project_Writer::write_project(const char *filename, int selected_only, bo
if (g_project.i18n_type) {
write_string("\ni18n_type %d", g_project.i18n_type);
switch (g_project.i18n_type) {
case 1 : /* GNU gettext */
case FD_I18N_NONE:
break;
case FD_I18N_GNU : /* GNU gettext */
write_string("\ni18n_include"); write_word(g_project.i18n_gnu_include.c_str());
write_string("\ni18n_conditional"); write_word(g_project.i18n_gnu_conditional.c_str());
write_string("\ni18n_gnu_function"); write_word(g_project.i18n_gnu_function.c_str());
write_string("\ni18n_gnu_static_function"); write_word(g_project.i18n_gnu_static_function.c_str());
break;
case 2 : /* POSIX catgets */
case FD_I18N_POSIX : /* POSIX catgets */
write_string("\ni18n_include"); write_word(g_project.i18n_pos_include.c_str());
write_string("\ni18n_conditional"); write_word(g_project.i18n_pos_conditional.c_str());
if (!g_project.i18n_pos_file.empty()) {

View File

@ -1,7 +1,7 @@
//
// FLUID main entry for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2023 by Bill Spitzak and others.
// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -67,10 +67,13 @@ extern "C"
// Globals..
//
/// Fluid-wide help dialog.
static Fl_Help_Dialog *help_dialog = 0;
/// FLUID-wide help dialog.
static Fl_Help_Dialog *help_dialog = NULL;
/// Main app window menu bar.
Fl_Menu_Bar *main_menubar = NULL;
/// Main app window.
Fl_Window *main_window;
/// Fluid application preferences, always accessible, will be flushed when app closes.
@ -143,7 +146,7 @@ Fl_Menu_Item *restricted_item = NULL;
////////////////////////////////////////////////////////////////
/// Filename of the current .fl design file
/// Filename of the current .fl project file
static const char *filename = NULL;
/// Set if the current design has been modified compared to the associated .fl design file.
@ -172,105 +175,23 @@ int compile_strings = 0; // fluid -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
/// command line arguments override settings in the project file
/// command line arguments that overrides the generate code file extension or name
Fl_String g_code_filename_arg;
/// command line arguments that overrides the generate header file extension or name
Fl_String g_header_filename_arg;
/// current directory path at application launch
Fl_String g_launch_path;
/// path to store temporary files during app run
/// \see tmpdir_create_called
Fl_String tmpdir_path;
/// true if the temporary file path was already created
/// \see tmpdir_path
bool tmpdir_create_called = false;
/** \var int Fluid_Project::header_file_set
If set, command line overrides header file name in .fl file.
*/
/** \var int Fluid_Project::code_file_set
If set, command line overrides source code file name in .fl file.
*/
/** \var int Fluid_Project::header_file_name
Hold the default extension for header files, or the entire filename if set via command line.
*/
/** \var int Fluid_Project::code_file_name
Hold the default extension for source code files, or the entire filename if set via command line.
*/
/** \var int Fluid_Project::i18n_type
Saved in the .fl design file.
\todo document me
*/
/** \var int Fluid_Project::i18n_gnu_include
Include file for GNU i18n, writes an #include statement into the
source file.
This is usually `<libintl.h>` or `"gettext.h"` for GNU gettext.
Fluid accepts filenames in quotes or in \< and \>. If neither is found,
double quotes are added.
If this value is empty, no include statement will be generated.
Saved in the .fl design file if GNU i18n is selected.
*/
/** \var int Fluid_Project::i18n_pos_include
Include file for Posix i18n, write a #include statement into the
source file.
This is usually `<nl_types.h>` for Posix catgets.
Fluid accepts filenames in quotes or in \< and \>. If neither is found,
double quotes are added.
If this value is empty, no include statement will be generated.
Saved in the .fl design file.
*/
/** \var int Fluid_Project::i18n_gnu_conditional
Saved in the .fl design file.
\todo document me
*/
/** \var int Fluid_Project::i18n_pos_conditional
Saved in the .fl design file.
\todo document me
*/
/** \var int Fluid_Project::i18n_gnu_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.
*/
/** \var int Fluid_Project::i18n_gnu_static_function
For the gettext/intl.h options, this is the function that marks the
translation of text at initialisation time.
This is usually "gettext_noop" or "N_".
This should not be empty.
Fluid will translate static text (usually in menu items) later when used
for the first time.
Saved in the .fl design file.
*/
/** \var int Fluid_Project::i18n_pos_file
Saved in the .fl design file.
\todo document me
*/
/** \var int Fluid_Project::i18n_pos_set
Saved in the .fl design file.
\todo document me
*/
/** \var int Fluid_Project::basename
\todo document me
*/
/// Offset in pixels when adding widgets from an .fl file.
int pasteoffset = 0;
@ -280,10 +201,14 @@ static int ipasteoffset = 0;
// ---- project settings
/// The current project, possibly a new, empty roject
Fluid_Project g_project;
/**
Initialize a new project.
*/
Fluid_Project::Fluid_Project() :
i18n_type(0),
i18n_type(FD_I18N_NONE),
include_H_from_C(1),
use_FL_COMMAND(0),
utf8_in_src(0),
@ -295,12 +220,19 @@ Fluid_Project::Fluid_Project() :
code_file_name(".cxx")
{ }
/**
Clear all project resources.
Not implemented.
*/
Fluid_Project::~Fluid_Project() {
}
/**
Reset all project setting to create a new empty project.
*/
void Fluid_Project::reset() {
::delete_all();
i18n_type = 0;
i18n_type = FD_I18N_NONE;
i18n_gnu_include = "<libintl.h>";
i18n_gnu_conditional = "";
@ -323,6 +255,9 @@ void Fluid_Project::reset() {
write_mergeback_data = 0;
}
/**
Tell the project and i18n tab of the settings dialog to refresh themselves.
*/
void Fluid_Project::update_settings_dialog() {
if (settings_window) {
w_settings_project_tab->do_callback(w_settings_project_tab, LOAD);
@ -330,7 +265,11 @@ void Fluid_Project::update_settings_dialog() {
}
}
// make sure that a path name ends with a forward slash
/**
Make sure that a path name ends with a forward slash.
\param[in] str directory or path name
\return a new string, ending with a '/'
*/
static Fl_String end_with_slash(const Fl_String &str) {
char last = str[str.size()-1];
if (last !='/' && last != '\\')
@ -339,7 +278,8 @@ static Fl_String end_with_slash(const Fl_String &str) {
return str;
}
/** Generate a path to a directory for temporary data storage.
/**
Generate a path to a directory for temporary data storage.
The path is stored in g_tmpdir.
*/
static void create_tmpdir() {
@ -396,11 +336,18 @@ static void create_tmpdir() {
fl_make_path(path.c_str());
if (fl_access(path.c_str(), 6) == 0) tmpdir_path = path;
}
if (tmpdir_path.empty())
if (tmpdir_path.empty()) {
if (batch_mode) {
fprintf(stderr, "ERROR: Can't create directory for temporary data storage.\n");
} else {
fl_alert("Can't create directory for temporary data storage.");
}
}
}
/** Delete the temporary directory that was created in set_tmpdir. */
/**
Delete the temporary directory that was created in set_tmpdir.
*/
static void delete_tmpdir() {
// was a temporary directory created
if (!tmpdir_create_called)
@ -421,15 +368,19 @@ static void delete_tmpdir() {
// then delete the directory itself
if (fl_rmdir(tmpdir_path.c_str()) < 0) {
if (batch_mode) {
fprintf(stderr, "WARNING: Can't delete tmpdir '%s': %s", tmpdir_path.c_str(), strerror(errno));
} else {
fl_alert("WARNING: Can't delete tmpdir '%s': %s", tmpdir_path.c_str(), strerror(errno));
}
}
}
/**
Return the path to a temporary directory for this instance of FLUID.
Fluid will do its best to clear and delete this directory when exiting.
\return the path to the temporary directory, ending in a '/', or and empty
string is no directory could be created.
string if no directory could be created.
*/
const Fl_String &get_tmpdir() {
if (!tmpdir_create_called)
@ -468,7 +419,13 @@ bool confirm_project_clear() {
// ----
extern Fl_Window *the_panel;
// make sure that a currently changed text widgets propagates its contents
/**
Ensure that text widgets in the widget panel propagates apply current changes.
By temporarily clearing the text focus, all text widgets with changed text
will unfocus and call their respective callbacks, propagating those changes to
their data set.
*/
void flush_text_widgets() {
if (Fl::focus() && (Fl::focus()->top_window() == the_panel)) {
Fl_Widget *old_focus = Fl::focus();
@ -476,6 +433,7 @@ void flush_text_widgets() {
Fl::focus(old_focus);
}
}
// ----
/**
@ -814,9 +772,14 @@ void revert_cb(Fl_Widget *,void *) {
*/
void exit_cb(Fl_Widget *,void *) {
if (shell_command_running()) {
fl_alert("Previous shell command still running!");
int choice = fl_choice("Previous shell command still running!",
"Cancel",
"Exit",
NULL);
if (choice == 0) { // user chose to cancel the exit operation
return;
}
}
flush_text_widgets();
@ -874,6 +837,8 @@ void exit_cb(Fl_Widget *,void *) {
If the current project was modified, FLUID will give the user the opportunity
to save the old project first.
\param[in] user_must_confirm if set, a confimation dialog is presented to the
user before resetting the project.
\return false if the operation was canceled
*/
bool new_project(bool user_must_confirm = true) {
@ -1122,6 +1087,7 @@ void apple_open_cb(const char *c) {
/**
Get the absolute path of the project file, for example `/Users/matt/dev/`.
\return the path ending in '/'
*/
Fl_String Fluid_Project::projectfile_path() const {
return end_with_slash(fl_filename_absolute(fl_filename_path(filename), g_launch_path));
@ -1129,6 +1095,7 @@ Fl_String Fluid_Project::projectfile_path() const {
/**
Get the project file name including extension, for example `test.fl`.
\return the file name without path
*/
Fl_String Fluid_Project::projectfile_name() const {
return fl_filename_name(filename);
@ -1136,6 +1103,7 @@ Fl_String Fluid_Project::projectfile_name() const {
/**
Get the absolute path of the generated C++ code file, for example `/Users/matt/dev/src/`.
\return the path ending in '/'
*/
Fl_String Fluid_Project::codefile_path() const {
Fl_String path = fl_filename_path(code_file_name);
@ -1147,6 +1115,7 @@ Fl_String Fluid_Project::codefile_path() const {
/**
Get the generated C++ code file name including extension, for example `test.cxx`.
\return the file name without path
*/
Fl_String Fluid_Project::codefile_name() const {
Fl_String name = fl_filename_name(code_file_name);
@ -1161,6 +1130,7 @@ Fl_String Fluid_Project::codefile_name() const {
/**
Get the absolute path of the generated C++ header file, for example `/Users/matt/dev/src/`.
\return the path ending in '/'
*/
Fl_String Fluid_Project::headerfile_path() const {
Fl_String path = fl_filename_path(header_file_name);
@ -1172,6 +1142,7 @@ Fl_String Fluid_Project::headerfile_path() const {
/**
Get the generated C++ header file name including extension, for example `test.cxx`.
\return the file name without path
*/
Fl_String Fluid_Project::headerfile_name() const {
Fl_String name = fl_filename_name(header_file_name);
@ -1190,33 +1161,35 @@ Fl_String Fluid_Project::headerfile_name() const {
with the source and header file, historically, the text is always saved with
the project file in interactive mode, and in the FLUID launch directory in
batch mode.
\return the path ending in '/'
*/
Fl_String Fluid_Project::stringsfile_path() const {
if (batch_mode)
return end_with_slash(g_launch_path);
return g_launch_path;
else
return projectfile_path();
}
/**
Get the generated i18n text file name including extension, for example `test.po`.
\return the file name without path
*/
Fl_String Fluid_Project::stringsfile_name() const {
switch (i18n_type) {
default: return fl_filename_setext(fl_filename_name(filename), ".txt");
case 1: return fl_filename_setext(fl_filename_name(filename), ".po");
case 2: return fl_filename_setext(fl_filename_name(filename), ".msg");
case FD_I18N_GNU: return fl_filename_setext(fl_filename_name(filename), ".po");
case FD_I18N_POSIX: return fl_filename_setext(fl_filename_name(filename), ".msg");
}
}
/**
Get the name of the project file without the filename extension.
\return the file name without path or extension
*/
Fl_String Fluid_Project::basename() const {
return fl_filename_setext(fl_filename_name(filename), "");
}
/**
Generate the C++ source and header filenames and write those files.
@ -1234,6 +1207,7 @@ Fl_String Fluid_Project::basename() const {
In interactive mode, it will pop up an error message, or, if the user
hasn't disabled that, pop up a confirmation message.
\param[in] dont_show_completion_dialog don't show the completion dialog
\return 1 if the operation failed, 0 if it succeeded
*/
int write_code_files(bool dont_show_completion_dialog)
@ -1670,7 +1644,7 @@ static void menu_file_open_history_cb(Fl_Widget *, void *v) { open_project_file(
\c New_Menu creates new widgets and is explained in detail in another location.
\see New_Menu
\todo This menu need some major modernisation. Menus are too long and their
\todo This menu needs some major modernization. Menus are too long and their
sorting is not always obvious.
\todo Shortcuts are all over the place (Alt, Ctrl, Command, Shift-Ctrl,
function keys), and there should be a help page listing all shortcuts.
@ -1772,6 +1746,8 @@ Fl_Menu_Item Main_Menu[] = {
This callback is triggered by changing the scheme in the
Fl_Scheme_Choice widget (\p Edit/GUI Settings).
\param[in] choice the calling widget
\see init_scheme() for choice values and backwards compatibility
*/
void scheme_cb(Fl_Scheme_Choice *choice, void *) {
@ -1860,10 +1836,16 @@ void toggle_widgetbin_cb(Fl_Widget *, void *) {
}
}
/**
Show or hide the code preview window.
*/
void toggle_sourceview_cb(Fl_Double_Window *, void *) {
sourceview_toggle_visibility();
}
/**
Show or hide the code preview window, button callback.
*/
void toggle_sourceview_b_cb(Fl_Button*, void *) {
sourceview_toggle_visibility();
}

View File

@ -1,7 +1,7 @@
//
// FLUID main entry for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2023 by Bill Spitzak and others.
// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -100,6 +100,18 @@ extern Fl_String g_launch_path;
// ---- project class declaration
/**
Enumeration of available internationalization types.
*/
typedef enum {
FD_I18N_NONE = 0, ///< No i18n, all strings are litearals
FD_I18N_GNU, ///< GNU gettext internationalization
FD_I18N_POSIX ///< Posix catgets internationalization
} Fd_I18n_Type;
/**
Data and settings for a FLUID project file.
*/
class Fluid_Project {
public:
Fluid_Project();
@ -117,25 +129,46 @@ public:
Fl_String stringsfile_name() const;
Fl_String basename() const;
int i18n_type;
/// One of the available internationalization types.
Fd_I18n_Type i18n_type;
/// Include file for GNU i18n, writes an #include statement into the source
/// file. This is usually `<libintl.h>` or `"gettext.h"` for GNU gettext.
Fl_String i18n_gnu_include;
// Optional name of a macro for conditional i18n compilation.
Fl_String i18n_gnu_conditional;
/// For the gettext/intl.h options, this is the function that translates text
/// at runtime. This is usually "gettext" or "_".
Fl_String i18n_gnu_function;
/// For the gettext/intl.h options, this is the function that marks the translation
/// of text at initialisation time. This is usually "gettext_noop" or "N_".
Fl_String i18n_gnu_static_function;
/// Include file for Posix i18n, write a #include statement into the source
/// file. This is usually `<nl_types.h>` for Posix catgets.
Fl_String i18n_pos_include;
// Optional name of a macro for conditional i18n compilation.
Fl_String i18n_pos_conditional;
/// Name of the nl_catd database
Fl_String i18n_pos_file;
/// Message set ID for the catalog.
Fl_String i18n_pos_set;
/// If set, generate code to include the header file form the c++ file
int include_H_from_C;
/// If set, handle keyboard shortcut Ctrl on macOS using Cmd instead
int use_FL_COMMAND;
/// Clear if UTF-8 characters in statics texts are written as escape sequences
int utf8_in_src;
/// If set, <FL/Fl.H> will not be included from the header code before anything else
int avoid_early_includes;
/// If set, command line overrides header file name in .fl file.
int header_file_set;
/// If set, command line overrides source code file name in .fl file.
int code_file_set;
int write_mergeback_data;
/// Hold the default extension for header files, or the entire filename if set via command line.
Fl_String header_file_name;
/// Hold the default extension for source code files, or the entire filename if set via command line.
Fl_String code_file_name;
};