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
20 #include <fx.h>
21 #include <cerrno>
22
23 #include "appname.h"
24 #include "appmain.h"
25 #include "prefs.h"
26 #include "lang.h"
27
28 #include "compat.h"
29 #include "scidoc.h"
30 #include "filer.h"
31 #include "toolmgr.h"
32 #include "prefdlg.h"
33 #include "theme.h"
34 #include "tagread.h"
35 #include "recorder.h"
36 #include "macro.h"
37 #include "search.h"
38 #include "backup.h"
39 #include "menuspec.h"
40 #include "mainmenu.h"
41 #include "toolbar.h"
42 #include "doctabs.h"
43 #include "outpane.h"
44 #include "statusbar.h"
45 #include "runcmd.h"
46 #include "cmd_utils.h"
47 #include "scidoc_util.h"
48 #include "foreachtab.h"
49
50 #include "intl.h"
51 #include "appwin_base.h"
52
53
54 #define STALECHECK 5 /* seconds between checks for external changes. */
55
56
57 FXDEFMAP(TopWindowBase) TopWindowBaseMap[]={
58 FXMAPFUNC(SEL_TIMEOUT, TopWindowBase::ID_TIMER, TopWindowBase::onTimer),
59 FXMAPFUNC(SEL_TIMEOUT, TopWindowBase::ID_CLOSEWAIT, TopWindowBase::onCloseWait),
60 FXMAPFUNC(SEL_CHORE, TopWindowBase::ID_CLOSEWAIT, TopWindowBase::onCloseWait),
61 FXMAPFUNC(SEL_CHORE, TopWindowBase::ID_CHECK_STALE, TopWindowBase::CheckStale),
62 FXMAPFUNC(SEL_CHORE, TopWindowBase::ID_CHECK_STYLE, TopWindowBase::CheckStyle),
63 FXMAPFUNC(SEL_CHORE, TopWindowBase::ID_FOCUS_DOC, TopWindowBase::onFocusDoc),
64 FXMAPFUNC(SEL_FOCUSIN, TopWindowBase::ID_SCINTILLA, TopWindowBase::onFocusSci),
65 FXMAPFUNC(SEL_FOCUSIN, 0, TopWindowBase::onFocusIn),
66 };
67 FXIMPLEMENT(TopWindowBase,MainWinWithClipBrd,TopWindowBaseMap,ARRAYNUMBER(TopWindowBaseMap))
68
69
70 static bool topwin_closing = false;
71 static TopWindowBase* global_top_window_instance=NULL;
72
73
Closing()74 bool TopWindowBase::Closing() { return topwin_closing; }
Closing(bool is_closing)75 void TopWindowBase::Closing(bool is_closing) { topwin_closing=is_closing; }
76
instance()77 TopWindowBase* TopWindowBase::instance() { return global_top_window_instance; }
78
ConfigDir()79 const FXString& TopWindowBase::ConfigDir() { return ((AppClass*)(FXApp::instance()))->ConfigDir(); }
80
Connector()81 const FXString& TopWindowBase::Connector() { return ((AppClass*)(FXApp::instance()))->Connector(); }
82
SessionFile()83 const FXString& TopWindowBase::SessionFile() { return ((AppClass*)getApp())->SessionFile(); }
84
85
Cut()86 void TopWindowBase::Cut() { SciDocUtils::Cut(FocusedDoc()); }
87
Copy()88 void TopWindowBase::Copy() { SciDocUtils::Copy(FocusedDoc()); }
89
Paste()90 void TopWindowBase::Paste() { SciDocUtils::Paste(FocusedDoc()); }
91
92
93
94
95
96 #define PACK_UNIFORM ( PACK_UNIFORM_WIDTH | PACK_UNIFORM_HEIGHT )
97
TopWindowBase(FXApp * a)98 TopWindowBase::TopWindowBase(FXApp* a):MainWinWithClipBrd(a,EXE_NAME,NULL,NULL,DECOR_ALL,0,0,600,400)
99 {
100 FXASSERT(!global_top_window_instance);
101 global_top_window_instance=this;
102 active_widget=0;
103 recorder=NULL;
104 recording=NULL;
105 need_status=0;
106 stale_ticks=0;
107 save_ticks=0;
108 skipfocus=false;
109 destroying=false;
110 close_all_confirmed=false;
111 kill_commands_confirmed=false;
112 topwin_closing=false;
113 StyleDef*sd=GetStyleFromId(Settings::globalStyle(), STYLE_CALLTIP);
114 tips=new FXToolTip(getApp(),0);
115 RgbToHex(getApp()->getTipbackColor(), sd->bg);
116 RgbToHex(getApp()->getTipforeColor(), sd->fg);
117 prefs=new Settings(this, ConfigDir());
118 SciDoc::DefaultStyles(prefs->Styles());
119 menubar=new MainMenu(this);
120 outerbox=new FXVerticalFrame(this,FRAME_NONE|LAYOUT_FILL,0,0,0,0,0,0,0,0,0,0);
121 innerbox=new FXVerticalFrame(outerbox,FRAME_NONE|LAYOUT_FILL,0,0,0,0,4,4,4,4);
122 toolbar=new ToolBarFrame(innerbox);
123 hsplit=new FXSplitter(innerbox,this, 0, SPLITTER_VERTICAL|SPLITTER_REVERSED|LAYOUT_FILL|SPLITTER_TRACKING);
124 innerbox=new FXVerticalFrame(hsplit,FRAME_NONE|LAYOUT_FILL,0,0,0,0,0,0,0,0);
125 tabbook=new DocTabs(innerbox,this,0,FRAME_NONE|PACK_UNIFORM|LAYOUT_FILL);
126 srchdlgs=new SearchDialogs(innerbox, this, 0);
127 tabbook->setTabStyleByChar(prefs->DocTabPosition);
128 tabbook->setTabsCompact(prefs->DocTabsPacked);
129 tabbook->MaxTabWidth(prefs->TabTitleMaxWidth);
130 outlist=new OutputList(hsplit,NULL,0,LAYOUT_SIDE_TOP|LAYOUT_FILL);
131 statusbar=new StatusBar(outerbox,(void*)CommandUtils::DontFreezeMe());
132 backups=new BackupMgr(this, ConfigDir());
133 completions=new AutoCompleter();
134 srchdlgs->SetPrefs(prefs->SearchOptions,prefs->SearchWrap,prefs->SearchVerbose,prefs->SearchGui);
135 cmdutils=new CommandUtils(this);
136 filedlgs=new FileDialogs(this,0);
137 }
138
139
140
~TopWindowBase()141 TopWindowBase::~TopWindowBase()
142 {
143 destroying=true;
144 delete filedlgs;
145 delete backups;
146 delete cmdutils;
147 delete recorder;
148 delete getIcon();
149 delete getMiniIcon();
150 delete completions;
151 global_top_window_instance=NULL;
152 }
153
154
155
156 const
157 #include "fxite.xpm"
158
159
create()160 void TopWindowBase::create()
161 {
162 AppClass* a=(AppClass*)getApp();
163 a->setWheelLines(prefs->WheelLines);
164 position(prefs->Left, prefs->Top,prefs->Width,prefs->Height);
165 MainWinWithClipBrd::create();
166 tips->create();
167 show(prefs->placement);
168 FXIcon*ico=NULL;
169 FXString icon_file=ConfigDir()+"icon.xpm";
170 if (FXStat::isFile(icon_file)) {
171 FXFileStream*icon_strm=new FXFileStream();
172 if (icon_strm->open(icon_file.text(),FXStreamLoad)) {
173 ico=new FXXPMIcon(a,NULL,0,IMAGE_KEEP);
174 if ( ((FXXPMIcon*)ico)->loadPixels(*icon_strm) ) {
175 ico->scale(32,32);
176 } else {
177 delete ico;
178 ico=NULL;
179 }
180 icon_strm->close();
181 }
182 delete icon_strm;
183 if (!ico) { fxwarning(_("NOTE: Failed to load custom icon.\n")); }
184 }
185 if (!ico) { ico=new FXXPMIcon(a,icon32x32_xpm,0,IMAGE_KEEP); }
186 ico->create();
187 setIcon(ico);
188 SetupXAtoms(this, a->ServerName().text(), APP_NAME);
189 if (prefs->Maximize) { maximize(); }
190 FXFont fnt(a, prefs->FontName, prefs->FontSize/10);
191 GetFontDescription(prefs->fontdesc,&fnt);
192 save_hook.format("%s%s%c%s%c%s.lua", ConfigDir().text(), "tools", PATHSEP, "hooks", PATHSEP, "saved");
193 UpdateToolbar();
194 RunHookScript("startup");
195 ParseCommands(a->Commands());
196 a->addTimeout(this,ID_TIMER,ONE_SECOND,NULL);
197 #ifndef FOX_1_6
198 if (!a->migration_errors.empty()) {
199 NewFile(false);
200 SciDoc*sci=ControlDoc();
201 sci->SetText(a->migration_errors.text());
202 a->migration_errors="";
203 }
204 #endif
205 }
206
207
208
209 #define confirm(hdr,fmt,arg) \
210 ( FXMessageBox::question(this,MBOX_OK_CANCEL,hdr,fmt,arg) == MBOX_CLICKED_OK )
211
212 #define not_confirmed() {\
213 close_all_confirmed=false; \
214 kill_commands_confirmed=false; \
215 Closing(false); \
216 }
217
218
close(FXbool notify)219 FXbool TopWindowBase::close(FXbool notify)
220 {
221 if (Closing()) { return false; }
222 if (!getApp()->getActiveWindow()) {
223 hide();
224 getApp()->runWhileEvents();
225 if (Closing()) { return false; }
226 show();
227 getApp()->runWhileEvents();
228 if (Closing()) { return false; }
229 }
230 if ((!tabbook->isEnabled()) && (!kill_commands_confirmed) ) {
231 if (!confirm(_("Command in progress"), "%s", _("External command in progress - exit anyway?"))) {
232 not_confirmed();
233 return false;
234 }
235 kill_commands_confirmed=true;
236 command_timeout=true;
237 getApp()->addChore(this,ID_CLOSEWAIT, NULL);
238 getApp()->runWhileEvents();
239 return false;
240 }
241
242 if (prefs->PromptCloseMultiExit && (tabbook->Count()>1) && (!close_all_confirmed)) {
243 if (!confirm(_("Multiple files"), _("Editing %d files - \nclose all tabs?"), tabbook->Count() ) ) {
244 not_confirmed();
245 FocusedDoc()->setFocus();
246 return false;
247 }
248 close_all_confirmed=true;
249 }
250
251 session_data="";
252 if (!RunHookScript("shutdown")) { return false; }
253 prefs->LastFocused=FocusedDoc()->Filename();
254 if (!CloseAll(true)) {
255 not_confirmed();
256 prefs->LastFocused="";
257 FocusedDoc()->setFocus();
258 return false;
259 }
260
261 if (!session_data.empty()) {
262 FXFile fh(SessionFile(), FXIO::Writing);
263 if (fh.isOpen()) {
264 FXival wrote=0;
265 wrote=fh.writeBlock(session_data.text(),session_data.length());
266 if (!(fh.close() && (wrote==session_data.length()))) {
267 fxwarning(_(EXE_NAME": Could not save %s (%s)"), SessionFile().text(), SystemErrorStr());
268 }
269 } else {
270 fxwarning(_(EXE_NAME": Could not open %s for writing (%s)"), SessionFile().text(), SystemErrorStr());
271 }
272 session_data="";
273 }
274 prefs->Maximize=isMaximized();
275 if (prefs->Maximize) {
276 restore();
277 repaint();
278 getApp()->runWhileEvents();
279 }
280 prefs->Left=getX();
281 prefs->Top=getY();
282 prefs->Width=getWidth();
283 prefs->Height=getHeight();
284
285 getApp()->runWhileEvents();
286 if (Closing()) { return false; }
287 Closing(true);
288 delete srchdlgs;
289 delete prefs;
290 delete menubar;
291 return FXMainWindow::close(notify);
292 }
293
294
295
296 /*
297 When in split-view mode, ControlDoc() refers to the view at the top (or left) of
298 the split,and FocusedDoc() refers to whichever view has the focus; In single-view
299 mode there is no difference between the ControlDoc and the FocusedDoc.
300 */
ControlDoc()301 SciDoc*TopWindowBase::ControlDoc()
302 {
303 FXWindow *page=tabbook->ActivePage();
304 return page?((SciDoc*)page->getFirst()):NULL;
305 }
306
307
308
FocusedDoc()309 SciDoc*TopWindowBase::FocusedDoc()
310 {
311 return (SciDoc*)tabbook->ActiveView();
312 }
313
314
315
CheckStale(FXObject * o,FXSelector sel,void * p)316 long TopWindowBase::CheckStale(FXObject*o, FXSelector sel, void*p)
317 {
318 static bool CheckingStale=false;
319 SciDoc*sci=ControlDoc();
320 if (!sci) { return 1; }
321 switch (sci->Stale()) {
322 case 0: { break; }
323 case 1: {
324 stale_ticks=0;
325 if ( !CheckingStale ) {
326 if (!IsDesktopCurrent(this)) { return 1; }
327 CheckingStale=true;
328 FXPopup *popup=getApp()->getPopupWindow();
329 if (popup) { popup->popdown(); }
330 if (filedlgs->AskReloadForExternalChanges(sci)) {
331 if (sci->GetReadOnly()) { SetTabLocked(sci,true); }
332 } else {
333 sci->DoStaleTest(false);
334 }
335 CheckingStale=false;
336 }
337 break;
338 }
339 case 2: {
340 stale_ticks=0;
341 if ( !CheckingStale ) {
342 if (!IsDesktopCurrent(this)) { return 1; }
343 CheckingStale=true;
344 FXPopup *popup=getApp()->getPopupWindow();
345 if (popup) { popup->popdown(); }
346 if (filedlgs->AskSaveMissingFile(sci)) {
347 if (!filedlgs->SaveFile(sci,sci->Filename())) { ShowSaveAsDlg(sci); }
348 } else {
349 sci->DoStaleTest(false);
350 }
351 CheckingStale=false;
352 }
353 break;
354 }
355 }
356 return 1;
357 }
358
359
360
361
362 /*
363 This chore updates a document's settings, and adds a chore to do the same
364 for the next document that needs updating. (See StyleNextDocCB() for more.)
365 */
CheckStyle(FXObject * o,FXSelector sel,void * p)366 long TopWindowBase::CheckStyle(FXObject*o, FXSelector sel, void*p)
367 {
368 SciDoc*sci=(SciDoc*)p;
369 if (sci && sci->NeedStyled()) {
370 SciDocUtils::SetSciDocPrefs(sci, (Settings*)prefs);
371 sci->UpdateStyle();
372 sci->NeedStyled(false);
373 }
374 tabbook->ForEachTab(TabCallbacks::StyleNextDocCB,this,false);
375 return 1;
376 }
377
378
379
onTimer(FXObject * o,FXSelector sel,void * p)380 long TopWindowBase::onTimer(FXObject*o, FXSelector sel, void*p)
381 {
382 if (prefs->WatchExternChanges) {
383 if (stale_ticks < STALECHECK) {
384 stale_ticks++;
385 } else {
386 if (getApp()->getActiveWindow() && (getApp()->getActiveWindow()->getShell()==this)) {
387 CheckStale(NULL,0,NULL);
388 }
389 }
390 }
391 if (prefs->Autosave) {
392 if (save_ticks < prefs->AutosaveInterval) {
393 save_ticks++;
394 } else {
395 save_ticks=0;
396 tabbook->ForEachTab(TabCallbacks::AutoSaveCB,backups);
397 }
398 }
399 if (prefs->Autosave||prefs->WatchExternChanges) { getApp()->addTimeout(this,ID_TIMER, ONE_SECOND, NULL); }
400 return 1;
401 }
402
403
404
onCloseWait(FXObject * o,FXSelector sel,void * p)405 long TopWindowBase::onCloseWait(FXObject*o, FXSelector sel, void*p)
406 {
407 if (FXSELTYPE(sel)==SEL_CHORE) {
408 static FXint CloseWaitChoreCount=10;
409 if (CloseWaitChoreCount>0) {
410 CloseWaitChoreCount--;
411 getApp()->addChore(this,ID_CLOSEWAIT, NULL);
412 } else {
413 CloseWaitChoreCount=10;
414 getApp()->addTimeout(this,ID_CLOSEWAIT, ONE_SECOND/10, NULL);
415 }
416 } else {
417 close();
418 }
419 return 1;
420 }
421
422
423
onFocusIn(FXObject * o,FXSelector sel,void * p)424 long TopWindowBase::onFocusIn(FXObject*o, FXSelector sel, void*p)
425 {
426 long rv=MainWinWithClipBrd::onFocusIn(o,sel,p);
427 FXWindow*mw=getApp()->getModalWindow();
428 FXWindow*mwo=mw?mw->getOwner():NULL;
429 if (mw&&(mwo!=this)) {
430 if (mwo) {
431 mw->hide();
432 mw->show();
433 }
434 mw->setFocus();
435 #ifdef FOX_1_6
436 FXWindow*dw=FXWindow::findDefault(mw);
437 #else
438 FXWindow*dw=mw->findDefault();
439 #endif
440 if (dw) { dw->setFocus(); }
441 } else {
442 FXWindow*aw=getApp()->findWindowWithId(active_widget);
443 if (aw) {
444 aw->setFocus();
445 } else if (FocusedDoc()) {
446 FocusedDoc()->setFocus();
447 }
448 }
449 return rv;
450 }
451
452
453
onFocusDoc(FXObject * o,FXSelector sel,void * p)454 long TopWindowBase::onFocusDoc(FXObject*o, FXSelector sel, void*p ) {
455 if (skipfocus) {
456 skipfocus=false;
457 } else {
458 if (getApp()->getActiveWindow()==this) {
459 SciDoc*sci=FocusedDoc();
460 if (sci) { sci->setFocus(); }
461 }
462 }
463 return 0;
464 }
465
466
467
onFocusSci(FXObject * o,FXSelector s,void * p)468 long TopWindowBase::onFocusSci(FXObject*o,FXSelector s,void*p)
469 {
470 getApp()->addChore(this, ID_CHECK_STALE);
471 if (((SciDoc*)o)->NeedStyled()) { getApp()->addChore(this, ID_CHECK_STYLE,o); }
472 active_widget=((SciDoc*)o)->id();
473 return 1;
474 }
475
476
477
SetTabDirty(SciDoc * sci,bool dirty)478 void TopWindowBase::SetTabDirty(SciDoc*sci, bool dirty)
479 {
480 DocTab*tab=(DocTab*)sci->getParent()->getPrev();
481 tab->SetIcon(dirty?DOCTAB_DIRTY:DOCTAB_CLEAN);
482 sci->Dirty(dirty);
483 }
484
485
486
SetTabLocked(SciDoc * sci,bool locked)487 void TopWindowBase::SetTabLocked(SciDoc*sci, bool locked)
488 {
489 DocTab*tab=(DocTab*)sci->getParent()->getPrev();
490 tab->SetIcon(locked?DOCTAB_LOCKED:DOCTAB_CLEAN);
491 sci->sendMessage(SCI_SETREADONLY,locked?1:0,0);
492 }
493
494
495
ShowSaveAsDlg(SciDoc * sci)496 bool TopWindowBase::ShowSaveAsDlg(SciDoc*sci)
497 {
498 FXString orig=sci->Filename();
499 if (filedlgs->SaveFileAs(sci)) {
500 if (!orig.empty()) { menubar->PrependRecentFile(orig); }
501 menubar->RemoveRecentFile(sci->Filename());
502 return true;
503 }
504 return false;
505 }
506
507
508
ShowInsertFileDlg()509 void TopWindowBase::ShowInsertFileDlg()
510 {
511 FXString* filename=NULL;
512 SciDoc*sci=FocusedDoc();
513 if (!sci->GetReadOnly()) {
514 if (filedlgs->GetOpenFilenames(sci,filename,false)&&!filename->empty()) {
515 SciDocUtils::InsertFile(sci,*filename);
516 delete[] filename;
517 }
518 }
519 sci->setFocus();
520 }
521
522
ToggleRecorder()523 void TopWindowBase::ToggleRecorder()
524 {
525 if (recording) {
526 recording=NULL;
527 } else {
528 if (!recorder) {recorder=new MacroRecorder(); }
529 recorder->clear();
530 recording=ControlDoc();
531 }
532 ControlDoc()->EnableRecorder(recording);
533 statusbar->Recording(recording);
534 menubar->Recording(recording,recorder);
535 ControlDoc()->setFocus();
536 }
537
538
539
IsMacroCancelled()540 bool TopWindowBase::IsMacroCancelled()
541 {
542 return cmdutils->IsMacroCancelled(command_timeout);
543 }
544
545
546
547 class MyCmdIO: public CmdIO {
IsCancelled()548 virtual bool IsCancelled() { return ((TopWindowBase*)win)->IsMacroCancelled(); }
549 public:
MyCmdIO(FXMainWindow * window,const char * shellcmd="/bin/sh -c")550 MyCmdIO(FXMainWindow *window, const char*shellcmd="/bin/sh -c"):CmdIO(window,shellcmd){}
551 };
552
553
554
FilterSelection(SciDoc * sci,const FXString & cmd,const FXString & input)555 bool TopWindowBase::FilterSelection(SciDoc *sci, const FXString &cmd, const FXString &input)
556 {
557 if (!cmdutils->IsCommandReady()) { return false; }
558 cmdutils->CommandBusy(true);
559 cmdutils->SetShellEnv(sci->Filename().text(),sci->GetLineNumber());
560 bool success=false;
561 if (!cmd.empty()) {
562 MyCmdIO cmdio(this, prefs->ShellCommand.text());
563 FXString output=FXString::null;
564 command_timeout=false;
565 getApp()->beginWaitCursor();
566 statusbar->Running(_("command"));
567 cmdutils->DisableUI(true);
568 success=cmdio.filter(cmdutils->FixUpCmdLineEnv(cmd).text(), input, output);
569 if (success) {
570 sci->sendString(SCI_REPLACESEL, 0, output.text());
571 sci->ScrollWrappedInsert();
572 }
573 cmdutils->DisableUI(false);
574 statusbar->Normal();
575 getApp()->endWaitCursor();
576 }
577 sci->setFocus();
578 need_status=1;
579 cmdutils->CommandBusy(false);
580 return success;
581 }
582
583
584
RunCommand(SciDoc * sci,const FXString & cmd)585 bool TopWindowBase::RunCommand(SciDoc *sci, const FXString &cmd)
586 {
587 if (!cmdutils->IsCommandReady()) { return false; }
588 cmdutils->CommandBusy(true);
589 cmdutils->SetShellEnv(sci->Filename().text(),sci->GetLineNumber());
590 bool success=false;
591 if (!cmd.empty()) {
592 MyCmdIO cmdio(this, prefs->ShellCommand.text());
593 command_timeout=false;
594 outlist->clearItems(true);
595 update();
596 repaint();
597 if (!prefs->ShowOutputPane) { ShowOutputPane(true); }
598 statusbar->Running(_("command"));
599 success=cmdio.lines(cmdutils->FixUpCmdLineEnv(cmd).text(), outlist, outlist->ID_CMDIO, true);
600 statusbar->Normal();
601 if (success) {
602 outlist->appendItem(_("Command succeeded."));
603 } else {
604 if (command_timeout) {
605 outlist->appendItem(_("Command cancelled."));
606 } else {
607 outlist->appendItem(_("Command failed."));
608 outlist->SelectFirstError();
609 }
610 }
611 }
612 if (FocusedDoc() && (GetNetActiveWindow()==id())) { FocusedDoc()->setFocus(); }
613 need_status=1;
614 cmdutils->CommandBusy(false);
615 return success;
616 }
617
618
619
RunMacro(const FXString & script,bool isfilename)620 bool TopWindowBase::RunMacro(const FXString &script, bool isfilename)
621 {
622 if (!cmdutils->IsCommandReady()) { return false; }
623 cmdutils->CommandBusy(true);
624 MacroRunner macros;
625 command_timeout=false;
626 statusbar->Running(_("macro"));
627 update();
628 statusbar->layout();
629 getApp()->runWhileEvents();
630 bool rv=isfilename?macros.DoFile(script):macros.DoString(script);
631 getApp()->runWhileEvents();
632 if (!destroying) {
633 tabbook->ForEachTab(TabCallbacks::ResetUndoLevelCB,NULL);
634 statusbar->Normal();
635 if (FocusedDoc() && (GetNetActiveWindow()==id())) { FocusedDoc()->setFocus(); }
636 need_status=1;
637 }
638 cmdutils->CommandBusy(false);
639 return rv;
640 }
641
642
643
RunHookScript(const char * hookname)644 bool TopWindowBase::RunHookScript(const char*hookname)
645 {
646 static bool running_hook_script=false;
647 FXString hook;
648 if (running_hook_script) { return false; }
649 hook.format("%s%s%c%s%c%s.lua", ConfigDir().text(), "tools", PATHSEP, "hooks", PATHSEP, hookname);
650 if (FXStat::isFile(hook)) {
651 bool rv;
652 running_hook_script=true;
653 rv=RunMacro(hook, true);
654 running_hook_script=false;
655 return rv;
656 } else {
657 return true;
658 }
659 }
660
661
662
FileSaved(SciDoc * saved)663 void TopWindowBase::FileSaved(SciDoc* saved)
664 {
665 SciDoc *active=ControlDoc();
666 FXStat st;
667 if ( FXStat::stat(save_hook,st) && (st.size()>0) && st.isFile() ) {
668 if (active!=saved) {
669 tabbook->ActivateTab((DocTab*)(saved->getParent()->getPrev()));
670 }
671 RunHookScript("saved");
672 if ( TabCallbacks::IsDocValid(active,tabbook) && (active!=saved) ) {
673 tabbook->ActivateTab((DocTab*)(active->getParent()->getPrev()));
674 }
675 }
676 }
677
678
679
AskReload()680 void TopWindowBase::AskReload()
681 {
682 SciDoc*sci=ControlDoc();
683 if (sci->Filename().empty()) {
684 FXMessageBox::error(this,MBOX_OK,_("Unamed file"), _("File has no name, can't reload."));
685 return;
686 }
687 if (!sci->Dirty()) {
688 if ( FXMessageBox::question(this, MBOX_YES_NO, _("Reload file"),
689 _("Reload current document?") ) != MBOX_CLICKED_YES ) { return; }
690 }
691 filedlgs->AskReload(sci);
692 }
693
694
695
AddFileToTagsMenu(const FXString & filename)696 void TopWindowBase::AddFileToTagsMenu(const FXString &filename)
697 {
698 menubar->AddFileToTagsList(filename);
699 }
700
701
702
RemoveFileFromTagsMenu(const FXString & filename)703 bool TopWindowBase::RemoveFileFromTagsMenu(const FXString &filename)
704 {
705 return menubar->RemoveFileFromTagsList(filename);
706 }
707
708
709
SetLanguage(FXMenuRadio * mnu)710 bool TopWindowBase::SetLanguage(FXMenuRadio *mnu)
711 {
712 if (mnu) {
713 LangStyle*ls=(LangStyle*) mnu->getUserData();
714 SciDoc*sci=ControlDoc();
715 sci->setLanguage(ls);
716 menubar->SetLanguageCheckmark(ls);
717 return true;
718 } else { return false; }
719 }
720
721
722
SetLanguage(const FXString & name)723 bool TopWindowBase::SetLanguage(const FXString &name)
724 {
725 return SetLanguage(menubar->GetMenuForLanguage(name));
726 }
727
728
729
AddOutput(const FXString & line)730 void TopWindowBase::AddOutput(const FXString&line)
731 {
732 outlist->appendItem(line.text());
733 }
734
735
736
ClearOutput()737 void TopWindowBase::ClearOutput()
738 {
739 outlist->clearItems();
740 }
741
742
743
TagFiles()744 FXMenuCaption*TopWindowBase::TagFiles() {
745 return (FXMenuCaption*)(menubar->TagsMenu()->getMenu()->getFirst());
746 }
747
748
749
SetKillCommandAccelKey(FXHotKey acckey)750 void TopWindowBase::SetKillCommandAccelKey(FXHotKey acckey)
751 {
752 cmdutils->SetKillCommandAccelKey(acckey);
753 }
754
755
756
SaveAll(bool break_on_fail)757 bool TopWindowBase::SaveAll(bool break_on_fail)
758 {
759 DocTab*curr=tabbook->ActiveTab();
760 FXWindow*tab,*page;
761 bool success=true;
762 for (tab=tabbook->getFirst(); tab && (page=tab->getNext()); tab=page->getNext()) {
763 SciDoc*sci=(SciDoc*)page->getFirst();
764 if (sci->Dirty()) {
765 if (sci->Filename().empty() ) {
766 tabbook->ActivateTab((DocTab*)tab);
767 }
768 if (!filedlgs->SaveFile(sci,sci->Filename())) {
769 if (break_on_fail) { return false; } else { success=false; }
770 }
771 }
772 }
773 if (curr!=tabbook->ActiveTab()) { tabbook->ActivateTab((curr)); }
774 return success;
775 }
776
777
778
779 // Tell the window manager we want the focus back after dialogs close...
ClosedDialog()780 void TopWindowBase::ClosedDialog()
781 {
782 setFocus();
783 FocusedDoc()->setFocus();
784 }
785
786
787
AvoidMultiLineCommand(TopWindowBase * w,const FXString & cmd)788 static bool AvoidMultiLineCommand(TopWindowBase*w, const FXString &cmd)
789 {
790 if (cmd.contains('\n')) {
791 FXMessageBox::error(w, MBOX_OK, _("Command Error"),
792 _("Multiline commands are not supported."));
793 return false;
794 } else {
795 return true;
796 }
797 }
798
799
800
ShowFilterDialog(bool is_filter)801 void TopWindowBase::ShowFilterDialog(bool is_filter)
802 {
803 SciDoc *sci=FocusedDoc();
804 HistBox *dlg;
805 bool save_first;
806 if(is_filter) {
807 dlg=new HistBox(this, _("Filter selection"), _("Command:"), "Filters");
808 save_first=prefs->SaveBeforeFilterSel;
809 } else {
810 dlg=new HistBox(this, _("Insert output of command"), _("Command:"), "InsertOutput");
811 save_first=prefs->SaveBeforeInsCmd;
812 }
813 dlg->setNumColumns(48);
814 if ( dlg->execute(PLACEMENT_OWNER) ) {
815 FXString cmd=dlg->getText();
816 if (AvoidMultiLineCommand(this, cmd)) {
817 if ( (!save_first) || SaveAll(true) ) {
818 FXString input="";
819 if (is_filter) { sci->GetSelText(input); }
820 FilterSelection(sci, cmd, input);
821 }
822 }
823 }
824 delete dlg;
825 ClosedDialog();
826 }
827
828
829
ShowCommandDialog()830 void TopWindowBase::ShowCommandDialog()
831 {
832 SciDoc *sci=FocusedDoc();
833 HistBox dlg(this, _("Run command"), _("Command:"), "Commands");
834 dlg.setNumColumns(48);
835 if ( dlg.execute(PLACEMENT_OWNER) ) {
836 FXString cmd=dlg.getText();
837 if (AvoidMultiLineCommand(this,cmd)) {
838 if ( (!prefs->SaveBeforeExecCmd) || SaveAll(true) ) {
839 ClosedDialog();
840 RunCommand(sci,cmd);
841 }
842 }
843 } else {
844 ClosedDialog();
845 }
846 }
847
848
849
850
SetBookmark()851 void TopWindowBase::SetBookmark()
852 {
853 SciDoc*sci=ControlDoc();
854 bookmarked_file=sci->Filename();
855 bookmarked_tab=tabbook->ActiveTab();
856 bookmarked_pos=sci->GetCaretPos();
857 }
858
859
SetReadOnly(SciDoc * sci,bool rdonly)860 bool TopWindowBase::SetReadOnly(SciDoc*sci, bool rdonly)
861 {
862 if (!sci) { return false; }
863 if (rdonly && sci->Dirty()) {
864 FXMessageBox::error(this, MBOX_OK, _("Unsaved changes"),
865 _("Cannot mark a modified document as read-only.\n"
866 "You should save or undo your changes first.")
867 );
868 return false;
869 }
870 SetTabLocked(sci,rdonly);
871 menubar->SetReadOnlyCheckmark(rdonly);
872 need_status=32;
873 return true;
874 }
875
876
EnableUserFilters(bool enabled)877 void TopWindowBase::EnableUserFilters(bool enabled)
878 {
879 toolbar->EnableFilterBtn(enabled);
880 menubar->EnableFilterMenu(enabled);
881 srchdlgs->setHaveSelection(enabled);
882 }
883
884
885
RemoveTBarBtnData(void * p)886 void TopWindowBase::RemoveTBarBtnData(void*p)
887 {
888 toolbar->NullifyButtonData(p);
889 }
890
891
892 // Exposes "userland" search behavior to scripting engine.
FindText(const char * searchfor,FXuint searchmode,bool forward)893 void TopWindowBase::FindText(const char*searchfor, FXuint searchmode, bool forward)
894 {
895 srchdlgs->FindPhrase(searchfor,searchmode,forward);
896 }
897
898
899
FindAndReplace(const char * searchfor,const char * replacewith,FXuint searchmode,bool forward)900 void TopWindowBase::FindAndReplace(const char*searchfor, const char*replacewith, FXuint searchmode, bool forward)
901 {
902 srchdlgs->FindAndReplace(searchfor, replacewith, searchmode, forward);
903 }
904
905
906
ReplaceAllInSelection(const char * searchfor,const char * replacewith,FXuint searchmode)907 void TopWindowBase::ReplaceAllInSelection(const char*searchfor, const char*replacewith, FXuint searchmode)
908 {
909 srchdlgs->ReplaceAllInSelection(searchfor, replacewith, searchmode);
910 }
911
912
913
ReplaceAllInDocument(const char * searchfor,const char * replacewith,FXuint searchmode)914 void TopWindowBase::ReplaceAllInDocument(const char*searchfor, const char*replacewith, FXuint searchmode)
915 {
916 srchdlgs->ReplaceAllInDocument(searchfor, replacewith, searchmode);
917 }
918
919
920
UserMenus() const921 UserMenu**TopWindowBase::UserMenus() const
922 {
923 return menubar->UserMenus();
924 }
925
926
927
AdjustIndent(SciDoc * sci,char ch)928 void TopWindowBase::AdjustIndent(SciDoc*sci, char ch)
929 {
930 SciDocUtils::AdjustIndent(sci, ch, (Settings*)prefs, recording);
931 }
932
933
934
OpenSelected()935 void TopWindowBase::OpenSelected()
936 {
937 SciDocUtils::OpenSelected(this, FocusedDoc());
938 }
939
940
941
942 // Create a new tab and editor panel
OpenFile(const char * filename,const char * rowcol,bool readonly,bool hooked)943 bool TopWindowBase::OpenFile(const char*filename, const char*rowcol, bool readonly, bool hooked)
944 {
945 if (Closing()) return false;
946 FXString fn="";
947 SciDoc*sci=NULL;
948 if ( tabbook->Count() >= prefs->MaxFiles ) { return false; }
949 if (filename) {
950 fn=FXPath::simplify(FXPath::absolute(filename));
951 #ifdef WIN32
952 FileDialogs::ReadShortcut(this,fn);
953 #endif
954 if (IsFileOpen(fn,true)) {
955 if (rowcol && *rowcol) { ControlDoc()->GoToStringCoords(rowcol); }
956 if (hooked) { RunHookScript("opened"); }
957 return true;
958 }
959 }
960 if (!FileDialogs::FileExistsOrConfirmCreate(this,fn)) { return false; }
961 DocTab*tab=tabbook->NewTab(fn.empty()?_("Untitled"):FXPath::name(fn));
962 sci=SciDocUtils::NewSci((FXComposite*)tab->getNext(),this,(Settings*)prefs);
963 if (!fn.empty()) {
964 if (!sci->LoadFromFile(fn.text())) {
965 if (!sci->GetLastError().contains(SciDoc::BinaryFileMessage())) {
966 FXMessageBox::error(this, MBOX_OK, _("Error opening file"), "%s:\n%s\n%s",
967 _("Could not open file"), fn.text(), sci->GetLastError().text());
968 }
969 SciDocUtils::DoneSci(sci,recording);
970 return false;
971 }
972 if (!sci->SetLanguageForHeader(fn)) {
973 if (!sci->setLanguageFromFileName(FXPath::name(fn).text())) {
974 sci->setLanguageFromContent();
975 }
976 }
977 } else {
978 sci->SetUTF8(!prefs->DefaultToAscii);
979 sci->UpdateStyle();
980 }
981 SetTabLocked(sci,readonly);
982 tabbook->ActivateTab(tabbook->Count()-1);
983 menubar->AppendDocList(sci->Filename(), tab);
984 if (shown()) {
985 sci->create();
986 if (rowcol && *rowcol) { sci->GoToStringCoords(rowcol); }
987 }
988
989 // If the only thing we had open prior to this file was a single,
990 // empty, untitled, unmodified document, then close it...
991 if ((tabbook->Count()==2) && (!sci->Filename().empty())) {
992 SciDoc*sc0=(SciDoc*)(tabbook->PageAt(0)->getFirst());
993 if ( sc0->Filename().empty() && (sc0->GetTextLength()==0) && (sc0->Dirty()==false) ) {
994 tabbook->ActivateTab(0);
995 CloseFile(false,false);
996 }
997 }
998 sci->setFocus();
999 sci->NeedStyled(true);
1000 getApp()->addChore(this, ID_CHECK_STYLE, sci);
1001 if (hooked) { RunHookScript("opened"); }
1002 return true;
1003 }
1004
1005
1006
NewFile(bool hooked)1007 bool TopWindowBase::NewFile(bool hooked)
1008 {
1009 return OpenFile(NULL,NULL,false,hooked);
1010 }
1011
1012
1013
CloseFile(bool close_last,bool hooked)1014 bool TopWindowBase::CloseFile(bool close_last, bool hooked)
1015 {
1016 FXint i=tabbook->getCurrent();
1017 DocTab*tab=tabbook->ActiveTab();
1018 SciDoc*sci=ControlDoc();
1019 if (!filedlgs->TryClose(sci,tab->getText().text())) { return false; }
1020 menubar->PrependRecentFile(sci->Filename());
1021 if (hooked) { RunHookScript("closing"); }
1022 if (close_last) {
1023 if (!sci->Filename().empty()) {
1024 FXString line;
1025 line.format("-%c\n+%ld,%ld\n%s\n", sci->GetReadOnly()?'r':'w',
1026 sci->GetLineNumber()+1, sci->GetColumnNumber(), sci->Filename().text());
1027 session_data.append(line);
1028 }
1029 }
1030 backups->RemoveBackup(sci);
1031 if (tabbook->numChildren()==2) {
1032 if (!close_last) { NewFile(false); }
1033 SciDocUtils::DoneSci(sci,recording);
1034 } else {
1035 SciDocUtils::DoneSci(sci,recording);
1036 tabbook->ActivateTab( tabbook->childAtIndex(i*2) ? i : i-1 );
1037 }
1038 need_status=1;
1039 return true;
1040 }
1041
1042
1043
CloseAll(bool close_last)1044 bool TopWindowBase::CloseAll(bool close_last)
1045 {
1046 bool rv;
1047 do {
1048 tabbook->ActivateTab(0);
1049 } while ((tabbook->numChildren()>0) && CloseFile(true,true));
1050 rv=tabbook->numChildren()==0;
1051 if (!close_last) { NewFile(false); }
1052 return rv;
1053 }
1054
1055
1056
ChangeCase(bool to_upper)1057 void TopWindowBase::ChangeCase(bool to_upper)
1058 {
1059 SciDoc*sci=FocusedDoc();
1060 if (sci->GetSelLength()==0) { return; }
1061 if (to_upper) { sci->SelectionToUpper(); } else { sci->SelectionToLower(); }
1062 if (recording==sci) { recorder->record(to_upper?SCI_UPPERCASE:SCI_LOWERCASE,0,0); }
1063 }
1064
1065
1066
FindTag()1067 void TopWindowBase::FindTag()
1068 {
1069 FXString filename;
1070 FXString locn;
1071 FXString pattern;
1072 if ( !TagHandler::FindTag(FocusedDoc(), TagFiles(), filename, locn, pattern) ) { return; }
1073 if ( filename.empty()) { return; }
1074 if (OpenFile(filename.text(), locn.text(),false,true)) {
1075 if (locn.empty()) { TagHandler::GoToTag(ControlDoc(),pattern); }
1076 }
1077 }
1078
1079
1080
GoToBookmark()1081 void TopWindowBase::GoToBookmark()
1082 {
1083 if (!bookmarked_file.empty()) {
1084 if (OpenFile(bookmarked_file.text(),NULL,false,false)) {
1085 FocusedDoc()->GoToPos(bookmarked_pos);
1086 }
1087 } else {
1088 tabbook->ForEachTab(TabCallbacks::BookmarkCB,this);
1089 }
1090 }
1091
1092
1093
FoundBookmarkedTab(DocTab * tab)1094 bool TopWindowBase::FoundBookmarkedTab(DocTab*tab)
1095 {
1096 if (bookmarked_tab == tab) {
1097 tabbook->ActivateTab(tab);
1098 FocusedDoc()->GoToPos(bookmarked_pos);
1099 return true;
1100 }
1101 return false;
1102 }
1103
1104
1105
UpdateToolbar()1106 void TopWindowBase::UpdateToolbar()
1107 {
1108 toolbar->CreateButtons((TopWindow*)this);
1109 menubar->UpdateDocTabSettings();
1110 menubar->Recording(recording,recorder);
1111 toolbar->EnableFilterBtn(FocusedDoc()&&(FocusedDoc()->GetSelLength()>0));
1112 }
1113
1114
1115
ShowPrefsDialog()1116 void TopWindowBase::ShowPrefsDialog()
1117 {
1118 PrefsDialog*prefdlg=new PrefsDialog(this, (Settings*)prefs);
1119 prefdlg->execute(PLACEMENT_DEFAULT);
1120 delete prefdlg;
1121 ClosedDialog();
1122 srchdlgs->SetPrefs(prefs->SearchOptions,prefs->SearchWrap,prefs->SearchVerbose,prefs->SearchGui);
1123 tabbook->MaxTabWidth(prefs->TabTitleMaxWidth);
1124 tabbook->ForEachTab(TabCallbacks::PrefsCB, NULL);
1125 CheckStyle(NULL,0,ControlDoc());
1126 if ((prefs->WatchExternChanges||prefs->Autosave) && !getApp()->hasTimeout(this,ID_TIMER)) {
1127 getApp()->addTimeout(this,ID_TIMER, ONE_SECOND, NULL);
1128 }
1129 getApp()->setWheelLines(prefs->WheelLines);
1130 if ( PrefsDialog::ChangedToolbar() & ToolbarChangedLayout ) {
1131 UpdateToolbar();
1132 }
1133 if ( PrefsDialog::ChangedToolbar() & ToolbarChangedWrap ) {
1134 toolbar->handle(toolbar,FXSEL(SEL_CONFIGURE,0),NULL);
1135 }
1136 if ( PrefsDialog::ChangedToolbar() & ToolbarChangedFont ) {
1137 toolbar->SetTBarFont();
1138 }
1139 if (Theme::changed() & ThemeChangedColors) {
1140 Theme::apply(this);
1141 Theme::apply(srchdlgs->FindDialog());
1142 tips->setBackColor(getApp()->getTipbackColor());
1143 tips->setTextColor(getApp()->getTipforeColor());
1144 statusbar->Colorize();
1145 }
1146 tabbook->ActivateTab(tabbook->ActiveTab());
1147 toolbar->SetToolbarColors();
1148 EnableUserFilters(FocusedDoc()->GetSelLength());
1149 }
1150
1151
1152
1153
ShowToolManagerDialog()1154 void TopWindowBase::ShowToolManagerDialog()
1155 {
1156 ToolsDialog tooldlg(this,UserMenus());
1157 tooldlg.execute(PLACEMENT_SCREEN);
1158 RescanUserMenu();
1159 ClosedDialog();
1160 }
1161
1162
1163
RescanUserMenu()1164 void TopWindowBase::RescanUserMenu()
1165 {
1166 menubar->RescanUserMenus();
1167 MenuMgr::PurgeTBarCmds();
1168 UpdateToolbar();
1169 }
1170
1171
1172
ParseCommands(FXString & commands)1173 void TopWindowBase::ParseCommands(FXString &commands)
1174 {
1175 FXString sect="";
1176 FXString rowcol="";
1177 FXRex rx_rowcol(":\\d+$",REX_CAPTURE);
1178 FXchar rw='w';
1179 bool tagopt=false;
1180 bool macopt=false;
1181 bool session_restored=false;
1182 bool quiet=((compare(commands,"-q\n",2)==0) || (commands.contains("\n-q\n")));
1183 int i=0;
1184 while (1) {
1185 sect=commands.section('\n',i++);
1186 if (sect.empty()) { break; }
1187 switch (sect.text()[0]) {
1188 case '+': {
1189 rowcol=sect.text();
1190 break;
1191 }
1192 case '-': {
1193 switch (sect.text()[1]) {
1194 case 'r':
1195 case 'w': {
1196 rw=sect.text()[1];
1197 break;
1198 }
1199 case 't': {
1200 tagopt=true;
1201 break;
1202 }
1203 case 'e': {
1204 macopt=true;
1205 break;
1206 }
1207 case 'p' : {
1208 if (!session_restored) {
1209 session_restored=true;
1210 FXString sessionname;
1211 FXFile fh(SessionFile(), FXIO::Reading);
1212 if (fh.isOpen()) {
1213 session_data.length(fh.size());
1214 fh.readBlock((void*)(session_data.text()),fh.size());
1215 fh.close();
1216 ParseCommands(session_data);
1217 if (!prefs->LastFocused.empty()) {
1218 if (FXStat::isFile(prefs->LastFocused)) {
1219 IsFileOpen(prefs->LastFocused,true);
1220 }
1221 }
1222 }
1223 }
1224 break;
1225 }
1226 case 'q' : {
1227 break; // "quiet" option is invalid for a new instance, so just ignore it.
1228 }
1229 default: fprintf(stderr, _("Warning: unrecognized option: %s\n"), sect.text());
1230 }
1231 break;
1232 }
1233 default: {
1234 if (tagopt) {
1235 AddFileToTagsMenu(sect);
1236 tagopt=false;
1237 } else {
1238 if (macopt) {
1239 macopt=false;
1240 if (tabbook->numChildren()==0) { /* Be sure we have a document before running a macro */
1241 NewFile(false);
1242 RunMacro(sect,false);
1243 if (tabbook->numChildren()==2) {
1244 SciDoc*sci=ControlDoc();
1245 if ( (sci->Filename().empty()) && (sci->GetTextLength()==0) && (!sci->Dirty()) ) {
1246 CloseFile(true,false); /* Forget this document if it wasn't changed */
1247 }
1248 }
1249 } else {
1250 RunMacro(sect,false);
1251 }
1252 } else {
1253 FXString filename=sect.text();
1254 if (rowcol.empty()) {
1255 FXint beg,end;
1256 #ifdef FOX_1_7_50_OR_NEWER
1257 if (rx_rowcol.search(filename,0,filename.length(),Normal,&beg,&end,1)>=0)
1258 #else
1259 if (rx_rowcol.match(filename,&beg,&end))
1260 #endif
1261 {
1262 if (!FXStat::isFile(filename)) {
1263 rowcol=filename.mid(beg,end-beg).text();
1264 filename=filename.left(beg).text();
1265 if (!FXStat::isFile(filename)) {
1266 rowcol="";
1267 filename=sect.text();
1268 }
1269 }
1270 }
1271 }
1272 OpenFile(filename.text(), rowcol.empty()?NULL:(rowcol.text())+1, rw=='r',true);
1273 rowcol="";
1274 }
1275 }
1276 }
1277 }
1278 }
1279 commands=FXString::null;
1280 if (tabbook->numChildren()==0) { NewFile(false); }
1281 if (!quiet) { WaitForWindowFocus(this); }
1282 }
1283
1284
1285
UpdateTitle(long line,long col)1286 void TopWindowBase::UpdateTitle(long line, long col)
1287 {
1288 SciDoc*sci=ControlDoc();
1289 if (sci) {
1290 DocTab *tab=tabbook->ActiveTab();
1291 FXString s;
1292 s.format("%s%s %s - %s", sci->Dirty()?"*":"", tab->getText().text(), FXPath::directory(sci->Filename()).text(), EXE_NAME);
1293 setTitle(s);
1294 menubar->SetLanguageCheckmark(sci->getLanguage());
1295 menubar->SetReadOnlyCheckmark(sci->sendMessage(SCI_GETREADONLY,0,0));
1296 menubar->SetWordWrapCheckmark(sci->GetWordWrap());
1297 statusbar->FileInfo(sci->Filename(),sci->GetEncoding(),line,col);
1298 MenuMgr::UpdateEolMenu(sci);
1299 } else {
1300 setTitle(EXE_NAME);
1301 statusbar->Clear();
1302 }
1303 }
1304
1305
1306
ShowLineNumbers(bool showit)1307 void TopWindowBase::ShowLineNumbers(bool showit)
1308 {
1309 prefs->ShowLineNumbers=showit;
1310 tabbook->ForEachTab(TabCallbacks::LineNumsCB, (void*)(FXival)showit);
1311 menubar->SyncPrefsCheckmarks();
1312 }
1313
1314
1315
ShowStatusBar(bool showit)1316 void TopWindowBase::ShowStatusBar(bool showit)
1317 {
1318 prefs->ShowStatusBar=showit;
1319 statusbar->Show(showit);
1320 menubar->SyncPrefsCheckmarks();
1321 }
1322
1323
1324
ShowOutputPane(bool showit)1325 void TopWindowBase::ShowOutputPane(bool showit)
1326 {
1327 prefs->ShowOutputPane=showit;
1328 if (showit) {
1329 if (prefs->OutputPaneHeight<16) { prefs->OutputPaneHeight=16; }
1330 hsplit->setSplit(1, prefs->OutputPaneHeight);
1331 outlist->show();
1332 } else {
1333 outlist->hide();
1334 hsplit->setSplit(1,0);
1335 }
1336 menubar->SyncPrefsCheckmarks();
1337 }
1338
1339
1340
ShowWhiteSpace(bool showit)1341 void TopWindowBase::ShowWhiteSpace(bool showit)
1342 {
1343 prefs->ShowWhiteSpace=showit;
1344 tabbook->ForEachTab(TabCallbacks::WhiteSpaceCB, (void*)(FXival)showit);
1345 menubar->SyncPrefsCheckmarks();
1346 }
1347
1348
1349
ShowToolbar(bool showit)1350 void TopWindowBase::ShowToolbar(bool showit)
1351 {
1352 prefs->ShowToolbar=showit;
1353 if (showit) { toolbar->show(); } else { toolbar->hide(); }
1354 menubar->SyncPrefsCheckmarks();
1355 }
1356
1357
1358
ShowMargin(bool showit)1359 void TopWindowBase::ShowMargin(bool showit)
1360 {
1361 prefs->ShowRightEdge = showit;
1362 tabbook->ForEachTab(TabCallbacks::ShowMarginCB, (void*)(FXival)showit);
1363 menubar->SyncPrefsCheckmarks();
1364 }
1365
1366
1367
ShowIndent(bool showit)1368 void TopWindowBase::ShowIndent(bool showit)
1369 {
1370 prefs->ShowIndentGuides = showit;
1371 tabbook->ForEachTab(TabCallbacks::ShowIndentCB, (void*)(FXival)showit);
1372 menubar->SyncPrefsCheckmarks();
1373 }
1374
1375
1376
ShowCaretLine(bool showit)1377 void TopWindowBase::ShowCaretLine(bool showit)
1378 {
1379 prefs->ShowCaretLine = showit;
1380 tabbook->ForEachTab(TabCallbacks::ShowCaretLineCB, (void*)prefs);
1381 menubar->SyncPrefsCheckmarks();
1382 }
1383
1384
1385
SetWordWrap(SciDoc * sci,bool wrapped)1386 void TopWindowBase::SetWordWrap(SciDoc*sci, bool wrapped)
1387 {
1388 sci->SetWordWrap(wrapped);
1389 menubar->SetWordWrapCheckmark(wrapped);
1390 }
1391
1392
1393
InvertColors(bool inverted)1394 void TopWindowBase::InvertColors(bool inverted)
1395 {
1396 prefs->InvertColors=inverted;
1397 toolbar->SetToolbarColors();
1398 tabbook->ForEachTab(TabCallbacks::PrefsCB,NULL);
1399 CheckStyle(NULL,0,ControlDoc());
1400 menubar->SyncPrefsCheckmarks();
1401 }
1402
1403
1404
1405 // Returns: 0=File not open; 1=File open and clean; 2=File open and dirty;
IsFileOpen(const FXString & filename,bool activate)1406 int TopWindowBase::IsFileOpen(const FXString &filename, bool activate)
1407 {
1408 void*userdata[3]={(void*)&filename,&activate,NULL};
1409 tabbook->ForEachTab(TabCallbacks::FileAlreadyOpenCB,userdata);
1410 SciDoc*sci=(SciDoc*)userdata[2];
1411 return sci?sci->Dirty()?2:1:0;
1412 }
1413
1414
1415
1416 // Caller should delete[] result when done!
NamedFiles() const1417 FXString* TopWindowBase::NamedFiles() const
1418 {
1419 FXint n=tabbook->Count();
1420 FXString *list=new FXString[n+1];
1421 for (FXint i=0; i<=n; i++) { list[i]=FXString::null; }
1422 tabbook->ForEachTab(TabCallbacks::NamedFilesCB,list);
1423 return list;
1424 }
1425
1426
1427
1428