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 | |
---|
139 | AW_awar *awar_focus = aw_root->awar_int(AWAR_AW_FOCUS_FOLLOWS_MOUSE, 0, aw_def); |
---|
140 | aw_root->focus_follows_mouse = awar_focus->read_int(); |
---|
141 | awar_focus->add_callback(AWAR_AW_FOCUS_FOLLOWS_MOUSE_changed_cb); |
---|
142 | declare_awar_global(awar_focus); |
---|
143 | } |
---|
144 | |
---|
145 | GB_ERROR ARB_bind_global_awars(GBDATA *gb_main) { |
---|
146 | aw_assert(!initialized); // don't call twice! |
---|
147 | aw_assert(!gb_main4awar); |
---|
148 | aw_assert(declared_awar_count); // b4 call ARB_declare_global_awars! |
---|
149 | |
---|
150 | initialized = true; |
---|
151 | gb_main4awar = gb_main; |
---|
152 | |
---|
153 | GB_ERROR error = NULp; |
---|
154 | for (int a = 0; a<declared_awar_count && !error; ++a) { |
---|
155 | error = declared_awar[a]->make_global(); |
---|
156 | } |
---|
157 | |
---|
158 | return error; |
---|
159 | } |
---|
160 | |
---|