~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/plugins/codecompletion/coderefactoring.cpp

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
 
3
 * http://www.gnu.org/licenses/gpl-3.0.html
 
4
 *
 
5
 * $Revision: 10265 $
 
6
 * $Id: coderefactoring.cpp 10265 2015-05-15 10:56:43Z jenslody $
 
7
 * $HeadURL: http://svn.code.sf.net/p/codeblocks/code/branches/release-16.xx/src/plugins/codecompletion/coderefactoring.cpp $
 
8
 */
 
9
 
 
10
#include <sdk.h>
 
11
 
 
12
#ifndef CB_PRECOMP
 
13
    #include <wx/button.h>
 
14
    #include <wx/image.h>
 
15
    #include <wx/sizer.h>
 
16
    #include <wx/statbmp.h>
 
17
    #include <wx/stattext.h>
 
18
    #include <wx/textdlg.h>
 
19
 
 
20
    #include <cbeditor.h>
 
21
    #include <cbproject.h>
 
22
    #include <editorcolourset.h>
 
23
    #include <editormanager.h>
 
24
    #include <logmanager.h>
 
25
#endif
 
26
 
 
27
#include <wx/progdlg.h>
 
28
 
 
29
#include <cbstyledtextctrl.h>
 
30
#include <encodingdetector.h>
 
31
#include <searchresultslog.h>
 
32
 
 
33
#include "coderefactoring.h"
 
34
#include "nativeparser.h"
 
35
 
 
36
#define CC_CODEREFACTORING_DEBUG_OUTPUT 0
 
37
 
 
38
#if defined(CC_GLOBAL_DEBUG_OUTPUT)
 
39
    #if CC_GLOBAL_DEBUG_OUTPUT == 1
 
40
        #undef CC_CODEREFACTORING_DEBUG_OUTPUT
 
41
        #define CC_CODEREFACTORING_DEBUG_OUTPUT 1
 
42
    #elif CC_GLOBAL_DEBUG_OUTPUT == 2
 
43
        #undef CC_CODEREFACTORING_DEBUG_OUTPUT
 
44
        #define CC_CODEREFACTORING_DEBUG_OUTPUT 2
 
45
    #endif
 
46
#endif
 
47
 
 
48
#if CC_CODEREFACTORING_DEBUG_OUTPUT == 1
 
49
    #define TRACE(format, args...) \
 
