~ubuntu-branches/ubuntu/trusty/codeblocks/trusty-proposed

« back to all changes in this revision

Viewing changes to src/sdk/editormanager.cpp

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2013-05-06 00:20:02 UTC
  • mfrom: (6.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20130506002002-ngc7bwkewnak8fja
Tags: 12.11-3
* Upload to unstable.
* Update watch file, thanks to Bart Martens.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
4
4
 *
5
 
 * $Revision: 6165 $
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 $
 
5
 * $Revision$
 
6
 * $Id$
 
7
 * $HeadURL$
8
8
 */
9
9
 
10
10
#include "sdk_precomp.h"
11
11
 
12
12
#ifndef CB_PRECOMP
 
13
    #include <wx/dir.h>
 
14
    #include <wx/file.h>
 
15
    #include <wx/imaglist.h>
 
16
    #include <wx/listctrl.h>
 
17
    #include <wx/menu.h>
13
18
    #include <wx/notebook.h>
14
 
    #include <wx/menu.h>
 
19
    #include <wx/regex.h>
15
20
    #include <wx/splitter.h>
16
 
    #include <wx/imaglist.h>
17
 
    #include <wx/regex.h>
18
 
    #include <wx/listctrl.h>
 
21
    #include <wx/xrc/xmlres.h>
19
22
 
 
23
    #include "cbeditor.h"
 
24
    #include "cbproject.h"
 
25
    #include "compiler.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"
 
30
    #include "globals.h"
23
31
    #include "infowindow.h"
24
32
    #include "logmanager.h"
25
 
    #include "projectmanager.h"
26
 
    #include "projectfile.h"
 
33
    #include "macrosmanager.h"
 
34
    #include "manager.h"
27
35
    #include "pluginmanager.h"
28
 
    #include "manager.h"
29
 
    #include "macrosmanager.h"
30
 
    #include "filemanager.h"
31
 
    #include "sdk_events.h"
32
36
    #include "projectbuildtarget.h"
33
 
    #include "cbproject.h"
34
 
    #include "cbeditor.h"
35
 
    #include "globals.h"
 
37
    #include "projectfile.h"
 
38
    #include "projectmanager.h"
36
39
    #include "sdk_events.h"
37
 
    #include <wx/file.h>
38
 
    #include <wx/dir.h>
39
40
#endif
 
41
 
 
42
#include "annoyingdialog.h"
40
43
#include "cbstyledtextctrl.h"
41
44
 
42
45
#include <wx/bmpbuttn.h>
47
50
#include "editorcolourset.h"
48
51
#include "editorconfigurationdlg.h"
49
52
#include "encodingdetector.h"
50
 
#include "finddlg.h"
51
 
#include "replacedlg.h"
 
53
#include "findreplacedlg.h"
52
54
#include "confirmreplacedlg.h"
53
55
#include "filefilters.h"
54
56
#include "searchresultslog.h"
58
60
template<> EditorManager* Mgr<EditorManager>::instance = 0;
59
61
template<> bool  Mgr<EditorManager>::isShutdown = false;
60
62
 
61
 
int ID_NBEditorManager = wxNewId();
62
 
int ID_EditorManager = wxNewId();
 
63
int ID_NBEditorManager        = wxNewId();
 
64
int ID_EditorManager          = wxNewId();
63
65
int idEditorManagerCheckFiles = wxNewId();
64
66
 
65
67
// static
74
76
    bool initialreplacing;
75
77
    bool findInFiles;
76
78
    bool delOldSearches;
 
79
    bool sortSearchResult;
77
80
    bool matchWord;
78
81
    bool startWord;
 
82
    bool startFile; //!< To be implemented.
79
83
    bool matchCase;
80
84
    bool regEx;
81
85
    bool directionDown;
83
87
    int scope;
84
88
    wxString searchPath;
85
89
    wxString searchMask;
 
90
    int searchProject;
 
91
    int searchTarget;
86
92
    bool recursiveSearch;
87
93
    bool hiddenSearch;
88
94
    bool NewSearch;     //!< only true when a new search has been started
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
 
102
 
 
103
    void ConvertEOLs(int newmode);
 
104
    bool IsMultiLine();
 
105
 
 
106
    cbFindReplaceData()
 
107
    {
 
108
        eolMode = wxSCI_EOL_LF;
 
109
        fixEOLs = false;
 
110
    }
93
111
};
94
112
 
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)
 
114
{
 
115
    if (eolMode != newmode)
 
116
    {
 
117
        const wxChar* eol_lf = _T("\n");
 
118
        const wxChar* eol_crlf = _T("\r\n");
 
119
        const wxChar* eol_cr = _T("\r");
 
120
 
 
121
        const wxChar* eol_from = eol_lf;
 
122
        const wxChar* eol_to = eol_lf;
 
123
        switch(eolMode)
 
124
        {
 
125
            case wxSCI_EOL_CR: eol_from = eol_cr; break;
 
126
            case wxSCI_EOL_CRLF: eol_from = eol_crlf; break;
 
127
            default: ;
 
128
        }
 
129
        switch(newmode)
 
130
        {
 
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;
 
134
        }
 
135
        findText.Replace(eol_from, eol_to, true);
 
136
        replaceText.Replace(eol_from, eol_to, true);
 
137
        eolMode = newmode;
 
138
    }
 
139
}
 
140
 
 
141
bool cbFindReplaceData::IsMultiLine()
 
142
{
 
143
    if (regEx) // For regex always assume multiline if the multiline checkbox is enabled because the user can enter "\n" to search for newlines
 
144
        return multiLine;
 
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));
 
147
}
 
148
 
 
149
// needed for initialization of variables
 
150
inline int cbRegisterId(int id)
 
151
{
 
152
    wxRegisterId(id);
 
153
    return id;
 
154
}
 
155
 
 
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();
 
172
 
 
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);
 
177
 
109
178
 
110
179
/** *******************************************************
111
180
  * struct EditorManagerInternalData                      *
137
206
    EVT_AUINOTEBOOK_PAGE_CHANGING(ID_NBEditorManager, EditorManager::OnPageChanging)
138
207
    EVT_AUINOTEBOOK_PAGE_CLOSE(ID_NBEditorManager, EditorManager::OnPageClose)
139
208
    EVT_AUINOTEBOOK_TAB_RIGHT_UP(ID_NBEditorManager, EditorManager::OnPageContextMenu)
 
209
    EVT_MENU_RANGE(idNBSwitchFile1, idNBSwitchFileMax, EditorManager::OnGenericContextMenuHandler)
140
210
    EVT_MENU(idNBTabSplitHorz, EditorManager::OnGenericContextMenuHandler)
141
211
    EVT_MENU(idNBTabSplitVert, EditorManager::OnGenericContextMenuHandler)
142
212
    EVT_MENU(idNBTabUnsplit, EditorManager::OnGenericContextMenuHandler)
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()
156
228
 
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),
160
235
        m_pSearchLog(0),
161
236
        m_SearchLogIndex(-1),
176
251
    Manager::Get()->GetAppWindow()->PushEventHandler(this);
177
252
 
178
253
    CreateSearchLog();
179
 
    LoadAutoComplete();
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));
181
258
}
182
259
 
183
260
EditorManager::~EditorManager()
184
261
{
185
 
    SaveAutoComplete();
186
 
 
187
262
    CodeBlocksLogEvent evt(cbEVT_REMOVE_LOG_WINDOW, m_pSearchLog);
188
263
    Manager::Get()->ProcessEvent(evt);
189
264
 
 
265
    DeleteNotebookStack();
 
266
    delete m_pNotebookStackHead;
190
267
    delete m_Theme;
191
268
    delete m_LastFindReplaceData;
192
269
    delete m_pData;
193
270
    Manager::Get()->GetConfigManager(_T("editor"))->Write(_T("/zoom"), m_Zoom);
194
271
}
195
272
 
196
 
void EditorManager::CreateMenu(wxMenuBar* menuBar)
197
 
{
198
 
}
199
 
 
200
 
void EditorManager::ReleaseMenu(wxMenuBar* menuBar)
 
273
cbNotebookStack* EditorManager::GetNotebookStack()
 
274
{
 
275
    bool found = false;
 
276
    wxWindow* wnd;
 
277
    cbNotebookStack* body;
 
278
    cbNotebookStack* prev_body;
 
279
 
 
280
    while (m_nNotebookStackSize != m_pNotebook->GetPageCount()) // Sync stack with Notebook
 
281
    {
 
282
        if (m_nNotebookStackSize < m_pNotebook->GetPageCount())
 
283
        {
 
284
            for (size_t i = 0; i<m_pNotebook->GetPageCount(); ++i)
 
285
            {
 
286
                wnd = m_pNotebook->GetPage(i);
 
287
                found = false;
 
288
                for (body = m_pNotebookStackHead->next; body != NULL; body = body->next)
 
289
                {
 
290
                    if (wnd == body->window)
 
291
                    {
 
292
                        found = true;
 
293
                        break;
 
294
                    }
 
295
                }
 
296
                if (!found)
 
297
                {
 
298
                    m_pNotebookStackTail->next = new cbNotebookStack(wnd);
 
299
                    m_pNotebookStackTail = m_pNotebookStackTail->next;
 
300
                    ++m_nNotebookStackSize;
 
301
                }
 
302
            }
 
303
        }
 
304
        if (m_nNotebookStackSize > m_pNotebook->GetPageCount())
 
305
        {
 
306
            for (prev_body = m_pNotebookStackHead, body = prev_body->next; body != NULL; prev_body = body, body = body->next)
 
307
            {
 
308
                if (m_pNotebook->GetPageIndex(body->window) == wxNOT_FOUND)
 
309
                {
 
310
                    prev_body->next = body->next;
 
311
                    delete body;
 
312
                    --m_nNotebookStackSize;
 
313
                    body = prev_body;
 
314
                }
 
315
            }
 
316
        }
 
317
    }
 
318
 
 
319
    return m_pNotebookStackHead->next;
 
320
}
 
321
 
 
322
void EditorManager::DeleteNotebookStack()
 
323
{
 
324
    cbNotebookStack* tmp;
 
325
    while(m_pNotebookStackHead->next)
 
326
    {
 
327
        tmp = m_pNotebookStackHead->next;
 
328
        m_pNotebookStackHead->next = tmp->next;
 
329
        delete tmp;
 
330
    }
 
331
    m_pNotebookStackTail = m_pNotebookStackHead;
 
332
    m_nNotebookStackSize = 0;
 
333
}
 
334
 
 
335
void EditorManager::RebuildNotebookStack()
 
336
{
 
337
    DeleteNotebookStack();
 
338
    for (size_t i = 0; i < m_pNotebook->GetPageCount(); ++i)
 
339
    {
 
340
        m_pNotebookStackTail->next = new cbNotebookStack(m_pNotebook->GetPage(i));
 
341
        m_pNotebookStackTail = m_pNotebookStackTail->next;
 
342
        ++m_nNotebookStackSize;
 
343
    }
 
344
}
 
345
 
 
346
void EditorManager::CreateMenu(cb_unused wxMenuBar* menuBar)
 
347
{
 
348
}
 
349
 
 
350
void EditorManager::ReleaseMenu(cb_unused wxMenuBar* menuBar)
201
351
{
202
352
}
203
353
 
279
429
    m_pSearchLog->Append(values, line == -1 ? Logger::caption : Logger::info);
280
430
}
281
431
 
282
 
void EditorManager::LoadAutoComplete()
283
 
{
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)
287
 
    {
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())
291
 
            continue;
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;
297
 
    }
298
 
 
299
 
    if (m_AutoCompleteMap.size() == 0)
300
 
    {
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");
314
 
    }
315
 
 
316
 
    // date and time macros
317
 
    // these are auto-added if they 're found to be missing
318
 
    const wxString timeAndDate[9][2] =
319
 
    {
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") },
329
 
    };
330
 
    for (int i = 0; i < 9; ++i)
331
 
    {
332
 
        if (m_AutoCompleteMap.find(timeAndDate[i][0]) == m_AutoCompleteMap.end())
333
 
            m_AutoCompleteMap[timeAndDate[i][0]] = timeAndDate[i][1];
334
 
    }
335
 
}
336
 
 
337
 
void EditorManager::SaveAutoComplete()
338
 
{
339
 
    Manager::Get()->GetConfigManager(_T("editor"))->DeleteSubPath(_T("/auto_complete"));
340
 
    AutoCompleteMap::iterator it;
341
 
    int count = 0;
342
 
    for (it = m_AutoCompleteMap.begin(); it != m_AutoCompleteMap.end(); ++it)
343
 
    {
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"));
349
 
 
350
 
        ++count;
351
 
        wxString key;
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);
356
 
    }
357
 
}
358
 
 
359
432
int EditorManager::GetEditorsCount()
360
433
{
361
434
    return m_pNotebook->GetPageCount();
427
500
    return Open(0, filename, pos, data);
428
501
}
429
502
 
430
 
cbEditor* EditorManager::Open(LoaderBase* fileLdr, const wxString& filename, int pos,ProjectFile* data)
 
503
cbEditor* EditorManager::Open(LoaderBase* fileLdr, const wxString& filename, int /*pos*/, ProjectFile* data)
431
504
{
432
505
    bool can_updateui = !GetActiveEditor() || !Manager::Get()->GetProjectManager()->IsLoading();
433
506
    wxFileName fn(realpath(filename));
474
547
        }
