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
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 $
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|
16
#include "sdk_precomp.h"
20
#include <wx/filename.h>
21
#include <wx/notebook.h>
23
#include <wx/textdlg.h> // wxGetTextFromUser
24
#include <wx/wfstream.h>
27
#include "seditorbase.h"
28
#include "scbeditor.h"
29
#include "seditormanager.h"
30
#include "pluginmanager.h"
31
#include "cbproject.h" // FileTreeData
34
#include <wx/xrc/xmlres.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
// ----------------------------------------------------------------------------
45
// ----------------------------------------------------------------------------
46
int idEditHighlightMode = XRCID("idEditHighlightMode");
47
int idEditHighlightModeText = XRCID("idEditHighlightModeText");
49
// needed for initialization of variables
50
// ----------------------------------------------------------------------------
51
int editorbase_RegisterId(int id)
52
// ----------------------------------------------------------------------------
58
// ----------------------------------------------------------------------------
59
struct EditorBaseInternalData
60
// ----------------------------------------------------------------------------
62
EditorBaseInternalData(SEditorBase* owner)
64
m_DisplayingPopupMenu(false),
68
SEditorBase* m_pOwner;
69
bool m_DisplayingPopupMenu;
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);
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();
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)
100
// ----------------------------------------------------------------------------
101
void SEditorBase::InitFilename(const wxString& filename)
102
// ----------------------------------------------------------------------------
104
if (filename.IsEmpty())
105
m_Filename = realpath(CreateUniqueFilename());
107
m_Filename = realpath(filename);
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());
115
// ----------------------------------------------------------------------------
116
wxString SEditorBase::CreateUniqueFilename()
117
// ----------------------------------------------------------------------------
119
const wxString prefix = _("Untitled");
120
const wxString path = wxGetCwd() + wxFILE_SEP_PATH;
126
tmp << path << prefix << wxString::Format(_T("%d"), iter);
127
if (! GetEditorManager()->GetEditor(tmp) &&
128
!wxFileExists(path + tmp))
136
// ----------------------------------------------------------------------------
137
SEditorBase::SEditorBase(wxWindow* parent, const wxString& filename)
138
// ----------------------------------------------------------------------------
139
: wxPanel(parent, -1),
140
m_IsBuiltinEditor(false),
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);
155
// ----------------------------------------------------------------------------
156
SEditorBase::~SEditorBase()
157
// ----------------------------------------------------------------------------
159
//asm("int3"); /*trap*/
160
if (GetEditorManager() ) // sanity check
161
GetEditorManager()->RemoveCustomEditor(this);
163
if (Manager::Get()->GetPluginManager())
165
CodeBlocksEvent event(cbEVT_EDITOR_CLOSE);
166
event.SetEditor((EditorBase*)this);
167
event.SetString(m_Filename);
169
////(pecan 2008/4/22) Dont notify plugins this non-sdk editor
170
//-Manager::Get()->GetPluginManager()->NotifyPlugins(event);
176
const wxString& SEditorBase::GetTitle()
181
void SEditorBase::SetTitle(const wxString& newTitle)
183
m_WinTitle = newTitle;
184
int mypage = GetEditorManager()->FindPageFromEditor(this);
186
GetEditorManager()->GetNotebook()->SetPageText(mypage, newTitle);
189
void SEditorBase::Activate()
191
GetEditorManager()->SetActiveEditor(this);
194
bool SEditorBase::Close()
200
bool SEditorBase::IsBuiltinEditor() const
202
return m_IsBuiltinEditor;
205
bool SEditorBase::ThereAreOthers() const
207
bool hasOthers = false;
208
hasOthers = GetEditorManager()->GetEditorsCount() > 1;
209
// for(int i = 0; i < SnippetsSearchFrame::GetEditorManager()->GetEditorsCount(); ++i)
211
// SEditorBase* other = SnippetsSearchFrame::GetEditorManager()->GetEditor(i);
212
// if (!other || other == (SEditorBase*)this)
220
wxMenu* SEditorBase::CreateContextSubMenu(int id) // For context menus
228
for (int i = 0; i < EditorMaxSwitchTo && i < GetEditorManager()->GetEditorsCount(); ++i)
230
SEditorBase* other = GetEditorManager()->GetEditor(i);
231
if (!other || other == this)
233
int id = idSwitchFile1+i;
234
//-m_SwitchTo[id] = (EditorBase*)other;
235
m_SwitchTo[id] = (SEditorBase*)other;
236
menu->Append(id, other->GetShortName());
238
if(!menu->GetMenuItemCount())
247
void SEditorBase::BasicAddToContextMenu(wxMenu* popup,ModuleType type) //pecan 2006/03/22
249
bool noeditor = (type != mtEditorManager); //pecan 2006/03/22
250
if (type == mtOpenFilesList) //pecan 2006/03/22
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());
262
bool hasOthers = ThereAreOthers();
263
popup->Enable(idCloseAll, hasOthers);
264
popup->Enable(idCloseAllOthers, hasOthers);
268
wxMenu* switchto = CreateContextSubMenu(idSwitchTo);
270
popup->Append(idSwitchTo, _("Switch to"), switchto);
274
void SEditorBase::DisplayContextMenu(const wxPoint& position, ModuleType type) //pecan 2006/03/22
276
bool noeditor = (type != mtEditorManager); //pecan 2006/03/22
278
// True if context menu belongs to open files tree;
279
// False if belongs to cbEditor
281
// inform the editors we 're just about to create a context menu
282
if (!OnBeforeBuildContextMenu(position, type)) //pecan 2006/03/22
285
wxMenu* popup = new wxMenu;
287
if(!noeditor && wxGetKeyState(WXK_CONTROL))
289
cbStyledTextCtrl* control = GetEditorManager()->GetBuiltinActiveEditor()->GetControl();
290
wxString text = control->GetSelectedText();
293
const int pos = control->GetCurrentPos();
294
text = control->GetTextRange(control->WordStartPosition(pos, true), control->WordEndPosition(pos, true));
297
if(wxMinimumVersion<2,6,1>::eval)
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 + _("\""));
305
wxMenu* switchto = CreateContextSubMenu(idSwitchTo);
308
popup->AppendSeparator();
309
popup->Append(idSwitchTo, _("Switch to"), switchto);
312
else if(!noeditor && wxGetKeyState(WXK_ALT))
318
BasicAddToContextMenu(popup, type); //pecan 2006/03/22
320
// Extended functions, part 1 (virtual)
321
AddToContextMenu(popup, type, false); //pecan 2006/03/22
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
329
popup->AppendSeparator();
330
// Extended functions, part 2 (virtual)
331
AddToContextMenu(popup, type, true); //pecan 2006/03/22
333
// inform the editors we 're done creating a context menu (just about to show it)
334
OnAfterBuildContextMenu(type); //pecan 2006/03/22
338
if (position==wxDefaultPosition) // "context menu" key
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());
347
clientpos = ScreenToClient(position);
350
m_pData->m_DisplayingPopupMenu = true;
351
PopupMenu(popup, clientpos);
353
m_pData->m_DisplayingPopupMenu = false;
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);
361
void SEditorBase::OnContextMenuEntry(wxCommandEvent& event)
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.
367
const int id = event.GetId();
368
m_pData->m_CloseMe = false;
372
if (m_pData->m_DisplayingPopupMenu)
373
m_pData->m_CloseMe = true; // defer delete 'this' until after PopupMenu() call returns
375
GetEditorManager()->Close(this);
377
else if (id == idCloseAll)
379
if (m_pData->m_DisplayingPopupMenu)
381
GetEditorManager()->CloseAllExcept(this);
382
m_pData->m_CloseMe = true; // defer delete 'this' until after PopupMenu() call returns
385
GetEditorManager()->CloseAll();
387
else if (id == idCloseAllOthers)
389
GetEditorManager()->CloseAllExcept(this);
391
else if (id == idSaveMe)
395
else if (id == idSaveAll)
397
GetEditorManager()->SaveAll();
400
if (id >= idSwitchFile1 && id <= idSwitchFileMax)
402
// "Switch to..." item
403
SEditorBase *const ed = (SEditorBase*)m_SwitchTo[id];
406
GetEditorManager()->SetActiveEditor(ed);
410
else if(wxMinimumVersion<2,6,1>::eval)
412
if (id == idGoogleCode)
414
wxLaunchDefaultBrowser(wxString(_T("http://www.google.com/codesearch?q=")) << URLEncode(lastWord));
416
else if (id == idGoogle)
418
wxLaunchDefaultBrowser(wxString(_T("http://www.google.com/search?q=")) << URLEncode(lastWord));
420
else if (id == idMsdn)
422
wxLaunchDefaultBrowser(wxString(_T("http://search.microsoft.com/search/results.aspx?qu=")) << URLEncode(lastWord) << _T("&View=msdn"));
430
// ----------------------------------------------------------------------------
431
void SEditorBase::SearchGotoLine()
432
// ----------------------------------------------------------------------------
434
ScbEditor* ed = GetEditorManager()->GetBuiltinActiveEditor();
438
int max = ed->GetControl()->LineFromPosition(ed->GetControl()->GetLength()) + 1;
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.
447
wxString strLine = wxGetTextFromUser( wxString::Format(_("Line (1 - %d): "), max),
452
strLine.ToLong(&line);
453
if ( line >= 1 && line <= max )
455
ed->UnfoldBlockFromLine(line - 1);
456
ed->GotoLine(line - 1);
459
// ----------------------------------------------------------------------------
460
void SEditorBase::SearchFind()
461
// ----------------------------------------------------------------------------
463
bool bDoMultipleFiles ;
464
bDoMultipleFiles = ! GetEditorManager()->GetBuiltinActiveEditor();
465
GetEditorManager()->ShowFindDialog(false, bDoMultipleFiles);
468
// ----------------------------------------------------------------------------
469
void SEditorBase::SearchFindNext(bool next)
470
// ----------------------------------------------------------------------------
472
GetEditorManager()->FindNext(next);
475
// ----------------------------------------------------------------------------
476
void SEditorBase::OnSearchReplace()
477
// ----------------------------------------------------------------------------
479
bool bDoMultipleFiles = false;
480
if(!bDoMultipleFiles)
482
bDoMultipleFiles = ! GetEditorManager()->GetBuiltinActiveEditor();
484
GetEditorManager()->ShowFindDialog(true, bDoMultipleFiles);
487
// ----------------------------------------------------------------------------
488
// ----------------------------------------------------------------------------