31 #include <sys/types.h>
40 "Species",
"Organism",
"Gene",
"Experiment",
44 #define SEC_XBORDER 3 // space left/right of NEW_SECTION line
45 #define SEC_YBORDER 4 // space above/below
46 #define SEC_LINE_WIDTH 1 // line width
48 #define MIN_TEXTFIELD_SIZE 1
49 #define MAX_TEXTFIELD_SIZE 1000
51 #define AWT_SCOPE_LOCAL 0
52 #define AWT_SCOPE_GLOBAL 1
59 #define AWAR_INPUT_MASK_BASE "tmp/inputMask"
60 #define AWAR_INPUT_MASK_NAME AWAR_INPUT_MASK_BASE"/name"
61 #define AWAR_INPUT_MASK_ITEM AWAR_INPUT_MASK_BASE"/item"
62 #define AWAR_INPUT_MASK_SCOPE AWAR_INPUT_MASK_BASE"/scope"
63 #define AWAR_INPUT_MASK_HIDDEN AWAR_INPUT_MASK_BASE"/hidden"
65 #define AWAR_INPUT_MASKS_EDIT_ENABLED AWAR_INPUT_MASK_BASE"/edit_enabled"
122 string awt_input_mask_global::generate_id(
const string& mask_name_) {
124 result.reserve(mask_name_.length());
125 for (string::const_iterator p = mask_name_.begin(); p != mask_name_.end(); ++p) {
126 if (isalnum(*p)) result.append(1, *p);
127 else result.append(1,
'_');
133 return !test_edit_enabled ||
139 awt_itemtype_names[get_itemtype()]));
150 if (!lookup(name))
return GBS_global_string(
"ID '%s' does not exist", name.c_str());
194 const char *root_name;
196 if (saved_with_properties) root_name =
"/input_masks";
197 else root_name =
"/tmp/input_masks";
201 printf(
"awarName='%s'\n", awarName.c_str());
220 is_global(is_global_)
227 string awt_script::get_value()
const {
229 AW_root *root = mask_global().get_root();
250 result =
"<undefined>";
257 GB_ERROR awt_script::set_value(
const string& ) {
258 return GBS_global_string(
"You cannot assign a value to script '%s'", has_name() ? get_name().c_str() :
"<unnamed>");
273 awt_script_viewport::awt_script_viewport(
awt_input_mask_global& global_,
const awt_script *script_,
const string& label_,
long field_width_) :
276 field_width(field_width_)
279 awt_script_viewport::~awt_script_viewport() {
287 remove_awarItem_callbacks();
290 remove_db_callbacks();
295 set_item(gb_new_item);
297 error = add_db_callbacks();
300 add_awarItem_callbacks();
305 void awt_script_viewport::build_widget(
AW_window *aws) {
306 const string& lab = get_label();
307 if (lab.length()) aws->
label(lab.c_str());
312 void awt_script_viewport::db_changed() {
314 string current_value = script->get_value();
320 void awt_script_viewport::awar_changed() {
321 aw_message(
"It makes no sense to change the result of a script");
324 GB_ERROR awt_input_handler::add_db_callbacks() {
329 void awt_input_handler::remove_db_callbacks() {
337 awt_viewport(global_, generate_baseName(global_, child_path_),
"",
false, label_),
339 child_path(child_path_),
345 in_destructor =
true;
356 remove_db_callbacks();
364 if (!gb_new_item && !in_destructor) {
368 if (!error && gb_new_item) {
374 error = add_db_callbacks();
385 bool relink_me =
false;
390 if (!
mask_global().edit_allowed()) error =
"Editing is disabled. Check the 'Enable edit' switch!";
392 if (!error && !gbdata) {
413 awt_itemtype_names[
mask_global().get_itemtype()]));
417 if (!error && gbdata) {
457 if (lab.length()) aws->
label(lab.c_str());
464 if (lab.length()) aws->
label(lab.c_str());
471 if (lab.length()) aws->
label(lab.c_str());
486 vector<string>::const_iterator b = buttons.begin();
487 vector<string>::const_iterator v = values.begin();
490 for (; b != buttons.end() && v != values.end(); ++b, ++v, ++pos) {
491 void (
AW_window::*ins_togg)(
const char*,
const char*,
const char*);
499 awt_assert(b == buttons.end() && v == values.end());
510 if (awar_content ==
"yes") {
520 if (db_content ==
"yes" || db_content ==
"1")
return "yes";
521 if (db_content ==
"no" || db_content ==
"0")
return "no";
522 return atoi(db_content.c_str()) ?
"yes" :
"no";
526 vector<string>::const_iterator b = buttons.begin();
527 vector<string>::const_iterator v = values.begin();
528 for (; b != buttons.end() && v != values.end(); ++b, ++v) {
529 if (*b == awar_content) {
534 return string(
"Unknown awar_content '")+awar_content+
"'";
538 vector<string>::const_iterator b = buttons.begin();
539 vector<string>::const_iterator v = values.begin();
540 for (; b != buttons.end() && v != values.end(); ++b, ++v) {
541 if (*v == db_content) {
545 return buttons[default_position];
549 long val = strtol(awar_content.c_str(),
NULp, 10);
552 if (val<min) val = min;
553 if (val>max) val = max;
564 char *res = fgets(&buffer[0], BUFSIZE-1, in);
567 if (
int err = ferror(in)) {
568 error = strerror(err);
571 error =
"Unexpected end of file (@MASK_BEGIN or @MASK_END missing?)";
575 res += strlen(buffer);
578 if (buffer[last-1] ==
'\n') {
585 size_t last = line.find_last_not_of(
" \t");
586 if (last != string::npos && line[last] ==
'\\') {
589 line = line.substr(0, last)+
' '+next;
593 if (error) line =
"";
599 if (start == string::npos)
return string::npos;
600 return line.find_first_not_of(
" \t", start);
608 if (para_sep == string::npos) {
609 error =
"',' or ')' expected after parameter";
612 switch (line[para_sep]) {
614 was_last_parameter =
true;
621 error =
"',' or ')' expected after parameter";
624 if (!error) para_sep++;
631 if (!error && !was_last_parameter) {
640 if (start == string::npos) {
641 error =
"')' expected";
643 else if (line[start] !=
')') {
644 was_last_parameter =
false;
653 string::iterator f = s.begin();
654 string::iterator t = s.begin();
656 for (; f != s.end(); ++f, ++t) {
677 scan_pos = open_quote;
679 if (open_quote == string::npos || line[open_quote] !=
'\"') {
680 error =
"string parameter expected";
683 size_t close_quote = string::npos;
686 size_t start = open_quote+1;
689 close_quote = line.find_first_of(
"\\\"", start);
691 if (close_quote == string::npos)
break;
692 if (line[close_quote] ==
'\"')
break;
694 if (line[close_quote] ==
'\\') {
697 start = close_quote+1;
701 close_quote = line.find(
'\"', open_quote+1);
704 if (close_quote == string::npos) {
705 error =
"string parameter missing closing '\"'";
708 result = line.substr(open_quote+1, close_quote-open_quote-1);
720 #if (GCC_VERSION_CODE >= 901) && (GCC_VERSION_CODE <= 905) // (please do not activate for all future versions, test each of them)
721 # define GCC_ARRAY_BOUNDS_FALSE_POSITIVE
723 #if (GCC_VERSION_CODE >= 1001) && (GCC_VERSION_CODE <= 1005) // (please do not activate for all future versions, test each of them)
724 # define GCC_ARRAY_BOUNDS_FALSE_POSITIVE
727 #ifdef GCC_ARRAY_BOUNDS_FALSE_POSITIVE
728 # pragma GCC diagnostic push
729 # pragma GCC diagnostic ignored "-Warray-bounds"
735 for (
int i = 0; allowed_keywords[i]; ++i) {
737 if (allowed_keywords[i+1]) result +=
", ";
738 else result +=
" or ";
740 result += allowed_keywords[i];
745 #ifdef GCC_ARRAY_BOUNDS_FALSE_POSITIVE
746 # pragma GCC diagnostic pop
749 inline int isKeyword(
const char *current,
const char *keyword) {
751 for (; keyword[pos]; ++pos) {
752 if (!current[pos] || std::tolower(current[pos]) != std::tolower(keyword[pos])) {
768 if (start == string::npos) {
774 const char *current = line.c_str()+
start;
777 for (; allowed_keywords[i]; ++i) {
778 int found_keyword_size =
isKeyword(current, allowed_keywords[i]);
779 if (found_keyword_size) {
781 scan_pos += found_keyword_size;
785 if (!allowed_keywords[i])
goto EXPECTED;
793 string& string_para,
int& keyword_index,
794 const char **allowed_keywords) {
807 if (keyword_index == -1) {
820 while (start != string::npos) {
821 char c = line[
start];
822 if (c !=
'+' && c !=
'-')
break;
825 if (c ==
'-') neg = !neg;
829 if (start == string::npos || !isdigit(line[start])) {
831 error =
"digits (or+-) expected";
834 size_t end = line.find_first_not_of(
"0123456789", start);
838 result = atoi(line.substr(start, end-start+1).c_str());
842 return neg ? -result :
result;
847 size_t old_scan_pos = scan_pos;
850 if (result<min || result>max) {
851 scan_pos = old_scan_pos;
852 error =
GBS_global_string(
"value %li is outside allowed range (%li-%li)", result, min, max);
860 size_t old_scan_pos = scan_pos;
864 scan_pos = old_scan_pos;
868 error =
"expected number or empty parameter";
869 scan_pos = old_scan_pos;
886 if (start == string::npos) {
890 char found = line[
start];
891 char upper_found = std::toupper(found);
892 size_t pos = allowed_flags.find(upper_found);
894 if (pos != string::npos) {
899 error =
GBS_global_string(
"One of '%s' expected (found '%c')", allowed_flags.c_str(), found);
906 size_t old_scan_pos = scan_pos;
909 if (!error && (result != 0) && (result != 1)) {
910 scan_pos = old_scan_pos;
911 error =
"'0' or '1' expected";
919 if (start == string::npos) {
920 error =
"identifier expected";
924 while (end<line.length()) {
926 if (!(isalnum(c) || c ==
'_'))
break;
929 id = line.substr(start, end-start);
937 static char *local_mask_dir;
939 return local_mask_dir;
942 static char *global_mask_dir;
944 return global_mask_dir;
949 return string(dir)+
'/'+mask_name;
952 #define ARB_INPUT_MASK_ID "ARB-Input-Mask"
954 static awt_input_mask_descriptor *
quick_scan_input_mask(
const string& mask_name,
const string& filename,
bool local) {
955 awt_input_mask_descriptor *res =
NULp;
956 FILE *in = fopen(filename.c_str(),
"rt");
975 if (line[0] ==
'#')
continue;
976 if (line ==
"@MASK_BEGIN") { done =
true;
break; }
978 size_t at = line.find(
'@');
979 size_t eq = line.find(
'=', at);
981 if (at == string::npos || eq == string::npos) {
985 string parameter = line.substr(at+1, eq-at-1);
986 string value = line.substr(eq+1);
988 if (parameter ==
"ITEMTYPE") itemtype = value;
989 else if (parameter ==
"TITLE") title = value;
990 else if (parameter ==
"HIDE") hidden = atoi(value.c_str());
994 if (!error && done) {
995 if (itemtype ==
"") {
996 error =
"No itemtype defined";
999 if (title ==
"") title = mask_name;
1000 res =
new awt_input_mask_descriptor(title.c_str(), mask_name.c_str(), itemtype.c_str(), local, hidden);
1005 fprintf(stderr,
"Skipping '%s' (not a input mask)\n", filename.c_str());
1050 return s[0] ==
'0' || s[0] ==
'1';
1054 InputMaskList::iterator mask_iter = input_mask_list.find(*internal_mask_name);
1059 if (mask_iter != input_mask_list.end()) {
1060 awt_input_mask_ptr mask = mask_iter->second;
1063 printf(
"aww=%p root=%p ; global=%p root=%p\n", aww, aww->
get_root(), &global, global.
get_root());
1066 if (reload) mask->set_reload_on_reinit(
true);
1067 if (hide_current) mask->hide();
1072 if (error && hide_current) {
1073 mask_iter = input_mask_list.find(*internal_mask_name);
1074 awt_assert(mask_iter != input_mask_list.end());
1075 mask_iter->second->show();
1080 string mask_name = internal_mask_name->substr(1);
1081 printf(
"'%s' (no such mask in input_mask_list)\n", mask_name.c_str());
1128 const awt_mask_item *item_source =
mask->mask_global().get_identified_item(id_source, error);
1129 awt_mask_item *item_dest =
mask->mask_global().get_identified_item(id_dest, error);
1136 awt_assignment(awt_input_mask_ptr mask_,
const string& id_dest_,
const string& id_source_) :
1139 id_source(id_source_)
1223 if (mask_command[mc].cmd_name == cmd_name) {
1224 return mask_command[mc].
cmd;
1233 string label, data_path;
1234 int default_position = -1, orientation = -1;
1235 vector<string> buttons;
1236 vector<string> values;
1237 bool allow_edit =
false;
1239 int edit_position = -1;
1246 orientation = orientation&1;
1248 while (!error && !was_last_parameter) {
1253 const char *allowed_keywords[] = {
"ALLOW_EDIT",
NULp };
1257 if (keyword_index != -1) {
1258 if (allow_edit) error =
"ALLOW_EDIT is allowed only once for each RADIO";
1265 edit_position = buttons.size()+1;
1266 buttons.push_back(but);
1267 values.push_back(val);
1271 buttons.push_back(but);
1272 values.push_back(val);
1279 if (!error && (buttons.size()<2)) error =
"You have to define at least 2 buttons.";
1281 if (!error && allow_edit && edit_position != default_position) {
1282 error =
GBS_global_string(
"Invalid default %i (must be index of ALLOW_EDIT: %i )", default_position, edit_position);
1284 if (!error && (default_position<1 ||
size_t(default_position)>buttons.size())) {
1285 error =
GBS_global_string(
"Invalid default %i (valid: 1..%zu)", default_position, buttons.size());
1291 handler1 =
new awt_radio_button(global, data_path, label, default_position-1, orientation, buttons, values);
1295 handler1 =
new awt_radio_button(global, data_path, label, default_position-1, orientation, buttons, values);
1301 const char *internal_local =
NULp;
1302 const char *internal_global =
NULp;
1304 for (
int id = 0; ; ++
id) {
1306 if (!descriptor)
break;
1308 const char *internal_name = descriptor->get_internal_maskname();
1310 if (strcmp(internal_name+1, mask_name.c_str()) == 0) {
1311 if (descriptor->is_local_mask()) {
1313 internal_local = internal_name;
1317 internal_global = internal_name;
1322 return (search_in_local && internal_local) ? internal_local : null2empty(internal_global);
1345 void db_changed() OVERRIDE;
1354 remove_awarItem_callbacks();
1357 remove_db_callbacks();
1362 set_item(gb_new_item);
1364 error = add_db_callbacks();
1367 add_awarItem_callbacks();
1371 void awt_marked_checkbox::awar_changed() {
1373 string value = get_value();
1374 bool marked = value ==
"yes";
1379 mask_global().no_item_selected();
1383 void awt_marked_checkbox::db_changed() {
1390 void awt_marked_checkbox::build_widget(
AW_window *aws) {
1391 const string& lab = get_label();
1392 if (lab.length()) aws->
label(lab.c_str());
1394 aws->create_toggle(awar_name().c_str());
1398 FILE *out = fopen(fullname.c_str(),
"wt");
1403 "# New mask '%s'\n\n"
1404 "# What kind of item to edit:\n"
1407 "@TITLE=%s\n\n",
ARB_INPUT_MASK_ID, maskname.c_str(), itemtypename.c_str(), maskname.c_str());
1410 "# Should mask appear in 'User mask' menu\n"
1411 "@HIDE=%i\n\n",
int(hidden));
1413 fputs(
"# Spacing in window:\n"
1416 "# Show edit/reload button?\n"
1418 "# Show 'edit enable' toggle?\n"
1420 "# Show 'marked' toggle?\n"
1422 "\n# ---------------------------\n"
1423 "# The definition of the mask:\n\n"
1425 " TEXT(\"You are editing\") SELF()\n"
1427 " TEXTFIELD(\"Full name\", \"full_name\", 30)\n\n"
1428 "@MASK_END\n\n", out);
1440 bool is_known(
const string&
id) {
return seen.find(
id) != seen.end(); }
1442 string makeUnique(
string id) {
1445 for (
int i = 0; ; ++i) {
1447 if (!is_known(undup)) {
1459 : reloading(reloading_)
1463 curr_id = makeUnique(
id);
1464 return reloading ?
NULp : curr_id.c_str();
1474 for (set<string>::iterator d = dup.begin(); d != dup.end(); ++d) {
1475 dupList = dupList+
" '"+*d+
"'";
1479 "(they need to be unique; change button texts etc. to change them)",
1480 maskName.c_str(), dupList.c_str());
1485 const string& mask_name,
bool local,
GB_ERROR& error,
bool reloading) {
1486 awt_input_mask_ptr mask;
1493 in = fopen(fullfile.c_str(),
"rt");
1498 bool mask_began =
false;
1499 bool mask_ended =
false;
1503 string itemtypename;
1506 bool edit_reload =
false;
1507 bool edit_enable =
true;
1508 bool show_marked =
true;
1514 error =
readLine(in, line, lineNo);
1520 while (!error && !mask_began && !feof(in)) {
1521 error =
readLine(in, line, lineNo);
1524 if (line[0] ==
'#')
continue;
1526 if (line ==
"@MASK_BEGIN") mask_began =
true;
1528 size_t at = line.find(
'@');
1529 size_t eq = line.find(
'=', at);
1531 if (at == string::npos || eq == string::npos) {
1535 string parameter = line.substr(at+1, eq-at-1);
1536 string value = line.substr(eq+1);
1538 if (parameter ==
"ITEMTYPE") itemtypename = value;
1539 else if (parameter ==
"TITLE") title = value;
1540 else if (parameter ==
"X_SPACING") x_spacing = atoi(value.c_str());
1541 else if (parameter ==
"Y_SPACING") y_spacing = atoi(value.c_str());
1542 else if (parameter ==
"EDIT") edit_reload = atoi(value.c_str()) != 0;
1543 else if (parameter ==
"EDIT_ENABLE") edit_enable = atoi(value.c_str()) != 0;
1544 else if (parameter ==
"SHOW_MARKED") show_marked = atoi(value.c_str()) != 0;
1545 else if (parameter ==
"HIDE") ;
1553 if (!error && !mask_began) error =
"@MASK_BEGIN expected";
1557 if (title ==
"") title =
string(
"Untitled (")+mask_name+
")";
1562 itemtypename.c_str(), awt_itemtype_names[sel->
get_item_type()]);
1565 if (!error) mask =
new awt_input_mask(root, gb_main, mask_name, itemtype, local, sel, edit_enable);
1571 AW_window_simple*& aws = mask->get_window();
1572 aws =
new AW_window_simple;
1578 aws->init(root, window_id, title.c_str());
1582 aws->load_xfig(
NULp,
true);
1585 aws->auto_space(x_spacing, y_spacing);
1588 aws->callback(
AW_POPDOWN); aws->create_button(ID.
fromKey(
"CLOSE"),
"CLOSE",
"C");
1592 aws->callback(makeWindowCallback(
AWT_edit_input_mask, &mask->mask_global().get_maskname(), mask->mask_global().is_local_mask()));
1593 aws->create_button(
NULp,
"!EDIT",
"E");
1595 aws->callback(makeWindowCallback(
AWT_reload_input_mask, &mask->mask_global().get_internal_maskname()));
1596 aws->create_button(
NULp,
"RELOAD",
"R");
1599 if (edit_reload && edit_enable && show_marked) aws->at_newline();
1602 aws->label(
"Enable edit?");
1607 awt_mask_item_ptr handler =
new awt_marked_checkbox(mask->mask_global(),
"Marked");
1608 mask->add_handler(handler);
1609 if (handler->is_viewport()) handler->to_viewport()->build_widget(aws);
1615 vector<int> horizontal_lines;
1616 map<string, size_t> referenced_ids;
1617 map<string, size_t> declared_ids;
1622 while (!error && !mask_ended && !feof(in)) {
1623 error =
readLine(in, line, lineNo);
1626 if (line.empty())
continue;
1627 if (line[0] ==
'#')
continue;
1629 if (line ==
"@MASK_END") {
1633 PARSE_REST_OF_LINE :
1634 was_last_parameter =
false;
1636 if (start != string::npos) {
1637 size_t after_command = line.find_first_of(
string(
" \t("), start);
1638 if (after_command == string::npos) {
1639 string command = line.substr(start);
1643 string command = line.substr(start, after_command-start);
1644 size_t paren_open = line.find(
'(', after_command);
1645 if (paren_open == string::npos) {
1649 size_t scan_pos = paren_open+1;
1658 string label, data_path;
1668 string label, data_path;
1671 long min = LONG_MIN;
1672 long max = LONG_MAX;
1677 if (!was_last_parameter) {
1686 string label, data_path;
1687 bool checked =
false;
1693 if (!error) handler =
new awt_check_box(mask->mask_global(), data_path,
label, checked);
1696 parse_CMD_RADIO(line, scan_pos, error, command, handler, radio_edit_handler, mask->mask_global());
1705 handler =
new awt_script(mask->mask_global(), script);
1706 error = handler->set_name(
id,
false);
1707 declared_ids[
id] = lineNo;
1711 string id, def_value;
1714 bool global_exists = mask->mask_global().has_global_id(
id);
1715 bool local_exists = mask->mask_global().has_local_id(
id);
1718 error =
GBS_global_string(
"ID '%s' already declared as %s ID (rename your local id)",
1719 id.c_str(), cmd ==
CMD_LOCAL ?
"global" :
"local");
1721 else if (cmd ==
CMD_LOCAL && local_exists) {
1728 if (!mask->mask_global().has_global_id(
id)) {
1737 declared_ids[
id] = lineNo;
1740 else if (cmd ==
CMD_ID) {
1745 if (lasthandler.
isNull()) {
1746 error =
"ID() may only be used BEHIND another element";
1749 error = lasthandler->set_name(
id,
false);
1750 declared_ids[
id] = lineNo;
1761 if (!error) item = (
awt_mask_item*)mask->mask_global().get_identified_item(
id, error);
1772 awt_script *script =
dynamic_cast<awt_script*
>(item);
1773 if (script) handler =
new awt_script_viewport(mask->mask_global(), script,
label, width);
1774 else error =
"SHOW cannot be used on this ID-type";
1777 referenced_ids[
id] = lineNo;
1781 string label, mask_to_start;
1789 if (mask_to_start_internal.length() == 0) {
1790 error =
"Can't detect which mask to load";
1793 const char *key = ID.
fromText(label);
1795 string *
const internal_mask_name =
new string(mask->mask_global().get_internal_maskname());
1796 string *
const mask_to_open =
new string(mask_to_start_internal);
1803 aws->button_length(label.length()+2);
1804 aws->create_button(key, label.c_str());
1809 string button_text, url_aci;
1815 const char *key = ID.
fromText(button_text);
1817 aws->button_length(button_text.length()+2);
1818 aws->create_button(key, button_text.c_str());
1822 string id_dest, id_source, button_text;
1829 referenced_ids[id_source] = lineNo;
1830 referenced_ids[id_dest] = lineNo;
1832 const char *key = ID.
fromText(button_text);
1834 aws->button_length(button_text.length()+2);
1835 aws->create_button(key, button_text.c_str());
1844 aws->button_length(text.length()+2);
1845 aws->create_button(
NULp, text.c_str());
1860 aws->get_window_size(width, height);
1868 aws->get_window_size(width, height);
1869 horizontal_lines.push_back(height);
1885 if (!radio_edit_handler.
isNull()) {
1889 int x_start, y_start;
1891 aws->get_at_position(&x_start, &y_start);
1893 mask->add_handler(handler);
1894 handler->to_viewport()->build_widget(aws);
1896 int x_end, y_end, dummy;
1897 aws->get_at_position(&x_end, &dummy);
1899 aws->get_at_position(&dummy, &y_end);
1901 int height = y_end-y_start;
1905 aws->at(x_end+x_spacing, y_start+y_offset);
1907 mask->add_handler(radio_edit_handler);
1908 radio_edit_handler->to_viewport()->build_widget(aws);
1913 mask->add_handler(handler);
1914 if (handler->is_viewport()) handler->to_viewport()->build_widget(aws);
1916 lasthandler = handler;
1921 line = line.substr(scan_pos);
1922 goto PARSE_REST_OF_LINE;
1925 if (err_pos != string::npos) err_pos++;
1937 for (map<string, size_t>::const_iterator r = referenced_ids.begin(); r != referenced_ids.end(); ++r) {
1938 if (declared_ids.find(r->first) == declared_ids.end()) {
1939 error =
GBS_global_string(
"ID '%s' used in line #%zu was not declared", r->first.c_str(), r->second);
1944 for (map<string, size_t>::const_iterator d = declared_ids.begin(); d != declared_ids.end(); ++d) {
1945 if (referenced_ids.find(d->first) == referenced_ids.end()) {
1947 d->first.c_str(), d->second, mask_name.c_str());
1952 if (error) error =
"Inconsistent IDs";
1956 if (!horizontal_lines.empty()) {
1958 aws->get_window_size(width, height);
1959 for (vector<int>::const_iterator yi = horizontal_lines.begin(); yi != horizontal_lines.end(); ++yi) {
1977 else if (err_pos == 0) {
1980 else if (err_pos == string::npos) {
1985 size_t end = line.length();
1987 context.reserve(wanted);
1988 bool last_was_space =
false;
1990 for (
size_t ex = err_pos-1; ex<end && wanted>0; ++ex) {
1992 bool this_is_space = ch ==
' ';
1994 if (!this_is_space || !last_was_space) {
1995 context.append(1, ch);
1998 last_was_space = this_is_space;
2001 error =
GBS_global_string(
"%s in line #%zu at '%s...'", error, lineNo, context.c_str());
2014 const char *mask_name = internal_mask_name+1;
2015 InputMaskList::iterator mask_iter = input_mask_list.find(internal_mask_name);
2017 awt_input_mask_ptr old_mask;
2018 bool unlink_old =
false;
2020 if (mask_iter != input_mask_list.end() && mask_iter->second->reload_on_reinit()) {
2022 old_mask = mask_iter->second;
2023 input_mask_list.erase(mask_iter);
2024 mask_iter = input_mask_list.end();
2030 if (mask_iter == input_mask_list.end()) {
2031 awt_input_mask_ptr newMask =
awt_create_input_mask(root, gb_main, sel, mask_name, local, error, unlink_old);
2034 if (!old_mask.
isNull()) {
2035 input_mask_list[internal_mask_name] = old_mask;
2040 input_mask_list[internal_mask_name] = newMask;
2042 mask_iter = input_mask_list.find(internal_mask_name);
2046 awt_assert(mask_iter != input_mask_list.end());
2047 mask_iter->second->get_window()->activate();
2061 awt_input_mask::~awt_input_mask() {
2063 for (awt_mask_item_list::iterator h = handlers.begin(); h != handlers.end(); ++h) {
2064 (*h)->remove_name();
2068 void awt_input_mask::link_to(
GBDATA *gb_item) {
2070 for (awt_mask_item_list::iterator h = handlers.begin(); h != handlers.end(); ++h) {
2071 if ((*h)->is_linked_item()) (*h)->to_linked_item()->link_to(gb_item);
2078 awt_input_mask_descriptor::awt_input_mask_descriptor(
const char *title_,
const char *maskname_,
const char *itemtypename_,
bool local,
bool hidden_) {
2080 internal_maskname = ARB_alloc<char>(strlen(maskname_)+2);
2081 internal_maskname[0] = local ?
'0' :
'1';
2082 strcpy(internal_maskname+1, maskname_);
2087 awt_input_mask_descriptor::~awt_input_mask_descriptor() {
2089 free(internal_maskname);
2093 awt_input_mask_descriptor::awt_input_mask_descriptor(
const awt_input_mask_descriptor& other) {
2095 internal_maskname =
ARB_strdup(other.internal_maskname);
2096 itemtypename =
ARB_strdup(other.itemtypename);
2097 local_mask = other.local_mask;
2098 hidden = other.hidden;
2100 awt_input_mask_descriptor& awt_input_mask_descriptor::operator = (
const awt_input_mask_descriptor& other) {
2101 if (
this != &other) {
2103 free(internal_maskname);
2107 internal_maskname =
ARB_strdup(other.internal_maskname);
2108 itemtypename =
ARB_strdup(other.itemtypename);
2109 local_mask = other.local_mask;
2110 hidden = other.hidden;
2122 existing_masks.push_back(*descriptor);
2129 for (
int scope = 0; scope <= 1; ++scope) {
2139 DIR *dirp = opendir(dirname);
2141 fprintf(stderr,
"Warning: No such directory '%s'\n", dirname);
2145 for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
2147 string maskname = dp->d_name;
2150 if (stat(fullname.c_str(), &st))
continue;
2151 if (!S_ISREG(st.st_mode))
continue;
2154 size_t ext_pos = maskname.find(
".mask");
2156 if (ext_pos != string::npos && maskname.substr(ext_pos) ==
".mask") {
2159 existing_masks.push_back(*descriptor);
2167 scanned_existing_input_masks =
true;
2173 if (
id<0 ||
size_t(
id) >= existing_masks.size())
return NULp;
2175 const awt_input_mask_descriptor *descriptor = &existing_masks[
id];
2183 if (itemtype_name == awt_itemtype_names[i]) {
2203 open_window_cb(
NULp)
2207 open_window_cb(open_window_cb_)
2220 TypeRegistryIter
registered = registeredTypes.find(type);
2223 if (registered == registeredTypes.end()) error =
GBS_global_string(
"Type '%s' not registered (yet)", awt_itemtype_names[type]);
2224 else registered->second.getOpenCb()(registered->second.getWindow(), mask_id,
NULp);
2230 TypeRegistryIter alreadyRegistered = registeredTypes.find(type);
2231 if (alreadyRegistered == registeredTypes.end()) {
2236 awt_assert(alreadyRegistered->second.getOpenCb() == open_window_cb);
2249 size_t ext = maskname.find(
".mask");
2251 if (ext == string::npos) maskname = maskname+
".mask";
2252 else maskname = maskname.substr(0, ext)+
".mask";
2263 bool openMask =
false;
2265 const char *error =
NULp;
2268 if (stat(maskfullname.c_str(), &st) == 0) {
2269 int answer =
aw_question(
"overwrite_mask",
"File does already exist",
"Overwrite mask,Cancel");
2289 if (!error && openMask) {
2293 for (mask_id = 0; ; ++mask_id) {
2296 error =
GBS_global_string(
"Can't find descriptor for mask '%s'", maskname.c_str());
2300 if (strcmp(descriptor->get_maskname(), maskname.c_str()) == 0 &&
2301 descriptor->is_local_mask() == local)
2317 static AW_window_simple *aws =
NULp;
2320 aws =
new AW_window_simple;
2322 aws->init(aww->
get_root(),
"CREATE_USER_MASK",
"Create new input mask:");
2324 aws->auto_space(10, 10);
2326 aws->button_length(10);
2328 aws->create_button(
"CLOSE",
"CLOSE");
2330 aws->create_button(
"HELP",
"HELP",
"H");
2334 aws->label(
"Name of new input mask");
2339 aws->label(
"Item type");
2342 aws->insert_option(awt_itemtype_names[i],
"", awt_itemtype_names[i]);
2344 aws->update_option_menu();
2351 aws->update_toggle_field();
2356 aws->insert_toggle(
"Normal",
"N", 0);
2357 aws->insert_toggle(
"Hidden",
"H", 1);
2358 aws->update_toggle_field();
2363 aws->create_button(
"CREATE",
"CREATE",
"C");
2379 char lc = tolower(c);
2380 char *cand = strchr(availableMnemonics, lc);
2382 char *last = strchr(cand+1, 0)-1;
2401 bool prevWasChar =
false;
2402 for (
int startOfWord = 1; startOfWord>=0; --startOfWord) {
2403 for (
int i = 0; orgTitle[i]; ++i) {
2404 char c = orgTitle[i];
2406 if (!prevWasChar || !startOfWord) {
2414 else prevWasChar =
false;
2418 for (
int i = 0; i<2; ++i) {
2419 const char *takeAny = i ? availableMnemonics :
"1234567890";
2420 for (
int t = 0; takeAny[t]; ++t) {
2421 char c = takeAny[t];
2441 char *availableMnemonics =
ARB_strdup(
"abcdefghijklmopqrstuvwxyz0123456789");
2443 for (
int scope = 0; scope <= 1; ++scope) {
2444 bool entries_made =
false;
2446 for (
int id = 0; ; ++
id) {
2449 if (!descriptor)
break;
2450 if (descriptor->is_local_mask() != (scope ==
AWT_SCOPE_LOCAL))
continue;
2454 if (item_type == wanted_item_type) {
2455 if (!descriptor->is_hidden()) {
2456 entries_made =
true;
2457 char *macroname2key =
GBS_string_2_key(descriptor->get_internal_maskname());
2458 #if defined(DEBUG) && 0
2459 printf(
"added user-mask '%s' with id=%i\n", descriptor->get_maskname(),
id);
2462 char *mod_title =
selectMnemonic(descriptor->get_title(), availableMnemonics, mnemonic[0]);
2464 awm->
insert_menu_topic(macroname2key, mod_title, mnemonic,
"input_mask.hlp",
AWM_ALL, makeWindowCallback(open_mask_window_cb,
id, gb_main));
2466 free(macroname2key);
2471 aw_message(
GBS_global_string(
"Unknown @ITEMTYPE '%s' in '%s'", descriptor->get_itemtypename(), descriptor->get_internal_maskname()));
2478 const char *itemname = awt_itemtype_names[wanted_item_type];
2484 free(new_item_mask_label);
2485 free(new_item_mask_id);
2487 free(availableMnemonics);
2494 for (InputMaskList::iterator i = input_mask_list.begin();
2495 i != input_mask_list.end();
2498 i->second->unlink();
2500 input_mask_list.clear();
const awt_input_mask_global & mask_global() const
GB_ERROR GBT_add_new_changekey_to_keypath(GBDATA *gb_main, const char *name, GB_TYPES type, const char *keypath)
virtual const char * get_self_awar() const =0
void insert_toggle(AW_label toggle_label, const char *mnemonic, const char *var_value)
GB_ERROR relink() OVERRIDE
awt_item_type get_item_type() const
void GB_warning(const char *message)
GB_CSTR GB_path_in_arbprop(const char *relative_path)
virtual void db_changed()=0
virtual size_t get_self_awar_content_length() const =0
const std::string & get_name() const
return string(buffer, length)
void insert_menu_topic(const char *id, const char *name, const char *mnemonic, const char *help_text_, AW_active mask, const WindowCallback &wcb)
GB_ERROR GB_add_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
virtual void build_widget(AW_window *aws)=0
void AW_edit(const char *path)
virtual GB_ERROR add_db_callbacks()
ID_checker(bool reloading_)
char * ARB_strdup(const char *str)
GB_ERROR awt_open_ACI_URL_with_item(AW_root *aw_root, GBDATA *gb_main, GBDATA *gb_item, const char *url_aci)
char * GB_read_as_string(GBDATA *gbd)
awt_marked_checkbox(awt_input_mask_global &global_, const std::string &label_)
void set_item(GBDATA *new_item)
const char * GBS_global_string(const char *templat,...)
void warning(int warning_num, const char *warning_message)
void AW_POPDOWN(AW_window *window)
const std::string & get_label() const
char * GBS_string_2_key(const char *str)
bool isNull() const
test if SmartPtr is NULp
void add_awarItem_callbacks()
void setNull()
set SmartPtr to NULp
char buffer[MESSAGE_BUFFERSIZE]
GB_ERROR GB_push_transaction(GBDATA *gbd)
virtual GB_ERROR set_value(const std::string &new_value)=0
static Shaders registered
void update_toggle_field()
AW_awar * add_callback(const RootCallback &cb)
virtual std::string awar2db(const std::string &awar_content) const
static HelixNrInfo * start
GB_ERROR GB_check_hkey(const char *key) __ATTR__USERESULT
const char * read_char_pntr() const
awt_mask_awar_item(awt_input_mask_global &global_, const std::string &awar_base, const std::string &default_value, bool saved_with_properties)
GB_ERROR GB_await_error()
WindowCallback makeHelpCallback(const char *helpfile)
GB_TYPES GB_read_type(GBDATA *gbd)
void create_toggle_field(const char *awar_name, AW_label label, AW_orientation orientation=AW_VERTICAL)
void build_widget(AW_window *aws) OVERRIDE
virtual GB_ERROR relink()=0
~awt_assignment() OVERRIDE
AW_window_menu_modes * getWindow() const
virtual ~awt_mask_action()
virtual void remove_db_callbacks()
static void error(const char *msg)
virtual const char * getKeyPath() const =0
GB_ERROR GB_abort_transaction(GBDATA *gbd)
void label(const char *label)
virtual GBDATA * current(AW_root *root, GBDATA *gb_main) const =0
void remove_awarItem_callbacks()
void awar_changed() OVERRIDE
void db_changed() FINAL_OVERRIDE
std::string awar2db(const std::string &awar_content) const OVERRIDE
int GB_read_flag(GBDATA *gbd)
char * read_string() const
GB_CSTR GB_path_in_ARBLIB(const char *relative_path)
AW_awar * awar(const char *awar)
GB_ERROR GB_pop_transaction(GBDATA *gbd)
const char * get_dup_error(const string &maskName) const
void insert_sub_menu(const char *name, const char *mnemonic, AW_active mask=AWM_ALL)
GB_TYPES GBT_get_type_of_changekey(GBDATA *gb_main, const char *field_name, const char *change_key_path)
AW_awar * remove_callback(const RootCallback &cb)
virtual void general_item_change()
virtual std::string db2awar(const std::string &db_content) const
static AW_window_menu_modes_opengl * awm
AWT_registered_itemtype(AW_window_menu_modes *awm_, AWT_OpenMaskWindowCallback open_window_cb_)
int aw_question(const char *unique_id, const char *question, const char *buttons, bool sameSizeButtons, const char *helpfile)
void create_input_field(const char *awar_name, int columns=0)
fputs(TRACE_PREFIX, stderr)
GB_ERROR set_name(const std::string &name_, bool is_global)
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
awt_variable(awt_input_mask_global &global_, const std::string &id, bool is_global_, const std::string &default_value, GB_ERROR &error)
void GB_write_flag(GBDATA *gbd, long flag)
std::string awar_name() const
virtual std::string get_value() const =0
bool GB_is_directory(const char *path)
void remove_awar_callbacks(AW_root *root, const RootCallback &cb) const
void GB_remove_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
virtual void awar_changed()=0
awt_assignment(awt_input_mask_ptr mask_, const string &id_dest_, const string &id_source_)
awt_mask_item(awt_input_mask_global &global_)
void aw_message(const char *msg)
AWT_OpenMaskWindowCallback getOpenCb() const
GB_ERROR set_value(const std::string &new_value) OVERRIDE
void insert_default_toggle(AW_label toggle_label, const char *mnemonic, const char *var_value)
const AW_awar * awar() const
const char * fromText(const string &anystr)
GB_ERROR write_string(const char *aw_string)
std::string db2awar(const std::string &db_content) const OVERRIDE
NOT4PERL char * GB_command_interpreter_in_env(const char *str, const char *commands, const GBL_call_env &callEnv)
virtual GB_ERROR link_to(GBDATA *gb_new_item)=0
const char * fromKey(const char *id)
void build_widget(AW_window *aws) OVERRIDE
GB_transaction ta(gb_var)
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
NOT4PERL bool GB_inside_callback(GBDATA *of_gbd, GB_CB_TYPE cbtype)
AWT_registered_itemtype()
~awt_marked_checkbox() OVERRIDE
GBDATA * get_gb_main(DbSel db)
awt_mask_action(awt_input_mask_ptr mask_)
GB_ERROR GB_create_directory(const char *path)
void add_awar_callbacks(AW_root *root, const RootCallback &cb) const
char * GBS_global_string_copy(const char *templat,...)
GB_ERROR GB_write_autoconv_string(GBDATA *gbd, const char *val)
GB_write_int const char s