475
548
    }
476
549
 
477
 
    if (can_updateui)
478
 
    {
479
 
        if (ed)
480
 
        {
481
 
            SetActiveEditor(ed);
482
 
            ed->GetControl()->SetFocus();
483
 
        }
484
 
    }
485
 
 
486
550
    // check for ProjectFile
487
551
    if (ed && !ed->GetProjectFile())
488
552
    {
489
 
        // First checks if we're already being passed a ProjectFile
490
 
        // as a parameter
 
553
        // First checks if we're already being passed a ProjectFile as a parameter
491
554
        if (data)
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());
493
556
        else
494
 
        {
495
 
            ProjectsArray* projects = Manager::Get()->GetProjectManager()->GetProjects();
496
 
            for (unsigned int i = 0; i < projects->GetCount(); ++i)
497
 
            {
498
 
                cbProject* prj = projects->Item(i);
499
 
                ProjectFile* pf = prj->GetFileByFilename(ed->GetFilename(), false);
500
 
                if (pf)
501
 
                {
502
 
//                    Manager::Get()->GetLogManager()->DebugLog(_T("Found ") + pf->file.GetFullPath());
503
 
                    data = pf;
504
 
                    break;
505
 
                }
506
 
            }
507
 
        }
 
557
            Manager::Get()->GetProjectManager()->FindProjectForFile(ed->GetFilename(), &data, false, false);
508
558
        if (data)
509
559
            ed->SetProjectFile(data,true);
510
560
    }
511
561
 
 
562
    if (can_updateui)
 
563
    {
 
564
        if (ed)
 
565
        {
 
566
            SetActiveEditor(ed); // fires the cbEVT_EDITOR_ACTIVATED event
 
567
            ed->GetControl()->SetFocus();
 
568
        }
 
569
    }
 
570
 
512
571
    // we 're done
513
572
    s_CanShutdown = true;
514
573
 
540
599
        return;
541
600
    int page = FindPageFromEditor(ed);
542
601
    if (page != -1)
 
602
    {
 
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;
 
607
        if (sel>=0)
 
608
            eb_old = static_cast<EditorBase*>(m_pNotebook->GetPage(sel));
 
609
 
 
610
        CodeBlocksEvent evt(cbEVT_EDITOR_SWITCHED, -1, 0, ed, 0, eb_old);
 
611
        Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
 
612
 
 
613
        CodeBlocksEvent evt2(cbEVT_EDITOR_ACTIVATED, -1, 0, ed);
 
614
        Manager::Get()->GetPluginManager()->NotifyPlugins(evt2);
 
615
    }
 
616
 
544
617
    if (ed->IsBuiltinEditor())
545
 
    {
546
618
        static_cast<cbEditor*>(ed)->GetControl()->SetFocus();
547
 
        CodeBlocksEvent evt(cbEVT_EDITOR_ACTIVATED, -1, 0, ed);
548
 
        Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
549
 
    }
550
619
}
551
620
 
552
621
cbEditor* EditorManager::New(const wxString& newFileName)
582
651
 
583
652
    ed->Show(true);
584
653
    SetActiveEditor(ed);
 
654
 
585
655
    CodeBlocksEvent evt(cbEVT_EDITOR_OPEN, -1, 0, ed);
586
656
    Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
 
657
 
587
658
    return ed;
588
659
}
589
660
 
608
679
    }
609
680
}
610
681
 
611
 
void EditorManager::RemoveEditorBase(EditorBase* eb, bool deleteObject)
 
682
void EditorManager::RemoveEditorBase(EditorBase* eb, cb_unused bool deleteObject)
612
683
{
613
684
    int page = FindPageFromEditor(eb);
614
 
   if (page != -1 && !Manager::isappShuttingDown())
 
685
    if (page != -1 && !Manager::IsAppShuttingDown())
615
686
        m_pNotebook->RemovePage(page);
616
687
 
617
688
    //    if (deleteObject)
630
701
            continue;
631
702
        if (pf->GetParentProject() != project)
632
703
            continue;
633
 
        pf->editorTopLine = ed->GetControl()->GetFirstVisibleLine();
634
 
        pf->editorPos = ed->GetControl()->GetCurrentPos();
635
 
//        pf->editorTabPos = i + 1;
 
704
 
636
705
        pf->editorTabPos = m_pNotebook->GetTabPositionFromIndex(i) + 1;
637
 
        pf->editorOpen = true;
 
706
 
 
707
        ed->UpdateProjectFile();
638
708
    }
639
709
    return true;
640
710
}
641
711
 
642
712
bool EditorManager::CloseAll(bool dontsave)
643
713
{
644
 
    //return CloseAllExcept(0L,dontsave);
645
714
    return CloseAllExcept(GetEditor(_("Start here")), dontsave);
646
715
}
647
716
 
656
725
    return true;
657
726
}
658
727
 
659
 
bool EditorManager::CloseAllExcept(EditorBase* editor,bool dontsave)
 
