~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/plugins/contrib/codesnippets/editor/seditorbase.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 Lesser General Public License, version 3
 
3
 * http://www.gnu.org/licenses/lgpl-3.0.html
 
4
 *
 
5
 * $Revision: 7443 $
 
6
 * $Id: seditorbase.cpp 7443 2011-09-01 16:29:16Z mortenmacfly $
 
7
 * $HeadURL: http://svn.code.sf.net/p/codeblocks/code/branches/release-16.xx/src/plugins/contrib/codesnippets/editor/seditorbase.cpp $
 
8
 */
 
9
 
 
10
// Get rid of some precompile warnings when using sdk
 
11
// Stop following warning:
 
12
//warning: .../trunk/src/include/sdk_precomp.h.gch: not used because `EXPORT_LIB' not defined|
 
13
#undef CB_PRECOMP
 
14
 
 
15
#ifdef CB_PRECOMP
 
16
    #include "sdk_precomp.h"
 
17
#endif
 
18
 
 
19
#ifndef CB_PRECOMP
 
20
    #include <wx/filename.h>
 
21
    #include <wx/notebook.h>
 
22
    #include <wx/menu.h>
 
23
    #include <wx/textdlg.h> // wxGetTextFromUser
 
24
    #include <wx/wfstream.h>
 
25
 
 
26
    #include "manager.h"
 
27
    #include "seditorbase.h"
 
28
    #include "scbeditor.h"
 
29
    #include "seditormanager.h"
 
30
    #include "pluginmanager.h"
 
31
    #include "cbproject.h" // FileTreeData
 
32
#endif
 
33
 
 
34
#include <wx/xrc/xmlres.h>
 
35
 
 
36
#include "prep.h"
 
37
#include "scbeditor.h"
 
38
#include "seditorbase.h"
 
39
#include "seditormanager.h"
 
40
#include "cbstyledtextctrl.h"
 
41
#include "cbauibook.h"
 
42
#include "snippetsconfig.h"
 
43
// ----------------------------------------------------------------------------
 
44
//  resources
 
45
// ----------------------------------------------------------------------------
 
46
int idEditHighlightMode = XRCID("idEditHighlightMode");
 
47
int idEditHighlightModeText = XRCID("idEditHighlightModeText");
 
48
 
 
49
// needed for initialization of variables
 
50
// ----------------------------------------------------------------------------
 
51
int editorbase_RegisterId(int id)
 
52
// ----------------------------------------------------------------------------
 
53
{
 
54
    wxRegisterId(id);
 
55
    return id;
 
56
}
 
57
 
 
58
// ----------------------------------------------------------------------------
 
59
struct EditorBaseInternalData
 
60
// ----------------------------------------------------------------------------
 
61
{
 
62
        EditorBaseInternalData(SEditorBase* owner)
 
63
                : m_pOwner(owner),
 
64
                m_DisplayingPopupMenu(false),
 
65
                m_CloseMe(false)
 
66
        {}
 
67
 
 
68
        SEditorBase* m_pOwner;
 
69
        bool m_DisplayingPopupMenu;
 
70
        bool m_CloseMe;
 
71
};
 
72
 
 
73
// The following lines reserve 255 consecutive id's
 
74
const int EditorMaxSwitchTo = 255;
 
75
const int idSwitchFile1 = wxNewId();
 
76
const int idSwitchFileMax = editorbase_RegisterId(idSwitchFile1 + EditorMaxSwitchTo -1);
 
77
 
 
78
const int idCloseMe = wxNewId();
 
79
const int idCloseAll = wxNewId();
 
80
const int idCloseAllOthers = wxNewId();
 
81
const int idSaveMe = wxNewId();
 
82
const int idSaveAll = wxNewId();
 
83
const int idSwitchTo = wxNewId();
 
84
const int idGoogle = wxNewId();
 
85
const int idGoogleCode = wxNewId();
 
86
const int idMsdn = wxNewId();
 
87
 
 
88
BEGIN_EVENT_TABLE(SEditorBase, wxPanel)
 
89
    EVT_MENU_RANGE(idSwitchFile1, idSwitchFileMax,SEditorBase::OnContextMenuEntry)
 
90
    EVT_MENU(idCloseMe, SEditorBase::OnContextMenuEntry)
 
91
    EVT_MENU(idCloseAll, SEditorBase::OnContextMenuEntry)
 
92
    EVT_MENU(idCloseAllOthers, SEditorBase::OnContextMenuEntry)
 
