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