728
bool EditorManager::CloseAllExcept(EditorBase* editor, bool dontsave)
660
729
{
661
730
    if (!dontsave)
662
731
    {
682
751
 
683
752
bool EditorManager::CloseActive(bool dontsave)
684
753
{
685
 
    return Close(GetActiveEditor(),dontsave);
 
754
    return Close(GetActiveEditor(), dontsave);
686
755
}
687
756
 
688
757
bool EditorManager::QueryClose(EditorBase *ed)
689
758
{
690
759
    if (!ed)
691
760
        return true;
692
 
    if (ed->GetModified())
693
 
    {
694
 
        // TODO (mandrav#1#): Move this in EditorBase
695
 
        wxString msg;
696
 
        msg.Printf(_("File %s is modified...\nDo you want to save the changes?"), ed->GetFilename().c_str());
697
 
        switch (cbMessageBox(msg, _("Save file"), wxICON_QUESTION | wxYES_NO | wxCANCEL))
698
 
        {
699
 
        case wxID_YES:
700
 
            if (!ed->Save())
701
 
                return false;
702
 
            break;
703
 
        case wxID_NO:
704
 
            break;
705
 
        case wxID_CANCEL:
706
 
            return false;
707
 
        }
708
 
        ed->SetModified(false);
709
 
    }
710
 
    else
711
 
    {
712
 
        return ed->QueryClose();
713
 
    }
714
 
    return true;
 
761
 
 
762
    return ed->QueryClose();
715
763
}
716
764
 
717
765
int EditorManager::FindPageFromEditor(EditorBase* eb)
718
766
{
 
767
    if (!m_pNotebook || !eb)
 
768
        return -1;
 
769
 
719
770
    for (size_t i = 0; i < m_pNotebook->GetPageCount(); ++i)
720
771
    {
721
772
        if (m_pNotebook->GetPage(i) == eb)
724
775
    return -1;
725
776
}
726
777
 
727
 
bool EditorManager::Close(const wxString& filename,bool dontsave)
 
778
bool EditorManager::Close(const wxString& filename, bool dontsave)
728
779
{
729
 
    return Close(IsOpen(filename),dontsave);
 
780
    return Close(IsOpen(filename), dontsave);
730
781
}
731
782
 
732
 
bool EditorManager::Close(EditorBase* editor,bool dontsave)
 
783
bool EditorManager::Close(EditorBase* editor, bool dontsave)
733
784
{
734
785
    if (editor)
735
786
    {
739
790
            if (!dontsave)
740
791
                if (!QueryClose(editor))
741
792
                    return false;
742
 
            wxString filename = editor->GetFilename();
743
793
            m_pNotebook->DeletePage(idx);
744
794
        }
745
795
    }
746
796
    return true;
747
797
}
748
798
 
749
 
bool EditorManager::Close(int index,bool dontsave)
 
799
bool EditorManager::Close(int index, bool dontsave)
750
800
{
751
801
    EditorBase* ed = InternalGetEditorBase(index);
752
802
    if (ed)
753
 
        return Close(ed,dontsave);
 
803
        return Close(ed, dontsave);
754
804
    return false;
755
805
}
756
806
 
757
807
bool EditorManager::Save(const wxString& filename)
758
808
{
759
 
    //    cbEditor* ed = GetBuiltinEditor(IsOpen(filename));
760
809
    EditorBase* ed = IsOpen(filename);
761
810
    if (ed)
762
811
    {
763
 
        wxString oldname = ed->GetFilename();
764
812
        if (!ed->Save())
765
813
            return false;
766
814
        return true;
773
821
    EditorBase* ed = InternalGetEditorBase(index);
774
822
    if (ed)
775
823
    {
776
 
        wxString oldname = ed->GetFilename();
777
824
        if (!ed->Save())
778
825
            return false;
779
826
        return true;
786
833
    EditorBase* ed = GetActiveEditor();
787
834
    if (ed)
788
835
    {
789
 
        wxString oldname = ed->GetFilename();
790
836
        if (!ed->Save())
791
837
            return false;
792
838
        return true;
842
888
            }
843
889
            break;
844
890
        }
 
891
    case psActiveEditor: // fall through
 
892
    case psSelection:    // fall through
845
893
    default:
846
894
        {
847
895
            cbEditor* ed = GetBuiltinEditor(GetActiveEditor());
928
976
                dlg.SetTitle(_("Reload file?"));
929
977
                dlg.GetSizer()->SetSizeHints(&dlg);
930
978
                PlaceWindow(&dlg);
 
979
 
 
980
                // Find the window, that actually has the mouse-focus and force a release
 
981
                // prevents crash on windows or hang on wxGTK
 
982
                wxWindow* win = wxWindow::GetCapture();
 
983
                if (win)
 
984
                    win->ReleaseMouse();
 
985
 
931
986
                ret = dlg.ShowModal();
932
987
                reloadAll = ret == crAll;
933
988
            }
969
1024
        if (    ((ftActive == ftHeader) && (ftTested == ftSource))
970
1025
             || ((ftActive == ftSource) && (ftTested == ftHeader)) )
971
1026
        {
 
1027
            // Handle the case where two files (in different directories) have the same name:
 
1028
            // Example: A project file with three files dir1/file.h dir1/file.cpp dir2/file.h
 
1029
            // If you are in dir2/file.h and you want to swap Code::Blocks will first look if there
 
1030
            // isn't a file.h in that directory, which is in this case and would then ask the user
 
1031
            // to create a new file.cpp in dir2
 
1032
            if (candidateFile.GetPath() != activeFile.GetPath()) // Check if we are not in the same Directory
 
1033
            {
 
1034
                wxArrayString fileArray;
 
1035
                wxDir::GetAllFiles(candidateFile.GetPath(wxPATH_GET_VOLUME), &fileArray, candidateFile.GetName() + _T(".*"), wxDIR_FILES | wxDIR_HIDDEN);
 
1036
                for (unsigned i=0; i<fileArray.GetCount(); i++)                             // if in this directory there is already
 
1037
                    if (wxFileName(fileArray[i]).GetFullName() == activeFile.GetFullName()) // a header file (or source file) for our candidate
 
1038
                        return false;                                                       // file it can't be our candidate file
 
1039
            }
972
1040
            if (candidateFile.FileExists())
973
1041
                return true;
974
1042
        }
1012
1080
    return candidateFile;
1013
1081
}
1014
1082
 
 
1083
bool EditorManager::OpenContainingFolder()
 
1084
{
 
1085
    cbEditor* ed = GetBuiltinEditor(GetActiveEditor());
 
1086
    if (!ed)
 
1087
        return false;
 
1088
 
 
1089
    ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("editor"));
 
1090
#if defined __WXMSW__
 
1091
    const wxString defCmds = _T("explorer.exe /select,");
 
1092
#elif defined __WXMAC__
 
1093
    const wxString defCmds = _T("open -R");
 
1094
#else
 
1095
    const wxString defCmds = _T("xdg-open");
 
1096
#endif
 
1097
 
 
1098
    wxString cmds = cfg->Read(_T("open_containing_folder"), defCmds) + _T(" ");
 
1099
    const wxString& fullPath = ed->GetFilename();
 
1100
#if defined __WXMSW__ || defined __WXMAC__
 
1101
    cmds << fullPath;   // Open folder with the file selected
 
1102
#else
 
1103
    // Cant select the file on Linux, so just extract the folder name
 
1104
    wxString splitPath;
 
1105
    wxFileName::SplitPath(fullPath, &splitPath, NULL, NULL);
 
1106
    cmds << splitPath;
 
1107
#endif
 
1108
 
 
1109
    wxExecute(cmds);
 
1110
    return true;
 
1111
}
 
1112
 
1015
1113
bool EditorManager::SwapActiveHeaderSource()
1016
1114
{
1017
1115
    cbEditor* ed = GetBuiltinEditor(GetActiveEditor());
1096
1194
 
1097
1195
        // build a list of project files
1098
1196
        fileArray.Clear();
1099
 
        for (int i = 0; i < project->GetFilesCount(); ++i)
 
1197
        for (FilesList::iterator it = project->GetFilesList().begin(); it != project->GetFilesList().end(); ++it)
1100
1198
        {
1101
 
            ProjectFile* pf = project->GetFile(i);
 
1199
            ProjectFile* pf = *it;
1102
1200
            if (!pf)
1103
1201
                continue;
1104
1202
 
1186
1284
    if (cbMessageBox(_("The file seems not to exist. Do you want to create it?"),
1187
1285
                _("Error"), wxICON_QUESTION | wxYES_NO) == wxID_YES)
1188
1286
    {
1189
 
        cbProject* project = Manager::Get()->GetProjectManager()->GetActiveProject();
 
1287
        project = Manager::Get()->GetProjectManager()->GetActiveProject();
1190
1288
        if (project)
1191
1289
            wxSetWorkingDirectory(project->GetBasePath());
1192
1290
 
1255
1353
 
1256
1354
    }
1257
1355
 
1258
 
    FindReplaceBase* dlg;
1259
 
    if (!replace)
1260
 
        dlg = new FindDlg(Manager::Get()->GetAppWindow(), phraseAtCursor, hasSelection, !ed, explicitly_find_in_files);
1261
 
    else
1262
 
        dlg = new ReplaceDlg(Manager::Get()->GetAppWindow(), phraseAtCursor, hasSelection, !ed, explicitly_find_in_files);
 
1356
    FindReplaceBase* dlg = new FindReplaceDlg(Manager::Get()->GetAppWindow(), phraseAtCursor, hasSelection,
 
1357
                                              !replace, !ed, explicitly_find_in_files);
1263
1358
 
1264
1359
    PlaceWindow(dlg);
1265
1360
    if (dlg->ShowModal() == wxID_CANCEL)
1283
1378
    m_LastFindReplaceData->end = 0;
1284
1379
    m_LastFindReplaceData->findText = dlg->GetFindString();
1285
1380
    m_LastFindReplaceData->replaceText = dlg->GetReplaceString();
 
1381
    m_LastFindReplaceData->eolMode = wxSCI_EOL_LF;
 
1382
    m_LastFindReplaceData->multiLine = dlg->GetMultiLine();
 
1383
    m_LastFindReplaceData->fixEOLs = dlg->GetFixEOLs();
 
1384
    m_LastFindReplaceData->startFile = dlg->GetStartFile();
1286
1385
 
1287
1386
    m_LastFindReplaceData->findInFiles = dlg->IsFindInFiles();
1288
1387
    if (!m_LastFindReplaceData->findInFiles)
1295
1394
            m_LastFindReplaceData->findUsesSelectedText = dlg->GetFindUsesSelectedText();
1296
1395
    }
1297
1396
    m_LastFindReplaceData->delOldSearches = dlg->GetDeleteOldSearches();
 
1397
    m_LastFindReplaceData->sortSearchResult = dlg->GetSortSearchResult();
1298
1398
    m_LastFindReplaceData->matchWord = dlg->GetMatchWord();
1299
1399
    m_LastFindReplaceData->startWord = dlg->GetStartWord();
1300
1400
    m_LastFindReplaceData->matchCase = dlg->GetMatchCase();
1305
1405
    m_LastFindReplaceData->searchPath = dlg->GetSearchPath();
1306
1406
    m_LastFindReplaceData->searchMask = dlg->GetSearchMask();
1307
1407
    m_LastFindReplaceData->recursiveSearch = dlg->GetRecursive();
 
1408
    m_LastFindReplaceData->searchProject = dlg->GetProject();
 
1409
    m_LastFindReplaceData->searchTarget = dlg->GetTarget();
1308
1410
    m_LastFindReplaceData->hiddenSearch = dlg->GetHidden();
1309
1411
    m_LastFindReplaceData->initialreplacing = false;
1310
1412
    m_LastFindReplaceData->NewSearch = true;
1347
1449
{
1348
1450
    if (!control || !data)
1349
1451
        return;
 
1452
    if (data->startFile) // Beginning-of-file needs the entire scope
 
1453
    {
 
1454
        int clen = control->GetLength();
 
1455
        int slen = data->findText.Len();
1350
1456
 
1351
 
    if (!data->findInFiles)   // Find in current Editor
 
1457
        data->start = 0;
 
1458
        data->end = std::min(slen, clen);
 
1459
    }
 
1460
    else if (!data->findInFiles)   // Find in current Editor
1352
1461
    {
1353
1462
        int ssta = control->GetSelectionStart();
1354
1463
        int send = control->GetSelectionEnd();
1449
1558
        return -1;
1450
1559
    }
1451
1560
 
1452
 
    bool AdvRegex=false;
1453
 
    int replacecount=0;
1454
 
    int foundcount=0;
1455
 
    int flags = 0;
 
1561
    bool advRegex = false;
 
1562
    bool advRegexNewLinePolicy =! data->IsMultiLine();
 
1563
    int replacecount = 0;
 
1564
    int foundcount   = 0;
 
1565
    int flags        = 0;
 
1566
 
 
1567
    {
 
1568
        int eolMode = control->GetEOLMode();
 
1569
        data->ConvertEOLs(eolMode); // Convert our S&R data to the file's EOL mode.
 
1570
        if (data->IsMultiLine() && data->fixEOLs)
 
1571
        {
 
1572
            // First we must ensure that the file has consistent line endings.
 
1573
            // As all the file's lines are affected, we disable change history for this step.
 
1574
 
 
1575
            control->BeginUndoAction();
 
1576
            control->SetChangeCollection(false);
 
1577
            control->ConvertEOLs(eolMode);
 
1578
            control->SetChangeCollection(true);
 
1579
            control->EndUndoAction();
 
1580
        }
 
1581
    }
 
1582
    control->BeginUndoAction(); // The undo is set at this point in case we need to convert the EOLs.
 
1583
 
1456
1584
    CalculateFindReplaceStartEnd(control, data);
1457
1585
 
1458
1586
    if (data->matchWord)
1467
1595
        if (Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_posix_style_regexes"), false))
1468
1596
            flags |= wxSCI_FIND_POSIX;
1469
1597
        #ifdef wxHAS_REGEX_ADVANCED
1470
 
        AdvRegex=Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
 
1598
        advRegex = Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
1471
1599
        #endif
1472
1600
    }
1473
1601
 
1474
1602
    wxRegEx re;
1475
1603
    #ifdef wxHAS_REGEX_ADVANCED
1476
 
    if (AdvRegex)
 
1604
    if (advRegex)
1477
1605
    {
1478
1606
        if (data->matchCase)
1479
 
            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE);
 
1607
            re.Compile(data->findText,wxRE_ADVANCED|(wxRE_NEWLINE*advRegexNewLinePolicy));
1480
1608
        else
1481
 
            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE|wxRE_ICASE);
 
1609
            re.Compile(data->findText,wxRE_ADVANCED|(wxRE_NEWLINE*advRegexNewLinePolicy)|wxRE_ICASE);
1482
1610
    }
1483
1611
    #endif
1484
1612
 
1485
 
    control->BeginUndoAction();
1486
1613
    int pos = -1;
1487
1614
    bool replace = false;
1488
1615
    bool confirm = true;
1491
1618
    bool HaveLastDlgPosition = false;
1492
1619
    bool wrapAround = false;
1493
1620
    int  data_start_initial = data->start;
 
1621
    bool wrapAroundNotification = false;
1494
1622
 
1495
1623
    while (!stop)
1496
1624
    {
1497
1625
        int lengthFound = 0;
1498
 
        if (!AdvRegex)
 
1626
        if (!advRegex)
1499
1627
            pos = control->FindText(data->start, data->end, data->findText, flags, &lengthFound);
1500
1628
        else
1501
1629
        {
1506
1634
                re.GetMatch(&start,&len,0);
1507
1635
                pos=start+data->start;
1508
1636
                lengthFound=len;
1509
 
                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
 
1637
                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
1510
1638
                {
1511
1639
                    text=text.Mid(1);
1512
1640
                    if (re.Matches(text))
1513
1641
                    {
1514
 
                        size_t start,len;
1515
 
                        re.GetMatch(&start,&len,0);
1516
 
                        pos=start+data->start+1;
1517
 
                        lengthFound=len;
 
1642
                        re.GetMatch(&start, &len, 0);
 
1643
                        pos = start+data->start + 1;
 
1644
                        lengthFound = len;
1518
1645
                    } else
1519
1646
                        pos=-1;
1520
1647
                }
1521
1648
            } else
1522
1649
                pos=-1;
1523
1650
        }
 
1651
 
 
1652
        if (data->startFile && pos > 0)
 
1653
            pos = -1; // Not found at the beginning of file
 
1654
 
1524
1655
        if (pos != -1 && data->start!=data->end)
1525
1656
        {
1526
1657
            control->GotoPos(pos);
1543
1674
 
1544
1675
                bool auto_wrap_around = data->autoWrapSearch;
1545
1676
                if (auto_wrap_around)
1546
 
                    wxBell();
 
1677
                    wrapAroundNotification = true;
1547
1678
                if (auto_wrap_around || cbMessageBox(msg, _("Result"), wxOK | wxCANCEL | wxICON_QUESTION) == wxID_OK)
1548
1679
                {
1549
1680
                    data->end = data_start_initial;
1560
1691
        else
1561
1692
            break; // done - already wrapped around once
1562
1693
 
 
1694
        if (wrapAroundNotification)
 
1695
        {
 
1696
            wxBell();
 
1697
            InfoWindow::Display(_("Find action"), _("Reached the end of the document"), 1000);
 
1698
            wrapAroundNotification = false;
 
1699
        }
 
1700
 
1563
1701
        foundcount++;
1564
1702
 
1565
1703
        if (confirm)
1594
1732
            case crAll:
1595
1733
                replace = true;
1596
1734
                confirm = false;
 
1735
                control->Freeze();
1597
1736
                break;
1598
1737
            case crCancel:
1599
1738
                stop = true;
1600
1739
                break;
 
1740
            default:
 
1741
                break;
1601
1742
            }
1602
1743
        }
1603
1744
 
1612
1753
                    // set target same as selection
1613
1754
                    control->SetTargetStart(control->GetSelectionStart());
1614
1755
                    control->SetTargetEnd(control->GetSelectionEnd());
1615
 
                    if (AdvRegex)
 
1756
                    if (advRegex)
1616
1757
                    {
1617
1758
                        wxString text=control->GetSelectedText();
1618
1759
                        re.Replace(&text,data->replaceText,1);
1619
1760
                        lengthReplace=text.Len();
1620
1761
                        control->ReplaceSelection(text);
1621
1762
                    }
1622
 
                                        else
 
1763
                    else
1623
1764
                    {
1624
1765
                        // replace with regEx support
1625
1766
                        lengthReplace = control->ReplaceTargetRE(data->replaceText);
1647
1788
                }
1648
1789
            }
1649
1790
            else
1650
 
                        {
 
1791
            {
1651
1792
                if (data->directionDown)
1652
1793
                    data->start += lengthFound;
1653
1794
                else
1654
1795
                    data->start -= lengthFound;
1655
 
                        }
 
1796
            }
1656
1797
        }
