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 #include <fx.h>
20 #include "doctabs.h"
21 #include "scidoc.h"
22 #include "backup.h"
23 #include "prefs.h"
24 #include "appwin.h"
25 
26 #include "foreachtab.h"
27 
28 
29 // Check each document to see if any of them should be auto-saved.
AutoSaveCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)30 bool TabCallbacks::AutoSaveCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
31 {
32   SciDoc*sci=(SciDoc*)page->getFirst();
33   if (sci->NeedBackup()) {
34     ((BackupMgr*)user_data)->SaveBackup(sci);
35   }
36   return true;
37 }
38 
39 
40 /* Zoom each document In/Out/Close/Far/Default */
ZoomStepCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)41 bool TabCallbacks::ZoomStepCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
42 {
43   SciDoc*sci=(SciDoc*)page->getFirst();
44   sci->ZoomStep(*((int*)user_data));
45   return true;
46 }
47 
48 
49 
50 /* Zoom each document to a specified amount (Used by Lua) */
ZoomSpecCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)51 bool TabCallbacks::ZoomSpecCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
52 {
53   SciDoc*sci=(SciDoc*)page->getFirst();
54   sci->SetZoom(*((int*)user_data));
55   return true;
56 }
57 
58 
59 
SetZoom(SciDoc * sci,FXSelector sel,void * p,DocTabs * tabbook,Settings * prefs)60 void TabCallbacks::SetZoom(SciDoc*sci, FXSelector sel, void*p, DocTabs*tabbook, Settings*prefs)
61 {
62   FXival z;
63   if (sel) {
64     switch (FXSELID(sel)) {
65       case TopWindow::ID_ZOOM_IN:   { z =  1;  break; }
66       case TopWindow::ID_ZOOM_OUT:  { z = -1; break; }
67       case TopWindow::ID_ZOOM_FAR:  { z = -2; break; }
68       case TopWindow::ID_ZOOM_NEAR: { z =  2;  break; }
69       case TopWindow::ID_ZOOM_NONE: { z =  0;  break; }
70     }
71     tabbook->ForEachTab(ZoomStepCB, &z);
72   } else {
73     z=(FXival)p;
74    tabbook->ForEachTab(ZoomSpecCB, &z);
75   }
76   prefs->ZoomFactor=sci->GetZoom();
77 }
78 
79 
80 
LineNumsCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)81 bool TabCallbacks::LineNumsCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
82 {
83   SciDoc*sci=(SciDoc*)page->getFirst();
84   sci->ShowLineNumbers((bool)user_data);
85   return true;
86 }
87 
88 
89 
WhiteSpaceCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)90 bool TabCallbacks::WhiteSpaceCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
91 {
92   SciDoc*sci=(SciDoc*)page->getFirst();
93   sci->ShowWhiteSpace((bool)user_data);
94   return true;
95 }
96 
97 
98 
ShowMarginCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)99 bool TabCallbacks::ShowMarginCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
100 {
101   for (SciDoc*sci=(SciDoc*)page->getFirst(); sci; sci=(SciDoc*)sci->getNext()) {
102     sci->SetShowEdge((bool)user_data);
103   }
104   return true;
105 }
106 
107 
108 
ShowIndentCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)109 bool TabCallbacks::ShowIndentCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
110 {
111   for (SciDoc*sci=(SciDoc*)page->getFirst(); sci; sci=(SciDoc*)sci->getNext()) {
112     sci->SetShowIndent((bool)user_data);
113   }
114   return true;
115 }
116 
117 
118 
ShowCaretLineCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)119 bool TabCallbacks::ShowCaretLineCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
120 {
121   Settings*p=(Settings*)user_data;
122   for (SciDoc*sci=(SciDoc*)page->getFirst(); sci; sci=(SciDoc*)sci->getNext()) {
123     sci->CaretLineBG(p->ShowCaretLine?p->CaretLineBG():NULL);
124   }
125   return true;
126 }
127 
128 
129 
130 /* Mark all open documents as needing their settings updated. */
PrefsCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)131 bool TabCallbacks::PrefsCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
132 {
133   ((SciDoc*)page->getFirst())->NeedStyled(true);
134   return true;
135 }
136 
137 
138 
139 /*
140   For each tab callback to add a chore to update the settings of the first
141   document it finds that needs updating -
142   CheckStyle() invokes this callback, and in turn, this callback adds a chore
143   that invokes CheckStyle(). This exchange continues until all documents have
144   had their settings updated.
145 */
StyleNextDocCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)146 bool TabCallbacks::StyleNextDocCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
147 {
148   SciDoc*sci=(SciDoc*)page->getFirst();
149   if (sci->NeedStyled()) {
150     TopWindow*tw=(TopWindow*)user_data;
151     tw->getApp()->addChore(tw, TopWindow::ID_CHECK_STYLE, sci);
152     return false;
153   }
154   return true;
155 }
156 
157 
158 
159 /*
160   ForEachTab callback that checks to see if a file is already open.
161   The user_data is an array of 3 pointers:
162      { FXString*filename, bool*activate, SciDoc*sci=NULL }
163   If we find the document, we set the NULL SciDoc* to the
164   found document and (optionally) activate that tab.
165   .
166 */
FileAlreadyOpenCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)167 bool TabCallbacks::FileAlreadyOpenCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
168 {
169   void**p=(void**)user_data;
170   FXString*filename=(FXString*)p[0];
171   bool activate=*((bool*)p[1]);
172   SciDoc*sci=(SciDoc*)page->getFirst();
173   if (FX::compare(sci->Filename(),*filename)==0) {
174     DocTabs*tabbook=(DocTabs*)tab->getParent();
175     if (activate) { tabbook->ActivateTab(index); }
176     p[2]=sci;
177     return false;
178   }
179   return true;
180 }
181 
182 
183 
184 /*
185   ForEachTab callback that checks to see if a file is still open
186   If we find the document, then we set the SciDoc** pointed to
187   by the user_data to NULL as a sign that we found it.
188 */
FileStillOpenCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)189 bool TabCallbacks::FileStillOpenCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
190 {
191   SciDoc**sci=(SciDoc**)user_data;
192   if (*sci==page->getFirst()) {
193     *sci=NULL;
194     return false;
195   }
196   return true;
197 }
198 
199 
200 
201 // In case a Lua script left the SCI_*UNDOACTION level in an unbalanced state.
ResetUndoLevelCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)202 bool TabCallbacks::ResetUndoLevelCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
203 {
204   ((SciDoc*)(page->getFirst()))->SetUserUndoLevel(0);
205   return true;
206 }
207 
208 
209 
BookmarkCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)210 bool TabCallbacks::BookmarkCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
211 {
212   TopWindow*tw=(TopWindow*)user_data;
213   return !tw->FoundBookmarkedTab(tab);
214 }
215 
216 
217 
218 /* Return true if the document is still open */
IsDocValid(SciDoc * sci,DocTabs * tabbook)219 bool TabCallbacks::IsDocValid(SciDoc*sci, DocTabs*tabbook)
220 {
221   if (sci) {
222     SciDoc*closed=sci;
223     tabbook->ForEachTab(FileStillOpenCB,&closed);
224     return (!closed);
225   } else {
226     return false;
227   }
228 }
229 
230 
231 
NamedFilesCB(FXint index,DocTab * tab,FXWindow * page,void * user_data)232 bool TabCallbacks::NamedFilesCB(FXint index, DocTab*tab, FXWindow*page, void*user_data)
233 {
234   const FXString filename=((SciDoc*)(page->getFirst()))->Filename();
235   if (!filename.empty()) {
236     FXString*p=(FXString*)user_data;
237     while (!p->empty()) { p++; }
238     *p=filename;
239   }
240   return true;
241 }
242