93
    EVT_MENU(idSaveMe, SEditorBase::OnContextMenuEntry)
 
94
    EVT_MENU(idSaveAll, SEditorBase::OnContextMenuEntry)
 
95
    EVT_MENU(idGoogle, SEditorBase::OnContextMenuEntry)
 
96
    EVT_MENU(idGoogleCode, SEditorBase::OnContextMenuEntry)
 
97
    EVT_MENU(idMsdn, SEditorBase::OnContextMenuEntry)
 
98
END_EVENT_TABLE()
 
99
 
 
100
// ----------------------------------------------------------------------------
 
101
void SEditorBase::InitFilename(const wxString& filename)
 
102
// ----------------------------------------------------------------------------
 
103
{
 
104
    if (filename.IsEmpty())
 
105
        m_Filename = realpath(CreateUniqueFilename());
 
106
    else
 
107
        m_Filename = realpath(filename);
 
108
 
 
109
    wxFileName fname;
 
110
    fname.Assign(m_Filename);
 
111
    m_Shortname = fname.GetFullName();
 
112
    //    Manager::Get()->GetLogManager()->DebugLog("ctor: Filename=%s\nShort=%s", m_Filename.c_str(), m_Shortname.c_str());
 
113
}
 
114
 
 
115
// ----------------------------------------------------------------------------
 
116
wxString SEditorBase::CreateUniqueFilename()
 
117
// ----------------------------------------------------------------------------
 
118
{
 
119
    const wxString prefix = _("Untitled");
 
120
    const wxString path = wxGetCwd() + wxFILE_SEP_PATH;
 
121
    wxString tmp;
 
122
    int iter = 0;
 
123
    while (true)
 
124
    {
 
125
        tmp.Clear();
 
126
        tmp << path << prefix << wxString::Format(_T("%d"), iter);
 
127
        if (! GetEditorManager()->GetEditor(tmp) &&
 
128
                !wxFileExists(path + tmp))
 
129
        {
 
130
            return tmp;
 
131
        }
 
132
        ++iter;
 
133
    }
 
134
}
 
135
 
 
136
// ----------------------------------------------------------------------------
 
137
SEditorBase::SEditorBase(wxWindow* parent, const wxString& filename)
 
138
// ----------------------------------------------------------------------------
 
139
        : wxPanel(parent, -1),
 
140
        m_IsBuiltinEditor(false),
 
141
        m_Shortname(_T("")),
 
142
        m_Filename(_T("")),
 
143
        m_WinTitle(filename)
 
144
{
 
145
    //ctor
 
146
    m_pParent = parent;
 
147
        m_pData = new EditorBaseInternalData(this);
 
148
    // memorize EditorManager for this editor
 
149
    m_pEditorManager = GetConfig()->GetEditorManager(::wxGetTopLevelParent(this));
 
150
    GetEditorManager()->AddCustomEditor(this);
 
151
    InitFilename(filename);
 
152
    SetTitle(m_Shortname);
 
153
}
 
154
 
 
155
// ----------------------------------------------------------------------------
 
156
SEditorBase::~SEditorBase()
 
157
// ----------------------------------------------------------------------------
 
158
{
 
159
    //asm("int3"); /*trap*/
 
160
    if (GetEditorManager() ) // sanity check
 
161
        GetEditorManager()->RemoveCustomEditor(this);
 
162
 
 
163
    if (Manager::Get()->GetPluginManager())
 
164
    {
 
165
        CodeBlocksEvent event(cbEVT_EDITOR_CLOSE);
 
166
        event.SetEditor((EditorBase*)this);
 
167
        event.SetString(m_Filename);
 
168
 
 
169
        ////(pecan 2008/4/22) Dont notify plugins this non-sdk editor
 
170
        //-Manager::Get()->GetPluginManager()->NotifyPlugins(event);
 
171
    }
 
172
 
 
173
    delete m_pData;
 
174
}
 
175
 
 
176
const wxString& SEditorBase::GetTitle()
 
177
{
 
178
    return m_WinTitle;
 
179
}
 
180
 
 
181
void SEditorBase::SetTitle(const wxString& newTitle)
 
182
{
 
183
    m_WinTitle = newTitle;
 
184
    int mypage = GetEditorManager()->FindPageFromEditor(this);
 
185
    if (mypage != -1)
 
186
        GetEditorManager()->GetNotebook()->SetPageText(mypage, newTitle);
 
187
}
 
188
 
 
189
void SEditorBase::Activate()
 
190
{
 
191
    GetEditorManager()->SetActiveEditor(this);
 
192
}
 