1657
1798
    }
 
1799
    if (control->IsFrozen())
 
1800
        control->Thaw();
1658
1801
    control->EndUndoAction();
1659
1802
    wxString msg;
1660
1803
    if (foundcount == 0)
1674
1817
    if (!data) return 0;
1675
1818
    if (data->findText.IsEmpty()) return 0;
1676
1819
 
 
1820
    bool IsMultiLine = data->IsMultiLine();
 
1821
 
1677
1822
    // let's make a list of all the files to search in
1678
1823
    wxArrayString filesList;
1679
1824
 
1690
1835
    else if (data->scope == 1) // find in project files
1691
1836
    {
1692
1837
        // fill the search list with all the project files
1693
 
        cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
1694
 
        if (!prj)
 
1838
        if (data->searchProject<0)
 
1839
        {
 
1840
            cbMessageBox(_("No project to search in!"), _("Error"), wxICON_WARNING);
1695
1841
            return 0;
1696
 
 
 
1842
        }
 
1843
        cbProject* prj = (*Manager::Get()->GetProjectManager()->GetProjects())[data->searchProject];
 
1844
        wxString target;
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)
1699
1849
        {
1700
 
            ProjectFile* pf = prj->GetFile(i);
 
1850
            ProjectFile* pf = *it;
1701
1851
            if (pf)
1702
1852
            {
 
1853
                if (target!=wxEmptyString && pf->buildTargets.Index(target)<0)
 
1854
                    continue;
1703
1855
                fullpath = pf->file.GetFullPath();
1704
 
                if (filesList.Index(fullpath) == -1) // avoid adding duplicates
1705
 
                {
1706
 
                    if (wxFileExists(fullpath))  // Does the file exist?
1707
 
                        filesList.Add(fullpath);
1708
 
                }
 
1856
                if (filesList.Index(fullpath) >= 0) // avoid adding duplicates
 
1857
                    continue;
 
1858
                if (wxFileExists(fullpath))  // Does the file exist?
 
1859
                    filesList.Add(fullpath);
1709
1860
            }
1710
1861
        }
1711
1862
    }
1722
1873
                if (pProject)
1723
1874
                {
1724
1875
                    wxString fullpath = _T("");
1725
 
                    for (int idxFile = 0; idxFile < pProject->GetFilesCount(); ++idxFile)
 
1876
 
 
1877
                    for (FilesList::iterator it = pProject->GetFilesList().begin(); it != pProject->GetFilesList().end(); ++it)
1726
1878
                    {
1727
 
                        ProjectFile* pf = pProject->GetFile(idxFile);
 
1879
                        ProjectFile* pf = *it;
1728
1880
                        if (pf)
1729
1881
                        {
1730
1882
                            fullpath = pf->file.GetFullPath();
1739
1891
            } // end for : idx : idxProject
1740
1892
        }
1741
1893
    }
1742
 
 
 
1894
    else if (data->scope == 3) // replace in custom search path and mask
 
1895
     {
 
1896
        // fill the search list with the files found under the search path
 
1897
        int flags = wxDIR_FILES |
 
1898
                    (data->recursiveSearch ? wxDIR_DIRS : 0) |
 
1899
                    (data->hiddenSearch ? wxDIR_HIDDEN : 0);
 
1900
        wxArrayString masks = GetArrayFromString(data->searchMask);
 
1901
        if (!masks.GetCount())
 
1902
            masks.Add(_T("*"));
 
1903
        unsigned int count = masks.GetCount();
 
1904
        wxLogNull ln; // no logging
 
1905
        for (unsigned int i = 0; i < count; ++i)
 
1906
        {
 
1907
            // wxDir::GetAllFiles() does *not* clear the array, so it suits us just fine ;)
 
1908
            wxDir::GetAllFiles(data->searchPath, &filesList, masks[i], flags);
 
1909
        }
 
1910
    }
1743
1911
    // if the list is empty, leave
