1 
2 #include "tab2space.h"
3 
4 #include <sdk.h>
5 #ifndef CB_PRECOMP
6     #include <wx/tokenzr.h>
7 
8     #include <cbeditor.h>
9     #include <cbproject.h>
10     #include <cbstyledtextctrl.h>
11     #include <editormanager.h>
12     #include <logmanager.h>
13     #include <projectmanager.h>
14 #endif
15 #include <set>
16 
17 #include "fortranfileext.h"
18 #include "textcutter.h"
19 
20 extern FortranFileExt g_FortranFileExt;
21 
22 //(*InternalHeaders(Tab2Space)
23 #include <wx/xrc/xmlres.h>
24 //*)
25 
26 //(*IdInit(Tab2Space)
27 //*)
28 
BEGIN_EVENT_TABLE(Tab2Space,wxScrollingDialog)29 BEGIN_EVENT_TABLE(Tab2Space,wxScrollingDialog)
30 	//(*EventTable(Tab2Space)
31 	//*)
32 	EVT_BUTTON  (wxID_OK,   Tab2Space::OnOK)
33 END_EVENT_TABLE()
34 
35 Tab2Space::Tab2Space(wxWindow* parent)
36 {
37 	//(*Initialize(Tab2Space)
38 	wxXmlResource::Get()->LoadObject(this,parent,_T("Tab2Space"),_T("wxScrollingDialog"));
39 	StaticText1 = (wxStaticText*)FindWindow(XRCID("ID_STATICTEXT1"));
40 	rb_ChCActiveProject = (wxRadioButton*)FindWindow(XRCID("ID_CHCACTIVEPROJECT"));
41 	rb_ChCCurrentFile = (wxRadioButton*)FindWindow(XRCID("ID_CHCCURRENTFILE"));
42 	rb_ChCSelection = (wxRadioButton*)FindWindow(XRCID("ID_CHCSELECTION"));
43 	StaticText2 = (wxStaticText*)FindWindow(XRCID("ID_STATICTEXT2"));
44 	sc_TabSize = (wxSpinCtrl*)FindWindow(XRCID("ID_SPINCTRL1"));
45 	//*)
46 
47 	rb_ChCCurrentFile->SetValue(true);
48 
49 	if (!Manager::Get()->GetEditorManager())
50         return;
51     cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
52     if (!ed)
53         return;
54     cbStyledTextCtrl* control = ed->GetControl();
55     if (!control)
56         return;
57     if (control->GetSelectedText().IsEmpty())
58         rb_ChCSelection->Disable();
59     else
60         rb_ChCSelection->SetValue(true);
61 
62     int tabW = control->GetTabWidth();
63     if (tabW <= 0) tabW = 4;
64 
65 	sc_TabSize->SetValue(tabW);
66 }
67 
~Tab2Space()68 Tab2Space::~Tab2Space()
69 {
70 	//(*Destroy(Tab2Space)
71 	//*)
72 }
73 
OnOK(wxCommandEvent & event)74 void Tab2Space::OnOK(wxCommandEvent& event)
75 {
76     Manager::Get()->GetLogManager()->DebugLog(_T("Tab2Space::OnOK is called"));
77 
78     Tab2SpaceIn chin;
79     if (rb_ChCActiveProject->GetValue())
80         chin = t2siProject;
81     else if (rb_ChCCurrentFile->GetValue())
82         chin = t2siFile;
83     else
84         chin = t2siSelection;
85 
86     int tabSize = sc_TabSize->GetValue();
87     if (tabSize <= 0)
88         tabSize = 4;
89 
90     MakeTab2Space(chin, tabSize);
91 
92     EndModal(wxID_OK);
93 }
94 
MakeTab2Space(Tab2SpaceIn chin,int tabSize)95 void Tab2Space::MakeTab2Space(Tab2SpaceIn chin, int tabSize)
96 {
97     if (!Manager::Get()->GetEditorManager())
98         return;
99 
100     if (chin == t2siProject)
101     {
102         cbProject* project = Manager::Get()->GetProjectManager()->GetActiveProject();
103         if (!project)
104             return;
105 
106         wxArrayString nonFFiles;
107         for (FilesList::iterator it = project->GetFilesList().begin(); it != project->GetFilesList().end(); ++it)
108         {
109             ProjectFile* pf = *it;
110             FortranSourceForm fsForm;
111             if (g_FortranFileExt.IsFileFortran(pf->file.GetFullPath(), fsForm))
112                 FileTab2Space(pf->file.GetFullPath(), chin, tabSize);
113             else
114                 nonFFiles.Add(pf->file.GetFullName());
115         }
116 
117         if (nonFFiles.size() > 0)
118         {
119             wxString mstr;
120             if (nonFFiles.size() == 1)
121             {
122                 mstr = _("File \"") + nonFFiles[0] + _("\" was not recognized as a Fortran file.");
123                 mstr << _(" The tab2space was not applied for it.");
124             }
125             else
126             {
127                 mstr = _("Files");
128                 size_t i=0;
129                 size_t imax=5;
130                 while (i < nonFFiles.size() && i < imax)
131                 {
132                     mstr << _("\n\"") << nonFFiles[i] << _T("\"");
133                     i++;
134                 }
135                 if (nonFFiles.size() > imax)
136                     mstr << _T("...\n");
137                 else
138                     mstr << _T("\n");
139                 mstr << wxString::Format(_T("(%d "), int(nonFFiles.size())) << _("files) ");
140                 mstr << _("were not recognized as the Fortran files.");
141                 mstr << _(" The tab2space was not applied for them.");
142                 cbMessageBox(mstr, _("Info"), wxICON_INFORMATION);
143             }
144         }
145 
146     }
147     else if (chin == t2siFile || chin == t2siSelection)
148     {
149         cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
150         if (!ed)
151             return;
152         FileTab2Space(ed->GetFilename(), chin, tabSize);
153     }
154 }
155 
FileTab2Space(wxString filename,Tab2SpaceIn chin,int tabSize)156 void Tab2Space::FileTab2Space(wxString filename, Tab2SpaceIn chin, int tabSize)
157 {
158     if (!Manager::Get()->GetEditorManager())
159         return;
160 
161     cbEditor* ed = Manager::Get()->GetEditorManager()->IsBuiltinOpen(filename);
162 
163     if (ed) // File is already opened
164         EditorTab2Space(ed, chin, tabSize);
165     else
166     {
167         // File is not opened.
168         ed = Manager::Get()->GetEditorManager()->Open( filename );
169         if (ed)
170         {
171             bool changed = EditorTab2Space(ed, chin, tabSize);
172             if ( !changed ) // We opened a file and it didn't change.  Close it.
173                 Manager::Get()->GetEditorManager()->Close( filename );
174         }
175     }
176 }
177 
EditorTab2Space(cbEditor * ed,Tab2SpaceIn chin,int tabSize)178 bool Tab2Space::EditorTab2Space(cbEditor* ed, Tab2SpaceIn chin, int tabSize)
179 {
180     if (!ed)
181         return false;
182 
183     cbStyledTextCtrl* control = ed->GetControl();
184     if (!control)
185         return false;
186 
187     if (control->GetReadOnly())
188     {
189         cbMessageBox(_("The file is read-only!"), _("Error"), wxICON_ERROR);
190         return false;
191     }
192 
193     FortranSourceForm fsForm;
194     if (!g_FortranFileExt.IsFileFortran(ed->GetFilename(), fsForm))
195     {
196         cbMessageBox( _("The file \n") + ed->GetFilename() +
197             _("\n is not recognized as a Fortran Source File."), _("Info"),
198             wxICON_INFORMATION);
199         return false;
200     }
201 
202     wxString allText;
203     if (chin == t2siSelection)
204     {
205         allText = control->GetSelectedText();
206         if (allText.IsEmpty())
207             return false;
208     }
209     else
210         allText = control->GetText();
211 
212     wxString allTextNew;
213 
214     if (allText.size() == 0)
215         return false;
216 
217     wxString contDigit = _T("123456789");
218 
219     size_t ncur = 0;
220     while (1)
221 	{
222 	    wxString line;
223 	    size_t ncur_old = ncur;
224 	    while (ncur < allText.size())
225         {
226             if (allText.GetChar(ncur) == '\n' || ncur == (allText.size()-1))
227             {
228                 ncur++;
229                 line = allText.Mid(ncur_old, ncur-ncur_old);
230                 break;
231             }
232             ncur++;
233         }
234 
235         if (line.size() == 0)
236             break;
237 
238         wxString lineNew;
239 
240         if (fsForm == fsfFixed)
241         {
242             if (line.GetChar(0) == '\t' && contDigit.Find(line.GetChar(1)) != wxNOT_FOUND)
243                 lineNew << _T("     ");
244             else if (line.GetChar(0) == '\t')
245                 lineNew << _T("      ");
246             else if (line.GetChar(0) == '\n')
247                 lineNew << _T("\n");
248             else
249                 lineNew << line.GetChar(0);
250         }
251         else
252         {
253             if (line.GetChar(0) == '\t')
254                 lineNew.Append(' ',tabSize);
255             else
256                 lineNew << line.GetChar(0);
257         }
258 
259         for (size_t i=1; i<line.size(); i++)
260         {
261             if (line.GetChar(i) == '\t')
262             {
263                 int nspace;
264                 if ((lineNew.size() >= 6) || (fsForm == fsfFree))
265                     nspace = tabSize - lineNew.size()%tabSize;
266                 else
267                     nspace = 6 - lineNew.size();
268 
269                 lineNew.Append(' ', nspace);
270             }
271             else
272             {
273                 lineNew << line.GetChar(i);
274             }
275         }
276         allTextNew.Append(lineNew);
277 
278         if (ncur >= allText.size())
279             break;
280 	}
281 
282     if (!allText.IsSameAs(allTextNew))
283     {
284         if (chin == t2siSelection)
285             control->ReplaceSelection(allTextNew);
286         else
287             control->SetText(allTextNew);
288         return true;
289     }
290     return false;
291 }
292 
293