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 <lua.hpp>
22 
23 
24 #include "appwin.h"
25 #include "filer.h"
26 #include "prefs_base.h"
27 
28 #include "intl.h"
29 
30 static TopWindow*tw=NULL;
31 static SettingsBase*prefs=NULL;
32 
33 
edit_indent(lua_State * L)34 static int edit_indent(lua_State* L){
35   const char*size=luaL_checkstring(L,1);
36   const char*dirn=luaL_checkstring(L,2);
37   bool bytab=false;
38   bool toright=true;
39   if (strcasecmp(size,"space")==0) {
40     bytab=false;
41   } else {
42     if ((strcasecmp(size,"tab")==0)) {
43      bytab=true;
44     } else {
45       luaL_argerror(L,1, _("expected keyword \"space\" or \"tab\""));
46     }
47   }
48   if (strcasecmp(dirn,"right")==0) {
49     toright=true;
50   } else {
51     if ((strcasecmp(dirn,"left")==0)) {
52       toright=false;
53     } else {
54       luaL_argerror(L,2, _("expected keyword \"right\" or \"left\""));
55     }
56   }
57   FXint id;
58   if (toright) {
59     if (bytab) {
60       id=TopWindow::ID_INDENT_FULL;
61     } else {
62       id=TopWindow::ID_INDENT_STEP;
63     }
64   } else {
65     if (bytab) {
66       id=TopWindow::ID_UNINDENT_FULL;
67     } else {
68       id=TopWindow::ID_UNINDENT_STEP;
69     }
70   }
71   tw->onIndent(NULL, FXSEL(SEL_COMMAND,id), NULL);
72   return 0;
73 }
74 
75 
76 
edit_format(lua_State * L)77 static int edit_format(lua_State* L)
78 {
79   const char*opts[]={"dos", "mac", "unix", NULL};
80   FXSelector cmd=0;
81   int opt=luaL_checkoption(L,1,NULL,opts);
82   switch (opt) {
83     case 0: { cmd=TopWindow::ID_FMT_DOS; break; }
84     case 1: { cmd=TopWindow::ID_FMT_MAC; break; }
85     case 2: { cmd=TopWindow::ID_FMT_UNIX; break; }
86   }
87   tw->onFileFormat(NULL,FXSEL(SEL_COMMAND, cmd),NULL);
88   return 0;
89 }
90 
91 
92 
edit_preferences(lua_State * L)93 static int edit_preferences(lua_State* L)
94 {
95   tw->onPrefsDialog(NULL,0,NULL);
96   return 0;
97 }
98 
99 
edit_redo(lua_State * L)100 static int edit_redo(lua_State* L)
101 {
102   tw->onRedo(NULL,0,NULL);
103   return 0;
104 }
105 
106 
107 
edit_undo(lua_State * L)108 static int edit_undo(lua_State* L){
109   tw->onUndo(NULL,0,NULL);
110   return 0;
111 }
112 
113 
file_new(lua_State * L)114 static int file_new(lua_State* L)
115 {
116   tw->onFileNew(NULL,0,NULL);
117   return 0;
118 }
119 
120 
121 
file_insert_file(lua_State * L)122 static int file_insert_file(lua_State* L)
123 {
124   tw->onInsertFile(NULL,0,NULL);
125   return 0;
126 }
127 
128 
129 
file_load_tags_file(lua_State * L)130 static int file_load_tags_file(lua_State* L)
131 {
132   if (lua_gettop(L)==0) {
133     tw->onLoadTags(NULL,0,NULL);
134   } else {
135     const char*fn=luaL_checkstring(L,1);
136     if (fn) {
137       FXStat *info= new FXStat;
138       FXString *filename=new FXString();
139       *filename=FXPath::simplify(FXPath::absolute(fn));
140       if (FXStat::statFile(*filename,*info)&&info->isFile()&&info->isReadable()) {
141         tw->AddFileToTagsMenu(*filename);
142         delete info;
143         delete filename;
144       } else {
145         delete info;
146         delete filename;
147         luaL_argerror(L,1,_("failed to read file"));
148       }
149     }
150   }
151   return 0;
152 }
153 
file_unload_tags_file(lua_State * L)154 static int file_unload_tags_file(lua_State* L)
155 {
156   const char* filename=luaL_optstring(L,1,"");
157   if (!tw->RemoveFileFromTagsMenu(filename)) {
158     luaL_argerror(L,1,_("file not loaded."));
159   }
160   return 0;
161 }
162 
file_open(lua_State * L)163 static int file_open(lua_State* L)
164 {
165   tw->onFileOpen(NULL,0,NULL);
166   return 0;
167 }
168 
169 
170 
file_save(lua_State * L)171 static int file_save(lua_State* L)
172 {
173   tw->onFileSave(NULL,0,NULL);
174   return 0;
175 }
176 
177 
178 
file_save_as(lua_State * L)179 static int file_save_as(lua_State* L)
180 {
181   tw->onFileSaveAs(NULL,0,NULL);
182   return 0;
183 }
184 
185 
186 
file_save_all(lua_State * L)187 static int file_save_all(lua_State* L)
188 {
189   tw->onFileSaveAll(NULL,0,NULL);
190   return 0;
191 }
192 
193 
194 
file_save_copy(lua_State * L)195 static int file_save_copy(lua_State* L)
196 {
197   tw->onFileSaveACopy(NULL,0,NULL);
198   return 0;
199 }
200 
201 
202 
file_close(lua_State * L)203 static int file_close(lua_State* L)
204 {
205   tw->onCloseTab(NULL,0,NULL);
206   return 0;
207 }
208 
209 
file_close_all(lua_State * L)210 static int file_close_all(lua_State* L)
211 {
212   tw->onCloseAll(NULL,0,NULL);
213   return 0;
214 }
215 
file_reload(lua_State * L)216 static int file_reload(lua_State* L){
217   tw->onReload(NULL,0,NULL);
218   return 0;
219 }
220 
221 
222 
search_find(lua_State * L)223 static int search_find(lua_State* L)
224 {
225   tw->onFind(NULL,0,NULL);
226   return 0;
227 }
228 
229 
230 
search_find_next(lua_State * L)231 static int search_find_next(lua_State* L)
232 {
233   tw->onFindNext(NULL,0,NULL);
234   return 0;
235 }
236 
237 
238 
search_find_prev(lua_State * L)239 static int search_find_prev(lua_State* L)
240 {
241   tw->onFindPrev(NULL,0,NULL);
242   return 0;
243 }
244 
245 
246 
search_find_selected(lua_State * L)247 static int search_find_selected(lua_State* L)
248 {
249   const char*size=luaL_checkstring(L,1);
250   if (strcasecmp(size,"next")==0) {
251     tw->onFindSelected(NULL,FXSEL(SEL_COMMAND,TopWindow::ID_NEXT_SELECTED),NULL);
252   } else {
253     if ((strcasecmp(size,"prev")==0)) {
254       tw->onFindSelected(NULL,FXSEL(SEL_COMMAND,TopWindow::ID_PREV_SELECTED),NULL);
255     } else {
256       luaL_argerror(L,1, _("expected keyword \"next\" or \"prev\""));
257     }
258   }
259   return 0;
260 }
261 
262 
search_go_to(lua_State * L)263 static int search_go_to(lua_State* L)
264 {
265   tw->onGoto(NULL,0,NULL);
266   return 0;
267 }
268 
269 
search_go_to_selected(lua_State * L)270 static int search_go_to_selected(lua_State* L)
271 {
272   tw->onGotoSelected(NULL,0,NULL);
273   return 0;
274 }
275 
276 
277 
search_replace(lua_State * L)278 static int search_replace(lua_State* L)
279 {
280   tw->onReplace(NULL,0,NULL);
281   return 0;
282 }
283 
284 
285 
search_find_definition(lua_State * L)286 static int search_find_definition(lua_State* L)
287 {
288   tw->onFindTag(NULL,0,NULL);
289   return 0;
290 }
291 
292 
293 
search_show_calltip(lua_State * L)294 static int search_show_calltip(lua_State* L)
295 {
296   tw->onShowCallTip(NULL,0,NULL);
297   return 0;
298 }
299 
300 
301 
search_show_completions(lua_State * L)302 static int search_show_completions(lua_State* L)
303 {
304   tw->onAutoComplete(NULL,0,NULL);
305   return 0;
306 }
307 
308 
309 
tools_rebuild_menu(lua_State * L)310 static int tools_rebuild_menu(lua_State* L)
311 {
312  tw->onRescanUserMenu(NULL,0,NULL);
313   return 0;
314 }
315 
316 
317 
tools_customize_menu(lua_State * L)318 static int tools_customize_menu(lua_State* L)
319 {
320   tw->onConfigureTools(NULL,0,NULL);
321   return 0;
322 }
323 
324 
325 
view_language(lua_State * L)326 static int view_language(lua_State* L)
327 {
328   const char*name=luaL_checkstring(L,1);
329   if (!tw->SetLanguage(name)) {
330     luaL_argerror(L,1,_("invalid language name"));
331   }
332   return 0;
333 }
334 
335 
336 
view_line_numbers(lua_State * L)337 static int view_line_numbers(lua_State* L)
338 {
339   bool show;
340   if (lua_gettop(L)==0) {
341     show=!prefs->ShowLineNumbers;
342   } else {
343     luaL_argcheck(L, lua_isboolean(L,1), 1, _("expected boolean"));
344     show=lua_toboolean(L,1);
345   }
346   tw->ShowLineNumbers(show);
347   return 0;
348 }
349 
350 
351 
view_status(lua_State * L)352 static int view_status(lua_State* L)
353 {
354   bool show;
355   if (lua_gettop(L)==0) {
356     show=!prefs->ShowStatusBar;
357   } else {
358     luaL_argcheck(L, lua_isboolean(L,1), 1, _("expected boolean"));
359     show=lua_toboolean(L,1);
360   }
361   tw->ShowStatusBar(show);
362   return 0;
363 }
364 
365 
366 
view_output_pane(lua_State * L)367 static int view_output_pane(lua_State* L)
368 {
369   bool show;
370   if (lua_gettop(L)==0) {
371     show=!prefs->ShowOutputPane;
372   } else {
373     luaL_argcheck(L, lua_isboolean(L,1), 1, _("expected boolean"));
374     show=lua_toboolean(L,1);
375   }
376   tw->ShowOutputPane(show);
377   return 0;
378 }
379 
380 
381 
view_white_space(lua_State * L)382 static int view_white_space(lua_State* L)
383 {
384   bool show;
385   if (lua_gettop(L)==0) {
386     show=!prefs->ShowWhiteSpace;
387   } else {
388     luaL_argcheck(L, lua_isboolean(L,1), 1, _("expected boolean"));
389     show=lua_toboolean(L,1);
390   }
391   tw->ShowWhiteSpace(show);
392   return 0;
393 }
394 
395 
396 
view_toolbar(lua_State * L)397 static int view_toolbar(lua_State* L)
398 {
399   bool show;
400   if (lua_gettop(L)==0) {
401     show=!prefs->ShowToolbar;
402   } else {
403     luaL_argcheck(L, lua_isboolean(L,1), 1, _("expected boolean"));
404     show=lua_toboolean(L,1);
405   }
406   tw->ShowToolbar(show);
407   return 0;
408 }
409 
410 
view_tabs(lua_State * L)411 static int view_tabs(lua_State* L)
412 {
413   const char*opts[]={"position","width",NULL};
414   int opt=luaL_checkoption(L,1,NULL,opts);
415   switch (opt) {
416     case 0: {
417       const char*cmds[]={"top", "bottom", "left", "right",NULL};
418       int cmd=luaL_checkoption(L,2,NULL,cmds);
419       switch (cmd) {
420         case 0:{cmd=TopWindow::ID_TABS_TOP;    break;}
421         case 1:{cmd=TopWindow::ID_TABS_BOTTOM; break;}
422         case 2:{cmd=TopWindow::ID_TABS_LEFT;   break;}
423         case 3:{cmd=TopWindow::ID_TABS_RIGHT;  break;}
424       }
425       tw->onTabOrient(NULL, FXSEL(SEL_COMMAND, cmd), NULL);
426       break;
427     }
428     case 1: {
429       const char*cmds[]={"uniform", "packed",NULL};
430       int cmd=luaL_checkoption(L,2,NULL,cmds);
431       switch (cmd) {
432         case 0:{cmd=TopWindow::ID_TABS_UNIFORM;    break;}
433         case 1:{cmd=TopWindow::ID_TABS_COMPACT;    break;}
434       }
435       tw->onPackTabWidth(NULL,FXSEL(SEL_COMMAND, cmd),NULL);
436       break;
437     }
438   }
439   return 0;
440 }
441 
442 
443 
view_zoom(lua_State * L)444 static int view_zoom(lua_State* L)
445 {
446   if ((lua_gettop(L)>0) && lua_isnumber(L,1)) {
447     int z=lua_tointeger(L,1);//-10 to +20
448     luaL_argcheck(L,(z>-11)&&(z<21), 1, _("zoom factor out of range (-10 to +20)"));
449     tw->onZoom(NULL, 0, (void*)(FXival)z);
450   } else {
451     const char*cmds[]={"in", "out", "default", "closest", "furthest" , NULL};
452     int cmd=luaL_checkoption(L,1,NULL,cmds);
453     switch(cmd) {
454       case 0:{ cmd=TopWindow::ID_ZOOM_IN; break; }
455       case 1:{ cmd=TopWindow::ID_ZOOM_OUT; break; }
456       case 2:{ cmd=TopWindow::ID_ZOOM_NONE; break; }
457       case 3:{ cmd=TopWindow::ID_ZOOM_NEAR; break; }
458       case 4:{ cmd=TopWindow::ID_ZOOM_FAR; break; }
459     }
460     tw->onZoom(NULL, FXSEL(SEL_COMMAND, cmd), NULL);
461   }
462   return 0;
463 }
464 
465 
466 
documents_next(lua_State * L)467 static int documents_next(lua_State* L)
468 {
469   tw->onNextTab(NULL, FXSEL(SEL_COMMAND,TopWindow::ID_TAB_NEXT), NULL);
470   return 0;
471 }
472 
473 
474 
documents_prev(lua_State * L)475 static int documents_prev(lua_State* L)
476 {
477   tw->onNextTab(NULL, FXSEL(SEL_COMMAND,TopWindow::ID_TAB_PREV), NULL);
478   return 0;
479 }
480 
481 
documents_output_pane(lua_State * L)482 static int documents_output_pane(lua_State* L)
483 {
484   tw->onOutlistFocus(NULL,0,NULL);
485   return 0;
486 }
487 
488 
documents_move(lua_State * L)489 static int documents_move(lua_State* L)
490 {
491   const char*cmds[]={"first","last","up", "down", NULL};
492   int cmd=luaL_checkoption(L,1,NULL,cmds);
493   switch (cmd) {
494     case 0: { cmd=TopWindow::ID_TAB_TOFIRST; break; }
495     case 1: { cmd=TopWindow::ID_TAB_TOLAST; break; }
496     case 2: { cmd=TopWindow::ID_TAB_UP; break; }
497     case 3: { cmd=TopWindow::ID_TAB_DOWN; break; }
498   }
499   tw->onMoveTab(NULL, FXSEL(SEL_COMMAND, cmd), NULL);
500   return 0;
501 }
502 
503 
file_export(lua_State * L)504 static int file_export(lua_State* L)
505 {
506   const char*cmds[]={"pdf","html", NULL};
507   int cmd=luaL_checkoption(L,1,NULL,cmds);
508   const char*filename=luaL_optstring(L,2,NULL);
509   bool ok=false;
510   switch (cmd) {
511     case 0: {
512       ok=tw->FileDlgs()->ExportPdf(tw->ControlDoc(), filename);
513       break;
514     }
515     case 1: {
516       ok=tw->FileDlgs()->ExportHtml(tw->ControlDoc(), filename);
517       break;
518     }
519   }
520   lua_pushboolean(L,ok);
521   return 1;
522 }
523 
524 
525 
view_clear_output(lua_State * L)526 static int view_clear_output(lua_State* L)
527 {
528   tw->ClearOutput();
529   return 0;
530 }
531 
532 
533 static const struct luaL_Reg fxte_commands[] = {
534   {"file_new",                  file_new},
535   {"file_open",                 file_open},
536   {"file_reload",               file_reload},
537   {"file_save",                 file_save},
538   {"file_save_as",              file_save_as},
539   {"file_save_all",             file_save_all},
540   {"file_save_copy",            file_save_copy},
541   {"file_export",               file_export},
542   {"file_close",                file_close},
543   {"file_close_all",            file_close_all},
544   {"file_insert_file",          file_insert_file},
545   {"file_load_tags_file",       file_load_tags_file},
546   {"file_unload_tags_file",     file_unload_tags_file},
547 
548 
549   {"edit_undo",                 edit_undo},
550   {"edit_redo",                 edit_redo},
551   {"edit_indent",               edit_indent},
552   {"edit_format",               edit_format},
553   {"edit_preferences",          edit_preferences},
554 
555   {"search_find",               search_find},
556   {"search_find_next",          search_find_next},
557   {"search_find_prev",          search_find_prev},
558   {"search_find_selected",      search_find_selected},
559   {"search_replace",            search_replace},
560   {"search_go_to",              search_go_to},
561   {"search_go_to_selected",     search_go_to_selected},
562   {"search_find_definition",    search_find_definition},
563   {"search_show_calltip",       search_show_calltip},
564   {"search_show_completions",   search_show_completions},
565 
566   {"tools_rebuild_menu",        tools_rebuild_menu},
567   {"tools_customize_menu",      tools_customize_menu},
568 
569   {"view_status",               view_status},
570   {"view_line_numbers",         view_line_numbers},
571   {"view_toolbar",              view_toolbar},
572   {"view_white_space",          view_white_space},
573   {"view_output_pane",          view_output_pane},
574   {"view_zoom",                 view_zoom},
575   {"view_tabs",                 view_tabs},
576   {"view_language",             view_language},
577   {"view_clear_output",         view_clear_output},
578 
579   {"documents_next",            documents_next},
580   {"documents_prev",            documents_prev},
581   {"documents_move",            documents_move},
582   {"documents_output_pane",     documents_output_pane},
583   {NULL,NULL}
584 };
585 
586 
587 
LuaCommands(FXMainWindow * topwin)588 const luaL_Reg* LuaCommands(FXMainWindow*topwin)
589 {
590   if (!tw) {
591     tw=(TopWindow*)topwin;
592     prefs=(SettingsBase*)tw->Prefs();
593   }
594   return fxte_commands;
595 }
596 
597