1 /*
2   FXiTe - The Free eXtensIble Text Editor
3   Copyright (c) 2009-2012 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 <fx.h>
20 #include "prefs.h"
21 #include "menuspec.h"
22 #include "tooltree.h"
23 #include "shmenu.h"
24 
25 #include "intl.h"
26 #include "prefdlg_tbar.h"
27 
28 
29 
30 // Subclass FXListItem to show custom tooltip...
31 class TBarListItem: public FXListItem {
32 public:
TBarListItem(const FXString & text,FXIcon * ic=NULL,void * ptr=NULL)33   TBarListItem(const FXString &text, FXIcon *ic=NULL, void *ptr=NULL):FXListItem(text,ic,ptr) {
34     if (text.empty()) {
35       const char *path=MenuMgr::GetUsrCmdPath((MenuSpec*)ptr);
36       FXString s;
37       if (path && UserMenu::MakeLabelFromPath(path,s)) {
38         setText(stripHotKey(s.section('\t',0)));
39       } else { setText(((MenuSpec*)ptr)->pref); }
40     }
41   }
getTipText() const42   virtual FXString getTipText() const {
43     FXString tip;
44     MenuSpec*spec=(MenuSpec*)getData();
45     if (spec) { MenuMgr::GetTBarBtnTip(spec,tip); } else { tip=label.text(); }
46     return tip;
47   }
48 };
49 
50 
51 
52 
53 FXDEFMAP(ToolbarPrefs) ToolbarPrefsMap[]={
54   FXMAPFUNC(SEL_COMMAND,ToolbarPrefs::ID_ITEM_REMOVE,ToolbarPrefs::onRemoveItem),
55   FXMAPFUNC(SEL_COMMAND,ToolbarPrefs::ID_INSERT_CUSTOM,ToolbarPrefs::onInsertCustomItem),
56   FXMAPFUNC(SEL_COMMAND,ToolbarPrefs::ID_CHANGE_BTN_SIZE,ToolbarPrefs::onChangeBtnSize),
57   FXMAPFUNC(SEL_COMMAND,ToolbarPrefs::ID_CHANGE_BTN_WRAP,ToolbarPrefs::onChangeBtnWrap),
58 };
59 
60 FXIMPLEMENT(ToolbarPrefs,DualListForm,ToolbarPrefsMap,ARRAYNUMBER(ToolbarPrefsMap));
61 
62 
63 
ToolbarPrefs(FXComposite * p,UserMenu ** ums,FXSelector lastid,FXObject * tgt,FXSelector sel)64 ToolbarPrefs::ToolbarPrefs(FXComposite*p, UserMenu**ums, FXSelector lastid, FXObject* tgt, FXSelector sel):
65   DualListForm(p,tgt,sel,TBAR_MAX_BTNS)
66 {
67   user_menus=ums;
68   invalid=(FXint)lastid;
69   udata = (void*)((FXival)ToolbarChangedLayout);
70   prefs=Settings::instance();
71 
72   FXHorizontalFrame* AvailBtns=new FXHorizontalFrame( left_column,
73                                                      FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_CENTER_X|PACK_UNIFORM_WIDTH);
74   custom_btn=new FXButton( AvailBtns, _("Custom &Tools..."),
75                                 NULL,this, ID_INSERT_CUSTOM,BUTTON_NORMAL|LAYOUT_CENTER_X);
76 
77   FXLabel*btn_size_cpn=new FXLabel(mid_column, _("Button size:"), NULL, LABEL_NORMAL|JUSTIFY_LEFT);
78   btn_size_cpn->setPadTop(48);
79   FXListBox *size_list=new FXListBox(mid_column,this,ID_CHANGE_BTN_SIZE);
80   size_list->appendItem(_("small"),  NULL,NULL);
81   size_list->appendItem(_("medium"), NULL,NULL);
82   size_list->appendItem(_("large"),  NULL,NULL);
83   size_list->setNumVisible(3);
84   size_list->setCurrentItem(prefs->ToolbarButtonSize);
85 
86   FXCheckButton*wrap_tbar_chk=new FXCheckButton(mid_column,_("Wrap buttons"),this,ID_CHANGE_BTN_WRAP);
87   wrap_tbar_chk->setCheck(prefs->WrapToolbar);
88 }
89 
90 
NotifyChanged(FXuint what)91 void ToolbarPrefs::NotifyChanged(FXuint what)
92 {
93   DualListForm::NotifyChanged((void*)((FXival)what));
94 }
95 
96 
97 
onChangeBtnSize(FXObject * o,FXSelector sel,void * p)98 long ToolbarPrefs::onChangeBtnSize(FXObject*o,FXSelector sel,void*p)
99 {
100   prefs->handle(o,FXSEL(SEL_COMMAND,Settings::ID_SET_TOOLBAR_BTN_SIZE),p);
101   NotifyChanged(ToolbarChangedFont);
102   return 1;
103 }
104 
105 
106 
onChangeBtnWrap(FXObject * o,FXSelector sel,void * p)107 long ToolbarPrefs::onChangeBtnWrap(FXObject*o,FXSelector sel,void*p)
108 {
109   prefs->handle(o,FXSEL(SEL_COMMAND,Settings::ID_TOGGLE_WRAP_TOOLBAR),p);
110   NotifyChanged(ToolbarChangedWrap);
111   return 1;
112 }
113 
114 
115 
onRemoveItem(FXObject * o,FXSelector sel,void * p)116 long ToolbarPrefs::onRemoveItem(FXObject*o,FXSelector sel,void*p)
117 {
118   FXint iUsed=used_items->getCurrentItem();
119   MenuSpec*spec=(MenuSpec*)used_items->getItemData(iUsed);
120   if (spec->type=='u') {
121     MenuMgr::RemoveTBarUsrCmd(spec);
122     used_items->removeItem(iUsed);
123     CheckCount();
124   } else {
125     DualListForm::onRemoveItem(o,sel,p);
126   }
127   return 1;
128 }
129 
130 
131 
onInsertCustomItem(FXObject * o,FXSelector sel,void * p)132 long ToolbarPrefs::onInsertCustomItem(FXObject*o,FXSelector sel,void*p)
133 {
134   FXMenuCommand*mc;
135   if (ToolsTree::SelectTool(this, user_menus, mc)) {
136     const char*newpath=(const char*)mc->getUserData();
137     if (newpath) {
138       // If the command is already in the used items list, just select it...
139       for (FXint i=0; i<used_items->getNumItems(); i++) {
140         const char*oldpath=MenuMgr::GetUsrCmdPath((MenuSpec*)used_items->getItemData(i));
141         if (oldpath && (strcmp(newpath, oldpath)==0)) {
142           used_items->selectItem(i);
143           used_items->setCurrentItem(i);
144           used_items->makeItemVisible(i);
145           CheckIndex();
146           return 1;
147         }
148       }
149     }
150     MenuSpec*spec=MenuMgr::AddTBarUsrCmd(mc);
151     FXListItem*item=new TBarListItem(FXString::null,NULL,(void*)spec);
152     InsertItem(item);
153   }
154   return 1;
155 }
156 
157 
158 
CheckCount()159 void ToolbarPrefs::CheckCount()
160 {
161   FXint*btns=MenuMgr::TBarBtns();
162   FXint iUsed;
163   for (iUsed=0; iUsed<max_items; iUsed++) {
164     btns[iUsed]=invalid;
165   }
166   for (iUsed=0; iUsed<used_items->getNumItems(); iUsed++) {
167     MenuSpec*spec=(MenuSpec*)(used_items->getItemData(iUsed));
168     btns[iUsed]=spec->sel;
169   }
170   DualListForm::CheckCount();
171   if (ins_btn->isEnabled()) { custom_btn->enable(); } else { custom_btn->disable(); }
172 }
173 
174 
175 
PopulateAvail()176 void ToolbarPrefs::PopulateAvail()
177 {
178   for (MenuSpec*spec=MenuMgr::MenuSpecs(); spec->sel!=invalid; spec++) {
179     if (spec->ms_mc) {
180       avail_items->appendItem(new TBarListItem(spec->pref, NULL, (void*)spec));
181     }
182   }
183 }
184 
185 
186 
PopulateUsed()187 void ToolbarPrefs::PopulateUsed()
188 {
189   for (FXint*isel=MenuMgr::TBarBtns(); *isel!=invalid; isel++) {
190     MenuSpec* spec=MenuMgr::LookupMenu(*isel);
191     if (spec) {
192       FXint found=avail_items->findItemByData((void*)spec);
193       if (found>=0) {
194         TBarListItem*item=(TBarListItem*)avail_items->extractItem(found);
195         item->setSelected(false);
196         used_items->appendItem(item);
197       } else {
198         used_items->appendItem(new TBarListItem(FXString::null,NULL,(void*)spec));
199       }
200     }
201   }
202 }
203 
204 
205 
206 
207 FXDEFMAP(PopupPrefs) PopupPrefsMap[]={
208   FXMAPFUNC(SEL_COMMAND,PopupPrefs::ID_INSERT_CUSTOM,PopupPrefs::onInsertCustomItem),
209   FXMAPFUNC(SEL_COMMAND,PopupPrefs::ID_INSERT_SEPARATOR,PopupPrefs::onInsertSeparator),
210 };
211 
212 FXIMPLEMENT(PopupPrefs,DualListForm,PopupPrefsMap,ARRAYNUMBER(PopupPrefsMap));
213 
214 
215 
216 class PopupListItem: public FXListItem {
217 public:
PopupListItem(const FXString & text,FXIcon * ic=NULL,void * ptr=NULL)218   PopupListItem(const FXString &text, FXIcon *ic=NULL, void *ptr=NULL):FXListItem() {
219     data=strdup((const char*)ptr);
220     setText(stripHotKey(text.section('\t',0)));
221   }
~PopupListItem()222   ~PopupListItem() { if (data) { free(data); }}
getTipText() const223   virtual FXString getTipText() const {
224     FXString tip;
225     MenuMgr::GetTipFromFilename((const char*)getData(),tip);
226     return tip;
227   }
228 };
229 
230 
231 
232 class PopupSeparator: public FXListItem {
233 public:
PopupSeparator()234   PopupSeparator():FXListItem("--"){}
getTipText() const235   virtual FXString getTipText() const { return _("<separator>"); }
236 };
237 
238 
239 
PopupPrefs(FXComposite * p,UserMenu ** ums,FXSelector lastid,FXObject * tgt,FXSelector sel)240 PopupPrefs::PopupPrefs(FXComposite*p, UserMenu**ums, FXSelector lastid, FXObject*tgt, FXSelector sel):DualListForm(p,tgt,sel,POPUP_MAX_CMDS)
241 {
242   user_menus=ums;
243   invalid=(FXint)lastid;
244   FXHorizontalFrame* AvailBtns=new FXHorizontalFrame( left_column,
245                                                      FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_CENTER_X|PACK_UNIFORM_WIDTH);
246   custom_btn=new FXButton( AvailBtns, _("Custom &Tools..."),
247                                 NULL,this, ID_INSERT_CUSTOM,BUTTON_NORMAL|LAYOUT_CENTER_X);
248   FXVerticalFrame* SepBtnFrm=new FXVerticalFrame( mid_column,
249                                                      FRAME_NONE|LAYOUT_FILL|LAYOUT_CENTER_X|LAYOUT_CENTER_Y|LAYOUT_SIDE_BOTTOM);
250   SepBtnFrm->setPadTop(32);
251   separator_btn=new FXButton( SepBtnFrm, _("&Separator>>"),
252                                 NULL,this, ID_INSERT_SEPARATOR,BUTTON_NORMAL|LAYOUT_CENTER_X|LAYOUT_CENTER_Y);
253 
254 }
255 
256 
257 
CheckCount()258 void PopupPrefs::CheckCount()
259 {
260   MenuMgr::FreePopupCommands();
261   char**commands=MenuMgr::GetPopupCommands();
262   for (FXint i=0; i<used_items->getNumItems(); i++) {
263     if (dynamic_cast<TBarListItem*>(used_items->getItem(i))) {
264       MenuSpec*ms=(MenuSpec*)(used_items->getItemData(i));
265       if (ms) {
266         commands[i]=strdup(ms->pref?ms->pref:"");
267       } else {
268         commands[i]=strdup("");
269       }
270     } else if (dynamic_cast<PopupListItem*>(used_items->getItem(i))) {
271       const char*cmd=(const char*)used_items->getItemData(i);
272       commands[i]=strdup(cmd?cmd:"");
273     } else {
274        commands[i]=strdup("");
275     }
276   }
277   DualListForm::CheckCount();
278   if (ins_btn->isEnabled()) { custom_btn->enable(); } else { custom_btn->disable(); }
279 }
280 
281 
282 
onInsertSeparator(FXObject * o,FXSelector sel,void * p)283 long PopupPrefs::onInsertSeparator(FXObject*o, FXSelector sel, void*p)
284 {
285   InsertItem(new PopupSeparator());
286   return 1;
287 }
288 
289 
290 
onInsertCustomItem(FXObject * o,FXSelector sel,void * p)291 long PopupPrefs::onInsertCustomItem(FXObject*o, FXSelector sel, void*p)
292 {
293   FXMenuCommand*mc;
294   if (ToolsTree::SelectTool(this, user_menus, mc)) {
295     const char*newpath=(const char*)mc->getUserData();
296     if (newpath) {
297       // If the command is already in the used items list, just select it...
298       for (FXint i=0; i<used_items->getNumItems(); i++) {
299         const char*oldpath=(const char*)used_items->getItemData(i);
300         if (oldpath && (strcmp(newpath, oldpath)==0)) {
301           used_items->selectItem(i);
302           used_items->setCurrentItem(i);
303           used_items->makeItemVisible(i);
304           CheckIndex();
305           return 1;
306         }
307       }
308       FXString label;
309       if (FXStat::exists(newpath) && UserMenu::MakeLabelFromPath(newpath,label)) {
310         FXListItem*item=new PopupListItem(label,NULL,(void*)newpath);
311         InsertItem(item);
312       }
313     }
314   }
315   return 1;
316 }
317 
318 
319 
PopulateAvail()320 void PopupPrefs::PopulateAvail()
321 {
322   for (MenuSpec*spec=MenuMgr::MenuSpecs(); spec->sel!=invalid; spec++) {
323     if ((spec->type=='m')&&(spec->ms_mc||(strncmp(spec->pref,"Popup",5)==0))) {
324       avail_items->appendItem(new TBarListItem(spec->pref, NULL, (void*)spec));
325     }
326   }
327 }
328 
329 
330 
PopulateUsed()331 void PopupPrefs::PopulateUsed()
332 {
333   for (char**cmd=MenuMgr::GetPopupCommands(); *cmd; cmd++) {
334     if (*cmd[0]) {
335       MenuSpec* spec=MenuMgr::LookupMenuByPref(*cmd);
336       if (spec) {
337         FXint found=avail_items->findItemByData((void*)spec);
338         if (found>=0) {
339           TBarListItem*item=(TBarListItem*)avail_items->extractItem(found);
340           item->setSelected(false);
341           used_items->appendItem(item);
342         } else {
343           used_items->appendItem(new TBarListItem(spec->pref,NULL,(void*)spec));
344         }
345       } else {
346         FXString label;
347         if (FXStat::exists(*cmd) && UserMenu::MakeLabelFromPath(*cmd,label)) {
348           used_items->appendItem(new PopupListItem(label,NULL,*cmd));
349         }
350       }
351     } else {
352       used_items->appendItem(new PopupSeparator());
353     }
354   }
355 }
356 
357