| 1 | // ==================================================================== // |
|---|
| 2 | // // |
|---|
| 3 | // File : AW_global_awars.cxx // |
|---|
| 4 | // Purpose : Make some awars accessible from ALL arb applications // |
|---|
| 5 | // // |
|---|
| 6 | // Coded by Ralf Westram (coder@reallysoft.de) in January 2003 // |
|---|
| 7 | // Copyright Department of Microbiology (Technical University Munich) // |
|---|
| 8 | // // |
|---|
| 9 | // Visit our web site at: http://www.arb-home.de/ // |
|---|
| 10 | // // |
|---|
| 11 | // ==================================================================== // |
|---|
| 12 | |
|---|
| 13 | #define TEMP_DB_PATH "tmp/global_awars" |
|---|
| 14 | |
|---|
| 15 | #include <arbdb.h> |
|---|
| 16 | #include <ad_cb.h> |
|---|
| 17 | #include <aw_global_awars.hxx> |
|---|
| 18 | #include <aw_awars.hxx> |
|---|
| 19 | #include <aw_root.hxx> |
|---|
| 20 | #include <aw_window.hxx> |
|---|
| 21 | |
|---|
| 22 | static GBDATA *gb_main4awar = NULp; // gb_main used for global awars |
|---|
| 23 | |
|---|
| 24 | inline const char *get_db_path(const AW_awar *awar) { |
|---|
| 25 | return GBS_global_string("%s/%s", TEMP_DB_PATH, awar->awar_name); |
|---|
| 26 | } |
|---|
| 27 | |
|---|
| 28 | static bool in_global_awar_cb = false; |
|---|
| 29 | |
|---|
| 30 | static void awar_updated_cb(AW_root*, AW_awar *awar) { |
|---|
| 31 | if (!in_global_awar_cb) { |
|---|
| 32 | char *content = awar->read_as_string(); |
|---|
| 33 | const char *db_path = get_db_path(awar); |
|---|
| 34 | GB_transaction ta(gb_main4awar); |
|---|
| 35 | GBDATA *gbd = GB_search(gb_main4awar, db_path, GB_FIND); |
|---|
| 36 | |
|---|
| 37 | aw_assert(gbd); // should exists |
|---|
| 38 | |
|---|
| 39 | LocallyModify<bool> flag(in_global_awar_cb, true); |
|---|
| 40 | GB_write_string(gbd, content); |
|---|
| 41 | free(content); |
|---|
| 42 | } |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | static void db_updated_cb(GBDATA *gbd, AW_awar *awar) { |
|---|
| 46 | if (!in_global_awar_cb) { |
|---|
| 47 | GB_transaction ta(gb_main4awar); |
|---|
| 48 | LocallyModify<bool> flag(in_global_awar_cb, true); |
|---|
| 49 | |
|---|
| 50 | awar->write_as_string(GB_read_char_pntr(gbd)); |
|---|
| 51 | } |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | GB_ERROR AW_awar::make_global() { |
|---|
| 55 | #if defined(DEBUG) |
|---|
| 56 | aw_assert(!is_global); // don't make awars global twice! |
|---|
| 57 | aw_assert(gb_main4awar); |
|---|
| 58 | is_global = true; |
|---|
| 59 | #endif // DEBUG |
|---|
| 60 | |
|---|
| 61 | add_callback(makeRootCallback(awar_updated_cb, this)); |
|---|
| 62 | |
|---|
| 63 | GB_transaction ta(gb_main4awar); |
|---|
| 64 | const char *db_path = get_db_path(this); |
|---|
| 65 | GBDATA *gbd = GB_search(gb_main4awar, db_path, GB_FIND); |
|---|
| 66 | GB_ERROR error = NULp; |
|---|
| 67 | |
|---|
| 68 | if (gbd) { // was already set by another ARB application |
|---|
| 69 | // -> read db value and store in awar |
|---|
| 70 | |
|---|
| 71 | const char *content = GB_read_char_pntr(gbd); |
|---|
| 72 | write_as_string(content); |
|---|
| 73 | } |
|---|
| 74 | else { |
|---|
| 75 | // store awar value in db |
|---|
| 76 | |
|---|
| 77 | char *content = read_as_string(); |
|---|
| 78 | gbd = GB_search(gb_main4awar, db_path, GB_STRING); |
|---|
| 79 | if (!gbd) error = GB_await_error(); |
|---|
| 80 | else error = GB_write_string(gbd, content); |
|---|
| 81 | free(content); |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | if (!error) GB_add_callback(gbd, GB_CB_CHANGED, makeDatabaseCallback(db_updated_cb, this)); |
|---|
| 85 | return error; |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | static bool initialized = false; |
|---|
| 89 | |
|---|
| 90 | bool ARB_global_awars_initialized() { |
|---|
| 91 | return initialized; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | bool ARB_in_expert_mode(AW_root *awr) { |
|---|
| 95 | aw_assert(ARB_global_awars_initialized()); |
|---|
| 96 | int mask = awr->awar(AWAR_AWM_MASK)->read_int(); |
|---|
| 97 | return mask == AWM_MASK_EXPERT; |
|---|
| 98 | } |
|---|
| 99 | |
|---|
| 100 | static void AWAR_AWM_MASK_changed_cb(AW_root *awr) { |
|---|
| 101 | int mask = awr->awar(AWAR_AWM_MASK)->read_int(); |
|---|
| 102 | #if defined(DEBUG) |
|---|
| 103 | printf("AWAR_AWM_MASK changed, calling apply_sensitivity(%i)\n", mask); |
|---|
| 104 | #endif |
|---|
| 105 | awr->apply_sensitivity(mask); |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | static void AWAR_AW_FOCUS_FOLLOWS_MOUSE_changed_cb(AW_root *awr) { |
|---|
| 109 | int focus = awr->awar(AWAR_AW_FOCUS_FOLLOWS_MOUSE)->read_int(); |
|---|
| 110 | #if defined(DEBUG) |
|---|
| 111 | printf("AWAR_AW_FOCUS_FOLLOWS_MOUSE changed, calling apply_focus_policy(%i)\n", focus); |
|---|
| 112 | #endif |
|---|
| 113 | awr->apply_focus_policy(focus); |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | #if defined(DARWIN) |
|---|
| 117 | #define OPENURL "open" |
|---|
| 118 | #else |
|---|
| 119 | #define OPENURL "xdg-open" |
|---|
| 120 | #endif // DARWIN |
|---|
| 121 | |
|---|
| 122 | #define MAX_GLOBAL_AWARS 5 |
|---|
| 123 | |
|---|
| 124 | static AW_awar *declared_awar[MAX_GLOBAL_AWARS]; |
|---|
| 125 | static int declared_awar_count = 0; |
|---|
| 126 | |
|---|
| 127 | inline void declare_awar_global(AW_awar *awar) { |
|---|
| 128 | aw_assert(declared_awar_count<MAX_GLOBAL_AWARS); |
|---|
| 129 | declared_awar[declared_awar_count++] = awar; |
|---|
| 130 | } |
|---|
| 131 | |
|---|
| 132 | void ARB_declare_global_awars(AW_root *aw_root, AW_default aw_def) { |
|---|
| 133 | aw_assert(!declared_awar_count); |
|---|
| 134 | |
|---|
| 135 | declare_awar_global(aw_root->awar_string(AWAR_WWW_BROWSER, OPENURL " \"$(URL)\"", aw_def)); |
|---|
| 136 | declare_awar_global(aw_root->awar_int(AWAR_AWM_MASK, AWM_MASK_UNKNOWN, aw_def)->add_callback(AWAR_AWM_MASK_changed_cb)); |
|---|
| 137 | declare_awar_global(aw_root->awar_string(AWAR_ARB_TREE_RENAMED, "", aw_def)); |
|---|
| 138 | declare_awar_global(aw_root->awar_string(AWAR_SAVED_DB_PATH, "", aw_def)); |
|---|
| 139 | |
|---|
| 140 | AW_awar *awar_focus = aw_root->awar_int(AWAR_AW_FOCUS_FOLLOWS_MOUSE, 0, aw_def); |
|---|
| 141 | aw_root->focus_follows_mouse = awar_focus->read_int(); |
|---|
| 142 | awar_focus->add_callback(AWAR_AW_FOCUS_FOLLOWS_MOUSE_changed_cb); |
|---|
| 143 | declare_awar_global(awar_focus); |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | GB_ERROR ARB_bind_global_awars(GBDATA *gb_main) { |
|---|
| 147 | aw_assert(!initialized); // don't call twice! |
|---|
| 148 | aw_assert(!gb_main4awar); |
|---|
| 149 | aw_assert(declared_awar_count); // b4 call ARB_declare_global_awars! |
|---|
| 150 | |
|---|
| 151 | initialized = true; |
|---|
| 152 | gb_main4awar = gb_main; |
|---|
| 153 | |
|---|
| 154 | GB_ERROR error = NULp; |
|---|
| 155 | for (int a = 0; a<declared_awar_count && !error; ++a) { |
|---|
| 156 | error = declared_awar[a]->make_global(); |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | return error; |
|---|
| 160 | } |
|---|
| 161 | |
|---|