193
 
 
194
bool SEditorBase::Close()
 
195
{
 
196
    Destroy();
 
197
    return true;
 
198
}
 
199
 
 
200
bool SEditorBase::IsBuiltinEditor() const
 
201
{
 
202
    return m_IsBuiltinEditor;
 
203
}
 
204
 
 
205
bool SEditorBase::ThereAreOthers() const
 
206
{
 
207
    bool hasOthers = false;
 
208
    hasOthers = GetEditorManager()->GetEditorsCount() > 1;
 
209
    //    for(int i = 0; i < SnippetsSearchFrame::GetEditorManager()->GetEditorsCount(); ++i)
 
210
    //    {
 
211
    //        SEditorBase* other = SnippetsSearchFrame::GetEditorManager()->GetEditor(i);
 
212
    //        if (!other || other == (SEditorBase*)this)
 
213
    //            continue;
 
214
    //        hasOthers = true;
 
215
    //        break;
 
216
    //    }
 
217
    return hasOthers;
 
218
}
 
219
 
 
220
wxMenu* SEditorBase::CreateContextSubMenu(int id) // For context menus
 
221
{
 
222
    wxMenu* menu = 0;
 
223
 
 
224
    if(id == idSwitchTo)
 
225
    {
 
226
        menu = new wxMenu;
 
227
        m_SwitchTo.clear();
 
228
        for (int i = 0; i < EditorMaxSwitchTo && i < GetEditorManager()->GetEditorsCount(); ++i)
 
229
        {
 
230
            SEditorBase* other = GetEditorManager()->GetEditor(i);
 
231
            if (!other || other == this)
 
232
                continue;
 
233
            int id = idSwitchFile1+i;
 
234
            //-m_SwitchTo[id] = (EditorBase*)other;
 
235
            m_SwitchTo[id] = (SEditorBase*)other;
 
236
            menu->Append(id, other->GetShortName());
 
237
        }
 
238
        if(!menu->GetMenuItemCount())
 
239
        {
 
240
            delete menu;
 
241
            menu = 0;
 
242
        }
 
243
    }
 
244
    return menu;
 
245
}
 
246
 
 
247
void SEditorBase::BasicAddToContextMenu(wxMenu* popup,ModuleType type)   //pecan 2006/03/22
 
248
{
 
249
    bool noeditor = (type != mtEditorManager);                          //pecan 2006/03/22
 
250
    if (type == mtOpenFilesList)                                        //pecan 2006/03/22
 
251
    {
 
252
      popup->Append(idCloseMe, _("Close"));
 
253
      popup->Append(idCloseAll, _("Close all"));
 
254
      popup->Append(idCloseAllOthers, _("Close all others"));
 
255
      popup->AppendSeparator();
 
256
      popup->Append(idSaveMe, _("Save"));
 
257
      popup->Append(idSaveAll, _("Save all"));
 
258
      popup->AppendSeparator();
 
259
      // enable/disable some items, based on state
 
260
      popup->Enable(idSaveMe, GetModified());
 
261
 
 
262
      bool hasOthers = ThereAreOthers();
 
263
      popup->Enable(idCloseAll, hasOthers);
 
264
      popup->Enable(idCloseAllOthers, hasOthers);
 
265
    }
 
266
    if(!noeditor)
 
267
    {
 
268
        wxMenu* switchto = CreateContextSubMenu(idSwitchTo);
 
269
        if(switchto)
 
270
            popup->Append(idSwitchTo, _("Switch to"), switchto);
 
271
    }
 
272
}
 
273
 
 
274
void SEditorBase::DisplayContextMenu(const wxPoint& position, ModuleType type)   //pecan 2006/03/22
 
