1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gtk.AccelMap; 26 27 private import glib.ScannerG; 28 private import glib.Str; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 public import gtkc.gdktypes; 32 private import gtkc.gtk; 33 public import gtkc.gtktypes; 34 private import std.algorithm; 35 36 37 /** 38 * Accelerator maps are used to define runtime configurable accelerators. 39 * Functions for manipulating them are are usually used by higher level 40 * convenience mechanisms like #GtkUIManager and are thus considered 41 * “low-level”. You’ll want to use them if you’re manually creating menus that 42 * should have user-configurable accelerators. 43 * 44 * An accelerator is uniquely defined by: 45 * - accelerator path 46 * - accelerator key 47 * - accelerator modifiers 48 * 49 * The accelerator path must consist of 50 * “<WINDOWTYPE>/Category1/Category2/.../Action”, where WINDOWTYPE 51 * should be a unique application-specific identifier that corresponds 52 * to the kind of window the accelerator is being used in, e.g. 53 * “Gimp-Image”, “Abiword-Document” or “Gnumeric-Settings”. 54 * The “Category1/.../Action” portion is most appropriately chosen by 55 * the action the accelerator triggers, i.e. for accelerators on menu 56 * items, choose the item’s menu path, e.g. “File/Save As”, 57 * “Image/View/Zoom” or “Edit/Select All”. So a full valid accelerator 58 * path may look like: “<Gimp-Toolbox>/File/Dialogs/Tool Options...”. 59 * 60 * All accelerators are stored inside one global #GtkAccelMap that can 61 * be obtained using gtk_accel_map_get(). See 62 * [Monitoring changes][monitoring-changes] for additional 63 * details. 64 * 65 * # Manipulating accelerators 66 * 67 * New accelerators can be added using gtk_accel_map_add_entry(). 68 * To search for specific accelerator, use gtk_accel_map_lookup_entry(). 69 * Modifications of existing accelerators should be done using 70 * gtk_accel_map_change_entry(). 71 * 72 * In order to avoid having some accelerators changed, they can be 73 * locked using gtk_accel_map_lock_path(). Unlocking is done using 74 * gtk_accel_map_unlock_path(). 75 * 76 * # Saving and loading accelerator maps 77 * 78 * Accelerator maps can be saved to and loaded from some external 79 * resource. For simple saving and loading from file, 80 * gtk_accel_map_save() and gtk_accel_map_load() are provided. 81 * Saving and loading can also be done by providing file descriptor 82 * to gtk_accel_map_save_fd() and gtk_accel_map_load_fd(). 83 * 84 * # Monitoring changes 85 * 86 * #GtkAccelMap object is only useful for monitoring changes of 87 * accelerators. By connecting to #GtkAccelMap::changed signal, one 88 * can monitor changes of all accelerators. It is also possible to 89 * monitor only single accelerator path by using it as a detail of 90 * the #GtkAccelMap::changed signal. 91 */ 92 public class AccelMap : ObjectG 93 { 94 /** the main Gtk struct */ 95 protected GtkAccelMap* gtkAccelMap; 96 97 /** Get the main Gtk struct */ 98 public GtkAccelMap* getAccelMapStruct() 99 { 100 return gtkAccelMap; 101 } 102 103 /** the main Gtk struct as a void* */ 104 protected override void* getStruct() 105 { 106 return cast(void*)gtkAccelMap; 107 } 108 109 protected override void setStruct(GObject* obj) 110 { 111 gtkAccelMap = cast(GtkAccelMap*)obj; 112 super.setStruct(obj); 113 } 114 115 /** 116 * Sets our main struct and passes it to the parent class. 117 */ 118 public this (GtkAccelMap* gtkAccelMap, bool ownedRef = false) 119 { 120 this.gtkAccelMap = gtkAccelMap; 121 super(cast(GObject*)gtkAccelMap, ownedRef); 122 } 123 124 125 /** */ 126 public static GType getType() 127 { 128 return gtk_accel_map_get_type(); 129 } 130 131 /** 132 * Registers a new accelerator with the global accelerator map. 133 * This function should only be called once per @accel_path 134 * with the canonical @accel_key and @accel_mods for this path. 135 * To change the accelerator during runtime programatically, use 136 * gtk_accel_map_change_entry(). 137 * 138 * Set @accel_key and @accel_mods to 0 to request a removal of 139 * the accelerator. 140 * 141 * Note that @accel_path string will be stored in a #GQuark. Therefore, if you 142 * pass a static string, you can save some memory by interning it first with 143 * g_intern_static_string(). 144 * 145 * Params: 146 * accelPath = valid accelerator path 147 * accelKey = the accelerator key 148 * accelMods = the accelerator modifiers 149 */ 150 public static void addEntry(string accelPath, uint accelKey, GdkModifierType accelMods) 151 { 152 gtk_accel_map_add_entry(Str.toStringz(accelPath), accelKey, accelMods); 153 } 154 155 /** 156 * Adds a filter to the global list of accel path filters. 157 * 158 * Accel map entries whose accel path matches one of the filters 159 * are skipped by gtk_accel_map_foreach(). 160 * 161 * This function is intended for GTK+ modules that create their own 162 * menus, but don’t want them to be saved into the applications accelerator 163 * map dump. 164 * 165 * Params: 166 * filterPattern = a pattern (see #GPatternSpec) 167 */ 168 public static void addFilter(string filterPattern) 169 { 170 gtk_accel_map_add_filter(Str.toStringz(filterPattern)); 171 } 172 173 /** 174 * Changes the @accel_key and @accel_mods currently associated with @accel_path. 175 * Due to conflicts with other accelerators, a change may not always be possible, 176 * @replace indicates whether other accelerators may be deleted to resolve such 177 * conflicts. A change will only occur if all conflicts could be resolved (which 178 * might not be the case if conflicting accelerators are locked). Successful 179 * changes are indicated by a %TRUE return value. 180 * 181 * Note that @accel_path string will be stored in a #GQuark. Therefore, if you 182 * pass a static string, you can save some memory by interning it first with 183 * g_intern_static_string(). 184 * 185 * Params: 186 * accelPath = a valid accelerator path 187 * accelKey = the new accelerator key 188 * accelMods = the new accelerator modifiers 189 * replace = %TRUE if other accelerators may be deleted upon conflicts 190 * 191 * Return: %TRUE if the accelerator could be changed, %FALSE otherwise 192 */ 193 public static bool changeEntry(string accelPath, uint accelKey, GdkModifierType accelMods, bool replace) 194 { 195 return gtk_accel_map_change_entry(Str.toStringz(accelPath), accelKey, accelMods, replace) != 0; 196 } 197 198 /** 199 * Loops over the entries in the accelerator map whose accel path 200 * doesn’t match any of the filters added with gtk_accel_map_add_filter(), 201 * and execute @foreach_func on each. The signature of @foreach_func is 202 * that of #GtkAccelMapForeach, the @changed parameter indicates whether 203 * this accelerator was changed during runtime (thus, would need 204 * saving during an accelerator map dump). 205 * 206 * Params: 207 * data = data to be passed into @foreach_func 208 * foreachFunc = function to be executed for each accel 209 * map entry which is not filtered out 210 */ 211 public static void foreac(void* data, GtkAccelMapForeach foreachFunc) 212 { 213 gtk_accel_map_foreach(data, foreachFunc); 214 } 215 216 /** 217 * Loops over all entries in the accelerator map, and execute 218 * @foreach_func on each. The signature of @foreach_func is that of 219 * #GtkAccelMapForeach, the @changed parameter indicates whether 220 * this accelerator was changed during runtime (thus, would need 221 * saving during an accelerator map dump). 222 * 223 * Params: 224 * data = data to be passed into @foreach_func 225 * foreachFunc = function to be executed for each accel 226 * map entry 227 */ 228 public static void foreachUnfiltered(void* data, GtkAccelMapForeach foreachFunc) 229 { 230 gtk_accel_map_foreach_unfiltered(data, foreachFunc); 231 } 232 233 /** 234 * Gets the singleton global #GtkAccelMap object. This object 235 * is useful only for notification of changes to the accelerator 236 * map via the ::changed signal; it isn’t a parameter to the 237 * other accelerator map functions. 238 * 239 * Return: the global #GtkAccelMap object 240 * 241 * Since: 2.4 242 */ 243 public static AccelMap get() 244 { 245 auto p = gtk_accel_map_get(); 246 247 if(p is null) 248 { 249 return null; 250 } 251 252 return ObjectG.getDObject!(AccelMap)(cast(GtkAccelMap*) p); 253 } 254 255 /** 256 * Parses a file previously saved with gtk_accel_map_save() for 257 * accelerator specifications, and propagates them accordingly. 258 * 259 * Params: 260 * fileName = a file containing accelerator specifications, 261 * in the GLib file name encoding 262 */ 263 public static void load(string fileName) 264 { 265 gtk_accel_map_load(Str.toStringz(fileName)); 266 } 267 268 /** 269 * Filedescriptor variant of gtk_accel_map_load(). 270 * 271 * Note that the file descriptor will not be closed by this function. 272 * 273 * Params: 274 * fd = a valid readable file descriptor 275 */ 276 public static void loadFd(int fd) 277 { 278 gtk_accel_map_load_fd(fd); 279 } 280 281 /** 282 * #GScanner variant of gtk_accel_map_load(). 283 * 284 * Params: 285 * scanner = a #GScanner which has already been provided with an input file 286 */ 287 public static void loadScanner(ScannerG scanner) 288 { 289 gtk_accel_map_load_scanner((scanner is null) ? null : scanner.getScannerGStruct()); 290 } 291 292 /** 293 * Locks the given accelerator path. If the accelerator map doesn’t yet contain 294 * an entry for @accel_path, a new one is created. 295 * 296 * Locking an accelerator path prevents its accelerator from being changed 297 * during runtime. A locked accelerator path can be unlocked by 298 * gtk_accel_map_unlock_path(). Refer to gtk_accel_map_change_entry() 299 * for information about runtime accelerator changes. 300 * 301 * If called more than once, @accel_path remains locked until 302 * gtk_accel_map_unlock_path() has been called an equivalent number 303 * of times. 304 * 305 * Note that locking of individual accelerator paths is independent from 306 * locking the #GtkAccelGroup containing them. For runtime accelerator 307 * changes to be possible, both the accelerator path and its #GtkAccelGroup 308 * have to be unlocked. 309 * 310 * Params: 311 * accelPath = a valid accelerator path 312 * 313 * Since: 2.4 314 */ 315 public static void lockPath(string accelPath) 316 { 317 gtk_accel_map_lock_path(Str.toStringz(accelPath)); 318 } 319 320 /** 321 * Looks up the accelerator entry for @accel_path and fills in @key. 322 * 323 * Params: 324 * accelPath = a valid accelerator path 325 * key = the accelerator key to be filled in (optional) 326 * 327 * Return: %TRUE if @accel_path is known, %FALSE otherwise 328 */ 329 public static bool lookupEntry(string accelPath, out GtkAccelKey key) 330 { 331 return gtk_accel_map_lookup_entry(Str.toStringz(accelPath), &key) != 0; 332 } 333 334 /** 335 * Saves current accelerator specifications (accelerator path, key 336 * and modifiers) to @file_name. 337 * The file is written in a format suitable to be read back in by 338 * gtk_accel_map_load(). 339 * 340 * Params: 341 * fileName = the name of the file to contain 342 * accelerator specifications, in the GLib file name encoding 343 */ 344 public static void save(string fileName) 345 { 346 gtk_accel_map_save(Str.toStringz(fileName)); 347 } 348 349 /** 350 * Filedescriptor variant of gtk_accel_map_save(). 351 * 352 * Note that the file descriptor will not be closed by this function. 353 * 354 * Params: 355 * fd = a valid writable file descriptor 356 */ 357 public static void saveFd(int fd) 358 { 359 gtk_accel_map_save_fd(fd); 360 } 361 362 /** 363 * Undoes the last call to gtk_accel_map_lock_path() on this @accel_path. 364 * Refer to gtk_accel_map_lock_path() for information about accelerator path locking. 365 * 366 * Params: 367 * accelPath = a valid accelerator path 368 * 369 * Since: 2.4 370 */ 371 public static void unlockPath(string accelPath) 372 { 373 gtk_accel_map_unlock_path(Str.toStringz(accelPath)); 374 } 375 376 protected class OnChangedDelegateWrapper 377 { 378 void delegate(string, uint, GdkModifierType, AccelMap) dlg; 379 gulong handlerId; 380 ConnectFlags flags; 381 this(void delegate(string, uint, GdkModifierType, AccelMap) dlg, gulong handlerId, ConnectFlags flags) 382 { 383 this.dlg = dlg; 384 this.handlerId = handlerId; 385 this.flags = flags; 386 } 387 } 388 protected OnChangedDelegateWrapper[] onChangedListeners; 389 390 /** 391 * Notifies of a change in the global accelerator map. 392 * The path is also used as the detail for the signal, 393 * so it is possible to connect to 394 * changed::`accel_path`. 395 * 396 * Params: 397 * accelPath = the path of the accelerator that changed 398 * accelKey = the key value for the new accelerator 399 * accelMods = the modifier mask for the new accelerator 400 * 401 * Since: 2.4 402 */ 403 gulong addOnChanged(void delegate(string, uint, GdkModifierType, AccelMap) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 404 { 405 onChangedListeners ~= new OnChangedDelegateWrapper(dlg, 0, connectFlags); 406 onChangedListeners[onChangedListeners.length - 1].handlerId = Signals.connectData( 407 this, 408 "changed", 409 cast(GCallback)&callBackChanged, 410 cast(void*)onChangedListeners[onChangedListeners.length - 1], 411 cast(GClosureNotify)&callBackChangedDestroy, 412 connectFlags); 413 return onChangedListeners[onChangedListeners.length - 1].handlerId; 414 } 415 416 extern(C) static void callBackChanged(GtkAccelMap* accelmapStruct, char* accelPath, uint accelKey, GdkModifierType accelMods,OnChangedDelegateWrapper wrapper) 417 { 418 wrapper.dlg(Str.toString(accelPath), accelKey, accelMods, wrapper.outer); 419 } 420 421 extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure) 422 { 423 wrapper.outer.internalRemoveOnChanged(wrapper); 424 } 425 426 protected void internalRemoveOnChanged(OnChangedDelegateWrapper source) 427 { 428 foreach(index, wrapper; onChangedListeners) 429 { 430 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 431 { 432 onChangedListeners[index] = null; 433 onChangedListeners = std.algorithm.remove(onChangedListeners, index); 434 break; 435 } 436 } 437 } 438 439 }