1 /*
2   FXiTe - The Free eXtensIble Text Editor
3   Copyright (c) 2009-2011 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 
20 #include <fx.h>
21 #include <Scintilla.h>
22 #include <FXScintilla.h>
23 #include <ILexer.h>
24 #include <LexerModule.h>
25 #include <Catalogue.h>
26 
27 #include "intl.h"
28 #include "appwin_pub.h"
29 #include "compat.h"
30 #include "histbox.h"
31 #include "lang.h"
32 #include "prefs.h"
33 #include "shady_tabs.h"
34 
35 #include "prefdlg_sntx.h"
36 
37 #define LIST_BOX_OPTS  ( FRAME_SUNKEN | FRAME_THICK | LISTBOX_NORMAL )
38 #define SPIN_OPTS      ( SPIN_NORMAL | FRAME_SUNKEN | FRAME_THICK )
39 #define PACK_UNIFORM   ( PACK_UNIFORM_WIDTH | PACK_UNIFORM_HEIGHT )
40 
41 #define SetPad(padwin, padsize) \
42 (padwin)->setPadLeft(padsize); \
43 (padwin)->setPadTop(padsize); \
44 (padwin)->setPadRight(padsize); \
45 (padwin)->setPadBottom(padsize);
46 
47 
48 #define COLORWELL_OPTS ( COLORWELL_OPAQUEONLY|LAYOUT_FIX_WIDTH|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y )
49 #define STYLE_BTN_OPTS ( TOGGLEBUTTON_NORMAL | TOGGLEBUTTON_KEEPSTATE )
50 
51 
52 static int whichlang=0;
53 
54 
55 class MyColorWell: public FXColorWell {
56   FXDECLARE(MyColorWell);
MyColorWell()57   MyColorWell(){};
58 public:
59   bool grayscale;
60   long onDoubleClicked(FXObject*o,FXSelector sel,void*p);
MyColorWell(FXComposite * p,FXColor clr=0,FXObject * tgt=NULL,FXSelector sel=0,FXuint opts=COLORWELL_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD)61   MyColorWell(FXComposite *p, FXColor clr=0, FXObject *tgt=NULL, FXSelector sel=0,
62   FXuint opts=COLORWELL_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0,
63     FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD):
64       FXColorWell(p,clr,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { grayscale=false; }
65 };
66 
67 
68 
69 FXDEFMAP(MyColorWell) MyColorWellMap[]={
70   FXMAPFUNC(SEL_DOUBLECLICKED,0,MyColorWell::onDoubleClicked)
71 };
72 
73 FXIMPLEMENT(MyColorWell,FXColorWell,MyColorWellMap,ARRAYNUMBER(MyColorWellMap));
74 
75 
76 
onDoubleClicked(FXObject * o,FXSelector sel,void * p)77 long MyColorWell::onDoubleClicked(FXObject*o,FXSelector sel,void*p)
78 {
79   if(target && target->tryHandle(this,FXSEL(SEL_DOUBLECLICKED,message),(void*)(FXuval)rgba)) return 1;
80   if(options&COLORWELL_SOURCEONLY) return 1;
81   FXColorDialog colordialog(getShell(),_("Color Dialog"));
82   FXColor oldcolor=getRGBA();
83   colordialog.setTarget(this);
84   colordialog.setSelector(ID_COLORDIALOG);
85   colordialog.setRGBA(oldcolor);
86   colordialog.setOpaqueOnly(isOpaqueOnly());
87   if(!colordialog.execute(PLACEMENT_SCREEN)) { setRGBA(oldcolor,true); }
88   return 1;
89 }
90 
91 
92 
93 class StyleEdit: public FXObject {
94   FXDECLARE(StyleEdit)
95 protected:
StyleEdit()96   StyleEdit(){}
97 private:
98   FXLabel *caption;
99   FXToggleButton*bold_btn;
100   FXToggleButton*italic_btn;
101   MyColorWell*fg_btn;
102   MyColorWell*bg_btn;
103   StyleDef*styledef;
104   FXFontDesc fontdesc;
105   FXFont* labelfont;
106   void SetButtonFont(FXToggleButton*btn,FXushort what);
107   void conceal(FXFrame*w);
108 public:
109   long onStyleBtn(FXObject*o,FXSelector sel,void*p);
110   long onColorBtn(FXObject*o,FXSelector sel,void*p);
111   StyleEdit(FXComposite *p, StyleDef*def, FXFont*scifont, bool bgonly=false);
~StyleEdit()112   ~StyleEdit(){ delete labelfont; }
113   void create();
114   enum {
115     ID_STYLE_BTN=FXHorizontalFrame::ID_LAST,
116     ID_COLOR_BTN,
117     ID_LAST
118   };
119 };
120 
121 
122 
123 FXDEFMAP(StyleEdit) StyleEditMap[]={
124   FXMAPFUNC(SEL_COMMAND,StyleEdit::ID_STYLE_BTN,StyleEdit::onStyleBtn),
125   FXMAPFUNC(SEL_COMMAND,StyleEdit::ID_COLOR_BTN,StyleEdit::onColorBtn)
126 };
127 
128 FXIMPLEMENT(StyleEdit,FXObject,StyleEditMap,ARRAYNUMBER(StyleEditMap));
129 
130 
131 
onStyleBtn(FXObject * o,FXSelector sel,void * p)132 long StyleEdit::onStyleBtn(FXObject*o,FXSelector sel,void*p)
133 {
134   FXival state=(FXival)p;
135   if (o==bold_btn) {
136     if (state==STATE_DOWN) {
137       fontdesc.weight=FXFont::Bold;
138       styledef->style=(SciDocFontStyle)(styledef->style|Bold);
139     } else {
140       fontdesc.weight=FXFont::Normal;
141       styledef->style=(SciDocFontStyle)(styledef->style&~Bold);
142     }
143   } else {
144     if (state==STATE_DOWN) {
145       fontdesc.slant=FXFont::Italic;
146       styledef->style=(SciDocFontStyle)(styledef->style|Italic);
147     } else {
148       fontdesc.slant=FXFont::Straight;
149       styledef->style=(SciDocFontStyle)(styledef->style&~Italic);
150     }
151   }
152   FXFont*tmpfont=new FXFont(caption->getApp(), fontdesc);
153   tmpfont->create();
154   caption->setFont(tmpfont);
155   caption->update();
156   return 1;
157 }
158 
159 
160 
onColorBtn(FXObject * o,FXSelector sel,void * p)161 long StyleEdit::onColorBtn(FXObject*o,FXSelector sel,void*p)
162 {
163   FXColorWell*cw=(FXColorWell*)o;
164   FXColor rgb=cw->getRGBA();
165   if (cw==fg_btn) {
166     caption->setTextColor(rgb);
167     RgbToHex(rgb,styledef->fg);
168   } else {
169     caption->setBackColor(rgb);
170     RgbToHex(rgb,styledef->bg);
171     if (!fg_btn->isEnabled()) {
172       caption->setTextColor(rgb>FXRGB(0x80,0x80,0x80)?FXRGB(0,0,0):FXRGB(0xFF,0xFF,0xFF));
173     }
174   }
175   caption->update();
176   return 1;
177 }
178 
179 
180 
conceal(FXFrame * w)181 void StyleEdit::conceal(FXFrame*w) {
182   FXColor c=w->getShell()->getBackColor();
183   w->disable();
184   w->setShadowColor(c);
185   w->setHiliteColor(c);
186   w->setBaseColor(c);
187   w->setBorderColor(c);
188 }
189 
190 
191 
create()192 void StyleEdit::create()
193 {
194   caption->create();
195   bold_btn->getParent()->create();
196   bold_btn->create();
197   italic_btn->create();
198   fg_btn->getParent()->create();
199   fg_btn->create();
200   bg_btn->create();
201 }
202 
203 
204 
SetButtonFont(FXToggleButton * btn,FXushort what)205 void StyleEdit::SetButtonFont(FXToggleButton*btn,FXushort what)
206 {
207   FXFont*tmpfont;
208   FXFontDesc fd;
209   GetFontDescription(fd,btn->getFont());
210   switch (what) {
211     case FXFont::Italic:fd.slant=FXFont::Italic;break;
212     case FXFont::Bold:fd.weight=FXFont::Bold;break;
213   }
214   strncpy(fd.face,"serif",sizeof(fd.face)-1);
215   tmpfont=new FXFont(btn->getApp(),fd);
216   btn->setFont(tmpfont);
217 }
218 
219 
220 
StyleEdit(FXComposite * p,StyleDef * sd,FXFont * scifont,bool bgonly)221 StyleEdit::StyleEdit(FXComposite *p, StyleDef*sd, FXFont*scifont, bool bgonly)
222 {
223   Settings*prefs=Settings::instance();
224   styledef=sd;
225   FXColor bg=HexToRGB(sd->bg[0]?sd->bg:prefs->globalStyle()->bg);
226   FXColor fg=HexToRGB(sd->fg[0]?sd->fg:prefs->globalStyle()->fg);
227   FXHorizontalFrame*stylebtns=new FXHorizontalFrame(p,LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0,0,0);
228   stylebtns->setBackColor(bg);
229 
230   caption=new FXLabel(p,sd->key,NULL,LABEL_NORMAL|LAYOUT_FILL|LAYOUT_FILL_COLUMN);
231   caption->setBackColor(bg);
232   caption->setTextColor(fg);
233   caption->setPadLeft(4);
234   caption->setPadRight(4);
235 
236   FXHorizontalFrame*colorbtns=new FXHorizontalFrame(p,LAYOUT_FILL_X|LAYOUT_CENTER_Y,0,0,0,0,0,0,0,0,0,0);
237   fg_btn=new MyColorWell(colorbtns, fg, this, ID_COLOR_BTN,COLORWELL_OPTS,0,0,32,32,0,0,0,0);
238   bg_btn=new MyColorWell(colorbtns, bg, this, ID_COLOR_BTN,COLORWELL_OPTS,0,0,32,32,0,0,0,0);
239 
240 
241   italic_btn=new FXToggleButton(stylebtns, "I", "I", NULL, NULL, this, ID_STYLE_BTN, STYLE_BTN_OPTS);
242   SetButtonFont(italic_btn,FXFont::Italic);
243   italic_btn->setState(sd->style&Italic?STATE_DOWN:STATE_UP);
244 
245   bold_btn = new FXToggleButton(stylebtns, "B", "B", NULL, NULL, this, ID_STYLE_BTN, STYLE_BTN_OPTS);
246   SetButtonFont(bold_btn,FXFont::Bold);
247   bold_btn->setState(sd->style&Bold?STATE_DOWN:STATE_UP);
248 
249   caption->setJustify(JUSTIFY_LEFT|JUSTIFY_CENTER_Y);
250   GetFontDescription(fontdesc,scifont);
251   fontdesc.weight=sd->style&Bold?FXFont::Bold:FXFont::Normal;
252   fontdesc.slant=sd->style&Italic?FXFont::Italic:FXFont::Straight;
253   labelfont=new FXFont(p->getApp(), fontdesc);
254   caption->setFont(labelfont);
255 
256   if (bgonly) {
257     caption->setTextColor(bg>FXRGB(0x80,0x80,0x80)?FXRGB(0,0,0):FXRGB(0xFF,0xFF,0xFF));
258     fg_btn->setRGBA(fg_btn->getShell()->getBackColor());
259     conceal(fg_btn);
260     fg_btn->setWidth(1);
261     conceal(italic_btn);
262     conceal(bold_btn);
263   }
264 }
265 
266 
267 
MakeStylePan(FXWindow * o)268 static FXMatrix*MakeStylePan(FXWindow*o)
269 {
270   return new FXMatrix((FXComposite*)o,3,MATRIX_BY_COLUMNS|LAYOUT_FILL,0,0,0,0,0,0,0,0,0,0);
271 }
272 
273 
274 
275 static ColorName rainbow[] = {
276   "#000000","#AA0000","#CC0000","#EE0000",
277   "#DDB000","#CCCC00","#B0CC00","#00DD00",
278   "#00CCB0","#00DDDD","#00B0DD","#0000EE",
279   "#B000DD","#DD00DD","#FFCCEE","#FFCCCC",
280   "#FFEECC","#FFFFCC","#EEFFCC","#CCFFCC",
281   "#CCFFEE","#CCFFFF","#CCEEFF","#CCCCFF",
282   "#EECCFF","#FFCCFF","#FFE0FF","#FFFFFF",
283   "\0\0\0\0\0\0\0"
284 };
285 
286 
287 
288 FXDEFMAP(LangGUI) LangGUIMap[]={
289   FXMAPFUNC(SEL_COMMAND,LangGUI::ID_LANG_SWITCH,LangGUI::onLangSwitch),
290   FXMAPFUNC(SEL_COMMAND,LangGUI::ID_KWORD_EDIT,LangGUI::onKeywordEdit),
291   FXMAPFUNC(SEL_COMMAND,LangGUI::ID_TABOPTS_SWITCH,LangGUI::onTabOptsSwitch),
292   FXMAPFUNCS(SEL_COMMAND,LangGUI::ID_EDIT_FILETYPES,LangGUI::ID_EDIT_SHABANGS,LangGUI::onSyntaxFiletypeEdit),
293 };
294 
FXIMPLEMENT(LangGUI,FXVerticalFrame,LangGUIMap,ARRAYNUMBER (LangGUIMap))295 FXIMPLEMENT(LangGUI,FXVerticalFrame,LangGUIMap,ARRAYNUMBER(LangGUIMap))
296 
297 
298 
299 long LangGUI::onLangSwitch(FXObject*o,FXSelector sel,void*p)
300 {
301   FXival index=(FXival)p;
302   if (index==-1) { index=langlist->getCurrentItem(); }
303   whichlang=index;
304   StyleDef*sd0,*sdN;
305   wordlist->clearItems();
306   LangStyle* ls=(LangStyle*)langlist->getItemData(index);
307   syntabs->setCurrent(0);
308   if (ls) {
309     opts_tab->enable();
310     wildcardbtn->enable();
311     wildcardbtn->setUserData(ls);
312     shabangbtn->enable();
313     shabangbtn->setUserData(ls);
314     kwordsgrp->enable();
315     tabopts->enable();
316     taboptlab->enable();
317     tabopts->setCurrentItem(ls->tabs);
318     tabwidthspin->enable();
319     tabwidthspin->setUserData(ls);
320     tabwidthspin->setValue(ls->tabwidth);
321     tabwidthlab->enable();
322     if (ls->words){
323       char**words;
324       const LexerModule*lm=Catalogue::Find(ls->id);
325       int nwl=lm?lm->GetNumWordLists():-1;
326       int i=0;
327       for (words=ls->words; *words; words++) {
328         FXString wld=(lm&&(i<nwl))?lm->GetWordListDescription(i++):NULL;
329         if (wld=="Unused") { wld=_("User defined"); }
330         if (wld.empty()) { wld.format(_("words #%d"), wordlist->getNumItems()+1); }
331         wordlist->appendItem(wld,NULL,*words);
332       }
333     }
334     if (wordlist->getNumItems()>0) {
335       kwordsgrp->enable();
336       wordlist->enable();
337       wordbtn->enable();
338       wordlist->setNumVisible(wordlist->getNumItems());
339     } else {
340       kwordsgrp->disable();
341       wordlist->disable();
342       wordbtn->disable();
343     }
344     sd0=ls->styles;
345   } else {
346     opts_tab->disable();
347     kwordsgrp->disable();
348     wordlist->disable();
349     wordbtn->disable();
350     tabopts->setCurrentItem(0);
351     tabopts->disable();
352     taboptlab->disable();
353     tabwidthspin->setUserData(NULL);
354     tabwidthspin->disable();
355     tabwidthlab->disable();
356     wildcardbtn->setUserData(NULL);
357     wildcardbtn->disable();
358     shabangbtn->setUserData(NULL);
359     shabangbtn->disable();
360     sd0=prefs->globalStyle();
361   }
362   if (scifont) { delete scifont; }
363   scifont=new FXFont(langlist->getApp(), prefs->FontName, prefs->FontSize/10);
364   FXWindow* w=style_pan->getParent();
365   delete style_pan;
366   style_pan=MakeStylePan(w);
367   if (sel) { style_pan->create(); }
368   StyleEdit*se;
369   for (sdN=sd0; sdN->key; sdN++) {
370     se=new StyleEdit(style_pan,sdN,scifont);
371     if (sel) { se->create(); }
372   }
373   if (sd0==prefs->globalStyle()) {
374 
375     se=new StyleEdit(style_pan,prefs->selectionStyle(),scifont,true);
376     if (sel) { se->create(); }
377 
378     se=new StyleEdit(style_pan,prefs->caretStyle(),scifont,true);
379     if (sel) { se->create(); }
380 
381     se=new StyleEdit(style_pan,prefs->caretlineStyle(),scifont,true);
382     if (sel) { se->create(); }
383 
384     se=new StyleEdit(style_pan,prefs->rightmarginStyle(),scifont,true);
385     if (sel) { se->create(); }
386 
387     se=new StyleEdit(style_pan,prefs->whitespaceStyle(),scifont,true);
388     if (sel) { se->create(); }
389 
390   }
391   if (style_pan->numChildren()==0) {
392     style_hdr->hide();
393     FXLabel*lab=new FXLabel(style_pan, _("No font styles available for this item"),
394       NULL,LAYOUT_FILL_X|JUSTIFY_CENTER_X);
395     lab->setPadTop(32);
396     if (shown()) { lab->create(); }
397   } else {
398     style_hdr->show();
399   }
400   return 1;
401 }
402 
403 
404 
onKeywordEdit(FXObject * o,FXSelector sel,void * p)405 long LangGUI::onKeywordEdit(FXObject*o,FXSelector sel,void*p)
406 {
407   LangStyle*ls=(LangStyle*)langlist->getItemData(langlist->getCurrentItem());
408   int n=wordlist->getCurrentItem();
409   char *words=(char*)wordlist->getItemData(wordlist->getCurrentItem());
410   FXDialogBox kwdlg(this,_("Edit word list"),DECOR_TITLE|DECOR_BORDER,0,0,480,320);
411   SetPad(&kwdlg, 0);
412   FXVerticalFrame*vframe=new FXVerticalFrame(&kwdlg, LAYOUT_FILL);
413   SetPad(vframe, 0);
414   FXVerticalFrame*scframe=new FXVerticalFrame(vframe, LAYOUT_FILL|FRAME_SUNKEN|FRAME_THICK);
415   SetPad(scframe, 0);
416   FXScintilla*sc=new FXScintilla(scframe, NULL,0,TEXT_WORDWRAP|LAYOUT_FILL|HSCROLLER_NEVER);
417   sc->sendMessage(SCI_SETHSCROLLBAR,false, 0);
418   sc->sendMessage(SCI_STYLESETFONT, STYLE_DEFAULT, reinterpret_cast<long>(scifont->getName().text()));
419   sc->sendMessage(SCI_STYLESETSIZE, STYLE_DEFAULT, 10);
420   sc->sendMessage(SCI_SETWRAPMODE,SC_WRAP_WORD,0);
421   sc->sendMessage(SCI_SETMARGINWIDTHN,1,0);
422   sc->sendMessage(SCI_SETMARGINLEFT,0,4);
423   sc->sendMessage(SCI_SETMARGINRIGHT,0,4);
424   sc->sendMessage(SCI_APPENDTEXT,strlen(words),reinterpret_cast<long>(words));
425   FXHorizontalFrame *btns=new FXHorizontalFrame(vframe, PACK_UNIFORM|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM);
426   new FXButton(btns,_(" &OK "), NULL, &kwdlg, FXDialogBox::ID_ACCEPT);
427   new FXButton(btns,_(" &Cancel "), NULL, &kwdlg, FXDialogBox::ID_CANCEL);
428   kwdlg.changeFocus(sc);
429   if (kwdlg.execute(PLACEMENT_SCREEN)) {
430     FXString newwords;
431     newwords.length(sc->sendMessage(SCI_GETLENGTH,0,0)+1);
432     sc->sendMessage(SCI_GETTEXT,newwords.length(), reinterpret_cast<long>(newwords.text()));
433     const char*whitechars="\t\r\n";
434     const char *c;
435     for (c=whitechars; *c; c++) {
436       newwords.substitute(*c, ' ', true);
437       newwords.trim();
438       newwords.simplify();
439     }
440     if (strcmp(words, newwords.text())!=0) {
441       SetKeywordList(ls,n,newwords);
442       wordlist->setItemData(wordlist->getCurrentItem(), ls->words[n]);
443     }
444   }
445   if (sc->hasClipboard()) {
446     TopWinPub::SaveClipboard();
447   }
448   return 1;
449 }
450 
451 
452 
onTabOptsSwitch(FXObject * o,FXSelector sel,void * p)453 long LangGUI::onTabOptsSwitch(FXObject*o,FXSelector sel,void*p)
454 {
455   LangStyle*ls=(LangStyle*)langlist->getItemData(langlist->getCurrentItem());
456   ls->tabs=(TabPolicy)tabopts->getCurrentItem();
457   return 1;
458 }
459 
460 
461 
onSyntaxFiletypeEdit(FXObject * o,FXSelector sel,void * p)462 long LangGUI::onSyntaxFiletypeEdit(FXObject*o,FXSelector sel,void*p)
463 {
464   ClipTextDialog *tb=NULL;
465   LangStyle*ls=(LangStyle*)((FXButton*)o)->getUserData();
466   FXString txt;
467   switch (FXSELID(sel)) {
468     case ID_EDIT_FILETYPES: {
469       txt.format( _(
470         "A list of wildcard masks, each separated by the pipe \"|\" symbol.\n"
471         "\n"
472         "Filenames that match any of these patterns will default to \"%s\" language.\n"
473       ), ls->name );
474       tb=new ClipTextDialog(this, _("Edit file types"), txt);
475       tb->setText(ls->mask);
476       sel=FXSEL(SEL_COMMAND,Settings::ID_SET_FILETYPES);
477       break;
478     }
479     case ID_EDIT_SHABANGS: {
480       txt.format( _(
481         "A list of program names, each separated by the pipe \"|\" symbol.\n"
482         "\n"
483         "Files beginning with a #! interpreter directive containing any of\n"
484         "these program names will default to \"%s\" language.\n"
485       ), ls->name );
486       tb=new ClipTextDialog(this,_("Edit shabang apps"),txt);
487       tb->setText(ls->apps);
488       sel=FXSEL(SEL_COMMAND,Settings::ID_SET_SHABANGS);
489       break;
490     }
491   }
492   tb->setUserData(ls);
493   tb->setNumColumns(40);
494   if (tb->execute()) {
495     prefs->handle(tb,sel,NULL);
496   }
497   delete tb;
498   return 1;
499 }
500 
501 
502 
MakeStyleTab()503 void LangGUI::MakeStyleTab()
504 {
505   FXVerticalFrame *style_gui;
506   FXHorizontalFrame *frame;
507   new FXTabItem(syntabs,_(" Styles   "));
508   style_gui=new FXVerticalFrame(syntabs,FRAME_RAISED|LAYOUT_FILL,0,0,0,0,0,0,0,0,0,0);
509   style_hdr=new FXHorizontalFrame(style_gui,LAYOUT_FILL_X|FRAME_GROOVE,0,0,0,0,0,0,0,0,0,0);
510   new FXLabel(style_hdr, _("Font"),NULL,FRAME_SUNKEN);
511   new FXLabel(style_hdr, _("Style Name"), NULL, LAYOUT_FILL_X|FRAME_SUNKEN);
512   new FXLabel(style_hdr, "  FG  /  BG  ",NULL,FRAME_SUNKEN);
513   scroll=new FXScrollWindow(style_gui,LAYOUT_FILL|HSCROLLING_OFF|VSCROLLING_ON|VSCROLLER_ALWAYS);
514   style_pan=MakeStylePan(scroll);
515   frame=new FXHorizontalFrame(style_gui,FRAME_RAISED|LAYOUT_FILL_X,0,0,0,0,0,0,0,0,0,0);
516   SetPad(frame,4);
517   frame=new FXHorizontalFrame(frame,FRAME_NONE|LAYOUT_CENTER_X,0,0,0,0,0,0,0,0,0,0);
518   for (FXint i=0; rainbow[i][0]; i++) {
519     new FXColorWell(frame,
520     HexToRGB(rainbow[i]),NULL,0,FRAME_NONE|COLORWELL_OPAQUEONLY|COLORWELL_SOURCEONLY|COLORWELL_NORMAL,0,0,0,0,0,0,0,0);
521   }
522 }
523 
524 
525 
MakeOptsTab()526 void LangGUI::MakeOptsTab()
527 {
528   FXHorizontalFrame *hframe;
529   FXGroupBox*grp;
530   FXVerticalFrame *opts_gui;
531   opts_tab=new FXTabItem(syntabs,_(" Options  "));
532   opts_gui=new FXVerticalFrame(syntabs,FRAME_RAISED|LAYOUT_FILL|PACK_UNIFORM);
533 
534   hframe=new FXHorizontalFrame(opts_gui,FRAME_NONE);
535   grp=new FXGroupBox(hframe,_("Recognition"),FRAME_GROOVE);
536   hframe=new FXHorizontalFrame(grp,FRAME_NONE|PACK_UNIFORM);
537   hframe->setHSpacing(8);
538   wildcardbtn=new FXButton(hframe,_("File types..."),NULL,this,ID_EDIT_FILETYPES,BUTTON_NORMAL|LAYOUT_FILL_X);
539   shabangbtn=new FXButton(hframe,_("#! programs..."),NULL,this,ID_EDIT_SHABANGS,BUTTON_NORMAL|LAYOUT_FILL_X);
540 
541   hframe=new FXHorizontalFrame(opts_gui,FRAME_NONE);
542   kwordsgrp=new FXGroupBox(hframe,_("Keyword lists"),FRAME_GROOVE);
543   hframe=new FXHorizontalFrame(kwordsgrp,FRAME_NONE);
544 
545   wordlist=new FXListBox(hframe,NULL,0,LIST_BOX_OPTS|LAYOUT_FILL_X );
546   wordbtn=new FXButton(hframe, "...", NULL, this, ID_KWORD_EDIT);
547 
548   grp=new FXGroupBox(opts_gui,_("Tab settings"),FRAME_GROOVE);
549   hframe=new FXHorizontalFrame(grp,FRAME_NONE);
550   taboptlab=new FXLabel(hframe,_("Use tabs:"));
551   tabopts=new FXListBox(hframe,this,ID_TABOPTS_SWITCH,LIST_BOX_OPTS|LAYOUT_FILL_X);
552   tabopts->appendItem(_("use default setting"));
553   tabopts->appendItem(_("always use tabs"));
554   tabopts->appendItem(_("never use tabs"));
555   tabopts->appendItem(_("detect from content"));
556   tabopts->setNumVisible(4);
557 
558   hframe=new FXHorizontalFrame(grp,FRAME_NONE);
559   tabwidthspin=new FXSpinner(hframe, 3, prefs, Settings::ID_SET_TAB_WIDTH_FOR_LANG,SPIN_OPTS);
560   tabwidthspin->setRange(0,16);
561   tabwidthspin->setValue(0);
562   tabwidthlab=new FXLabel(hframe,"Tab width (zero to use default)");
563 }
564 
565 
566 
~LangGUI()567 LangGUI::~LangGUI()
568 {
569   delete scifont;
570 }
571 
572 
573 
574 
LangGUI(FXComposite * o,Settings * aprefs,FXObject * trg,FXSelector sel)575 LangGUI::LangGUI(FXComposite*o,Settings*aprefs,FXObject*trg, FXSelector sel):FXVerticalFrame(o,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL)
576 {
577   FXHorizontalFrame *frame;
578   prefs=aprefs;
579   scifont=NULL;
580   frame=new FXHorizontalFrame(this,FRAME_GROOVE|LAYOUT_FILL_X);
581   new FXLabel(frame,_("Language:"));
582   langlist=new FXListBox(frame,this,ID_LANG_SWITCH,LIST_BOX_OPTS);
583   langlist->appendItem(_("global"),NULL,NULL);
584   LangStyle*ls;
585   for (ls=languages; ls->name; ls++) { langlist->appendItem(ls->name,NULL,ls); }
586   langlist->setNumVisible(langlist->getNumItems()>12?12:langlist->getNumItems());
587   langlist->setCurrentItem(whichlang);
588 
589   syntabs=new ShadyTabs(this,trg,sel,PACK_UNIFORM_WIDTH|LAYOUT_FILL);
590   SetPad(syntabs,0);
591   MakeStyleTab();
592   MakeOptsTab();
593   onLangSwitch(langlist, 0, (void*)(FXival)whichlang);
594 }
595 
596