1 /*
2 FXiTe - The Free eXtensIble Text Editor
3 Copyright (c) 2009-2013 Jeffrey Pohlmeyer <yetanothergeek@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License version 3 as
7 published by the Free Software Foundation.
8
9 This software is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <cctype>
20
21 #include <fxkeys.h>
22 #include <fx.h>
23
24 #include "compat.h"
25 #include "prefs.h"
26 #include "appname.h"
27 #include "appwin_pub.h"
28 #include "search.h"
29 #include "histbox.h"
30 #include "tooltree.h"
31 #include "menuspec.h"
32 #include "desclistdlg.h"
33 #include "prefdlg_ext.h"
34 #include "prefdlg_sntx.h"
35 #include "prefdlg_tbar.h"
36 #include "theme.h"
37 #include "shady_tabs.h"
38
39 #include "intl.h"
40 #include "prefdlg.h"
41
42
43 #define PACK_UNIFORM ( PACK_UNIFORM_WIDTH | PACK_UNIFORM_HEIGHT )
44 #define LAYOUT_CENTER ( LAYOUT_CENTER_Y | LAYOUT_CENTER_X )
45 #define SPIN_OPTS ( SPIN_NORMAL | FRAME_SUNKEN | FRAME_THICK )
46 #define LIST_BOX_OPTS ( FRAME_SUNKEN | FRAME_THICK | LISTBOX_NORMAL | LAYOUT_FILL_X )
47
48 static const char*color_hint = _("Drag a color square to FG/BG, or double-click FG/BG to edit");
49
50 static const char* hint_list[] = {
51 _("General application settings"),
52 _("Editor specific settings"),
53 color_hint,
54 _("Double-click an item to edit"),
55 _("Edit toolbar buttons"),
56 _("Edit popup menu items"),
57 _("User interface colors and font"),
58 NULL
59 };
60
61 static FXival whichtab=0;
62
63
64 static const char* sntx_hint_list[] = {
65 color_hint,
66 _("Language-specific options"),
67 NULL
68 };
69
70 static FXival whichsyntab=0;
71
72
73 FXDEFMAP(PrefsDialog) PrefsDialogMap[]={
74 FXMAPFUNC(SEL_COMMAND,PrefsDialog::ID_TAB_SWITCHED,PrefsDialog::onTabSwitch),
75 FXMAPFUNC(SEL_DOUBLECLICKED,PrefsDialog::ID_ACCEL_EDIT,PrefsDialog::onAccelEdit),
76 FXMAPFUNC(SEL_KEYPRESS,PrefsDialog::ID_ACCEL_EDIT,PrefsDialog::onAccelEdit),
77 FXMAPFUNC(SEL_COMMAND, PrefsDialog::ID_FILTERS_EDIT,PrefsDialog::onFiltersEdit),
78 FXMAPFUNC(SEL_COMMAND, PrefsDialog::ID_ERRPATS_EDIT,PrefsDialog::onErrPatsEdit),
79 FXMAPFUNC(SEL_COMMAND, PrefsDialog::ID_SYSINCS_EDIT,PrefsDialog::onSysIncsEdit),
80 FXMAPFUNC(SEL_COMMAND, PrefsDialog::ID_CHOOSE_FONT,PrefsDialog::onChooseFont),
81 FXMAPFUNC(SEL_CHANGED, PrefsDialog::ID_CHANGED_TOOLBAR,PrefsDialog::onChangedToolbar),
82 };
83
84 FXIMPLEMENT(PrefsDialog,FXDialogBox,PrefsDialogMap,ARRAYNUMBER(PrefsDialogMap));
85
86
AccelSanity(FXWindow * w,FXHotKey acckey)87 static bool AccelSanity(FXWindow*w, FXHotKey acckey)
88 {
89 FXushort key=FXSELID(acckey);
90 FXushort mod=FXSELTYPE(acckey);
91 if (key==0) {
92 FXMessageBox::error(w, MBOX_OK, _("Invalid keybinding"), _("That keybinding does not end with a valid key name"));
93 return false;
94 }
95 if ((key>=KEY_F1)&&(key<=KEY_F12)) { return true; }
96 if ((mod&CONTROLMASK)||(mod&ALTMASK)||(mod&METAMASK)) { return true; }
97 return (FXMessageBox::question(w, MBOX_YES_NO, _("Weak keybinding"), "%s\n\n%s",
98 _("That key binding doesn't contain any [Ctrl] or [Alt]\n"
99 "modifiers, which might cause you some problems."),
100 _("Are you sure you want to continue?")
101 )==MBOX_CLICKED_YES);
102 }
103
104
105
AccelUnique(FXWindow * w,FXAccelTable * table,FXHotKey acckey,MenuSpec * spec)106 static bool AccelUnique(FXWindow*w, FXAccelTable *table, FXHotKey acckey, MenuSpec*spec)
107 {
108 MenuSpec*killcmd=MenuMgr::LookupMenu(TopWinPub::KillCmdID());
109
110 if ( (acckey==parseAccel(killcmd->accel)) && (spec!=killcmd)) {
111 FXMessageBox::error(w, MBOX_OK, _("Conflicting keybinding"),
112 _("Keybinding for \"%s\" must not conflict with \"%s\""),spec->pref,killcmd->pref);
113 return false;
114 }
115
116 if (!table->hasAccel(acckey)) { return true; }
117
118 if (FXMessageBox::question(w, MBOX_YES_NO, _("Conflicting keybinding"), "%s\n\n%s",
119 _("This keybinding appears to conflict with an existing one."),
120 _("Are you sure you want to continue?")
121 )==MBOX_CLICKED_YES) {
122 table->removeAccel(acckey);
123 return true;
124 } else {
125 return false;
126 }
127
128 }
129
130
131
AccelDelete(FXWindow * w,FXAccelTable * table,const FXString & acctxt)132 static bool AccelDelete(FXWindow*w, FXAccelTable *table, const FXString &acctxt)
133 {
134 FXHotKey acckey=parseAccel(acctxt);
135 if (!table->hasAccel(acckey)) {
136 return true;
137 } else {
138 if (FXMessageBox::question(w, MBOX_YES_NO, _("Confirm delete"),
139 _("Are you sure you want to remove this keybinding?")
140 )==MBOX_CLICKED_YES) {
141 table->removeAccel(acckey);
142 return true;
143 } else {
144 return false;
145 }
146 }
147 }
148
149
150
EditAccel(FXString & acctxt,FXWindow * w,MenuSpec * spec,FXHotKey & acckey)151 static bool EditAccel(FXString&acctxt, FXWindow*w, MenuSpec*spec, FXHotKey &acckey)
152 {
153 FXInputDialog dlg(w,"","");
154 FXint maxlen=sizeof(spec->accel)-1;
155 dlg.setNumColumns(maxlen);
156 FXString msg;
157 msg.format(
158 "%s:\n"
159 " Ctrl+Shift+F12\n"
160 " F3\n"
161 " Alt+G\n\n"
162 "%s \"%s\"",
163 _("Examples"), _("Keybinding for"), spec->pref);
164 FXString orig=acctxt.text();
165 while (true) {
166 acckey=0;
167 if (dlg.getString(acctxt, w->getShell(), _("Edit keybinding"), msg )) {
168 if (acctxt.empty()) {
169 if (spec->sel==(FXint)TopWinPub::KillCmdID()) {
170 FXMessageBox::error(w->getShell(), MBOX_OK, _("Empty keybinding"), "%s \"%s\"",
171 _("You cannot remove the keybinding for"), spec->pref);
172 acctxt=orig.text();
173 continue;
174 } else {
175 return true;
176 }
177 }
178 acckey=parseAccel(acctxt);
179 if (acckey) {
180 acctxt=unparseAccel(acckey);
181 if ((acctxt.length())<maxlen) {
182 if (AccelSanity(w,acckey)) { return strcmp(spec->accel, acctxt.text())!=0; }
183 } else {
184 FXMessageBox::error(w->getShell(), MBOX_OK,
185 _("Keybinding too long"), _("Text of keybinding specification must not exceed %d bytes\n"), maxlen);
186 }
187 } else {
188 FXMessageBox::error(w->getShell(), MBOX_OK,
189 _("Invalid keybinding"), "%s:\n%s", _("Failed to parse accelerator"), acctxt.text());
190 acctxt=orig.text();
191 }
192 } else {
193 return false;
194 }
195 }
196 }
197
198
199
onAccelEdit(FXObject * o,FXSelector s,void * p)200 long PrefsDialog::onAccelEdit(FXObject*o, FXSelector s, void*p)
201 {
202 if (o!=acclist) { return 0; }
203 switch ( FXSELTYPE(s) ) {
204 case SEL_DOUBLECLICKED: { break; }
205 case SEL_KEYPRESS: {
206 FXint code=((FXEvent*)p)->code;
207 switch (code) {
208 case KEY_Return: { break; }
209 case KEY_KP_Enter: { break; }
210 case KEY_F2: { break; }
211 case KEY_space: { break; }
212 default: { return 0; }
213 }
214 break;
215 }
216 default: { return 0; }
217 }
218 MenuSpec*spec=(MenuSpec*)(acclist->getItemData(acclist->getCurrentItem()));
219 FXWindow*own=main_win;
220 FXAccelTable *table=own?own->getAccelTable():NULL;
221 if (spec && own && table) {
222 FXString acctxt=spec->accel;
223 FXHotKey acckey;
224 if ( EditAccel(acctxt,this,spec,acckey) ) {
225 if (acctxt.empty()) {
226 if (AccelDelete(this,table,spec->accel)) {
227 memset(spec->accel,0,sizeof(spec->accel));
228 if (spec->ms_mc) { spec->ms_mc->setAccelText(spec->accel); }
229 FXString txt;
230 txt.format("%s\t",spec->pref);
231 acclist->setItemText(acclist->getCurrentItem(),txt);
232 }
233 } else {
234 if (AccelUnique(this, table, acckey, spec)) {
235 FXHotKey oldkey=parseAccel(spec->accel);
236 memset(spec->accel,0,sizeof(spec->accel));
237 strncpy(spec->accel, acctxt.text(),sizeof(spec->accel)-1);
238 if (oldkey && table->hasAccel(oldkey)) { table->removeAccel(oldkey); }
239 if (spec->sel==(FXint)TopWinPub::KillCmdID()){
240 TopWinPub::SetKillCommandAccelKey(acckey);
241 } else {
242 if (spec->ms_mc) {
243 spec->ms_mc->setSelector(0);
244 spec->ms_mc->setAccelText(spec->accel);
245 table->addAccel(acckey,spec->ms_mc->getTarget(),FXSEL(SEL_COMMAND,spec->sel));
246 } else {
247 table->addAccel(acckey,own,FXSEL(SEL_COMMAND,spec->sel));
248 }
249 }
250 FXString txt;
251 txt.format("%s\t%s",spec->pref,spec->accel);
252 acclist->setItemText(acclist->getCurrentItem(),txt);
253 }
254 }
255 }
256 } else {
257 FXMessageBox::error(getShell(), MBOX_OK, _("Internal error"), _("Failed to retrieve keybinding information"));
258 }
259 return 1;
260 }
261
262
263
264 #define SetPad(padwin, padsize) \
265 (padwin)->setPadLeft(padsize); \
266 (padwin)->setPadTop(padsize); \
267 (padwin)->setPadRight(padsize); \
268 (padwin)->setPadBottom(padsize);
269
270
271
272 // Subclass FXListItem to show custom tooltip...
273 class TBarListItem: public FXListItem {
274 public:
TBarListItem(const FXString & text,FXIcon * ic=NULL,void * ptr=NULL)275 TBarListItem(const FXString &text, FXIcon *ic=NULL, void *ptr=NULL):FXListItem(text,ic,ptr){ }
getTipText() const276 virtual FXString getTipText() const {
277 FXString tip;
278 MenuSpec*spec=(MenuSpec*)getData();
279 if (spec) { MenuMgr::GetTBarBtnTip(spec,tip); } else { tip=label.text(); }
280 return tip;
281 }
282 };
283
284
285
286 // Subclass FXIconItem to show custom tooltip...
287 class KBindListItem: public FXIconItem {
288 public:
KBindListItem(const FXString & text,FXIcon * bi=NULL,FXIcon * mi=NULL,void * ptr=NULL)289 KBindListItem(const FXString &text, FXIcon*bi=NULL, FXIcon*mi=NULL, void*ptr=NULL):FXIconItem(text,bi,mi,ptr) {}
getTipText() const290 virtual FXString getTipText() const {
291 FXString tip;
292 MenuSpec*spec=(MenuSpec*)getData();
293 if (spec) { MenuMgr::GetTBarBtnTip(spec,tip); } else { tip=label.section('\t',0).text(); }
294 return tip;
295 }
296 };
297
298
299
300 static FXuint changed_toolbar = ToolbarUnchanged;
301
ChangedToolbar()302 FXuint PrefsDialog::ChangedToolbar()
303 {
304 if (Theme::changed() & ThemeChangedFont) { changed_toolbar |= ToolbarChangedFont; }
305 return changed_toolbar;
306 }
307
308
onChangedToolbar(FXObject * o,FXSelector sel,void * p)309 long PrefsDialog::onChangedToolbar(FXObject*o,FXSelector sel,void*p)
310 {
311 changed_toolbar|=(FXuint)((FXival)p);
312 return 1;
313 }
314
315
316
MakeToolbarTab()317 void PrefsDialog::MakeToolbarTab()
318 {
319 new FXTabItem(tabs,_("toolbar"));
320 new ToolbarPrefs(tabs, TopWinPub::UserMenus(), TopWinPub::LastID(), this, ID_CHANGED_TOOLBAR);
321 changed_toolbar=ToolbarUnchanged;
322 }
323
324
325
MakePopupTab()326 void PrefsDialog::MakePopupTab()
327 {
328 new FXTabItem(tabs,_("popup"));
329 new PopupPrefs(tabs, TopWinPub::UserMenus(), TopWinPub::LastID());
330 }
331
332
333
MakeKeybindingsTab()334 void PrefsDialog::MakeKeybindingsTab()
335 {
336 new FXTabItem(tabs,_("keys"));
337 FXHorizontalFrame *frame=new FXHorizontalFrame(tabs,FRAME_RAISED|LAYOUT_FILL);
338 acclist=new FXIconList(frame,
339 this,ID_ACCEL_EDIT,FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|ICONLIST_BROWSESELECT);
340
341 acclist->appendHeader(_("action"));
342 acclist->appendHeader(_("keybinding"));
343 FXString spaces;
344 for (MenuSpec*spec=MenuMgr::MenuSpecs(); spec->sel!=(FXint)TopWinPub::LastID(); spec++) {
345 FXString txt;
346 txt.format("%s\t%s", spec->pref, spec->accel);
347 acclist->appendItem(new KBindListItem(txt, NULL, NULL, (void*)spec));
348 }
349 acclist->selectItem(0);
350 }
351
352
353
MakeSyntaxTab()354 void PrefsDialog::MakeSyntaxTab()
355 {
356 new FXTabItem(tabs,_("syntax"));
357 langs=new LangGUI(tabs,prefs,this,ID_TAB_SWITCHED);
358
359 }
360
361
362
onFiltersEdit(FXObject * o,FXSelector sel,void * p)363 long PrefsDialog::onFiltersEdit(FXObject*o,FXSelector sel,void*p)
364 {
365 FileFiltersDlg(this).execute();
366 #ifdef WIN32
367 hide();
368 show();
369 ((FXWindow*)o)->setFocus();
370 #endif
371 return 1;
372 }
373
374
375
onErrPatsEdit(FXObject * o,FXSelector sel,void * p)376 long PrefsDialog::onErrPatsEdit(FXObject*o,FXSelector sel,void*p)
377 {
378 ErrPatDlg(this).execute();
379 #ifdef WIN32
380 hide();
381 show();
382 ((FXWindow*)o)->setFocus();
383 #endif
384 return 1;
385 }
386
387
388
onSysIncsEdit(FXObject * o,FXSelector sel,void * p)389 long PrefsDialog::onSysIncsEdit(FXObject*o,FXSelector sel,void*p)
390 {
391 SysIncDlg(this).execute();
392 #ifdef WIN32
393 hide();
394 show();
395 ((FXWindow*)o)->setFocus();
396 #endif
397 return 1;
398 }
399
400
401
MakeGeneralTab()402 void PrefsDialog::MakeGeneralTab()
403 {
404 new FXTabItem(tabs,_("general"));
405 FXHorizontalFrame* hframe;
406 FXVerticalFrame* vframe;
407 FXVerticalFrame* left_column;
408 FXVerticalFrame* right_column;
409 FXCheckButton*chk;
410 ClipTextField *tf;
411 FXSpinner *spin;
412 vframe=new FXVerticalFrame(tabs,FRAME_RAISED|LAYOUT_FILL,0,0,0,0,0,0,0,0,0,0);
413 hframe=new FXHorizontalFrame(vframe,FRAME_NONE|LAYOUT_FILL|PACK_UNIFORM_WIDTH);
414 left_column=new FXVerticalFrame(hframe,FRAME_SUNKEN|LAYOUT_FILL/*|PACK_UNIFORM_HEIGHT*/);
415 right_column=new FXVerticalFrame(hframe,FRAME_SUNKEN|LAYOUT_FILL/*|PACK_UNIFORM_HEIGHT*/);
416
417 chk=new FXCheckButton(left_column, _("Watch files for external changes."), prefs, Settings::ID_TOGGLE_WATCH_EXTERN);
418 chk->setCheck(prefs->WatchExternChanges, false);
419 chk->setPadBottom(8);
420
421 hframe=new FXHorizontalFrame(left_column);
422 SetPad(hframe,0);
423 chk=new FXCheckButton(hframe, _("Backup files every "), prefs, Settings::ID_TOGGLE_AUTOSAVE);
424 chk->setCheck(prefs->Autosave, false);
425 chk->setPadBottom(12);
426 spin=new FXSpinner(hframe, 3, prefs, Settings::ID_SET_AUTOSAVE_INT,SPIN_OPTS);
427 spin->setRange(15,900);
428 spin->setValue(prefs->AutosaveInterval);
429
430 new FXLabel(hframe, _(" seconds."));
431 if (!chk->getCheck()) { spin->disable(); }
432 chk->setUserData(spin);
433
434 new FXLabel(left_column, _("Ask before closing multiple files:"));
435 chk=new FXCheckButton(left_column, _("From menu"), prefs, Settings::ID_TOGGLE_ASK_CLOSE_MULTI_MENU);
436 chk->setCheck(prefs->PromptCloseMultiMenu, false);
437 chk->setPadLeft(12);
438 chk=new FXCheckButton(left_column, _("On exit"), prefs, Settings::ID_TOGGLE_ASK_CLOSE_MULTI_EXIT);
439 chk->setCheck(prefs->PromptCloseMultiExit, false);
440 chk->setPadLeft(12);
441 chk->setPadBottom(12);
442
443 hframe=new FXHorizontalFrame(left_column);
444 hframe->setPadBottom(8);
445 tf=new ClipTextField(hframe, 3, prefs, Settings::ID_SET_MAX_FILES,TEXTFIELD_LIMITED|TEXTFIELD_INTEGER|TEXTFIELD_NORMAL);
446 char maxfiles[8]="\0\0\0\0\0\0\0";
447 snprintf(maxfiles, sizeof(maxfiles)-1, "%d", prefs->MaxFiles);
448 tf->setText(maxfiles);
449 new FXLabel(hframe, _("Maximum number of open files."));
450
451 (new FXHorizontalSeparator(left_column,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE))->setPadBottom(12);
452 hframe=new FXHorizontalFrame(left_column);
453 hframe->setPadLeft(12);
454 new FXButton(hframe, _(" File dialog filters... "), NULL, this, ID_FILTERS_EDIT);
455
456 hframe=new FXHorizontalFrame(left_column, LAYOUT_FILL_X);
457 (new FXLabel(hframe, _("Remember\nlast-used filter :")))->setJustify(JUSTIFY_LEFT);
458 FXListBox* list=new FXListBox(hframe,prefs,Settings::ID_SET_KEEP_FILE_FILTER,LIST_BOX_OPTS|LAYOUT_BOTTOM);
459 list->appendItem(_("never"),NULL,NULL);
460 list->appendItem(_("during session"),NULL,NULL);
461 list->appendItem(_("across sessions"),NULL,NULL);
462 list->setNumVisible(list->getNumItems());
463 list->setCurrentItem(prefs->KeepFileFilter);
464
465 new FXLabel(right_column,_("Save open files before executing:"));
466 chk=new FXCheckButton(right_column, _("Tools->Filter Selection"), prefs, Settings::ID_SAVE_ON_FILTER_SEL);
467 chk->setCheck(prefs->SaveBeforeFilterSel, false);
468 chk->setPadLeft(12);
469
470 chk=new FXCheckButton(right_column, _("Tools->Insert Command"), prefs, Settings::ID_SAVE_ON_INS_CMD);
471 chk->setCheck(prefs->SaveBeforeInsCmd, false);
472 chk->setPadLeft(12);
473
474 chk=new FXCheckButton(right_column, _("Tools->Execute Command"), prefs, Settings::ID_SAVE_ON_EXEC_CMD);
475 chk->setCheck(prefs->SaveBeforeExecCmd, false);
476 chk->setPadLeft(12);
477
478 #ifndef WIN32
479 hframe=new FXHorizontalFrame(right_column);
480 hframe->setPadTop(16);
481 new FXLabel(hframe, _("Shell command: "));
482 tf=new ClipTextField(hframe,18,prefs,Settings::ID_SET_SHELL_CMD,TEXTFIELD_NORMAL);
483 tf->setText(prefs->ShellCommand);
484 #endif
485
486 new FXHorizontalSeparator(right_column,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE);
487
488 hframe=new FXHorizontalFrame(right_column);
489 hframe->setPadTop(12);
490 spin=new FXSpinner(hframe, 2, prefs, Settings::ID_SET_WHEEL_LINES,SPIN_OPTS);
491 spin->setRange(1,32);
492 spin->setValue(prefs->WheelLines);
493 new FXLabel(hframe, _("Mouse wheel acceleration."));
494
495 hframe=new FXHorizontalFrame(right_column);
496 hframe->setPadTop(12);
497 spin=new FXSpinner(hframe, 4, prefs, Settings::ID_SET_TAB_TITLE_MAX_WIDTH,SPIN_OPTS);
498 spin->setRange(0,prefs->ScreenWidth);
499 spin->setValue(prefs->TabTitleMaxWidth);
500 new FXLabel(hframe, _("Max width for tab titles.\n( in pixels; 0 = no limit. )"));
501
502 right_column=new FXVerticalFrame(right_column,FRAME_NONE|PACK_UNIFORM_WIDTH|LAYOUT_CENTER_X|LAYOUT_BOTTOM);
503 right_column->setVSpacing(8);
504 new FXButton(right_column, _("System header locations... "),NULL,this,ID_SYSINCS_EDIT,BUTTON_NORMAL|LAYOUT_CENTER_X);
505 new FXButton(right_column, _("Output pane line matching... "),NULL,this,ID_ERRPATS_EDIT,BUTTON_NORMAL|LAYOUT_CENTER_X);
506 }
507
508
509
onChooseFont(FXObject * o,FXSelector sel,void * p)510 long PrefsDialog::onChooseFont(FXObject*o,FXSelector sel,void*p)
511 {
512 prefs->handle(this, FXSEL(SEL_COMMAND, Settings::ID_CHOOSE_FONT), NULL);
513 langs->handle(langs,FXSEL(SEL_COMMAND,LangGUI::ID_LANG_SWITCH),(void*)((FXival)(-1)));
514 return 1;
515 }
516
517
518
MakeEditorTab()519 void PrefsDialog::MakeEditorTab()
520 {
521 new FXTabItem(tabs,_("editor"));
522 FXHorizontalFrame *frame;
523 FXVerticalFrame *column;
524 FXHorizontalFrame *spinframe;
525 FXCheckButton*chk;
526 FXSpinner *spin;
527 FXListBox*list;
528
529 frame=new FXHorizontalFrame(tabs,FRAME_RAISED|LAYOUT_FILL);
530 column=new FXVerticalFrame(frame,FRAME_SUNKEN|LAYOUT_FILL);
531
532 spinframe=new FXHorizontalFrame(column);
533 new FXLabel(spinframe, _("Auto indent:"));
534 list=new FXListBox(spinframe,prefs,Settings::ID_SET_AUTO_INDENT,LIST_BOX_OPTS);
535 list->appendItem(_("off"),NULL,NULL);
536 list->appendItem(_("basic"),NULL,NULL);
537 list->appendItem(_("smart"),NULL,NULL);
538 list->setNumVisible(list->getNumItems());
539 list->setCurrentItem(prefs->AutoIndent);
540
541 chk=new FXCheckButton(column, _("Smart home key"), prefs, Settings::ID_TOGGLE_SMART_HOME);
542 chk->setCheck(prefs->SmartHome, false);
543
544 chk=new FXCheckButton(column, _("Smooth scrolling"), prefs, Settings::ID_TOGGLE_SMOOTH_SCROLL);
545 chk->setCheck(prefs->SmoothScroll, false);
546
547 chk=new FXCheckButton(column, _("Allow caret beyond end of line"), prefs, Settings::ID_TOGGLE_CARET_PAST_EOL);
548 chk->setCheck(prefs->CaretPastEOL, false);
549
550 chk=new FXCheckButton(column,_("Turn line wrapping on by default"),prefs,Settings::ID_TOGGLE_WORD_WRAP);
551 chk->setCheck(prefs->WordWrap);
552
553 chk=new FXCheckButton(column, _("Wrap-aware home/end keys"), prefs, Settings::ID_TOGGLE_WRAP_AWARE);
554 chk->setCheck(prefs->WrapAwareHomeEnd, false);
555
556 spinframe=new FXHorizontalFrame(column);
557 spin=new FXSpinner(spinframe, 2, prefs, Settings::ID_SET_CARET_WIDTH, SPIN_OPTS);
558 spin->setRange(1,3);
559 spin->setValue(prefs->CaretWidth);
560 new FXLabel(spinframe, _("Caret width"));
561
562
563 spinframe=new FXHorizontalFrame(column);
564 spin=new FXSpinner(spinframe, 4, prefs, Settings::ID_SET_RIGHT_EDGE, SPIN_OPTS);
565 spin->setRange(1,1024);
566 spin->setValue(prefs->RightEdgeColumn);
567 new FXLabel(spinframe, _("Right Margin Indicator"));
568
569 spinframe=new FXHorizontalFrame(column);
570 new FXLabel(spinframe, _("Split views:"));
571 list=new FXListBox(spinframe,prefs,Settings::ID_SET_SPLIT_VIEW,LIST_BOX_OPTS);
572 list->appendItem(_("cycle"),NULL,NULL);
573 list->appendItem(_("below"),NULL,NULL);
574 list->appendItem(_("beside"),NULL,NULL);
575 list->setNumVisible(list->getNumItems());
576 list->setCurrentItem(prefs->SplitView);
577
578 new FXLabel(column, " ");
579 new FXButton(column, _(" Editor font... "), NULL, this, ID_CHOOSE_FONT, BUTTON_NORMAL|LAYOUT_CENTER_X);
580
581 column=new FXVerticalFrame(frame,FRAME_SUNKEN|LAYOUT_FILL);
582
583 spinframe=new FXHorizontalFrame(column);
584 new FXLabel(spinframe, _("Highlight matching braces\n(when caret is...)"));
585 list=new FXListBox(spinframe,prefs,Settings::ID_SET_BRACE_MATCHING,LIST_BOX_OPTS|LAYOUT_CENTER_Y);
586 list->appendItem(_("never"),NULL,NULL);
587 list->appendItem(_("inside"),NULL,NULL);
588 list->appendItem(_("outside"),NULL,NULL);
589 list->appendItem(_("on either side"),NULL,NULL);
590 list->appendItem(_("after"),NULL,NULL);
591 list->setNumVisible(list->getNumItems());
592 list->setCurrentItem(prefs->BraceMatch);
593
594 chk=new FXCheckButton(column, _("Use tabs for indent"), prefs, Settings::ID_TOGGLE_USE_TABS);
595
596 spinframe=new FXHorizontalFrame(column);
597 spin=new FXSpinner(spinframe, 2, prefs, Settings::ID_SET_TAB_WIDTH, SPIN_OPTS);
598 spin->setRange(1,16);
599 spin->setValue(prefs->TabWidth);
600 (new FXLabel(spinframe, _("Tab width")))->setPadRight(16);
601
602 spin=new FXSpinner(spinframe, 2, prefs, Settings::ID_SET_INDENT_WIDTH, SPIN_OPTS);
603 spin->setRange(1,16);
604 spin->setValue(prefs->IndentWidth);
605 new FXLabel(spinframe, _("Indent width"));
606
607 chk->setUserData((void*)spin);
608 chk->setCheck(prefs->UseTabs, true);
609
610 new FXHorizontalSeparator(column,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE);
611 new FXLabel(column, _("Default search options:"));
612 srchopts=new SciSearchOptions(column, prefs,Settings::ID_SET_SEARCH_OPTS);
613 srchopts->SetSciFlags(prefs->SearchOptions);
614 chk=new FXCheckButton(column, _("Verbose search messages"), prefs, Settings::ID_TOGGLE_SEARCH_VERBOSE);
615 chk->setCheck(prefs->SearchVerbose, false);
616 chk->setPadLeft(6);
617
618 spinframe=new FXHorizontalFrame(column);
619
620 new FXLabel(spinframe, _("Search wrap:"));
621 list=new FXListBox(spinframe,prefs,Settings::ID_SET_SEARCH_WRAP,LIST_BOX_OPTS);
622 list->appendItem(_("never"),NULL,NULL);
623 list->appendItem(_("always"),NULL,NULL);
624 list->appendItem(_("prompt"),NULL,NULL);
625 list->setNumVisible(list->getNumItems());
626 list->setCurrentItem(prefs->SearchWrap);
627
628 new FXLabel(spinframe, _(" GUI:"));
629 list=new FXListBox(spinframe,prefs,Settings::ID_SET_SEARCH_GUI,LIST_BOX_OPTS);
630 list->appendItem(_("above"),NULL,NULL);
631 list->appendItem(_("below"),NULL,NULL);
632 list->appendItem(_("float"),NULL,NULL);
633 list->setNumVisible(list->getNumItems());
634 list->setCurrentItem(prefs->SearchGui);
635
636 new FXHorizontalSeparator(column,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE);
637 chk=new FXCheckButton(column, _("Open 7-bit ASCII files as UTF-8"), prefs, Settings::ID_TOGGLE_ASCII_DEFAULT);
638 chk->setCheck(!prefs->DefaultToAscii, false);
639 chk->setPadBottom(4);
640 chk=new FXCheckButton(column, _("Treat other files as broken UTF-8"), prefs, Settings::ID_TOGGLE_SBCS_DEFAULT);
641 chk->setCheck(!prefs->DefaultToSbcs, false);
642 chk->setPadBottom(8);
643 spinframe=new FXHorizontalFrame(column);
644 new FXLabel(spinframe, _("Default file format:"));
645 list=new FXListBox(spinframe,prefs,Settings::ID_SET_FILE_FORMAT,LIST_BOX_OPTS);
646 list->appendItem(_("DOS [CRLF]"),NULL,NULL);
647 list->appendItem(_("Mac [CR]"),NULL,NULL);
648 list->appendItem(_("Unix [LF]"),NULL,NULL);
649 list->setNumVisible(list->getNumItems());
650 list->setCurrentItem(prefs->DefaultFileFormat);
651
652 chk=new FXCheckButton(column, _("Show line endings with \"View Whitespace\""),
653 prefs, Settings::ID_TOGGLE_VIEW_WHITESPACE_EOL);
654 chk->setCheck(prefs->WhitespaceShowsEOL, false);
655 chk->setPadLeft(6);
656 }
657
658
659
MakeThemeTab()660 void PrefsDialog::MakeThemeTab()
661 {
662 new FXTabItem(tabs,_("theme"));
663 Theme::MakeThemeGUI(tabs);
664 }
665
666
667
onTabSwitch(FXObject * o,FXSelector sel,void * p)668 long PrefsDialog::onTabSwitch(FXObject*o,FXSelector sel,void*p)
669 {
670
671 if (o==tabs) {
672 whichtab=(FXival)p;
673 hint_lab->setText(hint_list[whichtab]);
674 } else {
675 whichsyntab=(FXival)p;
676 hint_lab->setText(sntx_hint_list[whichsyntab]);
677 }
678 return 0;
679 }
680
681
682
create()683 void PrefsDialog::create()
684 {
685 FXDialogBox::create();
686 SetupXAtoms(this, "prefs", APP_NAME);
687 show(PLACEMENT_DEFAULT);
688 acclist->setWidth((acclist->getParent()->getWidth()/3)*2);
689 acclist->setHeaderSize(0,(acclist->getWidth()/2)-8);
690 acclist->setHeaderSize(1,(acclist->getWidth()/2)-8);
691 #ifndef FOX_1_6
692 acclist->hide();
693 acclist->show();
694 #endif
695 }
696
697
698
PrefsDialog(FXMainWindow * w,Settings * aprefs)699 PrefsDialog::PrefsDialog(FXMainWindow* w, Settings* aprefs):FXDialogBox(w->getApp(), "Preferences")
700 {
701 prefs=aprefs;
702 main_win=w;
703 setX(w->getX()+16);
704 setY(w->getY()+24);
705 setWidth(620);
706
707 FXHorizontalFrame* buttons=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X);
708 new FXButton(buttons,_(" &Close "), NULL,this,ID_ACCEPT,FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y);
709
710 hint_lab=new FXLabel(buttons, hint_list[0], NULL, LAYOUT_FILL_X);
711
712 new FXHorizontalSeparator(this,SEPARATOR_GROOVE|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X);
713 tabs=new ShadyTabs(this, this,ID_TAB_SWITCHED,FRAME_NONE|PACK_UNIFORM|LAYOUT_FILL);
714 MakeGeneralTab();
715 MakeEditorTab();
716 MakeSyntaxTab();
717 MakeKeybindingsTab();
718 MakeToolbarTab();
719 MakePopupTab();
720 MakeThemeTab();
721 tabs->setCurrent(whichtab,true);
722 tabs->childAtIndex(whichtab*2)->setFocus();
723 setIcon(w->getIcon());
724 }
725
726