275
{
 
276
    bool noeditor = (type != mtEditorManager);                                  //pecan 2006/03/22
 
277
    // noeditor:
 
278
    // True if context menu belongs to open files tree;
 
279
    // False if belongs to cbEditor
 
280
 
 
281
    // inform the editors we 're just about to create a context menu
 
282
    if (!OnBeforeBuildContextMenu(position, type))              //pecan 2006/03/22
 
283
        return;
 
284
 
 
285
    wxMenu* popup = new wxMenu;
 
286
 
 
287
    if(!noeditor && wxGetKeyState(WXK_CONTROL))
 
288
    {
 
289
        cbStyledTextCtrl* control = GetEditorManager()->GetBuiltinActiveEditor()->GetControl();
 
290
        wxString text = control->GetSelectedText();
 
291
        if (text.IsEmpty())
 
292
        {
 
293
            const int pos = control->GetCurrentPos();
 
294
            text = control->GetTextRange(control->WordStartPosition(pos, true), control->WordEndPosition(pos, true));
 
295
        }
 
296
 
 
297
        if(wxMinimumVersion<2,6,1>::eval)
 
298
        {
 
299
            popup->Append(idGoogle, _("Search the Internet for \"") + text + _("\""));
 
300
            popup->Append(idMsdn, _("Search MSDN for \"") + text + _("\""));
 
301
            popup->Append(idGoogleCode, _("Search Google Code for \"") + text + _("\""));
 
302
        }
 
303
        lastWord = text;
 
304
 
 
305
        wxMenu* switchto = CreateContextSubMenu(idSwitchTo);
 
306
        if(switchto)
 
307
        {
 
308
            popup->AppendSeparator();
 
309
            popup->Append(idSwitchTo, _("Switch to"), switchto);
 
310
        }
 
311
    }
 
312
    else if(!noeditor && wxGetKeyState(WXK_ALT))
 
313
    { // run a script
 
314
    }
 
315
    else
 
316
    {
 
317
        // Basic functions
 
318
        BasicAddToContextMenu(popup, type);         //pecan 2006/03/22
 
319
 
 
320
        // Extended functions, part 1 (virtual)
 
321
        AddToContextMenu(popup, type, false);       //pecan 2006/03/22
 
322
 
 
323
        // ask other editors / plugins if they need to add any entries in this menu...
 
324
        FileTreeData* ftd = new FileTreeData(0, FileTreeData::ftdkUndefined);
 
325
        ftd->SetFolder(m_Filename);
 
326
        Manager::Get()->GetPluginManager()->AskPluginsForModuleMenu(type, popup, ftd);              //pecan 2006/03/22
 
327
        delete ftd;
 
328
 
 
329
        popup->AppendSeparator();
 
330
        // Extended functions, part 2 (virtual)
 
331
        AddToContextMenu(popup, type, true);            //pecan 2006/03/22
 
332
    }
 
333
    // inform the editors we 're done creating a context menu (just about to show it)
 
334
    OnAfterBuildContextMenu(type);              //pecan 2006/03/22
 
335
 
 
336
    // display menu
 
337
    wxPoint clientpos;
 
338
    if (position==wxDefaultPosition) // "context menu" key
 
339
    {
 
340
        // obtain the caret point (on the screen) as we assume
 
341
        // that the user wants to work with the keyboard
 
342
        cbStyledTextCtrl* const control = GetEditorManager()->GetBuiltinActiveEditor()->GetControl();
 
343
        clientpos = control->PointFromPosition(control->GetCurrentPos());
 
344
    }
 
345
    else
 
346
    {
 
347
        clientpos = ScreenToClient(position);
 
348
    }
 
349
 
 
350
        m_pData->m_DisplayingPopupMenu = true;
 
351
    PopupMenu(popup, clientpos);
 
352
    delete popup;
 
353
    m_pData->m_DisplayingPopupMenu = false;
 
354
 
 
355
    // this code *must* be the last code executed by this function
 
356
    // because it *will* invalidate 'this'
 
357
    if (m_pData->m_CloseMe)
 
358
                GetEditorManager()->Close(this);
 
359
}
 
360
 
 
361
void SEditorBase::OnContextMenuEntry(wxCommandEvent& event)
 
