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