1744
1912
    int filesCount = filesList.GetCount();
1745
1913
    if (filesCount == 0)
1748
1916
        return 0;
1749
1917
    }
1750
1918
 
1751
 
    bool AdvRegex=false;
 
1919
    bool advRegex=false;
 
1920
    bool advRegexNewLinePolicy =! data->IsMultiLine();
1752
1921
    int flags = 0;
1753
1922
    if (data->matchWord)
1754
1923
        flags |= wxSCI_FIND_WHOLEWORD;
1762
1931
        if (Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_posix_style_regexes"), false))
1763
1932
            flags |= wxSCI_FIND_POSIX;
1764
1933
        #ifdef wxHAS_REGEX_ADVANCED
1765
 
        AdvRegex=Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
 
1934
        advRegex = Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
1766
1935
        #endif
1767
1936
    }
1768
1937
 
1769
1938
    wxRegEx re;
1770
1939
    #ifdef wxHAS_REGEX_ADVANCED
1771
 
    if (AdvRegex)
 
1940
    if (advRegex)
1772
1941
    {
1773
1942
        if (data->matchCase)
1774
 
            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE);
 
1943
            re.Compile(data->findText,wxRE_ADVANCED|(wxRE_NEWLINE*advRegexNewLinePolicy));
1775
1944
        else
1776
 
            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE|wxRE_ICASE);
 
1945
            re.Compile(data->findText,wxRE_ADVANCED|(wxRE_NEWLINE*advRegexNewLinePolicy)|wxRE_ICASE);
1777
1946
    }
1778
1947
    #endif
1779
1948
 
1799
1968
    int read_only_files_skipped = 0;
1800
1969
    for (int i = 0; i<filesCount && !stop; ++i)
1801
1970
    {
1802
 
        cbEditor *ed = NULL;
1803
 
        cbStyledTextCtrl *control = NULL;
 
1971
        cbEditor*         ed      = NULL;
 
1972
        cbStyledTextCtrl* control = NULL;
1804
1973
        bool fileWasNotOpen = false;
1805
1974
 
1806
1975
        if (progress)
1832
2001
            if (!file.IsOpened())
1833
2002
                continue;
1834
2003
            fileContents = cbReadFileContents(file, def_encoding);
1835
 
            if (fileContents.Find(data->findText) == -1)
1836
 
                continue;
 
2004
            if (advRegex)
 
2005
            {
 
2006
                if (!re.Matches(fileContents))
 
2007
                    continue;
 
2008
            } else
 
2009
            {
 
2010
                int pos;
 
2011
                if (!data->matchCase)
 
2012
                    pos = fileContents.Upper().Find(data->findText.Upper());
 
2013
                else
 
2014
                    pos = fileContents.Find(data->findText);
 
2015
                if (pos == -1)
 
2016
                    continue;
 
2017
                //TODO: handling to skip file if data->matchWord or data->startWord are set
 
2018
            }
1837
2019
 
1838
2020
            //File was not open, i opened it.
1839
2021
            fileWasNotOpen = true;
1852
2034
        }
1853
2035
 
1854
2036
        SetActiveEditor(ed);
1855
 
        control->BeginUndoAction(); //undo
1856
2037
 
1857
2038
        *data = dataCopy;
 
2039
 
 
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.
 
2044
 
 
2045
        {
 
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);
 
2050
 
 
2051
            if (IsMultiLine && data->fixEOLs)
 
2052
            {
 
2053
                control->BeginUndoAction(); //undo
 
2054
                control->SetChangeCollection(false);
 
2055
                control->ConvertEOLs(eolMode);
 
2056
                control->SetChangeCollection(true);
 
2057
                control->EndUndoAction();
 
2058
            }
 
2059
        }
 
2060
 
 
2061
        control->BeginUndoAction(); // undo
1858
2062
        CalculateFindReplaceStartEnd(control, data, true);
1859
2063
 
1860
2064
        //reset bools
1862
2066
        if (!all) confirm = true;
1863
2067
 
1864
2068
        //Replace in this file
1865
 
        while(!stop || wholeFile)
 
2069
        while (!stop || wholeFile)
1866
2070
        {
1867
2071
            int lengthFound = 0;
1868
 
            if (!AdvRegex)
 
2072
            if (!advRegex)
1869
2073
                pos = control->FindText(data->start, data->end, data->findText, flags, &lengthFound);
1870
2074
            else
1871
2075
            {
1873
2077
                if (re.Matches(text))
1874
2078
                {
1875
2079
                    size_t start,len;
1876
 
                    re.GetMatch(&start,&len,0);
1877
 
                    pos=start+data->start;
1878
 
                    lengthFound=len;
1879
 
                    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
 
2080
                    re.GetMatch(&start, &len, 0);
 
2081
                    pos = start + data->start;
 
2082
                    lengthFound = len;
 
2083
                    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
1880
2084
                    {
1881
 
                        text=text.Mid(1);
 
2085
                        text = text.Mid(1);
1882
2086
                        if (re.Matches(text))
1883
2087
                        {
1884
 
                            size_t start,len;
1885
 
                            re.GetMatch(&start,&len,0);
1886
 
                            pos=start+data->start+1;
1887
 
                            lengthFound=len;
 
2088
                            re.GetMatch(&start, &len, 0);
 
2089
                            pos = start + data->start + 1;
 
2090
                            lengthFound = len;
1888
2091
                        } else
1889
 
                            pos=-1;
 
2092
                            pos = -1;
1890
2093
                    }
1891
2094
                } else
1892
 
                    pos=-1;
 
2095
                    pos = -1;
1893
2096
            }
1894
2097
 
1895
 
            if (pos == -1 || data->start==data->end)
 
2098
            if (data->startFile && (pos > 0))
 
2099
                pos = -1; // Not found at the beginning of file
 
2100
 
 
2101
            if ((pos == -1) || (data->start == data->end))
1896
2102
                break;
1897
2103
 
1898
2104
            if (confirm)
1934
2140
                        replace = false;
1935
2141
                        break;
1936
2142
                    case crAllInFile:
1937
 
                        confirm = false;
1938
 
                        replace = true;
 
2143
                        confirm   = false;
 
2144
                        replace   = true;
1939
2145
                        wholeFile = true;
1940
2146
                        break;
1941
2147
                    case crSkipFile:
1942
 
                        confirm = false;
1943
 
                        replace = false;
 
2148
                        confirm   = false;
 
2149
                        replace   = false;
1944
2150
                        wholeFile = true;
1945
2151
                        break;
1946
2152
                    case crAll:
1947
2153
                        replace = true;
1948
2154
                        confirm = false;
1949
 
                        all = true;
 
2155
                        all     = true;
1950
2156
                        // let's create a progress dialog because it might take some time depending on the files count
1951
2157
                        progress = new wxProgressDialog(_("Replace in files"),
1952
2158
                                     _("Please wait while replacing in files..."),
1960
2166
                    case crCancel:
1961
2167
                        stop = true;
1962
2168
                        break;
 
2169
                    default:
 
2170
                        break;
1963
2171
                }
1964
2172
            }// if
1965
2173
 
1967
2175
            {
1968
2176
                if (replace)
1969
2177
                {
 
2178
                    replacementsWereMade = true;
1970
2179
                    int lengthReplace = data->replaceText.Length();
1971
2180
                    if (data->regEx)
1972
2181
                    {
1973
2182
                        // set target same as selection
1974
2183
                        control->SetTargetStart(control->GetSelectionStart());
1975
2184
                        control->SetTargetEnd(control->GetSelectionEnd());
1976
 
                        if (AdvRegex)
 
2185
                        if (advRegex)
1977
2186
                        {
1978
2187
                            wxString text=control->GetSelectedText();
1979
2188
                            re.Replace(&text,data->replaceText,1);
1980
2189
                            lengthReplace=text.Len();
1981
2190
                            control->ReplaceSelection(text);
1982
 
                        } else
1983
 
                        {
1984
 
                            // replace with regEx support
 
2191
                        }
 
2192
                        else // replace with regEx support
1985
2193
                            lengthReplace = control->ReplaceTargetRE(data->replaceText);
1986
 
                        }
 
2194
 
1987
2195
                        // reset target
1988
2196
                        control->SetTargetStart(0);
1989
2197
                        control->SetTargetEnd(0);
1994
2202
                    data->start += lengthReplace;
1995
2203
 
1996
2204
                    // adjust end pos by adding the length difference
1997
 
                    //between find and replace strings
 
2205
                    // between find and replace strings
1998
2206
                    int diff = lengthReplace - lengthFound;
1999
2207
                    if (data->directionDown)
2000
2208
                        data->end += diff;
2013
2221
 
2014
2222
        control->EndUndoAction(); // undo
2015
2223
 
2016
 
        //If i opened the file and no replacement was made,
2017
 
        //close the editor
2018
 
        if (!ed->GetModified() && fileWasNotOpen)
 
2224
        // If opened the file and no replacement was made, close the editor
 
2225
        if (!replacementsWereMade && fileWasNotOpen)
2019
2226
            Close(ed, true);
2020
2227
    }// for
2021
2228
 
2031
2238
        Manager::Get()->GetAppWindow()->Thaw();
2032
2239
 
2033
2240
    delete progress;
 
2241
    AnnoyingDialog dlg(_("Replace in files"),
 
2242
                       _("Replace in files has finished all operations."),
 
2243
                       wxART_INFORMATION, AnnoyingDialog::OK, wxID_OK);
 
2244
    dlg.ShowModal();
 
2245
 
2034
2246
    return pos;
2035
2247
}
2036
2248
 
2039
2251
    if (!control || !data)
2040
2252
        return -1;
2041
2253
 
2042
 
    bool AdvRegex=false;
 
2254
    bool advRegex = false;
 
2255
    bool advRegexNewLinePolicy =! data->IsMultiLine();
2043
2256
    int flags = 0;
 
2257
    data->ConvertEOLs(control->GetEOLMode());
2044
2258
    CalculateFindReplaceStartEnd(control, data);
2045
2259
 
2046
2260
    if (data->matchWord)
2055
2269
        if (Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_posix_style_regexes"), false))
2056
2270
            flags |= wxSCI_FIND_POSIX;
2057
2271
        #ifdef wxHAS_REGEX_ADVANCED
2058
 
        AdvRegex=Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
 
2272
        advRegex = Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_advanced_regexes"), false);
2059
2273
        #endif
2060
2274
    }
