ARB
xfergui.cxx
Go to the documentation of this file.
1 // ========================================================= //
2 // //
3 // File : xfergui.cxx //
4 // Purpose : GUI to configure transfer sets //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in Apr 19 //
7 // http://www.arb-home.de/ //
8 // //
9 // ========================================================= //
10 
11 #include "xfergui.h"
12 #include <xferset.h>
13 
14 #include <awt_prompt.hxx>
15 
16 #include <aw_window.hxx>
17 #include <aw_root.hxx>
18 #include <aw_awar.hxx>
19 #include <aw_file.hxx>
20 #include <aw_msg.hxx>
21 #include <aw_select.hxx>
22 
23 #include <arb_file.h>
24 #include <arb_str.h>
25 #include <StrUniquifier.h>
26 #include <FileWatch.h>
27 
28 #include <set>
29 #include <string>
30 
31 using namespace std;
32 using namespace FieldTransfer;
33 
34 // ---------------
35 // awars
36 #define AWARBASE_XFERSET_TMP "tmp/fts/"
37 #define AWARBASE_XFERRULE_TMP AWARBASE_XFERSET_TMP "rule/"
38 
39 #define AWAR_XFERSET_SELECTED AWARBASE_XFERSET_TMP "focus" // Note: FTS clients like importer or exporter react if this awar gets touched
40 #define AWAR_XFERSET_COMMENT AWARBASE_XFERSET_TMP "comment"
41 #define AWAR_XFERSET_UNDEFINED AWARBASE_XFERSET_TMP "undefined"
42 
43 // fts-selection box (selects files, similar to ift/eft-selection-boxes)
44 #define AWAR_XFERSET_FTSBASE AWARBASE_XFERSET_TMP "file"
45 #define AWAR_XFERSET_FTSNAME AWAR_XFERSET_FTSBASE "/file_name"
46 #define AWAR_XFERSET_FTSFILTER AWAR_XFERSET_FTSBASE "/filter"
47 #define AWAR_XFERSET_FTSDIR AWAR_XFERSET_FTSBASE "/directory"
48 
49 #define AWAR_XFERRULE_SELECTED AWARBASE_XFERRULE_TMP "focus"
50 #define AWAR_XFERRULE_TARGETFIELD AWARBASE_XFERRULE_TMP "rule"
51 #define AWAR_XFERRULE_ACI AWARBASE_XFERRULE_TMP "aci"
52 #define AWAR_XFERRULE_SEP AWARBASE_XFERRULE_TMP "sep"
53 #define AWAR_XFERRULE_TYPE AWARBASE_XFERRULE_TMP "type"
54 #define AWAR_XFERRULE_LOSS AWARBASE_XFERRULE_TMP "loss"
55 #define AWAR_XFERRULE_INPUT_FIELDS AWARBASE_XFERRULE_TMP "input/fields" // contains list of fieldnames separated by ';'
56 #define AWAR_XFERRULE_INPUT_SELECTED AWARBASE_XFERRULE_TMP "input/focus" // field selected in AWAR_XFERRULE_INPUT_FIELDS (duplicate entries contain suffix! better not use content of this awar)
57 #define AWAR_XFERRULE_AVAIL_SELECTED AWARBASE_XFERRULE_TMP "avail" // selected available field
58 #define AWAR_XFERRULE_AVAIL_CATEGORY AWARBASE_XFERRULE_TMP "acat" // shown available fields
59 #define AWAR_XFERRULE_FIELD AWARBASE_XFERRULE_TMP "field" // content of fieldname textbox
60 
61 // -------------------------
62 // other constants
63 #define NO_XFERSET_SELECTED ""
64 
65 // ---------------------
66 // field order
67 
68 inline bool is_info(const char *field) { return field[0] == '<'; }
69 inline bool is_info(const string& field) { return is_info(field.c_str()); }
70 
71 struct lt_field { // set order type for field selection
72  bool operator()(const string& s1, const string& s2) const {
73  int cmp = is_info(s1)-is_info(s2);
74  if (!cmp) cmp = s1.compare(s2);
75  return cmp<0;
76  }
77 };
78 
79 // -----------------
80 // globals
81 
83 
84 typedef set<string, lt_field> StrSet;
85 typedef StrSet::iterator StrSetIter;
86 
87 static StrArray knownFieldsClientInput; // known database fields (retrieved via AvailableFieldScanner; input fields)
88 static StrArray knownFieldsClientOutput; // ---------- (dito, but output fields)
89 static StrArray knownFieldsRulesetInput; // database fields read by current ruleset
90 static StrArray knownFieldsRulesetOutput; // ---------- (dito, but fields written)
91 static StrSet knownFields; // known database fields (merged from misc. sources according to AWAR_XFERRULE_AVAIL_CATEGORY)
92 
93 // --------------------------
94 // helper functions
95 
96 const char *XFER_getFullFTS(const char *name) {
100  static string result;
101  if (name[0]) result = GB_concat_path(GB_path_in_arbprop("fts"), GBS_global_string("%s.fts", name));
102  else result = name;
103  return result.c_str();
104 }
105 
108 }
109 static const char *get_selected_FTS() { // existing or new
110  const char *newname = awar_selected_FTS()->read_char_pntr();
111  return XFER_getFullFTS(newname);
112 }
113 inline void set_selected_FTS(const char *name) {
115 }
116 
117 inline char *getNameOnly(const char *fullpath) {
118  char *nameOnly = NULp;
119  GB_split_full_path(fullpath, NULp, NULp, &nameOnly, NULp);
120  return nameOnly;
121 }
122 
123 static RuleSetPtr getSelectedRuleset(const char*& failReason) {
124  RuleSetPtr ruleset;
125  string fts = get_selected_FTS();
126  failReason = NULp;
127 
128  if (GB_is_readablefile(fts.c_str())) {
129  ErrorOrRuleSetPtr loaded = RuleSet::loadFrom(fts.c_str());
130  if (loaded.hasError()) {
131  loaded.getError().set_handled();
132  failReason = "load error";
133  }
134  else {
135  ruleset = loaded.getValue();
136  }
137  }
138  else {
139  failReason = "no transfer set";
140  }
141  return ruleset;
142 }
143 
144 inline int getSelectedRuleIndex() {
148  int idx = -1;
150  if (ARB_strBeginsWith(rule_id, "rule")) {
151  idx = atoi(rule_id+4)-1;
152  xf_assert(idx>=0);
153  }
154  return idx;
155 }
156 inline const char *ruleSelId(int idx) {
157  return GBS_global_string("rule%i", idx+1);
158 }
159 inline GB_ERROR checkValidIndex(RuleSetPtr ruleset, int idx) {
161  return ruleset->validIdx(idx) ? NULp : "rule index out-of-bounds";
162 }
163 
164 static void selectRule(int idx, int ruleCount) {
169  const char *ruleId = idx>=0 && idx<ruleCount ? ruleSelId(idx) : "";
171 }
172 static void deselectRule() { selectRule(0, 0); }
173 
174 static RulePtr getSelectedRule(const char*& failReason) {
175  RulePtr rule;
176  failReason = NULp;
177 
178  int idx = getSelectedRuleIndex();
179  if (idx<0) {
180  failReason = "no rule";
181  }
182  else {
183  RuleSetPtr ruleset = getSelectedRuleset(failReason);
184  if (ruleset.isSet()) {
185  failReason = checkValidIndex(ruleset, idx);
186  if (!failReason) rule = ruleset->getPtr(idx);
187  }
188  }
189 
190  return rule;
191 }
192 
193 inline void refresh_fts_selbox() {
195 }
197  GB_ERROR error = NULp;
198  string fts = get_selected_FTS();
199  if (fts.empty()) {
200  error = "no ruleset selected"; // (should not happen)
201  }
202  else {
203  error = ruleset->saveTo(fts.c_str());
204  if (!error) {
207  }
208  }
209  return error;
210 }
211 
212 static int onlyLintRuleWithIdx = -1; // -1 or idx if rule was updated in ruleset editor
213 static bool warnAboutDuplicateTargets = true;
214 static void lintRuleset(RuleSetPtr ruleset) {
215  // examine ruleset (and rules within) and warn if problems are detected
216  xf_assert(ruleset.isSet());
217 
218  typedef map<string, int> StrMap;
219 
220  bool testsAllRules = onlyLintRuleWithIdx < 0;
221  int warningsPrinted = 0;
222  StrMap targetFieldCount;
223  string checkDupOf;
224 
225  for (size_t r = 0; r<ruleset->size(); ++r) {
226  const Rule& rule = ruleset->get(r);
227  const string& dest = rule.targetField();
228  {
229  StrMap::iterator found = targetFieldCount.find(dest);
230  if (found == targetFieldCount.end()) {
231  targetFieldCount[dest] = 1;
232  }
233  else {
234  ++found->second;
235  }
236  }
237 
238  bool lintThisRule = testsAllRules || (onlyLintRuleWithIdx == int(r));
239  if (lintThisRule) {
240  if (dest == "name") { // @@@ this is a hack (later use itemtype when provided)
241  aw_message("Warning: potentially dangerous target field 'name' detected");
242  ++warningsPrinted;
243  }
244  if (targetFieldCount[dest] == 2) {
246  aw_message(GBS_global_string("Warning: duplicated target field '%s' detected", dest.c_str()));
247  ++warningsPrinted;
248  }
249  }
250  else if (!testsAllRules) {
251  checkDupOf = dest;
252  }
253  }
254  }
255 
256  if (!checkDupOf.empty()) {
257  if (targetFieldCount[checkDupOf]>2) {
259  aw_message(GBS_global_string("Warning: duplicated target field '%s' detected", checkDupOf.c_str()));
260  ++warningsPrinted;
261  }
262  }
263  }
264 
265  if (warningsPrinted) {
267  }
268 }
269 
270 static void lintRulesetOnce(RuleSetPtr ruleset) {
271  // remember filename and call lintRuleset only on change
272  xf_assert(ruleset.isSet());
273 
274  string fts = get_selected_FTS();
275  static string last_linted_fts;
276  bool lintIt = false;
277 
278  if (last_linted_fts.empty()) {
279  lintIt = true;
280  }
281  else if (fts != last_linted_fts) {
282  lintIt = true;
283  }
284  else if (onlyLintRuleWithIdx>=0) {
285  lintIt = true;
286  }
287 
288  if (lintIt) {
289  lintRuleset(ruleset);
290  last_linted_fts = fts;
291  }
292 }
293 
294 static void overwriteSelectedRule(RulePtr newRule) {
295  GB_ERROR error = NULp;
296  int idx = getSelectedRuleIndex();
297 
298  if (idx<0) {
299  error = "no rule selected. update impossible.";
300  }
301  else {
302  RuleSetPtr ruleset = getSelectedRuleset(error);
303  if (ruleset.isSet()) {
304  error = checkValidIndex(ruleset, idx);
305  if (!error) {
306  ruleset->replace(idx, newRule);
307  LocallyModify<int> avoidWarningsAboutOtherRules(onlyLintRuleWithIdx, idx);
308  error = saveChangedRuleset(ruleset);
309  }
310  }
311  }
312  aw_message_if(error);
313 }
314 
315 inline GB_ERROR check_valid_existing_fts(const char *fullfts) {
316  return GB_is_readablefile(fullfts) ? NULp : "no FTS selected";
317 }
318 static GB_ERROR check_valid_target_fts(const char *fullfts) {
319  GB_ERROR error = NULp;
320  if (!fullfts[0]) {
321  error = "no name specified";
322  }
323  else if (GB_is_readablefile(fullfts)) {
324  char *fts_nameOnly = getNameOnly(fullfts);
325  error = GBS_global_string("field transfer set '%s' already exists",
326  fts_nameOnly ? fts_nameOnly : fullfts);
327  free(fts_nameOnly);
328  }
329  return error;
330 }
331 
332 // --------------------------------
333 // Rule definition window
334 
335 static bool ignoreRuleDetailChange = false;
336 
338  const char *failReason;
339  RulePtr rule = getSelectedRule(failReason);
340 
341  LocallyModify<bool> duringUpdate(ignoreRuleDetailChange, true);
342  const bool haveRule = rule.isSet();
343 
344  awr->awar(AWAR_XFERRULE_TARGETFIELD)->write_string(haveRule ? rule->targetField().c_str() : "");
345  awr->awar(AWAR_XFERRULE_ACI)->write_string(haveRule ? rule->getACI().c_str() : "");
346  awr->awar(AWAR_XFERRULE_SEP)->write_string(haveRule ? rule->getSeparator().c_str() : "");
347 
348  GB_TYPES forcedType = GB_NONE;
349  if (haveRule && rule->forcesType()) forcedType = rule->getTargetType();
350  awr->awar(AWAR_XFERRULE_TYPE)->write_int(forcedType);
351  awr->awar(AWAR_XFERRULE_LOSS)->write_int(haveRule && rule->precisionLossPermitted());
352  awr->awar(AWAR_XFERRULE_INPUT_FIELDS)->write_string(haveRule ? rule->getSourceFields().c_str() : "");
353 }
354 
356  // create a rule from settings currently selected in definition window
357  RulePtr newRule;
358 
359  const char *src = awr->awar(AWAR_XFERRULE_INPUT_FIELDS)->read_char_pntr();
360  const char *dest = awr->awar(AWAR_XFERRULE_TARGETFIELD)->read_char_pntr();
361  const char *aci = awr->awar(AWAR_XFERRULE_ACI)->read_char_pntr();
362  const char *sep = awr->awar(AWAR_XFERRULE_SEP)->read_char_pntr();
363 
364  newRule = aci[0] ? Rule::makeAciConverter(src, sep, aci, dest) : Rule::makeSimple(src, sep, dest);
365 
367  bool permitLoss = awr->awar(AWAR_XFERRULE_LOSS)->read_int();
368 
369  if (type != GB_NONE) newRule->setTargetType(type);
370  if (permitLoss) newRule->permitPrecisionLoss();
371 
372  return newRule;
373 }
374 
376  // rebuild a Rule from current AWAR settings
377  // (called back whenever any awar changes)
378  if (!ignoreRuleDetailChange) {
379  LocallyModify<bool> duringRebuild(ignoreRuleDetailChange, true);
380 
381  const char *failReason;
382  RulePtr selRule = getSelectedRule(failReason);
383  RulePtr newRule = build_rule_from_awars(awr);
384 
385 #if defined(DEBUG)
386  printf("rebuild_rule_from_awars_cb:\n");
387  // dump both configs (of rebuild and of stored rule) allowing to compare them:
388  if (selRule.isSet()) printf(" selRule config: %s\n", selRule->getConfig().c_str());
389  if (newRule.isSet()) printf(" newRule config: %s\n", newRule->getConfig().c_str());
390 #endif
391 
392  if (selRule.isSet() && newRule.isSet()) {
393  string selCfg = selRule->getConfig();
394  string newCfg = newRule->getConfig();
395  if (selCfg != newCfg) { // has rule been changed?
396 #if defined(DEBUG)
397  fputs("Rule has changed!\n", stdout);
398 #endif
399  overwriteSelectedRule(newRule);
400  }
401  }
402  }
403 }
404 
405 static void availfield_selected_cb(AW_root *awr) {
406  char *selField = awr->awar(AWAR_XFERRULE_AVAIL_SELECTED)->read_string();
407  awr->awar(AWAR_XFERRULE_FIELD)->write_string(selField);
408  free(selField);
409 }
410 
412  // called if (a) list of fields changed or
413  // (b) extraction substring changed
414 
415  const char *part = awr->awar(AWAR_XFERRULE_FIELD)->read_char_pntr();
416 
417  // detect whether content of AWAR_XFERRULE_FIELD is partial or full field name:
418  bool isPart = part[0];
419  for (StrSetIter f = knownFields.begin(); f != knownFields.end() && isPart; ++f) {
420  isPart = *f != part; // stop when field matches part
421  }
422 
423  avail->clear();
424 
425  int fieldCount = 0;
426  int shownFieldCount = 0;
427  for (StrSetIter f = knownFields.begin(); f != knownFields.end(); ++f) {
428  const char *field = f->c_str();
429  if (is_info(field)) {
430  avail->insert(field, "");
431  }
432  else {
433  ++fieldCount;
434  if (!isPart || strcasestr(field, part)) { // filter displayed entries based on AWAR_XFERRULE_FIELD content (if isPart)
435  avail->insert(field, field);
436  ++shownFieldCount;
437  }
438  }
439  }
440 
441  // add default (showing info):
442  {
443  const char *info = "";
444 
445  if (fieldCount == 0) info = "<no fields detected>";
446  else if (isPart) {
447  if (shownFieldCount>0) info = GBS_global_string("<fields matching '%s'>", part);
448  else info = GBS_global_string("<no field matches '%s'>", part);
449  }
450 
451  avail->insert_default(info, "");
452  }
453  avail->update();
454 
455  awr->awar(AWAR_XFERRULE_AVAIL_SELECTED)->write_string(part); // select name (or default) in list
456 }
457 
465 };
466 
467 inline void mergeToKnownFields(const StrArray& source) {
468  for (unsigned i = 0; i<source.size(); ++i) {
469  knownFields.insert(source[i]);
470  }
471 }
472 inline size_t removeFromKnownFields(const StrArray& unwanted) {
473  size_t removed = 0;
474  for (unsigned i = 0; i<unwanted.size(); ++i) {
475  removed += knownFields.erase(unwanted[i]);
476  }
477  return removed;
478 }
479 
480 static void mergeKnownFields(AW_root *awr) {
481  // merge fields from client and from RuleSet
483 
484  knownFields.clear();
485  switch (cat) {
488 
489  case FIELDS_BY_RULESET:
492  break;
493 
494  case UNREAD_BY_RULESET: {
497  knownFields.insert(GBS_global_string("<read fields: %zu>", removed));
498  break;
499  }
500 
501  case UNWRITTEN_BY_RULESET: {
504  knownFields.insert(GBS_global_string("<written fields: %zu>", removed));
505  break;
506  }
507 
513  break;
514  }
515 
516 
517  awr->awar(AWAR_XFERRULE_FIELD)->touch(); // calls refresh_availfield_selbox_cb
518 }
519 
521  knownFieldsRulesetInput.erase();
522  knownFieldsRulesetOutput.erase();
523  if (rulesetPtr.isSet()) {
524  rulesetPtr->extractUsedFields(knownFieldsRulesetInput, knownFieldsRulesetOutput);
525  }
526  else {
527  knownFieldsRulesetOutput.put(strdup("<no FTS selected>"));
528  }
529  mergeKnownFields(awr);
530 }
536  if (fieldScanner == currentFieldScanner) {
537  if (whatToScan & SCAN_INPUT_FIELDS) {
538  knownFieldsClientInput.erase();
539  currentFieldScanner->scanFields(knownFieldsClientInput, SCAN_INPUT_FIELDS);
540  }
541  if (whatToScan & SCAN_OUTPUT_FIELDS) {
542  knownFieldsClientOutput.erase();
543  currentFieldScanner->scanFields(knownFieldsClientOutput, SCAN_OUTPUT_FIELDS);
544  }
545  mergeKnownFields(awr);
546  }
547 }
548 
550  ConstStrArray field;
551  {
552  char *fieldsStr = awr->awar(AWAR_XFERRULE_INPUT_FIELDS)->read_string();
553  GBT_splitNdestroy_string(field, fieldsStr, ";", SPLIT_DROPEMPTY);
554  }
555 
556  // fill into selection box:
557  input->clear();
558  {
559  StrUniquifier keyTrack; // avoid problems in list-handling caused by using multiple identical keys
560  for (int i = 0; field[i]; ++i) {
561  const char *disp = field[i];
562  xf_assert(disp && disp[0]); // NULp / empty field unwanted
563 
564  const char *val = keyTrack.make_unique_key(field[i]);
565  xf_assert(val);
566 
567  input->insert(disp, val);
568  }
569  }
570  input->insert_default("", "");
571  input->update();
572 
573  rebuild_rule_from_awars_cb(awr); // @@@ useful?
574 }
575 
577  const char *defaultText; // displays failures (to load RuleSet) in default entry
578  RuleSetPtr ruleset = getSelectedRuleset(defaultText);
579 
580  rules->clear();
581  if (!defaultText) {
582  xf_assert(ruleset.isSet());
583 
584  lintRulesetOnce(ruleset);
585 
586  for (size_t r = 0; r<ruleset->size(); ++r) {
587  const Rule& rule = ruleset->get(r);
588  rules->insert(rule.getShortDescription().c_str(), ruleSelId(r));
589  }
590  defaultText = "no rule";
591  }
592  rules->insert_default(GBS_global_string("<%s>", defaultText), "");
593  rules->update();
594 
597 }
598 
608 
612 }
613 
614 static void clear_field_cb(AW_window *aww) {
616 }
617 
618 static void add_rule_cb(AW_window *aww) {
619  GB_ERROR error = NULp;
620 
621  RuleSetPtr ruleset = getSelectedRuleset(error);
622  if (ruleset.isSet()) {
623  int idx = getSelectedRuleIndex();
624  RulePtr toAdd;
625 
626  if (idx == -1) {
627  // if no rule is selected -> settings may be changed w/o changing any rule.
628  // Clicking ADD in that situation builds and adds a new rule from these settings:
629  toAdd = build_rule_from_awars(aww->get_root());
630  }
631  else {
632  toAdd = Rule::makeSimple("", "", ""); // create empty default rule
633  }
634  {
635  int newIdx = ruleset->insertBefore(idx, toAdd);
636  LocallyModify<int> avoidWarningsAboutOtherRules(onlyLintRuleWithIdx, newIdx);
637  error = saveChangedRuleset(ruleset);
638  }
639  if (!error) {
640  deselectRule();
641  clear_field_cb(aww);
642  }
643  }
644  aw_message_if(error);
645 }
646 static void del_rule_cb(AW_window*) {
647  GB_ERROR error = NULp;
648  int idx = getSelectedRuleIndex();
649 
650  if (idx<0) {
651  error = "no rule selected. nothing deleted.";
652  }
653  else {
654  RuleSetPtr ruleset = getSelectedRuleset(error);
655  if (ruleset.isSet()) {
656  error = checkValidIndex(ruleset, idx);
657  if (!error) {
658  ruleset->erase(idx);
659  error = saveChangedRuleset(ruleset);
660  if (!error) selectRule(idx, ruleset->size());
661  }
662  }
663  }
664  aw_message_if(error);
665 }
666 static void rule_stack_cb(AW_window*, bool toStack) {
667  static RuleContainer stack; // uses one stack for all Rulesets
668 
669  GB_ERROR error = NULp;
670  const bool fromStack = !toStack;
671 
672  if (fromStack && stack.empty()) {
673  error = "nothing copied. cannot paste.";
674  }
675  else {
676  int idx = getSelectedRuleIndex();
677 
678  if (idx<0 && toStack) {
679  error = "no rule selected. nothing copied.";
680  }
681  else {
682  RuleSetPtr ruleset = getSelectedRuleset(error);
683  if (ruleset.isSet()) {
684  if (toStack) {
685  error = checkValidIndex(ruleset, idx);
686  if (!error) {
687  stack.push_back(ruleset->getPtr(idx));
688  selectRule(idx+1, ruleset->size());
689  }
690  }
691  else { // fromStack
692  xf_assert(!stack.empty());
693  RulePtr rule = stack.back();
694  int newIdx = ruleset->insertBefore(idx, rule);
695  {
696  LocallyModify<int> avoidWarningsAboutOtherRules(onlyLintRuleWithIdx, newIdx);
697  LocallyModify<bool> avoidDupWarningsWhenPasting(warnAboutDuplicateTargets, false);
698  error = saveChangedRuleset(ruleset);
699  }
700  if (!error) {
701  selectRule(newIdx, ruleset->size());
702  stack.pop_back();
703  }
704  }
705  }
706  else if (fromStack) {
707  error = "did not paste to nowhere (no ruleset selected)";
708  }
709  }
710  }
711  aw_message_if(error);
712 }
713 
714 inline void updateChangedInputFields(const ConstStrArray& ifield, AW_awar *awar_input_fields) {
715  char *new_input_fields = GBT_join_strings(ifield, ';');
716  awar_input_fields->write_string(new_input_fields);
717  free(new_input_fields);
718 }
719 
720 static void add_field_cb(AW_window *aww, AW_selection_list *inputSel) {
721  AW_root *awr = aww->get_root();
722  const char *field = awr->awar(AWAR_XFERRULE_FIELD)->read_char_pntr();
723 
724  if (!field[0]) { // empty fieldname
725  aw_message("Please select an available field or\n"
726  "enter a custom field name in the textbox below.");
727  }
728  else {
729  GB_ERROR keyError = GB_check_hkey(field);
730  if (keyError) {
731  aw_message(keyError);
732  }
733  else if (inputSel) {
734  AW_awar *awar_input_fields = awr->awar(AWAR_XFERRULE_INPUT_FIELDS);
735  const char *used_input_fields = awar_input_fields->read_char_pntr();
736 
737  int selIdx;
738  if (used_input_fields[0]) { // if we already have fields..
739  ConstStrArray ifield;
740  GBT_split_string(ifield, used_input_fields, ';');
741  selIdx = inputSel->get_index_of_selected();
742  ifield.put_before(selIdx, field);
743  updateChangedInputFields(ifield, awar_input_fields);
744  }
745  else { // insert 1st field
746  awar_input_fields->write_string(field);
747  selIdx = 0;
748  }
749  inputSel->select_element_at(selIdx);
750  }
751  else {
753  }
754  }
755 }
756 
758 static void move_field_cb(AW_window *aww, FieldMoveDest dest, AW_selection_list *inputSel) {
759  AW_root *awr = aww->get_root();
760  AW_awar *awar_input_fields = awr->awar(AWAR_XFERRULE_INPUT_FIELDS);
761  const char *used_input_fields = awar_input_fields->read_char_pntr();
762 
763  if (used_input_fields[0]) {
764  int selIdx = inputSel->get_index_of_selected();
765  if (selIdx>=0) { // is any field selected?
766  ConstStrArray ifield;
767  GBT_split_string(ifield, used_input_fields, ';');
768 
769  int maxIdx = ifield.size()-1;
770  bool needUpdate = false;
771 
772  switch (dest) {
773  case MV_OFF:
774  ifield.remove(selIdx);
775  needUpdate = true;
776  break;
777  case MV_DOWN:
778  if (selIdx<maxIdx) {
779  ifield.move(selIdx, selIdx+1);
780  selIdx++;
781  needUpdate = true;
782  }
783  break;
784  case MV_UP:
785  if (selIdx>0) {
786  ifield.move(selIdx, selIdx-1);
787  selIdx--;
788  needUpdate = true;
789  }
790  break;
791  }
792 
793  if (needUpdate) {
794  updateChangedInputFields(ifield, awar_input_fields);
795  inputSel->select_element_at(selIdx);
796  }
797  }
798  }
799 }
800 
802  static AW_window *aw_define = NULp;
803  if (!aw_define) {
804  AW_window_simple *aws = new AW_window_simple;
805  aws->init(awr, "DEFINE_RULE", "Define rules for field transfer");
806  aws->load_xfig("fts_ruledef.fig");
807 
808  aws->button_length(8);
809 
810  aws->at("close");
811  aws->callback(AW_POPDOWN);
812  aws->create_button("CLOSE", "CLOSE", "C");
813 
814  aws->at("help");
815  aws->callback(makeHelpCallback("xferset.hlp"));
816  aws->create_button("HELP", "HELP", "H");
817 
818  // selection lists
819  aws->at("rules");
820  AW_selection_list *rules = aws->create_selection_list(AWAR_XFERRULE_SELECTED);
821 
822  aws->at("input");
823  AW_selection_list *input = aws->create_selection_list(AWAR_XFERRULE_INPUT_SELECTED);
824 
825  aws->at("avail");
826  AW_selection_list *avail = aws->create_selection_list(AWAR_XFERRULE_AVAIL_SELECTED);
827 
828  // section below left selection list:
829  aws->at("undef");
830  aws->label("Transfer undefined fields?");
831  aws->create_toggle(AWAR_XFERSET_UNDEFINED);
832 
833  // section below middle and right selection lists:
834  aws->at("acat");
835  aws->create_option_menu(AWAR_XFERRULE_AVAIL_CATEGORY);
836  aws->insert_default_option("all", "a", ALL_AVAILABLE_FIELDS);
837  aws->insert_option ("input", "i", INPUT_FIELDS_BY_CLIENT);
838  aws->insert_option ("output", "o", OUTPUT_FIELDS_BY_CLIENT);
839  aws->insert_option ("ruleset", "s", FIELDS_BY_RULESET);
840  aws->insert_option ("unread", "r", UNREAD_BY_RULESET);
841  aws->insert_option ("unwritten", "w", UNWRITTEN_BY_RULESET);
842  aws->update_option_menu();
843 
844  aws->at("field");
845  aws->create_input_field(AWAR_XFERRULE_FIELD);
846 
847  aws->at("sep"); aws->create_input_field(AWAR_XFERRULE_SEP);
848  aws->at("aci"); aws->create_input_field(AWAR_XFERRULE_ACI);
849  aws->at("target"); aws->create_input_field(AWAR_XFERRULE_TARGETFIELD);
850 
851  aws->at("type");
852  aws->create_option_menu(AWAR_XFERRULE_TYPE);
853  aws->insert_option ("Ascii text", "s", GB_STRING);
854  aws->insert_option ("Rounded numerical", "i", GB_INT);
855  aws->insert_option ("Floating-point n.", "F", GB_FLOAT);
856  aws->insert_option ("Bitmask (0/1)", "B", GB_BITS);
857  aws->insert_default_option("Automatic", "A", GB_NONE);
858  aws->update_option_menu();
859 
860  aws->at("loss"); aws->create_toggle(AWAR_XFERRULE_LOSS);
861 
862  // ---------------------------------------
863  // buttons below selection lists
864  aws->button_length(6);
865  aws->auto_space(5, 5);
866 
867  aws->at("rbut"); // left sellist
868  aws->callback(add_rule_cb); aws->create_button("ADD_RULE", "ADD");
869  aws->callback(del_rule_cb); aws->create_button("DEL_RULE", "DEL");
870  aws->callback(makeWindowCallback(rule_stack_cb, true)); aws->create_button("COPY_RULE", "COPY");
871  aws->callback(makeWindowCallback(rule_stack_cb, false)); aws->create_button("PASTE_RULE", "PASTE");
872 
873  aws->at("idel"); // center sellist
874  aws->callback(makeWindowCallback(move_field_cb, MV_OFF, input)); aws->create_button("INPUT_DROP", "DROP");
875  aws->callback(makeWindowCallback(move_field_cb, MV_UP, input)); aws->create_button("INPUT_UP", "UP");
876  aws->callback(makeWindowCallback(move_field_cb, MV_DOWN, input)); aws->create_button("INPUT_DOWN", "DOWN");
877 
878  aws->at("iadd"); // right sellist
879  aws->callback(makeWindowCallback(add_field_cb, input)); aws->create_button("INPUT_ADD", "FROM");
880  aws->callback(makeWindowCallback(add_field_cb, (AW_selection_list*)NULp)); aws->create_button("OUTPUT_ADD", "TO");
881  aws->callback(makeWindowCallback(clear_field_cb)); aws->create_button("CLEAR", "CLEAR");
882 
883  // bind awar callbacks:
884  awr->awar(AWAR_XFERSET_SELECTED) ->add_callback(makeRootCallback(refresh_rule_selection_box_cb, rules));
887  awr->awar(AWAR_XFERRULE_FIELD) ->add_callback(makeRootCallback(refresh_availfield_selbox_cb, avail));
890 
896 
897  awar_selected_FTS()->touch(); // calls refresh_rule_selection_box_cb
898  awr->awar(AWAR_XFERRULE_FIELD)->touch(); // calls refresh_availfield_selbox_cb
899 
900  aw_define = aws;
901  }
902  aw_define->activate();
903 }
904 
905 // ----------------------------------------------
906 // AWAR change callbacks (RuleSetAdmin)
907 
908 static void fts_filesel_changed_cb(AW_root *awr) {
909  static bool recursion = false;
910  if (!recursion) {
911  LocallyModify<bool> avoid(recursion, true);
912 
914  char *fts_nameOnly = getNameOnly(fts);
915 
916  if (fts_nameOnly && !GB_is_directory(fts)) { // avoid directory (otherwise would write 'fts' to AWAR_XFERSET_SELECTED)
917  set_selected_FTS(fts_nameOnly);
918  free(fts_nameOnly);
919  }
920  else {
922  }
923  free(fts);
924  }
925 }
926 
927 static bool ignoreRulesetAwarChange = false;
928 
929 static void selected_fts_changed_cb(AW_root *awr) {
930  static bool recursion = false;
931  if (!recursion) {
932  LocallyModify<bool> avoid(recursion, true);
933 
934  string fts = get_selected_FTS();
936 
937  string comment;
938  bool transferUndef = false;
939  if (GB_is_readablefile(fts.c_str())) {
940  ErrorOrRuleSetPtr loaded = RuleSet::loadFrom(fts.c_str());
941  if (loaded.hasError()) {
942  aw_message_if(loaded.getError().deliver());
943  }
944  else {
945  const RuleSet& ruleset = *loaded.getValue();
946 
947  comment = ruleset.getComment();
948  transferUndef = ruleset.shallTransferUndefFields();
949  }
950  }
951  LocallyModify<bool> duringCommentReload(ignoreRulesetAwarChange, true);
952  awr->awar(AWAR_XFERSET_COMMENT)->write_string(comment.c_str());
953  awr->awar(AWAR_XFERSET_UNDEFINED)->write_int(transferUndef);
954  }
955 }
956 
957 static void ruleset_awar_changed_cb(AW_root *awr, const char *awarname) {
959  string fts = get_selected_FTS();
960  if (GB_is_readablefile(fts.c_str())) {
961  ErrorOrRuleSetPtr loaded = RuleSet::loadFrom(fts.c_str());
962  if (loaded.hasError()) {
963  aw_message_if(loaded.getError().deliver());
964  }
965  else {
966  RuleSetPtr ruleset = loaded.getValue();
967  bool save = false;
968 
969  if (strcmp(awarname, AWAR_XFERSET_COMMENT) == 0) {
970  string saved = ruleset->getComment();
971  const char *changed = awr->awar(AWAR_XFERSET_COMMENT)->read_char_pntr();
972  if (strcmp(saved.c_str(), changed) != 0) { // comment was changed
973  ruleset->setComment(changed);
974  save = true;
975  }
976  }
977  else if (strcmp(awarname, AWAR_XFERSET_UNDEFINED) == 0) {
978  bool transferUndef = awr->awar(AWAR_XFERSET_UNDEFINED)->read_int();
979  if (transferUndef != ruleset->shallTransferUndefFields()) { // setting was changed
980  ruleset->set_transferUndefFields(transferUndef);
981  save = true;
982  }
983  }
984  else { xf_assert(0); } // unknown awar
985 
986  if (save) {
987  GB_ERROR error = ruleset->saveTo(fts.c_str());
988  aw_message_if(error);
990 
991  awar_selected_FTS()->touch(); // refresh fts if setting is changed
992  }
993  }
994  }
995  else {
996  aw_message("Please select an existing FTS, then try again to change this setting.");
997  }
998  }
999 }
1000 
1001 // -----------------------------------------
1002 // button callbacks (RuleSetAdmin)
1003 static void editRuleset_cb(AW_window *aww) {
1004  string fullfts = get_selected_FTS();
1005  GB_ERROR error = check_valid_existing_fts(fullfts.c_str());
1006  if (!error) popup_rule_definition_window(aww->get_root());
1007  aw_message_if(error);
1008 }
1009 static void createRuleset_cb(AW_window *aww) {
1010  string fullfts = get_selected_FTS();
1011  GB_ERROR error = check_valid_target_fts(fullfts.c_str());
1012  if (!error) {
1013  RuleSet empty;
1014  error = empty.saveTo(fullfts.c_str());
1015  if (!error) {
1017  awar_selected_FTS()->touch(); // will trigger refresh on client-side (e.g. rerun test-import or -export)
1018  editRuleset_cb(aww); // simulate press EDIT
1019  }
1020  }
1021  aw_message_if(error);
1022 }
1023 
1025 static GB_ERROR copyMoveRuleset_cb(const char *new_name, copyMoveMode mode) {
1026  // copy or rename the currently selected ruleset
1027 
1028  // error if no RuleSet selected
1029  string fullSourceFts = get_selected_FTS();
1030  GB_ERROR error = check_valid_existing_fts(fullSourceFts.c_str()); // (e.g. click COPY with selected, then deselect, then start copy)
1031 
1032  // build full target file name. fail if new_name exists.
1033  string fullTargetFts;
1034  if (!error) {
1035  char *path;
1036  GB_split_full_path(fullSourceFts.c_str(), &path, NULp, NULp, NULp);
1037  if (new_name[0]) {
1038  fullTargetFts = GB_concat_path(path, GB_append_suffix(new_name, "fts"));
1039  }
1040  error = check_valid_target_fts(fullTargetFts.c_str());
1041  }
1042 
1043  // copy or move file
1044  if (!error) {
1045  switch (mode) {
1046  case COPY_RULESET: error = GB_safe_copy_file(fullSourceFts.c_str(), fullTargetFts.c_str()); break;
1047  case MOVE_RULESET: error = GB_safe_rename_file(fullSourceFts.c_str(), fullTargetFts.c_str()); break;
1048  }
1049  }
1050 
1051  // force selbox refresh + select new
1052  if (!error) {
1055  set_selected_FTS(new_name);
1056  }
1057 
1058 
1059  return error;
1060 }
1061 
1063  string fullfts = get_selected_FTS();
1064  GB_ERROR error = check_valid_existing_fts(fullfts.c_str());
1065  if (error) {
1066  aw_message(error);
1067  }
1068  else {
1069  const char *title = NULp;
1070  const char *prompt = NULp;
1071  const char *butTxt = NULp;
1072  switch (mode) {
1073  case COPY_RULESET:
1074  title = "Copy ruleset";
1075  prompt = "Enter the name of the new ruleset:";
1076  butTxt = "Copy";
1077  break;
1078  case MOVE_RULESET:
1079  title = "Rename ruleset";
1080  prompt = "Enter the new name for the ruleset:";
1081  butTxt = "Rename";
1082  break;
1083  }
1084 
1085  char *old_name;
1086  GB_split_full_path(fullfts.c_str(), NULp, NULp, &old_name, NULp);
1087  AWT_activate_prompt(title, prompt, old_name, butTxt, makeResultHandler(copyMoveRuleset_cb, mode));
1088  free(old_name);
1089  }
1090 }
1091 static void deleteRuleset_cb() {
1092  string fullfts = get_selected_FTS();
1093  GB_ERROR error = check_valid_existing_fts(fullfts.c_str());
1094  if (!error) {
1095  if (GB_unlink(fullfts.c_str())<0) {
1096  error = GB_await_error();
1097  }
1098  else {
1101  }
1102  }
1103  aw_message_if(error);
1104 }
1105 
1106 static void noRuleset_cb() {
1109 }
1110 
1111 // ------------------------------
1112 // RuleSet admin window
1113 static void selected_fts_file_changed(const char *, ChangeReason reason) {
1114  switch (reason) {
1115  case CR_MODIFIED:
1116  awar_selected_FTS()->touch(); // triggers reload of RuleSet
1117  break;
1118 
1119  case CR_DELETED:
1120  noRuleset_cb(); // = press NONE button
1121  break;
1122 
1123  case CR_CREATED: break;
1124  }
1125 }
1126 
1127 static void initXferAwars(AW_root *awr) {
1128  static bool initialized = false;
1129  if (!initialized) {
1133 
1135 
1138 
1141 
1143 
1144  static FileWatch watchSelectedFts(AWAR_XFERSET_FTSNAME, makeFileChangedCallback(selected_fts_file_changed));
1145 
1146  initialized = true;
1147  }
1148 }
1149 
1151  static AW_window *aw_select = NULp;
1152  if (!aw_select) {
1153  AW_window_simple *aws = new AW_window_simple;
1154  aws->init(awr, "SELECT_FTS", "Select field transfer set (FTS)");
1155  aws->load_xfig("fts_select.fig");
1156 
1157  aws->button_length(8);
1158 
1159  aws->at("close");
1160  aws->callback(AW_POPDOWN);
1161  aws->create_button("CLOSE", "CLOSE", "C");
1162 
1163  aws->at("help");
1164  aws->callback(makeHelpCallback("xferset.hlp"));
1165  aws->create_button("HELP", "HELP", "H");
1166 
1167  aws->at("name");
1168  aws->create_input_field(AWAR_XFERSET_SELECTED);
1169 
1170  aws->at("comment");
1171  aws->create_text_field(AWAR_XFERSET_COMMENT);
1172 
1173  AW_create_fileselection(aws, AWAR_XFERSET_FTSBASE, "fts", ".", MULTI_DIRS, false);
1174 
1175  aws->at("create");
1176  aws->callback(makeWindowCallback(createRuleset_cb));
1177  aws->create_button("CREATE", "CREATE", "N");
1178 
1179  aws->at("edit");
1180  aws->callback(makeWindowCallback(editRuleset_cb));
1181  aws->create_button("EDIT", "EDIT", "E");
1182 
1183  aws->at("copy");
1184  aws->callback(makeWindowCallback(askCopyMoveRuleset_cb, COPY_RULESET));
1185  aws->create_button("COPY", "COPY", "Y");
1186 
1187  aws->at("delete");
1188  aws->callback(makeWindowCallback(deleteRuleset_cb));
1189  aws->create_button("DELETE", "DELETE", "D");
1190 
1191  aws->at("rename");
1192  aws->callback(makeWindowCallback(askCopyMoveRuleset_cb, MOVE_RULESET));
1193  aws->create_button("RENAME", "RENAME", "R");
1194 
1195  aws->at("none");
1196  aws->callback(makeWindowCallback(noRuleset_cb));
1197  aws->create_button("NONE", "NONE", "O");
1198 
1199  aw_select = aws;
1200  }
1201  aw_select->activate();
1202 }
1203 
1204 void XFER_select_RuleSet(AW_window *aww, const char *awar_selected_fts, const AvailableFieldScanner *fieldScanner) {
1209  AW_root *awr = aww->get_root();
1210  initXferAwars(awr);
1211  awr->awar(AWAR_XFERSET_SELECTED)->map(awar_selected_fts);
1212 
1213  if (fieldScanner != currentFieldScanner) {
1214  currentFieldScanner = fieldScanner;
1215  XFER_refresh_available_fields(awr, currentFieldScanner, SCAN_ALL_FIELDS);
1216  }
1217 
1219 }
1220 
const char * GB_ERROR
Definition: arb_core.h:25
static StrSet knownFields
Definition: xfergui.cxx:91
string result
GB_TYPES type
#define AWAR_XFERSET_COMMENT
Definition: xfergui.cxx:40
set< string, lt_field > StrSet
Definition: xfergui.cxx:84
GB_CSTR GB_path_in_arbprop(const char *relative_path)
Definition: adsocket.cxx:1166
size_t size() const
Definition: arb_strarray.h:85
void AW_set_selected_fullname(AW_root *awr, const char *awar_prefix, const char *to_fullname)
Definition: AW_file.cxx:940
static StrArray knownFieldsRulesetInput
Definition: xfergui.cxx:89
GB_ERROR GB_safe_copy_file(const char *oldpath, const char *newpath)
Definition: arb_file.cxx:342
void XFER_select_RuleSet(AW_window *aww, const char *awar_selected_fts, const AvailableFieldScanner *fieldScanner)
Definition: xfergui.cxx:1204
#define AWAR_XFERRULE_INPUT_SELECTED
Definition: xfergui.cxx:56
Definition: arbdb.h:69
static void refresh_inputfield_selbox_cb(AW_root *awr, AW_selection_list *input)
Definition: xfergui.cxx:549
void select_element_at(int wanted_index)
Definition: AW_select.cxx:433
void insert_default(const char *displayed, const AW_scalar &value)
Definition: AW_select.cxx:385
char * getNameOnly(const char *fullpath)
Definition: xfergui.cxx:117
static const char * get_selected_FTS()
Definition: xfergui.cxx:109
static void noRuleset_cb()
Definition: xfergui.cxx:1106
static void initXferAwars(AW_root *awr)
Definition: xfergui.cxx:1127
static void selected_fts_changed_cb(AW_root *awr)
Definition: xfergui.cxx:929
string getShortDescription() const
Definition: xferset.cxx:544
static bool ignoreRuleDetailChange
Definition: xfergui.cxx:335
long read_int() const
Definition: AW_awar.cxx:184
bool hasError() const
Definition: ErrorOrType.h:50
static const AvailableFieldScanner * currentFieldScanner
Definition: xfergui.cxx:82
TYPE getValue() const
Definition: ErrorOrType.h:58
StrSet::iterator StrSetIter
Definition: xfergui.cxx:85
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
const char * title
Definition: readseq.c:22
static ExportFieldScanner fieldScanner
char * AW_get_selected_fullname(AW_root *awr, const char *awar_prefix)
Definition: AW_file.cxx:906
STL namespace.
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
#define AWAR_XFERRULE_SEP
Definition: xfergui.cxx:52
int get_index_of_selected()
Definition: AW_select.cxx:316
int GB_unlink(const char *path)
Definition: arb_file.cxx:188
copyMoveMode
Definition: xfergui.cxx:1024
static GB_ERROR check_valid_target_fts(const char *fullfts)
Definition: xfergui.cxx:318
void activate()
Definition: aw_window.hxx:365
#define AWAR_XFERRULE_FIELD
Definition: xfergui.cxx:59
#define NO_XFERSET_SELECTED
Definition: xfergui.cxx:63
__ATTR__USERESULT GB_ERROR saveTo(const char *filename) const
Definition: xferset.cxx:323
static RulePtr build_rule_from_awars(AW_root *awr)
Definition: xfergui.cxx:355
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
static RuleSetPtr getSelectedRuleset(const char *&failReason)
Definition: xfergui.cxx:123
#define AWAR_XFERRULE_TARGETFIELD
Definition: xfergui.cxx:50
void mergeToKnownFields(const StrArray &source)
Definition: xfergui.cxx:467
#define AWAR_XFERRULE_INPUT_FIELDS
Definition: xfergui.cxx:55
void insert(const char *displayed, const AW_scalar &value)
Definition: AW_select.cxx:380
GB_ERROR GB_safe_rename_file(const char *oldpath, const char *newpath)
Definition: arb_file.cxx:332
static void createRuleset_cb(AW_window *aww)
Definition: xfergui.cxx:1009
static bool initialized
Definition: AW_advice.cxx:36
GB_ERROR GB_check_hkey(const char *key) __ATTR__USERESULT
Definition: adstring.cxx:92
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
static AW_root * SINGLETON
Definition: aw_root.hxx:102
AvailCategory
Definition: xfergui.cxx:458
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
Definition: arbdb.h:67
GB_ERROR check_valid_existing_fts(const char *fullfts)
Definition: xfergui.cxx:315
static bool warnAboutDuplicateTargets
Definition: xfergui.cxx:213
int getSelectedRuleIndex()
Definition: xfergui.cxx:144
GB_ERROR deliver() const
Definition: arb_error.h:116
static RulePtr getSelectedRule(const char *&failReason)
Definition: xfergui.cxx:174
const char * awarname(const char *awarname_template, int idx)
Definition: ED4_flags.cxx:37
bool isSet() const
test if SmartPtr is not NULp
Definition: smartptr.h:245
static void move_field_cb(AW_window *aww, FieldMoveDest dest, AW_selection_list *inputSel)
Definition: xfergui.cxx:758
static void popup_rule_definition_window(AW_root *awr)
Definition: xfergui.cxx:801
static void refresh_rule_selection_box_cb(AW_root *awr, AW_selection_list *rules)
Definition: xfergui.cxx:576
Generic smart pointer.
Definition: smartptr.h:149
AW_awar * awar_selected_FTS()
Definition: xfergui.cxx:106
static void deleteRuleset_cb()
Definition: xfergui.cxx:1091
void set_handled() const
Definition: arb_error.h:133
const string & targetField() const
Definition: xferset.h:153
static void selected_rule_changed_cb(AW_root *awr)
Definition: xfergui.cxx:337
bool operator()(const string &s1, const string &s2) const
Definition: xfergui.cxx:72
#define xf_assert(cond)
Definition: xferset.h:31
bool shallTransferUndefFields() const
Definition: xferset.h:261
static StrArray knownFieldsClientInput
Definition: xfergui.cxx:87
void touch()
Definition: AW_awar.cxx:207
static void error(const char *msg)
Definition: mkptypes.cxx:96
#define AWAR_XFERSET_FTSNAME
Definition: xfergui.cxx:45
void remove(int i)
void AW_create_fileselection_awars(AW_root *awr, const char *awar_base, const char *directories, const char *filter, const char *file_name)
Definition: AW_file.cxx:72
FieldsToScan
Definition: xfergui.h:21
const string & getComment() const
Definition: xferset.h:259
static void clear_field_cb(AW_window *aww)
Definition: xfergui.cxx:614
static void lintRuleset(RuleSetPtr ruleset)
Definition: xfergui.cxx:214
static void del_rule_cb(AW_window *)
Definition: xfergui.cxx:646
#define cmp(h1, h2)
Definition: admap.cxx:50
#define AWAR_XFERRULE_ACI
Definition: xfergui.cxx:51
static void rule_stack_cb(AW_window *, bool toStack)
Definition: xfergui.cxx:666
bool is_info(const char *field)
Definition: xfergui.cxx:68
char * read_string() const
Definition: AW_awar.cxx:198
void put_before(int insert_before, const char *elem)
Definition: arb_strarray.h:197
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
const char * ruleSelId(int idx)
Definition: xfergui.cxx:156
FieldMoveDest
Definition: xfergui.cxx:757
const char * XFER_getFullFTS(const char *name)
Definition: xfergui.cxx:96
#define AWAR_XFERSET_UNDEFINED
Definition: xfergui.cxx:41
void AW_refresh_fileselection(AW_root *awr, const char *awar_prefix)
Definition: AW_file.cxx:944
static char * cat(char *toBuf, const char *s1, const char *s2)
Definition: ED4_root.cxx:1023
static void selectRule(int idx, int ruleCount)
Definition: xfergui.cxx:164
static void editRuleset_cb(AW_window *aww)
Definition: xfergui.cxx:1003
GB_CSTR GB_append_suffix(const char *name, const char *suffix)
Definition: adsocket.cxx:984
static void init_rule_definition_awars(AW_root *awr)
Definition: xfergui.cxx:599
char * GBT_join_strings(const CharPtrArray &strings, char separator)
fputs(TRACE_PREFIX, stderr)
Definition: arbdb.h:63
#define AWAR_XFERRULE_AVAIL_SELECTED
Definition: xfergui.cxx:57
GB_CSTR GB_concat_path(GB_CSTR anypath_left, GB_CSTR anypath_right)
Definition: adsocket.cxx:1069
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
static bool ignoreRulesetAwarChange
Definition: xfergui.cxx:927
GB_ERROR saveChangedRuleset(RuleSetPtr ruleset)
Definition: xfergui.cxx:196
static void fts_filesel_changed_cb(AW_root *awr)
Definition: xfergui.cxx:908
#define AWAR_XFERRULE_LOSS
Definition: xfergui.cxx:54
static void askCopyMoveRuleset_cb(AW_window *, copyMoveMode mode)
Definition: xfergui.cxx:1062
bool GB_is_directory(const char *path)
Definition: arb_file.cxx:176
void set_selected_FTS(const char *name)
Definition: xfergui.cxx:113
static void add_rule_cb(AW_window *aww)
Definition: xfergui.cxx:618
static StrArray knownFieldsClientOutput
Definition: xfergui.cxx:88
AW_awar * map(const char *awarn)
Definition: AW_awar.cxx:521
void move(int from, int to)
ChangeReason
Definition: aw_inotify.hxx:18
GB_ERROR checkValidIndex(RuleSetPtr ruleset, int idx)
Definition: xfergui.cxx:159
static void deselectRule()
Definition: xfergui.cxx:172
static void overwriteSelectedRule(RulePtr newRule)
Definition: xfergui.cxx:294
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
static void selected_fts_file_changed(const char *, ChangeReason reason)
Definition: xfergui.cxx:1113
AW_root * get_root()
Definition: aw_window.hxx:359
#define AWAR_XFERRULE_TYPE
Definition: xfergui.cxx:53
void GB_split_full_path(const char *fullpath, char **res_dir, char **res_fullname, char **res_name_only, char **res_suffix)
Definition: adsocket.cxx:1268
static void add_field_cb(AW_window *aww, AW_selection_list *inputSel)
Definition: xfergui.cxx:720
static void refresh_availfield_selbox_cb(AW_root *awr, AW_selection_list *avail)
Definition: xfergui.cxx:411
#define NULp
Definition: cxxforward.h:116
bool GB_is_readablefile(const char *filename)
Definition: arb_file.cxx:172
#define AWAR_XFERSET_SELECTED
Definition: xfergui.cxx:39
static void refresh_available_fields_from_ruleset(AW_root *awr, RuleSetPtr rulesetPtr)
Definition: xfergui.cxx:520
void AW_create_fileselection(AW_window *aws, const char *awar_prefix, const char *at_prefix, const char *pwd, DirDisplay disp_dirs, bool allow_wildcards)
Definition: AW_file.cxx:870
GB_ERROR write_string(const char *aw_string)
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, SplitMode mode)
Definition: arb_strarray.h:223
static int onlyLintRuleWithIdx
Definition: xfergui.cxx:212
bool ARB_strBeginsWith(const char *str, const char *with)
Definition: arb_str.h:42
#define AWAR_XFERRULE_SELECTED
Definition: xfergui.cxx:49
GB_TYPES
Definition: arbdb.h:62
ARB_ERROR getError() const
Definition: ErrorOrType.h:53
#define AWAR_XFERRULE_AVAIL_CATEGORY
Definition: xfergui.cxx:58
static void mergeKnownFields(AW_root *awr)
Definition: xfergui.cxx:480
void updateChangedInputFields(const ConstStrArray &ifield, AW_awar *awar_input_fields)
Definition: xfergui.cxx:714
size_t removeFromKnownFields(const StrArray &unwanted)
Definition: xfergui.cxx:472
const char * make_unique_key(const char *key)
Definition: StrUniquifier.h:42
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
void XFER_refresh_available_fields(AW_root *awr, const AvailableFieldScanner *fieldScanner, FieldsToScan whatToScan)
Definition: xfergui.cxx:531
static void availfield_selected_cb(AW_root *awr)
Definition: xfergui.cxx:405
static void ruleset_awar_changed_cb(AW_root *awr, const char *awarname)
Definition: xfergui.cxx:957
static GB_ERROR copyMoveRuleset_cb(const char *new_name, copyMoveMode mode)
Definition: xfergui.cxx:1025
static int info[maxsites+1]
void GBT_splitNdestroy_string(ConstStrArray &names, char *&namelist, const char *separator, SplitMode mode)
void refresh_fts_selbox()
Definition: xfergui.cxx:193
static void rebuild_rule_from_awars_cb(AW_root *awr)
Definition: xfergui.cxx:375
static StrArray knownFieldsRulesetOutput
Definition: xfergui.cxx:90
#define AW_ROOT_DEFAULT
Definition: aw_base.hxx:106
#define AWAR_XFERSET_FTSBASE
Definition: xfergui.cxx:44
GB_ERROR write_int(long aw_int)
virtual void scanFields(StrArray &fields, FieldsToScan whatToScan) const =0
static void popup_ruleset_admin_window(AW_root *awr)
Definition: xfergui.cxx:1150
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
static void lintRulesetOnce(RuleSetPtr ruleset)
Definition: xfergui.cxx:270
Definition: arbdb.h:66
std::vector< RulePtr > RuleContainer
Definition: xferset.h:207
void AWT_activate_prompt(const char *title, const char *prompt, const char *defaultResult, const char *button, const ResultHandler &handle_result, const char *helpfile, const char *srt)
Definition: AWT_prompt.cxx:62