WindowMaker: appicon.h clean code
[wmaker-crm.git] / WPrefs.app / KeyboardShortcuts.c
blobaad8f334ffdfeba77c237eafa2b431defa6a2a35
1 /* KeyboardShortcuts.c- keyboard shortcut bindings
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 1998-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "config.h" /* for HAVE_XCONVERTCASE */
24 #include "WPrefs.h"
25 #include <ctype.h>
27 #include <X11/keysym.h>
29 typedef struct _Panel {
30 WMBox *box;
32 char *sectionName;
34 char *description;
36 CallbackRec callbacks;
38 WMWidget *parent;
40 WMLabel *actL;
41 WMList *actLs;
43 WMFrame *shoF;
44 WMTextField *shoT;
45 WMButton *cleB;
46 WMButton *defB;
48 WMLabel *instructionsL;
50 WMColor *white;
51 WMColor *black;
52 WMColor *gray;
53 WMFont *font;
55 Bool capturing;
56 char **shortcuts;
57 int actionCount;
58 } _Panel;
60 #define ICON_FILE "keyshortcuts"
63 * Must be in the same order as the corresponding items in
64 * "actions list" in createPanel()
66 static char *keyOptions[] = {
67 "RootMenuKey",
68 "WindowListKey",
69 "WindowMenuKey",
70 "HideKey",
71 "HideOthersKey",
72 "MiniaturizeKey",
73 "MinimizeAllKey",
74 "CloseKey",
75 "MaximizeKey",
76 "VMaximizeKey",
77 "HMaximizeKey",
78 "LHMaximizeKey",
79 "RHMaximizeKey",
80 "MaximusKey",
81 "RaiseKey",
82 "LowerKey",
83 "RaiseLowerKey",
84 "ShadeKey",
85 "MoveResizeKey",
86 "SelectKey",
87 "FocusNextKey",
88 "FocusPrevKey",
89 "GroupNextKey",
90 "GroupPrevKey",
91 "NextWorkspaceKey",
92 "PrevWorkspaceKey",
93 "NextWorkspaceLayerKey",
94 "PrevWorkspaceLayerKey",
95 "Workspace1Key",
96 "Workspace2Key",
97 "Workspace3Key",
98 "Workspace4Key",
99 "Workspace5Key",
100 "Workspace6Key",
101 "Workspace7Key",
102 "Workspace8Key",
103 "Workspace9Key",
104 "Workspace10Key",
105 "WindowShortcut1Key",
106 "WindowShortcut2Key",
107 "WindowShortcut3Key",
108 "WindowShortcut4Key",
109 "WindowShortcut5Key",
110 "WindowShortcut6Key",
111 "WindowShortcut7Key",
112 "WindowShortcut8Key",
113 "WindowShortcut9Key",
114 "WindowShortcut10Key",
115 "WindowRelaunchKey",
116 "ScreenSwitchKey",
117 "DockRaiseLowerKey",
118 #ifndef XKB_MODELOCK
119 "ClipRaiseLowerKey"
120 #else
121 "ClipRaiseLowerKey",
122 "ToggleKbdModeKey"
123 #endif /* XKB_MODELOCK */
126 #ifndef HAVE_XCONVERTCASE
127 /* from Xlib */
129 static void XConvertCase(register KeySym sym, KeySym * lower, KeySym * upper)
131 *lower = sym;
132 *upper = sym;
133 switch (sym >> 8) {
134 case 0: /* Latin 1 */
135 if ((sym >= XK_A) && (sym <= XK_Z))
136 *lower += (XK_a - XK_A);
137 else if ((sym >= XK_a) && (sym <= XK_z))
138 *upper -= (XK_a - XK_A);
139 else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
140 *lower += (XK_agrave - XK_Agrave);
141 else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
142 *upper -= (XK_agrave - XK_Agrave);
143 else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
144 *lower += (XK_oslash - XK_Ooblique);
145 else if ((sym >= XK_oslash) && (sym <= XK_thorn))
146 *upper -= (XK_oslash - XK_Ooblique);
147 break;
148 case 1: /* Latin 2 */
149 /* Assume the KeySym is a legal value (ignore discontinuities) */
150 if (sym == XK_Aogonek)
151 *lower = XK_aogonek;
152 else if (sym >= XK_Lstroke && sym <= XK_Sacute)
153 *lower += (XK_lstroke - XK_Lstroke);
154 else if (sym >= XK_Scaron && sym <= XK_Zacute)
155 *lower += (XK_scaron - XK_Scaron);
156 else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
157 *lower += (XK_zcaron - XK_Zcaron);
158 else if (sym == XK_aogonek)
159 *upper = XK_Aogonek;
160 else if (sym >= XK_lstroke && sym <= XK_sacute)
161 *upper -= (XK_lstroke - XK_Lstroke);
162 else if (sym >= XK_scaron && sym <= XK_zacute)
163 *upper -= (XK_scaron - XK_Scaron);
164 else if (sym >= XK_zcaron && sym <= XK_zabovedot)
165 *upper -= (XK_zcaron - XK_Zcaron);
166 else if (sym >= XK_Racute && sym <= XK_Tcedilla)
167 *lower += (XK_racute - XK_Racute);
168 else if (sym >= XK_racute && sym <= XK_tcedilla)
169 *upper -= (XK_racute - XK_Racute);
170 break;
171 case 2: /* Latin 3 */
172 /* Assume the KeySym is a legal value (ignore discontinuities) */
173 if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
174 *lower += (XK_hstroke - XK_Hstroke);
175 else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
176 *lower += (XK_gbreve - XK_Gbreve);
177 else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
178 *upper -= (XK_hstroke - XK_Hstroke);
179 else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
180 *upper -= (XK_gbreve - XK_Gbreve);
181 else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
182 *lower += (XK_cabovedot - XK_Cabovedot);
183 else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
184 *upper -= (XK_cabovedot - XK_Cabovedot);
185 break;
186 case 3: /* Latin 4 */
187 /* Assume the KeySym is a legal value (ignore discontinuities) */
188 if (sym >= XK_Rcedilla && sym <= XK_Tslash)
189 *lower += (XK_rcedilla - XK_Rcedilla);
190 else if (sym >= XK_rcedilla && sym <= XK_tslash)
191 *upper -= (XK_rcedilla - XK_Rcedilla);
192 else if (sym == XK_ENG)
193 *lower = XK_eng;
194 else if (sym == XK_eng)
195 *upper = XK_ENG;
196 else if (sym >= XK_Amacron && sym <= XK_Umacron)
197 *lower += (XK_amacron - XK_Amacron);
198 else if (sym >= XK_amacron && sym <= XK_umacron)
199 *upper -= (XK_amacron - XK_Amacron);
200 break;
201 case 6: /* Cyrillic */
202 /* Assume the KeySym is a legal value (ignore discontinuities) */
203 if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
204 *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
205 else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
206 *upper += (XK_Serbian_DJE - XK_Serbian_dje);
207 else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
208 *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
209 else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
210 *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
211 break;
212 case 7: /* Greek */
213 /* Assume the KeySym is a legal value (ignore discontinuities) */
214 if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
215 *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
216 else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
217 sym != XK_Greek_iotaaccentdieresis && sym != XK_Greek_upsilonaccentdieresis)
218 *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
219 else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
220 *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
221 else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && sym != XK_Greek_finalsmallsigma)
222 *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
223 break;
224 case 0x14: /* Armenian */
225 if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) {
226 *lower = sym | 1;
227 *upper = sym & ~1;
229 break;
232 #endif
234 char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case)
236 XEvent ev;
237 KeySym ksym, lksym, uksym;
238 char buffer[64];
239 char *key = NULL;
241 while (*capturing) {
242 XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
243 WMNextEvent(dpy, &ev);
244 if (ev.type == KeyPress && ev.xkey.keycode != 0) {
245 ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
246 if (!IsModifierKey(ksym)) {
247 if (convert_case) {
248 XConvertCase(ksym, &lksym, &uksym);
249 key = XKeysymToString(uksym);
250 } else {
251 key = XKeysymToString(ksym);
254 *capturing = 0;
255 break;
258 WMHandleEvent(&ev);
261 if (!key)
262 return NULL;
264 buffer[0] = 0;
266 if (ev.xkey.state & ControlMask) {
267 strcat(buffer, "Control+");
269 if (ev.xkey.state & ShiftMask) {
270 strcat(buffer, "Shift+");
272 if (ev.xkey.state & Mod1Mask) {
273 strcat(buffer, "Mod1+");
275 if (ev.xkey.state & Mod2Mask) {
276 strcat(buffer, "Mod2+");
278 if (ev.xkey.state & Mod3Mask) {
279 strcat(buffer, "Mod3+");
281 if (ev.xkey.state & Mod4Mask) {
282 strcat(buffer, "Mod4+");
284 if (ev.xkey.state & Mod5Mask) {
285 strcat(buffer, "Mod5+");
287 strcat(buffer, key);
289 return wstrdup(buffer);
292 static void captureClick(WMWidget * w, void *data)
294 _Panel *panel = (_Panel *) data;
295 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
296 char *shortcut;
298 if (!panel->capturing) {
299 panel->capturing = 1;
300 WMSetButtonText(w, _("Cancel"));
301 WMSetLabelText(panel->instructionsL,
302 _("Press the desired shortcut key(s) or click Cancel to stop capturing."));
303 XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync, GrabModeAsync, CurrentTime);
304 shortcut = capture_shortcut(dpy, &panel->capturing, 1);
305 if (shortcut) {
306 int row = WMGetListSelectedItemRow(panel->actLs);
308 WMSetTextFieldText(panel->shoT, shortcut);
309 if (row >= 0) {
310 if (panel->shortcuts[row])
311 wfree(panel->shortcuts[row]);
312 panel->shortcuts[row] = shortcut;
314 WMRedisplayWidget(panel->actLs);
315 } else {
316 wfree(shortcut);
320 panel->capturing = 0;
321 WMSetButtonText(w, _("Capture"));
322 WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
323 XUngrabKeyboard(dpy, CurrentTime);
326 static void clearShortcut(WMWidget * w, void *data)
328 _Panel *panel = (_Panel *) data;
329 int row = WMGetListSelectedItemRow(panel->actLs);
331 WMSetTextFieldText(panel->shoT, NULL);
333 if (row >= 0) {
334 if (panel->shortcuts[row])
335 wfree(panel->shortcuts[row]);
336 panel->shortcuts[row] = NULL;
337 WMRedisplayWidget(panel->actLs);
341 static void typedKeys(void *observerData, WMNotification * notification)
343 _Panel *panel = (_Panel *) observerData;
344 int row = WMGetListSelectedItemRow(panel->actLs);
346 if (row < 0)
347 return;
349 if (panel->shortcuts[row])
350 wfree(panel->shortcuts[row]);
351 panel->shortcuts[row] = WMGetTextFieldText(panel->shoT);
352 if (strlen(panel->shortcuts[row]) == 0) {
353 wfree(panel->shortcuts[row]);
354 panel->shortcuts[row] = NULL;
356 WMRedisplayWidget(panel->actLs);
359 static void listClick(WMWidget * w, void *data)
361 _Panel *panel = (_Panel *) data;
362 int row = WMGetListSelectedItemRow(w);
364 WMSetTextFieldText(panel->shoT, panel->shortcuts[row]);
367 static void showData(_Panel * panel)
369 char *str;
370 int i;
372 for (i = 0; i < panel->actionCount; i++) {
374 str = GetStringForKey(keyOptions[i]);
375 if (panel->shortcuts[i])
376 wfree(panel->shortcuts[i]);
377 if (str)
378 panel->shortcuts[i] = wtrimspace(str);
379 else
380 panel->shortcuts[i] = NULL;
382 if (panel->shortcuts[i] &&
383 (strcasecmp(panel->shortcuts[i], "none") == 0 || strlen(panel->shortcuts[i]) == 0)) {
384 wfree(panel->shortcuts[i]);
385 panel->shortcuts[i] = NULL;
388 WMRedisplayWidget(panel->actLs);
391 static void paintItem(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
393 int width, height, x, y;
394 _Panel *panel = (_Panel *) WMGetHangedData(lPtr);
395 WMScreen *scr = WMWidgetScreen(lPtr);
396 Display *dpy = WMScreenDisplay(scr);
397 WMColor *backColor = (state & WLDSSelected) ? panel->white : panel->gray;
399 width = rect->size.width;
400 height = rect->size.height;
401 x = rect->pos.x;
402 y = rect->pos.y;
404 XFillRectangle(dpy, d, WMColorGC(backColor), x, y, width, height);
406 if (panel->shortcuts[index]) {
407 WMPixmap *pix = WMGetSystemPixmap(scr, WSICheckMark);
408 WMSize size = WMGetPixmapSize(pix);
410 WMDrawPixmap(pix, d, x + (20 - size.width) / 2, (height - size.height) / 2 + y);
411 WMReleasePixmap(pix);
414 WMDrawString(scr, d, panel->black, panel->font, x + 20, y, text, strlen(text));
417 static void createPanel(Panel * p)
419 _Panel *panel = (_Panel *) p;
420 WMScreen *scr = WMWidgetScreen(panel->parent);
421 WMColor *color;
422 WMFont *boldFont;
424 panel->capturing = 0;
426 panel->white = WMWhiteColor(scr);
427 panel->black = WMBlackColor(scr);
428 panel->gray = WMGrayColor(scr);
429 panel->font = WMSystemFontOfSize(scr, 12);
431 panel->box = WMCreateBox(panel->parent);
432 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
434 boldFont = WMBoldSystemFontOfSize(scr, 12);
436 /* **************** Actions **************** */
437 panel->actL = WMCreateLabel(panel->box);
438 WMResizeWidget(panel->actL, 280, 20);
439 WMMoveWidget(panel->actL, 20, 10);
440 WMSetLabelFont(panel->actL, boldFont);
441 WMSetLabelText(panel->actL, _("Actions"));
442 WMSetLabelRelief(panel->actL, WRSunken);
443 WMSetLabelTextAlignment(panel->actL, WACenter);
444 color = WMDarkGrayColor(scr);
445 WMSetWidgetBackgroundColor(panel->actL, color);
446 WMReleaseColor(color);
447 WMSetLabelTextColor(panel->actL, panel->white);
449 panel->actLs = WMCreateList(panel->box);
450 WMResizeWidget(panel->actLs, 280, 190);
451 WMMoveWidget(panel->actLs, 20, 32);
452 WMSetListUserDrawProc(panel->actLs, paintItem);
453 WMHangData(panel->actLs, panel);
455 WMAddListItem(panel->actLs, _("Open applications menu"));
456 WMAddListItem(panel->actLs, _("Open window list menu"));
457 WMAddListItem(panel->actLs, _("Open window commands menu"));
458 WMAddListItem(panel->actLs, _("Hide active application"));
459 WMAddListItem(panel->actLs, _("Hide other applications"));
460 WMAddListItem(panel->actLs, _("Miniaturize active window"));
461 WMAddListItem(panel->actLs, _("Miniaturize all windows"));
462 WMAddListItem(panel->actLs, _("Close active window"));
463 WMAddListItem(panel->actLs, _("Maximize active window"));
464 WMAddListItem(panel->actLs, _("Maximize active window vertically"));
465 WMAddListItem(panel->actLs, _("Maximize active window horizontally"));
466 WMAddListItem(panel->actLs, _("Maximize active window left half"));
467 WMAddListItem(panel->actLs, _("Maximize active window right half"));
468 WMAddListItem(panel->actLs, _("Maximus: Tiled maximization "));
469 WMAddListItem(panel->actLs, _("Raise active window"));
470 WMAddListItem(panel->actLs, _("Lower active window"));
471 WMAddListItem(panel->actLs, _("Raise/Lower window under mouse pointer"));
472 WMAddListItem(panel->actLs, _("Shade active window"));
473 WMAddListItem(panel->actLs, _("Move/Resize active window"));
474 WMAddListItem(panel->actLs, _("Select active window"));
475 WMAddListItem(panel->actLs, _("Focus next window"));
476 WMAddListItem(panel->actLs, _("Focus previous window"));
477 WMAddListItem(panel->actLs, _("Focus next group window"));
478 WMAddListItem(panel->actLs, _("Focus previous group window"));
479 WMAddListItem(panel->actLs, _("Switch to next workspace"));
480 WMAddListItem(panel->actLs, _("Switch to previous workspace"));
481 WMAddListItem(panel->actLs, _("Switch to next ten workspaces"));
482 WMAddListItem(panel->actLs, _("Switch to previous ten workspaces"));
483 WMAddListItem(panel->actLs, _("Switch to workspace 1"));
484 WMAddListItem(panel->actLs, _("Switch to workspace 2"));
485 WMAddListItem(panel->actLs, _("Switch to workspace 3"));
486 WMAddListItem(panel->actLs, _("Switch to workspace 4"));
487 WMAddListItem(panel->actLs, _("Switch to workspace 5"));
488 WMAddListItem(panel->actLs, _("Switch to workspace 6"));
489 WMAddListItem(panel->actLs, _("Switch to workspace 7"));
490 WMAddListItem(panel->actLs, _("Switch to workspace 8"));
491 WMAddListItem(panel->actLs, _("Switch to workspace 9"));
492 WMAddListItem(panel->actLs, _("Switch to workspace 10"));
493 WMAddListItem(panel->actLs, _("Shortcut for window 1"));
494 WMAddListItem(panel->actLs, _("Shortcut for window 2"));
495 WMAddListItem(panel->actLs, _("Shortcut for window 3"));
496 WMAddListItem(panel->actLs, _("Shortcut for window 4"));
497 WMAddListItem(panel->actLs, _("Shortcut for window 5"));
498 WMAddListItem(panel->actLs, _("Shortcut for window 6"));
499 WMAddListItem(panel->actLs, _("Shortcut for window 7"));
500 WMAddListItem(panel->actLs, _("Shortcut for window 8"));
501 WMAddListItem(panel->actLs, _("Shortcut for window 9"));
502 WMAddListItem(panel->actLs, _("Shortcut for window 10"));
503 WMAddListItem(panel->actLs, _("Launch new instance of application"));
504 WMAddListItem(panel->actLs, _("Switch to Next Screen/Monitor"));
505 WMAddListItem(panel->actLs, _("Raise/Lower Dock"));
506 WMAddListItem(panel->actLs, _("Raise/Lower Clip"));
507 #ifdef XKB_MODELOCK
508 WMAddListItem(panel->actLs, _("Toggle keyboard language"));
509 #endif /* XKB_MODELOCK */
511 WMSetListAction(panel->actLs, listClick, panel);
513 panel->actionCount = WMGetListNumberOfRows(panel->actLs);
514 panel->shortcuts = wmalloc(sizeof(char *) * panel->actionCount);
515 memset(panel->shortcuts, 0, sizeof(char *) * panel->actionCount);
517 /***************** Shortcut ****************/
519 panel->shoF = WMCreateFrame(panel->box);
520 WMResizeWidget(panel->shoF, 190, 210);
521 WMMoveWidget(panel->shoF, 315, 10);
522 WMSetFrameTitle(panel->shoF, _("Shortcut"));
524 panel->shoT = WMCreateTextField(panel->shoF);
525 WMResizeWidget(panel->shoT, 160, 20);
526 WMMoveWidget(panel->shoT, 15, 65);
527 WMAddNotificationObserver(typedKeys, panel, WMTextDidChangeNotification, panel->shoT);
529 panel->cleB = WMCreateCommandButton(panel->shoF);
530 WMResizeWidget(panel->cleB, 75, 24);
531 WMMoveWidget(panel->cleB, 15, 95);
532 WMSetButtonText(panel->cleB, _("Clear"));
533 WMSetButtonAction(panel->cleB, clearShortcut, panel);
535 panel->defB = WMCreateCommandButton(panel->shoF);
536 WMResizeWidget(panel->defB, 75, 24);
537 WMMoveWidget(panel->defB, 100, 95);
538 WMSetButtonText(panel->defB, _("Capture"));
539 WMSetButtonAction(panel->defB, captureClick, panel);
541 panel->instructionsL = WMCreateLabel(panel->shoF);
542 WMResizeWidget(panel->instructionsL, 160, 55);
543 WMMoveWidget(panel->instructionsL, 15, 140);
544 WMSetLabelTextAlignment(panel->instructionsL, WACenter);
545 WMSetLabelWraps(panel->instructionsL, True);
546 WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
548 WMMapSubwidgets(panel->shoF);
550 WMReleaseFont(boldFont);
552 WMRealizeWidget(panel->box);
553 WMMapSubwidgets(panel->box);
555 showData(panel);
558 static void storeData(_Panel * panel)
560 int i;
561 char *str;
563 for (i = 0; i < panel->actionCount; i++) {
564 str = NULL;
565 if (panel->shortcuts[i]) {
566 str = wtrimspace(panel->shortcuts[i]);
567 if (strlen(str) == 0) {
568 wfree(str);
569 str = NULL;
572 if (str) {
573 SetStringForKey(str, keyOptions[i]);
574 wfree(str);
575 } else {
576 SetStringForKey("None", keyOptions[i]);
581 Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent)
583 _Panel *panel;
585 panel = wmalloc(sizeof(_Panel));
586 memset(panel, 0, sizeof(_Panel));
588 panel->sectionName = _("Keyboard Shortcut Preferences");
590 panel->description = _("Change the keyboard shortcuts for actions such\n"
591 "as changing workspaces and opening menus.");
593 panel->parent = parent;
595 panel->callbacks.createWidgets = createPanel;
596 panel->callbacks.updateDomain = storeData;
598 AddSection(panel, ICON_FILE);
600 return panel;