2061
2275
 
2062
2276
    wxRegEx re;
2063
2277
    #ifdef wxHAS_REGEX_ADVANCED
2064
 
    if (AdvRegex)
 
2278
    if (advRegex)
2065
2279
    {
2066
2280
        if (data->matchCase)
2067
 
            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE);
 
2281
            re.Compile(data->findText,wxRE_ADVANCED|(wxRE_NEWLINE*advRegexNewLinePolicy));
2068
2282
        else
2069
 
            re.Compile(data->findText,wxRE_ADVANCED|wxRE_NEWLINE|wxRE_ICASE);
 
2283
            re.Compile(data->findText,wxRE_ADVANCED|(wxRE_NEWLINE*advRegexNewLinePolicy)|wxRE_ICASE);
2070
2284
    }
2071
2285
    #endif
2072
2286
 
2080
2294
        StartPos = data->SearchInSelectionStart;
2081
2295
        EndPos = data->SearchInSelectionEnd;
2082
2296
    }
 
2297
    bool wrapAroundNotification = false;
2083
2298
    while (true) // loop while not found and user selects to start again from the top
2084
2299
    {
2085
2300
        int lengthFound = 0;
2086
 
        if (!AdvRegex)
 
2301
        if (!advRegex)
2087
2302
            pos = control->FindText(data->start, data->end, data->findText, flags, &lengthFound);
2088
2303
        else
2089
2304
        {
2090
 
            wxString text=control->GetTextRange(data->start, data->end);
 
2305
            wxString text = control->GetTextRange(data->start, data->end);
2091
2306
            if (re.Matches(text))
2092
2307
            {
2093
 
                size_t start,len;
2094
 
                re.GetMatch(&start,&len,0);
2095
 
                pos=start+data->start;
2096
 
                lengthFound=len;
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
 
2308
                size_t start, len;
 
2309
                re.GetMatch(&start, &len, 0);
 
2310
                pos = start + data->start;
 
2311
                lengthFound = len;
 
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
2098
2313
                {
2099
 
                    text=text.Mid(1);
 
2314
                    text = text.Mid(1);
2100
2315
                    if (re.Matches(text))
2101
2316
                    {
2102
 
                        size_t start,len;
2103
 
                        re.GetMatch(&start,&len,0);
2104
 
                        pos=start+data->start+1;
2105
 
                        lengthFound=len;
 
2317
                        re.GetMatch(&start, &len, 0);
 
2318
                        pos = start + data->start + 1;
 
2319
                        lengthFound = len;
2106
2320
                    }
2107
 
                                        else
 
2321
                    else
2108
2322
                        pos=-1;
2109
2323
                }
2110
2324
            }
2111
 
                        else
 
2325
            else
2112
2326
                pos=-1;
2113
2327
        }
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;
2128
2342
            break; // done
2129
2343
        }
2130
2344
        else if (!wrapAround && !data->findInFiles) // for "find in files" we don't want to show messages
2131
2345
        {
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) )
2134
2348
            {
2135
2349
                wxString msg;
2136
2350
                if (!data->scope == 1) // selected text
2150
2364
 
2151
2365
                bool auto_wrap_around = data->autoWrapSearch;
2152
2366
                if (auto_wrap_around)
2153
 
                    wxBell();
 
2367
                    wrapAroundNotification = true;
 
2368
 
2154
2369
                if (auto_wrap_around || cbMessageBox(msg, _("Result"), wxOK | wxCANCEL | wxICON_QUESTION) == wxID_OK)
2155
2370
                {
2156
2371
                    wrapAround = true; // signal the wrap-around
2190
2405
                msg.Printf(_("Not found: %s"), data->findText.c_str());
2191
2406
                cbMessageBox(msg, _("Result"), wxICON_INFORMATION);
2192
2407
                control->SetSCIFocus(true);
 
2408
                wrapAroundNotification = false;
2193
2409
                break; // done
2194
2410
            }
2195
2411
        }
2198
2414
            wxString msg;
2199
2415
            msg.Printf(_("Not found: %s"), data->findText.c_str());
2200
2416
            cbMessageBox(msg, _("Result"), wxICON_INFORMATION);
 
2417
            wrapAroundNotification = false;
2201
2418
            break; // done
2202
2419
        }
2203
2420
        else
2204
2421
            break; // done
2205
2422
    }
 
2423
 
 
2424
    if (wrapAroundNotification)
 
2425
    {
 
2426
        wxBell();
 
2427
        InfoWindow::Display(_("Find action"), _("Reached the end of the document"), 1000);
 
2428
    }
 
2429
 
2206
2430
    return pos;
2207
2431
}
2208
2432
 
2234
2458
    else if (data->scope == 1) // find in project files
2235
2459
    {
2236
2460
        // fill the search list with all the project files
2237
 
        cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
2238
 
        if (!prj)
 
2461
        if(data->searchProject<0)
2239
2462
        {
2240
2463
            cbMessageBox(_("No project to search in!"), _("Error"), wxICON_WARNING);
2241
2464
            return 0;
2242
2465
        }
2243
 
 
 
2466
        cbProject* prj = (*Manager::Get()->GetProjectManager()->GetProjects())[data->searchProject];
 
2467
        wxString target;
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)
2246
2472
        {
2247
 
            ProjectFile* pf = prj->GetFile(i);
 
2473
            ProjectFile* pf = *it;
2248
2474
            if (pf)
2249
2475
            {
 
2476
                if(target!=wxEmptyString && pf->buildTargets.Index(target)<0)
 
2477
                    continue;
2250
2478
                fullpath = pf->file.GetFullPath();
2251
 
                if (filesList.Index(fullpath) == -1) // avoid adding duplicates
2252
 
                {
2253
 
                    if (wxFileExists(fullpath))  // Does the file exist?
2254
 
                        filesList.Add(fullpath);
2255
 
                }
 
2479
                if (filesList.Index(fullpath) >= 0) // avoid adding duplicates
 
2480
                    continue;
 
2481
                if (wxFileExists(fullpath))  // Does the file exist?
 
2482
                    filesList.Add(fullpath);
2256
2483
            }
2257
2484
        }
2258
2485
    }
2274
2501
            if (pProject)
2275
2502
            {
2276
2503
                wxString fullpath = _T("");
2277
 
                for (int idxFile = 0; idxFile < pProject->GetFilesCount(); ++idxFile)
 
2504
                for (FilesList::iterator it = pProject->GetFilesList().begin(); it != pProject->GetFilesList().end(); ++it)
2278
2505
                {
2279
 
                    ProjectFile* pf = pProject->GetFile(idxFile);
 
2506
                    ProjectFile* pf = *it;
2280
2507
                    if (pf)
2281
2508
                    {
2282
2509
                        fullpath = pf->file.GetFullPath();
2307
2534
            wxDir::GetAllFiles(data->searchPath, &filesList, masks[i], flags);
2308
2535
        }
2309
2536
    }
 
2537
    else if (data->scope == 4) // find in current file only
 
2538
    {
 
2539
        cbEditor* ed = GetBuiltinActiveEditor();
 
2540
        if (ed)
 
2541
            filesList.Add(ed->GetFilename());
 
2542
    }
 
2543
 
2310
2544
 
2311
2545
    // if the list is empty, leave
2312
2546
    if (filesList.GetCount() == 0)
2315
2549
        return 0;
2316
2550
    }
2317
2551
 
 
2552
    // sort search results alphabetically if option is on
 
2553
    if (m_LastFindReplaceData->sortSearchResult)
 
2554
        filesList.Sort();
 
2555
 
2318
2556
    // now that list is filled, we'll search
2319
2557
    // but first we'll create a hidden cbStyledTextCtrl to do the search for us ;)
2320
2558
    cbStyledTextCtrl* control = new cbStyledTextCtrl(m_pNotebook, -1, wxDefaultPosition, wxSize(0, 0));
2404
2642
 
2405
2643
    if (count > 0)
2406
2644
    {
2407
 
        static_cast<SearchResultsLog*>(m_pSearchLog)->SetBasePath(data->searchPath);
 
2645
        m_pSearchLog->SetBasePath(data->searchPath);
2408
2646
        if (Manager::Get()->GetConfigManager(_T("message_manager"))->ReadBool(_T("/auto_show_search"), true))
2409
2647
        {
2410
2648
            CodeBlocksLogEvent evtSwitch(cbEVT_SWITCH_TO_LOG_WINDOW, m_pSearchLog);
2413
2651
            Manager::Get()->ProcessEvent(evtSwitch);
2414
2652
            Manager::Get()->ProcessEvent(evtShow);
2415
2653
        }
2416
 
        static_cast<SearchResultsLog*>(m_pSearchLog)->FocusEntry(oldcount);
 
2654
        m_pSearchLog->FocusEntry(oldcount);
2417
2655
    }
2418
2656
    else
2419
2657
    {
2428
2666
        }
2429
2667
        else
2430
2668
        {
2431
 
            msg.Printf(_("not found in %d files"), filesList.GetCount());
 
2669
            msg.Printf(_("not found in %lu files"), static_cast<unsigned long>(filesList.GetCount()));
2432
2670
            LogSearch(_T(""), -1, msg );
2433
 
            static_cast<SearchResultsLog*>(m_pSearchLog)->FocusEntry(oldcount);
 
2671
            m_pSearchLog->FocusEntry(oldcount);
2434
2672
        }
2435
2673
    }
2436
2674
 
2445
2683
        if (ed)
2446
2684
            control = ed->GetControl();
2447
2685
    }
 
2686
 
2448
2687
    if (!control)
2449
2688
        return -1;
2450
2689
 
2451
2690
    if (!data)
2452
2691
    {
2453
2692
        data = m_LastFindReplaceData;
2454
 
        //FindNext/Previous called from Search menu (F3/Shift-F3)
 
2693
        // FindNext/Previous called from Search menu (F3/Shift-F3)
2455
2694
        if (data) data->findInFiles = false;
2456
2695
    }
2457
2696
 
2496
2735
        ed->Split(cbEditor::stVertical);
2497
2736
    else if (id == idNBTabUnsplit && ed)
2498
2737
        ed->Unsplit();
 
2738
    else if (id >= idNBSwitchFile1 && id <= idNBSwitchFileMax)
 
