2
2
* This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3
3
* http://www.gnu.org/licenses/lgpl-3.0.html
6
* $Id: editormanager.cpp 6165 2010-02-15 15:29:55Z biplab $
7
* $HeadURL: svn+ssh://jenslody@svn.berlios.de/svnroot/repos/codeblocks/trunk/src/sdk/editormanager.cpp $
10
10
#include "sdk_precomp.h"
15
#include <wx/imaglist.h>
16
#include <wx/listctrl.h>
13
18
#include <wx/notebook.h>
15
20
#include <wx/splitter.h>
16
#include <wx/imaglist.h>
18
#include <wx/listctrl.h>
21
#include <wx/xrc/xmlres.h>
24
#include "cbproject.h"
26
#include "compilerfactory.h"
27
#include "configmanager.h"
20
28
#include "editormanager.h" // class's header file
21
#include "configmanager.h"
22
#include <wx/xrc/xmlres.h>
29
#include "filemanager.h"
23
31
#include "infowindow.h"
24
32
#include "logmanager.h"
25
#include "projectmanager.h"
26
#include "projectfile.h"
33
#include "macrosmanager.h"
27
35
#include "pluginmanager.h"
29
#include "macrosmanager.h"
30
#include "filemanager.h"
31
#include "sdk_events.h"
32
36
#include "projectbuildtarget.h"
33
#include "cbproject.h"
37
#include "projectfile.h"
38
#include "projectmanager.h"
36
39
#include "sdk_events.h"
42
#include "annoyingdialog.h"
40
43
#include "cbstyledtextctrl.h"
42
45
#include <wx/bmpbuttn.h>
90
96
int SearchInSelectionEnd; //!< keep track of the end of a 'search' selection
91
97
bool autoWrapSearch;
92
98
bool findUsesSelectedText;
99
bool multiLine; //!< for multi-line S&R.
100
bool fixEOLs; //!< for multi-line S&R. Fixes EOLs in all the files searched.
101
int eolMode; //!< for multi-line S&R
103
void ConvertEOLs(int newmode);
108
eolMode = wxSCI_EOL_LF;
95
static const int idNBTabSplitHorz = wxNewId();
96
static const int idNBTabSplitVert = wxNewId();
97
static const int idNBTabUnsplit = wxNewId();
98
static const int idNBTabClose = wxNewId();
99
static const int idNBTabCloseAll = wxNewId();
100
static const int idNBTabCloseAllOthers = wxNewId();
101
static const int idNBTabSave = wxNewId();
102
static const int idNBTabSaveAll = wxNewId();
103
static const int idNBSwapHeaderSource = wxNewId();
104
static const int idNBTabTop = wxNewId();
105
static const int idNBTabBottom = wxNewId();
106
static const int idNBProperties = wxNewId();
107
static const int idNBAddFileToProject = wxNewId();
108
static const int idNBRemoveFileFromProject = wxNewId();
113
void cbFindReplaceData::ConvertEOLs(int newmode)
115
if (eolMode != newmode)
117
const wxChar* eol_lf = _T("\n");
118
const wxChar* eol_crlf = _T("\r\n");
119
const wxChar* eol_cr = _T("\r");
121
const wxChar* eol_from = eol_lf;
122
const wxChar* eol_to = eol_lf;
125
case wxSCI_EOL_CR: eol_from = eol_cr; break;
126
case wxSCI_EOL_CRLF: eol_from = eol_crlf; break;
131
case wxSCI_EOL_CR: eol_to = eol_cr; break;
132
case wxSCI_EOL_CRLF: eol_to = eol_crlf; break;
133
default: newmode = wxSCI_EOL_LF;
135
findText.Replace(eol_from, eol_to, true);
136
replaceText.Replace(eol_from, eol_to, true);
141
bool cbFindReplaceData::IsMultiLine()
143
if (regEx) // For regex always assume multiline if the multiline checkbox is enabled because the user can enter "\n" to search for newlines
145
// otherwise only treat the search as a multiline search only if there are newline characters in the search string
146
return ((findText.Find(_T("\n")) != wxNOT_FOUND) || (findText.Find(_T("\r")) != wxNOT_FOUND));
149
// needed for initialization of variables
150
inline int cbRegisterId(int id)
156
static const int idNBTabSplitHorz = wxNewId();
157
static const int idNBTabSplitVert = wxNewId();
158
static const int idNBTabUnsplit = wxNewId();
159
static const int idNBTabClose = wxNewId();
160
static const int idNBTabCloseAll = wxNewId();
161
static const int idNBTabCloseAllOthers = wxNewId();
162
static const int idNBTabSave = wxNewId();
163
static const int idNBTabSaveAll = wxNewId();
164
static const int idNBSwapHeaderSource = wxNewId();
165
static const int idNBTabOpenContainingFolder = wxNewId();
166
static const int idNBTabTop = wxNewId();
167
static const int idNBTabBottom = wxNewId();
168
static const int idNBProperties = wxNewId();
169
static const int idNBAddFileToProject = wxNewId();
170
static const int idNBRemoveFileFromProject = wxNewId();
171
static const int idNBShowFileInTree = wxNewId();
173
// The following lines reserve 255 consecutive id's
174
static const int EditorMaxSwitchTo = 255;
175
static const int idNBSwitchFile1 = wxNewId();
176
static const int idNBSwitchFileMax = cbRegisterId(idNBSwitchFile1 + EditorMaxSwitchTo - 1);
110
179
/** *******************************************************
111
180
* struct EditorManagerInternalData *
145
215
EVT_MENU(idNBTabClose, EditorManager::OnClose)
146
216
EVT_MENU(idNBTabCloseAll, EditorManager::OnCloseAll)
147
217
EVT_MENU(idNBTabCloseAllOthers, EditorManager::OnCloseAllOthers)
218
EVT_MENU(idNBTabOpenContainingFolder, EditorManager::OnOpenContainingFolder)
148
219
EVT_MENU(idNBTabSave, EditorManager::OnSave)
149
220
EVT_MENU(idNBTabSaveAll, EditorManager::OnSaveAll)
150
221
EVT_MENU(idNBSwapHeaderSource, EditorManager::OnSwapHeaderSource)
151
222
EVT_MENU(idNBProperties, EditorManager::OnProperties)
152
223
EVT_MENU(idNBAddFileToProject, EditorManager::OnAddFileToProject)
153
224
EVT_MENU(idNBRemoveFileFromProject, EditorManager::OnRemoveFileFromProject)
225
EVT_MENU(idNBShowFileInTree, EditorManager::OnShowFileInTree)
154
226
EVT_MENU(idEditorManagerCheckFiles, EditorManager::OnCheckForModifiedFiles)
155
227
END_EVENT_TABLE()
157
229
EditorManager::EditorManager()
158
230
: m_pNotebook(0L),
231
m_pNotebookStackHead(new cbNotebookStack),
232
m_pNotebookStackTail(m_pNotebookStackHead),
233
m_nNotebookStackSize(0),
159
234
m_LastFindReplaceData(0L),
161
236
m_SearchLogIndex(-1),
176
251
Manager::Get()->GetAppWindow()->PushEventHandler(this);
178
253
CreateSearchLog();
180
254
m_Zoom = Manager::Get()->GetConfigManager(_T("editor"))->ReadInt(_T("/zoom"));
255
Manager::Get()->RegisterEventSink(cbEVT_BUILDTARGET_SELECTED, new cbEventFunctor<EditorManager, CodeBlocksEvent>(this, &EditorManager::CollectDefines));
256
Manager::Get()->RegisterEventSink(cbEVT_PROJECT_ACTIVATE, new cbEventFunctor<EditorManager, CodeBlocksEvent>(this, &EditorManager::CollectDefines));
257
Manager::Get()->RegisterEventSink(cbEVT_WORKSPACE_LOADING_COMPLETE, new cbEventFunctor<EditorManager, CodeBlocksEvent>(this, &EditorManager::CollectDefines));
183
260
EditorManager::~EditorManager()
187
262
CodeBlocksLogEvent evt(cbEVT_REMOVE_LOG_WINDOW, m_pSearchLog);
188
263
Manager::Get()->ProcessEvent(evt);
265
DeleteNotebookStack();
266
delete m_pNotebookStackHead;
191
268
delete m_LastFindReplaceData;
193
270
Manager::Get()->GetConfigManager(_T("editor"))->Write(_T("/zoom"), m_Zoom);
196
void EditorManager::CreateMenu(wxMenuBar* menuBar)
200
void EditorManager::ReleaseMenu(wxMenuBar* menuBar)
273
cbNotebookStack* EditorManager::GetNotebookStack()
277
cbNotebookStack* body;
278
cbNotebookStack* prev_body;
280
while (m_nNotebookStackSize != m_pNotebook->GetPageCount()) // Sync stack with Notebook
282
if (m_nNotebookStackSize < m_pNotebook->GetPageCount())
284
for (size_t i = 0; i<m_pNotebook->GetPageCount(); ++i)
286
wnd = m_pNotebook->GetPage(i);
288
for (body = m_pNotebookStackHead->next; body != NULL; body = body->next)
290
if (wnd == body->window)
298
m_pNotebookStackTail->next = new cbNotebookStack(wnd);
299
m_pNotebookStackTail = m_pNotebookStackTail->next;
300
++m_nNotebookStackSize;
304
if (m_nNotebookStackSize > m_pNotebook->GetPageCount())
306
for (prev_body = m_pNotebookStackHead, body = prev_body->next; body != NULL; prev_body = body, body = body->next)
308
if (m_pNotebook->GetPageIndex(body->window) == wxNOT_FOUND)
310
prev_body->next = body->next;
312
--m_nNotebookStackSize;
319
return m_pNotebookStackHead->next;
322
void EditorManager::DeleteNotebookStack()
324
cbNotebookStack* tmp;
325
while(m_pNotebookStackHead->next)
327
tmp = m_pNotebookStackHead->next;
328
m_pNotebookStackHead->next = tmp->next;
331
m_pNotebookStackTail = m_pNotebookStackHead;
332
m_nNotebookStackSize = 0;
335
void EditorManager::RebuildNotebookStack()
337
DeleteNotebookStack();
338
for (size_t i = 0; i < m_pNotebook->GetPageCount(); ++i)
340
m_pNotebookStackTail->next = new cbNotebookStack(m_pNotebook->GetPage(i));
341
m_pNotebookStackTail = m_pNotebookStackTail->next;
342
++m_nNotebookStackSize;
346
void EditorManager::CreateMenu(cb_unused wxMenuBar* menuBar)
350
void EditorManager::ReleaseMenu(cb_unused wxMenuBar* menuBar)
279
429
m_pSearchLog->Append(values, line == -1 ? Logger::caption : Logger::info);
282
void EditorManager::LoadAutoComplete()
284
m_AutoCompleteMap.clear();
285
wxArrayString list = Manager::Get()->GetConfigManager(_T("editor"))->EnumerateSubPaths(_T("/auto_complete"));
286
for (unsigned int i = 0; i < list.GetCount(); ++i)
288
wxString name = Manager::Get()->GetConfigManager(_T("editor"))->Read(_T("/auto_complete/") + list[i] + _T("/name"), wxEmptyString);
289
wxString code = Manager::Get()->GetConfigManager(_T("editor"))->Read(_T("/auto_complete/") + list[i] + _T("/code"), wxEmptyString);
290
if (name.IsEmpty() || code.IsEmpty())
292
// convert non-printable chars to printable
293
code.Replace(_T("\\n"), _T("\n"));
294
code.Replace(_T("\\r"), _T("\r"));
295
code.Replace(_T("\\t"), _T("\t"));
296
m_AutoCompleteMap[name] = code;
299
if (m_AutoCompleteMap.size() == 0)
301
// default auto-complete items
302
m_AutoCompleteMap[_T("if")] = _T("if (|)\n\t;");
303
m_AutoCompleteMap[_T("ifb")] = _T("if (|)\n{\n\t\n}");
304
m_AutoCompleteMap[_T("ife")] = _T("if (|)\n{\n\t\n}\nelse\n{\n\t\n}");
305
m_AutoCompleteMap[_T("ifei")] = _T("if (|)\n{\n\t\n}\nelse if ()\n{\n\t\n}\nelse\n{\n\t\n}");
306
m_AutoCompleteMap[_T("guard")] = _T("#ifndef $(Guard token)\n#define $(Guard token)\n\n|\n\n#endif // $(Guard token)\n");
307
m_AutoCompleteMap[_T("while")] = _T("while (|)\n\t;");
308
m_AutoCompleteMap[_T("whileb")] = _T("while (|)\n{\n\t\n}");
309
m_AutoCompleteMap[_T("switch")] = _T("switch (|)\n{\n\tcase :\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n}\n");
310
m_AutoCompleteMap[_T("for")] = _T("for (|; ; )\n\t;");
311
m_AutoCompleteMap[_T("forb")] = _T("for (|; ; )\n{\n\t\n}");
312
m_AutoCompleteMap[_T("class")] = _T("class $(Class name)|\n{\n\tpublic:\n\t\t$(Class name)();\n\t\t~$(Class name)();\n\tprotected:\n\t\t\n\tprivate:\n\t\t\n};\n");
313
m_AutoCompleteMap[_T("struct")] = _T("struct |\n{\n\t\n};\n");
316
// date and time macros
317
// these are auto-added if they 're found to be missing
318
const wxString timeAndDate[9][2] =
320
{ _T("tday"), _T("$TDAY") },
321
{ _T("tdayu"), _T("$TDAY_UTC") },
322
{ _T("today"), _T("$TODAY") },
323
{ _T("todayu"), _T("$TODAY_UTC") },
324
{ _T("now"), _T("$NOW") },
325
{ _T("nowl"), _T("$NOW_L") },
326
{ _T("nowu"), _T("$NOW_UTC") },
327
{ _T("nowlu"), _T("$NOW_L_UTC") },
328
{ _T("wdu"), _T("$WEEKDAY_UTC") },
330
for (int i = 0; i < 9; ++i)
332
if (m_AutoCompleteMap.find(timeAndDate[i][0]) == m_AutoCompleteMap.end())
333
m_AutoCompleteMap[timeAndDate[i][0]] = timeAndDate[i][1];
337
void EditorManager::SaveAutoComplete()
339
Manager::Get()->GetConfigManager(_T("editor"))->DeleteSubPath(_T("/auto_complete"));
340
AutoCompleteMap::iterator it;
342
for (it = m_AutoCompleteMap.begin(); it != m_AutoCompleteMap.end(); ++it)
344
wxString code = it->second;
345
// convert non-printable chars to printable
346
code.Replace(_T("\n"), _T("\\n"));
347
code.Replace(_T("\r"), _T("\\r"));
348
code.Replace(_T("\t"), _T("\\t"));
352
key.Printf(_T("/auto_complete/entry%d/name"), count);
353
Manager::Get()->GetConfigManager(_T("editor"))->Write(key, it->first);
354
key.Printf(_T("/auto_complete/entry%d/code"), count);
355
Manager::Get()->GetConfigManager(_T("editor"))->Write(key, code);
359
432
int EditorManager::GetEditorsCount()
361
434
return m_pNotebook->GetPageCount();
482
ed->GetControl()->SetFocus();
486
550
// check for ProjectFile
487
551
if (ed && !ed->GetProjectFile())
489
// First checks if we're already being passed a ProjectFile
553
// First checks if we're already being passed a ProjectFile as a parameter
492
Manager::Get()->GetLogManager()->DebugLog(_T("project data set for ") + data->file.GetFullPath());
555
Manager::Get()->GetLogManager()->DebugLog(_T("Project data set for ") + data->file.GetFullPath());
495
ProjectsArray* projects = Manager::Get()->GetProjectManager()->GetProjects();
496
for (unsigned int i = 0; i < projects->GetCount(); ++i)
498
cbProject* prj = projects->Item(i);
499
ProjectFile* pf = prj->GetFileByFilename(ed->GetFilename(), false);
502
// Manager::Get()->GetLogManager()->DebugLog(_T("Found ") + pf->file.GetFullPath());
557
Manager::Get()->GetProjectManager()->FindProjectForFile(ed->GetFilename(), &data, false, false);
509
559
ed->SetProjectFile(data,true);
566
SetActiveEditor(ed); // fires the cbEVT_EDITOR_ACTIVATED event
567
ed->GetControl()->SetFocus();
513
572
s_CanShutdown = true;
541
600
int page = FindPageFromEditor(ed);
603
// Previously the Activated event was only sent for built-in editors, which makes no sense
604
int sel = m_pNotebook->GetSelection();
543
605
m_pNotebook->SetSelection(page);
606
EditorBase* eb_old = 0;
608
eb_old = static_cast<EditorBase*>(m_pNotebook->GetPage(sel));
610
CodeBlocksEvent evt(cbEVT_EDITOR_SWITCHED, -1, 0, ed, 0, eb_old);
611
Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
613
CodeBlocksEvent evt2(cbEVT_EDITOR_ACTIVATED, -1, 0, ed);
614
Manager::Get()->GetPluginManager()->NotifyPlugins(evt2);
544
617
if (ed->IsBuiltinEditor())
546
618
static_cast<cbEditor*>(ed)->GetControl()->SetFocus();
547
CodeBlocksEvent evt(cbEVT_EDITOR_ACTIVATED, -1, 0, ed);
548
Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
552
621
cbEditor* EditorManager::New(const wxString& newFileName)
1690
1835
else if (data->scope == 1) // find in project files
1692
1837
// fill the search list with all the project files
1693
cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
1838
if (data->searchProject<0)
1840
cbMessageBox(_("No project to search in!"), _("Error"), wxICON_WARNING);
1843
cbProject* prj = (*Manager::Get()->GetProjectManager()->GetProjects())[data->searchProject];
1697
1845
wxString fullpath = _T("");
1698
for (int i = 0; i < prj->GetFilesCount(); ++i)
1846
if (data->searchTarget >= 0)
1847
target = prj->GetBuildTarget(data->searchTarget)->GetTitle();
1848
for (FilesList::iterator it = prj->GetFilesList().begin(); it != prj->GetFilesList().end(); ++it)
1700
ProjectFile* pf = prj->GetFile(i);
1850
ProjectFile* pf = *it;
1853
if (target!=wxEmptyString && pf->buildTargets.Index(target)<0)
1703
1855
fullpath = pf->file.GetFullPath();
1704
if (filesList.Index(fullpath) == -1) // avoid adding duplicates
1706
if (wxFileExists(fullpath)) // Does the file exist?
1707
filesList.Add(fullpath);
1856
if (filesList.Index(fullpath) >= 0) // avoid adding duplicates
1858
if (wxFileExists(fullpath)) // Does the file exist?
1859
filesList.Add(fullpath);
1854
2036
SetActiveEditor(ed);
1855
control->BeginUndoAction(); //undo
1857
2038
*data = dataCopy;
2040
bool replacementsWereMade = false;
2041
// If we fix the file's EOLs for multi-line S&R, we're actually modifying it.
2042
// What we really want to know is whether we actually did a replacement.
2043
// If not (and the file was not open in the first place), we can safely close the file.
2046
// We should be checking if the data has EOLs before converting them. But searching is
2047
// just as expensive as doing the conversion itself, so we just convert.
2048
int eolMode = control->GetEOLMode();
2049
data->ConvertEOLs(eolMode);
2051
if (IsMultiLine && data->fixEOLs)
2053
control->BeginUndoAction(); //undo
2054
control->SetChangeCollection(false);
2055
control->ConvertEOLs(eolMode);
2056
control->SetChangeCollection(true);
2057
control->EndUndoAction();
2061
control->BeginUndoAction(); // undo
1858
2062
CalculateFindReplaceStartEnd(control, data, true);
2080
2294
StartPos = data->SearchInSelectionStart;
2081
2295
EndPos = data->SearchInSelectionEnd;
2297
bool wrapAroundNotification = false;
2083
2298
while (true) // loop while not found and user selects to start again from the top
2085
2300
int lengthFound = 0;
2087
2302
pos = control->FindText(data->start, data->end, data->findText, flags, &lengthFound);
2090
wxString text=control->GetTextRange(data->start, data->end);
2305
wxString text = control->GetTextRange(data->start, data->end);
2091
2306
if (re.Matches(text))
2094
re.GetMatch(&start,&len,0);
2095
pos=start+data->start;
2097
if (start==0&&len==0) //For searches for "^" or "$" (and null returning variants on this) need to make sure we have forward progress and not simply matching on a previous BOL/EOL find
2309
re.GetMatch(&start, &len, 0);
2310
pos = start + data->start;
2312
if ((start==0) && (len==0)) //For searches for "^" or "$" (and null returning variants on this) need to make sure we have forward progress and not simply matching on a previous BOL/EOL find
2100
2315
if (re.Matches(text))
2103
re.GetMatch(&start,&len,0);
2104
pos=start+data->start+1;
2317
re.GetMatch(&start, &len, 0);
2318
pos = start + data->start + 1;
2114
2328
if (pos != -1 && data->start!=data->end)
2117
2331
int onScreen = control->LinesOnScreen() >> 1;
2118
2332
int l1 = line - onScreen;
2119
2333
int l2 = line + onScreen;
2120
for(int l=l1; l<=l2;l+=2) // unfold visible lines on screen
2334
for (int l=l1; l<=l2; l+=2) // unfold visible lines on screen
2121
2335
control->EnsureVisible(l);
2122
2336
control->GotoLine(l1); // center selection on screen
2123
2337
control->GotoLine(l2);
2124
2338
control->GotoLine(line);
2125
2339
control->SetSelectionVoid(pos, pos + lengthFound);
2126
// Manager::Get()->GetLogManager()->DebugLog("pos=%d, selLen=%d, length=%d", pos, data->end - data->start, lengthFound);
2340
// Manager::Get()->GetLogManager()->DebugLog("pos=%d, selLen=%d, length=%d", pos, data->end - data->start, lengthFound);
2127
2341
data->start = pos;
2130
2344
else if (!wrapAround && !data->findInFiles) // for "find in files" we don't want to show messages
2132
if ( (data->directionDown && data->start != StartPos) ||
2133
(!data->directionDown && data->start != EndPos) )
2346
if ( (data->directionDown && data->start != StartPos)
2347
|| (!data->directionDown && data->start != EndPos) )
2136
2350
if (!data->scope == 1) // selected text
2234
2458
else if (data->scope == 1) // find in project files
2236
2460
// fill the search list with all the project files
2237
cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
2461
if(data->searchProject<0)
2240
2463
cbMessageBox(_("No project to search in!"), _("Error"), wxICON_WARNING);
2466
cbProject* prj = (*Manager::Get()->GetProjectManager()->GetProjects())[data->searchProject];
2244
2468
wxString fullpath = _T("");
2245
for (int i = 0; i < prj->GetFilesCount(); ++i)
2469
if(data->searchTarget >= 0)
2470
target = prj->GetBuildTarget(data->searchTarget)->GetTitle();
2471
for (FilesList::iterator it = prj->GetFilesList().begin(); it != prj->GetFilesList().end(); ++it)
2247
ProjectFile* pf = prj->GetFile(i);
2473
ProjectFile* pf = *it;
2476
if(target!=wxEmptyString && pf->buildTargets.Index(target)<0)
2250
2478
fullpath = pf->file.GetFullPath();
2251
if (filesList.Index(fullpath) == -1) // avoid adding duplicates
2253
if (wxFileExists(fullpath)) // Does the file exist?
2254
filesList.Add(fullpath);
2479
if (filesList.Index(fullpath) >= 0) // avoid adding duplicates
2481
if (wxFileExists(fullpath)) // Does the file exist?
2482
filesList.Add(fullpath);
2496
2735
ed->Split(cbEditor::stVertical);
2497
2736
else if (id == idNBTabUnsplit && ed)
2738
else if (id >= idNBSwitchFile1 && id <= idNBSwitchFileMax)
2740
eb = GetEditor(id - idNBSwitchFile1);
2742
SetActiveEditor(eb);
2501
2746
void EditorManager::OnPageChanged(wxAuiNotebookEvent& event)
2503
2748
EditorBase* eb = static_cast<EditorBase*>(m_pNotebook->GetPage(event.GetSelection()));
2504
CodeBlocksEvent evt(cbEVT_EDITOR_ACTIVATED, -1, 0, eb);
2749
EditorBase* eb_old = 0;
2750
if (event.GetOldSelection()!=-1)
2751
eb_old = static_cast<EditorBase*>(m_pNotebook->GetPage(event.GetOldSelection()));
2753
CodeBlocksEvent evt(cbEVT_EDITOR_SWITCHED, -1, 0, eb, 0, eb_old);
2505
2754
Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
2756
CodeBlocksEvent evt2(cbEVT_EDITOR_ACTIVATED, -1, 0, eb);
2757
Manager::Get()->GetPluginManager()->NotifyPlugins(evt2);
2759
if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/tabs_stacked_based_switching")))
2762
cbNotebookStack* body;
2763
cbNotebookStack* tmp;
2764
wnd = m_pNotebook->GetPage(event.GetSelection());
2765
for (body = m_pNotebookStackHead; body->next != 0; body = body->next)
2767
if (wnd == body->next->window)
2769
if (m_pNotebookStackTail == body->next)
2770
m_pNotebookStackTail = body;
2772
body->next = tmp->next;
2773
tmp->next = m_pNotebookStackHead->next;
2774
m_pNotebookStackHead->next = tmp;
2778
if ( (m_pNotebookStackHead->next == 0)
2779
|| (wnd != m_pNotebookStackHead->next->window) )
2781
body = new cbNotebookStack(wnd);
2782
body->next = m_pNotebookStackHead->next;
2783
m_pNotebookStackHead->next = body;
2784
++m_nNotebookStackSize;
2507
2788
// focus editor on next update event
2508
2789
m_pData->m_SetFocusFlag = true;
2525
2806
void EditorManager::OnPageClose(wxAuiNotebookEvent& event)
2527
2808
int sel = event.GetSelection();
2809
bool doClose = false;
2810
EditorBase* eb = nullptr;
2530
EditorBase* eb = static_cast<EditorBase*>(m_pNotebook->GetPage(sel));
2531
if (!QueryClose(eb))
2534
event.Skip(); // allow others to process it too
2813
// veto it in any case, so we can handle the page delete or remove ourselves
2815
eb = static_cast<EditorBase*>(m_pNotebook->GetPage(sel));
2819
if (m_pNotebook->GetPageCount()<=1)
2821
CodeBlocksEvent evt(cbEVT_EDITOR_SWITCHED, -1, 0, 0, 0, eb);
2822
Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
2827
if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/tabs_stacked_based_switching")))
2830
cbNotebookStack* body;
2831
cbNotebookStack* tmp;
2832
wnd = m_pNotebook->GetPage(event.GetSelection());
2833
for (body = m_pNotebookStackHead; body->next != 0; body = body->next)
2835
if (wnd == body->next->window)
2838
body->next = tmp->next;
2840
--m_nNotebookStackSize;
2846
if (doClose && eb != nullptr)
2849
event.Skip(); // allow others to process it too
2537
2852
void EditorManager::OnPageContextMenu(wxAuiNotebookEvent& event)
2539
2854
if (event.GetSelection() == -1)
2857
if (wxGetKeyState(WXK_CONTROL) && GetEditorsCount() > 1)
2859
wxMenu* pop = new wxMenu;
2860
EditorBase* current = GetActiveEditor();
2861
for (int i = 0; i < EditorMaxSwitchTo && i < GetEditorsCount(); ++i)
2863
EditorBase* other = GetEditor(i);
2866
if (other == current)
2868
pop->AppendCheckItem(wxID_ANY, other->GetShortName()); // do nothing if the current tab is selected
2869
pop->FindItemByPosition(pop->GetMenuItemCount() - 1)->Check(); // and mark it as active
2872
pop->Append(idNBSwitchFile1 + i, other->GetShortName());
2874
m_pNotebook->PopupMenu(pop);
2541
2879
// select the notebook that sends the event, because the context menu-entries act on the actual selected tab
2542
2880
m_pNotebook->SetSelection(event.GetSelection());
2543
2881
wxMenu* pop = new wxMenu;
2547
2885
pop->Append(idNBTabCloseAll, _("Close all"));
2548
2886
pop->Append(idNBTabCloseAllOthers, _("Close all others"));
2550
pop->AppendSeparator();
2551
pop->Append(idNBTabSave, _("Save"));
2552
pop->Append(idNBTabSaveAll, _("Save all"));
2553
pop->AppendSeparator();
2554
pop->Append(idNBSwapHeaderSource, _("Swap header/source"));
2555
pop->AppendSeparator();
2556
pop->Append(idNBTabTop, _("Tabs at top"));
2557
pop->Append(idNBTabBottom, _("Tabs at bottom"));
2889
int any_modified = 0;
2890
for (int i = 0; i<GetEditorsCount(); ++i)
2892
EditorBase* ed = GetEditor(i);
2893
if (ed && ed->GetModified())
2895
if (++any_modified > 1)
2896
break; // more than one editor is modified -> enable "Save all"
2899
if (any_modified > 0)
2901
pop->AppendSeparator();
2902
if (GetEditor(event.GetSelection())->GetModified())
2903
pop->Append(idNBTabSave, _("Save"));
2904
if (any_modified > 1 || !GetEditor(event.GetSelection())->GetModified())
2905
pop->Append(idNBTabSaveAll, _("Save all"));
2908
pop->AppendSeparator();
2559
2909
cbEditor* ed = GetBuiltinEditor(event.GetSelection());
2562
pop->AppendSeparator();
2912
pop->Append(idNBSwapHeaderSource, _("Swap header/source"));
2913
pop->Append(idNBTabOpenContainingFolder, _("Open containing folder"));
2563
2914
pop->Append(idNBProperties, _("Properties..."));
2915
pop->AppendSeparator();
2918
if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/editor_tabs_bottom"), false))
2919
pop->Append(idNBTabTop, _("Tabs at top"));
2921
pop->Append(idNBTabBottom, _("Tabs at bottom"));
2565
2925
wxMenu* splitMenu = new wxMenu;
2566
splitMenu->Append(idNBTabSplitHorz, _("Horizontally"));
2567
splitMenu->Append(idNBTabSplitVert, _("Vertically"));
2568
splitMenu->AppendSeparator();
2569
splitMenu->Append(idNBTabUnsplit, _("Unsplit"));
2570
splitMenu->Enable(idNBTabSplitHorz, ed->GetSplitType() != cbEditor::stHorizontal);
2571
splitMenu->Enable(idNBTabSplitVert, ed->GetSplitType() != cbEditor::stVertical);
2572
splitMenu->Enable(idNBTabUnsplit, ed->GetSplitType() != cbEditor::stNoSplit);
2574
pop->AppendSeparator();
2926
if (ed->GetSplitType() != cbEditor::stHorizontal)
2927
splitMenu->Append(idNBTabSplitHorz, _("Horizontally"));
2928
if (ed->GetSplitType() != cbEditor::stVertical)
2929
splitMenu->Append(idNBTabSplitVert, _("Vertically"));
2930
if (ed->GetSplitType() != cbEditor::stNoSplit)
2932
splitMenu->AppendSeparator();
2933
splitMenu->Append(idNBTabUnsplit, _("Unsplit"));
2575
2935
pop->Append(-1, _("Split view"), splitMenu);
2577
2937
if (Manager::Get()->GetProjectManager()->GetActiveProject()) // project must be open
2579
2939
pop->AppendSeparator();
2581
if (ed->GetProjectFile())
2941
ProjectFile *projectFile = ed->GetProjectFile();
2582
2944
pop->Append(idNBRemoveFileFromProject, _("Remove file from project"));
2945
pop->Append(idNBShowFileInTree, _("Show file in the project tree"));
2584
2948
pop->Append(idNBAddFileToProject, _("Add file to active project"));
2588
bool any_modified = false;
2590
for(int i = 0; i < GetEditorsCount(); ++i)
2592
EditorBase* ed = GetEditor(i);
2593
if (ed && ed->GetModified())
2595
any_modified = true;
2600
pop->Enable(idNBTabSave, GetEditor(event.GetSelection())->GetModified());
2601
pop->Enable(idNBTabSaveAll, any_modified );
2952
// allow plugins to use this menu
2953
Manager::Get()->GetPluginManager()->AskPluginsForModuleMenu(mtEditorTab, pop);
2603
2955
m_pNotebook->PopupMenu(pop);
2607
void EditorManager::OnClose(wxCommandEvent& event)
2959
void EditorManager::OnClose(cb_unused wxCommandEvent& event)
2609
2961
Manager::Get()->GetEditorManager()->Close(GetActiveEditor());
2612
void EditorManager::OnCloseAll(wxCommandEvent& event)
2964
void EditorManager::OnCloseAll(cb_unused wxCommandEvent& event)
2614
2966
Manager::Get()->GetEditorManager()->CloseAll();
2617
void EditorManager::OnCloseAllOthers(wxCommandEvent& event)
2969
void EditorManager::OnCloseAllOthers(cb_unused wxCommandEvent& event)
2619
2971
Manager::Get()->GetEditorManager()->CloseAllExcept(GetActiveEditor());
2622
void EditorManager::OnSave(wxCommandEvent& event)
2974
void EditorManager::OnSave(cb_unused wxCommandEvent& event)
2624
2976
Manager::Get()->GetEditorManager()->Save(m_pNotebook->GetSelection());
2627
void EditorManager::OnSaveAll(wxCommandEvent& event)
2979
void EditorManager::OnSaveAll(cb_unused wxCommandEvent& event)
2629
2981
Manager::Get()->GetEditorManager()->SaveAll();
2632
void EditorManager::OnSwapHeaderSource(wxCommandEvent& event)
2984
void EditorManager::OnSwapHeaderSource(cb_unused wxCommandEvent& event)
2634
2986
Manager::Get()->GetEditorManager()->SwapActiveHeaderSource();
2989
void EditorManager::OnOpenContainingFolder(cb_unused wxCommandEvent& event)
2991
Manager::Get()->GetEditorManager()->OpenContainingFolder();
2637
2994
void EditorManager::OnTabPosition(wxCommandEvent& event)
2639
2996
long style = m_pNotebook->GetWindowStyleFlag();
3113
void EditorManager::CollectDefines(CodeBlocksEvent& event)
3115
cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
3117
|| !Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/track_preprocessor"), true)
3118
|| !Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/collect_prj_defines"), true) )
3124
wxArrayString compilerFlags = prj->GetCompilerOptions();
3125
ProjectBuildTarget* tgt = prj->GetBuildTarget(prj->GetActiveBuildTarget());
3130
AppendArray(tgt->GetCompilerOptions(), compilerFlags);
3131
lst = &tgt->GetFilesList();
3132
id = tgt->GetCompilerID();
3136
lst = &prj->GetFilesList();
3137
id = prj->GetCompilerID();
3140
Compiler* comp = CompilerFactory::GetCompiler(id); // get global flags
3142
AppendArray(comp->GetCompilerOptions(), compilerFlags);
3144
wxArrayString defines;
3145
for (size_t i = 0; i < compilerFlags.Count(); ++i)
3147
if ( compilerFlags[i].StartsWith(wxT("-D"))
3148
|| compilerFlags[i].StartsWith(wxT("/D")) )
3150
defines.Add(compilerFlags[i].Mid(2));
3152
else if (compilerFlags[i].Find(wxT("`")) != wxNOT_FOUND)
3154
wxString str = compilerFlags[i];
3155
ExpandBackticks(str);
3156
str.Replace(wxT("`"), wxT(" ")); // remove any leftover backticks to prevent an infinite loop
3157
AppendArray(GetArrayFromString(str, wxT(" ")), compilerFlags);
3159
else if ( compilerFlags[i] == wxT("-ansi")
3160
|| compilerFlags[i] == wxT("-std=c90")
3161
|| compilerFlags[i] == wxT("-std=c++98"))
3163
defines.Add(wxT("__STRICT_ANSI__"));
3167
defines.Add(wxT("__cplusplus"));
3168
for (FilesList::iterator it = lst->begin(); it != lst->end(); ++it)
3170
if ((*it)->relativeFilename.EndsWith(wxT(".c")))
3172
defines.RemoveAt(defines.GetCount() - 1); // do not define '__cplusplus' if even a single C file is found
3176
if (id.Find(wxT("gcc")) != wxNOT_FOUND)
3178
defines.Add(wxT("__GNUC__"));
3179
defines.Add(wxT("__GNUG__"));
3181
else if (id.Find(wxT("msvc")) != wxNOT_FOUND)
3183
defines.Add(wxT("_MSC_VER"));
3184
defines.Add(wxT("__VISUALC__"));
3186
if (Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/platform_defines"), false))
3188
if (platform::windows)
3190
defines.Add(wxT("_WIN32"));
3191
defines.Add(wxT("__WIN32"));
3192
defines.Add(wxT("__WIN32__"));
3193
defines.Add(wxT("WIN32"));
3194
defines.Add(wxT("__WINNT"));
3195
defines.Add(wxT("__WINNT__"));
3196
defines.Add(wxT("WINNT"));
3197
defines.Add(wxT("__WXMSW__"));
3198
defines.Add(wxT("__WINDOWS__"));
3199
if (platform::bits == 64)
3201
defines.Add(wxT("_WIN64"));
3202
defines.Add(wxT("__WIN64__"));
3205
else if (platform::macosx)
3207
defines.Add(wxT("__WXMAC__"));
3208
defines.Add(wxT("__WXOSX__"));
3209
defines.Add(wxT("__WXCOCOA__"));
3210
defines.Add(wxT("__WXOSX_MAC__"));
3211
defines.Add(wxT("__APPLE__"));
3213
else if (platform::linux)
3215
defines.Add(wxT("LINUX"));
3216
defines.Add(wxT("linux"));
3217
defines.Add(wxT("__linux"));
3218
defines.Add(wxT("__linux__"));
3220
else if (platform::freebsd)
3222
defines.Add(wxT("FREEBSD"));
3223
defines.Add(wxT("__FREEBSD__"));
3225
else if (platform::netbsd)
3227
defines.Add(wxT("NETBSD"));
3228
defines.Add(wxT("__NETBSD__"));
3230
else if (platform::openbsd)
3232
defines.Add(wxT("OPENBSD"));
3233
defines.Add(wxT("__OPENBSD__"));
3235
else if (platform::darwin)
3237
defines.Add(wxT("DARWIN"));
3238
defines.Add(wxT("__APPLE__"));
3240
else if (platform::solaris)
3242
defines.Add(wxT("sun"));
3243
defines.Add(wxT("__sun"));
3244
defines.Add(wxT("__SUN__"));
3245
defines.Add(wxT("__SUNOS__"));
3246
defines.Add(wxT("__SOLARIS__"));
3250
defines.Add(wxT("unix"));
3251
defines.Add(wxT("__unix"));
3252
defines.Add(wxT("__unix__"));
3253
defines.Add(wxT("__UNIX__"));
3256
defines.Add(wxT("__WXGTK__"));
3257
if (platform::bits == 32)
3259
defines.Add(wxT("i386"));
3260
defines.Add(wxT("__i386"));
3261
defines.Add(wxT("__i386__"));
3262
defines.Add(wxT("__i386__"));
3263
defines.Add(wxT("_X86_"));
3264
defines.Add(wxT("__INTEL__"));
3266
else if (platform::bits == 64)
3268
defines.Add(wxT("__amd64"));
3269
defines.Add(wxT("__amd64__"));
3270
defines.Add(wxT("__x86_64"));
3271
defines.Add(wxT("__x86_64__"));
3272
defines.Add(wxT("__IA64__"));
3275
wxString keywords = GetStringFromArray(MakeUniqueArray(defines, true), wxT(" "), false);
3276
m_Theme->SetKeywords(m_Theme->GetHighlightLanguage(wxT("C/C++")), 4, keywords);
3277
wxString key = wxT("/colour_sets/") + m_Theme->GetName() + wxT("/cc/");
3278
Manager::Get()->GetConfigManager(wxT("editor"))->Write(key + wxT("editor/keywords/set4"), keywords);
3279
Manager::Get()->GetConfigManager(wxT("editor"))->Write(key + wxT("name"), wxT("C/C++"));
2745
3283
void EditorManager::SetZoom(int zoom)