50
        CCLogger::Get()->DebugLog(F(format, ##args))
 
51
    #define TRACE2(format, args...)
 
52
#elif CC_CODEREFACTORING_DEBUG_OUTPUT == 2
 
53
    #define TRACE(format, args...)                                              \
 
54
        do                                                                      \
 
55
        {                                                                       \
 
56
            if (g_EnableDebugTrace)                                             \
 
57
                CCLogger::Get()->DebugLog(F(format, ##args));                   \
 
58
        }                                                                       \
 
59
        while (false)
 
60
    #define TRACE2(format, args...) \
 
61
        CCLogger::Get()->DebugLog(F(format, ##args))
 
62
#else
 
63
    #define TRACE(format, args...)
 
64
    #define TRACE2(format, args...)
 
65
#endif
 
66
 
 
67
class ScopeDialog : public wxDialog
 
68
{
 
69
public:
 
70
    ScopeDialog(wxWindow* parent, const wxString& title) :
 
71
        wxDialog(parent, wxID_ANY, title)
 
72
    {
 
73
        wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
 
74
        wxBoxSizer* infoSizer = new wxBoxSizer(wxHORIZONTAL);
 
75
        wxString findImgFile = ConfigManager::GetDataFolder() + _T("/images/filefind.png");
 
76
        wxStaticBitmap* findIco = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(findImgFile)));
 
77
        infoSizer->Add(findIco, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
 
78
        wxStaticText* scopeText = new wxStaticText(this, wxID_ANY, _("Please choose the find scope for search tokens"));
 
79
        infoSizer->Add(scopeText, 1, wxALL | wxALIGN_CENTER_VERTICAL,
 
80
                       wxDLG_UNIT(this, wxSize(5, 0)).GetWidth());
 
81
        sizer->Add(infoSizer, 1, wxALL | wxALIGN_CENTER_HORIZONTAL, 5);
 
82
        wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
 
83
        m_OpenFiles = new wxButton(this, ID_OPEN_FILES, _("&Open files"), wxDefaultPosition, wxDefaultSize, 0,
 
84
                                   wxDefaultValidator, _T("ID_OPEN_FILES"));
 
85
        m_OpenFiles->SetDefault();
 
86
        btnSizer->Add(m_OpenFiles, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
 
87
        m_ProjectFiles = new wxButton(this, ID_PROJECT_FILES, _("&Project files"), wxDefaultPosition,
 
88
                                      wxDefaultSize, 0, wxDefaultValidator, _T("ID_PROJECT_FILES"));
 
89
        btnSizer->Add(m_ProjectFiles, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
 
90
        sizer->Add(btnSizer, 1, wxBOTTOM | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
 
91
        SetSizer(sizer);
 
92
        sizer->Fit(this);
 
93
        sizer->SetSizeHints(this);
 
94
        Center();
 
95
 
 
96
        Connect(ID_OPEN_FILES, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&ScopeDialog::OnOpenFilesClick);
 
97
        Connect(ID_PROJECT_FILES, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&ScopeDialog::OnProjectFilesClick);
 
98
        Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&ScopeDialog::OnClose);
 
99
    }
 
100
 
 
101
public:
 
102
    static const long ID_OPEN_FILES;
 
103
    static const long ID_PROJECT_FILES;
 
104
 
 
105
private:
 
106
    void OnClose(cb_unused wxCloseEvent& event) { EndDialog(wxID_CLOSE); }
 
107
    void OnOpenFilesClick(cb_unused wxCommandEvent& event) { EndDialog(ID_OPEN_FILES);}
 
108
    void OnProjectFilesClick(cb_unused wxCommandEvent& event) { EndDialog(ID_PROJECT_FILES); }
 
109
 
 
110
    wxButton* m_OpenFiles;
 
111
    wxButton* m_ProjectFiles;
 
112
};
 
113
 
 
114
const long ScopeDialog::ID_OPEN_FILES = wxNewId();
 
115
const long ScopeDialog::ID_PROJECT_FILES = wxNewId();
 
116
 
 
117
CodeRefactoring::CodeRefactoring(NativeParser& np) :
 
118
    m_NativeParser(np)
 
119
{
 
120
}
 
121
 
 
122
CodeRefactoring::~CodeRefactoring()
 
123
{
 
124
}
 
125
 
 
126
wxString CodeRefactoring::GetSymbolUnderCursor()
 
127
{
 
128
    EditorManager* edMan = Manager::Get()->GetEditorManager();
 
129
    cbEditor* editor = edMan->GetBuiltinActiveEditor();
 
130
    if (!editor)
 
131
        return wxEmptyString;
 
132
 
 
133
    cbStyledTextCtrl* control = editor->GetControl();
 
134
    const int style = control->GetStyleAt(control->GetCurrentPos());
 
135
    if (control->IsString(style) || control->IsComment(style))
 
136
        return wxEmptyString;
 
137
 
 
138
    if (!m_NativeParser.GetParser().Done())
 
139
    {
 
140
        wxString msg(_("The Parser is still parsing files."));
 
141
        cbMessageBox(msg, _("Code Refactoring"), wxOK | wxICON_WARNING);
 
142
        msg += m_NativeParser.GetParser().NotDoneReason();
 
143
        CCLogger::Get()->DebugLog(msg);
 
144
 
 
145
        return wxEmptyString;
 
146
    }
 
147
 
 
148
    const int pos = editor->GetControl()->GetCurrentPos();
 
149
    const int start = editor->GetControl()->WordStartPosition(pos, true);
 
150
    const int end = editor->GetControl()->WordEndPosition(pos, true);
 
151
    return editor->GetControl()->GetTextRange(start, end);
 
152
}
 
153
 
 
154
bool CodeRefactoring::Parse()
 
155
{
 
156
    cbEditor* editor = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
157
    if (!editor)
 
158
        return false;
 
159
 
 
160
    const wxString targetText = GetSymbolUnderCursor();
 
161
    if (targetText.IsEmpty())
 
162
        return false;
 
163
 
 
164
    TokenIdxSet targetResult;
 
165
    const int endOfWord = editor->GetControl()->WordEndPosition(editor->GetControl()->GetCurrentPos(), true);
 
166
    m_NativeParser.MarkItemsByAI(targetResult, true, false, true, endOfWord);
 
167
    if (targetResult.empty())
 
168
    {
 
169
        cbMessageBox(_("Symbol not found under cursor!"), _("Code Refactoring"), wxOK | wxICON_WARNING);
 
170
        return false;
 
171
    }
 
172
 
 
173
    // handle local variables
 
174
    bool isLocalVariable = false;
 
175
 
 
176
    TokenTree* tree = m_NativeParser.GetParser().GetTokenTree();
 
177
 
 
178
    CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)
 
179
 
 
180
    const Token* token = tree->at(*targetResult.begin());
 
181
    if (token)
 
182
    {
 
183
        const Token* parent = tree->at(token->m_ParentIndex);
 
184
        if (parent && parent->m_TokenKind == tkFunction)
 
185
            isLocalVariable = true;
 
186
    }
 
187
 
 
188
    CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
 
189
 
 
190
    wxArrayString files;
 
191
    cbProject* project = m_NativeParser.GetProjectByEditor(editor);
 
192
    if (isLocalVariable || !project)
 
193
        files.Add(editor->GetFilename());
 
194
    else
 
195
    {
 
196
        ScopeDialog scopeDlg(Manager::Get()->GetAppWindow(), _("Code Refactoring"));
 
197
        const int ret = scopeDlg.ShowModal();
 
198
        if (ret == ScopeDialog::ID_OPEN_FILES)
 
199
            GetOpenedFiles(files);
 
200
        else if (ret == ScopeDialog::ID_PROJECT_FILES)
 
201
            GetAllProjectFiles(files, project);
 
202
        else
 
203
            return false;
 
204
    }
 
205
 
 
206
    if (files.IsEmpty())
 
207
        return false;
 
208
 
 
209
    size_t count = SearchInFiles(files, targetText);
 
210
    if (count)
 
211
        count = VerifyResult(targetResult, targetText, isLocalVariable);
 
212
 
 
213
    return count != 0;
 
214
}
 
215
 
 
216
void CodeRefactoring::FindReferences()
 
217
{
 
218
    if (Parse())
 
219
        DoFindReferences();
 
220
}
 
221
 
 
222
void CodeRefactoring::RenameSymbols()
 
223
{
 
224
    const wxString targetText = GetSymbolUnderCursor();
 
225
    if (targetText.IsEmpty())
 
226
        return;
 
227
 
 
228
    wxString replaceText = wxGetTextFromUser(_("Rename symbols under cursor"),
 
229
                                             _("Code Refactoring"),
 
230
                                             targetText,
 
231
                                             Manager::Get()->GetAppWindow());
 
232
    if (!replaceText.IsEmpty() && replaceText != targetText && Parse())
 
233
    {
 
234
        DoRenameSymbols(targetText, replaceText);
 
235
        DoFindReferences();
 
236
    }
 
237
}
 
238
 
 
239
size_t CodeRefactoring::SearchInFiles(const wxArrayString& files, const wxString& targetText)
 
240
{
 
241
    EditorManager* edMan = Manager::Get()->GetEditorManager();
 
242
    m_SearchDataMap.clear();
 
243
 
 
244
    // now that list is filled, we'll search
 
245
    wxWindow* parent = edMan->GetBuiltinActiveEditor()->GetParent();
 
246
    cbStyledTextCtrl* control = new cbStyledTextCtrl(parent, wxID_ANY, wxDefaultPosition, wxSize(0, 0));
 
247
    control->Show(false);
 
248
 
 
249
    // let's create a progress dialog because it might take some time depending on the files count
 
250
    wxProgressDialog* progress = new wxProgressDialog(_("Code Refactoring"),
 
251
                                                      _("Please wait while searching inside the project..."),
 
252
                                                      files.GetCount(),
 
253
                                                      Manager::Get()->GetAppWindow(),
 
254
                                                      wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
 
255
    PlaceWindow(progress);
 
256
 
 
257
    for (size_t i = 0; i < files.GetCount(); ++i)
 
258
    {
 
259
        // update the progress bar
 
260
        if (!progress->Update(i))
 
261
            break; // user pressed "Cancel"
 
262
 
 
263
        // check if the file is already opened in built-in editor and do search in it
 
264
        cbEditor* ed = edMan->IsBuiltinOpen(files[i]);
 
265
        if (ed)
 
266
            control->SetText(ed->GetControl()->GetText());
 
267
        else // else load the file in the control
 
268
        {
 
269
            EncodingDetector detector(files[i]);
 
270
            if (!detector.IsOK())
 
271
                continue; // failed
 
272
            control->SetText(detector.GetWxStr());
 
273
        }
 
274
 
 
275
        Find(control, files[i], targetText);
 
276
    }
 
277
 
 
278
    delete control; // done with it
 
279
    delete progress; // done here too
 
280
 
 
281
    return m_SearchDataMap.size();
 
282
}
 
283
 
 
284
size_t CodeRefactoring::VerifyResult(const TokenIdxSet& targetResult, const wxString& targetText,
 
285
                                     bool isLocalVariable)
 
286
{
 
287
    EditorManager* edMan = Manager::Get()->GetEditorManager();
 
288
    cbEditor* editor = edMan->GetBuiltinActiveEditor();
 
289
    if (!editor)
 
290
        return 0;
 
291
 
 
292
    const Token* parentOfLocalVariable = nullptr;
 
293
    if (isLocalVariable)
 
294
    {
 
295
        TokenTree* tree = m_NativeParser.GetParser().GetTokenTree();
 
296
 
 
297
        CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)
 
298
 
 
299
        const Token* token = tree->at(*targetResult.begin());
 
300
        parentOfLocalVariable = tree->at(token->m_ParentIndex);
 
301
 
 
302
        CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
 
303
    }
 
304
 
 
305
    // now that list is filled, we'll search
 
306
    cbStyledTextCtrl* control = new cbStyledTextCtrl(editor->GetParent(), wxID_ANY, wxDefaultPosition,
 
307
                                                     wxSize(0, 0));
 
308
    control->Show(false);
 
309
 
 
310
    // styled the text to support control->GetStyleAt()
 
311
    cbEditor::ApplyStyles(control);
 
312
    EditorColourSet edColSet;
 
313
 
 
314
    size_t totalCount = 0;
 
315
    for (SearchDataMap::const_iterator it = m_SearchDataMap.begin(); it != m_SearchDataMap.end(); ++it)
 
316
        totalCount += it->second.size();
 
317
 
 
318
    // let's create a progress dialog because it might take some time depending on the files count
 
319
    wxProgressDialog* progress = new wxProgressDialog(_("Code Refactoring"),
 
320
                                                      _("Please wait while verifying result..."),
 
321
                                                      totalCount,
 
322
                                                      Manager::Get()->GetAppWindow(),
 
323
                                                      wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
 
324
    PlaceWindow(progress);
 
325
 
 
326
    size_t task = totalCount;
 
327
    TokenIdxSet result;
 
328
    bool userBreak = false;
 
329
    for (SearchDataMap::iterator it = m_SearchDataMap.begin(); it != m_SearchDataMap.end();)
 
330
    {
 
331
        // check if the file is already opened in built-in editor and do search in it
 
332
        cbEditor* ed = edMan->IsBuiltinOpen(it->first);
 
333
        if (ed)
 
334
            control->SetText(ed->GetControl()->GetText());
 
335
        else // else load the file in the control
 
336
        {
 
337
            EncodingDetector detector(it->first);
 
338
            if (!detector.IsOK())
 
339
            {
 
340
                task -= it->second.size();
 
341
                m_SearchDataMap.erase(it++);
 
342
                continue; // failed
 
343
            }
 
344
            control->SetText(detector.GetWxStr());
 
345
        }
 
346
 
 
347
        // apply the corlor setting
 
348
        edColSet.Apply(editor->GetLanguage(), control);
 
349
 
 
350
        ccSearchData searchData = { control, it->first };
 
351
        for (SearchDataList::iterator itList = it->second.begin(); itList != it->second.end();)
 
352
        {
 
353
            // update the progress bar
 
354
            if (!progress->Update(totalCount - (--task)))
 
355
            {
 
356
                userBreak = true;
 
357
                break; // user pressed "Cancel"
 
358
            }
 
359
 
 
360
            // skip string or comment
 
361
            const int style = control->GetStyleAt(itList->pos);
 
362
            if (control->IsString(style) || control->IsComment(style))
 
363
            {
 
364
                it->second.erase(itList++);
 
365
                continue;
 
366
            }
 
367
 
 
368
            // do cc search
 
369
            const int endOfWord = itList->pos + targetText.Len();
 
370
            control->GotoPos(endOfWord);
 
371
            m_NativeParser.MarkItemsByAI(&searchData, result, true, false, true, endOfWord);
 
372
            if (result.empty())
 
373
            {
 
374
                it->second.erase(itList++);
 
375
                continue;
 
376
            }
 
377
 
 
378
            // verify result
 
379
            TokenIdxSet::const_iterator findIter = targetResult.begin();
 
380
            for (; findIter != targetResult.end(); ++findIter)
 
381
            {
 
382
                if (result.find(*findIter) != result.end())
 
383
                    break;
 
384
            }
 
385
 
 
386
            if (findIter == targetResult.end()) // not found
 
387
                it->second.erase(itList++);
 
388
            else
 
389
            {
 
390
                // handle for local variable
 
391
                if (isLocalVariable)
 
392
                {
 
393
                    bool do_continue = false;
 
394
 
 
395
                    TokenTree* tree = m_NativeParser.GetParser().GetTokenTree();
 
396
 
 
397
                    CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)
 
398
 
 
399
                    const Token* token = tree->at(*findIter);
 
400
                    if (token)
 
401
                    {
 
402
                        const Token* parent = tree->at(token->m_ParentIndex);
 
403
                        if (parent != parentOfLocalVariable)
 
404
                        {
 
405
                            it->second.erase(itList++);
 
406
                            do_continue = true;
 
407
                        }
 
408
                    }
 
409
 
 
410
                    CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
 
411
 
 
412
                    if (do_continue) continue;
 
413
                }
 
414
 
 
415
                ++itList;
 
416
            }
 
417
        }
 
418
 
 
419
        if (it->second.empty())
 
420
            m_SearchDataMap.erase(it++);
 
421
        else
 
422
            ++it;
 
423
 
 
424
        if (userBreak)
 
425
            break;
 
426
    }
 
427
 
 
428
    delete control; // done with it
 
429
    delete progress; // done here too
 
430
 
 
431
    return m_SearchDataMap.size();
 
432
}
 
433
 
 
434
void CodeRefactoring::Find(cbStyledTextCtrl* control, const wxString& file, const wxString& target)
 
435
{
 
436
    const int end = control->GetLength();
 
437
    int start = 0;
 
438
 
 
439
    for (;;)
 
440
    {
 
441
        int lengthFound;
 
442
        int pos = control->FindText(start, end, target, wxSCI_FIND_WHOLEWORD | wxSCI_FIND_MATCHCASE, &lengthFound);
 
443
        if (pos != wxSCI_INVALID_POSITION)
 
444
        {
 
445
            start = pos + lengthFound;
 
446
            const int line = control->LineFromPosition(pos);
 
447
            wxString text = control->GetLine(line).Trim(true).Trim(false);
 
448
            m_SearchDataMap[file].push_back(crSearchData(pos, line + 1, text));
 
449
        }
 
450
        else
 
451
            break;
 
452
    }
 
453
}
 
454
 
 
455
void CodeRefactoring::DoFindReferences()
 
456
{
 
457
    cbEditor* editor = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
458
    if (!editor)
 
459
        return;
 
460
 
 
461
    cbSearchResultsLog* searchLog = Manager::Get()->GetSearchResultLogger();
 
462
    if (!searchLog)
 
463
        return;
 
464
 
 
465
    const wxString focusFile = editor->GetFilename();
 
466
    const int focusLine = editor->GetControl()->GetCurrentLine() + 1;
 
467
    wxFileName fn(focusFile);
 
468
    const wxString basePath(fn.GetPath());
 
469
    size_t index = 0;
 
470
    size_t focusIndex = 0;
 
471
 
 
472
    searchLog->Clear();
 
473
    searchLog->SetBasePath(basePath);
 
474
 
 
475
    for (SearchDataMap::iterator it = m_SearchDataMap.begin(); it != m_SearchDataMap.end(); ++it)
 
476
    {
 
477
        for (SearchDataList::iterator itList = it->second.begin(); itList != it->second.end(); ++itList)
 
478
        {
 
479
            if (it->first == focusFile && itList->line == focusLine)
 
480
                focusIndex = index;
 
481
 
 
482
            wxArrayString values;
 
483
            wxFileName curFn(it->first);
 
484
            curFn.MakeRelativeTo(basePath);
 
485
            values.Add(curFn.GetFullPath());
 
486
            values.Add(wxString::Format(_T("%d"), itList->line));
 
487
            values.Add(itList->text);
 
488
            searchLog->Append(values, Logger::info);
 
489
 
 
490
            ++index;
 
491
        }
 
492
    }
 
493
 
 
494
    if (Manager::Get()->GetConfigManager(_T("message_manager"))->ReadBool(_T("/auto_show_search"), true))
 
495
    {
 
496
        CodeBlocksLogEvent evtSwitch(cbEVT_SWITCH_TO_LOG_WINDOW, searchLog);
 
497
        CodeBlocksLogEvent evtShow(cbEVT_SHOW_LOG_MANAGER);
 
498
        Manager::Get()->ProcessEvent(evtSwitch);
 
499
        Manager::Get()->ProcessEvent(evtShow);
 
500
    }
 
501
 
 
502
    searchLog->FocusEntry(focusIndex);
 
503
}
 
504
 
 
505
void CodeRefactoring::DoRenameSymbols(const wxString& targetText, const wxString& replaceText)
 
506
{
 
507
    EditorManager* edMan = Manager::Get()->GetEditorManager();
 
508
    cbEditor* editor = edMan->GetBuiltinActiveEditor();
 
509
    if (!editor)
 
510
        return;
 
511
 
 
512
    cbProject* project = m_NativeParser.GetProjectByEditor(editor);
 
513
    for (SearchDataMap::iterator it = m_SearchDataMap.begin(); it != m_SearchDataMap.end(); ++it)
 
514
    {
 
515
        // check if the file is already opened in built-in editor and do search in it
 
516
        cbEditor* ed = edMan->IsBuiltinOpen(it->first);
 
517
        if (!ed)
 
518
        {
 
519
            ProjectFile* pf = project ? project->GetFileByFilename(it->first) : 0;
 
520
            ed = edMan->Open(it->first, it->second.front().pos, pf);
 
521
        }
 
522
 
 
523
        cbStyledTextCtrl* control = ed->GetControl();
 
524
        control->BeginUndoAction();
 
525
 
 
526
        for (SearchDataList::reverse_iterator rIter = it->second.rbegin(); rIter != it->second.rend(); ++rIter)
 
527
        {
 
528
            control->SetTargetStart(rIter->pos);
 
529
            control->SetTargetEnd(rIter->pos + targetText.Len());
 
530
            control->ReplaceTarget(replaceText);
 
531
            // for find references
 
532
            rIter->text.Replace(targetText, replaceText);
 
533
        }
 
534
 
 
535
        control->EndUndoAction();
 
536
    }
 
537
}
 
538
 
 
539
void CodeRefactoring::GetAllProjectFiles(wxArrayString& files, cbProject* project)
 
540
{
 
541
    if (!project)
 
542
        return;
 
543
 
 
544
    // fill the search list with all the project files
 
545
    for (FilesList::const_iterator it = project->GetFilesList().begin();
 
546
                                   it != project->GetFilesList().end(); ++it)
 
547
    {
 
548
        ProjectFile* pf = *it;
 
549
        if (!pf)
 
550
            continue;
 
551
 
 
552
        ParserCommon::EFileType ft = ParserCommon::FileType(pf->relativeFilename);
 
553
        if (ft != ParserCommon::ftOther)
 
554
            files.Add(pf->file.GetFullPath());
 
555
    }
 
556
}
 
557
 
 
558
void CodeRefactoring::GetOpenedFiles(wxArrayString& files)
 
559
{
 
560
    EditorManager* edMan = Manager::Get()->GetEditorManager();
 
561
    if (edMan)
 
562
    {
 
563
        for (int i = 0; i < edMan->GetEditorsCount(); ++i)
 
564
            files.Add(edMan->GetEditor(i)->GetFilename());
 
565
    }
 
566
}