2739
    {
 
2740
        eb = GetEditor(id - idNBSwitchFile1);
 
2741
        if (eb)
 
2742
            SetActiveEditor(eb);
 
2743
    }
2499
2744
}
2500
2745
 
2501
2746
void EditorManager::OnPageChanged(wxAuiNotebookEvent& event)
2502
2747
{
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()));
 
2752
 
 
2753
    CodeBlocksEvent evt(cbEVT_EDITOR_SWITCHED, -1, 0, eb, 0, eb_old);
2505
2754
    Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
2506
2755
 
 
2756
    CodeBlocksEvent evt2(cbEVT_EDITOR_ACTIVATED, -1, 0, eb);
 
2757
    Manager::Get()->GetPluginManager()->NotifyPlugins(evt2);
 
2758
 
 
2759
    if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/tabs_stacked_based_switching")))
 
2760
    {
 
2761
        wxWindow*        wnd;
 
2762
        cbNotebookStack* body;
 
2763
        cbNotebookStack* tmp;
 
2764
        wnd = m_pNotebook->GetPage(event.GetSelection());
 
2765
        for (body = m_pNotebookStackHead; body->next != 0; body = body->next)
 
2766
        {
 
2767
            if (wnd == body->next->window)
 
2768
            {
 
2769
                if (m_pNotebookStackTail == body->next)
 
2770
                    m_pNotebookStackTail = body;
 
2771
                tmp = body->next;
 
2772
                body->next = tmp->next;
 
2773
                tmp->next = m_pNotebookStackHead->next;
 
2774
                m_pNotebookStackHead->next = tmp;
 
2775
                break;
 
2776
            }
 
2777
        }
 
2778
        if (   (m_pNotebookStackHead->next == 0)
 
2779
            || (wnd != m_pNotebookStackHead->next->window) )
 
2780
        {
 
2781
            body = new cbNotebookStack(wnd);
 
2782
            body->next = m_pNotebookStackHead->next;
 
2783
            m_pNotebookStackHead->next = body;
 
2784
            ++m_nNotebookStackSize;
 
2785
        }
 
2786
    }
 
2787
 
2507
2788
    // focus editor on next update event
2508
2789
    m_pData->m_SetFocusFlag = true;
2509
2790
 
2525
2806
void EditorManager::OnPageClose(wxAuiNotebookEvent& event)
2526
2807
{
2527
2808
    int sel = event.GetSelection();
 
2809
    bool doClose = false;
 
2810
    EditorBase* eb = nullptr;
2528
2811
    if (sel != -1)
2529
2812
    {
2530
 
        EditorBase* eb = static_cast<EditorBase*>(m_pNotebook->GetPage(sel));
2531
 
        if (!QueryClose(eb))
2532
 
            event.Veto();
2533
 
    }
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
 
2814
        event.Veto();
 
2815
        eb = static_cast<EditorBase*>(m_pNotebook->GetPage(sel));
 
2816
        if (QueryClose(eb))
 
2817
        {
 
2818
            doClose = true;
 
2819
            if (m_pNotebook->GetPageCount()<=1)
 
2820
            {
 
2821
                CodeBlocksEvent evt(cbEVT_EDITOR_SWITCHED, -1, 0, 0, 0, eb);
 
2822
                Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
 
2823
            }
 
2824
        }
 
2825
    }
 
2826
 
 
2827
    if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/tabs_stacked_based_switching")))
 
2828
    {
 
2829
        wxWindow* wnd;
 
2830
        cbNotebookStack* body;
 
2831
        cbNotebookStack* tmp;
 
2832
        wnd = m_pNotebook->GetPage(event.GetSelection());
 
2833
        for (body = m_pNotebookStackHead; body->next != 0; body = body->next)
 
2834
        {
 
2835
            if (wnd == body->next->window)
 
2836
            {
 
2837
                tmp = body->next;
 
2838
                body->next = tmp->next;
 
2839
                delete tmp;
 
2840
                --m_nNotebookStackSize;
 
2841
                break;
 
2842
            }
 
2843
        }
 
2844
    }
 
2845
 
 
2846
    if (doClose && eb != nullptr)
 
2847
        Close(eb);
 
2848
    else
 
2849
        event.Skip(); // allow others to process it too
2535
2850
}
2536
2851
 
2537
2852
void EditorManager::OnPageContextMenu(wxAuiNotebookEvent& event)
2538
2853
{
2539
2854
    if (event.GetSelection() == -1)
2540
2855
        return;
 
2856
 
 
2857
    if (wxGetKeyState(WXK_CONTROL) && GetEditorsCount() > 1)
 
2858
    {
 
2859
        wxMenu* pop = new wxMenu;
 
2860
        EditorBase* current = GetActiveEditor();
 
2861
        for (int i = 0; i < EditorMaxSwitchTo && i < GetEditorsCount(); ++i)
 
2862
        {
 
2863
            EditorBase* other = GetEditor(i);
 
2864
            if (!other)
 
2865
                continue;
 
2866
            if (other == current)
 
2867
            {
 
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
 
2870
            }
 
2871
            else
 
2872
                pop->Append(idNBSwitchFile1 + i, other->GetShortName());
 
2873
        }
 
2874
        m_pNotebook->PopupMenu(pop);
 
2875
        delete pop;
 
2876
        return;
 
2877
    }
 
2878
 
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"));
2549
2887
    }
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"));
2558
 
 
 
2888
 
 
2889
    int any_modified = 0;
 
2890
    for (int i = 0; i<GetEditorsCount(); ++i)
 
2891
    {
 
2892
        EditorBase* ed = GetEditor(i);
 
2893
        if (ed && ed->GetModified())
 
2894
        {
 
2895
            if (++any_modified > 1)
 
2896
                break; // more than one editor is modified -> enable "Save all"
 
2897
        }
 
2898
    }
 
2899
    if (any_modified > 0)
 
2900
    {
 
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"));
 
2906
    }
 
2907
 
 
2908
    pop->AppendSeparator();
2559
2909
    cbEditor* ed = GetBuiltinEditor(event.GetSelection());
2560
2910
    if (ed)
2561
2911
    {
2562
 
        pop->AppendSeparator();
 
2912
        pop->Append(idNBSwapHeaderSource, _("Swap header/source"));
 
2913
        pop->Append(idNBTabOpenContainingFolder, _("Open containing folder"));
2563
2914
        pop->Append(idNBProperties, _("Properties..."));
2564
 
 
 
2915
        pop->AppendSeparator();
 
2916
    }
 
2917
 
 
2918
    if (Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/editor_tabs_bottom"), false))
 
2919
        pop->Append(idNBTabTop, _("Tabs at top"));
 
2920
    else
 
2921
        pop->Append(idNBTabBottom, _("Tabs at bottom"));
 
2922
 
 
2923
    if (ed)
 
2924
    {
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);
2573
 
 
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)
 
2931
        {
 
2932
            splitMenu->AppendSeparator();
 
2933
            splitMenu->Append(idNBTabUnsplit, _("Unsplit"));
 
2934
        }
2575
2935
        pop->Append(-1, _("Split view"), splitMenu);
2576
2936
 
2577
2937
        if (Manager::Get()->GetProjectManager()->GetActiveProject()) // project must be open
2578
2938
        {
2579
2939
            pop->AppendSeparator();
2580
2940
 
2581
 
            if (ed->GetProjectFile())
 
2941
            ProjectFile *projectFile = ed->GetProjectFile();
 
2942
            if (projectFile)
 
2943
            {
2582
2944
                pop->Append(idNBRemoveFileFromProject, _("Remove file from project"));
 
2945
                pop->Append(idNBShowFileInTree, _("Show file in the project tree"));
 
2946
            }
2583
2947
            else
2584
2948
                pop->Append(idNBAddFileToProject, _("Add file to active project"));
2585
2949
        }
2586
2950
    }
2587
2951
 
2588
 
    bool any_modified = false;
2589
 
 
2590
 
    for(int i = 0; i < GetEditorsCount(); ++i)
2591
 
    {
2592
 
        EditorBase* ed = GetEditor(i);
2593
 
        if (ed && ed->GetModified())
2594
 
        {
2595
 
            any_modified = true;
2596
 
            break;
2597
 
        }
2598
 
    }
2599
 
 
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);
2602
2954
 
2603
2955
    m_pNotebook->PopupMenu(pop);
2604
2956
    delete pop;
2605
2957
}
2606
2958
 
2607
 
void EditorManager::OnClose(wxCommandEvent& event)
 
2959
void EditorManager::OnClose(cb_unused wxCommandEvent& event)
2608
2960
{
2609
2961
    Manager::Get()->GetEditorManager()->Close(GetActiveEditor());
2610
2962
}
2611
2963
 
2612
 
void EditorManager::OnCloseAll(wxCommandEvent& event)
 
2964
void EditorManager::OnCloseAll(cb_unused wxCommandEvent& event)
2613
2965
{
2614
2966
    Manager::Get()->GetEditorManager()->CloseAll();
2615
2967
}
2616
2968
 
2617
 
void EditorManager::OnCloseAllOthers(wxCommandEvent& event)
 
2969
void EditorManager::OnCloseAllOthers(cb_unused wxCommandEvent& event)
2618
2970
{
2619
2971
    Manager::Get()->GetEditorManager()->CloseAllExcept(GetActiveEditor());
2620
2972
}
2621
2973
 
2622
 
void EditorManager::OnSave(wxCommandEvent& event)
 
2974
void EditorManager::OnSave(cb_unused wxCommandEvent& event)
2623
2975
{
2624
2976
    Manager::Get()->GetEditorManager()->Save(m_pNotebook->GetSelection());
2625
2977
}
2626
2978
 
2627
 
void EditorManager::OnSaveAll(wxCommandEvent& event)
 
2979
void EditorManager::OnSaveAll(cb_unused wxCommandEvent& event)
2628
2980
{
2629
2981
    Manager::Get()->GetEditorManager()->SaveAll();
2630
2982
}
2631
2983
 
2632
 
void EditorManager::OnSwapHeaderSource(wxCommandEvent& event)
 
2984
void EditorManager::OnSwapHeaderSource(cb_unused wxCommandEvent& event)
2633
2985
{
2634
2986
    Manager::Get()->GetEditorManager()->SwapActiveHeaderSource();
2635
2987
}
2636
2988
 
 
2989
void EditorManager::OnOpenContainingFolder(cb_unused wxCommandEvent& event)
 