362
{
 
363
    // we have a single event handler for all popup menu entries
 
364
    // This was ported from cbEditor and used for the basic operations:
 
365
    // Switch to, close, save, etc.
 
366
 
 
367
    const int id = event.GetId();
 
368
    m_pData->m_CloseMe = false;
 
369
 
 
370
    if (id == idCloseMe)
 
371
    {
 
372
        if (m_pData->m_DisplayingPopupMenu)
 
373
                        m_pData->m_CloseMe = true; // defer delete 'this' until after PopupMenu() call returns
 
374
                else
 
375
                        GetEditorManager()->Close(this);
 
376
    }
 
377
    else if (id == idCloseAll)
 
378
    {
 
379
        if (m_pData->m_DisplayingPopupMenu)
 
380
        {
 
381
                        GetEditorManager()->CloseAllExcept(this);
 
382
                        m_pData->m_CloseMe = true; // defer delete 'this' until after PopupMenu() call returns
 
383
        }
 
384
                else
 
385
                        GetEditorManager()->CloseAll();
 
386
    }
 
387
    else if (id == idCloseAllOthers)
 
388
    {
 
389
        GetEditorManager()->CloseAllExcept(this);
 
390
    }
 
391
    else if (id == idSaveMe)
 
392
    {
 
393
        Save();
 
394
    }
 
395
    else if (id == idSaveAll)
 
396
    {
 
397
        GetEditorManager()->SaveAll();
 
398
    }
 
399
    else
 
400
    if (id >= idSwitchFile1 && id <= idSwitchFileMax)
 
401
    {
 
402
        // "Switch to..." item
 
403
        SEditorBase *const ed = (SEditorBase*)m_SwitchTo[id];
 
404
        if (ed)
 
405
        {
 
406
            GetEditorManager()->SetActiveEditor(ed);
 
407
        }
 
408
        m_SwitchTo.clear();
 
409
    }
 
410
    else if(wxMinimumVersion<2,6,1>::eval)
 
411
    {
 
412
        if (id == idGoogleCode)
 
413
        {
 
414
            wxLaunchDefaultBrowser(wxString(_T("http://www.google.com/codesearch?q=")) << URLEncode(lastWord));
 
415
        }
 
416
        else if (id == idGoogle)
 
417
        {
 
418
            wxLaunchDefaultBrowser(wxString(_T("http://www.google.com/search?q=")) << URLEncode(lastWord));
 
419
        }
 
420
        else if (id == idMsdn)
 
421
        {
 
422
            wxLaunchDefaultBrowser(wxString(_T("http://search.microsoft.com/search/results.aspx?qu=")) << URLEncode(lastWord) << _T("&View=msdn"));
 
423
        }
 
424
    }
 
425
    else
 
426
    {
 
427
        event.Skip();
 
428
    }
 
429
}
 
430
// ----------------------------------------------------------------------------
 
431
void SEditorBase::SearchGotoLine()
 
432
// ----------------------------------------------------------------------------
 
433
{
 
434
    ScbEditor* ed = GetEditorManager()->GetBuiltinActiveEditor();
 
435
    if (!ed)
 
436
        return;
 
437
 
 
438
    int max = ed->GetControl()->LineFromPosition(ed->GetControl()->GetLength()) + 1;
 
439
 
 
440
    /**
 
441
    @remarks We use wxGetText instead of wxGetNumber because wxGetNumber *must*
 
442
    provide an initial line number...which doesn't make sense, and just keeps the
 
443
    user deleting the initial line number everytime he instantiates the dialog.
 
444
    However, this is just a temporary hack, because the default dialog used isn't
 
445
    that suitable either.
 
446
    */
 
447
    wxString strLine = wxGetTextFromUser( wxString::Format(_("Line (1 - %d): "), max),
 
448
                                        _("Goto line"),
 
449
                                        _T( "" ),
 
450
                                        this );
 
451
    long int line = 0;
 
452
    strLine.ToLong(&line);
 
453
    if ( line >= 1 && line <= max )
 
454
    {
 
455
        ed->UnfoldBlockFromLine(line - 1);
 
456
        ed->GotoLine(line - 1);
 
457
    }
 
458
}
 
459
// ----------------------------------------------------------------------------
 
460
void SEditorBase::SearchFind()
 
461
// ----------------------------------------------------------------------------
 
462
{
 
463
    bool bDoMultipleFiles ;
 
464
    bDoMultipleFiles = ! GetEditorManager()->GetBuiltinActiveEditor();
 
465
    GetEditorManager()->ShowFindDialog(false, bDoMultipleFiles);
 
466
 
 
467
}//SearchFind
 
468
// ----------------------------------------------------------------------------
 
469
void SEditorBase::SearchFindNext(bool next)
 
470
// ----------------------------------------------------------------------------
 
471
{
 
472
    GetEditorManager()->FindNext(next);
 
473
 
 
474
} // SearchFindNext
 
475
// ----------------------------------------------------------------------------
 
476
void SEditorBase::OnSearchReplace()
 
477
// ----------------------------------------------------------------------------
 
478
{
 
479
    bool bDoMultipleFiles = false;
 
480
    if(!bDoMultipleFiles)
 
481
    {
 
482
        bDoMultipleFiles = ! GetEditorManager()->GetBuiltinActiveEditor();
 
483
    }
 
484
    GetEditorManager()->ShowFindDialog(true, bDoMultipleFiles);
 
485
 
 
486
}//SearchReplace
 
487
// ----------------------------------------------------------------------------
 
488
// ----------------------------------------------------------------------------