diff options
Diffstat (limited to 'fluid')
| -rw-r--r-- | fluid/io/Project_Reader.cxx | 7 | ||||
| -rw-r--r-- | fluid/nodes/Function_Node.cxx | 19 | ||||
| -rw-r--r-- | fluid/nodes/Function_Node.h | 10 | ||||
| -rw-r--r-- | fluid/nodes/Node.cxx | 6 | ||||
| -rw-r--r-- | fluid/panels/widget_panel.cxx | 40 | ||||
| -rw-r--r-- | fluid/panels/widget_panel.fl | 48 |
6 files changed, 86 insertions, 44 deletions
diff --git a/fluid/io/Project_Reader.cxx b/fluid/io/Project_Reader.cxx index 0eeee8014..a4c3695d6 100644 --- a/fluid/io/Project_Reader.cxx +++ b/fluid/io/Project_Reader.cxx @@ -320,11 +320,10 @@ Node *Project_Reader::read_children(Node *p, int merge, Strategy strategy, char c = read_word(1); // There can actually be two keywords here. The first one used to be a - // "prefix" in Fluid < 1.5.0, but is no longer supported. So if we still - // find the prefix in files, it will simply be prefixed to the name. + // "prefix", i.e. class attributes. if (strcmp(c,"{") && t->is_class()) { // <prefix> <name> - std::string tmp = std::string {t->name() } + " " + c; - t->name(tmp.c_str()); + ((Class_Node*)t)->prefix( t->name() ); + t->name( c ); c = read_word(1); } diff --git a/fluid/nodes/Function_Node.cxx b/fluid/nodes/Function_Node.cxx index 095b3fc5f..3e98a898f 100644 --- a/fluid/nodes/Function_Node.cxx +++ b/fluid/nodes/Function_Node.cxx @@ -1514,8 +1514,7 @@ Class_Node Class_Node::prototype; Class_Node::Class_Node() : Node(), subclass_of(nullptr), - public_(1), - class_prefix(nullptr) + public_(1) { } /** @@ -1524,8 +1523,6 @@ Class_Node::Class_Node() : Class_Node::~Class_Node() { if (subclass_of) free((void*)subclass_of); - if (class_prefix) - free((void*)class_prefix); } /** @@ -1536,14 +1533,6 @@ int Class_Node::is_public() const { } /** - Set the prefixx string. - */ -void Class_Node::prefix(const char*p) { - free((void*) class_prefix); - class_prefix=fl_strdup(p ? p : "" ); -} - -/** Make a new class node. \param[in] strategy add after current or as last child \return new Class node @@ -1559,7 +1548,7 @@ Node *Class_Node::make(Strategy strategy) { } Class_Node *o = new Class_Node(); o->name("UserInterface"); - o->class_prefix = nullptr; + o->prefix(""); o->subclass_of = nullptr; o->public_ = 1; o->add(anchor, strategy); @@ -1615,8 +1604,8 @@ void Class_Node::write_code1(fld::io::Code_Writer& f) { write_public_state = 0; f.write_h("\n"); write_comment_h(f); - if (prefix() && strlen(prefix())) - f.write_h("class %s %s ", prefix(), name()); + if (!prefix().empty()) + f.write_h("class %s %s ", prefix().c_str(), name()); else f.write_h("class %s ", name()); if (subclass_of) f.write_h(": %s ", subclass_of); diff --git a/fluid/nodes/Function_Node.h b/fluid/nodes/Function_Node.h index 56a0046e0..282f33312 100644 --- a/fluid/nodes/Function_Node.h +++ b/fluid/nodes/Function_Node.h @@ -34,6 +34,8 @@ #include <stdarg.h> #include <stdlib.h> +#include <string> + extern class Class_Node *current_class; int has_toplevel_function(const char *rtype, const char *sig); @@ -271,7 +273,7 @@ public: private: const char* subclass_of; char public_; - const char* class_prefix; + std::string prefix_; public: Class_Node(); ~Class_Node(); @@ -298,8 +300,10 @@ public: void visibility(char v) { public_ = v; } // class prefix attribute access - void prefix(const char* p); - const char* prefix() const {return class_prefix;} + /** Set the text between `class` and the class name */ + void prefix(const std::string& p) { prefix_ = p; } + /** Get the text between `class` and the class name */ + std::string prefix() const { return prefix_; } }; #endif // FLUID_NODES_FUNCTION_NODE_H diff --git a/fluid/nodes/Node.cxx b/fluid/nodes/Node.cxx index 0b1cb2d4d..7557e61f4 100644 --- a/fluid/nodes/Node.cxx +++ b/fluid/nodes/Node.cxx @@ -889,9 +889,9 @@ void Node::write(fld::io::Project_Writer &f) { f.write_word(type_name()); if (is_class()) { - const char * p = ((Class_Node*)this)->prefix(); - if (p && strlen(p)) - f.write_word(p); + auto p = ((Class_Node*)this)->prefix(); + if (!p.empty()) + f.write_word(p.c_str()); } f.write_word(name()); diff --git a/fluid/panels/widget_panel.cxx b/fluid/panels/widget_panel.cxx index 5bbde2fec..5556a19fa 100644 --- a/fluid/panels/widget_panel.cxx +++ b/fluid/panels/widget_panel.cxx @@ -31,6 +31,7 @@ #include <FL/fl_ask.H> #include <FL/Fl_Menu_Item.H> #include <FL/Fl_File_Chooser.H> +#include <ctype.h> #define ZERO_ENTRY 1000 extern const char* when_symbol_name(int n); extern void set_whenmenu(int n); @@ -2636,11 +2637,10 @@ static void cb_Attribute(Fl_Input* o, void* v) { Class_Node* nd = (Class_Node*)current_node; if (v == LOAD) { - o->value( nd->prefix() ); + o->value( nd->prefix().c_str() ); } else { - const char *nn = nd->prefix(); - if ( ( nn && (strcmp(nn, o->value()) != 0)) - || (!nn && (strcmp("", o->value()) != 0)) ) + auto nn = nd->prefix(); + if (nn != o->value()) { nd->prefix( o->value() ); Fluid.proj.set_modflag(1); @@ -2657,13 +2657,37 @@ static void cb_Class(Fl_Input* o, void* v) { o->value( nd->name() ); } else { const char *nn = nd->name(); - if ( ( nn && (strcmp(nn, o->value()) != 0)) - || (!nn && (strcmp("", o->value()) != 0)) ) + char *nv = strdup( o->value() ); + // There is an inconsistency in the project file reader, so this string + // must not coantain anything but alphanumeric and underscore characters. + char *s = (char*)nv; + char *d = (char*)nv; + while (*s) { + if (isalnum((unsigned char)*s) || *s == '_') { + *d++ = *s; + } + s++; + } + *d = 0; + // The class name must not be empty either + if (*nv == 0) { + free((void*)nv); + nv = strdup("MyClass"); + } + // The class name may have changed, so update the widget + o->value( nv ); + // Now copy the new name into the node if it changed + if ( ( nn && (strcmp(nn, nv) != 0)) + || (!nn && (strcmp("", nv) != 0)) ) { - nd->name( o->value() ); + nd->name( nv ); Fluid.proj.set_modflag(1); redraw_browser(); } + // Don't forget to clean up + if (nv) { + free((void*)nv); + } } } @@ -3239,6 +3263,7 @@ Fl_Double_Window* make_widget_panel() { widget_tabs->labelcolor(FL_BACKGROUND2_COLOR); widget_tabs->callback((Fl_Callback*)cb_widget_tabs); widget_tabs->when(FL_WHEN_NEVER); + widget_tabs->hide(); { wp_gui_tab = new Fl_Group(10, 30, 400, 330, "GUI"); wp_gui_tab->labelsize(11); wp_gui_tab->callback((Fl_Callback*)propagate_load); @@ -4326,7 +4351,6 @@ Fl_Double_Window* make_widget_panel() { class_tabs->labelsize(11); class_tabs->labelcolor(FL_WHITE); class_tabs->callback((Fl_Callback*)cb_class_tabs); - class_tabs->hide(); { class_tabs_main = new Fl_Group(10, 30, 400, 330, "Class"); class_tabs_main->labelsize(11); class_tabs_main->callback((Fl_Callback*)propagate_load); diff --git a/fluid/panels/widget_panel.fl b/fluid/panels/widget_panel.fl index beba75690..17c545d15 100644 --- a/fluid/panels/widget_panel.fl +++ b/fluid/panels/widget_panel.fl @@ -80,6 +80,9 @@ decl {\#include <FL/Fl_Menu_Item.H>} {private global decl {\#include <FL/Fl_File_Chooser.H>} {private global } +decl {\#include <ctype.h>} {selected private global +} + decl {\#define ZERO_ENTRY 1000} {private global } @@ -486,8 +489,8 @@ Function {make_widget_panel()} { } { Fl_Tabs widget_tabs { callback {if (current_widget) - propagate_load((Fl_Group *)o,v);} selected - xywh {10 10 400 350} selection_color 12 labelsize 11 labelcolor 7 when 0 + propagate_load((Fl_Group *)o,v);} + xywh {10 10 400 350} selection_color 12 labelsize 11 labelcolor 7 when 0 hide code0 {o->show();} } { Fl_Group wp_gui_tab { @@ -2972,8 +2975,8 @@ if (v == LOAD) { } Fl_Tabs class_tabs { callback {if (current_node && current_node->is_a(Type::Class)) - propagate_load((Fl_Group *)o,v);} - xywh {10 10 400 350} selection_color 12 labelsize 11 labelcolor 255 hide + propagate_load((Fl_Group *)o,v);} open + xywh {10 10 400 350} selection_color 12 labelsize 11 labelcolor 255 } { Fl_Group class_tabs_main { label Class @@ -3032,11 +3035,10 @@ if (v == LOAD) { Class_Node* nd = (Class_Node*)current_node; if (v == LOAD) { - o->value( nd->prefix() ); + o->value( nd->prefix().c_str() ); } else { - const char *nn = nd->prefix(); - if ( ( nn && (strcmp(nn, o->value()) != 0)) - || (!nn && (strcmp("", o->value()) != 0)) ) + auto nn = nd->prefix(); + if (nn != o->value()) { nd->prefix( o->value() ); Fluid.proj.set_modflag(1); @@ -3054,13 +3056,37 @@ if (v == LOAD) { o->value( nd->name() ); } else { const char *nn = nd->name(); - if ( ( nn && (strcmp(nn, o->value()) != 0)) - || (!nn && (strcmp("", o->value()) != 0)) ) + char *nv = strdup( o->value() ); + // There is an inconsistency in the project file reader, so this string + // must not coantain anything but alphanumeric and underscore characters. + char *s = (char*)nv; + char *d = (char*)nv; + while (*s) { + if (isalnum((unsigned char)*s) || *s == '_') { + *d++ = *s; + } + s++; + } + *d = 0; + // The class name must not be empty either + if (*nv == 0) { + free((void*)nv); + nv = strdup("MyClass"); + } + // The class name may have changed, so update the widget + o->value( nv ); + // Now copy the new name into the node if it changed + if ( ( nn && (strcmp(nn, nv) != 0)) + || (!nn && (strcmp("", nv) != 0)) ) { - nd->name( o->value() ); + nd->name( nv ); Fluid.proj.set_modflag(1); redraw_browser(); } + // Don't forget to clean up + if (nv) { + free((void*)nv); + } }} tooltip {class name, must be a single C++ keyword} xywh {95 75 305 20} labelfont 1 labelsize 11 textfont 4 textsize 11 } |