2990
{
 
2991
    Manager::Get()->GetEditorManager()->OpenContainingFolder();
 
2992
}
 
2993
 
2637
2994
void EditorManager::OnTabPosition(wxCommandEvent& event)
2638
2995
{
2639
2996
    long style = m_pNotebook->GetWindowStyleFlag();
2648
3005
    Manager::Get()->GetConfigManager(_T("app"))->Write(_T("/environment/editor_tabs_bottom"),       (bool)(style & wxAUI_NB_BOTTOM));
2649
3006
}
2650
3007
 
2651
 
void EditorManager::OnProperties(wxCommandEvent& event)
 
3008
void EditorManager::OnProperties(cb_unused wxCommandEvent& event)
2652
3009
{
2653
3010
    cbEditor* ed = GetBuiltinActiveEditor();
2654
3011
    ProjectFile* pf = 0;
2664
3021
    }
2665
3022
}
2666
3023
 
2667
 
void EditorManager::OnAddFileToProject(wxCommandEvent& event)
 
3024
void EditorManager::OnAddFileToProject(cb_unused wxCommandEvent& event)
2668
3025
{
2669
3026
    cbProject *project = Manager::Get()->GetProjectManager()->GetActiveProject();
2670
3027
    wxString fname = GetBuiltinActiveEditor()->GetFilename();
2678
3035
    }
2679
3036
}
2680
3037
 
2681
 
void EditorManager::OnRemoveFileFromProject(wxCommandEvent& event)
 
3038
void EditorManager::OnRemoveFileFromProject(cb_unused wxCommandEvent& event)
2682
3039
{
2683
3040
    ProjectFile* pf = GetBuiltinActiveEditor()->GetProjectFile();
2684
3041
    if (pf) // should be in any case, otherwise something went wrong between popup menu creation and here
2689
3046
    }
2690
3047
}
2691
3048
 
 
3049
void EditorManager::OnShowFileInTree(cb_unused wxCommandEvent& event)
 
3050
{
 
3051
    ProjectFile* pf = GetBuiltinActiveEditor()->GetProjectFile();
 
3052
    wxTreeCtrl* tree = Manager::Get()->GetProjectManager()->GetTree();
 
3053
    if (pf && tree) // should be in any case, otherwise something went wrong between popup menu creation and here
 
3054
    {
 
3055
        // first unselect previous selected item if any, needed because of wxTR_MULTIPLE flag
 
3056
        wxTreeItemId sel = Manager::Get()->GetProjectManager()->GetTreeSelection();
 
3057
        if (sel.IsOk())
 
3058
            tree->SelectItem(sel, false);
 
3059
 
 
3060
        const wxTreeItemId &itemId = pf->GetTreeItemId();
 
3061
        if (itemId.IsOk())
 
3062
        {
 
3063
            tree->EnsureVisible(itemId);
 
3064
            tree->SelectItem(itemId, true);
 
3065
        }
 
3066
    }
 
3067
}
 
3068
 
2692
3069
void EditorManager::OnAppDoneStartup(wxCommandEvent& event)
2693
3070
{
2694
3071
    event.Skip(); // allow others to process it too
2699
3076
    event.Skip(); // allow others to process it too
2700
3077
}
2701
3078
 
2702
 
void EditorManager::OnCheckForModifiedFiles(wxCommandEvent& event)
 
3079
void EditorManager::OnCheckForModifiedFiles(cb_unused wxCommandEvent& event)
2703
3080
{
2704
3081
    CheckForExternallyModifiedFiles();
2705
3082
}
2706
3083
 
2707
3084
void EditorManager::HideNotebook()
2708
3085
{
2709
 
    //    if (!this)
2710
 
    //        return;
2711
 
    //    if (m_pNotebook)
2712
 
    //        m_pNotebook->Hide();
2713
 
    //    m_pData->m_NeedsRefresh = false;
2714
 
    //    return;
 
3086
    if (m_pNotebook)
 
3087
        m_pNotebook->Hide();
2715
3088
}
2716
3089
 
2717
3090
void EditorManager::ShowNotebook()
2718
3091
{
2719
 
    //    if (!this)
2720
 
    //        return;
2721
 
    //    if (m_pNotebook)
2722
 
    //        m_pNotebook->Show();
2723
 
    //    m_pData->m_NeedsRefresh = true;
2724
 
    //    m_pData->InvalidateTree();
2725
 
    //    return;
 
3092
    if (m_pNotebook)
 
3093
        m_pNotebook->Show();
2726
3094
}
2727
3095
 
2728
3096
void EditorManager::OnUpdateUI(wxUpdateUIEvent& event)
2742
3110
    event.Skip();
2743
3111
}
2744
3112
 
 
3113
void EditorManager::CollectDefines(CodeBlocksEvent& event)
 
3114
{
 
3115
    cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
 
3116
    if (   !prj
 
3117
        || !Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/track_preprocessor"),  true)
 
3118
        || !Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/collect_prj_defines"), true) )
 
3119
    {
 
3120
        event.Skip();
 
3121
        return;
 
3122
    }
 
3123
 
 
3124
    wxArrayString compilerFlags = prj->GetCompilerOptions();
 
3125
    ProjectBuildTarget* tgt = prj->GetBuildTarget(prj->GetActiveBuildTarget());
 
3126
    FilesList* lst;
 
3127
    wxString id;
 
3128
    if (tgt)
 
3129
    {
 
3130
        AppendArray(tgt->GetCompilerOptions(), compilerFlags);
 
3131
        lst = &tgt->GetFilesList();
 
3132
        id  = tgt->GetCompilerID();
 
3133
    }
 
3134
    else
 
3135
    {
 
3136
        lst = &prj->GetFilesList();
 
3137
        id  = prj->GetCompilerID();
 
3138
    }
 
3139
 
 
3140
    Compiler* comp = CompilerFactory::GetCompiler(id); // get global flags
 
3141
    if (comp)
 
3142
        AppendArray(comp->GetCompilerOptions(), compilerFlags);
 
3143
 
 
3144
    wxArrayString defines;
 
3145
    for (size_t i = 0; i < compilerFlags.Count(); ++i)
 
3146
    {
 
3147
        if (   compilerFlags[i].StartsWith(wxT("-D"))
 
3148
            || compilerFlags[i].StartsWith(wxT("/D")) )
 
3149
        {
 
3150
            defines.Add(compilerFlags[i].Mid(2));
 
3151
        }
 
3152
        else if (compilerFlags[i].Find(wxT("`")) != wxNOT_FOUND)
 
3153
        {
 
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);
 
3158
        }
 
3159
        else if (   compilerFlags[i] == wxT("-ansi")
 
3160
                 || compilerFlags[i] == wxT("-std=c90")
 
3161
                 || compilerFlags[i] == wxT("-std=c++98"))
 
3162
        {
 
3163
            defines.Add(wxT("__STRICT_ANSI__"));
 
3164
        }
 
3165
    }
 
3166
 
 
3167
    defines.Add(wxT("__cplusplus"));
 
3168
    for (FilesList::iterator it = lst->begin(); it != lst->end(); ++it)
 
3169
    {
 
3170
        if ((*it)->relativeFilename.EndsWith(wxT(".c")))
 
3171
        {
 
3172
            defines.RemoveAt(defines.GetCount() - 1); // do not define '__cplusplus' if even a single C file is found
 
3173
            break;
 
3174
        }
 
3175
    }
 
3176
    if (id.Find(wxT("gcc")) != wxNOT_FOUND)
 
3177
    {
 
3178
        defines.Add(wxT("__GNUC__"));
 
3179
        defines.Add(wxT("__GNUG__"));
 
3180
    }
 
3181
    else if (id.Find(wxT("msvc")) != wxNOT_FOUND)
 
3182
    {
 
3183
        defines.Add(wxT("_MSC_VER"));
 
3184
        defines.Add(wxT("__VISUALC__"));
 
3185
    }
 
3186
    if (Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/platform_defines"), false))
 
3187
    {
 
3188
        if (platform::windows)
 
3189
        {
 
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)
 
3200
            {
 
3201
                defines.Add(wxT("_WIN64"));
 
3202
                defines.Add(wxT("__WIN64__"));
 
3203
            }
 
3204
        }
 
3205
        else if (platform::macosx)
 
3206
        {
 
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__"));
 
3212
        }
 
3213
        else if (platform::linux)
 
3214
        {
 
3215
            defines.Add(wxT("LINUX"));
 
3216
            defines.Add(wxT("linux"));
 
3217
            defines.Add(wxT("__linux"));
 
3218
            defines.Add(wxT("__linux__"));
 
3219
        }
 
3220
        else if (platform::freebsd)
 
3221
        {
 
3222
            defines.Add(wxT("FREEBSD"));
 
3223
            defines.Add(wxT("__FREEBSD__"));
 
3224
        }
 
3225
        else if (platform::netbsd)
 
3226
        {
 
3227
            defines.Add(wxT("NETBSD"));
 
3228
            defines.Add(wxT("__NETBSD__"));
 
3229
        }
 
3230
        else if (platform::openbsd)
 
3231
        {
 
3232
            defines.Add(wxT("OPENBSD"));
 
3233
            defines.Add(wxT("__OPENBSD__"));
 
3234
        }
 
3235
        else if (platform::darwin)
 
3236
        {
 
3237
            defines.Add(wxT("DARWIN"));
 
3238
            defines.Add(wxT("__APPLE__"));
 
3239
        }
 
3240
        else if (platform::solaris)
 
3241
        {
 
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__"));
 
3247
        }
 
3248
        if (platform::unix)
 
3249
        {
 
3250
            defines.Add(wxT("unix"));
 
3251
            defines.Add(wxT("__unix"));
 
3252
            defines.Add(wxT("__unix__"));
 
3253
            defines.Add(wxT("__UNIX__"));
 
3254
        }
 
3255
        if (platform::gtk)
 
3256
            defines.Add(wxT("__WXGTK__"));
 
3257
        if (platform::bits == 32)
 
3258
        {
 
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__"));
 
3265
        }
 
3266
        else if (platform::bits == 64)
 
3267
        {
 
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__"));
 
3273
        }
 
3274
    }
 
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++"));
 
3280
    event.Skip();
 
3281
}
 
3282
 
2745
3283
void EditorManager::SetZoom(int zoom)
2746
3284
{
2747
3285
    m_Zoom = zoom;