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 <= 903) // (please do not activate for all future versions, test each of them)
721 # define GCC_ARRAY_BOUNDS_FALSE_POSITIVE
724 #ifdef GCC_ARRAY_BOUNDS_FALSE_POSITIVE
725 # pragma GCC diagnostic push
726 # pragma GCC diagnostic ignored "-Warray-bounds"
732 for (
int i = 0; allowed_keywords[i]; ++i) {
734 if (allowed_keywords[i+1]) result +=
", ";
735 else result +=
" or ";
737 result += allowed_keywords[i];
742 #ifdef GCC_ARRAY_BOUNDS_FALSE_POSITIVE
743 # pragma GCC diagnostic pop
746 inline int isKeyword(
const char *current,
const char *keyword) {
748 for (; keyword[pos]; ++pos) {
749 if (!current[pos] || std::tolower(current[pos]) != std::tolower(keyword[pos])) {
765 if (start == string::npos) {
771 const char *current = line.c_str()+
start;
774 for (; allowed_keywords[i]; ++i) {
775 int found_keyword_size =
isKeyword(current, allowed_keywords[i]);
776 if (found_keyword_size) {
778 scan_pos += found_keyword_size;
782 if (!allowed_keywords[i])
goto EXPECTED;
790 string& string_para,
int& keyword_index,
791 const char **allowed_keywords) {
804 if (keyword_index == -1) {
817 while (start != string::npos) {
818 char c = line[
start];
819 if (c !=
'+' && c !=
'-')
break;
822 if (c ==
'-') neg = !neg;
826 if (start == string::npos || !isdigit(line[start])) {
828 error =
"digits (or+-) expected";
831 size_t end = line.find_first_not_of(
"0123456789", start);
835 result = atoi(line.substr(start, end-start+1).c_str());
839 return neg ? -result :
result;
844 size_t old_scan_pos = scan_pos;
847 if (result<min || result>max) {
848 scan_pos = old_scan_pos;
849 error =
GBS_global_string(
"value %li is outside allowed range (%li-%li)", result, min, max);
857 size_t old_scan_pos = scan_pos;
861 scan_pos = old_scan_pos;
865 error =
"expected number or empty parameter";
866 scan_pos = old_scan_pos;
883 if (start == string::npos) {
887 char found = line[
start];
888 char upper_found = std::toupper(found);
889 size_t pos = allowed_flags.find(upper_found);
891 if (pos != string::npos) {
896 error =
GBS_global_string(
"One of '%s' expected (found '%c')", allowed_flags.c_str(), found);
903 size_t old_scan_pos = scan_pos;
906 if (!error && (result != 0) && (result != 1)) {
907 scan_pos = old_scan_pos;
908 error =
"'0' or '1' expected";
916 if (start == string::npos) {
917 error =
"identifier expected";
921 while (end<line.length()) {
923 if (!(isalnum(c) || c ==
'_'))
break;
926 id = line.substr(start, end-start);
934 static char *local_mask_dir;
936 return local_mask_dir;
939 static char *global_mask_dir;
941 return global_mask_dir;
946 return string(dir)+
'/'+mask_name;
949 #define ARB_INPUT_MASK_ID "ARB-Input-Mask"
951 static awt_input_mask_descriptor *
quick_scan_input_mask(
const string& mask_name,
const string& filename,
bool local) {
952 awt_input_mask_descriptor *res =
NULp;
953 FILE *in = fopen(filename.c_str(),
"rt");
972 if (line[0] ==
'#')
continue;
973 if (line ==
"@MASK_BEGIN") { done =
true;
break; }
975 size_t at = line.find(
'@');
976 size_t eq = line.find(
'=', at);
978 if (at == string::npos || eq == string::npos) {
982 string parameter = line.substr(at+1, eq-at-1);
983 string value = line.substr(eq+1);
985 if (parameter ==
"ITEMTYPE") itemtype = value;
986 else if (parameter ==
"TITLE") title = value;
987 else if (parameter ==
"HIDE") hidden = atoi(value.c_str());
991 if (!error && done) {
992 if (itemtype ==
"") {
993 error =
"No itemtype defined";
996 if (title ==
"") title = mask_name;
997 res =
new awt_input_mask_descriptor(title.c_str(), mask_name.c_str(), itemtype.c_str(), local, hidden);
1002 fprintf(stderr,
"Skipping '%s' (not a input mask)\n", filename.c_str());
1047 return s[0] ==
'0' || s[0] ==
'1';
1051 InputMaskList::iterator mask_iter = input_mask_list.find(*internal_mask_name);
1056 if (mask_iter != input_mask_list.end()) {
1057 awt_input_mask_ptr mask = mask_iter->second;
1060 printf(
"aww=%p root=%p ; global=%p root=%p\n", aww, aww->
get_root(), &global, global.
get_root());
1063 if (reload) mask->set_reload_on_reinit(
true);
1064 if (hide_current) mask->hide();
1069 if (error && hide_current) {
1070 mask_iter = input_mask_list.find(*internal_mask_name);
1071 awt_assert(mask_iter != input_mask_list.end());
1072 mask_iter->second->show();
1077 string mask_name = internal_mask_name->substr(1);
1078 printf(
"'%s' (no such mask in input_mask_list)\n", mask_name.c_str());
1125 const awt_mask_item *item_source =
mask->mask_global().get_identified_item(id_source, error);
1126 awt_mask_item *item_dest =
mask->mask_global().get_identified_item(id_dest, error);
1133 awt_assignment(awt_input_mask_ptr mask_,
const string& id_dest_,
const string& id_source_) :
1136 id_source(id_source_)
1220 if (mask_command[mc].cmd_name == cmd_name) {
1221 return mask_command[mc].
cmd;
1230 string label, data_path;
1231 int default_position = -1, orientation = -1;
1232 vector<string> buttons;
1233 vector<string> values;
1234 bool allow_edit =
false;
1236 int edit_position = -1;
1243 orientation = orientation&1;
1245 while (!error && !was_last_parameter) {
1250 const char *allowed_keywords[] = {
"ALLOW_EDIT",
NULp };
1254 if (keyword_index != -1) {
1255 if (allow_edit) error =
"ALLOW_EDIT is allowed only once for each RADIO";
1262 edit_position = buttons.size()+1;
1263 buttons.push_back(but);
1264 values.push_back(val);
1268 buttons.push_back(but);
1269 values.push_back(val);
1276 if (!error && (buttons.size()<2)) error =
"You have to define at least 2 buttons.";
1278 if (!error && allow_edit && edit_position != default_position) {
1279 error =
GBS_global_string(
"Invalid default %i (must be index of ALLOW_EDIT: %i )", default_position, edit_position);
1281 if (!error && (default_position<1 ||
size_t(default_position)>buttons.size())) {
1282 error =
GBS_global_string(
"Invalid default %i (valid: 1..%zu)", default_position, buttons.size());
1288 handler1 =
new awt_radio_button(global, data_path, label, default_position-1, orientation, buttons, values);
1292 handler1 =
new awt_radio_button(global, data_path, label, default_position-1, orientation, buttons, values);
1298 const char *internal_local =
NULp;
1299 const char *internal_global =
NULp;
1301 for (
int id = 0; ; ++
id) {
1303 if (!descriptor)
break;
1305 const char *internal_name = descriptor->get_internal_maskname();
1307 if (strcmp(internal_name+1, mask_name.c_str()) == 0) {
1308 if (descriptor->is_local_mask()) {
1310 internal_local = internal_name;
1314 internal_global = internal_name;
1319 return (search_in_local && internal_local) ? internal_local : null2empty(internal_global);
1342 void db_changed() OVERRIDE;
1351 remove_awarItem_callbacks();
1354 remove_db_callbacks();
1359 set_item(gb_new_item);
1361 error = add_db_callbacks();
1364 add_awarItem_callbacks();
1368 void awt_marked_checkbox::awar_changed() {
1370 string value = get_value();
1371 bool marked = value ==
"yes";
1376 mask_global().no_item_selected();
1380 void awt_marked_checkbox::db_changed() {
1387 void awt_marked_checkbox::build_widget(
AW_window *aws) {
1388 const string& lab = get_label();
1389 if (lab.length()) aws->
label(lab.c_str());
1391 aws->create_toggle(awar_name().c_str());
1395 FILE *out = fopen(fullname.c_str(),
"wt");
1400 "# New mask '%s'\n\n"
1401 "# What kind of item to edit:\n"
1404 "@TITLE=%s\n\n",
ARB_INPUT_MASK_ID, maskname.c_str(), itemtypename.c_str(), maskname.c_str());
1407 "# Should mask appear in 'User mask' menu\n"
1408 "@HIDE=%i\n\n",
int(hidden));
1410 fputs(
"# Spacing in window:\n"
1413 "# Show edit/reload button?\n"
1415 "# Show 'edit enable' toggle?\n"
1417 "# Show 'marked' toggle?\n"
1419 "\n# ---------------------------\n"
1420 "# The definition of the mask:\n\n"
1422 " TEXT(\"You are editing\") SELF()\n"
1424 " TEXTFIELD(\"Full name\", \"full_name\", 30)\n\n"
1425 "@MASK_END\n\n", out);
1437 bool is_known(
const string&
id) {
return seen.find(
id) != seen.end(); }
1439 string makeUnique(
string id) {
1442 for (
int i = 0; ; ++i) {
1444 if (!is_known(undup)) {
1456 : reloading(reloading_)
1460 curr_id = makeUnique(
id);
1461 return reloading ?
NULp : curr_id.c_str();
1471 for (set<string>::iterator d = dup.begin(); d != dup.end(); ++d) {
1472 dupList = dupList+
" '"+*d+
"'";
1476 "(they need to be unique; change button texts etc. to change them)",
1477 maskName.c_str(), dupList.c_str());
1482 const string& mask_name,
bool local,
GB_ERROR& error,
bool reloading) {
1483 awt_input_mask_ptr mask;
1490 in = fopen(fullfile.c_str(),
"rt");
1495 bool mask_began =
false;
1496 bool mask_ended =
false;
1500 string itemtypename;
1503 bool edit_reload =
false;
1504 bool edit_enable =
true;
1505 bool show_marked =
true;
1511 error =
readLine(in, line, lineNo);
1517 while (!error && !mask_began && !feof(in)) {
1518 error =
readLine(in, line, lineNo);
1521 if (line[0] ==
'#')
continue;
1523 if (line ==
"@MASK_BEGIN") mask_began =
true;
1525 size_t at = line.find(
'@');
1526 size_t eq = line.find(
'=', at);
1528 if (at == string::npos || eq == string::npos) {
1532 string parameter = line.substr(at+1, eq-at-1);
1533 string value = line.substr(eq+1);
1535 if (parameter ==
"ITEMTYPE") itemtypename = value;
1536 else if (parameter ==
"TITLE") title = value;
1537 else if (parameter ==
"X_SPACING") x_spacing = atoi(value.c_str());
1538 else if (parameter ==
"Y_SPACING") y_spacing = atoi(value.c_str());
1539 else if (parameter ==
"EDIT") edit_reload = atoi(value.c_str()) != 0;
1540 else if (parameter ==
"EDIT_ENABLE") edit_enable = atoi(value.c_str()) != 0;
1541 else if (parameter ==
"SHOW_MARKED") show_marked = atoi(value.c_str()) != 0;
1542 else if (parameter ==
"HIDE") ;
1550 if (!error && !mask_began) error =
"@MASK_BEGIN expected";
1554 if (title ==
"") title =
string(
"Untitled (")+mask_name+
")";
1559 itemtypename.c_str(), awt_itemtype_names[sel->
get_item_type()]);
1562 if (!error) mask =
new awt_input_mask(root, gb_main, mask_name, itemtype, local, sel, edit_enable);
1568 AW_window_simple*& aws = mask->get_window();
1569 aws =
new AW_window_simple;
1575 aws->init(root, window_id, title.c_str());
1579 aws->load_xfig(
NULp,
true);
1582 aws->auto_space(x_spacing, y_spacing);
1585 aws->callback(
AW_POPDOWN); aws->create_button(ID.
fromKey(
"CLOSE"),
"CLOSE",
"C");
1589 aws->callback(makeWindowCallback(
AWT_edit_input_mask, &mask->mask_global().get_maskname(), mask->mask_global().is_local_mask()));
1590 aws->create_button(
NULp,
"!EDIT",
"E");
1592 aws->callback(makeWindowCallback(
AWT_reload_input_mask, &mask->mask_global().get_internal_maskname()));
1593 aws->create_button(
NULp,
"RELOAD",
"R");
1596 if (edit_reload && edit_enable && show_marked) aws->at_newline();
1599 aws->label(
"Enable edit?");
1604 awt_mask_item_ptr handler =
new awt_marked_checkbox(mask->mask_global(),
"Marked");
1605 mask->add_handler(handler);
1606 if (handler->is_viewport()) handler->to_viewport()->build_widget(aws);
1612 vector<int> horizontal_lines;
1613 map<string, size_t> referenced_ids;
1614 map<string, size_t> declared_ids;
1619 while (!error && !mask_ended && !feof(in)) {
1620 error =
readLine(in, line, lineNo);
1623 if (line.empty())
continue;
1624 if (line[0] ==
'#')
continue;
1626 if (line ==
"@MASK_END") {
1630 PARSE_REST_OF_LINE :
1631 was_last_parameter =
false;
1633 if (start != string::npos) {
1634 size_t after_command = line.find_first_of(
string(
" \t("), start);
1635 if (after_command == string::npos) {
1636 string command = line.substr(start);
1640 string command = line.substr(start, after_command-start);
1641 size_t paren_open = line.find(
'(', after_command);
1642 if (paren_open == string::npos) {
1646 size_t scan_pos = paren_open+1;
1655 string label, data_path;
1665 string label, data_path;
1668 long min = LONG_MIN;
1669 long max = LONG_MAX;
1674 if (!was_last_parameter) {
1683 string label, data_path;
1684 bool checked =
false;
1690 if (!error) handler =
new awt_check_box(mask->mask_global(), data_path,
label, checked);
1693 parse_CMD_RADIO(line, scan_pos, error, command, handler, radio_edit_handler, mask->mask_global());
1702 handler =
new awt_script(mask->mask_global(), script);
1703 error = handler->set_name(
id,
false);
1704 declared_ids[
id] = lineNo;
1708 string id, def_value;
1711 bool global_exists = mask->mask_global().has_global_id(
id);
1712 bool local_exists = mask->mask_global().has_local_id(
id);
1715 error =
GBS_global_string(
"ID '%s' already declared as %s ID (rename your local id)",
1716 id.c_str(), cmd ==
CMD_LOCAL ?
"global" :
"local");
1718 else if (cmd ==
CMD_LOCAL && local_exists) {
1725 if (!mask->mask_global().has_global_id(
id)) {
1734 declared_ids[
id] = lineNo;
1737 else if (cmd ==
CMD_ID) {
1742 if (lasthandler.
isNull()) {
1743 error =
"ID() may only be used BEHIND another element";
1746 error = lasthandler->set_name(
id,
false);
1747 declared_ids[
id] = lineNo;
1758 if (!error) item = (
awt_mask_item*)mask->mask_global().get_identified_item(
id, error);
1769 awt_script *script =
dynamic_cast<awt_script*
>(item);
1770 if (script) handler =
new awt_script_viewport(mask->mask_global(), script,
label, width);
1771 else error =
"SHOW cannot be used on this ID-type";
1774 referenced_ids[
id] = lineNo;
1778 string label, mask_to_start;
1786 if (mask_to_start_internal.length() == 0) {
1787 error =
"Can't detect which mask to load";
1790 const char *key = ID.
fromText(label);
1792 string *
const internal_mask_name =
new string(mask->mask_global().get_internal_maskname());
1793 string *
const mask_to_open =
new string(mask_to_start_internal);
1800 aws->button_length(label.length()+2);
1801 aws->create_button(key, label.c_str());
1806 string button_text, url_aci;
1812 const char *key = ID.
fromText(button_text);
1814 aws->button_length(button_text.length()+2);
1815 aws->create_button(key, button_text.c_str());
1819 string id_dest, id_source, button_text;
1826 referenced_ids[id_source] = lineNo;
1827 referenced_ids[id_dest] = lineNo;
1829 const char *key = ID.
fromText(button_text);
1831 aws->button_length(button_text.length()+2);
1832 aws->create_button(key, button_text.c_str());
1841 aws->button_length(text.length()+2);
1842 aws->create_button(
NULp, text.c_str());
1857 aws->get_window_size(width, height);
1865 aws->get_window_size(width, height);
1866 horizontal_lines.push_back(height);
1882 if (!radio_edit_handler.
isNull()) {
1886 int x_start, y_start;
1888 aws->get_at_position(&x_start, &y_start);
1890 mask->add_handler(handler);
1891 handler->to_viewport()->build_widget(aws);
1893 int x_end, y_end, dummy;
1894 aws->get_at_position(&x_end, &dummy);
1896 aws->get_at_position(&dummy, &y_end);
1898 int height = y_end-y_start;
1902 aws->at(x_end+x_spacing, y_start+y_offset);
1904 mask->add_handler(radio_edit_handler);
1905 radio_edit_handler->to_viewport()->build_widget(aws);
1910 mask->add_handler(handler);
1911 if (handler->is_viewport()) handler->to_viewport()->build_widget(aws);
1913 lasthandler = handler;
1918 line = line.substr(scan_pos);
1919 goto PARSE_REST_OF_LINE;
1922 if (err_pos != string::npos) err_pos++;
1934 for (map<string, size_t>::const_iterator r = referenced_ids.begin(); r != referenced_ids.end(); ++r) {
1935 if (declared_ids.find(r->first) == declared_ids.end()) {
1936 error =
GBS_global_string(
"ID '%s' used in line #%zu was not declared", r->first.c_str(), r->second);
1941 for (map<string, size_t>::const_iterator d = declared_ids.begin(); d != declared_ids.end(); ++d) {
1942 if (referenced_ids.find(d->first) == referenced_ids.end()) {
1944 d->first.c_str(), d->second, mask_name.c_str());
1949 if (error) error =
"Inconsistent IDs";
1953 if (!horizontal_lines.empty()) {
1955 aws->get_window_size(width, height);
1956 for (vector<int>::const_iterator yi = horizontal_lines.begin(); yi != horizontal_lines.end(); ++yi) {
1974 else if (err_pos == 0) {
1977 else if (err_pos == string::npos) {
1982 size_t end = line.length();
1984 context.reserve(wanted);
1985 bool last_was_space =
false;
1987 for (
size_t ex = err_pos-1; ex<end && wanted>0; ++ex) {
1989 bool this_is_space = ch ==
' ';
1991 if (!this_is_space || !last_was_space) {
1992 context.append(1, ch);
1995 last_was_space = this_is_space;
1998 error =
GBS_global_string(
"%s in line #%zu at '%s...'", error, lineNo, context.c_str());
2011 const char *mask_name = internal_mask_name+1;
2012 InputMaskList::iterator mask_iter = input_mask_list.find(internal_mask_name);
2014 awt_input_mask_ptr old_mask;
2015 bool unlink_old =
false;
2017 if (mask_iter != input_mask_list.end() && mask_iter->second->reload_on_reinit()) {
2019 old_mask = mask_iter->second;
2020 input_mask_list.erase(mask_iter);
2021 mask_iter = input_mask_list.end();
2027 if (mask_iter == input_mask_list.end()) {
2028 awt_input_mask_ptr newMask =
awt_create_input_mask(root, gb_main, sel, mask_name, local, error, unlink_old);
2031 if (!old_mask.
isNull()) {
2032 input_mask_list[internal_mask_name] = old_mask;
2037 input_mask_list[internal_mask_name] = newMask;
2039 mask_iter = input_mask_list.find(internal_mask_name);
2043 awt_assert(mask_iter != input_mask_list.end());
2044 mask_iter->second->get_window()->activate();
2058 awt_input_mask::~awt_input_mask() {
2060 for (awt_mask_item_list::iterator h = handlers.begin(); h != handlers.end(); ++h) {
2061 (*h)->remove_name();
2065 void awt_input_mask::link_to(
GBDATA *gb_item) {
2067 for (awt_mask_item_list::iterator h = handlers.begin(); h != handlers.end(); ++h) {
2068 if ((*h)->is_linked_item()) (*h)->to_linked_item()->link_to(gb_item);
2075 awt_input_mask_descriptor::awt_input_mask_descriptor(
const char *title_,
const char *maskname_,
const char *itemtypename_,
bool local,
bool hidden_) {
2077 internal_maskname = ARB_alloc<char>(strlen(maskname_)+2);
2078 internal_maskname[0] = local ?
'0' :
'1';
2079 strcpy(internal_maskname+1, maskname_);
2084 awt_input_mask_descriptor::~awt_input_mask_descriptor() {
2086 free(internal_maskname);
2090 awt_input_mask_descriptor::awt_input_mask_descriptor(
const awt_input_mask_descriptor& other) {
2092 internal_maskname =
ARB_strdup(other.internal_maskname);
2093 itemtypename =
ARB_strdup(other.itemtypename);
2094 local_mask = other.local_mask;
2095 hidden = other.hidden;
2097 awt_input_mask_descriptor& awt_input_mask_descriptor::operator = (
const awt_input_mask_descriptor& other) {
2098 if (
this != &other) {
2100 free(internal_maskname);
2104 internal_maskname =
ARB_strdup(other.internal_maskname);
2105 itemtypename =
ARB_strdup(other.itemtypename);
2106 local_mask = other.local_mask;
2107 hidden = other.hidden;
2119 existing_masks.push_back(*descriptor);
2126 for (
int scope = 0; scope <= 1; ++scope) {
2136 DIR *dirp = opendir(dirname);
2138 fprintf(stderr,
"Warning: No such directory '%s'\n", dirname);
2142 for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
2144 string maskname = dp->d_name;
2147 if (stat(fullname.c_str(), &st))
continue;
2148 if (!S_ISREG(st.st_mode))
continue;
2151 size_t ext_pos = maskname.find(
".mask");
2153 if (ext_pos != string::npos && maskname.substr(ext_pos) ==
".mask") {
2156 existing_masks.push_back(*descriptor);
2164 scanned_existing_input_masks =
true;
2170 if (
id<0 ||
size_t(
id) >= existing_masks.size())
return NULp;
2172 const awt_input_mask_descriptor *descriptor = &existing_masks[
id];
2180 if (itemtype_name == awt_itemtype_names[i]) {
2200 open_window_cb(
NULp)
2204 open_window_cb(open_window_cb_)
2217 TypeRegistryIter
registered = registeredTypes.find(type);
2220 if (registered == registeredTypes.end()) error =
GBS_global_string(
"Type '%s' not registered (yet)", awt_itemtype_names[type]);
2221 else registered->second.getOpenCb()(registered->second.getWindow(), mask_id,
NULp);
2227 TypeRegistryIter alreadyRegistered = registeredTypes.find(type);
2228 if (alreadyRegistered == registeredTypes.end()) {
2233 awt_assert(alreadyRegistered->second.getOpenCb() == open_window_cb);
2246 size_t ext = maskname.find(
".mask");
2248 if (ext == string::npos) maskname = maskname+
".mask";
2249 else maskname = maskname.substr(0, ext)+
".mask";
2260 bool openMask =
false;
2262 const char *error =
NULp;
2265 if (stat(maskfullname.c_str(), &st) == 0) {
2266 int answer =
aw_question(
"overwrite_mask",
"File does already exist",
"Overwrite mask,Cancel");
2286 if (!error && openMask) {
2290 for (mask_id = 0; ; ++mask_id) {
2293 error =
GBS_global_string(
"Can't find descriptor for mask '%s'", maskname.c_str());
2297 if (strcmp(descriptor->get_maskname(), maskname.c_str()) == 0 &&
2298 descriptor->is_local_mask() == local)
2314 static AW_window_simple *aws =
NULp;
2317 aws =
new AW_window_simple;
2319 aws->init(aww->
get_root(),
"CREATE_USER_MASK",
"Create new input mask:");
2321 aws->auto_space(10, 10);
2323 aws->button_length(10);
2325 aws->create_button(
"CLOSE",
"CLOSE");
2327 aws->create_button(
"HELP",
"HELP",
"H");
2331 aws->label(
"Name of new input mask");
2336 aws->label(
"Item type");
2339 aws->insert_option(awt_itemtype_names[i],
"", awt_itemtype_names[i]);
2341 aws->update_option_menu();
2348 aws->update_toggle_field();
2353 aws->insert_toggle(
"Normal",
"N", 0);
2354 aws->insert_toggle(
"Hidden",
"H", 1);
2355 aws->update_toggle_field();
2360 aws->create_button(
"CREATE",
"CREATE",
"C");
2376 char lc = tolower(c);
2377 char *cand = strchr(availableMnemonics, lc);
2379 char *last = strchr(cand+1, 0)-1;
2398 bool prevWasChar =
false;
2399 for (
int startOfWord = 1; startOfWord>=0; --startOfWord) {
2400 for (
int i = 0; orgTitle[i]; ++i) {
2401 char c = orgTitle[i];
2403 if (!prevWasChar || !startOfWord) {
2411 else prevWasChar =
false;
2415 for (
int i = 0; i<2; ++i) {
2416 const char *takeAny = i ? availableMnemonics :
"1234567890";
2417 for (
int t = 0; takeAny[t]; ++t) {
2418 char c = takeAny[t];
2438 char *availableMnemonics =
ARB_strdup(
"abcdefghijklmopqrstuvwxyz0123456789");
2440 for (
int scope = 0; scope <= 1; ++scope) {
2441 bool entries_made =
false;
2443 for (
int id = 0; ; ++
id) {
2446 if (!descriptor)
break;
2447 if (descriptor->is_local_mask() != (scope ==
AWT_SCOPE_LOCAL))
continue;
2451 if (item_type == wanted_item_type) {
2452 if (!descriptor->is_hidden()) {
2453 entries_made =
true;
2454 char *macroname2key =
GBS_string_2_key(descriptor->get_internal_maskname());
2455 #if defined(DEBUG) && 0
2456 printf(
"added user-mask '%s' with id=%i\n", descriptor->get_maskname(),
id);
2459 char *mod_title =
selectMnemonic(descriptor->get_title(), availableMnemonics, mnemonic[0]);
2461 awm->
insert_menu_topic(macroname2key, mod_title, mnemonic,
"input_mask.hlp",
AWM_ALL, makeWindowCallback(open_mask_window_cb,
id, gb_main));
2463 free(macroname2key);
2468 aw_message(
GBS_global_string(
"Unknown @ITEMTYPE '%s' in '%s'", descriptor->get_itemtypename(), descriptor->get_internal_maskname()));
2475 const char *itemname = awt_itemtype_names[wanted_item_type];
2481 free(new_item_mask_label);
2482 free(new_item_mask_id);
2484 free(availableMnemonics);
2491 for (InputMaskList::iterator i = input_mask_list.begin();
2492 i != input_mask_list.end();
2495 i->second->unlink();
2497 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